aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c142
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
44static 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
58void 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
130u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, 44u8 *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}
380EXPORT_SYMBOL(ieee80211_ctstoself_duration); 303EXPORT_SYMBOL(ieee80211_ctstoself_duration);
381 304
382struct ieee80211_rate *
383ieee80211_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
403void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) 305void 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);