aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-06-06 16:18:40 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-06 16:30:02 -0400
commitda2e852612967a53d17de930929574444a67fb52 (patch)
tree699fe0a30f7d5579ec4322fb6299c4cb56eb6457
parent55432d2b543a4b6dfae54f5c432a566877a85d90 (diff)
parent4e924fec591ef75076eab95954d90411862d3a87 (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
John Linville says: ==================== Amitkumar Karwar gives us a cfg80211 fix that changes some state tracking in order to avoid a WARNING. Arik Nemtsov provide a mac80211 fix for an RCU-related race. Avinash Patil shares a pair of mwifiex fixes, one which invalidates some stale configuration data before a channel change and another to restrict hidden SSID support to zero-length SSIDs only. Chun-Yeow Yeoh brings a mac80211 fix for a mesh problem triggered when combining multiple mesh networks into one. Felix Fietkau provides a mac80211 lockdep fix. Joe Perches fixes a couple of thinkos related to bitwise operations. Johannes Berg comes through with a flurry of fixes. The iwlwifi ones address a problem Linus recently reported, and some of the fallout discovered while fixing it. The mac80211 fix properly cleans-up remain-on-channel work on an interface that is stopped. The others are clean-ups for regressions caused by stricter checking of possible virtual interfaces supported by wireless drivers. Meenakshi Venkataraman provides a mac80211 fix for an off-by-one error. Seth Forshee provides a fix to make the wireless adapters used in some Mac boxes work after being in S3 power saving state. Stanislaw Gruszka offers a copule of fixes, a fix for a mac80211 scanning regression and an rt2x00 fix to avoid some lockdep spew. Last but not least, Vinicius Costa Gomes provides a bluetooth fix for a typo that "was preventing important features of Bluetooth from working". ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c4
-rw-r--r--drivers/bcma/sprom.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-mac80211.c3
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c21
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c13
-rw-r--r--drivers/net/wireless/mwifiex/fw.h6
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c13
-rw-r--r--net/bluetooth/af_bluetooth.c2
-rw-r--r--net/mac80211/agg-rx.c7
-rw-r--r--net/mac80211/cfg.c6
-rw-r--r--net/mac80211/iface.c12
-rw-r--r--net/mac80211/mlme.c36
-rw-r--r--net/mac80211/offchannel.c16
-rw-r--r--net/mac80211/sta_info.c4
-rw-r--r--net/mac80211/tx.c9
-rw-r--r--net/mac80211/util.c2
-rw-r--r--net/wireless/ibss.c6
-rw-r--r--net/wireless/util.c19
24 files changed, 180 insertions, 48 deletions
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index a058842f14fd..61ce4054b3c3 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -139,7 +139,9 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
139 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7); 139 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
140 break; 140 break;
141 case 0x4331: 141 case 0x4331:
142 /* BCM4331 workaround is SPROM-related, we put it in sprom.c */ 142 case 43431:
143 /* Ext PA lines must be enabled for tx on BCM4331 */
144 bcma_chipco_bcm4331_ext_pa_lines_ctl(cc, true);
143 break; 145 break;
144 case 43224: 146 case 43224:
145 if (bus->chipinfo.rev == 0) { 147 if (bus->chipinfo.rev == 0) {
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index c7f93359acb0..f16f42d36071 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -579,13 +579,13 @@ int bcma_sprom_get(struct bcma_bus *bus)
579 if (!sprom) 579 if (!sprom)
580 return -ENOMEM; 580 return -ENOMEM;
581 581
582 if (bus->chipinfo.id == 0x4331) 582 if (bus->chipinfo.id == 0x4331 || bus->chipinfo.id == 43431)
583 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); 583 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
584 584
585 pr_debug("SPROM offset 0x%x\n", offset); 585 pr_debug("SPROM offset 0x%x\n", offset);
586 bcma_sprom_read(bus, offset, sprom); 586 bcma_sprom_read(bus, offset, sprom);
587 587
588 if (bus->chipinfo.id == 0x4331) 588 if (bus->chipinfo.id == 0x4331 || bus->chipinfo.id == 43431)
589 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); 589 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
590 590
591 err = bcma_sprom_valid(sprom); 591 err = bcma_sprom_valid(sprom);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index e2480d196276..8e7e6928c936 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -89,9 +89,9 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
89 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; 89 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
90 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); 90 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
91 91
92 /* redirect, configure ane enable io for interrupt signal */ 92 /* redirect, configure and enable io for interrupt signal */
93 data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; 93 data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
94 if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH) 94 if (sdiodev->irq_flags & IRQF_TRIGGER_HIGH)
95 data |= SDIO_SEPINT_ACT_HI; 95 data |= SDIO_SEPINT_ACT_HI;
96 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); 96 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
97 97
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index d742900969ea..fac67a526a30 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -861,13 +861,18 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
861 861
862 /* We have our copies now, allow OS release its copies */ 862 /* We have our copies now, allow OS release its copies */
863 release_firmware(ucode_raw); 863 release_firmware(ucode_raw);
864 complete(&drv->request_firmware_complete);
865 864
866 drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); 865 drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw);
867 866
868 if (!drv->op_mode) 867 if (!drv->op_mode)
869 goto out_free_fw; 868 goto out_unbind;
870 869
870 /*
871 * Complete the firmware request last so that
872 * a driver unbind (stop) doesn't run while we
873 * are doing the start() above.
874 */
875 complete(&drv->request_firmware_complete);
871 return; 876 return;
872 877
873 try_again: 878 try_again:
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 50c58911e718..b8e2b223ac36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -568,28 +568,28 @@ static int iwl_find_otp_image(struct iwl_trans *trans,
568 * iwl_get_max_txpower_avg - get the highest tx power from all chains. 568 * iwl_get_max_txpower_avg - get the highest tx power from all chains.
569 * find the highest tx power from all chains for the channel 569 * find the highest tx power from all chains for the channel
570 */ 570 */
571static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg, 571static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
572 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, 572 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
573 int element, s8 *max_txpower_in_half_dbm) 573 int element, s8 *max_txpower_in_half_dbm)
574{ 574{
575 s8 max_txpower_avg = 0; /* (dBm) */ 575 s8 max_txpower_avg = 0; /* (dBm) */
576 576
577 /* Take the highest tx power from any valid chains */ 577 /* Take the highest tx power from any valid chains */
578 if ((cfg->valid_tx_ant & ANT_A) && 578 if ((priv->hw_params.valid_tx_ant & ANT_A) &&
579 (enhanced_txpower[element].chain_a_max > max_txpower_avg)) 579 (enhanced_txpower[element].chain_a_max > max_txpower_avg))
580 max_txpower_avg = enhanced_txpower[element].chain_a_max; 580 max_txpower_avg = enhanced_txpower[element].chain_a_max;
581 if ((cfg->valid_tx_ant & ANT_B) && 581 if ((priv->hw_params.valid_tx_ant & ANT_B) &&
582 (enhanced_txpower[element].chain_b_max > max_txpower_avg)) 582 (enhanced_txpower[element].chain_b_max > max_txpower_avg))
583 max_txpower_avg = enhanced_txpower[element].chain_b_max; 583 max_txpower_avg = enhanced_txpower[element].chain_b_max;
584 if ((cfg->valid_tx_ant & ANT_C) && 584 if ((priv->hw_params.valid_tx_ant & ANT_C) &&
585 (enhanced_txpower[element].chain_c_max > max_txpower_avg)) 585 (enhanced_txpower[element].chain_c_max > max_txpower_avg))
586 max_txpower_avg = enhanced_txpower[element].chain_c_max; 586 max_txpower_avg = enhanced_txpower[element].chain_c_max;
587 if (((cfg->valid_tx_ant == ANT_AB) | 587 if (((priv->hw_params.valid_tx_ant == ANT_AB) |
588 (cfg->valid_tx_ant == ANT_BC) | 588 (priv->hw_params.valid_tx_ant == ANT_BC) |
589 (cfg->valid_tx_ant == ANT_AC)) && 589 (priv->hw_params.valid_tx_ant == ANT_AC)) &&
590 (enhanced_txpower[element].mimo2_max > max_txpower_avg)) 590 (enhanced_txpower[element].mimo2_max > max_txpower_avg))
591 max_txpower_avg = enhanced_txpower[element].mimo2_max; 591 max_txpower_avg = enhanced_txpower[element].mimo2_max;
592 if ((cfg->valid_tx_ant == ANT_ABC) && 592 if ((priv->hw_params.valid_tx_ant == ANT_ABC) &&
593 (enhanced_txpower[element].mimo3_max > max_txpower_avg)) 593 (enhanced_txpower[element].mimo3_max > max_txpower_avg))
594 max_txpower_avg = enhanced_txpower[element].mimo3_max; 594 max_txpower_avg = enhanced_txpower[element].mimo3_max;
595 595
@@ -691,7 +691,7 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
691 ((txp->delta_20_in_40 & 0xf0) >> 4), 691 ((txp->delta_20_in_40 & 0xf0) >> 4),
692 (txp->delta_20_in_40 & 0x0f)); 692 (txp->delta_20_in_40 & 0x0f));
693 693
694 max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx, 694 max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx,
695 &max_txp_avg_halfdbm); 695 &max_txp_avg_halfdbm);
696 696
697 /* 697 /*
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
index ab2f4d7500a4..3ee23134c02b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c
+++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
@@ -199,6 +199,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
199 WIPHY_FLAG_DISABLE_BEACON_HINTS | 199 WIPHY_FLAG_DISABLE_BEACON_HINTS |
200 WIPHY_FLAG_IBSS_RSN; 200 WIPHY_FLAG_IBSS_RSN;
201 201
202#ifdef CONFIG_PM_SLEEP
202 if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && 203 if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
203 priv->trans->ops->wowlan_suspend && 204 priv->trans->ops->wowlan_suspend &&
204 device_can_wakeup(priv->trans->dev)) { 205 device_can_wakeup(priv->trans->dev)) {
@@ -217,6 +218,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
217 hw->wiphy->wowlan.pattern_max_len = 218 hw->wiphy->wowlan.pattern_max_len =
218 IWLAGN_WOWLAN_MAX_PATTERN_LEN; 219 IWLAGN_WOWLAN_MAX_PATTERN_LEN;
219 } 220 }
221#endif
220 222
221 if (iwlwifi_mod_params.power_save) 223 if (iwlwifi_mod_params.power_save)
222 hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; 224 hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -249,6 +251,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
249 ret = ieee80211_register_hw(priv->hw); 251 ret = ieee80211_register_hw(priv->hw);
250 if (ret) { 252 if (ret) {
251 IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); 253 IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
254 iwl_leds_exit(priv);
252 return ret; 255 return ret;
253 } 256 }
254 priv->mac80211_registered = 1; 257 priv->mac80211_registered = 1;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index fb787df01666..4c9336cee817 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1721,6 +1721,24 @@ static void hwsim_exit_netlink(void)
1721 "unregister family %i\n", ret); 1721 "unregister family %i\n", ret);
1722} 1722}
1723 1723
1724static const struct ieee80211_iface_limit hwsim_if_limits[] = {
1725 { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
1726 { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
1727 BIT(NL80211_IFTYPE_P2P_CLIENT) |
1728#ifdef CONFIG_MAC80211_MESH
1729 BIT(NL80211_IFTYPE_MESH_POINT) |
1730#endif
1731 BIT(NL80211_IFTYPE_AP) |
1732 BIT(NL80211_IFTYPE_P2P_GO) },
1733};
1734
1735static const struct ieee80211_iface_combination hwsim_if_comb = {
1736 .limits = hwsim_if_limits,
1737 .n_limits = ARRAY_SIZE(hwsim_if_limits),
1738 .max_interfaces = 2048,
1739 .num_different_channels = 1,
1740};
1741
1724static int __init init_mac80211_hwsim(void) 1742static int __init init_mac80211_hwsim(void)
1725{ 1743{
1726 int i, err = 0; 1744 int i, err = 0;
@@ -1782,6 +1800,9 @@ static int __init init_mac80211_hwsim(void)
1782 hw->wiphy->n_addresses = 2; 1800 hw->wiphy->n_addresses = 2;
1783 hw->wiphy->addresses = data->addresses; 1801 hw->wiphy->addresses = data->addresses;
1784 1802
1803 hw->wiphy->iface_combinations = &hwsim_if_comb;
1804 hw->wiphy->n_iface_combinations = 1;
1805
1785 if (fake_hw_scan) { 1806 if (fake_hw_scan) {
1786 hw->wiphy->max_scan_ssids = 255; 1807 hw->wiphy->max_scan_ssids = 255;
1787 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; 1808 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 87671446e24b..015fec3371a0 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -948,6 +948,19 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
948 bss_cfg->ssid.ssid_len = params->ssid_len; 948 bss_cfg->ssid.ssid_len = params->ssid_len;
949 } 949 }
950 950
951 switch (params->hidden_ssid) {
952 case NL80211_HIDDEN_SSID_NOT_IN_USE:
953 bss_cfg->bcast_ssid_ctl = 1;
954 break;
955 case NL80211_HIDDEN_SSID_ZERO_LEN:
956 bss_cfg->bcast_ssid_ctl = 0;
957 break;
958 case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
959 /* firmware doesn't support this type of hidden SSID */
960 default:
961 return -EINVAL;
962 }
963
951 if (mwifiex_set_secure_params(priv, bss_cfg, params)) { 964 if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
952 kfree(bss_cfg); 965 kfree(bss_cfg);
953 wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); 966 wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 9f674bbebe65..561452a5c818 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -122,6 +122,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
122#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) 122#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
123#define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) 123#define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44)
124#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) 124#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45)
125#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48)
125#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51) 126#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51)
126#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60) 127#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60)
127#define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64) 128#define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64)
@@ -1209,6 +1210,11 @@ struct host_cmd_tlv_ssid {
1209 u8 ssid[0]; 1210 u8 ssid[0];
1210} __packed; 1211} __packed;
1211 1212
1213struct host_cmd_tlv_bcast_ssid {
1214 struct host_cmd_tlv tlv;
1215 u8 bcast_ctl;
1216} __packed;
1217
1212struct host_cmd_tlv_beacon_period { 1218struct host_cmd_tlv_beacon_period {
1213 struct host_cmd_tlv tlv; 1219 struct host_cmd_tlv tlv;
1214 __le16 period; 1220 __le16 period;
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 76dfbc42a732..8173ab66066d 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -132,6 +132,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
132 struct host_cmd_tlv_dtim_period *dtim_period; 132 struct host_cmd_tlv_dtim_period *dtim_period;
133 struct host_cmd_tlv_beacon_period *beacon_period; 133 struct host_cmd_tlv_beacon_period *beacon_period;
134 struct host_cmd_tlv_ssid *ssid; 134 struct host_cmd_tlv_ssid *ssid;
135 struct host_cmd_tlv_bcast_ssid *bcast_ssid;
135 struct host_cmd_tlv_channel_band *chan_band; 136 struct host_cmd_tlv_channel_band *chan_band;
136 struct host_cmd_tlv_frag_threshold *frag_threshold; 137 struct host_cmd_tlv_frag_threshold *frag_threshold;
137 struct host_cmd_tlv_rts_threshold *rts_threshold; 138 struct host_cmd_tlv_rts_threshold *rts_threshold;
@@ -153,6 +154,14 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
153 cmd_size += sizeof(struct host_cmd_tlv) + 154 cmd_size += sizeof(struct host_cmd_tlv) +
154 bss_cfg->ssid.ssid_len; 155 bss_cfg->ssid.ssid_len;
155 tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len; 156 tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len;
157
158 bcast_ssid = (struct host_cmd_tlv_bcast_ssid *)tlv;
159 bcast_ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID);
160 bcast_ssid->tlv.len =
161 cpu_to_le16(sizeof(bcast_ssid->bcast_ctl));
162 bcast_ssid->bcast_ctl = bss_cfg->bcast_ssid_ctl;
163 cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid);
164 tlv += sizeof(struct host_cmd_tlv_bcast_ssid);
156 } 165 }
157 if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) { 166 if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) {
158 chan_band = (struct host_cmd_tlv_channel_band *)tlv; 167 chan_band = (struct host_cmd_tlv_channel_band *)tlv;
@@ -416,6 +425,7 @@ int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel)
416 if (!bss_cfg) 425 if (!bss_cfg)
417 return -ENOMEM; 426 return -ENOMEM;
418 427
428 mwifiex_set_sys_config_invalid_data(bss_cfg);
419 bss_cfg->band_cfg = BAND_CONFIG_MANUAL; 429 bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
420 bss_cfg->channel = channel; 430 bss_cfg->channel = channel;
421 431
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index ca36cccaba31..8f754025b06e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -396,8 +396,7 @@ struct rt2x00_intf {
396 * for hardware which doesn't support hardware 396 * for hardware which doesn't support hardware
397 * sequence counting. 397 * sequence counting.
398 */ 398 */
399 spinlock_t seqlock; 399 atomic_t seqno;
400 u16 seqno;
401}; 400};
402 401
403static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) 402static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index b49773ef72f2..dd24b2663b5e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -277,7 +277,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
277 else 277 else
278 rt2x00dev->intf_sta_count++; 278 rt2x00dev->intf_sta_count++;
279 279
280 spin_lock_init(&intf->seqlock);
281 mutex_init(&intf->beacon_skb_mutex); 280 mutex_init(&intf->beacon_skb_mutex);
282 intf->beacon = entry; 281 intf->beacon = entry;
283 282
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 4c662eccf53c..2fd830103415 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -207,6 +207,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev,
207 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 207 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
208 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 208 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
209 struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); 209 struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
210 u16 seqno;
210 211
211 if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) 212 if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
212 return; 213 return;
@@ -238,15 +239,13 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev,
238 * sequence counting per-frame, since those will override the 239 * sequence counting per-frame, since those will override the
239 * sequence counter given by mac80211. 240 * sequence counter given by mac80211.
240 */ 241 */
241 spin_lock(&intf->seqlock);
242
243 if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) 242 if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
244 intf->seqno += 0x10; 243 seqno = atomic_add_return(0x10, &intf->seqno);
245 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 244 else
246 hdr->seq_ctrl |= cpu_to_le16(intf->seqno); 245 seqno = atomic_read(&intf->seqno);
247
248 spin_unlock(&intf->seqlock);
249 246
247 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
248 hdr->seq_ctrl |= cpu_to_le16(seqno);
250} 249}
251 250
252static void rt2x00queue_create_tx_descriptor_plcp(struct rt2x00_dev *rt2x00dev, 251static void rt2x00queue_create_tx_descriptor_plcp(struct rt2x00_dev *rt2x00dev,
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 46e7f86acfc9..3e18af4dadc4 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -210,7 +210,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
210 } 210 }
211 211
212 if (sk->sk_state == BT_CONNECTED || !newsock || 212 if (sk->sk_state == BT_CONNECTED || !newsock ||
213 test_bit(BT_DEFER_SETUP, &bt_sk(parent)->flags)) { 213 test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) {
214 bt_accept_unlink(sk); 214 bt_accept_unlink(sk);
215 if (newsock) 215 if (newsock)
216 sock_graft(sk, newsock); 216 sock_graft(sk, newsock);
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 26ddb699d693..c649188314cc 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -145,15 +145,20 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
145 struct tid_ampdu_rx *tid_rx; 145 struct tid_ampdu_rx *tid_rx;
146 unsigned long timeout; 146 unsigned long timeout;
147 147
148 rcu_read_lock();
148 tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]); 149 tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]);
149 if (!tid_rx) 150 if (!tid_rx) {
151 rcu_read_unlock();
150 return; 152 return;
153 }
151 154
152 timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout); 155 timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout);
153 if (time_is_after_jiffies(timeout)) { 156 if (time_is_after_jiffies(timeout)) {
154 mod_timer(&tid_rx->session_timer, timeout); 157 mod_timer(&tid_rx->session_timer, timeout);
158 rcu_read_unlock();
155 return; 159 return;
156 } 160 }
161 rcu_read_unlock();
157 162
158#ifdef CONFIG_MAC80211_HT_DEBUG 163#ifdef CONFIG_MAC80211_HT_DEBUG
159 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); 164 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 495831ee48f1..e9cecca5c44d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -533,16 +533,16 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
533 sinfo.filled = 0; 533 sinfo.filled = 0;
534 sta_set_sinfo(sta, &sinfo); 534 sta_set_sinfo(sta, &sinfo);
535 535
536 if (sinfo.filled | STATION_INFO_TX_BITRATE) 536 if (sinfo.filled & STATION_INFO_TX_BITRATE)
537 data[i] = 100000 * 537 data[i] = 100000 *
538 cfg80211_calculate_bitrate(&sinfo.txrate); 538 cfg80211_calculate_bitrate(&sinfo.txrate);
539 i++; 539 i++;
540 if (sinfo.filled | STATION_INFO_RX_BITRATE) 540 if (sinfo.filled & STATION_INFO_RX_BITRATE)
541 data[i] = 100000 * 541 data[i] = 100000 *
542 cfg80211_calculate_bitrate(&sinfo.rxrate); 542 cfg80211_calculate_bitrate(&sinfo.rxrate);
543 i++; 543 i++;
544 544
545 if (sinfo.filled | STATION_INFO_SIGNAL_AVG) 545 if (sinfo.filled & STATION_INFO_SIGNAL_AVG)
546 data[i] = (u8)sinfo.signal_avg; 546 data[i] = (u8)sinfo.signal_avg;
547 i++; 547 i++;
548 } else { 548 } else {
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index d4c19a7773db..8664111d0566 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -637,6 +637,18 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
637 ieee80211_configure_filter(local); 637 ieee80211_configure_filter(local);
638 break; 638 break;
639 default: 639 default:
640 mutex_lock(&local->mtx);
641 if (local->hw_roc_dev == sdata->dev &&
642 local->hw_roc_channel) {
643 /* ignore return value since this is racy */
644 drv_cancel_remain_on_channel(local);
645 ieee80211_queue_work(&local->hw, &local->hw_roc_done);
646 }
647 mutex_unlock(&local->mtx);
648
649 flush_work(&local->hw_roc_start);
650 flush_work(&local->hw_roc_done);
651
640 flush_work(&sdata->work); 652 flush_work(&sdata->work);
641 /* 653 /*
642 * When we get here, the interface is marked down. 654 * When we get here, the interface is marked down.
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 04c306308987..d94627c2929c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1220,6 +1220,22 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
1220 sdata->vif.bss_conf.qos = true; 1220 sdata->vif.bss_conf.qos = true;
1221} 1221}
1222 1222
1223static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
1224{
1225 lockdep_assert_held(&sdata->local->mtx);
1226
1227 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
1228 IEEE80211_STA_BEACON_POLL);
1229 ieee80211_run_deferred_scan(sdata->local);
1230}
1231
1232static void ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
1233{
1234 mutex_lock(&sdata->local->mtx);
1235 __ieee80211_stop_poll(sdata);
1236 mutex_unlock(&sdata->local->mtx);
1237}
1238
1223static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, 1239static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
1224 u16 capab, bool erp_valid, u8 erp) 1240 u16 capab, bool erp_valid, u8 erp)
1225{ 1241{
@@ -1285,8 +1301,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1285 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; 1301 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
1286 1302
1287 /* just to be sure */ 1303 /* just to be sure */
1288 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | 1304 ieee80211_stop_poll(sdata);
1289 IEEE80211_STA_BEACON_POLL);
1290 1305
1291 ieee80211_led_assoc(local, 1); 1306 ieee80211_led_assoc(local, 1);
1292 1307
@@ -1456,8 +1471,7 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
1456 return; 1471 return;
1457 } 1472 }
1458 1473
1459 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | 1474 __ieee80211_stop_poll(sdata);
1460 IEEE80211_STA_BEACON_POLL);
1461 1475
1462 mutex_lock(&local->iflist_mtx); 1476 mutex_lock(&local->iflist_mtx);
1463 ieee80211_recalc_ps(local, -1); 1477 ieee80211_recalc_ps(local, -1);
@@ -1477,7 +1491,6 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
1477 round_jiffies_up(jiffies + 1491 round_jiffies_up(jiffies +
1478 IEEE80211_CONNECTION_IDLE_TIME)); 1492 IEEE80211_CONNECTION_IDLE_TIME));
1479out: 1493out:
1480 ieee80211_run_deferred_scan(local);
1481 mutex_unlock(&local->mtx); 1494 mutex_unlock(&local->mtx);
1482} 1495}
1483 1496
@@ -2408,7 +2421,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2408 net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", 2421 net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n",
2409 sdata->name); 2422 sdata->name);
2410#endif 2423#endif
2424 mutex_lock(&local->mtx);
2411 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; 2425 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
2426 ieee80211_run_deferred_scan(local);
2427 mutex_unlock(&local->mtx);
2428
2412 mutex_lock(&local->iflist_mtx); 2429 mutex_lock(&local->iflist_mtx);
2413 ieee80211_recalc_ps(local, -1); 2430 ieee80211_recalc_ps(local, -1);
2414 mutex_unlock(&local->iflist_mtx); 2431 mutex_unlock(&local->iflist_mtx);
@@ -2595,8 +2612,7 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
2595 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2612 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2596 u8 frame_buf[DEAUTH_DISASSOC_LEN]; 2613 u8 frame_buf[DEAUTH_DISASSOC_LEN];
2597 2614
2598 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | 2615 ieee80211_stop_poll(sdata);
2599 IEEE80211_STA_BEACON_POLL);
2600 2616
2601 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, 2617 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
2602 false, frame_buf); 2618 false, frame_buf);
@@ -2874,8 +2890,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
2874 u32 flags; 2890 u32 flags;
2875 2891
2876 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 2892 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
2877 sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL | 2893 __ieee80211_stop_poll(sdata);
2878 IEEE80211_STA_CONNECTION_POLL);
2879 2894
2880 /* let's probe the connection once */ 2895 /* let's probe the connection once */
2881 flags = sdata->local->hw.flags; 2896 flags = sdata->local->hw.flags;
@@ -2944,7 +2959,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
2944 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) 2959 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
2945 add_timer(&ifmgd->chswitch_timer); 2960 add_timer(&ifmgd->chswitch_timer);
2946 ieee80211_sta_reset_beacon_monitor(sdata); 2961 ieee80211_sta_reset_beacon_monitor(sdata);
2962
2963 mutex_lock(&sdata->local->mtx);
2947 ieee80211_restart_sta_timer(sdata); 2964 ieee80211_restart_sta_timer(sdata);
2965 mutex_unlock(&sdata->local->mtx);
2948} 2966}
2949#endif 2967#endif
2950 2968
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index f054e94901a2..935aa4b6deee 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -234,6 +234,22 @@ static void ieee80211_hw_roc_done(struct work_struct *work)
234 return; 234 return;
235 } 235 }
236 236
237 /* was never transmitted */
238 if (local->hw_roc_skb) {
239 u64 cookie;
240
241 cookie = local->hw_roc_cookie ^ 2;
242
243 cfg80211_mgmt_tx_status(local->hw_roc_dev, cookie,
244 local->hw_roc_skb->data,
245 local->hw_roc_skb->len, false,
246 GFP_KERNEL);
247
248 kfree_skb(local->hw_roc_skb);
249 local->hw_roc_skb = NULL;
250 local->hw_roc_skb_for_status = NULL;
251 }
252
237 if (!local->hw_roc_for_tx) 253 if (!local->hw_roc_for_tx)
238 cfg80211_remain_on_channel_expired(local->hw_roc_dev, 254 cfg80211_remain_on_channel_expired(local->hw_roc_dev,
239 local->hw_roc_cookie, 255 local->hw_roc_cookie,
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index f5b1638fbf80..de455f8bbb91 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -378,7 +378,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
378 /* make the station visible */ 378 /* make the station visible */
379 sta_info_hash_add(local, sta); 379 sta_info_hash_add(local, sta);
380 380
381 list_add(&sta->list, &local->sta_list); 381 list_add_rcu(&sta->list, &local->sta_list);
382 382
383 set_sta_flag(sta, WLAN_STA_INSERTED); 383 set_sta_flag(sta, WLAN_STA_INSERTED);
384 384
@@ -688,7 +688,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
688 if (ret) 688 if (ret)
689 return ret; 689 return ret;
690 690
691 list_del(&sta->list); 691 list_del_rcu(&sta->list);
692 692
693 mutex_lock(&local->key_mtx); 693 mutex_lock(&local->key_mtx);
694 for (i = 0; i < NUM_DEFAULT_KEYS; i++) 694 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 847215bb2a6f..e453212fa17f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1737,7 +1737,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1737 __le16 fc; 1737 __le16 fc;
1738 struct ieee80211_hdr hdr; 1738 struct ieee80211_hdr hdr;
1739 struct ieee80211s_hdr mesh_hdr __maybe_unused; 1739 struct ieee80211s_hdr mesh_hdr __maybe_unused;
1740 struct mesh_path __maybe_unused *mppath = NULL; 1740 struct mesh_path __maybe_unused *mppath = NULL, *mpath = NULL;
1741 const u8 *encaps_data; 1741 const u8 *encaps_data;
1742 int encaps_len, skip_header_bytes; 1742 int encaps_len, skip_header_bytes;
1743 int nh_pos, h_pos; 1743 int nh_pos, h_pos;
@@ -1803,8 +1803,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1803 goto fail; 1803 goto fail;
1804 } 1804 }
1805 rcu_read_lock(); 1805 rcu_read_lock();
1806 if (!is_multicast_ether_addr(skb->data)) 1806 if (!is_multicast_ether_addr(skb->data)) {
1807 mppath = mpp_path_lookup(skb->data, sdata); 1807 mpath = mesh_path_lookup(skb->data, sdata);
1808 if (!mpath)
1809 mppath = mpp_path_lookup(skb->data, sdata);
1810 }
1808 1811
1809 /* 1812 /*
1810 * Use address extension if it is a packet from 1813 * Use address extension if it is a packet from
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index a44c6807df01..8dd4712620ff 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1271,7 +1271,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1271 enum ieee80211_sta_state state; 1271 enum ieee80211_sta_state state;
1272 1272
1273 for (state = IEEE80211_STA_NOTEXIST; 1273 for (state = IEEE80211_STA_NOTEXIST;
1274 state < sta->sta_state - 1; state++) 1274 state < sta->sta_state; state++)
1275 WARN_ON(drv_sta_state(local, sta->sdata, sta, 1275 WARN_ON(drv_sta_state(local, sta->sdata, sta,
1276 state, state + 1)); 1276 state, state + 1));
1277 } 1277 }
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index d2a19b0ff71f..89baa3328411 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -42,6 +42,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
42 cfg80211_hold_bss(bss_from_pub(bss)); 42 cfg80211_hold_bss(bss_from_pub(bss));
43 wdev->current_bss = bss_from_pub(bss); 43 wdev->current_bss = bss_from_pub(bss);
44 44
45 wdev->sme_state = CFG80211_SME_CONNECTED;
45 cfg80211_upload_connect_keys(wdev); 46 cfg80211_upload_connect_keys(wdev);
46 47
47 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, 48 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid,
@@ -60,7 +61,7 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
60 struct cfg80211_event *ev; 61 struct cfg80211_event *ev;
61 unsigned long flags; 62 unsigned long flags;
62 63
63 CFG80211_DEV_WARN_ON(!wdev->ssid_len); 64 CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING);
64 65
65 ev = kzalloc(sizeof(*ev), gfp); 66 ev = kzalloc(sizeof(*ev), gfp);
66 if (!ev) 67 if (!ev)
@@ -115,9 +116,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
115#ifdef CONFIG_CFG80211_WEXT 116#ifdef CONFIG_CFG80211_WEXT
116 wdev->wext.ibss.channel = params->channel; 117 wdev->wext.ibss.channel = params->channel;
117#endif 118#endif
119 wdev->sme_state = CFG80211_SME_CONNECTING;
118 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); 120 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
119 if (err) { 121 if (err) {
120 wdev->connect_keys = NULL; 122 wdev->connect_keys = NULL;
123 wdev->sme_state = CFG80211_SME_IDLE;
121 return err; 124 return err;
122 } 125 }
123 126
@@ -169,6 +172,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
169 } 172 }
170 173
171 wdev->current_bss = NULL; 174 wdev->current_bss = NULL;
175 wdev->sme_state = CFG80211_SME_IDLE;
172 wdev->ssid_len = 0; 176 wdev->ssid_len = 0;
173#ifdef CONFIG_CFG80211_WEXT 177#ifdef CONFIG_CFG80211_WEXT
174 if (!nowext) 178 if (!nowext)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 55d99466babb..8f2d68fc3a44 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -935,6 +935,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
935 enum nl80211_iftype iftype) 935 enum nl80211_iftype iftype)
936{ 936{
937 struct wireless_dev *wdev_iter; 937 struct wireless_dev *wdev_iter;
938 u32 used_iftypes = BIT(iftype);
938 int num[NUM_NL80211_IFTYPES]; 939 int num[NUM_NL80211_IFTYPES];
939 int total = 1; 940 int total = 1;
940 int i, j; 941 int i, j;
@@ -961,6 +962,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
961 962
962 num[wdev_iter->iftype]++; 963 num[wdev_iter->iftype]++;
963 total++; 964 total++;
965 used_iftypes |= BIT(wdev_iter->iftype);
964 } 966 }
965 mutex_unlock(&rdev->devlist_mtx); 967 mutex_unlock(&rdev->devlist_mtx);
966 968
@@ -970,6 +972,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
970 for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { 972 for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) {
971 const struct ieee80211_iface_combination *c; 973 const struct ieee80211_iface_combination *c;
972 struct ieee80211_iface_limit *limits; 974 struct ieee80211_iface_limit *limits;
975 u32 all_iftypes = 0;
973 976
974 c = &rdev->wiphy.iface_combinations[i]; 977 c = &rdev->wiphy.iface_combinations[i];
975 978
@@ -984,6 +987,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
984 if (rdev->wiphy.software_iftypes & BIT(iftype)) 987 if (rdev->wiphy.software_iftypes & BIT(iftype))
985 continue; 988 continue;
986 for (j = 0; j < c->n_limits; j++) { 989 for (j = 0; j < c->n_limits; j++) {
990 all_iftypes |= limits[j].types;
987 if (!(limits[j].types & BIT(iftype))) 991 if (!(limits[j].types & BIT(iftype)))
988 continue; 992 continue;
989 if (limits[j].max < num[iftype]) 993 if (limits[j].max < num[iftype])
@@ -991,7 +995,20 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
991 limits[j].max -= num[iftype]; 995 limits[j].max -= num[iftype];
992 } 996 }
993 } 997 }
994 /* yay, it fits */ 998
999 /*
1000 * Finally check that all iftypes that we're currently
1001 * using are actually part of this combination. If they
1002 * aren't then we can't use this combination and have
1003 * to continue to the next.
1004 */
1005 if ((all_iftypes & used_iftypes) != used_iftypes)
1006 goto cont;
1007
1008 /*
1009 * This combination covered all interface types and
1010 * supported the requested numbers, so we're good.
1011 */
995 kfree(limits); 1012 kfree(limits);
996 return 0; 1013 return 0;
997 cont: 1014 cont: