aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-01-24 13:38:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:19:32 -0500
commit8318d78a44d49ac1edf2bdec7299de3617c4232e (patch)
treed434634418edd7399737801615d247be06616fdd /net/mac80211/util.c
parent10b6b80145cc93887dd8aab99bfffa375e9add31 (diff)
cfg80211 API for channels/bitrates, mac80211 and driver conversion
This patch creates new cfg80211 wiphy API for channel and bitrate registration and converts mac80211 and drivers to the new API. The old mac80211 API is completely ripped out. All drivers (except ath5k) are updated to the new API, in many cases I expect that optimisations can be done. Along with the regulatory code I've also ripped out the IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED flag, I believe it to be unnecessary if the hardware simply gives us whatever channels it wants to support and we then enable/disable them as required, which is pretty much required for travelling. Additionally, the patch adds proper "basic" rate handling for STA mode interface, AP mode interface will have to have new API added to allow userspace to set the basic rate set, currently it'll be empty... However, the basic rate handling will need to be moved to the BSS conf stuff. I do expect there to be bugs in this, especially wrt. transmit power handling where I'm basically clueless about how it should work. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
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);