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 | |
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>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 12 | ||||
-rw-r--r-- | include/net/mac80211.h | 66 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211.c | 29 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 19 | ||||
-rw-r--r-- | net/mac80211/ieee80211_sta.c | 69 | ||||
-rw-r--r-- | net/mac80211/tx.c | 13 | ||||
-rw-r--r-- | net/mac80211/util.c | 12 |
19 files changed, 183 insertions, 120 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index a793cd11f738..77e7202c026b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -520,10 +520,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
520 | break; | 520 | break; |
521 | 521 | ||
522 | /* | 522 | /* |
523 | * TODO: There is no callback function from upper | 523 | * TODO: Use the new callback function from |
524 | * stack to inform us when associated status. this | 524 | * mac80211 instead of sniffing these packets. |
525 | * work around to sniff assoc_resp management frame | ||
526 | * and finish the association process. | ||
527 | */ | 525 | */ |
528 | case IEEE80211_STYPE_ASSOC_RESP: | 526 | case IEEE80211_STYPE_ASSOC_RESP: |
529 | case IEEE80211_STYPE_REASSOC_RESP:{ | 527 | case IEEE80211_STYPE_REASSOC_RESP:{ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 89e2c44bfcca..ed3f119b56cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -4095,10 +4095,8 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, | |||
4095 | break; | 4095 | break; |
4096 | 4096 | ||
4097 | /* | 4097 | /* |
4098 | * TODO: There is no callback function from upper | 4098 | * TODO: Use the new callback function from |
4099 | * stack to inform us when associated status. this | 4099 | * mac80211 instead of sniffing these packets. |
4100 | * work around to sniff assoc_resp management frame | ||
4101 | * and finish the association process. | ||
4102 | */ | 4100 | */ |
4103 | case IEEE80211_STYPE_ASSOC_RESP: | 4101 | case IEEE80211_STYPE_ASSOC_RESP: |
4104 | case IEEE80211_STYPE_REASSOC_RESP: | 4102 | case IEEE80211_STYPE_REASSOC_RESP: |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 92bb7e13a1f0..2597c08a2395 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -7764,25 +7764,35 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, | |||
7764 | IWL_DEBUG_MAC80211("leave\n"); | 7764 | IWL_DEBUG_MAC80211("leave\n"); |
7765 | 7765 | ||
7766 | } | 7766 | } |
7767 | static void iwl4965_mac_erp_ie_changed(struct ieee80211_hw *hw, | 7767 | |
7768 | u8 changes, int cts_protection, int preamble) | 7768 | static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, |
7769 | struct ieee80211_vif *vif, | ||
7770 | struct ieee80211_bss_conf *bss_conf, | ||
7771 | u32 changes) | ||
7769 | { | 7772 | { |
7770 | struct iwl4965_priv *priv = hw->priv; | 7773 | struct iwl4965_priv *priv = hw->priv; |
7771 | 7774 | ||
7772 | if (changes & IEEE80211_ERP_CHANGE_PREAMBLE) { | 7775 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { |
7773 | if (preamble == WLAN_ERP_PREAMBLE_SHORT) | 7776 | if (bss_conf->use_short_preamble) |
7774 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 7777 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
7775 | else | 7778 | else |
7776 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; | 7779 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; |
7777 | } | 7780 | } |
7778 | 7781 | ||
7779 | if (changes & IEEE80211_ERP_CHANGE_PROTECTION) { | 7782 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { |
7780 | if (cts_protection && (priv->phymode != MODE_IEEE80211A)) | 7783 | if (bss_conf->use_cts_prot && (priv->phymode != MODE_IEEE80211A)) |
7781 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; | 7784 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; |
7782 | else | 7785 | else |
7783 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | 7786 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; |
7784 | } | 7787 | } |
7785 | 7788 | ||
7789 | if (changes & BSS_CHANGED_ASSOC) { | ||
7790 | /* | ||
7791 | * TODO: | ||
7792 | * do stuff instead of sniffing assoc resp | ||
7793 | */ | ||
7794 | } | ||
7795 | |||
7786 | if (iwl4965_is_associated(priv)) | 7796 | if (iwl4965_is_associated(priv)) |
7787 | iwl4965_send_rxon_assoc(priv); | 7797 | iwl4965_send_rxon_assoc(priv); |
7788 | } | 7798 | } |
@@ -8952,7 +8962,7 @@ static struct ieee80211_ops iwl4965_hw_ops = { | |||
8952 | .get_tsf = iwl4965_mac_get_tsf, | 8962 | .get_tsf = iwl4965_mac_get_tsf, |
8953 | .reset_tsf = iwl4965_mac_reset_tsf, | 8963 | .reset_tsf = iwl4965_mac_reset_tsf, |
8954 | .beacon_update = iwl4965_mac_beacon_update, | 8964 | .beacon_update = iwl4965_mac_beacon_update, |
8955 | .erp_ie_changed = iwl4965_mac_erp_ie_changed, | 8965 | .bss_info_changed = iwl4965_bss_info_changed, |
8956 | #ifdef CONFIG_IWL4965_HT | 8966 | #ifdef CONFIG_IWL4965_HT |
8957 | .conf_ht = iwl4965_mac_conf_ht, | 8967 | .conf_ht = iwl4965_mac_conf_ht, |
8958 | .ampdu_action = iwl4965_mac_ampdu_action, | 8968 | .ampdu_action = iwl4965_mac_ampdu_action, |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index f4d0c779ac78..d6cba138c7ab 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1524,7 +1524,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { | |||
1524 | .configure_filter = rt2400pci_configure_filter, | 1524 | .configure_filter = rt2400pci_configure_filter, |
1525 | .get_stats = rt2x00mac_get_stats, | 1525 | .get_stats = rt2x00mac_get_stats, |
1526 | .set_retry_limit = rt2400pci_set_retry_limit, | 1526 | .set_retry_limit = rt2400pci_set_retry_limit, |
1527 | .erp_ie_changed = rt2x00mac_erp_ie_changed, | 1527 | .bss_info_changed = rt2x00mac_bss_info_changed, |
1528 | .conf_tx = rt2400pci_conf_tx, | 1528 | .conf_tx = rt2400pci_conf_tx, |
1529 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1529 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1530 | .get_tsf = rt2400pci_get_tsf, | 1530 | .get_tsf = rt2400pci_get_tsf, |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 206b50ff831f..e874fdcae204 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1835,7 +1835,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { | |||
1835 | .configure_filter = rt2500pci_configure_filter, | 1835 | .configure_filter = rt2500pci_configure_filter, |
1836 | .get_stats = rt2x00mac_get_stats, | 1836 | .get_stats = rt2x00mac_get_stats, |
1837 | .set_retry_limit = rt2500pci_set_retry_limit, | 1837 | .set_retry_limit = rt2500pci_set_retry_limit, |
1838 | .erp_ie_changed = rt2x00mac_erp_ie_changed, | 1838 | .bss_info_changed = rt2x00mac_bss_info_changed, |
1839 | .conf_tx = rt2x00mac_conf_tx, | 1839 | .conf_tx = rt2x00mac_conf_tx, |
1840 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1840 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1841 | .get_tsf = rt2500pci_get_tsf, | 1841 | .get_tsf = rt2500pci_get_tsf, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 6579718f36ad..1933113d7baf 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1776,7 +1776,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { | |||
1776 | .config_interface = rt2x00mac_config_interface, | 1776 | .config_interface = rt2x00mac_config_interface, |
1777 | .configure_filter = rt2500usb_configure_filter, | 1777 | .configure_filter = rt2500usb_configure_filter, |
1778 | .get_stats = rt2x00mac_get_stats, | 1778 | .get_stats = rt2x00mac_get_stats, |
1779 | .erp_ie_changed = rt2x00mac_erp_ie_changed, | 1779 | .bss_info_changed = rt2x00mac_bss_info_changed, |
1780 | .conf_tx = rt2x00mac_conf_tx, | 1780 | .conf_tx = rt2x00mac_conf_tx, |
1781 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1781 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1782 | .beacon_update = rt2500usb_beacon_update, | 1782 | .beacon_update = rt2500usb_beacon_update, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 94a8a7ce5382..05927b908f80 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -936,8 +936,10 @@ int rt2x00mac_get_stats(struct ieee80211_hw *hw, | |||
936 | struct ieee80211_low_level_stats *stats); | 936 | struct ieee80211_low_level_stats *stats); |
937 | int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, | 937 | int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, |
938 | struct ieee80211_tx_queue_stats *stats); | 938 | struct ieee80211_tx_queue_stats *stats); |
939 | void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes, | 939 | void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, |
940 | int cts_protection, int preamble); | 940 | struct ieee80211_vif *vif, |
941 | struct ieee80211_bss_conf *bss_conf, | ||
942 | u32 changes); | ||
941 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, | 943 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, |
942 | const struct ieee80211_tx_queue_params *params); | 944 | const struct ieee80211_tx_queue_params *params); |
943 | 945 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b26c634f210b..72cfe6f866f8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -481,10 +481,17 @@ static void rt2x00lib_configuration_scheduled(struct work_struct *work) | |||
481 | { | 481 | { |
482 | struct rt2x00_dev *rt2x00dev = | 482 | struct rt2x00_dev *rt2x00dev = |
483 | container_of(work, struct rt2x00_dev, config_work); | 483 | container_of(work, struct rt2x00_dev, config_work); |
484 | int preamble = !test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 484 | struct ieee80211_bss_conf bss_conf; |
485 | 485 | ||
486 | rt2x00mac_erp_ie_changed(rt2x00dev->hw, | 486 | bss_conf.use_short_preamble = |
487 | IEEE80211_ERP_CHANGE_PREAMBLE, 0, preamble); | 487 | test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); |
488 | |||
489 | /* | ||
490 | * FIXME: shouldn't invoke it this way because all other contents | ||
491 | * of bss_conf is invalid. | ||
492 | */ | ||
493 | rt2x00mac_bss_info_changed(rt2x00dev->hw, rt2x00dev->interface.id, | ||
494 | &bss_conf, BSS_CHANGED_ERP_PREAMBLE); | ||
488 | } | 495 | } |
489 | 496 | ||
490 | /* | 497 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 1d67bcd46bcb..e3f15e518c76 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -342,23 +342,27 @@ int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, | |||
342 | } | 342 | } |
343 | EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats); | 343 | EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats); |
344 | 344 | ||
345 | void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes, | 345 | void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, |
346 | int cts_protection, int preamble) | 346 | struct ieee80211_vif *vif, |
347 | struct ieee80211_bss_conf *bss_conf, | ||
348 | u32 changes) | ||
347 | { | 349 | { |
348 | struct rt2x00_dev *rt2x00dev = hw->priv; | 350 | struct rt2x00_dev *rt2x00dev = hw->priv; |
349 | int short_preamble; | 351 | int short_preamble; |
350 | int ack_timeout; | 352 | int ack_timeout; |
351 | int ack_consume_time; | 353 | int ack_consume_time; |
352 | int difs; | 354 | int difs; |
355 | int preamble; | ||
353 | 356 | ||
354 | /* | 357 | /* |
355 | * We only support changing preamble mode. | 358 | * We only support changing preamble mode. |
356 | */ | 359 | */ |
357 | if (!(changes & IEEE80211_ERP_CHANGE_PREAMBLE)) | 360 | if (!(changes & BSS_CHANGED_ERP_PREAMBLE)) |
358 | return; | 361 | return; |
359 | 362 | ||
360 | short_preamble = !preamble; | 363 | short_preamble = bss_conf->use_short_preamble; |
361 | preamble = !!(preamble) ? PREAMBLE : SHORT_PREAMBLE; | 364 | preamble = bss_conf->use_short_preamble ? |
365 | SHORT_PREAMBLE : PREAMBLE; | ||
362 | 366 | ||
363 | difs = (hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | 367 | difs = (hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? |
364 | SHORT_DIFS : DIFS; | 368 | SHORT_DIFS : DIFS; |
@@ -374,7 +378,7 @@ void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes, | |||
374 | rt2x00dev->ops->lib->config_preamble(rt2x00dev, short_preamble, | 378 | rt2x00dev->ops->lib->config_preamble(rt2x00dev, short_preamble, |
375 | ack_timeout, ack_consume_time); | 379 | ack_timeout, ack_consume_time); |
376 | } | 380 | } |
377 | EXPORT_SYMBOL_GPL(rt2x00mac_erp_ie_changed); | 381 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); |
378 | 382 | ||
379 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, | 383 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, |
380 | const struct ieee80211_tx_queue_params *params) | 384 | const struct ieee80211_tx_queue_params *params) |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 88d169800886..ab52f221cd71 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -2441,7 +2441,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2441 | .configure_filter = rt61pci_configure_filter, | 2441 | .configure_filter = rt61pci_configure_filter, |
2442 | .get_stats = rt2x00mac_get_stats, | 2442 | .get_stats = rt2x00mac_get_stats, |
2443 | .set_retry_limit = rt61pci_set_retry_limit, | 2443 | .set_retry_limit = rt61pci_set_retry_limit, |
2444 | .erp_ie_changed = rt2x00mac_erp_ie_changed, | 2444 | .bss_info_changed = rt2x00mac_bss_info_changed, |
2445 | .conf_tx = rt2x00mac_conf_tx, | 2445 | .conf_tx = rt2x00mac_conf_tx, |
2446 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2446 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2447 | .get_tsf = rt61pci_get_tsf, | 2447 | .get_tsf = rt61pci_get_tsf, |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 47ed3070ae0b..f9518764aeb0 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2024,7 +2024,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2024 | .configure_filter = rt73usb_configure_filter, | 2024 | .configure_filter = rt73usb_configure_filter, |
2025 | .get_stats = rt2x00mac_get_stats, | 2025 | .get_stats = rt2x00mac_get_stats, |
2026 | .set_retry_limit = rt73usb_set_retry_limit, | 2026 | .set_retry_limit = rt73usb_set_retry_limit, |
2027 | .erp_ie_changed = rt2x00mac_erp_ie_changed, | 2027 | .bss_info_changed = rt2x00mac_bss_info_changed, |
2028 | .conf_tx = rt2x00mac_conf_tx, | 2028 | .conf_tx = rt2x00mac_conf_tx, |
2029 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2029 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2030 | .get_tsf = rt73usb_get_tsf, | 2030 | .get_tsf = rt73usb_get_tsf, |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 3409cf97f5f8..49127e4b42c2 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -849,17 +849,19 @@ static void set_rts_cts_work(struct work_struct *work) | |||
849 | mutex_unlock(&mac->chip.mutex); | 849 | mutex_unlock(&mac->chip.mutex); |
850 | } | 850 | } |
851 | 851 | ||
852 | static void zd_op_erp_ie_changed(struct ieee80211_hw *hw, u8 changes, | 852 | static void zd_op_bss_info_changed(struct ieee80211_hw *hw, |
853 | int cts_protection, int preamble) | 853 | struct ieee80211_vif *vif, |
854 | struct ieee80211_bss_conf *bss_conf, | ||
855 | u32 changes) | ||
854 | { | 856 | { |
855 | struct zd_mac *mac = zd_hw_mac(hw); | 857 | struct zd_mac *mac = zd_hw_mac(hw); |
856 | unsigned long flags; | 858 | unsigned long flags; |
857 | 859 | ||
858 | dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); | 860 | dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); |
859 | 861 | ||
860 | if (changes & IEEE80211_ERP_CHANGE_PREAMBLE) { | 862 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { |
861 | spin_lock_irqsave(&mac->lock, flags); | 863 | spin_lock_irqsave(&mac->lock, flags); |
862 | mac->short_preamble = !preamble; | 864 | mac->short_preamble = bss_conf->use_short_preamble; |
863 | if (!mac->updating_rts_rate) { | 865 | if (!mac->updating_rts_rate) { |
864 | mac->updating_rts_rate = 1; | 866 | mac->updating_rts_rate = 1; |
865 | /* FIXME: should disable TX here, until work has | 867 | /* FIXME: should disable TX here, until work has |
@@ -879,7 +881,7 @@ static const struct ieee80211_ops zd_ops = { | |||
879 | .config = zd_op_config, | 881 | .config = zd_op_config, |
880 | .config_interface = zd_op_config_interface, | 882 | .config_interface = zd_op_config_interface, |
881 | .configure_filter = zd_op_configure_filter, | 883 | .configure_filter = zd_op_configure_filter, |
882 | .erp_ie_changed = zd_op_erp_ie_changed, | 884 | .bss_info_changed = zd_op_bss_info_changed, |
883 | }; | 885 | }; |
884 | 886 | ||
885 | struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | 887 | struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 8a49c06dfd38..9083bafb63ca 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -275,6 +275,43 @@ struct ieee80211_low_level_stats { | |||
275 | unsigned int dot11RTSSuccessCount; | 275 | unsigned int dot11RTSSuccessCount; |
276 | }; | 276 | }; |
277 | 277 | ||
278 | /** | ||
279 | * enum ieee80211_bss_change - BSS change notification flags | ||
280 | * | ||
281 | * These flags are used with the bss_info_changed() callback | ||
282 | * to indicate which BSS parameter changed. | ||
283 | * | ||
284 | * @BSS_CHANGED_ASSOC: association status changed (associated/disassociated), | ||
285 | * also implies a change in the AID. | ||
286 | * @BSS_CHANGED_ERP_CTS_PROT: CTS protection changed | ||
287 | * @BSS_CHANGED_ERP_PREAMBLE: preamble changed | ||
288 | */ | ||
289 | enum ieee80211_bss_change { | ||
290 | BSS_CHANGED_ASSOC = 1<<0, | ||
291 | BSS_CHANGED_ERP_CTS_PROT = 1<<1, | ||
292 | BSS_CHANGED_ERP_PREAMBLE = 1<<2, | ||
293 | }; | ||
294 | |||
295 | /** | ||
296 | * struct ieee80211_bss_conf - holds the BSS's changing parameters | ||
297 | * | ||
298 | * This structure keeps information about a BSS (and an association | ||
299 | * to that BSS) that can change during the lifetime of the BSS. | ||
300 | * | ||
301 | * @assoc: association status | ||
302 | * @aid: association ID number, valid only when @assoc is true | ||
303 | * @use_cts_prot: use CTS protection | ||
304 | * @use_short_preamble: use 802.11b short preamble | ||
305 | */ | ||
306 | struct ieee80211_bss_conf { | ||
307 | /* association related data */ | ||
308 | bool assoc; | ||
309 | u16 aid; | ||
310 | /* erp related data */ | ||
311 | bool use_cts_prot; | ||
312 | bool use_short_preamble; | ||
313 | }; | ||
314 | |||
278 | /* Transmit control fields. This data structure is passed to low-level driver | 315 | /* Transmit control fields. This data structure is passed to low-level driver |
279 | * with each TX frame. The low-level driver is responsible for configuring | 316 | * with each TX frame. The low-level driver is responsible for configuring |
280 | * the hardware to use given values (depending on what is supported). */ | 317 | * the hardware to use given values (depending on what is supported). */ |
@@ -924,19 +961,6 @@ enum ieee80211_filter_flags { | |||
924 | }; | 961 | }; |
925 | 962 | ||
926 | /** | 963 | /** |
927 | * enum ieee80211_erp_change_flags - erp change flags | ||
928 | * | ||
929 | * These flags are used with the erp_ie_changed() callback in | ||
930 | * &struct ieee80211_ops to indicate which parameter(s) changed. | ||
931 | * @IEEE80211_ERP_CHANGE_PROTECTION: protection changed | ||
932 | * @IEEE80211_ERP_CHANGE_PREAMBLE: barker preamble mode changed | ||
933 | */ | ||
934 | enum ieee80211_erp_change_flags { | ||
935 | IEEE80211_ERP_CHANGE_PROTECTION = 1<<0, | ||
936 | IEEE80211_ERP_CHANGE_PREAMBLE = 1<<1, | ||
937 | }; | ||
938 | |||
939 | /** | ||
940 | * enum ieee80211_ampdu_mlme_action - A-MPDU actions | 964 | * enum ieee80211_ampdu_mlme_action - A-MPDU actions |
941 | * | 965 | * |
942 | * These flags are used with the ampdu_action() callback in | 966 | * These flags are used with the ampdu_action() callback in |
@@ -1004,6 +1028,14 @@ enum ieee80211_ampdu_mlme_action { | |||
1004 | * @config_interface: Handler for configuration requests related to interfaces | 1028 | * @config_interface: Handler for configuration requests related to interfaces |
1005 | * (e.g. BSSID changes.) | 1029 | * (e.g. BSSID changes.) |
1006 | * | 1030 | * |
1031 | * @bss_info_changed: Handler for configuration requests related to BSS | ||
1032 | * parameters that may vary during BSS's lifespan, and may affect low | ||
1033 | * level driver (e.g. assoc/disassoc status, erp parameters). | ||
1034 | * This function should not be used if no BSS has been set, unless | ||
1035 | * for association indication. The @changed parameter indicates which | ||
1036 | * of the bss parameters has changed when a call is made. This callback | ||
1037 | * has to be atomic. | ||
1038 | * | ||
1007 | * @configure_filter: Configure the device's RX filter. | 1039 | * @configure_filter: Configure the device's RX filter. |
1008 | * See the section "Frame filtering" for more information. | 1040 | * See the section "Frame filtering" for more information. |
1009 | * This callback must be implemented and atomic. | 1041 | * This callback must be implemented and atomic. |
@@ -1038,8 +1070,6 @@ enum ieee80211_ampdu_mlme_action { | |||
1038 | * @sta_notify: Notifies low level driver about addition or removal | 1070 | * @sta_notify: Notifies low level driver about addition or removal |
1039 | * of assocaited station or AP. | 1071 | * of assocaited station or AP. |
1040 | * | 1072 | * |
1041 | * @erp_ie_changed: Handle ERP IE change notifications. Must be atomic. | ||
1042 | * | ||
1043 | * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), | 1073 | * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), |
1044 | * bursting) for a hardware TX queue. The @queue parameter uses the | 1074 | * bursting) for a hardware TX queue. The @queue parameter uses the |
1045 | * %IEEE80211_TX_QUEUE_* constants. Must be atomic. | 1075 | * %IEEE80211_TX_QUEUE_* constants. Must be atomic. |
@@ -1096,6 +1126,10 @@ struct ieee80211_ops { | |||
1096 | int (*config_interface)(struct ieee80211_hw *hw, | 1126 | int (*config_interface)(struct ieee80211_hw *hw, |
1097 | struct ieee80211_vif *vif, | 1127 | struct ieee80211_vif *vif, |
1098 | struct ieee80211_if_conf *conf); | 1128 | struct ieee80211_if_conf *conf); |
1129 | void (*bss_info_changed)(struct ieee80211_hw *hw, | ||
1130 | struct ieee80211_vif *vif, | ||
1131 | struct ieee80211_bss_conf *info, | ||
1132 | u32 changed); | ||
1099 | void (*configure_filter)(struct ieee80211_hw *hw, | 1133 | void (*configure_filter)(struct ieee80211_hw *hw, |
1100 | unsigned int changed_flags, | 1134 | unsigned int changed_flags, |
1101 | unsigned int *total_flags, | 1135 | unsigned int *total_flags, |
@@ -1115,8 +1149,6 @@ struct ieee80211_ops { | |||
1115 | u32 short_retry, u32 long_retr); | 1149 | u32 short_retry, u32 long_retr); |
1116 | void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 1150 | void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
1117 | enum sta_notify_cmd, const u8 *addr); | 1151 | enum sta_notify_cmd, const u8 *addr); |
1118 | void (*erp_ie_changed)(struct ieee80211_hw *hw, u8 changes, | ||
1119 | int cts_protection, int preamble); | ||
1120 | int (*conf_tx)(struct ieee80211_hw *hw, int queue, | 1152 | int (*conf_tx)(struct ieee80211_hw *hw, int queue, |
1121 | const struct ieee80211_tx_queue_params *params); | 1153 | const struct ieee80211_tx_queue_params *params); |
1122 | int (*get_tx_stats)(struct ieee80211_hw *hw, | 1154 | int (*get_tx_stats)(struct ieee80211_hw *hw, |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 3500fe0d380b..829872a3ae81 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -118,7 +118,7 @@ static ssize_t ieee80211_if_fmt_flags( | |||
118 | sdata->u.sta.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "", | 118 | sdata->u.sta.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "", |
119 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "", | 119 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "", |
120 | sdata->u.sta.flags & IEEE80211_STA_PROBEREQ_POLL ? "PROBEREQ POLL\n" : "", | 120 | sdata->u.sta.flags & IEEE80211_STA_PROBEREQ_POLL ? "PROBEREQ POLL\n" : "", |
121 | sdata->flags & IEEE80211_SDATA_USE_PROTECTION ? "CTS prot\n" : ""); | 121 | sdata->bss_conf.use_cts_prot ? "CTS prot\n" : ""); |
122 | } | 122 | } |
123 | __IEEE80211_IF_FILE(flags); | 123 | __IEEE80211_IF_FILE(flags); |
124 | 124 | ||
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 859682eee547..177040218232 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -635,25 +635,30 @@ int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | |||
635 | return 0; | 635 | return 0; |
636 | } | 636 | } |
637 | 637 | ||
638 | void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes) | 638 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
639 | u32 changed) | ||
639 | { | 640 | { |
640 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 641 | struct ieee80211_local *local = sdata->local; |
641 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 642 | |
642 | if (local->ops->erp_ie_changed) | 643 | if (!changed) |
643 | local->ops->erp_ie_changed(local_to_hw(local), changes, | 644 | return; |
644 | !!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION), | 645 | |
645 | !(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE)); | 646 | if (local->ops->bss_info_changed) |
647 | local->ops->bss_info_changed(local_to_hw(local), | ||
648 | &sdata->vif, | ||
649 | &sdata->bss_conf, | ||
650 | changed); | ||
646 | } | 651 | } |
647 | 652 | ||
648 | void ieee80211_reset_erp_info(struct net_device *dev) | 653 | void ieee80211_reset_erp_info(struct net_device *dev) |
649 | { | 654 | { |
650 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 655 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
651 | 656 | ||
652 | sdata->flags &= ~(IEEE80211_SDATA_USE_PROTECTION | | 657 | sdata->bss_conf.use_cts_prot = 0; |
653 | IEEE80211_SDATA_SHORT_PREAMBLE); | 658 | sdata->bss_conf.use_short_preamble = 0; |
654 | ieee80211_erp_info_change_notify(dev, | 659 | ieee80211_bss_info_change_notify(sdata, |
655 | IEEE80211_ERP_CHANGE_PROTECTION | | 660 | BSS_CHANGED_ERP_CTS_PROT | |
656 | IEEE80211_ERP_CHANGE_PREAMBLE); | 661 | BSS_CHANGED_ERP_PREAMBLE); |
657 | } | 662 | } |
658 | 663 | ||
659 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 664 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 08a6c0cff690..72ecbf7bf962 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -291,12 +291,7 @@ struct ieee80211_if_sta { | |||
291 | /* flags used in struct ieee80211_sub_if_data.flags */ | 291 | /* flags used in struct ieee80211_sub_if_data.flags */ |
292 | #define IEEE80211_SDATA_ALLMULTI BIT(0) | 292 | #define IEEE80211_SDATA_ALLMULTI BIT(0) |
293 | #define IEEE80211_SDATA_PROMISC BIT(1) | 293 | #define IEEE80211_SDATA_PROMISC BIT(1) |
294 | #define IEEE80211_SDATA_USE_PROTECTION BIT(2) /* CTS protect ERP frames */ | 294 | #define IEEE80211_SDATA_USERSPACE_MLME BIT(2) |
295 | /* use short preamble with IEEE 802.11b: this flag is set when the AP or beacon | ||
296 | * generator reports that there are no present stations that cannot support short | ||
297 | * preambles */ | ||
298 | #define IEEE80211_SDATA_SHORT_PREAMBLE BIT(3) | ||
299 | #define IEEE80211_SDATA_USERSPACE_MLME BIT(4) | ||
300 | struct ieee80211_sub_if_data { | 295 | struct ieee80211_sub_if_data { |
301 | struct list_head list; | 296 | struct list_head list; |
302 | 297 | ||
@@ -327,6 +322,15 @@ struct ieee80211_sub_if_data { | |||
327 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; | 322 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; |
328 | struct ieee80211_key *default_key; | 323 | struct ieee80211_key *default_key; |
329 | 324 | ||
325 | /* | ||
326 | * BSS configuration for this interface. | ||
327 | * | ||
328 | * FIXME: I feel bad putting this here when we already have a | ||
329 | * bss pointer, but the bss pointer is just wrong when | ||
330 | * you have multiple virtual STA mode interfaces... | ||
331 | * This needs to be fixed. | ||
332 | */ | ||
333 | struct ieee80211_bss_conf bss_conf; | ||
330 | struct ieee80211_if_ap *bss; /* BSS that this device belongs to */ | 334 | struct ieee80211_if_ap *bss; /* BSS that this device belongs to */ |
331 | 335 | ||
332 | union { | 336 | union { |
@@ -770,7 +774,8 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | |||
770 | u8 *addr); | 774 | u8 *addr); |
771 | int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); | 775 | int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); |
772 | int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); | 776 | int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); |
773 | void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes); | 777 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
778 | u32 changed); | ||
774 | void ieee80211_reset_erp_info(struct net_device *dev); | 779 | void ieee80211_reset_erp_info(struct net_device *dev); |
775 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, | 780 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, |
776 | struct ieee80211_ht_info *ht_info); | 781 | struct ieee80211_ht_info *ht_info); |
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; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 51c0f00d02d1..f9088fe34d59 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -176,7 +176,7 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr, | |||
176 | * to closest integer */ | 176 | * to closest integer */ |
177 | 177 | ||
178 | dur = ieee80211_frame_duration(local, 10, rate, erp, | 178 | dur = ieee80211_frame_duration(local, 10, rate, erp, |
179 | tx->sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE); | 179 | tx->sdata->bss_conf.use_short_preamble); |
180 | 180 | ||
181 | if (next_frag_len) { | 181 | if (next_frag_len) { |
182 | /* Frame is fragmented: duration increases with time needed to | 182 | /* Frame is fragmented: duration increases with time needed to |
@@ -185,8 +185,7 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr, | |||
185 | /* next fragment */ | 185 | /* next fragment */ |
186 | dur += ieee80211_frame_duration(local, next_frag_len, | 186 | dur += ieee80211_frame_duration(local, next_frag_len, |
187 | txrate->rate, erp, | 187 | txrate->rate, erp, |
188 | tx->sdata->flags & | 188 | tx->sdata->bss_conf.use_short_preamble); |
189 | IEEE80211_SDATA_SHORT_PREAMBLE); | ||
190 | } | 189 | } |
191 | 190 | ||
192 | return dur; | 191 | return dur; |
@@ -605,7 +604,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) | |||
605 | tx->u.tx.control->alt_retry_rate = -1; | 604 | tx->u.tx.control->alt_retry_rate = -1; |
606 | 605 | ||
607 | if (tx->u.tx.mode->mode == MODE_IEEE80211G && | 606 | if (tx->u.tx.mode->mode == MODE_IEEE80211G && |
608 | (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) && | 607 | tx->sdata->bss_conf.use_cts_prot && |
609 | (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && rsel.nonerp) { | 608 | (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && rsel.nonerp) { |
610 | tx->u.tx.last_frag_rate = tx->u.tx.rate; | 609 | tx->u.tx.last_frag_rate = tx->u.tx.rate; |
611 | if (rsel.probe) | 610 | if (rsel.probe) |
@@ -667,7 +666,7 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
667 | if (mode->mode == MODE_IEEE80211G && | 666 | if (mode->mode == MODE_IEEE80211G && |
668 | (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) && | 667 | (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) && |
669 | (tx->flags & IEEE80211_TXRXD_TXUNICAST) && | 668 | (tx->flags & IEEE80211_TXRXD_TXUNICAST) && |
670 | (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) && | 669 | tx->sdata->bss_conf.use_cts_prot && |
671 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) | 670 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) |
672 | control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT; | 671 | control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT; |
673 | 672 | ||
@@ -676,7 +675,7 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
676 | * available on the network at the current point in time. */ | 675 | * available on the network at the current point in time. */ |
677 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 676 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && |
678 | (tx->u.tx.rate->flags & IEEE80211_RATE_PREAMBLE2) && | 677 | (tx->u.tx.rate->flags & IEEE80211_RATE_PREAMBLE2) && |
679 | (tx->sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) && | 678 | tx->sdata->bss_conf.use_short_preamble && |
680 | (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { | 679 | (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { |
681 | tx->u.tx.control->tx_rate = tx->u.tx.rate->val2; | 680 | tx->u.tx.control->tx_rate = tx->u.tx.rate->val2; |
682 | } | 681 | } |
@@ -1754,7 +1753,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1754 | } | 1753 | } |
1755 | 1754 | ||
1756 | control->tx_rate = | 1755 | control->tx_rate = |
1757 | ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) && | 1756 | (sdata->bss_conf.use_short_preamble && |
1758 | (rsel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ? | 1757 | (rsel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ? |
1759 | rsel.rate->val2 : rsel.rate->val; | 1758 | rsel.rate->val2 : rsel.rate->val; |
1760 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 1759 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index ba81cf542818..5e631ce98d7e 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -312,8 +312,8 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, | |||
312 | int erp; | 312 | int erp; |
313 | 313 | ||
314 | erp = ieee80211_is_erp_rate(hw->conf.phymode, rate); | 314 | erp = ieee80211_is_erp_rate(hw->conf.phymode, rate); |
315 | dur = ieee80211_frame_duration(local, frame_len, rate, | 315 | dur = ieee80211_frame_duration(local, frame_len, rate, erp, |
316 | erp, sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE); | 316 | sdata->bss_conf.use_short_preamble); |
317 | 317 | ||
318 | return cpu_to_le16(dur); | 318 | return cpu_to_le16(dur); |
319 | } | 319 | } |
@@ -326,11 +326,11 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
326 | struct ieee80211_local *local = hw_to_local(hw); | 326 | struct ieee80211_local *local = hw_to_local(hw); |
327 | struct ieee80211_rate *rate; | 327 | struct ieee80211_rate *rate; |
328 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 328 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
329 | int short_preamble; | 329 | bool short_preamble; |
330 | int erp; | 330 | int erp; |
331 | u16 dur; | 331 | u16 dur; |
332 | 332 | ||
333 | short_preamble = sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE; | 333 | short_preamble = sdata->bss_conf.use_short_preamble; |
334 | 334 | ||
335 | rate = frame_txctl->rts_rate; | 335 | rate = frame_txctl->rts_rate; |
336 | erp = !!(rate->flags & IEEE80211_RATE_ERP); | 336 | erp = !!(rate->flags & IEEE80211_RATE_ERP); |
@@ -357,11 +357,11 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
357 | struct ieee80211_local *local = hw_to_local(hw); | 357 | struct ieee80211_local *local = hw_to_local(hw); |
358 | struct ieee80211_rate *rate; | 358 | struct ieee80211_rate *rate; |
359 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 359 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
360 | int short_preamble; | 360 | bool short_preamble; |
361 | int erp; | 361 | int erp; |
362 | u16 dur; | 362 | u16 dur; |
363 | 363 | ||
364 | short_preamble = sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE; | 364 | short_preamble = sdata->bss_conf.use_short_preamble; |
365 | 365 | ||
366 | rate = frame_txctl->rts_rate; | 366 | rate = frame_txctl->rts_rate; |
367 | erp = !!(rate->flags & IEEE80211_RATE_ERP); | 367 | erp = !!(rate->flags & IEEE80211_RATE_ERP); |