diff options
author | Simon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de> | 2013-07-08 10:55:53 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-07-16 02:58:06 -0400 |
commit | 2103dec14792be2c2194a454630b01120d30e5cb (patch) | |
tree | 6bc0cd39eb2fe5317f0383ed7c4c238fb98ec114 /net/mac80211/scan.c | |
parent | a5e70697d0c4836e69c60de92db27eac9ae71e05 (diff) |
mac80211: select and adjust bitrates according to channel mode
The various components accessing the bitrates table must use consider
the used channel bandwidth to select only available rates or calculate
the bitrate correctly.
There are some rates in reduced bandwidth modes which can't be
represented as multiples of 500kbps, like 2.25 MBit/s in 5 MHz mode. The
standard suggests to round up to the next multiple of 500kbps, just do
that in mac80211 as well.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
[make rate unsigned in ieee80211_add_tx_radiotap_header(), squash fix]
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 1b122a79b0d8..819d0956eb3b 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -204,10 +204,29 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) | |||
204 | ieee80211_rx_bss_put(local, bss); | 204 | ieee80211_rx_bss_put(local, bss); |
205 | } | 205 | } |
206 | 206 | ||
207 | static void | ||
208 | ieee80211_prepare_scan_chandef(struct cfg80211_chan_def *chandef, | ||
209 | enum nl80211_bss_scan_width scan_width) | ||
210 | { | ||
211 | memset(chandef, 0, sizeof(*chandef)); | ||
212 | switch (scan_width) { | ||
213 | case NL80211_BSS_CHAN_WIDTH_5: | ||
214 | chandef->width = NL80211_CHAN_WIDTH_5; | ||
215 | break; | ||
216 | case NL80211_BSS_CHAN_WIDTH_10: | ||
217 | chandef->width = NL80211_CHAN_WIDTH_10; | ||
218 | break; | ||
219 | default: | ||
220 | chandef->width = NL80211_CHAN_WIDTH_20_NOHT; | ||
221 | break; | ||
222 | } | ||
223 | } | ||
224 | |||
207 | /* return false if no more work */ | 225 | /* return false if no more work */ |
208 | static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | 226 | static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) |
209 | { | 227 | { |
210 | struct cfg80211_scan_request *req = local->scan_req; | 228 | struct cfg80211_scan_request *req = local->scan_req; |
229 | struct cfg80211_chan_def chandef; | ||
211 | enum ieee80211_band band; | 230 | enum ieee80211_band band; |
212 | int i, ielen, n_chans; | 231 | int i, ielen, n_chans; |
213 | 232 | ||
@@ -229,11 +248,12 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
229 | } while (!n_chans); | 248 | } while (!n_chans); |
230 | 249 | ||
231 | local->hw_scan_req->n_channels = n_chans; | 250 | local->hw_scan_req->n_channels = n_chans; |
251 | ieee80211_prepare_scan_chandef(&chandef, req->scan_width); | ||
232 | 252 | ||
233 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, | 253 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, |
234 | local->hw_scan_ies_bufsize, | 254 | local->hw_scan_ies_bufsize, |
235 | req->ie, req->ie_len, band, | 255 | req->ie, req->ie_len, band, |
236 | req->rates[band], 0); | 256 | req->rates[band], &chandef); |
237 | local->hw_scan_req->ie_len = ielen; | 257 | local->hw_scan_req->ie_len = ielen; |
238 | local->hw_scan_req->no_cck = req->no_cck; | 258 | local->hw_scan_req->no_cck = req->no_cck; |
239 | 259 | ||
@@ -912,6 +932,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
912 | { | 932 | { |
913 | struct ieee80211_local *local = sdata->local; | 933 | struct ieee80211_local *local = sdata->local; |
914 | struct ieee80211_sched_scan_ies sched_scan_ies = {}; | 934 | struct ieee80211_sched_scan_ies sched_scan_ies = {}; |
935 | struct cfg80211_chan_def chandef; | ||
915 | int ret, i, iebufsz; | 936 | int ret, i, iebufsz; |
916 | 937 | ||
917 | iebufsz = 2 + IEEE80211_MAX_SSID_LEN + | 938 | iebufsz = 2 + IEEE80211_MAX_SSID_LEN + |
@@ -939,10 +960,12 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
939 | goto out_free; | 960 | goto out_free; |
940 | } | 961 | } |
941 | 962 | ||
963 | ieee80211_prepare_scan_chandef(&chandef, req->scan_width); | ||
964 | |||
942 | sched_scan_ies.len[i] = | 965 | sched_scan_ies.len[i] = |
943 | ieee80211_build_preq_ies(local, sched_scan_ies.ie[i], | 966 | ieee80211_build_preq_ies(local, sched_scan_ies.ie[i], |
944 | iebufsz, req->ie, req->ie_len, | 967 | iebufsz, req->ie, req->ie_len, |
945 | i, (u32) -1, 0); | 968 | i, (u32) -1, &chandef); |
946 | } | 969 | } |
947 | 970 | ||
948 | ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); | 971 | ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); |