[PATCH] softmac: ERP handling and driver-level notifications
This patch implements ERP handling in softmac so that the drivers can support protection and preambles properly. I added a new struct, ieee80211softmac_bss_info, which is used for BSS-dependent variables like these. A new hook has been added (bssinfo_change), which allows the drivers to be notified when anything in bssinfo changes. I modified the txrates_change API to match the bssinfo_change API. The existing one is a little messy and the usefulness of providing the old rates is questionable (and can be implemented at driver level if really necessary). No drivers are using this API (yet), so this should be safe. Signed-off-by: Daniel Drake <dsd@gentoo.org> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:

committed by
John W. Linville

父節點
d8e2be90d3
當前提交
5acd0c4153
@@ -44,6 +44,7 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv)
|
||||
softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response;
|
||||
softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req;
|
||||
softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc;
|
||||
softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon;
|
||||
softmac->scaninfo = NULL;
|
||||
|
||||
softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
|
||||
@@ -209,35 +210,59 @@ static u8 highest_supported_rate(struct ieee80211softmac_device *mac,
|
||||
return user_rate;
|
||||
}
|
||||
|
||||
void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
|
||||
u8 erp_value)
|
||||
{
|
||||
int use_protection;
|
||||
int short_preamble;
|
||||
u32 changes = 0;
|
||||
|
||||
/* Barker preamble mode */
|
||||
short_preamble = ((erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0
|
||||
&& mac->associnfo.short_preamble_available) ? 1 : 0;
|
||||
|
||||
/* Protection needed? */
|
||||
use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
|
||||
|
||||
if (mac->bssinfo.short_preamble != short_preamble) {
|
||||
changes |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
|
||||
mac->bssinfo.short_preamble = short_preamble;
|
||||
}
|
||||
|
||||
if (mac->bssinfo.use_protection != use_protection) {
|
||||
changes |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
|
||||
mac->bssinfo.use_protection = use_protection;
|
||||
}
|
||||
|
||||
if (mac->bssinfo_change && changes)
|
||||
mac->bssinfo_change(mac->dev, changes);
|
||||
}
|
||||
|
||||
void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac)
|
||||
{
|
||||
struct ieee80211softmac_txrates *txrates = &mac->txrates;
|
||||
struct ieee80211softmac_txrates oldrates;
|
||||
u32 change = 0;
|
||||
|
||||
if (mac->txrates_change)
|
||||
oldrates = mac->txrates;
|
||||
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
|
||||
txrates->default_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 0);
|
||||
txrates->default_rate = highest_supported_rate(mac, &mac->bssinfo.supported_rates, 0);
|
||||
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
|
||||
txrates->default_fallback = lower_rate(mac, txrates->default_rate);
|
||||
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
|
||||
txrates->mcast_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 1);
|
||||
txrates->mcast_rate = highest_supported_rate(mac, &mac->bssinfo.supported_rates, 1);
|
||||
|
||||
if (mac->txrates_change)
|
||||
mac->txrates_change(mac->dev, change, &oldrates);
|
||||
mac->txrates_change(mac->dev, change);
|
||||
|
||||
}
|
||||
|
||||
void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac)
|
||||
void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac)
|
||||
{
|
||||
struct ieee80211_device *ieee = mac->ieee;
|
||||
u32 change = 0;
|
||||
struct ieee80211softmac_txrates *txrates = &mac->txrates;
|
||||
struct ieee80211softmac_txrates oldrates;
|
||||
struct ieee80211softmac_bss_info *bssinfo = &mac->bssinfo;
|
||||
|
||||
/* TODO: We need some kind of state machine to lower the default rates
|
||||
* if we loose too many packets.
|
||||
@@ -245,8 +270,6 @@ void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac)
|
||||
/* Change the default txrate to the highest possible value.
|
||||
* The txrate machine will lower it, if it is too high.
|
||||
*/
|
||||
if (mac->txrates_change)
|
||||
oldrates = mac->txrates;
|
||||
/* FIXME: We don't correctly handle backing down to lower
|
||||
rates, so 801.11g devices start off at 11M for now. People
|
||||
can manually change it if they really need to, but 11M is
|
||||
@@ -272,7 +295,23 @@ void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac)
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST;
|
||||
|
||||
if (mac->txrates_change)
|
||||
mac->txrates_change(mac->dev, change, &oldrates);
|
||||
mac->txrates_change(mac->dev, change);
|
||||
|
||||
change = 0;
|
||||
|
||||
bssinfo->supported_rates.count = 0;
|
||||
memset(bssinfo->supported_rates.rates, 0,
|
||||
sizeof(bssinfo->supported_rates.rates));
|
||||
change |= IEEE80211SOFTMAC_BSSINFOCHG_RATES;
|
||||
|
||||
bssinfo->short_preamble = 0;
|
||||
change |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
|
||||
|
||||
bssinfo->use_protection = 0;
|
||||
change |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
|
||||
|
||||
if (mac->bssinfo_change)
|
||||
mac->bssinfo_change(mac->dev, change);
|
||||
|
||||
mac->running = 1;
|
||||
}
|
||||
@@ -282,7 +321,7 @@ void ieee80211softmac_start(struct net_device *dev)
|
||||
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
||||
|
||||
ieee80211softmac_start_check_rates(mac);
|
||||
ieee80211softmac_init_txrates(mac);
|
||||
ieee80211softmac_init_bss(mac);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee80211softmac_start);
|
||||
|
||||
@@ -335,7 +374,6 @@ u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rat
|
||||
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;
|
||||
@@ -348,8 +386,6 @@ 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);
|
||||
@@ -358,8 +394,6 @@ printk("badness %d\n", mac->txrate_badness);
|
||||
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);
|
||||
@@ -372,7 +406,7 @@ printk("Bitrate lowered to %u\n", default_rate);
|
||||
mac->txrates.default_fallback = default_fallback;
|
||||
|
||||
if (changes && mac->txrates_change)
|
||||
mac->txrates_change(mac->dev, changes, &oldrates);
|
||||
mac->txrates_change(mac->dev, changes);
|
||||
}
|
||||
|
||||
void ieee80211softmac_fragment_lost(struct net_device *dev,
|
||||
@@ -416,7 +450,11 @@ ieee80211softmac_create_network(struct ieee80211softmac_device *mac,
|
||||
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);
|
||||
|
||||
|
||||
/* we save the ERP value because it is needed at association time, and
|
||||
* many AP's do not include an ERP IE in the association response. */
|
||||
softnet->erp_value = net->erp_value;
|
||||
|
||||
softnet->capabilities = net->capability;
|
||||
return softnet;
|
||||
}
|
||||
|
Reference in New Issue
Block a user