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.c172
1 files changed, 47 insertions, 125 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 5e631ce98d7e..cc9f715c7bfc 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -25,7 +25,8 @@
25#include <net/rtnetlink.h> 25#include <net/rtnetlink.h>
26 26
27#include "ieee80211_i.h" 27#include "ieee80211_i.h"
28#include "ieee80211_rate.h" 28#include "rate.h"
29#include "mesh.h"
29#include "wme.h" 30#include "wme.h"
30 31
31/* privid for wiphys to determine whether they belong to us or not */ 32/* privid for wiphys to determine whether they belong to us or not */
@@ -41,92 +42,6 @@ const unsigned char bridge_tunnel_header[] =
41 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; 42 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
42 43
43 44
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, 45u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
131 enum ieee80211_if_types type) 46 enum ieee80211_if_types type)
132{ 47{
@@ -232,17 +147,35 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
232} 147}
233EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); 148EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
234 149
235void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx) 150int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
151{
152 int ae = meshhdr->flags & IEEE80211S_FLAGS_AE;
153 /* 7.1.3.5a.2 */
154 switch (ae) {
155 case 0:
156 return 5;
157 case 1:
158 return 11;
159 case 2:
160 return 17;
161 case 3:
162 return 23;
163 default:
164 return 5;
165 }
166}
167
168void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
236{ 169{
237 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 170 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
238 171
239 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 172 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
240 if (tx->u.tx.extra_frag) { 173 if (tx->extra_frag) {
241 struct ieee80211_hdr *fhdr; 174 struct ieee80211_hdr *fhdr;
242 int i; 175 int i;
243 for (i = 0; i < tx->u.tx.num_extra_frag; i++) { 176 for (i = 0; i < tx->num_extra_frag; i++) {
244 fhdr = (struct ieee80211_hdr *) 177 fhdr = (struct ieee80211_hdr *)
245 tx->u.tx.extra_frag[i]->data; 178 tx->extra_frag[i]->data;
246 fhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 179 fhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
247 } 180 }
248 } 181 }
@@ -262,7 +195,7 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
262 * DIV_ROUND_UP() operations. 195 * DIV_ROUND_UP() operations.
263 */ 196 */
264 197
265 if (local->hw.conf.phymode == MODE_IEEE80211A || erp) { 198 if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ || erp) {
266 /* 199 /*
267 * OFDM: 200 * OFDM:
268 * 201 *
@@ -304,15 +237,19 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
304/* Exported duration function for driver use */ 237/* Exported duration function for driver use */
305__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, 238__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
306 struct ieee80211_vif *vif, 239 struct ieee80211_vif *vif,
307 size_t frame_len, int rate) 240 size_t frame_len,
241 struct ieee80211_rate *rate)
308{ 242{
309 struct ieee80211_local *local = hw_to_local(hw); 243 struct ieee80211_local *local = hw_to_local(hw);
310 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 244 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
311 u16 dur; 245 u16 dur;
312 int erp; 246 int erp;
313 247
314 erp = ieee80211_is_erp_rate(hw->conf.phymode, rate); 248 erp = 0;
315 dur = ieee80211_frame_duration(local, frame_len, rate, erp, 249 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
250 erp = rate->flags & IEEE80211_RATE_ERP_G;
251
252 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp,
316 sdata->bss_conf.use_short_preamble); 253 sdata->bss_conf.use_short_preamble);
317 254
318 return cpu_to_le16(dur); 255 return cpu_to_le16(dur);
@@ -332,17 +269,20 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
332 269
333 short_preamble = sdata->bss_conf.use_short_preamble; 270 short_preamble = sdata->bss_conf.use_short_preamble;
334 271
335 rate = frame_txctl->rts_rate; 272 rate = frame_txctl->rts_cts_rate;
336 erp = !!(rate->flags & IEEE80211_RATE_ERP); 273
274 erp = 0;
275 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
276 erp = rate->flags & IEEE80211_RATE_ERP_G;
337 277
338 /* CTS duration */ 278 /* CTS duration */
339 dur = ieee80211_frame_duration(local, 10, rate->rate, 279 dur = ieee80211_frame_duration(local, 10, rate->bitrate,
340 erp, short_preamble); 280 erp, short_preamble);
341 /* Data frame duration */ 281 /* Data frame duration */
342 dur += ieee80211_frame_duration(local, frame_len, rate->rate, 282 dur += ieee80211_frame_duration(local, frame_len, rate->bitrate,
343 erp, short_preamble); 283 erp, short_preamble);
344 /* ACK duration */ 284 /* ACK duration */
345 dur += ieee80211_frame_duration(local, 10, rate->rate, 285 dur += ieee80211_frame_duration(local, 10, rate->bitrate,
346 erp, short_preamble); 286 erp, short_preamble);
347 287
348 return cpu_to_le16(dur); 288 return cpu_to_le16(dur);
@@ -363,15 +303,17 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
363 303
364 short_preamble = sdata->bss_conf.use_short_preamble; 304 short_preamble = sdata->bss_conf.use_short_preamble;
365 305
366 rate = frame_txctl->rts_rate; 306 rate = frame_txctl->rts_cts_rate;
367 erp = !!(rate->flags & IEEE80211_RATE_ERP); 307 erp = 0;
308 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
309 erp = rate->flags & IEEE80211_RATE_ERP_G;
368 310
369 /* Data frame duration */ 311 /* Data frame duration */
370 dur = ieee80211_frame_duration(local, frame_len, rate->rate, 312 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate,
371 erp, short_preamble); 313 erp, short_preamble);
372 if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) { 314 if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) {
373 /* ACK duration */ 315 /* ACK duration */
374 dur += ieee80211_frame_duration(local, 10, rate->rate, 316 dur += ieee80211_frame_duration(local, 10, rate->bitrate,
375 erp, short_preamble); 317 erp, short_preamble);
376 } 318 }
377 319
@@ -379,27 +321,6 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
379} 321}
380EXPORT_SYMBOL(ieee80211_ctstoself_duration); 322EXPORT_SYMBOL(ieee80211_ctstoself_duration);
381 323
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) 324void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
404{ 325{
405 struct ieee80211_local *local = hw_to_local(hw); 326 struct ieee80211_local *local = hw_to_local(hw);
@@ -480,6 +401,7 @@ void ieee80211_iterate_active_interfaces(
480 case IEEE80211_IF_TYPE_STA: 401 case IEEE80211_IF_TYPE_STA:
481 case IEEE80211_IF_TYPE_IBSS: 402 case IEEE80211_IF_TYPE_IBSS:
482 case IEEE80211_IF_TYPE_WDS: 403 case IEEE80211_IF_TYPE_WDS:
404 case IEEE80211_IF_TYPE_MESH_POINT:
483 break; 405 break;
484 } 406 }
485 if (sdata->dev == local->mdev) 407 if (sdata->dev == local->mdev)