aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c27
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.c20
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.h2
-rw-r--r--drivers/net/wireless/ti/wl18xx/scan.c16
-rw-r--r--drivers/net/wireless/ti/wl18xx/scan.h2
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c11
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.h2
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h2
-rw-r--r--include/net/mac80211.h23
-rw-r--r--net/mac80211/driver-ops.h2
-rw-r--r--net/mac80211/scan.c47
15 files changed, 88 insertions, 75 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 4dc2e05f49ce..7dd363dd3ad3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -1828,7 +1828,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
1828static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, 1828static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
1829 struct ieee80211_vif *vif, 1829 struct ieee80211_vif *vif,
1830 struct cfg80211_sched_scan_request *req, 1830 struct cfg80211_sched_scan_request *req,
1831 struct ieee80211_sched_scan_ies *ies) 1831 struct ieee80211_scan_ies *ies)
1832{ 1832{
1833 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1833 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1834 int ret; 1834 int ret;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index fcc6c29482d0..97630f9a7cb9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -854,7 +854,7 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
854int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, 854int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
855 struct ieee80211_vif *vif, 855 struct ieee80211_vif *vif,
856 struct cfg80211_sched_scan_request *req, 856 struct cfg80211_sched_scan_request *req,
857 struct ieee80211_sched_scan_ies *ies); 857 struct ieee80211_scan_ies *ies);
858int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, 858int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
859 struct cfg80211_sched_scan_request *req); 859 struct cfg80211_sched_scan_request *req);
860int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, 860int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 4b6c7d4bd199..3206fa097255 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -204,7 +204,8 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
204 */ 204 */
205static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, 205static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
206 int n_ssids, const u8 *ssid, int ssid_len, 206 int n_ssids, const u8 *ssid, int ssid_len,
207 const u8 *ie, int ie_len, 207 const u8 *band_ie, int band_ie_len,
208 const u8 *common_ie, int common_ie_len,
208 int left) 209 int left)
209{ 210{
210 int len = 0; 211 int len = 0;
@@ -244,12 +245,19 @@ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
244 245
245 len += ssid_len + 2; 246 len += ssid_len + 2;
246 247
247 if (WARN_ON(left < ie_len)) 248 if (WARN_ON(left < band_ie_len + common_ie_len))
248 return len; 249 return len;
249 250
250 if (ie && ie_len) { 251 if (band_ie && band_ie_len) {
251 memcpy(pos, ie, ie_len); 252 memcpy(pos, band_ie, band_ie_len);
252 len += ie_len; 253 pos += band_ie_len;
254 len += band_ie_len;
255 }
256
257 if (common_ie && common_ie_len) {
258 memcpy(pos, common_ie, common_ie_len);
259 pos += common_ie_len;
260 len += common_ie_len;
253 } 261 }
254 262
255 return (u16)len; 263 return (u16)len;
@@ -382,7 +390,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
382 (struct ieee80211_mgmt *)cmd->data, 390 (struct ieee80211_mgmt *)cmd->data,
383 vif->addr, 391 vif->addr,
384 req->n_ssids, ssid, ssid_len, 392 req->n_ssids, ssid, ssid_len,
385 req->ie, req->ie_len, 393 req->ie, req->ie_len, NULL, 0,
386 mvm->fw->ucode_capa.max_probe_length)); 394 mvm->fw->ucode_capa.max_probe_length));
387 395
388 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, &params); 396 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, &params);
@@ -561,7 +569,7 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
561 569
562static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm, 570static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
563 struct ieee80211_vif *vif, 571 struct ieee80211_vif *vif,
564 struct ieee80211_sched_scan_ies *ies, 572 struct ieee80211_scan_ies *ies,
565 enum ieee80211_band band, 573 enum ieee80211_band band,
566 struct iwl_tx_cmd *cmd, 574 struct iwl_tx_cmd *cmd,
567 u8 *data) 575 u8 *data)
@@ -577,7 +585,8 @@ static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
577 cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data, 585 cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data,
578 vif->addr, 586 vif->addr,
579 1, NULL, 0, 587 1, NULL, 0,
580 ies->ie[band], ies->len[band], 588 ies->ies[band], ies->len[band],
589 ies->common_ies, ies->common_ie_len,
581 SCAN_OFFLOAD_PROBE_REQ_SIZE); 590 SCAN_OFFLOAD_PROBE_REQ_SIZE);
582 cmd->len = cpu_to_le16(cmd_len); 591 cmd->len = cpu_to_le16(cmd_len);
583} 592}
@@ -735,7 +744,7 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
735int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, 744int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
736 struct ieee80211_vif *vif, 745 struct ieee80211_vif *vif,
737 struct cfg80211_sched_scan_request *req, 746 struct cfg80211_sched_scan_request *req,
738 struct ieee80211_sched_scan_ies *ies) 747 struct ieee80211_scan_ies *ies)
739{ 748{
740 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels; 749 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
741 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 750 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
diff --git a/drivers/net/wireless/ti/wl12xx/scan.c b/drivers/net/wireless/ti/wl12xx/scan.c
index 7541bd1a4a4b..0c0d5cd98514 100644
--- a/drivers/net/wireless/ti/wl12xx/scan.c
+++ b/drivers/net/wireless/ti/wl12xx/scan.c
@@ -156,7 +156,7 @@ static int wl1271_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
156 cmd->params.role_id, band, 156 cmd->params.role_id, band,
157 wl->scan.ssid, wl->scan.ssid_len, 157 wl->scan.ssid, wl->scan.ssid_len,
158 wl->scan.req->ie, 158 wl->scan.req->ie,
159 wl->scan.req->ie_len, false); 159 wl->scan.req->ie_len, NULL, 0, false);
160 if (ret < 0) { 160 if (ret < 0) {
161 wl1271_error("PROBE request template failed"); 161 wl1271_error("PROBE request template failed");
162 goto out; 162 goto out;
@@ -317,7 +317,7 @@ static void wl12xx_adjust_channels(struct wl1271_cmd_sched_scan_config *cmd,
317int wl1271_scan_sched_scan_config(struct wl1271 *wl, 317int wl1271_scan_sched_scan_config(struct wl1271 *wl,
318 struct wl12xx_vif *wlvif, 318 struct wl12xx_vif *wlvif,
319 struct cfg80211_sched_scan_request *req, 319 struct cfg80211_sched_scan_request *req,
320 struct ieee80211_sched_scan_ies *ies) 320 struct ieee80211_scan_ies *ies)
321{ 321{
322 struct wl1271_cmd_sched_scan_config *cfg = NULL; 322 struct wl1271_cmd_sched_scan_config *cfg = NULL;
323 struct wlcore_scan_channels *cfg_channels = NULL; 323 struct wlcore_scan_channels *cfg_channels = NULL;
@@ -378,8 +378,11 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
378 wlvif->role_id, band, 378 wlvif->role_id, band,
379 req->ssids[0].ssid, 379 req->ssids[0].ssid,
380 req->ssids[0].ssid_len, 380 req->ssids[0].ssid_len,
381 ies->ie[band], 381 ies->ies[band],
382 ies->len[band], true); 382 ies->len[band],
383 ies->common_ies,
384 ies->common_ie_len,
385 true);
383 if (ret < 0) { 386 if (ret < 0) {
384 wl1271_error("2.4GHz PROBE request template failed"); 387 wl1271_error("2.4GHz PROBE request template failed");
385 goto out; 388 goto out;
@@ -392,8 +395,11 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
392 wlvif->role_id, band, 395 wlvif->role_id, band,
393 req->ssids[0].ssid, 396 req->ssids[0].ssid,
394 req->ssids[0].ssid_len, 397 req->ssids[0].ssid_len,
395 ies->ie[band], 398 ies->ies[band],
396 ies->len[band], true); 399 ies->len[band],
400 ies->common_ies,
401 ies->common_ie_len,
402 true);
397 if (ret < 0) { 403 if (ret < 0) {
398 wl1271_error("5GHz PROBE request template failed"); 404 wl1271_error("5GHz PROBE request template failed");
399 goto out; 405 goto out;
@@ -449,7 +455,7 @@ out_free:
449 455
450int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif, 456int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
451 struct cfg80211_sched_scan_request *req, 457 struct cfg80211_sched_scan_request *req,
452 struct ieee80211_sched_scan_ies *ies) 458 struct ieee80211_scan_ies *ies)
453{ 459{
454 int ret; 460 int ret;
455 461
diff --git a/drivers/net/wireless/ti/wl12xx/scan.h b/drivers/net/wireless/ti/wl12xx/scan.h
index 264af7ac2785..427f9af85a00 100644
--- a/drivers/net/wireless/ti/wl12xx/scan.h
+++ b/drivers/net/wireless/ti/wl12xx/scan.h
@@ -135,6 +135,6 @@ int wl12xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
135void wl12xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif); 135void wl12xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif);
136int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif, 136int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
137 struct cfg80211_sched_scan_request *req, 137 struct cfg80211_sched_scan_request *req,
138 struct ieee80211_sched_scan_ies *ies); 138 struct ieee80211_scan_ies *ies);
139void wl12xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif); 139void wl12xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
140#endif 140#endif
diff --git a/drivers/net/wireless/ti/wl18xx/scan.c b/drivers/net/wireless/ti/wl18xx/scan.c
index 2b642f8c9266..98666f235a12 100644
--- a/drivers/net/wireless/ti/wl18xx/scan.c
+++ b/drivers/net/wireless/ti/wl18xx/scan.c
@@ -113,6 +113,8 @@ static int wl18xx_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
113 req->ssids ? req->ssids[0].ssid_len : 0, 113 req->ssids ? req->ssids[0].ssid_len : 0,
114 req->ie, 114 req->ie,
115 req->ie_len, 115 req->ie_len,
116 NULL,
117 0,
116 false); 118 false);
117 if (ret < 0) { 119 if (ret < 0) {
118 wl1271_error("2.4GHz PROBE request template failed"); 120 wl1271_error("2.4GHz PROBE request template failed");
@@ -128,6 +130,8 @@ static int wl18xx_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
128 req->ssids ? req->ssids[0].ssid_len : 0, 130 req->ssids ? req->ssids[0].ssid_len : 0,
129 req->ie, 131 req->ie,
130 req->ie_len, 132 req->ie_len,
133 NULL,
134 0,
131 false); 135 false);
132 if (ret < 0) { 136 if (ret < 0) {
133 wl1271_error("5GHz PROBE request template failed"); 137 wl1271_error("5GHz PROBE request template failed");
@@ -161,7 +165,7 @@ static
161int wl18xx_scan_sched_scan_config(struct wl1271 *wl, 165int wl18xx_scan_sched_scan_config(struct wl1271 *wl,
162 struct wl12xx_vif *wlvif, 166 struct wl12xx_vif *wlvif,
163 struct cfg80211_sched_scan_request *req, 167 struct cfg80211_sched_scan_request *req,
164 struct ieee80211_sched_scan_ies *ies) 168 struct ieee80211_scan_ies *ies)
165{ 169{
166 struct wl18xx_cmd_scan_params *cmd; 170 struct wl18xx_cmd_scan_params *cmd;
167 struct wlcore_scan_channels *cmd_channels = NULL; 171 struct wlcore_scan_channels *cmd_channels = NULL;
@@ -237,8 +241,10 @@ int wl18xx_scan_sched_scan_config(struct wl1271 *wl,
237 cmd->role_id, band, 241 cmd->role_id, band,
238 req->ssids ? req->ssids[0].ssid : NULL, 242 req->ssids ? req->ssids[0].ssid : NULL,
239 req->ssids ? req->ssids[0].ssid_len : 0, 243 req->ssids ? req->ssids[0].ssid_len : 0,
240 ies->ie[band], 244 ies->ies[band],
241 ies->len[band], 245 ies->len[band],
246 ies->common_ies,
247 ies->common_ie_len,
242 true); 248 true);
243 if (ret < 0) { 249 if (ret < 0) {
244 wl1271_error("2.4GHz PROBE request template failed"); 250 wl1271_error("2.4GHz PROBE request template failed");
@@ -252,8 +258,10 @@ int wl18xx_scan_sched_scan_config(struct wl1271 *wl,
252 cmd->role_id, band, 258 cmd->role_id, band,
253 req->ssids ? req->ssids[0].ssid : NULL, 259 req->ssids ? req->ssids[0].ssid : NULL,
254 req->ssids ? req->ssids[0].ssid_len : 0, 260 req->ssids ? req->ssids[0].ssid_len : 0,
255 ies->ie[band], 261 ies->ies[band],
256 ies->len[band], 262 ies->len[band],
263 ies->common_ies,
264 ies->common_ie_len,
257 true); 265 true);
258 if (ret < 0) { 266 if (ret < 0) {
259 wl1271_error("5GHz PROBE request template failed"); 267 wl1271_error("5GHz PROBE request template failed");
@@ -277,7 +285,7 @@ out:
277 285
278int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif, 286int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
279 struct cfg80211_sched_scan_request *req, 287 struct cfg80211_sched_scan_request *req,
280 struct ieee80211_sched_scan_ies *ies) 288 struct ieee80211_scan_ies *ies)
281{ 289{
282 return wl18xx_scan_sched_scan_config(wl, wlvif, req, ies); 290 return wl18xx_scan_sched_scan_config(wl, wlvif, req, ies);
283} 291}
diff --git a/drivers/net/wireless/ti/wl18xx/scan.h b/drivers/net/wireless/ti/wl18xx/scan.h
index eadee42689d1..2e636aa5dba9 100644
--- a/drivers/net/wireless/ti/wl18xx/scan.h
+++ b/drivers/net/wireless/ti/wl18xx/scan.h
@@ -122,6 +122,6 @@ int wl18xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
122void wl18xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif); 122void wl18xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif);
123int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif, 123int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
124 struct cfg80211_sched_scan_request *req, 124 struct cfg80211_sched_scan_request *req,
125 struct ieee80211_sched_scan_ies *ies); 125 struct ieee80211_scan_ies *ies);
126void wl18xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif); 126void wl18xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
127#endif 127#endif
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 40dc30f4faaa..e269c0a57017 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1124,7 +1124,8 @@ out:
1124int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1124int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1125 u8 role_id, u8 band, 1125 u8 role_id, u8 band,
1126 const u8 *ssid, size_t ssid_len, 1126 const u8 *ssid, size_t ssid_len,
1127 const u8 *ie, size_t ie_len, bool sched_scan) 1127 const u8 *ie0, size_t ie0_len, const u8 *ie1,
1128 size_t ie1_len, bool sched_scan)
1128{ 1129{
1129 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 1130 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
1130 struct sk_buff *skb; 1131 struct sk_buff *skb;
@@ -1136,13 +1137,15 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1136 wl1271_debug(DEBUG_SCAN, "build probe request band %d", band); 1137 wl1271_debug(DEBUG_SCAN, "build probe request band %d", band);
1137 1138
1138 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len, 1139 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
1139 ie_len); 1140 ie0_len + ie1_len);
1140 if (!skb) { 1141 if (!skb) {
1141 ret = -ENOMEM; 1142 ret = -ENOMEM;
1142 goto out; 1143 goto out;
1143 } 1144 }
1144 if (ie_len) 1145 if (ie0_len)
1145 memcpy(skb_put(skb, ie_len), ie, ie_len); 1146 memcpy(skb_put(skb, ie0_len), ie0, ie0_len);
1147 if (ie1_len)
1148 memcpy(skb_put(skb, ie1_len), ie1, ie1_len);
1146 1149
1147 if (sched_scan && 1150 if (sched_scan &&
1148 (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) { 1151 (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) {
diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h
index b084830a61cf..6788d7356ca5 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.h
+++ b/drivers/net/wireless/ti/wlcore/cmd.h
@@ -64,7 +64,8 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
64int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, 64int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
65 u8 role_id, u8 band, 65 u8 role_id, u8 band,
66 const u8 *ssid, size_t ssid_len, 66 const u8 *ssid, size_t ssid_len,
67 const u8 *ie, size_t ie_len, bool sched_scan); 67 const u8 *ie, size_t ie_len, const u8 *common_ie,
68 size_t common_ie_len, bool sched_scan);
68struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, 69struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
69 struct wl12xx_vif *wlvif, 70 struct wl12xx_vif *wlvif,
70 struct sk_buff *skb); 71 struct sk_buff *skb);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index e5ffb8b91dd4..48f83868f9cb 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -3637,7 +3637,7 @@ out:
3637static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw, 3637static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
3638 struct ieee80211_vif *vif, 3638 struct ieee80211_vif *vif,
3639 struct cfg80211_sched_scan_request *req, 3639 struct cfg80211_sched_scan_request *req,
3640 struct ieee80211_sched_scan_ies *ies) 3640 struct ieee80211_scan_ies *ies)
3641{ 3641{
3642 struct wl1271 *wl = hw->priv; 3642 struct wl1271 *wl = hw->priv;
3643 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 3643 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
diff --git a/drivers/net/wireless/ti/wlcore/scan.h b/drivers/net/wireless/ti/wlcore/scan.h
index a6ab24b5c0f9..4dadd0c62cde 100644
--- a/drivers/net/wireless/ti/wlcore/scan.h
+++ b/drivers/net/wireless/ti/wlcore/scan.h
@@ -37,7 +37,7 @@ void wl1271_scan_complete_work(struct work_struct *work);
37int wl1271_scan_sched_scan_config(struct wl1271 *wl, 37int wl1271_scan_sched_scan_config(struct wl1271 *wl,
38 struct wl12xx_vif *wlvif, 38 struct wl12xx_vif *wlvif,
39 struct cfg80211_sched_scan_request *req, 39 struct cfg80211_sched_scan_request *req,
40 struct ieee80211_sched_scan_ies *ies); 40 struct ieee80211_scan_ies *ies);
41int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif); 41int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif);
42void wlcore_scan_sched_scan_results(struct wl1271 *wl); 42void wlcore_scan_sched_scan_results(struct wl1271 *wl);
43 43
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 95a54504f0cc..71320509b56d 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -95,7 +95,7 @@ struct wlcore_ops {
95 int (*scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif); 95 int (*scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
96 int (*sched_scan_start)(struct wl1271 *wl, struct wl12xx_vif *wlvif, 96 int (*sched_scan_start)(struct wl1271 *wl, struct wl12xx_vif *wlvif,
97 struct cfg80211_sched_scan_request *req, 97 struct cfg80211_sched_scan_request *req,
98 struct ieee80211_sched_scan_ies *ies); 98 struct ieee80211_scan_ies *ies);
99 void (*sched_scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif); 99 void (*sched_scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
100 int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem); 100 int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem);
101 int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd, 101 int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd,
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9536ee3e22a9..545d2fa179c4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -754,26 +754,11 @@ struct ieee80211_tx_info {
754}; 754};
755 755
756/** 756/**
757 * struct ieee80211_sched_scan_ies - scheduled scan IEs
758 *
759 * This structure is used to pass the appropriate IEs to be used in scheduled
760 * scans for all bands. It contains both the IEs passed from the userspace
761 * and the ones generated by mac80211.
762 *
763 * @ie: array with the IEs for each supported band
764 * @len: array with the total length of the IEs for each band
765 */
766struct ieee80211_sched_scan_ies {
767 u8 *ie[IEEE80211_NUM_BANDS];
768 size_t len[IEEE80211_NUM_BANDS];
769};
770
771/**
772 * struct ieee80211_scan_ies - descriptors for different blocks of IEs 757 * struct ieee80211_scan_ies - descriptors for different blocks of IEs
773 * 758 *
774 * This structure is used to point to different blocks of IEs in HW scan. 759 * This structure is used to point to different blocks of IEs in HW scan
775 * These blocks contain the IEs passed by userspace and the ones generated 760 * and scheduled scan. These blocks contain the IEs passed by userspace
776 * by mac80211. 761 * and the ones generated by mac80211.
777 * 762 *
778 * @ies: pointers to band specific IEs. 763 * @ies: pointers to band specific IEs.
779 * @len: lengths of band_specific IEs. 764 * @len: lengths of band_specific IEs.
@@ -2917,7 +2902,7 @@ struct ieee80211_ops {
2917 int (*sched_scan_start)(struct ieee80211_hw *hw, 2902 int (*sched_scan_start)(struct ieee80211_hw *hw,
2918 struct ieee80211_vif *vif, 2903 struct ieee80211_vif *vif,
2919 struct cfg80211_sched_scan_request *req, 2904 struct cfg80211_sched_scan_request *req,
2920 struct ieee80211_sched_scan_ies *ies); 2905 struct ieee80211_scan_ies *ies);
2921 int (*sched_scan_stop)(struct ieee80211_hw *hw, 2906 int (*sched_scan_stop)(struct ieee80211_hw *hw,
2922 struct ieee80211_vif *vif); 2907 struct ieee80211_vif *vif);
2923 void (*sw_scan_start)(struct ieee80211_hw *hw); 2908 void (*sw_scan_start)(struct ieee80211_hw *hw);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index faa0d90f6e80..11423958116a 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -346,7 +346,7 @@ static inline int
346drv_sched_scan_start(struct ieee80211_local *local, 346drv_sched_scan_start(struct ieee80211_local *local,
347 struct ieee80211_sub_if_data *sdata, 347 struct ieee80211_sub_if_data *sdata,
348 struct cfg80211_sched_scan_request *req, 348 struct cfg80211_sched_scan_request *req,
349 struct ieee80211_sched_scan_ies *ies) 349 struct ieee80211_scan_ies *ies)
350{ 350{
351 int ret; 351 int ret;
352 352
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 116959e070d0..a0a938145dcc 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -1003,10 +1003,13 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
1003 struct cfg80211_sched_scan_request *req) 1003 struct cfg80211_sched_scan_request *req)
1004{ 1004{
1005 struct ieee80211_local *local = sdata->local; 1005 struct ieee80211_local *local = sdata->local;
1006 struct ieee80211_sched_scan_ies sched_scan_ies = {}; 1006 struct ieee80211_scan_ies sched_scan_ies = {};
1007 struct cfg80211_chan_def chandef; 1007 struct cfg80211_chan_def chandef;
1008 int ret, i, iebufsz; 1008 int ret, i, iebufsz, num_bands = 0;
1009 struct ieee80211_scan_ies dummy_ie_desc; 1009 u32 rate_masks[IEEE80211_NUM_BANDS] = {};
1010 u8 bands_used = 0;
1011 u8 *ie;
1012 size_t len;
1010 1013
1011 iebufsz = local->scan_ies_len + req->ie_len; 1014 iebufsz = local->scan_ies_len + req->ie_len;
1012 1015
@@ -1016,37 +1019,35 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
1016 return -ENOTSUPP; 1019 return -ENOTSUPP;
1017 1020
1018 for (i = 0; i < IEEE80211_NUM_BANDS; i++) { 1021 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
1019 u32 rate_masks[IEEE80211_NUM_BANDS] = {}; 1022 if (local->hw.wiphy->bands[i]) {
1020 1023 bands_used |= BIT(i);
1021 if (!local->hw.wiphy->bands[i]) 1024 rate_masks[i] = (u32) -1;
1022 continue; 1025 num_bands++;
1023
1024 sched_scan_ies.ie[i] = kzalloc(iebufsz, GFP_KERNEL);
1025 if (!sched_scan_ies.ie[i]) {
1026 ret = -ENOMEM;
1027 goto out_free;
1028 } 1026 }
1027 }
1029 1028
1030 ieee80211_prepare_scan_chandef(&chandef, req->scan_width); 1029 ie = kzalloc(num_bands * iebufsz, GFP_KERNEL);
1031 rate_masks[i] = (u32) -1; 1030 if (!ie) {
1032 1031 ret = -ENOMEM;
1033 sched_scan_ies.len[i] = 1032 goto out;
1034 ieee80211_build_preq_ies(local, sched_scan_ies.ie[i],
1035 iebufsz, &dummy_ie_desc,
1036 req->ie, req->ie_len, BIT(i),
1037 rate_masks, &chandef);
1038 } 1033 }
1039 1034
1035 ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
1036
1037 len = ieee80211_build_preq_ies(local, ie, num_bands * iebufsz,
1038 &sched_scan_ies, req->ie,
1039 req->ie_len, bands_used,
1040 rate_masks, &chandef);
1041
1040 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); 1042 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies);
1041 if (ret == 0) { 1043 if (ret == 0) {
1042 rcu_assign_pointer(local->sched_scan_sdata, sdata); 1044 rcu_assign_pointer(local->sched_scan_sdata, sdata);
1043 local->sched_scan_req = req; 1045 local->sched_scan_req = req;
1044 } 1046 }
1045 1047
1046out_free: 1048 kfree(ie);
1047 while (i > 0)
1048 kfree(sched_scan_ies.ie[--i]);
1049 1049
1050out:
1050 if (ret) { 1051 if (ret) {
1051 /* Clean in case of failure after HW restart or upon resume. */ 1052 /* Clean in case of failure after HW restart or upon resume. */
1052 RCU_INIT_POINTER(local->sched_scan_sdata, NULL); 1053 RCU_INIT_POINTER(local->sched_scan_sdata, NULL);