aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid Spinadel <david.spinadel@intel.com>2014-02-06 09:15:23 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-06-25 03:10:43 -0400
commit633e27132625a0692440c4db58b901fb3cb67c55 (patch)
tree6500b45b80c944e2addfda3f9c4515a2112056c9 /net
parentc56ef6725068c0ce499e517409c0da226ef51b08 (diff)
mac80211: split sched scan IEs
Split sched scan IEs to band specific and not band specific blocks. Common IEs blocks may be sent to the FW once per command, instead of per band. This allows optimization of size of the command, which may be required by some drivers (eg. iwlmvm with newer firmware version). As this changes the mac80211 API, update all drivers to use the new version correctly, even if they don't (yet) make use of the split data. Signed-off-by: David Spinadel <david.spinadel@intel.com> Reviewed-by: Alexander Bondar <alexander.bondar@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/driver-ops.h2
-rw-r--r--net/mac80211/scan.c47
2 files changed, 25 insertions, 24 deletions
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);