diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00')
32 files changed, 4309 insertions, 2875 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index da05b1faf60d..4709c11da419 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -5,30 +5,28 @@ config RT2X00 | |||
5 | This will enable the experimental support for the Ralink drivers, | 5 | This will enable the experimental support for the Ralink drivers, |
6 | developed in the rt2x00 project <http://rt2x00.serialmonkey.com>. | 6 | developed in the rt2x00 project <http://rt2x00.serialmonkey.com>. |
7 | 7 | ||
8 | These drivers will make use of the Devicescape ieee80211 stack. | 8 | These drivers will make use of the mac80211 stack. |
9 | 9 | ||
10 | When building one of the individual drivers, the rt2x00 library | 10 | When building one of the individual drivers, the rt2x00 library |
11 | will also be created. That library (when the driver is built as | 11 | will also be created. That library (when the driver is built as |
12 | a module) will be called "rt2x00lib.ko". | 12 | a module) will be called "rt2x00lib.ko". |
13 | 13 | ||
14 | if RT2X00 | ||
15 | |||
14 | config RT2X00_LIB | 16 | config RT2X00_LIB |
15 | tristate | 17 | tristate |
16 | depends on RT2X00 | ||
17 | 18 | ||
18 | config RT2X00_LIB_PCI | 19 | config RT2X00_LIB_PCI |
19 | tristate | 20 | tristate |
20 | depends on RT2X00 | ||
21 | select RT2X00_LIB | 21 | select RT2X00_LIB |
22 | 22 | ||
23 | config RT2X00_LIB_USB | 23 | config RT2X00_LIB_USB |
24 | tristate | 24 | tristate |
25 | depends on RT2X00 | ||
26 | select RT2X00_LIB | 25 | select RT2X00_LIB |
27 | 26 | ||
28 | config RT2X00_LIB_FIRMWARE | 27 | config RT2X00_LIB_FIRMWARE |
29 | boolean | 28 | boolean |
30 | depends on RT2X00_LIB | 29 | depends on RT2X00_LIB |
31 | select CRC_ITU_T | ||
32 | select FW_LOADER | 30 | select FW_LOADER |
33 | 31 | ||
34 | config RT2X00_LIB_RFKILL | 32 | config RT2X00_LIB_RFKILL |
@@ -37,9 +35,17 @@ config RT2X00_LIB_RFKILL | |||
37 | select RFKILL | 35 | select RFKILL |
38 | select INPUT_POLLDEV | 36 | select INPUT_POLLDEV |
39 | 37 | ||
38 | config RT2X00_LIB_LEDS | ||
39 | boolean | ||
40 | depends on RT2X00_LIB | ||
41 | select NEW_LEDS | ||
42 | select LEDS_CLASS | ||
43 | select LEDS_TRIGGERS | ||
44 | select MAC80211_LEDS | ||
45 | |||
40 | config RT2400PCI | 46 | config RT2400PCI |
41 | tristate "Ralink rt2400 pci/pcmcia support" | 47 | tristate "Ralink rt2400 pci/pcmcia support" |
42 | depends on RT2X00 && PCI | 48 | depends on PCI |
43 | select RT2X00_LIB_PCI | 49 | select RT2X00_LIB_PCI |
44 | select EEPROM_93CX6 | 50 | select EEPROM_93CX6 |
45 | ---help--- | 51 | ---help--- |
@@ -56,9 +62,16 @@ config RT2400PCI_RFKILL | |||
56 | hardware button to control the radio state. | 62 | hardware button to control the radio state. |
57 | This feature depends on the RF switch subsystem rfkill. | 63 | This feature depends on the RF switch subsystem rfkill. |
58 | 64 | ||
65 | config RT2400PCI_LEDS | ||
66 | bool "RT2400 leds support" | ||
67 | depends on RT2400PCI | ||
68 | select RT2X00_LIB_LEDS | ||
69 | ---help--- | ||
70 | This adds support for led triggers provided my mac80211. | ||
71 | |||
59 | config RT2500PCI | 72 | config RT2500PCI |
60 | tristate "Ralink rt2500 pci/pcmcia support" | 73 | tristate "Ralink rt2500 pci/pcmcia support" |
61 | depends on RT2X00 && PCI | 74 | depends on PCI |
62 | select RT2X00_LIB_PCI | 75 | select RT2X00_LIB_PCI |
63 | select EEPROM_93CX6 | 76 | select EEPROM_93CX6 |
64 | ---help--- | 77 | ---help--- |
@@ -75,11 +88,19 @@ config RT2500PCI_RFKILL | |||
75 | hardware button to control the radio state. | 88 | hardware button to control the radio state. |
76 | This feature depends on the RF switch subsystem rfkill. | 89 | This feature depends on the RF switch subsystem rfkill. |
77 | 90 | ||
91 | config RT2500PCI_LEDS | ||
92 | bool "RT2500 leds support" | ||
93 | depends on RT2500PCI | ||
94 | select RT2X00_LIB_LEDS | ||
95 | ---help--- | ||
96 | This adds support for led triggers provided my mac80211. | ||
97 | |||
78 | config RT61PCI | 98 | config RT61PCI |
79 | tristate "Ralink rt61 pci/pcmcia support" | 99 | tristate "Ralink rt61 pci/pcmcia support" |
80 | depends on RT2X00 && PCI | 100 | depends on PCI |
81 | select RT2X00_LIB_PCI | 101 | select RT2X00_LIB_PCI |
82 | select RT2X00_LIB_FIRMWARE | 102 | select RT2X00_LIB_FIRMWARE |
103 | select CRC_ITU_T | ||
83 | select EEPROM_93CX6 | 104 | select EEPROM_93CX6 |
84 | ---help--- | 105 | ---help--- |
85 | This is an experimental driver for the Ralink rt61 wireless chip. | 106 | This is an experimental driver for the Ralink rt61 wireless chip. |
@@ -95,25 +116,47 @@ config RT61PCI_RFKILL | |||
95 | hardware button to control the radio state. | 116 | hardware button to control the radio state. |
96 | This feature depends on the RF switch subsystem rfkill. | 117 | This feature depends on the RF switch subsystem rfkill. |
97 | 118 | ||
119 | config RT61PCI_LEDS | ||
120 | bool "RT61 leds support" | ||
121 | depends on RT61PCI | ||
122 | select RT2X00_LIB_LEDS | ||
123 | ---help--- | ||
124 | This adds support for led triggers provided my mac80211. | ||
125 | |||
98 | config RT2500USB | 126 | config RT2500USB |
99 | tristate "Ralink rt2500 usb support" | 127 | tristate "Ralink rt2500 usb support" |
100 | depends on RT2X00 && USB | 128 | depends on USB |
101 | select RT2X00_LIB_USB | 129 | select RT2X00_LIB_USB |
102 | ---help--- | 130 | ---help--- |
103 | This is an experimental driver for the Ralink rt2500 wireless chip. | 131 | This is an experimental driver for the Ralink rt2500 wireless chip. |
104 | 132 | ||
105 | When compiled as a module, this driver will be called "rt2500usb.ko". | 133 | When compiled as a module, this driver will be called "rt2500usb.ko". |
106 | 134 | ||
135 | config RT2500USB_LEDS | ||
136 | bool "RT2500 leds support" | ||
137 | depends on RT2500USB | ||
138 | select RT2X00_LIB_LEDS | ||
139 | ---help--- | ||
140 | This adds support for led triggers provided my mac80211. | ||
141 | |||
107 | config RT73USB | 142 | config RT73USB |
108 | tristate "Ralink rt73 usb support" | 143 | tristate "Ralink rt73 usb support" |
109 | depends on RT2X00 && USB | 144 | depends on USB |
110 | select RT2X00_LIB_USB | 145 | select RT2X00_LIB_USB |
111 | select RT2X00_LIB_FIRMWARE | 146 | select RT2X00_LIB_FIRMWARE |
147 | select CRC_ITU_T | ||
112 | ---help--- | 148 | ---help--- |
113 | This is an experimental driver for the Ralink rt73 wireless chip. | 149 | This is an experimental driver for the Ralink rt73 wireless chip. |
114 | 150 | ||
115 | When compiled as a module, this driver will be called "rt73usb.ko". | 151 | When compiled as a module, this driver will be called "rt73usb.ko". |
116 | 152 | ||
153 | config RT73USB_LEDS | ||
154 | bool "RT73 leds support" | ||
155 | depends on RT73USB | ||
156 | select RT2X00_LIB_LEDS | ||
157 | ---help--- | ||
158 | This adds support for led triggers provided my mac80211. | ||
159 | |||
117 | config RT2X00_LIB_DEBUGFS | 160 | config RT2X00_LIB_DEBUGFS |
118 | bool "Ralink debugfs support" | 161 | bool "Ralink debugfs support" |
119 | depends on RT2X00_LIB && MAC80211_DEBUGFS | 162 | depends on RT2X00_LIB && MAC80211_DEBUGFS |
@@ -128,3 +171,4 @@ config RT2X00_DEBUG | |||
128 | ---help--- | 171 | ---help--- |
129 | Enable debugging output for all rt2x00 modules | 172 | Enable debugging output for all rt2x00 modules |
130 | 173 | ||
174 | endif | ||
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile index 30d654a42eea..1087dbcf1a04 100644 --- a/drivers/net/wireless/rt2x00/Makefile +++ b/drivers/net/wireless/rt2x00/Makefile | |||
@@ -1,22 +1,17 @@ | |||
1 | rt2x00lib-objs := rt2x00dev.o rt2x00mac.o rt2x00config.o | 1 | rt2x00lib-y += rt2x00dev.o |
2 | rt2x00lib-y += rt2x00mac.o | ||
3 | rt2x00lib-y += rt2x00config.o | ||
4 | rt2x00lib-y += rt2x00queue.o | ||
5 | rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o | ||
6 | rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o | ||
7 | rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o | ||
8 | rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o | ||
2 | 9 | ||
3 | ifeq ($(CONFIG_RT2X00_LIB_DEBUGFS),y) | 10 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o |
4 | rt2x00lib-objs += rt2x00debug.o | 11 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o |
5 | endif | 12 | obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o |
6 | 13 | obj-$(CONFIG_RT2400PCI) += rt2400pci.o | |
7 | ifeq ($(CONFIG_RT2X00_LIB_RFKILL),y) | 14 | obj-$(CONFIG_RT2500PCI) += rt2500pci.o |
8 | rt2x00lib-objs += rt2x00rfkill.o | 15 | obj-$(CONFIG_RT61PCI) += rt61pci.o |
9 | endif | 16 | obj-$(CONFIG_RT2500USB) += rt2500usb.o |
10 | 17 | obj-$(CONFIG_RT73USB) += rt73usb.o | |
11 | ifeq ($(CONFIG_RT2X00_LIB_FIRMWARE),y) | ||
12 | rt2x00lib-objs += rt2x00firmware.o | ||
13 | endif | ||
14 | |||
15 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o | ||
16 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o | ||
17 | obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o | ||
18 | obj-$(CONFIG_RT2400PCI) += rt2400pci.o | ||
19 | obj-$(CONFIG_RT2500PCI) += rt2500pci.o | ||
20 | obj-$(CONFIG_RT61PCI) += rt61pci.o | ||
21 | obj-$(CONFIG_RT2500USB) += rt2500usb.o | ||
22 | obj-$(CONFIG_RT73USB) += rt73usb.o | ||
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index c69f85ed7669..1f49561d3ddc 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -243,53 +243,71 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
243 | #define rt2400pci_rfkill_poll NULL | 243 | #define rt2400pci_rfkill_poll NULL |
244 | #endif /* CONFIG_RT2400PCI_RFKILL */ | 244 | #endif /* CONFIG_RT2400PCI_RFKILL */ |
245 | 245 | ||
246 | /* | 246 | #ifdef CONFIG_RT2400PCI_LEDS |
247 | * Configuration handlers. | 247 | static void rt2400pci_led_brightness(struct led_classdev *led_cdev, |
248 | */ | 248 | enum led_brightness brightness) |
249 | static void rt2400pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, | ||
250 | __le32 *mac) | ||
251 | { | 249 | { |
252 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, mac, | 250 | struct rt2x00_led *led = |
253 | (2 * sizeof(__le32))); | 251 | container_of(led_cdev, struct rt2x00_led, led_dev); |
254 | } | 252 | unsigned int enabled = brightness != LED_OFF; |
253 | unsigned int activity = | ||
254 | led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; | ||
255 | u32 reg; | ||
255 | 256 | ||
256 | static void rt2400pci_config_bssid(struct rt2x00_dev *rt2x00dev, | 257 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); |
257 | __le32 *bssid) | 258 | |
258 | { | 259 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { |
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | 260 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); |
260 | (2 * sizeof(__le32))); | 261 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled && activity); |
262 | } | ||
263 | |||
264 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
261 | } | 265 | } |
266 | #else | ||
267 | #define rt2400pci_led_brightness NULL | ||
268 | #endif /* CONFIG_RT2400PCI_LEDS */ | ||
262 | 269 | ||
263 | static void rt2400pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 270 | /* |
264 | const int tsf_sync) | 271 | * Configuration handlers. |
272 | */ | ||
273 | static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, | ||
274 | struct rt2x00_intf *intf, | ||
275 | struct rt2x00intf_conf *conf, | ||
276 | const unsigned int flags) | ||
265 | { | 277 | { |
278 | unsigned int bcn_preload; | ||
266 | u32 reg; | 279 | u32 reg; |
267 | 280 | ||
268 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 281 | if (flags & CONFIG_UPDATE_TYPE) { |
282 | /* | ||
283 | * Enable beacon config | ||
284 | */ | ||
285 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); | ||
286 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | ||
287 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | ||
288 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
269 | 289 | ||
270 | /* | 290 | /* |
271 | * Enable beacon config | 291 | * Enable synchronisation. |
272 | */ | 292 | */ |
273 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 293 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
274 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | 294 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
275 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | 295 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
276 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | 296 | rt2x00_set_field32(®, CSR14_TBCN, 1); |
297 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
298 | } | ||
277 | 299 | ||
278 | /* | 300 | if (flags & CONFIG_UPDATE_MAC) |
279 | * Enable synchronisation. | 301 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, |
280 | */ | 302 | conf->mac, sizeof(conf->mac)); |
281 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 303 | |
282 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 304 | if (flags & CONFIG_UPDATE_BSSID) |
283 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | 305 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, |
284 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 306 | conf->bssid, sizeof(conf->bssid)); |
285 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | ||
286 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
287 | } | 307 | } |
288 | 308 | ||
289 | static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 309 | static int rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, |
290 | const int short_preamble, | 310 | struct rt2x00lib_erp *erp) |
291 | const int ack_timeout, | ||
292 | const int ack_consume_time) | ||
293 | { | 311 | { |
294 | int preamble_mask; | 312 | int preamble_mask; |
295 | u32 reg; | 313 | u32 reg; |
@@ -297,11 +315,13 @@ static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
297 | /* | 315 | /* |
298 | * When short preamble is enabled, we should set bit 0x08 | 316 | * When short preamble is enabled, we should set bit 0x08 |
299 | */ | 317 | */ |
300 | preamble_mask = short_preamble << 3; | 318 | preamble_mask = erp->short_preamble << 3; |
301 | 319 | ||
302 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | 320 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); |
303 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, ack_timeout); | 321 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, |
304 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, ack_consume_time); | 322 | erp->ack_timeout); |
323 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, | ||
324 | erp->ack_consume_time); | ||
305 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 325 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); |
306 | 326 | ||
307 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 327 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
@@ -327,6 +347,8 @@ static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
327 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 347 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
328 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 348 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); |
329 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 349 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); |
350 | |||
351 | return 0; | ||
330 | } | 352 | } |
331 | 353 | ||
332 | static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 354 | static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -397,6 +419,13 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
397 | u8 r1; | 419 | u8 r1; |
398 | u8 r4; | 420 | u8 r4; |
399 | 421 | ||
422 | /* | ||
423 | * We should never come here because rt2x00lib is supposed | ||
424 | * to catch this and send us the correct antenna explicitely. | ||
425 | */ | ||
426 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
427 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
428 | |||
400 | rt2400pci_bbp_read(rt2x00dev, 4, &r4); | 429 | rt2400pci_bbp_read(rt2x00dev, 4, &r4); |
401 | rt2400pci_bbp_read(rt2x00dev, 1, &r1); | 430 | rt2400pci_bbp_read(rt2x00dev, 1, &r1); |
402 | 431 | ||
@@ -410,14 +439,8 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
410 | case ANTENNA_A: | 439 | case ANTENNA_A: |
411 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0); | 440 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0); |
412 | break; | 441 | break; |
413 | case ANTENNA_SW_DIVERSITY: | ||
414 | /* | ||
415 | * NOTE: We should never come here because rt2x00lib is | ||
416 | * supposed to catch this and send us the correct antenna | ||
417 | * explicitely. However we are nog going to bug about this. | ||
418 | * Instead, just default to antenna B. | ||
419 | */ | ||
420 | case ANTENNA_B: | 442 | case ANTENNA_B: |
443 | default: | ||
421 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2); | 444 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2); |
422 | break; | 445 | break; |
423 | } | 446 | } |
@@ -432,14 +455,8 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
432 | case ANTENNA_A: | 455 | case ANTENNA_A: |
433 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0); | 456 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0); |
434 | break; | 457 | break; |
435 | case ANTENNA_SW_DIVERSITY: | ||
436 | /* | ||
437 | * NOTE: We should never come here because rt2x00lib is | ||
438 | * supposed to catch this and send us the correct antenna | ||
439 | * explicitely. However we are nog going to bug about this. | ||
440 | * Instead, just default to antenna B. | ||
441 | */ | ||
442 | case ANTENNA_B: | 458 | case ANTENNA_B: |
459 | default: | ||
443 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | 460 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); |
444 | break; | 461 | break; |
445 | } | 462 | } |
@@ -481,8 +498,8 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
481 | } | 498 | } |
482 | 499 | ||
483 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | 500 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, |
484 | const unsigned int flags, | 501 | struct rt2x00lib_conf *libconf, |
485 | struct rt2x00lib_conf *libconf) | 502 | const unsigned int flags) |
486 | { | 503 | { |
487 | if (flags & CONFIG_UPDATE_PHYMODE) | 504 | if (flags & CONFIG_UPDATE_PHYMODE) |
488 | rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates); | 505 | rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -498,45 +515,17 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | |||
498 | } | 515 | } |
499 | 516 | ||
500 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, | 517 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, |
501 | struct ieee80211_tx_queue_params *params) | 518 | const int cw_min, const int cw_max) |
502 | { | 519 | { |
503 | u32 reg; | 520 | u32 reg; |
504 | 521 | ||
505 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 522 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); |
506 | rt2x00_set_field32(®, CSR11_CWMIN, params->cw_min); | 523 | rt2x00_set_field32(®, CSR11_CWMIN, cw_min); |
507 | rt2x00_set_field32(®, CSR11_CWMAX, params->cw_max); | 524 | rt2x00_set_field32(®, CSR11_CWMAX, cw_max); |
508 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 525 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); |
509 | } | 526 | } |
510 | 527 | ||
511 | /* | 528 | /* |
512 | * LED functions. | ||
513 | */ | ||
514 | static void rt2400pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
515 | { | ||
516 | u32 reg; | ||
517 | |||
518 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
519 | |||
520 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
521 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
522 | rt2x00_set_field32(®, LEDCSR_LINK, | ||
523 | (rt2x00dev->led_mode != LED_MODE_ASUS)); | ||
524 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, | ||
525 | (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); | ||
526 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
527 | } | ||
528 | |||
529 | static void rt2400pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
530 | { | ||
531 | u32 reg; | ||
532 | |||
533 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
534 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
535 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
536 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Link tuning | 529 | * Link tuning |
541 | */ | 530 | */ |
542 | static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, | 531 | static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -593,90 +582,94 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
593 | * Initialization functions. | 582 | * Initialization functions. |
594 | */ | 583 | */ |
595 | static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 584 | static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
596 | struct data_entry *entry) | 585 | struct queue_entry *entry) |
597 | { | 586 | { |
598 | __le32 *rxd = entry->priv; | 587 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
599 | u32 word; | 588 | u32 word; |
600 | 589 | ||
601 | rt2x00_desc_read(rxd, 2, &word); | 590 | rt2x00_desc_read(priv_rx->desc, 2, &word); |
602 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->ring->data_size); | 591 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, |
603 | rt2x00_desc_write(rxd, 2, word); | 592 | entry->queue->data_size); |
593 | rt2x00_desc_write(priv_rx->desc, 2, word); | ||
604 | 594 | ||
605 | rt2x00_desc_read(rxd, 1, &word); | 595 | rt2x00_desc_read(priv_rx->desc, 1, &word); |
606 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma); | 596 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); |
607 | rt2x00_desc_write(rxd, 1, word); | 597 | rt2x00_desc_write(priv_rx->desc, 1, word); |
608 | 598 | ||
609 | rt2x00_desc_read(rxd, 0, &word); | 599 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
610 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 600 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
611 | rt2x00_desc_write(rxd, 0, word); | 601 | rt2x00_desc_write(priv_rx->desc, 0, word); |
612 | } | 602 | } |
613 | 603 | ||
614 | static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 604 | static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
615 | struct data_entry *entry) | 605 | struct queue_entry *entry) |
616 | { | 606 | { |
617 | __le32 *txd = entry->priv; | 607 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
618 | u32 word; | 608 | u32 word; |
619 | 609 | ||
620 | rt2x00_desc_read(txd, 1, &word); | 610 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
621 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma); | 611 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma); |
622 | rt2x00_desc_write(txd, 1, word); | 612 | rt2x00_desc_write(priv_tx->desc, 1, word); |
623 | 613 | ||
624 | rt2x00_desc_read(txd, 2, &word); | 614 | rt2x00_desc_read(priv_tx->desc, 2, &word); |
625 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, entry->ring->data_size); | 615 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, |
626 | rt2x00_desc_write(txd, 2, word); | 616 | entry->queue->data_size); |
617 | rt2x00_desc_write(priv_tx->desc, 2, word); | ||
627 | 618 | ||
628 | rt2x00_desc_read(txd, 0, &word); | 619 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
629 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 620 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
630 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 621 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
631 | rt2x00_desc_write(txd, 0, word); | 622 | rt2x00_desc_write(priv_tx->desc, 0, word); |
632 | } | 623 | } |
633 | 624 | ||
634 | static int rt2400pci_init_rings(struct rt2x00_dev *rt2x00dev) | 625 | static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) |
635 | { | 626 | { |
627 | struct queue_entry_priv_pci_rx *priv_rx; | ||
628 | struct queue_entry_priv_pci_tx *priv_tx; | ||
636 | u32 reg; | 629 | u32 reg; |
637 | 630 | ||
638 | /* | 631 | /* |
639 | * Initialize registers. | 632 | * Initialize registers. |
640 | */ | 633 | */ |
641 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 634 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
642 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | 635 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
643 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | 636 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
644 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | 637 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); |
645 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 638 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
646 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, | ||
647 | rt2x00dev->bcn[1].stats.limit); | ||
648 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, | ||
649 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
650 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 639 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
651 | 640 | ||
641 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
652 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 642 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); |
653 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 643 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
654 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 644 | priv_tx->desc_dma); |
655 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 645 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); |
656 | 646 | ||
647 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
657 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 648 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); |
658 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 649 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
659 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 650 | priv_tx->desc_dma); |
660 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 651 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
661 | 652 | ||
653 | priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; | ||
662 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 654 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
663 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 655 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
664 | rt2x00dev->bcn[1].data_dma); | 656 | priv_tx->desc_dma); |
665 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 657 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
666 | 658 | ||
659 | priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; | ||
667 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 660 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
668 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 661 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
669 | rt2x00dev->bcn[0].data_dma); | 662 | priv_tx->desc_dma); |
670 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 663 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); |
671 | 664 | ||
672 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 665 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); |
673 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 666 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
674 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | 667 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
675 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 668 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); |
676 | 669 | ||
670 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
677 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 671 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); |
678 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 672 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma); |
679 | rt2x00dev->rx->data_dma); | ||
680 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 673 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); |
681 | 674 | ||
682 | return 0; | 675 | return 0; |
@@ -702,6 +695,11 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
702 | (rt2x00dev->rx->data_size / 128)); | 695 | (rt2x00dev->rx->data_size / 128)); |
703 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); | 696 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); |
704 | 697 | ||
698 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
699 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
700 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
701 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
702 | |||
705 | rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); | 703 | rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); |
706 | 704 | ||
707 | rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); | 705 | rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); |
@@ -795,19 +793,15 @@ continue_csr_init: | |||
795 | rt2400pci_bbp_write(rt2x00dev, 30, 0x21); | 793 | rt2400pci_bbp_write(rt2x00dev, 30, 0x21); |
796 | rt2400pci_bbp_write(rt2x00dev, 31, 0x00); | 794 | rt2400pci_bbp_write(rt2x00dev, 31, 0x00); |
797 | 795 | ||
798 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
799 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 796 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
800 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 797 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
801 | 798 | ||
802 | if (eeprom != 0xffff && eeprom != 0x0000) { | 799 | if (eeprom != 0xffff && eeprom != 0x0000) { |
803 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 800 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
804 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 801 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
805 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
806 | reg_id, value); | ||
807 | rt2400pci_bbp_write(rt2x00dev, reg_id, value); | 802 | rt2400pci_bbp_write(rt2x00dev, reg_id, value); |
808 | } | 803 | } |
809 | } | 804 | } |
810 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
811 | 805 | ||
812 | return 0; | 806 | return 0; |
813 | } | 807 | } |
@@ -859,7 +853,7 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
859 | /* | 853 | /* |
860 | * Initialize all registers. | 854 | * Initialize all registers. |
861 | */ | 855 | */ |
862 | if (rt2400pci_init_rings(rt2x00dev) || | 856 | if (rt2400pci_init_queues(rt2x00dev) || |
863 | rt2400pci_init_registers(rt2x00dev) || | 857 | rt2400pci_init_registers(rt2x00dev) || |
864 | rt2400pci_init_bbp(rt2x00dev)) { | 858 | rt2400pci_init_bbp(rt2x00dev)) { |
865 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 859 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -871,11 +865,6 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
871 | */ | 865 | */ |
872 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | 866 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); |
873 | 867 | ||
874 | /* | ||
875 | * Enable LED | ||
876 | */ | ||
877 | rt2400pci_enable_led(rt2x00dev); | ||
878 | |||
879 | return 0; | 868 | return 0; |
880 | } | 869 | } |
881 | 870 | ||
@@ -883,11 +872,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
883 | { | 872 | { |
884 | u32 reg; | 873 | u32 reg; |
885 | 874 | ||
886 | /* | ||
887 | * Disable LED | ||
888 | */ | ||
889 | rt2400pci_disable_led(rt2x00dev); | ||
890 | |||
891 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 875 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
892 | 876 | ||
893 | /* | 877 | /* |
@@ -986,10 +970,10 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
986 | */ | 970 | */ |
987 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 971 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
988 | struct sk_buff *skb, | 972 | struct sk_buff *skb, |
989 | struct txdata_entry_desc *desc, | 973 | struct txentry_desc *txdesc, |
990 | struct ieee80211_tx_control *control) | 974 | struct ieee80211_tx_control *control) |
991 | { | 975 | { |
992 | struct skb_desc *skbdesc = get_skb_desc(skb); | 976 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
993 | __le32 *txd = skbdesc->desc; | 977 | __le32 *txd = skbdesc->desc; |
994 | u32 word; | 978 | u32 word; |
995 | 979 | ||
@@ -1001,19 +985,19 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1001 | rt2x00_desc_write(txd, 2, word); | 985 | rt2x00_desc_write(txd, 2, word); |
1002 | 986 | ||
1003 | rt2x00_desc_read(txd, 3, &word); | 987 | rt2x00_desc_read(txd, 3, &word); |
1004 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); | 988 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); |
1005 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); | 989 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); |
1006 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); | 990 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); |
1007 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); | 991 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); |
1008 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); | 992 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); |
1009 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); | 993 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); |
1010 | rt2x00_desc_write(txd, 3, word); | 994 | rt2x00_desc_write(txd, 3, word); |
1011 | 995 | ||
1012 | rt2x00_desc_read(txd, 4, &word); | 996 | rt2x00_desc_read(txd, 4, &word); |
1013 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, desc->length_low); | 997 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, txdesc->length_low); |
1014 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); | 998 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); |
1015 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); | 999 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); |
1016 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, desc->length_high); | 1000 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, txdesc->length_high); |
1017 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); | 1001 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); |
1018 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); | 1002 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); |
1019 | rt2x00_desc_write(txd, 4, word); | 1003 | rt2x00_desc_write(txd, 4, word); |
@@ -1022,14 +1006,14 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1022 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1006 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1023 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1007 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1024 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1008 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1025 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1009 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1026 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1010 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1027 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1011 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1028 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1012 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1029 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1013 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1030 | rt2x00_set_field32(&word, TXD_W0_RTS, | 1014 | rt2x00_set_field32(&word, TXD_W0_RTS, |
1031 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | 1015 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1032 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1016 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1033 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1017 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1034 | !!(control->flags & | 1018 | !!(control->flags & |
1035 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1019 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
@@ -1040,13 +1024,15 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1040 | * TX data initialization | 1024 | * TX data initialization |
1041 | */ | 1025 | */ |
1042 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1026 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1043 | unsigned int queue) | 1027 | const unsigned int queue) |
1044 | { | 1028 | { |
1045 | u32 reg; | 1029 | u32 reg; |
1046 | 1030 | ||
1047 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1031 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1048 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1032 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1049 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1033 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1034 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
1035 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1050 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1036 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
1051 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1037 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1052 | } | 1038 | } |
@@ -1059,56 +1045,61 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1059 | rt2x00_set_field32(®, TXCSR0_KICK_TX, | 1045 | rt2x00_set_field32(®, TXCSR0_KICK_TX, |
1060 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1046 | (queue == IEEE80211_TX_QUEUE_DATA1)); |
1061 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, | 1047 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, |
1062 | (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); | 1048 | (queue == RT2X00_BCN_QUEUE_ATIM)); |
1063 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1049 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1064 | } | 1050 | } |
1065 | 1051 | ||
1066 | /* | 1052 | /* |
1067 | * RX control handlers | 1053 | * RX control handlers |
1068 | */ | 1054 | */ |
1069 | static void rt2400pci_fill_rxdone(struct data_entry *entry, | 1055 | static void rt2400pci_fill_rxdone(struct queue_entry *entry, |
1070 | struct rxdata_entry_desc *desc) | 1056 | struct rxdone_entry_desc *rxdesc) |
1071 | { | 1057 | { |
1072 | __le32 *rxd = entry->priv; | 1058 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1073 | u32 word0; | 1059 | u32 word0; |
1074 | u32 word2; | 1060 | u32 word2; |
1061 | u32 word3; | ||
1075 | 1062 | ||
1076 | rt2x00_desc_read(rxd, 0, &word0); | 1063 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1077 | rt2x00_desc_read(rxd, 2, &word2); | 1064 | rt2x00_desc_read(priv_rx->desc, 2, &word2); |
1065 | rt2x00_desc_read(priv_rx->desc, 3, &word3); | ||
1078 | 1066 | ||
1079 | desc->flags = 0; | 1067 | rxdesc->flags = 0; |
1080 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1068 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1081 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1069 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1082 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1070 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1083 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1071 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1084 | 1072 | ||
1085 | /* | 1073 | /* |
1086 | * Obtain the status about this packet. | 1074 | * Obtain the status about this packet. |
1075 | * The signal is the PLCP value, and needs to be stripped | ||
1076 | * of the preamble bit (0x08). | ||
1087 | */ | 1077 | */ |
1088 | desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | 1078 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08; |
1089 | desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | 1079 | rxdesc->signal_plcp = 1; |
1090 | entry->ring->rt2x00dev->rssi_offset; | 1080 | rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) - |
1091 | desc->ofdm = 0; | 1081 | entry->queue->rt2x00dev->rssi_offset; |
1092 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1082 | rxdesc->ofdm = 0; |
1093 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1083 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1084 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | ||
1094 | } | 1085 | } |
1095 | 1086 | ||
1096 | /* | 1087 | /* |
1097 | * Interrupt functions. | 1088 | * Interrupt functions. |
1098 | */ | 1089 | */ |
1099 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | 1090 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, |
1091 | const enum ieee80211_tx_queue queue_idx) | ||
1100 | { | 1092 | { |
1101 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | 1093 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
1102 | struct data_entry *entry; | 1094 | struct queue_entry_priv_pci_tx *priv_tx; |
1103 | __le32 *txd; | 1095 | struct queue_entry *entry; |
1096 | struct txdone_entry_desc txdesc; | ||
1104 | u32 word; | 1097 | u32 word; |
1105 | int tx_status; | ||
1106 | int retry; | ||
1107 | 1098 | ||
1108 | while (!rt2x00_ring_empty(ring)) { | 1099 | while (!rt2x00queue_empty(queue)) { |
1109 | entry = rt2x00_get_data_entry_done(ring); | 1100 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1110 | txd = entry->priv; | 1101 | priv_tx = entry->priv_data; |
1111 | rt2x00_desc_read(txd, 0, &word); | 1102 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1112 | 1103 | ||
1113 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1104 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1114 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1105 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
@@ -1117,10 +1108,10 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | |||
1117 | /* | 1108 | /* |
1118 | * Obtain the status about this packet. | 1109 | * Obtain the status about this packet. |
1119 | */ | 1110 | */ |
1120 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | 1111 | txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); |
1121 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1112 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1122 | 1113 | ||
1123 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1114 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1124 | } | 1115 | } |
1125 | } | 1116 | } |
1126 | 1117 | ||
@@ -1164,7 +1155,7 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | |||
1164 | * 3 - Atim ring transmit done interrupt. | 1155 | * 3 - Atim ring transmit done interrupt. |
1165 | */ | 1156 | */ |
1166 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | 1157 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) |
1167 | rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | 1158 | rt2400pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); |
1168 | 1159 | ||
1169 | /* | 1160 | /* |
1170 | * 4 - Priority ring transmit done interrupt. | 1161 | * 4 - Priority ring transmit done interrupt. |
@@ -1272,8 +1263,24 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1272 | /* | 1263 | /* |
1273 | * Store led mode, for correct led behaviour. | 1264 | * Store led mode, for correct led behaviour. |
1274 | */ | 1265 | */ |
1275 | rt2x00dev->led_mode = | 1266 | #ifdef CONFIG_RT2400PCI_LEDS |
1276 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1267 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1268 | |||
1269 | switch (value) { | ||
1270 | case LED_MODE_ASUS: | ||
1271 | case LED_MODE_ALPHA: | ||
1272 | case LED_MODE_DEFAULT: | ||
1273 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1274 | break; | ||
1275 | case LED_MODE_TXRX_ACTIVITY: | ||
1276 | rt2x00dev->led_flags = | ||
1277 | LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; | ||
1278 | break; | ||
1279 | case LED_MODE_SIGNAL_STRENGTH: | ||
1280 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1281 | break; | ||
1282 | } | ||
1283 | #endif /* CONFIG_RT2400PCI_LEDS */ | ||
1277 | 1284 | ||
1278 | /* | 1285 | /* |
1279 | * Detect if this device has an hardware controlled radio. | 1286 | * Detect if this device has an hardware controlled radio. |
@@ -1343,8 +1350,8 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1343 | /* | 1350 | /* |
1344 | * Initialize hw_mode information. | 1351 | * Initialize hw_mode information. |
1345 | */ | 1352 | */ |
1346 | spec->num_modes = 1; | 1353 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1347 | spec->num_rates = 4; | 1354 | spec->supported_rates = SUPPORT_RATE_CCK; |
1348 | spec->tx_power_a = NULL; | 1355 | spec->tx_power_a = NULL; |
1349 | spec->tx_power_bg = txpower; | 1356 | spec->tx_power_bg = txpower; |
1350 | spec->tx_power_default = DEFAULT_TXPOWER; | 1357 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1374,9 +1381,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1374 | rt2400pci_probe_hw_mode(rt2x00dev); | 1381 | rt2400pci_probe_hw_mode(rt2x00dev); |
1375 | 1382 | ||
1376 | /* | 1383 | /* |
1377 | * This device requires the beacon ring | 1384 | * This device requires the atim queue |
1378 | */ | 1385 | */ |
1379 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1386 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1380 | 1387 | ||
1381 | /* | 1388 | /* |
1382 | * Set the rssi offset. | 1389 | * Set the rssi offset. |
@@ -1481,7 +1488,8 @@ static int rt2400pci_conf_tx(struct ieee80211_hw *hw, | |||
1481 | /* | 1488 | /* |
1482 | * Write configuration to register. | 1489 | * Write configuration to register. |
1483 | */ | 1490 | */ |
1484 | rt2400pci_config_cw(rt2x00dev, &rt2x00dev->tx->tx_params); | 1491 | rt2400pci_config_cw(rt2x00dev, |
1492 | rt2x00dev->tx->cw_min, rt2x00dev->tx->cw_max); | ||
1485 | 1493 | ||
1486 | return 0; | 1494 | return 0; |
1487 | } | 1495 | } |
@@ -1500,12 +1508,58 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw) | |||
1500 | return tsf; | 1508 | return tsf; |
1501 | } | 1509 | } |
1502 | 1510 | ||
1503 | static void rt2400pci_reset_tsf(struct ieee80211_hw *hw) | 1511 | static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1512 | struct ieee80211_tx_control *control) | ||
1504 | { | 1513 | { |
1505 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1514 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1515 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1516 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1517 | struct skb_frame_desc *skbdesc; | ||
1518 | u32 reg; | ||
1506 | 1519 | ||
1507 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | 1520 | if (unlikely(!intf->beacon)) |
1508 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | 1521 | return -ENOBUFS; |
1522 | priv_tx = intf->beacon->priv_data; | ||
1523 | |||
1524 | /* | ||
1525 | * Fill in skb descriptor | ||
1526 | */ | ||
1527 | skbdesc = get_skb_frame_desc(skb); | ||
1528 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1529 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1530 | skbdesc->data = skb->data; | ||
1531 | skbdesc->data_len = skb->len; | ||
1532 | skbdesc->desc = priv_tx->desc; | ||
1533 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1534 | skbdesc->entry = intf->beacon; | ||
1535 | |||
1536 | /* | ||
1537 | * Disable beaconing while we are reloading the beacon data, | ||
1538 | * otherwise we might be sending out invalid data. | ||
1539 | */ | ||
1540 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1541 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1542 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1543 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1544 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1545 | |||
1546 | /* | ||
1547 | * mac80211 doesn't provide the control->queue variable | ||
1548 | * for beacons. Set our own queue identification so | ||
1549 | * it can be used during descriptor initialization. | ||
1550 | */ | ||
1551 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1552 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
1553 | |||
1554 | /* | ||
1555 | * Enable beacon generation. | ||
1556 | * Write entire beacon with descriptor to register, | ||
1557 | * and kick the beacon generator. | ||
1558 | */ | ||
1559 | memcpy(priv_tx->data, skb->data, skb->len); | ||
1560 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
1561 | |||
1562 | return 0; | ||
1509 | } | 1563 | } |
1510 | 1564 | ||
1511 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) | 1565 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) |
@@ -1532,8 +1586,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { | |||
1532 | .conf_tx = rt2400pci_conf_tx, | 1586 | .conf_tx = rt2400pci_conf_tx, |
1533 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1587 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1534 | .get_tsf = rt2400pci_get_tsf, | 1588 | .get_tsf = rt2400pci_get_tsf, |
1535 | .reset_tsf = rt2400pci_reset_tsf, | 1589 | .beacon_update = rt2400pci_beacon_update, |
1536 | .beacon_update = rt2x00pci_beacon_update, | ||
1537 | .tx_last_beacon = rt2400pci_tx_last_beacon, | 1590 | .tx_last_beacon = rt2400pci_tx_last_beacon, |
1538 | }; | 1591 | }; |
1539 | 1592 | ||
@@ -1549,23 +1602,54 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
1549 | .link_stats = rt2400pci_link_stats, | 1602 | .link_stats = rt2400pci_link_stats, |
1550 | .reset_tuner = rt2400pci_reset_tuner, | 1603 | .reset_tuner = rt2400pci_reset_tuner, |
1551 | .link_tuner = rt2400pci_link_tuner, | 1604 | .link_tuner = rt2400pci_link_tuner, |
1605 | .led_brightness = rt2400pci_led_brightness, | ||
1552 | .write_tx_desc = rt2400pci_write_tx_desc, | 1606 | .write_tx_desc = rt2400pci_write_tx_desc, |
1553 | .write_tx_data = rt2x00pci_write_tx_data, | 1607 | .write_tx_data = rt2x00pci_write_tx_data, |
1554 | .kick_tx_queue = rt2400pci_kick_tx_queue, | 1608 | .kick_tx_queue = rt2400pci_kick_tx_queue, |
1555 | .fill_rxdone = rt2400pci_fill_rxdone, | 1609 | .fill_rxdone = rt2400pci_fill_rxdone, |
1556 | .config_mac_addr = rt2400pci_config_mac_addr, | 1610 | .config_intf = rt2400pci_config_intf, |
1557 | .config_bssid = rt2400pci_config_bssid, | 1611 | .config_erp = rt2400pci_config_erp, |
1558 | .config_type = rt2400pci_config_type, | ||
1559 | .config_preamble = rt2400pci_config_preamble, | ||
1560 | .config = rt2400pci_config, | 1612 | .config = rt2400pci_config, |
1561 | }; | 1613 | }; |
1562 | 1614 | ||
1615 | static const struct data_queue_desc rt2400pci_queue_rx = { | ||
1616 | .entry_num = RX_ENTRIES, | ||
1617 | .data_size = DATA_FRAME_SIZE, | ||
1618 | .desc_size = RXD_DESC_SIZE, | ||
1619 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
1620 | }; | ||
1621 | |||
1622 | static const struct data_queue_desc rt2400pci_queue_tx = { | ||
1623 | .entry_num = TX_ENTRIES, | ||
1624 | .data_size = DATA_FRAME_SIZE, | ||
1625 | .desc_size = TXD_DESC_SIZE, | ||
1626 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1627 | }; | ||
1628 | |||
1629 | static const struct data_queue_desc rt2400pci_queue_bcn = { | ||
1630 | .entry_num = BEACON_ENTRIES, | ||
1631 | .data_size = MGMT_FRAME_SIZE, | ||
1632 | .desc_size = TXD_DESC_SIZE, | ||
1633 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1634 | }; | ||
1635 | |||
1636 | static const struct data_queue_desc rt2400pci_queue_atim = { | ||
1637 | .entry_num = ATIM_ENTRIES, | ||
1638 | .data_size = DATA_FRAME_SIZE, | ||
1639 | .desc_size = TXD_DESC_SIZE, | ||
1640 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1641 | }; | ||
1642 | |||
1563 | static const struct rt2x00_ops rt2400pci_ops = { | 1643 | static const struct rt2x00_ops rt2400pci_ops = { |
1564 | .name = KBUILD_MODNAME, | 1644 | .name = KBUILD_MODNAME, |
1565 | .rxd_size = RXD_DESC_SIZE, | 1645 | .max_sta_intf = 1, |
1566 | .txd_size = TXD_DESC_SIZE, | 1646 | .max_ap_intf = 1, |
1567 | .eeprom_size = EEPROM_SIZE, | 1647 | .eeprom_size = EEPROM_SIZE, |
1568 | .rf_size = RF_SIZE, | 1648 | .rf_size = RF_SIZE, |
1649 | .rx = &rt2400pci_queue_rx, | ||
1650 | .tx = &rt2400pci_queue_tx, | ||
1651 | .bcn = &rt2400pci_queue_bcn, | ||
1652 | .atim = &rt2400pci_queue_atim, | ||
1569 | .lib = &rt2400pci_rt2x00_ops, | 1653 | .lib = &rt2400pci_rt2x00_ops, |
1570 | .hw = &rt2400pci_mac80211_ops, | 1654 | .hw = &rt2400pci_mac80211_ops, |
1571 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1655 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index 369aac6d0336..a5210f9a3360 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -899,13 +899,13 @@ | |||
899 | * Word2 | 899 | * Word2 |
900 | */ | 900 | */ |
901 | #define RXD_W2_BUFFER_LENGTH FIELD32(0x0000ffff) | 901 | #define RXD_W2_BUFFER_LENGTH FIELD32(0x0000ffff) |
902 | #define RXD_W2_SIGNAL FIELD32(0x00ff0000) | 902 | #define RXD_W2_BBR0 FIELD32(0x00ff0000) |
903 | #define RXD_W2_RSSI FIELD32(0xff000000) | 903 | #define RXD_W2_SIGNAL FIELD32(0xff000000) |
904 | 904 | ||
905 | /* | 905 | /* |
906 | * Word3 | 906 | * Word3 |
907 | */ | 907 | */ |
908 | #define RXD_W3_BBR2 FIELD32(0x000000ff) | 908 | #define RXD_W3_RSSI FIELD32(0x000000ff) |
909 | #define RXD_W3_BBR3 FIELD32(0x0000ff00) | 909 | #define RXD_W3_BBR3 FIELD32(0x0000ff00) |
910 | #define RXD_W3_BBR4 FIELD32(0x00ff0000) | 910 | #define RXD_W3_BBR4 FIELD32(0x00ff0000) |
911 | #define RXD_W3_BBR5 FIELD32(0xff000000) | 911 | #define RXD_W3_BBR5 FIELD32(0xff000000) |
@@ -923,13 +923,13 @@ | |||
923 | #define RXD_W7_RESERVED FIELD32(0xffffffff) | 923 | #define RXD_W7_RESERVED FIELD32(0xffffffff) |
924 | 924 | ||
925 | /* | 925 | /* |
926 | * Macro's for converting txpower from EEPROM to dscape value | 926 | * Macro's for converting txpower from EEPROM to mac80211 value |
927 | * and from dscape value to register value. | 927 | * and from mac80211 value to register value. |
928 | * NOTE: Logics in rt2400pci for txpower are reversed | 928 | * NOTE: Logics in rt2400pci for txpower are reversed |
929 | * compared to the other rt2x00 drivers. A higher txpower | 929 | * compared to the other rt2x00 drivers. A higher txpower |
930 | * value means that the txpower must be lowered. This is | 930 | * value means that the txpower must be lowered. This is |
931 | * important when converting the value coming from the | 931 | * important when converting the value coming from the |
932 | * dscape stack to the rt2400 acceptable value. | 932 | * mac80211 stack to the rt2400 acceptable value. |
933 | */ | 933 | */ |
934 | #define MIN_TXPOWER 31 | 934 | #define MIN_TXPOWER 31 |
935 | #define MAX_TXPOWER 62 | 935 | #define MAX_TXPOWER 62 |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 91e87b53374f..0f5139a2f238 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -243,57 +243,74 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
243 | #define rt2500pci_rfkill_poll NULL | 243 | #define rt2500pci_rfkill_poll NULL |
244 | #endif /* CONFIG_RT2500PCI_RFKILL */ | 244 | #endif /* CONFIG_RT2500PCI_RFKILL */ |
245 | 245 | ||
246 | /* | 246 | #ifdef CONFIG_RT2500PCI_LEDS |
247 | * Configuration handlers. | 247 | static void rt2500pci_led_brightness(struct led_classdev *led_cdev, |
248 | */ | 248 | enum led_brightness brightness) |
249 | static void rt2500pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, | ||
250 | __le32 *mac) | ||
251 | { | 249 | { |
252 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, mac, | 250 | struct rt2x00_led *led = |
253 | (2 * sizeof(__le32))); | 251 | container_of(led_cdev, struct rt2x00_led, led_dev); |
254 | } | 252 | unsigned int enabled = brightness != LED_OFF; |
253 | unsigned int activity = | ||
254 | led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; | ||
255 | u32 reg; | ||
255 | 256 | ||
256 | static void rt2500pci_config_bssid(struct rt2x00_dev *rt2x00dev, | 257 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); |
257 | __le32 *bssid) | 258 | |
258 | { | 259 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { |
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | 260 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); |
260 | (2 * sizeof(__le32))); | 261 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled && activity); |
262 | } | ||
263 | |||
264 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
261 | } | 265 | } |
266 | #else | ||
267 | #define rt2500pci_led_brightness NULL | ||
268 | #endif /* CONFIG_RT2500PCI_LEDS */ | ||
262 | 269 | ||
263 | static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 270 | /* |
264 | const int tsf_sync) | 271 | * Configuration handlers. |
272 | */ | ||
273 | static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, | ||
274 | struct rt2x00_intf *intf, | ||
275 | struct rt2x00intf_conf *conf, | ||
276 | const unsigned int flags) | ||
265 | { | 277 | { |
278 | struct data_queue *queue = | ||
279 | rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON); | ||
280 | unsigned int bcn_preload; | ||
266 | u32 reg; | 281 | u32 reg; |
267 | 282 | ||
268 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 283 | if (flags & CONFIG_UPDATE_TYPE) { |
284 | /* | ||
285 | * Enable beacon config | ||
286 | */ | ||
287 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); | ||
288 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | ||
289 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | ||
290 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); | ||
291 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
269 | 292 | ||
270 | /* | 293 | /* |
271 | * Enable beacon config | 294 | * Enable synchronisation. |
272 | */ | 295 | */ |
273 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 296 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
274 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | 297 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
275 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | 298 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
276 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, | 299 | rt2x00_set_field32(®, CSR14_TBCN, 1); |
277 | rt2x00lib_get_ring(rt2x00dev, | 300 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
278 | IEEE80211_TX_QUEUE_BEACON) | 301 | } |
279 | ->tx_params.cw_min); | ||
280 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
281 | 302 | ||
282 | /* | 303 | if (flags & CONFIG_UPDATE_MAC) |
283 | * Enable synchronisation. | 304 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, |
284 | */ | 305 | conf->mac, sizeof(conf->mac)); |
285 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 306 | |
286 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 307 | if (flags & CONFIG_UPDATE_BSSID) |
287 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | 308 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, |
288 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 309 | conf->bssid, sizeof(conf->bssid)); |
289 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | ||
290 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
291 | } | 310 | } |
292 | 311 | ||
293 | static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 312 | static int rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, |
294 | const int short_preamble, | 313 | struct rt2x00lib_erp *erp) |
295 | const int ack_timeout, | ||
296 | const int ack_consume_time) | ||
297 | { | 314 | { |
298 | int preamble_mask; | 315 | int preamble_mask; |
299 | u32 reg; | 316 | u32 reg; |
@@ -301,11 +318,13 @@ static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
301 | /* | 318 | /* |
302 | * When short preamble is enabled, we should set bit 0x08 | 319 | * When short preamble is enabled, we should set bit 0x08 |
303 | */ | 320 | */ |
304 | preamble_mask = short_preamble << 3; | 321 | preamble_mask = erp->short_preamble << 3; |
305 | 322 | ||
306 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | 323 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); |
307 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, ack_timeout); | 324 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, |
308 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, ack_consume_time); | 325 | erp->ack_timeout); |
326 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, | ||
327 | erp->ack_consume_time); | ||
309 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 328 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); |
310 | 329 | ||
311 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 330 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
@@ -331,6 +350,8 @@ static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
331 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 350 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
332 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 351 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); |
333 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 352 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); |
353 | |||
354 | return 0; | ||
334 | } | 355 | } |
335 | 356 | ||
336 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 357 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -425,6 +446,13 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
425 | u8 r14; | 446 | u8 r14; |
426 | u8 r2; | 447 | u8 r2; |
427 | 448 | ||
449 | /* | ||
450 | * We should never come here because rt2x00lib is supposed | ||
451 | * to catch this and send us the correct antenna explicitely. | ||
452 | */ | ||
453 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
454 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
455 | |||
428 | rt2x00pci_register_read(rt2x00dev, BBPCSR1, ®); | 456 | rt2x00pci_register_read(rt2x00dev, BBPCSR1, ®); |
429 | rt2500pci_bbp_read(rt2x00dev, 14, &r14); | 457 | rt2500pci_bbp_read(rt2x00dev, 14, &r14); |
430 | rt2500pci_bbp_read(rt2x00dev, 2, &r2); | 458 | rt2500pci_bbp_read(rt2x00dev, 2, &r2); |
@@ -438,15 +466,8 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
438 | rt2x00_set_field32(®, BBPCSR1_CCK, 0); | 466 | rt2x00_set_field32(®, BBPCSR1_CCK, 0); |
439 | rt2x00_set_field32(®, BBPCSR1_OFDM, 0); | 467 | rt2x00_set_field32(®, BBPCSR1_OFDM, 0); |
440 | break; | 468 | break; |
441 | case ANTENNA_HW_DIVERSITY: | ||
442 | case ANTENNA_SW_DIVERSITY: | ||
443 | /* | ||
444 | * NOTE: We should never come here because rt2x00lib is | ||
445 | * supposed to catch this and send us the correct antenna | ||
446 | * explicitely. However we are nog going to bug about this. | ||
447 | * Instead, just default to antenna B. | ||
448 | */ | ||
449 | case ANTENNA_B: | 469 | case ANTENNA_B: |
470 | default: | ||
450 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); | 471 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); |
451 | rt2x00_set_field32(®, BBPCSR1_CCK, 2); | 472 | rt2x00_set_field32(®, BBPCSR1_CCK, 2); |
452 | rt2x00_set_field32(®, BBPCSR1_OFDM, 2); | 473 | rt2x00_set_field32(®, BBPCSR1_OFDM, 2); |
@@ -460,15 +481,8 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
460 | case ANTENNA_A: | 481 | case ANTENNA_A: |
461 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); | 482 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); |
462 | break; | 483 | break; |
463 | case ANTENNA_HW_DIVERSITY: | ||
464 | case ANTENNA_SW_DIVERSITY: | ||
465 | /* | ||
466 | * NOTE: We should never come here because rt2x00lib is | ||
467 | * supposed to catch this and send us the correct antenna | ||
468 | * explicitely. However we are nog going to bug about this. | ||
469 | * Instead, just default to antenna B. | ||
470 | */ | ||
471 | case ANTENNA_B: | 484 | case ANTENNA_B: |
485 | default: | ||
472 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); | 486 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); |
473 | break; | 487 | break; |
474 | } | 488 | } |
@@ -530,8 +544,8 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
530 | } | 544 | } |
531 | 545 | ||
532 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | 546 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, |
533 | const unsigned int flags, | 547 | struct rt2x00lib_conf *libconf, |
534 | struct rt2x00lib_conf *libconf) | 548 | const unsigned int flags) |
535 | { | 549 | { |
536 | if (flags & CONFIG_UPDATE_PHYMODE) | 550 | if (flags & CONFIG_UPDATE_PHYMODE) |
537 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); | 551 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -548,34 +562,6 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | |||
548 | } | 562 | } |
549 | 563 | ||
550 | /* | 564 | /* |
551 | * LED functions. | ||
552 | */ | ||
553 | static void rt2500pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
554 | { | ||
555 | u32 reg; | ||
556 | |||
557 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
558 | |||
559 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
560 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
561 | rt2x00_set_field32(®, LEDCSR_LINK, | ||
562 | (rt2x00dev->led_mode != LED_MODE_ASUS)); | ||
563 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, | ||
564 | (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); | ||
565 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
566 | } | ||
567 | |||
568 | static void rt2500pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
569 | { | ||
570 | u32 reg; | ||
571 | |||
572 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
573 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
574 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
575 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
576 | } | ||
577 | |||
578 | /* | ||
579 | * Link tuning | 565 | * Link tuning |
580 | */ | 566 | */ |
581 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, | 567 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -610,9 +596,10 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
610 | /* | 596 | /* |
611 | * To prevent collisions with MAC ASIC on chipsets | 597 | * To prevent collisions with MAC ASIC on chipsets |
612 | * up to version C the link tuning should halt after 20 | 598 | * up to version C the link tuning should halt after 20 |
613 | * seconds. | 599 | * seconds while being associated. |
614 | */ | 600 | */ |
615 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && | 601 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && |
602 | rt2x00dev->intf_associated && | ||
616 | rt2x00dev->link.count > 20) | 603 | rt2x00dev->link.count > 20) |
617 | return; | 604 | return; |
618 | 605 | ||
@@ -620,9 +607,12 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
620 | 607 | ||
621 | /* | 608 | /* |
622 | * Chipset versions C and lower should directly continue | 609 | * Chipset versions C and lower should directly continue |
623 | * to the dynamic CCA tuning. | 610 | * to the dynamic CCA tuning. Chipset version D and higher |
611 | * should go straight to dynamic CCA tuning when they | ||
612 | * are not associated. | ||
624 | */ | 613 | */ |
625 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D) | 614 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D || |
615 | !rt2x00dev->intf_associated) | ||
626 | goto dynamic_cca_tune; | 616 | goto dynamic_cca_tune; |
627 | 617 | ||
628 | /* | 618 | /* |
@@ -684,82 +674,84 @@ dynamic_cca_tune: | |||
684 | * Initialization functions. | 674 | * Initialization functions. |
685 | */ | 675 | */ |
686 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 676 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
687 | struct data_entry *entry) | 677 | struct queue_entry *entry) |
688 | { | 678 | { |
689 | __le32 *rxd = entry->priv; | 679 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
690 | u32 word; | 680 | u32 word; |
691 | 681 | ||
692 | rt2x00_desc_read(rxd, 1, &word); | 682 | rt2x00_desc_read(priv_rx->desc, 1, &word); |
693 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma); | 683 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); |
694 | rt2x00_desc_write(rxd, 1, word); | 684 | rt2x00_desc_write(priv_rx->desc, 1, word); |
695 | 685 | ||
696 | rt2x00_desc_read(rxd, 0, &word); | 686 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
697 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 687 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
698 | rt2x00_desc_write(rxd, 0, word); | 688 | rt2x00_desc_write(priv_rx->desc, 0, word); |
699 | } | 689 | } |
700 | 690 | ||
701 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 691 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
702 | struct data_entry *entry) | 692 | struct queue_entry *entry) |
703 | { | 693 | { |
704 | __le32 *txd = entry->priv; | 694 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
705 | u32 word; | 695 | u32 word; |
706 | 696 | ||
707 | rt2x00_desc_read(txd, 1, &word); | 697 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
708 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma); | 698 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma); |
709 | rt2x00_desc_write(txd, 1, word); | 699 | rt2x00_desc_write(priv_tx->desc, 1, word); |
710 | 700 | ||
711 | rt2x00_desc_read(txd, 0, &word); | 701 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
712 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 702 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
713 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 703 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
714 | rt2x00_desc_write(txd, 0, word); | 704 | rt2x00_desc_write(priv_tx->desc, 0, word); |
715 | } | 705 | } |
716 | 706 | ||
717 | static int rt2500pci_init_rings(struct rt2x00_dev *rt2x00dev) | 707 | static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) |
718 | { | 708 | { |
709 | struct queue_entry_priv_pci_rx *priv_rx; | ||
710 | struct queue_entry_priv_pci_tx *priv_tx; | ||
719 | u32 reg; | 711 | u32 reg; |
720 | 712 | ||
721 | /* | 713 | /* |
722 | * Initialize registers. | 714 | * Initialize registers. |
723 | */ | 715 | */ |
724 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 716 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
725 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | 717 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
726 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | 718 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
727 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | 719 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); |
728 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 720 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
729 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, | ||
730 | rt2x00dev->bcn[1].stats.limit); | ||
731 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, | ||
732 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
733 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 721 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
734 | 722 | ||
723 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
735 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 724 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); |
736 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 725 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
737 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 726 | priv_tx->desc_dma); |
738 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 727 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); |
739 | 728 | ||
729 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
740 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 730 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); |
741 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 731 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
742 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 732 | priv_tx->desc_dma); |
743 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 733 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
744 | 734 | ||
735 | priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; | ||
745 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 736 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
746 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 737 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
747 | rt2x00dev->bcn[1].data_dma); | 738 | priv_tx->desc_dma); |
748 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 739 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
749 | 740 | ||
741 | priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; | ||
750 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 742 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
751 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 743 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
752 | rt2x00dev->bcn[0].data_dma); | 744 | priv_tx->desc_dma); |
753 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 745 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); |
754 | 746 | ||
755 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 747 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); |
756 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 748 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
757 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | 749 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
758 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 750 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); |
759 | 751 | ||
752 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
760 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 753 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); |
761 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 754 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma); |
762 | rt2x00dev->rx->data_dma); | ||
763 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 755 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); |
764 | 756 | ||
765 | return 0; | 757 | return 0; |
@@ -792,6 +784,11 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
792 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); | 784 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); |
793 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 785 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); |
794 | 786 | ||
787 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
788 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
789 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
790 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
791 | |||
795 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); | 792 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); |
796 | 793 | ||
797 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); | 794 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); |
@@ -947,19 +944,15 @@ continue_csr_init: | |||
947 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); | 944 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); |
948 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); | 945 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); |
949 | 946 | ||
950 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
951 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 947 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
952 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 948 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
953 | 949 | ||
954 | if (eeprom != 0xffff && eeprom != 0x0000) { | 950 | if (eeprom != 0xffff && eeprom != 0x0000) { |
955 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 951 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
956 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 952 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
957 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
958 | reg_id, value); | ||
959 | rt2500pci_bbp_write(rt2x00dev, reg_id, value); | 953 | rt2500pci_bbp_write(rt2x00dev, reg_id, value); |
960 | } | 954 | } |
961 | } | 955 | } |
962 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
963 | 956 | ||
964 | return 0; | 957 | return 0; |
965 | } | 958 | } |
@@ -1011,7 +1004,7 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1011 | /* | 1004 | /* |
1012 | * Initialize all registers. | 1005 | * Initialize all registers. |
1013 | */ | 1006 | */ |
1014 | if (rt2500pci_init_rings(rt2x00dev) || | 1007 | if (rt2500pci_init_queues(rt2x00dev) || |
1015 | rt2500pci_init_registers(rt2x00dev) || | 1008 | rt2500pci_init_registers(rt2x00dev) || |
1016 | rt2500pci_init_bbp(rt2x00dev)) { | 1009 | rt2500pci_init_bbp(rt2x00dev)) { |
1017 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 1010 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -1023,11 +1016,6 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1023 | */ | 1016 | */ |
1024 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | 1017 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); |
1025 | 1018 | ||
1026 | /* | ||
1027 | * Enable LED | ||
1028 | */ | ||
1029 | rt2500pci_enable_led(rt2x00dev); | ||
1030 | |||
1031 | return 0; | 1019 | return 0; |
1032 | } | 1020 | } |
1033 | 1021 | ||
@@ -1035,11 +1023,6 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1035 | { | 1023 | { |
1036 | u32 reg; | 1024 | u32 reg; |
1037 | 1025 | ||
1038 | /* | ||
1039 | * Disable LED | ||
1040 | */ | ||
1041 | rt2500pci_disable_led(rt2x00dev); | ||
1042 | |||
1043 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 1026 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
1044 | 1027 | ||
1045 | /* | 1028 | /* |
@@ -1138,10 +1121,10 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1138 | */ | 1121 | */ |
1139 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1122 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1140 | struct sk_buff *skb, | 1123 | struct sk_buff *skb, |
1141 | struct txdata_entry_desc *desc, | 1124 | struct txentry_desc *txdesc, |
1142 | struct ieee80211_tx_control *control) | 1125 | struct ieee80211_tx_control *control) |
1143 | { | 1126 | { |
1144 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1127 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1145 | __le32 *txd = skbdesc->desc; | 1128 | __le32 *txd = skbdesc->desc; |
1146 | u32 word; | 1129 | u32 word; |
1147 | 1130 | ||
@@ -1150,36 +1133,36 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1150 | */ | 1133 | */ |
1151 | rt2x00_desc_read(txd, 2, &word); | 1134 | rt2x00_desc_read(txd, 2, &word); |
1152 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); | 1135 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); |
1153 | rt2x00_set_field32(&word, TXD_W2_AIFS, desc->aifs); | 1136 | rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs); |
1154 | rt2x00_set_field32(&word, TXD_W2_CWMIN, desc->cw_min); | 1137 | rt2x00_set_field32(&word, TXD_W2_CWMIN, txdesc->cw_min); |
1155 | rt2x00_set_field32(&word, TXD_W2_CWMAX, desc->cw_max); | 1138 | rt2x00_set_field32(&word, TXD_W2_CWMAX, txdesc->cw_max); |
1156 | rt2x00_desc_write(txd, 2, word); | 1139 | rt2x00_desc_write(txd, 2, word); |
1157 | 1140 | ||
1158 | rt2x00_desc_read(txd, 3, &word); | 1141 | rt2x00_desc_read(txd, 3, &word); |
1159 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); | 1142 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); |
1160 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); | 1143 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); |
1161 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, desc->length_low); | 1144 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, txdesc->length_low); |
1162 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, desc->length_high); | 1145 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, txdesc->length_high); |
1163 | rt2x00_desc_write(txd, 3, word); | 1146 | rt2x00_desc_write(txd, 3, word); |
1164 | 1147 | ||
1165 | rt2x00_desc_read(txd, 10, &word); | 1148 | rt2x00_desc_read(txd, 10, &word); |
1166 | rt2x00_set_field32(&word, TXD_W10_RTS, | 1149 | rt2x00_set_field32(&word, TXD_W10_RTS, |
1167 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | 1150 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1168 | rt2x00_desc_write(txd, 10, word); | 1151 | rt2x00_desc_write(txd, 10, word); |
1169 | 1152 | ||
1170 | rt2x00_desc_read(txd, 0, &word); | 1153 | rt2x00_desc_read(txd, 0, &word); |
1171 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1154 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1172 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1155 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1173 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1156 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1174 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1157 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1175 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1158 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1176 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1159 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1177 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1160 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1178 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1161 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1179 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1162 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1180 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1163 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1181 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); | 1164 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); |
1182 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1165 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1183 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1166 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1184 | !!(control->flags & | 1167 | !!(control->flags & |
1185 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1168 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
@@ -1192,13 +1175,15 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1192 | * TX data initialization | 1175 | * TX data initialization |
1193 | */ | 1176 | */ |
1194 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1177 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1195 | unsigned int queue) | 1178 | const unsigned int queue) |
1196 | { | 1179 | { |
1197 | u32 reg; | 1180 | u32 reg; |
1198 | 1181 | ||
1199 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1182 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1200 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1183 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1201 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1184 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1185 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
1186 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1202 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1187 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
1203 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1188 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1204 | } | 1189 | } |
@@ -1211,53 +1196,60 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1211 | rt2x00_set_field32(®, TXCSR0_KICK_TX, | 1196 | rt2x00_set_field32(®, TXCSR0_KICK_TX, |
1212 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1197 | (queue == IEEE80211_TX_QUEUE_DATA1)); |
1213 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, | 1198 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, |
1214 | (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); | 1199 | (queue == RT2X00_BCN_QUEUE_ATIM)); |
1215 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1200 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1216 | } | 1201 | } |
1217 | 1202 | ||
1218 | /* | 1203 | /* |
1219 | * RX control handlers | 1204 | * RX control handlers |
1220 | */ | 1205 | */ |
1221 | static void rt2500pci_fill_rxdone(struct data_entry *entry, | 1206 | static void rt2500pci_fill_rxdone(struct queue_entry *entry, |
1222 | struct rxdata_entry_desc *desc) | 1207 | struct rxdone_entry_desc *rxdesc) |
1223 | { | 1208 | { |
1224 | __le32 *rxd = entry->priv; | 1209 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1225 | u32 word0; | 1210 | u32 word0; |
1226 | u32 word2; | 1211 | u32 word2; |
1227 | 1212 | ||
1228 | rt2x00_desc_read(rxd, 0, &word0); | 1213 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1229 | rt2x00_desc_read(rxd, 2, &word2); | 1214 | rt2x00_desc_read(priv_rx->desc, 2, &word2); |
1230 | 1215 | ||
1231 | desc->flags = 0; | 1216 | rxdesc->flags = 0; |
1232 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1217 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1233 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1218 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1234 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1219 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1235 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1220 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1236 | 1221 | ||
1237 | desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | 1222 | /* |
1238 | desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | 1223 | * Obtain the status about this packet. |
1239 | entry->ring->rt2x00dev->rssi_offset; | 1224 | * When frame was received with an OFDM bitrate, |
1240 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1225 | * the signal is the PLCP value. If it was received with |
1241 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1226 | * a CCK bitrate the signal is the rate in 100kbit/s. |
1242 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1227 | */ |
1228 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | ||
1229 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | ||
1230 | rxdesc->signal_plcp = rxdesc->ofdm; | ||
1231 | rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | ||
1232 | entry->queue->rt2x00dev->rssi_offset; | ||
1233 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
1234 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | ||
1243 | } | 1235 | } |
1244 | 1236 | ||
1245 | /* | 1237 | /* |
1246 | * Interrupt functions. | 1238 | * Interrupt functions. |
1247 | */ | 1239 | */ |
1248 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | 1240 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, |
1241 | const enum ieee80211_tx_queue queue_idx) | ||
1249 | { | 1242 | { |
1250 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | 1243 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
1251 | struct data_entry *entry; | 1244 | struct queue_entry_priv_pci_tx *priv_tx; |
1252 | __le32 *txd; | 1245 | struct queue_entry *entry; |
1246 | struct txdone_entry_desc txdesc; | ||
1253 | u32 word; | 1247 | u32 word; |
1254 | int tx_status; | ||
1255 | int retry; | ||
1256 | 1248 | ||
1257 | while (!rt2x00_ring_empty(ring)) { | 1249 | while (!rt2x00queue_empty(queue)) { |
1258 | entry = rt2x00_get_data_entry_done(ring); | 1250 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1259 | txd = entry->priv; | 1251 | priv_tx = entry->priv_data; |
1260 | rt2x00_desc_read(txd, 0, &word); | 1252 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1261 | 1253 | ||
1262 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1254 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1263 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1255 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
@@ -1266,10 +1258,10 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | |||
1266 | /* | 1258 | /* |
1267 | * Obtain the status about this packet. | 1259 | * Obtain the status about this packet. |
1268 | */ | 1260 | */ |
1269 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | 1261 | txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); |
1270 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1262 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1271 | 1263 | ||
1272 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1264 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1273 | } | 1265 | } |
1274 | } | 1266 | } |
1275 | 1267 | ||
@@ -1313,7 +1305,7 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) | |||
1313 | * 3 - Atim ring transmit done interrupt. | 1305 | * 3 - Atim ring transmit done interrupt. |
1314 | */ | 1306 | */ |
1315 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | 1307 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) |
1316 | rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | 1308 | rt2500pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); |
1317 | 1309 | ||
1318 | /* | 1310 | /* |
1319 | * 4 - Priority ring transmit done interrupt. | 1311 | * 4 - Priority ring transmit done interrupt. |
@@ -1442,8 +1434,24 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1442 | /* | 1434 | /* |
1443 | * Store led mode, for correct led behaviour. | 1435 | * Store led mode, for correct led behaviour. |
1444 | */ | 1436 | */ |
1445 | rt2x00dev->led_mode = | 1437 | #ifdef CONFIG_RT2500PCI_LEDS |
1446 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1438 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1439 | |||
1440 | switch (value) { | ||
1441 | case LED_MODE_ASUS: | ||
1442 | case LED_MODE_ALPHA: | ||
1443 | case LED_MODE_DEFAULT: | ||
1444 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1445 | break; | ||
1446 | case LED_MODE_TXRX_ACTIVITY: | ||
1447 | rt2x00dev->led_flags = | ||
1448 | LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; | ||
1449 | break; | ||
1450 | case LED_MODE_SIGNAL_STRENGTH: | ||
1451 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1452 | break; | ||
1453 | } | ||
1454 | #endif /* CONFIG_RT2500PCI_LEDS */ | ||
1447 | 1455 | ||
1448 | /* | 1456 | /* |
1449 | * Detect if this device has an hardware controlled radio. | 1457 | * Detect if this device has an hardware controlled radio. |
@@ -1656,8 +1664,8 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1656 | /* | 1664 | /* |
1657 | * Initialize hw_mode information. | 1665 | * Initialize hw_mode information. |
1658 | */ | 1666 | */ |
1659 | spec->num_modes = 2; | 1667 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1660 | spec->num_rates = 12; | 1668 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1661 | spec->tx_power_a = NULL; | 1669 | spec->tx_power_a = NULL; |
1662 | spec->tx_power_bg = txpower; | 1670 | spec->tx_power_bg = txpower; |
1663 | spec->tx_power_default = DEFAULT_TXPOWER; | 1671 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1678,9 +1686,9 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1678 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | 1686 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); |
1679 | spec->channels = rf_vals_bg_2525e; | 1687 | spec->channels = rf_vals_bg_2525e; |
1680 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | 1688 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { |
1689 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1681 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | 1690 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); |
1682 | spec->channels = rf_vals_5222; | 1691 | spec->channels = rf_vals_5222; |
1683 | spec->num_modes = 3; | ||
1684 | } | 1692 | } |
1685 | } | 1693 | } |
1686 | 1694 | ||
@@ -1705,9 +1713,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1705 | rt2500pci_probe_hw_mode(rt2x00dev); | 1713 | rt2500pci_probe_hw_mode(rt2x00dev); |
1706 | 1714 | ||
1707 | /* | 1715 | /* |
1708 | * This device requires the beacon ring | 1716 | * This device requires the atim queue |
1709 | */ | 1717 | */ |
1710 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1718 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1711 | 1719 | ||
1712 | /* | 1720 | /* |
1713 | * Set the rssi offset. | 1721 | * Set the rssi offset. |
@@ -1811,12 +1819,59 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) | |||
1811 | return tsf; | 1819 | return tsf; |
1812 | } | 1820 | } |
1813 | 1821 | ||
1814 | static void rt2500pci_reset_tsf(struct ieee80211_hw *hw) | 1822 | static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1823 | struct ieee80211_tx_control *control) | ||
1815 | { | 1824 | { |
1816 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1825 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1826 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1827 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1828 | struct skb_frame_desc *skbdesc; | ||
1829 | u32 reg; | ||
1817 | 1830 | ||
1818 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | 1831 | if (unlikely(!intf->beacon)) |
1819 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | 1832 | return -ENOBUFS; |
1833 | |||
1834 | priv_tx = intf->beacon->priv_data; | ||
1835 | |||
1836 | /* | ||
1837 | * Fill in skb descriptor | ||
1838 | */ | ||
1839 | skbdesc = get_skb_frame_desc(skb); | ||
1840 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1841 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1842 | skbdesc->data = skb->data; | ||
1843 | skbdesc->data_len = skb->len; | ||
1844 | skbdesc->desc = priv_tx->desc; | ||
1845 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1846 | skbdesc->entry = intf->beacon; | ||
1847 | |||
1848 | /* | ||
1849 | * Disable beaconing while we are reloading the beacon data, | ||
1850 | * otherwise we might be sending out invalid data. | ||
1851 | */ | ||
1852 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1853 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1854 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1855 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1856 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1857 | |||
1858 | /* | ||
1859 | * mac80211 doesn't provide the control->queue variable | ||
1860 | * for beacons. Set our own queue identification so | ||
1861 | * it can be used during descriptor initialization. | ||
1862 | */ | ||
1863 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1864 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
1865 | |||
1866 | /* | ||
1867 | * Enable beacon generation. | ||
1868 | * Write entire beacon with descriptor to register, | ||
1869 | * and kick the beacon generator. | ||
1870 | */ | ||
1871 | memcpy(priv_tx->data, skb->data, skb->len); | ||
1872 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
1873 | |||
1874 | return 0; | ||
1820 | } | 1875 | } |
1821 | 1876 | ||
1822 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) | 1877 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) |
@@ -1843,8 +1898,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { | |||
1843 | .conf_tx = rt2x00mac_conf_tx, | 1898 | .conf_tx = rt2x00mac_conf_tx, |
1844 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1899 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1845 | .get_tsf = rt2500pci_get_tsf, | 1900 | .get_tsf = rt2500pci_get_tsf, |
1846 | .reset_tsf = rt2500pci_reset_tsf, | 1901 | .beacon_update = rt2500pci_beacon_update, |
1847 | .beacon_update = rt2x00pci_beacon_update, | ||
1848 | .tx_last_beacon = rt2500pci_tx_last_beacon, | 1902 | .tx_last_beacon = rt2500pci_tx_last_beacon, |
1849 | }; | 1903 | }; |
1850 | 1904 | ||
@@ -1860,23 +1914,54 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
1860 | .link_stats = rt2500pci_link_stats, | 1914 | .link_stats = rt2500pci_link_stats, |
1861 | .reset_tuner = rt2500pci_reset_tuner, | 1915 | .reset_tuner = rt2500pci_reset_tuner, |
1862 | .link_tuner = rt2500pci_link_tuner, | 1916 | .link_tuner = rt2500pci_link_tuner, |
1917 | .led_brightness = rt2500pci_led_brightness, | ||
1863 | .write_tx_desc = rt2500pci_write_tx_desc, | 1918 | .write_tx_desc = rt2500pci_write_tx_desc, |
1864 | .write_tx_data = rt2x00pci_write_tx_data, | 1919 | .write_tx_data = rt2x00pci_write_tx_data, |
1865 | .kick_tx_queue = rt2500pci_kick_tx_queue, | 1920 | .kick_tx_queue = rt2500pci_kick_tx_queue, |
1866 | .fill_rxdone = rt2500pci_fill_rxdone, | 1921 | .fill_rxdone = rt2500pci_fill_rxdone, |
1867 | .config_mac_addr = rt2500pci_config_mac_addr, | 1922 | .config_intf = rt2500pci_config_intf, |
1868 | .config_bssid = rt2500pci_config_bssid, | 1923 | .config_erp = rt2500pci_config_erp, |
1869 | .config_type = rt2500pci_config_type, | ||
1870 | .config_preamble = rt2500pci_config_preamble, | ||
1871 | .config = rt2500pci_config, | 1924 | .config = rt2500pci_config, |
1872 | }; | 1925 | }; |
1873 | 1926 | ||
1927 | static const struct data_queue_desc rt2500pci_queue_rx = { | ||
1928 | .entry_num = RX_ENTRIES, | ||
1929 | .data_size = DATA_FRAME_SIZE, | ||
1930 | .desc_size = RXD_DESC_SIZE, | ||
1931 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
1932 | }; | ||
1933 | |||
1934 | static const struct data_queue_desc rt2500pci_queue_tx = { | ||
1935 | .entry_num = TX_ENTRIES, | ||
1936 | .data_size = DATA_FRAME_SIZE, | ||
1937 | .desc_size = TXD_DESC_SIZE, | ||
1938 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1939 | }; | ||
1940 | |||
1941 | static const struct data_queue_desc rt2500pci_queue_bcn = { | ||
1942 | .entry_num = BEACON_ENTRIES, | ||
1943 | .data_size = MGMT_FRAME_SIZE, | ||
1944 | .desc_size = TXD_DESC_SIZE, | ||
1945 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1946 | }; | ||
1947 | |||
1948 | static const struct data_queue_desc rt2500pci_queue_atim = { | ||
1949 | .entry_num = ATIM_ENTRIES, | ||
1950 | .data_size = DATA_FRAME_SIZE, | ||
1951 | .desc_size = TXD_DESC_SIZE, | ||
1952 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1953 | }; | ||
1954 | |||
1874 | static const struct rt2x00_ops rt2500pci_ops = { | 1955 | static const struct rt2x00_ops rt2500pci_ops = { |
1875 | .name = KBUILD_MODNAME, | 1956 | .name = KBUILD_MODNAME, |
1876 | .rxd_size = RXD_DESC_SIZE, | 1957 | .max_sta_intf = 1, |
1877 | .txd_size = TXD_DESC_SIZE, | 1958 | .max_ap_intf = 1, |
1878 | .eeprom_size = EEPROM_SIZE, | 1959 | .eeprom_size = EEPROM_SIZE, |
1879 | .rf_size = RF_SIZE, | 1960 | .rf_size = RF_SIZE, |
1961 | .rx = &rt2500pci_queue_rx, | ||
1962 | .tx = &rt2500pci_queue_tx, | ||
1963 | .bcn = &rt2500pci_queue_bcn, | ||
1964 | .atim = &rt2500pci_queue_atim, | ||
1880 | .lib = &rt2500pci_rt2x00_ops, | 1965 | .lib = &rt2500pci_rt2x00_ops, |
1881 | .hw = &rt2500pci_mac80211_ops, | 1966 | .hw = &rt2500pci_mac80211_ops, |
1882 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1967 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h index 92ba0902d107..13899550465a 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.h +++ b/drivers/net/wireless/rt2x00/rt2500pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -1213,8 +1213,8 @@ | |||
1213 | #define RXD_W10_DROP FIELD32(0x00000001) | 1213 | #define RXD_W10_DROP FIELD32(0x00000001) |
1214 | 1214 | ||
1215 | /* | 1215 | /* |
1216 | * Macro's for converting txpower from EEPROM to dscape value | 1216 | * Macro's for converting txpower from EEPROM to mac80211 value |
1217 | * and from dscape value to register value. | 1217 | * and from mac80211 value to register value. |
1218 | */ | 1218 | */ |
1219 | #define MIN_TXPOWER 0 | 1219 | #define MIN_TXPOWER 0 |
1220 | #define MAX_TXPOWER 31 | 1220 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 638c3d243108..c8216d755835 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -282,97 +282,110 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = { | |||
282 | }; | 282 | }; |
283 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 283 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
284 | 284 | ||
285 | /* | 285 | #ifdef CONFIG_RT2500USB_LEDS |
286 | * Configuration handlers. | 286 | static void rt2500usb_led_brightness(struct led_classdev *led_cdev, |
287 | */ | 287 | enum led_brightness brightness) |
288 | static void rt2500usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, | ||
289 | __le32 *mac) | ||
290 | { | 288 | { |
291 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 289 | struct rt2x00_led *led = |
292 | (3 * sizeof(__le16))); | 290 | container_of(led_cdev, struct rt2x00_led, led_dev); |
293 | } | 291 | unsigned int enabled = brightness != LED_OFF; |
292 | unsigned int activity = | ||
293 | led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; | ||
294 | 294 | ||
295 | static void rt2500usb_config_bssid(struct rt2x00_dev *rt2x00dev, | 295 | if (in_atomic()) { |
296 | __le32 *bssid) | 296 | NOTICE(led->rt2x00dev, |
297 | { | 297 | "Ignoring LED brightness command for led %d\n", |
298 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, bssid, | 298 | led->type); |
299 | (3 * sizeof(__le16))); | 299 | return; |
300 | } | ||
301 | |||
302 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { | ||
303 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
304 | MAC_CSR20_LINK, enabled); | ||
305 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
306 | MAC_CSR20_ACTIVITY, enabled && activity); | ||
307 | } | ||
308 | |||
309 | rt2500usb_register_write(led->rt2x00dev, MAC_CSR20, | ||
310 | led->rt2x00dev->led_mcu_reg); | ||
300 | } | 311 | } |
312 | #else | ||
313 | #define rt2500usb_led_brightness NULL | ||
314 | #endif /* CONFIG_RT2500USB_LEDS */ | ||
301 | 315 | ||
302 | static void rt2500usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 316 | /* |
303 | const int tsf_sync) | 317 | * Configuration handlers. |
318 | */ | ||
319 | static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, | ||
320 | struct rt2x00_intf *intf, | ||
321 | struct rt2x00intf_conf *conf, | ||
322 | const unsigned int flags) | ||
304 | { | 323 | { |
324 | unsigned int bcn_preload; | ||
305 | u16 reg; | 325 | u16 reg; |
306 | 326 | ||
307 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | 327 | if (flags & CONFIG_UPDATE_TYPE) { |
328 | /* | ||
329 | * Enable beacon config | ||
330 | */ | ||
331 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); | ||
332 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); | ||
333 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, bcn_preload >> 6); | ||
334 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, | ||
335 | 2 * (conf->type != IEEE80211_IF_TYPE_STA)); | ||
336 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); | ||
308 | 337 | ||
309 | /* | 338 | /* |
310 | * Enable beacon config | 339 | * Enable synchronisation. |
311 | */ | 340 | */ |
312 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); | 341 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); |
313 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, | 342 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); |
314 | (PREAMBLE + get_duration(IEEE80211_HEADER, 20)) >> 6); | 343 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); |
315 | if (type == IEEE80211_IF_TYPE_STA) | 344 | |
316 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 0); | 345 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
317 | else | 346 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); |
318 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 2); | 347 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync); |
319 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); | 348 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); |
349 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
350 | } | ||
320 | 351 | ||
321 | /* | 352 | if (flags & CONFIG_UPDATE_MAC) |
322 | * Enable synchronisation. | 353 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, conf->mac, |
323 | */ | 354 | (3 * sizeof(__le16))); |
324 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | ||
325 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); | ||
326 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | ||
327 | 355 | ||
328 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 356 | if (flags & CONFIG_UPDATE_BSSID) |
329 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | 357 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, conf->bssid, |
330 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, | 358 | (3 * sizeof(__le16))); |
331 | (tsf_sync == TSF_SYNC_BEACON)); | ||
332 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
333 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, tsf_sync); | ||
334 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
335 | } | 359 | } |
336 | 360 | ||
337 | static void rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 361 | static int rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 362 | struct rt2x00lib_erp *erp) |
339 | const int ack_timeout, | ||
340 | const int ack_consume_time) | ||
341 | { | 363 | { |
342 | u16 reg; | 364 | u16 reg; |
343 | 365 | ||
344 | /* | 366 | /* |
345 | * When in atomic context, reschedule and let rt2x00lib | 367 | * When in atomic context, we should let rt2x00lib |
346 | * call this function again. | 368 | * try this configuration again later. |
347 | */ | 369 | */ |
348 | if (in_atomic()) { | 370 | if (in_atomic()) |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 371 | return -EAGAIN; |
350 | return; | ||
351 | } | ||
352 | 372 | ||
353 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); | 373 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); |
354 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, ack_timeout); | 374 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, erp->ack_timeout); |
355 | rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg); | 375 | rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg); |
356 | 376 | ||
357 | rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); | 377 | rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); |
358 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, | 378 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 379 | !!erp->short_preamble); |
360 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); | 380 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); |
381 | |||
382 | return 0; | ||
361 | } | 383 | } |
362 | 384 | ||
363 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 385 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
364 | const int phymode, | ||
365 | const int basic_rate_mask) | 386 | const int basic_rate_mask) |
366 | { | 387 | { |
367 | rt2500usb_register_write(rt2x00dev, TXRX_CSR11, basic_rate_mask); | 388 | rt2500usb_register_write(rt2x00dev, TXRX_CSR11, basic_rate_mask); |
368 | |||
369 | if (phymode == HWMODE_B) { | ||
370 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, 0x000b); | ||
371 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, 0x0040); | ||
372 | } else { | ||
373 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, 0x0005); | ||
374 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, 0x016c); | ||
375 | } | ||
376 | } | 389 | } |
377 | 390 | ||
378 | static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev, | 391 | static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev, |
@@ -424,6 +437,13 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
424 | u16 csr5; | 437 | u16 csr5; |
425 | u16 csr6; | 438 | u16 csr6; |
426 | 439 | ||
440 | /* | ||
441 | * We should never come here because rt2x00lib is supposed | ||
442 | * to catch this and send us the correct antenna explicitely. | ||
443 | */ | ||
444 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
445 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
446 | |||
427 | rt2500usb_bbp_read(rt2x00dev, 2, &r2); | 447 | rt2500usb_bbp_read(rt2x00dev, 2, &r2); |
428 | rt2500usb_bbp_read(rt2x00dev, 14, &r14); | 448 | rt2500usb_bbp_read(rt2x00dev, 14, &r14); |
429 | rt2500usb_register_read(rt2x00dev, PHY_CSR5, &csr5); | 449 | rt2500usb_register_read(rt2x00dev, PHY_CSR5, &csr5); |
@@ -443,14 +463,8 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
443 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 0); | 463 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 0); |
444 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 0); | 464 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 0); |
445 | break; | 465 | break; |
446 | case ANTENNA_SW_DIVERSITY: | ||
447 | /* | ||
448 | * NOTE: We should never come here because rt2x00lib is | ||
449 | * supposed to catch this and send us the correct antenna | ||
450 | * explicitely. However we are nog going to bug about this. | ||
451 | * Instead, just default to antenna B. | ||
452 | */ | ||
453 | case ANTENNA_B: | 466 | case ANTENNA_B: |
467 | default: | ||
454 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); | 468 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); |
455 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 2); | 469 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 2); |
456 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 2); | 470 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 2); |
@@ -467,14 +481,8 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
467 | case ANTENNA_A: | 481 | case ANTENNA_A: |
468 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); | 482 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); |
469 | break; | 483 | break; |
470 | case ANTENNA_SW_DIVERSITY: | ||
471 | /* | ||
472 | * NOTE: We should never come here because rt2x00lib is | ||
473 | * supposed to catch this and send us the correct antenna | ||
474 | * explicitely. However we are nog going to bug about this. | ||
475 | * Instead, just default to antenna B. | ||
476 | */ | ||
477 | case ANTENNA_B: | 484 | case ANTENNA_B: |
485 | default: | ||
478 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); | 486 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); |
479 | break; | 487 | break; |
480 | } | 488 | } |
@@ -510,6 +518,8 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
510 | u16 reg; | 518 | u16 reg; |
511 | 519 | ||
512 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, libconf->slot_time); | 520 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, libconf->slot_time); |
521 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, libconf->sifs); | ||
522 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, libconf->eifs); | ||
513 | 523 | ||
514 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | 524 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); |
515 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, | 525 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, |
@@ -518,12 +528,11 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
518 | } | 528 | } |
519 | 529 | ||
520 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | 530 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, |
521 | const unsigned int flags, | 531 | struct rt2x00lib_conf *libconf, |
522 | struct rt2x00lib_conf *libconf) | 532 | const unsigned int flags) |
523 | { | 533 | { |
524 | if (flags & CONFIG_UPDATE_PHYMODE) | 534 | if (flags & CONFIG_UPDATE_PHYMODE) |
525 | rt2500usb_config_phymode(rt2x00dev, libconf->phymode, | 535 | rt2500usb_config_phymode(rt2x00dev, libconf->basic_rates); |
526 | libconf->basic_rates); | ||
527 | if (flags & CONFIG_UPDATE_CHANNEL) | 536 | if (flags & CONFIG_UPDATE_CHANNEL) |
528 | rt2500usb_config_channel(rt2x00dev, &libconf->rf, | 537 | rt2500usb_config_channel(rt2x00dev, &libconf->rf, |
529 | libconf->conf->power_level); | 538 | libconf->conf->power_level); |
@@ -537,36 +546,6 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | |||
537 | } | 546 | } |
538 | 547 | ||
539 | /* | 548 | /* |
540 | * LED functions. | ||
541 | */ | ||
542 | static void rt2500usb_enable_led(struct rt2x00_dev *rt2x00dev) | ||
543 | { | ||
544 | u16 reg; | ||
545 | |||
546 | rt2500usb_register_read(rt2x00dev, MAC_CSR21, ®); | ||
547 | rt2x00_set_field16(®, MAC_CSR21_ON_PERIOD, 70); | ||
548 | rt2x00_set_field16(®, MAC_CSR21_OFF_PERIOD, 30); | ||
549 | rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg); | ||
550 | |||
551 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, ®); | ||
552 | rt2x00_set_field16(®, MAC_CSR20_LINK, | ||
553 | (rt2x00dev->led_mode != LED_MODE_ASUS)); | ||
554 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, | ||
555 | (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); | ||
556 | rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg); | ||
557 | } | ||
558 | |||
559 | static void rt2500usb_disable_led(struct rt2x00_dev *rt2x00dev) | ||
560 | { | ||
561 | u16 reg; | ||
562 | |||
563 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, ®); | ||
564 | rt2x00_set_field16(®, MAC_CSR20_LINK, 0); | ||
565 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 0); | ||
566 | rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg); | ||
567 | } | ||
568 | |||
569 | /* | ||
570 | * Link tuning | 549 | * Link tuning |
571 | */ | 550 | */ |
572 | static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, | 551 | static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -626,6 +605,24 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
626 | u8 low_bound; | 605 | u8 low_bound; |
627 | 606 | ||
628 | /* | 607 | /* |
608 | * Read current r17 value, as well as the sensitivity values | ||
609 | * for the r17 register. | ||
610 | */ | ||
611 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
612 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
613 | |||
614 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
615 | up_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
616 | low_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCLOWER); | ||
617 | |||
618 | /* | ||
619 | * If we are not associated, we should go straight to the | ||
620 | * dynamic CCA tuning. | ||
621 | */ | ||
622 | if (!rt2x00dev->intf_associated) | ||
623 | goto dynamic_cca_tune; | ||
624 | |||
625 | /* | ||
629 | * Determine the BBP tuning threshold and correctly | 626 | * Determine the BBP tuning threshold and correctly |
630 | * set BBP 24, 25 and 61. | 627 | * set BBP 24, 25 and 61. |
631 | */ | 628 | */ |
@@ -651,13 +648,6 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
651 | rt2500usb_bbp_write(rt2x00dev, 61, r61); | 648 | rt2500usb_bbp_write(rt2x00dev, 61, r61); |
652 | 649 | ||
653 | /* | 650 | /* |
654 | * Read current r17 value, as well as the sensitivity values | ||
655 | * for the r17 register. | ||
656 | */ | ||
657 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
658 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
659 | |||
660 | /* | ||
661 | * A too low RSSI will cause too much false CCA which will | 651 | * A too low RSSI will cause too much false CCA which will |
662 | * then corrupt the R17 tuning. To remidy this the tuning should | 652 | * then corrupt the R17 tuning. To remidy this the tuning should |
663 | * be stopped (While making sure the R17 value will not exceed limits) | 653 | * be stopped (While making sure the R17 value will not exceed limits) |
@@ -692,14 +682,9 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
692 | * Leave short or middle distance condition, restore r17 | 682 | * Leave short or middle distance condition, restore r17 |
693 | * to the dynamic tuning range. | 683 | * to the dynamic tuning range. |
694 | */ | 684 | */ |
695 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
696 | vgc_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
697 | |||
698 | low_bound = 0x32; | 685 | low_bound = 0x32; |
699 | if (rssi >= -77) | 686 | if (rssi < -77) |
700 | up_bound = vgc_bound; | 687 | up_bound -= (-77 - rssi); |
701 | else | ||
702 | up_bound = vgc_bound - (-77 - rssi); | ||
703 | 688 | ||
704 | if (up_bound < low_bound) | 689 | if (up_bound < low_bound) |
705 | up_bound = low_bound; | 690 | up_bound = low_bound; |
@@ -707,7 +692,16 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
707 | if (r17 > up_bound) { | 692 | if (r17 > up_bound) { |
708 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); | 693 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); |
709 | rt2x00dev->link.vgc_level = up_bound; | 694 | rt2x00dev->link.vgc_level = up_bound; |
710 | } else if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | 695 | return; |
696 | } | ||
697 | |||
698 | dynamic_cca_tune: | ||
699 | |||
700 | /* | ||
701 | * R17 is inside the dynamic tuning range, | ||
702 | * start tuning the link based on the false cca counter. | ||
703 | */ | ||
704 | if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | ||
711 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); | 705 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); |
712 | rt2x00dev->link.vgc_level = r17; | 706 | rt2x00dev->link.vgc_level = r17; |
713 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { | 707 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { |
@@ -747,6 +741,11 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
747 | rt2x00_set_field16(®, MAC_CSR1_HOST_READY, 0); | 741 | rt2x00_set_field16(®, MAC_CSR1_HOST_READY, 0); |
748 | rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); | 742 | rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); |
749 | 743 | ||
744 | rt2500usb_register_read(rt2x00dev, MAC_CSR21, ®); | ||
745 | rt2x00_set_field16(®, MAC_CSR21_ON_PERIOD, 70); | ||
746 | rt2x00_set_field16(®, MAC_CSR21_OFF_PERIOD, 30); | ||
747 | rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg); | ||
748 | |||
750 | rt2500usb_register_read(rt2x00dev, TXRX_CSR5, ®); | 749 | rt2500usb_register_read(rt2x00dev, TXRX_CSR5, ®); |
751 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0, 13); | 750 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0, 13); |
752 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0_VALID, 1); | 751 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0_VALID, 1); |
@@ -878,19 +877,15 @@ continue_csr_init: | |||
878 | rt2500usb_bbp_write(rt2x00dev, 62, 0x10); | 877 | rt2500usb_bbp_write(rt2x00dev, 62, 0x10); |
879 | rt2500usb_bbp_write(rt2x00dev, 75, 0xff); | 878 | rt2500usb_bbp_write(rt2x00dev, 75, 0xff); |
880 | 879 | ||
881 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
882 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 880 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
883 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 881 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
884 | 882 | ||
885 | if (eeprom != 0xffff && eeprom != 0x0000) { | 883 | if (eeprom != 0xffff && eeprom != 0x0000) { |
886 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 884 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
887 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 885 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
888 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
889 | reg_id, value); | ||
890 | rt2500usb_bbp_write(rt2x00dev, reg_id, value); | 886 | rt2500usb_bbp_write(rt2x00dev, reg_id, value); |
891 | } | 887 | } |
892 | } | 888 | } |
893 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
894 | 889 | ||
895 | return 0; | 890 | return 0; |
896 | } | 891 | } |
@@ -920,21 +915,11 @@ static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
920 | return -EIO; | 915 | return -EIO; |
921 | } | 916 | } |
922 | 917 | ||
923 | /* | ||
924 | * Enable LED | ||
925 | */ | ||
926 | rt2500usb_enable_led(rt2x00dev); | ||
927 | |||
928 | return 0; | 918 | return 0; |
929 | } | 919 | } |
930 | 920 | ||
931 | static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 921 | static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
932 | { | 922 | { |
933 | /* | ||
934 | * Disable LED | ||
935 | */ | ||
936 | rt2500usb_disable_led(rt2x00dev); | ||
937 | |||
938 | rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121); | 923 | rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121); |
939 | rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121); | 924 | rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121); |
940 | 925 | ||
@@ -1027,10 +1012,10 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1027 | */ | 1012 | */ |
1028 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1013 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1029 | struct sk_buff *skb, | 1014 | struct sk_buff *skb, |
1030 | struct txdata_entry_desc *desc, | 1015 | struct txentry_desc *txdesc, |
1031 | struct ieee80211_tx_control *control) | 1016 | struct ieee80211_tx_control *control) |
1032 | { | 1017 | { |
1033 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1018 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1034 | __le32 *txd = skbdesc->desc; | 1019 | __le32 *txd = skbdesc->desc; |
1035 | u32 word; | 1020 | u32 word; |
1036 | 1021 | ||
@@ -1039,31 +1024,31 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1039 | */ | 1024 | */ |
1040 | rt2x00_desc_read(txd, 1, &word); | 1025 | rt2x00_desc_read(txd, 1, &word); |
1041 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1026 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1042 | rt2x00_set_field32(&word, TXD_W1_AIFS, desc->aifs); | 1027 | rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); |
1043 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1028 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1044 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1029 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1045 | rt2x00_desc_write(txd, 1, word); | 1030 | rt2x00_desc_write(txd, 1, word); |
1046 | 1031 | ||
1047 | rt2x00_desc_read(txd, 2, &word); | 1032 | rt2x00_desc_read(txd, 2, &word); |
1048 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1033 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1049 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1034 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1050 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1035 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); |
1051 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | 1036 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1052 | rt2x00_desc_write(txd, 2, word); | 1037 | rt2x00_desc_write(txd, 2, word); |
1053 | 1038 | ||
1054 | rt2x00_desc_read(txd, 0, &word); | 1039 | rt2x00_desc_read(txd, 0, &word); |
1055 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit); | 1040 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit); |
1056 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1041 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1057 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1042 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1058 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1043 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1059 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1044 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1060 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1045 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1061 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1046 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1062 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1047 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1063 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1048 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1064 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, | 1049 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, |
1065 | !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)); | 1050 | !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)); |
1066 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1051 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1067 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1052 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1068 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); | 1053 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); |
1069 | rt2x00_desc_write(txd, 0, word); | 1054 | rt2x00_desc_write(txd, 0, word); |
@@ -1088,15 +1073,17 @@ static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1088 | * TX data initialization | 1073 | * TX data initialization |
1089 | */ | 1074 | */ |
1090 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1075 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1091 | unsigned int queue) | 1076 | const unsigned int queue) |
1092 | { | 1077 | { |
1093 | u16 reg; | 1078 | u16 reg; |
1094 | 1079 | ||
1095 | if (queue != IEEE80211_TX_QUEUE_BEACON) | 1080 | if (queue != RT2X00_BCN_QUEUE_BEACON) |
1096 | return; | 1081 | return; |
1097 | 1082 | ||
1098 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 1083 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
1099 | if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { | 1084 | if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { |
1085 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
1086 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); | ||
1100 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); | 1087 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); |
1101 | /* | 1088 | /* |
1102 | * Beacon generation will fail initially. | 1089 | * Beacon generation will fail initially. |
@@ -1114,42 +1101,65 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1114 | /* | 1101 | /* |
1115 | * RX control handlers | 1102 | * RX control handlers |
1116 | */ | 1103 | */ |
1117 | static void rt2500usb_fill_rxdone(struct data_entry *entry, | 1104 | static void rt2500usb_fill_rxdone(struct queue_entry *entry, |
1118 | struct rxdata_entry_desc *desc) | 1105 | struct rxdone_entry_desc *rxdesc) |
1119 | { | 1106 | { |
1120 | struct skb_desc *skbdesc = get_skb_desc(entry->skb); | 1107 | struct queue_entry_priv_usb_rx *priv_rx = entry->priv_data; |
1121 | struct urb *urb = entry->priv; | 1108 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1122 | __le32 *rxd = (__le32 *)(entry->skb->data + | 1109 | __le32 *rxd = |
1123 | (urb->actual_length - entry->ring->desc_size)); | 1110 | (__le32 *)(entry->skb->data + |
1111 | (priv_rx->urb->actual_length - entry->queue->desc_size)); | ||
1112 | unsigned int offset = entry->queue->desc_size + 2; | ||
1124 | u32 word0; | 1113 | u32 word0; |
1125 | u32 word1; | 1114 | u32 word1; |
1126 | 1115 | ||
1116 | /* | ||
1117 | * Copy descriptor to the available headroom inside the skbuffer. | ||
1118 | */ | ||
1119 | skb_push(entry->skb, offset); | ||
1120 | memcpy(entry->skb->data, rxd, entry->queue->desc_size); | ||
1121 | rxd = (__le32 *)entry->skb->data; | ||
1122 | |||
1123 | /* | ||
1124 | * The descriptor is now aligned to 4 bytes and thus it is | ||
1125 | * now safe to read it on all architectures. | ||
1126 | */ | ||
1127 | rt2x00_desc_read(rxd, 0, &word0); | 1127 | rt2x00_desc_read(rxd, 0, &word0); |
1128 | rt2x00_desc_read(rxd, 1, &word1); | 1128 | rt2x00_desc_read(rxd, 1, &word1); |
1129 | 1129 | ||
1130 | desc->flags = 0; | 1130 | rxdesc->flags = 0; |
1131 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1131 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1132 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1132 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1133 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1133 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1134 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1134 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1135 | 1135 | ||
1136 | /* | 1136 | /* |
1137 | * Obtain the status about this packet. | 1137 | * Obtain the status about this packet. |
1138 | * When frame was received with an OFDM bitrate, | ||
1139 | * the signal is the PLCP value. If it was received with | ||
1140 | * a CCK bitrate the signal is the rate in 100kbit/s. | ||
1138 | */ | 1141 | */ |
1139 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1142 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1140 | desc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - | 1143 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1141 | entry->ring->rt2x00dev->rssi_offset; | 1144 | rxdesc->signal_plcp = rxdesc->ofdm; |
1142 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1145 | rxdesc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - |
1143 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1146 | entry->queue->rt2x00dev->rssi_offset; |
1144 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1147 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1148 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | ||
1149 | |||
1150 | /* | ||
1151 | * Adjust the skb memory window to the frame boundaries. | ||
1152 | */ | ||
1153 | skb_pull(entry->skb, offset); | ||
1154 | skb_trim(entry->skb, rxdesc->size); | ||
1145 | 1155 | ||
1146 | /* | 1156 | /* |
1147 | * Set descriptor and data pointer. | 1157 | * Set descriptor and data pointer. |
1148 | */ | 1158 | */ |
1149 | skbdesc->desc = entry->skb->data + desc->size; | ||
1150 | skbdesc->desc_len = entry->ring->desc_size; | ||
1151 | skbdesc->data = entry->skb->data; | 1159 | skbdesc->data = entry->skb->data; |
1152 | skbdesc->data_len = desc->size; | 1160 | skbdesc->data_len = rxdesc->size; |
1161 | skbdesc->desc = rxd; | ||
1162 | skbdesc->desc_len = entry->queue->desc_size; | ||
1153 | } | 1163 | } |
1154 | 1164 | ||
1155 | /* | 1165 | /* |
@@ -1157,10 +1167,10 @@ static void rt2500usb_fill_rxdone(struct data_entry *entry, | |||
1157 | */ | 1167 | */ |
1158 | static void rt2500usb_beacondone(struct urb *urb) | 1168 | static void rt2500usb_beacondone(struct urb *urb) |
1159 | { | 1169 | { |
1160 | struct data_entry *entry = (struct data_entry *)urb->context; | 1170 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
1161 | struct data_ring *ring = entry->ring; | 1171 | struct queue_entry_priv_usb_bcn *priv_bcn = entry->priv_data; |
1162 | 1172 | ||
1163 | if (!test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) | 1173 | if (!test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) |
1164 | return; | 1174 | return; |
1165 | 1175 | ||
1166 | /* | 1176 | /* |
@@ -1169,18 +1179,11 @@ static void rt2500usb_beacondone(struct urb *urb) | |||
1169 | * Otherwise we should free the sk_buffer, the device | 1179 | * Otherwise we should free the sk_buffer, the device |
1170 | * should be doing the rest of the work now. | 1180 | * should be doing the rest of the work now. |
1171 | */ | 1181 | */ |
1172 | if (ring->index == 1) { | 1182 | if (priv_bcn->guardian_urb == urb) { |
1173 | rt2x00_ring_index_done_inc(ring); | 1183 | usb_submit_urb(priv_bcn->urb, GFP_ATOMIC); |
1174 | entry = rt2x00_get_data_entry(ring); | 1184 | } else if (priv_bcn->urb == urb) { |
1175 | usb_submit_urb(entry->priv, GFP_ATOMIC); | 1185 | dev_kfree_skb(entry->skb); |
1176 | rt2x00_ring_index_inc(ring); | 1186 | entry->skb = NULL; |
1177 | } else if (ring->index_done == 1) { | ||
1178 | entry = rt2x00_get_data_entry_done(ring); | ||
1179 | if (entry->skb) { | ||
1180 | dev_kfree_skb(entry->skb); | ||
1181 | entry->skb = NULL; | ||
1182 | } | ||
1183 | rt2x00_ring_index_done_inc(ring); | ||
1184 | } | 1187 | } |
1185 | } | 1188 | } |
1186 | 1189 | ||
@@ -1191,6 +1194,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1191 | { | 1194 | { |
1192 | u16 word; | 1195 | u16 word; |
1193 | u8 *mac; | 1196 | u8 *mac; |
1197 | u8 bbp; | ||
1194 | 1198 | ||
1195 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); | 1199 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); |
1196 | 1200 | ||
@@ -1245,9 +1249,17 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1245 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); | 1249 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); |
1246 | } | 1250 | } |
1247 | 1251 | ||
1252 | /* | ||
1253 | * Switch lower vgc bound to current BBP R17 value, | ||
1254 | * lower the value a bit for better quality. | ||
1255 | */ | ||
1256 | rt2500usb_bbp_read(rt2x00dev, 17, &bbp); | ||
1257 | bbp -= 6; | ||
1258 | |||
1248 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); | 1259 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); |
1249 | if (word == 0xffff) { | 1260 | if (word == 0xffff) { |
1250 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); | 1261 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); |
1262 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | ||
1251 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | 1263 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); |
1252 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); | 1264 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); |
1253 | } | 1265 | } |
@@ -1258,6 +1270,9 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1258 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); | 1270 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); |
1259 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); | 1271 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); |
1260 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); | 1272 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); |
1273 | } else { | ||
1274 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | ||
1275 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | ||
1261 | } | 1276 | } |
1262 | 1277 | ||
1263 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); | 1278 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); |
@@ -1342,8 +1357,31 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1342 | /* | 1357 | /* |
1343 | * Store led mode, for correct led behaviour. | 1358 | * Store led mode, for correct led behaviour. |
1344 | */ | 1359 | */ |
1345 | rt2x00dev->led_mode = | 1360 | #ifdef CONFIG_RT2500USB_LEDS |
1346 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1361 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1362 | |||
1363 | switch (value) { | ||
1364 | case LED_MODE_ASUS: | ||
1365 | case LED_MODE_ALPHA: | ||
1366 | case LED_MODE_DEFAULT: | ||
1367 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1368 | break; | ||
1369 | case LED_MODE_TXRX_ACTIVITY: | ||
1370 | rt2x00dev->led_flags = | ||
1371 | LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; | ||
1372 | break; | ||
1373 | case LED_MODE_SIGNAL_STRENGTH: | ||
1374 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1375 | break; | ||
1376 | } | ||
1377 | |||
1378 | /* | ||
1379 | * Store the current led register value, we need it later | ||
1380 | * in set_brightness but that is called in irq context which | ||
1381 | * means we can't use rt2500usb_register_read() at that time. | ||
1382 | */ | ||
1383 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, &rt2x00dev->led_mcu_reg); | ||
1384 | #endif /* CONFIG_RT2500USB_LEDS */ | ||
1347 | 1385 | ||
1348 | /* | 1386 | /* |
1349 | * Check if the BBP tuning should be disabled. | 1387 | * Check if the BBP tuning should be disabled. |
@@ -1550,8 +1588,8 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1550 | /* | 1588 | /* |
1551 | * Initialize hw_mode information. | 1589 | * Initialize hw_mode information. |
1552 | */ | 1590 | */ |
1553 | spec->num_modes = 2; | 1591 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1554 | spec->num_rates = 12; | 1592 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1555 | spec->tx_power_a = NULL; | 1593 | spec->tx_power_a = NULL; |
1556 | spec->tx_power_bg = txpower; | 1594 | spec->tx_power_bg = txpower; |
1557 | spec->tx_power_default = DEFAULT_TXPOWER; | 1595 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1572,9 +1610,9 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1572 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | 1610 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); |
1573 | spec->channels = rf_vals_bg_2525e; | 1611 | spec->channels = rf_vals_bg_2525e; |
1574 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | 1612 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { |
1613 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1575 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | 1614 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); |
1576 | spec->channels = rf_vals_5222; | 1615 | spec->channels = rf_vals_5222; |
1577 | spec->num_modes = 3; | ||
1578 | } | 1616 | } |
1579 | } | 1617 | } |
1580 | 1618 | ||
@@ -1599,9 +1637,10 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1599 | rt2500usb_probe_hw_mode(rt2x00dev); | 1637 | rt2500usb_probe_hw_mode(rt2x00dev); |
1600 | 1638 | ||
1601 | /* | 1639 | /* |
1602 | * This device requires the beacon ring | 1640 | * This device requires the atim queue |
1603 | */ | 1641 | */ |
1604 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1642 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1643 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | ||
1605 | 1644 | ||
1606 | /* | 1645 | /* |
1607 | * Set the rssi offset. | 1646 | * Set the rssi offset. |
@@ -1691,48 +1730,53 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1691 | struct ieee80211_tx_control *control) | 1730 | struct ieee80211_tx_control *control) |
1692 | { | 1731 | { |
1693 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1732 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1694 | struct usb_device *usb_dev = | 1733 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
1695 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | 1734 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1696 | struct skb_desc *desc; | 1735 | struct queue_entry_priv_usb_bcn *priv_bcn; |
1697 | struct data_ring *ring; | 1736 | struct skb_frame_desc *skbdesc; |
1698 | struct data_entry *beacon; | ||
1699 | struct data_entry *guardian; | ||
1700 | int pipe = usb_sndbulkpipe(usb_dev, 1); | 1737 | int pipe = usb_sndbulkpipe(usb_dev, 1); |
1701 | int length; | 1738 | int length; |
1739 | u16 reg; | ||
1740 | |||
1741 | if (unlikely(!intf->beacon)) | ||
1742 | return -ENOBUFS; | ||
1743 | |||
1744 | priv_bcn = intf->beacon->priv_data; | ||
1702 | 1745 | ||
1703 | /* | 1746 | /* |
1704 | * Just in case the ieee80211 doesn't set this, | 1747 | * Add the descriptor in front of the skb. |
1705 | * but we need this queue set for the descriptor | ||
1706 | * initialization. | ||
1707 | */ | 1748 | */ |
1708 | control->queue = IEEE80211_TX_QUEUE_BEACON; | 1749 | skb_push(skb, intf->beacon->queue->desc_size); |
1709 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | 1750 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
1710 | 1751 | ||
1711 | /* | 1752 | /* |
1712 | * Obtain 2 entries, one for the guardian byte, | 1753 | * Fill in skb descriptor |
1713 | * the second for the actual beacon. | ||
1714 | */ | 1754 | */ |
1715 | guardian = rt2x00_get_data_entry(ring); | 1755 | skbdesc = get_skb_frame_desc(skb); |
1716 | rt2x00_ring_index_inc(ring); | 1756 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1717 | beacon = rt2x00_get_data_entry(ring); | 1757 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
1758 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; | ||
1759 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; | ||
1760 | skbdesc->desc = skb->data; | ||
1761 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1762 | skbdesc->entry = intf->beacon; | ||
1718 | 1763 | ||
1719 | /* | 1764 | /* |
1720 | * Add the descriptor in front of the skb. | 1765 | * Disable beaconing while we are reloading the beacon data, |
1766 | * otherwise we might be sending out invalid data. | ||
1721 | */ | 1767 | */ |
1722 | skb_push(skb, ring->desc_size); | 1768 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
1723 | memset(skb->data, 0, ring->desc_size); | 1769 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); |
1770 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); | ||
1771 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
1772 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
1724 | 1773 | ||
1725 | /* | 1774 | /* |
1726 | * Fill in skb descriptor | 1775 | * mac80211 doesn't provide the control->queue variable |
1776 | * for beacons. Set our own queue identification so | ||
1777 | * it can be used during descriptor initialization. | ||
1727 | */ | 1778 | */ |
1728 | desc = get_skb_desc(skb); | 1779 | control->queue = RT2X00_BCN_QUEUE_BEACON; |
1729 | desc->desc_len = ring->desc_size; | ||
1730 | desc->data_len = skb->len - ring->desc_size; | ||
1731 | desc->desc = skb->data; | ||
1732 | desc->data = skb->data + ring->desc_size; | ||
1733 | desc->ring = ring; | ||
1734 | desc->entry = beacon; | ||
1735 | |||
1736 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 1780 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
1737 | 1781 | ||
1738 | /* | 1782 | /* |
@@ -1742,27 +1786,29 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1742 | */ | 1786 | */ |
1743 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); | 1787 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); |
1744 | 1788 | ||
1745 | usb_fill_bulk_urb(beacon->priv, usb_dev, pipe, | 1789 | usb_fill_bulk_urb(priv_bcn->urb, usb_dev, pipe, |
1746 | skb->data, length, rt2500usb_beacondone, beacon); | 1790 | skb->data, length, rt2500usb_beacondone, |
1791 | intf->beacon); | ||
1747 | 1792 | ||
1748 | /* | 1793 | /* |
1749 | * Second we need to create the guardian byte. | 1794 | * Second we need to create the guardian byte. |
1750 | * We only need a single byte, so lets recycle | 1795 | * We only need a single byte, so lets recycle |
1751 | * the 'flags' field we are not using for beacons. | 1796 | * the 'flags' field we are not using for beacons. |
1752 | */ | 1797 | */ |
1753 | guardian->flags = 0; | 1798 | priv_bcn->guardian_data = 0; |
1754 | usb_fill_bulk_urb(guardian->priv, usb_dev, pipe, | 1799 | usb_fill_bulk_urb(priv_bcn->guardian_urb, usb_dev, pipe, |
1755 | &guardian->flags, 1, rt2500usb_beacondone, guardian); | 1800 | &priv_bcn->guardian_data, 1, rt2500usb_beacondone, |
1801 | intf->beacon); | ||
1756 | 1802 | ||
1757 | /* | 1803 | /* |
1758 | * Send out the guardian byte. | 1804 | * Send out the guardian byte. |
1759 | */ | 1805 | */ |
1760 | usb_submit_urb(guardian->priv, GFP_ATOMIC); | 1806 | usb_submit_urb(priv_bcn->guardian_urb, GFP_ATOMIC); |
1761 | 1807 | ||
1762 | /* | 1808 | /* |
1763 | * Enable beacon generation. | 1809 | * Enable beacon generation. |
1764 | */ | 1810 | */ |
1765 | rt2500usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 1811 | rt2500usb_kick_tx_queue(rt2x00dev, control->queue); |
1766 | 1812 | ||
1767 | return 0; | 1813 | return 0; |
1768 | } | 1814 | } |
@@ -1793,24 +1839,55 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1793 | .link_stats = rt2500usb_link_stats, | 1839 | .link_stats = rt2500usb_link_stats, |
1794 | .reset_tuner = rt2500usb_reset_tuner, | 1840 | .reset_tuner = rt2500usb_reset_tuner, |
1795 | .link_tuner = rt2500usb_link_tuner, | 1841 | .link_tuner = rt2500usb_link_tuner, |
1842 | .led_brightness = rt2500usb_led_brightness, | ||
1796 | .write_tx_desc = rt2500usb_write_tx_desc, | 1843 | .write_tx_desc = rt2500usb_write_tx_desc, |
1797 | .write_tx_data = rt2x00usb_write_tx_data, | 1844 | .write_tx_data = rt2x00usb_write_tx_data, |
1798 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1845 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1799 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1846 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1800 | .fill_rxdone = rt2500usb_fill_rxdone, | 1847 | .fill_rxdone = rt2500usb_fill_rxdone, |
1801 | .config_mac_addr = rt2500usb_config_mac_addr, | 1848 | .config_intf = rt2500usb_config_intf, |
1802 | .config_bssid = rt2500usb_config_bssid, | 1849 | .config_erp = rt2500usb_config_erp, |
1803 | .config_type = rt2500usb_config_type, | ||
1804 | .config_preamble = rt2500usb_config_preamble, | ||
1805 | .config = rt2500usb_config, | 1850 | .config = rt2500usb_config, |
1806 | }; | 1851 | }; |
1807 | 1852 | ||
1853 | static const struct data_queue_desc rt2500usb_queue_rx = { | ||
1854 | .entry_num = RX_ENTRIES, | ||
1855 | .data_size = DATA_FRAME_SIZE, | ||
1856 | .desc_size = RXD_DESC_SIZE, | ||
1857 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | ||
1858 | }; | ||
1859 | |||
1860 | static const struct data_queue_desc rt2500usb_queue_tx = { | ||
1861 | .entry_num = TX_ENTRIES, | ||
1862 | .data_size = DATA_FRAME_SIZE, | ||
1863 | .desc_size = TXD_DESC_SIZE, | ||
1864 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
1865 | }; | ||
1866 | |||
1867 | static const struct data_queue_desc rt2500usb_queue_bcn = { | ||
1868 | .entry_num = BEACON_ENTRIES, | ||
1869 | .data_size = MGMT_FRAME_SIZE, | ||
1870 | .desc_size = TXD_DESC_SIZE, | ||
1871 | .priv_size = sizeof(struct queue_entry_priv_usb_bcn), | ||
1872 | }; | ||
1873 | |||
1874 | static const struct data_queue_desc rt2500usb_queue_atim = { | ||
1875 | .entry_num = ATIM_ENTRIES, | ||
1876 | .data_size = DATA_FRAME_SIZE, | ||
1877 | .desc_size = TXD_DESC_SIZE, | ||
1878 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
1879 | }; | ||
1880 | |||
1808 | static const struct rt2x00_ops rt2500usb_ops = { | 1881 | static const struct rt2x00_ops rt2500usb_ops = { |
1809 | .name = KBUILD_MODNAME, | 1882 | .name = KBUILD_MODNAME, |
1810 | .rxd_size = RXD_DESC_SIZE, | 1883 | .max_sta_intf = 1, |
1811 | .txd_size = TXD_DESC_SIZE, | 1884 | .max_ap_intf = 1, |
1812 | .eeprom_size = EEPROM_SIZE, | 1885 | .eeprom_size = EEPROM_SIZE, |
1813 | .rf_size = RF_SIZE, | 1886 | .rf_size = RF_SIZE, |
1887 | .rx = &rt2500usb_queue_rx, | ||
1888 | .tx = &rt2500usb_queue_tx, | ||
1889 | .bcn = &rt2500usb_queue_bcn, | ||
1890 | .atim = &rt2500usb_queue_atim, | ||
1814 | .lib = &rt2500usb_rt2x00_ops, | 1891 | .lib = &rt2500usb_rt2x00_ops, |
1815 | .hw = &rt2500usb_mac80211_ops, | 1892 | .hw = &rt2500usb_mac80211_ops, |
1816 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1893 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index 9e0433722e3d..a37a068d0c71 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -135,7 +135,7 @@ | |||
135 | * Misc MAC_CSR registers. | 135 | * Misc MAC_CSR registers. |
136 | * MAC_CSR9: Timer control. | 136 | * MAC_CSR9: Timer control. |
137 | * MAC_CSR10: Slot time. | 137 | * MAC_CSR10: Slot time. |
138 | * MAC_CSR11: IFS. | 138 | * MAC_CSR11: SIFS. |
139 | * MAC_CSR12: EIFS. | 139 | * MAC_CSR12: EIFS. |
140 | * MAC_CSR13: Power mode0. | 140 | * MAC_CSR13: Power mode0. |
141 | * MAC_CSR14: Power mode1. | 141 | * MAC_CSR14: Power mode1. |
@@ -686,6 +686,7 @@ | |||
686 | */ | 686 | */ |
687 | #define EEPROM_BBPTUNE_VGC 0x0034 | 687 | #define EEPROM_BBPTUNE_VGC 0x0034 |
688 | #define EEPROM_BBPTUNE_VGCUPPER FIELD16(0x00ff) | 688 | #define EEPROM_BBPTUNE_VGCUPPER FIELD16(0x00ff) |
689 | #define EEPROM_BBPTUNE_VGCLOWER FIELD16(0xff00) | ||
689 | 690 | ||
690 | /* | 691 | /* |
691 | * EEPROM BBP R17 Tuning. | 692 | * EEPROM BBP R17 Tuning. |
@@ -786,8 +787,8 @@ | |||
786 | #define RXD_W3_EIV FIELD32(0xffffffff) | 787 | #define RXD_W3_EIV FIELD32(0xffffffff) |
787 | 788 | ||
788 | /* | 789 | /* |
789 | * Macro's for converting txpower from EEPROM to dscape value | 790 | * Macro's for converting txpower from EEPROM to mac80211 value |
790 | * and from dscape value to register value. | 791 | * and from mac80211 value to register value. |
791 | */ | 792 | */ |
792 | #define MIN_TXPOWER 0 | 793 | #define MIN_TXPOWER 0 |
793 | #define MAX_TXPOWER 31 | 794 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 6c725422af5a..c016bfe1defd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -27,23 +27,24 @@ | |||
27 | #define RT2X00_H | 27 | #define RT2X00_H |
28 | 28 | ||
29 | #include <linux/bitops.h> | 29 | #include <linux/bitops.h> |
30 | #include <linux/prefetch.h> | ||
31 | #include <linux/skbuff.h> | 30 | #include <linux/skbuff.h> |
32 | #include <linux/workqueue.h> | 31 | #include <linux/workqueue.h> |
33 | #include <linux/firmware.h> | 32 | #include <linux/firmware.h> |
33 | #include <linux/leds.h> | ||
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
36 | 36 | ||
37 | #include <net/mac80211.h> | 37 | #include <net/mac80211.h> |
38 | 38 | ||
39 | #include "rt2x00debug.h" | 39 | #include "rt2x00debug.h" |
40 | #include "rt2x00leds.h" | ||
40 | #include "rt2x00reg.h" | 41 | #include "rt2x00reg.h" |
41 | #include "rt2x00ring.h" | 42 | #include "rt2x00queue.h" |
42 | 43 | ||
43 | /* | 44 | /* |
44 | * Module information. | 45 | * Module information. |
45 | */ | 46 | */ |
46 | #define DRV_VERSION "2.0.14" | 47 | #define DRV_VERSION "2.1.4" |
47 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" | 48 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" |
48 | 49 | ||
49 | /* | 50 | /* |
@@ -91,26 +92,6 @@ | |||
91 | DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) | 92 | DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) |
92 | 93 | ||
93 | /* | 94 | /* |
94 | * Ring sizes. | ||
95 | * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes. | ||
96 | * DATA_FRAME_SIZE is used for TX, RX, ATIM and PRIO rings. | ||
97 | * MGMT_FRAME_SIZE is used for the BEACON ring. | ||
98 | */ | ||
99 | #define DATA_FRAME_SIZE 2432 | ||
100 | #define MGMT_FRAME_SIZE 256 | ||
101 | |||
102 | /* | ||
103 | * Number of entries in a packet ring. | ||
104 | * PCI devices only need 1 Beacon entry, | ||
105 | * but USB devices require a second because they | ||
106 | * have to send a Guardian byte first. | ||
107 | */ | ||
108 | #define RX_ENTRIES 12 | ||
109 | #define TX_ENTRIES 12 | ||
110 | #define ATIM_ENTRIES 1 | ||
111 | #define BEACON_ENTRIES 2 | ||
112 | |||
113 | /* | ||
114 | * Standard timing and size defines. | 95 | * Standard timing and size defines. |
115 | * These values should follow the ieee80211 specifications. | 96 | * These values should follow the ieee80211 specifications. |
116 | */ | 97 | */ |
@@ -364,20 +345,22 @@ static inline int rt2x00_update_ant_rssi(struct link *link, int rssi) | |||
364 | 345 | ||
365 | /* | 346 | /* |
366 | * Interface structure | 347 | * Interface structure |
367 | * Configuration details about the current interface. | 348 | * Per interface configuration details, this structure |
349 | * is allocated as the private data for ieee80211_vif. | ||
368 | */ | 350 | */ |
369 | struct interface { | 351 | struct rt2x00_intf { |
370 | /* | 352 | /* |
371 | * Interface identification. The value is assigned | 353 | * All fields within the rt2x00_intf structure |
372 | * to us by the 80211 stack, and is used to request | 354 | * must be protected with a spinlock. |
373 | * new beacons. | ||
374 | */ | 355 | */ |
375 | struct ieee80211_vif *id; | 356 | spinlock_t lock; |
376 | 357 | ||
377 | /* | 358 | /* |
378 | * Current working type (IEEE80211_IF_TYPE_*). | 359 | * BSS configuration. Copied from the structure |
360 | * passed to us through the bss_info_changed() | ||
361 | * callback funtion. | ||
379 | */ | 362 | */ |
380 | int type; | 363 | struct ieee80211_bss_conf conf; |
381 | 364 | ||
382 | /* | 365 | /* |
383 | * MAC of the device. | 366 | * MAC of the device. |
@@ -388,42 +371,59 @@ struct interface { | |||
388 | * BBSID of the AP to associate with. | 371 | * BBSID of the AP to associate with. |
389 | */ | 372 | */ |
390 | u8 bssid[ETH_ALEN]; | 373 | u8 bssid[ETH_ALEN]; |
391 | }; | ||
392 | 374 | ||
393 | static inline int is_interface_present(struct interface *intf) | 375 | /* |
394 | { | 376 | * Entry in the beacon queue which belongs to |
395 | return !!intf->id; | 377 | * this interface. Each interface has its own |
396 | } | 378 | * dedicated beacon entry. |
379 | */ | ||
380 | struct queue_entry *beacon; | ||
381 | |||
382 | /* | ||
383 | * Actions that needed rescheduling. | ||
384 | */ | ||
385 | unsigned int delayed_flags; | ||
386 | #define DELAYED_UPDATE_BEACON 0x00000001 | ||
387 | #define DELAYED_CONFIG_ERP 0x00000002 | ||
388 | }; | ||
397 | 389 | ||
398 | static inline int is_interface_type(struct interface *intf, int type) | 390 | static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) |
399 | { | 391 | { |
400 | return intf->type == type; | 392 | return (struct rt2x00_intf *)vif->drv_priv; |
401 | } | 393 | } |
402 | 394 | ||
403 | /* | 395 | /** |
396 | * struct hw_mode_spec: Hardware specifications structure | ||
397 | * | ||
404 | * Details about the supported modes, rates and channels | 398 | * Details about the supported modes, rates and channels |
405 | * of a particular chipset. This is used by rt2x00lib | 399 | * of a particular chipset. This is used by rt2x00lib |
406 | * to build the ieee80211_hw_mode array for mac80211. | 400 | * to build the ieee80211_hw_mode array for mac80211. |
401 | * | ||
402 | * @supported_bands: Bitmask contained the supported bands (2.4GHz, 5.2GHz). | ||
403 | * @supported_rates: Rate types which are supported (CCK, OFDM). | ||
404 | * @num_channels: Number of supported channels. This is used as array size | ||
405 | * for @tx_power_a, @tx_power_bg and @channels. | ||
406 | * channels: Device/chipset specific channel values (See &struct rf_channel). | ||
407 | * @tx_power_a: TX power values for all 5.2GHz channels (may be NULL). | ||
408 | * @tx_power_bg: TX power values for all 2.4GHz channels (may be NULL). | ||
409 | * @tx_power_default: Default TX power value to use when either | ||
410 | * @tx_power_a or @tx_power_bg is missing. | ||
407 | */ | 411 | */ |
408 | struct hw_mode_spec { | 412 | struct hw_mode_spec { |
409 | /* | 413 | unsigned int supported_bands; |
410 | * Number of modes, rates and channels. | 414 | #define SUPPORT_BAND_2GHZ 0x00000001 |
411 | */ | 415 | #define SUPPORT_BAND_5GHZ 0x00000002 |
412 | int num_modes; | 416 | |
413 | int num_rates; | 417 | unsigned int supported_rates; |
414 | int num_channels; | 418 | #define SUPPORT_RATE_CCK 0x00000001 |
419 | #define SUPPORT_RATE_OFDM 0x00000002 | ||
420 | |||
421 | unsigned int num_channels; | ||
422 | const struct rf_channel *channels; | ||
415 | 423 | ||
416 | /* | ||
417 | * txpower values. | ||
418 | */ | ||
419 | const u8 *tx_power_a; | 424 | const u8 *tx_power_a; |
420 | const u8 *tx_power_bg; | 425 | const u8 *tx_power_bg; |
421 | u8 tx_power_default; | 426 | u8 tx_power_default; |
422 | |||
423 | /* | ||
424 | * Device/chipset specific value. | ||
425 | */ | ||
426 | const struct rf_channel *channels; | ||
427 | }; | 427 | }; |
428 | 428 | ||
429 | /* | 429 | /* |
@@ -439,10 +439,10 @@ struct rt2x00lib_conf { | |||
439 | 439 | ||
440 | struct antenna_setup ant; | 440 | struct antenna_setup ant; |
441 | 441 | ||
442 | int phymode; | 442 | enum ieee80211_band band; |
443 | 443 | ||
444 | int basic_rates; | 444 | u32 basic_rates; |
445 | int slot_time; | 445 | u32 slot_time; |
446 | 446 | ||
447 | short sifs; | 447 | short sifs; |
448 | short pifs; | 448 | short pifs; |
@@ -451,6 +451,47 @@ struct rt2x00lib_conf { | |||
451 | }; | 451 | }; |
452 | 452 | ||
453 | /* | 453 | /* |
454 | * Configuration structure for erp settings. | ||
455 | */ | ||
456 | struct rt2x00lib_erp { | ||
457 | int short_preamble; | ||
458 | |||
459 | int ack_timeout; | ||
460 | int ack_consume_time; | ||
461 | }; | ||
462 | |||
463 | /* | ||
464 | * Configuration structure wrapper around the | ||
465 | * rt2x00 interface configuration handler. | ||
466 | */ | ||
467 | struct rt2x00intf_conf { | ||
468 | /* | ||
469 | * Interface type | ||
470 | */ | ||
471 | enum ieee80211_if_types type; | ||
472 | |||
473 | /* | ||
474 | * TSF sync value, this is dependant on the operation type. | ||
475 | */ | ||
476 | enum tsf_sync sync; | ||
477 | |||
478 | /* | ||
479 | * The MAC and BSSID addressess are simple array of bytes, | ||
480 | * these arrays are little endian, so when sending the addressess | ||
481 | * to the drivers, copy the it into a endian-signed variable. | ||
482 | * | ||
483 | * Note that all devices (except rt2500usb) have 32 bits | ||
484 | * register word sizes. This means that whatever variable we | ||
485 | * pass _must_ be a multiple of 32 bits. Otherwise the device | ||
486 | * might not accept what we are sending to it. | ||
487 | * This will also make it easier for the driver to write | ||
488 | * the data to the device. | ||
489 | */ | ||
490 | __le32 mac[2]; | ||
491 | __le32 bssid[2]; | ||
492 | }; | ||
493 | |||
494 | /* | ||
454 | * rt2x00lib callback functions. | 495 | * rt2x00lib callback functions. |
455 | */ | 496 | */ |
456 | struct rt2x00lib_ops { | 497 | struct rt2x00lib_ops { |
@@ -464,6 +505,7 @@ struct rt2x00lib_ops { | |||
464 | */ | 505 | */ |
465 | int (*probe_hw) (struct rt2x00_dev *rt2x00dev); | 506 | int (*probe_hw) (struct rt2x00_dev *rt2x00dev); |
466 | char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev); | 507 | char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev); |
508 | u16 (*get_firmware_crc) (void *data, const size_t len); | ||
467 | int (*load_firmware) (struct rt2x00_dev *rt2x00dev, void *data, | 509 | int (*load_firmware) (struct rt2x00_dev *rt2x00dev, void *data, |
468 | const size_t len); | 510 | const size_t len); |
469 | 511 | ||
@@ -474,12 +516,12 @@ struct rt2x00lib_ops { | |||
474 | void (*uninitialize) (struct rt2x00_dev *rt2x00dev); | 516 | void (*uninitialize) (struct rt2x00_dev *rt2x00dev); |
475 | 517 | ||
476 | /* | 518 | /* |
477 | * Ring initialization handlers | 519 | * queue initialization handlers |
478 | */ | 520 | */ |
479 | void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, | 521 | void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, |
480 | struct data_entry *entry); | 522 | struct queue_entry *entry); |
481 | void (*init_txentry) (struct rt2x00_dev *rt2x00dev, | 523 | void (*init_txentry) (struct rt2x00_dev *rt2x00dev, |
482 | struct data_entry *entry); | 524 | struct queue_entry *entry); |
483 | 525 | ||
484 | /* | 526 | /* |
485 | * Radio control handlers. | 527 | * Radio control handlers. |
@@ -491,41 +533,46 @@ struct rt2x00lib_ops { | |||
491 | struct link_qual *qual); | 533 | struct link_qual *qual); |
492 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); | 534 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); |
493 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev); | 535 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev); |
536 | void (*led_brightness) (struct led_classdev *led_cdev, | ||
537 | enum led_brightness brightness); | ||
494 | 538 | ||
495 | /* | 539 | /* |
496 | * TX control handlers | 540 | * TX control handlers |
497 | */ | 541 | */ |
498 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, | 542 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, |
499 | struct sk_buff *skb, | 543 | struct sk_buff *skb, |
500 | struct txdata_entry_desc *desc, | 544 | struct txentry_desc *txdesc, |
501 | struct ieee80211_tx_control *control); | 545 | struct ieee80211_tx_control *control); |
502 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, | 546 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, |
503 | struct data_ring *ring, struct sk_buff *skb, | 547 | struct data_queue *queue, struct sk_buff *skb, |
504 | struct ieee80211_tx_control *control); | 548 | struct ieee80211_tx_control *control); |
505 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, | 549 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, |
506 | struct sk_buff *skb); | 550 | struct sk_buff *skb); |
507 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 551 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, |
508 | unsigned int queue); | 552 | const unsigned int queue); |
509 | 553 | ||
510 | /* | 554 | /* |
511 | * RX control handlers | 555 | * RX control handlers |
512 | */ | 556 | */ |
513 | void (*fill_rxdone) (struct data_entry *entry, | 557 | void (*fill_rxdone) (struct queue_entry *entry, |
514 | struct rxdata_entry_desc *desc); | 558 | struct rxdone_entry_desc *rxdesc); |
515 | 559 | ||
516 | /* | 560 | /* |
517 | * Configuration handlers. | 561 | * Configuration handlers. |
518 | */ | 562 | */ |
519 | void (*config_mac_addr) (struct rt2x00_dev *rt2x00dev, __le32 *mac); | 563 | void (*config_intf) (struct rt2x00_dev *rt2x00dev, |
520 | void (*config_bssid) (struct rt2x00_dev *rt2x00dev, __le32 *bssid); | 564 | struct rt2x00_intf *intf, |
521 | void (*config_type) (struct rt2x00_dev *rt2x00dev, const int type, | 565 | struct rt2x00intf_conf *conf, |
522 | const int tsf_sync); | 566 | const unsigned int flags); |
523 | void (*config_preamble) (struct rt2x00_dev *rt2x00dev, | 567 | #define CONFIG_UPDATE_TYPE ( 1 << 1 ) |
524 | const int short_preamble, | 568 | #define CONFIG_UPDATE_MAC ( 1 << 2 ) |
525 | const int ack_timeout, | 569 | #define CONFIG_UPDATE_BSSID ( 1 << 3 ) |
526 | const int ack_consume_time); | 570 | |
527 | void (*config) (struct rt2x00_dev *rt2x00dev, const unsigned int flags, | 571 | int (*config_erp) (struct rt2x00_dev *rt2x00dev, |
528 | struct rt2x00lib_conf *libconf); | 572 | struct rt2x00lib_erp *erp); |
573 | void (*config) (struct rt2x00_dev *rt2x00dev, | ||
574 | struct rt2x00lib_conf *libconf, | ||
575 | const unsigned int flags); | ||
529 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) | 576 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) |
530 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) | 577 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) |
531 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) | 578 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) |
@@ -540,10 +587,14 @@ struct rt2x00lib_ops { | |||
540 | */ | 587 | */ |
541 | struct rt2x00_ops { | 588 | struct rt2x00_ops { |
542 | const char *name; | 589 | const char *name; |
543 | const unsigned int rxd_size; | 590 | const unsigned int max_sta_intf; |
544 | const unsigned int txd_size; | 591 | const unsigned int max_ap_intf; |
545 | const unsigned int eeprom_size; | 592 | const unsigned int eeprom_size; |
546 | const unsigned int rf_size; | 593 | const unsigned int rf_size; |
594 | const struct data_queue_desc *rx; | ||
595 | const struct data_queue_desc *tx; | ||
596 | const struct data_queue_desc *bcn; | ||
597 | const struct data_queue_desc *atim; | ||
547 | const struct rt2x00lib_ops *lib; | 598 | const struct rt2x00lib_ops *lib; |
548 | const struct ieee80211_ops *hw; | 599 | const struct ieee80211_ops *hw; |
549 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 600 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
@@ -569,8 +620,10 @@ enum rt2x00_flags { | |||
569 | /* | 620 | /* |
570 | * Driver features | 621 | * Driver features |
571 | */ | 622 | */ |
623 | DRIVER_SUPPORT_MIXED_INTERFACES, | ||
572 | DRIVER_REQUIRE_FIRMWARE, | 624 | DRIVER_REQUIRE_FIRMWARE, |
573 | DRIVER_REQUIRE_BEACON_RING, | 625 | DRIVER_REQUIRE_BEACON_GUARD, |
626 | DRIVER_REQUIRE_ATIM_QUEUE, | ||
574 | 627 | ||
575 | /* | 628 | /* |
576 | * Driver configuration | 629 | * Driver configuration |
@@ -582,7 +635,6 @@ enum rt2x00_flags { | |||
582 | CONFIG_EXTERNAL_LNA_BG, | 635 | CONFIG_EXTERNAL_LNA_BG, |
583 | CONFIG_DOUBLE_ANTENNA, | 636 | CONFIG_DOUBLE_ANTENNA, |
584 | CONFIG_DISABLE_LINK_TUNING, | 637 | CONFIG_DISABLE_LINK_TUNING, |
585 | CONFIG_SHORT_PREAMBLE, | ||
586 | }; | 638 | }; |
587 | 639 | ||
588 | /* | 640 | /* |
@@ -597,8 +649,10 @@ struct rt2x00_dev { | |||
597 | * macro's should be used for correct typecasting. | 649 | * macro's should be used for correct typecasting. |
598 | */ | 650 | */ |
599 | void *dev; | 651 | void *dev; |
600 | #define rt2x00dev_pci(__dev) ( (struct pci_dev*)(__dev)->dev ) | 652 | #define rt2x00dev_pci(__dev) ( (struct pci_dev *)(__dev)->dev ) |
601 | #define rt2x00dev_usb(__dev) ( (struct usb_interface*)(__dev)->dev ) | 653 | #define rt2x00dev_usb(__dev) ( (struct usb_interface *)(__dev)->dev ) |
654 | #define rt2x00dev_usb_dev(__dev)\ | ||
655 | ( (struct usb_device *)interface_to_usbdev(rt2x00dev_usb(__dev)) ) | ||
602 | 656 | ||
603 | /* | 657 | /* |
604 | * Callback functions. | 658 | * Callback functions. |
@@ -609,11 +663,8 @@ struct rt2x00_dev { | |||
609 | * IEEE80211 control structure. | 663 | * IEEE80211 control structure. |
610 | */ | 664 | */ |
611 | struct ieee80211_hw *hw; | 665 | struct ieee80211_hw *hw; |
612 | struct ieee80211_hw_mode *hwmodes; | 666 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
613 | unsigned int curr_hwmode; | 667 | enum ieee80211_band curr_band; |
614 | #define HWMODE_B 0 | ||
615 | #define HWMODE_G 1 | ||
616 | #define HWMODE_A 2 | ||
617 | 668 | ||
618 | /* | 669 | /* |
619 | * rfkill structure for RF state switching support. | 670 | * rfkill structure for RF state switching support. |
@@ -636,6 +687,19 @@ unsigned long rfkill_state; | |||
636 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 687 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
637 | 688 | ||
638 | /* | 689 | /* |
690 | * LED structure for changing the LED status | ||
691 | * by mac8011 or the kernel. | ||
692 | */ | ||
693 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
694 | unsigned int led_flags; | ||
695 | struct rt2x00_trigger trigger_qual; | ||
696 | struct rt2x00_led led_radio; | ||
697 | struct rt2x00_led led_assoc; | ||
698 | struct rt2x00_led led_qual; | ||
699 | u16 led_mcu_reg; | ||
700 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
701 | |||
702 | /* | ||
639 | * Device flags. | 703 | * Device flags. |
640 | * In these flags the current status and some | 704 | * In these flags the current status and some |
641 | * of the device capabilities are stored. | 705 | * of the device capabilities are stored. |
@@ -661,11 +725,13 @@ unsigned long rfkill_state; | |||
661 | 725 | ||
662 | /* | 726 | /* |
663 | * Register pointers | 727 | * Register pointers |
664 | * csr_addr: Base register address. (PCI) | 728 | * csr.base: CSR base register address. (PCI) |
665 | * csr_cache: CSR cache for usb_control_msg. (USB) | 729 | * csr.cache: CSR cache for usb_control_msg. (USB) |
666 | */ | 730 | */ |
667 | void __iomem *csr_addr; | 731 | union csr { |
668 | void *csr_cache; | 732 | void __iomem *base; |
733 | void *cache; | ||
734 | } csr; | ||
669 | 735 | ||
670 | /* | 736 | /* |
671 | * Mutex to protect register accesses on USB devices. | 737 | * Mutex to protect register accesses on USB devices. |
@@ -687,9 +753,14 @@ unsigned long rfkill_state; | |||
687 | unsigned int packet_filter; | 753 | unsigned int packet_filter; |
688 | 754 | ||
689 | /* | 755 | /* |
690 | * Interface configuration. | 756 | * Interface details: |
757 | * - Open ap interface count. | ||
758 | * - Open sta interface count. | ||
759 | * - Association count. | ||
691 | */ | 760 | */ |
692 | struct interface interface; | 761 | unsigned int intf_ap_count; |
762 | unsigned int intf_sta_count; | ||
763 | unsigned int intf_associated; | ||
693 | 764 | ||
694 | /* | 765 | /* |
695 | * Link quality | 766 | * Link quality |
@@ -722,16 +793,6 @@ unsigned long rfkill_state; | |||
722 | u16 tx_power; | 793 | u16 tx_power; |
723 | 794 | ||
724 | /* | 795 | /* |
725 | * LED register (for rt61pci & rt73usb). | ||
726 | */ | ||
727 | u16 led_reg; | ||
728 | |||
729 | /* | ||
730 | * Led mode (LED_MODE_*) | ||
731 | */ | ||
732 | u8 led_mode; | ||
733 | |||
734 | /* | ||
735 | * Rssi <-> Dbm offset | 796 | * Rssi <-> Dbm offset |
736 | */ | 797 | */ |
737 | u8 rssi_offset; | 798 | u8 rssi_offset; |
@@ -755,19 +816,18 @@ unsigned long rfkill_state; | |||
755 | /* | 816 | /* |
756 | * Scheduled work. | 817 | * Scheduled work. |
757 | */ | 818 | */ |
758 | struct work_struct beacon_work; | 819 | struct work_struct intf_work; |
759 | struct work_struct filter_work; | 820 | struct work_struct filter_work; |
760 | struct work_struct config_work; | ||
761 | 821 | ||
762 | /* | 822 | /* |
763 | * Data ring arrays for RX, TX and Beacon. | 823 | * Data queue arrays for RX, TX and Beacon. |
764 | * The Beacon array also contains the Atim ring | 824 | * The Beacon array also contains the Atim queue |
765 | * if that is supported by the device. | 825 | * if that is supported by the device. |
766 | */ | 826 | */ |
767 | int data_rings; | 827 | int data_queues; |
768 | struct data_ring *rx; | 828 | struct data_queue *rx; |
769 | struct data_ring *tx; | 829 | struct data_queue *tx; |
770 | struct data_ring *bcn; | 830 | struct data_queue *bcn; |
771 | 831 | ||
772 | /* | 832 | /* |
773 | * Firmware image. | 833 | * Firmware image. |
@@ -776,37 +836,6 @@ unsigned long rfkill_state; | |||
776 | }; | 836 | }; |
777 | 837 | ||
778 | /* | 838 | /* |
779 | * For-each loop for the ring array. | ||
780 | * All rings have been allocated as a single array, | ||
781 | * this means we can create a very simply loop macro | ||
782 | * that is capable of looping through all rings. | ||
783 | * ring_end(), txring_end() and ring_loop() are helper macro's which | ||
784 | * should not be used directly. Instead the following should be used: | ||
785 | * ring_for_each() - Loops through all rings (RX, TX, Beacon & Atim) | ||
786 | * txring_for_each() - Loops through TX data rings (TX only) | ||
787 | * txringall_for_each() - Loops through all TX rings (TX, Beacon & Atim) | ||
788 | */ | ||
789 | #define ring_end(__dev) \ | ||
790 | &(__dev)->rx[(__dev)->data_rings] | ||
791 | |||
792 | #define txring_end(__dev) \ | ||
793 | &(__dev)->tx[(__dev)->hw->queues] | ||
794 | |||
795 | #define ring_loop(__entry, __start, __end) \ | ||
796 | for ((__entry) = (__start); \ | ||
797 | prefetch(&(__entry)[1]), (__entry) != (__end); \ | ||
798 | (__entry) = &(__entry)[1]) | ||
799 | |||
800 | #define ring_for_each(__dev, __entry) \ | ||
801 | ring_loop(__entry, (__dev)->rx, ring_end(__dev)) | ||
802 | |||
803 | #define txring_for_each(__dev, __entry) \ | ||
804 | ring_loop(__entry, (__dev)->tx, txring_end(__dev)) | ||
805 | |||
806 | #define txringall_for_each(__dev, __entry) \ | ||
807 | ring_loop(__entry, (__dev)->tx, ring_end(__dev)) | ||
808 | |||
809 | /* | ||
810 | * Generic RF access. | 839 | * Generic RF access. |
811 | * The RF is being accessed by word index. | 840 | * The RF is being accessed by word index. |
812 | */ | 841 | */ |
@@ -898,20 +927,43 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) | |||
898 | return ((size * 8 * 10) % rate); | 927 | return ((size * 8 * 10) % rate); |
899 | } | 928 | } |
900 | 929 | ||
901 | /* | 930 | /** |
902 | * Library functions. | 931 | * rt2x00queue_get_queue - Convert mac80211 queue index to rt2x00 queue |
932 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
933 | * @queue: mac80211/rt2x00 queue index | ||
934 | * (see &enum ieee80211_tx_queue and &enum rt2x00_bcn_queue). | ||
935 | */ | ||
936 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | ||
937 | const unsigned int queue); | ||
938 | |||
939 | /** | ||
940 | * rt2x00queue_get_entry - Get queue entry where the given index points to. | ||
941 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
942 | * @index: Index identifier for obtaining the correct index. | ||
943 | */ | ||
944 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, | ||
945 | enum queue_index index); | ||
946 | |||
947 | /** | ||
948 | * rt2x00queue_index_inc - Index incrementation function | ||
949 | * @queue: Queue (&struct data_queue) to perform the action on. | ||
950 | * @action: Index type (&enum queue_index) to perform the action on. | ||
951 | * | ||
952 | * This function will increase the requested index on the queue, | ||
953 | * it will grab the appropriate locks and handle queue overflow events by | ||
954 | * resetting the index to the start of the queue. | ||
903 | */ | 955 | */ |
904 | struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev, | 956 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); |
905 | const unsigned int queue); | 957 | |
906 | 958 | ||
907 | /* | 959 | /* |
908 | * Interrupt context handlers. | 960 | * Interrupt context handlers. |
909 | */ | 961 | */ |
910 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); | 962 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); |
911 | void rt2x00lib_txdone(struct data_entry *entry, | 963 | void rt2x00lib_txdone(struct queue_entry *entry, |
912 | const int status, const int retry); | 964 | struct txdone_entry_desc *txdesc); |
913 | void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | 965 | void rt2x00lib_rxdone(struct queue_entry *entry, |
914 | struct rxdata_entry_desc *desc); | 966 | struct rxdone_entry_desc *rxdesc); |
915 | 967 | ||
916 | /* | 968 | /* |
917 | * TX descriptor initializer | 969 | * TX descriptor initializer |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 07adc576db49..5e2d81a9e438 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -29,64 +29,86 @@ | |||
29 | #include "rt2x00.h" | 29 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | 32 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, | |
33 | /* | 33 | struct rt2x00_intf *intf, |
34 | * The MAC and BSSID addressess are simple array of bytes, | 34 | enum ieee80211_if_types type, |
35 | * these arrays are little endian, so when sending the addressess | 35 | u8 *mac, u8 *bssid) |
36 | * to the drivers, copy the it into a endian-signed variable. | ||
37 | * | ||
38 | * Note that all devices (except rt2500usb) have 32 bits | ||
39 | * register word sizes. This means that whatever variable we | ||
40 | * pass _must_ be a multiple of 32 bits. Otherwise the device | ||
41 | * might not accept what we are sending to it. | ||
42 | * This will also make it easier for the driver to write | ||
43 | * the data to the device. | ||
44 | * | ||
45 | * Also note that when NULL is passed as address the | ||
46 | * we will send 00:00:00:00:00 to the device to clear the address. | ||
47 | * This will prevent the device being confused when it wants | ||
48 | * to ACK frames or consideres itself associated. | ||
49 | */ | ||
50 | void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac) | ||
51 | { | 36 | { |
52 | __le32 reg[2]; | 37 | struct rt2x00intf_conf conf; |
38 | unsigned int flags = 0; | ||
53 | 39 | ||
54 | memset(®, 0, sizeof(reg)); | 40 | conf.type = type; |
55 | if (mac) | ||
56 | memcpy(®, mac, ETH_ALEN); | ||
57 | |||
58 | rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, ®[0]); | ||
59 | } | ||
60 | |||
61 | void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | ||
62 | { | ||
63 | __le32 reg[2]; | ||
64 | |||
65 | memset(®, 0, sizeof(reg)); | ||
66 | if (bssid) | ||
67 | memcpy(®, bssid, ETH_ALEN); | ||
68 | |||
69 | rt2x00dev->ops->lib->config_bssid(rt2x00dev, ®[0]); | ||
70 | } | ||
71 | |||
72 | void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type) | ||
73 | { | ||
74 | int tsf_sync; | ||
75 | 41 | ||
76 | switch (type) { | 42 | switch (type) { |
77 | case IEEE80211_IF_TYPE_IBSS: | 43 | case IEEE80211_IF_TYPE_IBSS: |
78 | case IEEE80211_IF_TYPE_AP: | 44 | case IEEE80211_IF_TYPE_AP: |
79 | tsf_sync = TSF_SYNC_BEACON; | 45 | conf.sync = TSF_SYNC_BEACON; |
80 | break; | 46 | break; |
81 | case IEEE80211_IF_TYPE_STA: | 47 | case IEEE80211_IF_TYPE_STA: |
82 | tsf_sync = TSF_SYNC_INFRA; | 48 | conf.sync = TSF_SYNC_INFRA; |
83 | break; | 49 | break; |
84 | default: | 50 | default: |
85 | tsf_sync = TSF_SYNC_NONE; | 51 | conf.sync = TSF_SYNC_NONE; |
86 | break; | 52 | break; |
87 | } | 53 | } |
88 | 54 | ||
89 | rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync); | 55 | /* |
56 | * Note that when NULL is passed as address we will send | ||
57 | * 00:00:00:00:00 to the device to clear the address. | ||
58 | * This will prevent the device being confused when it wants | ||
59 | * to ACK frames or consideres itself associated. | ||
60 | */ | ||
61 | memset(&conf.mac, 0, sizeof(conf.mac)); | ||
62 | if (mac) | ||
63 | memcpy(&conf.mac, mac, ETH_ALEN); | ||
64 | |||
65 | memset(&conf.bssid, 0, sizeof(conf.bssid)); | ||
66 | if (bssid) | ||
67 | memcpy(&conf.bssid, bssid, ETH_ALEN); | ||
68 | |||
69 | flags |= CONFIG_UPDATE_TYPE; | ||
70 | if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)) | ||
71 | flags |= CONFIG_UPDATE_MAC; | ||
72 | if (bssid || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)) | ||
73 | flags |= CONFIG_UPDATE_BSSID; | ||
74 | |||
75 | rt2x00dev->ops->lib->config_intf(rt2x00dev, intf, &conf, flags); | ||
76 | } | ||
77 | |||
78 | void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | ||
79 | struct rt2x00_intf *intf, | ||
80 | struct ieee80211_bss_conf *bss_conf) | ||
81 | { | ||
82 | struct rt2x00lib_erp erp; | ||
83 | int retval; | ||
84 | |||
85 | memset(&erp, 0, sizeof(erp)); | ||
86 | |||
87 | erp.short_preamble = bss_conf->use_short_preamble; | ||
88 | erp.ack_timeout = PLCP + get_duration(ACK_SIZE, 10); | ||
89 | erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); | ||
90 | |||
91 | if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) | ||
92 | erp.ack_timeout += SHORT_DIFS; | ||
93 | else | ||
94 | erp.ack_timeout += DIFS; | ||
95 | |||
96 | if (bss_conf->use_short_preamble) { | ||
97 | erp.ack_timeout += SHORT_PREAMBLE; | ||
98 | erp.ack_consume_time += SHORT_PREAMBLE; | ||
99 | } else { | ||
100 | erp.ack_timeout += PREAMBLE; | ||
101 | erp.ack_consume_time += PREAMBLE; | ||
102 | } | ||
103 | |||
104 | retval = rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); | ||
105 | |||
106 | if (retval) { | ||
107 | spin_lock(&intf->lock); | ||
108 | intf->delayed_flags |= DELAYED_CONFIG_ERP; | ||
109 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | ||
110 | spin_unlock(&intf->lock); | ||
111 | } | ||
90 | } | 112 | } |
91 | 113 | ||
92 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 114 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
@@ -113,7 +135,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
113 | * The latter is required since we need to recalibrate the | 135 | * The latter is required since we need to recalibrate the |
114 | * noise-sensitivity ratio for the new setup. | 136 | * noise-sensitivity ratio for the new setup. |
115 | */ | 137 | */ |
116 | rt2x00dev->ops->lib->config(rt2x00dev, CONFIG_UPDATE_ANTENNA, &libconf); | 138 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); |
117 | rt2x00lib_reset_link_tuner(rt2x00dev); | 139 | rt2x00lib_reset_link_tuner(rt2x00dev); |
118 | 140 | ||
119 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 141 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; |
@@ -123,12 +145,26 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
123 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); | 145 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); |
124 | } | 146 | } |
125 | 147 | ||
148 | static u32 rt2x00lib_get_basic_rates(struct ieee80211_supported_band *band) | ||
149 | { | ||
150 | const struct rt2x00_rate *rate; | ||
151 | unsigned int i; | ||
152 | u32 mask = 0; | ||
153 | |||
154 | for (i = 0; i < band->n_bitrates; i++) { | ||
155 | rate = rt2x00_get_rate(band->bitrates[i].hw_value); | ||
156 | if (rate->flags & DEV_RATE_BASIC) | ||
157 | mask |= rate->ratemask; | ||
158 | } | ||
159 | |||
160 | return mask; | ||
161 | } | ||
162 | |||
126 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 163 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
127 | struct ieee80211_conf *conf, const int force_config) | 164 | struct ieee80211_conf *conf, const int force_config) |
128 | { | 165 | { |
129 | struct rt2x00lib_conf libconf; | 166 | struct rt2x00lib_conf libconf; |
130 | struct ieee80211_hw_mode *mode; | 167 | struct ieee80211_supported_band *band; |
131 | struct ieee80211_rate *rate; | ||
132 | struct antenna_setup *default_ant = &rt2x00dev->default_ant; | 168 | struct antenna_setup *default_ant = &rt2x00dev->default_ant; |
133 | struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; | 169 | struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; |
134 | int flags = 0; | 170 | int flags = 0; |
@@ -147,9 +183,9 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
147 | * Check which configuration options have been | 183 | * Check which configuration options have been |
148 | * updated and should be send to the device. | 184 | * updated and should be send to the device. |
149 | */ | 185 | */ |
150 | if (rt2x00dev->rx_status.phymode != conf->phymode) | 186 | if (rt2x00dev->rx_status.band != conf->channel->band) |
151 | flags |= CONFIG_UPDATE_PHYMODE; | 187 | flags |= CONFIG_UPDATE_PHYMODE; |
152 | if (rt2x00dev->rx_status.channel != conf->channel) | 188 | if (rt2x00dev->rx_status.freq != conf->channel->center_freq) |
153 | flags |= CONFIG_UPDATE_CHANNEL; | 189 | flags |= CONFIG_UPDATE_CHANNEL; |
154 | if (rt2x00dev->tx_power != conf->power_level) | 190 | if (rt2x00dev->tx_power != conf->power_level) |
155 | flags |= CONFIG_UPDATE_TXPOWER; | 191 | flags |= CONFIG_UPDATE_TXPOWER; |
@@ -204,33 +240,15 @@ config: | |||
204 | memset(&libconf, 0, sizeof(libconf)); | 240 | memset(&libconf, 0, sizeof(libconf)); |
205 | 241 | ||
206 | if (flags & CONFIG_UPDATE_PHYMODE) { | 242 | if (flags & CONFIG_UPDATE_PHYMODE) { |
207 | switch (conf->phymode) { | 243 | band = &rt2x00dev->bands[conf->channel->band]; |
208 | case MODE_IEEE80211A: | 244 | |
209 | libconf.phymode = HWMODE_A; | 245 | libconf.band = conf->channel->band; |
210 | break; | 246 | libconf.basic_rates = rt2x00lib_get_basic_rates(band); |
211 | case MODE_IEEE80211B: | ||
212 | libconf.phymode = HWMODE_B; | ||
213 | break; | ||
214 | case MODE_IEEE80211G: | ||
215 | libconf.phymode = HWMODE_G; | ||
216 | break; | ||
217 | default: | ||
218 | ERROR(rt2x00dev, | ||
219 | "Attempt to configure unsupported mode (%d)" | ||
220 | "Defaulting to 802.11b", conf->phymode); | ||
221 | libconf.phymode = HWMODE_B; | ||
222 | } | ||
223 | |||
224 | mode = &rt2x00dev->hwmodes[libconf.phymode]; | ||
225 | rate = &mode->rates[mode->num_rates - 1]; | ||
226 | |||
227 | libconf.basic_rates = | ||
228 | DEVICE_GET_RATE_FIELD(rate->val, RATEMASK) & DEV_BASIC_RATEMASK; | ||
229 | } | 247 | } |
230 | 248 | ||
231 | if (flags & CONFIG_UPDATE_CHANNEL) { | 249 | if (flags & CONFIG_UPDATE_CHANNEL) { |
232 | memcpy(&libconf.rf, | 250 | memcpy(&libconf.rf, |
233 | &rt2x00dev->spec.channels[conf->channel_val], | 251 | &rt2x00dev->spec.channels[conf->channel->hw_value], |
234 | sizeof(libconf.rf)); | 252 | sizeof(libconf.rf)); |
235 | } | 253 | } |
236 | 254 | ||
@@ -266,7 +284,7 @@ config: | |||
266 | /* | 284 | /* |
267 | * Start configuration. | 285 | * Start configuration. |
268 | */ | 286 | */ |
269 | rt2x00dev->ops->lib->config(rt2x00dev, flags, &libconf); | 287 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, flags); |
270 | 288 | ||
271 | /* | 289 | /* |
272 | * Some configuration changes affect the link quality | 290 | * Some configuration changes affect the link quality |
@@ -276,12 +294,11 @@ config: | |||
276 | rt2x00lib_reset_link_tuner(rt2x00dev); | 294 | rt2x00lib_reset_link_tuner(rt2x00dev); |
277 | 295 | ||
278 | if (flags & CONFIG_UPDATE_PHYMODE) { | 296 | if (flags & CONFIG_UPDATE_PHYMODE) { |
279 | rt2x00dev->curr_hwmode = libconf.phymode; | 297 | rt2x00dev->curr_band = conf->channel->band; |
280 | rt2x00dev->rx_status.phymode = conf->phymode; | 298 | rt2x00dev->rx_status.band = conf->channel->band; |
281 | } | 299 | } |
282 | 300 | ||
283 | rt2x00dev->rx_status.freq = conf->freq; | 301 | rt2x00dev->rx_status.freq = conf->channel->center_freq; |
284 | rt2x00dev->rx_status.channel = conf->channel; | ||
285 | rt2x00dev->tx_power = conf->power_level; | 302 | rt2x00dev->tx_power = conf->power_level; |
286 | 303 | ||
287 | if (flags & CONFIG_UPDATE_ANTENNA) { | 304 | if (flags & CONFIG_UPDATE_ANTENNA) { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index b44a9f4b9b7f..bfab3b8780d6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -33,7 +33,7 @@ | |||
33 | #include "rt2x00lib.h" | 33 | #include "rt2x00lib.h" |
34 | #include "rt2x00dump.h" | 34 | #include "rt2x00dump.h" |
35 | 35 | ||
36 | #define PRINT_LINE_LEN_MAX 32 | 36 | #define MAX_LINE_LENGTH 64 |
37 | 37 | ||
38 | struct rt2x00debug_intf { | 38 | struct rt2x00debug_intf { |
39 | /* | 39 | /* |
@@ -60,8 +60,9 @@ struct rt2x00debug_intf { | |||
60 | * - eeprom offset/value files | 60 | * - eeprom offset/value files |
61 | * - bbp offset/value files | 61 | * - bbp offset/value files |
62 | * - rf offset/value files | 62 | * - rf offset/value files |
63 | * - frame dump folder | 63 | * - queue folder |
64 | * - frame dump file | 64 | * - frame dump file |
65 | * - queue stats file | ||
65 | */ | 66 | */ |
66 | struct dentry *driver_folder; | 67 | struct dentry *driver_folder; |
67 | struct dentry *driver_entry; | 68 | struct dentry *driver_entry; |
@@ -76,8 +77,9 @@ struct rt2x00debug_intf { | |||
76 | struct dentry *bbp_val_entry; | 77 | struct dentry *bbp_val_entry; |
77 | struct dentry *rf_off_entry; | 78 | struct dentry *rf_off_entry; |
78 | struct dentry *rf_val_entry; | 79 | struct dentry *rf_val_entry; |
79 | struct dentry *frame_folder; | 80 | struct dentry *queue_folder; |
80 | struct dentry *frame_dump_entry; | 81 | struct dentry *queue_frame_dump_entry; |
82 | struct dentry *queue_stats_entry; | ||
81 | 83 | ||
82 | /* | 84 | /* |
83 | * The frame dump file only allows a single reader, | 85 | * The frame dump file only allows a single reader, |
@@ -116,7 +118,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
116 | struct sk_buff *skb) | 118 | struct sk_buff *skb) |
117 | { | 119 | { |
118 | struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; | 120 | struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; |
119 | struct skb_desc *desc = get_skb_desc(skb); | 121 | struct skb_frame_desc *desc = get_skb_frame_desc(skb); |
120 | struct sk_buff *skbcopy; | 122 | struct sk_buff *skbcopy; |
121 | struct rt2x00dump_hdr *dump_hdr; | 123 | struct rt2x00dump_hdr *dump_hdr; |
122 | struct timeval timestamp; | 124 | struct timeval timestamp; |
@@ -147,7 +149,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
147 | dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); | 149 | dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); |
148 | dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); | 150 | dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); |
149 | dump_hdr->type = cpu_to_le16(desc->frame_type); | 151 | dump_hdr->type = cpu_to_le16(desc->frame_type); |
150 | dump_hdr->ring_index = desc->ring->queue_idx; | 152 | dump_hdr->queue_index = desc->entry->queue->qid; |
151 | dump_hdr->entry_index = desc->entry->entry_idx; | 153 | dump_hdr->entry_index = desc->entry->entry_idx; |
152 | dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); | 154 | dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); |
153 | dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); | 155 | dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); |
@@ -186,7 +188,7 @@ static int rt2x00debug_file_release(struct inode *inode, struct file *file) | |||
186 | return 0; | 188 | return 0; |
187 | } | 189 | } |
188 | 190 | ||
189 | static int rt2x00debug_open_ring_dump(struct inode *inode, struct file *file) | 191 | static int rt2x00debug_open_queue_dump(struct inode *inode, struct file *file) |
190 | { | 192 | { |
191 | struct rt2x00debug_intf *intf = inode->i_private; | 193 | struct rt2x00debug_intf *intf = inode->i_private; |
192 | int retval; | 194 | int retval; |
@@ -203,7 +205,7 @@ static int rt2x00debug_open_ring_dump(struct inode *inode, struct file *file) | |||
203 | return 0; | 205 | return 0; |
204 | } | 206 | } |
205 | 207 | ||
206 | static int rt2x00debug_release_ring_dump(struct inode *inode, struct file *file) | 208 | static int rt2x00debug_release_queue_dump(struct inode *inode, struct file *file) |
207 | { | 209 | { |
208 | struct rt2x00debug_intf *intf = inode->i_private; | 210 | struct rt2x00debug_intf *intf = inode->i_private; |
209 | 211 | ||
@@ -214,10 +216,10 @@ static int rt2x00debug_release_ring_dump(struct inode *inode, struct file *file) | |||
214 | return rt2x00debug_file_release(inode, file); | 216 | return rt2x00debug_file_release(inode, file); |
215 | } | 217 | } |
216 | 218 | ||
217 | static ssize_t rt2x00debug_read_ring_dump(struct file *file, | 219 | static ssize_t rt2x00debug_read_queue_dump(struct file *file, |
218 | char __user *buf, | 220 | char __user *buf, |
219 | size_t length, | 221 | size_t length, |
220 | loff_t *offset) | 222 | loff_t *offset) |
221 | { | 223 | { |
222 | struct rt2x00debug_intf *intf = file->private_data; | 224 | struct rt2x00debug_intf *intf = file->private_data; |
223 | struct sk_buff *skb; | 225 | struct sk_buff *skb; |
@@ -248,8 +250,8 @@ exit: | |||
248 | return status; | 250 | return status; |
249 | } | 251 | } |
250 | 252 | ||
251 | static unsigned int rt2x00debug_poll_ring_dump(struct file *file, | 253 | static unsigned int rt2x00debug_poll_queue_dump(struct file *file, |
252 | poll_table *wait) | 254 | poll_table *wait) |
253 | { | 255 | { |
254 | struct rt2x00debug_intf *intf = file->private_data; | 256 | struct rt2x00debug_intf *intf = file->private_data; |
255 | 257 | ||
@@ -261,12 +263,68 @@ static unsigned int rt2x00debug_poll_ring_dump(struct file *file, | |||
261 | return 0; | 263 | return 0; |
262 | } | 264 | } |
263 | 265 | ||
264 | static const struct file_operations rt2x00debug_fop_ring_dump = { | 266 | static const struct file_operations rt2x00debug_fop_queue_dump = { |
265 | .owner = THIS_MODULE, | 267 | .owner = THIS_MODULE, |
266 | .read = rt2x00debug_read_ring_dump, | 268 | .read = rt2x00debug_read_queue_dump, |
267 | .poll = rt2x00debug_poll_ring_dump, | 269 | .poll = rt2x00debug_poll_queue_dump, |
268 | .open = rt2x00debug_open_ring_dump, | 270 | .open = rt2x00debug_open_queue_dump, |
269 | .release = rt2x00debug_release_ring_dump, | 271 | .release = rt2x00debug_release_queue_dump, |
272 | }; | ||
273 | |||
274 | static ssize_t rt2x00debug_read_queue_stats(struct file *file, | ||
275 | char __user *buf, | ||
276 | size_t length, | ||
277 | loff_t *offset) | ||
278 | { | ||
279 | struct rt2x00debug_intf *intf = file->private_data; | ||
280 | struct data_queue *queue; | ||
281 | unsigned long irqflags; | ||
282 | unsigned int lines = 1 + intf->rt2x00dev->data_queues; | ||
283 | size_t size; | ||
284 | char *data; | ||
285 | char *temp; | ||
286 | |||
287 | if (*offset) | ||
288 | return 0; | ||
289 | |||
290 | data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL); | ||
291 | if (!data) | ||
292 | return -ENOMEM; | ||
293 | |||
294 | temp = data + | ||
295 | sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n"); | ||
296 | |||
297 | queue_for_each(intf->rt2x00dev, queue) { | ||
298 | spin_lock_irqsave(&queue->lock, irqflags); | ||
299 | |||
300 | temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, | ||
301 | queue->count, queue->limit, queue->length, | ||
302 | queue->index[Q_INDEX], | ||
303 | queue->index[Q_INDEX_DONE], | ||
304 | queue->index[Q_INDEX_CRYPTO]); | ||
305 | |||
306 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
307 | } | ||
308 | |||
309 | size = strlen(data); | ||
310 | size = min(size, length); | ||
311 | |||
312 | if (copy_to_user(buf, data, size)) { | ||
313 | kfree(data); | ||
314 | return -EFAULT; | ||
315 | } | ||
316 | |||
317 | kfree(data); | ||
318 | |||
319 | *offset += size; | ||
320 | return size; | ||
321 | } | ||
322 | |||
323 | static const struct file_operations rt2x00debug_fop_queue_stats = { | ||
324 | .owner = THIS_MODULE, | ||
325 | .read = rt2x00debug_read_queue_stats, | ||
326 | .open = rt2x00debug_file_open, | ||
327 | .release = rt2x00debug_file_release, | ||
270 | }; | 328 | }; |
271 | 329 | ||
272 | #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ | 330 | #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ |
@@ -386,7 +444,7 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name, | |||
386 | { | 444 | { |
387 | char *data; | 445 | char *data; |
388 | 446 | ||
389 | data = kzalloc(3 * PRINT_LINE_LEN_MAX, GFP_KERNEL); | 447 | data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL); |
390 | if (!data) | 448 | if (!data) |
391 | return NULL; | 449 | return NULL; |
392 | 450 | ||
@@ -409,7 +467,7 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name, | |||
409 | const struct rt2x00debug *debug = intf->debug; | 467 | const struct rt2x00debug *debug = intf->debug; |
410 | char *data; | 468 | char *data; |
411 | 469 | ||
412 | data = kzalloc(8 * PRINT_LINE_LEN_MAX, GFP_KERNEL); | 470 | data = kzalloc(8 * MAX_LINE_LENGTH, GFP_KERNEL); |
413 | if (!data) | 471 | if (!data) |
414 | return NULL; | 472 | return NULL; |
415 | 473 | ||
@@ -496,20 +554,24 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
496 | 554 | ||
497 | #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY | 555 | #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY |
498 | 556 | ||
499 | intf->frame_folder = | 557 | intf->queue_folder = |
500 | debugfs_create_dir("frame", intf->driver_folder); | 558 | debugfs_create_dir("queue", intf->driver_folder); |
501 | if (IS_ERR(intf->frame_folder)) | 559 | if (IS_ERR(intf->queue_folder)) |
502 | goto exit; | 560 | goto exit; |
503 | 561 | ||
504 | intf->frame_dump_entry = | 562 | intf->queue_frame_dump_entry = |
505 | debugfs_create_file("dump", S_IRUGO, intf->frame_folder, | 563 | debugfs_create_file("dump", S_IRUGO, intf->queue_folder, |
506 | intf, &rt2x00debug_fop_ring_dump); | 564 | intf, &rt2x00debug_fop_queue_dump); |
507 | if (IS_ERR(intf->frame_dump_entry)) | 565 | if (IS_ERR(intf->queue_frame_dump_entry)) |
508 | goto exit; | 566 | goto exit; |
509 | 567 | ||
510 | skb_queue_head_init(&intf->frame_dump_skbqueue); | 568 | skb_queue_head_init(&intf->frame_dump_skbqueue); |
511 | init_waitqueue_head(&intf->frame_dump_waitqueue); | 569 | init_waitqueue_head(&intf->frame_dump_waitqueue); |
512 | 570 | ||
571 | intf->queue_stats_entry = | ||
572 | debugfs_create_file("queue", S_IRUGO, intf->queue_folder, | ||
573 | intf, &rt2x00debug_fop_queue_stats); | ||
574 | |||
513 | return; | 575 | return; |
514 | 576 | ||
515 | exit: | 577 | exit: |
@@ -528,8 +590,9 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) | |||
528 | 590 | ||
529 | skb_queue_purge(&intf->frame_dump_skbqueue); | 591 | skb_queue_purge(&intf->frame_dump_skbqueue); |
530 | 592 | ||
531 | debugfs_remove(intf->frame_dump_entry); | 593 | debugfs_remove(intf->queue_stats_entry); |
532 | debugfs_remove(intf->frame_folder); | 594 | debugfs_remove(intf->queue_frame_dump_entry); |
595 | debugfs_remove(intf->queue_folder); | ||
533 | debugfs_remove(intf->rf_val_entry); | 596 | debugfs_remove(intf->rf_val_entry); |
534 | debugfs_remove(intf->rf_off_entry); | 597 | debugfs_remove(intf->rf_off_entry); |
535 | debugfs_remove(intf->bbp_val_entry); | 598 | debugfs_remove(intf->bbp_val_entry); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h index d37efbd09c41..c4ce895aa1c7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.h +++ b/drivers/net/wireless/rt2x00/rt2x00debug.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index bd305f7f3efd..acf4d67ba43d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -31,34 +31,6 @@ | |||
31 | #include "rt2x00dump.h" | 31 | #include "rt2x00dump.h" |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Ring handler. | ||
35 | */ | ||
36 | struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev, | ||
37 | const unsigned int queue) | ||
38 | { | ||
39 | int beacon = test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | ||
40 | |||
41 | /* | ||
42 | * Check if we are requesting a reqular TX ring, | ||
43 | * or if we are requesting a Beacon or Atim ring. | ||
44 | * For Atim rings, we should check if it is supported. | ||
45 | */ | ||
46 | if (queue < rt2x00dev->hw->queues && rt2x00dev->tx) | ||
47 | return &rt2x00dev->tx[queue]; | ||
48 | |||
49 | if (!rt2x00dev->bcn || !beacon) | ||
50 | return NULL; | ||
51 | |||
52 | if (queue == IEEE80211_TX_QUEUE_BEACON) | ||
53 | return &rt2x00dev->bcn[0]; | ||
54 | else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
55 | return &rt2x00dev->bcn[1]; | ||
56 | |||
57 | return NULL; | ||
58 | } | ||
59 | EXPORT_SYMBOL_GPL(rt2x00lib_get_ring); | ||
60 | |||
61 | /* | ||
62 | * Link tuning handlers | 34 | * Link tuning handlers |
63 | */ | 35 | */ |
64 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) | 36 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) |
@@ -113,46 +85,6 @@ static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
113 | } | 85 | } |
114 | 86 | ||
115 | /* | 87 | /* |
116 | * Ring initialization | ||
117 | */ | ||
118 | static void rt2x00lib_init_rxrings(struct rt2x00_dev *rt2x00dev) | ||
119 | { | ||
120 | struct data_ring *ring = rt2x00dev->rx; | ||
121 | unsigned int i; | ||
122 | |||
123 | if (!rt2x00dev->ops->lib->init_rxentry) | ||
124 | return; | ||
125 | |||
126 | if (ring->data_addr) | ||
127 | memset(ring->data_addr, 0, rt2x00_get_ring_size(ring)); | ||
128 | |||
129 | for (i = 0; i < ring->stats.limit; i++) | ||
130 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, &ring->entry[i]); | ||
131 | |||
132 | rt2x00_ring_index_clear(ring); | ||
133 | } | ||
134 | |||
135 | static void rt2x00lib_init_txrings(struct rt2x00_dev *rt2x00dev) | ||
136 | { | ||
137 | struct data_ring *ring; | ||
138 | unsigned int i; | ||
139 | |||
140 | if (!rt2x00dev->ops->lib->init_txentry) | ||
141 | return; | ||
142 | |||
143 | txringall_for_each(rt2x00dev, ring) { | ||
144 | if (ring->data_addr) | ||
145 | memset(ring->data_addr, 0, rt2x00_get_ring_size(ring)); | ||
146 | |||
147 | for (i = 0; i < ring->stats.limit; i++) | ||
148 | rt2x00dev->ops->lib->init_txentry(rt2x00dev, | ||
149 | &ring->entry[i]); | ||
150 | |||
151 | rt2x00_ring_index_clear(ring); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Radio control handlers. | 88 | * Radio control handlers. |
157 | */ | 89 | */ |
158 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | 90 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) |
@@ -168,10 +100,10 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
168 | return 0; | 100 | return 0; |
169 | 101 | ||
170 | /* | 102 | /* |
171 | * Initialize all data rings. | 103 | * Initialize all data queues. |
172 | */ | 104 | */ |
173 | rt2x00lib_init_rxrings(rt2x00dev); | 105 | rt2x00queue_init_rx(rt2x00dev); |
174 | rt2x00lib_init_txrings(rt2x00dev); | 106 | rt2x00queue_init_tx(rt2x00dev); |
175 | 107 | ||
176 | /* | 108 | /* |
177 | * Enable radio. | 109 | * Enable radio. |
@@ -204,12 +136,10 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
204 | /* | 136 | /* |
205 | * Stop all scheduled work. | 137 | * Stop all scheduled work. |
206 | */ | 138 | */ |
207 | if (work_pending(&rt2x00dev->beacon_work)) | 139 | if (work_pending(&rt2x00dev->intf_work)) |
208 | cancel_work_sync(&rt2x00dev->beacon_work); | 140 | cancel_work_sync(&rt2x00dev->intf_work); |
209 | if (work_pending(&rt2x00dev->filter_work)) | 141 | if (work_pending(&rt2x00dev->filter_work)) |
210 | cancel_work_sync(&rt2x00dev->filter_work); | 142 | cancel_work_sync(&rt2x00dev->filter_work); |
211 | if (work_pending(&rt2x00dev->config_work)) | ||
212 | cancel_work_sync(&rt2x00dev->config_work); | ||
213 | 143 | ||
214 | /* | 144 | /* |
215 | * Stop the TX queues. | 145 | * Stop the TX queues. |
@@ -241,7 +171,7 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
241 | * When we are enabling the RX, we should also start the link tuner. | 171 | * When we are enabling the RX, we should also start the link tuner. |
242 | */ | 172 | */ |
243 | if (state == STATE_RADIO_RX_ON && | 173 | if (state == STATE_RADIO_RX_ON && |
244 | is_interface_present(&rt2x00dev->interface)) | 174 | (rt2x00dev->intf_ap_count || rt2x00dev->intf_sta_count)) |
245 | rt2x00lib_start_link_tuner(rt2x00dev); | 175 | rt2x00lib_start_link_tuner(rt2x00dev); |
246 | } | 176 | } |
247 | 177 | ||
@@ -449,6 +379,11 @@ static void rt2x00lib_link_tuner(struct work_struct *work) | |||
449 | rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); | 379 | rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); |
450 | 380 | ||
451 | /* | 381 | /* |
382 | * Send a signal to the led to update the led signal strength. | ||
383 | */ | ||
384 | rt2x00leds_led_quality(rt2x00dev, rt2x00dev->link.qual.avg_rssi); | ||
385 | |||
386 | /* | ||
452 | * Evaluate antenna setup, make this the last step since this could | 387 | * Evaluate antenna setup, make this the last step since this could |
453 | * possibly reset some statistics. | 388 | * possibly reset some statistics. |
454 | */ | 389 | */ |
@@ -469,10 +404,10 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | |||
469 | unsigned int filter = rt2x00dev->packet_filter; | 404 | unsigned int filter = rt2x00dev->packet_filter; |
470 | 405 | ||
471 | /* | 406 | /* |
472 | * Since we had stored the filter inside interface.filter, | 407 | * Since we had stored the filter inside rt2x00dev->packet_filter, |
473 | * we should now clear that field. Otherwise the driver will | 408 | * we should now clear that field. Otherwise the driver will |
474 | * assume nothing has changed (*total_flags will be compared | 409 | * assume nothing has changed (*total_flags will be compared |
475 | * to interface.filter to determine if any action is required). | 410 | * to rt2x00dev->packet_filter to determine if any action is required). |
476 | */ | 411 | */ |
477 | rt2x00dev->packet_filter = 0; | 412 | rt2x00dev->packet_filter = 0; |
478 | 413 | ||
@@ -480,45 +415,71 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | |||
480 | filter, &filter, 0, NULL); | 415 | filter, &filter, 0, NULL); |
481 | } | 416 | } |
482 | 417 | ||
483 | static void rt2x00lib_configuration_scheduled(struct work_struct *work) | 418 | static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, |
419 | struct ieee80211_vif *vif) | ||
484 | { | 420 | { |
485 | struct rt2x00_dev *rt2x00dev = | 421 | struct rt2x00_dev *rt2x00dev = data; |
486 | container_of(work, struct rt2x00_dev, config_work); | 422 | struct rt2x00_intf *intf = vif_to_intf(vif); |
487 | struct ieee80211_bss_conf bss_conf; | 423 | struct sk_buff *skb; |
424 | struct ieee80211_tx_control control; | ||
425 | struct ieee80211_bss_conf conf; | ||
426 | int delayed_flags; | ||
427 | |||
428 | /* | ||
429 | * Copy all data we need during this action under the protection | ||
430 | * of a spinlock. Otherwise race conditions might occur which results | ||
431 | * into an invalid configuration. | ||
432 | */ | ||
433 | spin_lock(&intf->lock); | ||
434 | |||
435 | memcpy(&conf, &intf->conf, sizeof(conf)); | ||
436 | delayed_flags = intf->delayed_flags; | ||
437 | intf->delayed_flags = 0; | ||
438 | |||
439 | spin_unlock(&intf->lock); | ||
440 | |||
441 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | ||
442 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); | ||
443 | if (skb) { | ||
444 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | ||
445 | &control); | ||
446 | dev_kfree_skb(skb); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if (delayed_flags & DELAYED_CONFIG_ERP) | ||
451 | rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf); | ||
452 | } | ||
488 | 453 | ||
489 | bss_conf.use_short_preamble = | 454 | static void rt2x00lib_intf_scheduled(struct work_struct *work) |
490 | test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 455 | { |
456 | struct rt2x00_dev *rt2x00dev = | ||
457 | container_of(work, struct rt2x00_dev, intf_work); | ||
491 | 458 | ||
492 | /* | 459 | /* |
493 | * FIXME: shouldn't invoke it this way because all other contents | 460 | * Iterate over each interface and perform the |
494 | * of bss_conf is invalid. | 461 | * requested configurations. |
495 | */ | 462 | */ |
496 | rt2x00mac_bss_info_changed(rt2x00dev->hw, rt2x00dev->interface.id, | 463 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
497 | &bss_conf, BSS_CHANGED_ERP_PREAMBLE); | 464 | rt2x00lib_intf_scheduled_iter, |
465 | rt2x00dev); | ||
498 | } | 466 | } |
499 | 467 | ||
500 | /* | 468 | /* |
501 | * Interrupt context handlers. | 469 | * Interrupt context handlers. |
502 | */ | 470 | */ |
503 | static void rt2x00lib_beacondone_scheduled(struct work_struct *work) | 471 | static void rt2x00lib_beacondone_iter(void *data, u8 *mac, |
472 | struct ieee80211_vif *vif) | ||
504 | { | 473 | { |
505 | struct rt2x00_dev *rt2x00dev = | 474 | struct rt2x00_intf *intf = vif_to_intf(vif); |
506 | container_of(work, struct rt2x00_dev, beacon_work); | ||
507 | struct data_ring *ring = | ||
508 | rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
509 | struct data_entry *entry = rt2x00_get_data_entry(ring); | ||
510 | struct sk_buff *skb; | ||
511 | 475 | ||
512 | skb = ieee80211_beacon_get(rt2x00dev->hw, | 476 | if (vif->type != IEEE80211_IF_TYPE_AP && |
513 | rt2x00dev->interface.id, | 477 | vif->type != IEEE80211_IF_TYPE_IBSS) |
514 | &entry->tx_status.control); | ||
515 | if (!skb) | ||
516 | return; | 478 | return; |
517 | 479 | ||
518 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | 480 | spin_lock(&intf->lock); |
519 | &entry->tx_status.control); | 481 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; |
520 | 482 | spin_unlock(&intf->lock); | |
521 | dev_kfree_skb(skb); | ||
522 | } | 483 | } |
523 | 484 | ||
524 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | 485 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) |
@@ -526,89 +487,102 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
526 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 487 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
527 | return; | 488 | return; |
528 | 489 | ||
529 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->beacon_work); | 490 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
491 | rt2x00lib_beacondone_iter, | ||
492 | rt2x00dev); | ||
493 | |||
494 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | ||
530 | } | 495 | } |
531 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 496 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
532 | 497 | ||
533 | void rt2x00lib_txdone(struct data_entry *entry, | 498 | void rt2x00lib_txdone(struct queue_entry *entry, |
534 | const int status, const int retry) | 499 | struct txdone_entry_desc *txdesc) |
535 | { | 500 | { |
536 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | 501 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
537 | struct ieee80211_tx_status *tx_status = &entry->tx_status; | 502 | struct skb_frame_desc *skbdesc; |
538 | struct ieee80211_low_level_stats *stats = &rt2x00dev->low_level_stats; | 503 | struct ieee80211_tx_status tx_status; |
539 | int success = !!(status == TX_SUCCESS || status == TX_SUCCESS_RETRY); | 504 | int success = !!(txdesc->status == TX_SUCCESS || |
540 | int fail = !!(status == TX_FAIL_RETRY || status == TX_FAIL_INVALID || | 505 | txdesc->status == TX_SUCCESS_RETRY); |
541 | status == TX_FAIL_OTHER); | 506 | int fail = !!(txdesc->status == TX_FAIL_RETRY || |
507 | txdesc->status == TX_FAIL_INVALID || | ||
508 | txdesc->status == TX_FAIL_OTHER); | ||
542 | 509 | ||
543 | /* | 510 | /* |
544 | * Update TX statistics. | 511 | * Update TX statistics. |
545 | */ | 512 | */ |
546 | tx_status->flags = 0; | ||
547 | tx_status->ack_signal = 0; | ||
548 | tx_status->excessive_retries = (status == TX_FAIL_RETRY); | ||
549 | tx_status->retry_count = retry; | ||
550 | rt2x00dev->link.qual.tx_success += success; | 513 | rt2x00dev->link.qual.tx_success += success; |
551 | rt2x00dev->link.qual.tx_failed += retry + fail; | 514 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; |
552 | 515 | ||
553 | if (!(tx_status->control.flags & IEEE80211_TXCTL_NO_ACK)) { | 516 | /* |
517 | * Initialize TX status | ||
518 | */ | ||
519 | tx_status.flags = 0; | ||
520 | tx_status.ack_signal = 0; | ||
521 | tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY); | ||
522 | tx_status.retry_count = txdesc->retry; | ||
523 | memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control)); | ||
524 | |||
525 | if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { | ||
554 | if (success) | 526 | if (success) |
555 | tx_status->flags |= IEEE80211_TX_STATUS_ACK; | 527 | tx_status.flags |= IEEE80211_TX_STATUS_ACK; |
556 | else | 528 | else |
557 | stats->dot11ACKFailureCount++; | 529 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; |
558 | } | 530 | } |
559 | 531 | ||
560 | tx_status->queue_length = entry->ring->stats.limit; | 532 | tx_status.queue_length = entry->queue->limit; |
561 | tx_status->queue_number = tx_status->control.queue; | 533 | tx_status.queue_number = tx_status.control.queue; |
562 | 534 | ||
563 | if (tx_status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 535 | if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
564 | if (success) | 536 | if (success) |
565 | stats->dot11RTSSuccessCount++; | 537 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; |
566 | else | 538 | else |
567 | stats->dot11RTSFailureCount++; | 539 | rt2x00dev->low_level_stats.dot11RTSFailureCount++; |
568 | } | 540 | } |
569 | 541 | ||
570 | /* | 542 | /* |
571 | * Send the tx_status to mac80211 & debugfs. | 543 | * Send the tx_status to debugfs. Only send the status report |
572 | * mac80211 will clean up the skb structure. | 544 | * to mac80211 when the frame originated from there. If this was |
545 | * a extra frame coming through a mac80211 library call (RTS/CTS) | ||
546 | * then we should not send the status report back. | ||
547 | * If send to mac80211, mac80211 will clean up the skb structure, | ||
548 | * otherwise we have to do it ourself. | ||
573 | */ | 549 | */ |
574 | get_skb_desc(entry->skb)->frame_type = DUMP_FRAME_TXDONE; | 550 | skbdesc = get_skb_frame_desc(entry->skb); |
551 | skbdesc->frame_type = DUMP_FRAME_TXDONE; | ||
552 | |||
575 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); | 553 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); |
576 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, tx_status); | 554 | |
555 | if (!(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED)) | ||
556 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, | ||
557 | entry->skb, &tx_status); | ||
558 | else | ||
559 | dev_kfree_skb(entry->skb); | ||
577 | entry->skb = NULL; | 560 | entry->skb = NULL; |
578 | } | 561 | } |
579 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 562 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
580 | 563 | ||
581 | void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | 564 | void rt2x00lib_rxdone(struct queue_entry *entry, |
582 | struct rxdata_entry_desc *desc) | 565 | struct rxdone_entry_desc *rxdesc) |
583 | { | 566 | { |
584 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | 567 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
585 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 568 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; |
586 | struct ieee80211_hw_mode *mode; | 569 | struct ieee80211_supported_band *sband; |
587 | struct ieee80211_rate *rate; | ||
588 | struct ieee80211_hdr *hdr; | 570 | struct ieee80211_hdr *hdr; |
571 | const struct rt2x00_rate *rate; | ||
589 | unsigned int i; | 572 | unsigned int i; |
590 | int val = 0; | 573 | int idx = -1; |
591 | u16 fc; | 574 | u16 fc; |
592 | 575 | ||
593 | /* | 576 | /* |
594 | * Update RX statistics. | 577 | * Update RX statistics. |
595 | */ | 578 | */ |
596 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | 579 | sband = &rt2x00dev->bands[rt2x00dev->curr_band]; |
597 | for (i = 0; i < mode->num_rates; i++) { | 580 | for (i = 0; i < sband->n_bitrates; i++) { |
598 | rate = &mode->rates[i]; | 581 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); |
599 | |||
600 | /* | ||
601 | * When frame was received with an OFDM bitrate, | ||
602 | * the signal is the PLCP value. If it was received with | ||
603 | * a CCK bitrate the signal is the rate in 0.5kbit/s. | ||
604 | */ | ||
605 | if (!desc->ofdm) | ||
606 | val = DEVICE_GET_RATE_FIELD(rate->val, RATE); | ||
607 | else | ||
608 | val = DEVICE_GET_RATE_FIELD(rate->val, PLCP); | ||
609 | 582 | ||
610 | if (val == desc->signal) { | 583 | if ((rxdesc->signal_plcp && rate->plcp == rxdesc->signal) || |
611 | val = rate->val; | 584 | (!rxdesc->signal_plcp && rate->bitrate == rxdesc->signal)) { |
585 | idx = i; | ||
612 | break; | 586 | break; |
613 | } | 587 | } |
614 | } | 588 | } |
@@ -616,26 +590,28 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | |||
616 | /* | 590 | /* |
617 | * Only update link status if this is a beacon frame carrying our bssid. | 591 | * Only update link status if this is a beacon frame carrying our bssid. |
618 | */ | 592 | */ |
619 | hdr = (struct ieee80211_hdr*)skb->data; | 593 | hdr = (struct ieee80211_hdr *)entry->skb->data; |
620 | fc = le16_to_cpu(hdr->frame_control); | 594 | fc = le16_to_cpu(hdr->frame_control); |
621 | if (is_beacon(fc) && desc->my_bss) | 595 | if (is_beacon(fc) && rxdesc->my_bss) |
622 | rt2x00lib_update_link_stats(&rt2x00dev->link, desc->rssi); | 596 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); |
623 | 597 | ||
624 | rt2x00dev->link.qual.rx_success++; | 598 | rt2x00dev->link.qual.rx_success++; |
625 | 599 | ||
626 | rx_status->rate = val; | 600 | rx_status->rate_idx = idx; |
627 | rx_status->signal = | 601 | rx_status->signal = |
628 | rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi); | 602 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); |
629 | rx_status->ssi = desc->rssi; | 603 | rx_status->ssi = rxdesc->rssi; |
630 | rx_status->flag = desc->flags; | 604 | rx_status->flag = rxdesc->flags; |
631 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 605 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
632 | 606 | ||
633 | /* | 607 | /* |
634 | * Send frame to mac80211 & debugfs | 608 | * Send frame to mac80211 & debugfs. |
609 | * mac80211 will clean up the skb structure. | ||
635 | */ | 610 | */ |
636 | get_skb_desc(skb)->frame_type = DUMP_FRAME_RXDONE; | 611 | get_skb_frame_desc(entry->skb)->frame_type = DUMP_FRAME_RXDONE; |
637 | rt2x00debug_dump_frame(rt2x00dev, skb); | 612 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); |
638 | ieee80211_rx_irqsafe(rt2x00dev->hw, skb, rx_status); | 613 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); |
614 | entry->skb = NULL; | ||
639 | } | 615 | } |
640 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 616 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |
641 | 617 | ||
@@ -646,83 +622,69 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
646 | struct sk_buff *skb, | 622 | struct sk_buff *skb, |
647 | struct ieee80211_tx_control *control) | 623 | struct ieee80211_tx_control *control) |
648 | { | 624 | { |
649 | struct txdata_entry_desc desc; | 625 | struct txentry_desc txdesc; |
650 | struct skb_desc *skbdesc = get_skb_desc(skb); | 626 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
651 | struct ieee80211_hdr *ieee80211hdr = skbdesc->data; | 627 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skbdesc->data; |
628 | const struct rt2x00_rate *rate; | ||
652 | int tx_rate; | 629 | int tx_rate; |
653 | int bitrate; | ||
654 | int length; | 630 | int length; |
655 | int duration; | 631 | int duration; |
656 | int residual; | 632 | int residual; |
657 | u16 frame_control; | 633 | u16 frame_control; |
658 | u16 seq_ctrl; | 634 | u16 seq_ctrl; |
659 | 635 | ||
660 | memset(&desc, 0, sizeof(desc)); | 636 | memset(&txdesc, 0, sizeof(txdesc)); |
661 | 637 | ||
662 | desc.cw_min = skbdesc->ring->tx_params.cw_min; | 638 | txdesc.queue = skbdesc->entry->queue->qid; |
663 | desc.cw_max = skbdesc->ring->tx_params.cw_max; | 639 | txdesc.cw_min = skbdesc->entry->queue->cw_min; |
664 | desc.aifs = skbdesc->ring->tx_params.aifs; | 640 | txdesc.cw_max = skbdesc->entry->queue->cw_max; |
665 | 641 | txdesc.aifs = skbdesc->entry->queue->aifs; | |
666 | /* | ||
667 | * Identify queue | ||
668 | */ | ||
669 | if (control->queue < rt2x00dev->hw->queues) | ||
670 | desc.queue = control->queue; | ||
671 | else if (control->queue == IEEE80211_TX_QUEUE_BEACON || | ||
672 | control->queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
673 | desc.queue = QUEUE_MGMT; | ||
674 | else | ||
675 | desc.queue = QUEUE_OTHER; | ||
676 | 642 | ||
677 | /* | 643 | /* |
678 | * Read required fields from ieee80211 header. | 644 | * Read required fields from ieee80211 header. |
679 | */ | 645 | */ |
680 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); | 646 | frame_control = le16_to_cpu(hdr->frame_control); |
681 | seq_ctrl = le16_to_cpu(ieee80211hdr->seq_ctrl); | 647 | seq_ctrl = le16_to_cpu(hdr->seq_ctrl); |
682 | 648 | ||
683 | tx_rate = control->tx_rate; | 649 | tx_rate = control->tx_rate->hw_value; |
684 | 650 | ||
685 | /* | 651 | /* |
686 | * Check whether this frame is to be acked | 652 | * Check whether this frame is to be acked |
687 | */ | 653 | */ |
688 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) | 654 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) |
689 | __set_bit(ENTRY_TXD_ACK, &desc.flags); | 655 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); |
690 | 656 | ||
691 | /* | 657 | /* |
692 | * Check if this is a RTS/CTS frame | 658 | * Check if this is a RTS/CTS frame |
693 | */ | 659 | */ |
694 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { | 660 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { |
695 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | 661 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
696 | if (is_rts_frame(frame_control)) { | 662 | if (is_rts_frame(frame_control)) { |
697 | __set_bit(ENTRY_TXD_RTS_FRAME, &desc.flags); | 663 | __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags); |
698 | __set_bit(ENTRY_TXD_ACK, &desc.flags); | 664 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); |
699 | } else | 665 | } else |
700 | __clear_bit(ENTRY_TXD_ACK, &desc.flags); | 666 | __clear_bit(ENTRY_TXD_ACK, &txdesc.flags); |
701 | if (control->rts_cts_rate) | 667 | if (control->rts_cts_rate) |
702 | tx_rate = control->rts_cts_rate; | 668 | tx_rate = control->rts_cts_rate->hw_value; |
703 | } | 669 | } |
704 | 670 | ||
705 | /* | 671 | rate = rt2x00_get_rate(tx_rate); |
706 | * Check for OFDM | ||
707 | */ | ||
708 | if (DEVICE_GET_RATE_FIELD(tx_rate, RATEMASK) & DEV_OFDM_RATEMASK) | ||
709 | __set_bit(ENTRY_TXD_OFDM_RATE, &desc.flags); | ||
710 | 672 | ||
711 | /* | 673 | /* |
712 | * Check if more fragments are pending | 674 | * Check if more fragments are pending |
713 | */ | 675 | */ |
714 | if (ieee80211_get_morefrag(ieee80211hdr)) { | 676 | if (ieee80211_get_morefrag(hdr)) { |
715 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | 677 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
716 | __set_bit(ENTRY_TXD_MORE_FRAG, &desc.flags); | 678 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags); |
717 | } | 679 | } |
718 | 680 | ||
719 | /* | 681 | /* |
720 | * Beacons and probe responses require the tsf timestamp | 682 | * Beacons and probe responses require the tsf timestamp |
721 | * to be inserted into the frame. | 683 | * to be inserted into the frame. |
722 | */ | 684 | */ |
723 | if (control->queue == IEEE80211_TX_QUEUE_BEACON || | 685 | if (control->queue == RT2X00_BCN_QUEUE_BEACON || |
724 | is_probe_resp(frame_control)) | 686 | is_probe_resp(frame_control)) |
725 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc.flags); | 687 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc.flags); |
726 | 688 | ||
727 | /* | 689 | /* |
728 | * Determine with what IFS priority this frame should be send. | 690 | * Determine with what IFS priority this frame should be send. |
@@ -730,30 +692,30 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
730 | * or this fragment came after RTS/CTS. | 692 | * or this fragment came after RTS/CTS. |
731 | */ | 693 | */ |
732 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || | 694 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || |
733 | test_bit(ENTRY_TXD_RTS_FRAME, &desc.flags)) | 695 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags)) |
734 | desc.ifs = IFS_SIFS; | 696 | txdesc.ifs = IFS_SIFS; |
735 | else | 697 | else |
736 | desc.ifs = IFS_BACKOFF; | 698 | txdesc.ifs = IFS_BACKOFF; |
737 | 699 | ||
738 | /* | 700 | /* |
739 | * PLCP setup | 701 | * PLCP setup |
740 | * Length calculation depends on OFDM/CCK rate. | 702 | * Length calculation depends on OFDM/CCK rate. |
741 | */ | 703 | */ |
742 | desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP); | 704 | txdesc.signal = rate->plcp; |
743 | desc.service = 0x04; | 705 | txdesc.service = 0x04; |
744 | 706 | ||
745 | length = skbdesc->data_len + FCS_LEN; | 707 | length = skbdesc->data_len + FCS_LEN; |
746 | if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) { | 708 | if (rate->flags & DEV_RATE_OFDM) { |
747 | desc.length_high = (length >> 6) & 0x3f; | 709 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags); |
748 | desc.length_low = length & 0x3f; | ||
749 | } else { | ||
750 | bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE); | ||
751 | 710 | ||
711 | txdesc.length_high = (length >> 6) & 0x3f; | ||
712 | txdesc.length_low = length & 0x3f; | ||
713 | } else { | ||
752 | /* | 714 | /* |
753 | * Convert length to microseconds. | 715 | * Convert length to microseconds. |
754 | */ | 716 | */ |
755 | residual = get_duration_res(length, bitrate); | 717 | residual = get_duration_res(length, rate->bitrate); |
756 | duration = get_duration(length, bitrate); | 718 | duration = get_duration(length, rate->bitrate); |
757 | 719 | ||
758 | if (residual != 0) { | 720 | if (residual != 0) { |
759 | duration++; | 721 | duration++; |
@@ -761,28 +723,27 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
761 | /* | 723 | /* |
762 | * Check if we need to set the Length Extension | 724 | * Check if we need to set the Length Extension |
763 | */ | 725 | */ |
764 | if (bitrate == 110 && residual <= 30) | 726 | if (rate->bitrate == 110 && residual <= 30) |
765 | desc.service |= 0x80; | 727 | txdesc.service |= 0x80; |
766 | } | 728 | } |
767 | 729 | ||
768 | desc.length_high = (duration >> 8) & 0xff; | 730 | txdesc.length_high = (duration >> 8) & 0xff; |
769 | desc.length_low = duration & 0xff; | 731 | txdesc.length_low = duration & 0xff; |
770 | 732 | ||
771 | /* | 733 | /* |
772 | * When preamble is enabled we should set the | 734 | * When preamble is enabled we should set the |
773 | * preamble bit for the signal. | 735 | * preamble bit for the signal. |
774 | */ | 736 | */ |
775 | if (DEVICE_GET_RATE_FIELD(tx_rate, PREAMBLE)) | 737 | if (rt2x00_get_rate_preamble(tx_rate)) |
776 | desc.signal |= 0x08; | 738 | txdesc.signal |= 0x08; |
777 | } | 739 | } |
778 | 740 | ||
779 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &desc, control); | 741 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &txdesc, control); |
780 | 742 | ||
781 | /* | 743 | /* |
782 | * Update ring entry. | 744 | * Update queue entry. |
783 | */ | 745 | */ |
784 | skbdesc->entry->skb = skb; | 746 | skbdesc->entry->skb = skb; |
785 | memcpy(&skbdesc->entry->tx_status.control, control, sizeof(*control)); | ||
786 | 747 | ||
787 | /* | 748 | /* |
788 | * The frame has been completely initialized and ready | 749 | * The frame has been completely initialized and ready |
@@ -798,133 +759,167 @@ EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc); | |||
798 | /* | 759 | /* |
799 | * Driver initialization handlers. | 760 | * Driver initialization handlers. |
800 | */ | 761 | */ |
762 | const struct rt2x00_rate rt2x00_supported_rates[12] = { | ||
763 | { | ||
764 | .flags = DEV_RATE_CCK | DEV_RATE_BASIC, | ||
765 | .bitrate = 10, | ||
766 | .ratemask = BIT(0), | ||
767 | .plcp = 0x00, | ||
768 | }, | ||
769 | { | ||
770 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC, | ||
771 | .bitrate = 20, | ||
772 | .ratemask = BIT(1), | ||
773 | .plcp = 0x01, | ||
774 | }, | ||
775 | { | ||
776 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC, | ||
777 | .bitrate = 55, | ||
778 | .ratemask = BIT(2), | ||
779 | .plcp = 0x02, | ||
780 | }, | ||
781 | { | ||
782 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC, | ||
783 | .bitrate = 110, | ||
784 | .ratemask = BIT(3), | ||
785 | .plcp = 0x03, | ||
786 | }, | ||
787 | { | ||
788 | .flags = DEV_RATE_OFDM | DEV_RATE_BASIC, | ||
789 | .bitrate = 60, | ||
790 | .ratemask = BIT(4), | ||
791 | .plcp = 0x0b, | ||
792 | }, | ||
793 | { | ||
794 | .flags = DEV_RATE_OFDM, | ||
795 | .bitrate = 90, | ||
796 | .ratemask = BIT(5), | ||
797 | .plcp = 0x0f, | ||
798 | }, | ||
799 | { | ||
800 | .flags = DEV_RATE_OFDM | DEV_RATE_BASIC, | ||
801 | .bitrate = 120, | ||
802 | .ratemask = BIT(6), | ||
803 | .plcp = 0x0a, | ||
804 | }, | ||
805 | { | ||
806 | .flags = DEV_RATE_OFDM, | ||
807 | .bitrate = 180, | ||
808 | .ratemask = BIT(7), | ||
809 | .plcp = 0x0e, | ||
810 | }, | ||
811 | { | ||
812 | .flags = DEV_RATE_OFDM | DEV_RATE_BASIC, | ||
813 | .bitrate = 240, | ||
814 | .ratemask = BIT(8), | ||
815 | .plcp = 0x09, | ||
816 | }, | ||
817 | { | ||
818 | .flags = DEV_RATE_OFDM, | ||
819 | .bitrate = 360, | ||
820 | .ratemask = BIT(9), | ||
821 | .plcp = 0x0d, | ||
822 | }, | ||
823 | { | ||
824 | .flags = DEV_RATE_OFDM, | ||
825 | .bitrate = 480, | ||
826 | .ratemask = BIT(10), | ||
827 | .plcp = 0x08, | ||
828 | }, | ||
829 | { | ||
830 | .flags = DEV_RATE_OFDM, | ||
831 | .bitrate = 540, | ||
832 | .ratemask = BIT(11), | ||
833 | .plcp = 0x0c, | ||
834 | }, | ||
835 | }; | ||
836 | |||
801 | static void rt2x00lib_channel(struct ieee80211_channel *entry, | 837 | static void rt2x00lib_channel(struct ieee80211_channel *entry, |
802 | const int channel, const int tx_power, | 838 | const int channel, const int tx_power, |
803 | const int value) | 839 | const int value) |
804 | { | 840 | { |
805 | entry->chan = channel; | 841 | entry->center_freq = ieee80211_channel_to_frequency(channel); |
806 | if (channel <= 14) | 842 | entry->hw_value = value; |
807 | entry->freq = 2407 + (5 * channel); | 843 | entry->max_power = tx_power; |
808 | else | 844 | entry->max_antenna_gain = 0xff; |
809 | entry->freq = 5000 + (5 * channel); | ||
810 | entry->val = value; | ||
811 | entry->flag = | ||
812 | IEEE80211_CHAN_W_IBSS | | ||
813 | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
814 | IEEE80211_CHAN_W_SCAN; | ||
815 | entry->power_level = tx_power; | ||
816 | entry->antenna_max = 0xff; | ||
817 | } | 845 | } |
818 | 846 | ||
819 | static void rt2x00lib_rate(struct ieee80211_rate *entry, | 847 | static void rt2x00lib_rate(struct ieee80211_rate *entry, |
820 | const int rate, const int mask, | 848 | const u16 index, const struct rt2x00_rate *rate) |
821 | const int plcp, const int flags) | ||
822 | { | 849 | { |
823 | entry->rate = rate; | 850 | entry->flags = 0; |
824 | entry->val = | 851 | entry->bitrate = rate->bitrate; |
825 | DEVICE_SET_RATE_FIELD(rate, RATE) | | 852 | entry->hw_value = rt2x00_create_rate_hw_value(index, 0); |
826 | DEVICE_SET_RATE_FIELD(mask, RATEMASK) | | 853 | entry->hw_value_short = entry->hw_value; |
827 | DEVICE_SET_RATE_FIELD(plcp, PLCP); | 854 | |
828 | entry->flags = flags; | 855 | if (rate->flags & DEV_RATE_SHORT_PREAMBLE) { |
829 | entry->val2 = entry->val; | 856 | entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; |
830 | if (entry->flags & IEEE80211_RATE_PREAMBLE2) | 857 | entry->hw_value_short |= rt2x00_create_rate_hw_value(index, 1); |
831 | entry->val2 |= DEVICE_SET_RATE_FIELD(1, PREAMBLE); | 858 | } |
832 | entry->min_rssi_ack = 0; | ||
833 | entry->min_rssi_ack_delta = 0; | ||
834 | } | 859 | } |
835 | 860 | ||
836 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | 861 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, |
837 | struct hw_mode_spec *spec) | 862 | struct hw_mode_spec *spec) |
838 | { | 863 | { |
839 | struct ieee80211_hw *hw = rt2x00dev->hw; | 864 | struct ieee80211_hw *hw = rt2x00dev->hw; |
840 | struct ieee80211_hw_mode *hwmodes; | ||
841 | struct ieee80211_channel *channels; | 865 | struct ieee80211_channel *channels; |
842 | struct ieee80211_rate *rates; | 866 | struct ieee80211_rate *rates; |
867 | unsigned int num_rates; | ||
843 | unsigned int i; | 868 | unsigned int i; |
844 | unsigned char tx_power; | 869 | unsigned char tx_power; |
845 | 870 | ||
846 | hwmodes = kzalloc(sizeof(*hwmodes) * spec->num_modes, GFP_KERNEL); | 871 | num_rates = 0; |
847 | if (!hwmodes) | 872 | if (spec->supported_rates & SUPPORT_RATE_CCK) |
848 | goto exit; | 873 | num_rates += 4; |
874 | if (spec->supported_rates & SUPPORT_RATE_OFDM) | ||
875 | num_rates += 8; | ||
849 | 876 | ||
850 | channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); | 877 | channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); |
851 | if (!channels) | 878 | if (!channels) |
852 | goto exit_free_modes; | 879 | return -ENOMEM; |
853 | 880 | ||
854 | rates = kzalloc(sizeof(*rates) * spec->num_rates, GFP_KERNEL); | 881 | rates = kzalloc(sizeof(*rates) * num_rates, GFP_KERNEL); |
855 | if (!rates) | 882 | if (!rates) |
856 | goto exit_free_channels; | 883 | goto exit_free_channels; |
857 | 884 | ||
858 | /* | 885 | /* |
859 | * Initialize Rate list. | 886 | * Initialize Rate list. |
860 | */ | 887 | */ |
861 | rt2x00lib_rate(&rates[0], 10, DEV_RATEMASK_1MB, | 888 | for (i = 0; i < num_rates; i++) |
862 | 0x00, IEEE80211_RATE_CCK); | 889 | rt2x00lib_rate(&rates[i], i, rt2x00_get_rate(i)); |
863 | rt2x00lib_rate(&rates[1], 20, DEV_RATEMASK_2MB, | ||
864 | 0x01, IEEE80211_RATE_CCK_2); | ||
865 | rt2x00lib_rate(&rates[2], 55, DEV_RATEMASK_5_5MB, | ||
866 | 0x02, IEEE80211_RATE_CCK_2); | ||
867 | rt2x00lib_rate(&rates[3], 110, DEV_RATEMASK_11MB, | ||
868 | 0x03, IEEE80211_RATE_CCK_2); | ||
869 | |||
870 | if (spec->num_rates > 4) { | ||
871 | rt2x00lib_rate(&rates[4], 60, DEV_RATEMASK_6MB, | ||
872 | 0x0b, IEEE80211_RATE_OFDM); | ||
873 | rt2x00lib_rate(&rates[5], 90, DEV_RATEMASK_9MB, | ||
874 | 0x0f, IEEE80211_RATE_OFDM); | ||
875 | rt2x00lib_rate(&rates[6], 120, DEV_RATEMASK_12MB, | ||
876 | 0x0a, IEEE80211_RATE_OFDM); | ||
877 | rt2x00lib_rate(&rates[7], 180, DEV_RATEMASK_18MB, | ||
878 | 0x0e, IEEE80211_RATE_OFDM); | ||
879 | rt2x00lib_rate(&rates[8], 240, DEV_RATEMASK_24MB, | ||
880 | 0x09, IEEE80211_RATE_OFDM); | ||
881 | rt2x00lib_rate(&rates[9], 360, DEV_RATEMASK_36MB, | ||
882 | 0x0d, IEEE80211_RATE_OFDM); | ||
883 | rt2x00lib_rate(&rates[10], 480, DEV_RATEMASK_48MB, | ||
884 | 0x08, IEEE80211_RATE_OFDM); | ||
885 | rt2x00lib_rate(&rates[11], 540, DEV_RATEMASK_54MB, | ||
886 | 0x0c, IEEE80211_RATE_OFDM); | ||
887 | } | ||
888 | 890 | ||
889 | /* | 891 | /* |
890 | * Initialize Channel list. | 892 | * Initialize Channel list. |
891 | */ | 893 | */ |
892 | for (i = 0; i < spec->num_channels; i++) { | 894 | for (i = 0; i < spec->num_channels; i++) { |
893 | if (spec->channels[i].channel <= 14) | 895 | if (spec->channels[i].channel <= 14) { |
894 | tx_power = spec->tx_power_bg[i]; | 896 | if (spec->tx_power_bg) |
895 | else if (spec->tx_power_a) | 897 | tx_power = spec->tx_power_bg[i]; |
896 | tx_power = spec->tx_power_a[i]; | 898 | else |
897 | else | 899 | tx_power = spec->tx_power_default; |
898 | tx_power = spec->tx_power_default; | 900 | } else { |
901 | if (spec->tx_power_a) | ||
902 | tx_power = spec->tx_power_a[i]; | ||
903 | else | ||
904 | tx_power = spec->tx_power_default; | ||
905 | } | ||
899 | 906 | ||
900 | rt2x00lib_channel(&channels[i], | 907 | rt2x00lib_channel(&channels[i], |
901 | spec->channels[i].channel, tx_power, i); | 908 | spec->channels[i].channel, tx_power, i); |
902 | } | 909 | } |
903 | 910 | ||
904 | /* | 911 | /* |
905 | * Intitialize 802.11b | 912 | * Intitialize 802.11b, 802.11g |
906 | * Rates: CCK. | ||
907 | * Channels: OFDM. | ||
908 | */ | ||
909 | if (spec->num_modes > HWMODE_B) { | ||
910 | hwmodes[HWMODE_B].mode = MODE_IEEE80211B; | ||
911 | hwmodes[HWMODE_B].num_channels = 14; | ||
912 | hwmodes[HWMODE_B].num_rates = 4; | ||
913 | hwmodes[HWMODE_B].channels = channels; | ||
914 | hwmodes[HWMODE_B].rates = rates; | ||
915 | } | ||
916 | |||
917 | /* | ||
918 | * Intitialize 802.11g | ||
919 | * Rates: CCK, OFDM. | 913 | * Rates: CCK, OFDM. |
920 | * Channels: OFDM. | 914 | * Channels: 2.4 GHz |
921 | */ | 915 | */ |
922 | if (spec->num_modes > HWMODE_G) { | 916 | if (spec->supported_bands & SUPPORT_BAND_2GHZ) { |
923 | hwmodes[HWMODE_G].mode = MODE_IEEE80211G; | 917 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].n_channels = 14; |
924 | hwmodes[HWMODE_G].num_channels = 14; | 918 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].n_bitrates = num_rates; |
925 | hwmodes[HWMODE_G].num_rates = spec->num_rates; | 919 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].channels = channels; |
926 | hwmodes[HWMODE_G].channels = channels; | 920 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates; |
927 | hwmodes[HWMODE_G].rates = rates; | 921 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
922 | &rt2x00dev->bands[IEEE80211_BAND_2GHZ]; | ||
928 | } | 923 | } |
929 | 924 | ||
930 | /* | 925 | /* |
@@ -932,40 +927,21 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | |||
932 | * Rates: OFDM. | 927 | * Rates: OFDM. |
933 | * Channels: OFDM, UNII, HiperLAN2. | 928 | * Channels: OFDM, UNII, HiperLAN2. |
934 | */ | 929 | */ |
935 | if (spec->num_modes > HWMODE_A) { | 930 | if (spec->supported_bands & SUPPORT_BAND_5GHZ) { |
936 | hwmodes[HWMODE_A].mode = MODE_IEEE80211A; | 931 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].n_channels = |
937 | hwmodes[HWMODE_A].num_channels = spec->num_channels - 14; | 932 | spec->num_channels - 14; |
938 | hwmodes[HWMODE_A].num_rates = spec->num_rates - 4; | 933 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].n_bitrates = |
939 | hwmodes[HWMODE_A].channels = &channels[14]; | 934 | num_rates - 4; |
940 | hwmodes[HWMODE_A].rates = &rates[4]; | 935 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].channels = &channels[14]; |
936 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4]; | ||
937 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
938 | &rt2x00dev->bands[IEEE80211_BAND_5GHZ]; | ||
941 | } | 939 | } |
942 | 940 | ||
943 | if (spec->num_modes > HWMODE_G && | ||
944 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_G])) | ||
945 | goto exit_free_rates; | ||
946 | |||
947 | if (spec->num_modes > HWMODE_B && | ||
948 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_B])) | ||
949 | goto exit_free_rates; | ||
950 | |||
951 | if (spec->num_modes > HWMODE_A && | ||
952 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_A])) | ||
953 | goto exit_free_rates; | ||
954 | |||
955 | rt2x00dev->hwmodes = hwmodes; | ||
956 | |||
957 | return 0; | 941 | return 0; |
958 | 942 | ||
959 | exit_free_rates: | 943 | exit_free_channels: |
960 | kfree(rates); | ||
961 | |||
962 | exit_free_channels: | ||
963 | kfree(channels); | 944 | kfree(channels); |
964 | |||
965 | exit_free_modes: | ||
966 | kfree(hwmodes); | ||
967 | |||
968 | exit: | ||
969 | ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); | 945 | ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); |
970 | return -ENOMEM; | 946 | return -ENOMEM; |
971 | } | 947 | } |
@@ -975,11 +951,11 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev) | |||
975 | if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) | 951 | if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) |
976 | ieee80211_unregister_hw(rt2x00dev->hw); | 952 | ieee80211_unregister_hw(rt2x00dev->hw); |
977 | 953 | ||
978 | if (likely(rt2x00dev->hwmodes)) { | 954 | if (likely(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ])) { |
979 | kfree(rt2x00dev->hwmodes->channels); | 955 | kfree(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels); |
980 | kfree(rt2x00dev->hwmodes->rates); | 956 | kfree(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->bitrates); |
981 | kfree(rt2x00dev->hwmodes); | 957 | rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; |
982 | rt2x00dev->hwmodes = NULL; | 958 | rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; |
983 | } | 959 | } |
984 | } | 960 | } |
985 | 961 | ||
@@ -1012,86 +988,6 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1012 | /* | 988 | /* |
1013 | * Initialization/uninitialization handlers. | 989 | * Initialization/uninitialization handlers. |
1014 | */ | 990 | */ |
1015 | static int rt2x00lib_alloc_entries(struct data_ring *ring, | ||
1016 | const u16 max_entries, const u16 data_size, | ||
1017 | const u16 desc_size) | ||
1018 | { | ||
1019 | struct data_entry *entry; | ||
1020 | unsigned int i; | ||
1021 | |||
1022 | ring->stats.limit = max_entries; | ||
1023 | ring->data_size = data_size; | ||
1024 | ring->desc_size = desc_size; | ||
1025 | |||
1026 | /* | ||
1027 | * Allocate all ring entries. | ||
1028 | */ | ||
1029 | entry = kzalloc(ring->stats.limit * sizeof(*entry), GFP_KERNEL); | ||
1030 | if (!entry) | ||
1031 | return -ENOMEM; | ||
1032 | |||
1033 | for (i = 0; i < ring->stats.limit; i++) { | ||
1034 | entry[i].flags = 0; | ||
1035 | entry[i].ring = ring; | ||
1036 | entry[i].skb = NULL; | ||
1037 | entry[i].entry_idx = i; | ||
1038 | } | ||
1039 | |||
1040 | ring->entry = entry; | ||
1041 | |||
1042 | return 0; | ||
1043 | } | ||
1044 | |||
1045 | static int rt2x00lib_alloc_ring_entries(struct rt2x00_dev *rt2x00dev) | ||
1046 | { | ||
1047 | struct data_ring *ring; | ||
1048 | |||
1049 | /* | ||
1050 | * Allocate the RX ring. | ||
1051 | */ | ||
1052 | if (rt2x00lib_alloc_entries(rt2x00dev->rx, RX_ENTRIES, DATA_FRAME_SIZE, | ||
1053 | rt2x00dev->ops->rxd_size)) | ||
1054 | return -ENOMEM; | ||
1055 | |||
1056 | /* | ||
1057 | * First allocate the TX rings. | ||
1058 | */ | ||
1059 | txring_for_each(rt2x00dev, ring) { | ||
1060 | if (rt2x00lib_alloc_entries(ring, TX_ENTRIES, DATA_FRAME_SIZE, | ||
1061 | rt2x00dev->ops->txd_size)) | ||
1062 | return -ENOMEM; | ||
1063 | } | ||
1064 | |||
1065 | if (!test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)) | ||
1066 | return 0; | ||
1067 | |||
1068 | /* | ||
1069 | * Allocate the BEACON ring. | ||
1070 | */ | ||
1071 | if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[0], BEACON_ENTRIES, | ||
1072 | MGMT_FRAME_SIZE, rt2x00dev->ops->txd_size)) | ||
1073 | return -ENOMEM; | ||
1074 | |||
1075 | /* | ||
1076 | * Allocate the Atim ring. | ||
1077 | */ | ||
1078 | if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[1], ATIM_ENTRIES, | ||
1079 | DATA_FRAME_SIZE, rt2x00dev->ops->txd_size)) | ||
1080 | return -ENOMEM; | ||
1081 | |||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | static void rt2x00lib_free_ring_entries(struct rt2x00_dev *rt2x00dev) | ||
1086 | { | ||
1087 | struct data_ring *ring; | ||
1088 | |||
1089 | ring_for_each(rt2x00dev, ring) { | ||
1090 | kfree(ring->entry); | ||
1091 | ring->entry = NULL; | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) | 991 | static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) |
1096 | { | 992 | { |
1097 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) | 993 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) |
@@ -1108,9 +1004,9 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
1108 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); | 1004 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); |
1109 | 1005 | ||
1110 | /* | 1006 | /* |
1111 | * Free allocated ring entries. | 1007 | * Free allocated queue entries. |
1112 | */ | 1008 | */ |
1113 | rt2x00lib_free_ring_entries(rt2x00dev); | 1009 | rt2x00queue_uninitialize(rt2x00dev); |
1114 | } | 1010 | } |
1115 | 1011 | ||
1116 | static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | 1012 | static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) |
@@ -1121,13 +1017,11 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1121 | return 0; | 1017 | return 0; |
1122 | 1018 | ||
1123 | /* | 1019 | /* |
1124 | * Allocate all ring entries. | 1020 | * Allocate all queue entries. |
1125 | */ | 1021 | */ |
1126 | status = rt2x00lib_alloc_ring_entries(rt2x00dev); | 1022 | status = rt2x00queue_initialize(rt2x00dev); |
1127 | if (status) { | 1023 | if (status) |
1128 | ERROR(rt2x00dev, "Ring entries allocation failed.\n"); | ||
1129 | return status; | 1024 | return status; |
1130 | } | ||
1131 | 1025 | ||
1132 | /* | 1026 | /* |
1133 | * Initialize the device. | 1027 | * Initialize the device. |
@@ -1146,7 +1040,7 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1146 | return 0; | 1040 | return 0; |
1147 | 1041 | ||
1148 | exit: | 1042 | exit: |
1149 | rt2x00lib_free_ring_entries(rt2x00dev); | 1043 | rt2x00lib_uninitialize(rt2x00dev); |
1150 | 1044 | ||
1151 | return status; | 1045 | return status; |
1152 | } | 1046 | } |
@@ -1162,11 +1056,9 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
1162 | * If this is the first interface which is added, | 1056 | * If this is the first interface which is added, |
1163 | * we should load the firmware now. | 1057 | * we should load the firmware now. |
1164 | */ | 1058 | */ |
1165 | if (test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) { | 1059 | retval = rt2x00lib_load_firmware(rt2x00dev); |
1166 | retval = rt2x00lib_load_firmware(rt2x00dev); | 1060 | if (retval) |
1167 | if (retval) | 1061 | return retval; |
1168 | return retval; | ||
1169 | } | ||
1170 | 1062 | ||
1171 | /* | 1063 | /* |
1172 | * Initialize the device. | 1064 | * Initialize the device. |
@@ -1184,6 +1076,10 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
1184 | return retval; | 1076 | return retval; |
1185 | } | 1077 | } |
1186 | 1078 | ||
1079 | rt2x00dev->intf_ap_count = 0; | ||
1080 | rt2x00dev->intf_sta_count = 0; | ||
1081 | rt2x00dev->intf_associated = 0; | ||
1082 | |||
1187 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1083 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1188 | 1084 | ||
1189 | return 0; | 1085 | return 0; |
@@ -1200,74 +1096,25 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) | |||
1200 | */ | 1096 | */ |
1201 | rt2x00lib_disable_radio(rt2x00dev); | 1097 | rt2x00lib_disable_radio(rt2x00dev); |
1202 | 1098 | ||
1099 | rt2x00dev->intf_ap_count = 0; | ||
1100 | rt2x00dev->intf_sta_count = 0; | ||
1101 | rt2x00dev->intf_associated = 0; | ||
1102 | |||
1203 | __clear_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1103 | __clear_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1204 | } | 1104 | } |
1205 | 1105 | ||
1206 | /* | 1106 | /* |
1207 | * driver allocation handlers. | 1107 | * driver allocation handlers. |
1208 | */ | 1108 | */ |
1209 | static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev) | 1109 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) |
1210 | { | 1110 | { |
1211 | struct data_ring *ring; | 1111 | int retval = -ENOMEM; |
1212 | unsigned int index; | ||
1213 | |||
1214 | /* | ||
1215 | * We need the following rings: | ||
1216 | * RX: 1 | ||
1217 | * TX: hw->queues | ||
1218 | * Beacon: 1 (if required) | ||
1219 | * Atim: 1 (if required) | ||
1220 | */ | ||
1221 | rt2x00dev->data_rings = 1 + rt2x00dev->hw->queues + | ||
1222 | (2 * test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)); | ||
1223 | |||
1224 | ring = kzalloc(rt2x00dev->data_rings * sizeof(*ring), GFP_KERNEL); | ||
1225 | if (!ring) { | ||
1226 | ERROR(rt2x00dev, "Ring allocation failed.\n"); | ||
1227 | return -ENOMEM; | ||
1228 | } | ||
1229 | 1112 | ||
1230 | /* | 1113 | /* |
1231 | * Initialize pointers | 1114 | * Make room for rt2x00_intf inside the per-interface |
1115 | * structure ieee80211_vif. | ||
1232 | */ | 1116 | */ |
1233 | rt2x00dev->rx = ring; | 1117 | rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); |
1234 | rt2x00dev->tx = &rt2x00dev->rx[1]; | ||
1235 | if (test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)) | ||
1236 | rt2x00dev->bcn = &rt2x00dev->tx[rt2x00dev->hw->queues]; | ||
1237 | |||
1238 | /* | ||
1239 | * Initialize ring parameters. | ||
1240 | * RX: queue_idx = 0 | ||
1241 | * TX: queue_idx = IEEE80211_TX_QUEUE_DATA0 + index | ||
1242 | * TX: cw_min: 2^5 = 32. | ||
1243 | * TX: cw_max: 2^10 = 1024. | ||
1244 | */ | ||
1245 | rt2x00dev->rx->rt2x00dev = rt2x00dev; | ||
1246 | rt2x00dev->rx->queue_idx = 0; | ||
1247 | |||
1248 | index = IEEE80211_TX_QUEUE_DATA0; | ||
1249 | txring_for_each(rt2x00dev, ring) { | ||
1250 | ring->rt2x00dev = rt2x00dev; | ||
1251 | ring->queue_idx = index++; | ||
1252 | ring->tx_params.aifs = 2; | ||
1253 | ring->tx_params.cw_min = 5; | ||
1254 | ring->tx_params.cw_max = 10; | ||
1255 | } | ||
1256 | |||
1257 | return 0; | ||
1258 | } | ||
1259 | |||
1260 | static void rt2x00lib_free_rings(struct rt2x00_dev *rt2x00dev) | ||
1261 | { | ||
1262 | kfree(rt2x00dev->rx); | ||
1263 | rt2x00dev->rx = NULL; | ||
1264 | rt2x00dev->tx = NULL; | ||
1265 | rt2x00dev->bcn = NULL; | ||
1266 | } | ||
1267 | |||
1268 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | ||
1269 | { | ||
1270 | int retval = -ENOMEM; | ||
1271 | 1118 | ||
1272 | /* | 1119 | /* |
1273 | * Let the driver probe the device to detect the capabilities. | 1120 | * Let the driver probe the device to detect the capabilities. |
@@ -1281,20 +1128,14 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1281 | /* | 1128 | /* |
1282 | * Initialize configuration work. | 1129 | * Initialize configuration work. |
1283 | */ | 1130 | */ |
1284 | INIT_WORK(&rt2x00dev->beacon_work, rt2x00lib_beacondone_scheduled); | 1131 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1285 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); | 1132 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); |
1286 | INIT_WORK(&rt2x00dev->config_work, rt2x00lib_configuration_scheduled); | ||
1287 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); | 1133 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); |
1288 | 1134 | ||
1289 | /* | 1135 | /* |
1290 | * Reset current working type. | 1136 | * Allocate queue array. |
1291 | */ | ||
1292 | rt2x00dev->interface.type = IEEE80211_IF_TYPE_INVALID; | ||
1293 | |||
1294 | /* | ||
1295 | * Allocate ring array. | ||
1296 | */ | 1137 | */ |
1297 | retval = rt2x00lib_alloc_rings(rt2x00dev); | 1138 | retval = rt2x00queue_allocate(rt2x00dev); |
1298 | if (retval) | 1139 | if (retval) |
1299 | goto exit; | 1140 | goto exit; |
1300 | 1141 | ||
@@ -1310,6 +1151,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1310 | /* | 1151 | /* |
1311 | * Register extra components. | 1152 | * Register extra components. |
1312 | */ | 1153 | */ |
1154 | rt2x00leds_register(rt2x00dev); | ||
1313 | rt2x00rfkill_allocate(rt2x00dev); | 1155 | rt2x00rfkill_allocate(rt2x00dev); |
1314 | rt2x00debug_register(rt2x00dev); | 1156 | rt2x00debug_register(rt2x00dev); |
1315 | 1157 | ||
@@ -1345,6 +1187,11 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1345 | rt2x00rfkill_free(rt2x00dev); | 1187 | rt2x00rfkill_free(rt2x00dev); |
1346 | 1188 | ||
1347 | /* | 1189 | /* |
1190 | * Free LED. | ||
1191 | */ | ||
1192 | rt2x00leds_unregister(rt2x00dev); | ||
1193 | |||
1194 | /* | ||
1348 | * Free ieee80211_hw memory. | 1195 | * Free ieee80211_hw memory. |
1349 | */ | 1196 | */ |
1350 | rt2x00lib_remove_hw(rt2x00dev); | 1197 | rt2x00lib_remove_hw(rt2x00dev); |
@@ -1355,9 +1202,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1355 | rt2x00lib_free_firmware(rt2x00dev); | 1202 | rt2x00lib_free_firmware(rt2x00dev); |
1356 | 1203 | ||
1357 | /* | 1204 | /* |
1358 | * Free ring structures. | 1205 | * Free queue structures. |
1359 | */ | 1206 | */ |
1360 | rt2x00lib_free_rings(rt2x00dev); | 1207 | rt2x00queue_free(rt2x00dev); |
1361 | } | 1208 | } |
1362 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); | 1209 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); |
1363 | 1210 | ||
@@ -1388,6 +1235,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | |||
1388 | /* | 1235 | /* |
1389 | * Suspend/disable extra components. | 1236 | * Suspend/disable extra components. |
1390 | */ | 1237 | */ |
1238 | rt2x00leds_suspend(rt2x00dev); | ||
1391 | rt2x00rfkill_suspend(rt2x00dev); | 1239 | rt2x00rfkill_suspend(rt2x00dev); |
1392 | rt2x00debug_deregister(rt2x00dev); | 1240 | rt2x00debug_deregister(rt2x00dev); |
1393 | 1241 | ||
@@ -1403,9 +1251,30 @@ exit: | |||
1403 | } | 1251 | } |
1404 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); | 1252 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); |
1405 | 1253 | ||
1254 | static void rt2x00lib_resume_intf(void *data, u8 *mac, | ||
1255 | struct ieee80211_vif *vif) | ||
1256 | { | ||
1257 | struct rt2x00_dev *rt2x00dev = data; | ||
1258 | struct rt2x00_intf *intf = vif_to_intf(vif); | ||
1259 | |||
1260 | spin_lock(&intf->lock); | ||
1261 | |||
1262 | rt2x00lib_config_intf(rt2x00dev, intf, | ||
1263 | vif->type, intf->mac, intf->bssid); | ||
1264 | |||
1265 | |||
1266 | /* | ||
1267 | * Master or Ad-hoc mode require a new beacon update. | ||
1268 | */ | ||
1269 | if (vif->type == IEEE80211_IF_TYPE_AP || | ||
1270 | vif->type == IEEE80211_IF_TYPE_IBSS) | ||
1271 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; | ||
1272 | |||
1273 | spin_unlock(&intf->lock); | ||
1274 | } | ||
1275 | |||
1406 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | 1276 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) |
1407 | { | 1277 | { |
1408 | struct interface *intf = &rt2x00dev->interface; | ||
1409 | int retval; | 1278 | int retval; |
1410 | 1279 | ||
1411 | NOTICE(rt2x00dev, "Waking up.\n"); | 1280 | NOTICE(rt2x00dev, "Waking up.\n"); |
@@ -1415,6 +1284,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1415 | */ | 1284 | */ |
1416 | rt2x00debug_register(rt2x00dev); | 1285 | rt2x00debug_register(rt2x00dev); |
1417 | rt2x00rfkill_resume(rt2x00dev); | 1286 | rt2x00rfkill_resume(rt2x00dev); |
1287 | rt2x00leds_resume(rt2x00dev); | ||
1418 | 1288 | ||
1419 | /* | 1289 | /* |
1420 | * Only continue if mac80211 had open interfaces. | 1290 | * Only continue if mac80211 had open interfaces. |
@@ -1436,9 +1306,12 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1436 | if (!rt2x00dev->hw->conf.radio_enabled) | 1306 | if (!rt2x00dev->hw->conf.radio_enabled) |
1437 | rt2x00lib_disable_radio(rt2x00dev); | 1307 | rt2x00lib_disable_radio(rt2x00dev); |
1438 | 1308 | ||
1439 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 1309 | /* |
1440 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 1310 | * Iterator over each active interface to |
1441 | rt2x00lib_config_type(rt2x00dev, intf->type); | 1311 | * reconfigure the hardware. |
1312 | */ | ||
1313 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | ||
1314 | rt2x00lib_resume_intf, rt2x00dev); | ||
1442 | 1315 | ||
1443 | /* | 1316 | /* |
1444 | * We are ready again to receive requests from mac80211. | 1317 | * We are ready again to receive requests from mac80211. |
@@ -1454,12 +1327,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1454 | ieee80211_start_queues(rt2x00dev->hw); | 1327 | ieee80211_start_queues(rt2x00dev->hw); |
1455 | 1328 | ||
1456 | /* | 1329 | /* |
1457 | * When in Master or Ad-hoc mode, | 1330 | * During interface iteration we might have changed the |
1458 | * restart Beacon transmitting by faking a beacondone event. | 1331 | * delayed_flags, time to handles the event by calling |
1332 | * the work handler directly. | ||
1459 | */ | 1333 | */ |
1460 | if (intf->type == IEEE80211_IF_TYPE_AP || | 1334 | rt2x00lib_intf_scheduled(&rt2x00dev->intf_work); |
1461 | intf->type == IEEE80211_IF_TYPE_IBSS) | ||
1462 | rt2x00lib_beacondone(rt2x00dev); | ||
1463 | 1335 | ||
1464 | return 0; | 1336 | return 0; |
1465 | 1337 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h index 99f3f367adce..7169c222a486 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dump.h +++ b/drivers/net/wireless/rt2x00/rt2x00dump.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -93,8 +93,8 @@ enum rt2x00_dump_type { | |||
93 | * @chip_rf: RF chipset | 93 | * @chip_rf: RF chipset |
94 | * @chip_rev: Chipset revision | 94 | * @chip_rev: Chipset revision |
95 | * @type: The frame type (&rt2x00_dump_type) | 95 | * @type: The frame type (&rt2x00_dump_type) |
96 | * @ring_index: The index number of the data ring. | 96 | * @queue_index: The index number of the data queue. |
97 | * @entry_index: The index number of the entry inside the data ring. | 97 | * @entry_index: The index number of the entry inside the data queue. |
98 | * @timestamp_sec: Timestamp - seconds | 98 | * @timestamp_sec: Timestamp - seconds |
99 | * @timestamp_usec: Timestamp - microseconds | 99 | * @timestamp_usec: Timestamp - microseconds |
100 | */ | 100 | */ |
@@ -111,7 +111,7 @@ struct rt2x00dump_hdr { | |||
111 | __le32 chip_rev; | 111 | __le32 chip_rev; |
112 | 112 | ||
113 | __le16 type; | 113 | __le16 type; |
114 | __u8 ring_index; | 114 | __u8 queue_index; |
115 | __u8 entry_index; | 115 | __u8 entry_index; |
116 | 116 | ||
117 | __le32 timestamp_sec; | 117 | __le32 timestamp_sec; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index 0a475e4e2442..b971bc6e7ee2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -23,7 +23,6 @@ | |||
23 | Abstract: rt2x00 firmware loading routines. | 23 | Abstract: rt2x00 firmware loading routines. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/crc-itu-t.h> | ||
27 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
29 | 28 | ||
@@ -37,7 +36,6 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
37 | char *fw_name; | 36 | char *fw_name; |
38 | int retval; | 37 | int retval; |
39 | u16 crc; | 38 | u16 crc; |
40 | u16 tmp; | ||
41 | 39 | ||
42 | /* | 40 | /* |
43 | * Read correct firmware from harddisk. | 41 | * Read correct firmware from harddisk. |
@@ -63,18 +61,9 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
63 | return -ENOENT; | 61 | return -ENOENT; |
64 | } | 62 | } |
65 | 63 | ||
66 | /* | 64 | crc = rt2x00dev->ops->lib->get_firmware_crc(fw->data, fw->size); |
67 | * Validate the firmware using 16 bit CRC. | ||
68 | * The last 2 bytes of the firmware are the CRC | ||
69 | * so substract those 2 bytes from the CRC checksum, | ||
70 | * and set those 2 bytes to 0 when calculating CRC. | ||
71 | */ | ||
72 | tmp = 0; | ||
73 | crc = crc_itu_t(0, fw->data, fw->size - 2); | ||
74 | crc = crc_itu_t(crc, (u8 *)&tmp, 2); | ||
75 | |||
76 | if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) { | 65 | if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) { |
77 | ERROR(rt2x00dev, "Firmware CRC error.\n"); | 66 | ERROR(rt2x00dev, "Firmware checksum error.\n"); |
78 | retval = -ENOENT; | 67 | retval = -ENOENT; |
79 | goto exit; | 68 | goto exit; |
80 | } | 69 | } |
@@ -96,6 +85,9 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) | |||
96 | { | 85 | { |
97 | int retval; | 86 | int retval; |
98 | 87 | ||
88 | if (!test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) | ||
89 | return 0; | ||
90 | |||
99 | if (!rt2x00dev->fw) { | 91 | if (!rt2x00dev->fw) { |
100 | retval = rt2x00lib_request_firmware(rt2x00dev); | 92 | retval = rt2x00lib_request_firmware(rt2x00dev); |
101 | if (retval) | 93 | if (retval) |
@@ -116,4 +108,3 @@ void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev) | |||
116 | release_firmware(rt2x00dev->fw); | 108 | release_firmware(rt2x00dev->fw); |
117 | rt2x00dev->fw = NULL; | 109 | rt2x00dev->fw = NULL; |
118 | } | 110 | } |
119 | |||
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c new file mode 100644 index 000000000000..ca2d282a9f75 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 led specific routines. | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #include "rt2x00.h" | ||
30 | #include "rt2x00lib.h" | ||
31 | |||
32 | void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi) | ||
33 | { | ||
34 | if (!rt2x00dev->trigger_qual.registered) | ||
35 | return; | ||
36 | |||
37 | /* | ||
38 | * Led handling requires a positive value for the rssi, | ||
39 | * to do that correctly we need to add the correction. | ||
40 | */ | ||
41 | rssi += rt2x00dev->rssi_offset; | ||
42 | |||
43 | /* | ||
44 | * Get the rssi level, this is used to convert the rssi | ||
45 | * to a LED value inside the range LED_OFF - LED_FULL. | ||
46 | */ | ||
47 | if (rssi <= 30) | ||
48 | rssi = 0; | ||
49 | else if (rssi <= 39) | ||
50 | rssi = 1; | ||
51 | else if (rssi <= 49) | ||
52 | rssi = 2; | ||
53 | else if (rssi <= 53) | ||
54 | rssi = 3; | ||
55 | else if (rssi <= 63) | ||
56 | rssi = 4; | ||
57 | else | ||
58 | rssi = 5; | ||
59 | |||
60 | /* | ||
61 | * Note that we must _not_ send LED_OFF since the driver | ||
62 | * is going to calculate the value and might use it in a | ||
63 | * division. | ||
64 | */ | ||
65 | led_trigger_event(&rt2x00dev->trigger_qual.trigger, | ||
66 | ((LED_FULL / 6) * rssi) + 1); | ||
67 | } | ||
68 | |||
69 | static int rt2x00leds_register_trigger(struct rt2x00_dev *rt2x00dev, | ||
70 | struct rt2x00_trigger *trigger, | ||
71 | const char *name) | ||
72 | { | ||
73 | int retval; | ||
74 | |||
75 | trigger->trigger.name = name; | ||
76 | retval = led_trigger_register(&trigger->trigger); | ||
77 | if (retval) { | ||
78 | ERROR(rt2x00dev, "Failed to register led trigger.\n"); | ||
79 | return retval; | ||
80 | } | ||
81 | |||
82 | trigger->registered = 1; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, | ||
88 | struct rt2x00_led *led, | ||
89 | enum led_type type, | ||
90 | const char *name, char *trigger) | ||
91 | { | ||
92 | struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); | ||
93 | int retval; | ||
94 | |||
95 | led->led_dev.name = name; | ||
96 | led->led_dev.brightness_set = rt2x00dev->ops->lib->led_brightness; | ||
97 | led->led_dev.default_trigger = trigger; | ||
98 | |||
99 | retval = led_classdev_register(device, &led->led_dev); | ||
100 | if (retval) { | ||
101 | ERROR(rt2x00dev, "Failed to register led handler.\n"); | ||
102 | return retval; | ||
103 | } | ||
104 | |||
105 | led->rt2x00dev = rt2x00dev; | ||
106 | led->type = type; | ||
107 | led->registered = 1; | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | void rt2x00leds_register(struct rt2x00_dev *rt2x00dev) | ||
113 | { | ||
114 | char *trigger; | ||
115 | char dev_name[16]; | ||
116 | char name[32]; | ||
117 | int retval; | ||
118 | |||
119 | if (!rt2x00dev->ops->lib->led_brightness) | ||
120 | return; | ||
121 | |||
122 | snprintf(dev_name, sizeof(dev_name), "%s-%s", | ||
123 | rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy)); | ||
124 | |||
125 | if (rt2x00dev->led_flags & LED_SUPPORT_RADIO) { | ||
126 | trigger = ieee80211_get_radio_led_name(rt2x00dev->hw); | ||
127 | snprintf(name, sizeof(name), "%s:radio", dev_name); | ||
128 | |||
129 | retval = rt2x00leds_register_led(rt2x00dev, | ||
130 | &rt2x00dev->led_radio, | ||
131 | LED_TYPE_RADIO, | ||
132 | name, trigger); | ||
133 | if (retval) | ||
134 | goto exit_fail; | ||
135 | } | ||
136 | |||
137 | if (rt2x00dev->led_flags & LED_SUPPORT_ASSOC) { | ||
138 | trigger = ieee80211_get_assoc_led_name(rt2x00dev->hw); | ||
139 | snprintf(name, sizeof(name), "%s:assoc", dev_name); | ||
140 | |||
141 | retval = rt2x00leds_register_led(rt2x00dev, | ||
142 | &rt2x00dev->led_assoc, | ||
143 | LED_TYPE_ASSOC, | ||
144 | name, trigger); | ||
145 | if (retval) | ||
146 | goto exit_fail; | ||
147 | } | ||
148 | |||
149 | if (rt2x00dev->led_flags & LED_SUPPORT_QUALITY) { | ||
150 | snprintf(name, sizeof(name), "%s:quality", dev_name); | ||
151 | |||
152 | retval = rt2x00leds_register_trigger(rt2x00dev, | ||
153 | &rt2x00dev->trigger_qual, | ||
154 | name); | ||
155 | |||
156 | retval = rt2x00leds_register_led(rt2x00dev, | ||
157 | &rt2x00dev->led_qual, | ||
158 | LED_TYPE_QUALITY, | ||
159 | name, name); | ||
160 | if (retval) | ||
161 | goto exit_fail; | ||
162 | } | ||
163 | |||
164 | return; | ||
165 | |||
166 | exit_fail: | ||
167 | rt2x00leds_unregister(rt2x00dev); | ||
168 | } | ||
169 | |||
170 | static void rt2x00leds_unregister_trigger(struct rt2x00_trigger *trigger) | ||
171 | { | ||
172 | if (!trigger->registered) | ||
173 | return; | ||
174 | |||
175 | led_trigger_unregister(&trigger->trigger); | ||
176 | trigger->registered = 0; | ||
177 | } | ||
178 | |||
179 | static void rt2x00leds_unregister_led(struct rt2x00_led *led) | ||
180 | { | ||
181 | if (!led->registered) | ||
182 | return; | ||
183 | |||
184 | led_classdev_unregister(&led->led_dev); | ||
185 | |||
186 | led->led_dev.brightness_set(&led->led_dev, LED_OFF); | ||
187 | led->registered = 0; | ||
188 | } | ||
189 | |||
190 | void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) | ||
191 | { | ||
192 | rt2x00leds_unregister_trigger(&rt2x00dev->trigger_qual); | ||
193 | rt2x00leds_unregister_led(&rt2x00dev->led_qual); | ||
194 | rt2x00leds_unregister_led(&rt2x00dev->led_assoc); | ||
195 | rt2x00leds_unregister_led(&rt2x00dev->led_radio); | ||
196 | } | ||
197 | |||
198 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) | ||
199 | { | ||
200 | if (rt2x00dev->led_qual.registered) | ||
201 | led_classdev_suspend(&rt2x00dev->led_qual.led_dev); | ||
202 | if (rt2x00dev->led_assoc.registered) | ||
203 | led_classdev_suspend(&rt2x00dev->led_assoc.led_dev); | ||
204 | if (rt2x00dev->led_radio.registered) | ||
205 | led_classdev_suspend(&rt2x00dev->led_radio.led_dev); | ||
206 | } | ||
207 | |||
208 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) | ||
209 | { | ||
210 | if (rt2x00dev->led_radio.registered) | ||
211 | led_classdev_resume(&rt2x00dev->led_radio.led_dev); | ||
212 | if (rt2x00dev->led_assoc.registered) | ||
213 | led_classdev_resume(&rt2x00dev->led_assoc.led_dev); | ||
214 | if (rt2x00dev->led_qual.registered) | ||
215 | led_classdev_resume(&rt2x00dev->led_qual.led_dev); | ||
216 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.h b/drivers/net/wireless/rt2x00/rt2x00leds.h new file mode 100644 index 000000000000..11e71e9ce853 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00leds.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 led datastructures and routines | ||
24 | */ | ||
25 | |||
26 | #ifndef RT2X00LEDS_H | ||
27 | #define RT2X00LEDS_H | ||
28 | |||
29 | /* | ||
30 | * Flags used by driver to indicate which | ||
31 | * which led types are supported. | ||
32 | */ | ||
33 | #define LED_SUPPORT_RADIO 0x000001 | ||
34 | #define LED_SUPPORT_ASSOC 0x000002 | ||
35 | #define LED_SUPPORT_ACTIVITY 0x000004 | ||
36 | #define LED_SUPPORT_QUALITY 0x000008 | ||
37 | |||
38 | enum led_type { | ||
39 | LED_TYPE_RADIO, | ||
40 | LED_TYPE_ASSOC, | ||
41 | LED_TYPE_QUALITY, | ||
42 | }; | ||
43 | |||
44 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
45 | |||
46 | struct rt2x00_led { | ||
47 | struct rt2x00_dev *rt2x00dev; | ||
48 | struct led_classdev led_dev; | ||
49 | |||
50 | enum led_type type; | ||
51 | unsigned int registered; | ||
52 | }; | ||
53 | |||
54 | struct rt2x00_trigger { | ||
55 | struct led_trigger trigger; | ||
56 | |||
57 | enum led_type type; | ||
58 | unsigned int registered; | ||
59 | }; | ||
60 | |||
61 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
62 | |||
63 | #endif /* RT2X00LEDS_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index ce58c654ade1..64fae7e3f73b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -34,6 +34,40 @@ | |||
34 | #define RFKILL_POLL_INTERVAL ( 1000 ) | 34 | #define RFKILL_POLL_INTERVAL ( 1000 ) |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * rt2x00_rate: Per rate device information | ||
38 | */ | ||
39 | struct rt2x00_rate { | ||
40 | unsigned short flags; | ||
41 | #define DEV_RATE_CCK 0x0001 | ||
42 | #define DEV_RATE_OFDM 0x0002 | ||
43 | #define DEV_RATE_SHORT_PREAMBLE 0x0004 | ||
44 | #define DEV_RATE_BASIC 0x0008 | ||
45 | |||
46 | unsigned short bitrate; /* In 100kbit/s */ | ||
47 | unsigned short ratemask; | ||
48 | |||
49 | unsigned short plcp; | ||
50 | }; | ||
51 | |||
52 | extern const struct rt2x00_rate rt2x00_supported_rates[12]; | ||
53 | |||
54 | static inline u16 rt2x00_create_rate_hw_value(const u16 index, | ||
55 | const u16 short_preamble) | ||
56 | { | ||
57 | return (short_preamble << 8) | (index & 0xff); | ||
58 | } | ||
59 | |||
60 | static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value) | ||
61 | { | ||
62 | return &rt2x00_supported_rates[hw_value & 0xff]; | ||
63 | } | ||
64 | |||
65 | static inline int rt2x00_get_rate_preamble(const u16 hw_value) | ||
66 | { | ||
67 | return (hw_value & 0xff00); | ||
68 | } | ||
69 | |||
70 | /* | ||
37 | * Radio control handlers. | 71 | * Radio control handlers. |
38 | */ | 72 | */ |
39 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); | 73 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); |
@@ -50,15 +84,29 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev); | |||
50 | /* | 84 | /* |
51 | * Configuration handlers. | 85 | * Configuration handlers. |
52 | */ | 86 | */ |
53 | void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac); | 87 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, |
54 | void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid); | 88 | struct rt2x00_intf *intf, |
55 | void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type); | 89 | enum ieee80211_if_types type, |
90 | u8 *mac, u8 *bssid); | ||
91 | void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | ||
92 | struct rt2x00_intf *intf, | ||
93 | struct ieee80211_bss_conf *conf); | ||
56 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 94 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
57 | enum antenna rx, enum antenna tx); | 95 | enum antenna rx, enum antenna tx); |
58 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 96 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
59 | struct ieee80211_conf *conf, const int force_config); | 97 | struct ieee80211_conf *conf, const int force_config); |
60 | 98 | ||
61 | /* | 99 | /* |
100 | * Queue handlers. | ||
101 | */ | ||
102 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); | ||
103 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); | ||
104 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); | ||
105 | void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev); | ||
106 | int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev); | ||
107 | void rt2x00queue_free(struct rt2x00_dev *rt2x00dev); | ||
108 | |||
109 | /* | ||
62 | * Firmware handlers. | 110 | * Firmware handlers. |
63 | */ | 111 | */ |
64 | #ifdef CONFIG_RT2X00_LIB_FIRMWARE | 112 | #ifdef CONFIG_RT2X00_LIB_FIRMWARE |
@@ -132,4 +180,36 @@ static inline void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev) | |||
132 | } | 180 | } |
133 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | 181 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ |
134 | 182 | ||
183 | /* | ||
184 | * LED handlers | ||
185 | */ | ||
186 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
187 | void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi); | ||
188 | void rt2x00leds_register(struct rt2x00_dev *rt2x00dev); | ||
189 | void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev); | ||
190 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev); | ||
191 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev); | ||
192 | #else | ||
193 | static inline void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, | ||
194 | int rssi) | ||
195 | { | ||
196 | } | ||
197 | |||
198 | static inline void rt2x00leds_register(struct rt2x00_dev *rt2x00dev) | ||
199 | { | ||
200 | } | ||
201 | |||
202 | static inline void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) | ||
203 | { | ||
204 | } | ||
205 | |||
206 | static inline void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) | ||
207 | { | ||
208 | } | ||
209 | |||
210 | static inline void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) | ||
211 | { | ||
212 | } | ||
213 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
214 | |||
135 | #endif /* RT2X00LIB_H */ | 215 | #endif /* RT2X00LIB_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index e3f15e518c76..0a11c27d603b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -30,10 +30,11 @@ | |||
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | 32 | static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, |
33 | struct data_ring *ring, | 33 | struct data_queue *queue, |
34 | struct sk_buff *frag_skb, | 34 | struct sk_buff *frag_skb, |
35 | struct ieee80211_tx_control *control) | 35 | struct ieee80211_tx_control *control) |
36 | { | 36 | { |
37 | struct skb_frame_desc *skbdesc; | ||
37 | struct sk_buff *skb; | 38 | struct sk_buff *skb; |
38 | int size; | 39 | int size; |
39 | 40 | ||
@@ -52,15 +53,22 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
52 | skb_put(skb, size); | 53 | skb_put(skb, size); |
53 | 54 | ||
54 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 55 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) |
55 | ieee80211_ctstoself_get(rt2x00dev->hw, rt2x00dev->interface.id, | 56 | ieee80211_ctstoself_get(rt2x00dev->hw, control->vif, |
56 | frag_skb->data, frag_skb->len, control, | 57 | frag_skb->data, frag_skb->len, control, |
57 | (struct ieee80211_cts *)(skb->data)); | 58 | (struct ieee80211_cts *)(skb->data)); |
58 | else | 59 | else |
59 | ieee80211_rts_get(rt2x00dev->hw, rt2x00dev->interface.id, | 60 | ieee80211_rts_get(rt2x00dev->hw, control->vif, |
60 | frag_skb->data, frag_skb->len, control, | 61 | frag_skb->data, frag_skb->len, control, |
61 | (struct ieee80211_rts *)(skb->data)); | 62 | (struct ieee80211_rts *)(skb->data)); |
62 | 63 | ||
63 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) { | 64 | /* |
65 | * Initialize skb descriptor | ||
66 | */ | ||
67 | skbdesc = get_skb_frame_desc(skb); | ||
68 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
69 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
70 | |||
71 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) { | ||
64 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); | 72 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); |
65 | return NETDEV_TX_BUSY; | 73 | return NETDEV_TX_BUSY; |
66 | } | 74 | } |
@@ -73,7 +81,8 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
73 | { | 81 | { |
74 | struct rt2x00_dev *rt2x00dev = hw->priv; | 82 | struct rt2x00_dev *rt2x00dev = hw->priv; |
75 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | 83 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; |
76 | struct data_ring *ring; | 84 | struct data_queue *queue; |
85 | struct skb_frame_desc *skbdesc; | ||
77 | u16 frame_control; | 86 | u16 frame_control; |
78 | 87 | ||
79 | /* | 88 | /* |
@@ -88,10 +97,14 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
88 | } | 97 | } |
89 | 98 | ||
90 | /* | 99 | /* |
91 | * Determine which ring to put packet on. | 100 | * Determine which queue to put packet on. |
92 | */ | 101 | */ |
93 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | 102 | if (control->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM && |
94 | if (unlikely(!ring)) { | 103 | test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) |
104 | queue = rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); | ||
105 | else | ||
106 | queue = rt2x00queue_get_queue(rt2x00dev, control->queue); | ||
107 | if (unlikely(!queue)) { | ||
95 | ERROR(rt2x00dev, | 108 | ERROR(rt2x00dev, |
96 | "Attempt to send packet over invalid queue %d.\n" | 109 | "Attempt to send packet over invalid queue %d.\n" |
97 | "Please file bug report to %s.\n", | 110 | "Please file bug report to %s.\n", |
@@ -110,23 +123,29 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
110 | if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && | 123 | if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && |
111 | (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS | | 124 | (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS | |
112 | IEEE80211_TXCTL_USE_CTS_PROTECT))) { | 125 | IEEE80211_TXCTL_USE_CTS_PROTECT))) { |
113 | if (rt2x00_ring_free(ring) <= 1) { | 126 | if (rt2x00queue_available(queue) <= 1) { |
114 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 127 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
115 | return NETDEV_TX_BUSY; | 128 | return NETDEV_TX_BUSY; |
116 | } | 129 | } |
117 | 130 | ||
118 | if (rt2x00mac_tx_rts_cts(rt2x00dev, ring, skb, control)) { | 131 | if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb, control)) { |
119 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 132 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
120 | return NETDEV_TX_BUSY; | 133 | return NETDEV_TX_BUSY; |
121 | } | 134 | } |
122 | } | 135 | } |
123 | 136 | ||
124 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) { | 137 | /* |
138 | * Initialize skb descriptor | ||
139 | */ | ||
140 | skbdesc = get_skb_frame_desc(skb); | ||
141 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
142 | |||
143 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) { | ||
125 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 144 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
126 | return NETDEV_TX_BUSY; | 145 | return NETDEV_TX_BUSY; |
127 | } | 146 | } |
128 | 147 | ||
129 | if (rt2x00_ring_full(ring)) | 148 | if (rt2x00queue_full(queue)) |
130 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 149 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
131 | 150 | ||
132 | if (rt2x00dev->ops->lib->kick_tx_queue) | 151 | if (rt2x00dev->ops->lib->kick_tx_queue) |
@@ -162,27 +181,67 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
162 | struct ieee80211_if_init_conf *conf) | 181 | struct ieee80211_if_init_conf *conf) |
163 | { | 182 | { |
164 | struct rt2x00_dev *rt2x00dev = hw->priv; | 183 | struct rt2x00_dev *rt2x00dev = hw->priv; |
165 | struct interface *intf = &rt2x00dev->interface; | 184 | struct rt2x00_intf *intf = vif_to_intf(conf->vif); |
166 | 185 | struct data_queue *queue = | |
167 | /* FIXME: Beaconing is broken in rt2x00. */ | 186 | rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON); |
168 | if (conf->type == IEEE80211_IF_TYPE_IBSS || | 187 | struct queue_entry *entry = NULL; |
169 | conf->type == IEEE80211_IF_TYPE_AP) { | 188 | unsigned int i; |
170 | ERROR(rt2x00dev, | ||
171 | "rt2x00 does not support Adhoc or Master mode"); | ||
172 | return -EOPNOTSUPP; | ||
173 | } | ||
174 | 189 | ||
175 | /* | 190 | /* |
176 | * Don't allow interfaces to be added while | 191 | * Don't allow interfaces to be added |
177 | * either the device has disappeared or when | 192 | * the device has disappeared. |
178 | * another interface is already present. | ||
179 | */ | 193 | */ |
180 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 194 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || |
181 | is_interface_present(intf)) | 195 | !test_bit(DEVICE_STARTED, &rt2x00dev->flags)) |
196 | return -ENODEV; | ||
197 | |||
198 | /* | ||
199 | * When we don't support mixed interfaces (a combination | ||
200 | * of sta and ap virtual interfaces) then we can only | ||
201 | * add this interface when the rival interface count is 0. | ||
202 | */ | ||
203 | if (!test_bit(DRIVER_SUPPORT_MIXED_INTERFACES, &rt2x00dev->flags) && | ||
204 | ((conf->type == IEEE80211_IF_TYPE_AP && rt2x00dev->intf_sta_count) || | ||
205 | (conf->type != IEEE80211_IF_TYPE_AP && rt2x00dev->intf_ap_count))) | ||
182 | return -ENOBUFS; | 206 | return -ENOBUFS; |
183 | 207 | ||
184 | intf->id = conf->vif; | 208 | /* |
185 | intf->type = conf->type; | 209 | * Check if we exceeded the maximum amount of supported interfaces. |
210 | */ | ||
211 | if ((conf->type == IEEE80211_IF_TYPE_AP && | ||
212 | rt2x00dev->intf_ap_count >= rt2x00dev->ops->max_ap_intf) || | ||
213 | (conf->type != IEEE80211_IF_TYPE_AP && | ||
214 | rt2x00dev->intf_sta_count >= rt2x00dev->ops->max_sta_intf)) | ||
215 | return -ENOBUFS; | ||
216 | |||
217 | /* | ||
218 | * Loop through all beacon queues to find a free | ||
219 | * entry. Since there are as much beacon entries | ||
220 | * as the maximum interfaces, this search shouldn't | ||
221 | * fail. | ||
222 | */ | ||
223 | for (i = 0; i < queue->limit; i++) { | ||
224 | entry = &queue->entries[i]; | ||
225 | if (!__test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags)) | ||
226 | break; | ||
227 | } | ||
228 | |||
229 | if (unlikely(i == queue->limit)) | ||
230 | return -ENOBUFS; | ||
231 | |||
232 | /* | ||
233 | * We are now absolutely sure the interface can be created, | ||
234 | * increase interface count and start initialization. | ||
235 | */ | ||
236 | |||
237 | if (conf->type == IEEE80211_IF_TYPE_AP) | ||
238 | rt2x00dev->intf_ap_count++; | ||
239 | else | ||
240 | rt2x00dev->intf_sta_count++; | ||
241 | |||
242 | spin_lock_init(&intf->lock); | ||
243 | intf->beacon = entry; | ||
244 | |||
186 | if (conf->type == IEEE80211_IF_TYPE_AP) | 245 | if (conf->type == IEEE80211_IF_TYPE_AP) |
187 | memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN); | 246 | memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN); |
188 | memcpy(&intf->mac, conf->mac_addr, ETH_ALEN); | 247 | memcpy(&intf->mac, conf->mac_addr, ETH_ALEN); |
@@ -192,8 +251,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
192 | * has been initialized. Otherwise the device can reset | 251 | * has been initialized. Otherwise the device can reset |
193 | * the MAC registers. | 252 | * the MAC registers. |
194 | */ | 253 | */ |
195 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 254 | rt2x00lib_config_intf(rt2x00dev, intf, conf->type, intf->mac, NULL); |
196 | rt2x00lib_config_type(rt2x00dev, conf->type); | ||
197 | 255 | ||
198 | return 0; | 256 | return 0; |
199 | } | 257 | } |
@@ -203,7 +261,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
203 | struct ieee80211_if_init_conf *conf) | 261 | struct ieee80211_if_init_conf *conf) |
204 | { | 262 | { |
205 | struct rt2x00_dev *rt2x00dev = hw->priv; | 263 | struct rt2x00_dev *rt2x00dev = hw->priv; |
206 | struct interface *intf = &rt2x00dev->interface; | 264 | struct rt2x00_intf *intf = vif_to_intf(conf->vif); |
207 | 265 | ||
208 | /* | 266 | /* |
209 | * Don't allow interfaces to be remove while | 267 | * Don't allow interfaces to be remove while |
@@ -211,21 +269,27 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
211 | * no interface is present. | 269 | * no interface is present. |
212 | */ | 270 | */ |
213 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 271 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || |
214 | !is_interface_present(intf)) | 272 | (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) || |
273 | (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count)) | ||
215 | return; | 274 | return; |
216 | 275 | ||
217 | intf->id = 0; | 276 | if (conf->type == IEEE80211_IF_TYPE_AP) |
218 | intf->type = IEEE80211_IF_TYPE_INVALID; | 277 | rt2x00dev->intf_ap_count--; |
219 | memset(&intf->bssid, 0x00, ETH_ALEN); | 278 | else |
220 | memset(&intf->mac, 0x00, ETH_ALEN); | 279 | rt2x00dev->intf_sta_count--; |
280 | |||
281 | /* | ||
282 | * Release beacon entry so it is available for | ||
283 | * new interfaces again. | ||
284 | */ | ||
285 | __clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); | ||
221 | 286 | ||
222 | /* | 287 | /* |
223 | * Make sure the bssid and mac address registers | 288 | * Make sure the bssid and mac address registers |
224 | * are cleared to prevent false ACKing of frames. | 289 | * are cleared to prevent false ACKing of frames. |
225 | */ | 290 | */ |
226 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 291 | rt2x00lib_config_intf(rt2x00dev, intf, |
227 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 292 | IEEE80211_IF_TYPE_INVALID, NULL, NULL); |
228 | rt2x00lib_config_type(rt2x00dev, intf->type); | ||
229 | } | 293 | } |
230 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); | 294 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); |
231 | 295 | ||
@@ -270,7 +334,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
270 | struct ieee80211_if_conf *conf) | 334 | struct ieee80211_if_conf *conf) |
271 | { | 335 | { |
272 | struct rt2x00_dev *rt2x00dev = hw->priv; | 336 | struct rt2x00_dev *rt2x00dev = hw->priv; |
273 | struct interface *intf = &rt2x00dev->interface; | 337 | struct rt2x00_intf *intf = vif_to_intf(vif); |
274 | int status; | 338 | int status; |
275 | 339 | ||
276 | /* | 340 | /* |
@@ -280,12 +344,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
280 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) | 344 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) |
281 | return 0; | 345 | return 0; |
282 | 346 | ||
283 | /* | 347 | spin_lock(&intf->lock); |
284 | * If the given type does not match the configured type, | ||
285 | * there has been a problem. | ||
286 | */ | ||
287 | if (conf->type != intf->type) | ||
288 | return -EINVAL; | ||
289 | 348 | ||
290 | /* | 349 | /* |
291 | * If the interface does not work in master mode, | 350 | * If the interface does not work in master mode, |
@@ -294,7 +353,16 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
294 | */ | 353 | */ |
295 | if (conf->type != IEEE80211_IF_TYPE_AP) | 354 | if (conf->type != IEEE80211_IF_TYPE_AP) |
296 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); | 355 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); |
297 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 356 | |
357 | spin_unlock(&intf->lock); | ||
358 | |||
359 | /* | ||
360 | * Call rt2x00_config_intf() outside of the spinlock context since | ||
361 | * the call will sleep for USB drivers. By using the ieee80211_if_conf | ||
362 | * values as arguments we make keep access to rt2x00_intf thread safe | ||
363 | * even without the lock. | ||
364 | */ | ||
365 | rt2x00lib_config_intf(rt2x00dev, intf, conf->type, NULL, conf->bssid); | ||
298 | 366 | ||
299 | /* | 367 | /* |
300 | * We only need to initialize the beacon when master mode is enabled. | 368 | * We only need to initialize the beacon when master mode is enabled. |
@@ -334,9 +402,11 @@ int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, | |||
334 | struct rt2x00_dev *rt2x00dev = hw->priv; | 402 | struct rt2x00_dev *rt2x00dev = hw->priv; |
335 | unsigned int i; | 403 | unsigned int i; |
336 | 404 | ||
337 | for (i = 0; i < hw->queues; i++) | 405 | for (i = 0; i < hw->queues; i++) { |
338 | memcpy(&stats->data[i], &rt2x00dev->tx[i].stats, | 406 | stats->data[i].len = rt2x00dev->tx[i].length; |
339 | sizeof(rt2x00dev->tx[i].stats)); | 407 | stats->data[i].limit = rt2x00dev->tx[i].limit; |
408 | stats->data[i].count = rt2x00dev->tx[i].count; | ||
409 | } | ||
340 | 410 | ||
341 | return 0; | 411 | return 0; |
342 | } | 412 | } |
@@ -348,71 +418,68 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
348 | u32 changes) | 418 | u32 changes) |
349 | { | 419 | { |
350 | struct rt2x00_dev *rt2x00dev = hw->priv; | 420 | struct rt2x00_dev *rt2x00dev = hw->priv; |
351 | int short_preamble; | 421 | struct rt2x00_intf *intf = vif_to_intf(vif); |
352 | int ack_timeout; | ||
353 | int ack_consume_time; | ||
354 | int difs; | ||
355 | int preamble; | ||
356 | 422 | ||
357 | /* | 423 | /* |
358 | * We only support changing preamble mode. | 424 | * When the association status has changed we must reset the link |
425 | * tuner counter. This is because some drivers determine if they | ||
426 | * should perform link tuning based on the number of seconds | ||
427 | * while associated or not associated. | ||
359 | */ | 428 | */ |
360 | if (!(changes & BSS_CHANGED_ERP_PREAMBLE)) | 429 | if (changes & BSS_CHANGED_ASSOC) { |
361 | return; | 430 | rt2x00dev->link.count = 0; |
362 | |||
363 | short_preamble = bss_conf->use_short_preamble; | ||
364 | preamble = bss_conf->use_short_preamble ? | ||
365 | SHORT_PREAMBLE : PREAMBLE; | ||
366 | 431 | ||
367 | difs = (hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | 432 | if (bss_conf->assoc) |
368 | SHORT_DIFS : DIFS; | 433 | rt2x00dev->intf_associated++; |
369 | ack_timeout = difs + PLCP + preamble + get_duration(ACK_SIZE, 10); | 434 | else |
370 | 435 | rt2x00dev->intf_associated--; | |
371 | ack_consume_time = SIFS + PLCP + preamble + get_duration(ACK_SIZE, 10); | 436 | } |
372 | 437 | ||
373 | if (short_preamble) | 438 | /* |
374 | __set_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 439 | * When the erp information has changed, we should perform |
375 | else | 440 | * additional configuration steps. For all other changes we are done. |
376 | __clear_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 441 | */ |
442 | if (changes & BSS_CHANGED_ERP_PREAMBLE) | ||
443 | rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); | ||
377 | 444 | ||
378 | rt2x00dev->ops->lib->config_preamble(rt2x00dev, short_preamble, | 445 | spin_lock(&intf->lock); |
379 | ack_timeout, ack_consume_time); | 446 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); |
447 | spin_unlock(&intf->lock); | ||
380 | } | 448 | } |
381 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); | 449 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); |
382 | 450 | ||
383 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, | 451 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue_idx, |
384 | const struct ieee80211_tx_queue_params *params) | 452 | const struct ieee80211_tx_queue_params *params) |
385 | { | 453 | { |
386 | struct rt2x00_dev *rt2x00dev = hw->priv; | 454 | struct rt2x00_dev *rt2x00dev = hw->priv; |
387 | struct data_ring *ring; | 455 | struct data_queue *queue; |
388 | 456 | ||
389 | ring = rt2x00lib_get_ring(rt2x00dev, queue); | 457 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
390 | if (unlikely(!ring)) | 458 | if (unlikely(!queue)) |
391 | return -EINVAL; | 459 | return -EINVAL; |
392 | 460 | ||
393 | /* | 461 | /* |
394 | * The passed variables are stored as real value ((2^n)-1). | 462 | * The passed variables are stored as real value ((2^n)-1). |
395 | * Ralink registers require to know the bit number 'n'. | 463 | * Ralink registers require to know the bit number 'n'. |
396 | */ | 464 | */ |
397 | if (params->cw_min) | 465 | if (params->cw_min > 0) |
398 | ring->tx_params.cw_min = fls(params->cw_min); | 466 | queue->cw_min = fls(params->cw_min); |
399 | else | 467 | else |
400 | ring->tx_params.cw_min = 5; /* cw_min: 2^5 = 32. */ | 468 | queue->cw_min = 5; /* cw_min: 2^5 = 32. */ |
401 | 469 | ||
402 | if (params->cw_max) | 470 | if (params->cw_max > 0) |
403 | ring->tx_params.cw_max = fls(params->cw_max); | 471 | queue->cw_max = fls(params->cw_max); |
404 | else | 472 | else |
405 | ring->tx_params.cw_max = 10; /* cw_min: 2^10 = 1024. */ | 473 | queue->cw_max = 10; /* cw_min: 2^10 = 1024. */ |
406 | 474 | ||
407 | if (params->aifs) | 475 | if (params->aifs >= 0) |
408 | ring->tx_params.aifs = params->aifs; | 476 | queue->aifs = params->aifs; |
409 | else | 477 | else |
410 | ring->tx_params.aifs = 2; | 478 | queue->aifs = 2; |
411 | 479 | ||
412 | INFO(rt2x00dev, | 480 | INFO(rt2x00dev, |
413 | "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", | 481 | "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", |
414 | queue, ring->tx_params.cw_min, ring->tx_params.cw_max, | 482 | queue_idx, queue->cw_min, queue->cw_max, queue->aifs); |
415 | ring->tx_params.aifs); | ||
416 | 483 | ||
417 | return 0; | 484 | return 0; |
418 | } | 485 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 804a9980055d..7867ec64bd2c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -32,64 +32,21 @@ | |||
32 | #include "rt2x00pci.h" | 32 | #include "rt2x00pci.h" |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Beacon handlers. | ||
36 | */ | ||
37 | int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
38 | struct ieee80211_tx_control *control) | ||
39 | { | ||
40 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
41 | struct skb_desc *desc; | ||
42 | struct data_ring *ring; | ||
43 | struct data_entry *entry; | ||
44 | |||
45 | /* | ||
46 | * Just in case mac80211 doesn't set this correctly, | ||
47 | * but we need this queue set for the descriptor | ||
48 | * initialization. | ||
49 | */ | ||
50 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
51 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
52 | entry = rt2x00_get_data_entry(ring); | ||
53 | |||
54 | /* | ||
55 | * Fill in skb descriptor | ||
56 | */ | ||
57 | desc = get_skb_desc(skb); | ||
58 | desc->desc_len = ring->desc_size; | ||
59 | desc->data_len = skb->len; | ||
60 | desc->desc = entry->priv; | ||
61 | desc->data = skb->data; | ||
62 | desc->ring = ring; | ||
63 | desc->entry = entry; | ||
64 | |||
65 | memcpy(entry->data_addr, skb->data, skb->len); | ||
66 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
67 | |||
68 | /* | ||
69 | * Enable beacon generation. | ||
70 | */ | ||
71 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | EXPORT_SYMBOL_GPL(rt2x00pci_beacon_update); | ||
76 | |||
77 | /* | ||
78 | * TX data handlers. | 35 | * TX data handlers. |
79 | */ | 36 | */ |
80 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 37 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, |
81 | struct data_ring *ring, struct sk_buff *skb, | 38 | struct data_queue *queue, struct sk_buff *skb, |
82 | struct ieee80211_tx_control *control) | 39 | struct ieee80211_tx_control *control) |
83 | { | 40 | { |
84 | struct data_entry *entry = rt2x00_get_data_entry(ring); | 41 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
85 | __le32 *txd = entry->priv; | 42 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
86 | struct skb_desc *desc; | 43 | struct skb_frame_desc *skbdesc; |
87 | u32 word; | 44 | u32 word; |
88 | 45 | ||
89 | if (rt2x00_ring_full(ring)) | 46 | if (rt2x00queue_full(queue)) |
90 | return -EINVAL; | 47 | return -EINVAL; |
91 | 48 | ||
92 | rt2x00_desc_read(txd, 0, &word); | 49 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
93 | 50 | ||
94 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | 51 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || |
95 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { | 52 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { |
@@ -103,18 +60,18 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | |||
103 | /* | 60 | /* |
104 | * Fill in skb descriptor | 61 | * Fill in skb descriptor |
105 | */ | 62 | */ |
106 | desc = get_skb_desc(skb); | 63 | skbdesc = get_skb_frame_desc(skb); |
107 | desc->desc_len = ring->desc_size; | 64 | skbdesc->data = skb->data; |
108 | desc->data_len = skb->len; | 65 | skbdesc->data_len = skb->len; |
109 | desc->desc = entry->priv; | 66 | skbdesc->desc = priv_tx->desc; |
110 | desc->data = skb->data; | 67 | skbdesc->desc_len = queue->desc_size; |
111 | desc->ring = ring; | 68 | skbdesc->entry = entry; |
112 | desc->entry = entry; | 69 | |
113 | 70 | memcpy(&priv_tx->control, control, sizeof(priv_tx->control)); | |
114 | memcpy(entry->data_addr, skb->data, skb->len); | 71 | memcpy(priv_tx->data, skb->data, skb->len); |
115 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 72 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
116 | 73 | ||
117 | rt2x00_ring_index_inc(ring); | 74 | rt2x00queue_index_inc(queue, Q_INDEX); |
118 | 75 | ||
119 | return 0; | 76 | return 0; |
120 | } | 77 | } |
@@ -125,29 +82,28 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); | |||
125 | */ | 82 | */ |
126 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | 83 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) |
127 | { | 84 | { |
128 | struct data_ring *ring = rt2x00dev->rx; | 85 | struct data_queue *queue = rt2x00dev->rx; |
129 | struct data_entry *entry; | 86 | struct queue_entry *entry; |
130 | struct sk_buff *skb; | 87 | struct queue_entry_priv_pci_rx *priv_rx; |
131 | struct ieee80211_hdr *hdr; | 88 | struct ieee80211_hdr *hdr; |
132 | struct skb_desc *skbdesc; | 89 | struct skb_frame_desc *skbdesc; |
133 | struct rxdata_entry_desc desc; | 90 | struct rxdone_entry_desc rxdesc; |
134 | int header_size; | 91 | int header_size; |
135 | __le32 *rxd; | ||
136 | int align; | 92 | int align; |
137 | u32 word; | 93 | u32 word; |
138 | 94 | ||
139 | while (1) { | 95 | while (1) { |
140 | entry = rt2x00_get_data_entry(ring); | 96 | entry = rt2x00queue_get_entry(queue, Q_INDEX); |
141 | rxd = entry->priv; | 97 | priv_rx = entry->priv_data; |
142 | rt2x00_desc_read(rxd, 0, &word); | 98 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
143 | 99 | ||
144 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) | 100 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) |
145 | break; | 101 | break; |
146 | 102 | ||
147 | memset(&desc, 0, sizeof(desc)); | 103 | memset(&rxdesc, 0, sizeof(rxdesc)); |
148 | rt2x00dev->ops->lib->fill_rxdone(entry, &desc); | 104 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); |
149 | 105 | ||
150 | hdr = (struct ieee80211_hdr *)entry->data_addr; | 106 | hdr = (struct ieee80211_hdr *)priv_rx->data; |
151 | header_size = | 107 | header_size = |
152 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | 108 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); |
153 | 109 | ||
@@ -161,66 +117,68 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
161 | * Allocate the sk_buffer, initialize it and copy | 117 | * Allocate the sk_buffer, initialize it and copy |
162 | * all data into it. | 118 | * all data into it. |
163 | */ | 119 | */ |
164 | skb = dev_alloc_skb(desc.size + align); | 120 | entry->skb = dev_alloc_skb(rxdesc.size + align); |
165 | if (!skb) | 121 | if (!entry->skb) |
166 | return; | 122 | return; |
167 | 123 | ||
168 | skb_reserve(skb, align); | 124 | skb_reserve(entry->skb, align); |
169 | memcpy(skb_put(skb, desc.size), entry->data_addr, desc.size); | 125 | memcpy(skb_put(entry->skb, rxdesc.size), |
126 | priv_rx->data, rxdesc.size); | ||
170 | 127 | ||
171 | /* | 128 | /* |
172 | * Fill in skb descriptor | 129 | * Fill in skb descriptor |
173 | */ | 130 | */ |
174 | skbdesc = get_skb_desc(skb); | 131 | skbdesc = get_skb_frame_desc(entry->skb); |
175 | skbdesc->desc_len = entry->ring->desc_size; | 132 | memset(skbdesc, 0, sizeof(*skbdesc)); |
176 | skbdesc->data_len = skb->len; | 133 | skbdesc->data = entry->skb->data; |
177 | skbdesc->desc = entry->priv; | 134 | skbdesc->data_len = entry->skb->len; |
178 | skbdesc->data = skb->data; | 135 | skbdesc->desc = priv_rx->desc; |
179 | skbdesc->ring = ring; | 136 | skbdesc->desc_len = queue->desc_size; |
180 | skbdesc->entry = entry; | 137 | skbdesc->entry = entry; |
181 | 138 | ||
182 | /* | 139 | /* |
183 | * Send the frame to rt2x00lib for further processing. | 140 | * Send the frame to rt2x00lib for further processing. |
184 | */ | 141 | */ |
185 | rt2x00lib_rxdone(entry, skb, &desc); | 142 | rt2x00lib_rxdone(entry, &rxdesc); |
186 | 143 | ||
187 | if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) { | 144 | if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { |
188 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); | 145 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); |
189 | rt2x00_desc_write(rxd, 0, word); | 146 | rt2x00_desc_write(priv_rx->desc, 0, word); |
190 | } | 147 | } |
191 | 148 | ||
192 | rt2x00_ring_index_inc(ring); | 149 | rt2x00queue_index_inc(queue, Q_INDEX); |
193 | } | 150 | } |
194 | } | 151 | } |
195 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | 152 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); |
196 | 153 | ||
197 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry, | 154 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, |
198 | const int tx_status, const int retry) | 155 | struct txdone_entry_desc *txdesc) |
199 | { | 156 | { |
157 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; | ||
200 | u32 word; | 158 | u32 word; |
201 | 159 | ||
202 | rt2x00lib_txdone(entry, tx_status, retry); | 160 | txdesc->control = &priv_tx->control; |
161 | rt2x00lib_txdone(entry, txdesc); | ||
203 | 162 | ||
204 | /* | 163 | /* |
205 | * Make this entry available for reuse. | 164 | * Make this entry available for reuse. |
206 | */ | 165 | */ |
207 | entry->flags = 0; | 166 | entry->flags = 0; |
208 | 167 | ||
209 | rt2x00_desc_read(entry->priv, 0, &word); | 168 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
210 | rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); | 169 | rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); |
211 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); | 170 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); |
212 | rt2x00_desc_write(entry->priv, 0, word); | 171 | rt2x00_desc_write(priv_tx->desc, 0, word); |
213 | 172 | ||
214 | rt2x00_ring_index_done_inc(entry->ring); | 173 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
215 | 174 | ||
216 | /* | 175 | /* |
217 | * If the data ring was full before the txdone handler | 176 | * If the data queue was full before the txdone handler |
218 | * we must make sure the packet queue in the mac80211 stack | 177 | * we must make sure the packet queue in the mac80211 stack |
219 | * is reenabled when the txdone handler has finished. | 178 | * is reenabled when the txdone handler has finished. |
220 | */ | 179 | */ |
221 | if (!rt2x00_ring_full(entry->ring)) | 180 | if (!rt2x00queue_full(entry->queue)) |
222 | ieee80211_wake_queue(rt2x00dev->hw, | 181 | ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); |
223 | entry->tx_status.control.queue); | ||
224 | 182 | ||
225 | } | 183 | } |
226 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | 184 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); |
@@ -228,73 +186,122 @@ EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | |||
228 | /* | 186 | /* |
229 | * Device initialization handlers. | 187 | * Device initialization handlers. |
230 | */ | 188 | */ |
231 | #define priv_offset(__ring, __i) \ | 189 | #define desc_size(__queue) \ |
232 | ({ \ | 190 | ({ \ |
233 | ring->data_addr + (i * ring->desc_size); \ | 191 | ((__queue)->limit * (__queue)->desc_size);\ |
192 | }) | ||
193 | |||
194 | #define data_size(__queue) \ | ||
195 | ({ \ | ||
196 | ((__queue)->limit * (__queue)->data_size);\ | ||
234 | }) | 197 | }) |
235 | 198 | ||
236 | #define data_addr_offset(__ring, __i) \ | 199 | #define dma_size(__queue) \ |
237 | ({ \ | 200 | ({ \ |
238 | (__ring)->data_addr + \ | 201 | data_size(__queue) + desc_size(__queue);\ |
239 | ((__ring)->stats.limit * (__ring)->desc_size) + \ | ||
240 | ((__i) * (__ring)->data_size); \ | ||
241 | }) | 202 | }) |
242 | 203 | ||
243 | #define data_dma_offset(__ring, __i) \ | 204 | #define desc_offset(__queue, __base, __i) \ |
244 | ({ \ | 205 | ({ \ |
245 | (__ring)->data_dma + \ | 206 | (__base) + data_size(__queue) + \ |
246 | ((__ring)->stats.limit * (__ring)->desc_size) + \ | 207 | ((__i) * (__queue)->desc_size); \ |
247 | ((__i) * (__ring)->data_size); \ | ||
248 | }) | 208 | }) |
249 | 209 | ||
250 | static int rt2x00pci_alloc_dma(struct rt2x00_dev *rt2x00dev, | 210 | #define data_offset(__queue, __base, __i) \ |
251 | struct data_ring *ring) | 211 | ({ \ |
212 | (__base) + \ | ||
213 | ((__i) * (__queue)->data_size); \ | ||
214 | }) | ||
215 | |||
216 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | ||
217 | struct data_queue *queue) | ||
252 | { | 218 | { |
219 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | ||
220 | struct queue_entry_priv_pci_rx *priv_rx; | ||
221 | struct queue_entry_priv_pci_tx *priv_tx; | ||
222 | void *addr; | ||
223 | dma_addr_t dma; | ||
224 | void *desc_addr; | ||
225 | dma_addr_t desc_dma; | ||
226 | void *data_addr; | ||
227 | dma_addr_t data_dma; | ||
253 | unsigned int i; | 228 | unsigned int i; |
254 | 229 | ||
255 | /* | 230 | /* |
256 | * Allocate DMA memory for descriptor and buffer. | 231 | * Allocate DMA memory for descriptor and buffer. |
257 | */ | 232 | */ |
258 | ring->data_addr = pci_alloc_consistent(rt2x00dev_pci(rt2x00dev), | 233 | addr = pci_alloc_consistent(pci_dev, dma_size(queue), &dma); |
259 | rt2x00_get_ring_size(ring), | 234 | if (!addr) |
260 | &ring->data_dma); | ||
261 | if (!ring->data_addr) | ||
262 | return -ENOMEM; | 235 | return -ENOMEM; |
263 | 236 | ||
237 | memset(addr, 0, dma_size(queue)); | ||
238 | |||
264 | /* | 239 | /* |
265 | * Initialize all ring entries to contain valid | 240 | * Initialize all queue entries to contain valid addresses. |
266 | * addresses. | ||
267 | */ | 241 | */ |
268 | for (i = 0; i < ring->stats.limit; i++) { | 242 | for (i = 0; i < queue->limit; i++) { |
269 | ring->entry[i].priv = priv_offset(ring, i); | 243 | desc_addr = desc_offset(queue, addr, i); |
270 | ring->entry[i].data_addr = data_addr_offset(ring, i); | 244 | desc_dma = desc_offset(queue, dma, i); |
271 | ring->entry[i].data_dma = data_dma_offset(ring, i); | 245 | data_addr = data_offset(queue, addr, i); |
246 | data_dma = data_offset(queue, dma, i); | ||
247 | |||
248 | if (queue->qid == QID_RX) { | ||
249 | priv_rx = queue->entries[i].priv_data; | ||
250 | priv_rx->desc = desc_addr; | ||
251 | priv_rx->desc_dma = desc_dma; | ||
252 | priv_rx->data = data_addr; | ||
253 | priv_rx->data_dma = data_dma; | ||
254 | } else { | ||
255 | priv_tx = queue->entries[i].priv_data; | ||
256 | priv_tx->desc = desc_addr; | ||
257 | priv_tx->desc_dma = desc_dma; | ||
258 | priv_tx->data = data_addr; | ||
259 | priv_tx->data_dma = data_dma; | ||
260 | } | ||
272 | } | 261 | } |
273 | 262 | ||
274 | return 0; | 263 | return 0; |
275 | } | 264 | } |
276 | 265 | ||
277 | static void rt2x00pci_free_dma(struct rt2x00_dev *rt2x00dev, | 266 | static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, |
278 | struct data_ring *ring) | 267 | struct data_queue *queue) |
279 | { | 268 | { |
280 | if (ring->data_addr) | 269 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
281 | pci_free_consistent(rt2x00dev_pci(rt2x00dev), | 270 | struct queue_entry_priv_pci_rx *priv_rx; |
282 | rt2x00_get_ring_size(ring), | 271 | struct queue_entry_priv_pci_tx *priv_tx; |
283 | ring->data_addr, ring->data_dma); | 272 | void *data_addr; |
284 | ring->data_addr = NULL; | 273 | dma_addr_t data_dma; |
274 | |||
275 | if (queue->qid == QID_RX) { | ||
276 | priv_rx = queue->entries[0].priv_data; | ||
277 | data_addr = priv_rx->data; | ||
278 | data_dma = priv_rx->data_dma; | ||
279 | |||
280 | priv_rx->data = NULL; | ||
281 | } else { | ||
282 | priv_tx = queue->entries[0].priv_data; | ||
283 | data_addr = priv_tx->data; | ||
284 | data_dma = priv_tx->data_dma; | ||
285 | |||
286 | priv_tx->data = NULL; | ||
287 | } | ||
288 | |||
289 | if (data_addr) | ||
290 | pci_free_consistent(pci_dev, dma_size(queue), | ||
291 | data_addr, data_dma); | ||
285 | } | 292 | } |
286 | 293 | ||
287 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | 294 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) |
288 | { | 295 | { |
289 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 296 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
290 | struct data_ring *ring; | 297 | struct data_queue *queue; |
291 | int status; | 298 | int status; |
292 | 299 | ||
293 | /* | 300 | /* |
294 | * Allocate DMA | 301 | * Allocate DMA |
295 | */ | 302 | */ |
296 | ring_for_each(rt2x00dev, ring) { | 303 | queue_for_each(rt2x00dev, queue) { |
297 | status = rt2x00pci_alloc_dma(rt2x00dev, ring); | 304 | status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); |
298 | if (status) | 305 | if (status) |
299 | goto exit; | 306 | goto exit; |
300 | } | 307 | } |
@@ -321,7 +328,7 @@ EXPORT_SYMBOL_GPL(rt2x00pci_initialize); | |||
321 | 328 | ||
322 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | 329 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) |
323 | { | 330 | { |
324 | struct data_ring *ring; | 331 | struct data_queue *queue; |
325 | 332 | ||
326 | /* | 333 | /* |
327 | * Free irq line. | 334 | * Free irq line. |
@@ -331,8 +338,8 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
331 | /* | 338 | /* |
332 | * Free DMA | 339 | * Free DMA |
333 | */ | 340 | */ |
334 | ring_for_each(rt2x00dev, ring) | 341 | queue_for_each(rt2x00dev, queue) |
335 | rt2x00pci_free_dma(rt2x00dev, ring); | 342 | rt2x00pci_free_queue_dma(rt2x00dev, queue); |
336 | } | 343 | } |
337 | EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); | 344 | EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); |
338 | 345 | ||
@@ -347,9 +354,9 @@ static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) | |||
347 | kfree(rt2x00dev->eeprom); | 354 | kfree(rt2x00dev->eeprom); |
348 | rt2x00dev->eeprom = NULL; | 355 | rt2x00dev->eeprom = NULL; |
349 | 356 | ||
350 | if (rt2x00dev->csr_addr) { | 357 | if (rt2x00dev->csr.base) { |
351 | iounmap(rt2x00dev->csr_addr); | 358 | iounmap(rt2x00dev->csr.base); |
352 | rt2x00dev->csr_addr = NULL; | 359 | rt2x00dev->csr.base = NULL; |
353 | } | 360 | } |
354 | } | 361 | } |
355 | 362 | ||
@@ -357,9 +364,9 @@ static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) | |||
357 | { | 364 | { |
358 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 365 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
359 | 366 | ||
360 | rt2x00dev->csr_addr = ioremap(pci_resource_start(pci_dev, 0), | 367 | rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0), |
361 | pci_resource_len(pci_dev, 0)); | 368 | pci_resource_len(pci_dev, 0)); |
362 | if (!rt2x00dev->csr_addr) | 369 | if (!rt2x00dev->csr.base) |
363 | goto exit; | 370 | goto exit; |
364 | 371 | ||
365 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); | 372 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); |
@@ -530,5 +537,5 @@ EXPORT_SYMBOL_GPL(rt2x00pci_resume); | |||
530 | */ | 537 | */ |
531 | MODULE_AUTHOR(DRV_PROJECT); | 538 | MODULE_AUTHOR(DRV_PROJECT); |
532 | MODULE_VERSION(DRV_VERSION); | 539 | MODULE_VERSION(DRV_VERSION); |
533 | MODULE_DESCRIPTION("rt2x00 library"); | 540 | MODULE_DESCRIPTION("rt2x00 pci library"); |
534 | MODULE_LICENSE("GPL"); | 541 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 2d1eb8144da4..9d1cdb99431c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -61,7 +61,7 @@ static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, | |||
61 | const unsigned long offset, | 61 | const unsigned long offset, |
62 | u32 *value) | 62 | u32 *value) |
63 | { | 63 | { |
64 | *value = readl(rt2x00dev->csr_addr + offset); | 64 | *value = readl(rt2x00dev->csr.base + offset); |
65 | } | 65 | } |
66 | 66 | ||
67 | static inline void | 67 | static inline void |
@@ -69,14 +69,14 @@ rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, | |||
69 | const unsigned long offset, | 69 | const unsigned long offset, |
70 | void *value, const u16 length) | 70 | void *value, const u16 length) |
71 | { | 71 | { |
72 | memcpy_fromio(value, rt2x00dev->csr_addr + offset, length); | 72 | memcpy_fromio(value, rt2x00dev->csr.base + offset, length); |
73 | } | 73 | } |
74 | 74 | ||
75 | static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, | 75 | static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, |
76 | const unsigned long offset, | 76 | const unsigned long offset, |
77 | u32 value) | 77 | u32 value) |
78 | { | 78 | { |
79 | writel(value, rt2x00dev->csr_addr + offset); | 79 | writel(value, rt2x00dev->csr.base + offset); |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline void | 82 | static inline void |
@@ -84,28 +84,63 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, | |||
84 | const unsigned long offset, | 84 | const unsigned long offset, |
85 | void *value, const u16 length) | 85 | void *value, const u16 length) |
86 | { | 86 | { |
87 | memcpy_toio(rt2x00dev->csr_addr + offset, value, length); | 87 | memcpy_toio(rt2x00dev->csr.base + offset, value, length); |
88 | } | 88 | } |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * Beacon handlers. | ||
92 | */ | ||
93 | int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
94 | struct ieee80211_tx_control *control); | ||
95 | |||
96 | /* | ||
97 | * TX data handlers. | 91 | * TX data handlers. |
98 | */ | 92 | */ |
99 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 93 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, |
100 | struct data_ring *ring, struct sk_buff *skb, | 94 | struct data_queue *queue, struct sk_buff *skb, |
101 | struct ieee80211_tx_control *control); | 95 | struct ieee80211_tx_control *control); |
102 | 96 | ||
103 | /* | 97 | /** |
104 | * RX/TX data handlers. | 98 | * struct queue_entry_priv_pci_rx: Per RX entry PCI specific information |
99 | * | ||
100 | * @desc: Pointer to device descriptor. | ||
101 | * @data: Pointer to device's entry memory. | ||
102 | * @dma: DMA pointer to &data. | ||
103 | */ | ||
104 | struct queue_entry_priv_pci_rx { | ||
105 | __le32 *desc; | ||
106 | dma_addr_t desc_dma; | ||
107 | |||
108 | void *data; | ||
109 | dma_addr_t data_dma; | ||
110 | }; | ||
111 | |||
112 | /** | ||
113 | * struct queue_entry_priv_pci_tx: Per TX entry PCI specific information | ||
114 | * | ||
115 | * @desc: Pointer to device descriptor | ||
116 | * @data: Pointer to device's entry memory. | ||
117 | * @dma: DMA pointer to &data. | ||
118 | * @control: mac80211 control structure used to transmit data. | ||
119 | */ | ||
120 | struct queue_entry_priv_pci_tx { | ||
121 | __le32 *desc; | ||
122 | dma_addr_t desc_dma; | ||
123 | |||
124 | void *data; | ||
125 | dma_addr_t data_dma; | ||
126 | |||
127 | struct ieee80211_tx_control control; | ||
128 | }; | ||
129 | |||
130 | /** | ||
131 | * rt2x00pci_rxdone - Handle RX done events | ||
132 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
105 | */ | 133 | */ |
106 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); | 134 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); |
107 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry, | 135 | |
108 | const int tx_status, const int retry); | 136 | /** |
137 | * rt2x00pci_txdone - Handle TX done events | ||
138 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
139 | * @entry: Entry which has completed the transmission of a frame. | ||
140 | * @desc: TX done descriptor | ||
141 | */ | ||
142 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | ||
143 | struct txdone_entry_desc *desc); | ||
109 | 144 | ||
110 | /* | 145 | /* |
111 | * Device initialization handlers. | 146 | * Device initialization handlers. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c new file mode 100644 index 000000000000..659e9f44c40c --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -0,0 +1,304 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 queue specific routines. | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #include "rt2x00.h" | ||
30 | #include "rt2x00lib.h" | ||
31 | |||
32 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | ||
33 | const unsigned int queue) | ||
34 | { | ||
35 | int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | ||
36 | |||
37 | if (queue < rt2x00dev->hw->queues && rt2x00dev->tx) | ||
38 | return &rt2x00dev->tx[queue]; | ||
39 | |||
40 | if (!rt2x00dev->bcn) | ||
41 | return NULL; | ||
42 | |||
43 | if (queue == RT2X00_BCN_QUEUE_BEACON) | ||
44 | return &rt2x00dev->bcn[0]; | ||
45 | else if (queue == RT2X00_BCN_QUEUE_ATIM && atim) | ||
46 | return &rt2x00dev->bcn[1]; | ||
47 | |||
48 | return NULL; | ||
49 | } | ||
50 | EXPORT_SYMBOL_GPL(rt2x00queue_get_queue); | ||
51 | |||
52 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, | ||
53 | enum queue_index index) | ||
54 | { | ||
55 | struct queue_entry *entry; | ||
56 | unsigned long irqflags; | ||
57 | |||
58 | if (unlikely(index >= Q_INDEX_MAX)) { | ||
59 | ERROR(queue->rt2x00dev, | ||
60 | "Entry requested from invalid index type (%d)\n", index); | ||
61 | return NULL; | ||
62 | } | ||
63 | |||
64 | spin_lock_irqsave(&queue->lock, irqflags); | ||
65 | |||
66 | entry = &queue->entries[queue->index[index]]; | ||
67 | |||
68 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
69 | |||
70 | return entry; | ||
71 | } | ||
72 | EXPORT_SYMBOL_GPL(rt2x00queue_get_entry); | ||
73 | |||
74 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | ||
75 | { | ||
76 | unsigned long irqflags; | ||
77 | |||
78 | if (unlikely(index >= Q_INDEX_MAX)) { | ||
79 | ERROR(queue->rt2x00dev, | ||
80 | "Index change on invalid index type (%d)\n", index); | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | spin_lock_irqsave(&queue->lock, irqflags); | ||
85 | |||
86 | queue->index[index]++; | ||
87 | if (queue->index[index] >= queue->limit) | ||
88 | queue->index[index] = 0; | ||
89 | |||
90 | if (index == Q_INDEX) { | ||
91 | queue->length++; | ||
92 | } else if (index == Q_INDEX_DONE) { | ||
93 | queue->length--; | ||
94 | queue->count ++; | ||
95 | } | ||
96 | |||
97 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
98 | } | ||
99 | EXPORT_SYMBOL_GPL(rt2x00queue_index_inc); | ||
100 | |||
101 | static void rt2x00queue_reset(struct data_queue *queue) | ||
102 | { | ||
103 | unsigned long irqflags; | ||
104 | |||
105 | spin_lock_irqsave(&queue->lock, irqflags); | ||
106 | |||
107 | queue->count = 0; | ||
108 | queue->length = 0; | ||
109 | memset(queue->index, 0, sizeof(queue->index)); | ||
110 | |||
111 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
112 | } | ||
113 | |||
114 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev) | ||
115 | { | ||
116 | struct data_queue *queue = rt2x00dev->rx; | ||
117 | unsigned int i; | ||
118 | |||
119 | rt2x00queue_reset(queue); | ||
120 | |||
121 | if (!rt2x00dev->ops->lib->init_rxentry) | ||
122 | return; | ||
123 | |||
124 | for (i = 0; i < queue->limit; i++) | ||
125 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, | ||
126 | &queue->entries[i]); | ||
127 | } | ||
128 | |||
129 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev) | ||
130 | { | ||
131 | struct data_queue *queue; | ||
132 | unsigned int i; | ||
133 | |||
134 | txall_queue_for_each(rt2x00dev, queue) { | ||
135 | rt2x00queue_reset(queue); | ||
136 | |||
137 | if (!rt2x00dev->ops->lib->init_txentry) | ||
138 | continue; | ||
139 | |||
140 | for (i = 0; i < queue->limit; i++) | ||
141 | rt2x00dev->ops->lib->init_txentry(rt2x00dev, | ||
142 | &queue->entries[i]); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | static int rt2x00queue_alloc_entries(struct data_queue *queue, | ||
147 | const struct data_queue_desc *qdesc) | ||
148 | { | ||
149 | struct queue_entry *entries; | ||
150 | unsigned int entry_size; | ||
151 | unsigned int i; | ||
152 | |||
153 | rt2x00queue_reset(queue); | ||
154 | |||
155 | queue->limit = qdesc->entry_num; | ||
156 | queue->data_size = qdesc->data_size; | ||
157 | queue->desc_size = qdesc->desc_size; | ||
158 | |||
159 | /* | ||
160 | * Allocate all queue entries. | ||
161 | */ | ||
162 | entry_size = sizeof(*entries) + qdesc->priv_size; | ||
163 | entries = kzalloc(queue->limit * entry_size, GFP_KERNEL); | ||
164 | if (!entries) | ||
165 | return -ENOMEM; | ||
166 | |||
167 | #define QUEUE_ENTRY_PRIV_OFFSET(__base, __index, __limit, __esize, __psize) \ | ||
168 | ( ((char *)(__base)) + ((__limit) * (__esize)) + \ | ||
169 | ((__index) * (__psize)) ) | ||
170 | |||
171 | for (i = 0; i < queue->limit; i++) { | ||
172 | entries[i].flags = 0; | ||
173 | entries[i].queue = queue; | ||
174 | entries[i].skb = NULL; | ||
175 | entries[i].entry_idx = i; | ||
176 | entries[i].priv_data = | ||
177 | QUEUE_ENTRY_PRIV_OFFSET(entries, i, queue->limit, | ||
178 | sizeof(*entries), qdesc->priv_size); | ||
179 | } | ||
180 | |||
181 | #undef QUEUE_ENTRY_PRIV_OFFSET | ||
182 | |||
183 | queue->entries = entries; | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | ||
189 | { | ||
190 | struct data_queue *queue; | ||
191 | int status; | ||
192 | |||
193 | |||
194 | status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); | ||
195 | if (status) | ||
196 | goto exit; | ||
197 | |||
198 | tx_queue_for_each(rt2x00dev, queue) { | ||
199 | status = rt2x00queue_alloc_entries(queue, rt2x00dev->ops->tx); | ||
200 | if (status) | ||
201 | goto exit; | ||
202 | } | ||
203 | |||
204 | status = rt2x00queue_alloc_entries(rt2x00dev->bcn, rt2x00dev->ops->bcn); | ||
205 | if (status) | ||
206 | goto exit; | ||
207 | |||
208 | if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | ||
209 | return 0; | ||
210 | |||
211 | status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], | ||
212 | rt2x00dev->ops->atim); | ||
213 | if (status) | ||
214 | goto exit; | ||
215 | |||
216 | return 0; | ||
217 | |||
218 | exit: | ||
219 | ERROR(rt2x00dev, "Queue entries allocation failed.\n"); | ||
220 | |||
221 | rt2x00queue_uninitialize(rt2x00dev); | ||
222 | |||
223 | return status; | ||
224 | } | ||
225 | |||
226 | void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) | ||
227 | { | ||
228 | struct data_queue *queue; | ||
229 | |||
230 | queue_for_each(rt2x00dev, queue) { | ||
231 | kfree(queue->entries); | ||
232 | queue->entries = NULL; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, | ||
237 | struct data_queue *queue, enum data_queue_qid qid) | ||
238 | { | ||
239 | spin_lock_init(&queue->lock); | ||
240 | |||
241 | queue->rt2x00dev = rt2x00dev; | ||
242 | queue->qid = qid; | ||
243 | queue->aifs = 2; | ||
244 | queue->cw_min = 5; | ||
245 | queue->cw_max = 10; | ||
246 | } | ||
247 | |||
248 | int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | ||
249 | { | ||
250 | struct data_queue *queue; | ||
251 | enum data_queue_qid qid; | ||
252 | unsigned int req_atim = | ||
253 | !!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | ||
254 | |||
255 | /* | ||
256 | * We need the following queues: | ||
257 | * RX: 1 | ||
258 | * TX: hw->queues | ||
259 | * Beacon: 1 | ||
260 | * Atim: 1 (if required) | ||
261 | */ | ||
262 | rt2x00dev->data_queues = 2 + rt2x00dev->hw->queues + req_atim; | ||
263 | |||
264 | queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL); | ||
265 | if (!queue) { | ||
266 | ERROR(rt2x00dev, "Queue allocation failed.\n"); | ||
267 | return -ENOMEM; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * Initialize pointers | ||
272 | */ | ||
273 | rt2x00dev->rx = queue; | ||
274 | rt2x00dev->tx = &queue[1]; | ||
275 | rt2x00dev->bcn = &queue[1 + rt2x00dev->hw->queues]; | ||
276 | |||
277 | /* | ||
278 | * Initialize queue parameters. | ||
279 | * RX: qid = QID_RX | ||
280 | * TX: qid = QID_AC_BE + index | ||
281 | * TX: cw_min: 2^5 = 32. | ||
282 | * TX: cw_max: 2^10 = 1024. | ||
283 | * BCN & Atim: qid = QID_MGMT | ||
284 | */ | ||
285 | rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX); | ||
286 | |||
287 | qid = QID_AC_BE; | ||
288 | tx_queue_for_each(rt2x00dev, queue) | ||
289 | rt2x00queue_init(rt2x00dev, queue, qid++); | ||
290 | |||
291 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_MGMT); | ||
292 | if (req_atim) | ||
293 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_MGMT); | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | void rt2x00queue_free(struct rt2x00_dev *rt2x00dev) | ||
299 | { | ||
300 | kfree(rt2x00dev->rx); | ||
301 | rt2x00dev->rx = NULL; | ||
302 | rt2x00dev->tx = NULL; | ||
303 | rt2x00dev->bcn = NULL; | ||
304 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h new file mode 100644 index 000000000000..c5f46f234083 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -0,0 +1,460 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00 | ||
23 | Abstract: rt2x00 queue datastructures and routines | ||
24 | */ | ||
25 | |||
26 | #ifndef RT2X00QUEUE_H | ||
27 | #define RT2X00QUEUE_H | ||
28 | |||
29 | #include <linux/prefetch.h> | ||
30 | |||
31 | /** | ||
32 | * DOC: Entrie frame size | ||
33 | * | ||
34 | * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes, | ||
35 | * for USB devices this restriction does not apply, but the value of | ||
36 | * 2432 makes sense since it is big enough to contain the maximum fragment | ||
37 | * size according to the ieee802.11 specs. | ||
38 | */ | ||
39 | #define DATA_FRAME_SIZE 2432 | ||
40 | #define MGMT_FRAME_SIZE 256 | ||
41 | |||
42 | /** | ||
43 | * DOC: Number of entries per queue | ||
44 | * | ||
45 | * After research it was concluded that 12 entries in a RX and TX | ||
46 | * queue would be sufficient. Although this is almost one third of | ||
47 | * the amount the legacy driver allocated, the queues aren't getting | ||
48 | * filled to the maximum even when working with the maximum rate. | ||
49 | */ | ||
50 | #define RX_ENTRIES 12 | ||
51 | #define TX_ENTRIES 12 | ||
52 | #define BEACON_ENTRIES 1 | ||
53 | #define ATIM_ENTRIES 1 | ||
54 | |||
55 | /** | ||
56 | * enum data_queue_qid: Queue identification | ||
57 | */ | ||
58 | enum data_queue_qid { | ||
59 | QID_AC_BE = 0, | ||
60 | QID_AC_BK = 1, | ||
61 | QID_AC_VI = 2, | ||
62 | QID_AC_VO = 3, | ||
63 | QID_HCCA = 4, | ||
64 | QID_MGMT = 13, | ||
65 | QID_RX = 14, | ||
66 | QID_OTHER = 15, | ||
67 | }; | ||
68 | |||
69 | /** | ||
70 | * enum rt2x00_bcn_queue: Beacon queue index | ||
71 | * | ||
72 | * Start counting with a high offset, this because this enumeration | ||
73 | * supplements &enum ieee80211_tx_queue and we should prevent value | ||
74 | * conflicts. | ||
75 | * | ||
76 | * @RT2X00_BCN_QUEUE_BEACON: Beacon queue | ||
77 | * @RT2X00_BCN_QUEUE_ATIM: Atim queue (sends frame after beacon) | ||
78 | */ | ||
79 | enum rt2x00_bcn_queue { | ||
80 | RT2X00_BCN_QUEUE_BEACON = 100, | ||
81 | RT2X00_BCN_QUEUE_ATIM = 101, | ||
82 | }; | ||
83 | |||
84 | /** | ||
85 | * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc | ||
86 | * | ||
87 | * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver | ||
88 | * and should not be reported back to mac80211 during txdone. | ||
89 | */ | ||
90 | enum skb_frame_desc_flags { | ||
91 | FRAME_DESC_DRIVER_GENERATED = 1 << 0, | ||
92 | }; | ||
93 | |||
94 | /** | ||
95 | * struct skb_frame_desc: Descriptor information for the skb buffer | ||
96 | * | ||
97 | * This structure is placed over the skb->cb array, this means that | ||
98 | * this structure should not exceed the size of that array (48 bytes). | ||
99 | * | ||
100 | * @flags: Frame flags, see &enum skb_frame_desc_flags. | ||
101 | * @frame_type: Frame type, see &enum rt2x00_dump_type. | ||
102 | * @data: Pointer to data part of frame (Start of ieee80211 header). | ||
103 | * @desc: Pointer to descriptor part of the frame. | ||
104 | * Note that this pointer could point to something outside | ||
105 | * of the scope of the skb->data pointer. | ||
106 | * @data_len: Length of the frame data. | ||
107 | * @desc_len: Length of the frame descriptor. | ||
108 | |||
109 | * @entry: The entry to which this sk buffer belongs. | ||
110 | */ | ||
111 | struct skb_frame_desc { | ||
112 | unsigned int flags; | ||
113 | |||
114 | unsigned int frame_type; | ||
115 | |||
116 | void *data; | ||
117 | void *desc; | ||
118 | |||
119 | unsigned int data_len; | ||
120 | unsigned int desc_len; | ||
121 | |||
122 | struct queue_entry *entry; | ||
123 | }; | ||
124 | |||
125 | static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb) | ||
126 | { | ||
127 | BUILD_BUG_ON(sizeof(struct skb_frame_desc) > sizeof(skb->cb)); | ||
128 | return (struct skb_frame_desc *)&skb->cb[0]; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * struct rxdone_entry_desc: RX Entry descriptor | ||
133 | * | ||
134 | * Summary of information that has been read from the RX frame descriptor. | ||
135 | * | ||
136 | * @signal: Signal of the received frame. | ||
137 | * @signal_plcp: Does the signal field contain the plcp value, | ||
138 | * or does it contain the bitrate itself. | ||
139 | * @rssi: RSSI of the received frame. | ||
140 | * @ofdm: Was frame send with an OFDM rate. | ||
141 | * @size: Data size of the received frame. | ||
142 | * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). | ||
143 | * @my_bss: Does this frame originate from device's BSS. | ||
144 | */ | ||
145 | struct rxdone_entry_desc { | ||
146 | int signal; | ||
147 | int signal_plcp; | ||
148 | int rssi; | ||
149 | int ofdm; | ||
150 | int size; | ||
151 | int flags; | ||
152 | int my_bss; | ||
153 | }; | ||
154 | |||
155 | /** | ||
156 | * struct txdone_entry_desc: TX done entry descriptor | ||
157 | * | ||
158 | * Summary of information that has been read from the TX frame descriptor | ||
159 | * after the device is done with transmission. | ||
160 | * | ||
161 | * @control: Control structure which was used to transmit the frame. | ||
162 | * @status: TX status (See &enum tx_status). | ||
163 | * @retry: Retry count. | ||
164 | */ | ||
165 | struct txdone_entry_desc { | ||
166 | struct ieee80211_tx_control *control; | ||
167 | int status; | ||
168 | int retry; | ||
169 | }; | ||
170 | |||
171 | /** | ||
172 | * enum txentry_desc_flags: Status flags for TX entry descriptor | ||
173 | * | ||
174 | * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame. | ||
175 | * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate. | ||
176 | * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment. | ||
177 | * @ENTRY_TXD_REQ_TIMESTAMP: Require timestamp to be inserted. | ||
178 | * @ENTRY_TXD_BURST: This frame belongs to the same burst event. | ||
179 | * @ENTRY_TXD_ACK: An ACK is required for this frame. | ||
180 | */ | ||
181 | enum txentry_desc_flags { | ||
182 | ENTRY_TXD_RTS_FRAME, | ||
183 | ENTRY_TXD_OFDM_RATE, | ||
184 | ENTRY_TXD_MORE_FRAG, | ||
185 | ENTRY_TXD_REQ_TIMESTAMP, | ||
186 | ENTRY_TXD_BURST, | ||
187 | ENTRY_TXD_ACK, | ||
188 | }; | ||
189 | |||
190 | /** | ||
191 | * struct txentry_desc: TX Entry descriptor | ||
192 | * | ||
193 | * Summary of information for the frame descriptor before sending a TX frame. | ||
194 | * | ||
195 | * @flags: Descriptor flags (See &enum queue_entry_flags). | ||
196 | * @queue: Queue identification (See &enum data_queue_qid). | ||
197 | * @length_high: PLCP length high word. | ||
198 | * @length_low: PLCP length low word. | ||
199 | * @signal: PLCP signal. | ||
200 | * @service: PLCP service. | ||
201 | * @aifs: AIFS value. | ||
202 | * @ifs: IFS value. | ||
203 | * @cw_min: cwmin value. | ||
204 | * @cw_max: cwmax value. | ||
205 | */ | ||
206 | struct txentry_desc { | ||
207 | unsigned long flags; | ||
208 | |||
209 | enum data_queue_qid queue; | ||
210 | |||
211 | u16 length_high; | ||
212 | u16 length_low; | ||
213 | u16 signal; | ||
214 | u16 service; | ||
215 | |||
216 | int aifs; | ||
217 | int ifs; | ||
218 | int cw_min; | ||
219 | int cw_max; | ||
220 | }; | ||
221 | |||
222 | /** | ||
223 | * enum queue_entry_flags: Status flags for queue entry | ||
224 | * | ||
225 | * @ENTRY_BCN_ASSIGNED: This entry has been assigned to an interface. | ||
226 | * As long as this bit is set, this entry may only be touched | ||
227 | * through the interface structure. | ||
228 | * @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data | ||
229 | * transfer (either TX or RX depending on the queue). The entry should | ||
230 | * only be touched after the device has signaled it is done with it. | ||
231 | * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data | ||
232 | * encryption or decryption. The entry should only be touched after | ||
233 | * the device has signaled it is done with it. | ||
234 | */ | ||
235 | |||
236 | enum queue_entry_flags { | ||
237 | ENTRY_BCN_ASSIGNED, | ||
238 | ENTRY_OWNER_DEVICE_DATA, | ||
239 | ENTRY_OWNER_DEVICE_CRYPTO, | ||
240 | }; | ||
241 | |||
242 | /** | ||
243 | * struct queue_entry: Entry inside the &struct data_queue | ||
244 | * | ||
245 | * @flags: Entry flags, see &enum queue_entry_flags. | ||
246 | * @queue: The data queue (&struct data_queue) to which this entry belongs. | ||
247 | * @skb: The buffer which is currently being transmitted (for TX queue), | ||
248 | * or used to directly recieve data in (for RX queue). | ||
249 | * @entry_idx: The entry index number. | ||
250 | * @priv_data: Private data belonging to this queue entry. The pointer | ||
251 | * points to data specific to a particular driver and queue type. | ||
252 | */ | ||
253 | struct queue_entry { | ||
254 | unsigned long flags; | ||
255 | |||
256 | struct data_queue *queue; | ||
257 | |||
258 | struct sk_buff *skb; | ||
259 | |||
260 | unsigned int entry_idx; | ||
261 | |||
262 | void *priv_data; | ||
263 | }; | ||
264 | |||
265 | /** | ||
266 | * enum queue_index: Queue index type | ||
267 | * | ||
268 | * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is | ||
269 | * owned by the hardware then the queue is considered to be full. | ||
270 | * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by | ||
271 | * the hardware and for which we need to run the txdone handler. If this | ||
272 | * entry is not owned by the hardware the queue is considered to be empty. | ||
273 | * @Q_INDEX_CRYPTO: Index pointer to the next entry which encryption/decription | ||
274 | * will be completed by the hardware next. | ||
275 | * @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size | ||
276 | * of the index array. | ||
277 | */ | ||
278 | enum queue_index { | ||
279 | Q_INDEX, | ||
280 | Q_INDEX_DONE, | ||
281 | Q_INDEX_CRYPTO, | ||
282 | Q_INDEX_MAX, | ||
283 | }; | ||
284 | |||
285 | /** | ||
286 | * struct data_queue: Data queue | ||
287 | * | ||
288 | * @rt2x00dev: Pointer to main &struct rt2x00dev where this queue belongs to. | ||
289 | * @entries: Base address of the &struct queue_entry which are | ||
290 | * part of this queue. | ||
291 | * @qid: The queue identification, see &enum data_queue_qid. | ||
292 | * @lock: Spinlock to protect index handling. Whenever @index, @index_done or | ||
293 | * @index_crypt needs to be changed this lock should be grabbed to prevent | ||
294 | * index corruption due to concurrency. | ||
295 | * @count: Number of frames handled in the queue. | ||
296 | * @limit: Maximum number of entries in the queue. | ||
297 | * @length: Number of frames in queue. | ||
298 | * @index: Index pointers to entry positions in the queue, | ||
299 | * use &enum queue_index to get a specific index field. | ||
300 | * @aifs: The aifs value for outgoing frames (field ignored in RX queue). | ||
301 | * @cw_min: The cw min value for outgoing frames (field ignored in RX queue). | ||
302 | * @cw_max: The cw max value for outgoing frames (field ignored in RX queue). | ||
303 | * @data_size: Maximum data size for the frames in this queue. | ||
304 | * @desc_size: Hardware descriptor size for the data in this queue. | ||
305 | */ | ||
306 | struct data_queue { | ||
307 | struct rt2x00_dev *rt2x00dev; | ||
308 | struct queue_entry *entries; | ||
309 | |||
310 | enum data_queue_qid qid; | ||
311 | |||
312 | spinlock_t lock; | ||
313 | unsigned int count; | ||
314 | unsigned short limit; | ||
315 | unsigned short length; | ||
316 | unsigned short index[Q_INDEX_MAX]; | ||
317 | |||
318 | unsigned short aifs; | ||
319 | unsigned short cw_min; | ||
320 | unsigned short cw_max; | ||
321 | |||
322 | unsigned short data_size; | ||
323 | unsigned short desc_size; | ||
324 | }; | ||
325 | |||
326 | /** | ||
327 | * struct data_queue_desc: Data queue description | ||
328 | * | ||
329 | * The information in this structure is used by drivers | ||
330 | * to inform rt2x00lib about the creation of the data queue. | ||
331 | * | ||
332 | * @entry_num: Maximum number of entries for a queue. | ||
333 | * @data_size: Maximum data size for the frames in this queue. | ||
334 | * @desc_size: Hardware descriptor size for the data in this queue. | ||
335 | * @priv_size: Size of per-queue_entry private data. | ||
336 | */ | ||
337 | struct data_queue_desc { | ||
338 | unsigned short entry_num; | ||
339 | unsigned short data_size; | ||
340 | unsigned short desc_size; | ||
341 | unsigned short priv_size; | ||
342 | }; | ||
343 | |||
344 | /** | ||
345 | * queue_end - Return pointer to the last queue (HELPER MACRO). | ||
346 | * @__dev: Pointer to &struct rt2x00_dev | ||
347 | * | ||
348 | * Using the base rx pointer and the maximum number of available queues, | ||
349 | * this macro will return the address of 1 position beyond the end of the | ||
350 | * queues array. | ||
351 | */ | ||
352 | #define queue_end(__dev) \ | ||
353 | &(__dev)->rx[(__dev)->data_queues] | ||
354 | |||
355 | /** | ||
356 | * tx_queue_end - Return pointer to the last TX queue (HELPER MACRO). | ||
357 | * @__dev: Pointer to &struct rt2x00_dev | ||
358 | * | ||
359 | * Using the base tx pointer and the maximum number of available TX | ||
360 | * queues, this macro will return the address of 1 position beyond | ||
361 | * the end of the TX queue array. | ||
362 | */ | ||
363 | #define tx_queue_end(__dev) \ | ||
364 | &(__dev)->tx[(__dev)->hw->queues] | ||
365 | |||
366 | /** | ||
367 | * queue_loop - Loop through the queues within a specific range (HELPER MACRO). | ||
368 | * @__entry: Pointer where the current queue entry will be stored in. | ||
369 | * @__start: Start queue pointer. | ||
370 | * @__end: End queue pointer. | ||
371 | * | ||
372 | * This macro will loop through all queues between &__start and &__end. | ||
373 | */ | ||
374 | #define queue_loop(__entry, __start, __end) \ | ||
375 | for ((__entry) = (__start); \ | ||
376 | prefetch(&(__entry)[1]), (__entry) != (__end); \ | ||
377 | (__entry) = &(__entry)[1]) | ||
378 | |||
379 | /** | ||
380 | * queue_for_each - Loop through all queues | ||
381 | * @__dev: Pointer to &struct rt2x00_dev | ||
382 | * @__entry: Pointer where the current queue entry will be stored in. | ||
383 | * | ||
384 | * This macro will loop through all available queues. | ||
385 | */ | ||
386 | #define queue_for_each(__dev, __entry) \ | ||
387 | queue_loop(__entry, (__dev)->rx, queue_end(__dev)) | ||
388 | |||
389 | /** | ||
390 | * tx_queue_for_each - Loop through the TX queues | ||
391 | * @__dev: Pointer to &struct rt2x00_dev | ||
392 | * @__entry: Pointer where the current queue entry will be stored in. | ||
393 | * | ||
394 | * This macro will loop through all TX related queues excluding | ||
395 | * the Beacon and Atim queues. | ||
396 | */ | ||
397 | #define tx_queue_for_each(__dev, __entry) \ | ||
398 | queue_loop(__entry, (__dev)->tx, tx_queue_end(__dev)) | ||
399 | |||
400 | /** | ||
401 | * txall_queue_for_each - Loop through all TX related queues | ||
402 | * @__dev: Pointer to &struct rt2x00_dev | ||
403 | * @__entry: Pointer where the current queue entry will be stored in. | ||
404 | * | ||
405 | * This macro will loop through all TX related queues including | ||
406 | * the Beacon and Atim queues. | ||
407 | */ | ||
408 | #define txall_queue_for_each(__dev, __entry) \ | ||
409 | queue_loop(__entry, (__dev)->tx, queue_end(__dev)) | ||
410 | |||
411 | /** | ||
412 | * rt2x00queue_empty - Check if the queue is empty. | ||
413 | * @queue: Queue to check if empty. | ||
414 | */ | ||
415 | static inline int rt2x00queue_empty(struct data_queue *queue) | ||
416 | { | ||
417 | return queue->length == 0; | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * rt2x00queue_full - Check if the queue is full. | ||
422 | * @queue: Queue to check if full. | ||
423 | */ | ||
424 | static inline int rt2x00queue_full(struct data_queue *queue) | ||
425 | { | ||
426 | return queue->length == queue->limit; | ||
427 | } | ||
428 | |||
429 | /** | ||
430 | * rt2x00queue_free - Check the number of available entries in queue. | ||
431 | * @queue: Queue to check. | ||
432 | */ | ||
433 | static inline int rt2x00queue_available(struct data_queue *queue) | ||
434 | { | ||
435 | return queue->limit - queue->length; | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * rt2x00_desc_read - Read a word from the hardware descriptor. | ||
440 | * @desc: Base descriptor address | ||
441 | * @word: Word index from where the descriptor should be read. | ||
442 | * @value: Address where the descriptor value should be written into. | ||
443 | */ | ||
444 | static inline void rt2x00_desc_read(__le32 *desc, const u8 word, u32 *value) | ||
445 | { | ||
446 | *value = le32_to_cpu(desc[word]); | ||
447 | } | ||
448 | |||
449 | /** | ||
450 | * rt2x00_desc_write - wrote a word to the hardware descriptor. | ||
451 | * @desc: Base descriptor address | ||
452 | * @word: Word index from where the descriptor should be written. | ||
453 | * @value: Value that should be written into the descriptor. | ||
454 | */ | ||
455 | static inline void rt2x00_desc_write(__le32 *desc, const u8 word, u32 value) | ||
456 | { | ||
457 | desc[word] = cpu_to_le32(value); | ||
458 | } | ||
459 | |||
460 | #endif /* RT2X00QUEUE_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index b1915dc7dda1..0325bed2fbf5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -29,7 +29,7 @@ | |||
29 | /* | 29 | /* |
30 | * TX result flags. | 30 | * TX result flags. |
31 | */ | 31 | */ |
32 | enum TX_STATUS { | 32 | enum tx_status { |
33 | TX_SUCCESS = 0, | 33 | TX_SUCCESS = 0, |
34 | TX_SUCCESS_RETRY = 1, | 34 | TX_SUCCESS_RETRY = 1, |
35 | TX_FAIL_RETRY = 2, | 35 | TX_FAIL_RETRY = 2, |
@@ -220,75 +220,4 @@ static inline u8 rt2x00_get_field8(const u8 reg, | |||
220 | return (reg & field.bit_mask) >> field.bit_offset; | 220 | return (reg & field.bit_mask) >> field.bit_offset; |
221 | } | 221 | } |
222 | 222 | ||
223 | /* | ||
224 | * Device specific rate value. | ||
225 | * We will have to create the device specific rate value | ||
226 | * passed to the ieee80211 kernel. We need to make it a consist of | ||
227 | * multiple fields because we want to store more then 1 device specific | ||
228 | * values inside the value. | ||
229 | * 1 - rate, stored as 100 kbit/s. | ||
230 | * 2 - preamble, short_preamble enabled flag. | ||
231 | * 3 - MASK_RATE, which rates are enabled in this mode, this mask | ||
232 | * corresponds with the TX register format for the current device. | ||
233 | * 4 - plcp, 802.11b rates are device specific, | ||
234 | * 802.11g rates are set according to the ieee802.11a-1999 p.14. | ||
235 | * The bit to enable preamble is set in a seperate define. | ||
236 | */ | ||
237 | #define DEV_RATE FIELD32(0x000007ff) | ||
238 | #define DEV_PREAMBLE FIELD32(0x00000800) | ||
239 | #define DEV_RATEMASK FIELD32(0x00fff000) | ||
240 | #define DEV_PLCP FIELD32(0xff000000) | ||
241 | |||
242 | /* | ||
243 | * Bitfields | ||
244 | */ | ||
245 | #define DEV_RATEBIT_1MB ( 1 << 0 ) | ||
246 | #define DEV_RATEBIT_2MB ( 1 << 1 ) | ||
247 | #define DEV_RATEBIT_5_5MB ( 1 << 2 ) | ||
248 | #define DEV_RATEBIT_11MB ( 1 << 3 ) | ||
249 | #define DEV_RATEBIT_6MB ( 1 << 4 ) | ||
250 | #define DEV_RATEBIT_9MB ( 1 << 5 ) | ||
251 | #define DEV_RATEBIT_12MB ( 1 << 6 ) | ||
252 | #define DEV_RATEBIT_18MB ( 1 << 7 ) | ||
253 | #define DEV_RATEBIT_24MB ( 1 << 8 ) | ||
254 | #define DEV_RATEBIT_36MB ( 1 << 9 ) | ||
255 | #define DEV_RATEBIT_48MB ( 1 << 10 ) | ||
256 | #define DEV_RATEBIT_54MB ( 1 << 11 ) | ||
257 | |||
258 | /* | ||
259 | * Bitmasks for DEV_RATEMASK | ||
260 | */ | ||
261 | #define DEV_RATEMASK_1MB ( (DEV_RATEBIT_1MB << 1) -1 ) | ||
262 | #define DEV_RATEMASK_2MB ( (DEV_RATEBIT_2MB << 1) -1 ) | ||
263 | #define DEV_RATEMASK_5_5MB ( (DEV_RATEBIT_5_5MB << 1) -1 ) | ||
264 | #define DEV_RATEMASK_11MB ( (DEV_RATEBIT_11MB << 1) -1 ) | ||
265 | #define DEV_RATEMASK_6MB ( (DEV_RATEBIT_6MB << 1) -1 ) | ||
266 | #define DEV_RATEMASK_9MB ( (DEV_RATEBIT_9MB << 1) -1 ) | ||
267 | #define DEV_RATEMASK_12MB ( (DEV_RATEBIT_12MB << 1) -1 ) | ||
268 | #define DEV_RATEMASK_18MB ( (DEV_RATEBIT_18MB << 1) -1 ) | ||
269 | #define DEV_RATEMASK_24MB ( (DEV_RATEBIT_24MB << 1) -1 ) | ||
270 | #define DEV_RATEMASK_36MB ( (DEV_RATEBIT_36MB << 1) -1 ) | ||
271 | #define DEV_RATEMASK_48MB ( (DEV_RATEBIT_48MB << 1) -1 ) | ||
272 | #define DEV_RATEMASK_54MB ( (DEV_RATEBIT_54MB << 1) -1 ) | ||
273 | |||
274 | /* | ||
275 | * Bitmask groups of bitrates | ||
276 | */ | ||
277 | #define DEV_BASIC_RATEMASK \ | ||
278 | ( DEV_RATEMASK_11MB | \ | ||
279 | DEV_RATEBIT_6MB | DEV_RATEBIT_12MB | DEV_RATEBIT_24MB ) | ||
280 | |||
281 | #define DEV_CCK_RATEMASK ( DEV_RATEMASK_11MB ) | ||
282 | #define DEV_OFDM_RATEMASK ( DEV_RATEMASK_54MB & ~DEV_CCK_RATEMASK ) | ||
283 | |||
284 | /* | ||
285 | * Macro's to set and get specific fields from the device specific val and val2 | ||
286 | * fields inside the ieee80211_rate entry. | ||
287 | */ | ||
288 | #define DEVICE_SET_RATE_FIELD(__value, __mask) \ | ||
289 | (int)( ((__value) << DEV_##__mask.bit_offset) & DEV_##__mask.bit_mask ) | ||
290 | |||
291 | #define DEVICE_GET_RATE_FIELD(__value, __mask) \ | ||
292 | (int)( ((__value) & DEV_##__mask.bit_mask) >> DEV_##__mask.bit_offset ) | ||
293 | |||
294 | #endif /* RT2X00REG_H */ | 223 | #endif /* RT2X00REG_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index f95577596206..fcef9885ab5e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h deleted file mode 100644 index 1caa6d688c40..000000000000 --- a/drivers/net/wireless/rt2x00/rt2x00ring.h +++ /dev/null | |||
@@ -1,290 +0,0 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00 | ||
23 | Abstract: rt2x00 ring datastructures and routines | ||
24 | */ | ||
25 | |||
26 | #ifndef RT2X00RING_H | ||
27 | #define RT2X00RING_H | ||
28 | |||
29 | /* | ||
30 | * skb_desc | ||
31 | * Descriptor information for the skb buffer | ||
32 | */ | ||
33 | struct skb_desc { | ||
34 | unsigned int frame_type; | ||
35 | |||
36 | unsigned int desc_len; | ||
37 | unsigned int data_len; | ||
38 | |||
39 | void *desc; | ||
40 | void *data; | ||
41 | |||
42 | struct data_ring *ring; | ||
43 | struct data_entry *entry; | ||
44 | }; | ||
45 | |||
46 | static inline struct skb_desc* get_skb_desc(struct sk_buff *skb) | ||
47 | { | ||
48 | return (struct skb_desc*)&skb->cb[0]; | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * rxdata_entry_desc | ||
53 | * Summary of information that has been read from the | ||
54 | * RX frame descriptor. | ||
55 | */ | ||
56 | struct rxdata_entry_desc { | ||
57 | int signal; | ||
58 | int rssi; | ||
59 | int ofdm; | ||
60 | int size; | ||
61 | int flags; | ||
62 | int my_bss; | ||
63 | }; | ||
64 | |||
65 | /* | ||
66 | * txdata_entry_desc | ||
67 | * Summary of information that should be written into the | ||
68 | * descriptor for sending a TX frame. | ||
69 | */ | ||
70 | struct txdata_entry_desc { | ||
71 | unsigned long flags; | ||
72 | #define ENTRY_TXDONE 1 | ||
73 | #define ENTRY_TXD_RTS_FRAME 2 | ||
74 | #define ENTRY_TXD_OFDM_RATE 3 | ||
75 | #define ENTRY_TXD_MORE_FRAG 4 | ||
76 | #define ENTRY_TXD_REQ_TIMESTAMP 5 | ||
77 | #define ENTRY_TXD_BURST 6 | ||
78 | #define ENTRY_TXD_ACK 7 | ||
79 | |||
80 | /* | ||
81 | * Queue ID. ID's 0-4 are data TX rings | ||
82 | */ | ||
83 | int queue; | ||
84 | #define QUEUE_MGMT 13 | ||
85 | #define QUEUE_RX 14 | ||
86 | #define QUEUE_OTHER 15 | ||
87 | |||
88 | /* | ||
89 | * PLCP values. | ||
90 | */ | ||
91 | u16 length_high; | ||
92 | u16 length_low; | ||
93 | u16 signal; | ||
94 | u16 service; | ||
95 | |||
96 | /* | ||
97 | * Timing information | ||
98 | */ | ||
99 | int aifs; | ||
100 | int ifs; | ||
101 | int cw_min; | ||
102 | int cw_max; | ||
103 | }; | ||
104 | |||
105 | /* | ||
106 | * data_entry | ||
107 | * The data ring is a list of data entries. | ||
108 | * Each entry holds a reference to the descriptor | ||
109 | * and the data buffer. For TX rings the reference to the | ||
110 | * sk_buff of the packet being transmitted is also stored here. | ||
111 | */ | ||
112 | struct data_entry { | ||
113 | /* | ||
114 | * Status flags | ||
115 | */ | ||
116 | unsigned long flags; | ||
117 | #define ENTRY_OWNER_NIC 1 | ||
118 | |||
119 | /* | ||
120 | * Ring we belong to. | ||
121 | */ | ||
122 | struct data_ring *ring; | ||
123 | |||
124 | /* | ||
125 | * sk_buff for the packet which is being transmitted | ||
126 | * in this entry (Only used with TX related rings). | ||
127 | */ | ||
128 | struct sk_buff *skb; | ||
129 | |||
130 | /* | ||
131 | * Store a ieee80211_tx_status structure in each | ||
132 | * ring entry, this will optimize the txdone | ||
133 | * handler. | ||
134 | */ | ||
135 | struct ieee80211_tx_status tx_status; | ||
136 | |||
137 | /* | ||
138 | * private pointer specific to driver. | ||
139 | */ | ||
140 | void *priv; | ||
141 | |||
142 | /* | ||
143 | * Data address for this entry. | ||
144 | */ | ||
145 | void *data_addr; | ||
146 | dma_addr_t data_dma; | ||
147 | |||
148 | /* | ||
149 | * Entry identification number (index). | ||
150 | */ | ||
151 | unsigned int entry_idx; | ||
152 | }; | ||
153 | |||
154 | /* | ||
155 | * data_ring | ||
156 | * Data rings are used by the device to send and receive packets. | ||
157 | * The data_addr is the base address of the data memory. | ||
158 | * To determine at which point in the ring we are, | ||
159 | * have to use the rt2x00_ring_index_*() functions. | ||
160 | */ | ||
161 | struct data_ring { | ||
162 | /* | ||
163 | * Pointer to main rt2x00dev structure where this | ||
164 | * ring belongs to. | ||
165 | */ | ||
166 | struct rt2x00_dev *rt2x00dev; | ||
167 | |||
168 | /* | ||
169 | * Base address for the device specific data entries. | ||
170 | */ | ||
171 | struct data_entry *entry; | ||
172 | |||
173 | /* | ||
174 | * TX queue statistic info. | ||
175 | */ | ||
176 | struct ieee80211_tx_queue_stats_data stats; | ||
177 | |||
178 | /* | ||
179 | * TX Queue parameters. | ||
180 | */ | ||
181 | struct ieee80211_tx_queue_params tx_params; | ||
182 | |||
183 | /* | ||
184 | * Base address for data ring. | ||
185 | */ | ||
186 | dma_addr_t data_dma; | ||
187 | void *data_addr; | ||
188 | |||
189 | /* | ||
190 | * Queue identification number: | ||
191 | * RX: 0 | ||
192 | * TX: IEEE80211_TX_* | ||
193 | */ | ||
194 | unsigned int queue_idx; | ||
195 | |||
196 | /* | ||
197 | * Index variables. | ||
198 | */ | ||
199 | u16 index; | ||
200 | u16 index_done; | ||
201 | |||
202 | /* | ||
203 | * Size of packet and descriptor in bytes. | ||
204 | */ | ||
205 | u16 data_size; | ||
206 | u16 desc_size; | ||
207 | }; | ||
208 | |||
209 | /* | ||
210 | * Handlers to determine the address of the current device specific | ||
211 | * data entry, where either index or index_done points to. | ||
212 | */ | ||
213 | static inline struct data_entry *rt2x00_get_data_entry(struct data_ring *ring) | ||
214 | { | ||
215 | return &ring->entry[ring->index]; | ||
216 | } | ||
217 | |||
218 | static inline struct data_entry *rt2x00_get_data_entry_done(struct data_ring | ||
219 | *ring) | ||
220 | { | ||
221 | return &ring->entry[ring->index_done]; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Total ring memory | ||
226 | */ | ||
227 | static inline int rt2x00_get_ring_size(struct data_ring *ring) | ||
228 | { | ||
229 | return ring->stats.limit * (ring->desc_size + ring->data_size); | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Ring index manipulation functions. | ||
234 | */ | ||
235 | static inline void rt2x00_ring_index_inc(struct data_ring *ring) | ||
236 | { | ||
237 | ring->index++; | ||
238 | if (ring->index >= ring->stats.limit) | ||
239 | ring->index = 0; | ||
240 | ring->stats.len++; | ||
241 | } | ||
242 | |||
243 | static inline void rt2x00_ring_index_done_inc(struct data_ring *ring) | ||
244 | { | ||
245 | ring->index_done++; | ||
246 | if (ring->index_done >= ring->stats.limit) | ||
247 | ring->index_done = 0; | ||
248 | ring->stats.len--; | ||
249 | ring->stats.count++; | ||
250 | } | ||
251 | |||
252 | static inline void rt2x00_ring_index_clear(struct data_ring *ring) | ||
253 | { | ||
254 | ring->index = 0; | ||
255 | ring->index_done = 0; | ||
256 | ring->stats.len = 0; | ||
257 | ring->stats.count = 0; | ||
258 | } | ||
259 | |||
260 | static inline int rt2x00_ring_empty(struct data_ring *ring) | ||
261 | { | ||
262 | return ring->stats.len == 0; | ||
263 | } | ||
264 | |||
265 | static inline int rt2x00_ring_full(struct data_ring *ring) | ||
266 | { | ||
267 | return ring->stats.len == ring->stats.limit; | ||
268 | } | ||
269 | |||
270 | static inline int rt2x00_ring_free(struct data_ring *ring) | ||
271 | { | ||
272 | return ring->stats.limit - ring->stats.len; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * TX/RX Descriptor access functions. | ||
277 | */ | ||
278 | static inline void rt2x00_desc_read(__le32 *desc, | ||
279 | const u8 word, u32 *value) | ||
280 | { | ||
281 | *value = le32_to_cpu(desc[word]); | ||
282 | } | ||
283 | |||
284 | static inline void rt2x00_desc_write(__le32 *desc, | ||
285 | const u8 word, const u32 value) | ||
286 | { | ||
287 | desc[word] = cpu_to_le32(value); | ||
288 | } | ||
289 | |||
290 | #endif /* RT2X00RING_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 84e9bdb73910..5a331674dcb2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -40,8 +40,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, | |||
40 | void *buffer, const u16 buffer_length, | 40 | void *buffer, const u16 buffer_length, |
41 | const int timeout) | 41 | const int timeout) |
42 | { | 42 | { |
43 | struct usb_device *usb_dev = | 43 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
44 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | ||
45 | int status; | 44 | int status; |
46 | unsigned int i; | 45 | unsigned int i; |
47 | unsigned int pipe = | 46 | unsigned int pipe = |
@@ -85,20 +84,20 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | |||
85 | /* | 84 | /* |
86 | * Check for Cache availability. | 85 | * Check for Cache availability. |
87 | */ | 86 | */ |
88 | if (unlikely(!rt2x00dev->csr_cache || buffer_length > CSR_CACHE_SIZE)) { | 87 | if (unlikely(!rt2x00dev->csr.cache || buffer_length > CSR_CACHE_SIZE)) { |
89 | ERROR(rt2x00dev, "CSR cache not available.\n"); | 88 | ERROR(rt2x00dev, "CSR cache not available.\n"); |
90 | return -ENOMEM; | 89 | return -ENOMEM; |
91 | } | 90 | } |
92 | 91 | ||
93 | if (requesttype == USB_VENDOR_REQUEST_OUT) | 92 | if (requesttype == USB_VENDOR_REQUEST_OUT) |
94 | memcpy(rt2x00dev->csr_cache, buffer, buffer_length); | 93 | memcpy(rt2x00dev->csr.cache, buffer, buffer_length); |
95 | 94 | ||
96 | status = rt2x00usb_vendor_request(rt2x00dev, request, requesttype, | 95 | status = rt2x00usb_vendor_request(rt2x00dev, request, requesttype, |
97 | offset, 0, rt2x00dev->csr_cache, | 96 | offset, 0, rt2x00dev->csr.cache, |
98 | buffer_length, timeout); | 97 | buffer_length, timeout); |
99 | 98 | ||
100 | if (!status && requesttype == USB_VENDOR_REQUEST_IN) | 99 | if (!status && requesttype == USB_VENDOR_REQUEST_IN) |
101 | memcpy(buffer, rt2x00dev->csr_cache, buffer_length); | 100 | memcpy(buffer, rt2x00dev->csr.cache, buffer_length); |
102 | 101 | ||
103 | return status; | 102 | return status; |
104 | } | 103 | } |
@@ -128,15 +127,15 @@ EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); | |||
128 | */ | 127 | */ |
129 | static void rt2x00usb_interrupt_txdone(struct urb *urb) | 128 | static void rt2x00usb_interrupt_txdone(struct urb *urb) |
130 | { | 129 | { |
131 | struct data_entry *entry = (struct data_entry *)urb->context; | 130 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
132 | struct data_ring *ring = entry->ring; | 131 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
133 | struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; | 132 | struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data; |
133 | struct txdone_entry_desc txdesc; | ||
134 | __le32 *txd = (__le32 *)entry->skb->data; | 134 | __le32 *txd = (__le32 *)entry->skb->data; |
135 | u32 word; | 135 | u32 word; |
136 | int tx_status; | ||
137 | 136 | ||
138 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 137 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
139 | !__test_and_clear_bit(ENTRY_OWNER_NIC, &entry->flags)) | 138 | !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
140 | return; | 139 | return; |
141 | 140 | ||
142 | rt2x00_desc_read(txd, 0, &word); | 141 | rt2x00_desc_read(txd, 0, &word); |
@@ -144,45 +143,46 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
144 | /* | 143 | /* |
145 | * Remove the descriptor data from the buffer. | 144 | * Remove the descriptor data from the buffer. |
146 | */ | 145 | */ |
147 | skb_pull(entry->skb, ring->desc_size); | 146 | skb_pull(entry->skb, entry->queue->desc_size); |
148 | 147 | ||
149 | /* | 148 | /* |
150 | * Obtain the status about this packet. | 149 | * Obtain the status about this packet. |
151 | */ | 150 | */ |
152 | tx_status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY; | 151 | txdesc.status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY; |
152 | txdesc.retry = 0; | ||
153 | txdesc.control = &priv_tx->control; | ||
153 | 154 | ||
154 | rt2x00lib_txdone(entry, tx_status, 0); | 155 | rt2x00lib_txdone(entry, &txdesc); |
155 | 156 | ||
156 | /* | 157 | /* |
157 | * Make this entry available for reuse. | 158 | * Make this entry available for reuse. |
158 | */ | 159 | */ |
159 | entry->flags = 0; | 160 | entry->flags = 0; |
160 | rt2x00_ring_index_done_inc(entry->ring); | 161 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
161 | 162 | ||
162 | /* | 163 | /* |
163 | * If the data ring was full before the txdone handler | 164 | * If the data queue was full before the txdone handler |
164 | * we must make sure the packet queue in the mac80211 stack | 165 | * we must make sure the packet queue in the mac80211 stack |
165 | * is reenabled when the txdone handler has finished. | 166 | * is reenabled when the txdone handler has finished. |
166 | */ | 167 | */ |
167 | if (!rt2x00_ring_full(ring)) | 168 | if (!rt2x00queue_full(entry->queue)) |
168 | ieee80211_wake_queue(rt2x00dev->hw, | 169 | ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); |
169 | entry->tx_status.control.queue); | ||
170 | } | 170 | } |
171 | 171 | ||
172 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | 172 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, |
173 | struct data_ring *ring, struct sk_buff *skb, | 173 | struct data_queue *queue, struct sk_buff *skb, |
174 | struct ieee80211_tx_control *control) | 174 | struct ieee80211_tx_control *control) |
175 | { | 175 | { |
176 | struct usb_device *usb_dev = | 176 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
177 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | 177 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
178 | struct data_entry *entry = rt2x00_get_data_entry(ring); | 178 | struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data; |
179 | struct skb_desc *desc; | 179 | struct skb_frame_desc *skbdesc; |
180 | u32 length; | 180 | u32 length; |
181 | 181 | ||
182 | if (rt2x00_ring_full(ring)) | 182 | if (rt2x00queue_full(queue)) |
183 | return -EINVAL; | 183 | return -EINVAL; |
184 | 184 | ||
185 | if (test_bit(ENTRY_OWNER_NIC, &entry->flags)) { | 185 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { |
186 | ERROR(rt2x00dev, | 186 | ERROR(rt2x00dev, |
187 | "Arrived at non-free entry in the non-full queue %d.\n" | 187 | "Arrived at non-free entry in the non-full queue %d.\n" |
188 | "Please file bug report to %s.\n", | 188 | "Please file bug report to %s.\n", |
@@ -193,20 +193,20 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | |||
193 | /* | 193 | /* |
194 | * Add the descriptor in front of the skb. | 194 | * Add the descriptor in front of the skb. |
195 | */ | 195 | */ |
196 | skb_push(skb, ring->desc_size); | 196 | skb_push(skb, queue->desc_size); |
197 | memset(skb->data, 0, ring->desc_size); | 197 | memset(skb->data, 0, queue->desc_size); |
198 | 198 | ||
199 | /* | 199 | /* |
200 | * Fill in skb descriptor | 200 | * Fill in skb descriptor |
201 | */ | 201 | */ |
202 | desc = get_skb_desc(skb); | 202 | skbdesc = get_skb_frame_desc(skb); |
203 | desc->desc_len = ring->desc_size; | 203 | skbdesc->data = skb->data + queue->desc_size; |
204 | desc->data_len = skb->len - ring->desc_size; | 204 | skbdesc->data_len = skb->len - queue->desc_size; |
205 | desc->desc = skb->data; | 205 | skbdesc->desc = skb->data; |
206 | desc->data = skb->data + ring->desc_size; | 206 | skbdesc->desc_len = queue->desc_size; |
207 | desc->ring = ring; | 207 | skbdesc->entry = entry; |
208 | desc->entry = entry; | ||
209 | 208 | ||
209 | memcpy(&priv_tx->control, control, sizeof(priv_tx->control)); | ||
210 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 210 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
211 | 211 | ||
212 | /* | 212 | /* |
@@ -219,12 +219,12 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | |||
219 | /* | 219 | /* |
220 | * Initialize URB and send the frame to the device. | 220 | * Initialize URB and send the frame to the device. |
221 | */ | 221 | */ |
222 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | 222 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
223 | usb_fill_bulk_urb(entry->priv, usb_dev, usb_sndbulkpipe(usb_dev, 1), | 223 | usb_fill_bulk_urb(priv_tx->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1), |
224 | skb->data, length, rt2x00usb_interrupt_txdone, entry); | 224 | skb->data, length, rt2x00usb_interrupt_txdone, entry); |
225 | usb_submit_urb(entry->priv, GFP_ATOMIC); | 225 | usb_submit_urb(priv_tx->urb, GFP_ATOMIC); |
226 | 226 | ||
227 | rt2x00_ring_index_inc(ring); | 227 | rt2x00queue_index_inc(queue, Q_INDEX); |
228 | 228 | ||
229 | return 0; | 229 | return 0; |
230 | } | 230 | } |
@@ -233,20 +233,42 @@ EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); | |||
233 | /* | 233 | /* |
234 | * RX data handlers. | 234 | * RX data handlers. |
235 | */ | 235 | */ |
236 | static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue) | ||
237 | { | ||
238 | struct sk_buff *skb; | ||
239 | unsigned int frame_size; | ||
240 | |||
241 | /* | ||
242 | * As alignment we use 2 and not NET_IP_ALIGN because we need | ||
243 | * to be sure we have 2 bytes room in the head. (NET_IP_ALIGN | ||
244 | * can be 0 on some hardware). We use these 2 bytes for frame | ||
245 | * alignment later, we assume that the chance that | ||
246 | * header_size % 4 == 2 is bigger then header_size % 2 == 0 | ||
247 | * and thus optimize alignment by reserving the 2 bytes in | ||
248 | * advance. | ||
249 | */ | ||
250 | frame_size = queue->data_size + queue->desc_size; | ||
251 | skb = dev_alloc_skb(queue->desc_size + frame_size + 2); | ||
252 | if (!skb) | ||
253 | return NULL; | ||
254 | |||
255 | skb_reserve(skb, queue->desc_size + 2); | ||
256 | skb_put(skb, frame_size); | ||
257 | |||
258 | return skb; | ||
259 | } | ||
260 | |||
236 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) | 261 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) |
237 | { | 262 | { |
238 | struct data_entry *entry = (struct data_entry *)urb->context; | 263 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
239 | struct data_ring *ring = entry->ring; | 264 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
240 | struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; | ||
241 | struct sk_buff *skb; | 265 | struct sk_buff *skb; |
242 | struct ieee80211_hdr *hdr; | 266 | struct skb_frame_desc *skbdesc; |
243 | struct skb_desc *skbdesc; | 267 | struct rxdone_entry_desc rxdesc; |
244 | struct rxdata_entry_desc desc; | ||
245 | int header_size; | 268 | int header_size; |
246 | int frame_size; | ||
247 | 269 | ||
248 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 270 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
249 | !test_and_clear_bit(ENTRY_OWNER_NIC, &entry->flags)) | 271 | !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
250 | return; | 272 | return; |
251 | 273 | ||
252 | /* | 274 | /* |
@@ -254,67 +276,45 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
254 | * to be actually valid, or if the urb is signaling | 276 | * to be actually valid, or if the urb is signaling |
255 | * a problem. | 277 | * a problem. |
256 | */ | 278 | */ |
257 | if (urb->actual_length < entry->ring->desc_size || urb->status) | 279 | if (urb->actual_length < entry->queue->desc_size || urb->status) |
258 | goto skip_entry; | 280 | goto skip_entry; |
259 | 281 | ||
260 | /* | 282 | /* |
261 | * Fill in skb descriptor | 283 | * Fill in skb descriptor |
262 | */ | 284 | */ |
263 | skbdesc = get_skb_desc(entry->skb); | 285 | skbdesc = get_skb_frame_desc(entry->skb); |
264 | skbdesc->ring = ring; | 286 | memset(skbdesc, 0, sizeof(*skbdesc)); |
265 | skbdesc->entry = entry; | 287 | skbdesc->entry = entry; |
266 | 288 | ||
267 | memset(&desc, 0, sizeof(desc)); | 289 | memset(&rxdesc, 0, sizeof(rxdesc)); |
268 | rt2x00dev->ops->lib->fill_rxdone(entry, &desc); | 290 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); |
269 | |||
270 | /* | ||
271 | * Allocate a new sk buffer to replace the current one. | ||
272 | * If allocation fails, we should drop the current frame | ||
273 | * so we can recycle the existing sk buffer for the new frame. | ||
274 | * As alignment we use 2 and not NET_IP_ALIGN because we need | ||
275 | * to be sure we have 2 bytes room in the head. (NET_IP_ALIGN | ||
276 | * can be 0 on some hardware). We use these 2 bytes for frame | ||
277 | * alignment later, we assume that the chance that | ||
278 | * header_size % 4 == 2 is bigger then header_size % 2 == 0 | ||
279 | * and thus optimize alignment by reserving the 2 bytes in | ||
280 | * advance. | ||
281 | */ | ||
282 | frame_size = entry->ring->data_size + entry->ring->desc_size; | ||
283 | skb = dev_alloc_skb(frame_size + 2); | ||
284 | if (!skb) | ||
285 | goto skip_entry; | ||
286 | |||
287 | skb_reserve(skb, 2); | ||
288 | skb_put(skb, frame_size); | ||
289 | 291 | ||
290 | /* | 292 | /* |
291 | * The data behind the ieee80211 header must be | 293 | * The data behind the ieee80211 header must be |
292 | * aligned on a 4 byte boundary. | 294 | * aligned on a 4 byte boundary. |
293 | */ | 295 | */ |
294 | hdr = (struct ieee80211_hdr *)entry->skb->data; | 296 | header_size = ieee80211_get_hdrlen_from_skb(entry->skb); |
295 | header_size = | ||
296 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
297 | |||
298 | if (header_size % 4 == 0) { | 297 | if (header_size % 4 == 0) { |
299 | skb_push(entry->skb, 2); | 298 | skb_push(entry->skb, 2); |
300 | memmove(entry->skb->data, entry->skb->data + 2, skb->len - 2); | 299 | memmove(entry->skb->data, entry->skb->data + 2, |
300 | entry->skb->len - 2); | ||
301 | skbdesc->data = entry->skb->data; | ||
302 | skb_trim(entry->skb,entry->skb->len - 2); | ||
301 | } | 303 | } |
302 | 304 | ||
303 | /* | 305 | /* |
304 | * Trim the entire buffer down to only contain the valid frame data | 306 | * Allocate a new sk buffer to replace the current one. |
305 | * excluding the device descriptor. The position of the descriptor | 307 | * If allocation fails, we should drop the current frame |
306 | * varies. This means that we should check where the descriptor is | 308 | * so we can recycle the existing sk buffer for the new frame. |
307 | * and decide if we need to pull the data pointer to exclude the | ||
308 | * device descriptor. | ||
309 | */ | 309 | */ |
310 | if (skbdesc->data > skbdesc->desc) | 310 | skb = rt2x00usb_alloc_rxskb(entry->queue); |
311 | skb_pull(entry->skb, skbdesc->desc_len); | 311 | if (!skb) |
312 | skb_trim(entry->skb, desc.size); | 312 | goto skip_entry; |
313 | 313 | ||
314 | /* | 314 | /* |
315 | * Send the frame to rt2x00lib for further processing. | 315 | * Send the frame to rt2x00lib for further processing. |
316 | */ | 316 | */ |
317 | rt2x00lib_rxdone(entry, entry->skb, &desc); | 317 | rt2x00lib_rxdone(entry, &rxdesc); |
318 | 318 | ||
319 | /* | 319 | /* |
320 | * Replace current entry's skb with the newly allocated one, | 320 | * Replace current entry's skb with the newly allocated one, |
@@ -325,12 +325,12 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
325 | urb->transfer_buffer_length = entry->skb->len; | 325 | urb->transfer_buffer_length = entry->skb->len; |
326 | 326 | ||
327 | skip_entry: | 327 | skip_entry: |
328 | if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) { | 328 | if (test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) { |
329 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | 329 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
330 | usb_submit_urb(urb, GFP_ATOMIC); | 330 | usb_submit_urb(urb, GFP_ATOMIC); |
331 | } | 331 | } |
332 | 332 | ||
333 | rt2x00_ring_index_inc(ring); | 333 | rt2x00queue_index_inc(entry->queue, Q_INDEX); |
334 | } | 334 | } |
335 | 335 | ||
336 | /* | 336 | /* |
@@ -338,18 +338,44 @@ skip_entry: | |||
338 | */ | 338 | */ |
339 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 339 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
340 | { | 340 | { |
341 | struct data_ring *ring; | 341 | struct queue_entry_priv_usb_rx *priv_rx; |
342 | struct queue_entry_priv_usb_tx *priv_tx; | ||
343 | struct queue_entry_priv_usb_bcn *priv_bcn; | ||
344 | struct data_queue *queue; | ||
342 | unsigned int i; | 345 | unsigned int i; |
343 | 346 | ||
344 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0x0000, 0x0000, | 347 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0x0000, 0x0000, |
345 | REGISTER_TIMEOUT); | 348 | REGISTER_TIMEOUT); |
346 | 349 | ||
347 | /* | 350 | /* |
348 | * Cancel all rings. | 351 | * Cancel all queues. |
349 | */ | 352 | */ |
350 | ring_for_each(rt2x00dev, ring) { | 353 | for (i = 0; i < rt2x00dev->rx->limit; i++) { |
351 | for (i = 0; i < ring->stats.limit; i++) | 354 | priv_rx = rt2x00dev->rx->entries[i].priv_data; |
352 | usb_kill_urb(ring->entry[i].priv); | 355 | usb_kill_urb(priv_rx->urb); |
356 | } | ||
357 | |||
358 | tx_queue_for_each(rt2x00dev, queue) { | ||
359 | for (i = 0; i < queue->limit; i++) { | ||
360 | priv_tx = queue->entries[i].priv_data; | ||
361 | usb_kill_urb(priv_tx->urb); | ||
362 | } | ||
363 | } | ||
364 | |||
365 | for (i = 0; i < rt2x00dev->bcn->limit; i++) { | ||
366 | priv_bcn = rt2x00dev->bcn->entries[i].priv_data; | ||
367 | usb_kill_urb(priv_bcn->urb); | ||
368 | |||
369 | if (priv_bcn->guardian_urb) | ||
370 | usb_kill_urb(priv_bcn->guardian_urb); | ||
371 | } | ||
372 | |||
373 | if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | ||
374 | return; | ||
375 | |||
376 | for (i = 0; i < rt2x00dev->bcn[1].limit; i++) { | ||
377 | priv_tx = rt2x00dev->bcn[1].entries[i].priv_data; | ||
378 | usb_kill_urb(priv_tx->urb); | ||
353 | } | 379 | } |
354 | } | 380 | } |
355 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | 381 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); |
@@ -358,64 +384,108 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | |||
358 | * Device initialization handlers. | 384 | * Device initialization handlers. |
359 | */ | 385 | */ |
360 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, | 386 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, |
361 | struct data_entry *entry) | 387 | struct queue_entry *entry) |
362 | { | 388 | { |
363 | struct usb_device *usb_dev = | 389 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
364 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | 390 | struct queue_entry_priv_usb_rx *priv_rx = entry->priv_data; |
365 | 391 | ||
366 | usb_fill_bulk_urb(entry->priv, usb_dev, | 392 | usb_fill_bulk_urb(priv_rx->urb, usb_dev, |
367 | usb_rcvbulkpipe(usb_dev, 1), | 393 | usb_rcvbulkpipe(usb_dev, 1), |
368 | entry->skb->data, entry->skb->len, | 394 | entry->skb->data, entry->skb->len, |
369 | rt2x00usb_interrupt_rxdone, entry); | 395 | rt2x00usb_interrupt_rxdone, entry); |
370 | 396 | ||
371 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | 397 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
372 | usb_submit_urb(entry->priv, GFP_ATOMIC); | 398 | usb_submit_urb(priv_rx->urb, GFP_ATOMIC); |
373 | } | 399 | } |
374 | EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); | 400 | EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); |
375 | 401 | ||
376 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, | 402 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, |
377 | struct data_entry *entry) | 403 | struct queue_entry *entry) |
378 | { | 404 | { |
379 | entry->flags = 0; | 405 | entry->flags = 0; |
380 | } | 406 | } |
381 | EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry); | 407 | EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry); |
382 | 408 | ||
383 | static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, | 409 | static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, |
384 | struct data_ring *ring) | 410 | struct data_queue *queue) |
385 | { | 411 | { |
412 | struct queue_entry_priv_usb_rx *priv_rx; | ||
413 | struct queue_entry_priv_usb_tx *priv_tx; | ||
414 | struct queue_entry_priv_usb_bcn *priv_bcn; | ||
415 | struct urb *urb; | ||
416 | unsigned int guardian = | ||
417 | test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | ||
386 | unsigned int i; | 418 | unsigned int i; |
387 | 419 | ||
388 | /* | 420 | /* |
389 | * Allocate the URB's | 421 | * Allocate the URB's |
390 | */ | 422 | */ |
391 | for (i = 0; i < ring->stats.limit; i++) { | 423 | for (i = 0; i < queue->limit; i++) { |
392 | ring->entry[i].priv = usb_alloc_urb(0, GFP_KERNEL); | 424 | urb = usb_alloc_urb(0, GFP_KERNEL); |
393 | if (!ring->entry[i].priv) | 425 | if (!urb) |
394 | return -ENOMEM; | 426 | return -ENOMEM; |
427 | |||
428 | if (queue->qid == QID_RX) { | ||
429 | priv_rx = queue->entries[i].priv_data; | ||
430 | priv_rx->urb = urb; | ||
431 | } else if (queue->qid == QID_MGMT && guardian) { | ||
432 | priv_bcn = queue->entries[i].priv_data; | ||
433 | priv_bcn->urb = urb; | ||
434 | |||
435 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
436 | if (!urb) | ||
437 | return -ENOMEM; | ||
438 | |||
439 | priv_bcn->guardian_urb = urb; | ||
440 | } else { | ||
441 | priv_tx = queue->entries[i].priv_data; | ||
442 | priv_tx->urb = urb; | ||
443 | } | ||
395 | } | 444 | } |
396 | 445 | ||
397 | return 0; | 446 | return 0; |
398 | } | 447 | } |
399 | 448 | ||
400 | static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, | 449 | static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, |
401 | struct data_ring *ring) | 450 | struct data_queue *queue) |
402 | { | 451 | { |
452 | struct queue_entry_priv_usb_rx *priv_rx; | ||
453 | struct queue_entry_priv_usb_tx *priv_tx; | ||
454 | struct queue_entry_priv_usb_bcn *priv_bcn; | ||
455 | struct urb *urb; | ||
456 | unsigned int guardian = | ||
457 | test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | ||
403 | unsigned int i; | 458 | unsigned int i; |
404 | 459 | ||
405 | if (!ring->entry) | 460 | if (!queue->entries) |
406 | return; | 461 | return; |
407 | 462 | ||
408 | for (i = 0; i < ring->stats.limit; i++) { | 463 | for (i = 0; i < queue->limit; i++) { |
409 | usb_kill_urb(ring->entry[i].priv); | 464 | if (queue->qid == QID_RX) { |
410 | usb_free_urb(ring->entry[i].priv); | 465 | priv_rx = queue->entries[i].priv_data; |
411 | if (ring->entry[i].skb) | 466 | urb = priv_rx->urb; |
412 | kfree_skb(ring->entry[i].skb); | 467 | } else if (queue->qid == QID_MGMT && guardian) { |
468 | priv_bcn = queue->entries[i].priv_data; | ||
469 | |||
470 | usb_kill_urb(priv_bcn->guardian_urb); | ||
471 | usb_free_urb(priv_bcn->guardian_urb); | ||
472 | |||
473 | urb = priv_bcn->urb; | ||
474 | } else { | ||
475 | priv_tx = queue->entries[i].priv_data; | ||
476 | urb = priv_tx->urb; | ||
477 | } | ||
478 | |||
479 | usb_kill_urb(urb); | ||
480 | usb_free_urb(urb); | ||
481 | if (queue->entries[i].skb) | ||
482 | kfree_skb(queue->entries[i].skb); | ||
413 | } | 483 | } |
414 | } | 484 | } |
415 | 485 | ||
416 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | 486 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) |
417 | { | 487 | { |
418 | struct data_ring *ring; | 488 | struct data_queue *queue; |
419 | struct sk_buff *skb; | 489 | struct sk_buff *skb; |
420 | unsigned int entry_size; | 490 | unsigned int entry_size; |
421 | unsigned int i; | 491 | unsigned int i; |
@@ -424,25 +494,22 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | |||
424 | /* | 494 | /* |
425 | * Allocate DMA | 495 | * Allocate DMA |
426 | */ | 496 | */ |
427 | ring_for_each(rt2x00dev, ring) { | 497 | queue_for_each(rt2x00dev, queue) { |
428 | status = rt2x00usb_alloc_urb(rt2x00dev, ring); | 498 | status = rt2x00usb_alloc_urb(rt2x00dev, queue); |
429 | if (status) | 499 | if (status) |
430 | goto exit; | 500 | goto exit; |
431 | } | 501 | } |
432 | 502 | ||
433 | /* | 503 | /* |
434 | * For the RX ring, skb's should be allocated. | 504 | * For the RX queue, skb's should be allocated. |
435 | */ | 505 | */ |
436 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; | 506 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; |
437 | for (i = 0; i < rt2x00dev->rx->stats.limit; i++) { | 507 | for (i = 0; i < rt2x00dev->rx->limit; i++) { |
438 | skb = dev_alloc_skb(NET_IP_ALIGN + entry_size); | 508 | skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx); |
439 | if (!skb) | 509 | if (!skb) |
440 | goto exit; | 510 | goto exit; |
441 | 511 | ||
442 | skb_reserve(skb, NET_IP_ALIGN); | 512 | rt2x00dev->rx->entries[i].skb = skb; |
443 | skb_put(skb, entry_size); | ||
444 | |||
445 | rt2x00dev->rx->entry[i].skb = skb; | ||
446 | } | 513 | } |
447 | 514 | ||
448 | return 0; | 515 | return 0; |
@@ -456,10 +523,10 @@ EXPORT_SYMBOL_GPL(rt2x00usb_initialize); | |||
456 | 523 | ||
457 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) | 524 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) |
458 | { | 525 | { |
459 | struct data_ring *ring; | 526 | struct data_queue *queue; |
460 | 527 | ||
461 | ring_for_each(rt2x00dev, ring) | 528 | queue_for_each(rt2x00dev, queue) |
462 | rt2x00usb_free_urb(rt2x00dev, ring); | 529 | rt2x00usb_free_urb(rt2x00dev, queue); |
463 | } | 530 | } |
464 | EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); | 531 | EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); |
465 | 532 | ||
@@ -474,14 +541,14 @@ static void rt2x00usb_free_reg(struct rt2x00_dev *rt2x00dev) | |||
474 | kfree(rt2x00dev->eeprom); | 541 | kfree(rt2x00dev->eeprom); |
475 | rt2x00dev->eeprom = NULL; | 542 | rt2x00dev->eeprom = NULL; |
476 | 543 | ||
477 | kfree(rt2x00dev->csr_cache); | 544 | kfree(rt2x00dev->csr.cache); |
478 | rt2x00dev->csr_cache = NULL; | 545 | rt2x00dev->csr.cache = NULL; |
479 | } | 546 | } |
480 | 547 | ||
481 | static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev) | 548 | static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev) |
482 | { | 549 | { |
483 | rt2x00dev->csr_cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL); | 550 | rt2x00dev->csr.cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL); |
484 | if (!rt2x00dev->csr_cache) | 551 | if (!rt2x00dev->csr.cache) |
485 | goto exit; | 552 | goto exit; |
486 | 553 | ||
487 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); | 554 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); |
@@ -627,9 +694,9 @@ EXPORT_SYMBOL_GPL(rt2x00usb_resume); | |||
627 | #endif /* CONFIG_PM */ | 694 | #endif /* CONFIG_PM */ |
628 | 695 | ||
629 | /* | 696 | /* |
630 | * rt2x00pci module information. | 697 | * rt2x00usb module information. |
631 | */ | 698 | */ |
632 | MODULE_AUTHOR(DRV_PROJECT); | 699 | MODULE_AUTHOR(DRV_PROJECT); |
633 | MODULE_VERSION(DRV_VERSION); | 700 | MODULE_VERSION(DRV_VERSION); |
634 | MODULE_DESCRIPTION("rt2x00 library"); | 701 | MODULE_DESCRIPTION("rt2x00 usb library"); |
635 | MODULE_LICENSE("GPL"); | 702 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index e40df4050cd0..11e55180cbaf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -60,34 +60,47 @@ | |||
60 | #define USB_VENDOR_REQUEST_IN ( USB_DIR_IN | USB_VENDOR_REQUEST ) | 60 | #define USB_VENDOR_REQUEST_IN ( USB_DIR_IN | USB_VENDOR_REQUEST ) |
61 | #define USB_VENDOR_REQUEST_OUT ( USB_DIR_OUT | USB_VENDOR_REQUEST ) | 61 | #define USB_VENDOR_REQUEST_OUT ( USB_DIR_OUT | USB_VENDOR_REQUEST ) |
62 | 62 | ||
63 | /* | 63 | /** |
64 | * USB vendor commands. | 64 | * enum rt2x00usb_vendor_request: USB vendor commands. |
65 | */ | 65 | */ |
66 | #define USB_DEVICE_MODE 0x01 | 66 | enum rt2x00usb_vendor_request { |
67 | #define USB_SINGLE_WRITE 0x02 | 67 | USB_DEVICE_MODE = 1, |
68 | #define USB_SINGLE_READ 0x03 | 68 | USB_SINGLE_WRITE = 2, |
69 | #define USB_MULTI_WRITE 0x06 | 69 | USB_SINGLE_READ = 3, |
70 | #define USB_MULTI_READ 0x07 | 70 | USB_MULTI_WRITE = 6, |
71 | #define USB_EEPROM_WRITE 0x08 | 71 | USB_MULTI_READ = 7, |
72 | #define USB_EEPROM_READ 0x09 | 72 | USB_EEPROM_WRITE = 8, |
73 | #define USB_LED_CONTROL 0x0a /* RT73USB */ | 73 | USB_EEPROM_READ = 9, |
74 | #define USB_RX_CONTROL 0x0c | 74 | USB_LED_CONTROL = 10, /* RT73USB */ |
75 | USB_RX_CONTROL = 12, | ||
76 | }; | ||
75 | 77 | ||
76 | /* | 78 | /** |
77 | * Device modes offset | 79 | * enum rt2x00usb_mode_offset: Device modes offset. |
78 | */ | 80 | */ |
79 | #define USB_MODE_RESET 0x01 | 81 | enum rt2x00usb_mode_offset { |
80 | #define USB_MODE_UNPLUG 0x02 | 82 | USB_MODE_RESET = 1, |
81 | #define USB_MODE_FUNCTION 0x03 | 83 | USB_MODE_UNPLUG = 2, |
82 | #define USB_MODE_TEST 0x04 | 84 | USB_MODE_FUNCTION = 3, |
83 | #define USB_MODE_SLEEP 0x07 /* RT73USB */ | 85 | USB_MODE_TEST = 4, |
84 | #define USB_MODE_FIRMWARE 0x08 /* RT73USB */ | 86 | USB_MODE_SLEEP = 7, /* RT73USB */ |
85 | #define USB_MODE_WAKEUP 0x09 /* RT73USB */ | 87 | USB_MODE_FIRMWARE = 8, /* RT73USB */ |
88 | USB_MODE_WAKEUP = 9, /* RT73USB */ | ||
89 | }; | ||
86 | 90 | ||
87 | /* | 91 | /** |
88 | * Used to read/write from/to the device. | 92 | * rt2x00usb_vendor_request - Send register command to device |
93 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
94 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
95 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
96 | * @offset: Register offset to perform action on | ||
97 | * @value: Value to write to device | ||
98 | * @buffer: Buffer where information will be read/written to by device | ||
99 | * @buffer_length: Size of &buffer | ||
100 | * @timeout: Operation timeout | ||
101 | * | ||
89 | * This is the main function to communicate with the device, | 102 | * This is the main function to communicate with the device, |
90 | * the buffer argument _must_ either be NULL or point to | 103 | * the &buffer argument _must_ either be NULL or point to |
91 | * a buffer allocated by kmalloc. Failure to do so can lead | 104 | * a buffer allocated by kmalloc. Failure to do so can lead |
92 | * to unexpected behavior depending on the architecture. | 105 | * to unexpected behavior depending on the architecture. |
93 | */ | 106 | */ |
@@ -97,13 +110,21 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, | |||
97 | void *buffer, const u16 buffer_length, | 110 | void *buffer, const u16 buffer_length, |
98 | const int timeout); | 111 | const int timeout); |
99 | 112 | ||
100 | /* | 113 | /** |
101 | * Used to read/write from/to the device. | 114 | * rt2x00usb_vendor_request_buff - Send register command to device (buffered) |
115 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
116 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
117 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
118 | * @offset: Register offset to perform action on | ||
119 | * @buffer: Buffer where information will be read/written to by device | ||
120 | * @buffer_length: Size of &buffer | ||
121 | * @timeout: Operation timeout | ||
122 | * | ||
102 | * This function will use a previously with kmalloc allocated cache | 123 | * This function will use a previously with kmalloc allocated cache |
103 | * to communicate with the device. The contents of the buffer pointer | 124 | * to communicate with the device. The contents of the buffer pointer |
104 | * will be copied to this cache when writing, or read from the cache | 125 | * will be copied to this cache when writing, or read from the cache |
105 | * when reading. | 126 | * when reading. |
106 | * Buffers send to rt2x00usb_vendor_request _must_ be allocated with | 127 | * Buffers send to &rt2x00usb_vendor_request _must_ be allocated with |
107 | * kmalloc. Hence the reason for using a previously allocated cache | 128 | * kmalloc. Hence the reason for using a previously allocated cache |
108 | * which has been allocated properly. | 129 | * which has been allocated properly. |
109 | */ | 130 | */ |
@@ -112,15 +133,32 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, | |||
112 | const u16 offset, void *buffer, | 133 | const u16 offset, void *buffer, |
113 | const u16 buffer_length, const int timeout); | 134 | const u16 buffer_length, const int timeout); |
114 | 135 | ||
115 | /* | 136 | /** |
116 | * A version of rt2x00usb_vendor_request_buff which must be called | 137 | * rt2x00usb_vendor_request_buff - Send register command to device (buffered) |
117 | * if the usb_cache_mutex is already held. */ | 138 | * @rt2x00dev: Pointer to &struct rt2x00_dev |
139 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
140 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
141 | * @offset: Register offset to perform action on | ||
142 | * @buffer: Buffer where information will be read/written to by device | ||
143 | * @buffer_length: Size of &buffer | ||
144 | * @timeout: Operation timeout | ||
145 | * | ||
146 | * A version of &rt2x00usb_vendor_request_buff which must be called | ||
147 | * if the usb_cache_mutex is already held. | ||
148 | */ | ||
118 | int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | 149 | int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, |
119 | const u8 request, const u8 requesttype, | 150 | const u8 request, const u8 requesttype, |
120 | const u16 offset, void *buffer, | 151 | const u16 offset, void *buffer, |
121 | const u16 buffer_length, const int timeout); | 152 | const u16 buffer_length, const int timeout); |
122 | 153 | ||
123 | /* | 154 | /** |
155 | * rt2x00usb_vendor_request_sw - Send single register command to device | ||
156 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
157 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
158 | * @offset: Register offset to perform action on | ||
159 | * @value: Value to write to device | ||
160 | * @timeout: Operation timeout | ||
161 | * | ||
124 | * Simple wrapper around rt2x00usb_vendor_request to write a single | 162 | * Simple wrapper around rt2x00usb_vendor_request to write a single |
125 | * command to the device. Since we don't use the buffer argument we | 163 | * command to the device. Since we don't use the buffer argument we |
126 | * don't have to worry about kmalloc here. | 164 | * don't have to worry about kmalloc here. |
@@ -136,7 +174,12 @@ static inline int rt2x00usb_vendor_request_sw(struct rt2x00_dev *rt2x00dev, | |||
136 | value, NULL, 0, timeout); | 174 | value, NULL, 0, timeout); |
137 | } | 175 | } |
138 | 176 | ||
139 | /* | 177 | /** |
178 | * rt2x00usb_eeprom_read - Read eeprom from device | ||
179 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
180 | * @eeprom: Pointer to eeprom array to store the information in | ||
181 | * @length: Number of bytes to read from the eeprom | ||
182 | * | ||
140 | * Simple wrapper around rt2x00usb_vendor_request to read the eeprom | 183 | * Simple wrapper around rt2x00usb_vendor_request to read the eeprom |
141 | * from the device. Note that the eeprom argument _must_ be allocated using | 184 | * from the device. Note that the eeprom argument _must_ be allocated using |
142 | * kmalloc for correct handling inside the kernel USB layer. | 185 | * kmalloc for correct handling inside the kernel USB layer. |
@@ -147,8 +190,8 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev, | |||
147 | int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16)); | 190 | int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16)); |
148 | 191 | ||
149 | return rt2x00usb_vendor_request(rt2x00dev, USB_EEPROM_READ, | 192 | return rt2x00usb_vendor_request(rt2x00dev, USB_EEPROM_READ, |
150 | USB_VENDOR_REQUEST_IN, 0x0000, | 193 | USB_VENDOR_REQUEST_IN, 0, 0, |
151 | 0x0000, eeprom, lenght, timeout); | 194 | eeprom, lenght, timeout); |
152 | } | 195 | } |
153 | 196 | ||
154 | /* | 197 | /* |
@@ -160,16 +203,58 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); | |||
160 | * TX data handlers. | 203 | * TX data handlers. |
161 | */ | 204 | */ |
162 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | 205 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, |
163 | struct data_ring *ring, struct sk_buff *skb, | 206 | struct data_queue *queue, struct sk_buff *skb, |
164 | struct ieee80211_tx_control *control); | 207 | struct ieee80211_tx_control *control); |
165 | 208 | ||
209 | /** | ||
210 | * struct queue_entry_priv_usb_rx: Per RX entry USB specific information | ||
211 | * | ||
212 | * @urb: Urb structure used for device communication. | ||
213 | */ | ||
214 | struct queue_entry_priv_usb_rx { | ||
215 | struct urb *urb; | ||
216 | }; | ||
217 | |||
218 | /** | ||
219 | * struct queue_entry_priv_usb_tx: Per TX entry USB specific information | ||
220 | * | ||
221 | * @urb: Urb structure used for device communication. | ||
222 | * @control: mac80211 control structure used to transmit data. | ||
223 | */ | ||
224 | struct queue_entry_priv_usb_tx { | ||
225 | struct urb *urb; | ||
226 | |||
227 | struct ieee80211_tx_control control; | ||
228 | }; | ||
229 | |||
230 | /** | ||
231 | * struct queue_entry_priv_usb_tx: Per TX entry USB specific information | ||
232 | * | ||
233 | * The first section should match &struct queue_entry_priv_usb_tx exactly. | ||
234 | * rt2500usb can use this structure to send a guardian byte when working | ||
235 | * with beacons. | ||
236 | * | ||
237 | * @urb: Urb structure used for device communication. | ||
238 | * @control: mac80211 control structure used to transmit data. | ||
239 | * @guardian_data: Set to 0, used for sending the guardian data. | ||
240 | * @guardian_urb: Urb structure used to send the guardian data. | ||
241 | */ | ||
242 | struct queue_entry_priv_usb_bcn { | ||
243 | struct urb *urb; | ||
244 | |||
245 | struct ieee80211_tx_control control; | ||
246 | |||
247 | unsigned int guardian_data; | ||
248 | struct urb *guardian_urb; | ||
249 | }; | ||
250 | |||
166 | /* | 251 | /* |
167 | * Device initialization handlers. | 252 | * Device initialization handlers. |
168 | */ | 253 | */ |
169 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, | 254 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, |
170 | struct data_entry *entry); | 255 | struct queue_entry *entry); |
171 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, | 256 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, |
172 | struct data_entry *entry); | 257 | struct queue_entry *entry); |
173 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); | 258 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); |
174 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); | 259 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); |
175 | 260 | ||
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 93ea212fedd5..babb240cef3d 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -24,6 +24,7 @@ | |||
24 | Supported chipsets: RT2561, RT2561s, RT2661. | 24 | Supported chipsets: RT2561, RT2561s, RT2661. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/crc-itu-t.h> | ||
27 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
28 | #include <linux/etherdevice.h> | 29 | #include <linux/etherdevice.h> |
29 | #include <linux/init.h> | 30 | #include <linux/init.h> |
@@ -155,6 +156,12 @@ rf_write: | |||
155 | rt2x00_rf_write(rt2x00dev, word, value); | 156 | rt2x00_rf_write(rt2x00dev, word, value); |
156 | } | 157 | } |
157 | 158 | ||
159 | #ifdef CONFIG_RT61PCI_LEDS | ||
160 | /* | ||
161 | * This function is only called from rt61pci_led_brightness() | ||
162 | * make gcc happy by placing this function inside the | ||
163 | * same ifdef statement as the caller. | ||
164 | */ | ||
158 | static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | 165 | static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, |
159 | const u8 command, const u8 token, | 166 | const u8 command, const u8 token, |
160 | const u8 arg0, const u8 arg1) | 167 | const u8 arg0, const u8 arg1) |
@@ -181,6 +188,7 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
181 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | 188 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); |
182 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); | 189 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); |
183 | } | 190 | } |
191 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
184 | 192 | ||
185 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | 193 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) |
186 | { | 194 | { |
@@ -262,83 +270,119 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
262 | u32 reg; | 270 | u32 reg; |
263 | 271 | ||
264 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | 272 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); |
265 | return rt2x00_get_field32(reg, MAC_CSR13_BIT5);; | 273 | return rt2x00_get_field32(reg, MAC_CSR13_BIT5); |
266 | } | 274 | } |
267 | #else | 275 | #else |
268 | #define rt61pci_rfkill_poll NULL | 276 | #define rt61pci_rfkill_poll NULL |
269 | #endif /* CONFIG_RT61PCI_RFKILL */ | 277 | #endif /* CONFIG_RT61PCI_RFKILL */ |
270 | 278 | ||
279 | #ifdef CONFIG_RT61PCI_LEDS | ||
280 | static void rt61pci_led_brightness(struct led_classdev *led_cdev, | ||
281 | enum led_brightness brightness) | ||
282 | { | ||
283 | struct rt2x00_led *led = | ||
284 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
285 | unsigned int enabled = brightness != LED_OFF; | ||
286 | unsigned int a_mode = | ||
287 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); | ||
288 | unsigned int bg_mode = | ||
289 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); | ||
290 | |||
291 | if (led->type == LED_TYPE_RADIO) { | ||
292 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
293 | MCU_LEDCS_RADIO_STATUS, enabled); | ||
294 | |||
295 | rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff, | ||
296 | (led->rt2x00dev->led_mcu_reg & 0xff), | ||
297 | ((led->rt2x00dev->led_mcu_reg >> 8))); | ||
298 | } else if (led->type == LED_TYPE_ASSOC) { | ||
299 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
300 | MCU_LEDCS_LINK_BG_STATUS, bg_mode); | ||
301 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
302 | MCU_LEDCS_LINK_A_STATUS, a_mode); | ||
303 | |||
304 | rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff, | ||
305 | (led->rt2x00dev->led_mcu_reg & 0xff), | ||
306 | ((led->rt2x00dev->led_mcu_reg >> 8))); | ||
307 | } else if (led->type == LED_TYPE_QUALITY) { | ||
308 | /* | ||
309 | * The brightness is divided into 6 levels (0 - 5), | ||
310 | * this means we need to convert the brightness | ||
311 | * argument into the matching level within that range. | ||
312 | */ | ||
313 | rt61pci_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, | ||
314 | brightness / (LED_FULL / 6), 0); | ||
315 | } | ||
316 | } | ||
317 | #else | ||
318 | #define rt61pci_led_brightness NULL | ||
319 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
320 | |||
271 | /* | 321 | /* |
272 | * Configuration handlers. | 322 | * Configuration handlers. |
273 | */ | 323 | */ |
274 | static void rt61pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | 324 | static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, |
325 | struct rt2x00_intf *intf, | ||
326 | struct rt2x00intf_conf *conf, | ||
327 | const unsigned int flags) | ||
275 | { | 328 | { |
276 | u32 tmp; | 329 | unsigned int beacon_base; |
277 | 330 | u32 reg; | |
278 | tmp = le32_to_cpu(mac[1]); | ||
279 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
280 | mac[1] = cpu_to_le32(tmp); | ||
281 | |||
282 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | ||
283 | (2 * sizeof(__le32))); | ||
284 | } | ||
285 | 331 | ||
286 | static void rt61pci_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 332 | if (flags & CONFIG_UPDATE_TYPE) { |
287 | { | 333 | /* |
288 | u32 tmp; | 334 | * Clear current synchronisation setup. |
335 | * For the Beacon base registers we only need to clear | ||
336 | * the first byte since that byte contains the VALID and OWNER | ||
337 | * bits which (when set to 0) will invalidate the entire beacon. | ||
338 | */ | ||
339 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
340 | rt2x00pci_register_write(rt2x00dev, beacon_base, 0); | ||
289 | 341 | ||
290 | tmp = le32_to_cpu(bssid[1]); | 342 | /* |
291 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 343 | * Enable synchronisation. |
292 | bssid[1] = cpu_to_le32(tmp); | 344 | */ |
345 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
346 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
347 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
348 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
349 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
350 | } | ||
293 | 351 | ||
294 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 352 | if (flags & CONFIG_UPDATE_MAC) { |
295 | (2 * sizeof(__le32))); | 353 | reg = le32_to_cpu(conf->mac[1]); |
296 | } | 354 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); |
355 | conf->mac[1] = cpu_to_le32(reg); | ||
297 | 356 | ||
298 | static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 357 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, |
299 | const int tsf_sync) | 358 | conf->mac, sizeof(conf->mac)); |
300 | { | 359 | } |
301 | u32 reg; | ||
302 | 360 | ||
303 | /* | 361 | if (flags & CONFIG_UPDATE_BSSID) { |
304 | * Clear current synchronisation setup. | 362 | reg = le32_to_cpu(conf->bssid[1]); |
305 | * For the Beacon base registers we only need to clear | 363 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); |
306 | * the first byte since that byte contains the VALID and OWNER | 364 | conf->bssid[1] = cpu_to_le32(reg); |
307 | * bits which (when set to 0) will invalidate the entire beacon. | ||
308 | */ | ||
309 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
310 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
311 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
312 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
313 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
314 | 365 | ||
315 | /* | 366 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, |
316 | * Enable synchronisation. | 367 | conf->bssid, sizeof(conf->bssid)); |
317 | */ | 368 | } |
318 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
319 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
320 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
321 | (tsf_sync == TSF_SYNC_BEACON)); | ||
322 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
323 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | ||
324 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
325 | } | 369 | } |
326 | 370 | ||
327 | static void rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 371 | static int rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, |
328 | const int short_preamble, | 372 | struct rt2x00lib_erp *erp) |
329 | const int ack_timeout, | ||
330 | const int ack_consume_time) | ||
331 | { | 373 | { |
332 | u32 reg; | 374 | u32 reg; |
333 | 375 | ||
334 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | 376 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); |
335 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); | 377 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout); |
336 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 378 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); |
337 | 379 | ||
338 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | 380 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); |
339 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 381 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
340 | !!short_preamble); | 382 | !!erp->short_preamble); |
341 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | 383 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); |
384 | |||
385 | return 0; | ||
342 | } | 386 | } |
343 | 387 | ||
344 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 388 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -427,27 +471,21 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
427 | case ANTENNA_HW_DIVERSITY: | 471 | case ANTENNA_HW_DIVERSITY: |
428 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); | 472 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
429 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | 473 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, |
430 | (rt2x00dev->curr_hwmode != HWMODE_A)); | 474 | (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ)); |
431 | break; | 475 | break; |
432 | case ANTENNA_A: | 476 | case ANTENNA_A: |
433 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 477 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
434 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 478 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
435 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 479 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
436 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 480 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
437 | else | 481 | else |
438 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 482 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
439 | break; | 483 | break; |
440 | case ANTENNA_SW_DIVERSITY: | ||
441 | /* | ||
442 | * NOTE: We should never come here because rt2x00lib is | ||
443 | * supposed to catch this and send us the correct antenna | ||
444 | * explicitely. However we are nog going to bug about this. | ||
445 | * Instead, just default to antenna B. | ||
446 | */ | ||
447 | case ANTENNA_B: | 484 | case ANTENNA_B: |
485 | default: | ||
448 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 486 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
449 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 487 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
450 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 488 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
451 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 489 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
452 | else | 490 | else |
453 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 491 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
@@ -486,14 +524,8 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | |||
486 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 524 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
487 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 525 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
488 | break; | 526 | break; |
489 | case ANTENNA_SW_DIVERSITY: | ||
490 | /* | ||
491 | * NOTE: We should never come here because rt2x00lib is | ||
492 | * supposed to catch this and send us the correct antenna | ||
493 | * explicitely. However we are nog going to bug about this. | ||
494 | * Instead, just default to antenna B. | ||
495 | */ | ||
496 | case ANTENNA_B: | 527 | case ANTENNA_B: |
528 | default: | ||
497 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 529 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
498 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 530 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
499 | break; | 531 | break; |
@@ -531,10 +563,6 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, | |||
531 | rt61pci_bbp_read(rt2x00dev, 4, &r4); | 563 | rt61pci_bbp_read(rt2x00dev, 4, &r4); |
532 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | 564 | rt61pci_bbp_read(rt2x00dev, 77, &r77); |
533 | 565 | ||
534 | /* FIXME: Antenna selection for the rf 2529 is very confusing in the | ||
535 | * legacy driver. The code below should be ok for non-diversity setups. | ||
536 | */ | ||
537 | |||
538 | /* | 566 | /* |
539 | * Configure the RX antenna. | 567 | * Configure the RX antenna. |
540 | */ | 568 | */ |
@@ -544,15 +572,14 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, | |||
544 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 572 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
545 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); | 573 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); |
546 | break; | 574 | break; |
547 | case ANTENNA_SW_DIVERSITY: | ||
548 | case ANTENNA_HW_DIVERSITY: | 575 | case ANTENNA_HW_DIVERSITY: |
549 | /* | 576 | /* |
550 | * NOTE: We should never come here because rt2x00lib is | 577 | * FIXME: Antenna selection for the rf 2529 is very confusing |
551 | * supposed to catch this and send us the correct antenna | 578 | * in the legacy driver. Just default to antenna B until the |
552 | * explicitely. However we are nog going to bug about this. | 579 | * legacy code can be properly translated into rt2x00 code. |
553 | * Instead, just default to antenna B. | ||
554 | */ | 580 | */ |
555 | case ANTENNA_B: | 581 | case ANTENNA_B: |
582 | default: | ||
556 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 583 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
557 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 584 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
558 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); | 585 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); |
@@ -603,7 +630,14 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
603 | unsigned int i; | 630 | unsigned int i; |
604 | u32 reg; | 631 | u32 reg; |
605 | 632 | ||
606 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | 633 | /* |
634 | * We should never come here because rt2x00lib is supposed | ||
635 | * to catch this and send us the correct antenna explicitely. | ||
636 | */ | ||
637 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
638 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
639 | |||
640 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { | ||
607 | sel = antenna_sel_a; | 641 | sel = antenna_sel_a; |
608 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 642 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); |
609 | } else { | 643 | } else { |
@@ -617,10 +651,9 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
617 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); | 651 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); |
618 | 652 | ||
619 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 653 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
620 | (rt2x00dev->curr_hwmode == HWMODE_B || | 654 | rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); |
621 | rt2x00dev->curr_hwmode == HWMODE_G)); | ||
622 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 655 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
623 | (rt2x00dev->curr_hwmode == HWMODE_A)); | 656 | rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); |
624 | 657 | ||
625 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); | 658 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); |
626 | 659 | ||
@@ -667,8 +700,8 @@ static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
667 | } | 700 | } |
668 | 701 | ||
669 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | 702 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, |
670 | const unsigned int flags, | 703 | struct rt2x00lib_conf *libconf, |
671 | struct rt2x00lib_conf *libconf) | 704 | const unsigned int flags) |
672 | { | 705 | { |
673 | if (flags & CONFIG_UPDATE_PHYMODE) | 706 | if (flags & CONFIG_UPDATE_PHYMODE) |
674 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); | 707 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -684,78 +717,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | |||
684 | } | 717 | } |
685 | 718 | ||
686 | /* | 719 | /* |
687 | * LED functions. | ||
688 | */ | ||
689 | static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
690 | { | ||
691 | u32 reg; | ||
692 | u8 arg0; | ||
693 | u8 arg1; | ||
694 | |||
695 | rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); | ||
696 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
697 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
698 | rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); | ||
699 | |||
700 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); | ||
701 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, | ||
702 | (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); | ||
703 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, | ||
704 | (rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); | ||
705 | |||
706 | arg0 = rt2x00dev->led_reg & 0xff; | ||
707 | arg1 = (rt2x00dev->led_reg >> 8) & 0xff; | ||
708 | |||
709 | rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); | ||
710 | } | ||
711 | |||
712 | static void rt61pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
713 | { | ||
714 | u16 led_reg; | ||
715 | u8 arg0; | ||
716 | u8 arg1; | ||
717 | |||
718 | led_reg = rt2x00dev->led_reg; | ||
719 | rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 0); | ||
720 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); | ||
721 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 0); | ||
722 | |||
723 | arg0 = led_reg & 0xff; | ||
724 | arg1 = (led_reg >> 8) & 0xff; | ||
725 | |||
726 | rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); | ||
727 | } | ||
728 | |||
729 | static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) | ||
730 | { | ||
731 | u8 led; | ||
732 | |||
733 | if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) | ||
734 | return; | ||
735 | |||
736 | /* | ||
737 | * Led handling requires a positive value for the rssi, | ||
738 | * to do that correctly we need to add the correction. | ||
739 | */ | ||
740 | rssi += rt2x00dev->rssi_offset; | ||
741 | |||
742 | if (rssi <= 30) | ||
743 | led = 0; | ||
744 | else if (rssi <= 39) | ||
745 | led = 1; | ||
746 | else if (rssi <= 49) | ||
747 | led = 2; | ||
748 | else if (rssi <= 53) | ||
749 | led = 3; | ||
750 | else if (rssi <= 63) | ||
751 | led = 4; | ||
752 | else | ||
753 | led = 5; | ||
754 | |||
755 | rt61pci_mcu_request(rt2x00dev, MCU_LED_STRENGTH, 0xff, led, 0); | ||
756 | } | ||
757 | |||
758 | /* | ||
759 | * Link tuning | 720 | * Link tuning |
760 | */ | 721 | */ |
761 | static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, | 722 | static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -789,17 +750,12 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
789 | u8 up_bound; | 750 | u8 up_bound; |
790 | u8 low_bound; | 751 | u8 low_bound; |
791 | 752 | ||
792 | /* | ||
793 | * Update Led strength | ||
794 | */ | ||
795 | rt61pci_activity_led(rt2x00dev, rssi); | ||
796 | |||
797 | rt61pci_bbp_read(rt2x00dev, 17, &r17); | 753 | rt61pci_bbp_read(rt2x00dev, 17, &r17); |
798 | 754 | ||
799 | /* | 755 | /* |
800 | * Determine r17 bounds. | 756 | * Determine r17 bounds. |
801 | */ | 757 | */ |
802 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 758 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
803 | low_bound = 0x28; | 759 | low_bound = 0x28; |
804 | up_bound = 0x48; | 760 | up_bound = 0x48; |
805 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 761 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
@@ -816,6 +772,13 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
816 | } | 772 | } |
817 | 773 | ||
818 | /* | 774 | /* |
775 | * If we are not associated, we should go straight to the | ||
776 | * dynamic CCA tuning. | ||
777 | */ | ||
778 | if (!rt2x00dev->intf_associated) | ||
779 | goto dynamic_cca_tune; | ||
780 | |||
781 | /* | ||
819 | * Special big-R17 for very short distance | 782 | * Special big-R17 for very short distance |
820 | */ | 783 | */ |
821 | if (rssi >= -35) { | 784 | if (rssi >= -35) { |
@@ -866,6 +829,8 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
866 | return; | 829 | return; |
867 | } | 830 | } |
868 | 831 | ||
832 | dynamic_cca_tune: | ||
833 | |||
869 | /* | 834 | /* |
870 | * r17 does not yet exceed upper limit, continue and base | 835 | * r17 does not yet exceed upper limit, continue and base |
871 | * the r17 tuning on the false CCA count. | 836 | * the r17 tuning on the false CCA count. |
@@ -882,7 +847,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
882 | } | 847 | } |
883 | 848 | ||
884 | /* | 849 | /* |
885 | * Firmware name function. | 850 | * Firmware functions |
886 | */ | 851 | */ |
887 | static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 852 | static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) |
888 | { | 853 | { |
@@ -906,9 +871,23 @@ static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) | |||
906 | return fw_name; | 871 | return fw_name; |
907 | } | 872 | } |
908 | 873 | ||
909 | /* | 874 | static u16 rt61pci_get_firmware_crc(void *data, const size_t len) |
910 | * Initialization functions. | 875 | { |
911 | */ | 876 | u16 crc; |
877 | |||
878 | /* | ||
879 | * Use the crc itu-t algorithm. | ||
880 | * The last 2 bytes in the firmware array are the crc checksum itself, | ||
881 | * this means that we should never pass those 2 bytes to the crc | ||
882 | * algorithm. | ||
883 | */ | ||
884 | crc = crc_itu_t(0, data, len - 2); | ||
885 | crc = crc_itu_t_byte(crc, 0); | ||
886 | crc = crc_itu_t_byte(crc, 0); | ||
887 | |||
888 | return crc; | ||
889 | } | ||
890 | |||
912 | static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | 891 | static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, |
913 | const size_t len) | 892 | const size_t len) |
914 | { | 893 | { |
@@ -989,50 +968,55 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
989 | return 0; | 968 | return 0; |
990 | } | 969 | } |
991 | 970 | ||
971 | /* | ||
972 | * Initialization functions. | ||
973 | */ | ||
992 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 974 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
993 | struct data_entry *entry) | 975 | struct queue_entry *entry) |
994 | { | 976 | { |
995 | __le32 *rxd = entry->priv; | 977 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
996 | u32 word; | 978 | u32 word; |
997 | 979 | ||
998 | rt2x00_desc_read(rxd, 5, &word); | 980 | rt2x00_desc_read(priv_rx->desc, 5, &word); |
999 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, | 981 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, |
1000 | entry->data_dma); | 982 | priv_rx->data_dma); |
1001 | rt2x00_desc_write(rxd, 5, word); | 983 | rt2x00_desc_write(priv_rx->desc, 5, word); |
1002 | 984 | ||
1003 | rt2x00_desc_read(rxd, 0, &word); | 985 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
1004 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 986 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
1005 | rt2x00_desc_write(rxd, 0, word); | 987 | rt2x00_desc_write(priv_rx->desc, 0, word); |
1006 | } | 988 | } |
1007 | 989 | ||
1008 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 990 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
1009 | struct data_entry *entry) | 991 | struct queue_entry *entry) |
1010 | { | 992 | { |
1011 | __le32 *txd = entry->priv; | 993 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
1012 | u32 word; | 994 | u32 word; |
1013 | 995 | ||
1014 | rt2x00_desc_read(txd, 1, &word); | 996 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
1015 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); | 997 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); |
1016 | rt2x00_desc_write(txd, 1, word); | 998 | rt2x00_desc_write(priv_tx->desc, 1, word); |
1017 | 999 | ||
1018 | rt2x00_desc_read(txd, 5, &word); | 1000 | rt2x00_desc_read(priv_tx->desc, 5, &word); |
1019 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->ring->queue_idx); | 1001 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid); |
1020 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx); | 1002 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx); |
1021 | rt2x00_desc_write(txd, 5, word); | 1003 | rt2x00_desc_write(priv_tx->desc, 5, word); |
1022 | 1004 | ||
1023 | rt2x00_desc_read(txd, 6, &word); | 1005 | rt2x00_desc_read(priv_tx->desc, 6, &word); |
1024 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | 1006 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, |
1025 | entry->data_dma); | 1007 | priv_tx->data_dma); |
1026 | rt2x00_desc_write(txd, 6, word); | 1008 | rt2x00_desc_write(priv_tx->desc, 6, word); |
1027 | 1009 | ||
1028 | rt2x00_desc_read(txd, 0, &word); | 1010 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1029 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 1011 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
1030 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 1012 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
1031 | rt2x00_desc_write(txd, 0, word); | 1013 | rt2x00_desc_write(priv_tx->desc, 0, word); |
1032 | } | 1014 | } |
1033 | 1015 | ||
1034 | static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | 1016 | static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) |
1035 | { | 1017 | { |
1018 | struct queue_entry_priv_pci_rx *priv_rx; | ||
1019 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1036 | u32 reg; | 1020 | u32 reg; |
1037 | 1021 | ||
1038 | /* | 1022 | /* |
@@ -1040,59 +1024,55 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1040 | */ | 1024 | */ |
1041 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); | 1025 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); |
1042 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, | 1026 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, |
1043 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | 1027 | rt2x00dev->tx[0].limit); |
1044 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, | 1028 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, |
1045 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 1029 | rt2x00dev->tx[1].limit); |
1046 | rt2x00_set_field32(®, TX_RING_CSR0_AC2_RING_SIZE, | 1030 | rt2x00_set_field32(®, TX_RING_CSR0_AC2_RING_SIZE, |
1047 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].stats.limit); | 1031 | rt2x00dev->tx[2].limit); |
1048 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, | 1032 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, |
1049 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].stats.limit); | 1033 | rt2x00dev->tx[3].limit); |
1050 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); | 1034 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); |
1051 | 1035 | ||
1052 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); | 1036 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); |
1053 | rt2x00_set_field32(®, TX_RING_CSR1_MGMT_RING_SIZE, | ||
1054 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA4].stats.limit); | ||
1055 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, | 1037 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, |
1056 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size / | 1038 | rt2x00dev->tx[0].desc_size / 4); |
1057 | 4); | ||
1058 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); | 1039 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); |
1059 | 1040 | ||
1041 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
1060 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); | 1042 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); |
1061 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, | 1043 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, |
1062 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 1044 | priv_tx->desc_dma); |
1063 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); | 1045 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); |
1064 | 1046 | ||
1047 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
1065 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); | 1048 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); |
1066 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, | 1049 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, |
1067 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 1050 | priv_tx->desc_dma); |
1068 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); | 1051 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); |
1069 | 1052 | ||
1053 | priv_tx = rt2x00dev->tx[2].entries[0].priv_data; | ||
1070 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); | 1054 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); |
1071 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, | 1055 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, |
1072 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].data_dma); | 1056 | priv_tx->desc_dma); |
1073 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); | 1057 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); |
1074 | 1058 | ||
1059 | priv_tx = rt2x00dev->tx[3].entries[0].priv_data; | ||
1075 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); | 1060 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); |
1076 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, | 1061 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, |
1077 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].data_dma); | 1062 | priv_tx->desc_dma); |
1078 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); | 1063 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); |
1079 | 1064 | ||
1080 | rt2x00pci_register_read(rt2x00dev, MGMT_BASE_CSR, ®); | ||
1081 | rt2x00_set_field32(®, MGMT_BASE_CSR_RING_REGISTER, | ||
1082 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA4].data_dma); | ||
1083 | rt2x00pci_register_write(rt2x00dev, MGMT_BASE_CSR, reg); | ||
1084 | |||
1085 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); | 1065 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); |
1086 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, | 1066 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, rt2x00dev->rx->limit); |
1087 | rt2x00dev->rx->stats.limit); | ||
1088 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, | 1067 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, |
1089 | rt2x00dev->rx->desc_size / 4); | 1068 | rt2x00dev->rx->desc_size / 4); |
1090 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); | 1069 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); |
1091 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); | 1070 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); |
1092 | 1071 | ||
1072 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
1093 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); | 1073 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); |
1094 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, | 1074 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, |
1095 | rt2x00dev->rx->data_dma); | 1075 | priv_rx->desc_dma); |
1096 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); | 1076 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); |
1097 | 1077 | ||
1098 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); | 1078 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); |
@@ -1100,7 +1080,6 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1100 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); | 1080 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); |
1101 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); | 1081 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); |
1102 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); | 1082 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); |
1103 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_MGMT, 0); | ||
1104 | rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); | 1083 | rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); |
1105 | 1084 | ||
1106 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); | 1085 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); |
@@ -1108,7 +1087,6 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1108 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); | 1087 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); |
1109 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); | 1088 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); |
1110 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); | 1089 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); |
1111 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_MGMT, 1); | ||
1112 | rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); | 1090 | rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); |
1113 | 1091 | ||
1114 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); | 1092 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); |
@@ -1194,6 +1172,11 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1194 | 1172 | ||
1195 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); | 1173 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); |
1196 | 1174 | ||
1175 | rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); | ||
1176 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
1177 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
1178 | rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); | ||
1179 | |||
1197 | /* | 1180 | /* |
1198 | * Invalidate all Shared Keys (SEC_CSR0), | 1181 | * Invalidate all Shared Keys (SEC_CSR0), |
1199 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) | 1182 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) |
@@ -1224,6 +1207,17 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1224 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | 1207 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); |
1225 | 1208 | ||
1226 | /* | 1209 | /* |
1210 | * Clear all beacons | ||
1211 | * For the Beacon base registers we only need to clear | ||
1212 | * the first byte since that byte contains the VALID and OWNER | ||
1213 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1214 | */ | ||
1215 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1216 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1217 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1218 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1219 | |||
1220 | /* | ||
1227 | * We must clear the error counters. | 1221 | * We must clear the error counters. |
1228 | * These registers are cleared on read, | 1222 | * These registers are cleared on read, |
1229 | * so we may pass a useless variable to store the value. | 1223 | * so we may pass a useless variable to store the value. |
@@ -1296,19 +1290,15 @@ continue_csr_init: | |||
1296 | rt61pci_bbp_write(rt2x00dev, 102, 0x16); | 1290 | rt61pci_bbp_write(rt2x00dev, 102, 0x16); |
1297 | rt61pci_bbp_write(rt2x00dev, 107, 0x04); | 1291 | rt61pci_bbp_write(rt2x00dev, 107, 0x04); |
1298 | 1292 | ||
1299 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
1300 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 1293 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
1301 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 1294 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
1302 | 1295 | ||
1303 | if (eeprom != 0xffff && eeprom != 0x0000) { | 1296 | if (eeprom != 0xffff && eeprom != 0x0000) { |
1304 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 1297 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
1305 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 1298 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
1306 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
1307 | reg_id, value); | ||
1308 | rt61pci_bbp_write(rt2x00dev, reg_id, value); | 1299 | rt61pci_bbp_write(rt2x00dev, reg_id, value); |
1309 | } | 1300 | } |
1310 | } | 1301 | } |
1311 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
1312 | 1302 | ||
1313 | return 0; | 1303 | return 0; |
1314 | } | 1304 | } |
@@ -1375,7 +1365,7 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1375 | /* | 1365 | /* |
1376 | * Initialize all registers. | 1366 | * Initialize all registers. |
1377 | */ | 1367 | */ |
1378 | if (rt61pci_init_rings(rt2x00dev) || | 1368 | if (rt61pci_init_queues(rt2x00dev) || |
1379 | rt61pci_init_registers(rt2x00dev) || | 1369 | rt61pci_init_registers(rt2x00dev) || |
1380 | rt61pci_init_bbp(rt2x00dev)) { | 1370 | rt61pci_init_bbp(rt2x00dev)) { |
1381 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 1371 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -1394,11 +1384,6 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1394 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); | 1384 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); |
1395 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); | 1385 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); |
1396 | 1386 | ||
1397 | /* | ||
1398 | * Enable LED | ||
1399 | */ | ||
1400 | rt61pci_enable_led(rt2x00dev); | ||
1401 | |||
1402 | return 0; | 1387 | return 0; |
1403 | } | 1388 | } |
1404 | 1389 | ||
@@ -1406,11 +1391,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1406 | { | 1391 | { |
1407 | u32 reg; | 1392 | u32 reg; |
1408 | 1393 | ||
1409 | /* | ||
1410 | * Disable LED | ||
1411 | */ | ||
1412 | rt61pci_disable_led(rt2x00dev); | ||
1413 | |||
1414 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | 1394 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
1415 | 1395 | ||
1416 | /* | 1396 | /* |
@@ -1426,7 +1406,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1426 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); | 1406 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); |
1427 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); | 1407 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); |
1428 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); | 1408 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); |
1429 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_MGMT, 1); | ||
1430 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1409 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1431 | 1410 | ||
1432 | /* | 1411 | /* |
@@ -1508,10 +1487,10 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1508 | */ | 1487 | */ |
1509 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1488 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1510 | struct sk_buff *skb, | 1489 | struct sk_buff *skb, |
1511 | struct txdata_entry_desc *desc, | 1490 | struct txentry_desc *txdesc, |
1512 | struct ieee80211_tx_control *control) | 1491 | struct ieee80211_tx_control *control) |
1513 | { | 1492 | { |
1514 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1493 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1515 | __le32 *txd = skbdesc->desc; | 1494 | __le32 *txd = skbdesc->desc; |
1516 | u32 word; | 1495 | u32 word; |
1517 | 1496 | ||
@@ -1519,50 +1498,52 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1519 | * Start writing the descriptor words. | 1498 | * Start writing the descriptor words. |
1520 | */ | 1499 | */ |
1521 | rt2x00_desc_read(txd, 1, &word); | 1500 | rt2x00_desc_read(txd, 1, &word); |
1522 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | 1501 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); |
1523 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | 1502 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1524 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1503 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1525 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1504 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1526 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1505 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1527 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1506 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); |
1528 | rt2x00_desc_write(txd, 1, word); | 1507 | rt2x00_desc_write(txd, 1, word); |
1529 | 1508 | ||
1530 | rt2x00_desc_read(txd, 2, &word); | 1509 | rt2x00_desc_read(txd, 2, &word); |
1531 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1510 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1532 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1511 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1533 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1512 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); |
1534 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | 1513 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1535 | rt2x00_desc_write(txd, 2, word); | 1514 | rt2x00_desc_write(txd, 2, word); |
1536 | 1515 | ||
1537 | rt2x00_desc_read(txd, 5, &word); | 1516 | rt2x00_desc_read(txd, 5, &word); |
1538 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1517 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1539 | TXPOWER_TO_DEV(control->power_level)); | 1518 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); |
1540 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1519 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1541 | rt2x00_desc_write(txd, 5, word); | 1520 | rt2x00_desc_write(txd, 5, word); |
1542 | 1521 | ||
1543 | rt2x00_desc_read(txd, 11, &word); | 1522 | if (skbdesc->desc_len > TXINFO_SIZE) { |
1544 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); | 1523 | rt2x00_desc_read(txd, 11, &word); |
1545 | rt2x00_desc_write(txd, 11, word); | 1524 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); |
1525 | rt2x00_desc_write(txd, 11, word); | ||
1526 | } | ||
1546 | 1527 | ||
1547 | rt2x00_desc_read(txd, 0, &word); | 1528 | rt2x00_desc_read(txd, 0, &word); |
1548 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1529 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1549 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1530 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1550 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1531 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1551 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1532 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1552 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1533 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1553 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1534 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1554 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1535 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1555 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1536 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1556 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1537 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1557 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1538 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1558 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1539 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1559 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1540 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1560 | !!(control->flags & | 1541 | !!(control->flags & |
1561 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1542 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
1562 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1543 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1563 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1544 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1564 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1545 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1565 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1546 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1566 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1547 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1567 | rt2x00_desc_write(txd, 0, word); | 1548 | rt2x00_desc_write(txd, 0, word); |
1568 | } | 1549 | } |
@@ -1571,11 +1552,11 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1571 | * TX data initialization | 1552 | * TX data initialization |
1572 | */ | 1553 | */ |
1573 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1554 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1574 | unsigned int queue) | 1555 | const unsigned int queue) |
1575 | { | 1556 | { |
1576 | u32 reg; | 1557 | u32 reg; |
1577 | 1558 | ||
1578 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1559 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1579 | /* | 1560 | /* |
1580 | * For Wi-Fi faily generated beacons between participating | 1561 | * For Wi-Fi faily generated beacons between participating |
1581 | * stations. Set TBTT phase adaptive adjustment step to 8us. | 1562 | * stations. Set TBTT phase adaptive adjustment step to 8us. |
@@ -1584,6 +1565,8 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1584 | 1565 | ||
1585 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 1566 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); |
1586 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { | 1567 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { |
1568 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1569 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1587 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1570 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
1588 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 1571 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); |
1589 | } | 1572 | } |
@@ -1599,8 +1582,6 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1599 | (queue == IEEE80211_TX_QUEUE_DATA2)); | 1582 | (queue == IEEE80211_TX_QUEUE_DATA2)); |
1600 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, | 1583 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, |
1601 | (queue == IEEE80211_TX_QUEUE_DATA3)); | 1584 | (queue == IEEE80211_TX_QUEUE_DATA3)); |
1602 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_MGMT, | ||
1603 | (queue == IEEE80211_TX_QUEUE_DATA4)); | ||
1604 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1585 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1605 | } | 1586 | } |
1606 | 1587 | ||
@@ -1628,7 +1609,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1628 | return 0; | 1609 | return 0; |
1629 | } | 1610 | } |
1630 | 1611 | ||
1631 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 1612 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
1632 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | 1613 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) |
1633 | offset += 14; | 1614 | offset += 14; |
1634 | 1615 | ||
@@ -1648,28 +1629,32 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1648 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | 1629 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; |
1649 | } | 1630 | } |
1650 | 1631 | ||
1651 | static void rt61pci_fill_rxdone(struct data_entry *entry, | 1632 | static void rt61pci_fill_rxdone(struct queue_entry *entry, |
1652 | struct rxdata_entry_desc *desc) | 1633 | struct rxdone_entry_desc *rxdesc) |
1653 | { | 1634 | { |
1654 | __le32 *rxd = entry->priv; | 1635 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1655 | u32 word0; | 1636 | u32 word0; |
1656 | u32 word1; | 1637 | u32 word1; |
1657 | 1638 | ||
1658 | rt2x00_desc_read(rxd, 0, &word0); | 1639 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1659 | rt2x00_desc_read(rxd, 1, &word1); | 1640 | rt2x00_desc_read(priv_rx->desc, 1, &word1); |
1660 | 1641 | ||
1661 | desc->flags = 0; | 1642 | rxdesc->flags = 0; |
1662 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1643 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1663 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1644 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1664 | 1645 | ||
1665 | /* | 1646 | /* |
1666 | * Obtain the status about this packet. | 1647 | * Obtain the status about this packet. |
1667 | */ | 1648 | * When frame was received with an OFDM bitrate, |
1668 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1649 | * the signal is the PLCP value. If it was received with |
1669 | desc->rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1); | 1650 | * a CCK bitrate the signal is the rate in 100kbit/s. |
1670 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1651 | */ |
1671 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1652 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1672 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1653 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1654 | rxdesc->signal_plcp = rxdesc->ofdm; | ||
1655 | rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1); | ||
1656 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
1657 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | ||
1673 | } | 1658 | } |
1674 | 1659 | ||
1675 | /* | 1660 | /* |
@@ -1677,17 +1662,16 @@ static void rt61pci_fill_rxdone(struct data_entry *entry, | |||
1677 | */ | 1662 | */ |
1678 | static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | 1663 | static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) |
1679 | { | 1664 | { |
1680 | struct data_ring *ring; | 1665 | struct data_queue *queue; |
1681 | struct data_entry *entry; | 1666 | struct queue_entry *entry; |
1682 | struct data_entry *entry_done; | 1667 | struct queue_entry *entry_done; |
1683 | __le32 *txd; | 1668 | struct queue_entry_priv_pci_tx *priv_tx; |
1669 | struct txdone_entry_desc txdesc; | ||
1684 | u32 word; | 1670 | u32 word; |
1685 | u32 reg; | 1671 | u32 reg; |
1686 | u32 old_reg; | 1672 | u32 old_reg; |
1687 | int type; | 1673 | int type; |
1688 | int index; | 1674 | int index; |
1689 | int tx_status; | ||
1690 | int retry; | ||
1691 | 1675 | ||
1692 | /* | 1676 | /* |
1693 | * During each loop we will compare the freshly read | 1677 | * During each loop we will compare the freshly read |
@@ -1710,11 +1694,11 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1710 | 1694 | ||
1711 | /* | 1695 | /* |
1712 | * Skip this entry when it contains an invalid | 1696 | * Skip this entry when it contains an invalid |
1713 | * ring identication number. | 1697 | * queue identication number. |
1714 | */ | 1698 | */ |
1715 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); | 1699 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); |
1716 | ring = rt2x00lib_get_ring(rt2x00dev, type); | 1700 | queue = rt2x00queue_get_queue(rt2x00dev, type); |
1717 | if (unlikely(!ring)) | 1701 | if (unlikely(!queue)) |
1718 | continue; | 1702 | continue; |
1719 | 1703 | ||
1720 | /* | 1704 | /* |
@@ -1722,36 +1706,40 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1722 | * index number. | 1706 | * index number. |
1723 | */ | 1707 | */ |
1724 | index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); | 1708 | index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); |
1725 | if (unlikely(index >= ring->stats.limit)) | 1709 | if (unlikely(index >= queue->limit)) |
1726 | continue; | 1710 | continue; |
1727 | 1711 | ||
1728 | entry = &ring->entry[index]; | 1712 | entry = &queue->entries[index]; |
1729 | txd = entry->priv; | 1713 | priv_tx = entry->priv_data; |
1730 | rt2x00_desc_read(txd, 0, &word); | 1714 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1731 | 1715 | ||
1732 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1716 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1733 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1717 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
1734 | return; | 1718 | return; |
1735 | 1719 | ||
1736 | entry_done = rt2x00_get_data_entry_done(ring); | 1720 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1737 | while (entry != entry_done) { | 1721 | while (entry != entry_done) { |
1738 | /* Catch up. Just report any entries we missed as | 1722 | /* Catch up. |
1739 | * failed. */ | 1723 | * Just report any entries we missed as failed. |
1724 | */ | ||
1740 | WARNING(rt2x00dev, | 1725 | WARNING(rt2x00dev, |
1741 | "TX status report missed for entry %p\n", | 1726 | "TX status report missed for entry %d\n", |
1742 | entry_done); | 1727 | entry_done->entry_idx); |
1743 | rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER, | 1728 | |
1744 | 0); | 1729 | txdesc.status = TX_FAIL_OTHER; |
1745 | entry_done = rt2x00_get_data_entry_done(ring); | 1730 | txdesc.retry = 0; |
1731 | |||
1732 | rt2x00pci_txdone(rt2x00dev, entry_done, &txdesc); | ||
1733 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
1746 | } | 1734 | } |
1747 | 1735 | ||
1748 | /* | 1736 | /* |
1749 | * Obtain the status about this packet. | 1737 | * Obtain the status about this packet. |
1750 | */ | 1738 | */ |
1751 | tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); | 1739 | txdesc.status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); |
1752 | retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); | 1740 | txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); |
1753 | 1741 | ||
1754 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1742 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1755 | } | 1743 | } |
1756 | } | 1744 | } |
1757 | 1745 | ||
@@ -1906,7 +1894,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1906 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 1894 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
1907 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 1895 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
1908 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 1896 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
1909 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 1897 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
1910 | } else { | 1898 | } else { |
1911 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 1899 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
1912 | if (value < -10 || value > 10) | 1900 | if (value < -10 || value > 10) |
@@ -2035,35 +2023,51 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2035 | * If the eeprom value is invalid, | 2023 | * If the eeprom value is invalid, |
2036 | * switch to default led mode. | 2024 | * switch to default led mode. |
2037 | */ | 2025 | */ |
2026 | #ifdef CONFIG_RT61PCI_LEDS | ||
2038 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 2027 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
2039 | 2028 | ||
2040 | rt2x00dev->led_mode = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); | 2029 | value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); |
2030 | |||
2031 | switch (value) { | ||
2032 | case LED_MODE_TXRX_ACTIVITY: | ||
2033 | case LED_MODE_ASUS: | ||
2034 | case LED_MODE_ALPHA: | ||
2035 | case LED_MODE_DEFAULT: | ||
2036 | rt2x00dev->led_flags = | ||
2037 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC; | ||
2038 | break; | ||
2039 | case LED_MODE_SIGNAL_STRENGTH: | ||
2040 | rt2x00dev->led_flags = | ||
2041 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC | | ||
2042 | LED_SUPPORT_QUALITY; | ||
2043 | break; | ||
2044 | } | ||
2041 | 2045 | ||
2042 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | 2046 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); |
2043 | rt2x00dev->led_mode); | 2047 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, |
2044 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
2045 | rt2x00_get_field16(eeprom, | 2048 | rt2x00_get_field16(eeprom, |
2046 | EEPROM_LED_POLARITY_GPIO_0)); | 2049 | EEPROM_LED_POLARITY_GPIO_0)); |
2047 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | 2050 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1, |
2048 | rt2x00_get_field16(eeprom, | 2051 | rt2x00_get_field16(eeprom, |
2049 | EEPROM_LED_POLARITY_GPIO_1)); | 2052 | EEPROM_LED_POLARITY_GPIO_1)); |
2050 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | 2053 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2, |
2051 | rt2x00_get_field16(eeprom, | 2054 | rt2x00_get_field16(eeprom, |
2052 | EEPROM_LED_POLARITY_GPIO_2)); | 2055 | EEPROM_LED_POLARITY_GPIO_2)); |
2053 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | 2056 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3, |
2054 | rt2x00_get_field16(eeprom, | 2057 | rt2x00_get_field16(eeprom, |
2055 | EEPROM_LED_POLARITY_GPIO_3)); | 2058 | EEPROM_LED_POLARITY_GPIO_3)); |
2056 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | 2059 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4, |
2057 | rt2x00_get_field16(eeprom, | 2060 | rt2x00_get_field16(eeprom, |
2058 | EEPROM_LED_POLARITY_GPIO_4)); | 2061 | EEPROM_LED_POLARITY_GPIO_4)); |
2059 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | 2062 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT, |
2060 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | 2063 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); |
2061 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | 2064 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG, |
2062 | rt2x00_get_field16(eeprom, | 2065 | rt2x00_get_field16(eeprom, |
2063 | EEPROM_LED_POLARITY_RDY_G)); | 2066 | EEPROM_LED_POLARITY_RDY_G)); |
2064 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | 2067 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, |
2065 | rt2x00_get_field16(eeprom, | 2068 | rt2x00_get_field16(eeprom, |
2066 | EEPROM_LED_POLARITY_RDY_A)); | 2069 | EEPROM_LED_POLARITY_RDY_A)); |
2070 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
2067 | 2071 | ||
2068 | return 0; | 2072 | return 0; |
2069 | } | 2073 | } |
@@ -2197,7 +2201,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2197 | rt2x00dev->hw->extra_tx_headroom = 0; | 2201 | rt2x00dev->hw->extra_tx_headroom = 0; |
2198 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | 2202 | rt2x00dev->hw->max_signal = MAX_SIGNAL; |
2199 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | 2203 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; |
2200 | rt2x00dev->hw->queues = 5; | 2204 | rt2x00dev->hw->queues = 4; |
2201 | 2205 | ||
2202 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 2206 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); |
2203 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 2207 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -2214,8 +2218,8 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2214 | /* | 2218 | /* |
2215 | * Initialize hw_mode information. | 2219 | * Initialize hw_mode information. |
2216 | */ | 2220 | */ |
2217 | spec->num_modes = 2; | 2221 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
2218 | spec->num_rates = 12; | 2222 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
2219 | spec->tx_power_a = NULL; | 2223 | spec->tx_power_a = NULL; |
2220 | spec->tx_power_bg = txpower; | 2224 | spec->tx_power_bg = txpower; |
2221 | spec->tx_power_default = DEFAULT_TXPOWER; | 2225 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -2230,7 +2234,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2230 | 2234 | ||
2231 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 2235 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || |
2232 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { | 2236 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { |
2233 | spec->num_modes = 3; | 2237 | spec->supported_bands |= SUPPORT_BAND_5GHZ; |
2234 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); | 2238 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); |
2235 | 2239 | ||
2236 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2240 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
@@ -2262,7 +2266,7 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2262 | rt61pci_probe_hw_mode(rt2x00dev); | 2266 | rt61pci_probe_hw_mode(rt2x00dev); |
2263 | 2267 | ||
2264 | /* | 2268 | /* |
2265 | * This device requires firmware | 2269 | * This device requires firmware. |
2266 | */ | 2270 | */ |
2267 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 2271 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
2268 | 2272 | ||
@@ -2336,8 +2340,9 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw, | |||
2336 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | 2340 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); |
2337 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | 2341 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, |
2338 | !(*total_flags & FIF_ALLMULTI)); | 2342 | !(*total_flags & FIF_ALLMULTI)); |
2339 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BORADCAST, 0); | 2343 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); |
2340 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | 2344 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, |
2345 | !(*total_flags & FIF_CONTROL)); | ||
2341 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 2346 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); |
2342 | } | 2347 | } |
2343 | 2348 | ||
@@ -2369,37 +2374,25 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | |||
2369 | return tsf; | 2374 | return tsf; |
2370 | } | 2375 | } |
2371 | 2376 | ||
2372 | static void rt61pci_reset_tsf(struct ieee80211_hw *hw) | ||
2373 | { | ||
2374 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2375 | |||
2376 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR12, 0); | ||
2377 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR13, 0); | ||
2378 | } | ||
2379 | |||
2380 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 2377 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
2381 | struct ieee80211_tx_control *control) | 2378 | struct ieee80211_tx_control *control) |
2382 | { | 2379 | { |
2383 | struct rt2x00_dev *rt2x00dev = hw->priv; | 2380 | struct rt2x00_dev *rt2x00dev = hw->priv; |
2384 | struct skb_desc *desc; | 2381 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
2385 | struct data_ring *ring; | 2382 | struct skb_frame_desc *skbdesc; |
2386 | struct data_entry *entry; | 2383 | unsigned int beacon_base; |
2384 | u32 reg; | ||
2387 | 2385 | ||
2388 | /* | 2386 | if (unlikely(!intf->beacon)) |
2389 | * Just in case the ieee80211 doesn't set this, | 2387 | return -ENOBUFS; |
2390 | * but we need this queue set for the descriptor | ||
2391 | * initialization. | ||
2392 | */ | ||
2393 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
2394 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
2395 | entry = rt2x00_get_data_entry(ring); | ||
2396 | 2388 | ||
2397 | /* | 2389 | /* |
2398 | * We need to append the descriptor in front of the | 2390 | * We need to append the descriptor in front of the |
2399 | * beacon frame. | 2391 | * beacon frame. |
2400 | */ | 2392 | */ |
2401 | if (skb_headroom(skb) < TXD_DESC_SIZE) { | 2393 | if (skb_headroom(skb) < intf->beacon->queue->desc_size) { |
2402 | if (pskb_expand_head(skb, TXD_DESC_SIZE, 0, GFP_ATOMIC)) { | 2394 | if (pskb_expand_head(skb, intf->beacon->queue->desc_size, |
2395 | 0, GFP_ATOMIC)) { | ||
2403 | dev_kfree_skb(skb); | 2396 | dev_kfree_skb(skb); |
2404 | return -ENOMEM; | 2397 | return -ENOMEM; |
2405 | } | 2398 | } |
@@ -2408,29 +2401,47 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2408 | /* | 2401 | /* |
2409 | * Add the descriptor in front of the skb. | 2402 | * Add the descriptor in front of the skb. |
2410 | */ | 2403 | */ |
2411 | skb_push(skb, ring->desc_size); | 2404 | skb_push(skb, intf->beacon->queue->desc_size); |
2412 | memset(skb->data, 0, ring->desc_size); | 2405 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
2413 | 2406 | ||
2414 | /* | 2407 | /* |
2415 | * Fill in skb descriptor | 2408 | * Fill in skb descriptor |
2416 | */ | 2409 | */ |
2417 | desc = get_skb_desc(skb); | 2410 | skbdesc = get_skb_frame_desc(skb); |
2418 | desc->desc_len = ring->desc_size; | 2411 | memset(skbdesc, 0, sizeof(*skbdesc)); |
2419 | desc->data_len = skb->len - ring->desc_size; | 2412 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
2420 | desc->desc = skb->data; | 2413 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
2421 | desc->data = skb->data + ring->desc_size; | 2414 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
2422 | desc->ring = ring; | 2415 | skbdesc->desc = skb->data; |
2423 | desc->entry = entry; | 2416 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2417 | skbdesc->entry = intf->beacon; | ||
2418 | |||
2419 | /* | ||
2420 | * Disable beaconing while we are reloading the beacon data, | ||
2421 | * otherwise we might be sending out invalid data. | ||
2422 | */ | ||
2423 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2424 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2425 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2426 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2427 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2424 | 2428 | ||
2429 | /* | ||
2430 | * mac80211 doesn't provide the control->queue variable | ||
2431 | * for beacons. Set our own queue identification so | ||
2432 | * it can be used during descriptor initialization. | ||
2433 | */ | ||
2434 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2425 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2435 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2426 | 2436 | ||
2427 | /* | 2437 | /* |
2428 | * Write entire beacon with descriptor to register, | 2438 | * Write entire beacon with descriptor to register, |
2429 | * and kick the beacon generator. | 2439 | * and kick the beacon generator. |
2430 | */ | 2440 | */ |
2431 | rt2x00pci_register_multiwrite(rt2x00dev, HW_BEACON_BASE0, | 2441 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); |
2442 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | ||
2432 | skb->data, skb->len); | 2443 | skb->data, skb->len); |
2433 | rt61pci_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2444 | rt61pci_kick_tx_queue(rt2x00dev, control->queue); |
2434 | 2445 | ||
2435 | return 0; | 2446 | return 0; |
2436 | } | 2447 | } |
@@ -2450,7 +2461,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2450 | .conf_tx = rt2x00mac_conf_tx, | 2461 | .conf_tx = rt2x00mac_conf_tx, |
2451 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2462 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2452 | .get_tsf = rt61pci_get_tsf, | 2463 | .get_tsf = rt61pci_get_tsf, |
2453 | .reset_tsf = rt61pci_reset_tsf, | ||
2454 | .beacon_update = rt61pci_beacon_update, | 2464 | .beacon_update = rt61pci_beacon_update, |
2455 | }; | 2465 | }; |
2456 | 2466 | ||
@@ -2458,6 +2468,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2458 | .irq_handler = rt61pci_interrupt, | 2468 | .irq_handler = rt61pci_interrupt, |
2459 | .probe_hw = rt61pci_probe_hw, | 2469 | .probe_hw = rt61pci_probe_hw, |
2460 | .get_firmware_name = rt61pci_get_firmware_name, | 2470 | .get_firmware_name = rt61pci_get_firmware_name, |
2471 | .get_firmware_crc = rt61pci_get_firmware_crc, | ||
2461 | .load_firmware = rt61pci_load_firmware, | 2472 | .load_firmware = rt61pci_load_firmware, |
2462 | .initialize = rt2x00pci_initialize, | 2473 | .initialize = rt2x00pci_initialize, |
2463 | .uninitialize = rt2x00pci_uninitialize, | 2474 | .uninitialize = rt2x00pci_uninitialize, |
@@ -2468,23 +2479,46 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2468 | .link_stats = rt61pci_link_stats, | 2479 | .link_stats = rt61pci_link_stats, |
2469 | .reset_tuner = rt61pci_reset_tuner, | 2480 | .reset_tuner = rt61pci_reset_tuner, |
2470 | .link_tuner = rt61pci_link_tuner, | 2481 | .link_tuner = rt61pci_link_tuner, |
2482 | .led_brightness = rt61pci_led_brightness, | ||
2471 | .write_tx_desc = rt61pci_write_tx_desc, | 2483 | .write_tx_desc = rt61pci_write_tx_desc, |
2472 | .write_tx_data = rt2x00pci_write_tx_data, | 2484 | .write_tx_data = rt2x00pci_write_tx_data, |
2473 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2485 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2474 | .fill_rxdone = rt61pci_fill_rxdone, | 2486 | .fill_rxdone = rt61pci_fill_rxdone, |
2475 | .config_mac_addr = rt61pci_config_mac_addr, | 2487 | .config_intf = rt61pci_config_intf, |
2476 | .config_bssid = rt61pci_config_bssid, | 2488 | .config_erp = rt61pci_config_erp, |
2477 | .config_type = rt61pci_config_type, | ||
2478 | .config_preamble = rt61pci_config_preamble, | ||
2479 | .config = rt61pci_config, | 2489 | .config = rt61pci_config, |
2480 | }; | 2490 | }; |
2481 | 2491 | ||
2492 | static const struct data_queue_desc rt61pci_queue_rx = { | ||
2493 | .entry_num = RX_ENTRIES, | ||
2494 | .data_size = DATA_FRAME_SIZE, | ||
2495 | .desc_size = RXD_DESC_SIZE, | ||
2496 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
2497 | }; | ||
2498 | |||
2499 | static const struct data_queue_desc rt61pci_queue_tx = { | ||
2500 | .entry_num = TX_ENTRIES, | ||
2501 | .data_size = DATA_FRAME_SIZE, | ||
2502 | .desc_size = TXD_DESC_SIZE, | ||
2503 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
2504 | }; | ||
2505 | |||
2506 | static const struct data_queue_desc rt61pci_queue_bcn = { | ||
2507 | .entry_num = 4 * BEACON_ENTRIES, | ||
2508 | .data_size = MGMT_FRAME_SIZE, | ||
2509 | .desc_size = TXINFO_SIZE, | ||
2510 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
2511 | }; | ||
2512 | |||
2482 | static const struct rt2x00_ops rt61pci_ops = { | 2513 | static const struct rt2x00_ops rt61pci_ops = { |
2483 | .name = KBUILD_MODNAME, | 2514 | .name = KBUILD_MODNAME, |
2484 | .rxd_size = RXD_DESC_SIZE, | 2515 | .max_sta_intf = 1, |
2485 | .txd_size = TXD_DESC_SIZE, | 2516 | .max_ap_intf = 4, |
2486 | .eeprom_size = EEPROM_SIZE, | 2517 | .eeprom_size = EEPROM_SIZE, |
2487 | .rf_size = RF_SIZE, | 2518 | .rf_size = RF_SIZE, |
2519 | .rx = &rt61pci_queue_rx, | ||
2520 | .tx = &rt61pci_queue_tx, | ||
2521 | .bcn = &rt61pci_queue_bcn, | ||
2488 | .lib = &rt61pci_rt2x00_ops, | 2522 | .lib = &rt61pci_rt2x00_ops, |
2489 | .hw = &rt61pci_mac80211_ops, | 2523 | .hw = &rt61pci_mac80211_ops, |
2490 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 2524 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 4c6524eedad0..3511bba7ff65 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -161,7 +161,9 @@ struct hw_pairwise_ta_entry { | |||
161 | #define HW_BEACON_BASE1 0x2d00 | 161 | #define HW_BEACON_BASE1 0x2d00 |
162 | #define HW_BEACON_BASE2 0x2e00 | 162 | #define HW_BEACON_BASE2 0x2e00 |
163 | #define HW_BEACON_BASE3 0x2f00 | 163 | #define HW_BEACON_BASE3 0x2f00 |
164 | #define HW_BEACON_OFFSET 0x0100 | 164 | |
165 | #define HW_BEACON_OFFSET(__index) \ | ||
166 | ( HW_BEACON_BASE0 + (__index * 0x0100) ) | ||
165 | 167 | ||
166 | /* | 168 | /* |
167 | * HOST-MCU shared memory. | 169 | * HOST-MCU shared memory. |
@@ -234,6 +236,11 @@ struct hw_pairwise_ta_entry { | |||
234 | 236 | ||
235 | /* | 237 | /* |
236 | * MAC_CSR3: STA MAC register 1. | 238 | * MAC_CSR3: STA MAC register 1. |
239 | * UNICAST_TO_ME_MASK: | ||
240 | * Used to mask off bits from byte 5 of the MAC address | ||
241 | * to determine the UNICAST_TO_ME bit for RX frames. | ||
242 | * The full mask is complemented by BSS_ID_MASK: | ||
243 | * MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK | ||
237 | */ | 244 | */ |
238 | #define MAC_CSR3 0x300c | 245 | #define MAC_CSR3 0x300c |
239 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) | 246 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) |
@@ -251,7 +258,14 @@ struct hw_pairwise_ta_entry { | |||
251 | 258 | ||
252 | /* | 259 | /* |
253 | * MAC_CSR5: BSSID register 1. | 260 | * MAC_CSR5: BSSID register 1. |
254 | * BSS_ID_MASK: 3: one BSSID, 0: 4 BSSID, 2 or 1: 2 BSSID. | 261 | * BSS_ID_MASK: |
262 | * This mask is used to mask off bits 0 and 1 of byte 5 of the | ||
263 | * BSSID. This will make sure that those bits will be ignored | ||
264 | * when determining the MY_BSS of RX frames. | ||
265 | * 0: 1-BSSID mode (BSS index = 0) | ||
266 | * 1: 2-BSSID mode (BSS index: Byte5, bit 0) | ||
267 | * 2: 2-BSSID mode (BSS index: byte5, bit 1) | ||
268 | * 3: 4-BSSID mode (BSS index: byte5, bit 0 - 1) | ||
255 | */ | 269 | */ |
256 | #define MAC_CSR5 0x3014 | 270 | #define MAC_CSR5 0x3014 |
257 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) | 271 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) |
@@ -391,7 +405,7 @@ struct hw_pairwise_ta_entry { | |||
391 | #define TXRX_CSR0_DROP_TO_DS FIELD32(0x00200000) | 405 | #define TXRX_CSR0_DROP_TO_DS FIELD32(0x00200000) |
392 | #define TXRX_CSR0_DROP_VERSION_ERROR FIELD32(0x00400000) | 406 | #define TXRX_CSR0_DROP_VERSION_ERROR FIELD32(0x00400000) |
393 | #define TXRX_CSR0_DROP_MULTICAST FIELD32(0x00800000) | 407 | #define TXRX_CSR0_DROP_MULTICAST FIELD32(0x00800000) |
394 | #define TXRX_CSR0_DROP_BORADCAST FIELD32(0x01000000) | 408 | #define TXRX_CSR0_DROP_BROADCAST FIELD32(0x01000000) |
395 | #define TXRX_CSR0_DROP_ACK_CTS FIELD32(0x02000000) | 409 | #define TXRX_CSR0_DROP_ACK_CTS FIELD32(0x02000000) |
396 | #define TXRX_CSR0_TX_WITHOUT_WAITING FIELD32(0x04000000) | 410 | #define TXRX_CSR0_TX_WITHOUT_WAITING FIELD32(0x04000000) |
397 | 411 | ||
@@ -866,7 +880,7 @@ struct hw_pairwise_ta_entry { | |||
866 | #define TX_CNTL_CSR_ABORT_TX_MGMT FIELD32(0x00100000) | 880 | #define TX_CNTL_CSR_ABORT_TX_MGMT FIELD32(0x00100000) |
867 | 881 | ||
868 | /* | 882 | /* |
869 | * LOAD_TX_RING_CSR: Load RX de | 883 | * LOAD_TX_RING_CSR: Load RX desriptor |
870 | */ | 884 | */ |
871 | #define LOAD_TX_RING_CSR 0x3434 | 885 | #define LOAD_TX_RING_CSR 0x3434 |
872 | #define LOAD_TX_RING_CSR_LOAD_TXD_AC0 FIELD32(0x00000001) | 886 | #define LOAD_TX_RING_CSR_LOAD_TXD_AC0 FIELD32(0x00000001) |
@@ -1116,10 +1130,10 @@ struct hw_pairwise_ta_entry { | |||
1116 | #define EEPROM_MAC_ADDR_0 0x0002 | 1130 | #define EEPROM_MAC_ADDR_0 0x0002 |
1117 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) | 1131 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) |
1118 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) | 1132 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) |
1119 | #define EEPROM_MAC_ADDR1 0x0004 | 1133 | #define EEPROM_MAC_ADDR1 0x0003 |
1120 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) | 1134 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) |
1121 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) | 1135 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) |
1122 | #define EEPROM_MAC_ADDR_2 0x0006 | 1136 | #define EEPROM_MAC_ADDR_2 0x0004 |
1123 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) | 1137 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) |
1124 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) | 1138 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) |
1125 | 1139 | ||
@@ -1247,6 +1261,7 @@ struct hw_pairwise_ta_entry { | |||
1247 | * DMA descriptor defines. | 1261 | * DMA descriptor defines. |
1248 | */ | 1262 | */ |
1249 | #define TXD_DESC_SIZE ( 16 * sizeof(__le32) ) | 1263 | #define TXD_DESC_SIZE ( 16 * sizeof(__le32) ) |
1264 | #define TXINFO_SIZE ( 6 * sizeof(__le32) ) | ||
1250 | #define RXD_DESC_SIZE ( 16 * sizeof(__le32) ) | 1265 | #define RXD_DESC_SIZE ( 16 * sizeof(__le32) ) |
1251 | 1266 | ||
1252 | /* | 1267 | /* |
@@ -1440,8 +1455,8 @@ struct hw_pairwise_ta_entry { | |||
1440 | #define RXD_W15_RESERVED FIELD32(0xffffffff) | 1455 | #define RXD_W15_RESERVED FIELD32(0xffffffff) |
1441 | 1456 | ||
1442 | /* | 1457 | /* |
1443 | * Macro's for converting txpower from EEPROM to dscape value | 1458 | * Macro's for converting txpower from EEPROM to mac80211 value |
1444 | * and from dscape value to register value. | 1459 | * and from mac80211 value to register value. |
1445 | */ | 1460 | */ |
1446 | #define MIN_TXPOWER 0 | 1461 | #define MIN_TXPOWER 0 |
1447 | #define MAX_TXPOWER 31 | 1462 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 8103d41a1543..46b040bf62de 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -24,6 +24,7 @@ | |||
24 | Supported chipsets: rt2571W & rt2671. | 24 | Supported chipsets: rt2571W & rt2671. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/crc-itu-t.h> | ||
27 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
28 | #include <linux/etherdevice.h> | 29 | #include <linux/etherdevice.h> |
29 | #include <linux/init.h> | 30 | #include <linux/init.h> |
@@ -278,86 +279,129 @@ static const struct rt2x00debug rt73usb_rt2x00debug = { | |||
278 | }; | 279 | }; |
279 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 280 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
280 | 281 | ||
281 | /* | 282 | #ifdef CONFIG_RT73USB_LEDS |
282 | * Configuration handlers. | 283 | static void rt73usb_led_brightness(struct led_classdev *led_cdev, |
283 | */ | 284 | enum led_brightness brightness) |
284 | static void rt73usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | ||
285 | { | 285 | { |
286 | u32 tmp; | 286 | struct rt2x00_led *led = |
287 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
288 | unsigned int enabled = brightness != LED_OFF; | ||
289 | unsigned int a_mode = | ||
290 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); | ||
291 | unsigned int bg_mode = | ||
292 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); | ||
287 | 293 | ||
288 | tmp = le32_to_cpu(mac[1]); | 294 | if (in_atomic()) { |
289 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | 295 | NOTICE(led->rt2x00dev, |
290 | mac[1] = cpu_to_le32(tmp); | 296 | "Ignoring LED brightness command for led %d\n", |
297 | led->type); | ||
298 | return; | ||
299 | } | ||
291 | 300 | ||
292 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 301 | if (led->type == LED_TYPE_RADIO) { |
293 | (2 * sizeof(__le32))); | 302 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, |
303 | MCU_LEDCS_RADIO_STATUS, enabled); | ||
304 | |||
305 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
306 | 0, led->rt2x00dev->led_mcu_reg, | ||
307 | REGISTER_TIMEOUT); | ||
308 | } else if (led->type == LED_TYPE_ASSOC) { | ||
309 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
310 | MCU_LEDCS_LINK_BG_STATUS, bg_mode); | ||
311 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
312 | MCU_LEDCS_LINK_A_STATUS, a_mode); | ||
313 | |||
314 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
315 | 0, led->rt2x00dev->led_mcu_reg, | ||
316 | REGISTER_TIMEOUT); | ||
317 | } else if (led->type == LED_TYPE_QUALITY) { | ||
318 | /* | ||
319 | * The brightness is divided into 6 levels (0 - 5), | ||
320 | * this means we need to convert the brightness | ||
321 | * argument into the matching level within that range. | ||
322 | */ | ||
323 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
324 | brightness / (LED_FULL / 6), | ||
325 | led->rt2x00dev->led_mcu_reg, | ||
326 | REGISTER_TIMEOUT); | ||
327 | } | ||
294 | } | 328 | } |
329 | #else | ||
330 | #define rt73usb_led_brightness NULL | ||
331 | #endif /* CONFIG_RT73USB_LEDS */ | ||
295 | 332 | ||
296 | static void rt73usb_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 333 | /* |
334 | * Configuration handlers. | ||
335 | */ | ||
336 | static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, | ||
337 | struct rt2x00_intf *intf, | ||
338 | struct rt2x00intf_conf *conf, | ||
339 | const unsigned int flags) | ||
297 | { | 340 | { |
298 | u32 tmp; | 341 | unsigned int beacon_base; |
342 | u32 reg; | ||
299 | 343 | ||
300 | tmp = le32_to_cpu(bssid[1]); | 344 | if (flags & CONFIG_UPDATE_TYPE) { |
301 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 345 | /* |
302 | bssid[1] = cpu_to_le32(tmp); | 346 | * Clear current synchronisation setup. |
347 | * For the Beacon base registers we only need to clear | ||
348 | * the first byte since that byte contains the VALID and OWNER | ||
349 | * bits which (when set to 0) will invalidate the entire beacon. | ||
350 | */ | ||
351 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
352 | rt73usb_register_write(rt2x00dev, beacon_base, 0); | ||
303 | 353 | ||
304 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 354 | /* |
305 | (2 * sizeof(__le32))); | 355 | * Enable synchronisation. |
306 | } | 356 | */ |
357 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
358 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
359 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
360 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
361 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
362 | } | ||
307 | 363 | ||
308 | static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 364 | if (flags & CONFIG_UPDATE_MAC) { |
309 | const int tsf_sync) | 365 | reg = le32_to_cpu(conf->mac[1]); |
310 | { | 366 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); |
311 | u32 reg; | 367 | conf->mac[1] = cpu_to_le32(reg); |
312 | 368 | ||
313 | /* | 369 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, |
314 | * Clear current synchronisation setup. | 370 | conf->mac, sizeof(conf->mac)); |
315 | * For the Beacon base registers we only need to clear | 371 | } |
316 | * the first byte since that byte contains the VALID and OWNER | ||
317 | * bits which (when set to 0) will invalidate the entire beacon. | ||
318 | */ | ||
319 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
320 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
321 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
322 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
323 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
324 | 372 | ||
325 | /* | 373 | if (flags & CONFIG_UPDATE_BSSID) { |
326 | * Enable synchronisation. | 374 | reg = le32_to_cpu(conf->bssid[1]); |
327 | */ | 375 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); |
328 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 376 | conf->bssid[1] = cpu_to_le32(reg); |
329 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | 377 | |
330 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | 378 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, |
331 | (tsf_sync == TSF_SYNC_BEACON)); | 379 | conf->bssid, sizeof(conf->bssid)); |
332 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 380 | } |
333 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | ||
334 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
335 | } | 381 | } |
336 | 382 | ||
337 | static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 383 | static int rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 384 | struct rt2x00lib_erp *erp) |
339 | const int ack_timeout, | ||
340 | const int ack_consume_time) | ||
341 | { | 385 | { |
342 | u32 reg; | 386 | u32 reg; |
343 | 387 | ||
344 | /* | 388 | /* |
345 | * When in atomic context, reschedule and let rt2x00lib | 389 | * When in atomic context, we should let rt2x00lib |
346 | * call this function again. | 390 | * try this configuration again later. |
347 | */ | 391 | */ |
348 | if (in_atomic()) { | 392 | if (in_atomic()) |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 393 | return -EAGAIN; |
350 | return; | ||
351 | } | ||
352 | 394 | ||
353 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 395 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
354 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); | 396 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout); |
355 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 397 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
356 | 398 | ||
357 | rt73usb_register_read(rt2x00dev, TXRX_CSR4, ®); | 399 | rt73usb_register_read(rt2x00dev, TXRX_CSR4, ®); |
358 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 400 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 401 | !!erp->short_preamble); |
360 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | 402 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); |
403 | |||
404 | return 0; | ||
361 | } | 405 | } |
362 | 406 | ||
363 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 407 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -442,28 +486,22 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
442 | case ANTENNA_HW_DIVERSITY: | 486 | case ANTENNA_HW_DIVERSITY: |
443 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); | 487 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
444 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) | 488 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) |
445 | && (rt2x00dev->curr_hwmode != HWMODE_A); | 489 | && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); |
446 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); | 490 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); |
447 | break; | 491 | break; |
448 | case ANTENNA_A: | 492 | case ANTENNA_A: |
449 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 493 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
450 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 494 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
451 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 495 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
452 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 496 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
453 | else | 497 | else |
454 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 498 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
455 | break; | 499 | break; |
456 | case ANTENNA_SW_DIVERSITY: | ||
457 | /* | ||
458 | * NOTE: We should never come here because rt2x00lib is | ||
459 | * supposed to catch this and send us the correct antenna | ||
460 | * explicitely. However we are nog going to bug about this. | ||
461 | * Instead, just default to antenna B. | ||
462 | */ | ||
463 | case ANTENNA_B: | 500 | case ANTENNA_B: |
501 | default: | ||
464 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 502 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
465 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 503 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
466 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 504 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
467 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 505 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
468 | else | 506 | else |
469 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 507 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
@@ -501,14 +539,8 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | |||
501 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 539 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
502 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 540 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
503 | break; | 541 | break; |
504 | case ANTENNA_SW_DIVERSITY: | ||
505 | /* | ||
506 | * NOTE: We should never come here because rt2x00lib is | ||
507 | * supposed to catch this and send us the correct antenna | ||
508 | * explicitely. However we are nog going to bug about this. | ||
509 | * Instead, just default to antenna B. | ||
510 | */ | ||
511 | case ANTENNA_B: | 542 | case ANTENNA_B: |
543 | default: | ||
512 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 544 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
513 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 545 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
514 | break; | 546 | break; |
@@ -558,7 +590,14 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
558 | unsigned int i; | 590 | unsigned int i; |
559 | u32 reg; | 591 | u32 reg; |
560 | 592 | ||
561 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | 593 | /* |
594 | * We should never come here because rt2x00lib is supposed | ||
595 | * to catch this and send us the correct antenna explicitely. | ||
596 | */ | ||
597 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
598 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
599 | |||
600 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { | ||
562 | sel = antenna_sel_a; | 601 | sel = antenna_sel_a; |
563 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 602 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); |
564 | } else { | 603 | } else { |
@@ -572,10 +611,9 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
572 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); | 611 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); |
573 | 612 | ||
574 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 613 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
575 | (rt2x00dev->curr_hwmode == HWMODE_B || | 614 | (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ)); |
576 | rt2x00dev->curr_hwmode == HWMODE_G)); | ||
577 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 615 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
578 | (rt2x00dev->curr_hwmode == HWMODE_A)); | 616 | (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)); |
579 | 617 | ||
580 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); | 618 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); |
581 | 619 | ||
@@ -617,8 +655,8 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
617 | } | 655 | } |
618 | 656 | ||
619 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | 657 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, |
620 | const unsigned int flags, | 658 | struct rt2x00lib_conf *libconf, |
621 | struct rt2x00lib_conf *libconf) | 659 | const unsigned int flags) |
622 | { | 660 | { |
623 | if (flags & CONFIG_UPDATE_PHYMODE) | 661 | if (flags & CONFIG_UPDATE_PHYMODE) |
624 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); | 662 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -634,68 +672,6 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | |||
634 | } | 672 | } |
635 | 673 | ||
636 | /* | 674 | /* |
637 | * LED functions. | ||
638 | */ | ||
639 | static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev) | ||
640 | { | ||
641 | u32 reg; | ||
642 | |||
643 | rt73usb_register_read(rt2x00dev, MAC_CSR14, ®); | ||
644 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
645 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
646 | rt73usb_register_write(rt2x00dev, MAC_CSR14, reg); | ||
647 | |||
648 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); | ||
649 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, | ||
650 | (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); | ||
651 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, | ||
652 | (rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); | ||
653 | |||
654 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, | ||
655 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
656 | } | ||
657 | |||
658 | static void rt73usb_disable_led(struct rt2x00_dev *rt2x00dev) | ||
659 | { | ||
660 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 0); | ||
661 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); | ||
662 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, 0); | ||
663 | |||
664 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, | ||
665 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
666 | } | ||
667 | |||
668 | static void rt73usb_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) | ||
669 | { | ||
670 | u32 led; | ||
671 | |||
672 | if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) | ||
673 | return; | ||
674 | |||
675 | /* | ||
676 | * Led handling requires a positive value for the rssi, | ||
677 | * to do that correctly we need to add the correction. | ||
678 | */ | ||
679 | rssi += rt2x00dev->rssi_offset; | ||
680 | |||
681 | if (rssi <= 30) | ||
682 | led = 0; | ||
683 | else if (rssi <= 39) | ||
684 | led = 1; | ||
685 | else if (rssi <= 49) | ||
686 | led = 2; | ||
687 | else if (rssi <= 53) | ||
688 | led = 3; | ||
689 | else if (rssi <= 63) | ||
690 | led = 4; | ||
691 | else | ||
692 | led = 5; | ||
693 | |||
694 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, led, | ||
695 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * Link tuning | 675 | * Link tuning |
700 | */ | 676 | */ |
701 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, | 677 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -729,17 +705,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
729 | u8 up_bound; | 705 | u8 up_bound; |
730 | u8 low_bound; | 706 | u8 low_bound; |
731 | 707 | ||
732 | /* | ||
733 | * Update Led strength | ||
734 | */ | ||
735 | rt73usb_activity_led(rt2x00dev, rssi); | ||
736 | |||
737 | rt73usb_bbp_read(rt2x00dev, 17, &r17); | 708 | rt73usb_bbp_read(rt2x00dev, 17, &r17); |
738 | 709 | ||
739 | /* | 710 | /* |
740 | * Determine r17 bounds. | 711 | * Determine r17 bounds. |
741 | */ | 712 | */ |
742 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 713 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
743 | low_bound = 0x28; | 714 | low_bound = 0x28; |
744 | up_bound = 0x48; | 715 | up_bound = 0x48; |
745 | 716 | ||
@@ -766,6 +737,13 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
766 | } | 737 | } |
767 | 738 | ||
768 | /* | 739 | /* |
740 | * If we are not associated, we should go straight to the | ||
741 | * dynamic CCA tuning. | ||
742 | */ | ||
743 | if (!rt2x00dev->intf_associated) | ||
744 | goto dynamic_cca_tune; | ||
745 | |||
746 | /* | ||
769 | * Special big-R17 for very short distance | 747 | * Special big-R17 for very short distance |
770 | */ | 748 | */ |
771 | if (rssi > -35) { | 749 | if (rssi > -35) { |
@@ -815,6 +793,8 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
815 | return; | 793 | return; |
816 | } | 794 | } |
817 | 795 | ||
796 | dynamic_cca_tune: | ||
797 | |||
818 | /* | 798 | /* |
819 | * r17 does not yet exceed upper limit, continue and base | 799 | * r17 does not yet exceed upper limit, continue and base |
820 | * the r17 tuning on the false CCA count. | 800 | * the r17 tuning on the false CCA count. |
@@ -833,16 +813,30 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
833 | } | 813 | } |
834 | 814 | ||
835 | /* | 815 | /* |
836 | * Firmware name function. | 816 | * Firmware functions |
837 | */ | 817 | */ |
838 | static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 818 | static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) |
839 | { | 819 | { |
840 | return FIRMWARE_RT2571; | 820 | return FIRMWARE_RT2571; |
841 | } | 821 | } |
842 | 822 | ||
843 | /* | 823 | static u16 rt73usb_get_firmware_crc(void *data, const size_t len) |
844 | * Initialization functions. | 824 | { |
845 | */ | 825 | u16 crc; |
826 | |||
827 | /* | ||
828 | * Use the crc itu-t algorithm. | ||
829 | * The last 2 bytes in the firmware array are the crc checksum itself, | ||
830 | * this means that we should never pass those 2 bytes to the crc | ||
831 | * algorithm. | ||
832 | */ | ||
833 | crc = crc_itu_t(0, data, len - 2); | ||
834 | crc = crc_itu_t_byte(crc, 0); | ||
835 | crc = crc_itu_t_byte(crc, 0); | ||
836 | |||
837 | return crc; | ||
838 | } | ||
839 | |||
846 | static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | 840 | static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, |
847 | const size_t len) | 841 | const size_t len) |
848 | { | 842 | { |
@@ -889,7 +883,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
889 | 883 | ||
890 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 884 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
891 | USB_VENDOR_REQUEST_OUT, | 885 | USB_VENDOR_REQUEST_OUT, |
892 | FIRMWARE_IMAGE_BASE + i, 0x0000, | 886 | FIRMWARE_IMAGE_BASE + i, 0, |
893 | cache, buflen, timeout); | 887 | cache, buflen, timeout); |
894 | 888 | ||
895 | ptr += buflen; | 889 | ptr += buflen; |
@@ -902,18 +896,19 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
902 | * we need to specify a long timeout time. | 896 | * we need to specify a long timeout time. |
903 | */ | 897 | */ |
904 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, | 898 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, |
905 | 0x0000, USB_MODE_FIRMWARE, | 899 | 0, USB_MODE_FIRMWARE, |
906 | REGISTER_TIMEOUT_FIRMWARE); | 900 | REGISTER_TIMEOUT_FIRMWARE); |
907 | if (status < 0) { | 901 | if (status < 0) { |
908 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); | 902 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); |
909 | return status; | 903 | return status; |
910 | } | 904 | } |
911 | 905 | ||
912 | rt73usb_disable_led(rt2x00dev); | ||
913 | |||
914 | return 0; | 906 | return 0; |
915 | } | 907 | } |
916 | 908 | ||
909 | /* | ||
910 | * Initialization functions. | ||
911 | */ | ||
917 | static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | 912 | static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) |
918 | { | 913 | { |
919 | u32 reg; | 914 | u32 reg; |
@@ -988,6 +983,11 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
988 | 983 | ||
989 | rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00); | 984 | rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00); |
990 | 985 | ||
986 | rt73usb_register_read(rt2x00dev, MAC_CSR14, ®); | ||
987 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
988 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
989 | rt73usb_register_write(rt2x00dev, MAC_CSR14, reg); | ||
990 | |||
991 | /* | 991 | /* |
992 | * Invalidate all Shared Keys (SEC_CSR0), | 992 | * Invalidate all Shared Keys (SEC_CSR0), |
993 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) | 993 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) |
@@ -1021,6 +1021,17 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1021 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); | 1021 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); |
1022 | 1022 | ||
1023 | /* | 1023 | /* |
1024 | * Clear all beacons | ||
1025 | * For the Beacon base registers we only need to clear | ||
1026 | * the first byte since that byte contains the VALID and OWNER | ||
1027 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1028 | */ | ||
1029 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1030 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1031 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1032 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1033 | |||
1034 | /* | ||
1024 | * We must clear the error counters. | 1035 | * We must clear the error counters. |
1025 | * These registers are cleared on read, | 1036 | * These registers are cleared on read, |
1026 | * so we may pass a useless variable to store the value. | 1037 | * so we may pass a useless variable to store the value. |
@@ -1094,19 +1105,15 @@ continue_csr_init: | |||
1094 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); | 1105 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); |
1095 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); | 1106 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); |
1096 | 1107 | ||
1097 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
1098 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 1108 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
1099 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 1109 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
1100 | 1110 | ||
1101 | if (eeprom != 0xffff && eeprom != 0x0000) { | 1111 | if (eeprom != 0xffff && eeprom != 0x0000) { |
1102 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 1112 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
1103 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 1113 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
1104 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
1105 | reg_id, value); | ||
1106 | rt73usb_bbp_write(rt2x00dev, reg_id, value); | 1114 | rt73usb_bbp_write(rt2x00dev, reg_id, value); |
1107 | } | 1115 | } |
1108 | } | 1116 | } |
1109 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
1110 | 1117 | ||
1111 | return 0; | 1118 | return 0; |
1112 | } | 1119 | } |
@@ -1136,21 +1143,11 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1136 | return -EIO; | 1143 | return -EIO; |
1137 | } | 1144 | } |
1138 | 1145 | ||
1139 | /* | ||
1140 | * Enable LED | ||
1141 | */ | ||
1142 | rt73usb_enable_led(rt2x00dev); | ||
1143 | |||
1144 | return 0; | 1146 | return 0; |
1145 | } | 1147 | } |
1146 | 1148 | ||
1147 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 1149 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
1148 | { | 1150 | { |
1149 | /* | ||
1150 | * Disable LED | ||
1151 | */ | ||
1152 | rt73usb_disable_led(rt2x00dev); | ||
1153 | |||
1154 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | 1151 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
1155 | 1152 | ||
1156 | /* | 1153 | /* |
@@ -1234,10 +1231,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1234 | */ | 1231 | */ |
1235 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1232 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1236 | struct sk_buff *skb, | 1233 | struct sk_buff *skb, |
1237 | struct txdata_entry_desc *desc, | 1234 | struct txentry_desc *txdesc, |
1238 | struct ieee80211_tx_control *control) | 1235 | struct ieee80211_tx_control *control) |
1239 | { | 1236 | { |
1240 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1237 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1241 | __le32 *txd = skbdesc->desc; | 1238 | __le32 *txd = skbdesc->desc; |
1242 | u32 word; | 1239 | u32 word; |
1243 | 1240 | ||
@@ -1245,47 +1242,47 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1245 | * Start writing the descriptor words. | 1242 | * Start writing the descriptor words. |
1246 | */ | 1243 | */ |
1247 | rt2x00_desc_read(txd, 1, &word); | 1244 | rt2x00_desc_read(txd, 1, &word); |
1248 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | 1245 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); |
1249 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | 1246 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1250 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1247 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1251 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1248 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1252 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1249 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1253 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1250 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); |
1254 | rt2x00_desc_write(txd, 1, word); | 1251 | rt2x00_desc_write(txd, 1, word); |
1255 | 1252 | ||
1256 | rt2x00_desc_read(txd, 2, &word); | 1253 | rt2x00_desc_read(txd, 2, &word); |
1257 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1254 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1258 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1255 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1259 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1256 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); |
1260 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | 1257 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1261 | rt2x00_desc_write(txd, 2, word); | 1258 | rt2x00_desc_write(txd, 2, word); |
1262 | 1259 | ||
1263 | rt2x00_desc_read(txd, 5, &word); | 1260 | rt2x00_desc_read(txd, 5, &word); |
1264 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1261 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1265 | TXPOWER_TO_DEV(control->power_level)); | 1262 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); |
1266 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1263 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1267 | rt2x00_desc_write(txd, 5, word); | 1264 | rt2x00_desc_write(txd, 5, word); |
1268 | 1265 | ||
1269 | rt2x00_desc_read(txd, 0, &word); | 1266 | rt2x00_desc_read(txd, 0, &word); |
1270 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1267 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1271 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1268 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1272 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1269 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1273 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1270 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1274 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1271 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1275 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1272 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1276 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1273 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1277 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1274 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1278 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1275 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1279 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1276 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1280 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1277 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1281 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1278 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1282 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1279 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1283 | !!(control->flags & | 1280 | !!(control->flags & |
1284 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1281 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
1285 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1282 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1286 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1283 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1287 | rt2x00_set_field32(&word, TXD_W0_BURST2, | 1284 | rt2x00_set_field32(&word, TXD_W0_BURST2, |
1288 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1285 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1289 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1286 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1290 | rt2x00_desc_write(txd, 0, word); | 1287 | rt2x00_desc_write(txd, 0, word); |
1291 | } | 1288 | } |
@@ -1309,11 +1306,11 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1309 | * TX data initialization | 1306 | * TX data initialization |
1310 | */ | 1307 | */ |
1311 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1308 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1312 | unsigned int queue) | 1309 | const unsigned int queue) |
1313 | { | 1310 | { |
1314 | u32 reg; | 1311 | u32 reg; |
1315 | 1312 | ||
1316 | if (queue != IEEE80211_TX_QUEUE_BEACON) | 1313 | if (queue != RT2X00_BCN_QUEUE_BEACON) |
1317 | return; | 1314 | return; |
1318 | 1315 | ||
1319 | /* | 1316 | /* |
@@ -1324,6 +1321,8 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1324 | 1321 | ||
1325 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 1322 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
1326 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { | 1323 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { |
1324 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1325 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1327 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1326 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
1328 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 1327 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
1329 | } | 1328 | } |
@@ -1353,7 +1352,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1353 | return 0; | 1352 | return 0; |
1354 | } | 1353 | } |
1355 | 1354 | ||
1356 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 1355 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
1357 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 1356 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
1358 | if (lna == 3 || lna == 2) | 1357 | if (lna == 3 || lna == 2) |
1359 | offset += 10; | 1358 | offset += 10; |
@@ -1377,37 +1376,59 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1377 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | 1376 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; |
1378 | } | 1377 | } |
1379 | 1378 | ||
1380 | static void rt73usb_fill_rxdone(struct data_entry *entry, | 1379 | static void rt73usb_fill_rxdone(struct queue_entry *entry, |
1381 | struct rxdata_entry_desc *desc) | 1380 | struct rxdone_entry_desc *rxdesc) |
1382 | { | 1381 | { |
1383 | struct skb_desc *skbdesc = get_skb_desc(entry->skb); | 1382 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1384 | __le32 *rxd = (__le32 *)entry->skb->data; | 1383 | __le32 *rxd = (__le32 *)entry->skb->data; |
1384 | unsigned int offset = entry->queue->desc_size + 2; | ||
1385 | u32 word0; | 1385 | u32 word0; |
1386 | u32 word1; | 1386 | u32 word1; |
1387 | 1387 | ||
1388 | /* | ||
1389 | * Copy descriptor to the available headroom inside the skbuffer. | ||
1390 | */ | ||
1391 | skb_push(entry->skb, offset); | ||
1392 | memcpy(entry->skb->data, rxd, entry->queue->desc_size); | ||
1393 | rxd = (__le32 *)entry->skb->data; | ||
1394 | |||
1395 | /* | ||
1396 | * The descriptor is now aligned to 4 bytes and thus it is | ||
1397 | * now safe to read it on all architectures. | ||
1398 | */ | ||
1388 | rt2x00_desc_read(rxd, 0, &word0); | 1399 | rt2x00_desc_read(rxd, 0, &word0); |
1389 | rt2x00_desc_read(rxd, 1, &word1); | 1400 | rt2x00_desc_read(rxd, 1, &word1); |
1390 | 1401 | ||
1391 | desc->flags = 0; | 1402 | rxdesc->flags = 0; |
1392 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1403 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1393 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1404 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1394 | 1405 | ||
1395 | /* | 1406 | /* |
1396 | * Obtain the status about this packet. | 1407 | * Obtain the status about this packet. |
1408 | * When frame was received with an OFDM bitrate, | ||
1409 | * the signal is the PLCP value. If it was received with | ||
1410 | * a CCK bitrate the signal is the rate in 100kbit/s. | ||
1411 | */ | ||
1412 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | ||
1413 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | ||
1414 | rxdesc->signal_plcp = rxdesc->ofdm; | ||
1415 | rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1); | ||
1416 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
1417 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | ||
1418 | |||
1419 | /* | ||
1420 | * Adjust the skb memory window to the frame boundaries. | ||
1397 | */ | 1421 | */ |
1398 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1422 | skb_pull(entry->skb, offset + entry->queue->desc_size); |
1399 | desc->rssi = rt73usb_agc_to_rssi(entry->ring->rt2x00dev, word1); | 1423 | skb_trim(entry->skb, rxdesc->size); |
1400 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | ||
1401 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
1402 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | ||
1403 | 1424 | ||
1404 | /* | 1425 | /* |
1405 | * Set descriptor and data pointer. | 1426 | * Set descriptor and data pointer. |
1406 | */ | 1427 | */ |
1407 | skbdesc->desc = entry->skb->data; | 1428 | skbdesc->data = entry->skb->data; |
1408 | skbdesc->desc_len = entry->ring->desc_size; | 1429 | skbdesc->data_len = rxdesc->size; |
1409 | skbdesc->data = entry->skb->data + entry->ring->desc_size; | 1430 | skbdesc->desc = rxd; |
1410 | skbdesc->data_len = desc->size; | 1431 | skbdesc->desc_len = entry->queue->desc_size; |
1411 | } | 1432 | } |
1412 | 1433 | ||
1413 | /* | 1434 | /* |
@@ -1499,7 +1520,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1499 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 1520 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
1500 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 1521 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
1501 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 1522 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
1502 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 1523 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
1503 | } else { | 1524 | } else { |
1504 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 1525 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
1505 | if (value < -10 || value > 10) | 1526 | if (value < -10 || value > 10) |
@@ -1577,33 +1598,49 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1577 | /* | 1598 | /* |
1578 | * Store led settings, for correct led behaviour. | 1599 | * Store led settings, for correct led behaviour. |
1579 | */ | 1600 | */ |
1601 | #ifdef CONFIG_RT73USB_LEDS | ||
1580 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 1602 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
1581 | 1603 | ||
1582 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | 1604 | switch (value) { |
1583 | rt2x00dev->led_mode); | 1605 | case LED_MODE_TXRX_ACTIVITY: |
1584 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | 1606 | case LED_MODE_ASUS: |
1607 | case LED_MODE_ALPHA: | ||
1608 | case LED_MODE_DEFAULT: | ||
1609 | rt2x00dev->led_flags = | ||
1610 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC; | ||
1611 | break; | ||
1612 | case LED_MODE_SIGNAL_STRENGTH: | ||
1613 | rt2x00dev->led_flags = | ||
1614 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC | | ||
1615 | LED_SUPPORT_QUALITY; | ||
1616 | break; | ||
1617 | } | ||
1618 | |||
1619 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); | ||
1620 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
1585 | rt2x00_get_field16(eeprom, | 1621 | rt2x00_get_field16(eeprom, |
1586 | EEPROM_LED_POLARITY_GPIO_0)); | 1622 | EEPROM_LED_POLARITY_GPIO_0)); |
1587 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | 1623 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1, |
1588 | rt2x00_get_field16(eeprom, | 1624 | rt2x00_get_field16(eeprom, |
1589 | EEPROM_LED_POLARITY_GPIO_1)); | 1625 | EEPROM_LED_POLARITY_GPIO_1)); |
1590 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | 1626 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2, |
1591 | rt2x00_get_field16(eeprom, | 1627 | rt2x00_get_field16(eeprom, |
1592 | EEPROM_LED_POLARITY_GPIO_2)); | 1628 | EEPROM_LED_POLARITY_GPIO_2)); |
1593 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | 1629 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3, |
1594 | rt2x00_get_field16(eeprom, | 1630 | rt2x00_get_field16(eeprom, |
1595 | EEPROM_LED_POLARITY_GPIO_3)); | 1631 | EEPROM_LED_POLARITY_GPIO_3)); |
1596 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | 1632 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4, |
1597 | rt2x00_get_field16(eeprom, | 1633 | rt2x00_get_field16(eeprom, |
1598 | EEPROM_LED_POLARITY_GPIO_4)); | 1634 | EEPROM_LED_POLARITY_GPIO_4)); |
1599 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | 1635 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT, |
1600 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | 1636 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); |
1601 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | 1637 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG, |
1602 | rt2x00_get_field16(eeprom, | 1638 | rt2x00_get_field16(eeprom, |
1603 | EEPROM_LED_POLARITY_RDY_G)); | 1639 | EEPROM_LED_POLARITY_RDY_G)); |
1604 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | 1640 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, |
1605 | rt2x00_get_field16(eeprom, | 1641 | rt2x00_get_field16(eeprom, |
1606 | EEPROM_LED_POLARITY_RDY_A)); | 1642 | EEPROM_LED_POLARITY_RDY_A)); |
1643 | #endif /* CONFIG_RT73USB_LEDS */ | ||
1607 | 1644 | ||
1608 | return 0; | 1645 | return 0; |
1609 | } | 1646 | } |
@@ -1759,7 +1796,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1759 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1796 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1760 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | 1797 | rt2x00dev->hw->max_signal = MAX_SIGNAL; |
1761 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | 1798 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; |
1762 | rt2x00dev->hw->queues = 5; | 1799 | rt2x00dev->hw->queues = 4; |
1763 | 1800 | ||
1764 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1801 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); |
1765 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1802 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -1776,8 +1813,8 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1776 | /* | 1813 | /* |
1777 | * Initialize hw_mode information. | 1814 | * Initialize hw_mode information. |
1778 | */ | 1815 | */ |
1779 | spec->num_modes = 2; | 1816 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1780 | spec->num_rates = 12; | 1817 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1781 | spec->tx_power_a = NULL; | 1818 | spec->tx_power_a = NULL; |
1782 | spec->tx_power_bg = txpower; | 1819 | spec->tx_power_bg = txpower; |
1783 | spec->tx_power_default = DEFAULT_TXPOWER; | 1820 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1786,20 +1823,20 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1786 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); | 1823 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); |
1787 | spec->channels = rf_vals_bg_2528; | 1824 | spec->channels = rf_vals_bg_2528; |
1788 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { | 1825 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { |
1826 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1789 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); | 1827 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); |
1790 | spec->channels = rf_vals_5226; | 1828 | spec->channels = rf_vals_5226; |
1791 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { | 1829 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { |
1792 | spec->num_channels = 14; | 1830 | spec->num_channels = 14; |
1793 | spec->channels = rf_vals_5225_2527; | 1831 | spec->channels = rf_vals_5225_2527; |
1794 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { | 1832 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { |
1833 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1795 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); | 1834 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); |
1796 | spec->channels = rf_vals_5225_2527; | 1835 | spec->channels = rf_vals_5225_2527; |
1797 | } | 1836 | } |
1798 | 1837 | ||
1799 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 1838 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || |
1800 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { | 1839 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { |
1801 | spec->num_modes = 3; | ||
1802 | |||
1803 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 1840 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
1804 | for (i = 0; i < 14; i++) | 1841 | for (i = 0; i < 14; i++) |
1805 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | 1842 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); |
@@ -1829,7 +1866,7 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1829 | rt73usb_probe_hw_mode(rt2x00dev); | 1866 | rt73usb_probe_hw_mode(rt2x00dev); |
1830 | 1867 | ||
1831 | /* | 1868 | /* |
1832 | * This device requires firmware | 1869 | * This device requires firmware. |
1833 | */ | 1870 | */ |
1834 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 1871 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
1835 | 1872 | ||
@@ -1913,7 +1950,8 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw, | |||
1913 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | 1950 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, |
1914 | !(*total_flags & FIF_ALLMULTI)); | 1951 | !(*total_flags & FIF_ALLMULTI)); |
1915 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | 1952 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); |
1916 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | 1953 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, |
1954 | !(*total_flags & FIF_CONTROL)); | ||
1917 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 1955 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
1918 | } | 1956 | } |
1919 | 1957 | ||
@@ -1955,61 +1993,65 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) | |||
1955 | #define rt73usb_get_tsf NULL | 1993 | #define rt73usb_get_tsf NULL |
1956 | #endif | 1994 | #endif |
1957 | 1995 | ||
1958 | static void rt73usb_reset_tsf(struct ieee80211_hw *hw) | ||
1959 | { | ||
1960 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1961 | |||
1962 | rt73usb_register_write(rt2x00dev, TXRX_CSR12, 0); | ||
1963 | rt73usb_register_write(rt2x00dev, TXRX_CSR13, 0); | ||
1964 | } | ||
1965 | |||
1966 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 1996 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1967 | struct ieee80211_tx_control *control) | 1997 | struct ieee80211_tx_control *control) |
1968 | { | 1998 | { |
1969 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1999 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1970 | struct skb_desc *desc; | 2000 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1971 | struct data_ring *ring; | 2001 | struct skb_frame_desc *skbdesc; |
1972 | struct data_entry *entry; | 2002 | unsigned int beacon_base; |
1973 | int timeout; | 2003 | unsigned int timeout; |
2004 | u32 reg; | ||
1974 | 2005 | ||
1975 | /* | 2006 | if (unlikely(!intf->beacon)) |
1976 | * Just in case the ieee80211 doesn't set this, | 2007 | return -ENOBUFS; |
1977 | * but we need this queue set for the descriptor | ||
1978 | * initialization. | ||
1979 | */ | ||
1980 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
1981 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
1982 | entry = rt2x00_get_data_entry(ring); | ||
1983 | 2008 | ||
1984 | /* | 2009 | /* |
1985 | * Add the descriptor in front of the skb. | 2010 | * Add the descriptor in front of the skb. |
1986 | */ | 2011 | */ |
1987 | skb_push(skb, ring->desc_size); | 2012 | skb_push(skb, intf->beacon->queue->desc_size); |
1988 | memset(skb->data, 0, ring->desc_size); | 2013 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
1989 | 2014 | ||
1990 | /* | 2015 | /* |
1991 | * Fill in skb descriptor | 2016 | * Fill in skb descriptor |
1992 | */ | 2017 | */ |
1993 | desc = get_skb_desc(skb); | 2018 | skbdesc = get_skb_frame_desc(skb); |
1994 | desc->desc_len = ring->desc_size; | 2019 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1995 | desc->data_len = skb->len - ring->desc_size; | 2020 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
1996 | desc->desc = skb->data; | 2021 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
1997 | desc->data = skb->data + ring->desc_size; | 2022 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
1998 | desc->ring = ring; | 2023 | skbdesc->desc = skb->data; |
1999 | desc->entry = entry; | 2024 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2025 | skbdesc->entry = intf->beacon; | ||
2026 | |||
2027 | /* | ||
2028 | * Disable beaconing while we are reloading the beacon data, | ||
2029 | * otherwise we might be sending out invalid data. | ||
2030 | */ | ||
2031 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2032 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2033 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2034 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2035 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2000 | 2036 | ||
2037 | /* | ||
2038 | * mac80211 doesn't provide the control->queue variable | ||
2039 | * for beacons. Set our own queue identification so | ||
2040 | * it can be used during descriptor initialization. | ||
2041 | */ | ||
2042 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2001 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2043 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2002 | 2044 | ||
2003 | /* | 2045 | /* |
2004 | * Write entire beacon with descriptor to register, | 2046 | * Write entire beacon with descriptor to register, |
2005 | * and kick the beacon generator. | 2047 | * and kick the beacon generator. |
2006 | */ | 2048 | */ |
2049 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2007 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); | 2050 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); |
2008 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 2051 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
2009 | USB_VENDOR_REQUEST_OUT, | 2052 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, |
2010 | HW_BEACON_BASE0, 0x0000, | ||
2011 | skb->data, skb->len, timeout); | 2053 | skb->data, skb->len, timeout); |
2012 | rt73usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2054 | rt73usb_kick_tx_queue(rt2x00dev, control->queue); |
2013 | 2055 | ||
2014 | return 0; | 2056 | return 0; |
2015 | } | 2057 | } |
@@ -2029,13 +2071,13 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2029 | .conf_tx = rt2x00mac_conf_tx, | 2071 | .conf_tx = rt2x00mac_conf_tx, |
2030 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2072 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2031 | .get_tsf = rt73usb_get_tsf, | 2073 | .get_tsf = rt73usb_get_tsf, |
2032 | .reset_tsf = rt73usb_reset_tsf, | ||
2033 | .beacon_update = rt73usb_beacon_update, | 2074 | .beacon_update = rt73usb_beacon_update, |
2034 | }; | 2075 | }; |
2035 | 2076 | ||
2036 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | 2077 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { |
2037 | .probe_hw = rt73usb_probe_hw, | 2078 | .probe_hw = rt73usb_probe_hw, |
2038 | .get_firmware_name = rt73usb_get_firmware_name, | 2079 | .get_firmware_name = rt73usb_get_firmware_name, |
2080 | .get_firmware_crc = rt73usb_get_firmware_crc, | ||
2039 | .load_firmware = rt73usb_load_firmware, | 2081 | .load_firmware = rt73usb_load_firmware, |
2040 | .initialize = rt2x00usb_initialize, | 2082 | .initialize = rt2x00usb_initialize, |
2041 | .uninitialize = rt2x00usb_uninitialize, | 2083 | .uninitialize = rt2x00usb_uninitialize, |
@@ -2045,24 +2087,47 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2045 | .link_stats = rt73usb_link_stats, | 2087 | .link_stats = rt73usb_link_stats, |
2046 | .reset_tuner = rt73usb_reset_tuner, | 2088 | .reset_tuner = rt73usb_reset_tuner, |
2047 | .link_tuner = rt73usb_link_tuner, | 2089 | .link_tuner = rt73usb_link_tuner, |
2090 | .led_brightness = rt73usb_led_brightness, | ||
2048 | .write_tx_desc = rt73usb_write_tx_desc, | 2091 | .write_tx_desc = rt73usb_write_tx_desc, |
2049 | .write_tx_data = rt2x00usb_write_tx_data, | 2092 | .write_tx_data = rt2x00usb_write_tx_data, |
2050 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2093 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2051 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2094 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2052 | .fill_rxdone = rt73usb_fill_rxdone, | 2095 | .fill_rxdone = rt73usb_fill_rxdone, |
2053 | .config_mac_addr = rt73usb_config_mac_addr, | 2096 | .config_intf = rt73usb_config_intf, |
2054 | .config_bssid = rt73usb_config_bssid, | 2097 | .config_erp = rt73usb_config_erp, |
2055 | .config_type = rt73usb_config_type, | ||
2056 | .config_preamble = rt73usb_config_preamble, | ||
2057 | .config = rt73usb_config, | 2098 | .config = rt73usb_config, |
2058 | }; | 2099 | }; |
2059 | 2100 | ||
2101 | static const struct data_queue_desc rt73usb_queue_rx = { | ||
2102 | .entry_num = RX_ENTRIES, | ||
2103 | .data_size = DATA_FRAME_SIZE, | ||
2104 | .desc_size = RXD_DESC_SIZE, | ||
2105 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | ||
2106 | }; | ||
2107 | |||
2108 | static const struct data_queue_desc rt73usb_queue_tx = { | ||
2109 | .entry_num = TX_ENTRIES, | ||
2110 | .data_size = DATA_FRAME_SIZE, | ||
2111 | .desc_size = TXD_DESC_SIZE, | ||
2112 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
2113 | }; | ||
2114 | |||
2115 | static const struct data_queue_desc rt73usb_queue_bcn = { | ||
2116 | .entry_num = 4 * BEACON_ENTRIES, | ||
2117 | .data_size = MGMT_FRAME_SIZE, | ||
2118 | .desc_size = TXINFO_SIZE, | ||
2119 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
2120 | }; | ||
2121 | |||
2060 | static const struct rt2x00_ops rt73usb_ops = { | 2122 | static const struct rt2x00_ops rt73usb_ops = { |
2061 | .name = KBUILD_MODNAME, | 2123 | .name = KBUILD_MODNAME, |
2062 | .rxd_size = RXD_DESC_SIZE, | 2124 | .max_sta_intf = 1, |
2063 | .txd_size = TXD_DESC_SIZE, | 2125 | .max_ap_intf = 4, |
2064 | .eeprom_size = EEPROM_SIZE, | 2126 | .eeprom_size = EEPROM_SIZE, |
2065 | .rf_size = RF_SIZE, | 2127 | .rf_size = RF_SIZE, |
2128 | .rx = &rt73usb_queue_rx, | ||
2129 | .tx = &rt73usb_queue_tx, | ||
2130 | .bcn = &rt73usb_queue_bcn, | ||
2066 | .lib = &rt73usb_rt2x00_ops, | 2131 | .lib = &rt73usb_rt2x00_ops, |
2067 | .hw = &rt73usb_mac80211_ops, | 2132 | .hw = &rt73usb_mac80211_ops, |
2068 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 2133 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index d49dcaacecee..06d687425fef 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -114,6 +114,9 @@ struct hw_pairwise_ta_entry { | |||
114 | #define HW_BEACON_BASE2 0x2600 | 114 | #define HW_BEACON_BASE2 0x2600 |
115 | #define HW_BEACON_BASE3 0x2700 | 115 | #define HW_BEACON_BASE3 0x2700 |
116 | 116 | ||
117 | #define HW_BEACON_OFFSET(__index) \ | ||
118 | ( HW_BEACON_BASE0 + (__index * 0x0100) ) | ||
119 | |||
117 | /* | 120 | /* |
118 | * MAC Control/Status Registers(CSR). | 121 | * MAC Control/Status Registers(CSR). |
119 | * Some values are set in TU, whereas 1 TU == 1024 us. | 122 | * Some values are set in TU, whereas 1 TU == 1024 us. |
@@ -146,6 +149,11 @@ struct hw_pairwise_ta_entry { | |||
146 | 149 | ||
147 | /* | 150 | /* |
148 | * MAC_CSR3: STA MAC register 1. | 151 | * MAC_CSR3: STA MAC register 1. |
152 | * UNICAST_TO_ME_MASK: | ||
153 | * Used to mask off bits from byte 5 of the MAC address | ||
154 | * to determine the UNICAST_TO_ME bit for RX frames. | ||
155 | * The full mask is complemented by BSS_ID_MASK: | ||
156 | * MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK | ||
149 | */ | 157 | */ |
150 | #define MAC_CSR3 0x300c | 158 | #define MAC_CSR3 0x300c |
151 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) | 159 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) |
@@ -163,7 +171,14 @@ struct hw_pairwise_ta_entry { | |||
163 | 171 | ||
164 | /* | 172 | /* |
165 | * MAC_CSR5: BSSID register 1. | 173 | * MAC_CSR5: BSSID register 1. |
166 | * BSS_ID_MASK: 3: one BSSID, 0: 4 BSSID, 2 or 1: 2 BSSID. | 174 | * BSS_ID_MASK: |
175 | * This mask is used to mask off bits 0 and 1 of byte 5 of the | ||
176 | * BSSID. This will make sure that those bits will be ignored | ||
177 | * when determining the MY_BSS of RX frames. | ||
178 | * 0: 1-BSSID mode (BSS index = 0) | ||
179 | * 1: 2-BSSID mode (BSS index: Byte5, bit 0) | ||
180 | * 2: 2-BSSID mode (BSS index: byte5, bit 1) | ||
181 | * 3: 4-BSSID mode (BSS index: byte5, bit 0 - 1) | ||
167 | */ | 182 | */ |
168 | #define MAC_CSR5 0x3014 | 183 | #define MAC_CSR5 0x3014 |
169 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) | 184 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) |
@@ -867,6 +882,7 @@ struct hw_pairwise_ta_entry { | |||
867 | * DMA descriptor defines. | 882 | * DMA descriptor defines. |
868 | */ | 883 | */ |
869 | #define TXD_DESC_SIZE ( 6 * sizeof(__le32) ) | 884 | #define TXD_DESC_SIZE ( 6 * sizeof(__le32) ) |
885 | #define TXINFO_SIZE ( 6 * sizeof(__le32) ) | ||
870 | #define RXD_DESC_SIZE ( 6 * sizeof(__le32) ) | 886 | #define RXD_DESC_SIZE ( 6 * sizeof(__le32) ) |
871 | 887 | ||
872 | /* | 888 | /* |
@@ -1007,8 +1023,8 @@ struct hw_pairwise_ta_entry { | |||
1007 | #define RXD_W5_RESERVED FIELD32(0xffffffff) | 1023 | #define RXD_W5_RESERVED FIELD32(0xffffffff) |
1008 | 1024 | ||
1009 | /* | 1025 | /* |
1010 | * Macro's for converting txpower from EEPROM to dscape value | 1026 | * Macro's for converting txpower from EEPROM to mac80211 value |
1011 | * and from dscape value to register value. | 1027 | * and from mac80211 value to register value. |
1012 | */ | 1028 | */ |
1013 | #define MIN_TXPOWER 0 | 1029 | #define MIN_TXPOWER 0 |
1014 | #define MAX_TXPOWER 31 | 1030 | #define MAX_TXPOWER 31 |