summaryrefslogtreecommitdiff
path: root/net/mac80211
diff options
context:
space:
mode:
authorDavid Spinadel <david.spinadel@intel.com>2014-02-06 18:15:23 +0400
committerJohannes Berg <johannes.berg@intel.com>2014-06-25 11:10:43 +0400
commit633e27132625a0692440c4db58b901fb3cb67c55 (patch)
tree6500b45b80c944e2addfda3f9c4515a2112056c9 /net/mac80211
parentc56ef6725068c0ce499e517409c0da226ef51b08 (diff)
downloadlinux-633e27132625a0692440c4db58b901fb3cb67c55.tar.xz
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/mac80211')
-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
drv_sched_scan_start(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies)
+ struct ieee80211_scan_ies *ies)
{
int ret;
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,
struct cfg80211_sched_scan_request *req)
{
struct ieee80211_local *local = sdata->local;
- struct ieee80211_sched_scan_ies sched_scan_ies = {};
+ struct ieee80211_scan_ies sched_scan_ies = {};
struct cfg80211_chan_def chandef;
- int ret, i, iebufsz;
- struct ieee80211_scan_ies dummy_ie_desc;
+ int ret, i, iebufsz, num_bands = 0;
+ u32 rate_masks[IEEE80211_NUM_BANDS] = {};
+ u8 bands_used = 0;
+ u8 *ie;
+ size_t len;
iebufsz = local->scan_ies_len + req->ie_len;
@@ -1016,37 +1019,35 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
return -ENOTSUPP;
for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
- u32 rate_masks[IEEE80211_NUM_BANDS] = {};
-
- if (!local->hw.wiphy->bands[i])
- continue;
-
- sched_scan_ies.ie[i] = kzalloc(iebufsz, GFP_KERNEL);
- if (!sched_scan_ies.ie[i]) {
- ret = -ENOMEM;
- goto out_free;
+ if (local->hw.wiphy->bands[i]) {
+ bands_used |= BIT(i);
+ rate_masks[i] = (u32) -1;
+ num_bands++;
}
+ }
- ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
- rate_masks[i] = (u32) -1;
-
- sched_scan_ies.len[i] =
- ieee80211_build_preq_ies(local, sched_scan_ies.ie[i],
- iebufsz, &dummy_ie_desc,
- req->ie, req->ie_len, BIT(i),
- rate_masks, &chandef);
+ ie = kzalloc(num_bands * iebufsz, GFP_KERNEL);
+ if (!ie) {
+ ret = -ENOMEM;
+ goto out;
}
+ ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
+
+ len = ieee80211_build_preq_ies(local, ie, num_bands * iebufsz,
+ &sched_scan_ies, req->ie,
+ req->ie_len, bands_used,
+ rate_masks, &chandef);
+
ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies);
if (ret == 0) {
rcu_assign_pointer(local->sched_scan_sdata, sdata);
local->sched_scan_req = req;
}
-out_free:
- while (i > 0)
- kfree(sched_scan_ies.ie[--i]);
+ kfree(ie);
+out:
if (ret) {
/* Clean in case of failure after HW restart or upon resume. */
RCU_INIT_POINTER(local->sched_scan_sdata, NULL);