diff options
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 142 |
1 files changed, 22 insertions, 120 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 5e631ce98d7e..f64804fed0a9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -41,92 +41,6 @@ const unsigned char bridge_tunnel_header[] = | |||
41 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; | 41 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; |
42 | 42 | ||
43 | 43 | ||
44 | static int rate_list_match(const int *rate_list, int rate) | ||
45 | { | ||
46 | int i; | ||
47 | |||
48 | if (!rate_list) | ||
49 | return 0; | ||
50 | |||
51 | for (i = 0; rate_list[i] >= 0; i++) | ||
52 | if (rate_list[i] == rate) | ||
53 | return 1; | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | void ieee80211_prepare_rates(struct ieee80211_local *local, | ||
59 | struct ieee80211_hw_mode *mode) | ||
60 | { | ||
61 | int i; | ||
62 | |||
63 | for (i = 0; i < mode->num_rates; i++) { | ||
64 | struct ieee80211_rate *rate = &mode->rates[i]; | ||
65 | |||
66 | rate->flags &= ~(IEEE80211_RATE_SUPPORTED | | ||
67 | IEEE80211_RATE_BASIC); | ||
68 | |||
69 | if (local->supp_rates[mode->mode]) { | ||
70 | if (!rate_list_match(local->supp_rates[mode->mode], | ||
71 | rate->rate)) | ||
72 | continue; | ||
73 | } | ||
74 | |||
75 | rate->flags |= IEEE80211_RATE_SUPPORTED; | ||
76 | |||
77 | /* Use configured basic rate set if it is available. If not, | ||
78 | * use defaults that are sane for most cases. */ | ||
79 | if (local->basic_rates[mode->mode]) { | ||
80 | if (rate_list_match(local->basic_rates[mode->mode], | ||
81 | rate->rate)) | ||
82 | rate->flags |= IEEE80211_RATE_BASIC; | ||
83 | } else switch (mode->mode) { | ||
84 | case MODE_IEEE80211A: | ||
85 | if (rate->rate == 60 || rate->rate == 120 || | ||
86 | rate->rate == 240) | ||
87 | rate->flags |= IEEE80211_RATE_BASIC; | ||
88 | break; | ||
89 | case MODE_IEEE80211B: | ||
90 | if (rate->rate == 10 || rate->rate == 20) | ||
91 | rate->flags |= IEEE80211_RATE_BASIC; | ||
92 | break; | ||
93 | case MODE_IEEE80211G: | ||
94 | if (rate->rate == 10 || rate->rate == 20 || | ||
95 | rate->rate == 55 || rate->rate == 110) | ||
96 | rate->flags |= IEEE80211_RATE_BASIC; | ||
97 | break; | ||
98 | case NUM_IEEE80211_MODES: | ||
99 | /* not useful */ | ||
100 | break; | ||
101 | } | ||
102 | |||
103 | /* Set ERP and MANDATORY flags based on phymode */ | ||
104 | switch (mode->mode) { | ||
105 | case MODE_IEEE80211A: | ||
106 | if (rate->rate == 60 || rate->rate == 120 || | ||
107 | rate->rate == 240) | ||
108 | rate->flags |= IEEE80211_RATE_MANDATORY; | ||
109 | break; | ||
110 | case MODE_IEEE80211B: | ||
111 | if (rate->rate == 10) | ||
112 | rate->flags |= IEEE80211_RATE_MANDATORY; | ||
113 | break; | ||
114 | case MODE_IEEE80211G: | ||
115 | if (rate->rate == 10 || rate->rate == 20 || | ||
116 | rate->rate == 55 || rate->rate == 110 || | ||
117 | rate->rate == 60 || rate->rate == 120 || | ||
118 | rate->rate == 240) | ||
119 | rate->flags |= IEEE80211_RATE_MANDATORY; | ||
120 | break; | ||
121 | case NUM_IEEE80211_MODES: | ||
122 | /* not useful */ | ||
123 | break; | ||
124 | } | ||
125 | if (ieee80211_is_erp_rate(mode->mode, rate->rate)) | ||
126 | rate->flags |= IEEE80211_RATE_ERP; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | 44 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, |
131 | enum ieee80211_if_types type) | 45 | enum ieee80211_if_types type) |
132 | { | 46 | { |
@@ -262,7 +176,7 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | |||
262 | * DIV_ROUND_UP() operations. | 176 | * DIV_ROUND_UP() operations. |
263 | */ | 177 | */ |
264 | 178 | ||
265 | if (local->hw.conf.phymode == MODE_IEEE80211A || erp) { | 179 | if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ || erp) { |
266 | /* | 180 | /* |
267 | * OFDM: | 181 | * OFDM: |
268 | * | 182 | * |
@@ -304,15 +218,19 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | |||
304 | /* Exported duration function for driver use */ | 218 | /* Exported duration function for driver use */ |
305 | __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, | 219 | __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, |
306 | struct ieee80211_vif *vif, | 220 | struct ieee80211_vif *vif, |
307 | size_t frame_len, int rate) | 221 | size_t frame_len, |
222 | struct ieee80211_rate *rate) | ||
308 | { | 223 | { |
309 | struct ieee80211_local *local = hw_to_local(hw); | 224 | struct ieee80211_local *local = hw_to_local(hw); |
310 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 225 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
311 | u16 dur; | 226 | u16 dur; |
312 | int erp; | 227 | int erp; |
313 | 228 | ||
314 | erp = ieee80211_is_erp_rate(hw->conf.phymode, rate); | 229 | erp = 0; |
315 | dur = ieee80211_frame_duration(local, frame_len, rate, erp, | 230 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
231 | erp = rate->flags & IEEE80211_RATE_ERP_G; | ||
232 | |||
233 | dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp, | ||
316 | sdata->bss_conf.use_short_preamble); | 234 | sdata->bss_conf.use_short_preamble); |
317 | 235 | ||
318 | return cpu_to_le16(dur); | 236 | return cpu_to_le16(dur); |
@@ -332,17 +250,20 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
332 | 250 | ||
333 | short_preamble = sdata->bss_conf.use_short_preamble; | 251 | short_preamble = sdata->bss_conf.use_short_preamble; |
334 | 252 | ||
335 | rate = frame_txctl->rts_rate; | 253 | rate = frame_txctl->rts_cts_rate; |
336 | erp = !!(rate->flags & IEEE80211_RATE_ERP); | 254 | |
255 | erp = 0; | ||
256 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
257 | erp = rate->flags & IEEE80211_RATE_ERP_G; | ||
337 | 258 | ||
338 | /* CTS duration */ | 259 | /* CTS duration */ |
339 | dur = ieee80211_frame_duration(local, 10, rate->rate, | 260 | dur = ieee80211_frame_duration(local, 10, rate->bitrate, |
340 | erp, short_preamble); | 261 | erp, short_preamble); |
341 | /* Data frame duration */ | 262 | /* Data frame duration */ |
342 | dur += ieee80211_frame_duration(local, frame_len, rate->rate, | 263 | dur += ieee80211_frame_duration(local, frame_len, rate->bitrate, |
343 | erp, short_preamble); | 264 | erp, short_preamble); |
344 | /* ACK duration */ | 265 | /* ACK duration */ |
345 | dur += ieee80211_frame_duration(local, 10, rate->rate, | 266 | dur += ieee80211_frame_duration(local, 10, rate->bitrate, |
346 | erp, short_preamble); | 267 | erp, short_preamble); |
347 | 268 | ||
348 | return cpu_to_le16(dur); | 269 | return cpu_to_le16(dur); |
@@ -363,15 +284,17 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
363 | 284 | ||
364 | short_preamble = sdata->bss_conf.use_short_preamble; | 285 | short_preamble = sdata->bss_conf.use_short_preamble; |
365 | 286 | ||
366 | rate = frame_txctl->rts_rate; | 287 | rate = frame_txctl->rts_cts_rate; |
367 | erp = !!(rate->flags & IEEE80211_RATE_ERP); | 288 | erp = 0; |
289 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
290 | erp = rate->flags & IEEE80211_RATE_ERP_G; | ||
368 | 291 | ||
369 | /* Data frame duration */ | 292 | /* Data frame duration */ |
370 | dur = ieee80211_frame_duration(local, frame_len, rate->rate, | 293 | dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, |
371 | erp, short_preamble); | 294 | erp, short_preamble); |
372 | if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) { | 295 | if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) { |
373 | /* ACK duration */ | 296 | /* ACK duration */ |
374 | dur += ieee80211_frame_duration(local, 10, rate->rate, | 297 | dur += ieee80211_frame_duration(local, 10, rate->bitrate, |
375 | erp, short_preamble); | 298 | erp, short_preamble); |
376 | } | 299 | } |
377 | 300 | ||
@@ -379,27 +302,6 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
379 | } | 302 | } |
380 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); | 303 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); |
381 | 304 | ||
382 | struct ieee80211_rate * | ||
383 | ieee80211_get_rate(struct ieee80211_local *local, int phymode, int hw_rate) | ||
384 | { | ||
385 | struct ieee80211_hw_mode *mode; | ||
386 | int r; | ||
387 | |||
388 | list_for_each_entry(mode, &local->modes_list, list) { | ||
389 | if (mode->mode != phymode) | ||
390 | continue; | ||
391 | for (r = 0; r < mode->num_rates; r++) { | ||
392 | struct ieee80211_rate *rate = &mode->rates[r]; | ||
393 | if (rate->val == hw_rate || | ||
394 | (rate->flags & IEEE80211_RATE_PREAMBLE2 && | ||
395 | rate->val2 == hw_rate)) | ||
396 | return rate; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | return NULL; | ||
401 | } | ||
402 | |||
403 | void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | 305 | void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) |
404 | { | 306 | { |
405 | struct ieee80211_local *local = hw_to_local(hw); | 307 | struct ieee80211_local *local = hw_to_local(hw); |