aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-02-12 11:06:52 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-02-12 11:06:52 -0500
commit4fe0c75eedb15af13859ef123db17fefed5af7ae (patch)
tree6ed38d8e2e0ae457d10a2af2e496e9ecb4d34e08
parent8457703f1e86aaf0f134402dd1e09e1f13e65222 (diff)
parent9c35d7d2368f54313b988a01c408e5cf863ffd9e (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c1
-rw-r--r--drivers/net/wireless/libertas/cfg.c8
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c2
-rw-r--r--drivers/net/wireless/mwifiex/scan.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c11
-rw-r--r--drivers/net/wireless/orinoco/scan.c4
-rw-r--r--drivers/net/wireless/rndis_wlan.c4
-rw-r--r--drivers/net/wireless/ti/wl1251/event.c6
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c24
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c1
-rw-r--r--drivers/staging/wlan-ng/cfg80211.c2
-rw-r--r--include/net/cfg80211.h38
-rw-r--r--include/net/mac80211.h80
-rw-r--r--net/mac80211/cfg.c5
-rw-r--r--net/mac80211/chan.c65
-rw-r--r--net/mac80211/debugfs.c2
-rw-r--r--net/mac80211/driver-ops.h37
-rw-r--r--net/mac80211/ibss.c26
-rw-r--r--net/mac80211/ieee80211_i.h19
-rw-r--r--net/mac80211/iface.c106
-rw-r--r--net/mac80211/main.c17
-rw-r--r--net/mac80211/mesh.c38
-rw-r--r--net/mac80211/mesh.h3
-rw-r--r--net/mac80211/mesh_plink.c11
-rw-r--r--net/mac80211/mlme.c160
-rw-r--r--net/mac80211/offchannel.c35
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c4
-rw-r--r--net/mac80211/rc80211_minstrel_ht_debugfs.c11
-rw-r--r--net/mac80211/rx.c81
-rw-r--r--net/mac80211/scan.c20
-rw-r--r--net/mac80211/sta_info.c9
-rw-r--r--net/mac80211/sta_info.h1
-rw-r--r--net/mac80211/trace.h4
-rw-r--r--net/mac80211/tx.c15
-rw-r--r--net/wireless/core.c2
-rw-r--r--net/wireless/core.h4
-rw-r--r--net/wireless/ibss.c4
-rw-r--r--net/wireless/mlme.c14
-rw-r--r--net/wireless/nl80211.c27
-rw-r--r--net/wireless/reg.c9
-rw-r--r--net/wireless/scan.c295
-rw-r--r--net/wireless/sme.c16
-rw-r--r--net/wireless/util.c2
49 files changed, 720 insertions, 522 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 259c43332fb8..a29f04e30830 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -767,7 +767,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
767 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n", 767 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
768 nw_type & ADHOC_CREATOR ? "creator" : "joiner"); 768 nw_type & ADHOC_CREATOR ? "creator" : "joiner");
769 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); 769 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
770 cfg80211_put_bss(bss); 770 cfg80211_put_bss(ar->wiphy, bss);
771 return; 771 return;
772 } 772 }
773 773
@@ -778,7 +778,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
778 assoc_req_ie, assoc_req_len, 778 assoc_req_ie, assoc_req_len,
779 assoc_resp_ie, assoc_resp_len, 779 assoc_resp_ie, assoc_resp_len,
780 WLAN_STATUS_SUCCESS, GFP_KERNEL); 780 WLAN_STATUS_SUCCESS, GFP_KERNEL);
781 cfg80211_put_bss(bss); 781 cfg80211_put_bss(ar->wiphy, bss);
782 } else if (vif->sme_state == SME_CONNECTED) { 782 } else if (vif->sme_state == SME_CONNECTED) {
783 /* inform roam event to cfg80211 */ 783 /* inform roam event to cfg80211 */
784 cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len, 784 cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 998f8b0f62fd..d366cf105c7c 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -1108,7 +1108,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len,
1108 kfree(mgmt); 1108 kfree(mgmt);
1109 if (bss == NULL) 1109 if (bss == NULL)
1110 return -ENOMEM; 1110 return -ENOMEM;
1111 cfg80211_put_bss(bss); 1111 cfg80211_put_bss(ar->wiphy, bss);
1112 1112
1113 /* 1113 /*
1114 * Firmware doesn't return any event when scheduled scan has 1114 * Firmware doesn't return any event when scheduled scan has
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 002851fceb2f..9ecc1968262c 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -341,7 +341,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
341 } 341 }
342 342
343 out: 343 out:
344 cfg80211_put_bss(bss); 344 cfg80211_put_bss(wiphy, bss);
345 345
346 return rc; 346 return rc;
347} 347}
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 0b70e17cd1fb..79d608caa903 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -338,7 +338,7 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
338 if (bss) { 338 if (bss) {
339 wil_dbg_wmi(wil, "Added BSS %pM\n", 339 wil_dbg_wmi(wil, "Added BSS %pM\n",
340 rx_mgmt_frame->bssid); 340 rx_mgmt_frame->bssid);
341 cfg80211_put_bss(bss); 341 cfg80211_put_bss(wiphy, bss);
342 } else { 342 } else {
343 wil_err(wil, "cfg80211_inform_bss() failed\n"); 343 wil_err(wil, "cfg80211_inform_bss() failed\n");
344 } 344 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 481f41ad7989..cecc3eff72e9 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -2323,7 +2323,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2323 if (!bss) 2323 if (!bss)
2324 return -ENOMEM; 2324 return -ENOMEM;
2325 2325
2326 cfg80211_put_bss(bss); 2326 cfg80211_put_bss(wiphy, bss);
2327 2327
2328 return err; 2328 return err;
2329} 2329}
@@ -2429,7 +2429,7 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2429 goto CleanUp; 2429 goto CleanUp;
2430 } 2430 }
2431 2431
2432 cfg80211_put_bss(bss); 2432 cfg80211_put_bss(wiphy, bss);
2433 2433
2434CleanUp: 2434CleanUp:
2435 2435
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 75f6f6cfdd47..0fccf725a2e6 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -151,8 +151,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
151 IEEE80211_HW_QUEUE_CONTROL | 151 IEEE80211_HW_QUEUE_CONTROL |
152 IEEE80211_HW_SUPPORTS_PS | 152 IEEE80211_HW_SUPPORTS_PS |
153 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 153 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
154 IEEE80211_HW_WANT_MONITOR_VIF | 154 IEEE80211_HW_WANT_MONITOR_VIF;
155 IEEE80211_HW_SCAN_WHILE_IDLE;
156 155
157 hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE; 156 hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE;
158 hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FMT; 157 hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FMT;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index ce6127caabdf..bbb8a5b35662 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -113,7 +113,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
113 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 113 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
114 IEEE80211_HW_QUEUE_CONTROL | 114 IEEE80211_HW_QUEUE_CONTROL |
115 IEEE80211_HW_WANT_MONITOR_VIF | 115 IEEE80211_HW_WANT_MONITOR_VIF |
116 IEEE80211_HW_SCAN_WHILE_IDLE |
117 IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | 116 IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC |
118 IEEE80211_HW_SUPPORTS_PS | 117 IEEE80211_HW_SUPPORTS_PS |
119 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 118 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 230f8ebbe289..61735db3b051 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -657,7 +657,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
657 capa, intvl, ie, ielen, 657 capa, intvl, ie, ielen,
658 LBS_SCAN_RSSI_TO_MBM(rssi), 658 LBS_SCAN_RSSI_TO_MBM(rssi),
659 GFP_KERNEL); 659 GFP_KERNEL);
660 cfg80211_put_bss(bss); 660 cfg80211_put_bss(wiphy, bss);
661 } 661 }
662 } else 662 } else
663 lbs_deb_scan("scan response: missing BSS channel IE\n"); 663 lbs_deb_scan("scan response: missing BSS channel IE\n");
@@ -1444,7 +1444,7 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1444 1444
1445 done: 1445 done:
1446 if (bss) 1446 if (bss)
1447 cfg80211_put_bss(bss); 1447 cfg80211_put_bss(wiphy, bss);
1448 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 1448 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1449 return ret; 1449 return ret;
1450} 1450}
@@ -1766,7 +1766,7 @@ static void lbs_join_post(struct lbs_private *priv,
1766 params->beacon_interval, 1766 params->beacon_interval,
1767 fake_ie, fake - fake_ie, 1767 fake_ie, fake - fake_ie,
1768 0, GFP_KERNEL); 1768 0, GFP_KERNEL);
1769 cfg80211_put_bss(bss); 1769 cfg80211_put_bss(priv->wdev->wiphy, bss);
1770 1770
1771 memcpy(priv->wdev->ssid, params->ssid, params->ssid_len); 1771 memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
1772 priv->wdev->ssid_len = params->ssid_len; 1772 priv->wdev->ssid_len = params->ssid_len;
@@ -2011,7 +2011,7 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
2011 2011
2012 if (bss) { 2012 if (bss) {
2013 ret = lbs_ibss_join_existing(priv, params, bss); 2013 ret = lbs_ibss_join_existing(priv, params, bss);
2014 cfg80211_put_bss(bss); 2014 cfg80211_put_bss(wiphy, bss);
2015 } else 2015 } else
2016 ret = lbs_ibss_start_new(priv, params); 2016 ret = lbs_ibss_start_new(priv, params);
2017 2017
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 3a004b85b99f..81c84a29308f 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1430,7 +1430,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
1430 bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, 1430 bss = cfg80211_inform_bss(priv->wdev->wiphy, chan,
1431 bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, 1431 bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
1432 0, ie_buf, ie_len, 0, GFP_KERNEL); 1432 0, ie_buf, ie_len, 0, GFP_KERNEL);
1433 cfg80211_put_bss(bss); 1433 cfg80211_put_bss(priv->wdev->wiphy, bss);
1434 memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); 1434 memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
1435 1435
1436 return 0; 1436 return 0;
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 9189a32b7844..232492487527 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1746,7 +1746,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1746 .mac_address, ETH_ALEN)) 1746 .mac_address, ETH_ALEN))
1747 mwifiex_update_curr_bss_params(priv, 1747 mwifiex_update_curr_bss_params(priv,
1748 bss); 1748 bss);
1749 cfg80211_put_bss(bss); 1749 cfg80211_put_bss(priv->wdev->wiphy, bss);
1750 } 1750 }
1751 } else { 1751 } else {
1752 dev_dbg(adapter->dev, "missing BSS channel IE\n"); 1752 dev_dbg(adapter->dev, "missing BSS channel IE\n");
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index f542bb8ccbc8..0d018460daf9 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -162,13 +162,9 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
162 162
163 rcu_read_lock(); 163 rcu_read_lock();
164 ies = rcu_dereference(bss->ies); 164 ies = rcu_dereference(bss->ies);
165 if (WARN_ON(!ies)) {
166 /* should never happen */
167 rcu_read_unlock();
168 return -EINVAL;
169 }
170 beacon_ie = kmemdup(ies->data, ies->len, GFP_ATOMIC); 165 beacon_ie = kmemdup(ies->data, ies->len, GFP_ATOMIC);
171 beacon_ie_len = ies->len; 166 beacon_ie_len = ies->len;
167 bss_desc->timestamp = ies->tsf;
172 rcu_read_unlock(); 168 rcu_read_unlock();
173 169
174 if (!beacon_ie) { 170 if (!beacon_ie) {
@@ -184,7 +180,6 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
184 bss_desc->cap_info_bitmap = bss->capability; 180 bss_desc->cap_info_bitmap = bss->capability;
185 bss_desc->bss_band = bss_priv->band; 181 bss_desc->bss_band = bss_priv->band;
186 bss_desc->fw_tsf = bss_priv->fw_tsf; 182 bss_desc->fw_tsf = bss_priv->fw_tsf;
187 bss_desc->timestamp = bss->tsf;
188 if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) { 183 if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
189 dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n"); 184 dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n");
190 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP; 185 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
@@ -324,7 +319,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
324 } 319 }
325 320
326 if (bss) 321 if (bss)
327 cfg80211_put_bss(bss); 322 cfg80211_put_bss(priv->adapter->wiphy, bss);
328 } else { 323 } else {
329 /* Adhoc mode */ 324 /* Adhoc mode */
330 /* If the requested SSID matches current SSID, return */ 325 /* If the requested SSID matches current SSID, return */
@@ -354,7 +349,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
354 " list. Joining...\n"); 349 " list. Joining...\n");
355 ret = mwifiex_adhoc_join(priv, bss_desc); 350 ret = mwifiex_adhoc_join(priv, bss_desc);
356 if (bss) 351 if (bss)
357 cfg80211_put_bss(bss); 352 cfg80211_put_bss(priv->adapter->wiphy, bss);
358 } else { 353 } else {
359 dev_dbg(adapter->dev, "info: Network not found in " 354 dev_dbg(adapter->dev, "info: Network not found in "
360 "the list, creating adhoc with ssid = %s\n", 355 "the list, creating adhoc with ssid = %s\n",
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
index 96e39edfec77..e8c5714bfd11 100644
--- a/drivers/net/wireless/orinoco/scan.c
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -125,7 +125,7 @@ static void orinoco_add_hostscan_result(struct orinoco_private *priv,
125 cbss = cfg80211_inform_bss(wiphy, channel, bss->a.bssid, timestamp, 125 cbss = cfg80211_inform_bss(wiphy, channel, bss->a.bssid, timestamp,
126 capability, beacon_interval, ie_buf, ie_len, 126 capability, beacon_interval, ie_buf, ie_len,
127 signal, GFP_KERNEL); 127 signal, GFP_KERNEL);
128 cfg80211_put_bss(cbss); 128 cfg80211_put_bss(wiphy, cbss);
129} 129}
130 130
131void orinoco_add_extscan_result(struct orinoco_private *priv, 131void orinoco_add_extscan_result(struct orinoco_private *priv,
@@ -158,7 +158,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
158 cbss = cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp, 158 cbss = cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp,
159 capability, beacon_interval, ie, ie_len, 159 capability, beacon_interval, ie, ie_len,
160 signal, GFP_KERNEL); 160 signal, GFP_KERNEL);
161 cfg80211_put_bss(cbss); 161 cfg80211_put_bss(wiphy, cbss);
162} 162}
163 163
164void orinoco_add_hostscan_results(struct orinoco_private *priv, 164void orinoco_add_hostscan_results(struct orinoco_private *priv,
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index abe1d039be81..fe2f272689aa 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2029,7 +2029,7 @@ static bool rndis_bss_info_update(struct usbnet *usbdev,
2029 bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac, 2029 bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac,
2030 timestamp, capability, beacon_interval, ie, ie_len, signal, 2030 timestamp, capability, beacon_interval, ie, ie_len, signal,
2031 GFP_KERNEL); 2031 GFP_KERNEL);
2032 cfg80211_put_bss(bss); 2032 cfg80211_put_bss(priv->wdev.wiphy, bss);
2033 2033
2034 return (bss != NULL); 2034 return (bss != NULL);
2035} 2035}
@@ -2718,7 +2718,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
2718 bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, 2718 bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid,
2719 timestamp, capability, beacon_period, ie_buf, ie_len, 2719 timestamp, capability, beacon_period, ie_buf, ie_len,
2720 signal, GFP_KERNEL); 2720 signal, GFP_KERNEL);
2721 cfg80211_put_bss(bss); 2721 cfg80211_put_bss(priv->wdev.wiphy, bss);
2722} 2722}
2723 2723
2724/* 2724/*
diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c
index 5ec50a476a69..74ae8e1c2e33 100644
--- a/drivers/net/wireless/ti/wl1251/event.c
+++ b/drivers/net/wireless/ti/wl1251/event.c
@@ -29,6 +29,8 @@
29static int wl1251_event_scan_complete(struct wl1251 *wl, 29static int wl1251_event_scan_complete(struct wl1251 *wl,
30 struct event_mailbox *mbox) 30 struct event_mailbox *mbox)
31{ 31{
32 int ret = 0;
33
32 wl1251_debug(DEBUG_EVENT, "status: 0x%x, channels: %d", 34 wl1251_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
33 mbox->scheduled_scan_status, 35 mbox->scheduled_scan_status,
34 mbox->scheduled_scan_channels); 36 mbox->scheduled_scan_channels);
@@ -37,9 +39,11 @@ static int wl1251_event_scan_complete(struct wl1251 *wl,
37 ieee80211_scan_completed(wl->hw, false); 39 ieee80211_scan_completed(wl->hw, false);
38 wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed"); 40 wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed");
39 wl->scanning = false; 41 wl->scanning = false;
42 if (wl->hw->conf.flags & IEEE80211_CONF_IDLE)
43 ret = wl1251_ps_set_mode(wl, STATION_IDLE);
40 } 44 }
41 45
42 return 0; 46 return ret;
43} 47}
44 48
45static void wl1251_event_mbox_dump(struct event_mailbox *mbox) 49static void wl1251_event_mbox_dump(struct event_mailbox *mbox)
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index f47e8b0482ad..bbbf68cf50a7 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -623,7 +623,7 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
623 } 623 }
624 } 624 }
625 625
626 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 626 if (changed & IEEE80211_CONF_CHANGE_IDLE && !wl->scanning) {
627 if (conf->flags & IEEE80211_CONF_IDLE) { 627 if (conf->flags & IEEE80211_CONF_IDLE) {
628 ret = wl1251_ps_set_mode(wl, STATION_IDLE); 628 ret = wl1251_ps_set_mode(wl, STATION_IDLE);
629 if (ret < 0) 629 if (ret < 0)
@@ -895,11 +895,21 @@ static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
895 if (ret < 0) 895 if (ret < 0)
896 goto out; 896 goto out;
897 897
898 if (hw->conf.flags & IEEE80211_CONF_IDLE) {
899 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
900 if (ret < 0)
901 goto out_sleep;
902 ret = wl1251_join(wl, wl->bss_type, wl->channel,
903 wl->beacon_int, wl->dtim_period);
904 if (ret < 0)
905 goto out_sleep;
906 }
907
898 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, 908 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
899 req->ie_len); 909 req->ie_len);
900 if (!skb) { 910 if (!skb) {
901 ret = -ENOMEM; 911 ret = -ENOMEM;
902 goto out; 912 goto out_idle;
903 } 913 }
904 if (req->ie_len) 914 if (req->ie_len)
905 memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len); 915 memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len);
@@ -908,11 +918,11 @@ static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
908 skb->len); 918 skb->len);
909 dev_kfree_skb(skb); 919 dev_kfree_skb(skb);
910 if (ret < 0) 920 if (ret < 0)
911 goto out_sleep; 921 goto out_idle;
912 922
913 ret = wl1251_cmd_trigger_scan_to(wl, 0); 923 ret = wl1251_cmd_trigger_scan_to(wl, 0);
914 if (ret < 0) 924 if (ret < 0)
915 goto out_sleep; 925 goto out_idle;
916 926
917 wl->scanning = true; 927 wl->scanning = true;
918 928
@@ -920,9 +930,13 @@ static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
920 req->n_channels, WL1251_SCAN_NUM_PROBES); 930 req->n_channels, WL1251_SCAN_NUM_PROBES);
921 if (ret < 0) { 931 if (ret < 0) {
922 wl->scanning = false; 932 wl->scanning = false;
923 goto out_sleep; 933 goto out_idle;
924 } 934 }
935 goto out_sleep;
925 936
937out_idle:
938 if (hw->conf.flags & IEEE80211_CONF_IDLE)
939 ret = wl1251_ps_set_mode(wl, STATION_IDLE);
926out_sleep: 940out_sleep:
927 wl1251_ps_elp_sleep(wl); 941 wl1251_ps_elp_sleep(wl);
928 942
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 28a37576d568..2c2ff3e1f849 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5636,7 +5636,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5636 IEEE80211_HW_AP_LINK_PS | 5636 IEEE80211_HW_AP_LINK_PS |
5637 IEEE80211_HW_AMPDU_AGGREGATION | 5637 IEEE80211_HW_AMPDU_AGGREGATION |
5638 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | 5638 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
5639 IEEE80211_HW_SCAN_WHILE_IDLE |
5640 IEEE80211_HW_QUEUE_CONTROL; 5639 IEEE80211_HW_QUEUE_CONTROL;
5641 5640
5642 wl->hw->wiphy->cipher_suites = cipher_suites; 5641 wl->hw->wiphy->cipher_suites = cipher_suites;
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c
index 18c06a59c091..a233f64ca22f 100644
--- a/drivers/staging/wlan-ng/cfg80211.c
+++ b/drivers/staging/wlan-ng/cfg80211.c
@@ -424,7 +424,7 @@ int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
424 goto exit; 424 goto exit;
425 } 425 }
426 426
427 cfg80211_put_bss(bss); 427 cfg80211_put_bss(wiphy, bss);
428 } 428 }
429 429
430 if (result) 430 if (result)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3ec70e1681d3..77686ca28948 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -535,7 +535,7 @@ struct mac_address {
535 * struct cfg80211_acl_data - Access control list data 535 * struct cfg80211_acl_data - Access control list data
536 * 536 *
537 * @acl_policy: ACL policy to be applied on the station's 537 * @acl_policy: ACL policy to be applied on the station's
538 entry specified by mac_addr 538 * entry specified by mac_addr
539 * @n_acl_entries: Number of MAC address entries passed 539 * @n_acl_entries: Number of MAC address entries passed
540 * @mac_addrs: List of MAC addresses of stations to be used for ACL 540 * @mac_addrs: List of MAC addresses of stations to be used for ACL
541 */ 541 */
@@ -666,6 +666,8 @@ struct station_parameters {
666 * @STATION_INFO_INACTIVE_TIME: @inactive_time filled 666 * @STATION_INFO_INACTIVE_TIME: @inactive_time filled
667 * @STATION_INFO_RX_BYTES: @rx_bytes filled 667 * @STATION_INFO_RX_BYTES: @rx_bytes filled
668 * @STATION_INFO_TX_BYTES: @tx_bytes filled 668 * @STATION_INFO_TX_BYTES: @tx_bytes filled
669 * @STATION_INFO_RX_BYTES64: @rx_bytes filled with 64-bit value
670 * @STATION_INFO_TX_BYTES64: @tx_bytes filled with 64-bit value
669 * @STATION_INFO_LLID: @llid filled 671 * @STATION_INFO_LLID: @llid filled
670 * @STATION_INFO_PLID: @plid filled 672 * @STATION_INFO_PLID: @plid filled
671 * @STATION_INFO_PLINK_STATE: @plink_state filled 673 * @STATION_INFO_PLINK_STATE: @plink_state filled
@@ -674,8 +676,6 @@ struct station_parameters {
674 * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) 676 * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs)
675 * @STATION_INFO_RX_PACKETS: @rx_packets filled with 32-bit value 677 * @STATION_INFO_RX_PACKETS: @rx_packets filled with 32-bit value
676 * @STATION_INFO_TX_PACKETS: @tx_packets filled with 32-bit value 678 * @STATION_INFO_TX_PACKETS: @tx_packets filled with 32-bit value
677 * @STATION_INFO_RX_PACKETS64: @rx_packets filled with 64-bit value
678 * @STATION_INFO_TX_PACKETS64: @tx_packets filled with 64-bit value
679 * @STATION_INFO_TX_RETRIES: @tx_retries filled 679 * @STATION_INFO_TX_RETRIES: @tx_retries filled
680 * @STATION_INFO_TX_FAILED: @tx_failed filled 680 * @STATION_INFO_TX_FAILED: @tx_failed filled
681 * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled 681 * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
@@ -1226,6 +1226,7 @@ struct cfg80211_match_set {
1226 * @n_match_sets: number of match sets 1226 * @n_match_sets: number of match sets
1227 * @wiphy: the wiphy this was for 1227 * @wiphy: the wiphy this was for
1228 * @dev: the interface 1228 * @dev: the interface
1229 * @scan_start: start time of the scheduled scan
1229 * @channels: channels to scan 1230 * @channels: channels to scan
1230 * @rssi_thold: don't report scan results below this threshold (in s32 dBm) 1231 * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
1231 */ 1232 */
@@ -1265,11 +1266,13 @@ enum cfg80211_signal_type {
1265 1266
1266/** 1267/**
1267 * struct cfg80211_bss_ie_data - BSS entry IE data 1268 * struct cfg80211_bss_ie_data - BSS entry IE data
1269 * @tsf: TSF contained in the frame that carried these IEs
1268 * @rcu_head: internal use, for freeing 1270 * @rcu_head: internal use, for freeing
1269 * @len: length of the IEs 1271 * @len: length of the IEs
1270 * @data: IE data 1272 * @data: IE data
1271 */ 1273 */
1272struct cfg80211_bss_ies { 1274struct cfg80211_bss_ies {
1275 u64 tsf;
1273 struct rcu_head rcu_head; 1276 struct rcu_head rcu_head;
1274 int len; 1277 int len;
1275 u8 data[]; 1278 u8 data[];
@@ -1283,27 +1286,33 @@ struct cfg80211_bss_ies {
1283 * 1286 *
1284 * @channel: channel this BSS is on 1287 * @channel: channel this BSS is on
1285 * @bssid: BSSID of the BSS 1288 * @bssid: BSSID of the BSS
1286 * @tsf: timestamp of last received update
1287 * @beacon_interval: the beacon interval as from the frame 1289 * @beacon_interval: the beacon interval as from the frame
1288 * @capability: the capability field in host byte order 1290 * @capability: the capability field in host byte order
1289 * @ies: the information elements (Note that there 1291 * @ies: the information elements (Note that there is no guarantee that these
1290 * is no guarantee that these are well-formed!); this is a pointer to 1292 * are well-formed!); this is a pointer to either the beacon_ies or
1291 * either the beacon_ies or proberesp_ies depending on whether Probe 1293 * proberesp_ies depending on whether Probe Response frame has been
1292 * Response frame has been received 1294 * received. It is always non-%NULL.
1293 * @beacon_ies: the information elements from the last Beacon frame 1295 * @beacon_ies: the information elements from the last Beacon frame
1296 * (implementation note: if @hidden_beacon_bss is set this struct doesn't
1297 * own the beacon_ies, but they're just pointers to the ones from the
1298 * @hidden_beacon_bss struct)
1294 * @proberesp_ies: the information elements from the last Probe Response frame 1299 * @proberesp_ies: the information elements from the last Probe Response frame
1300 * @hidden_beacon_bss: in case this BSS struct represents a probe response from
1301 * a BSS that hides the SSID in its beacon, this points to the BSS struct
1302 * that holds the beacon data. @beacon_ies is still valid, of course, and
1303 * points to the same data as hidden_beacon_bss->beacon_ies in that case.
1295 * @signal: signal strength value (type depends on the wiphy's signal_type) 1304 * @signal: signal strength value (type depends on the wiphy's signal_type)
1296 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes 1305 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
1297 */ 1306 */
1298struct cfg80211_bss { 1307struct cfg80211_bss {
1299 u64 tsf;
1300
1301 struct ieee80211_channel *channel; 1308 struct ieee80211_channel *channel;
1302 1309
1303 const struct cfg80211_bss_ies __rcu *ies; 1310 const struct cfg80211_bss_ies __rcu *ies;
1304 const struct cfg80211_bss_ies __rcu *beacon_ies; 1311 const struct cfg80211_bss_ies __rcu *beacon_ies;
1305 const struct cfg80211_bss_ies __rcu *proberesp_ies; 1312 const struct cfg80211_bss_ies __rcu *proberesp_ies;
1306 1313
1314 struct cfg80211_bss *hidden_beacon_bss;
1315
1307 s32 signal; 1316 s32 signal;
1308 1317
1309 u16 beacon_interval; 1318 u16 beacon_interval;
@@ -1404,6 +1413,8 @@ struct cfg80211_assoc_request {
1404 * @ie: Extra IEs to add to Deauthentication frame or %NULL 1413 * @ie: Extra IEs to add to Deauthentication frame or %NULL
1405 * @ie_len: Length of ie buffer in octets 1414 * @ie_len: Length of ie buffer in octets
1406 * @reason_code: The reason code for the deauthentication 1415 * @reason_code: The reason code for the deauthentication
1416 * @local_state_change: if set, change local state only and
1417 * do not set a deauth frame
1407 */ 1418 */
1408struct cfg80211_deauth_request { 1419struct cfg80211_deauth_request {
1409 const u8 *bssid; 1420 const u8 *bssid;
@@ -2629,7 +2640,6 @@ struct cfg80211_cached_keys;
2629 * the user-set AP, monitor and WDS channel 2640 * the user-set AP, monitor and WDS channel
2630 * @preset_chan: (private) Used by the internal configuration code to 2641 * @preset_chan: (private) Used by the internal configuration code to
2631 * track the channel to be used for AP later 2642 * track the channel to be used for AP later
2632 * @preset_chantype: (private) the corresponding channel type
2633 * @bssid: (private) Used by the internal configuration code 2643 * @bssid: (private) Used by the internal configuration code
2634 * @ssid: (private) Used by the internal configuration code 2644 * @ssid: (private) Used by the internal configuration code
2635 * @ssid_len: (private) Used by the internal configuration code 2645 * @ssid_len: (private) Used by the internal configuration code
@@ -3166,19 +3176,21 @@ cfg80211_get_ibss(struct wiphy *wiphy,
3166 3176
3167/** 3177/**
3168 * cfg80211_ref_bss - reference BSS struct 3178 * cfg80211_ref_bss - reference BSS struct
3179 * @wiphy: the wiphy this BSS struct belongs to
3169 * @bss: the BSS struct to reference 3180 * @bss: the BSS struct to reference
3170 * 3181 *
3171 * Increments the refcount of the given BSS struct. 3182 * Increments the refcount of the given BSS struct.
3172 */ 3183 */
3173void cfg80211_ref_bss(struct cfg80211_bss *bss); 3184void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
3174 3185
3175/** 3186/**
3176 * cfg80211_put_bss - unref BSS struct 3187 * cfg80211_put_bss - unref BSS struct
3188 * @wiphy: the wiphy this BSS struct belongs to
3177 * @bss: the BSS struct 3189 * @bss: the BSS struct
3178 * 3190 *
3179 * Decrements the refcount of the given BSS struct. 3191 * Decrements the refcount of the given BSS struct.
3180 */ 3192 */
3181void cfg80211_put_bss(struct cfg80211_bss *bss); 3193void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
3182 3194
3183/** 3195/**
3184 * cfg80211_unlink_bss - unlink BSS from internal data structures 3196 * cfg80211_unlink_bss - unlink BSS from internal data structures
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7da11211825d..0eaa9092364b 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -277,9 +277,16 @@ enum ieee80211_rssi_event {
277 * valid in station mode only if after the driver was notified 277 * valid in station mode only if after the driver was notified
278 * with the %BSS_CHANGED_DTIM_PERIOD flag, will be non-zero then. 278 * with the %BSS_CHANGED_DTIM_PERIOD flag, will be non-zero then.
279 * @sync_tsf: last beacon's/probe response's TSF timestamp (could be old 279 * @sync_tsf: last beacon's/probe response's TSF timestamp (could be old
280 * as it may have been received during scanning long ago) 280 * as it may have been received during scanning long ago). If the
281 * HW flag %IEEE80211_HW_TIMING_BEACON_ONLY is set, then this can
282 * only come from a beacon, but might not become valid until after
283 * association when a beacon is received (which is notified with the
284 * %BSS_CHANGED_DTIM flag.)
281 * @sync_device_ts: the device timestamp corresponding to the sync_tsf, 285 * @sync_device_ts: the device timestamp corresponding to the sync_tsf,
282 * the driver/device can use this to calculate synchronisation 286 * the driver/device can use this to calculate synchronisation
287 * (see @sync_tsf)
288 * @sync_dtim_count: Only valid when %IEEE80211_HW_TIMING_BEACON_ONLY
289 * is requested, see @sync_tsf/@sync_device_ts.
283 * @beacon_int: beacon interval 290 * @beacon_int: beacon interval
284 * @assoc_capability: capabilities taken from assoc resp 291 * @assoc_capability: capabilities taken from assoc resp
285 * @basic_rates: bitmap of basic rates, each bit stands for an 292 * @basic_rates: bitmap of basic rates, each bit stands for an
@@ -331,6 +338,7 @@ struct ieee80211_bss_conf {
331 u16 assoc_capability; 338 u16 assoc_capability;
332 u64 sync_tsf; 339 u64 sync_tsf;
333 u32 sync_device_ts; 340 u32 sync_device_ts;
341 u8 sync_dtim_count;
334 u32 basic_rates; 342 u32 basic_rates;
335 int mcast_rate[IEEE80211_NUM_BANDS]; 343 int mcast_rate[IEEE80211_NUM_BANDS];
336 u16 ht_operation_mode; 344 u16 ht_operation_mode;
@@ -391,6 +399,9 @@ struct ieee80211_bss_conf {
391 * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be 399 * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be
392 * set by rate control algorithms to indicate probe rate, will 400 * set by rate control algorithms to indicate probe rate, will
393 * be cleared for fragmented frames (except on the last fragment) 401 * be cleared for fragmented frames (except on the last fragment)
402 * @IEEE80211_TX_INTFL_OFFCHAN_TX_OK: Internal to mac80211. Used to indicate
403 * that a frame can be transmitted while the queues are stopped for
404 * off-channel operation.
394 * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211, 405 * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211,
395 * used to indicate that a pending frame requires TX processing before 406 * used to indicate that a pending frame requires TX processing before
396 * it can be sent out. 407 * it can be sent out.
@@ -456,6 +467,7 @@ enum mac80211_tx_control_flags {
456 IEEE80211_TX_STAT_AMPDU = BIT(10), 467 IEEE80211_TX_STAT_AMPDU = BIT(10),
457 IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11), 468 IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11),
458 IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), 469 IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12),
470 IEEE80211_TX_INTFL_OFFCHAN_TX_OK = BIT(13),
459 IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14), 471 IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14),
460 IEEE80211_TX_INTFL_RETRIED = BIT(15), 472 IEEE80211_TX_INTFL_RETRIED = BIT(15),
461 IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16), 473 IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16),
@@ -1355,10 +1367,6 @@ struct ieee80211_tx_control {
1355 * setup strictly in HW. mac80211 should not attempt to do this in 1367 * setup strictly in HW. mac80211 should not attempt to do this in
1356 * software. 1368 * software.
1357 * 1369 *
1358 * @IEEE80211_HW_SCAN_WHILE_IDLE: The device can do hw scan while
1359 * being idle (i.e. mac80211 doesn't have to go idle-off during the
1360 * the scan).
1361 *
1362 * @IEEE80211_HW_WANT_MONITOR_VIF: The driver would like to be informed of 1370 * @IEEE80211_HW_WANT_MONITOR_VIF: The driver would like to be informed of
1363 * a virtual monitor interface when monitor interfaces are the only 1371 * a virtual monitor interface when monitor interfaces are the only
1364 * active interfaces. 1372 * active interfaces.
@@ -1371,6 +1379,9 @@ struct ieee80211_tx_control {
1371 * @IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF: Use the P2P Device address for any 1379 * @IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF: Use the P2P Device address for any
1372 * P2P Interface. This will be honoured even if more than one interface 1380 * P2P Interface. This will be honoured even if more than one interface
1373 * is supported. 1381 * is supported.
1382 *
1383 * @IEEE80211_HW_TIMING_BEACON_ONLY: Use sync timing from beacon frames
1384 * only, to allow getting TBTT of a DTIM beacon.
1374 */ 1385 */
1375enum ieee80211_hw_flags { 1386enum ieee80211_hw_flags {
1376 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, 1387 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -1397,8 +1408,8 @@ enum ieee80211_hw_flags {
1397 IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21, 1408 IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21,
1398 IEEE80211_HW_AP_LINK_PS = 1<<22, 1409 IEEE80211_HW_AP_LINK_PS = 1<<22,
1399 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23, 1410 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23,
1400 IEEE80211_HW_SCAN_WHILE_IDLE = 1<<24,
1401 IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25, 1411 IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25,
1412 IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26,
1402}; 1413};
1403 1414
1404/** 1415/**
@@ -1683,15 +1694,6 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
1683 * dynamic PS feature in stack and will just keep %IEEE80211_CONF_PS 1694 * dynamic PS feature in stack and will just keep %IEEE80211_CONF_PS
1684 * enabled whenever user has enabled powersave. 1695 * enabled whenever user has enabled powersave.
1685 * 1696 *
1686 * Some hardware need to toggle a single shared antenna between WLAN and
1687 * Bluetooth to facilitate co-existence. These types of hardware set
1688 * limitations on the use of host controlled dynamic powersave whenever there
1689 * is simultaneous WLAN and Bluetooth traffic. For these types of hardware, the
1690 * driver may request temporarily going into full power save, in order to
1691 * enable toggling the antenna between BT and WLAN. If the driver requests
1692 * disabling dynamic powersave, the @dynamic_ps_timeout value will be
1693 * temporarily set to zero until the driver re-enables dynamic powersave.
1694 *
1695 * Driver informs U-APSD client support by enabling 1697 * Driver informs U-APSD client support by enabling
1696 * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the 1698 * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the
1697 * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS 1699 * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS
@@ -2167,6 +2169,18 @@ enum ieee80211_rate_control_changed {
2167 * MAC address of the device going away. 2169 * MAC address of the device going away.
2168 * Hence, this callback must be implemented. It can sleep. 2170 * Hence, this callback must be implemented. It can sleep.
2169 * 2171 *
2172 * @add_interface_debugfs: Drivers can use this callback to add debugfs files
2173 * when a vif is added to mac80211. This callback and
2174 * @remove_interface_debugfs should be within a CONFIG_MAC80211_DEBUGFS
2175 * conditional. @remove_interface_debugfs must be provided for cleanup.
2176 * This callback can sleep.
2177 *
2178 * @remove_interface_debugfs: Remove the debugfs files which were added using
2179 * @add_interface_debugfs. This callback must remove all debugfs entries
2180 * that were added because mac80211 only removes interface debugfs when the
2181 * interface is destroyed, not when it is removed from the driver.
2182 * This callback can sleep.
2183 *
2170 * @config: Handler for configuration requests. IEEE 802.11 code calls this 2184 * @config: Handler for configuration requests. IEEE 802.11 code calls this
2171 * function to change hardware configuration, e.g., channel. 2185 * function to change hardware configuration, e.g., channel.
2172 * This function should never fail but returns a negative error code 2186 * This function should never fail but returns a negative error code
@@ -2580,6 +2594,12 @@ struct ieee80211_ops {
2580 struct ieee80211_vif *vif, 2594 struct ieee80211_vif *vif,
2581 struct ieee80211_sta *sta, 2595 struct ieee80211_sta *sta,
2582 struct dentry *dir); 2596 struct dentry *dir);
2597 void (*add_interface_debugfs)(struct ieee80211_hw *hw,
2598 struct ieee80211_vif *vif,
2599 struct dentry *dir);
2600 void (*remove_interface_debugfs)(struct ieee80211_hw *hw,
2601 struct ieee80211_vif *vif,
2602 struct dentry *dir);
2583#endif 2603#endif
2584 void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2604 void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2585 enum sta_notify_cmd, struct ieee80211_sta *sta); 2605 enum sta_notify_cmd, struct ieee80211_sta *sta);
@@ -3909,36 +3929,6 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif);
3909void ieee80211_resume_disconnect(struct ieee80211_vif *vif); 3929void ieee80211_resume_disconnect(struct ieee80211_vif *vif);
3910 3930
3911/** 3931/**
3912 * ieee80211_disable_dyn_ps - force mac80211 to temporarily disable dynamic psm
3913 *
3914 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
3915 *
3916 * Some hardware require full power save to manage simultaneous BT traffic
3917 * on the WLAN frequency. Full PSM is required periodically, whenever there are
3918 * burst of BT traffic. The hardware gets information of BT traffic via
3919 * hardware co-existence lines, and consequentially requests mac80211 to
3920 * (temporarily) enter full psm.
3921 * This function will only temporarily disable dynamic PS, not enable PSM if
3922 * it was not already enabled.
3923 * The driver must make sure to re-enable dynamic PS using
3924 * ieee80211_enable_dyn_ps() if the driver has disabled it.
3925 *
3926 */
3927void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif);
3928
3929/**
3930 * ieee80211_enable_dyn_ps - restore dynamic psm after being disabled
3931 *
3932 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
3933 *
3934 * This function restores dynamic PS after being temporarily disabled via
3935 * ieee80211_disable_dyn_ps(). Each ieee80211_disable_dyn_ps() call must
3936 * be coupled with an eventual call to this function.
3937 *
3938 */
3939void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif);
3940
3941/**
3942 * ieee80211_cqm_rssi_notify - inform a configured connection quality monitoring 3932 * ieee80211_cqm_rssi_notify - inform a configured connection quality monitoring
3943 * rssi threshold triggered 3933 * rssi threshold triggered
3944 * 3934 *
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f4f7e7691077..e3dec80cf617 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -933,6 +933,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
933 IEEE80211_CHANCTX_SHARED); 933 IEEE80211_CHANCTX_SHARED);
934 if (err) 934 if (err)
935 return err; 935 return err;
936 ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
936 937
937 /* 938 /*
938 * Apply control port protocol, this allows us to 939 * Apply control port protocol, this allows us to
@@ -1047,6 +1048,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1047 local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf); 1048 local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
1048 skb_queue_purge(&sdata->u.ap.ps.bc_buf); 1049 skb_queue_purge(&sdata->u.ap.ps.bc_buf);
1049 1050
1051 ieee80211_vif_copy_chanctx_to_vlans(sdata, true);
1050 ieee80211_vif_release_channel(sdata); 1052 ieee80211_vif_release_channel(sdata);
1051 1053
1052 return 0; 1054 return 0;
@@ -2747,7 +2749,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2747 goto out_unlock; 2749 goto out_unlock;
2748 } 2750 }
2749 2751
2750 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; 2752 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN |
2753 IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
2751 if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) 2754 if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
2752 IEEE80211_SKB_CB(skb)->hw_queue = 2755 IEEE80211_SKB_CB(skb)->hw_queue =
2753 local->hw.offchannel_tx_hw_queue; 2756 local->hw.offchannel_tx_hw_queue;
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 1bfe0a8b19d2..038f249966d6 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -91,6 +91,10 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
91 91
92 list_add_rcu(&ctx->list, &local->chanctx_list); 92 list_add_rcu(&ctx->list, &local->chanctx_list);
93 93
94 mutex_lock(&local->mtx);
95 ieee80211_recalc_idle(local);
96 mutex_unlock(&local->mtx);
97
94 return ctx; 98 return ctx;
95} 99}
96 100
@@ -110,6 +114,10 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local,
110 114
111 list_del_rcu(&ctx->list); 115 list_del_rcu(&ctx->list);
112 kfree_rcu(ctx, rcu_head); 116 kfree_rcu(ctx, rcu_head);
117
118 mutex_lock(&local->mtx);
119 ieee80211_recalc_idle(local);
120 mutex_unlock(&local->mtx);
113} 121}
114 122
115static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, 123static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
@@ -128,6 +136,8 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
128 ctx->refcount++; 136 ctx->refcount++;
129 137
130 ieee80211_recalc_txpower(sdata); 138 ieee80211_recalc_txpower(sdata);
139 sdata->vif.bss_conf.idle = false;
140 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
131 141
132 return 0; 142 return 0;
133} 143}
@@ -175,6 +185,9 @@ static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
175 ctx->refcount--; 185 ctx->refcount--;
176 rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); 186 rcu_assign_pointer(sdata->vif.chanctx_conf, NULL);
177 187
188 sdata->vif.bss_conf.idle = true;
189 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
190
178 drv_unassign_vif_chanctx(local, sdata, ctx); 191 drv_unassign_vif_chanctx(local, sdata, ctx);
179 192
180 if (ctx->refcount > 0) { 193 if (ctx->refcount > 0) {
@@ -198,15 +211,6 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
198 211
199 ctx = container_of(conf, struct ieee80211_chanctx, conf); 212 ctx = container_of(conf, struct ieee80211_chanctx, conf);
200 213
201 if (sdata->vif.type == NL80211_IFTYPE_AP) {
202 struct ieee80211_sub_if_data *vlan;
203
204 /* for the VLAN list */
205 ASSERT_RTNL();
206 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
207 rcu_assign_pointer(vlan->vif.chanctx_conf, NULL);
208 }
209
210 ieee80211_unassign_vif_chanctx(sdata, ctx); 214 ieee80211_unassign_vif_chanctx(sdata, ctx);
211 if (ctx->refcount == 0) 215 if (ctx->refcount == 0)
212 ieee80211_free_chanctx(local, ctx); 216 ieee80211_free_chanctx(local, ctx);
@@ -326,15 +330,6 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
326 goto out; 330 goto out;
327 } 331 }
328 332
329 if (sdata->vif.type == NL80211_IFTYPE_AP) {
330 struct ieee80211_sub_if_data *vlan;
331
332 /* for the VLAN list */
333 ASSERT_RTNL();
334 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
335 rcu_assign_pointer(vlan->vif.chanctx_conf, &ctx->conf);
336 }
337
338 ieee80211_recalc_smps_chanctx(local, ctx); 333 ieee80211_recalc_smps_chanctx(local, ctx);
339 out: 334 out:
340 mutex_unlock(&local->chanctx_mtx); 335 mutex_unlock(&local->chanctx_mtx);
@@ -369,6 +364,40 @@ void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata)
369 mutex_unlock(&local->chanctx_mtx); 364 mutex_unlock(&local->chanctx_mtx);
370} 365}
371 366
367void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
368 bool clear)
369{
370 struct ieee80211_local *local = sdata->local;
371 struct ieee80211_sub_if_data *vlan;
372 struct ieee80211_chanctx_conf *conf;
373
374 ASSERT_RTNL();
375
376 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
377 return;
378
379 mutex_lock(&local->chanctx_mtx);
380
381 /*
382 * Check that conf exists, even when clearing this function
383 * must be called with the AP's channel context still there
384 * as it would otherwise cause VLANs to have an invalid
385 * channel context pointer for a while, possibly pointing
386 * to a channel context that has already been freed.
387 */
388 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
389 lockdep_is_held(&local->chanctx_mtx));
390 WARN_ON(!conf);
391
392 if (clear)
393 conf = NULL;
394
395 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
396 rcu_assign_pointer(vlan->vif.chanctx_conf, conf);
397
398 mutex_unlock(&local->chanctx_mtx);
399}
400
372void ieee80211_iter_chan_contexts_atomic( 401void ieee80211_iter_chan_contexts_atomic(
373 struct ieee80211_hw *hw, 402 struct ieee80211_hw *hw,
374 void (*iter)(struct ieee80211_hw *hw, 403 void (*iter)(struct ieee80211_hw *hw,
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 8e6040998ba6..b0e32d628114 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -151,8 +151,6 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf,
151 sf += snprintf(buf + sf, mxln - sf, "AP_LINK_PS\n"); 151 sf += snprintf(buf + sf, mxln - sf, "AP_LINK_PS\n");
152 if (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW) 152 if (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)
153 sf += snprintf(buf + sf, mxln - sf, "TX_AMPDU_SETUP_IN_HW\n"); 153 sf += snprintf(buf + sf, mxln - sf, "TX_AMPDU_SETUP_IN_HW\n");
154 if (local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)
155 sf += snprintf(buf + sf, mxln - sf, "SCAN_WHILE_IDLE\n");
156 154
157 rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 155 rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
158 kfree(buf); 156 kfree(buf);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 434b3c4f31b5..2b08b9982d06 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -528,6 +528,43 @@ static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
528 local->ops->sta_remove_debugfs(&local->hw, &sdata->vif, 528 local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
529 sta, dir); 529 sta, dir);
530} 530}
531
532static inline
533void drv_add_interface_debugfs(struct ieee80211_local *local,
534 struct ieee80211_sub_if_data *sdata)
535{
536 might_sleep();
537
538 check_sdata_in_driver(sdata);
539
540 if (!local->ops->add_interface_debugfs)
541 return;
542
543 local->ops->add_interface_debugfs(&local->hw, &sdata->vif,
544 sdata->debugfs.dir);
545}
546
547static inline
548void drv_remove_interface_debugfs(struct ieee80211_local *local,
549 struct ieee80211_sub_if_data *sdata)
550{
551 might_sleep();
552
553 check_sdata_in_driver(sdata);
554
555 if (!local->ops->remove_interface_debugfs)
556 return;
557
558 local->ops->remove_interface_debugfs(&local->hw, &sdata->vif,
559 sdata->debugfs.dir);
560}
561#else
562static inline
563void drv_add_interface_debugfs(struct ieee80211_local *local,
564 struct ieee80211_sub_if_data *sdata) {}
565static inline
566void drv_remove_interface_debugfs(struct ieee80211_local *local,
567 struct ieee80211_sub_if_data *sdata) {}
531#endif 568#endif
532 569
533static inline __must_check 570static inline __must_check
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index a54c8248e0e0..2db1f2b90bfe 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -228,7 +228,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
228 228
229 bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan, 229 bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan,
230 mgmt, skb->len, 0, GFP_KERNEL); 230 mgmt, skb->len, 0, GFP_KERNEL);
231 cfg80211_put_bss(bss); 231 cfg80211_put_bss(local->hw.wiphy, bss);
232 netif_carrier_on(sdata->dev); 232 netif_carrier_on(sdata->dev);
233 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); 233 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
234} 234}
@@ -242,6 +242,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
242 u32 basic_rates; 242 u32 basic_rates;
243 int i, j; 243 int i, j;
244 u16 beacon_int = cbss->beacon_interval; 244 u16 beacon_int = cbss->beacon_interval;
245 const struct cfg80211_bss_ies *ies;
246 u64 tsf;
245 247
246 lockdep_assert_held(&sdata->u.ibss.mtx); 248 lockdep_assert_held(&sdata->u.ibss.mtx);
247 249
@@ -265,13 +267,17 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
265 } 267 }
266 } 268 }
267 269
270 rcu_read_lock();
271 ies = rcu_dereference(cbss->ies);
272 tsf = ies->tsf;
273 rcu_read_unlock();
274
268 __ieee80211_sta_join_ibss(sdata, cbss->bssid, 275 __ieee80211_sta_join_ibss(sdata, cbss->bssid,
269 beacon_int, 276 beacon_int,
270 cbss->channel, 277 cbss->channel,
271 basic_rates, 278 basic_rates,
272 cbss->capability, 279 cbss->capability,
273 cbss->tsf, 280 tsf, false);
274 false);
275} 281}
276 282
277static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, 283static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
@@ -535,8 +541,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
535 541
536 cbss = container_of((void *)bss, struct cfg80211_bss, priv); 542 cbss = container_of((void *)bss, struct cfg80211_bss, priv);
537 543
538 /* was just updated in ieee80211_bss_info_update */ 544 /* same for beacon and probe response */
539 beacon_timestamp = cbss->tsf; 545 beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
540 546
541 /* check if we need to merge IBSS */ 547 /* check if we need to merge IBSS */
542 548
@@ -1102,10 +1108,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1102 1108
1103 mutex_unlock(&sdata->u.ibss.mtx); 1109 mutex_unlock(&sdata->u.ibss.mtx);
1104 1110
1105 mutex_lock(&sdata->local->mtx);
1106 ieee80211_recalc_idle(sdata->local);
1107 mutex_unlock(&sdata->local->mtx);
1108
1109 /* 1111 /*
1110 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is 1112 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is
1111 * reserved, but an HT STA shall protect HT transmissions as though 1113 * reserved, but an HT STA shall protect HT transmissions as though
@@ -1159,7 +1161,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1159 1161
1160 if (cbss) { 1162 if (cbss) {
1161 cfg80211_unlink_bss(local->hw.wiphy, cbss); 1163 cfg80211_unlink_bss(local->hw.wiphy, cbss);
1162 cfg80211_put_bss(cbss); 1164 cfg80211_put_bss(local->hw.wiphy, cbss);
1163 } 1165 }
1164 } 1166 }
1165 1167
@@ -1203,9 +1205,5 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1203 1205
1204 mutex_unlock(&sdata->u.ibss.mtx); 1206 mutex_unlock(&sdata->u.ibss.mtx);
1205 1207
1206 mutex_lock(&local->mtx);
1207 ieee80211_recalc_idle(sdata->local);
1208 mutex_unlock(&local->mtx);
1209
1210 return 0; 1208 return 0;
1211} 1209}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 5fe9db707880..76cdcfcd614c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -86,7 +86,7 @@ struct ieee80211_fragment_entry {
86 86
87 87
88struct ieee80211_bss { 88struct ieee80211_bss {
89 u32 device_ts; 89 u32 device_ts_beacon, device_ts_presp;
90 90
91 bool wmm_used; 91 bool wmm_used;
92 bool uapsd_supported; 92 bool uapsd_supported;
@@ -689,9 +689,6 @@ struct ieee80211_sub_if_data {
689 689
690 char name[IFNAMSIZ]; 690 char name[IFNAMSIZ];
691 691
692 /* to detect idle changes */
693 bool old_idle;
694
695 /* Fragment table for host-based reassembly */ 692 /* Fragment table for host-based reassembly */
696 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; 693 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
697 unsigned int fragment_next; 694 unsigned int fragment_next;
@@ -812,6 +809,7 @@ enum queue_stop_reason {
812 IEEE80211_QUEUE_STOP_REASON_AGGREGATION, 809 IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
813 IEEE80211_QUEUE_STOP_REASON_SUSPEND, 810 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
814 IEEE80211_QUEUE_STOP_REASON_SKB_ADD, 811 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
812 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
815}; 813};
816 814
817#ifdef CONFIG_MAC80211_LEDS 815#ifdef CONFIG_MAC80211_LEDS
@@ -958,14 +956,7 @@ struct ieee80211_local {
958 struct sk_buff_head skb_queue; 956 struct sk_buff_head skb_queue;
959 struct sk_buff_head skb_queue_unreliable; 957 struct sk_buff_head skb_queue_unreliable;
960 958
961 /* 959 spinlock_t rx_path_lock;
962 * Internal FIFO queue which is shared between multiple rx path
963 * stages. Its main task is to provide a serialization mechanism,
964 * so all rx handlers can enjoy having exclusive access to their
965 * private data structures.
966 */
967 struct sk_buff_head rx_skb_queue;
968 bool running_rx_handler; /* protected by rx_skb_queue.lock */
969 960
970 /* Station data */ 961 /* Station data */
971 /* 962 /*
@@ -1106,8 +1097,6 @@ struct ieee80211_local {
1106 * this will override whatever chosen by mac80211 internally. 1097 * this will override whatever chosen by mac80211 internally.
1107 */ 1098 */
1108 int dynamic_ps_forced_timeout; 1099 int dynamic_ps_forced_timeout;
1109 int dynamic_ps_user_timeout;
1110 bool disable_dynamic_ps;
1111 1100
1112 int user_power_level; /* in dBm, for all interfaces */ 1101 int user_power_level; /* in dBm, for all interfaces */
1113 1102
@@ -1612,6 +1601,8 @@ ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
1612 enum ieee80211_chanctx_mode mode); 1601 enum ieee80211_chanctx_mode mode);
1613void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); 1602void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
1614void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); 1603void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
1604void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
1605 bool clear);
1615 1606
1616void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, 1607void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
1617 struct ieee80211_chanctx *chanctx); 1608 struct ieee80211_chanctx *chanctx);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 0a36dc6346bb..40ff0307d089 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -78,8 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
78 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); 78 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
79} 79}
80 80
81static u32 ieee80211_idle_off(struct ieee80211_local *local, 81static u32 ieee80211_idle_off(struct ieee80211_local *local)
82 const char *reason)
83{ 82{
84 if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) 83 if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
85 return 0; 84 return 0;
@@ -99,110 +98,45 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local)
99 return IEEE80211_CONF_CHANGE_IDLE; 98 return IEEE80211_CONF_CHANGE_IDLE;
100} 99}
101 100
102static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) 101void ieee80211_recalc_idle(struct ieee80211_local *local)
103{ 102{
104 struct ieee80211_sub_if_data *sdata; 103 bool working = false, scanning, active;
105 int count = 0;
106 bool working = false, scanning = false;
107 unsigned int led_trig_start = 0, led_trig_stop = 0; 104 unsigned int led_trig_start = 0, led_trig_stop = 0;
108 struct ieee80211_roc_work *roc; 105 struct ieee80211_roc_work *roc;
106 u32 change;
109 107
110#ifdef CONFIG_PROVE_LOCKING
111 WARN_ON(debug_locks && !lockdep_rtnl_is_held() &&
112 !lockdep_is_held(&local->iflist_mtx));
113#endif
114 lockdep_assert_held(&local->mtx); 108 lockdep_assert_held(&local->mtx);
115 109
116 list_for_each_entry(sdata, &local->interfaces, list) { 110 active = !list_empty(&local->chanctx_list);
117 if (!ieee80211_sdata_running(sdata)) {
118 sdata->vif.bss_conf.idle = true;
119 continue;
120 }
121
122 sdata->old_idle = sdata->vif.bss_conf.idle;
123
124 /* do not count disabled managed interfaces */
125 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
126 !sdata->u.mgd.associated &&
127 !sdata->u.mgd.auth_data &&
128 !sdata->u.mgd.assoc_data) {
129 sdata->vif.bss_conf.idle = true;
130 continue;
131 }
132 /* do not count unused IBSS interfaces */
133 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
134 !sdata->u.ibss.ssid_len) {
135 sdata->vif.bss_conf.idle = true;
136 continue;
137 }
138
139 if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
140 continue;
141
142 /* count everything else */
143 sdata->vif.bss_conf.idle = false;
144 count++;
145 }
146 111
147 if (!local->ops->remain_on_channel) { 112 if (!local->ops->remain_on_channel) {
148 list_for_each_entry(roc, &local->roc_list, list) { 113 list_for_each_entry(roc, &local->roc_list, list) {
149 working = true; 114 working = true;
150 roc->sdata->vif.bss_conf.idle = false; 115 break;
151 } 116 }
152 } 117 }
153 118
154 sdata = rcu_dereference_protected(local->scan_sdata, 119 scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
155 lockdep_is_held(&local->mtx)); 120 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning);
156 if (sdata && !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) {
157 scanning = true;
158 sdata->vif.bss_conf.idle = false;
159 }
160
161 list_for_each_entry(sdata, &local->interfaces, list) {
162 if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
163 sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
164 sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
165 continue;
166 if (sdata->old_idle == sdata->vif.bss_conf.idle)
167 continue;
168 if (!ieee80211_sdata_running(sdata))
169 continue;
170 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
171 }
172 121
173 if (working || scanning) 122 if (working || scanning)
174 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; 123 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK;
175 else 124 else
176 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; 125 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK;
177 126
178 if (count) 127 if (active)
179 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; 128 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
180 else 129 else
181 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; 130 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
182 131
183 ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); 132 ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
184 133
185 if (working) 134 if (working || scanning || active)
186 return ieee80211_idle_off(local, "working"); 135 change = ieee80211_idle_off(local);
187 if (scanning)
188 return ieee80211_idle_off(local, "scanning");
189 if (!count)
190 return ieee80211_idle_on(local);
191 else 136 else
192 return ieee80211_idle_off(local, "in use"); 137 change = ieee80211_idle_on(local);
193 138 if (change)
194 return 0; 139 ieee80211_hw_config(local, change);
195}
196
197void ieee80211_recalc_idle(struct ieee80211_local *local)
198{
199 u32 chg;
200
201 mutex_lock(&local->iflist_mtx);
202 chg = __ieee80211_recalc_idle(local);
203 mutex_unlock(&local->iflist_mtx);
204 if (chg)
205 ieee80211_hw_config(local, chg);
206} 140}
207 141
208static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) 142static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
@@ -621,6 +555,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
621 goto err_del_interface; 555 goto err_del_interface;
622 } 556 }
623 557
558 drv_add_interface_debugfs(local, sdata);
559
624 if (sdata->vif.type == NL80211_IFTYPE_AP) { 560 if (sdata->vif.type == NL80211_IFTYPE_AP) {
625 local->fif_pspoll++; 561 local->fif_pspoll++;
626 local->fif_probe_req++; 562 local->fif_probe_req++;
@@ -694,10 +630,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
694 if (sdata->flags & IEEE80211_SDATA_PROMISC) 630 if (sdata->flags & IEEE80211_SDATA_PROMISC)
695 atomic_inc(&local->iff_promiscs); 631 atomic_inc(&local->iff_promiscs);
696 632
697 mutex_lock(&local->mtx);
698 hw_reconf_flags |= __ieee80211_recalc_idle(local);
699 mutex_unlock(&local->mtx);
700
701 if (coming_up) 633 if (coming_up)
702 local->open_count++; 634 local->open_count++;
703 635
@@ -882,16 +814,14 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
882 */ 814 */
883 ieee80211_free_keys(sdata); 815 ieee80211_free_keys(sdata);
884 816
817 drv_remove_interface_debugfs(local, sdata);
818
885 if (going_down) 819 if (going_down)
886 drv_remove_interface(local, sdata); 820 drv_remove_interface(local, sdata);
887 } 821 }
888 822
889 sdata->bss = NULL; 823 sdata->bss = NULL;
890 824
891 mutex_lock(&local->mtx);
892 hw_reconf_flags |= __ieee80211_recalc_idle(local);
893 mutex_unlock(&local->mtx);
894
895 ieee80211_recalc_ps(local, -1); 825 ieee80211_recalc_ps(local, -1);
896 826
897 if (local->open_count == 0) { 827 if (local->open_count == 0) {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 2bdd454e8bcf..38b3468bc515 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -34,8 +34,6 @@
34#include "cfg.h" 34#include "cfg.h"
35#include "debugfs.h" 35#include "debugfs.h"
36 36
37static struct lock_class_key ieee80211_rx_skb_queue_class;
38
39void ieee80211_configure_filter(struct ieee80211_local *local) 37void ieee80211_configure_filter(struct ieee80211_local *local)
40{ 38{
41 u64 mc; 39 u64 mc;
@@ -613,21 +611,12 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
613 611
614 mutex_init(&local->key_mtx); 612 mutex_init(&local->key_mtx);
615 spin_lock_init(&local->filter_lock); 613 spin_lock_init(&local->filter_lock);
614 spin_lock_init(&local->rx_path_lock);
616 spin_lock_init(&local->queue_stop_reason_lock); 615 spin_lock_init(&local->queue_stop_reason_lock);
617 616
618 INIT_LIST_HEAD(&local->chanctx_list); 617 INIT_LIST_HEAD(&local->chanctx_list);
619 mutex_init(&local->chanctx_mtx); 618 mutex_init(&local->chanctx_mtx);
620 619
621 /*
622 * The rx_skb_queue is only accessed from tasklets,
623 * but other SKB queues are used from within IRQ
624 * context. Therefore, this one needs a different
625 * locking class so our direct, non-irq-safe use of
626 * the queue's lock doesn't throw lockdep warnings.
627 */
628 skb_queue_head_init_class(&local->rx_skb_queue,
629 &ieee80211_rx_skb_queue_class);
630
631 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); 620 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
632 621
633 INIT_WORK(&local->restart_work, ieee80211_restart_work); 622 INIT_WORK(&local->restart_work, ieee80211_restart_work);
@@ -707,9 +696,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
707 return -EINVAL; 696 return -EINVAL;
708#endif 697#endif
709 698
710 if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan)
711 return -EINVAL;
712
713 if (!local->use_chanctx) { 699 if (!local->use_chanctx) {
714 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) { 700 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) {
715 const struct ieee80211_iface_combination *comb; 701 const struct ieee80211_iface_combination *comb;
@@ -1089,7 +1075,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1089 wiphy_warn(local->hw.wiphy, "skb_queue not empty\n"); 1075 wiphy_warn(local->hw.wiphy, "skb_queue not empty\n");
1090 skb_queue_purge(&local->skb_queue); 1076 skb_queue_purge(&local->skb_queue);
1091 skb_queue_purge(&local->skb_queue_unreliable); 1077 skb_queue_purge(&local->skb_queue_unreliable);
1092 skb_queue_purge(&local->rx_skb_queue);
1093 1078
1094 destroy_workqueue(local->workqueue); 1079 destroy_workqueue(local->workqueue);
1095 wiphy_unregister(local->hw.wiphy); 1080 wiphy_unregister(local->hw.wiphy);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 35ac38871420..2bf0158c3f82 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -149,6 +149,31 @@ u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
149 return changed; 149 return changed;
150} 150}
151 151
152/*
153 * mesh_sta_cleanup - clean up any mesh sta state
154 *
155 * @sta: mesh sta to clean up.
156 */
157void mesh_sta_cleanup(struct sta_info *sta)
158{
159 struct ieee80211_sub_if_data *sdata = sta->sdata;
160 u32 changed;
161
162 /*
163 * maybe userspace handles peer allocation and peering, but in either
164 * case the beacon is still generated by the kernel and we might need
165 * an update.
166 */
167 changed = mesh_accept_plinks_update(sdata);
168 if (sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
169 changed |= mesh_plink_deactivate(sta);
170 del_timer_sync(&sta->plink_timer);
171 }
172
173 if (changed)
174 ieee80211_bss_info_change_notify(sdata, changed);
175}
176
152int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 177int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
153{ 178{
154 int i; 179 int i;
@@ -368,8 +393,6 @@ mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
368int mesh_add_ds_params_ie(struct sk_buff *skb, 393int mesh_add_ds_params_ie(struct sk_buff *skb,
369 struct ieee80211_sub_if_data *sdata) 394 struct ieee80211_sub_if_data *sdata)
370{ 395{
371 struct ieee80211_local *local = sdata->local;
372 struct ieee80211_supported_band *sband;
373 struct ieee80211_chanctx_conf *chanctx_conf; 396 struct ieee80211_chanctx_conf *chanctx_conf;
374 struct ieee80211_channel *chan; 397 struct ieee80211_channel *chan;
375 u8 *pos; 398 u8 *pos;
@@ -386,13 +409,10 @@ int mesh_add_ds_params_ie(struct sk_buff *skb,
386 chan = chanctx_conf->def.chan; 409 chan = chanctx_conf->def.chan;
387 rcu_read_unlock(); 410 rcu_read_unlock();
388 411
389 sband = local->hw.wiphy->bands[chan->band]; 412 pos = skb_put(skb, 2 + 1);
390 if (sband->band == IEEE80211_BAND_2GHZ) { 413 *pos++ = WLAN_EID_DS_PARAMS;
391 pos = skb_put(skb, 2 + 1); 414 *pos++ = 1;
392 *pos++ = WLAN_EID_DS_PARAMS; 415 *pos++ = ieee80211_frequency_to_channel(chan->center_freq);
393 *pos++ = 1;
394 *pos++ = ieee80211_frequency_to_channel(chan->center_freq);
395 }
396 416
397 return 0; 417 return 0;
398} 418}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index eb336253b6b3..3b9d862744ba 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -288,12 +288,13 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
288bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 288bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
289u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 289u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
290void mesh_plink_broken(struct sta_info *sta); 290void mesh_plink_broken(struct sta_info *sta);
291void mesh_plink_deactivate(struct sta_info *sta); 291u32 mesh_plink_deactivate(struct sta_info *sta);
292int mesh_plink_open(struct sta_info *sta); 292int mesh_plink_open(struct sta_info *sta);
293void mesh_plink_block(struct sta_info *sta); 293void mesh_plink_block(struct sta_info *sta);
294void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, 294void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
295 struct ieee80211_mgmt *mgmt, size_t len, 295 struct ieee80211_mgmt *mgmt, size_t len,
296 struct ieee80211_rx_status *rx_status); 296 struct ieee80211_rx_status *rx_status);
297void mesh_sta_cleanup(struct sta_info *sta);
297 298
298/* Private interfaces */ 299/* Private interfaces */
299/* Mesh tables */ 300/* Mesh tables */
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index fe7c3334d6fe..56c9b318a97e 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -214,7 +214,7 @@ static u32 __mesh_plink_deactivate(struct sta_info *sta)
214 * 214 *
215 * All mesh paths with this peer as next hop will be flushed 215 * All mesh paths with this peer as next hop will be flushed
216 */ 216 */
217void mesh_plink_deactivate(struct sta_info *sta) 217u32 mesh_plink_deactivate(struct sta_info *sta)
218{ 218{
219 struct ieee80211_sub_if_data *sdata = sta->sdata; 219 struct ieee80211_sub_if_data *sdata = sta->sdata;
220 u32 changed; 220 u32 changed;
@@ -227,7 +227,7 @@ void mesh_plink_deactivate(struct sta_info *sta)
227 sta->reason); 227 sta->reason);
228 spin_unlock_bh(&sta->lock); 228 spin_unlock_bh(&sta->lock);
229 229
230 ieee80211_bss_info_change_notify(sdata, changed); 230 return changed;
231} 231}
232 232
233static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 233static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
@@ -592,6 +592,13 @@ static void mesh_plink_timer(unsigned long data)
592#ifdef CONFIG_PM 592#ifdef CONFIG_PM
593void mesh_plink_quiesce(struct sta_info *sta) 593void mesh_plink_quiesce(struct sta_info *sta)
594{ 594{
595 if (!ieee80211_vif_is_mesh(&sta->sdata->vif))
596 return;
597
598 /* no kernel mesh sta timers have been initialized */
599 if (sta->sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
600 return;
601
595 if (del_timer_sync(&sta->plink_timer)) 602 if (del_timer_sync(&sta->plink_timer))
596 sta->plink_timer_was_running = true; 603 sta->plink_timer_was_running = true;
597} 604}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 353b690900e9..efb22763d56d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -685,7 +685,8 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
685 if (powersave) 685 if (powersave)
686 nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); 686 nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
687 687
688 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 688 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
689 IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
689 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 690 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
690 IEEE80211_STA_CONNECTION_POLL)) 691 IEEE80211_STA_CONNECTION_POLL))
691 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE; 692 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;
@@ -951,39 +952,6 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
951 return 0; 952 return 0;
952} 953}
953 954
954void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
955{
956 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
957 struct ieee80211_local *local = sdata->local;
958 struct ieee80211_conf *conf = &local->hw.conf;
959
960 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
961 !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
962 (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));
963
964 local->disable_dynamic_ps = false;
965 conf->dynamic_ps_timeout = local->dynamic_ps_user_timeout;
966}
967EXPORT_SYMBOL(ieee80211_enable_dyn_ps);
968
969void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif)
970{
971 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
972 struct ieee80211_local *local = sdata->local;
973 struct ieee80211_conf *conf = &local->hw.conf;
974
975 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
976 !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
977 (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));
978
979 local->disable_dynamic_ps = true;
980 conf->dynamic_ps_timeout = 0;
981 del_timer_sync(&local->dynamic_ps_timer);
982 ieee80211_queue_work(&local->hw,
983 &local->dynamic_ps_enable_work);
984}
985EXPORT_SYMBOL(ieee80211_disable_dyn_ps);
986
987/* powersave */ 955/* powersave */
988static void ieee80211_enable_ps(struct ieee80211_local *local, 956static void ieee80211_enable_ps(struct ieee80211_local *local,
989 struct ieee80211_sub_if_data *sdata) 957 struct ieee80211_sub_if_data *sdata)
@@ -1086,7 +1054,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
1086 } 1054 }
1087 1055
1088 if (count == 1 && ieee80211_powersave_allowed(found)) { 1056 if (count == 1 && ieee80211_powersave_allowed(found)) {
1089 struct ieee80211_conf *conf = &local->hw.conf;
1090 s32 beaconint_us; 1057 s32 beaconint_us;
1091 1058
1092 if (latency < 0) 1059 if (latency < 0)
@@ -1110,10 +1077,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
1110 else 1077 else
1111 timeout = 100; 1078 timeout = 100;
1112 } 1079 }
1113 local->dynamic_ps_user_timeout = timeout; 1080 local->hw.conf.dynamic_ps_timeout = timeout;
1114 if (!local->disable_dynamic_ps)
1115 conf->dynamic_ps_timeout =
1116 local->dynamic_ps_user_timeout;
1117 1081
1118 if (beaconint_us > latency) { 1082 if (beaconint_us > latency) {
1119 local->ps_sdata = NULL; 1083 local->ps_sdata = NULL;
@@ -1183,8 +1147,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
1183 if (local->hw.conf.flags & IEEE80211_CONF_PS) 1147 if (local->hw.conf.flags & IEEE80211_CONF_PS)
1184 return; 1148 return;
1185 1149
1186 if (!local->disable_dynamic_ps && 1150 if (local->hw.conf.dynamic_ps_timeout > 0) {
1187 local->hw.conf.dynamic_ps_timeout > 0) {
1188 /* don't enter PS if TX frames are pending */ 1151 /* don't enter PS if TX frames are pending */
1189 if (drv_tx_frames_pending(local)) { 1152 if (drv_tx_frames_pending(local)) {
1190 mod_timer(&local->dynamic_ps_timer, jiffies + 1153 mod_timer(&local->dynamic_ps_timer, jiffies +
@@ -1746,7 +1709,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1746 1709
1747 if (beacon) 1710 if (beacon)
1748 mlme_dbg_ratelimited(sdata, 1711 mlme_dbg_ratelimited(sdata,
1749 "detected beacon loss from AP - sending probe request\n"); 1712 "detected beacon loss from AP - probing\n");
1750 1713
1751 ieee80211_cqm_rssi_notify(&sdata->vif, 1714 ieee80211_cqm_rssi_notify(&sdata->vif,
1752 NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL); 1715 NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL);
@@ -1830,7 +1793,6 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get);
1830static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) 1793static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
1831{ 1794{
1832 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1795 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1833 struct ieee80211_local *local = sdata->local;
1834 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 1796 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
1835 1797
1836 mutex_lock(&ifmgd->mtx); 1798 mutex_lock(&ifmgd->mtx);
@@ -1850,10 +1812,6 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
1850 * but that's not a problem. 1812 * but that's not a problem.
1851 */ 1813 */
1852 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 1814 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
1853
1854 mutex_lock(&local->mtx);
1855 ieee80211_recalc_idle(local);
1856 mutex_unlock(&local->mtx);
1857} 1815}
1858 1816
1859static void ieee80211_beacon_connection_loss_work(struct work_struct *work) 1817static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
@@ -1934,7 +1892,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
1934 ieee80211_vif_release_channel(sdata); 1892 ieee80211_vif_release_channel(sdata);
1935 } 1893 }
1936 1894
1937 cfg80211_put_bss(auth_data->bss); 1895 cfg80211_put_bss(sdata->local->hw.wiphy, auth_data->bss);
1938 kfree(auth_data); 1896 kfree(auth_data);
1939 sdata->u.mgd.auth_data = NULL; 1897 sdata->u.mgd.auth_data = NULL;
1940} 1898}
@@ -2086,10 +2044,6 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2086 2044
2087 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2045 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2088 2046
2089 mutex_lock(&sdata->local->mtx);
2090 ieee80211_recalc_idle(sdata->local);
2091 mutex_unlock(&sdata->local->mtx);
2092
2093 return RX_MGMT_CFG80211_DEAUTH; 2047 return RX_MGMT_CFG80211_DEAUTH;
2094} 2048}
2095 2049
@@ -2117,10 +2071,6 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
2117 2071
2118 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2072 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2119 2073
2120 mutex_lock(&sdata->local->mtx);
2121 ieee80211_recalc_idle(sdata->local);
2122 mutex_unlock(&sdata->local->mtx);
2123
2124 return RX_MGMT_CFG80211_DISASSOC; 2074 return RX_MGMT_CFG80211_DISASSOC;
2125} 2075}
2126 2076
@@ -2263,9 +2213,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2263 if (elems.wmm_param) 2213 if (elems.wmm_param)
2264 set_sta_flag(sta, WLAN_STA_WME); 2214 set_sta_flag(sta, WLAN_STA_WME);
2265 2215
2266 err = sta_info_move_state(sta, IEEE80211_STA_AUTH); 2216 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
2267 if (!err)
2268 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
2269 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) 2217 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
2270 err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); 2218 err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
2271 if (err) { 2219 if (err) {
@@ -2387,7 +2335,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2387 if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { 2335 if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
2388 /* oops -- internal error -- send timeout for now */ 2336 /* oops -- internal error -- send timeout for now */
2389 ieee80211_destroy_assoc_data(sdata, false); 2337 ieee80211_destroy_assoc_data(sdata, false);
2390 cfg80211_put_bss(*bss); 2338 cfg80211_put_bss(sdata->local->hw.wiphy, *bss);
2391 return RX_MGMT_CFG80211_ASSOC_TIMEOUT; 2339 return RX_MGMT_CFG80211_ASSOC_TIMEOUT;
2392 } 2340 }
2393 sdata_info(sdata, "associated\n"); 2341 sdata_info(sdata, "associated\n");
@@ -2567,6 +2515,17 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2567 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); 2515 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
2568 ifmgd->assoc_data->have_beacon = true; 2516 ifmgd->assoc_data->have_beacon = true;
2569 ifmgd->assoc_data->need_beacon = false; 2517 ifmgd->assoc_data->need_beacon = false;
2518 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
2519 sdata->vif.bss_conf.sync_tsf =
2520 le64_to_cpu(mgmt->u.beacon.timestamp);
2521 sdata->vif.bss_conf.sync_device_ts =
2522 rx_status->device_timestamp;
2523 if (elems.tim)
2524 sdata->vif.bss_conf.sync_dtim_count =
2525 elems.tim->dtim_count;
2526 else
2527 sdata->vif.bss_conf.sync_dtim_count = 0;
2528 }
2570 /* continue assoc process */ 2529 /* continue assoc process */
2571 ifmgd->assoc_data->timeout = jiffies; 2530 ifmgd->assoc_data->timeout = jiffies;
2572 run_again(ifmgd, ifmgd->assoc_data->timeout); 2531 run_again(ifmgd, ifmgd->assoc_data->timeout);
@@ -2641,7 +2600,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2641 2600
2642 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { 2601 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
2643 mlme_dbg_ratelimited(sdata, 2602 mlme_dbg_ratelimited(sdata,
2644 "cancelling probereq poll due to a received beacon\n"); 2603 "cancelling AP probe due to a received beacon\n");
2645 mutex_lock(&local->mtx); 2604 mutex_lock(&local->mtx);
2646 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; 2605 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
2647 ieee80211_run_deferred_scan(local); 2606 ieee80211_run_deferred_scan(local);
@@ -2725,7 +2684,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2725 2684
2726 /* 2685 /*
2727 * If we haven't had a beacon before, tell the driver about the 2686 * If we haven't had a beacon before, tell the driver about the
2728 * DTIM period now. 2687 * DTIM period (and beacon timing if desired) now.
2729 */ 2688 */
2730 if (!bss_conf->dtim_period) { 2689 if (!bss_conf->dtim_period) {
2731 /* a few bogus AP send dtim_period = 0 or no TIM IE */ 2690 /* a few bogus AP send dtim_period = 0 or no TIM IE */
@@ -2733,6 +2692,19 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2733 bss_conf->dtim_period = elems.tim->dtim_period ?: 1; 2692 bss_conf->dtim_period = elems.tim->dtim_period ?: 1;
2734 else 2693 else
2735 bss_conf->dtim_period = 1; 2694 bss_conf->dtim_period = 1;
2695
2696 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
2697 sdata->vif.bss_conf.sync_tsf =
2698 le64_to_cpu(mgmt->u.beacon.timestamp);
2699 sdata->vif.bss_conf.sync_device_ts =
2700 rx_status->device_timestamp;
2701 if (elems.tim)
2702 sdata->vif.bss_conf.sync_dtim_count =
2703 elems.tim->dtim_count;
2704 else
2705 sdata->vif.bss_conf.sync_dtim_count = 0;
2706 }
2707
2736 changed |= BSS_CHANGED_DTIM_PERIOD; 2708 changed |= BSS_CHANGED_DTIM_PERIOD;
2737 } 2709 }
2738 2710
@@ -2853,7 +2825,6 @@ static void ieee80211_sta_timer(unsigned long data)
2853static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, 2825static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
2854 u8 *bssid, u8 reason, bool tx) 2826 u8 *bssid, u8 reason, bool tx)
2855{ 2827{
2856 struct ieee80211_local *local = sdata->local;
2857 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2828 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2858 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 2829 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
2859 2830
@@ -2867,10 +2838,6 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
2867 */ 2838 */
2868 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 2839 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
2869 2840
2870 mutex_lock(&local->mtx);
2871 ieee80211_recalc_idle(local);
2872 mutex_unlock(&local->mtx);
2873
2874 mutex_lock(&ifmgd->mtx); 2841 mutex_lock(&ifmgd->mtx);
2875} 2842}
2876 2843
@@ -3141,10 +3108,6 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3141 } 3108 }
3142 3109
3143 mutex_unlock(&ifmgd->mtx); 3110 mutex_unlock(&ifmgd->mtx);
3144
3145 mutex_lock(&local->mtx);
3146 ieee80211_recalc_idle(local);
3147 mutex_unlock(&local->mtx);
3148} 3111}
3149 3112
3150static void ieee80211_sta_bcn_mon_timer(unsigned long data) 3113static void ieee80211_sta_bcn_mon_timer(unsigned long data)
@@ -3658,15 +3621,12 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3658 return -ENOMEM; 3621 return -ENOMEM;
3659 } 3622 }
3660 3623
3661 mutex_lock(&local->mtx);
3662 ieee80211_recalc_idle(sdata->local);
3663 mutex_unlock(&local->mtx);
3664
3665 if (new_sta) { 3624 if (new_sta) {
3666 u32 rates = 0, basic_rates = 0; 3625 u32 rates = 0, basic_rates = 0;
3667 bool have_higher_than_11mbit; 3626 bool have_higher_than_11mbit;
3668 int min_rate = INT_MAX, min_rate_index = -1; 3627 int min_rate = INT_MAX, min_rate_index = -1;
3669 struct ieee80211_supported_band *sband; 3628 struct ieee80211_supported_band *sband;
3629 const struct cfg80211_bss_ies *ies;
3670 3630
3671 sband = local->hw.wiphy->bands[cbss->channel->band]; 3631 sband = local->hw.wiphy->bands[cbss->channel->band];
3672 3632
@@ -3710,8 +3670,34 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3710 3670
3711 /* set timing information */ 3671 /* set timing information */
3712 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval; 3672 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
3713 sdata->vif.bss_conf.sync_tsf = cbss->tsf; 3673 rcu_read_lock();
3714 sdata->vif.bss_conf.sync_device_ts = bss->device_ts; 3674 ies = rcu_dereference(cbss->beacon_ies);
3675 if (ies) {
3676 const u8 *tim_ie;
3677
3678 sdata->vif.bss_conf.sync_tsf = ies->tsf;
3679 sdata->vif.bss_conf.sync_device_ts =
3680 bss->device_ts_beacon;
3681 tim_ie = cfg80211_find_ie(WLAN_EID_TIM,
3682 ies->data, ies->len);
3683 if (tim_ie && tim_ie[1] >= 2)
3684 sdata->vif.bss_conf.sync_dtim_count = tim_ie[2];
3685 else
3686 sdata->vif.bss_conf.sync_dtim_count = 0;
3687 } else if (!(local->hw.flags &
3688 IEEE80211_HW_TIMING_BEACON_ONLY)) {
3689 ies = rcu_dereference(cbss->proberesp_ies);
3690 /* must be non-NULL since beacon IEs were NULL */
3691 sdata->vif.bss_conf.sync_tsf = ies->tsf;
3692 sdata->vif.bss_conf.sync_device_ts =
3693 bss->device_ts_presp;
3694 sdata->vif.bss_conf.sync_dtim_count = 0;
3695 } else {
3696 sdata->vif.bss_conf.sync_tsf = 0;
3697 sdata->vif.bss_conf.sync_device_ts = 0;
3698 sdata->vif.bss_conf.sync_dtim_count = 0;
3699 }
3700 rcu_read_unlock();
3715 3701
3716 /* tell driver about BSSID, basic rates and timing */ 3702 /* tell driver about BSSID, basic rates and timing */
3717 ieee80211_bss_info_change_notify(sdata, 3703 ieee80211_bss_info_change_notify(sdata,
@@ -3831,7 +3817,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3831 } 3817 }
3832 3818
3833 /* hold our own reference */ 3819 /* hold our own reference */
3834 cfg80211_ref_bss(auth_data->bss); 3820 cfg80211_ref_bss(local->hw.wiphy, auth_data->bss);
3835 err = 0; 3821 err = 0;
3836 goto out_unlock; 3822 goto out_unlock;
3837 3823
@@ -4037,13 +4023,23 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4037 const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM, 4023 const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM,
4038 beacon_ies->data, 4024 beacon_ies->data,
4039 beacon_ies->len); 4025 beacon_ies->len);
4026 u8 dtim_count = 0;
4027
4040 if (tim_ie && tim_ie[1] >= sizeof(struct ieee80211_tim_ie)) { 4028 if (tim_ie && tim_ie[1] >= sizeof(struct ieee80211_tim_ie)) {
4041 const struct ieee80211_tim_ie *tim; 4029 const struct ieee80211_tim_ie *tim;
4042 tim = (void *)(tim_ie + 2); 4030 tim = (void *)(tim_ie + 2);
4043 ifmgd->dtim_period = tim->dtim_period; 4031 ifmgd->dtim_period = tim->dtim_period;
4032 dtim_count = tim->dtim_count;
4044 } 4033 }
4045 assoc_data->have_beacon = true; 4034 assoc_data->have_beacon = true;
4046 assoc_data->timeout = jiffies; 4035 assoc_data->timeout = jiffies;
4036
4037 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
4038 sdata->vif.bss_conf.sync_tsf = beacon_ies->tsf;
4039 sdata->vif.bss_conf.sync_device_ts =
4040 bss->device_ts_beacon;
4041 sdata->vif.bss_conf.sync_dtim_count = dtim_count;
4042 }
4047 } else { 4043 } else {
4048 assoc_data->timeout = jiffies; 4044 assoc_data->timeout = jiffies;
4049 } 4045 }
@@ -4115,10 +4111,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4115 mutex_unlock(&ifmgd->mtx); 4111 mutex_unlock(&ifmgd->mtx);
4116 4112
4117 out: 4113 out:
4118 mutex_lock(&sdata->local->mtx);
4119 ieee80211_recalc_idle(sdata->local);
4120 mutex_unlock(&sdata->local->mtx);
4121
4122 if (sent_frame) 4114 if (sent_frame)
4123 __cfg80211_send_deauth(sdata->dev, frame_buf, 4115 __cfg80211_send_deauth(sdata->dev, frame_buf,
4124 IEEE80211_DEAUTH_FRAME_LEN); 4116 IEEE80211_DEAUTH_FRAME_LEN);
@@ -4159,10 +4151,6 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
4159 __cfg80211_send_disassoc(sdata->dev, frame_buf, 4151 __cfg80211_send_disassoc(sdata->dev, frame_buf,
4160 IEEE80211_DEAUTH_FRAME_LEN); 4152 IEEE80211_DEAUTH_FRAME_LEN);
4161 4153
4162 mutex_lock(&sdata->local->mtx);
4163 ieee80211_recalc_idle(sdata->local);
4164 mutex_unlock(&sdata->local->mtx);
4165
4166 return 0; 4154 return 0;
4167} 4155}
4168 4156
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 82baf5b6ecf4..cc79b4a2e821 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -113,6 +113,15 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
113 * notify the AP about us leaving the channel and stop all 113 * notify the AP about us leaving the channel and stop all
114 * STA interfaces. 114 * STA interfaces.
115 */ 115 */
116
117 /*
118 * Stop queues and transmit all frames queued by the driver
119 * before sending nullfunc to enable powersave at the AP.
120 */
121 ieee80211_stop_queues_by_reason(&local->hw,
122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL);
123 drv_flush(local, false);
124
116 mutex_lock(&local->iflist_mtx); 125 mutex_lock(&local->iflist_mtx);
117 list_for_each_entry(sdata, &local->interfaces, list) { 126 list_for_each_entry(sdata, &local->interfaces, list) {
118 if (!ieee80211_sdata_running(sdata)) 127 if (!ieee80211_sdata_running(sdata))
@@ -133,12 +142,9 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
133 sdata, BSS_CHANGED_BEACON_ENABLED); 142 sdata, BSS_CHANGED_BEACON_ENABLED);
134 } 143 }
135 144
136 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { 145 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
137 netif_tx_stop_all_queues(sdata->dev); 146 sdata->u.mgd.associated)
138 if (sdata->vif.type == NL80211_IFTYPE_STATION && 147 ieee80211_offchannel_ps_enable(sdata);
139 sdata->u.mgd.associated)
140 ieee80211_offchannel_ps_enable(sdata);
141 }
142 } 148 }
143 mutex_unlock(&local->iflist_mtx); 149 mutex_unlock(&local->iflist_mtx);
144} 150}
@@ -166,20 +172,6 @@ void ieee80211_offchannel_return(struct ieee80211_local *local)
166 sdata->u.mgd.associated) 172 sdata->u.mgd.associated)
167 ieee80211_offchannel_ps_disable(sdata); 173 ieee80211_offchannel_ps_disable(sdata);
168 174
169 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
170 /*
171 * This may wake up queues even though the driver
172 * currently has them stopped. This is not very
173 * likely, since the driver won't have gotten any
174 * (or hardly any) new packets while we weren't
175 * on the right channel, and even if it happens
176 * it will at most lead to queueing up one more
177 * packet per queue in mac80211 rather than on
178 * the interface qdisc.
179 */
180 netif_tx_wake_all_queues(sdata->dev);
181 }
182
183 if (test_and_clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, 175 if (test_and_clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED,
184 &sdata->state)) { 176 &sdata->state)) {
185 sdata->vif.bss_conf.enable_beacon = true; 177 sdata->vif.bss_conf.enable_beacon = true;
@@ -188,6 +180,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local)
188 } 180 }
189 } 181 }
190 mutex_unlock(&local->iflist_mtx); 182 mutex_unlock(&local->iflist_mtx);
183
184 ieee80211_wake_queues_by_reason(&local->hw,
185 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL);
191} 186}
192 187
193void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) 188void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 9f9c453bc45d..5bb316aff21a 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -231,10 +231,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
231 if (!mr->cur_tp) 231 if (!mr->cur_tp)
232 continue; 232 continue;
233 233
234 /* ignore the lowest rate of each single-stream group */
235 if (!i && minstrel_mcs_groups[group].streams == 1)
236 continue;
237
238 if ((mr->cur_tp > cur_prob_tp && mr->probability > 234 if ((mr->cur_tp > cur_prob_tp && mr->probability >
239 MINSTREL_FRAC(3, 4)) || mr->probability > cur_prob) { 235 MINSTREL_FRAC(3, 4)) || mr->probability > cur_prob) {
240 mg->max_prob_rate = index; 236 mg->max_prob_rate = index;
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c
index e788f76a1dfe..f2b7d26370f0 100644
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -38,8 +38,8 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
38 38
39 file->private_data = ms; 39 file->private_data = ms;
40 p = ms->buf; 40 p = ms->buf;
41 p += sprintf(p, "type rate throughput ewma prob this prob " 41 p += sprintf(p, "type rate throughput ewma prob this prob "
42 "this succ/attempt success attempts\n"); 42 "retry this succ/attempt success attempts\n");
43 for (i = 0; i < MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; i++) { 43 for (i = 0; i < MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; i++) {
44 char htmode = '2'; 44 char htmode = '2';
45 char gimode = 'L'; 45 char gimode = 'L';
@@ -64,18 +64,19 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
64 *(p++) = (idx == mi->max_tp_rate) ? 'T' : ' '; 64 *(p++) = (idx == mi->max_tp_rate) ? 'T' : ' ';
65 *(p++) = (idx == mi->max_tp_rate2) ? 't' : ' '; 65 *(p++) = (idx == mi->max_tp_rate2) ? 't' : ' ';
66 *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; 66 *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' ';
67 p += sprintf(p, "MCS%-2u", (minstrel_mcs_groups[i].streams - 1) * 67 p += sprintf(p, " MCS%-2u", (minstrel_mcs_groups[i].streams - 1) *
68 MCS_GROUP_RATES + j); 68 MCS_GROUP_RATES + j);
69 69
70 tp = mr->cur_tp / 10; 70 tp = mr->cur_tp / 10;
71 prob = MINSTREL_TRUNC(mr->cur_prob * 1000); 71 prob = MINSTREL_TRUNC(mr->cur_prob * 1000);
72 eprob = MINSTREL_TRUNC(mr->probability * 1000); 72 eprob = MINSTREL_TRUNC(mr->probability * 1000);
73 73
74 p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u " 74 p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u "
75 "%3u(%3u) %8llu %8llu\n", 75 "%3u %3u(%3u) %8llu %8llu\n",
76 tp / 10, tp % 10, 76 tp / 10, tp % 10,
77 eprob / 10, eprob % 10, 77 eprob / 10, eprob % 10,
78 prob / 10, prob % 10, 78 prob / 10, prob % 10,
79 mr->retry_count,
79 mr->last_success, 80 mr->last_success,
80 mr->last_attempts, 81 mr->last_attempts,
81 (unsigned long long)mr->succ_hist, 82 (unsigned long long)mr->succ_hist,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c98be0593756..b5f1bba7ffe1 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -668,9 +668,9 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
668 668
669static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, 669static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
670 struct tid_ampdu_rx *tid_agg_rx, 670 struct tid_ampdu_rx *tid_agg_rx,
671 int index) 671 int index,
672 struct sk_buff_head *frames)
672{ 673{
673 struct ieee80211_local *local = sdata->local;
674 struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; 674 struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
675 struct ieee80211_rx_status *status; 675 struct ieee80211_rx_status *status;
676 676
@@ -684,7 +684,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
684 tid_agg_rx->reorder_buf[index] = NULL; 684 tid_agg_rx->reorder_buf[index] = NULL;
685 status = IEEE80211_SKB_RXCB(skb); 685 status = IEEE80211_SKB_RXCB(skb);
686 status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE; 686 status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE;
687 skb_queue_tail(&local->rx_skb_queue, skb); 687 __skb_queue_tail(frames, skb);
688 688
689no_frame: 689no_frame:
690 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); 690 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
@@ -692,7 +692,8 @@ no_frame:
692 692
693static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata, 693static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata,
694 struct tid_ampdu_rx *tid_agg_rx, 694 struct tid_ampdu_rx *tid_agg_rx,
695 u16 head_seq_num) 695 u16 head_seq_num,
696 struct sk_buff_head *frames)
696{ 697{
697 int index; 698 int index;
698 699
@@ -701,7 +702,8 @@ static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata
701 while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { 702 while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) {
702 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % 703 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
703 tid_agg_rx->buf_size; 704 tid_agg_rx->buf_size;
704 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); 705 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
706 frames);
705 } 707 }
706} 708}
707 709
@@ -717,7 +719,8 @@ static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata
717#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) 719#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
718 720
719static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, 721static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
720 struct tid_ampdu_rx *tid_agg_rx) 722 struct tid_ampdu_rx *tid_agg_rx,
723 struct sk_buff_head *frames)
721{ 724{
722 int index, j; 725 int index, j;
723 726
@@ -746,7 +749,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
746 749
747 ht_dbg_ratelimited(sdata, 750 ht_dbg_ratelimited(sdata,
748 "release an RX reorder frame due to timeout on earlier frames\n"); 751 "release an RX reorder frame due to timeout on earlier frames\n");
749 ieee80211_release_reorder_frame(sdata, tid_agg_rx, j); 752 ieee80211_release_reorder_frame(sdata, tid_agg_rx, j,
753 frames);
750 754
751 /* 755 /*
752 * Increment the head seq# also for the skipped slots. 756 * Increment the head seq# also for the skipped slots.
@@ -756,7 +760,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
756 skipped = 0; 760 skipped = 0;
757 } 761 }
758 } else while (tid_agg_rx->reorder_buf[index]) { 762 } else while (tid_agg_rx->reorder_buf[index]) {
759 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); 763 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
764 frames);
760 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % 765 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
761 tid_agg_rx->buf_size; 766 tid_agg_rx->buf_size;
762 } 767 }
@@ -788,7 +793,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
788 */ 793 */
789static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata, 794static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata,
790 struct tid_ampdu_rx *tid_agg_rx, 795 struct tid_ampdu_rx *tid_agg_rx,
791 struct sk_buff *skb) 796 struct sk_buff *skb,
797 struct sk_buff_head *frames)
792{ 798{
793 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 799 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
794 u16 sc = le16_to_cpu(hdr->seq_ctrl); 800 u16 sc = le16_to_cpu(hdr->seq_ctrl);
@@ -816,7 +822,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
816 head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); 822 head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size));
817 /* release stored frames up to new head to stack */ 823 /* release stored frames up to new head to stack */
818 ieee80211_release_reorder_frames(sdata, tid_agg_rx, 824 ieee80211_release_reorder_frames(sdata, tid_agg_rx,
819 head_seq_num); 825 head_seq_num, frames);
820 } 826 }
821 827
822 /* Now the new frame is always in the range of the reordering buffer */ 828 /* Now the new frame is always in the range of the reordering buffer */
@@ -846,7 +852,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
846 tid_agg_rx->reorder_buf[index] = skb; 852 tid_agg_rx->reorder_buf[index] = skb;
847 tid_agg_rx->reorder_time[index] = jiffies; 853 tid_agg_rx->reorder_time[index] = jiffies;
848 tid_agg_rx->stored_mpdu_num++; 854 tid_agg_rx->stored_mpdu_num++;
849 ieee80211_sta_reorder_release(sdata, tid_agg_rx); 855 ieee80211_sta_reorder_release(sdata, tid_agg_rx, frames);
850 856
851 out: 857 out:
852 spin_unlock(&tid_agg_rx->reorder_lock); 858 spin_unlock(&tid_agg_rx->reorder_lock);
@@ -857,7 +863,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
857 * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns 863 * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns
858 * true if the MPDU was buffered, false if it should be processed. 864 * true if the MPDU was buffered, false if it should be processed.
859 */ 865 */
860static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) 866static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
867 struct sk_buff_head *frames)
861{ 868{
862 struct sk_buff *skb = rx->skb; 869 struct sk_buff *skb = rx->skb;
863 struct ieee80211_local *local = rx->local; 870 struct ieee80211_local *local = rx->local;
@@ -922,11 +929,12 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
922 * sure that we cannot get to it any more before doing 929 * sure that we cannot get to it any more before doing
923 * anything with it. 930 * anything with it.
924 */ 931 */
925 if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb)) 932 if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb,
933 frames))
926 return; 934 return;
927 935
928 dont_reorder: 936 dont_reorder:
929 skb_queue_tail(&local->rx_skb_queue, skb); 937 __skb_queue_tail(frames, skb);
930} 938}
931 939
932static ieee80211_rx_result debug_noinline 940static ieee80211_rx_result debug_noinline
@@ -2184,7 +2192,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
2184} 2192}
2185 2193
2186static ieee80211_rx_result debug_noinline 2194static ieee80211_rx_result debug_noinline
2187ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) 2195ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
2188{ 2196{
2189 struct sk_buff *skb = rx->skb; 2197 struct sk_buff *skb = rx->skb;
2190 struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; 2198 struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data;
@@ -2223,7 +2231,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
2223 spin_lock(&tid_agg_rx->reorder_lock); 2231 spin_lock(&tid_agg_rx->reorder_lock);
2224 /* release stored frames up to start of BAR */ 2232 /* release stored frames up to start of BAR */
2225 ieee80211_release_reorder_frames(rx->sdata, tid_agg_rx, 2233 ieee80211_release_reorder_frames(rx->sdata, tid_agg_rx,
2226 start_seq_num); 2234 start_seq_num, frames);
2227 spin_unlock(&tid_agg_rx->reorder_lock); 2235 spin_unlock(&tid_agg_rx->reorder_lock);
2228 2236
2229 kfree_skb(skb); 2237 kfree_skb(skb);
@@ -2808,7 +2816,8 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
2808 } 2816 }
2809} 2817}
2810 2818
2811static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx) 2819static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
2820 struct sk_buff_head *frames)
2812{ 2821{
2813 ieee80211_rx_result res = RX_DROP_MONITOR; 2822 ieee80211_rx_result res = RX_DROP_MONITOR;
2814 struct sk_buff *skb; 2823 struct sk_buff *skb;
@@ -2820,15 +2829,9 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
2820 goto rxh_next; \ 2829 goto rxh_next; \
2821 } while (0); 2830 } while (0);
2822 2831
2823 spin_lock(&rx->local->rx_skb_queue.lock); 2832 spin_lock_bh(&rx->local->rx_path_lock);
2824 if (rx->local->running_rx_handler)
2825 goto unlock;
2826
2827 rx->local->running_rx_handler = true;
2828
2829 while ((skb = __skb_dequeue(&rx->local->rx_skb_queue))) {
2830 spin_unlock(&rx->local->rx_skb_queue.lock);
2831 2833
2834 while ((skb = __skb_dequeue(frames))) {
2832 /* 2835 /*
2833 * all the other fields are valid across frames 2836 * all the other fields are valid across frames
2834 * that belong to an aMPDU since they are on the 2837 * that belong to an aMPDU since they are on the
@@ -2849,7 +2852,12 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
2849#endif 2852#endif
2850 CALL_RXH(ieee80211_rx_h_amsdu) 2853 CALL_RXH(ieee80211_rx_h_amsdu)
2851 CALL_RXH(ieee80211_rx_h_data) 2854 CALL_RXH(ieee80211_rx_h_data)
2852 CALL_RXH(ieee80211_rx_h_ctrl); 2855
2856 /* special treatment -- needs the queue */
2857 res = ieee80211_rx_h_ctrl(rx, frames);
2858 if (res != RX_CONTINUE)
2859 goto rxh_next;
2860
2853 CALL_RXH(ieee80211_rx_h_mgmt_check) 2861 CALL_RXH(ieee80211_rx_h_mgmt_check)
2854 CALL_RXH(ieee80211_rx_h_action) 2862 CALL_RXH(ieee80211_rx_h_action)
2855 CALL_RXH(ieee80211_rx_h_userspace_mgmt) 2863 CALL_RXH(ieee80211_rx_h_userspace_mgmt)
@@ -2858,20 +2866,20 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
2858 2866
2859 rxh_next: 2867 rxh_next:
2860 ieee80211_rx_handlers_result(rx, res); 2868 ieee80211_rx_handlers_result(rx, res);
2861 spin_lock(&rx->local->rx_skb_queue.lock); 2869
2862#undef CALL_RXH 2870#undef CALL_RXH
2863 } 2871 }
2864 2872
2865 rx->local->running_rx_handler = false; 2873 spin_unlock_bh(&rx->local->rx_path_lock);
2866
2867 unlock:
2868 spin_unlock(&rx->local->rx_skb_queue.lock);
2869} 2874}
2870 2875
2871static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) 2876static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
2872{ 2877{
2878 struct sk_buff_head reorder_release;
2873 ieee80211_rx_result res = RX_DROP_MONITOR; 2879 ieee80211_rx_result res = RX_DROP_MONITOR;
2874 2880
2881 __skb_queue_head_init(&reorder_release);
2882
2875#define CALL_RXH(rxh) \ 2883#define CALL_RXH(rxh) \
2876 do { \ 2884 do { \
2877 res = rxh(rx); \ 2885 res = rxh(rx); \
@@ -2881,9 +2889,9 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
2881 2889
2882 CALL_RXH(ieee80211_rx_h_check) 2890 CALL_RXH(ieee80211_rx_h_check)
2883 2891
2884 ieee80211_rx_reorder_ampdu(rx); 2892 ieee80211_rx_reorder_ampdu(rx, &reorder_release);
2885 2893
2886 ieee80211_rx_handlers(rx); 2894 ieee80211_rx_handlers(rx, &reorder_release);
2887 return; 2895 return;
2888 2896
2889 rxh_next: 2897 rxh_next:
@@ -2898,6 +2906,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
2898 */ 2906 */
2899void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) 2907void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
2900{ 2908{
2909 struct sk_buff_head frames;
2901 struct ieee80211_rx_data rx = { 2910 struct ieee80211_rx_data rx = {
2902 .sta = sta, 2911 .sta = sta,
2903 .sdata = sta->sdata, 2912 .sdata = sta->sdata,
@@ -2913,11 +2922,13 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
2913 if (!tid_agg_rx) 2922 if (!tid_agg_rx)
2914 return; 2923 return;
2915 2924
2925 __skb_queue_head_init(&frames);
2926
2916 spin_lock(&tid_agg_rx->reorder_lock); 2927 spin_lock(&tid_agg_rx->reorder_lock);
2917 ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx); 2928 ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx, &frames);
2918 spin_unlock(&tid_agg_rx->reorder_lock); 2929 spin_unlock(&tid_agg_rx->reorder_lock);
2919 2930
2920 ieee80211_rx_handlers(&rx); 2931 ieee80211_rx_handlers(&rx, &frames);
2921} 2932}
2922 2933
2923/* main receive path */ 2934/* main receive path */
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 7f80f0a5026e..6d0b89e4aa31 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -34,7 +34,8 @@ void ieee80211_rx_bss_put(struct ieee80211_local *local,
34{ 34{
35 if (!bss) 35 if (!bss)
36 return; 36 return;
37 cfg80211_put_bss(container_of((void *)bss, struct cfg80211_bss, priv)); 37 cfg80211_put_bss(local->hw.wiphy,
38 container_of((void *)bss, struct cfg80211_bss, priv));
38} 39}
39 40
40static bool is_uapsd_supported(struct ieee802_11_elems *elems) 41static bool is_uapsd_supported(struct ieee802_11_elems *elems)
@@ -79,7 +80,10 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
79 80
80 bss = (void *)cbss->priv; 81 bss = (void *)cbss->priv;
81 82
82 bss->device_ts = rx_status->device_timestamp; 83 if (beacon)
84 bss->device_ts_beacon = rx_status->device_timestamp;
85 else
86 bss->device_ts_presp = rx_status->device_timestamp;
83 87
84 if (elems->parse_error) { 88 if (elems->parse_error) {
85 if (beacon) 89 if (beacon)
@@ -330,6 +334,9 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
330 334
331 ieee80211_offchannel_stop_vifs(local); 335 ieee80211_offchannel_stop_vifs(local);
332 336
337 /* ensure nullfunc is transmitted before leaving operating channel */
338 drv_flush(local, false);
339
333 ieee80211_configure_filter(local); 340 ieee80211_configure_filter(local);
334 341
335 /* We need to set power level at maximum rate for scanning. */ 342 /* We need to set power level at maximum rate for scanning. */
@@ -378,6 +385,11 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
378 int i; 385 int i;
379 struct ieee80211_sub_if_data *sdata; 386 struct ieee80211_sub_if_data *sdata;
380 enum ieee80211_band band = local->hw.conf.channel->band; 387 enum ieee80211_band band = local->hw.conf.channel->band;
388 u32 tx_flags;
389
390 tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
391 if (local->scan_req->no_cck)
392 tx_flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
381 393
382 sdata = rcu_dereference_protected(local->scan_sdata, 394 sdata = rcu_dereference_protected(local->scan_sdata,
383 lockdep_is_held(&local->mtx)); 395 lockdep_is_held(&local->mtx));
@@ -389,9 +401,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
389 local->scan_req->ssids[i].ssid_len, 401 local->scan_req->ssids[i].ssid_len,
390 local->scan_req->ie, local->scan_req->ie_len, 402 local->scan_req->ie, local->scan_req->ie_len,
391 local->scan_req->rates[band], false, 403 local->scan_req->rates[band], false,
392 local->scan_req->no_cck ? 404 tx_flags, local->hw.conf.channel, true);
393 IEEE80211_TX_CTL_NO_CCK_RATE : 0,
394 local->hw.conf.channel, true);
395 405
396 /* 406 /*
397 * After sending probe requests, wait for probe responses 407 * After sending probe requests, wait for probe responses
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 47a0f0601768..19db20a58e23 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -137,13 +137,8 @@ static void cleanup_single_sta(struct sta_info *sta)
137 ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); 137 ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]);
138 } 138 }
139 139
140#ifdef CONFIG_MAC80211_MESH 140 if (ieee80211_vif_is_mesh(&sdata->vif))
141 if (ieee80211_vif_is_mesh(&sdata->vif)) { 141 mesh_sta_cleanup(sta);
142 mesh_accept_plinks_update(sdata);
143 mesh_plink_deactivate(sta);
144 del_timer_sync(&sta->plink_timer);
145 }
146#endif
147 142
148 cancel_work_sync(&sta->drv_unblock_wk); 143 cancel_work_sync(&sta->drv_unblock_wk);
149 144
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 5a1deba2c645..350578c396c0 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -298,6 +298,7 @@ struct sta_ampdu_mlme {
298 * @beacon_loss_count: number of times beacon loss has triggered 298 * @beacon_loss_count: number of times beacon loss has triggered
299 * @supports_40mhz: tracks whether the station advertised 40 MHz support 299 * @supports_40mhz: tracks whether the station advertised 40 MHz support
300 * as we overwrite its HT parameters with the currently used value 300 * as we overwrite its HT parameters with the currently used value
301 * @rcu_head: RCU head used for freeing this station struct
301 */ 302 */
302struct sta_info { 303struct sta_info {
303 /* General information, mostly static */ 304 /* General information, mostly static */
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 6ca53d64cb28..0bdd7aeb8958 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -36,7 +36,7 @@
36 __entry->control_freq = (c)->chan->center_freq; \ 36 __entry->control_freq = (c)->chan->center_freq; \
37 __entry->chan_width = (c)->width; \ 37 __entry->chan_width = (c)->width; \
38 __entry->center_freq1 = (c)->center_freq1; \ 38 __entry->center_freq1 = (c)->center_freq1; \
39 __entry->center_freq1 = (c)->center_freq2; 39 __entry->center_freq2 = (c)->center_freq2;
40#define CHANDEF_PR_FMT " control:%d MHz width:%d center: %d/%d MHz" 40#define CHANDEF_PR_FMT " control:%d MHz width:%d center: %d/%d MHz"
41#define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width, \ 41#define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width, \
42 __entry->center_freq1, __entry->center_freq2 42 __entry->center_freq1, __entry->center_freq2
@@ -340,6 +340,7 @@ TRACE_EVENT(drv_bss_info_changed,
340 __field(u16, assoc_cap) 340 __field(u16, assoc_cap)
341 __field(u64, sync_tsf) 341 __field(u64, sync_tsf)
342 __field(u32, sync_device_ts) 342 __field(u32, sync_device_ts)
343 __field(u8, sync_dtim_count)
343 __field(u32, basic_rates) 344 __field(u32, basic_rates)
344 __array(int, mcast_rate, IEEE80211_NUM_BANDS) 345 __array(int, mcast_rate, IEEE80211_NUM_BANDS)
345 __field(u16, ht_operation_mode) 346 __field(u16, ht_operation_mode)
@@ -379,6 +380,7 @@ TRACE_EVENT(drv_bss_info_changed,
379 __entry->assoc_cap = info->assoc_capability; 380 __entry->assoc_cap = info->assoc_capability;
380 __entry->sync_tsf = info->sync_tsf; 381 __entry->sync_tsf = info->sync_tsf;
381 __entry->sync_device_ts = info->sync_device_ts; 382 __entry->sync_device_ts = info->sync_device_ts;
383 __entry->sync_dtim_count = info->sync_dtim_count;
382 __entry->basic_rates = info->basic_rates; 384 __entry->basic_rates = info->basic_rates;
383 memcpy(__entry->mcast_rate, info->mcast_rate, 385 memcpy(__entry->mcast_rate, info->mcast_rate,
384 sizeof(__entry->mcast_rate)); 386 sizeof(__entry->mcast_rate));
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 2ef0e19b06bb..f476aa6a771d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1230,6 +1230,21 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
1230 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 1230 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
1231 if (local->queue_stop_reasons[q] || 1231 if (local->queue_stop_reasons[q] ||
1232 (!txpending && !skb_queue_empty(&local->pending[q]))) { 1232 (!txpending && !skb_queue_empty(&local->pending[q]))) {
1233 if (unlikely(info->flags &
1234 IEEE80211_TX_INTFL_OFFCHAN_TX_OK &&
1235 local->queue_stop_reasons[q] &
1236 ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL))) {
1237 /*
1238 * Drop off-channel frames if queues are stopped
1239 * for any reason other than off-channel
1240 * operation. Never queue them.
1241 */
1242 spin_unlock_irqrestore(
1243 &local->queue_stop_reason_lock, flags);
1244 ieee80211_purge_tx_queue(&local->hw, skbs);
1245 return true;
1246 }
1247
1233 /* 1248 /*
1234 * Since queue is stopped, queue up frames for later 1249 * Since queue is stopped, queue up frames for later
1235 * transmission from the tx-pending tasklet when the 1250 * transmission from the tx-pending tasklet when the
diff --git a/net/wireless/core.c b/net/wireless/core.c
index ce827242f390..f0a1bbe95cff 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -715,7 +715,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
715 kfree(reg); 715 kfree(reg);
716 } 716 }
717 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) 717 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
718 cfg80211_put_bss(&scan->pub); 718 cfg80211_put_bss(&rdev->wiphy, &scan->pub);
719 kfree(rdev); 719 kfree(rdev);
720} 720}
721 721
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 8396f7671c8d..37d70dc2fe82 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -8,7 +8,6 @@
8#include <linux/mutex.h> 8#include <linux/mutex.h>
9#include <linux/list.h> 9#include <linux/list.h>
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/kref.h>
12#include <linux/rbtree.h> 11#include <linux/rbtree.h>
13#include <linux/debugfs.h> 12#include <linux/debugfs.h>
14#include <linux/rfkill.h> 13#include <linux/rfkill.h>
@@ -124,9 +123,10 @@ static inline void assert_cfg80211_lock(void)
124 123
125struct cfg80211_internal_bss { 124struct cfg80211_internal_bss {
126 struct list_head list; 125 struct list_head list;
126 struct list_head hidden_list;
127 struct rb_node rbn; 127 struct rb_node rbn;
128 unsigned long ts; 128 unsigned long ts;
129 struct kref ref; 129 unsigned long refcount;
130 atomic_t hold; 130 atomic_t hold;
131 131
132 /* must be last because of priv member */ 132 /* must be last because of priv member */
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 9b9551e4a6f9..d80e47194d49 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -37,7 +37,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
37 37
38 if (wdev->current_bss) { 38 if (wdev->current_bss) {
39 cfg80211_unhold_bss(wdev->current_bss); 39 cfg80211_unhold_bss(wdev->current_bss);
40 cfg80211_put_bss(&wdev->current_bss->pub); 40 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
41 } 41 }
42 42
43 cfg80211_hold_bss(bss_from_pub(bss)); 43 cfg80211_hold_bss(bss_from_pub(bss));
@@ -182,7 +182,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
182 182
183 if (wdev->current_bss) { 183 if (wdev->current_bss) {
184 cfg80211_unhold_bss(wdev->current_bss); 184 cfg80211_unhold_bss(wdev->current_bss);
185 cfg80211_put_bss(&wdev->current_bss->pub); 185 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
186 } 186 }
187 187
188 wdev->current_bss = NULL; 188 wdev->current_bss = NULL;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index fee9bf70efcf..8e6920728c43 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -58,7 +58,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
58 */ 58 */
59 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn && 59 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
60 cfg80211_sme_failed_reassoc(wdev)) { 60 cfg80211_sme_failed_reassoc(wdev)) {
61 cfg80211_put_bss(bss); 61 cfg80211_put_bss(wiphy, bss);
62 goto out; 62 goto out;
63 } 63 }
64 64
@@ -70,7 +70,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
70 * do not call connect_result() now because the 70 * do not call connect_result() now because the
71 * sme will schedule work that does it later. 71 * sme will schedule work that does it later.
72 */ 72 */
73 cfg80211_put_bss(bss); 73 cfg80211_put_bss(wiphy, bss);
74 goto out; 74 goto out;
75 } 75 }
76 76
@@ -108,7 +108,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
108 if (wdev->current_bss && 108 if (wdev->current_bss &&
109 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { 109 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
110 cfg80211_unhold_bss(wdev->current_bss); 110 cfg80211_unhold_bss(wdev->current_bss);
111 cfg80211_put_bss(&wdev->current_bss->pub); 111 cfg80211_put_bss(wiphy, &wdev->current_bss->pub);
112 wdev->current_bss = NULL; 112 wdev->current_bss = NULL;
113 was_current = true; 113 was_current = true;
114 } 114 }
@@ -164,7 +164,7 @@ void __cfg80211_send_disassoc(struct net_device *dev,
164 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { 164 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
165 cfg80211_sme_disassoc(dev, wdev->current_bss); 165 cfg80211_sme_disassoc(dev, wdev->current_bss);
166 cfg80211_unhold_bss(wdev->current_bss); 166 cfg80211_unhold_bss(wdev->current_bss);
167 cfg80211_put_bss(&wdev->current_bss->pub); 167 cfg80211_put_bss(wiphy, &wdev->current_bss->pub);
168 wdev->current_bss = NULL; 168 wdev->current_bss = NULL;
169 } else 169 } else
170 WARN_ON(1); 170 WARN_ON(1);
@@ -324,7 +324,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
324 err = rdev_auth(rdev, dev, &req); 324 err = rdev_auth(rdev, dev, &req);
325 325
326out: 326out:
327 cfg80211_put_bss(req.bss); 327 cfg80211_put_bss(&rdev->wiphy, req.bss);
328 return err; 328 return err;
329} 329}
330 330
@@ -432,7 +432,7 @@ out:
432 if (err) { 432 if (err) {
433 if (was_connected) 433 if (was_connected)
434 wdev->sme_state = CFG80211_SME_CONNECTED; 434 wdev->sme_state = CFG80211_SME_CONNECTED;
435 cfg80211_put_bss(req.bss); 435 cfg80211_put_bss(&rdev->wiphy, req.bss);
436 } 436 }
437 437
438 return err; 438 return err;
@@ -572,7 +572,7 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
572 572
573 if (wdev->current_bss) { 573 if (wdev->current_bss) {
574 cfg80211_unhold_bss(wdev->current_bss); 574 cfg80211_unhold_bss(wdev->current_bss);
575 cfg80211_put_bss(&wdev->current_bss->pub); 575 cfg80211_put_bss(&rdev->wiphy, &wdev->current_bss->pub);
576 wdev->current_bss = NULL; 576 wdev->current_bss = NULL;
577 } 577 }
578} 578}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 807d448e702e..93bc63eae076 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4997,6 +4997,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
4997 const struct cfg80211_bss_ies *ies; 4997 const struct cfg80211_bss_ies *ies;
4998 void *hdr; 4998 void *hdr;
4999 struct nlattr *bss; 4999 struct nlattr *bss;
5000 bool tsf = false;
5000 5001
5001 ASSERT_WDEV_LOCK(wdev); 5002 ASSERT_WDEV_LOCK(wdev);
5002 5003
@@ -5020,22 +5021,24 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
5020 5021
5021 rcu_read_lock(); 5022 rcu_read_lock();
5022 ies = rcu_dereference(res->ies); 5023 ies = rcu_dereference(res->ies);
5023 if (ies && ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, 5024 if (ies) {
5024 ies->len, ies->data)) { 5025 if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
5025 rcu_read_unlock(); 5026 goto fail_unlock_rcu;
5026 goto nla_put_failure; 5027 tsf = true;
5028 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
5029 ies->len, ies->data))
5030 goto fail_unlock_rcu;
5027 } 5031 }
5028 ies = rcu_dereference(res->beacon_ies); 5032 ies = rcu_dereference(res->beacon_ies);
5029 if (ies && ies->len && nla_put(msg, NL80211_BSS_BEACON_IES, 5033 if (ies) {
5030 ies->len, ies->data)) { 5034 if (!tsf && nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
5031 rcu_read_unlock(); 5035 goto fail_unlock_rcu;
5032 goto nla_put_failure; 5036 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
5037 ies->len, ies->data))
5038 goto fail_unlock_rcu;
5033 } 5039 }
5034 rcu_read_unlock(); 5040 rcu_read_unlock();
5035 5041
5036 if (res->tsf &&
5037 nla_put_u64(msg, NL80211_BSS_TSF, res->tsf))
5038 goto nla_put_failure;
5039 if (res->beacon_interval && 5042 if (res->beacon_interval &&
5040 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval)) 5043 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
5041 goto nla_put_failure; 5044 goto nla_put_failure;
@@ -5080,6 +5083,8 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
5080 5083
5081 return genlmsg_end(msg, hdr); 5084 return genlmsg_end(msg, hdr);
5082 5085
5086 fail_unlock_rcu:
5087 rcu_read_unlock();
5083 nla_put_failure: 5088 nla_put_failure:
5084 genlmsg_cancel(msg, hdr); 5089 genlmsg_cancel(msg, hdr);
5085 return -EMSGSIZE; 5090 return -EMSGSIZE;
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 6ea626b30a2a..08d3da2c70ab 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2189,10 +2189,15 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2189 * However if a driver requested this specific regulatory 2189 * However if a driver requested this specific regulatory
2190 * domain we keep it for its private use 2190 * domain we keep it for its private use
2191 */ 2191 */
2192 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER) 2192 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
2193 const struct ieee80211_regdomain *tmp;
2194
2195 tmp = get_wiphy_regdom(request_wiphy);
2193 rcu_assign_pointer(request_wiphy->regd, rd); 2196 rcu_assign_pointer(request_wiphy->regd, rd);
2194 else 2197 rcu_free_regdom(tmp);
2198 } else {
2195 kfree(rd); 2199 kfree(rd);
2200 }
2196 2201
2197 rd = NULL; 2202 rd = NULL;
2198 2203
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 36daacb31788..b7a167984986 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -19,46 +19,124 @@
19#include "wext-compat.h" 19#include "wext-compat.h"
20#include "rdev-ops.h" 20#include "rdev-ops.h"
21 21
22/**
23 * DOC: BSS tree/list structure
24 *
25 * At the top level, the BSS list is kept in both a list in each
26 * registered device (@bss_list) as well as an RB-tree for faster
27 * lookup. In the RB-tree, entries can be looked up using their
28 * channel, MESHID, MESHCONF (for MBSSes) or channel, BSSID, SSID
29 * for other BSSes.
30 *
31 * Due to the possibility of hidden SSIDs, there's a second level
32 * structure, the "hidden_list" and "hidden_beacon_bss" pointer.
33 * The hidden_list connects all BSSes belonging to a single AP
34 * that has a hidden SSID, and connects beacon and probe response
35 * entries. For a probe response entry for a hidden SSID, the
36 * hidden_beacon_bss pointer points to the BSS struct holding the
37 * beacon's information.
38 *
39 * Reference counting is done for all these references except for
40 * the hidden_list, so that a beacon BSS struct that is otherwise
41 * not referenced has one reference for being on the bss_list and
42 * one for each probe response entry that points to it using the
43 * hidden_beacon_bss pointer. When a BSS struct that has such a
44 * pointer is get/put, the refcount update is also propagated to
45 * the referenced struct, this ensure that it cannot get removed
46 * while somebody is using the probe response version.
47 *
48 * Note that the hidden_beacon_bss pointer never changes, due to
49 * the reference counting. Therefore, no locking is needed for
50 * it.
51 *
52 * Also note that the hidden_beacon_bss pointer is only relevant
53 * if the driver uses something other than the IEs, e.g. private
54 * data stored stored in the BSS struct, since the beacon IEs are
55 * also linked into the probe response struct.
56 */
57
22#define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ) 58#define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ)
23 59
24static void bss_release(struct kref *ref) 60static void bss_free(struct cfg80211_internal_bss *bss)
25{ 61{
26 struct cfg80211_bss_ies *ies; 62 struct cfg80211_bss_ies *ies;
27 struct cfg80211_internal_bss *bss;
28
29 bss = container_of(ref, struct cfg80211_internal_bss, ref);
30 63
31 if (WARN_ON(atomic_read(&bss->hold))) 64 if (WARN_ON(atomic_read(&bss->hold)))
32 return; 65 return;
33 66
34 ies = (void *)rcu_access_pointer(bss->pub.beacon_ies); 67 ies = (void *)rcu_access_pointer(bss->pub.beacon_ies);
35 if (ies) 68 if (ies && !bss->pub.hidden_beacon_bss)
36 kfree_rcu(ies, rcu_head); 69 kfree_rcu(ies, rcu_head);
37 ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies); 70 ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies);
38 if (ies) 71 if (ies)
39 kfree_rcu(ies, rcu_head); 72 kfree_rcu(ies, rcu_head);
40 73
74 /*
75 * This happens when the module is removed, it doesn't
76 * really matter any more save for completeness
77 */
78 if (!list_empty(&bss->hidden_list))
79 list_del(&bss->hidden_list);
80
41 kfree(bss); 81 kfree(bss);
42} 82}
43 83
44static inline void bss_ref_get(struct cfg80211_internal_bss *bss) 84static inline void bss_ref_get(struct cfg80211_registered_device *dev,
85 struct cfg80211_internal_bss *bss)
45{ 86{
46 kref_get(&bss->ref); 87 lockdep_assert_held(&dev->bss_lock);
88
89 bss->refcount++;
90 if (bss->pub.hidden_beacon_bss) {
91 bss = container_of(bss->pub.hidden_beacon_bss,
92 struct cfg80211_internal_bss,
93 pub);
94 bss->refcount++;
95 }
47} 96}
48 97
49static inline void bss_ref_put(struct cfg80211_internal_bss *bss) 98static inline void bss_ref_put(struct cfg80211_registered_device *dev,
99 struct cfg80211_internal_bss *bss)
50{ 100{
51 kref_put(&bss->ref, bss_release); 101 lockdep_assert_held(&dev->bss_lock);
102
103 if (bss->pub.hidden_beacon_bss) {
104 struct cfg80211_internal_bss *hbss;
105 hbss = container_of(bss->pub.hidden_beacon_bss,
106 struct cfg80211_internal_bss,
107 pub);
108 hbss->refcount--;
109 if (hbss->refcount == 0)
110 bss_free(hbss);
111 }
112 bss->refcount--;
113 if (bss->refcount == 0)
114 bss_free(bss);
52} 115}
53 116
54static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev, 117static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *dev,
55 struct cfg80211_internal_bss *bss) 118 struct cfg80211_internal_bss *bss)
56{ 119{
57 lockdep_assert_held(&dev->bss_lock); 120 lockdep_assert_held(&dev->bss_lock);
58 121
122 if (!list_empty(&bss->hidden_list)) {
123 /*
124 * don't remove the beacon entry if it has
125 * probe responses associated with it
126 */
127 if (!bss->pub.hidden_beacon_bss)
128 return false;
129 /*
130 * if it's a probe response entry break its
131 * link to the other entries in the group
132 */
133 list_del_init(&bss->hidden_list);
134 }
135
59 list_del_init(&bss->list); 136 list_del_init(&bss->list);
60 rb_erase(&bss->rbn, &dev->bss_tree); 137 rb_erase(&bss->rbn, &dev->bss_tree);
61 bss_ref_put(bss); 138 bss_ref_put(dev, bss);
139 return true;
62} 140}
63 141
64static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev, 142static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev,
@@ -75,8 +153,8 @@ static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev,
75 if (!time_after(expire_time, bss->ts)) 153 if (!time_after(expire_time, bss->ts))
76 continue; 154 continue;
77 155
78 __cfg80211_unlink_bss(dev, bss); 156 if (__cfg80211_unlink_bss(dev, bss))
79 expired = true; 157 expired = true;
80 } 158 }
81 159
82 if (expired) 160 if (expired)
@@ -466,7 +544,7 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
466 continue; 544 continue;
467 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) { 545 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
468 res = bss; 546 res = bss;
469 bss_ref_get(res); 547 bss_ref_get(dev, res);
470 break; 548 break;
471 } 549 }
472 } 550 }
@@ -532,23 +610,67 @@ rb_find_bss(struct cfg80211_registered_device *dev,
532 return NULL; 610 return NULL;
533} 611}
534 612
535static void 613static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
536copy_hidden_ies(struct cfg80211_internal_bss *res, 614 struct cfg80211_internal_bss *new)
537 struct cfg80211_internal_bss *hidden)
538{ 615{
539 const struct cfg80211_bss_ies *ies; 616 const struct cfg80211_bss_ies *ies;
617 struct cfg80211_internal_bss *bss;
618 const u8 *ie;
619 int i, ssidlen;
620 u8 fold = 0;
540 621
541 if (rcu_access_pointer(res->pub.beacon_ies)) 622 ies = rcu_access_pointer(new->pub.beacon_ies);
542 return;
543
544 ies = rcu_access_pointer(hidden->pub.beacon_ies);
545 if (WARN_ON(!ies)) 623 if (WARN_ON(!ies))
546 return; 624 return false;
547 625
548 ies = kmemdup(ies, sizeof(*ies) + ies->len, GFP_ATOMIC); 626 ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
549 if (unlikely(!ies)) 627 if (!ie) {
550 return; 628 /* nothing to do */
551 rcu_assign_pointer(res->pub.beacon_ies, ies); 629 return true;
630 }
631
632 ssidlen = ie[1];
633 for (i = 0; i < ssidlen; i++)
634 fold |= ie[2 + i];
635
636 if (fold) {
637 /* not a hidden SSID */
638 return true;
639 }
640
641 /* This is the bad part ... */
642
643 list_for_each_entry(bss, &dev->bss_list, list) {
644 if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
645 continue;
646 if (bss->pub.channel != new->pub.channel)
647 continue;
648 if (rcu_access_pointer(bss->pub.beacon_ies))
649 continue;
650 ies = rcu_access_pointer(bss->pub.ies);
651 if (!ies)
652 continue;
653 ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
654 if (!ie)
655 continue;
656 if (ssidlen && ie[1] != ssidlen)
657 continue;
658 /* that would be odd ... */
659 if (bss->pub.beacon_ies)
660 continue;
661 if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
662 continue;
663 if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
664 list_del(&bss->hidden_list);
665 /* combine them */
666 list_add(&bss->hidden_list, &new->hidden_list);
667 bss->pub.hidden_beacon_bss = &new->pub;
668 new->refcount += bss->refcount;
669 rcu_assign_pointer(bss->pub.beacon_ies,
670 new->pub.beacon_ies);
671 }
672
673 return true;
552} 674}
553 675
554static struct cfg80211_internal_bss * 676static struct cfg80211_internal_bss *
@@ -573,7 +695,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
573 695
574 if (found) { 696 if (found) {
575 found->pub.beacon_interval = tmp->pub.beacon_interval; 697 found->pub.beacon_interval = tmp->pub.beacon_interval;
576 found->pub.tsf = tmp->pub.tsf;
577 found->pub.signal = tmp->pub.signal; 698 found->pub.signal = tmp->pub.signal;
578 found->pub.capability = tmp->pub.capability; 699 found->pub.capability = tmp->pub.capability;
579 found->ts = tmp->ts; 700 found->ts = tmp->ts;
@@ -594,6 +715,21 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
594 rcu_head); 715 rcu_head);
595 } else if (rcu_access_pointer(tmp->pub.beacon_ies)) { 716 } else if (rcu_access_pointer(tmp->pub.beacon_ies)) {
596 const struct cfg80211_bss_ies *old; 717 const struct cfg80211_bss_ies *old;
718 struct cfg80211_internal_bss *bss;
719
720 if (found->pub.hidden_beacon_bss &&
721 !list_empty(&found->hidden_list)) {
722 /*
723 * The found BSS struct is one of the probe
724 * response members of a group, but we're
725 * receiving a beacon (beacon_ies in the tmp
726 * bss is used). This can only mean that the
727 * AP changed its beacon from not having an
728 * SSID to showing it, which is confusing so
729 * drop this information.
730 */
731 goto drop;
732 }
597 733
598 old = rcu_access_pointer(found->pub.beacon_ies); 734 old = rcu_access_pointer(found->pub.beacon_ies);
599 735
@@ -605,6 +741,18 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
605 rcu_assign_pointer(found->pub.ies, 741 rcu_assign_pointer(found->pub.ies,
606 tmp->pub.beacon_ies); 742 tmp->pub.beacon_ies);
607 743
744 /* Assign beacon IEs to all sub entries */
745 list_for_each_entry(bss, &found->hidden_list,
746 hidden_list) {
747 const struct cfg80211_bss_ies *ies;
748
749 ies = rcu_access_pointer(bss->pub.beacon_ies);
750 WARN_ON(ies != old);
751
752 rcu_assign_pointer(bss->pub.beacon_ies,
753 tmp->pub.beacon_ies);
754 }
755
608 if (old) 756 if (old)
609 kfree_rcu((struct cfg80211_bss_ies *)old, 757 kfree_rcu((struct cfg80211_bss_ies *)old,
610 rcu_head); 758 rcu_head);
@@ -614,24 +762,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
614 struct cfg80211_internal_bss *hidden; 762 struct cfg80211_internal_bss *hidden;
615 struct cfg80211_bss_ies *ies; 763 struct cfg80211_bss_ies *ies;
616 764
617 /* First check if the beacon is a probe response from
618 * a hidden bss. If so, copy beacon ies (with nullified
619 * ssid) into the probe response bss entry (with real ssid).
620 * It is required basically for PSM implementation
621 * (probe responses do not contain tim ie) */
622
623 /* TODO: The code is not trying to update existing probe
624 * response bss entries when beacon ies are
625 * getting changed. */
626 hidden = rb_find_bss(dev, tmp, BSS_CMP_HIDE_ZLEN);
627 if (hidden) {
628 copy_hidden_ies(tmp, hidden);
629 } else {
630 hidden = rb_find_bss(dev, tmp, BSS_CMP_HIDE_NUL);
631 if (hidden)
632 copy_hidden_ies(tmp, hidden);
633 }
634
635 /* 765 /*
636 * create a copy -- the "res" variable that is passed in 766 * create a copy -- the "res" variable that is passed in
637 * is allocated on the stack since it's not needed in the 767 * is allocated on the stack since it's not needed in the
@@ -646,21 +776,51 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
646 ies = (void *)rcu_dereference(tmp->pub.proberesp_ies); 776 ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
647 if (ies) 777 if (ies)
648 kfree_rcu(ies, rcu_head); 778 kfree_rcu(ies, rcu_head);
649 spin_unlock_bh(&dev->bss_lock); 779 goto drop;
650 return NULL;
651 } 780 }
652 memcpy(new, tmp, sizeof(*new)); 781 memcpy(new, tmp, sizeof(*new));
653 kref_init(&new->ref); 782 new->refcount = 1;
783 INIT_LIST_HEAD(&new->hidden_list);
784
785 if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
786 hidden = rb_find_bss(dev, tmp, BSS_CMP_HIDE_ZLEN);
787 if (!hidden)
788 hidden = rb_find_bss(dev, tmp,
789 BSS_CMP_HIDE_NUL);
790 if (hidden) {
791 new->pub.hidden_beacon_bss = &hidden->pub;
792 list_add(&new->hidden_list,
793 &hidden->hidden_list);
794 hidden->refcount++;
795 rcu_assign_pointer(new->pub.beacon_ies,
796 hidden->pub.beacon_ies);
797 }
798 } else {
799 /*
800 * Ok so we found a beacon, and don't have an entry. If
801 * it's a beacon with hidden SSID, we might be in for an
802 * expensive search for any probe responses that should
803 * be grouped with this beacon for updates ...
804 */
805 if (!cfg80211_combine_bsses(dev, new)) {
806 kfree(new);
807 goto drop;
808 }
809 }
810
654 list_add_tail(&new->list, &dev->bss_list); 811 list_add_tail(&new->list, &dev->bss_list);
655 rb_insert_bss(dev, new); 812 rb_insert_bss(dev, new);
656 found = new; 813 found = new;
657 } 814 }
658 815
659 dev->bss_generation++; 816 dev->bss_generation++;
817 bss_ref_get(dev, found);
660 spin_unlock_bh(&dev->bss_lock); 818 spin_unlock_bh(&dev->bss_lock);
661 819
662 bss_ref_get(found);
663 return found; 820 return found;
821 drop:
822 spin_unlock_bh(&dev->bss_lock);
823 return NULL;
664} 824}
665 825
666static struct ieee80211_channel * 826static struct ieee80211_channel *
@@ -719,7 +879,6 @@ cfg80211_inform_bss(struct wiphy *wiphy,
719 memcpy(tmp.pub.bssid, bssid, ETH_ALEN); 879 memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
720 tmp.pub.channel = channel; 880 tmp.pub.channel = channel;
721 tmp.pub.signal = signal; 881 tmp.pub.signal = signal;
722 tmp.pub.tsf = tsf;
723 tmp.pub.beacon_interval = beacon_interval; 882 tmp.pub.beacon_interval = beacon_interval;
724 tmp.pub.capability = capability; 883 tmp.pub.capability = capability;
725 /* 884 /*
@@ -734,6 +893,7 @@ cfg80211_inform_bss(struct wiphy *wiphy,
734 if (!ies) 893 if (!ies)
735 return NULL; 894 return NULL;
736 ies->len = ielen; 895 ies->len = ielen;
896 ies->tsf = tsf;
737 memcpy(ies->data, ie, ielen); 897 memcpy(ies->data, ie, ielen);
738 898
739 rcu_assign_pointer(tmp.pub.beacon_ies, ies); 899 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
@@ -790,6 +950,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
790 if (!ies) 950 if (!ies)
791 return NULL; 951 return NULL;
792 ies->len = ielen; 952 ies->len = ielen;
953 ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
793 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen); 954 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen);
794 955
795 if (ieee80211_is_probe_resp(mgmt->frame_control)) 956 if (ieee80211_is_probe_resp(mgmt->frame_control))
@@ -801,7 +962,6 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
801 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN); 962 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN);
802 tmp.pub.channel = channel; 963 tmp.pub.channel = channel;
803 tmp.pub.signal = signal; 964 tmp.pub.signal = signal;
804 tmp.pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
805 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 965 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
806 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); 966 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
807 967
@@ -818,27 +978,35 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
818} 978}
819EXPORT_SYMBOL(cfg80211_inform_bss_frame); 979EXPORT_SYMBOL(cfg80211_inform_bss_frame);
820 980
821void cfg80211_ref_bss(struct cfg80211_bss *pub) 981void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
822{ 982{
983 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
823 struct cfg80211_internal_bss *bss; 984 struct cfg80211_internal_bss *bss;
824 985
825 if (!pub) 986 if (!pub)
826 return; 987 return;
827 988
828 bss = container_of(pub, struct cfg80211_internal_bss, pub); 989 bss = container_of(pub, struct cfg80211_internal_bss, pub);
829 bss_ref_get(bss); 990
991 spin_lock_bh(&dev->bss_lock);
992 bss_ref_get(dev, bss);
993 spin_unlock_bh(&dev->bss_lock);
830} 994}
831EXPORT_SYMBOL(cfg80211_ref_bss); 995EXPORT_SYMBOL(cfg80211_ref_bss);
832 996
833void cfg80211_put_bss(struct cfg80211_bss *pub) 997void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
834{ 998{
999 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
835 struct cfg80211_internal_bss *bss; 1000 struct cfg80211_internal_bss *bss;
836 1001
837 if (!pub) 1002 if (!pub)
838 return; 1003 return;
839 1004
840 bss = container_of(pub, struct cfg80211_internal_bss, pub); 1005 bss = container_of(pub, struct cfg80211_internal_bss, pub);
841 bss_ref_put(bss); 1006
1007 spin_lock_bh(&dev->bss_lock);
1008 bss_ref_put(dev, bss);
1009 spin_unlock_bh(&dev->bss_lock);
842} 1010}
843EXPORT_SYMBOL(cfg80211_put_bss); 1011EXPORT_SYMBOL(cfg80211_put_bss);
844 1012
@@ -854,8 +1022,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
854 1022
855 spin_lock_bh(&dev->bss_lock); 1023 spin_lock_bh(&dev->bss_lock);
856 if (!list_empty(&bss->list)) { 1024 if (!list_empty(&bss->list)) {
857 __cfg80211_unlink_bss(dev, bss); 1025 if (__cfg80211_unlink_bss(dev, bss))
858 dev->bss_generation++; 1026 dev->bss_generation++;
859 } 1027 }
860 spin_unlock_bh(&dev->bss_lock); 1028 spin_unlock_bh(&dev->bss_lock);
861} 1029}
@@ -1124,15 +1292,10 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1124 1292
1125 rcu_read_lock(); 1293 rcu_read_lock();
1126 ies = rcu_dereference(bss->pub.ies); 1294 ies = rcu_dereference(bss->pub.ies);
1127 if (ies) { 1295 rem = ies->len;
1128 rem = ies->len; 1296 ie = ies->data;
1129 ie = ies->data;
1130 } else {
1131 rem = 0;
1132 ie = NULL;
1133 }
1134 1297
1135 while (ies && rem >= 2) { 1298 while (rem >= 2) {
1136 /* invalid data */ 1299 /* invalid data */
1137 if (ie[1] > rem - 2) 1300 if (ie[1] > rem - 2)
1138 break; 1301 break;
@@ -1245,7 +1408,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1245 if (buf) { 1408 if (buf) {
1246 memset(&iwe, 0, sizeof(iwe)); 1409 memset(&iwe, 0, sizeof(iwe));
1247 iwe.cmd = IWEVCUSTOM; 1410 iwe.cmd = IWEVCUSTOM;
1248 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->pub.tsf)); 1411 sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf));
1249 iwe.u.data.length = strlen(buf); 1412 iwe.u.data.length = strlen(buf);
1250 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1413 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1251 &iwe, buf); 1414 &iwe, buf);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index a825dfe12cf7..f432bd3755b1 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -301,7 +301,7 @@ static void __cfg80211_sme_scan_done(struct net_device *dev)
301 301
302 bss = cfg80211_get_conn_bss(wdev); 302 bss = cfg80211_get_conn_bss(wdev);
303 if (bss) { 303 if (bss) {
304 cfg80211_put_bss(bss); 304 cfg80211_put_bss(&rdev->wiphy, bss);
305 } else { 305 } else {
306 /* not found */ 306 /* not found */
307 if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) 307 if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)
@@ -464,7 +464,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
464 464
465 if (wdev->current_bss) { 465 if (wdev->current_bss) {
466 cfg80211_unhold_bss(wdev->current_bss); 466 cfg80211_unhold_bss(wdev->current_bss);
467 cfg80211_put_bss(&wdev->current_bss->pub); 467 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
468 wdev->current_bss = NULL; 468 wdev->current_bss = NULL;
469 } 469 }
470 470
@@ -480,7 +480,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
480 kfree(wdev->connect_keys); 480 kfree(wdev->connect_keys);
481 wdev->connect_keys = NULL; 481 wdev->connect_keys = NULL;
482 wdev->ssid_len = 0; 482 wdev->ssid_len = 0;
483 cfg80211_put_bss(bss); 483 cfg80211_put_bss(wdev->wiphy, bss);
484 return; 484 return;
485 } 485 }
486 486
@@ -586,7 +586,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev,
586 } 586 }
587 587
588 cfg80211_unhold_bss(wdev->current_bss); 588 cfg80211_unhold_bss(wdev->current_bss);
589 cfg80211_put_bss(&wdev->current_bss->pub); 589 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
590 wdev->current_bss = NULL; 590 wdev->current_bss = NULL;
591 591
592 cfg80211_hold_bss(bss_from_pub(bss)); 592 cfg80211_hold_bss(bss_from_pub(bss));
@@ -621,7 +621,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev,
621 621
622 return; 622 return;
623out: 623out:
624 cfg80211_put_bss(bss); 624 cfg80211_put_bss(wdev->wiphy, bss);
625} 625}
626 626
627void cfg80211_roamed(struct net_device *dev, 627void cfg80211_roamed(struct net_device *dev,
@@ -663,7 +663,7 @@ void cfg80211_roamed_bss(struct net_device *dev,
663 663
664 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp); 664 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
665 if (!ev) { 665 if (!ev) {
666 cfg80211_put_bss(bss); 666 cfg80211_put_bss(wdev->wiphy, bss);
667 return; 667 return;
668 } 668 }
669 669
@@ -704,7 +704,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
704 704
705 if (wdev->current_bss) { 705 if (wdev->current_bss) {
706 cfg80211_unhold_bss(wdev->current_bss); 706 cfg80211_unhold_bss(wdev->current_bss);
707 cfg80211_put_bss(&wdev->current_bss->pub); 707 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
708 } 708 }
709 709
710 wdev->current_bss = NULL; 710 wdev->current_bss = NULL;
@@ -875,7 +875,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
875 if (bss) { 875 if (bss) {
876 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; 876 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
877 err = cfg80211_conn_do_work(wdev); 877 err = cfg80211_conn_do_work(wdev);
878 cfg80211_put_bss(bss); 878 cfg80211_put_bss(wdev->wiphy, bss);
879 } else { 879 } else {
880 /* otherwise we'll need to scan for the AP first */ 880 /* otherwise we'll need to scan for the AP first */
881 err = cfg80211_conn_scan(wdev); 881 err = cfg80211_conn_scan(wdev);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index d7873c7ae0ec..37a56ee1e1ed 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1217,10 +1217,10 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1217 break; 1217 break;
1218 case NL80211_IFTYPE_P2P_CLIENT: 1218 case NL80211_IFTYPE_P2P_CLIENT:
1219 case NL80211_IFTYPE_STATION: 1219 case NL80211_IFTYPE_STATION:
1220 case NL80211_IFTYPE_P2P_DEVICE:
1220 case NL80211_IFTYPE_MONITOR: 1221 case NL80211_IFTYPE_MONITOR:
1221 radar_required = false; 1222 radar_required = false;
1222 break; 1223 break;
1223 case NL80211_IFTYPE_P2P_DEVICE:
1224 case NUM_NL80211_IFTYPES: 1224 case NUM_NL80211_IFTYPES:
1225 case NL80211_IFTYPE_UNSPECIFIED: 1225 case NL80211_IFTYPE_UNSPECIFIED:
1226 default: 1226 default: