aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw/zd_mac.c
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2006-06-02 12:11:32 -0400
committerJeff Garzik <jeff@garzik.org>2006-07-05 13:42:58 -0400
commite85d0918b54fbd9b38003752f7d665416b06edd8 (patch)
tree6f53e6bb10562eec331defc6811fb6d434eb21e5 /drivers/net/wireless/zd1211rw/zd_mac.c
parent4a232e725b5cc1bc7fc5b177424a9ff8313b23ad (diff)
[PATCH] ZyDAS ZD1211 USB-WLAN driver
There are 60+ USB wifi adapters available on the market based on the ZyDAS ZD1211 chip. Unlike the predecessor (ZD1201), ZD1211 does not have a hardware MAC, so most data operations are coordinated by the device driver. The ZD1211 chip sits alongside an RF transceiver which is also controlled by the driver. Our driver currently supports 2 RF types, we know of one other available in a few marketed products which we will be supporting soon. Our driver also supports the newer revision of ZD1211, called ZD1211B. The initialization and RF operations are slightly different for the new revision, but the main difference is 802.11e support. Our driver does not support the QoS features yet, but we think we know how to use them. This driver is based on ZyDAS's own GPL driver available from www.zydas.com.tw. ZyDAS engineers have been responsive and supportive of our efforts, so thumbs up to them. Additionally, the firmware is redistributable and they have provided device specs. This driver has been written primarily by Ulrich Kunitz and myself. Graham Gower, Greg KH, Remco and Bryan Rittmeyer have also contributed. The developers of ieee80211 and softmac have made our lives so much easier- thanks! We maintain a small info-page: http://zd1211.ath.cx/wiki/DriverRewrite If there is enough time for review, we would like to aim for inclusion in 2.6.18. The driver works nicely as a STA, and can connect to both open and encrypted networks (we are using software-based encryption for now). We will work towards supporting more advanced features in the future (ad-hoc, master mode, 802.11a, ...). Signed-off-by: Daniel Drake <dsd@gentoo.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_mac.c')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c1055
1 files changed, 1055 insertions, 0 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
new file mode 100644
index 00000000000..bbe067ec7de
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -0,0 +1,1055 @@
1/* zd_mac.c
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18#include <linux/netdevice.h>
19#include <linux/etherdevice.h>
20#include <linux/wireless.h>
21#include <linux/usb.h>
22#include <linux/jiffies.h>
23#include <net/ieee80211_radiotap.h>
24
25#include "zd_def.h"
26#include "zd_chip.h"
27#include "zd_mac.h"
28#include "zd_ieee80211.h"
29#include "zd_netdev.h"
30#include "zd_rf.h"
31#include "zd_util.h"
32
33static void ieee_init(struct ieee80211_device *ieee);
34static void softmac_init(struct ieee80211softmac_device *sm);
35
36int zd_mac_init(struct zd_mac *mac,
37 struct net_device *netdev,
38 struct usb_interface *intf)
39{
40 struct ieee80211_device *ieee = zd_netdev_ieee80211(netdev);
41
42 memset(mac, 0, sizeof(*mac));
43 spin_lock_init(&mac->lock);
44 mac->netdev = netdev;
45
46 ieee_init(ieee);
47 softmac_init(ieee80211_priv(netdev));
48 zd_chip_init(&mac->chip, netdev, intf);
49 return 0;
50}
51
52static int reset_channel(struct zd_mac *mac)
53{
54 int r;
55 unsigned long flags;
56 const struct channel_range *range;
57
58 spin_lock_irqsave(&mac->lock, flags);
59 range = zd_channel_range(mac->regdomain);
60 if (!range->start) {
61 r = -EINVAL;
62 goto out;
63 }
64 mac->requested_channel = range->start;
65 r = 0;
66out:
67 spin_unlock_irqrestore(&mac->lock, flags);
68 return r;
69}
70
71int zd_mac_init_hw(struct zd_mac *mac, u8 device_type)
72{
73 int r;
74 struct zd_chip *chip = &mac->chip;
75 u8 addr[ETH_ALEN];
76 u8 default_regdomain;
77
78 r = zd_chip_enable_int(chip);
79 if (r)
80 goto out;
81 r = zd_chip_init_hw(chip, device_type);
82 if (r)
83 goto disable_int;
84
85 zd_get_e2p_mac_addr(chip, addr);
86 r = zd_write_mac_addr(chip, addr);
87 if (r)
88 goto disable_int;
89 ZD_ASSERT(!irqs_disabled());
90 spin_lock_irq(&mac->lock);
91 memcpy(mac->netdev->dev_addr, addr, ETH_ALEN);
92 spin_unlock_irq(&mac->lock);
93
94 r = zd_read_regdomain(chip, &default_regdomain);
95 if (r)
96 goto disable_int;
97 if (!zd_regdomain_supported(default_regdomain)) {
98 dev_dbg_f(zd_mac_dev(mac),
99 "Regulatory Domain %#04x is not supported.\n",
100 default_regdomain);
101 r = -EINVAL;
102 goto disable_int;
103 }
104 spin_lock_irq(&mac->lock);
105 mac->regdomain = mac->default_regdomain = default_regdomain;
106 spin_unlock_irq(&mac->lock);
107 r = reset_channel(mac);
108 if (r)
109 goto disable_int;
110
111 r = zd_set_encryption_type(chip, NO_WEP);
112 if (r)
113 goto disable_int;
114
115 r = zd_geo_init(zd_mac_to_ieee80211(mac), mac->regdomain);
116 if (r)
117 goto disable_int;
118
119 r = 0;
120disable_int:
121 zd_chip_disable_int(chip);
122out:
123 return r;
124}
125
126void zd_mac_clear(struct zd_mac *mac)
127{
128 /* Aquire the lock. */
129 spin_lock(&mac->lock);
130 spin_unlock(&mac->lock);
131 zd_chip_clear(&mac->chip);
132 memset(mac, 0, sizeof(*mac));
133}
134
135static int reset_mode(struct zd_mac *mac)
136{
137 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
138 struct zd_ioreq32 ioreqs[3] = {
139 { CR_RX_FILTER, RX_FILTER_BEACON|RX_FILTER_PROBE_RESPONSE|
140 RX_FILTER_AUTH|RX_FILTER_ASSOC_RESPONSE },
141 { CR_SNIFFER_ON, 0U },
142 { CR_ENCRYPTION_TYPE, NO_WEP },
143 };
144
145 if (ieee->iw_mode == IW_MODE_MONITOR) {
146 ioreqs[0].value = 0xffffffff;
147 ioreqs[1].value = 0x1;
148 ioreqs[2].value = ENC_SNIFFER;
149 }
150
151 return zd_iowrite32a(&mac->chip, ioreqs, 3);
152}
153
154int zd_mac_open(struct net_device *netdev)
155{
156 struct zd_mac *mac = zd_netdev_mac(netdev);
157 struct zd_chip *chip = &mac->chip;
158 int r;
159
160 r = zd_chip_enable_int(chip);
161 if (r < 0)
162 goto out;
163
164 r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G);
165 if (r < 0)
166 goto disable_int;
167 r = reset_mode(mac);
168 if (r)
169 goto disable_int;
170 r = zd_chip_switch_radio_on(chip);
171 if (r < 0)
172 goto disable_int;
173 r = zd_chip_set_channel(chip, mac->requested_channel);
174 if (r < 0)
175 goto disable_radio;
176 r = zd_chip_enable_rx(chip);
177 if (r < 0)
178 goto disable_radio;
179 r = zd_chip_enable_hwint(chip);
180 if (r < 0)
181 goto disable_rx;
182
183 ieee80211softmac_start(netdev);
184 return 0;
185disable_rx:
186 zd_chip_disable_rx(chip);
187disable_radio:
188 zd_chip_switch_radio_off(chip);
189disable_int:
190 zd_chip_disable_int(chip);
191out:
192 return r;
193}
194
195int zd_mac_stop(struct net_device *netdev)
196{
197 struct zd_mac *mac = zd_netdev_mac(netdev);
198 struct zd_chip *chip = &mac->chip;
199
200 /*
201 * The order here deliberately is a little different from the open()
202 * method, since we need to make sure there is no opportunity for RX
203 * frames to be processed by softmac after we have stopped it.
204 */
205
206 zd_chip_disable_rx(chip);
207 ieee80211softmac_stop(netdev);
208
209 zd_chip_disable_hwint(chip);
210 zd_chip_switch_radio_off(chip);
211 zd_chip_disable_int(chip);
212
213 return 0;
214}
215
216int zd_mac_set_mac_address(struct net_device *netdev, void *p)
217{
218 int r;
219 unsigned long flags;
220 struct sockaddr *addr = p;
221 struct zd_mac *mac = zd_netdev_mac(netdev);
222 struct zd_chip *chip = &mac->chip;
223
224 if (!is_valid_ether_addr(addr->sa_data))
225 return -EADDRNOTAVAIL;
226
227 dev_dbg_f(zd_mac_dev(mac),
228 "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data));
229
230 r = zd_write_mac_addr(chip, addr->sa_data);
231 if (r)
232 return r;
233
234 spin_lock_irqsave(&mac->lock, flags);
235 memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN);
236 spin_unlock_irqrestore(&mac->lock, flags);
237
238 return 0;
239}
240
241int zd_mac_set_regdomain(struct zd_mac *mac, u8 regdomain)
242{
243 int r;
244 u8 channel;
245
246 ZD_ASSERT(!irqs_disabled());
247 spin_lock_irq(&mac->lock);
248 if (regdomain == 0) {
249 regdomain = mac->default_regdomain;
250 }
251 if (!zd_regdomain_supported(regdomain)) {
252 spin_unlock_irq(&mac->lock);
253 return -EINVAL;
254 }
255 mac->regdomain = regdomain;
256 channel = mac->requested_channel;
257 spin_unlock_irq(&mac->lock);
258
259 r = zd_geo_init(zd_mac_to_ieee80211(mac), regdomain);
260 if (r)
261 return r;
262 if (!zd_regdomain_supports_channel(regdomain, channel)) {
263 r = reset_channel(mac);
264 if (r)
265 return r;
266 }
267
268 return 0;
269}
270
271u8 zd_mac_get_regdomain(struct zd_mac *mac)
272{
273 unsigned long flags;
274 u8 regdomain;
275
276 spin_lock_irqsave(&mac->lock, flags);
277 regdomain = mac->regdomain;
278 spin_unlock_irqrestore(&mac->lock, flags);
279 return regdomain;
280}
281
282static void set_channel(struct net_device *netdev, u8 channel)
283{
284 struct zd_mac *mac = zd_netdev_mac(netdev);
285
286 dev_dbg_f(zd_mac_dev(mac), "channel %d\n", channel);
287
288 zd_chip_set_channel(&mac->chip, channel);
289}
290
291/* TODO: Should not work in Managed mode. */
292int zd_mac_request_channel(struct zd_mac *mac, u8 channel)
293{
294 unsigned long lock_flags;
295 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
296
297 if (ieee->iw_mode == IW_MODE_INFRA)
298 return -EPERM;
299
300 spin_lock_irqsave(&mac->lock, lock_flags);
301 if (!zd_regdomain_supports_channel(mac->regdomain, channel)) {
302 spin_unlock_irqrestore(&mac->lock, lock_flags);
303 return -EINVAL;
304 }
305 mac->requested_channel = channel;
306 spin_unlock_irqrestore(&mac->lock, lock_flags);
307 if (netif_running(mac->netdev))
308 return zd_chip_set_channel(&mac->chip, channel);
309 else
310 return 0;
311}
312
313int zd_mac_get_channel(struct zd_mac *mac, u8 *channel, u8 *flags)
314{
315 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
316
317 *channel = zd_chip_get_channel(&mac->chip);
318 if (ieee->iw_mode != IW_MODE_INFRA) {
319 spin_lock_irq(&mac->lock);
320 *flags = *channel == mac->requested_channel ?
321 MAC_FIXED_CHANNEL : 0;
322 spin_unlock(&mac->lock);
323 } else {
324 *flags = 0;
325 }
326 dev_dbg_f(zd_mac_dev(mac), "channel %u flags %u\n", *channel, *flags);
327 return 0;
328}
329
330/* If wrong rate is given, we are falling back to the slowest rate: 1MBit/s */
331static u8 cs_typed_rate(u8 cs_rate)
332{
333 static const u8 typed_rates[16] = {
334 [ZD_CS_CCK_RATE_1M] = ZD_CS_CCK|ZD_CS_CCK_RATE_1M,
335 [ZD_CS_CCK_RATE_2M] = ZD_CS_CCK|ZD_CS_CCK_RATE_2M,
336 [ZD_CS_CCK_RATE_5_5M] = ZD_CS_CCK|ZD_CS_CCK_RATE_5_5M,
337 [ZD_CS_CCK_RATE_11M] = ZD_CS_CCK|ZD_CS_CCK_RATE_11M,
338 [ZD_OFDM_RATE_6M] = ZD_CS_OFDM|ZD_OFDM_RATE_6M,
339 [ZD_OFDM_RATE_9M] = ZD_CS_OFDM|ZD_OFDM_RATE_9M,
340 [ZD_OFDM_RATE_12M] = ZD_CS_OFDM|ZD_OFDM_RATE_12M,
341 [ZD_OFDM_RATE_18M] = ZD_CS_OFDM|ZD_OFDM_RATE_18M,
342 [ZD_OFDM_RATE_24M] = ZD_CS_OFDM|ZD_OFDM_RATE_24M,
343 [ZD_OFDM_RATE_36M] = ZD_CS_OFDM|ZD_OFDM_RATE_36M,
344 [ZD_OFDM_RATE_48M] = ZD_CS_OFDM|ZD_OFDM_RATE_48M,
345 [ZD_OFDM_RATE_54M] = ZD_CS_OFDM|ZD_OFDM_RATE_54M,
346 };
347
348 ZD_ASSERT(ZD_CS_RATE_MASK == 0x0f);
349 return typed_rates[cs_rate & ZD_CS_RATE_MASK];
350}
351
352/* Fallback to lowest rate, if rate is unknown. */
353static u8 rate_to_cs_rate(u8 rate)
354{
355 switch (rate) {
356 case IEEE80211_CCK_RATE_2MB:
357 return ZD_CS_CCK_RATE_2M;
358 case IEEE80211_CCK_RATE_5MB:
359 return ZD_CS_CCK_RATE_5_5M;
360 case IEEE80211_CCK_RATE_11MB:
361 return ZD_CS_CCK_RATE_11M;
362 case IEEE80211_OFDM_RATE_6MB:
363 return ZD_OFDM_RATE_6M;
364 case IEEE80211_OFDM_RATE_9MB:
365 return ZD_OFDM_RATE_9M;
366 case IEEE80211_OFDM_RATE_12MB:
367 return ZD_OFDM_RATE_12M;
368 case IEEE80211_OFDM_RATE_18MB:
369 return ZD_OFDM_RATE_18M;
370 case IEEE80211_OFDM_RATE_24MB:
371 return ZD_OFDM_RATE_24M;
372 case IEEE80211_OFDM_RATE_36MB:
373 return ZD_OFDM_RATE_36M;
374 case IEEE80211_OFDM_RATE_48MB:
375 return ZD_OFDM_RATE_48M;
376 case IEEE80211_OFDM_RATE_54MB:
377 return ZD_OFDM_RATE_54M;
378 }
379 return ZD_CS_CCK_RATE_1M;
380}
381
382int zd_mac_set_mode(struct zd_mac *mac, u32 mode)
383{
384 struct ieee80211_device *ieee;
385
386 switch (mode) {
387 case IW_MODE_AUTO:
388 case IW_MODE_ADHOC:
389 case IW_MODE_INFRA:
390 mac->netdev->type = ARPHRD_ETHER;
391 break;
392 case IW_MODE_MONITOR:
393 mac->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
394 break;
395 default:
396 dev_dbg_f(zd_mac_dev(mac), "wrong mode %u\n", mode);
397 return -EINVAL;
398 }
399
400 ieee = zd_mac_to_ieee80211(mac);
401 ZD_ASSERT(!irqs_disabled());
402 spin_lock_irq(&ieee->lock);
403 ieee->iw_mode = mode;
404 spin_unlock_irq(&ieee->lock);
405
406 if (netif_running(mac->netdev))
407 return reset_mode(mac);
408
409 return 0;
410}
411
412int zd_mac_get_mode(struct zd_mac *mac, u32 *mode)
413{
414 unsigned long flags;
415 struct ieee80211_device *ieee;
416
417 ieee = zd_mac_to_ieee80211(mac);
418 spin_lock_irqsave(&ieee->lock, flags);
419 *mode = ieee->iw_mode;
420 spin_unlock_irqrestore(&ieee->lock, flags);
421 return 0;
422}
423
424int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range)
425{
426 int i;
427 const struct channel_range *channel_range;
428 u8 regdomain;
429
430 memset(range, 0, sizeof(*range));
431
432 /* FIXME: Not so important and depends on the mode. For 802.11g
433 * usually this value is used. It seems to be that Bit/s number is
434 * given here.
435 */
436 range->throughput = 27 * 1000 * 1000;
437
438 range->max_qual.qual = 100;
439 range->max_qual.level = 100;
440
441 /* FIXME: Needs still to be tuned. */
442 range->avg_qual.qual = 71;
443 range->avg_qual.level = 80;
444
445 /* FIXME: depends on standard? */
446 range->min_rts = 256;
447 range->max_rts = 2346;
448
449 range->min_frag = MIN_FRAG_THRESHOLD;
450 range->max_frag = MAX_FRAG_THRESHOLD;
451
452 range->max_encoding_tokens = WEP_KEYS;
453 range->num_encoding_sizes = 2;
454 range->encoding_size[0] = 5;
455 range->encoding_size[1] = WEP_KEY_LEN;
456
457 range->we_version_compiled = WIRELESS_EXT;
458 range->we_version_source = 20;
459
460 ZD_ASSERT(!irqs_disabled());
461 spin_lock_irq(&mac->lock);
462 regdomain = mac->regdomain;
463 spin_unlock_irq(&mac->lock);
464 channel_range = zd_channel_range(regdomain);
465
466 range->num_channels = channel_range->end - channel_range->start;
467 range->old_num_channels = range->num_channels;
468 range->num_frequency = range->num_channels;
469 range->old_num_frequency = range->num_frequency;
470
471 for (i = 0; i < range->num_frequency; i++) {
472 struct iw_freq *freq = &range->freq[i];
473 freq->i = channel_range->start + i;
474 zd_channel_to_freq(freq, freq->i);
475 }
476
477 return 0;
478}
479
480static int zd_calc_tx_length_us(u8 *service, u8 cs_rate, u16 tx_length)
481{
482 static const u8 rate_divisor[] = {
483 [ZD_CS_CCK_RATE_1M] = 1,
484 [ZD_CS_CCK_RATE_2M] = 2,
485 [ZD_CS_CCK_RATE_5_5M] = 11, /* bits must be doubled */
486 [ZD_CS_CCK_RATE_11M] = 11,
487 [ZD_OFDM_RATE_6M] = 6,
488 [ZD_OFDM_RATE_9M] = 9,
489 [ZD_OFDM_RATE_12M] = 12,
490 [ZD_OFDM_RATE_18M] = 18,
491 [ZD_OFDM_RATE_24M] = 24,
492 [ZD_OFDM_RATE_36M] = 36,
493 [ZD_OFDM_RATE_48M] = 48,
494 [ZD_OFDM_RATE_54M] = 54,
495 };
496
497 u32 bits = (u32)tx_length * 8;
498 u32 divisor;
499
500 divisor = rate_divisor[cs_rate];
501 if (divisor == 0)
502 return -EINVAL;
503
504 switch (cs_rate) {
505 case ZD_CS_CCK_RATE_5_5M:
506 bits = (2*bits) + 10; /* round up to the next integer */
507 break;
508 case ZD_CS_CCK_RATE_11M:
509 if (service) {
510 u32 t = bits % 11;
511 *service &= ~ZD_PLCP_SERVICE_LENGTH_EXTENSION;
512 if (0 < t && t <= 3) {
513 *service |= ZD_PLCP_SERVICE_LENGTH_EXTENSION;
514 }
515 }
516 bits += 10; /* round up to the next integer */
517 break;
518 }
519
520 return bits/divisor;
521}
522
523enum {
524 R2M_SHORT_PREAMBLE = 0x01,
525 R2M_11A = 0x02,
526};
527
528static u8 cs_rate_to_modulation(u8 cs_rate, int flags)
529{
530 u8 modulation;
531
532 modulation = cs_typed_rate(cs_rate);
533 if (flags & R2M_SHORT_PREAMBLE) {
534 switch (ZD_CS_RATE(modulation)) {
535 case ZD_CS_CCK_RATE_2M:
536 case ZD_CS_CCK_RATE_5_5M:
537 case ZD_CS_CCK_RATE_11M:
538 modulation |= ZD_CS_CCK_PREA_SHORT;
539 return modulation;
540 }
541 }
542 if (flags & R2M_11A) {
543 if (ZD_CS_TYPE(modulation) == ZD_CS_OFDM)
544 modulation |= ZD_CS_OFDM_MODE_11A;
545 }
546 return modulation;
547}
548
549static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs,
550 struct ieee80211_hdr_4addr *hdr)
551{
552 struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev);
553 u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl));
554 u8 rate, cs_rate;
555 int is_mgt = (ftype == IEEE80211_FTYPE_MGMT) != 0;
556
557 /* FIXME: 802.11a? short preamble? */
558 rate = ieee80211softmac_suggest_txrate(softmac,
559 is_multicast_ether_addr(hdr->addr1), is_mgt);
560
561 cs_rate = rate_to_cs_rate(rate);
562 cs->modulation = cs_rate_to_modulation(cs_rate, 0);
563}
564
565static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
566 struct ieee80211_hdr_4addr *header)
567{
568 unsigned int tx_length = le16_to_cpu(cs->tx_length);
569 u16 fctl = le16_to_cpu(header->frame_ctl);
570 u16 ftype = WLAN_FC_GET_TYPE(fctl);
571 u16 stype = WLAN_FC_GET_STYPE(fctl);
572
573 /*
574 * CONTROL:
575 * - start at 0x00
576 * - if fragment 0, enable bit 0
577 * - if backoff needed, enable bit 0
578 * - if burst (backoff not needed) disable bit 0
579 * - if multicast, enable bit 1
580 * - if PS-POLL frame, enable bit 2
581 * - if in INDEPENDENT_BSS mode and zd1205_DestPowerSave, then enable
582 * bit 4 (FIXME: wtf)
583 * - if frag_len > RTS threshold, set bit 5 as long if it isnt
584 * multicast or mgt
585 * - if bit 5 is set, and we are in OFDM mode, unset bit 5 and set bit
586 * 7
587 */
588
589 cs->control = 0;
590
591 /* First fragment */
592 if (WLAN_GET_SEQ_FRAG(le16_to_cpu(header->seq_ctl)) == 0)
593 cs->control |= ZD_CS_NEED_RANDOM_BACKOFF;
594
595 /* Multicast */
596 if (is_multicast_ether_addr(header->addr1))
597 cs->control |= ZD_CS_MULTICAST;
598
599 /* PS-POLL */
600 if (stype == IEEE80211_STYPE_PSPOLL)
601 cs->control |= ZD_CS_PS_POLL_FRAME;
602
603 if (!is_multicast_ether_addr(header->addr1) &&
604 ftype != IEEE80211_FTYPE_MGMT &&
605 tx_length > zd_netdev_ieee80211(mac->netdev)->rts)
606 {
607 /* FIXME: check the logic */
608 if (ZD_CS_TYPE(cs->modulation) == ZD_CS_OFDM) {
609 /* 802.11g */
610 cs->control |= ZD_CS_SELF_CTS;
611 } else { /* 802.11b */
612 cs->control |= ZD_CS_RTS;
613 }
614 }
615
616 /* FIXME: Management frame? */
617}
618
619static int fill_ctrlset(struct zd_mac *mac,
620 struct ieee80211_txb *txb,
621 int frag_num)
622{
623 int r;
624 struct sk_buff *skb = txb->fragments[frag_num];
625 struct ieee80211_hdr_4addr *hdr =
626 (struct ieee80211_hdr_4addr *) skb->data;
627 unsigned int frag_len = skb->len + IEEE80211_FCS_LEN;
628 unsigned int next_frag_len;
629 unsigned int packet_length;
630 struct zd_ctrlset *cs = (struct zd_ctrlset *)
631 skb_push(skb, sizeof(struct zd_ctrlset));
632
633 if (frag_num+1 < txb->nr_frags) {
634 next_frag_len = txb->fragments[frag_num+1]->len +
635 IEEE80211_FCS_LEN;
636 } else {
637 next_frag_len = 0;
638 }
639 ZD_ASSERT(frag_len <= 0xffff);
640 ZD_ASSERT(next_frag_len <= 0xffff);
641
642 cs_set_modulation(mac, cs, hdr);
643
644 cs->tx_length = cpu_to_le16(frag_len);
645
646 cs_set_control(mac, cs, hdr);
647
648 packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
649 ZD_ASSERT(packet_length <= 0xffff);
650 /* ZD1211B: Computing the length difference this way, gives us
651 * flexibility to compute the packet length.
652 */
653 cs->packet_length = cpu_to_le16(mac->chip.is_zd1211b ?
654 packet_length - frag_len : packet_length);
655
656 /*
657 * CURRENT LENGTH:
658 * - transmit frame length in microseconds
659 * - seems to be derived from frame length
660 * - see Cal_Us_Service() in zdinlinef.h
661 * - if macp->bTxBurstEnable is enabled, then multiply by 4
662 * - bTxBurstEnable is never set in the vendor driver
663 *
664 * SERVICE:
665 * - "for PLCP configuration"
666 * - always 0 except in some situations at 802.11b 11M
667 * - see line 53 of zdinlinef.h
668 */
669 cs->service = 0;
670 r = zd_calc_tx_length_us(&cs->service, ZD_CS_RATE(cs->modulation),
671 le16_to_cpu(cs->tx_length));
672 if (r < 0)
673 return r;
674 cs->current_length = cpu_to_le16(r);
675
676 if (next_frag_len == 0) {
677 cs->next_frame_length = 0;
678 } else {
679 r = zd_calc_tx_length_us(NULL, ZD_CS_RATE(cs->modulation),
680 next_frag_len);
681 if (r < 0)
682 return r;
683 cs->next_frame_length = cpu_to_le16(r);
684 }
685
686 return 0;
687}
688
689static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri)
690{
691 int i, r;
692
693 for (i = 0; i < txb->nr_frags; i++) {
694 struct sk_buff *skb = txb->fragments[i];
695
696 r = fill_ctrlset(mac, txb, i);
697 if (r)
698 return r;
699 r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len);
700 if (r)
701 return r;
702 }
703
704 /* FIXME: shouldn't this be handled by the upper layers? */
705 mac->netdev->trans_start = jiffies;
706
707 ieee80211_txb_free(txb);
708 return 0;
709}
710
711struct zd_rt_hdr {
712 struct ieee80211_radiotap_header rt_hdr;
713 u8 rt_flags;
714 u16 rt_channel;
715 u16 rt_chbitmask;
716 u16 rt_rate;
717};
718
719static void fill_rt_header(void *buffer, struct zd_mac *mac,
720 const struct ieee80211_rx_stats *stats,
721 const struct rx_status *status)
722{
723 struct zd_rt_hdr *hdr = buffer;
724
725 hdr->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
726 hdr->rt_hdr.it_pad = 0;
727 hdr->rt_hdr.it_len = cpu_to_le16(sizeof(struct zd_rt_hdr));
728 hdr->rt_hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
729 (1 << IEEE80211_RADIOTAP_CHANNEL) |
730 (1 << IEEE80211_RADIOTAP_RATE));
731
732 hdr->rt_flags = 0;
733 if (status->decryption_type & (ZD_RX_WEP64|ZD_RX_WEP128|ZD_RX_WEP256))
734 hdr->rt_flags |= IEEE80211_RADIOTAP_F_WEP;
735
736 /* FIXME: 802.11a */
737 hdr->rt_channel = cpu_to_le16(ieee80211chan2mhz(
738 _zd_chip_get_channel(&mac->chip)));
739 hdr->rt_chbitmask = cpu_to_le16(IEEE80211_CHAN_2GHZ |
740 ((status->frame_status & ZD_RX_FRAME_MODULATION_MASK) ==
741 ZD_RX_OFDM ? IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK));
742
743 hdr->rt_rate = stats->rate / 5;
744}
745
746/* Returns 1 if the data packet is for us and 0 otherwise. */
747static int is_data_packet_for_us(struct ieee80211_device *ieee,
748 struct ieee80211_hdr_4addr *hdr)
749{
750 struct net_device *netdev = ieee->dev;
751 u16 fc = le16_to_cpu(hdr->frame_ctl);
752
753 ZD_ASSERT(WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA);
754
755 switch (ieee->iw_mode) {
756 case IW_MODE_ADHOC:
757 if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 ||
758 memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) != 0)
759 return 0;
760 break;
761 case IW_MODE_AUTO:
762 case IW_MODE_INFRA:
763 if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) !=
764 IEEE80211_FCTL_FROMDS ||
765 memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) != 0)
766 return 0;
767 break;
768 default:
769 ZD_ASSERT(ieee->iw_mode != IW_MODE_MONITOR);
770 return 0;
771 }
772
773 return memcmp(hdr->addr1, netdev->dev_addr, ETH_ALEN) == 0 ||
774 is_multicast_ether_addr(hdr->addr1) ||
775 (netdev->flags & IFF_PROMISC);
776}
777
778/* Filters receiving packets. If it returns 1 send it to ieee80211_rx, if 0
779 * return. If an error is detected -EINVAL is returned. ieee80211_rx_mgt() is
780 * called here.
781 *
782 * It has been based on ieee80211_rx_any.
783 */
784static int filter_rx(struct ieee80211_device *ieee,
785 const u8 *buffer, unsigned int length,
786 struct ieee80211_rx_stats *stats)
787{
788 struct ieee80211_hdr_4addr *hdr;
789 u16 fc;
790
791 if (ieee->iw_mode == IW_MODE_MONITOR)
792 return 1;
793
794 hdr = (struct ieee80211_hdr_4addr *)buffer;
795 fc = le16_to_cpu(hdr->frame_ctl);
796 if ((fc & IEEE80211_FCTL_VERS) != 0)
797 return -EINVAL;
798
799 switch (WLAN_FC_GET_TYPE(fc)) {
800 case IEEE80211_FTYPE_MGMT:
801 if (length < sizeof(struct ieee80211_hdr_3addr))
802 return -EINVAL;
803 ieee80211_rx_mgt(ieee, hdr, stats);
804 return 0;
805 case IEEE80211_FTYPE_CTL:
806 /* Ignore invalid short buffers */
807 return 0;
808 case IEEE80211_FTYPE_DATA:
809 if (length < sizeof(struct ieee80211_hdr_3addr))
810 return -EINVAL;
811 return is_data_packet_for_us(ieee, hdr);
812 }
813
814 return -EINVAL;
815}
816
817static void update_qual_rssi(struct zd_mac *mac, u8 qual_percent, u8 rssi)
818{
819 unsigned long flags;
820
821 spin_lock_irqsave(&mac->lock, flags);
822 mac->qual_average = (7 * mac->qual_average + qual_percent) / 8;
823 mac->rssi_average = (7 * mac->rssi_average + rssi) / 8;
824 spin_unlock_irqrestore(&mac->lock, flags);
825}
826
827static int fill_rx_stats(struct ieee80211_rx_stats *stats,
828 const struct rx_status **pstatus,
829 struct zd_mac *mac,
830 const u8 *buffer, unsigned int length)
831{
832 const struct rx_status *status;
833
834 *pstatus = status = zd_tail(buffer, length, sizeof(struct rx_status));
835 if (status->frame_status & ZD_RX_ERROR) {
836 /* FIXME: update? */
837 return -EINVAL;
838 }
839 memset(stats, 0, sizeof(struct ieee80211_rx_stats));
840 stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN +
841 + sizeof(struct rx_status));
842 /* FIXME: 802.11a */
843 stats->freq = IEEE80211_24GHZ_BAND;
844 stats->received_channel = _zd_chip_get_channel(&mac->chip);
845 stats->rssi = zd_rx_strength_percent(status->signal_strength);
846 stats->signal = zd_rx_qual_percent(buffer,
847 length - sizeof(struct rx_status),
848 status);
849 stats->mask = IEEE80211_STATMASK_RSSI | IEEE80211_STATMASK_SIGNAL;
850 stats->rate = zd_rx_rate(buffer, status);
851 if (stats->rate)
852 stats->mask |= IEEE80211_STATMASK_RATE;
853
854 update_qual_rssi(mac, stats->signal, stats->rssi);
855 return 0;
856}
857
858int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length)
859{
860 int r;
861 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
862 struct ieee80211_rx_stats stats;
863 const struct rx_status *status;
864 struct sk_buff *skb;
865
866 if (length < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN +
867 IEEE80211_FCS_LEN + sizeof(struct rx_status))
868 return -EINVAL;
869
870 r = fill_rx_stats(&stats, &status, mac, buffer, length);
871 if (r)
872 return r;
873
874 length -= ZD_PLCP_HEADER_SIZE+IEEE80211_FCS_LEN+
875 sizeof(struct rx_status);
876 buffer += ZD_PLCP_HEADER_SIZE;
877
878 r = filter_rx(ieee, buffer, length, &stats);
879 if (r <= 0)
880 return r;
881
882 skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length);
883 if (!skb)
884 return -ENOMEM;
885 if (ieee->iw_mode == IW_MODE_MONITOR)
886 fill_rt_header(skb_put(skb, sizeof(struct zd_rt_hdr)), mac,
887 &stats, status);
888 memcpy(skb_put(skb, length), buffer, length);
889
890 r = ieee80211_rx(ieee, skb, &stats);
891 if (!r) {
892 ZD_ASSERT(in_irq());
893 dev_kfree_skb_irq(skb);
894 }
895 return 0;
896}
897
898static int netdev_tx(struct ieee80211_txb *txb, struct net_device *netdev,
899 int pri)
900{
901 return zd_mac_tx(zd_netdev_mac(netdev), txb, pri);
902}
903
904static void set_security(struct net_device *netdev,
905 struct ieee80211_security *sec)
906{
907 struct ieee80211_device *ieee = zd_netdev_ieee80211(netdev);
908 struct ieee80211_security *secinfo = &ieee->sec;
909 int keyidx;
910
911 dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n");
912
913 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
914 if (sec->flags & (1<<keyidx)) {
915 secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx];
916 secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx];
917 memcpy(secinfo->keys[keyidx], sec->keys[keyidx],
918 SCM_KEY_LEN);
919 }
920
921 if (sec->flags & SEC_ACTIVE_KEY) {
922 secinfo->active_key = sec->active_key;
923 dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
924 " .active_key = %d\n", sec->active_key);
925 }
926 if (sec->flags & SEC_UNICAST_GROUP) {
927 secinfo->unicast_uses_group = sec->unicast_uses_group;
928 dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
929 " .unicast_uses_group = %d\n",
930 sec->unicast_uses_group);
931 }
932 if (sec->flags & SEC_LEVEL) {
933 secinfo->level = sec->level;
934 dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
935 " .level = %d\n", sec->level);
936 }
937 if (sec->flags & SEC_ENABLED) {
938 secinfo->enabled = sec->enabled;
939 dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
940 " .enabled = %d\n", sec->enabled);
941 }
942 if (sec->flags & SEC_ENCRYPT) {
943 secinfo->encrypt = sec->encrypt;
944 dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
945 " .encrypt = %d\n", sec->encrypt);
946 }
947 if (sec->flags & SEC_AUTH_MODE) {
948 secinfo->auth_mode = sec->auth_mode;
949 dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
950 " .auth_mode = %d\n", sec->auth_mode);
951 }
952}
953
954static void ieee_init(struct ieee80211_device *ieee)
955{
956 ieee->mode = IEEE_B | IEEE_G;
957 ieee->freq_band = IEEE80211_24GHZ_BAND;
958 ieee->modulation = IEEE80211_OFDM_MODULATION | IEEE80211_CCK_MODULATION;
959 ieee->tx_headroom = sizeof(struct zd_ctrlset);
960 ieee->set_security = set_security;
961 ieee->hard_start_xmit = netdev_tx;
962
963 /* Software encryption/decryption for now */
964 ieee->host_build_iv = 0;
965 ieee->host_encrypt = 1;
966 ieee->host_decrypt = 1;
967
968 /* FIXME: default to managed mode, until ieee80211 and zd1211rw can
969 * correctly support AUTO */
970 ieee->iw_mode = IW_MODE_INFRA;
971}
972
973static void softmac_init(struct ieee80211softmac_device *sm)
974{
975 sm->set_channel = set_channel;
976}
977
978struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev)
979{
980 struct zd_mac *mac = zd_netdev_mac(ndev);
981 struct iw_statistics *iw_stats = &mac->iw_stats;
982
983 memset(iw_stats, 0, sizeof(struct iw_statistics));
984 /* We are not setting the status, because ieee->state is not updated
985 * at all and this driver doesn't track authentication state.
986 */
987 spin_lock_irq(&mac->lock);
988 iw_stats->qual.qual = mac->qual_average;
989 iw_stats->qual.level = mac->rssi_average;
990 iw_stats->qual.updated = IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED|
991 IW_QUAL_NOISE_INVALID;
992 spin_unlock_irq(&mac->lock);
993 /* TODO: update counter */
994 return iw_stats;
995}
996
997#ifdef DEBUG
998static const char* decryption_types[] = {
999 [ZD_RX_NO_WEP] = "none",
1000 [ZD_RX_WEP64] = "WEP64",
1001 [ZD_RX_TKIP] = "TKIP",
1002 [ZD_RX_AES] = "AES",
1003 [ZD_RX_WEP128] = "WEP128",
1004 [ZD_RX_WEP256] = "WEP256",
1005};
1006
1007static const char *decryption_type_string(u8 type)
1008{
1009 const char *s;
1010
1011 if (type < ARRAY_SIZE(decryption_types)) {
1012 s = decryption_types[type];
1013 } else {
1014 s = NULL;
1015 }
1016 return s ? s : "unknown";
1017}
1018
1019static int is_ofdm(u8 frame_status)
1020{
1021 return (frame_status & ZD_RX_OFDM);
1022}
1023
1024void zd_dump_rx_status(const struct rx_status *status)
1025{
1026 const char* modulation;
1027 u8 quality;
1028
1029 if (is_ofdm(status->frame_status)) {
1030 modulation = "ofdm";
1031 quality = status->signal_quality_ofdm;
1032 } else {
1033 modulation = "cck";
1034 quality = status->signal_quality_cck;
1035 }
1036 pr_debug("rx status %s strength %#04x qual %#04x decryption %s\n",
1037 modulation, status->signal_strength, quality,
1038 decryption_type_string(status->decryption_type));
1039 if (status->frame_status & ZD_RX_ERROR) {
1040 pr_debug("rx error %s%s%s%s%s%s\n",
1041 (status->frame_status & ZD_RX_TIMEOUT_ERROR) ?
1042 "timeout " : "",
1043 (status->frame_status & ZD_RX_FIFO_OVERRUN_ERROR) ?
1044 "fifo " : "",
1045 (status->frame_status & ZD_RX_DECRYPTION_ERROR) ?
1046 "decryption " : "",
1047 (status->frame_status & ZD_RX_CRC32_ERROR) ?
1048 "crc32 " : "",
1049 (status->frame_status & ZD_RX_NO_ADDR1_MATCH_ERROR) ?
1050 "addr1 " : "",
1051 (status->frame_status & ZD_RX_CRC16_ERROR) ?
1052 "crc16" : "");
1053 }
1054}
1055#endif /* DEBUG */