diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2007-12-28 08:32:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:09:43 -0500 |
commit | 471b3efdfccc257591331724145f8ccf8b3217e1 (patch) | |
tree | c9e576442c7b62c8c667ae1046e560323f0821fd /net/mac80211/ieee80211_sta.c | |
parent | 2bc454b0b30b3645d114689b64321cb49be99923 (diff) |
mac80211: add unified BSS configuration
This patch (based on Ron Rindjunsky's) creates a framework for
a unified way to pass BSS configuration to drivers that require
the information, e.g. for implementing power save mode.
This patch introduces new ieee80211_bss_conf structure that is
passed to the driver via the new bss_info_changed() callback
when the BSS configuration changes.
This new BSS configuration infrastructure adds the following
new features:
* drivers are notified of their association AID
* drivers are notified of association status
and replaces the erp_ie_changed() callback. The patch also does
the relevant driver updates for the latter change.
Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
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, 35 insertions, 34 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index b1e7d17ee253..866eb8078121 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
@@ -313,48 +313,42 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
313 | } | 313 | } |
314 | 314 | ||
315 | 315 | ||
316 | static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) | 316 | static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, |
317 | u8 erp_value) | ||
317 | { | 318 | { |
318 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 319 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; |
319 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 320 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
320 | int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; | 321 | bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; |
321 | int preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0; | 322 | bool preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0; |
322 | u8 changes = 0; | ||
323 | DECLARE_MAC_BUF(mac); | 323 | DECLARE_MAC_BUF(mac); |
324 | u32 changed = 0; | ||
324 | 325 | ||
325 | if (use_protection != !!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION)) { | 326 | if (use_protection != bss_conf->use_cts_prot) { |
326 | if (net_ratelimit()) { | 327 | if (net_ratelimit()) { |
327 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" | 328 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" |
328 | "%s)\n", | 329 | "%s)\n", |
329 | dev->name, | 330 | sdata->dev->name, |
330 | use_protection ? "enabled" : "disabled", | 331 | use_protection ? "enabled" : "disabled", |
331 | print_mac(mac, ifsta->bssid)); | 332 | print_mac(mac, ifsta->bssid)); |
332 | } | 333 | } |
333 | if (use_protection) | 334 | bss_conf->use_cts_prot = use_protection; |
334 | sdata->flags |= IEEE80211_SDATA_USE_PROTECTION; | 335 | changed |= BSS_CHANGED_ERP_CTS_PROT; |
335 | else | ||
336 | sdata->flags &= ~IEEE80211_SDATA_USE_PROTECTION; | ||
337 | changes |= IEEE80211_ERP_CHANGE_PROTECTION; | ||
338 | } | 336 | } |
339 | 337 | ||
340 | if (preamble_mode != !(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE)) { | 338 | if (preamble_mode != bss_conf->use_short_preamble) { |
341 | if (net_ratelimit()) { | 339 | if (net_ratelimit()) { |
342 | printk(KERN_DEBUG "%s: switched to %s barker preamble" | 340 | printk(KERN_DEBUG "%s: switched to %s barker preamble" |
343 | " (BSSID=%s)\n", | 341 | " (BSSID=%s)\n", |
344 | dev->name, | 342 | sdata->dev->name, |
345 | (preamble_mode == WLAN_ERP_PREAMBLE_SHORT) ? | 343 | (preamble_mode == WLAN_ERP_PREAMBLE_SHORT) ? |
346 | "short" : "long", | 344 | "short" : "long", |
347 | print_mac(mac, ifsta->bssid)); | 345 | print_mac(mac, ifsta->bssid)); |
348 | } | 346 | } |
349 | if (preamble_mode) | 347 | bss_conf->use_short_preamble = preamble_mode; |
350 | sdata->flags &= ~IEEE80211_SDATA_SHORT_PREAMBLE; | 348 | changed |= BSS_CHANGED_ERP_PREAMBLE; |
351 | else | ||
352 | sdata->flags |= IEEE80211_SDATA_SHORT_PREAMBLE; | ||
353 | changes |= IEEE80211_ERP_CHANGE_PREAMBLE; | ||
354 | } | 349 | } |
355 | 350 | ||
356 | if (changes) | 351 | return changed; |
357 | ieee80211_erp_info_change_notify(dev, changes); | ||
358 | } | 352 | } |
359 | 353 | ||
360 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, | 354 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, |
@@ -458,19 +452,16 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
458 | struct ieee80211_if_sta *ifsta, | 452 | struct ieee80211_if_sta *ifsta, |
459 | bool assoc) | 453 | bool assoc) |
460 | { | 454 | { |
461 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 455 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
456 | struct ieee80211_local *local = sdata->local; | ||
462 | union iwreq_data wrqu; | 457 | union iwreq_data wrqu; |
463 | 458 | u32 changed = BSS_CHANGED_ASSOC; | |
464 | if (!!(ifsta->flags & IEEE80211_STA_ASSOCIATED) == assoc) | ||
465 | return; | ||
466 | 459 | ||
467 | if (assoc) { | 460 | if (assoc) { |
468 | struct ieee80211_sub_if_data *sdata; | ||
469 | struct ieee80211_sta_bss *bss; | 461 | struct ieee80211_sta_bss *bss; |
470 | 462 | ||
471 | ifsta->flags |= IEEE80211_STA_ASSOCIATED; | 463 | ifsta->flags |= IEEE80211_STA_ASSOCIATED; |
472 | 464 | ||
473 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
474 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | 465 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) |
475 | return; | 466 | return; |
476 | 467 | ||
@@ -479,7 +470,8 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
479 | ifsta->ssid, ifsta->ssid_len); | 470 | ifsta->ssid, ifsta->ssid_len); |
480 | if (bss) { | 471 | if (bss) { |
481 | if (bss->has_erp_value) | 472 | if (bss->has_erp_value) |
482 | ieee80211_handle_erp_ie(dev, bss->erp_value); | 473 | changed |= ieee80211_handle_erp_ie( |
474 | sdata, bss->erp_value); | ||
483 | ieee80211_rx_bss_put(dev, bss); | 475 | ieee80211_rx_bss_put(dev, bss); |
484 | } | 476 | } |
485 | 477 | ||
@@ -499,6 +491,8 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
499 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); | 491 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); |
500 | ifsta->last_probe = jiffies; | 492 | ifsta->last_probe = jiffies; |
501 | ieee80211_led_assoc(local, assoc); | 493 | ieee80211_led_assoc(local, assoc); |
494 | |||
495 | ieee80211_bss_info_change_notify(sdata, changed); | ||
502 | } | 496 | } |
503 | 497 | ||
504 | static void ieee80211_set_disassoc(struct net_device *dev, | 498 | static void ieee80211_set_disassoc(struct net_device *dev, |
@@ -1536,18 +1530,20 @@ static void ieee80211_rx_mgmt_disassoc(struct net_device *dev, | |||
1536 | } | 1530 | } |
1537 | 1531 | ||
1538 | 1532 | ||
1539 | static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, | 1533 | static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, |
1540 | struct ieee80211_if_sta *ifsta, | 1534 | struct ieee80211_if_sta *ifsta, |
1541 | struct ieee80211_mgmt *mgmt, | 1535 | struct ieee80211_mgmt *mgmt, |
1542 | size_t len, | 1536 | size_t len, |
1543 | int reassoc) | 1537 | int reassoc) |
1544 | { | 1538 | { |
1545 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1539 | struct ieee80211_local *local = sdata->local; |
1540 | struct net_device *dev = sdata->dev; | ||
1546 | struct ieee80211_hw_mode *mode; | 1541 | struct ieee80211_hw_mode *mode; |
1547 | struct sta_info *sta; | 1542 | struct sta_info *sta; |
1548 | u32 rates; | 1543 | u32 rates; |
1549 | u16 capab_info, status_code, aid; | 1544 | u16 capab_info, status_code, aid; |
1550 | struct ieee802_11_elems elems; | 1545 | struct ieee802_11_elems elems; |
1546 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | ||
1551 | u8 *pos; | 1547 | u8 *pos; |
1552 | int i, j; | 1548 | int i, j; |
1553 | DECLARE_MAC_BUF(mac); | 1549 | DECLARE_MAC_BUF(mac); |
@@ -1620,6 +1616,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, | |||
1620 | if (ifsta->assocresp_ies) | 1616 | if (ifsta->assocresp_ies) |
1621 | memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len); | 1617 | memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len); |
1622 | 1618 | ||
1619 | /* set AID, ieee80211_set_associated() will tell the driver */ | ||
1620 | bss_conf->aid = aid; | ||
1623 | ieee80211_set_associated(dev, ifsta, 1); | 1621 | ieee80211_set_associated(dev, ifsta, 1); |
1624 | 1622 | ||
1625 | /* Add STA entry for the AP */ | 1623 | /* Add STA entry for the AP */ |
@@ -2099,6 +2097,7 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
2099 | struct ieee802_11_elems elems; | 2097 | struct ieee802_11_elems elems; |
2100 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2098 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
2101 | struct ieee80211_conf *conf = &local->hw.conf; | 2099 | struct ieee80211_conf *conf = &local->hw.conf; |
2100 | u32 changed = 0; | ||
2102 | 2101 | ||
2103 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 1); | 2102 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 1); |
2104 | 2103 | ||
@@ -2119,7 +2118,7 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
2119 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | 2118 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); |
2120 | 2119 | ||
2121 | if (elems.erp_info && elems.erp_info_len >= 1) | 2120 | if (elems.erp_info && elems.erp_info_len >= 1) |
2122 | ieee80211_handle_erp_ie(dev, elems.erp_info[0]); | 2121 | changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); |
2123 | 2122 | ||
2124 | if (elems.ht_cap_elem && elems.ht_info_elem && | 2123 | if (elems.ht_cap_elem && elems.ht_info_elem && |
2125 | elems.wmm_param && local->ops->conf_ht && | 2124 | elems.wmm_param && local->ops->conf_ht && |
@@ -2142,6 +2141,8 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
2142 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | 2141 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
2143 | elems.wmm_param_len); | 2142 | elems.wmm_param_len); |
2144 | } | 2143 | } |
2144 | |||
2145 | ieee80211_bss_info_change_notify(sdata, changed); | ||
2145 | } | 2146 | } |
2146 | 2147 | ||
2147 | 2148 | ||
@@ -2329,10 +2330,10 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev, | |||
2329 | ieee80211_rx_mgmt_auth(dev, ifsta, mgmt, skb->len); | 2330 | ieee80211_rx_mgmt_auth(dev, ifsta, mgmt, skb->len); |
2330 | break; | 2331 | break; |
2331 | case IEEE80211_STYPE_ASSOC_RESP: | 2332 | case IEEE80211_STYPE_ASSOC_RESP: |
2332 | ieee80211_rx_mgmt_assoc_resp(dev, ifsta, mgmt, skb->len, 0); | 2333 | ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0); |
2333 | break; | 2334 | break; |
2334 | case IEEE80211_STYPE_REASSOC_RESP: | 2335 | case IEEE80211_STYPE_REASSOC_RESP: |
2335 | ieee80211_rx_mgmt_assoc_resp(dev, ifsta, mgmt, skb->len, 1); | 2336 | ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1); |
2336 | break; | 2337 | break; |
2337 | case IEEE80211_STYPE_DEAUTH: | 2338 | case IEEE80211_STYPE_DEAUTH: |
2338 | ieee80211_rx_mgmt_deauth(dev, ifsta, mgmt, skb->len); | 2339 | ieee80211_rx_mgmt_deauth(dev, ifsta, mgmt, skb->len); |
@@ -2787,7 +2788,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2787 | break; | 2788 | break; |
2788 | } | 2789 | } |
2789 | control.tx_rate = | 2790 | control.tx_rate = |
2790 | ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) && | 2791 | (sdata->bss_conf.use_short_preamble && |
2791 | (ratesel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ? | 2792 | (ratesel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ? |
2792 | ratesel.rate->val2 : ratesel.rate->val; | 2793 | ratesel.rate->val2 : ratesel.rate->val; |
2793 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 2794 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; |