📄 ieee80211softmac_module.c
字号:
int i; struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo; for (i=0; i<ri->count-1; i++) { if (ri->rates[i] == rate) return ri->rates[i+1]; } /* I guess we can't go any higher... */ return ri->rates[ri->count];}u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta){ int i; struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo; for (i=delta; i<ri->count; i++) { if (ri->rates[i] == rate) return ri->rates[i-delta]; } /* I guess we can't go any lower... */ return ri->rates[0];}static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac, int amount){ struct ieee80211softmac_txrates oldrates; u8 default_rate = mac->txrates.default_rate; u8 default_fallback = mac->txrates.default_fallback; u32 changes = 0; //TODO: This is highly experimental code. // Maybe the dynamic rate selection does not work // and it has to be removed again.printk("badness %d\n", mac->txrate_badness); mac->txrate_badness += amount; if (mac->txrate_badness <= -1000) { /* Very small badness. Try a faster bitrate. */ if (mac->txrates_change) memcpy(&oldrates, &mac->txrates, sizeof(oldrates)); default_rate = raise_rate(mac, default_rate); changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; default_fallback = get_fallback_rate(mac, default_rate); changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK; mac->txrate_badness = 0;printk("Bitrate raised to %u\n", default_rate); } else if (mac->txrate_badness >= 10000) { /* Very high badness. Try a slower bitrate. */ if (mac->txrates_change) memcpy(&oldrates, &mac->txrates, sizeof(oldrates)); default_rate = lower_rate(mac, default_rate); changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; default_fallback = get_fallback_rate(mac, default_rate); changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK; mac->txrate_badness = 0;printk("Bitrate lowered to %u\n", default_rate); } mac->txrates.default_rate = default_rate; mac->txrates.default_fallback = default_fallback; if (changes && mac->txrates_change) mac->txrates_change(mac->dev, changes, &oldrates);}void ieee80211softmac_fragment_lost(struct net_device *dev, u16 wl_seq){ struct ieee80211softmac_device *mac = ieee80211_priv(dev); unsigned long flags; spin_lock_irqsave(&mac->lock, flags); ieee80211softmac_add_txrates_badness(mac, 1000); //TODO spin_unlock_irqrestore(&mac->lock, flags);}EXPORT_SYMBOL_GPL(ieee80211softmac_fragment_lost);static int rate_cmp(const void *a_, const void *b_) { u8 *a, *b; a = (u8*)a_; b = (u8*)b_; return ((*a & ~IEEE80211_BASIC_RATE_MASK) - (*b & ~IEEE80211_BASIC_RATE_MASK));}/* Allocate a softmac network struct and fill it from a network */struct ieee80211softmac_network *ieee80211softmac_create_network(struct ieee80211softmac_device *mac, struct ieee80211_network *net){ struct ieee80211softmac_network *softnet; softnet = kzalloc(sizeof(struct ieee80211softmac_network), GFP_ATOMIC); if(softnet == NULL) return NULL; memcpy(softnet->bssid, net->bssid, ETH_ALEN); softnet->channel = net->channel; softnet->essid.len = net->ssid_len; memcpy(softnet->essid.data, net->ssid, softnet->essid.len); /* copy rates over */ softnet->supported_rates.count = net->rates_len; memcpy(&softnet->supported_rates.rates[0], net->rates, net->rates_len); memcpy(&softnet->supported_rates.rates[softnet->supported_rates.count], net->rates_ex, net->rates_ex_len); softnet->supported_rates.count += net->rates_ex_len; sort(softnet->supported_rates.rates, softnet->supported_rates.count, sizeof(softnet->supported_rates.rates[0]), rate_cmp, NULL); softnet->capabilities = net->capability; return softnet;}/* Add a network to the list, while locked */voidieee80211softmac_add_network_locked(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *add_net){ struct list_head *list_ptr; struct ieee80211softmac_network *softmac_net = NULL; list_for_each(list_ptr, &mac->network_list) { softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list); if(!memcmp(softmac_net->bssid, add_net->bssid, ETH_ALEN)) break; else softmac_net = NULL; } if(softmac_net == NULL) list_add(&(add_net->list), &mac->network_list);}/* Add a network to the list, with locking */voidieee80211softmac_add_network(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *add_net){ unsigned long flags; spin_lock_irqsave(&mac->lock, flags); ieee80211softmac_add_network_locked(mac, add_net); spin_unlock_irqrestore(&mac->lock, flags);}/* Delete a network from the list, while locked*/voidieee80211softmac_del_network_locked(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *del_net){ list_del(&(del_net->list));}/* Delete a network from the list with locking */voidieee80211softmac_del_network(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *del_net){ unsigned long flags; spin_lock_irqsave(&mac->lock, flags); ieee80211softmac_del_network_locked(mac, del_net); spin_unlock_irqrestore(&mac->lock, flags);}/* Get a network from the list by MAC while locked */struct ieee80211softmac_network *ieee80211softmac_get_network_by_bssid_locked(struct ieee80211softmac_device *mac, u8 *bssid){ struct list_head *list_ptr; struct ieee80211softmac_network *softmac_net = NULL; list_for_each(list_ptr, &mac->network_list) { softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list); if(!memcmp(softmac_net->bssid, bssid, ETH_ALEN)) break; else softmac_net = NULL; } return softmac_net;}/* Get a network from the list by BSSID with locking */struct ieee80211softmac_network *ieee80211softmac_get_network_by_bssid(struct ieee80211softmac_device *mac, u8 *bssid){ unsigned long flags; struct ieee80211softmac_network *softmac_net; spin_lock_irqsave(&mac->lock, flags); softmac_net = ieee80211softmac_get_network_by_bssid_locked(mac, bssid); spin_unlock_irqrestore(&mac->lock, flags); return softmac_net;}/* Get a network from the list by ESSID while locked */struct ieee80211softmac_network *ieee80211softmac_get_network_by_essid_locked(struct ieee80211softmac_device *mac, struct ieee80211softmac_essid *essid){ struct list_head *list_ptr; struct ieee80211softmac_network *softmac_net = NULL; list_for_each(list_ptr, &mac->network_list) { softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list); if (softmac_net->essid.len == essid->len && !memcmp(softmac_net->essid.data, essid->data, essid->len)) return softmac_net; } return NULL;}/* Get a network from the list by ESSID with locking */struct ieee80211softmac_network *ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac, struct ieee80211softmac_essid *essid) { unsigned long flags; struct ieee80211softmac_network *softmac_net = NULL; spin_lock_irqsave(&mac->lock, flags); softmac_net = ieee80211softmac_get_network_by_essid_locked(mac, essid); spin_unlock_irqrestore(&mac->lock, flags); return softmac_net;}MODULE_LICENSE("GPL");MODULE_AUTHOR("Johannes Berg");MODULE_AUTHOR("Joseph Jezak");MODULE_AUTHOR("Larry Finger");MODULE_AUTHOR("Danny van Dyk");MODULE_AUTHOR("Michael Buesch");MODULE_DESCRIPTION("802.11 software MAC");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -