aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-12-28 08:32:58 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:43 -0500
commit471b3efdfccc257591331724145f8ccf8b3217e1 (patch)
treec9e576442c7b62c8c667ae1046e560323f0821fd
parent2bc454b0b30b3645d114689b64321cb49be99923 (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.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c24
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c13
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c12
-rw-r--r--include/net/mac80211.h66
-rw-r--r--net/mac80211/debugfs_netdev.c2
-rw-r--r--net/mac80211/ieee80211.c29
-rw-r--r--net/mac80211/ieee80211_i.h19
-rw-r--r--net/mac80211/ieee80211_sta.c69
-rw-r--r--net/mac80211/tx.c13
-rw-r--r--net/mac80211/util.c12
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}
7767static void iwl4965_mac_erp_ie_changed(struct ieee80211_hw *hw, 7767
7768 u8 changes, int cts_protection, int preamble) 7768static 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);
937int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, 937int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
938 struct ieee80211_tx_queue_stats *stats); 938 struct ieee80211_tx_queue_stats *stats);
939void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes, 939void 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);
941int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, 943int 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}
343EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats); 343EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats);
344 344
345void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes, 345void 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}
377EXPORT_SYMBOL_GPL(rt2x00mac_erp_ie_changed); 381EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
378 382
379int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, 383int 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
852static void zd_op_erp_ie_changed(struct ieee80211_hw *hw, u8 changes, 852static 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
885struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) 887struct 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 */
289enum 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 */
306struct 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 */
934enum 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
638void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes) 638void 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
648void ieee80211_reset_erp_info(struct net_device *dev) 653void 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
659void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, 664void 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)
300struct ieee80211_sub_if_data { 295struct 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);
771int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); 775int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason);
772int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); 776int ieee80211_sta_disassociate(struct net_device *dev, u16 reason);
773void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes); 777void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
778 u32 changed);
774void ieee80211_reset_erp_info(struct net_device *dev); 779void ieee80211_reset_erp_info(struct net_device *dev);
775int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, 780int 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
316static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) 316static 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
360int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, 354int 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
504static void ieee80211_set_disassoc(struct net_device *dev, 498static 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
1539static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, 1533static 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);