diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-12-02 15:44:03 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-12-02 15:44:03 -0500 |
commit | d7a4858c0fde8383f7aa494eda0fba6bef3f2fec (patch) | |
tree | 2cbf6915ea069ada4e3e1bca0b91b12e06500681 | |
parent | ba5736a5e9ac20c378ae4179e8a0ed3cc4b44351 (diff) | |
parent | 9995ffe5f5fdddcc73e4465cc3f8b38714df8108 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts:
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/libertas/cfg.c
30 files changed, 210 insertions, 91 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6ceb2e188080..caf572cf270f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1967,7 +1967,8 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | |||
1967 | } | 1967 | } |
1968 | 1968 | ||
1969 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ | 1969 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ |
1970 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); | 1970 | if (AR_SREV_9300_20_OR_LATER(ah)) |
1971 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); | ||
1971 | } | 1972 | } |
1972 | 1973 | ||
1973 | /* | 1974 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index bc9bbbb2b494..8d3bad7ea5d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -182,6 +182,7 @@ static struct iwl_base_params iwl1000_base_params = { | |||
182 | .chain_noise_scale = 1000, | 182 | .chain_noise_scale = 1000, |
183 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 183 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
184 | .max_event_log_size = 128, | 184 | .max_event_log_size = 128, |
185 | .wd_disable = true, | ||
185 | }; | 186 | }; |
186 | static struct iwl_ht_params iwl1000_ht_params = { | 187 | static struct iwl_ht_params iwl1000_ht_params = { |
187 | .ht_greenfield_support = true, | 188 | .ht_greenfield_support = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 3a3f83032382..cf2fb47529b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -350,6 +350,7 @@ static struct iwl_base_params iwl5000_base_params = { | |||
350 | .wd_timeout = IWL_LONG_WD_TIMEOUT, | 350 | .wd_timeout = IWL_LONG_WD_TIMEOUT, |
351 | .max_event_log_size = 512, | 351 | .max_event_log_size = 512, |
352 | .no_idle_support = true, | 352 | .no_idle_support = true, |
353 | .wd_disable = true, | ||
353 | }; | 354 | }; |
354 | static struct iwl_ht_params iwl5000_ht_params = { | 355 | static struct iwl_ht_params iwl5000_ht_params = { |
355 | .ht_greenfield_support = true, | 356 | .ht_greenfield_support = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 8de97f5a1825..00b38711c15d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -529,6 +529,24 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
529 | return 0; | 529 | return 0; |
530 | } | 530 | } |
531 | 531 | ||
532 | void iwlagn_config_ht40(struct ieee80211_conf *conf, | ||
533 | struct iwl_rxon_context *ctx) | ||
534 | { | ||
535 | if (conf_is_ht40_minus(conf)) { | ||
536 | ctx->ht.extension_chan_offset = | ||
537 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
538 | ctx->ht.is_40mhz = true; | ||
539 | } else if (conf_is_ht40_plus(conf)) { | ||
540 | ctx->ht.extension_chan_offset = | ||
541 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
542 | ctx->ht.is_40mhz = true; | ||
543 | } else { | ||
544 | ctx->ht.extension_chan_offset = | ||
545 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
546 | ctx->ht.is_40mhz = false; | ||
547 | } | ||
548 | } | ||
549 | |||
532 | int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | 550 | int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) |
533 | { | 551 | { |
534 | struct iwl_priv *priv = hw->priv; | 552 | struct iwl_priv *priv = hw->priv; |
@@ -590,19 +608,11 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
590 | ctx->ht.enabled = conf_is_ht(conf); | 608 | ctx->ht.enabled = conf_is_ht(conf); |
591 | 609 | ||
592 | if (ctx->ht.enabled) { | 610 | if (ctx->ht.enabled) { |
593 | if (conf_is_ht40_minus(conf)) { | 611 | /* if HT40 is used, it should not change |
594 | ctx->ht.extension_chan_offset = | 612 | * after associated except channel switch */ |
595 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | 613 | if (iwl_is_associated_ctx(ctx) && |
596 | ctx->ht.is_40mhz = true; | 614 | !ctx->ht.is_40mhz) |
597 | } else if (conf_is_ht40_plus(conf)) { | 615 | iwlagn_config_ht40(conf, ctx); |
598 | ctx->ht.extension_chan_offset = | ||
599 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
600 | ctx->ht.is_40mhz = true; | ||
601 | } else { | ||
602 | ctx->ht.extension_chan_offset = | ||
603 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
604 | ctx->ht.is_40mhz = false; | ||
605 | } | ||
606 | } else | 616 | } else |
607 | ctx->ht.is_40mhz = false; | 617 | ctx->ht.is_40mhz = false; |
608 | 618 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 901fd9485d75..626ed701100e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
@@ -1250,9 +1250,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
1250 | 1250 | ||
1251 | switch (keyconf->cipher) { | 1251 | switch (keyconf->cipher) { |
1252 | case WLAN_CIPHER_SUITE_TKIP: | 1252 | case WLAN_CIPHER_SUITE_TKIP: |
1253 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
1254 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1255 | |||
1256 | if (sta) | 1253 | if (sta) |
1257 | addr = sta->addr; | 1254 | addr = sta->addr; |
1258 | else /* station mode case only */ | 1255 | else /* station mode case only */ |
@@ -1265,8 +1262,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
1265 | seq.tkip.iv32, p1k, CMD_SYNC); | 1262 | seq.tkip.iv32, p1k, CMD_SYNC); |
1266 | break; | 1263 | break; |
1267 | case WLAN_CIPHER_SUITE_CCMP: | 1264 | case WLAN_CIPHER_SUITE_CCMP: |
1268 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1269 | /* fall through */ | ||
1270 | case WLAN_CIPHER_SUITE_WEP40: | 1265 | case WLAN_CIPHER_SUITE_WEP40: |
1271 | case WLAN_CIPHER_SUITE_WEP104: | 1266 | case WLAN_CIPHER_SUITE_WEP104: |
1272 | ret = iwlagn_send_sta_key(priv, keyconf, sta_id, | 1267 | ret = iwlagn_send_sta_key(priv, keyconf, sta_id, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index db0d3a84b1e4..4d20be9dea39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2022,9 +2022,10 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); | |||
2022 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); | 2022 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); |
2023 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); | 2023 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); |
2024 | 2024 | ||
2025 | module_param_named(wd_disable, iwlagn_mod_params.wd_disable, bool, S_IRUGO); | 2025 | module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO); |
2026 | MODULE_PARM_DESC(wd_disable, | 2026 | MODULE_PARM_DESC(wd_disable, |
2027 | "Disable stuck queue watchdog timer (default: 0 [enabled])"); | 2027 | "Disable stuck queue watchdog timer 0=system default, " |
2028 | "1=disable, 2=enable (default: 0)"); | ||
2028 | 2029 | ||
2029 | /* | 2030 | /* |
2030 | * set bt_coex_active to true, uCode will do kill/defer | 2031 | * set bt_coex_active to true, uCode will do kill/defer |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5d8d2f445923..2f446a353514 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -101,6 +101,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
101 | struct ieee80211_vif *vif, | 101 | struct ieee80211_vif *vif, |
102 | struct ieee80211_bss_conf *bss_conf, | 102 | struct ieee80211_bss_conf *bss_conf, |
103 | u32 changes); | 103 | u32 changes); |
104 | void iwlagn_config_ht40(struct ieee80211_conf *conf, | ||
105 | struct iwl_rxon_context *ctx); | ||
104 | 106 | ||
105 | /* uCode */ | 107 | /* uCode */ |
106 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 108 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f9e9170e977a..b24623b3bdb3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1505,11 +1505,23 @@ void iwl_setup_watchdog(struct iwl_priv *priv) | |||
1505 | { | 1505 | { |
1506 | unsigned int timeout = priv->cfg->base_params->wd_timeout; | 1506 | unsigned int timeout = priv->cfg->base_params->wd_timeout; |
1507 | 1507 | ||
1508 | if (timeout && !iwlagn_mod_params.wd_disable) | 1508 | if (!iwlagn_mod_params.wd_disable) { |
1509 | mod_timer(&priv->watchdog, | 1509 | /* use system default */ |
1510 | jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); | 1510 | if (timeout && !priv->cfg->base_params->wd_disable) |
1511 | else | 1511 | mod_timer(&priv->watchdog, |
1512 | del_timer(&priv->watchdog); | 1512 | jiffies + |
1513 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
1514 | else | ||
1515 | del_timer(&priv->watchdog); | ||
1516 | } else { | ||
1517 | /* module parameter overwrite default configuration */ | ||
1518 | if (timeout && iwlagn_mod_params.wd_disable == 2) | ||
1519 | mod_timer(&priv->watchdog, | ||
1520 | jiffies + | ||
1521 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
1522 | else | ||
1523 | del_timer(&priv->watchdog); | ||
1524 | } | ||
1513 | } | 1525 | } |
1514 | 1526 | ||
1515 | /** | 1527 | /** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f1d9d0c13e4c..6da53a36c1be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -113,6 +113,7 @@ struct iwl_lib_ops { | |||
113 | * @shadow_reg_enable: HW shadhow register bit | 113 | * @shadow_reg_enable: HW shadhow register bit |
114 | * @no_idle_support: do not support idle mode | 114 | * @no_idle_support: do not support idle mode |
115 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | 115 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up |
116 | * wd_disable: disable watchdog timer | ||
116 | */ | 117 | */ |
117 | struct iwl_base_params { | 118 | struct iwl_base_params { |
118 | int eeprom_size; | 119 | int eeprom_size; |
@@ -134,6 +135,7 @@ struct iwl_base_params { | |||
134 | const bool shadow_reg_enable; | 135 | const bool shadow_reg_enable; |
135 | const bool no_idle_support; | 136 | const bool no_idle_support; |
136 | const bool hd_v2; | 137 | const bool hd_v2; |
138 | const bool wd_disable; | ||
137 | }; | 139 | }; |
138 | /* | 140 | /* |
139 | * @advanced_bt_coexist: support advanced bt coexist | 141 | * @advanced_bt_coexist: support advanced bt coexist |
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 47be77a8a0a7..30af95b19f78 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
@@ -120,7 +120,7 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
120 | * @restart_fw: restart firmware, default = 1 | 120 | * @restart_fw: restart firmware, default = 1 |
121 | * @plcp_check: enable plcp health check, default = true | 121 | * @plcp_check: enable plcp health check, default = true |
122 | * @ack_check: disable ack health check, default = false | 122 | * @ack_check: disable ack health check, default = false |
123 | * @wd_disable: enable stuck queue check, default = false | 123 | * @wd_disable: enable stuck queue check, default = 0 |
124 | * @bt_coex_active: enable bt coex, default = true | 124 | * @bt_coex_active: enable bt coex, default = true |
125 | * @led_mode: system default, default = 0 | 125 | * @led_mode: system default, default = 0 |
126 | * @no_sleep_autoadjust: disable autoadjust, default = true | 126 | * @no_sleep_autoadjust: disable autoadjust, default = true |
@@ -141,7 +141,7 @@ struct iwl_mod_params { | |||
141 | int restart_fw; | 141 | int restart_fw; |
142 | bool plcp_check; | 142 | bool plcp_check; |
143 | bool ack_check; | 143 | bool ack_check; |
144 | bool wd_disable; | 144 | int wd_disable; |
145 | bool bt_coex_active; | 145 | bool bt_coex_active; |
146 | int led_mode; | 146 | int led_mode; |
147 | bool no_sleep_autoadjust; | 147 | bool no_sleep_autoadjust; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 2ac75427f10b..304b2ea0375c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -990,29 +990,16 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
990 | return 0; | 990 | return 0; |
991 | } | 991 | } |
992 | 992 | ||
993 | static void iwl_trans_pcie_disable_sync_irq(struct iwl_trans *trans) | 993 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) |
994 | { | 994 | { |
995 | unsigned long flags; | 995 | unsigned long flags; |
996 | struct iwl_trans_pcie *trans_pcie = | 996 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
997 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
998 | 997 | ||
998 | /* tell the device to stop sending interrupts */ | ||
999 | spin_lock_irqsave(&trans->shrd->lock, flags); | 999 | spin_lock_irqsave(&trans->shrd->lock, flags); |
1000 | iwl_disable_interrupts(trans); | 1000 | iwl_disable_interrupts(trans); |
1001 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 1001 | spin_unlock_irqrestore(&trans->shrd->lock, flags); |
1002 | 1002 | ||
1003 | /* wait to make sure we flush pending tasklet*/ | ||
1004 | synchronize_irq(bus(trans)->irq); | ||
1005 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
1006 | } | ||
1007 | |||
1008 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | ||
1009 | { | ||
1010 | /* stop and reset the on-board processor */ | ||
1011 | iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
1012 | |||
1013 | /* tell the device to stop sending interrupts */ | ||
1014 | iwl_trans_pcie_disable_sync_irq(trans); | ||
1015 | |||
1016 | /* device going down, Stop using ICT table */ | 1003 | /* device going down, Stop using ICT table */ |
1017 | iwl_disable_ict(trans); | 1004 | iwl_disable_ict(trans); |
1018 | 1005 | ||
@@ -1039,6 +1026,20 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1039 | 1026 | ||
1040 | /* Stop the device, and put it in low power state */ | 1027 | /* Stop the device, and put it in low power state */ |
1041 | iwl_apm_stop(priv(trans)); | 1028 | iwl_apm_stop(priv(trans)); |
1029 | |||
1030 | /* Upon stop, the APM issues an interrupt if HW RF kill is set. | ||
1031 | * Clean again the interrupt here | ||
1032 | */ | ||
1033 | spin_lock_irqsave(&trans->shrd->lock, flags); | ||
1034 | iwl_disable_interrupts(trans); | ||
1035 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | ||
1036 | |||
1037 | /* wait to make sure we flush pending tasklet*/ | ||
1038 | synchronize_irq(bus(trans)->irq); | ||
1039 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
1040 | |||
1041 | /* stop and reset the on-board processor */ | ||
1042 | iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
1042 | } | 1043 | } |
1043 | 1044 | ||
1044 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | 1045 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 89f34ad8d34a..d1d84e0e30fc 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -635,7 +635,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
635 | if (channel && | 635 | if (channel && |
636 | !(channel->flags & IEEE80211_CHAN_DISABLED)) { | 636 | !(channel->flags & IEEE80211_CHAN_DISABLED)) { |
637 | bss = cfg80211_inform_bss(wiphy, channel, | 637 | bss = cfg80211_inform_bss(wiphy, channel, |
638 | bssid, le64_to_cpu(*(__le64 *)tsfdesc), | 638 | bssid, get_unaligned_le64(tsfdesc), |
639 | capa, intvl, ie, ielen, | 639 | capa, intvl, ie, ielen, |
640 | LBS_SCAN_RSSI_TO_MBM(rssi), | 640 | LBS_SCAN_RSSI_TO_MBM(rssi), |
641 | GFP_KERNEL); | 641 | GFP_KERNEL); |
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 0c87f42fa660..50b1ee7721e9 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -995,6 +995,7 @@ static int if_spi_host_to_card(struct lbs_private *priv, | |||
995 | spin_unlock_irqrestore(&card->buffer_lock, flags); | 995 | spin_unlock_irqrestore(&card->buffer_lock, flags); |
996 | break; | 996 | break; |
997 | default: | 997 | default: |
998 | kfree(packet); | ||
998 | netdev_err(priv->dev, "can't transfer buffer of type %d\n", | 999 | netdev_err(priv->dev, "can't transfer buffer of type %d\n", |
999 | type); | 1000 | type); |
1000 | err = -EINVAL; | 1001 | err = -EINVAL; |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 8a18bcc23b26..b8b9d37b01a9 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -819,8 +819,10 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
819 | wildcard_ssid_tlv->header.len = cpu_to_le16( | 819 | wildcard_ssid_tlv->header.len = cpu_to_le16( |
820 | (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> | 820 | (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> |
821 | max_ssid_length))); | 821 | max_ssid_length))); |
822 | wildcard_ssid_tlv->max_ssid_length = | 822 | |
823 | user_scan_in->ssid_list[ssid_idx].max_len; | 823 | /* max_ssid_length = 0 tells firmware to perform |
824 | specific scan for the SSID filled */ | ||
825 | wildcard_ssid_tlv->max_ssid_length = 0; | ||
824 | 826 | ||
825 | memcpy(wildcard_ssid_tlv->ssid, | 827 | memcpy(wildcard_ssid_tlv->ssid, |
826 | user_scan_in->ssid_list[ssid_idx].ssid, | 828 | user_scan_in->ssid_list[ssid_idx].ssid, |
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 546551389a1d..7faed62c6378 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c | |||
@@ -584,8 +584,6 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) | |||
584 | mutex_lock(&priv->mutex); | 584 | mutex_lock(&priv->mutex); |
585 | WARN_ON(priv->fw_state != FW_STATE_READY); | 585 | WARN_ON(priv->fw_state != FW_STATE_READY); |
586 | 586 | ||
587 | cancel_work_sync(&priv->work); | ||
588 | |||
589 | p54spi_power_off(priv); | 587 | p54spi_power_off(priv); |
590 | spin_lock_irqsave(&priv->tx_lock, flags); | 588 | spin_lock_irqsave(&priv->tx_lock, flags); |
591 | INIT_LIST_HEAD(&priv->tx_pending); | 589 | INIT_LIST_HEAD(&priv->tx_pending); |
@@ -593,6 +591,8 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) | |||
593 | 591 | ||
594 | priv->fw_state = FW_STATE_OFF; | 592 | priv->fw_state = FW_STATE_OFF; |
595 | mutex_unlock(&priv->mutex); | 593 | mutex_unlock(&priv->mutex); |
594 | |||
595 | cancel_work_sync(&priv->work); | ||
596 | } | 596 | } |
597 | 597 | ||
598 | static int __devinit p54spi_probe(struct spi_device *spi) | 598 | static int __devinit p54spi_probe(struct spi_device *spi) |
@@ -652,6 +652,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
652 | init_completion(&priv->fw_comp); | 652 | init_completion(&priv->fw_comp); |
653 | INIT_LIST_HEAD(&priv->tx_pending); | 653 | INIT_LIST_HEAD(&priv->tx_pending); |
654 | mutex_init(&priv->mutex); | 654 | mutex_init(&priv->mutex); |
655 | spin_lock_init(&priv->tx_lock); | ||
655 | SET_IEEE80211_DEV(hw, &spi->dev); | 656 | SET_IEEE80211_DEV(hw, &spi->dev); |
656 | priv->common.open = p54spi_op_start; | 657 | priv->common.open = p54spi_op_start; |
657 | priv->common.stop = p54spi_op_stop; | 658 | priv->common.stop = p54spi_op_stop; |
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index f83bc5a5e81f..4e44b1af119a 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
@@ -778,7 +778,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, | |||
778 | dwrq->flags = 0; | 778 | dwrq->flags = 0; |
779 | dwrq->length = 0; | 779 | dwrq->length = 0; |
780 | } | 780 | } |
781 | essid->octets[essid->length] = '\0'; | 781 | essid->octets[dwrq->length] = '\0'; |
782 | memcpy(extra, essid->octets, dwrq->length); | 782 | memcpy(extra, essid->octets, dwrq->length); |
783 | kfree(essid); | 783 | kfree(essid); |
784 | 784 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 25dab2987131..e5df380d4fbe 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -3773,7 +3773,7 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) | |||
3773 | /* Apparently the data is read from end to start */ | 3773 | /* Apparently the data is read from end to start */ |
3774 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); | 3774 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); |
3775 | /* The returned value is in CPU order, but eeprom is le */ | 3775 | /* The returned value is in CPU order, but eeprom is le */ |
3776 | rt2x00dev->eeprom[i] = cpu_to_le32(reg); | 3776 | *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg); |
3777 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); | 3777 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); |
3778 | *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); | 3778 | *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); |
3779 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); | 3779 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f1565792f270..377876315b8d 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -919,6 +919,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
919 | { USB_DEVICE(0x050d, 0x935b) }, | 919 | { USB_DEVICE(0x050d, 0x935b) }, |
920 | /* Buffalo */ | 920 | /* Buffalo */ |
921 | { USB_DEVICE(0x0411, 0x00e8) }, | 921 | { USB_DEVICE(0x0411, 0x00e8) }, |
922 | { USB_DEVICE(0x0411, 0x0158) }, | ||
922 | { USB_DEVICE(0x0411, 0x016f) }, | 923 | { USB_DEVICE(0x0411, 0x016f) }, |
923 | { USB_DEVICE(0x0411, 0x01a2) }, | 924 | { USB_DEVICE(0x0411, 0x01a2) }, |
924 | /* Corega */ | 925 | /* Corega */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 2ec5c00235e6..99ff12d0c29d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -943,6 +943,7 @@ struct rt2x00_dev { | |||
943 | * Powersaving work | 943 | * Powersaving work |
944 | */ | 944 | */ |
945 | struct delayed_work autowakeup_work; | 945 | struct delayed_work autowakeup_work; |
946 | struct work_struct sleep_work; | ||
946 | 947 | ||
947 | /* | 948 | /* |
948 | * Data queue arrays for RX, TX, Beacon and ATIM. | 949 | * Data queue arrays for RX, TX, Beacon and ATIM. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e1fb2a8569be..edd317fa7c0a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -465,6 +465,23 @@ static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie) | |||
465 | return NULL; | 465 | return NULL; |
466 | } | 466 | } |
467 | 467 | ||
468 | static void rt2x00lib_sleep(struct work_struct *work) | ||
469 | { | ||
470 | struct rt2x00_dev *rt2x00dev = | ||
471 | container_of(work, struct rt2x00_dev, sleep_work); | ||
472 | |||
473 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | ||
474 | return; | ||
475 | |||
476 | /* | ||
477 | * Check again is powersaving is enabled, to prevent races from delayed | ||
478 | * work execution. | ||
479 | */ | ||
480 | if (!test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) | ||
481 | rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, | ||
482 | IEEE80211_CONF_CHANGE_PS); | ||
483 | } | ||
484 | |||
468 | static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, | 485 | static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, |
469 | struct sk_buff *skb, | 486 | struct sk_buff *skb, |
470 | struct rxdone_entry_desc *rxdesc) | 487 | struct rxdone_entry_desc *rxdesc) |
@@ -512,8 +529,7 @@ static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, | |||
512 | cam |= (tim_ie->bitmap_ctrl & 0x01); | 529 | cam |= (tim_ie->bitmap_ctrl & 0x01); |
513 | 530 | ||
514 | if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) | 531 | if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) |
515 | rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, | 532 | queue_work(rt2x00dev->workqueue, &rt2x00dev->sleep_work); |
516 | IEEE80211_CONF_CHANGE_PS); | ||
517 | } | 533 | } |
518 | 534 | ||
519 | static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, | 535 | static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, |
@@ -1141,6 +1157,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1141 | 1157 | ||
1142 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); | 1158 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1143 | INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); | 1159 | INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); |
1160 | INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); | ||
1144 | 1161 | ||
1145 | /* | 1162 | /* |
1146 | * Let the driver probe the device to detect the capabilities. | 1163 | * Let the driver probe the device to detect the capabilities. |
@@ -1197,6 +1214,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1197 | */ | 1214 | */ |
1198 | cancel_work_sync(&rt2x00dev->intf_work); | 1215 | cancel_work_sync(&rt2x00dev->intf_work); |
1199 | cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); | 1216 | cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); |
1217 | cancel_work_sync(&rt2x00dev->sleep_work); | ||
1200 | if (rt2x00_is_usb(rt2x00dev)) { | 1218 | if (rt2x00_is_usb(rt2x00dev)) { |
1201 | del_timer_sync(&rt2x00dev->txstatus_timer); | 1219 | del_timer_sync(&rt2x00dev->txstatus_timer); |
1202 | cancel_work_sync(&rt2x00dev->rxdone_work); | 1220 | cancel_work_sync(&rt2x00dev->rxdone_work); |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index db5262844543..55c8e50f45fd 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -395,7 +395,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
395 | if (mac->link_state != MAC80211_LINKED) | 395 | if (mac->link_state != MAC80211_LINKED) |
396 | return; | 396 | return; |
397 | 397 | ||
398 | spin_lock(&rtlpriv->locks.lps_lock); | 398 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
399 | 399 | ||
400 | /* Idle for a while if we connect to AP a while ago. */ | 400 | /* Idle for a while if we connect to AP a while ago. */ |
401 | if (mac->cnt_after_linked >= 2) { | 401 | if (mac->cnt_after_linked >= 2) { |
@@ -407,7 +407,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
407 | } | 407 | } |
408 | } | 408 | } |
409 | 409 | ||
410 | spin_unlock(&rtlpriv->locks.lps_lock); | 410 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
411 | } | 411 | } |
412 | 412 | ||
413 | /*Leave the leisure power save mode.*/ | 413 | /*Leave the leisure power save mode.*/ |
@@ -416,8 +416,9 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
416 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 416 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
417 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 417 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
418 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 418 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
419 | unsigned long flags; | ||
419 | 420 | ||
420 | spin_lock(&rtlpriv->locks.lps_lock); | 421 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flags); |
421 | 422 | ||
422 | if (ppsc->fwctrl_lps) { | 423 | if (ppsc->fwctrl_lps) { |
423 | if (ppsc->dot11_psmode != EACTIVE) { | 424 | if (ppsc->dot11_psmode != EACTIVE) { |
@@ -438,7 +439,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
438 | rtl_lps_set_psmode(hw, EACTIVE); | 439 | rtl_lps_set_psmode(hw, EACTIVE); |
439 | } | 440 | } |
440 | } | 441 | } |
441 | spin_unlock(&rtlpriv->locks.lps_lock); | 442 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flags); |
442 | } | 443 | } |
443 | 444 | ||
444 | /* For sw LPS*/ | 445 | /* For sw LPS*/ |
@@ -539,9 +540,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | |||
539 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); | 540 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); |
540 | } | 541 | } |
541 | 542 | ||
542 | spin_lock(&rtlpriv->locks.lps_lock); | 543 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
543 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); | 544 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); |
544 | spin_unlock(&rtlpriv->locks.lps_lock); | 545 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
545 | } | 546 | } |
546 | 547 | ||
547 | void rtl_swlps_rfon_wq_callback(void *data) | 548 | void rtl_swlps_rfon_wq_callback(void *data) |
@@ -574,9 +575,9 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | |||
574 | if (rtlpriv->link_info.busytraffic) | 575 | if (rtlpriv->link_info.busytraffic) |
575 | return; | 576 | return; |
576 | 577 | ||
577 | spin_lock(&rtlpriv->locks.lps_lock); | 578 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
578 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); | 579 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); |
579 | spin_unlock(&rtlpriv->locks.lps_lock); | 580 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
580 | 581 | ||
581 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && | 582 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && |
582 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { | 583 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 266cc871c72d..2c2e9519a2e7 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -162,6 +162,12 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
162 | return -ENOENT; | 162 | return -ENOENT; |
163 | } | 163 | } |
164 | 164 | ||
165 | /* if we're already stopping ignore any new requests to stop */ | ||
166 | if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { | ||
167 | spin_unlock_bh(&sta->lock); | ||
168 | return -EALREADY; | ||
169 | } | ||
170 | |||
165 | if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { | 171 | if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { |
166 | /* not even started yet! */ | 172 | /* not even started yet! */ |
167 | ieee80211_assign_tid_tx(sta, tid, NULL); | 173 | ieee80211_assign_tid_tx(sta, tid, NULL); |
@@ -170,6 +176,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
170 | return 0; | 176 | return 0; |
171 | } | 177 | } |
172 | 178 | ||
179 | set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); | ||
180 | |||
173 | spin_unlock_bh(&sta->lock); | 181 | spin_unlock_bh(&sta->lock); |
174 | 182 | ||
175 | #ifdef CONFIG_MAC80211_HT_DEBUG | 183 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -177,8 +185,6 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
177 | sta->sta.addr, tid); | 185 | sta->sta.addr, tid); |
178 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 186 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
179 | 187 | ||
180 | set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); | ||
181 | |||
182 | del_timer_sync(&tid_tx->addba_resp_timer); | 188 | del_timer_sync(&tid_tx->addba_resp_timer); |
183 | del_timer_sync(&tid_tx->session_timer); | 189 | del_timer_sync(&tid_tx->session_timer); |
184 | 190 | ||
@@ -189,6 +195,20 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
189 | */ | 195 | */ |
190 | clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); | 196 | clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); |
191 | 197 | ||
198 | /* | ||
199 | * There might be a few packets being processed right now (on | ||
200 | * another CPU) that have already gotten past the aggregation | ||
201 | * check when it was still OPERATIONAL and consequently have | ||
202 | * IEEE80211_TX_CTL_AMPDU set. In that case, this code might | ||
203 | * call into the driver at the same time or even before the | ||
204 | * TX paths calls into it, which could confuse the driver. | ||
205 | * | ||
206 | * Wait for all currently running TX paths to finish before | ||
207 | * telling the driver. New packets will not go through since | ||
208 | * the aggregation session is no longer OPERATIONAL. | ||
209 | */ | ||
210 | synchronize_net(); | ||
211 | |||
192 | tid_tx->stop_initiator = initiator; | 212 | tid_tx->stop_initiator = initiator; |
193 | tid_tx->tx_stop = tx; | 213 | tid_tx->tx_stop = tx; |
194 | 214 | ||
@@ -781,11 +801,27 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
781 | goto out; | 801 | goto out; |
782 | } | 802 | } |
783 | 803 | ||
784 | del_timer(&tid_tx->addba_resp_timer); | 804 | del_timer_sync(&tid_tx->addba_resp_timer); |
785 | 805 | ||
786 | #ifdef CONFIG_MAC80211_HT_DEBUG | 806 | #ifdef CONFIG_MAC80211_HT_DEBUG |
787 | printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid); | 807 | printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid); |
788 | #endif | 808 | #endif |
809 | |||
810 | /* | ||
811 | * addba_resp_timer may have fired before we got here, and | ||
812 | * caused WANT_STOP to be set. If the stop then was already | ||
813 | * processed further, STOPPING might be set. | ||
814 | */ | ||
815 | if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || | ||
816 | test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { | ||
817 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
818 | printk(KERN_DEBUG | ||
819 | "got addBA resp for tid %d but we already gave up\n", | ||
820 | tid); | ||
821 | #endif | ||
822 | goto out; | ||
823 | } | ||
824 | |||
789 | /* | 825 | /* |
790 | * IEEE 802.11-2007 7.3.1.14: | 826 | * IEEE 802.11-2007 7.3.1.14: |
791 | * In an ADDBA Response frame, when the Status Code field | 827 | * In an ADDBA Response frame, when the Status Code field |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index edfdd74d4351..2406b3e7393f 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -274,9 +274,9 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf, | |||
274 | 274 | ||
275 | PRINT_HT_CAP((htc->cap & BIT(10)), "HT Delayed Block Ack"); | 275 | PRINT_HT_CAP((htc->cap & BIT(10)), "HT Delayed Block Ack"); |
276 | 276 | ||
277 | PRINT_HT_CAP((htc->cap & BIT(11)), "Max AMSDU length: " | ||
278 | "3839 bytes"); | ||
279 | PRINT_HT_CAP(!(htc->cap & BIT(11)), "Max AMSDU length: " | 277 | PRINT_HT_CAP(!(htc->cap & BIT(11)), "Max AMSDU length: " |
278 | "3839 bytes"); | ||
279 | PRINT_HT_CAP((htc->cap & BIT(11)), "Max AMSDU length: " | ||
280 | "7935 bytes"); | 280 | "7935 bytes"); |
281 | 281 | ||
282 | /* | 282 | /* |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 944bed35d923..24cc50b963a9 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -738,6 +738,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
738 | if (!local->int_scan_req) | 738 | if (!local->int_scan_req) |
739 | return -ENOMEM; | 739 | return -ENOMEM; |
740 | 740 | ||
741 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
742 | if (!local->hw.wiphy->bands[band]) | ||
743 | continue; | ||
744 | local->int_scan_req->rates[band] = (u32) -1; | ||
745 | } | ||
746 | |||
741 | /* if low-level driver supports AP, we also support VLAN */ | 747 | /* if low-level driver supports AP, we also support VLAN */ |
742 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { | 748 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { |
743 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); | 749 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a6ad19757bac..09019d135942 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2301,6 +2301,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
2301 | 2301 | ||
2302 | cancel_work_sync(&ifmgd->request_smps_work); | 2302 | cancel_work_sync(&ifmgd->request_smps_work); |
2303 | 2303 | ||
2304 | cancel_work_sync(&ifmgd->monitor_work); | ||
2304 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); | 2305 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); |
2305 | if (del_timer_sync(&ifmgd->timer)) | 2306 | if (del_timer_sync(&ifmgd->timer)) |
2306 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); | 2307 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); |
@@ -2309,7 +2310,6 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
2309 | if (del_timer_sync(&ifmgd->chswitch_timer)) | 2310 | if (del_timer_sync(&ifmgd->chswitch_timer)) |
2310 | set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); | 2311 | set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); |
2311 | 2312 | ||
2312 | cancel_work_sync(&ifmgd->monitor_work); | ||
2313 | /* these will just be re-established on connection */ | 2313 | /* these will just be re-established on connection */ |
2314 | del_timer_sync(&ifmgd->conn_mon_timer); | 2314 | del_timer_sync(&ifmgd->conn_mon_timer); |
2315 | del_timer_sync(&ifmgd->bcn_mon_timer); | 2315 | del_timer_sync(&ifmgd->bcn_mon_timer); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 1e231e95f466..daf5cde65b30 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -141,8 +141,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
141 | pos++; | 141 | pos++; |
142 | 142 | ||
143 | /* IEEE80211_RADIOTAP_RATE */ | 143 | /* IEEE80211_RADIOTAP_RATE */ |
144 | if (status->flag & RX_FLAG_HT) { | 144 | if (!rate || status->flag & RX_FLAG_HT) { |
145 | /* | 145 | /* |
146 | * Without rate information don't add it. If we have, | ||
146 | * MCS information is a separate field in radiotap, | 147 | * MCS information is a separate field in radiotap, |
147 | * added below. The byte here is needed as padding | 148 | * added below. The byte here is needed as padding |
148 | * for the channel though, so initialise it to 0. | 149 | * for the channel though, so initialise it to 0. |
@@ -163,12 +164,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
163 | else if (status->flag & RX_FLAG_HT) | 164 | else if (status->flag & RX_FLAG_HT) |
164 | put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, | 165 | put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, |
165 | pos); | 166 | pos); |
166 | else if (rate->flags & IEEE80211_RATE_ERP_G) | 167 | else if (rate && rate->flags & IEEE80211_RATE_ERP_G) |
167 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, | 168 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, |
168 | pos); | 169 | pos); |
169 | else | 170 | else if (rate) |
170 | put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, | 171 | put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, |
171 | pos); | 172 | pos); |
173 | else | ||
174 | put_unaligned_le16(IEEE80211_CHAN_2GHZ, pos); | ||
172 | pos += 2; | 175 | pos += 2; |
173 | 176 | ||
174 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ | 177 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index a9da6ee69803..46222ce0e5b1 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -260,7 +260,7 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band | |||
260 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 260 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
261 | struct ieee80211_radiotap_header *rthdr; | 261 | struct ieee80211_radiotap_header *rthdr; |
262 | unsigned char *pos; | 262 | unsigned char *pos; |
263 | __le16 txflags; | 263 | u16 txflags; |
264 | 264 | ||
265 | rthdr = (struct ieee80211_radiotap_header *) skb_push(skb, rtap_len); | 265 | rthdr = (struct ieee80211_radiotap_header *) skb_push(skb, rtap_len); |
266 | 266 | ||
@@ -290,13 +290,13 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band | |||
290 | txflags = 0; | 290 | txflags = 0; |
291 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | 291 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
292 | !is_multicast_ether_addr(hdr->addr1)) | 292 | !is_multicast_ether_addr(hdr->addr1)) |
293 | txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 293 | txflags |= IEEE80211_RADIOTAP_F_TX_FAIL; |
294 | 294 | ||
295 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | 295 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || |
296 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) | 296 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) |
297 | txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 297 | txflags |= IEEE80211_RADIOTAP_F_TX_CTS; |
298 | else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | 298 | else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) |
299 | txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | 299 | txflags |= IEEE80211_RADIOTAP_F_TX_RTS; |
300 | 300 | ||
301 | put_unaligned_le16(txflags, pos); | 301 | put_unaligned_le16(txflags, pos); |
302 | pos += 2; | 302 | pos += 2; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 5f7c1c601dc5..5243c2cadeef 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1034,6 +1034,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1034 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, | 1034 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, |
1035 | ssid, ssid_len, | 1035 | ssid, ssid_len, |
1036 | buf, buf_len); | 1036 | buf, buf_len); |
1037 | if (!skb) | ||
1038 | goto out; | ||
1037 | 1039 | ||
1038 | if (dst) { | 1040 | if (dst) { |
1039 | mgmt = (struct ieee80211_mgmt *) skb->data; | 1041 | mgmt = (struct ieee80211_mgmt *) skb->data; |
@@ -1042,6 +1044,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1042 | } | 1044 | } |
1043 | 1045 | ||
1044 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 1046 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
1047 | |||
1048 | out: | ||
1045 | kfree(buf); | 1049 | kfree(buf); |
1046 | 1050 | ||
1047 | return skb; | 1051 | return skb; |
@@ -1188,7 +1192,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1188 | struct ieee80211_sub_if_data, | 1192 | struct ieee80211_sub_if_data, |
1189 | u.ap); | 1193 | u.ap); |
1190 | 1194 | ||
1191 | memset(&sta->sta.drv_priv, 0, hw->sta_data_size); | ||
1192 | WARN_ON(drv_sta_add(local, sdata, &sta->sta)); | 1195 | WARN_ON(drv_sta_add(local, sdata, &sta->sta)); |
1193 | } | 1196 | } |
1194 | } | 1197 | } |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0ee512b85a1f..8a9b4d817ae6 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -89,8 +89,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
89 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, | 89 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, |
90 | [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, | 90 | [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, |
91 | 91 | ||
92 | [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN }, | 92 | [NL80211_ATTR_MAC] = { .len = ETH_ALEN }, |
93 | [NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN }, | 93 | [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN }, |
94 | 94 | ||
95 | [NL80211_ATTR_KEY] = { .type = NLA_NESTED, }, | 95 | [NL80211_ATTR_KEY] = { .type = NLA_NESTED, }, |
96 | [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, | 96 | [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 0e67016ce78f..70b171a52aea 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -57,8 +57,17 @@ | |||
57 | #define REG_DBG_PRINT(args...) | 57 | #define REG_DBG_PRINT(args...) |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | static struct regulatory_request core_request_world = { | ||
61 | .initiator = NL80211_REGDOM_SET_BY_CORE, | ||
62 | .alpha2[0] = '0', | ||
63 | .alpha2[1] = '0', | ||
64 | .intersect = false, | ||
65 | .processed = true, | ||
66 | .country_ie_env = ENVIRON_ANY, | ||
67 | }; | ||
68 | |||
60 | /* Receipt of information from last regulatory request */ | 69 | /* Receipt of information from last regulatory request */ |
61 | static struct regulatory_request *last_request; | 70 | static struct regulatory_request *last_request = &core_request_world; |
62 | 71 | ||
63 | /* To trigger userspace events */ | 72 | /* To trigger userspace events */ |
64 | static struct platform_device *reg_pdev; | 73 | static struct platform_device *reg_pdev; |
@@ -150,7 +159,7 @@ static char user_alpha2[2]; | |||
150 | module_param(ieee80211_regdom, charp, 0444); | 159 | module_param(ieee80211_regdom, charp, 0444); |
151 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); | 160 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); |
152 | 161 | ||
153 | static void reset_regdomains(void) | 162 | static void reset_regdomains(bool full_reset) |
154 | { | 163 | { |
155 | /* avoid freeing static information or freeing something twice */ | 164 | /* avoid freeing static information or freeing something twice */ |
156 | if (cfg80211_regdomain == cfg80211_world_regdom) | 165 | if (cfg80211_regdomain == cfg80211_world_regdom) |
@@ -165,6 +174,13 @@ static void reset_regdomains(void) | |||
165 | 174 | ||
166 | cfg80211_world_regdom = &world_regdom; | 175 | cfg80211_world_regdom = &world_regdom; |
167 | cfg80211_regdomain = NULL; | 176 | cfg80211_regdomain = NULL; |
177 | |||
178 | if (!full_reset) | ||
179 | return; | ||
180 | |||
181 | if (last_request != &core_request_world) | ||
182 | kfree(last_request); | ||
183 | last_request = &core_request_world; | ||
168 | } | 184 | } |
169 | 185 | ||
170 | /* | 186 | /* |
@@ -175,7 +191,7 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd) | |||
175 | { | 191 | { |
176 | BUG_ON(!last_request); | 192 | BUG_ON(!last_request); |
177 | 193 | ||
178 | reset_regdomains(); | 194 | reset_regdomains(false); |
179 | 195 | ||
180 | cfg80211_world_regdom = rd; | 196 | cfg80211_world_regdom = rd; |
181 | cfg80211_regdomain = rd; | 197 | cfg80211_regdomain = rd; |
@@ -1409,7 +1425,8 @@ static int __regulatory_hint(struct wiphy *wiphy, | |||
1409 | } | 1425 | } |
1410 | 1426 | ||
1411 | new_request: | 1427 | new_request: |
1412 | kfree(last_request); | 1428 | if (last_request != &core_request_world) |
1429 | kfree(last_request); | ||
1413 | 1430 | ||
1414 | last_request = pending_request; | 1431 | last_request = pending_request; |
1415 | last_request->intersect = intersect; | 1432 | last_request->intersect = intersect; |
@@ -1579,9 +1596,6 @@ static int regulatory_hint_core(const char *alpha2) | |||
1579 | { | 1596 | { |
1580 | struct regulatory_request *request; | 1597 | struct regulatory_request *request; |
1581 | 1598 | ||
1582 | kfree(last_request); | ||
1583 | last_request = NULL; | ||
1584 | |||
1585 | request = kzalloc(sizeof(struct regulatory_request), | 1599 | request = kzalloc(sizeof(struct regulatory_request), |
1586 | GFP_KERNEL); | 1600 | GFP_KERNEL); |
1587 | if (!request) | 1601 | if (!request) |
@@ -1779,7 +1793,7 @@ static void restore_regulatory_settings(bool reset_user) | |||
1779 | mutex_lock(&cfg80211_mutex); | 1793 | mutex_lock(&cfg80211_mutex); |
1780 | mutex_lock(®_mutex); | 1794 | mutex_lock(®_mutex); |
1781 | 1795 | ||
1782 | reset_regdomains(); | 1796 | reset_regdomains(true); |
1783 | restore_alpha2(alpha2, reset_user); | 1797 | restore_alpha2(alpha2, reset_user); |
1784 | 1798 | ||
1785 | /* | 1799 | /* |
@@ -2076,12 +2090,18 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2076 | } | 2090 | } |
2077 | 2091 | ||
2078 | request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); | 2092 | request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); |
2093 | if (!request_wiphy && | ||
2094 | (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER || | ||
2095 | last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) { | ||
2096 | schedule_delayed_work(®_timeout, 0); | ||
2097 | return -ENODEV; | ||
2098 | } | ||
2079 | 2099 | ||
2080 | if (!last_request->intersect) { | 2100 | if (!last_request->intersect) { |
2081 | int r; | 2101 | int r; |
2082 | 2102 | ||
2083 | if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { | 2103 | if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { |
2084 | reset_regdomains(); | 2104 | reset_regdomains(false); |
2085 | cfg80211_regdomain = rd; | 2105 | cfg80211_regdomain = rd; |
2086 | return 0; | 2106 | return 0; |
2087 | } | 2107 | } |
@@ -2102,7 +2122,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2102 | if (r) | 2122 | if (r) |
2103 | return r; | 2123 | return r; |
2104 | 2124 | ||
2105 | reset_regdomains(); | 2125 | reset_regdomains(false); |
2106 | cfg80211_regdomain = rd; | 2126 | cfg80211_regdomain = rd; |
2107 | return 0; | 2127 | return 0; |
2108 | } | 2128 | } |
@@ -2127,7 +2147,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2127 | 2147 | ||
2128 | rd = NULL; | 2148 | rd = NULL; |
2129 | 2149 | ||
2130 | reset_regdomains(); | 2150 | reset_regdomains(false); |
2131 | cfg80211_regdomain = intersected_rd; | 2151 | cfg80211_regdomain = intersected_rd; |
2132 | 2152 | ||
2133 | return 0; | 2153 | return 0; |
@@ -2147,7 +2167,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2147 | kfree(rd); | 2167 | kfree(rd); |
2148 | rd = NULL; | 2168 | rd = NULL; |
2149 | 2169 | ||
2150 | reset_regdomains(); | 2170 | reset_regdomains(false); |
2151 | cfg80211_regdomain = intersected_rd; | 2171 | cfg80211_regdomain = intersected_rd; |
2152 | 2172 | ||
2153 | return 0; | 2173 | return 0; |
@@ -2300,9 +2320,9 @@ void /* __init_or_exit */ regulatory_exit(void) | |||
2300 | mutex_lock(&cfg80211_mutex); | 2320 | mutex_lock(&cfg80211_mutex); |
2301 | mutex_lock(®_mutex); | 2321 | mutex_lock(®_mutex); |
2302 | 2322 | ||
2303 | reset_regdomains(); | 2323 | reset_regdomains(true); |
2304 | 2324 | ||
2305 | kfree(last_request); | 2325 | dev_set_uevent_suppress(®_pdev->dev, true); |
2306 | 2326 | ||
2307 | platform_device_unregister(reg_pdev); | 2327 | platform_device_unregister(reg_pdev); |
2308 | 2328 | ||