diff options
author | Daniel Drake <dsd@gentoo.org> | 2007-07-10 13:32:10 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2007-07-12 16:07:26 -0400 |
commit | 5628221caf88e2a052782b042e12da7cd34111b0 (patch) | |
tree | b4dbee3be1aa2b39e3d4c6f384b28d07740465fd /net/mac80211/ieee80211_sta.c | |
parent | 1fd5e589d8c7d3cd42ddd39358338766cfcedec8 (diff) |
[PATCH] mac80211: ERP IE handling improvements
The "protection needed" flag is currently parsed out of the ERP IE in
beacons. This patch allows the ERP IE to be available at assocation time
and causes the appropriate actions to be performed earlier.
It is slightly complicated by the fact that most APs don't include the
ERP IE in association responses. To work around this, we store ERP
values in the ieee80211_sta_bss structure.
Also added some WLAN_ERP defines for use by upcoming patches.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ieee80211_sta.c')
-rw-r--r-- | net/mac80211/ieee80211_sta.c | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index f3ca83743b48..df6c410de161 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
@@ -314,6 +314,27 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
314 | } | 314 | } |
315 | 315 | ||
316 | 316 | ||
317 | static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) | ||
318 | { | ||
319 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
320 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
321 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | ||
322 | int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; | ||
323 | |||
324 | if (use_protection != !!ifsta->use_protection) { | ||
325 | if (net_ratelimit()) { | ||
326 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" | ||
327 | MAC_FMT ")\n", | ||
328 | dev->name, | ||
329 | use_protection ? "enabled" : "disabled", | ||
330 | MAC_ARG(ifsta->bssid)); | ||
331 | } | ||
332 | ifsta->use_protection = use_protection ? 1 : 0; | ||
333 | local->cts_protect_erp_frames = use_protection; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | |||
317 | static void ieee80211_sta_send_associnfo(struct net_device *dev, | 338 | static void ieee80211_sta_send_associnfo(struct net_device *dev, |
318 | struct ieee80211_if_sta *ifsta) | 339 | struct ieee80211_if_sta *ifsta) |
319 | { | 340 | { |
@@ -377,9 +398,18 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
377 | 398 | ||
378 | if (assoc) { | 399 | if (assoc) { |
379 | struct ieee80211_sub_if_data *sdata; | 400 | struct ieee80211_sub_if_data *sdata; |
401 | struct ieee80211_sta_bss *bss; | ||
380 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 402 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
381 | if (sdata->type != IEEE80211_IF_TYPE_STA) | 403 | if (sdata->type != IEEE80211_IF_TYPE_STA) |
382 | return; | 404 | return; |
405 | |||
406 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid); | ||
407 | if (bss) { | ||
408 | if (bss->has_erp_value) | ||
409 | ieee80211_handle_erp_ie(dev, bss->erp_value); | ||
410 | ieee80211_rx_bss_put(dev, bss); | ||
411 | } | ||
412 | |||
383 | netif_carrier_on(dev); | 413 | netif_carrier_on(dev); |
384 | ifsta->prev_bssid_set = 1; | 414 | ifsta->prev_bssid_set = 1; |
385 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); | 415 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); |
@@ -1177,6 +1207,18 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, | |||
1177 | return; | 1207 | return; |
1178 | } | 1208 | } |
1179 | 1209 | ||
1210 | /* it probably doesn't, but if the frame includes an ERP value then | ||
1211 | * update our stored copy */ | ||
1212 | if (elems.erp_info && elems.erp_info_len >= 1) { | ||
1213 | struct ieee80211_sta_bss *bss | ||
1214 | = ieee80211_rx_bss_get(dev, ifsta->bssid); | ||
1215 | if (bss) { | ||
1216 | bss->erp_value = elems.erp_info[0]; | ||
1217 | bss->has_erp_value = 1; | ||
1218 | ieee80211_rx_bss_put(dev, bss); | ||
1219 | } | ||
1220 | } | ||
1221 | |||
1180 | printk(KERN_DEBUG "%s: associated\n", dev->name); | 1222 | printk(KERN_DEBUG "%s: associated\n", dev->name); |
1181 | ifsta->aid = aid; | 1223 | ifsta->aid = aid; |
1182 | ifsta->ap_capab = capab_info; | 1224 | ifsta->ap_capab = capab_info; |
@@ -1499,6 +1541,12 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
1499 | return; | 1541 | return; |
1500 | } | 1542 | } |
1501 | 1543 | ||
1544 | /* save the ERP value so that it is available at association time */ | ||
1545 | if (elems.erp_info && elems.erp_info_len >= 1) { | ||
1546 | bss->erp_value = elems.erp_info[0]; | ||
1547 | bss->has_erp_value = 1; | ||
1548 | } | ||
1549 | |||
1502 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); | 1550 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); |
1503 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); | 1551 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); |
1504 | if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) { | 1552 | if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) { |
@@ -1614,10 +1662,8 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
1614 | size_t len, | 1662 | size_t len, |
1615 | struct ieee80211_rx_status *rx_status) | 1663 | struct ieee80211_rx_status *rx_status) |
1616 | { | 1664 | { |
1617 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1618 | struct ieee80211_sub_if_data *sdata; | 1665 | struct ieee80211_sub_if_data *sdata; |
1619 | struct ieee80211_if_sta *ifsta; | 1666 | struct ieee80211_if_sta *ifsta; |
1620 | int use_protection; | ||
1621 | size_t baselen; | 1667 | size_t baselen; |
1622 | struct ieee802_11_elems elems; | 1668 | struct ieee802_11_elems elems; |
1623 | 1669 | ||
@@ -1641,23 +1687,8 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
1641 | &elems) == ParseFailed) | 1687 | &elems) == ParseFailed) |
1642 | return; | 1688 | return; |
1643 | 1689 | ||
1644 | use_protection = 0; | 1690 | if (elems.erp_info && elems.erp_info_len >= 1) |
1645 | if (elems.erp_info && elems.erp_info_len >= 1) { | 1691 | ieee80211_handle_erp_ie(dev, elems.erp_info[0]); |
1646 | use_protection = | ||
1647 | (elems.erp_info[0] & ERP_INFO_USE_PROTECTION) != 0; | ||
1648 | } | ||
1649 | |||
1650 | if (use_protection != !!ifsta->use_protection) { | ||
1651 | if (net_ratelimit()) { | ||
1652 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" | ||
1653 | MAC_FMT ")\n", | ||
1654 | dev->name, | ||
1655 | use_protection ? "enabled" : "disabled", | ||
1656 | MAC_ARG(ifsta->bssid)); | ||
1657 | } | ||
1658 | ifsta->use_protection = use_protection ? 1 : 0; | ||
1659 | local->cts_protect_erp_frames = use_protection; | ||
1660 | } | ||
1661 | 1692 | ||
1662 | if (elems.wmm_param && ifsta->wmm_enabled) { | 1693 | if (elems.wmm_param && ifsta->wmm_enabled) { |
1663 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | 1694 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |