aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c3
-rw-r--r--drivers/net/wireless/ath/regd.c2
-rw-r--r--drivers/net/wireless/b43/xmit.c15
-rw-r--r--drivers/net/wireless/b43/xmit.h16
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c36
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-shared.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie.c33
-rw-r--r--drivers/net/wireless/libertas/cfg.c2
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1
-rw-r--r--drivers/net/wireless/mwifiex/scan.c9
-rw-r--r--drivers/net/wireless/p54/p54spi.c5
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c22
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c17
-rw-r--r--drivers/net/wireless/wl12xx/scan.c2
-rw-r--r--include/net/cfg80211.h4
-rw-r--r--include/net/mac80211.h3
-rw-r--r--net/mac80211/agg-tx.c42
-rw-r--r--net/mac80211/debugfs_sta.c4
-rw-r--r--net/mac80211/main.c6
-rw-r--r--net/mac80211/mlme.c21
-rw-r--r--net/mac80211/rx.c9
-rw-r--r--net/mac80211/sta_info.c8
-rw-r--r--net/mac80211/status.c8
-rw-r--r--net/mac80211/util.c5
-rw-r--r--net/wireless/nl80211.c13
-rw-r--r--net/wireless/reg.c48
-rw-r--r--net/wireless/scan.c13
39 files changed, 304 insertions, 125 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index b479160dc262..7a9c6f7cd7e1 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1826,7 +1826,8 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
1826 } 1826 }
1827 1827
1828 /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ 1828 /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
1829 REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); 1829 if (AR_SREV_9300_20_OR_LATER(ah))
1830 REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
1830} 1831}
1831 1832
1832/* 1833/*
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 028310f263c8..f1be57f0f5bb 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -253,6 +253,8 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
253 int r; 253 int r;
254 254
255 sband = wiphy->bands[IEEE80211_BAND_2GHZ]; 255 sband = wiphy->bands[IEEE80211_BAND_2GHZ];
256 if (!sband)
257 return;
256 258
257 /* 259 /*
258 * If no country IE has been received always enable active scan 260 * If no country IE has been received always enable active scan
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 58ea0e5fabfd..5f77cbe0b6aa 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -175,6 +175,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
175 } 175 }
176} 176}
177 177
178/* TODO: verify if needed for SSLPN or LCN */
178static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate) 179static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
179{ 180{
180 const struct b43_phy *phy = &dev->phy; 181 const struct b43_phy *phy = &dev->phy;
@@ -256,6 +257,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
256 unsigned int plcp_fragment_len; 257 unsigned int plcp_fragment_len;
257 u32 mac_ctl = 0; 258 u32 mac_ctl = 0;
258 u16 phy_ctl = 0; 259 u16 phy_ctl = 0;
260 bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP ||
261 phy->type == B43_PHYTYPE_N ||
262 phy->type == B43_PHYTYPE_HT);
259 u8 extra_ft = 0; 263 u8 extra_ft = 0;
260 struct ieee80211_rate *txrate; 264 struct ieee80211_rate *txrate;
261 struct ieee80211_tx_rate *rates; 265 struct ieee80211_tx_rate *rates;
@@ -531,7 +535,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
531 extra_ft |= B43_TXH_EFT_RTSFB_CCK; 535 extra_ft |= B43_TXH_EFT_RTSFB_CCK;
532 536
533 if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS && 537 if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
534 phy->type == B43_PHYTYPE_N) { 538 fill_phy_ctl1) {
535 txhdr->phy_ctl1_rts = cpu_to_le16( 539 txhdr->phy_ctl1_rts = cpu_to_le16(
536 b43_generate_tx_phy_ctl1(dev, rts_rate)); 540 b43_generate_tx_phy_ctl1(dev, rts_rate));
537 txhdr->phy_ctl1_rts_fb = cpu_to_le16( 541 txhdr->phy_ctl1_rts_fb = cpu_to_le16(
@@ -552,7 +556,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
552 break; 556 break;
553 } 557 }
554 558
555 if (phy->type == B43_PHYTYPE_N) { 559 if (fill_phy_ctl1) {
556 txhdr->phy_ctl1 = 560 txhdr->phy_ctl1 =
557 cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate)); 561 cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
558 txhdr->phy_ctl1_fb = 562 txhdr->phy_ctl1_fb =
@@ -736,7 +740,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
736 740
737 /* Link quality statistics */ 741 /* Link quality statistics */
738 switch (chanstat & B43_RX_CHAN_PHYTYPE) { 742 switch (chanstat & B43_RX_CHAN_PHYTYPE) {
743 case B43_PHYTYPE_HT:
744 /* TODO: is max the right choice? */
745 status.signal = max_t(__s8,
746 max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1),
747 rxhdr->phy_ht_power2);
748 break;
739 case B43_PHYTYPE_N: 749 case B43_PHYTYPE_N:
750 /* Broadcom has code for min and avg, but always uses max */
740 if (rxhdr->power0 == 16 || rxhdr->power0 == 32) 751 if (rxhdr->power0 == 16 || rxhdr->power0 == 32)
741 status.signal = max(rxhdr->power1, rxhdr->power2); 752 status.signal = max(rxhdr->power1, rxhdr->power2);
742 else 753 else
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 16c514d54afa..98d90747836a 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -249,6 +249,12 @@ struct b43_rxhdr_fw4 {
249 } __packed; 249 } __packed;
250 } __packed; 250 } __packed;
251 union { 251 union {
252 /* HT-PHY */
253 struct {
254 PAD_BYTES(1);
255 __s8 phy_ht_power0;
256 } __packed;
257
252 /* RSSI for N-PHYs */ 258 /* RSSI for N-PHYs */
253 struct { 259 struct {
254 __s8 power2; 260 __s8 power2;
@@ -257,7 +263,15 @@ struct b43_rxhdr_fw4 {
257 263
258 __le16 phy_status2; /* PHY RX Status 2 */ 264 __le16 phy_status2; /* PHY RX Status 2 */
259 } __packed; 265 } __packed;
260 __le16 phy_status3; /* PHY RX Status 3 */ 266 union {
267 /* HT-PHY */
268 struct {
269 __s8 phy_ht_power1;
270 __s8 phy_ht_power2;
271 } __packed;
272
273 __le16 phy_status3; /* PHY RX Status 3 */
274 } __packed;
261 union { 275 union {
262 /* Tested with 598.314, 644.1001 and 666.2 */ 276 /* Tested with 598.314, 644.1001 and 666.2 */
263 struct { 277 struct {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index b56a30297c26..6ebec8f42846 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t)
358 358
359static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) 359static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
360{ 360{
361 uint dmactrlflags = di->dma.dmactrlflags; 361 uint dmactrlflags;
362 362
363 if (di == NULL) { 363 if (di == NULL) {
364 DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name)); 364 DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
365 return 0; 365 return 0;
366 } 366 }
367 367
368 dmactrlflags = di->dma.dmactrlflags;
368 dmactrlflags &= ~mask; 369 dmactrlflags &= ~mask;
369 dmactrlflags |= flags; 370 dmactrlflags |= flags;
370 371
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index e12b48c2cff6..dd008b0e6417 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -191,6 +191,7 @@ static struct iwl_base_params iwl1000_base_params = {
191 .chain_noise_scale = 1000, 191 .chain_noise_scale = 1000,
192 .wd_timeout = IWL_DEF_WD_TIMEOUT, 192 .wd_timeout = IWL_DEF_WD_TIMEOUT,
193 .max_event_log_size = 128, 193 .max_event_log_size = 128,
194 .wd_disable = true,
194}; 195};
195static struct iwl_ht_params iwl1000_ht_params = { 196static struct iwl_ht_params iwl1000_ht_params = {
196 .ht_greenfield_support = true, 197 .ht_greenfield_support = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index c511c98a89a8..f55fb2d1af52 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -364,6 +364,7 @@ static struct iwl_base_params iwl5000_base_params = {
364 .wd_timeout = IWL_LONG_WD_TIMEOUT, 364 .wd_timeout = IWL_LONG_WD_TIMEOUT,
365 .max_event_log_size = 512, 365 .max_event_log_size = 512,
366 .no_idle_support = true, 366 .no_idle_support = true,
367 .wd_disable = true,
367}; 368};
368static struct iwl_ht_params iwl5000_ht_params = { 369static struct iwl_ht_params iwl5000_ht_params = {
369 .ht_greenfield_support = true, 370 .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 58a381c01c89..a7a6def40d05 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -528,6 +528,24 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
528 return 0; 528 return 0;
529} 529}
530 530
531void iwlagn_config_ht40(struct ieee80211_conf *conf,
532 struct iwl_rxon_context *ctx)
533{
534 if (conf_is_ht40_minus(conf)) {
535 ctx->ht.extension_chan_offset =
536 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
537 ctx->ht.is_40mhz = true;
538 } else if (conf_is_ht40_plus(conf)) {
539 ctx->ht.extension_chan_offset =
540 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
541 ctx->ht.is_40mhz = true;
542 } else {
543 ctx->ht.extension_chan_offset =
544 IEEE80211_HT_PARAM_CHA_SEC_NONE;
545 ctx->ht.is_40mhz = false;
546 }
547}
548
531int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) 549int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
532{ 550{
533 struct iwl_priv *priv = hw->priv; 551 struct iwl_priv *priv = hw->priv;
@@ -586,19 +604,11 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
586 ctx->ht.enabled = conf_is_ht(conf); 604 ctx->ht.enabled = conf_is_ht(conf);
587 605
588 if (ctx->ht.enabled) { 606 if (ctx->ht.enabled) {
589 if (conf_is_ht40_minus(conf)) { 607 /* if HT40 is used, it should not change
590 ctx->ht.extension_chan_offset = 608 * after associated except channel switch */
591 IEEE80211_HT_PARAM_CHA_SEC_BELOW; 609 if (iwl_is_associated_ctx(ctx) &&
592 ctx->ht.is_40mhz = true; 610 !ctx->ht.is_40mhz)
593 } else if (conf_is_ht40_plus(conf)) { 611 iwlagn_config_ht40(conf, ctx);
594 ctx->ht.extension_chan_offset =
595 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
596 ctx->ht.is_40mhz = true;
597 } else {
598 ctx->ht.extension_chan_offset =
599 IEEE80211_HT_PARAM_CHA_SEC_NONE;
600 ctx->ht.is_40mhz = false;
601 }
602 } else 612 } else
603 ctx->ht.is_40mhz = false; 613 ctx->ht.is_40mhz = false;
604 614
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index ed6283623932..4b2aa1da0953 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -1268,9 +1268,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
1268 1268
1269 switch (keyconf->cipher) { 1269 switch (keyconf->cipher) {
1270 case WLAN_CIPHER_SUITE_TKIP: 1270 case WLAN_CIPHER_SUITE_TKIP:
1271 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1272 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1273
1274 if (sta) 1271 if (sta)
1275 addr = sta->addr; 1272 addr = sta->addr;
1276 else /* station mode case only */ 1273 else /* station mode case only */
@@ -1283,8 +1280,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
1283 seq.tkip.iv32, p1k, CMD_SYNC); 1280 seq.tkip.iv32, p1k, CMD_SYNC);
1284 break; 1281 break;
1285 case WLAN_CIPHER_SUITE_CCMP: 1282 case WLAN_CIPHER_SUITE_CCMP:
1286 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1287 /* fall through */
1288 case WLAN_CIPHER_SUITE_WEP40: 1283 case WLAN_CIPHER_SUITE_WEP40:
1289 case WLAN_CIPHER_SUITE_WEP104: 1284 case WLAN_CIPHER_SUITE_WEP104:
1290 ret = iwlagn_send_sta_key(priv, keyconf, sta_id, 1285 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 ccba69b7f8a7..bacc06c95e7a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2316,6 +2316,17 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2316 return -EOPNOTSUPP; 2316 return -EOPNOTSUPP;
2317 } 2317 }
2318 2318
2319 switch (key->cipher) {
2320 case WLAN_CIPHER_SUITE_TKIP:
2321 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
2322 /* fall through */
2323 case WLAN_CIPHER_SUITE_CCMP:
2324 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
2325 break;
2326 default:
2327 break;
2328 }
2329
2319 /* 2330 /*
2320 * We could program these keys into the hardware as well, but we 2331 * We could program these keys into the hardware as well, but we
2321 * don't expect much multicast traffic in IBSS and having keys 2332 * don't expect much multicast traffic in IBSS and having keys
@@ -2599,21 +2610,9 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
2599 2610
2600 /* Configure HT40 channels */ 2611 /* Configure HT40 channels */
2601 ctx->ht.enabled = conf_is_ht(conf); 2612 ctx->ht.enabled = conf_is_ht(conf);
2602 if (ctx->ht.enabled) { 2613 if (ctx->ht.enabled)
2603 if (conf_is_ht40_minus(conf)) { 2614 iwlagn_config_ht40(conf, ctx);
2604 ctx->ht.extension_chan_offset = 2615 else
2605 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
2606 ctx->ht.is_40mhz = true;
2607 } else if (conf_is_ht40_plus(conf)) {
2608 ctx->ht.extension_chan_offset =
2609 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
2610 ctx->ht.is_40mhz = true;
2611 } else {
2612 ctx->ht.extension_chan_offset =
2613 IEEE80211_HT_PARAM_CHA_SEC_NONE;
2614 ctx->ht.is_40mhz = false;
2615 }
2616 } else
2617 ctx->ht.is_40mhz = false; 2616 ctx->ht.is_40mhz = false;
2618 2617
2619 if ((le16_to_cpu(ctx->staging.channel) != ch)) 2618 if ((le16_to_cpu(ctx->staging.channel) != ch))
@@ -3499,9 +3498,10 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
3499module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); 3498module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO);
3500MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); 3499MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])");
3501 3500
3502module_param_named(wd_disable, iwlagn_mod_params.wd_disable, bool, S_IRUGO); 3501module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO);
3503MODULE_PARM_DESC(wd_disable, 3502MODULE_PARM_DESC(wd_disable,
3504 "Disable stuck queue watchdog timer (default: 0 [enabled])"); 3503 "Disable stuck queue watchdog timer 0=system default, "
3504 "1=disable, 2=enable (default: 0)");
3505 3505
3506/* 3506/*
3507 * set bt_coex_active to true, uCode will do kill/defer 3507 * 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 5b936ec1a541..3856abaea507 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -86,6 +86,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
86 struct ieee80211_vif *vif, 86 struct ieee80211_vif *vif,
87 struct ieee80211_bss_conf *bss_conf, 87 struct ieee80211_bss_conf *bss_conf,
88 u32 changes); 88 u32 changes);
89void iwlagn_config_ht40(struct ieee80211_conf *conf,
90 struct iwl_rxon_context *ctx);
89 91
90/* uCode */ 92/* uCode */
91int iwlagn_rx_calib_result(struct iwl_priv *priv, 93int 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 001fdf140abb..fcf54160e4ed 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1810,11 +1810,23 @@ void iwl_setup_watchdog(struct iwl_priv *priv)
1810{ 1810{
1811 unsigned int timeout = priv->cfg->base_params->wd_timeout; 1811 unsigned int timeout = priv->cfg->base_params->wd_timeout;
1812 1812
1813 if (timeout && !iwlagn_mod_params.wd_disable) 1813 if (!iwlagn_mod_params.wd_disable) {
1814 mod_timer(&priv->watchdog, 1814 /* use system default */
1815 jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); 1815 if (timeout && !priv->cfg->base_params->wd_disable)
1816 else 1816 mod_timer(&priv->watchdog,
1817 del_timer(&priv->watchdog); 1817 jiffies +
1818 msecs_to_jiffies(IWL_WD_TICK(timeout)));
1819 else
1820 del_timer(&priv->watchdog);
1821 } else {
1822 /* module parameter overwrite default configuration */
1823 if (timeout && iwlagn_mod_params.wd_disable == 2)
1824 mod_timer(&priv->watchdog,
1825 jiffies +
1826 msecs_to_jiffies(IWL_WD_TICK(timeout)));
1827 else
1828 del_timer(&priv->watchdog);
1829 }
1818} 1830}
1819 1831
1820/** 1832/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 137da3380704..f2fc288f3dd3 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 */
117struct iwl_base_params { 118struct 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 1f7a93c67c45..14eaf37ce3b1 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 da3411057afc..ce918980e977 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
993static void iwl_trans_pcie_disable_sync_irq(struct iwl_trans *trans) 993static 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
1008static 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
1044static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, 1045static 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 4fcd653bddc4..a7f1ab28940d 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -634,7 +634,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
634 if (channel && 634 if (channel &&
635 !(channel->flags & IEEE80211_CHAN_DISABLED)) 635 !(channel->flags & IEEE80211_CHAN_DISABLED))
636 cfg80211_inform_bss(wiphy, channel, 636 cfg80211_inform_bss(wiphy, channel,
637 bssid, le64_to_cpu(*(__le64 *)tsfdesc), 637 bssid, get_unaligned_le64(tsfdesc),
638 capa, intvl, ie, ielen, 638 capa, intvl, ie, ielen,
639 LBS_SCAN_RSSI_TO_MBM(rssi), 639 LBS_SCAN_RSSI_TO_MBM(rssi),
640 GFP_KERNEL); 640 GFP_KERNEL);
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 622ae6de0d8b..7059d9645dab 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 dae8dbb24a03..8d3ab378662b 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,
@@ -1469,7 +1471,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
1469 s32 rssi, const u8 *ie_buf, size_t ie_len, 1471 s32 rssi, const u8 *ie_buf, size_t ie_len,
1470 u16 beacon_period, u16 cap_info_bitmap, u8 band) 1472 u16 beacon_period, u16 cap_info_bitmap, u8 band)
1471{ 1473{
1472 struct mwifiex_bssdescriptor *bss_desc = NULL; 1474 struct mwifiex_bssdescriptor *bss_desc;
1473 int ret; 1475 int ret;
1474 unsigned long flags; 1476 unsigned long flags;
1475 u8 *beacon_ie; 1477 u8 *beacon_ie;
@@ -1484,6 +1486,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
1484 1486
1485 beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL); 1487 beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL);
1486 if (!beacon_ie) { 1488 if (!beacon_ie) {
1489 kfree(bss_desc);
1487 dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); 1490 dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
1488 return -ENOMEM; 1491 return -ENOMEM;
1489 } 1492 }
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index f18df82eeb92..78d0d6988553 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -588,8 +588,6 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
588 588
589 WARN_ON(priv->fw_state != FW_STATE_READY); 589 WARN_ON(priv->fw_state != FW_STATE_READY);
590 590
591 cancel_work_sync(&priv->work);
592
593 p54spi_power_off(priv); 591 p54spi_power_off(priv);
594 spin_lock_irqsave(&priv->tx_lock, flags); 592 spin_lock_irqsave(&priv->tx_lock, flags);
595 INIT_LIST_HEAD(&priv->tx_pending); 593 INIT_LIST_HEAD(&priv->tx_pending);
@@ -597,6 +595,8 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
597 595
598 priv->fw_state = FW_STATE_OFF; 596 priv->fw_state = FW_STATE_OFF;
599 mutex_unlock(&priv->mutex); 597 mutex_unlock(&priv->mutex);
598
599 cancel_work_sync(&priv->work);
600} 600}
601 601
602static int __devinit p54spi_probe(struct spi_device *spi) 602static int __devinit p54spi_probe(struct spi_device *spi)
@@ -656,6 +656,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)
656 init_completion(&priv->fw_comp); 656 init_completion(&priv->fw_comp);
657 INIT_LIST_HEAD(&priv->tx_pending); 657 INIT_LIST_HEAD(&priv->tx_pending);
658 mutex_init(&priv->mutex); 658 mutex_init(&priv->mutex);
659 spin_lock_init(&priv->tx_lock);
659 SET_IEEE80211_DEV(hw, &spi->dev); 660 SET_IEEE80211_DEV(hw, &spi->dev);
660 priv->common.open = p54spi_op_start; 661 priv->common.open = p54spi_op_start;
661 priv->common.stop = p54spi_op_stop; 662 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 d97a2caf582b..bc2ba80c47bb 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 3f183a15186e..1ba079dffb11 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -3771,7 +3771,7 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i)
3771 /* Apparently the data is read from end to start */ 3771 /* Apparently the data is read from end to start */
3772 rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, &reg); 3772 rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, &reg);
3773 /* The returned value is in CPU order, but eeprom is le */ 3773 /* The returned value is in CPU order, but eeprom is le */
3774 rt2x00dev->eeprom[i] = cpu_to_le32(reg); 3774 *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg);
3775 rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, &reg); 3775 rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, &reg);
3776 *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); 3776 *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg);
3777 rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, &reg); 3777 rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, &reg);
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
468static 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
468static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, 485static 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
519static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, 535static 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 a693feffbe72..0b04b2e7b597 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -394,7 +394,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
394 if (mac->link_state != MAC80211_LINKED) 394 if (mac->link_state != MAC80211_LINKED)
395 return; 395 return;
396 396
397 spin_lock(&rtlpriv->locks.lps_lock); 397 spin_lock_irq(&rtlpriv->locks.lps_lock);
398 398
399 /* Idle for a while if we connect to AP a while ago. */ 399 /* Idle for a while if we connect to AP a while ago. */
400 if (mac->cnt_after_linked >= 2) { 400 if (mac->cnt_after_linked >= 2) {
@@ -406,7 +406,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
406 } 406 }
407 } 407 }
408 408
409 spin_unlock(&rtlpriv->locks.lps_lock); 409 spin_unlock_irq(&rtlpriv->locks.lps_lock);
410} 410}
411 411
412/*Leave the leisure power save mode.*/ 412/*Leave the leisure power save mode.*/
@@ -415,8 +415,9 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
415 struct rtl_priv *rtlpriv = rtl_priv(hw); 415 struct rtl_priv *rtlpriv = rtl_priv(hw);
416 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 416 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
417 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 417 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
418 unsigned long flags;
418 419
419 spin_lock(&rtlpriv->locks.lps_lock); 420 spin_lock_irqsave(&rtlpriv->locks.lps_lock, flags);
420 421
421 if (ppsc->fwctrl_lps) { 422 if (ppsc->fwctrl_lps) {
422 if (ppsc->dot11_psmode != EACTIVE) { 423 if (ppsc->dot11_psmode != EACTIVE) {
@@ -437,7 +438,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
437 rtl_lps_set_psmode(hw, EACTIVE); 438 rtl_lps_set_psmode(hw, EACTIVE);
438 } 439 }
439 } 440 }
440 spin_unlock(&rtlpriv->locks.lps_lock); 441 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flags);
441} 442}
442 443
443/* For sw LPS*/ 444/* For sw LPS*/
@@ -538,9 +539,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
538 RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); 539 RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
539 } 540 }
540 541
541 spin_lock(&rtlpriv->locks.lps_lock); 542 spin_lock_irq(&rtlpriv->locks.lps_lock);
542 rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); 543 rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS);
543 spin_unlock(&rtlpriv->locks.lps_lock); 544 spin_unlock_irq(&rtlpriv->locks.lps_lock);
544} 545}
545 546
546void rtl_swlps_rfon_wq_callback(void *data) 547void rtl_swlps_rfon_wq_callback(void *data)
@@ -573,9 +574,9 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
573 if (rtlpriv->link_info.busytraffic) 574 if (rtlpriv->link_info.busytraffic)
574 return; 575 return;
575 576
576 spin_lock(&rtlpriv->locks.lps_lock); 577 spin_lock_irq(&rtlpriv->locks.lps_lock);
577 rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); 578 rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS);
578 spin_unlock(&rtlpriv->locks.lps_lock); 579 spin_unlock_irq(&rtlpriv->locks.lps_lock);
579 580
580 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && 581 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
581 !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { 582 !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
index 128ccb79318c..fc29c671cf3b 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -559,7 +559,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
559 break; 559 break;
560 } 560 }
561 /* Fail if SSID isn't present in the filters */ 561 /* Fail if SSID isn't present in the filters */
562 if (j == req->n_ssids) { 562 if (j == cmd->n_ssids) {
563 ret = -EINVAL; 563 ret = -EINVAL;
564 goto out_free; 564 goto out_free;
565 } 565 }
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 92cf1c2c30c9..95852e36713b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -456,6 +456,9 @@ enum station_parameters_apply_mask {
456 * as the AC bitmap in the QoS info field 456 * as the AC bitmap in the QoS info field
457 * @max_sp: max Service Period. same format as the MAX_SP in the 457 * @max_sp: max Service Period. same format as the MAX_SP in the
458 * QoS info field (but already shifted down) 458 * QoS info field (but already shifted down)
459 * @sta_modify_mask: bitmap indicating which parameters changed
460 * (for those that don't have a natural "no change" value),
461 * see &enum station_parameters_apply_mask
459 */ 462 */
460struct station_parameters { 463struct station_parameters {
461 u8 *supported_rates; 464 u8 *supported_rates;
@@ -615,6 +618,7 @@ struct sta_bss_parameters {
615 * user space MLME/SME implementation. The information is provided for 618 * user space MLME/SME implementation. The information is provided for
616 * the cfg80211_new_sta() calls to notify user space of the IEs. 619 * the cfg80211_new_sta() calls to notify user space of the IEs.
617 * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets. 620 * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
621 * @sta_flags: station flags mask & values
618 */ 622 */
619struct station_info { 623struct station_info {
620 u32 filled; 624 u32 filled;
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dc1123aa8181..72eddd1b410b 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3567,8 +3567,9 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
3567 return i; 3567 return i;
3568 3568
3569 /* warn when we cannot find a rate. */ 3569 /* warn when we cannot find a rate. */
3570 WARN_ON(1); 3570 WARN_ON_ONCE(1);
3571 3571
3572 /* and return 0 (the lowest index) */
3572 return 0; 3573 return 0;
3573} 3574}
3574 3575
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 2ac033989e01..331472ce038c 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -160,6 +160,12 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
160 return -ENOENT; 160 return -ENOENT;
161 } 161 }
162 162
163 /* if we're already stopping ignore any new requests to stop */
164 if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
165 spin_unlock_bh(&sta->lock);
166 return -EALREADY;
167 }
168
163 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { 169 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
164 /* not even started yet! */ 170 /* not even started yet! */
165 ieee80211_assign_tid_tx(sta, tid, NULL); 171 ieee80211_assign_tid_tx(sta, tid, NULL);
@@ -168,6 +174,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
168 return 0; 174 return 0;
169 } 175 }
170 176
177 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
178
171 spin_unlock_bh(&sta->lock); 179 spin_unlock_bh(&sta->lock);
172 180
173#ifdef CONFIG_MAC80211_HT_DEBUG 181#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -175,8 +183,6 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
175 sta->sta.addr, tid); 183 sta->sta.addr, tid);
176#endif /* CONFIG_MAC80211_HT_DEBUG */ 184#endif /* CONFIG_MAC80211_HT_DEBUG */
177 185
178 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
179
180 del_timer_sync(&tid_tx->addba_resp_timer); 186 del_timer_sync(&tid_tx->addba_resp_timer);
181 187
182 /* 188 /*
@@ -186,6 +192,20 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
186 */ 192 */
187 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); 193 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
188 194
195 /*
196 * There might be a few packets being processed right now (on
197 * another CPU) that have already gotten past the aggregation
198 * check when it was still OPERATIONAL and consequently have
199 * IEEE80211_TX_CTL_AMPDU set. In that case, this code might
200 * call into the driver at the same time or even before the
201 * TX paths calls into it, which could confuse the driver.
202 *
203 * Wait for all currently running TX paths to finish before
204 * telling the driver. New packets will not go through since
205 * the aggregation session is no longer OPERATIONAL.
206 */
207 synchronize_net();
208
189 tid_tx->stop_initiator = initiator; 209 tid_tx->stop_initiator = initiator;
190 tid_tx->tx_stop = tx; 210 tid_tx->tx_stop = tx;
191 211
@@ -756,11 +776,27 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
756 goto out; 776 goto out;
757 } 777 }
758 778
759 del_timer(&tid_tx->addba_resp_timer); 779 del_timer_sync(&tid_tx->addba_resp_timer);
760 780
761#ifdef CONFIG_MAC80211_HT_DEBUG 781#ifdef CONFIG_MAC80211_HT_DEBUG
762 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid); 782 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
763#endif 783#endif
784
785 /*
786 * addba_resp_timer may have fired before we got here, and
787 * caused WANT_STOP to be set. If the stop then was already
788 * processed further, STOPPING might be set.
789 */
790 if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) ||
791 test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
792#ifdef CONFIG_MAC80211_HT_DEBUG
793 printk(KERN_DEBUG
794 "got addBA resp for tid %d but we already gave up\n",
795 tid);
796#endif
797 goto out;
798 }
799
764 /* 800 /*
765 * IEEE 802.11-2007 7.3.1.14: 801 * IEEE 802.11-2007 7.3.1.14:
766 * In an ADDBA Response frame, when the Status Code field 802 * 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 c5f341798c16..3110cbdc501b 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 d999bf3b84e1..cae443563ec9 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -757,6 +757,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
757 if (!local->int_scan_req) 757 if (!local->int_scan_req)
758 return -ENOMEM; 758 return -ENOMEM;
759 759
760 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
761 if (!local->hw.wiphy->bands[band])
762 continue;
763 local->int_scan_req->rates[band] = (u32) -1;
764 }
765
760 /* if low-level driver supports AP, we also support VLAN */ 766 /* if low-level driver supports AP, we also support VLAN */
761 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { 767 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
762 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); 768 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 17258feaab9b..40db011da580 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1485,6 +1485,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1485 int i, j, err; 1485 int i, j, err;
1486 bool have_higher_than_11mbit = false; 1486 bool have_higher_than_11mbit = false;
1487 u16 ap_ht_cap_flags; 1487 u16 ap_ht_cap_flags;
1488 int min_rate = INT_MAX, min_rate_index = -1;
1488 1489
1489 /* AssocResp and ReassocResp have identical structure */ 1490 /* AssocResp and ReassocResp have identical structure */
1490 1491
@@ -1551,6 +1552,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1551 rates |= BIT(j); 1552 rates |= BIT(j);
1552 if (is_basic) 1553 if (is_basic)
1553 basic_rates |= BIT(j); 1554 basic_rates |= BIT(j);
1555 if (rate < min_rate) {
1556 min_rate = rate;
1557 min_rate_index = j;
1558 }
1554 break; 1559 break;
1555 } 1560 }
1556 } 1561 }
@@ -1568,11 +1573,25 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1568 rates |= BIT(j); 1573 rates |= BIT(j);
1569 if (is_basic) 1574 if (is_basic)
1570 basic_rates |= BIT(j); 1575 basic_rates |= BIT(j);
1576 if (rate < min_rate) {
1577 min_rate = rate;
1578 min_rate_index = j;
1579 }
1571 break; 1580 break;
1572 } 1581 }
1573 } 1582 }
1574 } 1583 }
1575 1584
1585 /*
1586 * some buggy APs don't advertise basic_rates. use the lowest
1587 * supported rate instead.
1588 */
1589 if (unlikely(!basic_rates) && min_rate_index >= 0) {
1590 printk(KERN_DEBUG "%s: No basic rates in AssocResp. "
1591 "Using min supported rate instead.\n", sdata->name);
1592 basic_rates = BIT(min_rate_index);
1593 }
1594
1576 sta->sta.supp_rates[wk->chan->band] = rates; 1595 sta->sta.supp_rates[wk->chan->band] = rates;
1577 sdata->vif.bss_conf.basic_rates = basic_rates; 1596 sdata->vif.bss_conf.basic_rates = basic_rates;
1578 1597
@@ -2267,6 +2286,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
2267 2286
2268 cancel_work_sync(&ifmgd->request_smps_work); 2287 cancel_work_sync(&ifmgd->request_smps_work);
2269 2288
2289 cancel_work_sync(&ifmgd->monitor_work);
2270 cancel_work_sync(&ifmgd->beacon_connection_loss_work); 2290 cancel_work_sync(&ifmgd->beacon_connection_loss_work);
2271 if (del_timer_sync(&ifmgd->timer)) 2291 if (del_timer_sync(&ifmgd->timer))
2272 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); 2292 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
@@ -2275,7 +2295,6 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
2275 if (del_timer_sync(&ifmgd->chswitch_timer)) 2295 if (del_timer_sync(&ifmgd->chswitch_timer))
2276 set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); 2296 set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
2277 2297
2278 cancel_work_sync(&ifmgd->monitor_work);
2279 /* these will just be re-established on connection */ 2298 /* these will just be re-established on connection */
2280 del_timer_sync(&ifmgd->conn_mon_timer); 2299 del_timer_sync(&ifmgd->conn_mon_timer);
2281 del_timer_sync(&ifmgd->bcn_mon_timer); 2300 del_timer_sync(&ifmgd->bcn_mon_timer);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b867bd55de7a..097b42d286e2 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -140,8 +140,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
140 pos++; 140 pos++;
141 141
142 /* IEEE80211_RADIOTAP_RATE */ 142 /* IEEE80211_RADIOTAP_RATE */
143 if (status->flag & RX_FLAG_HT) { 143 if (!rate || status->flag & RX_FLAG_HT) {
144 /* 144 /*
145 * Without rate information don't add it. If we have,
145 * MCS information is a separate field in radiotap, 146 * MCS information is a separate field in radiotap,
146 * added below. The byte here is needed as padding 147 * added below. The byte here is needed as padding
147 * for the channel though, so initialise it to 0. 148 * for the channel though, so initialise it to 0.
@@ -162,12 +163,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
162 else if (status->flag & RX_FLAG_HT) 163 else if (status->flag & RX_FLAG_HT)
163 put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, 164 put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
164 pos); 165 pos);
165 else if (rate->flags & IEEE80211_RATE_ERP_G) 166 else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
166 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, 167 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
167 pos); 168 pos);
168 else 169 else if (rate)
169 put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, 170 put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
170 pos); 171 pos);
172 else
173 put_unaligned_le16(IEEE80211_CHAN_2GHZ, pos);
171 pos += 2; 174 pos += 2;
172 175
173 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ 176 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index ce962d2c8782..8eaa746ec7a2 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1354,12 +1354,12 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
1354 * Use MoreData flag to indicate whether there are 1354 * Use MoreData flag to indicate whether there are
1355 * more buffered frames for this STA 1355 * more buffered frames for this STA
1356 */ 1356 */
1357 if (!more_data) 1357 if (more_data || !skb_queue_empty(&frames))
1358 hdr->frame_control &=
1359 cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
1360 else
1361 hdr->frame_control |= 1358 hdr->frame_control |=
1362 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1359 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1360 else
1361 hdr->frame_control &=
1362 cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
1363 1363
1364 if (ieee80211_is_data_qos(hdr->frame_control) || 1364 if (ieee80211_is_data_qos(hdr->frame_control) ||
1365 ieee80211_is_qos_nullfunc(hdr->frame_control)) 1365 ieee80211_is_qos_nullfunc(hdr->frame_control))
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index df643cedf9b9..5533a74e9bb3 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -259,7 +259,7 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
259 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 259 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
260 struct ieee80211_radiotap_header *rthdr; 260 struct ieee80211_radiotap_header *rthdr;
261 unsigned char *pos; 261 unsigned char *pos;
262 __le16 txflags; 262 u16 txflags;
263 263
264 rthdr = (struct ieee80211_radiotap_header *) skb_push(skb, rtap_len); 264 rthdr = (struct ieee80211_radiotap_header *) skb_push(skb, rtap_len);
265 265
@@ -289,13 +289,13 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
289 txflags = 0; 289 txflags = 0;
290 if (!(info->flags & IEEE80211_TX_STAT_ACK) && 290 if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
291 !is_multicast_ether_addr(hdr->addr1)) 291 !is_multicast_ether_addr(hdr->addr1))
292 txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); 292 txflags |= IEEE80211_RADIOTAP_F_TX_FAIL;
293 293
294 if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || 294 if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
295 (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) 295 (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
296 txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); 296 txflags |= IEEE80211_RADIOTAP_F_TX_CTS;
297 else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) 297 else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
298 txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); 298 txflags |= IEEE80211_RADIOTAP_F_TX_RTS;
299 299
300 put_unaligned_le16(txflags, pos); 300 put_unaligned_le16(txflags, pos);
301 pos += 2; 301 pos += 2;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7439d26bf5f9..6719bce4a081 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -880,6 +880,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
880 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 880 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
881 ssid, ssid_len, 881 ssid, ssid_len,
882 buf, buf_len); 882 buf, buf_len);
883 if (!skb)
884 goto out;
883 885
884 if (dst) { 886 if (dst) {
885 mgmt = (struct ieee80211_mgmt *) skb->data; 887 mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -888,6 +890,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
888 } 890 }
889 891
890 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 892 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
893
894 out:
891 kfree(buf); 895 kfree(buf);
892 896
893 return skb; 897 return skb;
@@ -1034,7 +1038,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1034 struct ieee80211_sub_if_data, 1038 struct ieee80211_sub_if_data,
1035 u.ap); 1039 u.ap);
1036 1040
1037 memset(&sta->sta.drv_priv, 0, hw->sta_data_size);
1038 WARN_ON(drv_sta_add(local, sdata, &sta->sta)); 1041 WARN_ON(drv_sta_add(local, sdata, &sta->sta));
1039 } 1042 }
1040 } 1043 }
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 48260c2d092a..ffafda5022c2 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,
@@ -132,8 +132,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
132 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, 132 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
133 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, 133 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
134 134
135 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 135 [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
136 .len = NL80211_HT_CAPABILITY_LEN },
137 136
138 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 }, 137 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
139 [NL80211_ATTR_IE] = { .type = NLA_BINARY, 138 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
@@ -1253,6 +1252,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1253 goto bad_res; 1252 goto bad_res;
1254 } 1253 }
1255 1254
1255 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1256 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
1257 result = -EINVAL;
1258 goto bad_res;
1259 }
1260
1256 nla_for_each_nested(nl_txq_params, 1261 nla_for_each_nested(nl_txq_params,
1257 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], 1262 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
1258 rem_txq_params) { 1263 rem_txq_params) {
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 2520a1b7e7db..074c1122ce42 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -55,8 +55,17 @@
55#define REG_DBG_PRINT(args...) 55#define REG_DBG_PRINT(args...)
56#endif 56#endif
57 57
58static struct regulatory_request core_request_world = {
59 .initiator = NL80211_REGDOM_SET_BY_CORE,
60 .alpha2[0] = '0',
61 .alpha2[1] = '0',
62 .intersect = false,
63 .processed = true,
64 .country_ie_env = ENVIRON_ANY,
65};
66
58/* Receipt of information from last regulatory request */ 67/* Receipt of information from last regulatory request */
59static struct regulatory_request *last_request; 68static struct regulatory_request *last_request = &core_request_world;
60 69
61/* To trigger userspace events */ 70/* To trigger userspace events */
62static struct platform_device *reg_pdev; 71static struct platform_device *reg_pdev;
@@ -148,7 +157,7 @@ static char user_alpha2[2];
148module_param(ieee80211_regdom, charp, 0444); 157module_param(ieee80211_regdom, charp, 0444);
149MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 158MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
150 159
151static void reset_regdomains(void) 160static void reset_regdomains(bool full_reset)
152{ 161{
153 /* avoid freeing static information or freeing something twice */ 162 /* avoid freeing static information or freeing something twice */
154 if (cfg80211_regdomain == cfg80211_world_regdom) 163 if (cfg80211_regdomain == cfg80211_world_regdom)
@@ -163,6 +172,13 @@ static void reset_regdomains(void)
163 172
164 cfg80211_world_regdom = &world_regdom; 173 cfg80211_world_regdom = &world_regdom;
165 cfg80211_regdomain = NULL; 174 cfg80211_regdomain = NULL;
175
176 if (!full_reset)
177 return;
178
179 if (last_request != &core_request_world)
180 kfree(last_request);
181 last_request = &core_request_world;
166} 182}
167 183
168/* 184/*
@@ -173,7 +189,7 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd)
173{ 189{
174 BUG_ON(!last_request); 190 BUG_ON(!last_request);
175 191
176 reset_regdomains(); 192 reset_regdomains(false);
177 193
178 cfg80211_world_regdom = rd; 194 cfg80211_world_regdom = rd;
179 cfg80211_regdomain = rd; 195 cfg80211_regdomain = rd;
@@ -1405,7 +1421,8 @@ static int __regulatory_hint(struct wiphy *wiphy,
1405 } 1421 }
1406 1422
1407new_request: 1423new_request:
1408 kfree(last_request); 1424 if (last_request != &core_request_world)
1425 kfree(last_request);
1409 1426
1410 last_request = pending_request; 1427 last_request = pending_request;
1411 last_request->intersect = intersect; 1428 last_request->intersect = intersect;
@@ -1575,9 +1592,6 @@ static int regulatory_hint_core(const char *alpha2)
1575{ 1592{
1576 struct regulatory_request *request; 1593 struct regulatory_request *request;
1577 1594
1578 kfree(last_request);
1579 last_request = NULL;
1580
1581 request = kzalloc(sizeof(struct regulatory_request), 1595 request = kzalloc(sizeof(struct regulatory_request),
1582 GFP_KERNEL); 1596 GFP_KERNEL);
1583 if (!request) 1597 if (!request)
@@ -1775,7 +1789,7 @@ static void restore_regulatory_settings(bool reset_user)
1775 mutex_lock(&cfg80211_mutex); 1789 mutex_lock(&cfg80211_mutex);
1776 mutex_lock(&reg_mutex); 1790 mutex_lock(&reg_mutex);
1777 1791
1778 reset_regdomains(); 1792 reset_regdomains(true);
1779 restore_alpha2(alpha2, reset_user); 1793 restore_alpha2(alpha2, reset_user);
1780 1794
1781 /* 1795 /*
@@ -2035,12 +2049,18 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2035 } 2049 }
2036 2050
2037 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 2051 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
2052 if (!request_wiphy &&
2053 (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
2054 last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) {
2055 schedule_delayed_work(&reg_timeout, 0);
2056 return -ENODEV;
2057 }
2038 2058
2039 if (!last_request->intersect) { 2059 if (!last_request->intersect) {
2040 int r; 2060 int r;
2041 2061
2042 if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { 2062 if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) {
2043 reset_regdomains(); 2063 reset_regdomains(false);
2044 cfg80211_regdomain = rd; 2064 cfg80211_regdomain = rd;
2045 return 0; 2065 return 0;
2046 } 2066 }
@@ -2061,7 +2081,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2061 if (r) 2081 if (r)
2062 return r; 2082 return r;
2063 2083
2064 reset_regdomains(); 2084 reset_regdomains(false);
2065 cfg80211_regdomain = rd; 2085 cfg80211_regdomain = rd;
2066 return 0; 2086 return 0;
2067 } 2087 }
@@ -2086,7 +2106,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2086 2106
2087 rd = NULL; 2107 rd = NULL;
2088 2108
2089 reset_regdomains(); 2109 reset_regdomains(false);
2090 cfg80211_regdomain = intersected_rd; 2110 cfg80211_regdomain = intersected_rd;
2091 2111
2092 return 0; 2112 return 0;
@@ -2106,7 +2126,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2106 kfree(rd); 2126 kfree(rd);
2107 rd = NULL; 2127 rd = NULL;
2108 2128
2109 reset_regdomains(); 2129 reset_regdomains(false);
2110 cfg80211_regdomain = intersected_rd; 2130 cfg80211_regdomain = intersected_rd;
2111 2131
2112 return 0; 2132 return 0;
@@ -2259,9 +2279,9 @@ void /* __init_or_exit */ regulatory_exit(void)
2259 mutex_lock(&cfg80211_mutex); 2279 mutex_lock(&cfg80211_mutex);
2260 mutex_lock(&reg_mutex); 2280 mutex_lock(&reg_mutex);
2261 2281
2262 reset_regdomains(); 2282 reset_regdomains(true);
2263 2283
2264 kfree(last_request); 2284 dev_set_uevent_suppress(&reg_pdev->dev, true);
2265 2285
2266 platform_device_unregister(reg_pdev); 2286 platform_device_unregister(reg_pdev);
2267 2287
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 0fb142410404..dc23b31594e0 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -259,17 +259,20 @@ static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
259{ 259{
260 const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); 260 const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
261 const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); 261 const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
262 int r;
263 262
263 /* equal if both missing */
264 if (!ie1 && !ie2) 264 if (!ie1 && !ie2)
265 return 0; 265 return 0;
266 if (!ie1 || !ie2) 266 /* sort missing IE before (left of) present IE */
267 if (!ie1)
267 return -1; 268 return -1;
269 if (!ie2)
270 return 1;
268 271
269 r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1])); 272 /* sort by length first, then by contents */
270 if (r == 0 && ie1[1] != ie2[1]) 273 if (ie1[1] != ie2[1])
271 return ie2[1] - ie1[1]; 274 return ie2[1] - ie1[1];
272 return r; 275 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
273} 276}
274 277
275static bool is_bss(struct cfg80211_bss *a, 278static bool is_bss(struct cfg80211_bss *a,