diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00')
32 files changed, 4565 insertions, 3205 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index da05b1faf60d..a1e3938cba9b 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,13 @@ 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 | |||
40 | config RT2400PCI | 42 | config RT2400PCI |
41 | tristate "Ralink rt2400 pci/pcmcia support" | 43 | tristate "Ralink rt2400 pci/pcmcia support" |
42 | depends on RT2X00 && PCI | 44 | depends on PCI |
43 | select RT2X00_LIB_PCI | 45 | select RT2X00_LIB_PCI |
44 | select EEPROM_93CX6 | 46 | select EEPROM_93CX6 |
45 | ---help--- | 47 | ---help--- |
@@ -56,9 +58,16 @@ config RT2400PCI_RFKILL | |||
56 | hardware button to control the radio state. | 58 | hardware button to control the radio state. |
57 | This feature depends on the RF switch subsystem rfkill. | 59 | This feature depends on the RF switch subsystem rfkill. |
58 | 60 | ||
61 | config RT2400PCI_LEDS | ||
62 | bool "RT2400 leds support" | ||
63 | depends on RT2400PCI && LEDS_CLASS | ||
64 | select RT2X00_LIB_LEDS | ||
65 | ---help--- | ||
66 | This adds support for led triggers provided my mac80211. | ||
67 | |||
59 | config RT2500PCI | 68 | config RT2500PCI |
60 | tristate "Ralink rt2500 pci/pcmcia support" | 69 | tristate "Ralink rt2500 pci/pcmcia support" |
61 | depends on RT2X00 && PCI | 70 | depends on PCI |
62 | select RT2X00_LIB_PCI | 71 | select RT2X00_LIB_PCI |
63 | select EEPROM_93CX6 | 72 | select EEPROM_93CX6 |
64 | ---help--- | 73 | ---help--- |
@@ -75,11 +84,19 @@ config RT2500PCI_RFKILL | |||
75 | hardware button to control the radio state. | 84 | hardware button to control the radio state. |
76 | This feature depends on the RF switch subsystem rfkill. | 85 | This feature depends on the RF switch subsystem rfkill. |
77 | 86 | ||
87 | config RT2500PCI_LEDS | ||
88 | bool "RT2500 leds support" | ||
89 | depends on RT2500PCI && LEDS_CLASS | ||
90 | select RT2X00_LIB_LEDS | ||
91 | ---help--- | ||
92 | This adds support for led triggers provided my mac80211. | ||
93 | |||
78 | config RT61PCI | 94 | config RT61PCI |
79 | tristate "Ralink rt61 pci/pcmcia support" | 95 | tristate "Ralink rt61 pci/pcmcia support" |
80 | depends on RT2X00 && PCI | 96 | depends on PCI |
81 | select RT2X00_LIB_PCI | 97 | select RT2X00_LIB_PCI |
82 | select RT2X00_LIB_FIRMWARE | 98 | select RT2X00_LIB_FIRMWARE |
99 | select CRC_ITU_T | ||
83 | select EEPROM_93CX6 | 100 | select EEPROM_93CX6 |
84 | ---help--- | 101 | ---help--- |
85 | This is an experimental driver for the Ralink rt61 wireless chip. | 102 | This is an experimental driver for the Ralink rt61 wireless chip. |
@@ -95,25 +112,47 @@ config RT61PCI_RFKILL | |||
95 | hardware button to control the radio state. | 112 | hardware button to control the radio state. |
96 | This feature depends on the RF switch subsystem rfkill. | 113 | This feature depends on the RF switch subsystem rfkill. |
97 | 114 | ||
115 | config RT61PCI_LEDS | ||
116 | bool "RT61 leds support" | ||
117 | depends on RT61PCI && LEDS_CLASS | ||
118 | select RT2X00_LIB_LEDS | ||
119 | ---help--- | ||
120 | This adds support for led triggers provided my mac80211. | ||
121 | |||
98 | config RT2500USB | 122 | config RT2500USB |
99 | tristate "Ralink rt2500 usb support" | 123 | tristate "Ralink rt2500 usb support" |
100 | depends on RT2X00 && USB | 124 | depends on USB |
101 | select RT2X00_LIB_USB | 125 | select RT2X00_LIB_USB |
102 | ---help--- | 126 | ---help--- |
103 | This is an experimental driver for the Ralink rt2500 wireless chip. | 127 | This is an experimental driver for the Ralink rt2500 wireless chip. |
104 | 128 | ||
105 | When compiled as a module, this driver will be called "rt2500usb.ko". | 129 | When compiled as a module, this driver will be called "rt2500usb.ko". |
106 | 130 | ||
131 | config RT2500USB_LEDS | ||
132 | bool "RT2500 leds support" | ||
133 | depends on RT2500USB && LEDS_CLASS | ||
134 | select RT2X00_LIB_LEDS | ||
135 | ---help--- | ||
136 | This adds support for led triggers provided my mac80211. | ||
137 | |||
107 | config RT73USB | 138 | config RT73USB |
108 | tristate "Ralink rt73 usb support" | 139 | tristate "Ralink rt73 usb support" |
109 | depends on RT2X00 && USB | 140 | depends on USB |
110 | select RT2X00_LIB_USB | 141 | select RT2X00_LIB_USB |
111 | select RT2X00_LIB_FIRMWARE | 142 | select RT2X00_LIB_FIRMWARE |
143 | select CRC_ITU_T | ||
112 | ---help--- | 144 | ---help--- |
113 | This is an experimental driver for the Ralink rt73 wireless chip. | 145 | This is an experimental driver for the Ralink rt73 wireless chip. |
114 | 146 | ||
115 | When compiled as a module, this driver will be called "rt73usb.ko". | 147 | When compiled as a module, this driver will be called "rt73usb.ko". |
116 | 148 | ||
149 | config RT73USB_LEDS | ||
150 | bool "RT73 leds support" | ||
151 | depends on RT73USB && LEDS_CLASS | ||
152 | select RT2X00_LIB_LEDS | ||
153 | ---help--- | ||
154 | This adds support for led triggers provided my mac80211. | ||
155 | |||
117 | config RT2X00_LIB_DEBUGFS | 156 | config RT2X00_LIB_DEBUGFS |
118 | bool "Ralink debugfs support" | 157 | bool "Ralink debugfs support" |
119 | depends on RT2X00_LIB && MAC80211_DEBUGFS | 158 | depends on RT2X00_LIB && MAC80211_DEBUGFS |
@@ -128,3 +167,4 @@ config RT2X00_DEBUG | |||
128 | ---help--- | 167 | ---help--- |
129 | Enable debugging output for all rt2x00 modules | 168 | Enable debugging output for all rt2x00 modules |
130 | 169 | ||
170 | 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..b41187af1306 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,109 @@ 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_brightness_set(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); |
252 | unsigned int enabled = brightness != LED_OFF; | ||
253 | u32 reg; | ||
254 | |||
255 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); | ||
256 | |||
257 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) | ||
258 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); | ||
259 | else if (led->type == LED_TYPE_ACTIVITY) | ||
260 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled); | ||
261 | |||
262 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
254 | } | 263 | } |
255 | 264 | ||
256 | static void rt2400pci_config_bssid(struct rt2x00_dev *rt2x00dev, | 265 | static int rt2400pci_blink_set(struct led_classdev *led_cdev, |
257 | __le32 *bssid) | 266 | unsigned long *delay_on, |
267 | unsigned long *delay_off) | ||
258 | { | 268 | { |
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | 269 | struct rt2x00_led *led = |
260 | (2 * sizeof(__le32))); | 270 | container_of(led_cdev, struct rt2x00_led, led_dev); |
271 | u32 reg; | ||
272 | |||
273 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); | ||
274 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, *delay_on); | ||
275 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, *delay_off); | ||
276 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
277 | |||
278 | return 0; | ||
261 | } | 279 | } |
280 | #endif /* CONFIG_RT2400PCI_LEDS */ | ||
262 | 281 | ||
263 | static void rt2400pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 282 | /* |
264 | const int tsf_sync) | 283 | * Configuration handlers. |
284 | */ | ||
285 | static void rt2400pci_config_filter(struct rt2x00_dev *rt2x00dev, | ||
286 | const unsigned int filter_flags) | ||
265 | { | 287 | { |
266 | u32 reg; | 288 | u32 reg; |
267 | 289 | ||
268 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
269 | |||
270 | /* | 290 | /* |
271 | * Enable beacon config | 291 | * Start configuration steps. |
292 | * Note that the version error will always be dropped | ||
293 | * since there is no filter for it at this time. | ||
272 | */ | 294 | */ |
273 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 295 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); |
274 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | 296 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, |
275 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | 297 | !(filter_flags & FIF_FCSFAIL)); |
276 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | 298 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, |
299 | !(filter_flags & FIF_PLCPFAIL)); | ||
300 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, | ||
301 | !(filter_flags & FIF_CONTROL)); | ||
302 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, | ||
303 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
304 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, | ||
305 | !(filter_flags & FIF_PROMISC_IN_BSS) && | ||
306 | !rt2x00dev->intf_ap_count); | ||
307 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | ||
308 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
309 | } | ||
277 | 310 | ||
278 | /* | 311 | static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, |
279 | * Enable synchronisation. | 312 | struct rt2x00_intf *intf, |
280 | */ | 313 | struct rt2x00intf_conf *conf, |
281 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 314 | const unsigned int flags) |
282 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 315 | { |
283 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | 316 | unsigned int bcn_preload; |
284 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 317 | u32 reg; |
285 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | 318 | |
286 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 319 | if (flags & CONFIG_UPDATE_TYPE) { |
320 | /* | ||
321 | * Enable beacon config | ||
322 | */ | ||
323 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); | ||
324 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | ||
325 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | ||
326 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
327 | |||
328 | /* | ||
329 | * Enable synchronisation. | ||
330 | */ | ||
331 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
332 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
333 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); | ||
334 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
335 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
336 | } | ||
337 | |||
338 | if (flags & CONFIG_UPDATE_MAC) | ||
339 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, | ||
340 | conf->mac, sizeof(conf->mac)); | ||
341 | |||
342 | if (flags & CONFIG_UPDATE_BSSID) | ||
343 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, | ||
344 | conf->bssid, sizeof(conf->bssid)); | ||
287 | } | 345 | } |
288 | 346 | ||
289 | static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 347 | static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, |
290 | const int short_preamble, | 348 | struct rt2x00lib_erp *erp) |
291 | const int ack_timeout, | ||
292 | const int ack_consume_time) | ||
293 | { | 349 | { |
294 | int preamble_mask; | 350 | int preamble_mask; |
295 | u32 reg; | 351 | u32 reg; |
@@ -297,11 +353,13 @@ static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
297 | /* | 353 | /* |
298 | * When short preamble is enabled, we should set bit 0x08 | 354 | * When short preamble is enabled, we should set bit 0x08 |
299 | */ | 355 | */ |
300 | preamble_mask = short_preamble << 3; | 356 | preamble_mask = erp->short_preamble << 3; |
301 | 357 | ||
302 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | 358 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); |
303 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, ack_timeout); | 359 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, |
304 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, ack_consume_time); | 360 | erp->ack_timeout); |
361 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, | ||
362 | erp->ack_consume_time); | ||
305 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 363 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); |
306 | 364 | ||
307 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 365 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
@@ -397,6 +455,13 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
397 | u8 r1; | 455 | u8 r1; |
398 | u8 r4; | 456 | u8 r4; |
399 | 457 | ||
458 | /* | ||
459 | * We should never come here because rt2x00lib is supposed | ||
460 | * to catch this and send us the correct antenna explicitely. | ||
461 | */ | ||
462 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
463 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
464 | |||
400 | rt2400pci_bbp_read(rt2x00dev, 4, &r4); | 465 | rt2400pci_bbp_read(rt2x00dev, 4, &r4); |
401 | rt2400pci_bbp_read(rt2x00dev, 1, &r1); | 466 | rt2400pci_bbp_read(rt2x00dev, 1, &r1); |
402 | 467 | ||
@@ -410,14 +475,8 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
410 | case ANTENNA_A: | 475 | case ANTENNA_A: |
411 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0); | 476 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0); |
412 | break; | 477 | 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: | 478 | case ANTENNA_B: |
479 | default: | ||
421 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2); | 480 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2); |
422 | break; | 481 | break; |
423 | } | 482 | } |
@@ -432,14 +491,8 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
432 | case ANTENNA_A: | 491 | case ANTENNA_A: |
433 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0); | 492 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0); |
434 | break; | 493 | 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: | 494 | case ANTENNA_B: |
495 | default: | ||
443 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | 496 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); |
444 | break; | 497 | break; |
445 | } | 498 | } |
@@ -481,8 +534,8 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
481 | } | 534 | } |
482 | 535 | ||
483 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | 536 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, |
484 | const unsigned int flags, | 537 | struct rt2x00lib_conf *libconf, |
485 | struct rt2x00lib_conf *libconf) | 538 | const unsigned int flags) |
486 | { | 539 | { |
487 | if (flags & CONFIG_UPDATE_PHYMODE) | 540 | if (flags & CONFIG_UPDATE_PHYMODE) |
488 | rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates); | 541 | rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -498,45 +551,17 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | |||
498 | } | 551 | } |
499 | 552 | ||
500 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, | 553 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, |
501 | struct ieee80211_tx_queue_params *params) | 554 | const int cw_min, const int cw_max) |
502 | { | 555 | { |
503 | u32 reg; | 556 | u32 reg; |
504 | 557 | ||
505 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 558 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); |
506 | rt2x00_set_field32(®, CSR11_CWMIN, params->cw_min); | 559 | rt2x00_set_field32(®, CSR11_CWMIN, cw_min); |
507 | rt2x00_set_field32(®, CSR11_CWMAX, params->cw_max); | 560 | rt2x00_set_field32(®, CSR11_CWMAX, cw_max); |
508 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 561 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); |
509 | } | 562 | } |
510 | 563 | ||
511 | /* | 564 | /* |
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 | 565 | * Link tuning |
541 | */ | 566 | */ |
542 | static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, | 567 | static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -593,90 +618,94 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
593 | * Initialization functions. | 618 | * Initialization functions. |
594 | */ | 619 | */ |
595 | static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 620 | static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
596 | struct data_entry *entry) | 621 | struct queue_entry *entry) |
597 | { | 622 | { |
598 | __le32 *rxd = entry->priv; | 623 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
599 | u32 word; | 624 | u32 word; |
600 | 625 | ||
601 | rt2x00_desc_read(rxd, 2, &word); | 626 | rt2x00_desc_read(priv_rx->desc, 2, &word); |
602 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->ring->data_size); | 627 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, |
603 | rt2x00_desc_write(rxd, 2, word); | 628 | entry->queue->data_size); |
629 | rt2x00_desc_write(priv_rx->desc, 2, word); | ||
604 | 630 | ||
605 | rt2x00_desc_read(rxd, 1, &word); | 631 | rt2x00_desc_read(priv_rx->desc, 1, &word); |
606 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma); | 632 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); |
607 | rt2x00_desc_write(rxd, 1, word); | 633 | rt2x00_desc_write(priv_rx->desc, 1, word); |
608 | 634 | ||
609 | rt2x00_desc_read(rxd, 0, &word); | 635 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
610 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 636 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
611 | rt2x00_desc_write(rxd, 0, word); | 637 | rt2x00_desc_write(priv_rx->desc, 0, word); |
612 | } | 638 | } |
613 | 639 | ||
614 | static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 640 | static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
615 | struct data_entry *entry) | 641 | struct queue_entry *entry) |
616 | { | 642 | { |
617 | __le32 *txd = entry->priv; | 643 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
618 | u32 word; | 644 | u32 word; |
619 | 645 | ||
620 | rt2x00_desc_read(txd, 1, &word); | 646 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
621 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma); | 647 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma); |
622 | rt2x00_desc_write(txd, 1, word); | 648 | rt2x00_desc_write(priv_tx->desc, 1, word); |
623 | 649 | ||
624 | rt2x00_desc_read(txd, 2, &word); | 650 | rt2x00_desc_read(priv_tx->desc, 2, &word); |
625 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, entry->ring->data_size); | 651 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, |
626 | rt2x00_desc_write(txd, 2, word); | 652 | entry->queue->data_size); |
653 | rt2x00_desc_write(priv_tx->desc, 2, word); | ||
627 | 654 | ||
628 | rt2x00_desc_read(txd, 0, &word); | 655 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
629 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 656 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
630 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 657 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
631 | rt2x00_desc_write(txd, 0, word); | 658 | rt2x00_desc_write(priv_tx->desc, 0, word); |
632 | } | 659 | } |
633 | 660 | ||
634 | static int rt2400pci_init_rings(struct rt2x00_dev *rt2x00dev) | 661 | static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) |
635 | { | 662 | { |
663 | struct queue_entry_priv_pci_rx *priv_rx; | ||
664 | struct queue_entry_priv_pci_tx *priv_tx; | ||
636 | u32 reg; | 665 | u32 reg; |
637 | 666 | ||
638 | /* | 667 | /* |
639 | * Initialize registers. | 668 | * Initialize registers. |
640 | */ | 669 | */ |
641 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 670 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
642 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | 671 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
643 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | 672 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
644 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | 673 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); |
645 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 674 | 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); | 675 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
651 | 676 | ||
677 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
652 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 678 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); |
653 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 679 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
654 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 680 | priv_tx->desc_dma); |
655 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 681 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); |
656 | 682 | ||
683 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
657 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 684 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); |
658 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 685 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
659 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 686 | priv_tx->desc_dma); |
660 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 687 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
661 | 688 | ||
689 | priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; | ||
662 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 690 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
663 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 691 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
664 | rt2x00dev->bcn[1].data_dma); | 692 | priv_tx->desc_dma); |
665 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 693 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
666 | 694 | ||
695 | priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; | ||
667 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 696 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
668 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 697 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
669 | rt2x00dev->bcn[0].data_dma); | 698 | priv_tx->desc_dma); |
670 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 699 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); |
671 | 700 | ||
672 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 701 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); |
673 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 702 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
674 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | 703 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
675 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 704 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); |
676 | 705 | ||
706 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
677 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 707 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); |
678 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 708 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma); |
679 | rt2x00dev->rx->data_dma); | ||
680 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 709 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); |
681 | 710 | ||
682 | return 0; | 711 | return 0; |
@@ -795,19 +824,15 @@ continue_csr_init: | |||
795 | rt2400pci_bbp_write(rt2x00dev, 30, 0x21); | 824 | rt2400pci_bbp_write(rt2x00dev, 30, 0x21); |
796 | rt2400pci_bbp_write(rt2x00dev, 31, 0x00); | 825 | rt2400pci_bbp_write(rt2x00dev, 31, 0x00); |
797 | 826 | ||
798 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
799 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 827 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
800 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 828 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
801 | 829 | ||
802 | if (eeprom != 0xffff && eeprom != 0x0000) { | 830 | if (eeprom != 0xffff && eeprom != 0x0000) { |
803 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 831 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
804 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 832 | 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); | 833 | rt2400pci_bbp_write(rt2x00dev, reg_id, value); |
808 | } | 834 | } |
809 | } | 835 | } |
810 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
811 | 836 | ||
812 | return 0; | 837 | return 0; |
813 | } | 838 | } |
@@ -859,7 +884,7 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
859 | /* | 884 | /* |
860 | * Initialize all registers. | 885 | * Initialize all registers. |
861 | */ | 886 | */ |
862 | if (rt2400pci_init_rings(rt2x00dev) || | 887 | if (rt2400pci_init_queues(rt2x00dev) || |
863 | rt2400pci_init_registers(rt2x00dev) || | 888 | rt2400pci_init_registers(rt2x00dev) || |
864 | rt2400pci_init_bbp(rt2x00dev)) { | 889 | rt2400pci_init_bbp(rt2x00dev)) { |
865 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 890 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -871,11 +896,6 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
871 | */ | 896 | */ |
872 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | 897 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); |
873 | 898 | ||
874 | /* | ||
875 | * Enable LED | ||
876 | */ | ||
877 | rt2400pci_enable_led(rt2x00dev); | ||
878 | |||
879 | return 0; | 899 | return 0; |
880 | } | 900 | } |
881 | 901 | ||
@@ -883,11 +903,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
883 | { | 903 | { |
884 | u32 reg; | 904 | u32 reg; |
885 | 905 | ||
886 | /* | ||
887 | * Disable LED | ||
888 | */ | ||
889 | rt2400pci_disable_led(rt2x00dev); | ||
890 | |||
891 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 906 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
892 | 907 | ||
893 | /* | 908 | /* |
@@ -986,10 +1001,10 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
986 | */ | 1001 | */ |
987 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1002 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
988 | struct sk_buff *skb, | 1003 | struct sk_buff *skb, |
989 | struct txdata_entry_desc *desc, | 1004 | struct txentry_desc *txdesc, |
990 | struct ieee80211_tx_control *control) | 1005 | struct ieee80211_tx_control *control) |
991 | { | 1006 | { |
992 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1007 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
993 | __le32 *txd = skbdesc->desc; | 1008 | __le32 *txd = skbdesc->desc; |
994 | u32 word; | 1009 | u32 word; |
995 | 1010 | ||
@@ -1001,19 +1016,19 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1001 | rt2x00_desc_write(txd, 2, word); | 1016 | rt2x00_desc_write(txd, 2, word); |
1002 | 1017 | ||
1003 | rt2x00_desc_read(txd, 3, &word); | 1018 | rt2x00_desc_read(txd, 3, &word); |
1004 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); | 1019 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); |
1005 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); | 1020 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); |
1006 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); | 1021 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); |
1007 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); | 1022 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); |
1008 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); | 1023 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); |
1009 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); | 1024 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); |
1010 | rt2x00_desc_write(txd, 3, word); | 1025 | rt2x00_desc_write(txd, 3, word); |
1011 | 1026 | ||
1012 | rt2x00_desc_read(txd, 4, &word); | 1027 | rt2x00_desc_read(txd, 4, &word); |
1013 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, desc->length_low); | 1028 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, txdesc->length_low); |
1014 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); | 1029 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); |
1015 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); | 1030 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); |
1016 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, desc->length_high); | 1031 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, txdesc->length_high); |
1017 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); | 1032 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); |
1018 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); | 1033 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); |
1019 | rt2x00_desc_write(txd, 4, word); | 1034 | rt2x00_desc_write(txd, 4, word); |
@@ -1022,14 +1037,14 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1022 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1037 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1023 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1038 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1024 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1039 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1025 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1040 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1026 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1041 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1027 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1042 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1028 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1043 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1029 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1044 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1030 | rt2x00_set_field32(&word, TXD_W0_RTS, | 1045 | rt2x00_set_field32(&word, TXD_W0_RTS, |
1031 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | 1046 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1032 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1047 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1033 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1048 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1034 | !!(control->flags & | 1049 | !!(control->flags & |
1035 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1050 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
@@ -1040,13 +1055,15 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1040 | * TX data initialization | 1055 | * TX data initialization |
1041 | */ | 1056 | */ |
1042 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1057 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1043 | unsigned int queue) | 1058 | const unsigned int queue) |
1044 | { | 1059 | { |
1045 | u32 reg; | 1060 | u32 reg; |
1046 | 1061 | ||
1047 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1062 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1048 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1063 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1049 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1064 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1065 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
1066 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1050 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1067 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
1051 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1068 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1052 | } | 1069 | } |
@@ -1059,56 +1076,62 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1059 | rt2x00_set_field32(®, TXCSR0_KICK_TX, | 1076 | rt2x00_set_field32(®, TXCSR0_KICK_TX, |
1060 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1077 | (queue == IEEE80211_TX_QUEUE_DATA1)); |
1061 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, | 1078 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, |
1062 | (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); | 1079 | (queue == RT2X00_BCN_QUEUE_ATIM)); |
1063 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1080 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1064 | } | 1081 | } |
1065 | 1082 | ||
1066 | /* | 1083 | /* |
1067 | * RX control handlers | 1084 | * RX control handlers |
1068 | */ | 1085 | */ |
1069 | static void rt2400pci_fill_rxdone(struct data_entry *entry, | 1086 | static void rt2400pci_fill_rxdone(struct queue_entry *entry, |
1070 | struct rxdata_entry_desc *desc) | 1087 | struct rxdone_entry_desc *rxdesc) |
1071 | { | 1088 | { |
1072 | __le32 *rxd = entry->priv; | 1089 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1073 | u32 word0; | 1090 | u32 word0; |
1074 | u32 word2; | 1091 | u32 word2; |
1092 | u32 word3; | ||
1075 | 1093 | ||
1076 | rt2x00_desc_read(rxd, 0, &word0); | 1094 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1077 | rt2x00_desc_read(rxd, 2, &word2); | 1095 | rt2x00_desc_read(priv_rx->desc, 2, &word2); |
1096 | rt2x00_desc_read(priv_rx->desc, 3, &word3); | ||
1078 | 1097 | ||
1079 | desc->flags = 0; | 1098 | rxdesc->flags = 0; |
1080 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1099 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1081 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1100 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1082 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1101 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1083 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1102 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1084 | 1103 | ||
1085 | /* | 1104 | /* |
1086 | * Obtain the status about this packet. | 1105 | * Obtain the status about this packet. |
1106 | * The signal is the PLCP value, and needs to be stripped | ||
1107 | * of the preamble bit (0x08). | ||
1087 | */ | 1108 | */ |
1088 | desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | 1109 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08; |
1089 | desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | 1110 | rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) - |
1090 | entry->ring->rt2x00dev->rssi_offset; | 1111 | entry->queue->rt2x00dev->rssi_offset; |
1091 | desc->ofdm = 0; | 1112 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1092 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1113 | |
1093 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1114 | rxdesc->dev_flags = RXDONE_SIGNAL_PLCP; |
1115 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | ||
1116 | rxdesc->dev_flags |= RXDONE_MY_BSS; | ||
1094 | } | 1117 | } |
1095 | 1118 | ||
1096 | /* | 1119 | /* |
1097 | * Interrupt functions. | 1120 | * Interrupt functions. |
1098 | */ | 1121 | */ |
1099 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | 1122 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, |
1123 | const enum ieee80211_tx_queue queue_idx) | ||
1100 | { | 1124 | { |
1101 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | 1125 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
1102 | struct data_entry *entry; | 1126 | struct queue_entry_priv_pci_tx *priv_tx; |
1103 | __le32 *txd; | 1127 | struct queue_entry *entry; |
1128 | struct txdone_entry_desc txdesc; | ||
1104 | u32 word; | 1129 | u32 word; |
1105 | int tx_status; | ||
1106 | int retry; | ||
1107 | 1130 | ||
1108 | while (!rt2x00_ring_empty(ring)) { | 1131 | while (!rt2x00queue_empty(queue)) { |
1109 | entry = rt2x00_get_data_entry_done(ring); | 1132 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1110 | txd = entry->priv; | 1133 | priv_tx = entry->priv_data; |
1111 | rt2x00_desc_read(txd, 0, &word); | 1134 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1112 | 1135 | ||
1113 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1136 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1114 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1137 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
@@ -1117,10 +1140,10 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | |||
1117 | /* | 1140 | /* |
1118 | * Obtain the status about this packet. | 1141 | * Obtain the status about this packet. |
1119 | */ | 1142 | */ |
1120 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | 1143 | txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); |
1121 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1144 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1122 | 1145 | ||
1123 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1146 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1124 | } | 1147 | } |
1125 | } | 1148 | } |
1126 | 1149 | ||
@@ -1164,7 +1187,7 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | |||
1164 | * 3 - Atim ring transmit done interrupt. | 1187 | * 3 - Atim ring transmit done interrupt. |
1165 | */ | 1188 | */ |
1166 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | 1189 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) |
1167 | rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | 1190 | rt2400pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); |
1168 | 1191 | ||
1169 | /* | 1192 | /* |
1170 | * 4 - Priority ring transmit done interrupt. | 1193 | * 4 - Priority ring transmit done interrupt. |
@@ -1272,8 +1295,27 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1272 | /* | 1295 | /* |
1273 | * Store led mode, for correct led behaviour. | 1296 | * Store led mode, for correct led behaviour. |
1274 | */ | 1297 | */ |
1275 | rt2x00dev->led_mode = | 1298 | #ifdef CONFIG_RT2400PCI_LEDS |
1276 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1299 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1300 | |||
1301 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | ||
1302 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | ||
1303 | rt2x00dev->led_radio.led_dev.brightness_set = | ||
1304 | rt2400pci_brightness_set; | ||
1305 | rt2x00dev->led_radio.led_dev.blink_set = | ||
1306 | rt2400pci_blink_set; | ||
1307 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
1308 | |||
1309 | if (value == LED_MODE_TXRX_ACTIVITY) { | ||
1310 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
1311 | rt2x00dev->led_radio.type = LED_TYPE_ACTIVITY; | ||
1312 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
1313 | rt2400pci_brightness_set; | ||
1314 | rt2x00dev->led_qual.led_dev.blink_set = | ||
1315 | rt2400pci_blink_set; | ||
1316 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
1317 | } | ||
1318 | #endif /* CONFIG_RT2400PCI_LEDS */ | ||
1277 | 1319 | ||
1278 | /* | 1320 | /* |
1279 | * Detect if this device has an hardware controlled radio. | 1321 | * Detect if this device has an hardware controlled radio. |
@@ -1343,8 +1385,8 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1343 | /* | 1385 | /* |
1344 | * Initialize hw_mode information. | 1386 | * Initialize hw_mode information. |
1345 | */ | 1387 | */ |
1346 | spec->num_modes = 1; | 1388 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1347 | spec->num_rates = 4; | 1389 | spec->supported_rates = SUPPORT_RATE_CCK; |
1348 | spec->tx_power_a = NULL; | 1390 | spec->tx_power_a = NULL; |
1349 | spec->tx_power_bg = txpower; | 1391 | spec->tx_power_bg = txpower; |
1350 | spec->tx_power_default = DEFAULT_TXPOWER; | 1392 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1374,9 +1416,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1374 | rt2400pci_probe_hw_mode(rt2x00dev); | 1416 | rt2400pci_probe_hw_mode(rt2x00dev); |
1375 | 1417 | ||
1376 | /* | 1418 | /* |
1377 | * This device requires the beacon ring | 1419 | * This device requires the atim queue |
1378 | */ | 1420 | */ |
1379 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1421 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1380 | 1422 | ||
1381 | /* | 1423 | /* |
1382 | * Set the rssi offset. | 1424 | * Set the rssi offset. |
@@ -1389,64 +1431,6 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1389 | /* | 1431 | /* |
1390 | * IEEE80211 stack callback functions. | 1432 | * IEEE80211 stack callback functions. |
1391 | */ | 1433 | */ |
1392 | static void rt2400pci_configure_filter(struct ieee80211_hw *hw, | ||
1393 | unsigned int changed_flags, | ||
1394 | unsigned int *total_flags, | ||
1395 | int mc_count, | ||
1396 | struct dev_addr_list *mc_list) | ||
1397 | { | ||
1398 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1399 | u32 reg; | ||
1400 | |||
1401 | /* | ||
1402 | * Mask off any flags we are going to ignore from | ||
1403 | * the total_flags field. | ||
1404 | */ | ||
1405 | *total_flags &= | ||
1406 | FIF_ALLMULTI | | ||
1407 | FIF_FCSFAIL | | ||
1408 | FIF_PLCPFAIL | | ||
1409 | FIF_CONTROL | | ||
1410 | FIF_OTHER_BSS | | ||
1411 | FIF_PROMISC_IN_BSS; | ||
1412 | |||
1413 | /* | ||
1414 | * Apply some rules to the filters: | ||
1415 | * - Some filters imply different filters to be set. | ||
1416 | * - Some things we can't filter out at all. | ||
1417 | */ | ||
1418 | *total_flags |= FIF_ALLMULTI; | ||
1419 | if (*total_flags & FIF_OTHER_BSS || | ||
1420 | *total_flags & FIF_PROMISC_IN_BSS) | ||
1421 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
1422 | |||
1423 | /* | ||
1424 | * Check if there is any work left for us. | ||
1425 | */ | ||
1426 | if (rt2x00dev->packet_filter == *total_flags) | ||
1427 | return; | ||
1428 | rt2x00dev->packet_filter = *total_flags; | ||
1429 | |||
1430 | /* | ||
1431 | * Start configuration steps. | ||
1432 | * Note that the version error will always be dropped | ||
1433 | * since there is no filter for it at this time. | ||
1434 | */ | ||
1435 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
1436 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, | ||
1437 | !(*total_flags & FIF_FCSFAIL)); | ||
1438 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, | ||
1439 | !(*total_flags & FIF_PLCPFAIL)); | ||
1440 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, | ||
1441 | !(*total_flags & FIF_CONTROL)); | ||
1442 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, | ||
1443 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1444 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, | ||
1445 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1446 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | ||
1447 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
1448 | } | ||
1449 | |||
1450 | static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw, | 1434 | static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw, |
1451 | u32 short_retry, u32 long_retry) | 1435 | u32 short_retry, u32 long_retry) |
1452 | { | 1436 | { |
@@ -1481,7 +1465,8 @@ static int rt2400pci_conf_tx(struct ieee80211_hw *hw, | |||
1481 | /* | 1465 | /* |
1482 | * Write configuration to register. | 1466 | * Write configuration to register. |
1483 | */ | 1467 | */ |
1484 | rt2400pci_config_cw(rt2x00dev, &rt2x00dev->tx->tx_params); | 1468 | rt2400pci_config_cw(rt2x00dev, |
1469 | rt2x00dev->tx->cw_min, rt2x00dev->tx->cw_max); | ||
1485 | 1470 | ||
1486 | return 0; | 1471 | return 0; |
1487 | } | 1472 | } |
@@ -1500,12 +1485,58 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw) | |||
1500 | return tsf; | 1485 | return tsf; |
1501 | } | 1486 | } |
1502 | 1487 | ||
1503 | static void rt2400pci_reset_tsf(struct ieee80211_hw *hw) | 1488 | static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1489 | struct ieee80211_tx_control *control) | ||
1504 | { | 1490 | { |
1505 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1491 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1492 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1493 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1494 | struct skb_frame_desc *skbdesc; | ||
1495 | u32 reg; | ||
1496 | |||
1497 | if (unlikely(!intf->beacon)) | ||
1498 | return -ENOBUFS; | ||
1499 | priv_tx = intf->beacon->priv_data; | ||
1506 | 1500 | ||
1507 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | 1501 | /* |
1508 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | 1502 | * Fill in skb descriptor |
1503 | */ | ||
1504 | skbdesc = get_skb_frame_desc(skb); | ||
1505 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1506 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1507 | skbdesc->data = skb->data; | ||
1508 | skbdesc->data_len = skb->len; | ||
1509 | skbdesc->desc = priv_tx->desc; | ||
1510 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1511 | skbdesc->entry = intf->beacon; | ||
1512 | |||
1513 | /* | ||
1514 | * Disable beaconing while we are reloading the beacon data, | ||
1515 | * otherwise we might be sending out invalid data. | ||
1516 | */ | ||
1517 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1518 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1519 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1520 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1521 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1522 | |||
1523 | /* | ||
1524 | * mac80211 doesn't provide the control->queue variable | ||
1525 | * for beacons. Set our own queue identification so | ||
1526 | * it can be used during descriptor initialization. | ||
1527 | */ | ||
1528 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1529 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
1530 | |||
1531 | /* | ||
1532 | * Enable beacon generation. | ||
1533 | * Write entire beacon with descriptor to register, | ||
1534 | * and kick the beacon generator. | ||
1535 | */ | ||
1536 | memcpy(priv_tx->data, skb->data, skb->len); | ||
1537 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
1538 | |||
1539 | return 0; | ||
1509 | } | 1540 | } |
1510 | 1541 | ||
1511 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) | 1542 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) |
@@ -1525,15 +1556,14 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { | |||
1525 | .remove_interface = rt2x00mac_remove_interface, | 1556 | .remove_interface = rt2x00mac_remove_interface, |
1526 | .config = rt2x00mac_config, | 1557 | .config = rt2x00mac_config, |
1527 | .config_interface = rt2x00mac_config_interface, | 1558 | .config_interface = rt2x00mac_config_interface, |
1528 | .configure_filter = rt2400pci_configure_filter, | 1559 | .configure_filter = rt2x00mac_configure_filter, |
1529 | .get_stats = rt2x00mac_get_stats, | 1560 | .get_stats = rt2x00mac_get_stats, |
1530 | .set_retry_limit = rt2400pci_set_retry_limit, | 1561 | .set_retry_limit = rt2400pci_set_retry_limit, |
1531 | .bss_info_changed = rt2x00mac_bss_info_changed, | 1562 | .bss_info_changed = rt2x00mac_bss_info_changed, |
1532 | .conf_tx = rt2400pci_conf_tx, | 1563 | .conf_tx = rt2400pci_conf_tx, |
1533 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1564 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1534 | .get_tsf = rt2400pci_get_tsf, | 1565 | .get_tsf = rt2400pci_get_tsf, |
1535 | .reset_tsf = rt2400pci_reset_tsf, | 1566 | .beacon_update = rt2400pci_beacon_update, |
1536 | .beacon_update = rt2x00pci_beacon_update, | ||
1537 | .tx_last_beacon = rt2400pci_tx_last_beacon, | 1567 | .tx_last_beacon = rt2400pci_tx_last_beacon, |
1538 | }; | 1568 | }; |
1539 | 1569 | ||
@@ -1553,19 +1583,50 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
1553 | .write_tx_data = rt2x00pci_write_tx_data, | 1583 | .write_tx_data = rt2x00pci_write_tx_data, |
1554 | .kick_tx_queue = rt2400pci_kick_tx_queue, | 1584 | .kick_tx_queue = rt2400pci_kick_tx_queue, |
1555 | .fill_rxdone = rt2400pci_fill_rxdone, | 1585 | .fill_rxdone = rt2400pci_fill_rxdone, |
1556 | .config_mac_addr = rt2400pci_config_mac_addr, | 1586 | .config_filter = rt2400pci_config_filter, |
1557 | .config_bssid = rt2400pci_config_bssid, | 1587 | .config_intf = rt2400pci_config_intf, |
1558 | .config_type = rt2400pci_config_type, | 1588 | .config_erp = rt2400pci_config_erp, |
1559 | .config_preamble = rt2400pci_config_preamble, | ||
1560 | .config = rt2400pci_config, | 1589 | .config = rt2400pci_config, |
1561 | }; | 1590 | }; |
1562 | 1591 | ||
1592 | static const struct data_queue_desc rt2400pci_queue_rx = { | ||
1593 | .entry_num = RX_ENTRIES, | ||
1594 | .data_size = DATA_FRAME_SIZE, | ||
1595 | .desc_size = RXD_DESC_SIZE, | ||
1596 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
1597 | }; | ||
1598 | |||
1599 | static const struct data_queue_desc rt2400pci_queue_tx = { | ||
1600 | .entry_num = TX_ENTRIES, | ||
1601 | .data_size = DATA_FRAME_SIZE, | ||
1602 | .desc_size = TXD_DESC_SIZE, | ||
1603 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1604 | }; | ||
1605 | |||
1606 | static const struct data_queue_desc rt2400pci_queue_bcn = { | ||
1607 | .entry_num = BEACON_ENTRIES, | ||
1608 | .data_size = MGMT_FRAME_SIZE, | ||
1609 | .desc_size = TXD_DESC_SIZE, | ||
1610 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1611 | }; | ||
1612 | |||
1613 | static const struct data_queue_desc rt2400pci_queue_atim = { | ||
1614 | .entry_num = ATIM_ENTRIES, | ||
1615 | .data_size = DATA_FRAME_SIZE, | ||
1616 | .desc_size = TXD_DESC_SIZE, | ||
1617 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1618 | }; | ||
1619 | |||
1563 | static const struct rt2x00_ops rt2400pci_ops = { | 1620 | static const struct rt2x00_ops rt2400pci_ops = { |
1564 | .name = KBUILD_MODNAME, | 1621 | .name = KBUILD_MODNAME, |
1565 | .rxd_size = RXD_DESC_SIZE, | 1622 | .max_sta_intf = 1, |
1566 | .txd_size = TXD_DESC_SIZE, | 1623 | .max_ap_intf = 1, |
1567 | .eeprom_size = EEPROM_SIZE, | 1624 | .eeprom_size = EEPROM_SIZE, |
1568 | .rf_size = RF_SIZE, | 1625 | .rf_size = RF_SIZE, |
1626 | .rx = &rt2400pci_queue_rx, | ||
1627 | .tx = &rt2400pci_queue_tx, | ||
1628 | .bcn = &rt2400pci_queue_bcn, | ||
1629 | .atim = &rt2400pci_queue_atim, | ||
1569 | .lib = &rt2400pci_rt2x00_ops, | 1630 | .lib = &rt2400pci_rt2x00_ops, |
1570 | .hw = &rt2400pci_mac80211_ops, | 1631 | .hw = &rt2400pci_mac80211_ops, |
1571 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1632 | #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..5ade097ed45e 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,116 @@ 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_brightness_set(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); |
252 | unsigned int enabled = brightness != LED_OFF; | ||
253 | u32 reg; | ||
254 | |||
255 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); | ||
256 | |||
257 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) | ||
258 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); | ||
259 | else if (led->type == LED_TYPE_ACTIVITY) | ||
260 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled); | ||
261 | |||
262 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
254 | } | 263 | } |
255 | 264 | ||
256 | static void rt2500pci_config_bssid(struct rt2x00_dev *rt2x00dev, | 265 | static int rt2500pci_blink_set(struct led_classdev *led_cdev, |
257 | __le32 *bssid) | 266 | unsigned long *delay_on, |
267 | unsigned long *delay_off) | ||
258 | { | 268 | { |
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | 269 | struct rt2x00_led *led = |
260 | (2 * sizeof(__le32))); | 270 | container_of(led_cdev, struct rt2x00_led, led_dev); |
271 | u32 reg; | ||
272 | |||
273 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); | ||
274 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, *delay_on); | ||
275 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, *delay_off); | ||
276 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
277 | |||
278 | return 0; | ||
261 | } | 279 | } |
280 | #endif /* CONFIG_RT2500PCI_LEDS */ | ||
262 | 281 | ||
263 | static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 282 | /* |
264 | const int tsf_sync) | 283 | * Configuration handlers. |
284 | */ | ||
285 | static void rt2500pci_config_filter(struct rt2x00_dev *rt2x00dev, | ||
286 | const unsigned int filter_flags) | ||
265 | { | 287 | { |
266 | u32 reg; | 288 | u32 reg; |
267 | 289 | ||
268 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
269 | |||
270 | /* | 290 | /* |
271 | * Enable beacon config | 291 | * Start configuration steps. |
292 | * Note that the version error will always be dropped | ||
293 | * and broadcast frames will always be accepted since | ||
294 | * there is no filter for it at this time. | ||
272 | */ | 295 | */ |
273 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 296 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); |
274 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | 297 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, |
275 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | 298 | !(filter_flags & FIF_FCSFAIL)); |
276 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, | 299 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, |
277 | rt2x00lib_get_ring(rt2x00dev, | 300 | !(filter_flags & FIF_PLCPFAIL)); |
278 | IEEE80211_TX_QUEUE_BEACON) | 301 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, |
279 | ->tx_params.cw_min); | 302 | !(filter_flags & FIF_CONTROL)); |
280 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | 303 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, |
304 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
305 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, | ||
306 | !(filter_flags & FIF_PROMISC_IN_BSS) && | ||
307 | !rt2x00dev->intf_ap_count); | ||
308 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | ||
309 | rt2x00_set_field32(®, RXCSR0_DROP_MCAST, | ||
310 | !(filter_flags & FIF_ALLMULTI)); | ||
311 | rt2x00_set_field32(®, RXCSR0_DROP_BCAST, 0); | ||
312 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
313 | } | ||
281 | 314 | ||
282 | /* | 315 | static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, |
283 | * Enable synchronisation. | 316 | struct rt2x00_intf *intf, |
284 | */ | 317 | struct rt2x00intf_conf *conf, |
285 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 318 | const unsigned int flags) |
286 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 319 | { |
287 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | 320 | struct data_queue *queue = |
288 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 321 | rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON); |
289 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | 322 | unsigned int bcn_preload; |
290 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 323 | u32 reg; |
324 | |||
325 | if (flags & CONFIG_UPDATE_TYPE) { | ||
326 | /* | ||
327 | * Enable beacon config | ||
328 | */ | ||
329 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); | ||
330 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | ||
331 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | ||
332 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); | ||
333 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
334 | |||
335 | /* | ||
336 | * Enable synchronisation. | ||
337 | */ | ||
338 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
339 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
340 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); | ||
341 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
342 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
343 | } | ||
344 | |||
345 | if (flags & CONFIG_UPDATE_MAC) | ||
346 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, | ||
347 | conf->mac, sizeof(conf->mac)); | ||
348 | |||
349 | if (flags & CONFIG_UPDATE_BSSID) | ||
350 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, | ||
351 | conf->bssid, sizeof(conf->bssid)); | ||
291 | } | 352 | } |
292 | 353 | ||
293 | static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 354 | static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, |
294 | const int short_preamble, | 355 | struct rt2x00lib_erp *erp) |
295 | const int ack_timeout, | ||
296 | const int ack_consume_time) | ||
297 | { | 356 | { |
298 | int preamble_mask; | 357 | int preamble_mask; |
299 | u32 reg; | 358 | u32 reg; |
@@ -301,11 +360,13 @@ static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
301 | /* | 360 | /* |
302 | * When short preamble is enabled, we should set bit 0x08 | 361 | * When short preamble is enabled, we should set bit 0x08 |
303 | */ | 362 | */ |
304 | preamble_mask = short_preamble << 3; | 363 | preamble_mask = erp->short_preamble << 3; |
305 | 364 | ||
306 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | 365 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); |
307 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, ack_timeout); | 366 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, |
308 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, ack_consume_time); | 367 | erp->ack_timeout); |
368 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, | ||
369 | erp->ack_consume_time); | ||
309 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 370 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); |
310 | 371 | ||
311 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 372 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
@@ -425,6 +486,13 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
425 | u8 r14; | 486 | u8 r14; |
426 | u8 r2; | 487 | u8 r2; |
427 | 488 | ||
489 | /* | ||
490 | * We should never come here because rt2x00lib is supposed | ||
491 | * to catch this and send us the correct antenna explicitely. | ||
492 | */ | ||
493 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
494 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
495 | |||
428 | rt2x00pci_register_read(rt2x00dev, BBPCSR1, ®); | 496 | rt2x00pci_register_read(rt2x00dev, BBPCSR1, ®); |
429 | rt2500pci_bbp_read(rt2x00dev, 14, &r14); | 497 | rt2500pci_bbp_read(rt2x00dev, 14, &r14); |
430 | rt2500pci_bbp_read(rt2x00dev, 2, &r2); | 498 | rt2500pci_bbp_read(rt2x00dev, 2, &r2); |
@@ -438,15 +506,8 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
438 | rt2x00_set_field32(®, BBPCSR1_CCK, 0); | 506 | rt2x00_set_field32(®, BBPCSR1_CCK, 0); |
439 | rt2x00_set_field32(®, BBPCSR1_OFDM, 0); | 507 | rt2x00_set_field32(®, BBPCSR1_OFDM, 0); |
440 | break; | 508 | 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: | 509 | case ANTENNA_B: |
510 | default: | ||
450 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); | 511 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); |
451 | rt2x00_set_field32(®, BBPCSR1_CCK, 2); | 512 | rt2x00_set_field32(®, BBPCSR1_CCK, 2); |
452 | rt2x00_set_field32(®, BBPCSR1_OFDM, 2); | 513 | rt2x00_set_field32(®, BBPCSR1_OFDM, 2); |
@@ -460,15 +521,8 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
460 | case ANTENNA_A: | 521 | case ANTENNA_A: |
461 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); | 522 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); |
462 | break; | 523 | 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: | 524 | case ANTENNA_B: |
525 | default: | ||
472 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); | 526 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); |
473 | break; | 527 | break; |
474 | } | 528 | } |
@@ -530,8 +584,8 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
530 | } | 584 | } |
531 | 585 | ||
532 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | 586 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, |
533 | const unsigned int flags, | 587 | struct rt2x00lib_conf *libconf, |
534 | struct rt2x00lib_conf *libconf) | 588 | const unsigned int flags) |
535 | { | 589 | { |
536 | if (flags & CONFIG_UPDATE_PHYMODE) | 590 | if (flags & CONFIG_UPDATE_PHYMODE) |
537 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); | 591 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -548,34 +602,6 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | |||
548 | } | 602 | } |
549 | 603 | ||
550 | /* | 604 | /* |
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 | 605 | * Link tuning |
580 | */ | 606 | */ |
581 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, | 607 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -610,9 +636,10 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
610 | /* | 636 | /* |
611 | * To prevent collisions with MAC ASIC on chipsets | 637 | * To prevent collisions with MAC ASIC on chipsets |
612 | * up to version C the link tuning should halt after 20 | 638 | * up to version C the link tuning should halt after 20 |
613 | * seconds. | 639 | * seconds while being associated. |
614 | */ | 640 | */ |
615 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && | 641 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && |
642 | rt2x00dev->intf_associated && | ||
616 | rt2x00dev->link.count > 20) | 643 | rt2x00dev->link.count > 20) |
617 | return; | 644 | return; |
618 | 645 | ||
@@ -620,9 +647,12 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
620 | 647 | ||
621 | /* | 648 | /* |
622 | * Chipset versions C and lower should directly continue | 649 | * Chipset versions C and lower should directly continue |
623 | * to the dynamic CCA tuning. | 650 | * to the dynamic CCA tuning. Chipset version D and higher |
651 | * should go straight to dynamic CCA tuning when they | ||
652 | * are not associated. | ||
624 | */ | 653 | */ |
625 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D) | 654 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D || |
655 | !rt2x00dev->intf_associated) | ||
626 | goto dynamic_cca_tune; | 656 | goto dynamic_cca_tune; |
627 | 657 | ||
628 | /* | 658 | /* |
@@ -684,82 +714,84 @@ dynamic_cca_tune: | |||
684 | * Initialization functions. | 714 | * Initialization functions. |
685 | */ | 715 | */ |
686 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 716 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
687 | struct data_entry *entry) | 717 | struct queue_entry *entry) |
688 | { | 718 | { |
689 | __le32 *rxd = entry->priv; | 719 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
690 | u32 word; | 720 | u32 word; |
691 | 721 | ||
692 | rt2x00_desc_read(rxd, 1, &word); | 722 | rt2x00_desc_read(priv_rx->desc, 1, &word); |
693 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma); | 723 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); |
694 | rt2x00_desc_write(rxd, 1, word); | 724 | rt2x00_desc_write(priv_rx->desc, 1, word); |
695 | 725 | ||
696 | rt2x00_desc_read(rxd, 0, &word); | 726 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
697 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 727 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
698 | rt2x00_desc_write(rxd, 0, word); | 728 | rt2x00_desc_write(priv_rx->desc, 0, word); |
699 | } | 729 | } |
700 | 730 | ||
701 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 731 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
702 | struct data_entry *entry) | 732 | struct queue_entry *entry) |
703 | { | 733 | { |
704 | __le32 *txd = entry->priv; | 734 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
705 | u32 word; | 735 | u32 word; |
706 | 736 | ||
707 | rt2x00_desc_read(txd, 1, &word); | 737 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
708 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma); | 738 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma); |
709 | rt2x00_desc_write(txd, 1, word); | 739 | rt2x00_desc_write(priv_tx->desc, 1, word); |
710 | 740 | ||
711 | rt2x00_desc_read(txd, 0, &word); | 741 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
712 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 742 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
713 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 743 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
714 | rt2x00_desc_write(txd, 0, word); | 744 | rt2x00_desc_write(priv_tx->desc, 0, word); |
715 | } | 745 | } |
716 | 746 | ||
717 | static int rt2500pci_init_rings(struct rt2x00_dev *rt2x00dev) | 747 | static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) |
718 | { | 748 | { |
749 | struct queue_entry_priv_pci_rx *priv_rx; | ||
750 | struct queue_entry_priv_pci_tx *priv_tx; | ||
719 | u32 reg; | 751 | u32 reg; |
720 | 752 | ||
721 | /* | 753 | /* |
722 | * Initialize registers. | 754 | * Initialize registers. |
723 | */ | 755 | */ |
724 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 756 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
725 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | 757 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
726 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | 758 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
727 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | 759 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); |
728 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 760 | 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); | 761 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
734 | 762 | ||
763 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
735 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 764 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); |
736 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 765 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
737 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 766 | priv_tx->desc_dma); |
738 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 767 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); |
739 | 768 | ||
769 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
740 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 770 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); |
741 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 771 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
742 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 772 | priv_tx->desc_dma); |
743 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 773 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
744 | 774 | ||
775 | priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; | ||
745 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 776 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
746 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 777 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
747 | rt2x00dev->bcn[1].data_dma); | 778 | priv_tx->desc_dma); |
748 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 779 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
749 | 780 | ||
781 | priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; | ||
750 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 782 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
751 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 783 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
752 | rt2x00dev->bcn[0].data_dma); | 784 | priv_tx->desc_dma); |
753 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 785 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); |
754 | 786 | ||
755 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 787 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); |
756 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 788 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
757 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | 789 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
758 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 790 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); |
759 | 791 | ||
792 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
760 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 793 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); |
761 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 794 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma); |
762 | rt2x00dev->rx->data_dma); | ||
763 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 795 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); |
764 | 796 | ||
765 | return 0; | 797 | return 0; |
@@ -947,19 +979,15 @@ continue_csr_init: | |||
947 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); | 979 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); |
948 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); | 980 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); |
949 | 981 | ||
950 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
951 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 982 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
952 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 983 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
953 | 984 | ||
954 | if (eeprom != 0xffff && eeprom != 0x0000) { | 985 | if (eeprom != 0xffff && eeprom != 0x0000) { |
955 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 986 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
956 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 987 | 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); | 988 | rt2500pci_bbp_write(rt2x00dev, reg_id, value); |
960 | } | 989 | } |
961 | } | 990 | } |
962 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
963 | 991 | ||
964 | return 0; | 992 | return 0; |
965 | } | 993 | } |
@@ -1011,7 +1039,7 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1011 | /* | 1039 | /* |
1012 | * Initialize all registers. | 1040 | * Initialize all registers. |
1013 | */ | 1041 | */ |
1014 | if (rt2500pci_init_rings(rt2x00dev) || | 1042 | if (rt2500pci_init_queues(rt2x00dev) || |
1015 | rt2500pci_init_registers(rt2x00dev) || | 1043 | rt2500pci_init_registers(rt2x00dev) || |
1016 | rt2500pci_init_bbp(rt2x00dev)) { | 1044 | rt2500pci_init_bbp(rt2x00dev)) { |
1017 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 1045 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -1023,11 +1051,6 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1023 | */ | 1051 | */ |
1024 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | 1052 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); |
1025 | 1053 | ||
1026 | /* | ||
1027 | * Enable LED | ||
1028 | */ | ||
1029 | rt2500pci_enable_led(rt2x00dev); | ||
1030 | |||
1031 | return 0; | 1054 | return 0; |
1032 | } | 1055 | } |
1033 | 1056 | ||
@@ -1035,11 +1058,6 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1035 | { | 1058 | { |
1036 | u32 reg; | 1059 | u32 reg; |
1037 | 1060 | ||
1038 | /* | ||
1039 | * Disable LED | ||
1040 | */ | ||
1041 | rt2500pci_disable_led(rt2x00dev); | ||
1042 | |||
1043 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 1061 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
1044 | 1062 | ||
1045 | /* | 1063 | /* |
@@ -1138,10 +1156,10 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1138 | */ | 1156 | */ |
1139 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1157 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1140 | struct sk_buff *skb, | 1158 | struct sk_buff *skb, |
1141 | struct txdata_entry_desc *desc, | 1159 | struct txentry_desc *txdesc, |
1142 | struct ieee80211_tx_control *control) | 1160 | struct ieee80211_tx_control *control) |
1143 | { | 1161 | { |
1144 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1162 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1145 | __le32 *txd = skbdesc->desc; | 1163 | __le32 *txd = skbdesc->desc; |
1146 | u32 word; | 1164 | u32 word; |
1147 | 1165 | ||
@@ -1150,36 +1168,36 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1150 | */ | 1168 | */ |
1151 | rt2x00_desc_read(txd, 2, &word); | 1169 | rt2x00_desc_read(txd, 2, &word); |
1152 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); | 1170 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); |
1153 | rt2x00_set_field32(&word, TXD_W2_AIFS, desc->aifs); | 1171 | rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs); |
1154 | rt2x00_set_field32(&word, TXD_W2_CWMIN, desc->cw_min); | 1172 | rt2x00_set_field32(&word, TXD_W2_CWMIN, txdesc->cw_min); |
1155 | rt2x00_set_field32(&word, TXD_W2_CWMAX, desc->cw_max); | 1173 | rt2x00_set_field32(&word, TXD_W2_CWMAX, txdesc->cw_max); |
1156 | rt2x00_desc_write(txd, 2, word); | 1174 | rt2x00_desc_write(txd, 2, word); |
1157 | 1175 | ||
1158 | rt2x00_desc_read(txd, 3, &word); | 1176 | rt2x00_desc_read(txd, 3, &word); |
1159 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); | 1177 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); |
1160 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); | 1178 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); |
1161 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, desc->length_low); | 1179 | 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); | 1180 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, txdesc->length_high); |
1163 | rt2x00_desc_write(txd, 3, word); | 1181 | rt2x00_desc_write(txd, 3, word); |
1164 | 1182 | ||
1165 | rt2x00_desc_read(txd, 10, &word); | 1183 | rt2x00_desc_read(txd, 10, &word); |
1166 | rt2x00_set_field32(&word, TXD_W10_RTS, | 1184 | rt2x00_set_field32(&word, TXD_W10_RTS, |
1167 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | 1185 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1168 | rt2x00_desc_write(txd, 10, word); | 1186 | rt2x00_desc_write(txd, 10, word); |
1169 | 1187 | ||
1170 | rt2x00_desc_read(txd, 0, &word); | 1188 | rt2x00_desc_read(txd, 0, &word); |
1171 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1189 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1172 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1190 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1173 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1191 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1174 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1192 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1175 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1193 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1176 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1194 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1177 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1195 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1178 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1196 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1179 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1197 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1180 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1198 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1181 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); | 1199 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); |
1182 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1200 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1183 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1201 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1184 | !!(control->flags & | 1202 | !!(control->flags & |
1185 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1203 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
@@ -1192,13 +1210,15 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1192 | * TX data initialization | 1210 | * TX data initialization |
1193 | */ | 1211 | */ |
1194 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1212 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1195 | unsigned int queue) | 1213 | const unsigned int queue) |
1196 | { | 1214 | { |
1197 | u32 reg; | 1215 | u32 reg; |
1198 | 1216 | ||
1199 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1217 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1200 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1218 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1201 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1219 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1220 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
1221 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1202 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1222 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
1203 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1223 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1204 | } | 1224 | } |
@@ -1211,53 +1231,63 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1211 | rt2x00_set_field32(®, TXCSR0_KICK_TX, | 1231 | rt2x00_set_field32(®, TXCSR0_KICK_TX, |
1212 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1232 | (queue == IEEE80211_TX_QUEUE_DATA1)); |
1213 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, | 1233 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, |
1214 | (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); | 1234 | (queue == RT2X00_BCN_QUEUE_ATIM)); |
1215 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1235 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1216 | } | 1236 | } |
1217 | 1237 | ||
1218 | /* | 1238 | /* |
1219 | * RX control handlers | 1239 | * RX control handlers |
1220 | */ | 1240 | */ |
1221 | static void rt2500pci_fill_rxdone(struct data_entry *entry, | 1241 | static void rt2500pci_fill_rxdone(struct queue_entry *entry, |
1222 | struct rxdata_entry_desc *desc) | 1242 | struct rxdone_entry_desc *rxdesc) |
1223 | { | 1243 | { |
1224 | __le32 *rxd = entry->priv; | 1244 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1225 | u32 word0; | 1245 | u32 word0; |
1226 | u32 word2; | 1246 | u32 word2; |
1227 | 1247 | ||
1228 | rt2x00_desc_read(rxd, 0, &word0); | 1248 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1229 | rt2x00_desc_read(rxd, 2, &word2); | 1249 | rt2x00_desc_read(priv_rx->desc, 2, &word2); |
1230 | 1250 | ||
1231 | desc->flags = 0; | 1251 | rxdesc->flags = 0; |
1232 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1252 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1233 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1253 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1234 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1254 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1235 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1255 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1236 | 1256 | ||
1237 | desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | 1257 | /* |
1238 | desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | 1258 | * Obtain the status about this packet. |
1239 | entry->ring->rt2x00dev->rssi_offset; | 1259 | * When frame was received with an OFDM bitrate, |
1240 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1260 | * the signal is the PLCP value. If it was received with |
1241 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1261 | * a CCK bitrate the signal is the rate in 100kbit/s. |
1242 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1262 | */ |
1263 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | ||
1264 | rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | ||
1265 | entry->queue->rt2x00dev->rssi_offset; | ||
1266 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
1267 | |||
1268 | rxdesc->dev_flags = 0; | ||
1269 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | ||
1270 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; | ||
1271 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | ||
1272 | rxdesc->dev_flags |= RXDONE_MY_BSS; | ||
1243 | } | 1273 | } |
1244 | 1274 | ||
1245 | /* | 1275 | /* |
1246 | * Interrupt functions. | 1276 | * Interrupt functions. |
1247 | */ | 1277 | */ |
1248 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | 1278 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, |
1279 | const enum ieee80211_tx_queue queue_idx) | ||
1249 | { | 1280 | { |
1250 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | 1281 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
1251 | struct data_entry *entry; | 1282 | struct queue_entry_priv_pci_tx *priv_tx; |
1252 | __le32 *txd; | 1283 | struct queue_entry *entry; |
1284 | struct txdone_entry_desc txdesc; | ||
1253 | u32 word; | 1285 | u32 word; |
1254 | int tx_status; | ||
1255 | int retry; | ||
1256 | 1286 | ||
1257 | while (!rt2x00_ring_empty(ring)) { | 1287 | while (!rt2x00queue_empty(queue)) { |
1258 | entry = rt2x00_get_data_entry_done(ring); | 1288 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1259 | txd = entry->priv; | 1289 | priv_tx = entry->priv_data; |
1260 | rt2x00_desc_read(txd, 0, &word); | 1290 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1261 | 1291 | ||
1262 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1292 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1263 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1293 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
@@ -1266,10 +1296,10 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | |||
1266 | /* | 1296 | /* |
1267 | * Obtain the status about this packet. | 1297 | * Obtain the status about this packet. |
1268 | */ | 1298 | */ |
1269 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | 1299 | txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); |
1270 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1300 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1271 | 1301 | ||
1272 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1302 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1273 | } | 1303 | } |
1274 | } | 1304 | } |
1275 | 1305 | ||
@@ -1313,7 +1343,7 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) | |||
1313 | * 3 - Atim ring transmit done interrupt. | 1343 | * 3 - Atim ring transmit done interrupt. |
1314 | */ | 1344 | */ |
1315 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | 1345 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) |
1316 | rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | 1346 | rt2500pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); |
1317 | 1347 | ||
1318 | /* | 1348 | /* |
1319 | * 4 - Priority ring transmit done interrupt. | 1349 | * 4 - Priority ring transmit done interrupt. |
@@ -1442,8 +1472,27 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1442 | /* | 1472 | /* |
1443 | * Store led mode, for correct led behaviour. | 1473 | * Store led mode, for correct led behaviour. |
1444 | */ | 1474 | */ |
1445 | rt2x00dev->led_mode = | 1475 | #ifdef CONFIG_RT2500PCI_LEDS |
1446 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1476 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1477 | |||
1478 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | ||
1479 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | ||
1480 | rt2x00dev->led_radio.led_dev.brightness_set = | ||
1481 | rt2500pci_brightness_set; | ||
1482 | rt2x00dev->led_radio.led_dev.blink_set = | ||
1483 | rt2500pci_blink_set; | ||
1484 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
1485 | |||
1486 | if (value == LED_MODE_TXRX_ACTIVITY) { | ||
1487 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
1488 | rt2x00dev->led_radio.type = LED_TYPE_ACTIVITY; | ||
1489 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
1490 | rt2500pci_brightness_set; | ||
1491 | rt2x00dev->led_qual.led_dev.blink_set = | ||
1492 | rt2500pci_blink_set; | ||
1493 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
1494 | } | ||
1495 | #endif /* CONFIG_RT2500PCI_LEDS */ | ||
1447 | 1496 | ||
1448 | /* | 1497 | /* |
1449 | * Detect if this device has an hardware controlled radio. | 1498 | * Detect if this device has an hardware controlled radio. |
@@ -1656,8 +1705,8 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1656 | /* | 1705 | /* |
1657 | * Initialize hw_mode information. | 1706 | * Initialize hw_mode information. |
1658 | */ | 1707 | */ |
1659 | spec->num_modes = 2; | 1708 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1660 | spec->num_rates = 12; | 1709 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1661 | spec->tx_power_a = NULL; | 1710 | spec->tx_power_a = NULL; |
1662 | spec->tx_power_bg = txpower; | 1711 | spec->tx_power_bg = txpower; |
1663 | spec->tx_power_default = DEFAULT_TXPOWER; | 1712 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1678,9 +1727,9 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1678 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | 1727 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); |
1679 | spec->channels = rf_vals_bg_2525e; | 1728 | spec->channels = rf_vals_bg_2525e; |
1680 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | 1729 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { |
1730 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1681 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | 1731 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); |
1682 | spec->channels = rf_vals_5222; | 1732 | spec->channels = rf_vals_5222; |
1683 | spec->num_modes = 3; | ||
1684 | } | 1733 | } |
1685 | } | 1734 | } |
1686 | 1735 | ||
@@ -1705,9 +1754,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1705 | rt2500pci_probe_hw_mode(rt2x00dev); | 1754 | rt2500pci_probe_hw_mode(rt2x00dev); |
1706 | 1755 | ||
1707 | /* | 1756 | /* |
1708 | * This device requires the beacon ring | 1757 | * This device requires the atim queue |
1709 | */ | 1758 | */ |
1710 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1759 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1711 | 1760 | ||
1712 | /* | 1761 | /* |
1713 | * Set the rssi offset. | 1762 | * Set the rssi offset. |
@@ -1720,69 +1769,6 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1720 | /* | 1769 | /* |
1721 | * IEEE80211 stack callback functions. | 1770 | * IEEE80211 stack callback functions. |
1722 | */ | 1771 | */ |
1723 | static void rt2500pci_configure_filter(struct ieee80211_hw *hw, | ||
1724 | unsigned int changed_flags, | ||
1725 | unsigned int *total_flags, | ||
1726 | int mc_count, | ||
1727 | struct dev_addr_list *mc_list) | ||
1728 | { | ||
1729 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1730 | u32 reg; | ||
1731 | |||
1732 | /* | ||
1733 | * Mask off any flags we are going to ignore from | ||
1734 | * the total_flags field. | ||
1735 | */ | ||
1736 | *total_flags &= | ||
1737 | FIF_ALLMULTI | | ||
1738 | FIF_FCSFAIL | | ||
1739 | FIF_PLCPFAIL | | ||
1740 | FIF_CONTROL | | ||
1741 | FIF_OTHER_BSS | | ||
1742 | FIF_PROMISC_IN_BSS; | ||
1743 | |||
1744 | /* | ||
1745 | * Apply some rules to the filters: | ||
1746 | * - Some filters imply different filters to be set. | ||
1747 | * - Some things we can't filter out at all. | ||
1748 | */ | ||
1749 | if (mc_count) | ||
1750 | *total_flags |= FIF_ALLMULTI; | ||
1751 | if (*total_flags & FIF_OTHER_BSS || | ||
1752 | *total_flags & FIF_PROMISC_IN_BSS) | ||
1753 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
1754 | |||
1755 | /* | ||
1756 | * Check if there is any work left for us. | ||
1757 | */ | ||
1758 | if (rt2x00dev->packet_filter == *total_flags) | ||
1759 | return; | ||
1760 | rt2x00dev->packet_filter = *total_flags; | ||
1761 | |||
1762 | /* | ||
1763 | * Start configuration steps. | ||
1764 | * Note that the version error will always be dropped | ||
1765 | * and broadcast frames will always be accepted since | ||
1766 | * there is no filter for it at this time. | ||
1767 | */ | ||
1768 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
1769 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, | ||
1770 | !(*total_flags & FIF_FCSFAIL)); | ||
1771 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, | ||
1772 | !(*total_flags & FIF_PLCPFAIL)); | ||
1773 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, | ||
1774 | !(*total_flags & FIF_CONTROL)); | ||
1775 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, | ||
1776 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1777 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, | ||
1778 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1779 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | ||
1780 | rt2x00_set_field32(®, RXCSR0_DROP_MCAST, | ||
1781 | !(*total_flags & FIF_ALLMULTI)); | ||
1782 | rt2x00_set_field32(®, RXCSR0_DROP_BCAST, 0); | ||
1783 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
1784 | } | ||
1785 | |||
1786 | static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw, | 1772 | static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw, |
1787 | u32 short_retry, u32 long_retry) | 1773 | u32 short_retry, u32 long_retry) |
1788 | { | 1774 | { |
@@ -1811,12 +1797,59 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) | |||
1811 | return tsf; | 1797 | return tsf; |
1812 | } | 1798 | } |
1813 | 1799 | ||
1814 | static void rt2500pci_reset_tsf(struct ieee80211_hw *hw) | 1800 | static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1801 | struct ieee80211_tx_control *control) | ||
1815 | { | 1802 | { |
1816 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1803 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1804 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1805 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1806 | struct skb_frame_desc *skbdesc; | ||
1807 | u32 reg; | ||
1817 | 1808 | ||
1818 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | 1809 | if (unlikely(!intf->beacon)) |
1819 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | 1810 | return -ENOBUFS; |
1811 | |||
1812 | priv_tx = intf->beacon->priv_data; | ||
1813 | |||
1814 | /* | ||
1815 | * Fill in skb descriptor | ||
1816 | */ | ||
1817 | skbdesc = get_skb_frame_desc(skb); | ||
1818 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1819 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1820 | skbdesc->data = skb->data; | ||
1821 | skbdesc->data_len = skb->len; | ||
1822 | skbdesc->desc = priv_tx->desc; | ||
1823 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1824 | skbdesc->entry = intf->beacon; | ||
1825 | |||
1826 | /* | ||
1827 | * Disable beaconing while we are reloading the beacon data, | ||
1828 | * otherwise we might be sending out invalid data. | ||
1829 | */ | ||
1830 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1831 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1832 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1833 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1834 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1835 | |||
1836 | /* | ||
1837 | * mac80211 doesn't provide the control->queue variable | ||
1838 | * for beacons. Set our own queue identification so | ||
1839 | * it can be used during descriptor initialization. | ||
1840 | */ | ||
1841 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1842 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
1843 | |||
1844 | /* | ||
1845 | * Enable beacon generation. | ||
1846 | * Write entire beacon with descriptor to register, | ||
1847 | * and kick the beacon generator. | ||
1848 | */ | ||
1849 | memcpy(priv_tx->data, skb->data, skb->len); | ||
1850 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
1851 | |||
1852 | return 0; | ||
1820 | } | 1853 | } |
1821 | 1854 | ||
1822 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) | 1855 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) |
@@ -1836,15 +1869,14 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { | |||
1836 | .remove_interface = rt2x00mac_remove_interface, | 1869 | .remove_interface = rt2x00mac_remove_interface, |
1837 | .config = rt2x00mac_config, | 1870 | .config = rt2x00mac_config, |
1838 | .config_interface = rt2x00mac_config_interface, | 1871 | .config_interface = rt2x00mac_config_interface, |
1839 | .configure_filter = rt2500pci_configure_filter, | 1872 | .configure_filter = rt2x00mac_configure_filter, |
1840 | .get_stats = rt2x00mac_get_stats, | 1873 | .get_stats = rt2x00mac_get_stats, |
1841 | .set_retry_limit = rt2500pci_set_retry_limit, | 1874 | .set_retry_limit = rt2500pci_set_retry_limit, |
1842 | .bss_info_changed = rt2x00mac_bss_info_changed, | 1875 | .bss_info_changed = rt2x00mac_bss_info_changed, |
1843 | .conf_tx = rt2x00mac_conf_tx, | 1876 | .conf_tx = rt2x00mac_conf_tx, |
1844 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1877 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1845 | .get_tsf = rt2500pci_get_tsf, | 1878 | .get_tsf = rt2500pci_get_tsf, |
1846 | .reset_tsf = rt2500pci_reset_tsf, | 1879 | .beacon_update = rt2500pci_beacon_update, |
1847 | .beacon_update = rt2x00pci_beacon_update, | ||
1848 | .tx_last_beacon = rt2500pci_tx_last_beacon, | 1880 | .tx_last_beacon = rt2500pci_tx_last_beacon, |
1849 | }; | 1881 | }; |
1850 | 1882 | ||
@@ -1864,19 +1896,50 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
1864 | .write_tx_data = rt2x00pci_write_tx_data, | 1896 | .write_tx_data = rt2x00pci_write_tx_data, |
1865 | .kick_tx_queue = rt2500pci_kick_tx_queue, | 1897 | .kick_tx_queue = rt2500pci_kick_tx_queue, |
1866 | .fill_rxdone = rt2500pci_fill_rxdone, | 1898 | .fill_rxdone = rt2500pci_fill_rxdone, |
1867 | .config_mac_addr = rt2500pci_config_mac_addr, | 1899 | .config_filter = rt2500pci_config_filter, |
1868 | .config_bssid = rt2500pci_config_bssid, | 1900 | .config_intf = rt2500pci_config_intf, |
1869 | .config_type = rt2500pci_config_type, | 1901 | .config_erp = rt2500pci_config_erp, |
1870 | .config_preamble = rt2500pci_config_preamble, | ||
1871 | .config = rt2500pci_config, | 1902 | .config = rt2500pci_config, |
1872 | }; | 1903 | }; |
1873 | 1904 | ||
1905 | static const struct data_queue_desc rt2500pci_queue_rx = { | ||
1906 | .entry_num = RX_ENTRIES, | ||
1907 | .data_size = DATA_FRAME_SIZE, | ||
1908 | .desc_size = RXD_DESC_SIZE, | ||
1909 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
1910 | }; | ||
1911 | |||
1912 | static const struct data_queue_desc rt2500pci_queue_tx = { | ||
1913 | .entry_num = TX_ENTRIES, | ||
1914 | .data_size = DATA_FRAME_SIZE, | ||
1915 | .desc_size = TXD_DESC_SIZE, | ||
1916 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1917 | }; | ||
1918 | |||
1919 | static const struct data_queue_desc rt2500pci_queue_bcn = { | ||
1920 | .entry_num = BEACON_ENTRIES, | ||
1921 | .data_size = MGMT_FRAME_SIZE, | ||
1922 | .desc_size = TXD_DESC_SIZE, | ||
1923 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1924 | }; | ||
1925 | |||
1926 | static const struct data_queue_desc rt2500pci_queue_atim = { | ||
1927 | .entry_num = ATIM_ENTRIES, | ||
1928 | .data_size = DATA_FRAME_SIZE, | ||
1929 | .desc_size = TXD_DESC_SIZE, | ||
1930 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1931 | }; | ||
1932 | |||
1874 | static const struct rt2x00_ops rt2500pci_ops = { | 1933 | static const struct rt2x00_ops rt2500pci_ops = { |
1875 | .name = KBUILD_MODNAME, | 1934 | .name = KBUILD_MODNAME, |
1876 | .rxd_size = RXD_DESC_SIZE, | 1935 | .max_sta_intf = 1, |
1877 | .txd_size = TXD_DESC_SIZE, | 1936 | .max_ap_intf = 1, |
1878 | .eeprom_size = EEPROM_SIZE, | 1937 | .eeprom_size = EEPROM_SIZE, |
1879 | .rf_size = RF_SIZE, | 1938 | .rf_size = RF_SIZE, |
1939 | .rx = &rt2500pci_queue_rx, | ||
1940 | .tx = &rt2500pci_queue_tx, | ||
1941 | .bcn = &rt2500pci_queue_bcn, | ||
1942 | .atim = &rt2500pci_queue_atim, | ||
1880 | .lib = &rt2500pci_rt2x00_ops, | 1943 | .lib = &rt2500pci_rt2x00_ops, |
1881 | .hw = &rt2500pci_mac80211_ops, | 1944 | .hw = &rt2500pci_mac80211_ops, |
1882 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1945 | #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..6bb07b339325 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,136 @@ 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_brightness_set(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 | u16 reg; | ||
294 | 293 | ||
295 | static void rt2500usb_config_bssid(struct rt2x00_dev *rt2x00dev, | 294 | rt2500usb_register_read(led->rt2x00dev, MAC_CSR20, ®); |
296 | __le32 *bssid) | 295 | |
297 | { | 296 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) |
298 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, bssid, | 297 | rt2x00_set_field16(®, MAC_CSR20_LINK, enabled); |
299 | (3 * sizeof(__le16))); | 298 | else if (led->type == LED_TYPE_ACTIVITY) |
299 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, enabled); | ||
300 | |||
301 | rt2500usb_register_write(led->rt2x00dev, MAC_CSR20, reg); | ||
300 | } | 302 | } |
301 | 303 | ||
302 | static void rt2500usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 304 | static int rt2500usb_blink_set(struct led_classdev *led_cdev, |
303 | const int tsf_sync) | 305 | unsigned long *delay_on, |
306 | unsigned long *delay_off) | ||
304 | { | 307 | { |
308 | struct rt2x00_led *led = | ||
309 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
305 | u16 reg; | 310 | u16 reg; |
306 | 311 | ||
307 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | 312 | rt2500usb_register_read(led->rt2x00dev, MAC_CSR21, ®); |
313 | rt2x00_set_field16(®, MAC_CSR21_ON_PERIOD, *delay_on); | ||
314 | rt2x00_set_field16(®, MAC_CSR21_OFF_PERIOD, *delay_off); | ||
315 | rt2500usb_register_write(led->rt2x00dev, MAC_CSR21, reg); | ||
308 | 316 | ||
309 | /* | 317 | return 0; |
310 | * Enable beacon config | 318 | } |
311 | */ | 319 | #endif /* CONFIG_RT2500USB_LEDS */ |
312 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); | 320 | |
313 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, | 321 | /* |
314 | (PREAMBLE + get_duration(IEEE80211_HEADER, 20)) >> 6); | 322 | * Configuration handlers. |
315 | if (type == IEEE80211_IF_TYPE_STA) | 323 | */ |
316 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 0); | 324 | static void rt2500usb_config_filter(struct rt2x00_dev *rt2x00dev, |
317 | else | 325 | const unsigned int filter_flags) |
318 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 2); | 326 | { |
319 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); | 327 | u16 reg; |
320 | 328 | ||
321 | /* | 329 | /* |
322 | * Enable synchronisation. | 330 | * Start configuration steps. |
331 | * Note that the version error will always be dropped | ||
332 | * and broadcast frames will always be accepted since | ||
333 | * there is no filter for it at this time. | ||
323 | */ | 334 | */ |
324 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | 335 | rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); |
325 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); | 336 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CRC, |
326 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | 337 | !(filter_flags & FIF_FCSFAIL)); |
327 | 338 | rt2x00_set_field16(®, TXRX_CSR2_DROP_PHYSICAL, | |
328 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 339 | !(filter_flags & FIF_PLCPFAIL)); |
329 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | 340 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, |
330 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, | 341 | !(filter_flags & FIF_CONTROL)); |
331 | (tsf_sync == TSF_SYNC_BEACON)); | 342 | rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME, |
332 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | 343 | !(filter_flags & FIF_PROMISC_IN_BSS)); |
333 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, tsf_sync); | 344 | rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, |
334 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | 345 | !(filter_flags & FIF_PROMISC_IN_BSS) && |
346 | !rt2x00dev->intf_ap_count); | ||
347 | rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 1); | ||
348 | rt2x00_set_field16(®, TXRX_CSR2_DROP_MULTICAST, | ||
349 | !(filter_flags & FIF_ALLMULTI)); | ||
350 | rt2x00_set_field16(®, TXRX_CSR2_DROP_BROADCAST, 0); | ||
351 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
335 | } | 352 | } |
336 | 353 | ||
337 | static void rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 354 | static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 355 | struct rt2x00_intf *intf, |
339 | const int ack_timeout, | 356 | struct rt2x00intf_conf *conf, |
340 | const int ack_consume_time) | 357 | const unsigned int flags) |
341 | { | 358 | { |
359 | unsigned int bcn_preload; | ||
342 | u16 reg; | 360 | u16 reg; |
343 | 361 | ||
344 | /* | 362 | if (flags & CONFIG_UPDATE_TYPE) { |
345 | * When in atomic context, reschedule and let rt2x00lib | 363 | /* |
346 | * call this function again. | 364 | * Enable beacon config |
347 | */ | 365 | */ |
348 | if (in_atomic()) { | 366 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 367 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); |
350 | return; | 368 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, bcn_preload >> 6); |
369 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, | ||
370 | 2 * (conf->type != IEEE80211_IF_TYPE_STA)); | ||
371 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); | ||
372 | |||
373 | /* | ||
374 | * Enable synchronisation. | ||
375 | */ | ||
376 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | ||
377 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); | ||
378 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | ||
379 | |||
380 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
381 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
382 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync); | ||
383 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); | ||
384 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
351 | } | 385 | } |
352 | 386 | ||
387 | if (flags & CONFIG_UPDATE_MAC) | ||
388 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, conf->mac, | ||
389 | (3 * sizeof(__le16))); | ||
390 | |||
391 | if (flags & CONFIG_UPDATE_BSSID) | ||
392 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, conf->bssid, | ||
393 | (3 * sizeof(__le16))); | ||
394 | } | ||
395 | |||
396 | static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, | ||
397 | struct rt2x00lib_erp *erp) | ||
398 | { | ||
399 | u16 reg; | ||
400 | |||
353 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); | 401 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); |
354 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, ack_timeout); | 402 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, erp->ack_timeout); |
355 | rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg); | 403 | rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg); |
356 | 404 | ||
357 | rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); | 405 | rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); |
358 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, | 406 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 407 | !!erp->short_preamble); |
360 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); | 408 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); |
361 | } | 409 | } |
362 | 410 | ||
363 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 411 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
364 | const int phymode, | ||
365 | const int basic_rate_mask) | 412 | const int basic_rate_mask) |
366 | { | 413 | { |
367 | rt2500usb_register_write(rt2x00dev, TXRX_CSR11, basic_rate_mask); | 414 | 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 | } | 415 | } |
377 | 416 | ||
378 | static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev, | 417 | static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev, |
@@ -424,6 +463,13 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
424 | u16 csr5; | 463 | u16 csr5; |
425 | u16 csr6; | 464 | u16 csr6; |
426 | 465 | ||
466 | /* | ||
467 | * We should never come here because rt2x00lib is supposed | ||
468 | * to catch this and send us the correct antenna explicitely. | ||
469 | */ | ||
470 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
471 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
472 | |||
427 | rt2500usb_bbp_read(rt2x00dev, 2, &r2); | 473 | rt2500usb_bbp_read(rt2x00dev, 2, &r2); |
428 | rt2500usb_bbp_read(rt2x00dev, 14, &r14); | 474 | rt2500usb_bbp_read(rt2x00dev, 14, &r14); |
429 | rt2500usb_register_read(rt2x00dev, PHY_CSR5, &csr5); | 475 | rt2500usb_register_read(rt2x00dev, PHY_CSR5, &csr5); |
@@ -443,14 +489,8 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
443 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 0); | 489 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 0); |
444 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 0); | 490 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 0); |
445 | break; | 491 | 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: | 492 | case ANTENNA_B: |
493 | default: | ||
454 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); | 494 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); |
455 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 2); | 495 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 2); |
456 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 2); | 496 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 2); |
@@ -467,14 +507,8 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
467 | case ANTENNA_A: | 507 | case ANTENNA_A: |
468 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); | 508 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); |
469 | break; | 509 | 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: | 510 | case ANTENNA_B: |
511 | default: | ||
478 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); | 512 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); |
479 | break; | 513 | break; |
480 | } | 514 | } |
@@ -510,6 +544,8 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
510 | u16 reg; | 544 | u16 reg; |
511 | 545 | ||
512 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, libconf->slot_time); | 546 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, libconf->slot_time); |
547 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, libconf->sifs); | ||
548 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, libconf->eifs); | ||
513 | 549 | ||
514 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | 550 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); |
515 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, | 551 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, |
@@ -518,12 +554,11 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
518 | } | 554 | } |
519 | 555 | ||
520 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | 556 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, |
521 | const unsigned int flags, | 557 | struct rt2x00lib_conf *libconf, |
522 | struct rt2x00lib_conf *libconf) | 558 | const unsigned int flags) |
523 | { | 559 | { |
524 | if (flags & CONFIG_UPDATE_PHYMODE) | 560 | if (flags & CONFIG_UPDATE_PHYMODE) |
525 | rt2500usb_config_phymode(rt2x00dev, libconf->phymode, | 561 | rt2500usb_config_phymode(rt2x00dev, libconf->basic_rates); |
526 | libconf->basic_rates); | ||
527 | if (flags & CONFIG_UPDATE_CHANNEL) | 562 | if (flags & CONFIG_UPDATE_CHANNEL) |
528 | rt2500usb_config_channel(rt2x00dev, &libconf->rf, | 563 | rt2500usb_config_channel(rt2x00dev, &libconf->rf, |
529 | libconf->conf->power_level); | 564 | libconf->conf->power_level); |
@@ -537,36 +572,6 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | |||
537 | } | 572 | } |
538 | 573 | ||
539 | /* | 574 | /* |
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 | 575 | * Link tuning |
571 | */ | 576 | */ |
572 | static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, | 577 | static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -626,6 +631,24 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
626 | u8 low_bound; | 631 | u8 low_bound; |
627 | 632 | ||
628 | /* | 633 | /* |
634 | * Read current r17 value, as well as the sensitivity values | ||
635 | * for the r17 register. | ||
636 | */ | ||
637 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
638 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
639 | |||
640 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
641 | up_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
642 | low_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCLOWER); | ||
643 | |||
644 | /* | ||
645 | * If we are not associated, we should go straight to the | ||
646 | * dynamic CCA tuning. | ||
647 | */ | ||
648 | if (!rt2x00dev->intf_associated) | ||
649 | goto dynamic_cca_tune; | ||
650 | |||
651 | /* | ||
629 | * Determine the BBP tuning threshold and correctly | 652 | * Determine the BBP tuning threshold and correctly |
630 | * set BBP 24, 25 and 61. | 653 | * set BBP 24, 25 and 61. |
631 | */ | 654 | */ |
@@ -651,13 +674,6 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
651 | rt2500usb_bbp_write(rt2x00dev, 61, r61); | 674 | rt2500usb_bbp_write(rt2x00dev, 61, r61); |
652 | 675 | ||
653 | /* | 676 | /* |
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 | 677 | * A too low RSSI will cause too much false CCA which will |
662 | * then corrupt the R17 tuning. To remidy this the tuning should | 678 | * then corrupt the R17 tuning. To remidy this the tuning should |
663 | * be stopped (While making sure the R17 value will not exceed limits) | 679 | * be stopped (While making sure the R17 value will not exceed limits) |
@@ -692,14 +708,9 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
692 | * Leave short or middle distance condition, restore r17 | 708 | * Leave short or middle distance condition, restore r17 |
693 | * to the dynamic tuning range. | 709 | * to the dynamic tuning range. |
694 | */ | 710 | */ |
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; | 711 | low_bound = 0x32; |
699 | if (rssi >= -77) | 712 | if (rssi < -77) |
700 | up_bound = vgc_bound; | 713 | up_bound -= (-77 - rssi); |
701 | else | ||
702 | up_bound = vgc_bound - (-77 - rssi); | ||
703 | 714 | ||
704 | if (up_bound < low_bound) | 715 | if (up_bound < low_bound) |
705 | up_bound = low_bound; | 716 | up_bound = low_bound; |
@@ -707,7 +718,16 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
707 | if (r17 > up_bound) { | 718 | if (r17 > up_bound) { |
708 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); | 719 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); |
709 | rt2x00dev->link.vgc_level = up_bound; | 720 | rt2x00dev->link.vgc_level = up_bound; |
710 | } else if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | 721 | return; |
722 | } | ||
723 | |||
724 | dynamic_cca_tune: | ||
725 | |||
726 | /* | ||
727 | * R17 is inside the dynamic tuning range, | ||
728 | * start tuning the link based on the false cca counter. | ||
729 | */ | ||
730 | if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | ||
711 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); | 731 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); |
712 | rt2x00dev->link.vgc_level = r17; | 732 | rt2x00dev->link.vgc_level = r17; |
713 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { | 733 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { |
@@ -878,19 +898,15 @@ continue_csr_init: | |||
878 | rt2500usb_bbp_write(rt2x00dev, 62, 0x10); | 898 | rt2500usb_bbp_write(rt2x00dev, 62, 0x10); |
879 | rt2500usb_bbp_write(rt2x00dev, 75, 0xff); | 899 | rt2500usb_bbp_write(rt2x00dev, 75, 0xff); |
880 | 900 | ||
881 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
882 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 901 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
883 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 902 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
884 | 903 | ||
885 | if (eeprom != 0xffff && eeprom != 0x0000) { | 904 | if (eeprom != 0xffff && eeprom != 0x0000) { |
886 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 905 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
887 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 906 | 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); | 907 | rt2500usb_bbp_write(rt2x00dev, reg_id, value); |
891 | } | 908 | } |
892 | } | 909 | } |
893 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
894 | 910 | ||
895 | return 0; | 911 | return 0; |
896 | } | 912 | } |
@@ -920,21 +936,11 @@ static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
920 | return -EIO; | 936 | return -EIO; |
921 | } | 937 | } |
922 | 938 | ||
923 | /* | ||
924 | * Enable LED | ||
925 | */ | ||
926 | rt2500usb_enable_led(rt2x00dev); | ||
927 | |||
928 | return 0; | 939 | return 0; |
929 | } | 940 | } |
930 | 941 | ||
931 | static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 942 | static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
932 | { | 943 | { |
933 | /* | ||
934 | * Disable LED | ||
935 | */ | ||
936 | rt2500usb_disable_led(rt2x00dev); | ||
937 | |||
938 | rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121); | 944 | rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121); |
939 | rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121); | 945 | rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121); |
940 | 946 | ||
@@ -1027,10 +1033,10 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1027 | */ | 1033 | */ |
1028 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1034 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1029 | struct sk_buff *skb, | 1035 | struct sk_buff *skb, |
1030 | struct txdata_entry_desc *desc, | 1036 | struct txentry_desc *txdesc, |
1031 | struct ieee80211_tx_control *control) | 1037 | struct ieee80211_tx_control *control) |
1032 | { | 1038 | { |
1033 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1039 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1034 | __le32 *txd = skbdesc->desc; | 1040 | __le32 *txd = skbdesc->desc; |
1035 | u32 word; | 1041 | u32 word; |
1036 | 1042 | ||
@@ -1039,31 +1045,31 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1039 | */ | 1045 | */ |
1040 | rt2x00_desc_read(txd, 1, &word); | 1046 | rt2x00_desc_read(txd, 1, &word); |
1041 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1047 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1042 | rt2x00_set_field32(&word, TXD_W1_AIFS, desc->aifs); | 1048 | rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); |
1043 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1049 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1044 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1050 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1045 | rt2x00_desc_write(txd, 1, word); | 1051 | rt2x00_desc_write(txd, 1, word); |
1046 | 1052 | ||
1047 | rt2x00_desc_read(txd, 2, &word); | 1053 | rt2x00_desc_read(txd, 2, &word); |
1048 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1054 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1049 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1055 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1050 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1056 | 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); | 1057 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1052 | rt2x00_desc_write(txd, 2, word); | 1058 | rt2x00_desc_write(txd, 2, word); |
1053 | 1059 | ||
1054 | rt2x00_desc_read(txd, 0, &word); | 1060 | rt2x00_desc_read(txd, 0, &word); |
1055 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit); | 1061 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit); |
1056 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1062 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1057 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1063 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1058 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1064 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1059 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1065 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1060 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1066 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1061 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1067 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1062 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1068 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1063 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1069 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1064 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, | 1070 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, |
1065 | !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)); | 1071 | !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)); |
1066 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1072 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1067 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1073 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1068 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); | 1074 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); |
1069 | rt2x00_desc_write(txd, 0, word); | 1075 | rt2x00_desc_write(txd, 0, word); |
@@ -1088,15 +1094,17 @@ static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1088 | * TX data initialization | 1094 | * TX data initialization |
1089 | */ | 1095 | */ |
1090 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1096 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1091 | unsigned int queue) | 1097 | const unsigned int queue) |
1092 | { | 1098 | { |
1093 | u16 reg; | 1099 | u16 reg; |
1094 | 1100 | ||
1095 | if (queue != IEEE80211_TX_QUEUE_BEACON) | 1101 | if (queue != RT2X00_BCN_QUEUE_BEACON) |
1096 | return; | 1102 | return; |
1097 | 1103 | ||
1098 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 1104 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
1099 | if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { | 1105 | if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { |
1106 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
1107 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); | ||
1100 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); | 1108 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); |
1101 | /* | 1109 | /* |
1102 | * Beacon generation will fail initially. | 1110 | * Beacon generation will fail initially. |
@@ -1114,42 +1122,68 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1114 | /* | 1122 | /* |
1115 | * RX control handlers | 1123 | * RX control handlers |
1116 | */ | 1124 | */ |
1117 | static void rt2500usb_fill_rxdone(struct data_entry *entry, | 1125 | static void rt2500usb_fill_rxdone(struct queue_entry *entry, |
1118 | struct rxdata_entry_desc *desc) | 1126 | struct rxdone_entry_desc *rxdesc) |
1119 | { | 1127 | { |
1120 | struct skb_desc *skbdesc = get_skb_desc(entry->skb); | 1128 | struct queue_entry_priv_usb_rx *priv_rx = entry->priv_data; |
1121 | struct urb *urb = entry->priv; | 1129 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1122 | __le32 *rxd = (__le32 *)(entry->skb->data + | 1130 | __le32 *rxd = |
1123 | (urb->actual_length - entry->ring->desc_size)); | 1131 | (__le32 *)(entry->skb->data + |
1132 | (priv_rx->urb->actual_length - entry->queue->desc_size)); | ||
1133 | unsigned int offset = entry->queue->desc_size + 2; | ||
1124 | u32 word0; | 1134 | u32 word0; |
1125 | u32 word1; | 1135 | u32 word1; |
1126 | 1136 | ||
1137 | /* | ||
1138 | * Copy descriptor to the available headroom inside the skbuffer. | ||
1139 | */ | ||
1140 | skb_push(entry->skb, offset); | ||
1141 | memcpy(entry->skb->data, rxd, entry->queue->desc_size); | ||
1142 | rxd = (__le32 *)entry->skb->data; | ||
1143 | |||
1144 | /* | ||
1145 | * The descriptor is now aligned to 4 bytes and thus it is | ||
1146 | * now safe to read it on all architectures. | ||
1147 | */ | ||
1127 | rt2x00_desc_read(rxd, 0, &word0); | 1148 | rt2x00_desc_read(rxd, 0, &word0); |
1128 | rt2x00_desc_read(rxd, 1, &word1); | 1149 | rt2x00_desc_read(rxd, 1, &word1); |
1129 | 1150 | ||
1130 | desc->flags = 0; | 1151 | rxdesc->flags = 0; |
1131 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1152 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1132 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1153 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1133 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1154 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1134 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1155 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1135 | 1156 | ||
1136 | /* | 1157 | /* |
1137 | * Obtain the status about this packet. | 1158 | * Obtain the status about this packet. |
1159 | * When frame was received with an OFDM bitrate, | ||
1160 | * the signal is the PLCP value. If it was received with | ||
1161 | * a CCK bitrate the signal is the rate in 100kbit/s. | ||
1162 | */ | ||
1163 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | ||
1164 | rxdesc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - | ||
1165 | entry->queue->rt2x00dev->rssi_offset; | ||
1166 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
1167 | |||
1168 | rxdesc->dev_flags = 0; | ||
1169 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | ||
1170 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; | ||
1171 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | ||
1172 | rxdesc->dev_flags |= RXDONE_MY_BSS; | ||
1173 | |||
1174 | /* | ||
1175 | * Adjust the skb memory window to the frame boundaries. | ||
1138 | */ | 1176 | */ |
1139 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1177 | skb_pull(entry->skb, offset); |
1140 | desc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - | 1178 | skb_trim(entry->skb, rxdesc->size); |
1141 | entry->ring->rt2x00dev->rssi_offset; | ||
1142 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | ||
1143 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
1144 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | ||
1145 | 1179 | ||
1146 | /* | 1180 | /* |
1147 | * Set descriptor and data pointer. | 1181 | * Set descriptor and data pointer. |
1148 | */ | 1182 | */ |
1149 | skbdesc->desc = entry->skb->data + desc->size; | ||
1150 | skbdesc->desc_len = entry->ring->desc_size; | ||
1151 | skbdesc->data = entry->skb->data; | 1183 | skbdesc->data = entry->skb->data; |
1152 | skbdesc->data_len = desc->size; | 1184 | skbdesc->data_len = rxdesc->size; |
1185 | skbdesc->desc = rxd; | ||
1186 | skbdesc->desc_len = entry->queue->desc_size; | ||
1153 | } | 1187 | } |
1154 | 1188 | ||
1155 | /* | 1189 | /* |
@@ -1157,10 +1191,10 @@ static void rt2500usb_fill_rxdone(struct data_entry *entry, | |||
1157 | */ | 1191 | */ |
1158 | static void rt2500usb_beacondone(struct urb *urb) | 1192 | static void rt2500usb_beacondone(struct urb *urb) |
1159 | { | 1193 | { |
1160 | struct data_entry *entry = (struct data_entry *)urb->context; | 1194 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
1161 | struct data_ring *ring = entry->ring; | 1195 | struct queue_entry_priv_usb_bcn *priv_bcn = entry->priv_data; |
1162 | 1196 | ||
1163 | if (!test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) | 1197 | if (!test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) |
1164 | return; | 1198 | return; |
1165 | 1199 | ||
1166 | /* | 1200 | /* |
@@ -1169,18 +1203,11 @@ static void rt2500usb_beacondone(struct urb *urb) | |||
1169 | * Otherwise we should free the sk_buffer, the device | 1203 | * Otherwise we should free the sk_buffer, the device |
1170 | * should be doing the rest of the work now. | 1204 | * should be doing the rest of the work now. |
1171 | */ | 1205 | */ |
1172 | if (ring->index == 1) { | 1206 | if (priv_bcn->guardian_urb == urb) { |
1173 | rt2x00_ring_index_done_inc(ring); | 1207 | usb_submit_urb(priv_bcn->urb, GFP_ATOMIC); |
1174 | entry = rt2x00_get_data_entry(ring); | 1208 | } else if (priv_bcn->urb == urb) { |
1175 | usb_submit_urb(entry->priv, GFP_ATOMIC); | 1209 | dev_kfree_skb(entry->skb); |
1176 | rt2x00_ring_index_inc(ring); | 1210 | 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 | } | 1211 | } |
1185 | } | 1212 | } |
1186 | 1213 | ||
@@ -1191,6 +1218,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1191 | { | 1218 | { |
1192 | u16 word; | 1219 | u16 word; |
1193 | u8 *mac; | 1220 | u8 *mac; |
1221 | u8 bbp; | ||
1194 | 1222 | ||
1195 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); | 1223 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); |
1196 | 1224 | ||
@@ -1245,9 +1273,17 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1245 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); | 1273 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); |
1246 | } | 1274 | } |
1247 | 1275 | ||
1276 | /* | ||
1277 | * Switch lower vgc bound to current BBP R17 value, | ||
1278 | * lower the value a bit for better quality. | ||
1279 | */ | ||
1280 | rt2500usb_bbp_read(rt2x00dev, 17, &bbp); | ||
1281 | bbp -= 6; | ||
1282 | |||
1248 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); | 1283 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); |
1249 | if (word == 0xffff) { | 1284 | if (word == 0xffff) { |
1250 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); | 1285 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); |
1286 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | ||
1251 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | 1287 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); |
1252 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); | 1288 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); |
1253 | } | 1289 | } |
@@ -1258,6 +1294,9 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1258 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); | 1294 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); |
1259 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); | 1295 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); |
1260 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); | 1296 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); |
1297 | } else { | ||
1298 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | ||
1299 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | ||
1261 | } | 1300 | } |
1262 | 1301 | ||
1263 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); | 1302 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); |
@@ -1342,8 +1381,27 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1342 | /* | 1381 | /* |
1343 | * Store led mode, for correct led behaviour. | 1382 | * Store led mode, for correct led behaviour. |
1344 | */ | 1383 | */ |
1345 | rt2x00dev->led_mode = | 1384 | #ifdef CONFIG_RT2500USB_LEDS |
1346 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1385 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1386 | |||
1387 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | ||
1388 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | ||
1389 | rt2x00dev->led_radio.led_dev.brightness_set = | ||
1390 | rt2500usb_brightness_set; | ||
1391 | rt2x00dev->led_radio.led_dev.blink_set = | ||
1392 | rt2500usb_blink_set; | ||
1393 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
1394 | |||
1395 | if (value == LED_MODE_TXRX_ACTIVITY) { | ||
1396 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
1397 | rt2x00dev->led_radio.type = LED_TYPE_ACTIVITY; | ||
1398 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
1399 | rt2500usb_brightness_set; | ||
1400 | rt2x00dev->led_qual.led_dev.blink_set = | ||
1401 | rt2500usb_blink_set; | ||
1402 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
1403 | } | ||
1404 | #endif /* CONFIG_RT2500USB_LEDS */ | ||
1347 | 1405 | ||
1348 | /* | 1406 | /* |
1349 | * Check if the BBP tuning should be disabled. | 1407 | * Check if the BBP tuning should be disabled. |
@@ -1550,8 +1608,8 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1550 | /* | 1608 | /* |
1551 | * Initialize hw_mode information. | 1609 | * Initialize hw_mode information. |
1552 | */ | 1610 | */ |
1553 | spec->num_modes = 2; | 1611 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1554 | spec->num_rates = 12; | 1612 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1555 | spec->tx_power_a = NULL; | 1613 | spec->tx_power_a = NULL; |
1556 | spec->tx_power_bg = txpower; | 1614 | spec->tx_power_bg = txpower; |
1557 | spec->tx_power_default = DEFAULT_TXPOWER; | 1615 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1572,9 +1630,9 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1572 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | 1630 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); |
1573 | spec->channels = rf_vals_bg_2525e; | 1631 | spec->channels = rf_vals_bg_2525e; |
1574 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | 1632 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { |
1633 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1575 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | 1634 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); |
1576 | spec->channels = rf_vals_5222; | 1635 | spec->channels = rf_vals_5222; |
1577 | spec->num_modes = 3; | ||
1578 | } | 1636 | } |
1579 | } | 1637 | } |
1580 | 1638 | ||
@@ -1599,9 +1657,11 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1599 | rt2500usb_probe_hw_mode(rt2x00dev); | 1657 | rt2500usb_probe_hw_mode(rt2x00dev); |
1600 | 1658 | ||
1601 | /* | 1659 | /* |
1602 | * This device requires the beacon ring | 1660 | * This device requires the atim queue |
1603 | */ | 1661 | */ |
1604 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1662 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1663 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | ||
1664 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); | ||
1605 | 1665 | ||
1606 | /* | 1666 | /* |
1607 | * Set the rssi offset. | 1667 | * Set the rssi offset. |
@@ -1614,125 +1674,58 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1614 | /* | 1674 | /* |
1615 | * IEEE80211 stack callback functions. | 1675 | * IEEE80211 stack callback functions. |
1616 | */ | 1676 | */ |
1617 | static void rt2500usb_configure_filter(struct ieee80211_hw *hw, | ||
1618 | unsigned int changed_flags, | ||
1619 | unsigned int *total_flags, | ||
1620 | int mc_count, | ||
1621 | struct dev_addr_list *mc_list) | ||
1622 | { | ||
1623 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1624 | u16 reg; | ||
1625 | |||
1626 | /* | ||
1627 | * Mask off any flags we are going to ignore from | ||
1628 | * the total_flags field. | ||
1629 | */ | ||
1630 | *total_flags &= | ||
1631 | FIF_ALLMULTI | | ||
1632 | FIF_FCSFAIL | | ||
1633 | FIF_PLCPFAIL | | ||
1634 | FIF_CONTROL | | ||
1635 | FIF_OTHER_BSS | | ||
1636 | FIF_PROMISC_IN_BSS; | ||
1637 | |||
1638 | /* | ||
1639 | * Apply some rules to the filters: | ||
1640 | * - Some filters imply different filters to be set. | ||
1641 | * - Some things we can't filter out at all. | ||
1642 | */ | ||
1643 | if (mc_count) | ||
1644 | *total_flags |= FIF_ALLMULTI; | ||
1645 | if (*total_flags & FIF_OTHER_BSS || | ||
1646 | *total_flags & FIF_PROMISC_IN_BSS) | ||
1647 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
1648 | |||
1649 | /* | ||
1650 | * Check if there is any work left for us. | ||
1651 | */ | ||
1652 | if (rt2x00dev->packet_filter == *total_flags) | ||
1653 | return; | ||
1654 | rt2x00dev->packet_filter = *total_flags; | ||
1655 | |||
1656 | /* | ||
1657 | * When in atomic context, reschedule and let rt2x00lib | ||
1658 | * call this function again. | ||
1659 | */ | ||
1660 | if (in_atomic()) { | ||
1661 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); | ||
1662 | return; | ||
1663 | } | ||
1664 | |||
1665 | /* | ||
1666 | * Start configuration steps. | ||
1667 | * Note that the version error will always be dropped | ||
1668 | * and broadcast frames will always be accepted since | ||
1669 | * there is no filter for it at this time. | ||
1670 | */ | ||
1671 | rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); | ||
1672 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CRC, | ||
1673 | !(*total_flags & FIF_FCSFAIL)); | ||
1674 | rt2x00_set_field16(®, TXRX_CSR2_DROP_PHYSICAL, | ||
1675 | !(*total_flags & FIF_PLCPFAIL)); | ||
1676 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, | ||
1677 | !(*total_flags & FIF_CONTROL)); | ||
1678 | rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME, | ||
1679 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1680 | rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, | ||
1681 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1682 | rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 1); | ||
1683 | rt2x00_set_field16(®, TXRX_CSR2_DROP_MULTICAST, | ||
1684 | !(*total_flags & FIF_ALLMULTI)); | ||
1685 | rt2x00_set_field16(®, TXRX_CSR2_DROP_BROADCAST, 0); | ||
1686 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
1687 | } | ||
1688 | |||
1689 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | 1677 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, |
1690 | struct sk_buff *skb, | 1678 | struct sk_buff *skb, |
1691 | struct ieee80211_tx_control *control) | 1679 | struct ieee80211_tx_control *control) |
1692 | { | 1680 | { |
1693 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1681 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1694 | struct usb_device *usb_dev = | 1682 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
1695 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | 1683 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1696 | struct skb_desc *desc; | 1684 | struct queue_entry_priv_usb_bcn *priv_bcn; |
1697 | struct data_ring *ring; | 1685 | struct skb_frame_desc *skbdesc; |
1698 | struct data_entry *beacon; | ||
1699 | struct data_entry *guardian; | ||
1700 | int pipe = usb_sndbulkpipe(usb_dev, 1); | 1686 | int pipe = usb_sndbulkpipe(usb_dev, 1); |
1701 | int length; | 1687 | int length; |
1688 | u16 reg; | ||
1689 | |||
1690 | if (unlikely(!intf->beacon)) | ||
1691 | return -ENOBUFS; | ||
1692 | |||
1693 | priv_bcn = intf->beacon->priv_data; | ||
1702 | 1694 | ||
1703 | /* | 1695 | /* |
1704 | * Just in case the ieee80211 doesn't set this, | 1696 | * Add the descriptor in front of the skb. |
1705 | * but we need this queue set for the descriptor | ||
1706 | * initialization. | ||
1707 | */ | 1697 | */ |
1708 | control->queue = IEEE80211_TX_QUEUE_BEACON; | 1698 | skb_push(skb, intf->beacon->queue->desc_size); |
1709 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | 1699 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
1710 | 1700 | ||
1711 | /* | 1701 | /* |
1712 | * Obtain 2 entries, one for the guardian byte, | 1702 | * Fill in skb descriptor |
1713 | * the second for the actual beacon. | ||
1714 | */ | 1703 | */ |
1715 | guardian = rt2x00_get_data_entry(ring); | 1704 | skbdesc = get_skb_frame_desc(skb); |
1716 | rt2x00_ring_index_inc(ring); | 1705 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1717 | beacon = rt2x00_get_data_entry(ring); | 1706 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
1707 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; | ||
1708 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; | ||
1709 | skbdesc->desc = skb->data; | ||
1710 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1711 | skbdesc->entry = intf->beacon; | ||
1718 | 1712 | ||
1719 | /* | 1713 | /* |
1720 | * Add the descriptor in front of the skb. | 1714 | * Disable beaconing while we are reloading the beacon data, |
1715 | * otherwise we might be sending out invalid data. | ||
1721 | */ | 1716 | */ |
1722 | skb_push(skb, ring->desc_size); | 1717 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
1723 | memset(skb->data, 0, ring->desc_size); | 1718 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); |
1719 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); | ||
1720 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
1721 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
1724 | 1722 | ||
1725 | /* | 1723 | /* |
1726 | * Fill in skb descriptor | 1724 | * mac80211 doesn't provide the control->queue variable |
1725 | * for beacons. Set our own queue identification so | ||
1726 | * it can be used during descriptor initialization. | ||
1727 | */ | 1727 | */ |
1728 | desc = get_skb_desc(skb); | 1728 | 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); | 1729 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
1737 | 1730 | ||
1738 | /* | 1731 | /* |
@@ -1742,27 +1735,29 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1742 | */ | 1735 | */ |
1743 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); | 1736 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); |
1744 | 1737 | ||
1745 | usb_fill_bulk_urb(beacon->priv, usb_dev, pipe, | 1738 | usb_fill_bulk_urb(priv_bcn->urb, usb_dev, pipe, |
1746 | skb->data, length, rt2500usb_beacondone, beacon); | 1739 | skb->data, length, rt2500usb_beacondone, |
1740 | intf->beacon); | ||
1747 | 1741 | ||
1748 | /* | 1742 | /* |
1749 | * Second we need to create the guardian byte. | 1743 | * Second we need to create the guardian byte. |
1750 | * We only need a single byte, so lets recycle | 1744 | * We only need a single byte, so lets recycle |
1751 | * the 'flags' field we are not using for beacons. | 1745 | * the 'flags' field we are not using for beacons. |
1752 | */ | 1746 | */ |
1753 | guardian->flags = 0; | 1747 | priv_bcn->guardian_data = 0; |
1754 | usb_fill_bulk_urb(guardian->priv, usb_dev, pipe, | 1748 | usb_fill_bulk_urb(priv_bcn->guardian_urb, usb_dev, pipe, |
1755 | &guardian->flags, 1, rt2500usb_beacondone, guardian); | 1749 | &priv_bcn->guardian_data, 1, rt2500usb_beacondone, |
1750 | intf->beacon); | ||
1756 | 1751 | ||
1757 | /* | 1752 | /* |
1758 | * Send out the guardian byte. | 1753 | * Send out the guardian byte. |
1759 | */ | 1754 | */ |
1760 | usb_submit_urb(guardian->priv, GFP_ATOMIC); | 1755 | usb_submit_urb(priv_bcn->guardian_urb, GFP_ATOMIC); |
1761 | 1756 | ||
1762 | /* | 1757 | /* |
1763 | * Enable beacon generation. | 1758 | * Enable beacon generation. |
1764 | */ | 1759 | */ |
1765 | rt2500usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 1760 | rt2500usb_kick_tx_queue(rt2x00dev, control->queue); |
1766 | 1761 | ||
1767 | return 0; | 1762 | return 0; |
1768 | } | 1763 | } |
@@ -1775,7 +1770,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { | |||
1775 | .remove_interface = rt2x00mac_remove_interface, | 1770 | .remove_interface = rt2x00mac_remove_interface, |
1776 | .config = rt2x00mac_config, | 1771 | .config = rt2x00mac_config, |
1777 | .config_interface = rt2x00mac_config_interface, | 1772 | .config_interface = rt2x00mac_config_interface, |
1778 | .configure_filter = rt2500usb_configure_filter, | 1773 | .configure_filter = rt2x00mac_configure_filter, |
1779 | .get_stats = rt2x00mac_get_stats, | 1774 | .get_stats = rt2x00mac_get_stats, |
1780 | .bss_info_changed = rt2x00mac_bss_info_changed, | 1775 | .bss_info_changed = rt2x00mac_bss_info_changed, |
1781 | .conf_tx = rt2x00mac_conf_tx, | 1776 | .conf_tx = rt2x00mac_conf_tx, |
@@ -1798,19 +1793,50 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1798 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1793 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1799 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1794 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1800 | .fill_rxdone = rt2500usb_fill_rxdone, | 1795 | .fill_rxdone = rt2500usb_fill_rxdone, |
1801 | .config_mac_addr = rt2500usb_config_mac_addr, | 1796 | .config_filter = rt2500usb_config_filter, |
1802 | .config_bssid = rt2500usb_config_bssid, | 1797 | .config_intf = rt2500usb_config_intf, |
1803 | .config_type = rt2500usb_config_type, | 1798 | .config_erp = rt2500usb_config_erp, |
1804 | .config_preamble = rt2500usb_config_preamble, | ||
1805 | .config = rt2500usb_config, | 1799 | .config = rt2500usb_config, |
1806 | }; | 1800 | }; |
1807 | 1801 | ||
1802 | static const struct data_queue_desc rt2500usb_queue_rx = { | ||
1803 | .entry_num = RX_ENTRIES, | ||
1804 | .data_size = DATA_FRAME_SIZE, | ||
1805 | .desc_size = RXD_DESC_SIZE, | ||
1806 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | ||
1807 | }; | ||
1808 | |||
1809 | static const struct data_queue_desc rt2500usb_queue_tx = { | ||
1810 | .entry_num = TX_ENTRIES, | ||
1811 | .data_size = DATA_FRAME_SIZE, | ||
1812 | .desc_size = TXD_DESC_SIZE, | ||
1813 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
1814 | }; | ||
1815 | |||
1816 | static const struct data_queue_desc rt2500usb_queue_bcn = { | ||
1817 | .entry_num = BEACON_ENTRIES, | ||
1818 | .data_size = MGMT_FRAME_SIZE, | ||
1819 | .desc_size = TXD_DESC_SIZE, | ||
1820 | .priv_size = sizeof(struct queue_entry_priv_usb_bcn), | ||
1821 | }; | ||
1822 | |||
1823 | static const struct data_queue_desc rt2500usb_queue_atim = { | ||
1824 | .entry_num = ATIM_ENTRIES, | ||
1825 | .data_size = DATA_FRAME_SIZE, | ||
1826 | .desc_size = TXD_DESC_SIZE, | ||
1827 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
1828 | }; | ||
1829 | |||
1808 | static const struct rt2x00_ops rt2500usb_ops = { | 1830 | static const struct rt2x00_ops rt2500usb_ops = { |
1809 | .name = KBUILD_MODNAME, | 1831 | .name = KBUILD_MODNAME, |
1810 | .rxd_size = RXD_DESC_SIZE, | 1832 | .max_sta_intf = 1, |
1811 | .txd_size = TXD_DESC_SIZE, | 1833 | .max_ap_intf = 1, |
1812 | .eeprom_size = EEPROM_SIZE, | 1834 | .eeprom_size = EEPROM_SIZE, |
1813 | .rf_size = RF_SIZE, | 1835 | .rf_size = RF_SIZE, |
1836 | .rx = &rt2500usb_queue_rx, | ||
1837 | .tx = &rt2500usb_queue_tx, | ||
1838 | .bcn = &rt2500usb_queue_bcn, | ||
1839 | .atim = &rt2500usb_queue_atim, | ||
1814 | .lib = &rt2500usb_rt2x00_ops, | 1840 | .lib = &rt2500usb_rt2x00_ops, |
1815 | .hw = &rt2500usb_mac80211_ops, | 1841 | .hw = &rt2500usb_mac80211_ops, |
1816 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1842 | #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..57bdc153952f 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,60 @@ 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 | #define DELAYED_LED_ASSOC 0x00000004 | ||
389 | }; | ||
397 | 390 | ||
398 | static inline int is_interface_type(struct interface *intf, int type) | 391 | static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) |
399 | { | 392 | { |
400 | return intf->type == type; | 393 | return (struct rt2x00_intf *)vif->drv_priv; |
401 | } | 394 | } |
402 | 395 | ||
403 | /* | 396 | /** |
397 | * struct hw_mode_spec: Hardware specifications structure | ||
398 | * | ||
404 | * Details about the supported modes, rates and channels | 399 | * Details about the supported modes, rates and channels |
405 | * of a particular chipset. This is used by rt2x00lib | 400 | * of a particular chipset. This is used by rt2x00lib |
406 | * to build the ieee80211_hw_mode array for mac80211. | 401 | * to build the ieee80211_hw_mode array for mac80211. |
402 | * | ||
403 | * @supported_bands: Bitmask contained the supported bands (2.4GHz, 5.2GHz). | ||
404 | * @supported_rates: Rate types which are supported (CCK, OFDM). | ||
405 | * @num_channels: Number of supported channels. This is used as array size | ||
406 | * for @tx_power_a, @tx_power_bg and @channels. | ||
407 | * channels: Device/chipset specific channel values (See &struct rf_channel). | ||
408 | * @tx_power_a: TX power values for all 5.2GHz channels (may be NULL). | ||
409 | * @tx_power_bg: TX power values for all 2.4GHz channels (may be NULL). | ||
410 | * @tx_power_default: Default TX power value to use when either | ||
411 | * @tx_power_a or @tx_power_bg is missing. | ||
407 | */ | 412 | */ |
408 | struct hw_mode_spec { | 413 | struct hw_mode_spec { |
409 | /* | 414 | unsigned int supported_bands; |
410 | * Number of modes, rates and channels. | 415 | #define SUPPORT_BAND_2GHZ 0x00000001 |
411 | */ | 416 | #define SUPPORT_BAND_5GHZ 0x00000002 |
412 | int num_modes; | 417 | |
413 | int num_rates; | 418 | unsigned int supported_rates; |
414 | int num_channels; | 419 | #define SUPPORT_RATE_CCK 0x00000001 |
420 | #define SUPPORT_RATE_OFDM 0x00000002 | ||
421 | |||
422 | unsigned int num_channels; | ||
423 | const struct rf_channel *channels; | ||
415 | 424 | ||
416 | /* | ||
417 | * txpower values. | ||
418 | */ | ||
419 | const u8 *tx_power_a; | 425 | const u8 *tx_power_a; |
420 | const u8 *tx_power_bg; | 426 | const u8 *tx_power_bg; |
421 | u8 tx_power_default; | 427 | u8 tx_power_default; |
422 | |||
423 | /* | ||
424 | * Device/chipset specific value. | ||
425 | */ | ||
426 | const struct rf_channel *channels; | ||
427 | }; | 428 | }; |
428 | 429 | ||
429 | /* | 430 | /* |
@@ -439,10 +440,10 @@ struct rt2x00lib_conf { | |||
439 | 440 | ||
440 | struct antenna_setup ant; | 441 | struct antenna_setup ant; |
441 | 442 | ||
442 | int phymode; | 443 | enum ieee80211_band band; |
443 | 444 | ||
444 | int basic_rates; | 445 | u32 basic_rates; |
445 | int slot_time; | 446 | u32 slot_time; |
446 | 447 | ||
447 | short sifs; | 448 | short sifs; |
448 | short pifs; | 449 | short pifs; |
@@ -451,6 +452,47 @@ struct rt2x00lib_conf { | |||
451 | }; | 452 | }; |
452 | 453 | ||
453 | /* | 454 | /* |
455 | * Configuration structure for erp settings. | ||
456 | */ | ||
457 | struct rt2x00lib_erp { | ||
458 | int short_preamble; | ||
459 | |||
460 | int ack_timeout; | ||
461 | int ack_consume_time; | ||
462 | }; | ||
463 | |||
464 | /* | ||
465 | * Configuration structure wrapper around the | ||
466 | * rt2x00 interface configuration handler. | ||
467 | */ | ||
468 | struct rt2x00intf_conf { | ||
469 | /* | ||
470 | * Interface type | ||
471 | */ | ||
472 | enum ieee80211_if_types type; | ||
473 | |||
474 | /* | ||
475 | * TSF sync value, this is dependant on the operation type. | ||
476 | */ | ||
477 | enum tsf_sync sync; | ||
478 | |||
479 | /* | ||
480 | * The MAC and BSSID addressess are simple array of bytes, | ||
481 | * these arrays are little endian, so when sending the addressess | ||
482 | * to the drivers, copy the it into a endian-signed variable. | ||
483 | * | ||
484 | * Note that all devices (except rt2500usb) have 32 bits | ||
485 | * register word sizes. This means that whatever variable we | ||
486 | * pass _must_ be a multiple of 32 bits. Otherwise the device | ||
487 | * might not accept what we are sending to it. | ||
488 | * This will also make it easier for the driver to write | ||
489 | * the data to the device. | ||
490 | */ | ||
491 | __le32 mac[2]; | ||
492 | __le32 bssid[2]; | ||
493 | }; | ||
494 | |||
495 | /* | ||
454 | * rt2x00lib callback functions. | 496 | * rt2x00lib callback functions. |
455 | */ | 497 | */ |
456 | struct rt2x00lib_ops { | 498 | struct rt2x00lib_ops { |
@@ -464,6 +506,7 @@ struct rt2x00lib_ops { | |||
464 | */ | 506 | */ |
465 | int (*probe_hw) (struct rt2x00_dev *rt2x00dev); | 507 | int (*probe_hw) (struct rt2x00_dev *rt2x00dev); |
466 | char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev); | 508 | char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev); |
509 | u16 (*get_firmware_crc) (void *data, const size_t len); | ||
467 | int (*load_firmware) (struct rt2x00_dev *rt2x00dev, void *data, | 510 | int (*load_firmware) (struct rt2x00_dev *rt2x00dev, void *data, |
468 | const size_t len); | 511 | const size_t len); |
469 | 512 | ||
@@ -474,12 +517,12 @@ struct rt2x00lib_ops { | |||
474 | void (*uninitialize) (struct rt2x00_dev *rt2x00dev); | 517 | void (*uninitialize) (struct rt2x00_dev *rt2x00dev); |
475 | 518 | ||
476 | /* | 519 | /* |
477 | * Ring initialization handlers | 520 | * queue initialization handlers |
478 | */ | 521 | */ |
479 | void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, | 522 | void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, |
480 | struct data_entry *entry); | 523 | struct queue_entry *entry); |
481 | void (*init_txentry) (struct rt2x00_dev *rt2x00dev, | 524 | void (*init_txentry) (struct rt2x00_dev *rt2x00dev, |
482 | struct data_entry *entry); | 525 | struct queue_entry *entry); |
483 | 526 | ||
484 | /* | 527 | /* |
485 | * Radio control handlers. | 528 | * Radio control handlers. |
@@ -497,35 +540,40 @@ struct rt2x00lib_ops { | |||
497 | */ | 540 | */ |
498 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, | 541 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, |
499 | struct sk_buff *skb, | 542 | struct sk_buff *skb, |
500 | struct txdata_entry_desc *desc, | 543 | struct txentry_desc *txdesc, |
501 | struct ieee80211_tx_control *control); | 544 | struct ieee80211_tx_control *control); |
502 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, | 545 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, |
503 | struct data_ring *ring, struct sk_buff *skb, | 546 | struct data_queue *queue, struct sk_buff *skb, |
504 | struct ieee80211_tx_control *control); | 547 | struct ieee80211_tx_control *control); |
505 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, | 548 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, |
506 | struct sk_buff *skb); | 549 | struct sk_buff *skb); |
507 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 550 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, |
508 | unsigned int queue); | 551 | const unsigned int queue); |
509 | 552 | ||
510 | /* | 553 | /* |
511 | * RX control handlers | 554 | * RX control handlers |
512 | */ | 555 | */ |
513 | void (*fill_rxdone) (struct data_entry *entry, | 556 | void (*fill_rxdone) (struct queue_entry *entry, |
514 | struct rxdata_entry_desc *desc); | 557 | struct rxdone_entry_desc *rxdesc); |
515 | 558 | ||
516 | /* | 559 | /* |
517 | * Configuration handlers. | 560 | * Configuration handlers. |
518 | */ | 561 | */ |
519 | void (*config_mac_addr) (struct rt2x00_dev *rt2x00dev, __le32 *mac); | 562 | void (*config_filter) (struct rt2x00_dev *rt2x00dev, |
520 | void (*config_bssid) (struct rt2x00_dev *rt2x00dev, __le32 *bssid); | 563 | const unsigned int filter_flags); |
521 | void (*config_type) (struct rt2x00_dev *rt2x00dev, const int type, | 564 | void (*config_intf) (struct rt2x00_dev *rt2x00dev, |
522 | const int tsf_sync); | 565 | struct rt2x00_intf *intf, |
523 | void (*config_preamble) (struct rt2x00_dev *rt2x00dev, | 566 | struct rt2x00intf_conf *conf, |
524 | const int short_preamble, | 567 | const unsigned int flags); |
525 | const int ack_timeout, | 568 | #define CONFIG_UPDATE_TYPE ( 1 << 1 ) |
526 | const int ack_consume_time); | 569 | #define CONFIG_UPDATE_MAC ( 1 << 2 ) |
527 | void (*config) (struct rt2x00_dev *rt2x00dev, const unsigned int flags, | 570 | #define CONFIG_UPDATE_BSSID ( 1 << 3 ) |
528 | struct rt2x00lib_conf *libconf); | 571 | |
572 | void (*config_erp) (struct rt2x00_dev *rt2x00dev, | ||
573 | struct rt2x00lib_erp *erp); | ||
574 | void (*config) (struct rt2x00_dev *rt2x00dev, | ||
575 | struct rt2x00lib_conf *libconf, | ||
576 | const unsigned int flags); | ||
529 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) | 577 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) |
530 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) | 578 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) |
531 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) | 579 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) |
@@ -540,10 +588,14 @@ struct rt2x00lib_ops { | |||
540 | */ | 588 | */ |
541 | struct rt2x00_ops { | 589 | struct rt2x00_ops { |
542 | const char *name; | 590 | const char *name; |
543 | const unsigned int rxd_size; | 591 | const unsigned int max_sta_intf; |
544 | const unsigned int txd_size; | 592 | const unsigned int max_ap_intf; |
545 | const unsigned int eeprom_size; | 593 | const unsigned int eeprom_size; |
546 | const unsigned int rf_size; | 594 | const unsigned int rf_size; |
595 | const struct data_queue_desc *rx; | ||
596 | const struct data_queue_desc *tx; | ||
597 | const struct data_queue_desc *bcn; | ||
598 | const struct data_queue_desc *atim; | ||
547 | const struct rt2x00lib_ops *lib; | 599 | const struct rt2x00lib_ops *lib; |
548 | const struct ieee80211_ops *hw; | 600 | const struct ieee80211_ops *hw; |
549 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 601 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
@@ -569,8 +621,11 @@ enum rt2x00_flags { | |||
569 | /* | 621 | /* |
570 | * Driver features | 622 | * Driver features |
571 | */ | 623 | */ |
624 | DRIVER_SUPPORT_MIXED_INTERFACES, | ||
572 | DRIVER_REQUIRE_FIRMWARE, | 625 | DRIVER_REQUIRE_FIRMWARE, |
573 | DRIVER_REQUIRE_BEACON_RING, | 626 | DRIVER_REQUIRE_BEACON_GUARD, |
627 | DRIVER_REQUIRE_ATIM_QUEUE, | ||
628 | DRIVER_REQUIRE_SCHEDULED, | ||
574 | 629 | ||
575 | /* | 630 | /* |
576 | * Driver configuration | 631 | * Driver configuration |
@@ -582,7 +637,6 @@ enum rt2x00_flags { | |||
582 | CONFIG_EXTERNAL_LNA_BG, | 637 | CONFIG_EXTERNAL_LNA_BG, |
583 | CONFIG_DOUBLE_ANTENNA, | 638 | CONFIG_DOUBLE_ANTENNA, |
584 | CONFIG_DISABLE_LINK_TUNING, | 639 | CONFIG_DISABLE_LINK_TUNING, |
585 | CONFIG_SHORT_PREAMBLE, | ||
586 | }; | 640 | }; |
587 | 641 | ||
588 | /* | 642 | /* |
@@ -597,8 +651,10 @@ struct rt2x00_dev { | |||
597 | * macro's should be used for correct typecasting. | 651 | * macro's should be used for correct typecasting. |
598 | */ | 652 | */ |
599 | void *dev; | 653 | void *dev; |
600 | #define rt2x00dev_pci(__dev) ( (struct pci_dev*)(__dev)->dev ) | 654 | #define rt2x00dev_pci(__dev) ( (struct pci_dev *)(__dev)->dev ) |
601 | #define rt2x00dev_usb(__dev) ( (struct usb_interface*)(__dev)->dev ) | 655 | #define rt2x00dev_usb(__dev) ( (struct usb_interface *)(__dev)->dev ) |
656 | #define rt2x00dev_usb_dev(__dev)\ | ||
657 | ( (struct usb_device *)interface_to_usbdev(rt2x00dev_usb(__dev)) ) | ||
602 | 658 | ||
603 | /* | 659 | /* |
604 | * Callback functions. | 660 | * Callback functions. |
@@ -609,18 +665,15 @@ struct rt2x00_dev { | |||
609 | * IEEE80211 control structure. | 665 | * IEEE80211 control structure. |
610 | */ | 666 | */ |
611 | struct ieee80211_hw *hw; | 667 | struct ieee80211_hw *hw; |
612 | struct ieee80211_hw_mode *hwmodes; | 668 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
613 | unsigned int curr_hwmode; | 669 | enum ieee80211_band curr_band; |
614 | #define HWMODE_B 0 | ||
615 | #define HWMODE_G 1 | ||
616 | #define HWMODE_A 2 | ||
617 | 670 | ||
618 | /* | 671 | /* |
619 | * rfkill structure for RF state switching support. | 672 | * rfkill structure for RF state switching support. |
620 | * This will only be compiled in when required. | 673 | * This will only be compiled in when required. |
621 | */ | 674 | */ |
622 | #ifdef CONFIG_RT2X00_LIB_RFKILL | 675 | #ifdef CONFIG_RT2X00_LIB_RFKILL |
623 | unsigned long rfkill_state; | 676 | unsigned long rfkill_state; |
624 | #define RFKILL_STATE_ALLOCATED 1 | 677 | #define RFKILL_STATE_ALLOCATED 1 |
625 | #define RFKILL_STATE_REGISTERED 2 | 678 | #define RFKILL_STATE_REGISTERED 2 |
626 | struct rfkill *rfkill; | 679 | struct rfkill *rfkill; |
@@ -636,6 +689,17 @@ unsigned long rfkill_state; | |||
636 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 689 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
637 | 690 | ||
638 | /* | 691 | /* |
692 | * LED structure for changing the LED status | ||
693 | * by mac8011 or the kernel. | ||
694 | */ | ||
695 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
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 |
@@ -935,6 +987,10 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); | |||
935 | int rt2x00mac_config_interface(struct ieee80211_hw *hw, | 987 | int rt2x00mac_config_interface(struct ieee80211_hw *hw, |
936 | struct ieee80211_vif *vif, | 988 | struct ieee80211_vif *vif, |
937 | struct ieee80211_if_conf *conf); | 989 | struct ieee80211_if_conf *conf); |
990 | void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | ||
991 | unsigned int changed_flags, | ||
992 | unsigned int *total_flags, | ||
993 | int mc_count, struct dev_addr_list *mc_list); | ||
938 | int rt2x00mac_get_stats(struct ieee80211_hw *hw, | 994 | int rt2x00mac_get_stats(struct ieee80211_hw *hw, |
939 | struct ieee80211_low_level_stats *stats); | 995 | struct ieee80211_low_level_stats *stats); |
940 | int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, | 996 | int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 07adc576db49..a9930a03f450 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,78 @@ | |||
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 | { | ||
52 | __le32 reg[2]; | ||
53 | |||
54 | memset(®, 0, sizeof(reg)); | ||
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 | { | 36 | { |
63 | __le32 reg[2]; | 37 | struct rt2x00intf_conf conf; |
38 | unsigned int flags = 0; | ||
64 | 39 | ||
65 | memset(®, 0, sizeof(reg)); | 40 | conf.type = type; |
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 | |||
84 | memset(&erp, 0, sizeof(erp)); | ||
85 | |||
86 | erp.short_preamble = bss_conf->use_short_preamble; | ||
87 | erp.ack_timeout = PLCP + get_duration(ACK_SIZE, 10); | ||
88 | erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); | ||
89 | |||
90 | if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) | ||
91 | erp.ack_timeout += SHORT_DIFS; | ||
92 | else | ||
93 | erp.ack_timeout += DIFS; | ||
94 | |||
95 | if (bss_conf->use_short_preamble) { | ||
96 | erp.ack_timeout += SHORT_PREAMBLE; | ||
97 | erp.ack_consume_time += SHORT_PREAMBLE; | ||
98 | } else { | ||
99 | erp.ack_timeout += PREAMBLE; | ||
100 | erp.ack_consume_time += PREAMBLE; | ||
101 | } | ||
102 | |||
103 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); | ||
90 | } | 104 | } |
91 | 105 | ||
92 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 106 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
@@ -113,7 +127,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
113 | * The latter is required since we need to recalibrate the | 127 | * The latter is required since we need to recalibrate the |
114 | * noise-sensitivity ratio for the new setup. | 128 | * noise-sensitivity ratio for the new setup. |
115 | */ | 129 | */ |
116 | rt2x00dev->ops->lib->config(rt2x00dev, CONFIG_UPDATE_ANTENNA, &libconf); | 130 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); |
117 | rt2x00lib_reset_link_tuner(rt2x00dev); | 131 | rt2x00lib_reset_link_tuner(rt2x00dev); |
118 | 132 | ||
119 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 133 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; |
@@ -123,12 +137,26 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
123 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); | 137 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); |
124 | } | 138 | } |
125 | 139 | ||
140 | static u32 rt2x00lib_get_basic_rates(struct ieee80211_supported_band *band) | ||
141 | { | ||
142 | const struct rt2x00_rate *rate; | ||
143 | unsigned int i; | ||
144 | u32 mask = 0; | ||
145 | |||
146 | for (i = 0; i < band->n_bitrates; i++) { | ||
147 | rate = rt2x00_get_rate(band->bitrates[i].hw_value); | ||
148 | if (rate->flags & DEV_RATE_BASIC) | ||
149 | mask |= rate->ratemask; | ||
150 | } | ||
151 | |||
152 | return mask; | ||
153 | } | ||
154 | |||
126 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 155 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
127 | struct ieee80211_conf *conf, const int force_config) | 156 | struct ieee80211_conf *conf, const int force_config) |
128 | { | 157 | { |
129 | struct rt2x00lib_conf libconf; | 158 | struct rt2x00lib_conf libconf; |
130 | struct ieee80211_hw_mode *mode; | 159 | struct ieee80211_supported_band *band; |
131 | struct ieee80211_rate *rate; | ||
132 | struct antenna_setup *default_ant = &rt2x00dev->default_ant; | 160 | struct antenna_setup *default_ant = &rt2x00dev->default_ant; |
133 | struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; | 161 | struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; |
134 | int flags = 0; | 162 | int flags = 0; |
@@ -147,9 +175,9 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
147 | * Check which configuration options have been | 175 | * Check which configuration options have been |
148 | * updated and should be send to the device. | 176 | * updated and should be send to the device. |
149 | */ | 177 | */ |
150 | if (rt2x00dev->rx_status.phymode != conf->phymode) | 178 | if (rt2x00dev->rx_status.band != conf->channel->band) |
151 | flags |= CONFIG_UPDATE_PHYMODE; | 179 | flags |= CONFIG_UPDATE_PHYMODE; |
152 | if (rt2x00dev->rx_status.channel != conf->channel) | 180 | if (rt2x00dev->rx_status.freq != conf->channel->center_freq) |
153 | flags |= CONFIG_UPDATE_CHANNEL; | 181 | flags |= CONFIG_UPDATE_CHANNEL; |
154 | if (rt2x00dev->tx_power != conf->power_level) | 182 | if (rt2x00dev->tx_power != conf->power_level) |
155 | flags |= CONFIG_UPDATE_TXPOWER; | 183 | flags |= CONFIG_UPDATE_TXPOWER; |
@@ -204,33 +232,15 @@ config: | |||
204 | memset(&libconf, 0, sizeof(libconf)); | 232 | memset(&libconf, 0, sizeof(libconf)); |
205 | 233 | ||
206 | if (flags & CONFIG_UPDATE_PHYMODE) { | 234 | if (flags & CONFIG_UPDATE_PHYMODE) { |
207 | switch (conf->phymode) { | 235 | band = &rt2x00dev->bands[conf->channel->band]; |
208 | case MODE_IEEE80211A: | 236 | |
209 | libconf.phymode = HWMODE_A; | 237 | libconf.band = conf->channel->band; |
210 | break; | 238 | 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 | } | 239 | } |
230 | 240 | ||
231 | if (flags & CONFIG_UPDATE_CHANNEL) { | 241 | if (flags & CONFIG_UPDATE_CHANNEL) { |
232 | memcpy(&libconf.rf, | 242 | memcpy(&libconf.rf, |
233 | &rt2x00dev->spec.channels[conf->channel_val], | 243 | &rt2x00dev->spec.channels[conf->channel->hw_value], |
234 | sizeof(libconf.rf)); | 244 | sizeof(libconf.rf)); |
235 | } | 245 | } |
236 | 246 | ||
@@ -266,7 +276,7 @@ config: | |||
266 | /* | 276 | /* |
267 | * Start configuration. | 277 | * Start configuration. |
268 | */ | 278 | */ |
269 | rt2x00dev->ops->lib->config(rt2x00dev, flags, &libconf); | 279 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, flags); |
270 | 280 | ||
271 | /* | 281 | /* |
272 | * Some configuration changes affect the link quality | 282 | * Some configuration changes affect the link quality |
@@ -276,12 +286,11 @@ config: | |||
276 | rt2x00lib_reset_link_tuner(rt2x00dev); | 286 | rt2x00lib_reset_link_tuner(rt2x00dev); |
277 | 287 | ||
278 | if (flags & CONFIG_UPDATE_PHYMODE) { | 288 | if (flags & CONFIG_UPDATE_PHYMODE) { |
279 | rt2x00dev->curr_hwmode = libconf.phymode; | 289 | rt2x00dev->curr_band = conf->channel->band; |
280 | rt2x00dev->rx_status.phymode = conf->phymode; | 290 | rt2x00dev->rx_status.band = conf->channel->band; |
281 | } | 291 | } |
282 | 292 | ||
283 | rt2x00dev->rx_status.freq = conf->freq; | 293 | rt2x00dev->rx_status.freq = conf->channel->center_freq; |
284 | rt2x00dev->rx_status.channel = conf->channel; | ||
285 | rt2x00dev->tx_power = conf->power_level; | 294 | rt2x00dev->tx_power = conf->power_level; |
286 | 295 | ||
287 | if (flags & CONFIG_UPDATE_ANTENNA) { | 296 | 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 e873a39fcce3..0361524d193c 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,19 +100,21 @@ 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. |
178 | */ | 110 | */ |
179 | status = rt2x00dev->ops->lib->set_device_state(rt2x00dev, | 111 | status = |
180 | STATE_RADIO_ON); | 112 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_ON); |
181 | if (status) | 113 | if (status) |
182 | return status; | 114 | return status; |
183 | 115 | ||
116 | rt2x00leds_led_radio(rt2x00dev, true); | ||
117 | |||
184 | __set_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags); | 118 | __set_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags); |
185 | 119 | ||
186 | /* | 120 | /* |
@@ -204,12 +138,10 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
204 | /* | 138 | /* |
205 | * Stop all scheduled work. | 139 | * Stop all scheduled work. |
206 | */ | 140 | */ |
207 | if (work_pending(&rt2x00dev->beacon_work)) | 141 | if (work_pending(&rt2x00dev->intf_work)) |
208 | cancel_work_sync(&rt2x00dev->beacon_work); | 142 | cancel_work_sync(&rt2x00dev->intf_work); |
209 | if (work_pending(&rt2x00dev->filter_work)) | 143 | if (work_pending(&rt2x00dev->filter_work)) |
210 | cancel_work_sync(&rt2x00dev->filter_work); | 144 | cancel_work_sync(&rt2x00dev->filter_work); |
211 | if (work_pending(&rt2x00dev->config_work)) | ||
212 | cancel_work_sync(&rt2x00dev->config_work); | ||
213 | 145 | ||
214 | /* | 146 | /* |
215 | * Stop the TX queues. | 147 | * Stop the TX queues. |
@@ -225,6 +157,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
225 | * Disable radio. | 157 | * Disable radio. |
226 | */ | 158 | */ |
227 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_OFF); | 159 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_OFF); |
160 | rt2x00leds_led_radio(rt2x00dev, false); | ||
228 | } | 161 | } |
229 | 162 | ||
230 | void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) | 163 | void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) |
@@ -241,7 +174,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. | 174 | * When we are enabling the RX, we should also start the link tuner. |
242 | */ | 175 | */ |
243 | if (state == STATE_RADIO_RX_ON && | 176 | if (state == STATE_RADIO_RX_ON && |
244 | is_interface_present(&rt2x00dev->interface)) | 177 | (rt2x00dev->intf_ap_count || rt2x00dev->intf_sta_count)) |
245 | rt2x00lib_start_link_tuner(rt2x00dev); | 178 | rt2x00lib_start_link_tuner(rt2x00dev); |
246 | } | 179 | } |
247 | 180 | ||
@@ -449,6 +382,11 @@ static void rt2x00lib_link_tuner(struct work_struct *work) | |||
449 | rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); | 382 | rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); |
450 | 383 | ||
451 | /* | 384 | /* |
385 | * Send a signal to the led to update the led signal strength. | ||
386 | */ | ||
387 | rt2x00leds_led_quality(rt2x00dev, rt2x00dev->link.qual.avg_rssi); | ||
388 | |||
389 | /* | ||
452 | * Evaluate antenna setup, make this the last step since this could | 390 | * Evaluate antenna setup, make this the last step since this could |
453 | * possibly reset some statistics. | 391 | * possibly reset some statistics. |
454 | */ | 392 | */ |
@@ -466,59 +404,78 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | |||
466 | { | 404 | { |
467 | struct rt2x00_dev *rt2x00dev = | 405 | struct rt2x00_dev *rt2x00dev = |
468 | container_of(work, struct rt2x00_dev, filter_work); | 406 | container_of(work, struct rt2x00_dev, filter_work); |
469 | unsigned int filter = rt2x00dev->packet_filter; | 407 | |
408 | rt2x00dev->ops->lib->config_filter(rt2x00dev, rt2x00dev->packet_filter); | ||
409 | } | ||
410 | |||
411 | static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | ||
412 | struct ieee80211_vif *vif) | ||
413 | { | ||
414 | struct rt2x00_dev *rt2x00dev = data; | ||
415 | struct rt2x00_intf *intf = vif_to_intf(vif); | ||
416 | struct sk_buff *skb; | ||
417 | struct ieee80211_tx_control control; | ||
418 | struct ieee80211_bss_conf conf; | ||
419 | int delayed_flags; | ||
470 | 420 | ||
471 | /* | 421 | /* |
472 | * Since we had stored the filter inside interface.filter, | 422 | * Copy all data we need during this action under the protection |
473 | * we should now clear that field. Otherwise the driver will | 423 | * of a spinlock. Otherwise race conditions might occur which results |
474 | * assume nothing has changed (*total_flags will be compared | 424 | * into an invalid configuration. |
475 | * to interface.filter to determine if any action is required). | ||
476 | */ | 425 | */ |
477 | rt2x00dev->packet_filter = 0; | 426 | spin_lock(&intf->lock); |
427 | |||
428 | memcpy(&conf, &intf->conf, sizeof(conf)); | ||
429 | delayed_flags = intf->delayed_flags; | ||
430 | intf->delayed_flags = 0; | ||
431 | |||
432 | spin_unlock(&intf->lock); | ||
433 | |||
434 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | ||
435 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); | ||
436 | if (skb) { | ||
437 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | ||
438 | &control); | ||
439 | dev_kfree_skb(skb); | ||
440 | } | ||
441 | } | ||
442 | |||
443 | if (delayed_flags & DELAYED_CONFIG_ERP) | ||
444 | rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf); | ||
478 | 445 | ||
479 | rt2x00dev->ops->hw->configure_filter(rt2x00dev->hw, | 446 | if (delayed_flags & DELAYED_LED_ASSOC) |
480 | filter, &filter, 0, NULL); | 447 | rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); |
481 | } | 448 | } |
482 | 449 | ||
483 | static void rt2x00lib_configuration_scheduled(struct work_struct *work) | 450 | static void rt2x00lib_intf_scheduled(struct work_struct *work) |
484 | { | 451 | { |
485 | struct rt2x00_dev *rt2x00dev = | 452 | struct rt2x00_dev *rt2x00dev = |
486 | container_of(work, struct rt2x00_dev, config_work); | 453 | container_of(work, struct rt2x00_dev, intf_work); |
487 | struct ieee80211_bss_conf bss_conf; | ||
488 | |||
489 | bss_conf.use_short_preamble = | ||
490 | test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | ||
491 | 454 | ||
492 | /* | 455 | /* |
493 | * FIXME: shouldn't invoke it this way because all other contents | 456 | * Iterate over each interface and perform the |
494 | * of bss_conf is invalid. | 457 | * requested configurations. |
495 | */ | 458 | */ |
496 | rt2x00mac_bss_info_changed(rt2x00dev->hw, rt2x00dev->interface.id, | 459 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
497 | &bss_conf, BSS_CHANGED_ERP_PREAMBLE); | 460 | rt2x00lib_intf_scheduled_iter, |
461 | rt2x00dev); | ||
498 | } | 462 | } |
499 | 463 | ||
500 | /* | 464 | /* |
501 | * Interrupt context handlers. | 465 | * Interrupt context handlers. |
502 | */ | 466 | */ |
503 | static void rt2x00lib_beacondone_scheduled(struct work_struct *work) | 467 | static void rt2x00lib_beacondone_iter(void *data, u8 *mac, |
468 | struct ieee80211_vif *vif) | ||
504 | { | 469 | { |
505 | struct rt2x00_dev *rt2x00dev = | 470 | 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 | 471 | ||
512 | skb = ieee80211_beacon_get(rt2x00dev->hw, | 472 | if (vif->type != IEEE80211_IF_TYPE_AP && |
513 | rt2x00dev->interface.id, | 473 | vif->type != IEEE80211_IF_TYPE_IBSS) |
514 | &entry->tx_status.control); | ||
515 | if (!skb) | ||
516 | return; | 474 | return; |
517 | 475 | ||
518 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | 476 | spin_lock(&intf->lock); |
519 | &entry->tx_status.control); | 477 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; |
520 | 478 | spin_unlock(&intf->lock); | |
521 | dev_kfree_skb(skb); | ||
522 | } | 479 | } |
523 | 480 | ||
524 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | 481 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) |
@@ -526,116 +483,140 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
526 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 483 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
527 | return; | 484 | return; |
528 | 485 | ||
529 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->beacon_work); | 486 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
487 | rt2x00lib_beacondone_iter, | ||
488 | rt2x00dev); | ||
489 | |||
490 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | ||
530 | } | 491 | } |
531 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 492 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
532 | 493 | ||
533 | void rt2x00lib_txdone(struct data_entry *entry, | 494 | void rt2x00lib_txdone(struct queue_entry *entry, |
534 | const int status, const int retry) | 495 | struct txdone_entry_desc *txdesc) |
535 | { | 496 | { |
536 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | 497 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
537 | struct ieee80211_tx_status *tx_status = &entry->tx_status; | 498 | struct skb_frame_desc *skbdesc; |
538 | struct ieee80211_low_level_stats *stats = &rt2x00dev->low_level_stats; | 499 | struct ieee80211_tx_status tx_status; |
539 | int success = !!(status == TX_SUCCESS || status == TX_SUCCESS_RETRY); | 500 | int success = !!(txdesc->status == TX_SUCCESS || |
540 | int fail = !!(status == TX_FAIL_RETRY || status == TX_FAIL_INVALID || | 501 | txdesc->status == TX_SUCCESS_RETRY); |
541 | status == TX_FAIL_OTHER); | 502 | int fail = !!(txdesc->status == TX_FAIL_RETRY || |
503 | txdesc->status == TX_FAIL_INVALID || | ||
504 | txdesc->status == TX_FAIL_OTHER); | ||
542 | 505 | ||
543 | /* | 506 | /* |
544 | * Update TX statistics. | 507 | * Update TX statistics. |
545 | */ | 508 | */ |
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; | 509 | rt2x00dev->link.qual.tx_success += success; |
551 | rt2x00dev->link.qual.tx_failed += retry + fail; | 510 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; |
511 | |||
512 | /* | ||
513 | * Initialize TX status | ||
514 | */ | ||
515 | tx_status.flags = 0; | ||
516 | tx_status.ack_signal = 0; | ||
517 | tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY); | ||
518 | tx_status.retry_count = txdesc->retry; | ||
519 | memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control)); | ||
552 | 520 | ||
553 | if (!(tx_status->control.flags & IEEE80211_TXCTL_NO_ACK)) { | 521 | if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { |
554 | if (success) | 522 | if (success) |
555 | tx_status->flags |= IEEE80211_TX_STATUS_ACK; | 523 | tx_status.flags |= IEEE80211_TX_STATUS_ACK; |
556 | else | 524 | else |
557 | stats->dot11ACKFailureCount++; | 525 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; |
558 | } | 526 | } |
559 | 527 | ||
560 | tx_status->queue_length = entry->ring->stats.limit; | 528 | tx_status.queue_length = entry->queue->limit; |
561 | tx_status->queue_number = tx_status->control.queue; | 529 | tx_status.queue_number = tx_status.control.queue; |
562 | 530 | ||
563 | if (tx_status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 531 | if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
564 | if (success) | 532 | if (success) |
565 | stats->dot11RTSSuccessCount++; | 533 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; |
566 | else | 534 | else |
567 | stats->dot11RTSFailureCount++; | 535 | rt2x00dev->low_level_stats.dot11RTSFailureCount++; |
568 | } | 536 | } |
569 | 537 | ||
570 | /* | 538 | /* |
571 | * Send the tx_status to mac80211 & debugfs. | 539 | * Send the tx_status to debugfs. Only send the status report |
572 | * mac80211 will clean up the skb structure. | 540 | * to mac80211 when the frame originated from there. If this was |
541 | * a extra frame coming through a mac80211 library call (RTS/CTS) | ||
542 | * then we should not send the status report back. | ||
543 | * If send to mac80211, mac80211 will clean up the skb structure, | ||
544 | * otherwise we have to do it ourself. | ||
573 | */ | 545 | */ |
574 | get_skb_desc(entry->skb)->frame_type = DUMP_FRAME_TXDONE; | 546 | skbdesc = get_skb_frame_desc(entry->skb); |
547 | skbdesc->frame_type = DUMP_FRAME_TXDONE; | ||
548 | |||
575 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); | 549 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); |
576 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, tx_status); | 550 | |
551 | if (!(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED)) | ||
552 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, | ||
553 | entry->skb, &tx_status); | ||
554 | else | ||
555 | dev_kfree_skb(entry->skb); | ||
577 | entry->skb = NULL; | 556 | entry->skb = NULL; |
578 | } | 557 | } |
579 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 558 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
580 | 559 | ||
581 | void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | 560 | void rt2x00lib_rxdone(struct queue_entry *entry, |
582 | struct rxdata_entry_desc *desc) | 561 | struct rxdone_entry_desc *rxdesc) |
583 | { | 562 | { |
584 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | 563 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
585 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 564 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; |
586 | struct ieee80211_hw_mode *mode; | 565 | struct ieee80211_supported_band *sband; |
587 | struct ieee80211_rate *rate; | ||
588 | struct ieee80211_hdr *hdr; | 566 | struct ieee80211_hdr *hdr; |
567 | const struct rt2x00_rate *rate; | ||
589 | unsigned int i; | 568 | unsigned int i; |
590 | int val = 0; | 569 | int idx = -1; |
591 | u16 fc; | 570 | u16 fc; |
592 | 571 | ||
593 | /* | 572 | /* |
594 | * Update RX statistics. | 573 | * Update RX statistics. |
595 | */ | 574 | */ |
596 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | 575 | sband = &rt2x00dev->bands[rt2x00dev->curr_band]; |
597 | for (i = 0; i < mode->num_rates; i++) { | 576 | for (i = 0; i < sband->n_bitrates; i++) { |
598 | rate = &mode->rates[i]; | 577 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); |
599 | 578 | ||
600 | /* | 579 | if (((rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && |
601 | * When frame was received with an OFDM bitrate, | 580 | (rate->plcp == rxdesc->signal)) || |
602 | * the signal is the PLCP value. If it was received with | 581 | (!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && |
603 | * a CCK bitrate the signal is the rate in 0.5kbit/s. | 582 | (rate->bitrate == rxdesc->signal))) { |
604 | */ | 583 | idx = i; |
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 | |||
610 | if (val == desc->signal) { | ||
611 | val = rate->val; | ||
612 | break; | 584 | break; |
613 | } | 585 | } |
614 | } | 586 | } |
615 | 587 | ||
588 | if (idx < 0) { | ||
589 | WARNING(rt2x00dev, "Frame received with unrecognized signal," | ||
590 | "signal=0x%.2x, plcp=%d.\n", rxdesc->signal, | ||
591 | !!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP)); | ||
592 | idx = 0; | ||
593 | } | ||
594 | |||
616 | /* | 595 | /* |
617 | * Only update link status if this is a beacon frame carrying our bssid. | 596 | * Only update link status if this is a beacon frame carrying our bssid. |
618 | */ | 597 | */ |
619 | hdr = (struct ieee80211_hdr*)skb->data; | 598 | hdr = (struct ieee80211_hdr *)entry->skb->data; |
620 | fc = le16_to_cpu(hdr->frame_control); | 599 | fc = le16_to_cpu(hdr->frame_control); |
621 | if (is_beacon(fc) && desc->my_bss) | 600 | if (is_beacon(fc) && (rxdesc->dev_flags & RXDONE_MY_BSS)) |
622 | rt2x00lib_update_link_stats(&rt2x00dev->link, desc->rssi); | 601 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); |
623 | 602 | ||
624 | rt2x00dev->link.qual.rx_success++; | 603 | rt2x00dev->link.qual.rx_success++; |
625 | 604 | ||
626 | rx_status->rate = val; | 605 | rx_status->rate_idx = idx; |
627 | rx_status->signal = | 606 | rx_status->signal = |
628 | rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi); | 607 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); |
629 | rx_status->ssi = desc->rssi; | 608 | rx_status->ssi = rxdesc->rssi; |
630 | rx_status->flag = desc->flags; | 609 | rx_status->flag = rxdesc->flags; |
631 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 610 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
632 | 611 | ||
633 | /* | 612 | /* |
634 | * Send frame to mac80211 & debugfs | 613 | * Send frame to mac80211 & debugfs. |
614 | * mac80211 will clean up the skb structure. | ||
635 | */ | 615 | */ |
636 | get_skb_desc(skb)->frame_type = DUMP_FRAME_RXDONE; | 616 | get_skb_frame_desc(entry->skb)->frame_type = DUMP_FRAME_RXDONE; |
637 | rt2x00debug_dump_frame(rt2x00dev, skb); | 617 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); |
638 | ieee80211_rx_irqsafe(rt2x00dev->hw, skb, rx_status); | 618 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); |
619 | entry->skb = NULL; | ||
639 | } | 620 | } |
640 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 621 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |
641 | 622 | ||
@@ -646,83 +627,69 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
646 | struct sk_buff *skb, | 627 | struct sk_buff *skb, |
647 | struct ieee80211_tx_control *control) | 628 | struct ieee80211_tx_control *control) |
648 | { | 629 | { |
649 | struct txdata_entry_desc desc; | 630 | struct txentry_desc txdesc; |
650 | struct skb_desc *skbdesc = get_skb_desc(skb); | 631 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
651 | struct ieee80211_hdr *ieee80211hdr = skbdesc->data; | 632 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skbdesc->data; |
633 | const struct rt2x00_rate *rate; | ||
652 | int tx_rate; | 634 | int tx_rate; |
653 | int bitrate; | ||
654 | int length; | 635 | int length; |
655 | int duration; | 636 | int duration; |
656 | int residual; | 637 | int residual; |
657 | u16 frame_control; | 638 | u16 frame_control; |
658 | u16 seq_ctrl; | 639 | u16 seq_ctrl; |
659 | 640 | ||
660 | memset(&desc, 0, sizeof(desc)); | 641 | memset(&txdesc, 0, sizeof(txdesc)); |
661 | |||
662 | desc.cw_min = skbdesc->ring->tx_params.cw_min; | ||
663 | desc.cw_max = skbdesc->ring->tx_params.cw_max; | ||
664 | desc.aifs = skbdesc->ring->tx_params.aifs; | ||
665 | 642 | ||
666 | /* | 643 | txdesc.queue = skbdesc->entry->queue->qid; |
667 | * Identify queue | 644 | txdesc.cw_min = skbdesc->entry->queue->cw_min; |
668 | */ | 645 | txdesc.cw_max = skbdesc->entry->queue->cw_max; |
669 | if (control->queue < rt2x00dev->hw->queues) | 646 | txdesc.aifs = skbdesc->entry->queue->aifs; |
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 | 647 | ||
677 | /* | 648 | /* |
678 | * Read required fields from ieee80211 header. | 649 | * Read required fields from ieee80211 header. |
679 | */ | 650 | */ |
680 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); | 651 | frame_control = le16_to_cpu(hdr->frame_control); |
681 | seq_ctrl = le16_to_cpu(ieee80211hdr->seq_ctrl); | 652 | seq_ctrl = le16_to_cpu(hdr->seq_ctrl); |
682 | 653 | ||
683 | tx_rate = control->tx_rate; | 654 | tx_rate = control->tx_rate->hw_value; |
684 | 655 | ||
685 | /* | 656 | /* |
686 | * Check whether this frame is to be acked | 657 | * Check whether this frame is to be acked |
687 | */ | 658 | */ |
688 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) | 659 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) |
689 | __set_bit(ENTRY_TXD_ACK, &desc.flags); | 660 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); |
690 | 661 | ||
691 | /* | 662 | /* |
692 | * Check if this is a RTS/CTS frame | 663 | * Check if this is a RTS/CTS frame |
693 | */ | 664 | */ |
694 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { | 665 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { |
695 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | 666 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
696 | if (is_rts_frame(frame_control)) { | 667 | if (is_rts_frame(frame_control)) { |
697 | __set_bit(ENTRY_TXD_RTS_FRAME, &desc.flags); | 668 | __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags); |
698 | __set_bit(ENTRY_TXD_ACK, &desc.flags); | 669 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); |
699 | } else | 670 | } else |
700 | __clear_bit(ENTRY_TXD_ACK, &desc.flags); | 671 | __clear_bit(ENTRY_TXD_ACK, &txdesc.flags); |
701 | if (control->rts_cts_rate) | 672 | if (control->rts_cts_rate) |
702 | tx_rate = control->rts_cts_rate; | 673 | tx_rate = control->rts_cts_rate->hw_value; |
703 | } | 674 | } |
704 | 675 | ||
705 | /* | 676 | 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 | 677 | ||
711 | /* | 678 | /* |
712 | * Check if more fragments are pending | 679 | * Check if more fragments are pending |
713 | */ | 680 | */ |
714 | if (ieee80211_get_morefrag(ieee80211hdr)) { | 681 | if (ieee80211_get_morefrag(hdr)) { |
715 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | 682 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
716 | __set_bit(ENTRY_TXD_MORE_FRAG, &desc.flags); | 683 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags); |
717 | } | 684 | } |
718 | 685 | ||
719 | /* | 686 | /* |
720 | * Beacons and probe responses require the tsf timestamp | 687 | * Beacons and probe responses require the tsf timestamp |
721 | * to be inserted into the frame. | 688 | * to be inserted into the frame. |
722 | */ | 689 | */ |
723 | if (control->queue == IEEE80211_TX_QUEUE_BEACON || | 690 | if (control->queue == RT2X00_BCN_QUEUE_BEACON || |
724 | is_probe_resp(frame_control)) | 691 | is_probe_resp(frame_control)) |
725 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc.flags); | 692 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc.flags); |
726 | 693 | ||
727 | /* | 694 | /* |
728 | * Determine with what IFS priority this frame should be send. | 695 | * Determine with what IFS priority this frame should be send. |
@@ -730,30 +697,30 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
730 | * or this fragment came after RTS/CTS. | 697 | * or this fragment came after RTS/CTS. |
731 | */ | 698 | */ |
732 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || | 699 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || |
733 | test_bit(ENTRY_TXD_RTS_FRAME, &desc.flags)) | 700 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags)) |
734 | desc.ifs = IFS_SIFS; | 701 | txdesc.ifs = IFS_SIFS; |
735 | else | 702 | else |
736 | desc.ifs = IFS_BACKOFF; | 703 | txdesc.ifs = IFS_BACKOFF; |
737 | 704 | ||
738 | /* | 705 | /* |
739 | * PLCP setup | 706 | * PLCP setup |
740 | * Length calculation depends on OFDM/CCK rate. | 707 | * Length calculation depends on OFDM/CCK rate. |
741 | */ | 708 | */ |
742 | desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP); | 709 | txdesc.signal = rate->plcp; |
743 | desc.service = 0x04; | 710 | txdesc.service = 0x04; |
744 | 711 | ||
745 | length = skbdesc->data_len + FCS_LEN; | 712 | length = skbdesc->data_len + FCS_LEN; |
746 | if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) { | 713 | if (rate->flags & DEV_RATE_OFDM) { |
747 | desc.length_high = (length >> 6) & 0x3f; | 714 | __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 | 715 | ||
716 | txdesc.length_high = (length >> 6) & 0x3f; | ||
717 | txdesc.length_low = length & 0x3f; | ||
718 | } else { | ||
752 | /* | 719 | /* |
753 | * Convert length to microseconds. | 720 | * Convert length to microseconds. |
754 | */ | 721 | */ |
755 | residual = get_duration_res(length, bitrate); | 722 | residual = get_duration_res(length, rate->bitrate); |
756 | duration = get_duration(length, bitrate); | 723 | duration = get_duration(length, rate->bitrate); |
757 | 724 | ||
758 | if (residual != 0) { | 725 | if (residual != 0) { |
759 | duration++; | 726 | duration++; |
@@ -761,28 +728,27 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
761 | /* | 728 | /* |
762 | * Check if we need to set the Length Extension | 729 | * Check if we need to set the Length Extension |
763 | */ | 730 | */ |
764 | if (bitrate == 110 && residual <= 30) | 731 | if (rate->bitrate == 110 && residual <= 30) |
765 | desc.service |= 0x80; | 732 | txdesc.service |= 0x80; |
766 | } | 733 | } |
767 | 734 | ||
768 | desc.length_high = (duration >> 8) & 0xff; | 735 | txdesc.length_high = (duration >> 8) & 0xff; |
769 | desc.length_low = duration & 0xff; | 736 | txdesc.length_low = duration & 0xff; |
770 | 737 | ||
771 | /* | 738 | /* |
772 | * When preamble is enabled we should set the | 739 | * When preamble is enabled we should set the |
773 | * preamble bit for the signal. | 740 | * preamble bit for the signal. |
774 | */ | 741 | */ |
775 | if (DEVICE_GET_RATE_FIELD(tx_rate, PREAMBLE)) | 742 | if (rt2x00_get_rate_preamble(tx_rate)) |
776 | desc.signal |= 0x08; | 743 | txdesc.signal |= 0x08; |
777 | } | 744 | } |
778 | 745 | ||
779 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &desc, control); | 746 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &txdesc, control); |
780 | 747 | ||
781 | /* | 748 | /* |
782 | * Update ring entry. | 749 | * Update queue entry. |
783 | */ | 750 | */ |
784 | skbdesc->entry->skb = skb; | 751 | skbdesc->entry->skb = skb; |
785 | memcpy(&skbdesc->entry->tx_status.control, control, sizeof(*control)); | ||
786 | 752 | ||
787 | /* | 753 | /* |
788 | * The frame has been completely initialized and ready | 754 | * The frame has been completely initialized and ready |
@@ -798,133 +764,167 @@ EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc); | |||
798 | /* | 764 | /* |
799 | * Driver initialization handlers. | 765 | * Driver initialization handlers. |
800 | */ | 766 | */ |
767 | const struct rt2x00_rate rt2x00_supported_rates[12] = { | ||
768 | { | ||
769 | .flags = DEV_RATE_CCK | DEV_RATE_BASIC, | ||
770 | .bitrate = 10, | ||
771 | .ratemask = BIT(0), | ||
772 | .plcp = 0x00, | ||
773 | }, | ||
774 | { | ||
775 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC, | ||
776 | .bitrate = 20, | ||
777 | .ratemask = BIT(1), | ||
778 | .plcp = 0x01, | ||
779 | }, | ||
780 | { | ||
781 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC, | ||
782 | .bitrate = 55, | ||
783 | .ratemask = BIT(2), | ||
784 | .plcp = 0x02, | ||
785 | }, | ||
786 | { | ||
787 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC, | ||
788 | .bitrate = 110, | ||
789 | .ratemask = BIT(3), | ||
790 | .plcp = 0x03, | ||
791 | }, | ||
792 | { | ||
793 | .flags = DEV_RATE_OFDM | DEV_RATE_BASIC, | ||
794 | .bitrate = 60, | ||
795 | .ratemask = BIT(4), | ||
796 | .plcp = 0x0b, | ||
797 | }, | ||
798 | { | ||
799 | .flags = DEV_RATE_OFDM, | ||
800 | .bitrate = 90, | ||
801 | .ratemask = BIT(5), | ||
802 | .plcp = 0x0f, | ||
803 | }, | ||
804 | { | ||
805 | .flags = DEV_RATE_OFDM | DEV_RATE_BASIC, | ||
806 | .bitrate = 120, | ||
807 | .ratemask = BIT(6), | ||
808 | .plcp = 0x0a, | ||
809 | }, | ||
810 | { | ||
811 | .flags = DEV_RATE_OFDM, | ||
812 | .bitrate = 180, | ||
813 | .ratemask = BIT(7), | ||
814 | .plcp = 0x0e, | ||
815 | }, | ||
816 | { | ||
817 | .flags = DEV_RATE_OFDM | DEV_RATE_BASIC, | ||
818 | .bitrate = 240, | ||
819 | .ratemask = BIT(8), | ||
820 | .plcp = 0x09, | ||
821 | }, | ||
822 | { | ||
823 | .flags = DEV_RATE_OFDM, | ||
824 | .bitrate = 360, | ||
825 | .ratemask = BIT(9), | ||
826 | .plcp = 0x0d, | ||
827 | }, | ||
828 | { | ||
829 | .flags = DEV_RATE_OFDM, | ||
830 | .bitrate = 480, | ||
831 | .ratemask = BIT(10), | ||
832 | .plcp = 0x08, | ||
833 | }, | ||
834 | { | ||
835 | .flags = DEV_RATE_OFDM, | ||
836 | .bitrate = 540, | ||
837 | .ratemask = BIT(11), | ||
838 | .plcp = 0x0c, | ||
839 | }, | ||
840 | }; | ||
841 | |||
801 | static void rt2x00lib_channel(struct ieee80211_channel *entry, | 842 | static void rt2x00lib_channel(struct ieee80211_channel *entry, |
802 | const int channel, const int tx_power, | 843 | const int channel, const int tx_power, |
803 | const int value) | 844 | const int value) |
804 | { | 845 | { |
805 | entry->chan = channel; | 846 | entry->center_freq = ieee80211_channel_to_frequency(channel); |
806 | if (channel <= 14) | 847 | entry->hw_value = value; |
807 | entry->freq = 2407 + (5 * channel); | 848 | entry->max_power = tx_power; |
808 | else | 849 | 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 | } | 850 | } |
818 | 851 | ||
819 | static void rt2x00lib_rate(struct ieee80211_rate *entry, | 852 | static void rt2x00lib_rate(struct ieee80211_rate *entry, |
820 | const int rate, const int mask, | 853 | const u16 index, const struct rt2x00_rate *rate) |
821 | const int plcp, const int flags) | ||
822 | { | 854 | { |
823 | entry->rate = rate; | 855 | entry->flags = 0; |
824 | entry->val = | 856 | entry->bitrate = rate->bitrate; |
825 | DEVICE_SET_RATE_FIELD(rate, RATE) | | 857 | entry->hw_value = rt2x00_create_rate_hw_value(index, 0); |
826 | DEVICE_SET_RATE_FIELD(mask, RATEMASK) | | 858 | entry->hw_value_short = entry->hw_value; |
827 | DEVICE_SET_RATE_FIELD(plcp, PLCP); | 859 | |
828 | entry->flags = flags; | 860 | if (rate->flags & DEV_RATE_SHORT_PREAMBLE) { |
829 | entry->val2 = entry->val; | 861 | entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; |
830 | if (entry->flags & IEEE80211_RATE_PREAMBLE2) | 862 | entry->hw_value_short |= rt2x00_create_rate_hw_value(index, 1); |
831 | entry->val2 |= DEVICE_SET_RATE_FIELD(1, PREAMBLE); | 863 | } |
832 | entry->min_rssi_ack = 0; | ||
833 | entry->min_rssi_ack_delta = 0; | ||
834 | } | 864 | } |
835 | 865 | ||
836 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | 866 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, |
837 | struct hw_mode_spec *spec) | 867 | struct hw_mode_spec *spec) |
838 | { | 868 | { |
839 | struct ieee80211_hw *hw = rt2x00dev->hw; | 869 | struct ieee80211_hw *hw = rt2x00dev->hw; |
840 | struct ieee80211_hw_mode *hwmodes; | ||
841 | struct ieee80211_channel *channels; | 870 | struct ieee80211_channel *channels; |
842 | struct ieee80211_rate *rates; | 871 | struct ieee80211_rate *rates; |
872 | unsigned int num_rates; | ||
843 | unsigned int i; | 873 | unsigned int i; |
844 | unsigned char tx_power; | 874 | unsigned char tx_power; |
845 | 875 | ||
846 | hwmodes = kzalloc(sizeof(*hwmodes) * spec->num_modes, GFP_KERNEL); | 876 | num_rates = 0; |
847 | if (!hwmodes) | 877 | if (spec->supported_rates & SUPPORT_RATE_CCK) |
848 | goto exit; | 878 | num_rates += 4; |
879 | if (spec->supported_rates & SUPPORT_RATE_OFDM) | ||
880 | num_rates += 8; | ||
849 | 881 | ||
850 | channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); | 882 | channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); |
851 | if (!channels) | 883 | if (!channels) |
852 | goto exit_free_modes; | 884 | return -ENOMEM; |
853 | 885 | ||
854 | rates = kzalloc(sizeof(*rates) * spec->num_rates, GFP_KERNEL); | 886 | rates = kzalloc(sizeof(*rates) * num_rates, GFP_KERNEL); |
855 | if (!rates) | 887 | if (!rates) |
856 | goto exit_free_channels; | 888 | goto exit_free_channels; |
857 | 889 | ||
858 | /* | 890 | /* |
859 | * Initialize Rate list. | 891 | * Initialize Rate list. |
860 | */ | 892 | */ |
861 | rt2x00lib_rate(&rates[0], 10, DEV_RATEMASK_1MB, | 893 | for (i = 0; i < num_rates; i++) |
862 | 0x00, IEEE80211_RATE_CCK); | 894 | 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 | 895 | ||
889 | /* | 896 | /* |
890 | * Initialize Channel list. | 897 | * Initialize Channel list. |
891 | */ | 898 | */ |
892 | for (i = 0; i < spec->num_channels; i++) { | 899 | for (i = 0; i < spec->num_channels; i++) { |
893 | if (spec->channels[i].channel <= 14) | 900 | if (spec->channels[i].channel <= 14) { |
894 | tx_power = spec->tx_power_bg[i]; | 901 | if (spec->tx_power_bg) |
895 | else if (spec->tx_power_a) | 902 | tx_power = spec->tx_power_bg[i]; |
896 | tx_power = spec->tx_power_a[i]; | 903 | else |
897 | else | 904 | tx_power = spec->tx_power_default; |
898 | tx_power = spec->tx_power_default; | 905 | } else { |
906 | if (spec->tx_power_a) | ||
907 | tx_power = spec->tx_power_a[i]; | ||
908 | else | ||
909 | tx_power = spec->tx_power_default; | ||
910 | } | ||
899 | 911 | ||
900 | rt2x00lib_channel(&channels[i], | 912 | rt2x00lib_channel(&channels[i], |
901 | spec->channels[i].channel, tx_power, i); | 913 | spec->channels[i].channel, tx_power, i); |
902 | } | 914 | } |
903 | 915 | ||
904 | /* | 916 | /* |
905 | * Intitialize 802.11b | 917 | * 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. | 918 | * Rates: CCK, OFDM. |
920 | * Channels: OFDM. | 919 | * Channels: 2.4 GHz |
921 | */ | 920 | */ |
922 | if (spec->num_modes > HWMODE_G) { | 921 | if (spec->supported_bands & SUPPORT_BAND_2GHZ) { |
923 | hwmodes[HWMODE_G].mode = MODE_IEEE80211G; | 922 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].n_channels = 14; |
924 | hwmodes[HWMODE_G].num_channels = 14; | 923 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].n_bitrates = num_rates; |
925 | hwmodes[HWMODE_G].num_rates = spec->num_rates; | 924 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].channels = channels; |
926 | hwmodes[HWMODE_G].channels = channels; | 925 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates; |
927 | hwmodes[HWMODE_G].rates = rates; | 926 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
927 | &rt2x00dev->bands[IEEE80211_BAND_2GHZ]; | ||
928 | } | 928 | } |
929 | 929 | ||
930 | /* | 930 | /* |
@@ -932,40 +932,21 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | |||
932 | * Rates: OFDM. | 932 | * Rates: OFDM. |
933 | * Channels: OFDM, UNII, HiperLAN2. | 933 | * Channels: OFDM, UNII, HiperLAN2. |
934 | */ | 934 | */ |
935 | if (spec->num_modes > HWMODE_A) { | 935 | if (spec->supported_bands & SUPPORT_BAND_5GHZ) { |
936 | hwmodes[HWMODE_A].mode = MODE_IEEE80211A; | 936 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].n_channels = |
937 | hwmodes[HWMODE_A].num_channels = spec->num_channels - 14; | 937 | spec->num_channels - 14; |
938 | hwmodes[HWMODE_A].num_rates = spec->num_rates - 4; | 938 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].n_bitrates = |
939 | hwmodes[HWMODE_A].channels = &channels[14]; | 939 | num_rates - 4; |
940 | hwmodes[HWMODE_A].rates = &rates[4]; | 940 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].channels = &channels[14]; |
941 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4]; | ||
942 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
943 | &rt2x00dev->bands[IEEE80211_BAND_5GHZ]; | ||
941 | } | 944 | } |
942 | 945 | ||
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; | 946 | return 0; |
958 | 947 | ||
959 | exit_free_rates: | 948 | exit_free_channels: |
960 | kfree(rates); | ||
961 | |||
962 | exit_free_channels: | ||
963 | kfree(channels); | 949 | kfree(channels); |
964 | |||
965 | exit_free_modes: | ||
966 | kfree(hwmodes); | ||
967 | |||
968 | exit: | ||
969 | ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); | 950 | ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); |
970 | return -ENOMEM; | 951 | return -ENOMEM; |
971 | } | 952 | } |
@@ -975,11 +956,11 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev) | |||
975 | if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) | 956 | if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) |
976 | ieee80211_unregister_hw(rt2x00dev->hw); | 957 | ieee80211_unregister_hw(rt2x00dev->hw); |
977 | 958 | ||
978 | if (likely(rt2x00dev->hwmodes)) { | 959 | if (likely(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ])) { |
979 | kfree(rt2x00dev->hwmodes->channels); | 960 | kfree(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels); |
980 | kfree(rt2x00dev->hwmodes->rates); | 961 | kfree(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->bitrates); |
981 | kfree(rt2x00dev->hwmodes); | 962 | rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; |
982 | rt2x00dev->hwmodes = NULL; | 963 | rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; |
983 | } | 964 | } |
984 | } | 965 | } |
985 | 966 | ||
@@ -1012,86 +993,6 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1012 | /* | 993 | /* |
1013 | * Initialization/uninitialization handlers. | 994 | * Initialization/uninitialization handlers. |
1014 | */ | 995 | */ |
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) | 996 | static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) |
1096 | { | 997 | { |
1097 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) | 998 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) |
@@ -1108,9 +1009,9 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
1108 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); | 1009 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); |
1109 | 1010 | ||
1110 | /* | 1011 | /* |
1111 | * Free allocated ring entries. | 1012 | * Free allocated queue entries. |
1112 | */ | 1013 | */ |
1113 | rt2x00lib_free_ring_entries(rt2x00dev); | 1014 | rt2x00queue_uninitialize(rt2x00dev); |
1114 | } | 1015 | } |
1115 | 1016 | ||
1116 | static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | 1017 | static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) |
@@ -1121,13 +1022,11 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1121 | return 0; | 1022 | return 0; |
1122 | 1023 | ||
1123 | /* | 1024 | /* |
1124 | * Allocate all ring entries. | 1025 | * Allocate all queue entries. |
1125 | */ | 1026 | */ |
1126 | status = rt2x00lib_alloc_ring_entries(rt2x00dev); | 1027 | status = rt2x00queue_initialize(rt2x00dev); |
1127 | if (status) { | 1028 | if (status) |
1128 | ERROR(rt2x00dev, "Ring entries allocation failed.\n"); | ||
1129 | return status; | 1029 | return status; |
1130 | } | ||
1131 | 1030 | ||
1132 | /* | 1031 | /* |
1133 | * Initialize the device. | 1032 | * Initialize the device. |
@@ -1146,7 +1045,7 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1146 | return 0; | 1045 | return 0; |
1147 | 1046 | ||
1148 | exit: | 1047 | exit: |
1149 | rt2x00lib_free_ring_entries(rt2x00dev); | 1048 | rt2x00lib_uninitialize(rt2x00dev); |
1150 | 1049 | ||
1151 | return status; | 1050 | return status; |
1152 | } | 1051 | } |
@@ -1162,11 +1061,9 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
1162 | * If this is the first interface which is added, | 1061 | * If this is the first interface which is added, |
1163 | * we should load the firmware now. | 1062 | * we should load the firmware now. |
1164 | */ | 1063 | */ |
1165 | if (test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) { | 1064 | retval = rt2x00lib_load_firmware(rt2x00dev); |
1166 | retval = rt2x00lib_load_firmware(rt2x00dev); | 1065 | if (retval) |
1167 | if (retval) | 1066 | return retval; |
1168 | return retval; | ||
1169 | } | ||
1170 | 1067 | ||
1171 | /* | 1068 | /* |
1172 | * Initialize the device. | 1069 | * Initialize the device. |
@@ -1184,6 +1081,10 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
1184 | return retval; | 1081 | return retval; |
1185 | } | 1082 | } |
1186 | 1083 | ||
1084 | rt2x00dev->intf_ap_count = 0; | ||
1085 | rt2x00dev->intf_sta_count = 0; | ||
1086 | rt2x00dev->intf_associated = 0; | ||
1087 | |||
1187 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1088 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1188 | 1089 | ||
1189 | return 0; | 1090 | return 0; |
@@ -1200,74 +1101,25 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) | |||
1200 | */ | 1101 | */ |
1201 | rt2x00lib_disable_radio(rt2x00dev); | 1102 | rt2x00lib_disable_radio(rt2x00dev); |
1202 | 1103 | ||
1104 | rt2x00dev->intf_ap_count = 0; | ||
1105 | rt2x00dev->intf_sta_count = 0; | ||
1106 | rt2x00dev->intf_associated = 0; | ||
1107 | |||
1203 | __clear_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1108 | __clear_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1204 | } | 1109 | } |
1205 | 1110 | ||
1206 | /* | 1111 | /* |
1207 | * driver allocation handlers. | 1112 | * driver allocation handlers. |
1208 | */ | 1113 | */ |
1209 | static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev) | 1114 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) |
1210 | { | 1115 | { |
1211 | struct data_ring *ring; | 1116 | 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 | |||
1230 | /* | ||
1231 | * Initialize pointers | ||
1232 | */ | ||
1233 | rt2x00dev->rx = ring; | ||
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 | 1117 | ||
1238 | /* | 1118 | /* |
1239 | * Initialize ring parameters. | 1119 | * Make room for rt2x00_intf inside the per-interface |
1240 | * RX: queue_idx = 0 | 1120 | * structure ieee80211_vif. |
1241 | * TX: queue_idx = IEEE80211_TX_QUEUE_DATA0 + index | ||
1242 | * TX: cw_min: 2^5 = 32. | ||
1243 | * TX: cw_max: 2^10 = 1024. | ||
1244 | */ | 1121 | */ |
1245 | rt2x00dev->rx->rt2x00dev = rt2x00dev; | 1122 | rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); |
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 | 1123 | ||
1272 | /* | 1124 | /* |
1273 | * Let the driver probe the device to detect the capabilities. | 1125 | * Let the driver probe the device to detect the capabilities. |
@@ -1281,20 +1133,14 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1281 | /* | 1133 | /* |
1282 | * Initialize configuration work. | 1134 | * Initialize configuration work. |
1283 | */ | 1135 | */ |
1284 | INIT_WORK(&rt2x00dev->beacon_work, rt2x00lib_beacondone_scheduled); | 1136 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1285 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); | 1137 | 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); | 1138 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); |
1288 | 1139 | ||
1289 | /* | 1140 | /* |
1290 | * Reset current working type. | 1141 | * Allocate queue array. |
1291 | */ | ||
1292 | rt2x00dev->interface.type = IEEE80211_IF_TYPE_INVALID; | ||
1293 | |||
1294 | /* | ||
1295 | * Allocate ring array. | ||
1296 | */ | 1142 | */ |
1297 | retval = rt2x00lib_alloc_rings(rt2x00dev); | 1143 | retval = rt2x00queue_allocate(rt2x00dev); |
1298 | if (retval) | 1144 | if (retval) |
1299 | goto exit; | 1145 | goto exit; |
1300 | 1146 | ||
@@ -1310,6 +1156,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1310 | /* | 1156 | /* |
1311 | * Register extra components. | 1157 | * Register extra components. |
1312 | */ | 1158 | */ |
1159 | rt2x00leds_register(rt2x00dev); | ||
1313 | rt2x00rfkill_allocate(rt2x00dev); | 1160 | rt2x00rfkill_allocate(rt2x00dev); |
1314 | rt2x00debug_register(rt2x00dev); | 1161 | rt2x00debug_register(rt2x00dev); |
1315 | 1162 | ||
@@ -1343,6 +1190,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1343 | */ | 1190 | */ |
1344 | rt2x00debug_deregister(rt2x00dev); | 1191 | rt2x00debug_deregister(rt2x00dev); |
1345 | rt2x00rfkill_free(rt2x00dev); | 1192 | rt2x00rfkill_free(rt2x00dev); |
1193 | rt2x00leds_unregister(rt2x00dev); | ||
1346 | 1194 | ||
1347 | /* | 1195 | /* |
1348 | * Free ieee80211_hw memory. | 1196 | * Free ieee80211_hw memory. |
@@ -1355,9 +1203,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1355 | rt2x00lib_free_firmware(rt2x00dev); | 1203 | rt2x00lib_free_firmware(rt2x00dev); |
1356 | 1204 | ||
1357 | /* | 1205 | /* |
1358 | * Free ring structures. | 1206 | * Free queue structures. |
1359 | */ | 1207 | */ |
1360 | rt2x00lib_free_rings(rt2x00dev); | 1208 | rt2x00queue_free(rt2x00dev); |
1361 | } | 1209 | } |
1362 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); | 1210 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); |
1363 | 1211 | ||
@@ -1388,6 +1236,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | |||
1388 | /* | 1236 | /* |
1389 | * Suspend/disable extra components. | 1237 | * Suspend/disable extra components. |
1390 | */ | 1238 | */ |
1239 | rt2x00leds_suspend(rt2x00dev); | ||
1391 | rt2x00rfkill_suspend(rt2x00dev); | 1240 | rt2x00rfkill_suspend(rt2x00dev); |
1392 | rt2x00debug_deregister(rt2x00dev); | 1241 | rt2x00debug_deregister(rt2x00dev); |
1393 | 1242 | ||
@@ -1412,9 +1261,30 @@ exit: | |||
1412 | } | 1261 | } |
1413 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); | 1262 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); |
1414 | 1263 | ||
1264 | static void rt2x00lib_resume_intf(void *data, u8 *mac, | ||
1265 | struct ieee80211_vif *vif) | ||
1266 | { | ||
1267 | struct rt2x00_dev *rt2x00dev = data; | ||
1268 | struct rt2x00_intf *intf = vif_to_intf(vif); | ||
1269 | |||
1270 | spin_lock(&intf->lock); | ||
1271 | |||
1272 | rt2x00lib_config_intf(rt2x00dev, intf, | ||
1273 | vif->type, intf->mac, intf->bssid); | ||
1274 | |||
1275 | |||
1276 | /* | ||
1277 | * Master or Ad-hoc mode require a new beacon update. | ||
1278 | */ | ||
1279 | if (vif->type == IEEE80211_IF_TYPE_AP || | ||
1280 | vif->type == IEEE80211_IF_TYPE_IBSS) | ||
1281 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; | ||
1282 | |||
1283 | spin_unlock(&intf->lock); | ||
1284 | } | ||
1285 | |||
1415 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | 1286 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) |
1416 | { | 1287 | { |
1417 | struct interface *intf = &rt2x00dev->interface; | ||
1418 | int retval; | 1288 | int retval; |
1419 | 1289 | ||
1420 | NOTICE(rt2x00dev, "Waking up.\n"); | 1290 | NOTICE(rt2x00dev, "Waking up.\n"); |
@@ -1424,6 +1294,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1424 | */ | 1294 | */ |
1425 | rt2x00debug_register(rt2x00dev); | 1295 | rt2x00debug_register(rt2x00dev); |
1426 | rt2x00rfkill_resume(rt2x00dev); | 1296 | rt2x00rfkill_resume(rt2x00dev); |
1297 | rt2x00leds_resume(rt2x00dev); | ||
1427 | 1298 | ||
1428 | /* | 1299 | /* |
1429 | * Only continue if mac80211 had open interfaces. | 1300 | * Only continue if mac80211 had open interfaces. |
@@ -1445,9 +1316,12 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1445 | if (!rt2x00dev->hw->conf.radio_enabled) | 1316 | if (!rt2x00dev->hw->conf.radio_enabled) |
1446 | rt2x00lib_disable_radio(rt2x00dev); | 1317 | rt2x00lib_disable_radio(rt2x00dev); |
1447 | 1318 | ||
1448 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 1319 | /* |
1449 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 1320 | * Iterator over each active interface to |
1450 | rt2x00lib_config_type(rt2x00dev, intf->type); | 1321 | * reconfigure the hardware. |
1322 | */ | ||
1323 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | ||
1324 | rt2x00lib_resume_intf, rt2x00dev); | ||
1451 | 1325 | ||
1452 | /* | 1326 | /* |
1453 | * We are ready again to receive requests from mac80211. | 1327 | * We are ready again to receive requests from mac80211. |
@@ -1463,12 +1337,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1463 | ieee80211_start_queues(rt2x00dev->hw); | 1337 | ieee80211_start_queues(rt2x00dev->hw); |
1464 | 1338 | ||
1465 | /* | 1339 | /* |
1466 | * When in Master or Ad-hoc mode, | 1340 | * During interface iteration we might have changed the |
1467 | * restart Beacon transmitting by faking a beacondone event. | 1341 | * delayed_flags, time to handles the event by calling |
1342 | * the work handler directly. | ||
1468 | */ | 1343 | */ |
1469 | if (intf->type == IEEE80211_IF_TYPE_AP || | 1344 | rt2x00lib_intf_scheduled(&rt2x00dev->intf_work); |
1470 | intf->type == IEEE80211_IF_TYPE_IBSS) | ||
1471 | rt2x00lib_beacondone(rt2x00dev); | ||
1472 | 1345 | ||
1473 | return 0; | 1346 | return 0; |
1474 | 1347 | ||
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..40c1f5c1b805 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c | |||
@@ -0,0 +1,219 @@ | |||
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 | struct rt2x00_led *led = &rt2x00dev->led_qual; | ||
35 | unsigned int brightness; | ||
36 | |||
37 | if ((led->type != LED_TYPE_QUALITY) || !(led->flags & LED_REGISTERED)) | ||
38 | return; | ||
39 | |||
40 | /* | ||
41 | * Led handling requires a positive value for the rssi, | ||
42 | * to do that correctly we need to add the correction. | ||
43 | */ | ||
44 | rssi += rt2x00dev->rssi_offset; | ||
45 | |||
46 | /* | ||
47 | * Get the rssi level, this is used to convert the rssi | ||
48 | * to a LED value inside the range LED_OFF - LED_FULL. | ||
49 | */ | ||
50 | if (rssi <= 30) | ||
51 | rssi = 0; | ||
52 | else if (rssi <= 39) | ||
53 | rssi = 1; | ||
54 | else if (rssi <= 49) | ||
55 | rssi = 2; | ||
56 | else if (rssi <= 53) | ||
57 | rssi = 3; | ||
58 | else if (rssi <= 63) | ||
59 | rssi = 4; | ||
60 | else | ||
61 | rssi = 5; | ||
62 | |||
63 | /* | ||
64 | * Note that we must _not_ send LED_OFF since the driver | ||
65 | * is going to calculate the value and might use it in a | ||
66 | * division. | ||
67 | */ | ||
68 | brightness = ((LED_FULL / 6) * rssi) + 1; | ||
69 | if (brightness != led->led_dev.brightness) { | ||
70 | led->led_dev.brightness_set(&led->led_dev, brightness); | ||
71 | led->led_dev.brightness = brightness; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled) | ||
76 | { | ||
77 | struct rt2x00_led *led = &rt2x00dev->led_assoc; | ||
78 | unsigned int brightness; | ||
79 | |||
80 | if ((led->type != LED_TYPE_ASSOC) || !(led->flags & LED_REGISTERED)) | ||
81 | return; | ||
82 | |||
83 | brightness = enabled ? LED_FULL : LED_OFF; | ||
84 | if (brightness != led->led_dev.brightness) { | ||
85 | led->led_dev.brightness_set(&led->led_dev, brightness); | ||
86 | led->led_dev.brightness = brightness; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled) | ||
91 | { | ||
92 | struct rt2x00_led *led = &rt2x00dev->led_radio; | ||
93 | unsigned int brightness; | ||
94 | |||
95 | if ((led->type != LED_TYPE_RADIO) || !(led->flags & LED_REGISTERED)) | ||
96 | return; | ||
97 | |||
98 | brightness = enabled ? LED_FULL : LED_OFF; | ||
99 | if (brightness != led->led_dev.brightness) { | ||
100 | led->led_dev.brightness_set(&led->led_dev, brightness); | ||
101 | led->led_dev.brightness = brightness; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, | ||
106 | struct rt2x00_led *led, | ||
107 | const char *name) | ||
108 | { | ||
109 | struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); | ||
110 | int retval; | ||
111 | |||
112 | led->led_dev.name = name; | ||
113 | |||
114 | retval = led_classdev_register(device, &led->led_dev); | ||
115 | if (retval) { | ||
116 | ERROR(rt2x00dev, "Failed to register led handler.\n"); | ||
117 | return retval; | ||
118 | } | ||
119 | |||
120 | led->flags |= LED_REGISTERED; | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | void rt2x00leds_register(struct rt2x00_dev *rt2x00dev) | ||
126 | { | ||
127 | char dev_name[16]; | ||
128 | char name[32]; | ||
129 | int retval; | ||
130 | unsigned long on_period; | ||
131 | unsigned long off_period; | ||
132 | |||
133 | snprintf(dev_name, sizeof(dev_name), "%s-%s", | ||
134 | rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy)); | ||
135 | |||
136 | if (rt2x00dev->led_radio.flags & LED_INITIALIZED) { | ||
137 | snprintf(name, sizeof(name), "%s:radio", dev_name); | ||
138 | |||
139 | retval = rt2x00leds_register_led(rt2x00dev, | ||
140 | &rt2x00dev->led_radio, | ||
141 | name); | ||
142 | if (retval) | ||
143 | goto exit_fail; | ||
144 | } | ||
145 | |||
146 | if (rt2x00dev->led_assoc.flags & LED_INITIALIZED) { | ||
147 | snprintf(name, sizeof(name), "%s:assoc", dev_name); | ||
148 | |||
149 | retval = rt2x00leds_register_led(rt2x00dev, | ||
150 | &rt2x00dev->led_assoc, | ||
151 | name); | ||
152 | if (retval) | ||
153 | goto exit_fail; | ||
154 | } | ||
155 | |||
156 | if (rt2x00dev->led_qual.flags & LED_INITIALIZED) { | ||
157 | snprintf(name, sizeof(name), "%s:quality", dev_name); | ||
158 | |||
159 | retval = rt2x00leds_register_led(rt2x00dev, | ||
160 | &rt2x00dev->led_qual, | ||
161 | name); | ||
162 | if (retval) | ||
163 | goto exit_fail; | ||
164 | } | ||
165 | |||
166 | /* | ||
167 | * Initialize blink time to default value: | ||
168 | * On period: 70ms | ||
169 | * Off period: 30ms | ||
170 | */ | ||
171 | if (rt2x00dev->led_radio.led_dev.blink_set) { | ||
172 | on_period = 70; | ||
173 | off_period = 30; | ||
174 | rt2x00dev->led_radio.led_dev.blink_set( | ||
175 | &rt2x00dev->led_radio.led_dev, &on_period, &off_period); | ||
176 | } | ||
177 | |||
178 | return; | ||
179 | |||
180 | exit_fail: | ||
181 | rt2x00leds_unregister(rt2x00dev); | ||
182 | } | ||
183 | |||
184 | static void rt2x00leds_unregister_led(struct rt2x00_led *led) | ||
185 | { | ||
186 | led_classdev_unregister(&led->led_dev); | ||
187 | led->led_dev.brightness_set(&led->led_dev, LED_OFF); | ||
188 | led->flags &= ~LED_REGISTERED; | ||
189 | } | ||
190 | |||
191 | void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) | ||
192 | { | ||
193 | if (rt2x00dev->led_qual.flags & LED_REGISTERED) | ||
194 | rt2x00leds_unregister_led(&rt2x00dev->led_qual); | ||
195 | if (rt2x00dev->led_assoc.flags & LED_REGISTERED) | ||
196 | rt2x00leds_unregister_led(&rt2x00dev->led_assoc); | ||
197 | if (rt2x00dev->led_radio.flags & LED_REGISTERED) | ||
198 | rt2x00leds_unregister_led(&rt2x00dev->led_radio); | ||
199 | } | ||
200 | |||
201 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) | ||
202 | { | ||
203 | if (rt2x00dev->led_qual.flags & LED_REGISTERED) | ||
204 | led_classdev_suspend(&rt2x00dev->led_qual.led_dev); | ||
205 | if (rt2x00dev->led_assoc.flags & LED_REGISTERED) | ||
206 | led_classdev_suspend(&rt2x00dev->led_assoc.led_dev); | ||
207 | if (rt2x00dev->led_radio.flags & LED_REGISTERED) | ||
208 | led_classdev_suspend(&rt2x00dev->led_radio.led_dev); | ||
209 | } | ||
210 | |||
211 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) | ||
212 | { | ||
213 | if (rt2x00dev->led_radio.flags & LED_REGISTERED) | ||
214 | led_classdev_resume(&rt2x00dev->led_radio.led_dev); | ||
215 | if (rt2x00dev->led_assoc.flags & LED_REGISTERED) | ||
216 | led_classdev_resume(&rt2x00dev->led_assoc.led_dev); | ||
217 | if (rt2x00dev->led_qual.flags & LED_REGISTERED) | ||
218 | led_classdev_resume(&rt2x00dev->led_qual.led_dev); | ||
219 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.h b/drivers/net/wireless/rt2x00/rt2x00leds.h new file mode 100644 index 000000000000..9df4a49bdcad --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00leds.h | |||
@@ -0,0 +1,50 @@ | |||
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 | enum led_type { | ||
30 | LED_TYPE_RADIO, | ||
31 | LED_TYPE_ASSOC, | ||
32 | LED_TYPE_ACTIVITY, | ||
33 | LED_TYPE_QUALITY, | ||
34 | }; | ||
35 | |||
36 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
37 | |||
38 | struct rt2x00_led { | ||
39 | struct rt2x00_dev *rt2x00dev; | ||
40 | struct led_classdev led_dev; | ||
41 | |||
42 | enum led_type type; | ||
43 | unsigned int flags; | ||
44 | #define LED_INITIALIZED ( 1 << 0 ) | ||
45 | #define LED_REGISTERED ( 1 << 1 ) | ||
46 | }; | ||
47 | |||
48 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
49 | |||
50 | #endif /* RT2X00LEDS_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index ce58c654ade1..5be32fffc74c 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,48 @@ 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_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled); | ||
189 | void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled); | ||
190 | void rt2x00leds_register(struct rt2x00_dev *rt2x00dev); | ||
191 | void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev); | ||
192 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev); | ||
193 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev); | ||
194 | #else | ||
195 | static inline void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, | ||
196 | int rssi) | ||
197 | { | ||
198 | } | ||
199 | |||
200 | static inline void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, | ||
201 | bool enabled) | ||
202 | { | ||
203 | } | ||
204 | |||
205 | static inline void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, | ||
206 | bool enabled) | ||
207 | { | ||
208 | } | ||
209 | |||
210 | static inline void rt2x00leds_register(struct rt2x00_dev *rt2x00dev) | ||
211 | { | ||
212 | } | ||
213 | |||
214 | static inline void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) | ||
215 | { | ||
216 | } | ||
217 | |||
218 | static inline void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) | ||
219 | { | ||
220 | } | ||
221 | |||
222 | static inline void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) | ||
223 | { | ||
224 | } | ||
225 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
226 | |||
135 | #endif /* RT2X00LIB_H */ | 227 | #endif /* RT2X00LIB_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index e3f15e518c76..c206b5092070 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))) | ||
206 | return -ENOBUFS; | ||
207 | |||
208 | /* | ||
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)) | ||
182 | return -ENOBUFS; | 215 | return -ENOBUFS; |
183 | 216 | ||
184 | intf->id = conf->vif; | 217 | /* |
185 | intf->type = conf->type; | 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,14 @@ 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); | 255 | |
256 | /* | ||
257 | * Some filters depend on the current working mode. We can force | ||
258 | * an update during the next configure_filter() run by mac80211 by | ||
259 | * resetting the current packet_filter state. | ||
260 | */ | ||
261 | rt2x00dev->packet_filter = 0; | ||
197 | 262 | ||
198 | return 0; | 263 | return 0; |
199 | } | 264 | } |
@@ -203,7 +268,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
203 | struct ieee80211_if_init_conf *conf) | 268 | struct ieee80211_if_init_conf *conf) |
204 | { | 269 | { |
205 | struct rt2x00_dev *rt2x00dev = hw->priv; | 270 | struct rt2x00_dev *rt2x00dev = hw->priv; |
206 | struct interface *intf = &rt2x00dev->interface; | 271 | struct rt2x00_intf *intf = vif_to_intf(conf->vif); |
207 | 272 | ||
208 | /* | 273 | /* |
209 | * Don't allow interfaces to be remove while | 274 | * Don't allow interfaces to be remove while |
@@ -211,21 +276,27 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
211 | * no interface is present. | 276 | * no interface is present. |
212 | */ | 277 | */ |
213 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 278 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || |
214 | !is_interface_present(intf)) | 279 | (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) || |
280 | (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count)) | ||
215 | return; | 281 | return; |
216 | 282 | ||
217 | intf->id = 0; | 283 | if (conf->type == IEEE80211_IF_TYPE_AP) |
218 | intf->type = IEEE80211_IF_TYPE_INVALID; | 284 | rt2x00dev->intf_ap_count--; |
219 | memset(&intf->bssid, 0x00, ETH_ALEN); | 285 | else |
220 | memset(&intf->mac, 0x00, ETH_ALEN); | 286 | rt2x00dev->intf_sta_count--; |
287 | |||
288 | /* | ||
289 | * Release beacon entry so it is available for | ||
290 | * new interfaces again. | ||
291 | */ | ||
292 | __clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); | ||
221 | 293 | ||
222 | /* | 294 | /* |
223 | * Make sure the bssid and mac address registers | 295 | * Make sure the bssid and mac address registers |
224 | * are cleared to prevent false ACKing of frames. | 296 | * are cleared to prevent false ACKing of frames. |
225 | */ | 297 | */ |
226 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 298 | rt2x00lib_config_intf(rt2x00dev, intf, |
227 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 299 | IEEE80211_IF_TYPE_INVALID, NULL, NULL); |
228 | rt2x00lib_config_type(rt2x00dev, intf->type); | ||
229 | } | 300 | } |
230 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); | 301 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); |
231 | 302 | ||
@@ -270,7 +341,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
270 | struct ieee80211_if_conf *conf) | 341 | struct ieee80211_if_conf *conf) |
271 | { | 342 | { |
272 | struct rt2x00_dev *rt2x00dev = hw->priv; | 343 | struct rt2x00_dev *rt2x00dev = hw->priv; |
273 | struct interface *intf = &rt2x00dev->interface; | 344 | struct rt2x00_intf *intf = vif_to_intf(vif); |
274 | int status; | 345 | int status; |
275 | 346 | ||
276 | /* | 347 | /* |
@@ -280,12 +351,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
280 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) | 351 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) |
281 | return 0; | 352 | return 0; |
282 | 353 | ||
283 | /* | 354 | 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 | 355 | ||
290 | /* | 356 | /* |
291 | * If the interface does not work in master mode, | 357 | * If the interface does not work in master mode, |
@@ -294,7 +360,16 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
294 | */ | 360 | */ |
295 | if (conf->type != IEEE80211_IF_TYPE_AP) | 361 | if (conf->type != IEEE80211_IF_TYPE_AP) |
296 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); | 362 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); |
297 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 363 | |
364 | spin_unlock(&intf->lock); | ||
365 | |||
366 | /* | ||
367 | * Call rt2x00_config_intf() outside of the spinlock context since | ||
368 | * the call will sleep for USB drivers. By using the ieee80211_if_conf | ||
369 | * values as arguments we make keep access to rt2x00_intf thread safe | ||
370 | * even without the lock. | ||
371 | */ | ||
372 | rt2x00lib_config_intf(rt2x00dev, intf, conf->type, NULL, conf->bssid); | ||
298 | 373 | ||
299 | /* | 374 | /* |
300 | * We only need to initialize the beacon when master mode is enabled. | 375 | * We only need to initialize the beacon when master mode is enabled. |
@@ -312,6 +387,50 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
312 | } | 387 | } |
313 | EXPORT_SYMBOL_GPL(rt2x00mac_config_interface); | 388 | EXPORT_SYMBOL_GPL(rt2x00mac_config_interface); |
314 | 389 | ||
390 | void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | ||
391 | unsigned int changed_flags, | ||
392 | unsigned int *total_flags, | ||
393 | int mc_count, struct dev_addr_list *mc_list) | ||
394 | { | ||
395 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
396 | |||
397 | /* | ||
398 | * Mask off any flags we are going to ignore | ||
399 | * from the total_flags field. | ||
400 | */ | ||
401 | *total_flags &= | ||
402 | FIF_ALLMULTI | | ||
403 | FIF_FCSFAIL | | ||
404 | FIF_PLCPFAIL | | ||
405 | FIF_CONTROL | | ||
406 | FIF_OTHER_BSS | | ||
407 | FIF_PROMISC_IN_BSS; | ||
408 | |||
409 | /* | ||
410 | * Apply some rules to the filters: | ||
411 | * - Some filters imply different filters to be set. | ||
412 | * - Some things we can't filter out at all. | ||
413 | * - Multicast filter seems to kill broadcast traffic so never use it. | ||
414 | */ | ||
415 | *total_flags |= FIF_ALLMULTI; | ||
416 | if (*total_flags & FIF_OTHER_BSS || | ||
417 | *total_flags & FIF_PROMISC_IN_BSS) | ||
418 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
419 | |||
420 | /* | ||
421 | * Check if there is any work left for us. | ||
422 | */ | ||
423 | if (rt2x00dev->packet_filter == *total_flags) | ||
424 | return; | ||
425 | rt2x00dev->packet_filter = *total_flags; | ||
426 | |||
427 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) | ||
428 | rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); | ||
429 | else | ||
430 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); | ||
431 | } | ||
432 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); | ||
433 | |||
315 | int rt2x00mac_get_stats(struct ieee80211_hw *hw, | 434 | int rt2x00mac_get_stats(struct ieee80211_hw *hw, |
316 | struct ieee80211_low_level_stats *stats) | 435 | struct ieee80211_low_level_stats *stats) |
317 | { | 436 | { |
@@ -334,9 +453,11 @@ int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, | |||
334 | struct rt2x00_dev *rt2x00dev = hw->priv; | 453 | struct rt2x00_dev *rt2x00dev = hw->priv; |
335 | unsigned int i; | 454 | unsigned int i; |
336 | 455 | ||
337 | for (i = 0; i < hw->queues; i++) | 456 | for (i = 0; i < hw->queues; i++) { |
338 | memcpy(&stats->data[i], &rt2x00dev->tx[i].stats, | 457 | stats->data[i].len = rt2x00dev->tx[i].length; |
339 | sizeof(rt2x00dev->tx[i].stats)); | 458 | stats->data[i].limit = rt2x00dev->tx[i].limit; |
459 | stats->data[i].count = rt2x00dev->tx[i].count; | ||
460 | } | ||
340 | 461 | ||
341 | return 0; | 462 | return 0; |
342 | } | 463 | } |
@@ -348,71 +469,83 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
348 | u32 changes) | 469 | u32 changes) |
349 | { | 470 | { |
350 | struct rt2x00_dev *rt2x00dev = hw->priv; | 471 | struct rt2x00_dev *rt2x00dev = hw->priv; |
351 | int short_preamble; | 472 | struct rt2x00_intf *intf = vif_to_intf(vif); |
352 | int ack_timeout; | 473 | unsigned int delayed = 0; |
353 | int ack_consume_time; | ||
354 | int difs; | ||
355 | int preamble; | ||
356 | 474 | ||
357 | /* | 475 | /* |
358 | * We only support changing preamble mode. | 476 | * When the association status has changed we must reset the link |
477 | * tuner counter. This is because some drivers determine if they | ||
478 | * should perform link tuning based on the number of seconds | ||
479 | * while associated or not associated. | ||
359 | */ | 480 | */ |
360 | if (!(changes & BSS_CHANGED_ERP_PREAMBLE)) | 481 | if (changes & BSS_CHANGED_ASSOC) { |
361 | return; | 482 | 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 | 483 | ||
367 | difs = (hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | 484 | if (bss_conf->assoc) |
368 | SHORT_DIFS : DIFS; | 485 | rt2x00dev->intf_associated++; |
369 | ack_timeout = difs + PLCP + preamble + get_duration(ACK_SIZE, 10); | 486 | else |
487 | rt2x00dev->intf_associated--; | ||
370 | 488 | ||
371 | ack_consume_time = SIFS + PLCP + preamble + get_duration(ACK_SIZE, 10); | 489 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) |
490 | rt2x00leds_led_assoc(rt2x00dev, | ||
491 | !!rt2x00dev->intf_associated); | ||
492 | else | ||
493 | delayed |= DELAYED_LED_ASSOC; | ||
494 | } | ||
372 | 495 | ||
373 | if (short_preamble) | 496 | /* |
374 | __set_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 497 | * When the erp information has changed, we should perform |
375 | else | 498 | * additional configuration steps. For all other changes we are done. |
376 | __clear_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 499 | */ |
500 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | ||
501 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) | ||
502 | rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); | ||
503 | else | ||
504 | delayed |= DELAYED_CONFIG_ERP; | ||
505 | } | ||
377 | 506 | ||
378 | rt2x00dev->ops->lib->config_preamble(rt2x00dev, short_preamble, | 507 | spin_lock(&intf->lock); |
379 | ack_timeout, ack_consume_time); | 508 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); |
509 | if (delayed) { | ||
510 | intf->delayed_flags |= delayed; | ||
511 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | ||
512 | } | ||
513 | spin_unlock(&intf->lock); | ||
380 | } | 514 | } |
381 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); | 515 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); |
382 | 516 | ||
383 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, | 517 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue_idx, |
384 | const struct ieee80211_tx_queue_params *params) | 518 | const struct ieee80211_tx_queue_params *params) |
385 | { | 519 | { |
386 | struct rt2x00_dev *rt2x00dev = hw->priv; | 520 | struct rt2x00_dev *rt2x00dev = hw->priv; |
387 | struct data_ring *ring; | 521 | struct data_queue *queue; |
388 | 522 | ||
389 | ring = rt2x00lib_get_ring(rt2x00dev, queue); | 523 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
390 | if (unlikely(!ring)) | 524 | if (unlikely(!queue)) |
391 | return -EINVAL; | 525 | return -EINVAL; |
392 | 526 | ||
393 | /* | 527 | /* |
394 | * The passed variables are stored as real value ((2^n)-1). | 528 | * The passed variables are stored as real value ((2^n)-1). |
395 | * Ralink registers require to know the bit number 'n'. | 529 | * Ralink registers require to know the bit number 'n'. |
396 | */ | 530 | */ |
397 | if (params->cw_min) | 531 | if (params->cw_min > 0) |
398 | ring->tx_params.cw_min = fls(params->cw_min); | 532 | queue->cw_min = fls(params->cw_min); |
399 | else | 533 | else |
400 | ring->tx_params.cw_min = 5; /* cw_min: 2^5 = 32. */ | 534 | queue->cw_min = 5; /* cw_min: 2^5 = 32. */ |
401 | 535 | ||
402 | if (params->cw_max) | 536 | if (params->cw_max > 0) |
403 | ring->tx_params.cw_max = fls(params->cw_max); | 537 | queue->cw_max = fls(params->cw_max); |
404 | else | 538 | else |
405 | ring->tx_params.cw_max = 10; /* cw_min: 2^10 = 1024. */ | 539 | queue->cw_max = 10; /* cw_min: 2^10 = 1024. */ |
406 | 540 | ||
407 | if (params->aifs) | 541 | if (params->aifs >= 0) |
408 | ring->tx_params.aifs = params->aifs; | 542 | queue->aifs = params->aifs; |
409 | else | 543 | else |
410 | ring->tx_params.aifs = 2; | 544 | queue->aifs = 2; |
411 | 545 | ||
412 | INFO(rt2x00dev, | 546 | INFO(rt2x00dev, |
413 | "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", | 547 | "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", |
414 | queue, ring->tx_params.cw_min, ring->tx_params.cw_max, | 548 | queue_idx, queue->cw_min, queue->cw_max, queue->aifs); |
415 | ring->tx_params.aifs); | ||
416 | 549 | ||
417 | return 0; | 550 | return 0; |
418 | } | 551 | } |
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..7027c9f47d3f --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -0,0 +1,468 @@ | |||
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 | * enum rxdone_entry_desc_flags: Flags for &struct rxdone_entry_desc | ||
133 | * | ||
134 | * @RXDONE_SIGNAL_PLCP: Does the signal field contain the plcp value, | ||
135 | * or does it contain the bitrate itself. | ||
136 | * @RXDONE_MY_BSS: Does this frame originate from device's BSS. | ||
137 | */ | ||
138 | enum rxdone_entry_desc_flags { | ||
139 | RXDONE_SIGNAL_PLCP = 1 << 0, | ||
140 | RXDONE_MY_BSS = 1 << 1, | ||
141 | }; | ||
142 | |||
143 | /** | ||
144 | * struct rxdone_entry_desc: RX Entry descriptor | ||
145 | * | ||
146 | * Summary of information that has been read from the RX frame descriptor. | ||
147 | * | ||
148 | * @signal: Signal of the received frame. | ||
149 | * @rssi: RSSI of the received frame. | ||
150 | * @size: Data size of the received frame. | ||
151 | * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). | ||
152 | * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). | ||
153 | |||
154 | */ | ||
155 | struct rxdone_entry_desc { | ||
156 | int signal; | ||
157 | int rssi; | ||
158 | int size; | ||
159 | int flags; | ||
160 | int dev_flags; | ||
161 | }; | ||
162 | |||
163 | /** | ||
164 | * struct txdone_entry_desc: TX done entry descriptor | ||
165 | * | ||
166 | * Summary of information that has been read from the TX frame descriptor | ||
167 | * after the device is done with transmission. | ||
168 | * | ||
169 | * @control: Control structure which was used to transmit the frame. | ||
170 | * @status: TX status (See &enum tx_status). | ||
171 | * @retry: Retry count. | ||
172 | */ | ||
173 | struct txdone_entry_desc { | ||
174 | struct ieee80211_tx_control *control; | ||
175 | int status; | ||
176 | int retry; | ||
177 | }; | ||
178 | |||
179 | /** | ||
180 | * enum txentry_desc_flags: Status flags for TX entry descriptor | ||
181 | * | ||
182 | * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame. | ||
183 | * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate. | ||
184 | * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment. | ||
185 | * @ENTRY_TXD_REQ_TIMESTAMP: Require timestamp to be inserted. | ||
186 | * @ENTRY_TXD_BURST: This frame belongs to the same burst event. | ||
187 | * @ENTRY_TXD_ACK: An ACK is required for this frame. | ||
188 | */ | ||
189 | enum txentry_desc_flags { | ||
190 | ENTRY_TXD_RTS_FRAME, | ||
191 | ENTRY_TXD_OFDM_RATE, | ||
192 | ENTRY_TXD_MORE_FRAG, | ||
193 | ENTRY_TXD_REQ_TIMESTAMP, | ||
194 | ENTRY_TXD_BURST, | ||
195 | ENTRY_TXD_ACK, | ||
196 | }; | ||
197 | |||
198 | /** | ||
199 | * struct txentry_desc: TX Entry descriptor | ||
200 | * | ||
201 | * Summary of information for the frame descriptor before sending a TX frame. | ||
202 | * | ||
203 | * @flags: Descriptor flags (See &enum queue_entry_flags). | ||
204 | * @queue: Queue identification (See &enum data_queue_qid). | ||
205 | * @length_high: PLCP length high word. | ||
206 | * @length_low: PLCP length low word. | ||
207 | * @signal: PLCP signal. | ||
208 | * @service: PLCP service. | ||
209 | * @aifs: AIFS value. | ||
210 | * @ifs: IFS value. | ||
211 | * @cw_min: cwmin value. | ||
212 | * @cw_max: cwmax value. | ||
213 | */ | ||
214 | struct txentry_desc { | ||
215 | unsigned long flags; | ||
216 | |||
217 | enum data_queue_qid queue; | ||
218 | |||
219 | u16 length_high; | ||
220 | u16 length_low; | ||
221 | u16 signal; | ||
222 | u16 service; | ||
223 | |||
224 | int aifs; | ||
225 | int ifs; | ||
226 | int cw_min; | ||
227 | int cw_max; | ||
228 | }; | ||
229 | |||
230 | /** | ||
231 | * enum queue_entry_flags: Status flags for queue entry | ||
232 | * | ||
233 | * @ENTRY_BCN_ASSIGNED: This entry has been assigned to an interface. | ||
234 | * As long as this bit is set, this entry may only be touched | ||
235 | * through the interface structure. | ||
236 | * @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data | ||
237 | * transfer (either TX or RX depending on the queue). The entry should | ||
238 | * only be touched after the device has signaled it is done with it. | ||
239 | * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data | ||
240 | * encryption or decryption. The entry should only be touched after | ||
241 | * the device has signaled it is done with it. | ||
242 | */ | ||
243 | |||
244 | enum queue_entry_flags { | ||
245 | ENTRY_BCN_ASSIGNED, | ||
246 | ENTRY_OWNER_DEVICE_DATA, | ||
247 | ENTRY_OWNER_DEVICE_CRYPTO, | ||
248 | }; | ||
249 | |||
250 | /** | ||
251 | * struct queue_entry: Entry inside the &struct data_queue | ||
252 | * | ||
253 | * @flags: Entry flags, see &enum queue_entry_flags. | ||
254 | * @queue: The data queue (&struct data_queue) to which this entry belongs. | ||
255 | * @skb: The buffer which is currently being transmitted (for TX queue), | ||
256 | * or used to directly recieve data in (for RX queue). | ||
257 | * @entry_idx: The entry index number. | ||
258 | * @priv_data: Private data belonging to this queue entry. The pointer | ||
259 | * points to data specific to a particular driver and queue type. | ||
260 | */ | ||
261 | struct queue_entry { | ||
262 | unsigned long flags; | ||
263 | |||
264 | struct data_queue *queue; | ||
265 | |||
266 | struct sk_buff *skb; | ||
267 | |||
268 | unsigned int entry_idx; | ||
269 | |||
270 | void *priv_data; | ||
271 | }; | ||
272 | |||
273 | /** | ||
274 | * enum queue_index: Queue index type | ||
275 | * | ||
276 | * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is | ||
277 | * owned by the hardware then the queue is considered to be full. | ||
278 | * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by | ||
279 | * the hardware and for which we need to run the txdone handler. If this | ||
280 | * entry is not owned by the hardware the queue is considered to be empty. | ||
281 | * @Q_INDEX_CRYPTO: Index pointer to the next entry which encryption/decription | ||
282 | * will be completed by the hardware next. | ||
283 | * @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size | ||
284 | * of the index array. | ||
285 | */ | ||
286 | enum queue_index { | ||
287 | Q_INDEX, | ||
288 | Q_INDEX_DONE, | ||
289 | Q_INDEX_CRYPTO, | ||
290 | Q_INDEX_MAX, | ||
291 | }; | ||
292 | |||
293 | /** | ||
294 | * struct data_queue: Data queue | ||
295 | * | ||
296 | * @rt2x00dev: Pointer to main &struct rt2x00dev where this queue belongs to. | ||
297 | * @entries: Base address of the &struct queue_entry which are | ||
298 | * part of this queue. | ||
299 | * @qid: The queue identification, see &enum data_queue_qid. | ||
300 | * @lock: Spinlock to protect index handling. Whenever @index, @index_done or | ||
301 | * @index_crypt needs to be changed this lock should be grabbed to prevent | ||
302 | * index corruption due to concurrency. | ||
303 | * @count: Number of frames handled in the queue. | ||
304 | * @limit: Maximum number of entries in the queue. | ||
305 | * @length: Number of frames in queue. | ||
306 | * @index: Index pointers to entry positions in the queue, | ||
307 | * use &enum queue_index to get a specific index field. | ||
308 | * @aifs: The aifs value for outgoing frames (field ignored in RX queue). | ||
309 | * @cw_min: The cw min value for outgoing frames (field ignored in RX queue). | ||
310 | * @cw_max: The cw max value for outgoing frames (field ignored in RX queue). | ||
311 | * @data_size: Maximum data size for the frames in this queue. | ||
312 | * @desc_size: Hardware descriptor size for the data in this queue. | ||
313 | */ | ||
314 | struct data_queue { | ||
315 | struct rt2x00_dev *rt2x00dev; | ||
316 | struct queue_entry *entries; | ||
317 | |||
318 | enum data_queue_qid qid; | ||
319 | |||
320 | spinlock_t lock; | ||
321 | unsigned int count; | ||
322 | unsigned short limit; | ||
323 | unsigned short length; | ||
324 | unsigned short index[Q_INDEX_MAX]; | ||
325 | |||
326 | unsigned short aifs; | ||
327 | unsigned short cw_min; | ||
328 | unsigned short cw_max; | ||
329 | |||
330 | unsigned short data_size; | ||
331 | unsigned short desc_size; | ||
332 | }; | ||
333 | |||
334 | /** | ||
335 | * struct data_queue_desc: Data queue description | ||
336 | * | ||
337 | * The information in this structure is used by drivers | ||
338 | * to inform rt2x00lib about the creation of the data queue. | ||
339 | * | ||
340 | * @entry_num: Maximum number of entries for a queue. | ||
341 | * @data_size: Maximum data size for the frames in this queue. | ||
342 | * @desc_size: Hardware descriptor size for the data in this queue. | ||
343 | * @priv_size: Size of per-queue_entry private data. | ||
344 | */ | ||
345 | struct data_queue_desc { | ||
346 | unsigned short entry_num; | ||
347 | unsigned short data_size; | ||
348 | unsigned short desc_size; | ||
349 | unsigned short priv_size; | ||
350 | }; | ||
351 | |||
352 | /** | ||
353 | * queue_end - Return pointer to the last queue (HELPER MACRO). | ||
354 | * @__dev: Pointer to &struct rt2x00_dev | ||
355 | * | ||
356 | * Using the base rx pointer and the maximum number of available queues, | ||
357 | * this macro will return the address of 1 position beyond the end of the | ||
358 | * queues array. | ||
359 | */ | ||
360 | #define queue_end(__dev) \ | ||
361 | &(__dev)->rx[(__dev)->data_queues] | ||
362 | |||
363 | /** | ||
364 | * tx_queue_end - Return pointer to the last TX queue (HELPER MACRO). | ||
365 | * @__dev: Pointer to &struct rt2x00_dev | ||
366 | * | ||
367 | * Using the base tx pointer and the maximum number of available TX | ||
368 | * queues, this macro will return the address of 1 position beyond | ||
369 | * the end of the TX queue array. | ||
370 | */ | ||
371 | #define tx_queue_end(__dev) \ | ||
372 | &(__dev)->tx[(__dev)->hw->queues] | ||
373 | |||
374 | /** | ||
375 | * queue_loop - Loop through the queues within a specific range (HELPER MACRO). | ||
376 | * @__entry: Pointer where the current queue entry will be stored in. | ||
377 | * @__start: Start queue pointer. | ||
378 | * @__end: End queue pointer. | ||
379 | * | ||
380 | * This macro will loop through all queues between &__start and &__end. | ||
381 | */ | ||
382 | #define queue_loop(__entry, __start, __end) \ | ||
383 | for ((__entry) = (__start); \ | ||
384 | prefetch(&(__entry)[1]), (__entry) != (__end); \ | ||
385 | (__entry) = &(__entry)[1]) | ||
386 | |||
387 | /** | ||
388 | * queue_for_each - Loop through all queues | ||
389 | * @__dev: Pointer to &struct rt2x00_dev | ||
390 | * @__entry: Pointer where the current queue entry will be stored in. | ||
391 | * | ||
392 | * This macro will loop through all available queues. | ||
393 | */ | ||
394 | #define queue_for_each(__dev, __entry) \ | ||
395 | queue_loop(__entry, (__dev)->rx, queue_end(__dev)) | ||
396 | |||
397 | /** | ||
398 | * tx_queue_for_each - Loop through the TX queues | ||
399 | * @__dev: Pointer to &struct rt2x00_dev | ||
400 | * @__entry: Pointer where the current queue entry will be stored in. | ||
401 | * | ||
402 | * This macro will loop through all TX related queues excluding | ||
403 | * the Beacon and Atim queues. | ||
404 | */ | ||
405 | #define tx_queue_for_each(__dev, __entry) \ | ||
406 | queue_loop(__entry, (__dev)->tx, tx_queue_end(__dev)) | ||
407 | |||
408 | /** | ||
409 | * txall_queue_for_each - Loop through all TX related queues | ||
410 | * @__dev: Pointer to &struct rt2x00_dev | ||
411 | * @__entry: Pointer where the current queue entry will be stored in. | ||
412 | * | ||
413 | * This macro will loop through all TX related queues including | ||
414 | * the Beacon and Atim queues. | ||
415 | */ | ||
416 | #define txall_queue_for_each(__dev, __entry) \ | ||
417 | queue_loop(__entry, (__dev)->tx, queue_end(__dev)) | ||
418 | |||
419 | /** | ||
420 | * rt2x00queue_empty - Check if the queue is empty. | ||
421 | * @queue: Queue to check if empty. | ||
422 | */ | ||
423 | static inline int rt2x00queue_empty(struct data_queue *queue) | ||
424 | { | ||
425 | return queue->length == 0; | ||
426 | } | ||
427 | |||
428 | /** | ||
429 | * rt2x00queue_full - Check if the queue is full. | ||
430 | * @queue: Queue to check if full. | ||
431 | */ | ||
432 | static inline int rt2x00queue_full(struct data_queue *queue) | ||
433 | { | ||
434 | return queue->length == queue->limit; | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * rt2x00queue_free - Check the number of available entries in queue. | ||
439 | * @queue: Queue to check. | ||
440 | */ | ||
441 | static inline int rt2x00queue_available(struct data_queue *queue) | ||
442 | { | ||
443 | return queue->limit - queue->length; | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * rt2x00_desc_read - Read a word from the hardware descriptor. | ||
448 | * @desc: Base descriptor address | ||
449 | * @word: Word index from where the descriptor should be read. | ||
450 | * @value: Address where the descriptor value should be written into. | ||
451 | */ | ||
452 | static inline void rt2x00_desc_read(__le32 *desc, const u8 word, u32 *value) | ||
453 | { | ||
454 | *value = le32_to_cpu(desc[word]); | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * rt2x00_desc_write - wrote a word to the hardware descriptor. | ||
459 | * @desc: Base descriptor address | ||
460 | * @word: Word index from where the descriptor should be written. | ||
461 | * @value: Value that should be written into the descriptor. | ||
462 | */ | ||
463 | static inline void rt2x00_desc_write(__le32 *desc, const u8 word, u32 value) | ||
464 | { | ||
465 | desc[word] = cpu_to_le32(value); | ||
466 | } | ||
467 | |||
468 | #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 ad2e7d53b3da..468a31c8c113 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,82 +270,162 @@ 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 | ||
271 | /* | 279 | #ifdef CONFIG_RT61PCI_LEDS |
272 | * Configuration handlers. | 280 | static void rt61pci_brightness_set(struct led_classdev *led_cdev, |
273 | */ | 281 | enum led_brightness brightness) |
274 | static void rt61pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | ||
275 | { | 282 | { |
276 | u32 tmp; | 283 | struct rt2x00_led *led = |
277 | 284 | container_of(led_cdev, struct rt2x00_led, led_dev); | |
278 | tmp = le32_to_cpu(mac[1]); | 285 | unsigned int enabled = brightness != LED_OFF; |
279 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | 286 | unsigned int a_mode = |
280 | mac[1] = cpu_to_le32(tmp); | 287 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); |
281 | 288 | unsigned int bg_mode = | |
282 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 289 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); |
283 | (2 * sizeof(__le32))); | 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 | } | ||
284 | } | 316 | } |
285 | 317 | ||
286 | static void rt61pci_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 318 | static int rt61pci_blink_set(struct led_classdev *led_cdev, |
319 | unsigned long *delay_on, | ||
320 | unsigned long *delay_off) | ||
287 | { | 321 | { |
288 | u32 tmp; | 322 | struct rt2x00_led *led = |
323 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
324 | u32 reg; | ||
289 | 325 | ||
290 | tmp = le32_to_cpu(bssid[1]); | 326 | rt2x00pci_register_read(led->rt2x00dev, MAC_CSR14, ®); |
291 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 327 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, *delay_on); |
292 | bssid[1] = cpu_to_le32(tmp); | 328 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, *delay_off); |
329 | rt2x00pci_register_write(led->rt2x00dev, MAC_CSR14, reg); | ||
293 | 330 | ||
294 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 331 | return 0; |
295 | (2 * sizeof(__le32))); | ||
296 | } | 332 | } |
333 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
297 | 334 | ||
298 | static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 335 | /* |
299 | const int tsf_sync) | 336 | * Configuration handlers. |
337 | */ | ||
338 | static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev, | ||
339 | const unsigned int filter_flags) | ||
300 | { | 340 | { |
301 | u32 reg; | 341 | u32 reg; |
302 | 342 | ||
303 | /* | 343 | /* |
304 | * Clear current synchronisation setup. | 344 | * Start configuration steps. |
305 | * For the Beacon base registers we only need to clear | 345 | * Note that the version error will always be dropped |
306 | * the first byte since that byte contains the VALID and OWNER | 346 | * and broadcast frames will always be accepted since |
307 | * bits which (when set to 0) will invalidate the entire beacon. | 347 | * there is no filter for it at this time. |
308 | */ | 348 | */ |
309 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | 349 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); |
310 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | 350 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, |
311 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | 351 | !(filter_flags & FIF_FCSFAIL)); |
312 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | 352 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, |
313 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | 353 | !(filter_flags & FIF_PLCPFAIL)); |
354 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, | ||
355 | !(filter_flags & FIF_CONTROL)); | ||
356 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, | ||
357 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
358 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, | ||
359 | !(filter_flags & FIF_PROMISC_IN_BSS) && | ||
360 | !rt2x00dev->intf_ap_count); | ||
361 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
362 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | ||
363 | !(filter_flags & FIF_ALLMULTI)); | ||
364 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | ||
365 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, | ||
366 | !(filter_flags & FIF_CONTROL)); | ||
367 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
368 | } | ||
314 | 369 | ||
315 | /* | 370 | static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, |
316 | * Enable synchronisation. | 371 | struct rt2x00_intf *intf, |
317 | */ | 372 | struct rt2x00intf_conf *conf, |
318 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 373 | const unsigned int flags) |
319 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | 374 | { |
320 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | 375 | unsigned int beacon_base; |
321 | (tsf_sync == TSF_SYNC_BEACON)); | 376 | u32 reg; |
322 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 377 | |
323 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | 378 | if (flags & CONFIG_UPDATE_TYPE) { |
324 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 379 | /* |
380 | * Clear current synchronisation setup. | ||
381 | * For the Beacon base registers we only need to clear | ||
382 | * the first byte since that byte contains the VALID and OWNER | ||
383 | * bits which (when set to 0) will invalidate the entire beacon. | ||
384 | */ | ||
385 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
386 | rt2x00pci_register_write(rt2x00dev, beacon_base, 0); | ||
387 | |||
388 | /* | ||
389 | * Enable synchronisation. | ||
390 | */ | ||
391 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
392 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
393 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
394 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
395 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
396 | } | ||
397 | |||
398 | if (flags & CONFIG_UPDATE_MAC) { | ||
399 | reg = le32_to_cpu(conf->mac[1]); | ||
400 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
401 | conf->mac[1] = cpu_to_le32(reg); | ||
402 | |||
403 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, | ||
404 | conf->mac, sizeof(conf->mac)); | ||
405 | } | ||
406 | |||
407 | if (flags & CONFIG_UPDATE_BSSID) { | ||
408 | reg = le32_to_cpu(conf->bssid[1]); | ||
409 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); | ||
410 | conf->bssid[1] = cpu_to_le32(reg); | ||
411 | |||
412 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, | ||
413 | conf->bssid, sizeof(conf->bssid)); | ||
414 | } | ||
325 | } | 415 | } |
326 | 416 | ||
327 | static void rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 417 | static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, |
328 | const int short_preamble, | 418 | struct rt2x00lib_erp *erp) |
329 | const int ack_timeout, | ||
330 | const int ack_consume_time) | ||
331 | { | 419 | { |
332 | u32 reg; | 420 | u32 reg; |
333 | 421 | ||
334 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | 422 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); |
335 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); | 423 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout); |
336 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 424 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); |
337 | 425 | ||
338 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | 426 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); |
339 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 427 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
340 | !!short_preamble); | 428 | !!erp->short_preamble); |
341 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | 429 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); |
342 | } | 430 | } |
343 | 431 | ||
@@ -427,27 +515,21 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
427 | case ANTENNA_HW_DIVERSITY: | 515 | case ANTENNA_HW_DIVERSITY: |
428 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); | 516 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
429 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | 517 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, |
430 | (rt2x00dev->curr_hwmode != HWMODE_A)); | 518 | (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ)); |
431 | break; | 519 | break; |
432 | case ANTENNA_A: | 520 | case ANTENNA_A: |
433 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 521 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
434 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 522 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
435 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 523 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
436 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 524 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
437 | else | 525 | else |
438 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 526 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
439 | break; | 527 | 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: | 528 | case ANTENNA_B: |
529 | default: | ||
448 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 530 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
449 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 531 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
450 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 532 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
451 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 533 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
452 | else | 534 | else |
453 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 535 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
@@ -486,14 +568,8 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | |||
486 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 568 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
487 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 569 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
488 | break; | 570 | 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: | 571 | case ANTENNA_B: |
572 | default: | ||
497 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 573 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
498 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 574 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
499 | break; | 575 | break; |
@@ -531,10 +607,6 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, | |||
531 | rt61pci_bbp_read(rt2x00dev, 4, &r4); | 607 | rt61pci_bbp_read(rt2x00dev, 4, &r4); |
532 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | 608 | rt61pci_bbp_read(rt2x00dev, 77, &r77); |
533 | 609 | ||
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 | /* | 610 | /* |
539 | * Configure the RX antenna. | 611 | * Configure the RX antenna. |
540 | */ | 612 | */ |
@@ -544,15 +616,14 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, | |||
544 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 616 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
545 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); | 617 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); |
546 | break; | 618 | break; |
547 | case ANTENNA_SW_DIVERSITY: | ||
548 | case ANTENNA_HW_DIVERSITY: | 619 | case ANTENNA_HW_DIVERSITY: |
549 | /* | 620 | /* |
550 | * NOTE: We should never come here because rt2x00lib is | 621 | * FIXME: Antenna selection for the rf 2529 is very confusing |
551 | * supposed to catch this and send us the correct antenna | 622 | * in the legacy driver. Just default to antenna B until the |
552 | * explicitely. However we are nog going to bug about this. | 623 | * legacy code can be properly translated into rt2x00 code. |
553 | * Instead, just default to antenna B. | ||
554 | */ | 624 | */ |
555 | case ANTENNA_B: | 625 | case ANTENNA_B: |
626 | default: | ||
556 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 627 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
557 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 628 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
558 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); | 629 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); |
@@ -603,7 +674,14 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
603 | unsigned int i; | 674 | unsigned int i; |
604 | u32 reg; | 675 | u32 reg; |
605 | 676 | ||
606 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | 677 | /* |
678 | * We should never come here because rt2x00lib is supposed | ||
679 | * to catch this and send us the correct antenna explicitely. | ||
680 | */ | ||
681 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
682 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
683 | |||
684 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { | ||
607 | sel = antenna_sel_a; | 685 | sel = antenna_sel_a; |
608 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 686 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); |
609 | } else { | 687 | } else { |
@@ -617,10 +695,9 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
617 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); | 695 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); |
618 | 696 | ||
619 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 697 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
620 | (rt2x00dev->curr_hwmode == HWMODE_B || | 698 | rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); |
621 | rt2x00dev->curr_hwmode == HWMODE_G)); | ||
622 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 699 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
623 | (rt2x00dev->curr_hwmode == HWMODE_A)); | 700 | rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); |
624 | 701 | ||
625 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); | 702 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); |
626 | 703 | ||
@@ -667,8 +744,8 @@ static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
667 | } | 744 | } |
668 | 745 | ||
669 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | 746 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, |
670 | const unsigned int flags, | 747 | struct rt2x00lib_conf *libconf, |
671 | struct rt2x00lib_conf *libconf) | 748 | const unsigned int flags) |
672 | { | 749 | { |
673 | if (flags & CONFIG_UPDATE_PHYMODE) | 750 | if (flags & CONFIG_UPDATE_PHYMODE) |
674 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); | 751 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -684,78 +761,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | |||
684 | } | 761 | } |
685 | 762 | ||
686 | /* | 763 | /* |
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 | 764 | * Link tuning |
760 | */ | 765 | */ |
761 | static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, | 766 | static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -789,17 +794,12 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
789 | u8 up_bound; | 794 | u8 up_bound; |
790 | u8 low_bound; | 795 | u8 low_bound; |
791 | 796 | ||
792 | /* | ||
793 | * Update Led strength | ||
794 | */ | ||
795 | rt61pci_activity_led(rt2x00dev, rssi); | ||
796 | |||
797 | rt61pci_bbp_read(rt2x00dev, 17, &r17); | 797 | rt61pci_bbp_read(rt2x00dev, 17, &r17); |
798 | 798 | ||
799 | /* | 799 | /* |
800 | * Determine r17 bounds. | 800 | * Determine r17 bounds. |
801 | */ | 801 | */ |
802 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 802 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
803 | low_bound = 0x28; | 803 | low_bound = 0x28; |
804 | up_bound = 0x48; | 804 | up_bound = 0x48; |
805 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 805 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
@@ -816,6 +816,13 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
816 | } | 816 | } |
817 | 817 | ||
818 | /* | 818 | /* |
819 | * If we are not associated, we should go straight to the | ||
820 | * dynamic CCA tuning. | ||
821 | */ | ||
822 | if (!rt2x00dev->intf_associated) | ||
823 | goto dynamic_cca_tune; | ||
824 | |||
825 | /* | ||
819 | * Special big-R17 for very short distance | 826 | * Special big-R17 for very short distance |
820 | */ | 827 | */ |
821 | if (rssi >= -35) { | 828 | if (rssi >= -35) { |
@@ -866,6 +873,8 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
866 | return; | 873 | return; |
867 | } | 874 | } |
868 | 875 | ||
876 | dynamic_cca_tune: | ||
877 | |||
869 | /* | 878 | /* |
870 | * r17 does not yet exceed upper limit, continue and base | 879 | * r17 does not yet exceed upper limit, continue and base |
871 | * the r17 tuning on the false CCA count. | 880 | * the r17 tuning on the false CCA count. |
@@ -882,7 +891,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
882 | } | 891 | } |
883 | 892 | ||
884 | /* | 893 | /* |
885 | * Firmware name function. | 894 | * Firmware functions |
886 | */ | 895 | */ |
887 | static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 896 | static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) |
888 | { | 897 | { |
@@ -906,9 +915,23 @@ static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) | |||
906 | return fw_name; | 915 | return fw_name; |
907 | } | 916 | } |
908 | 917 | ||
909 | /* | 918 | static u16 rt61pci_get_firmware_crc(void *data, const size_t len) |
910 | * Initialization functions. | 919 | { |
911 | */ | 920 | u16 crc; |
921 | |||
922 | /* | ||
923 | * Use the crc itu-t algorithm. | ||
924 | * The last 2 bytes in the firmware array are the crc checksum itself, | ||
925 | * this means that we should never pass those 2 bytes to the crc | ||
926 | * algorithm. | ||
927 | */ | ||
928 | crc = crc_itu_t(0, data, len - 2); | ||
929 | crc = crc_itu_t_byte(crc, 0); | ||
930 | crc = crc_itu_t_byte(crc, 0); | ||
931 | |||
932 | return crc; | ||
933 | } | ||
934 | |||
912 | static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | 935 | static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, |
913 | const size_t len) | 936 | const size_t len) |
914 | { | 937 | { |
@@ -989,50 +1012,55 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
989 | return 0; | 1012 | return 0; |
990 | } | 1013 | } |
991 | 1014 | ||
1015 | /* | ||
1016 | * Initialization functions. | ||
1017 | */ | ||
992 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 1018 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
993 | struct data_entry *entry) | 1019 | struct queue_entry *entry) |
994 | { | 1020 | { |
995 | __le32 *rxd = entry->priv; | 1021 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
996 | u32 word; | 1022 | u32 word; |
997 | 1023 | ||
998 | rt2x00_desc_read(rxd, 5, &word); | 1024 | rt2x00_desc_read(priv_rx->desc, 5, &word); |
999 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, | 1025 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, |
1000 | entry->data_dma); | 1026 | priv_rx->data_dma); |
1001 | rt2x00_desc_write(rxd, 5, word); | 1027 | rt2x00_desc_write(priv_rx->desc, 5, word); |
1002 | 1028 | ||
1003 | rt2x00_desc_read(rxd, 0, &word); | 1029 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
1004 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 1030 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
1005 | rt2x00_desc_write(rxd, 0, word); | 1031 | rt2x00_desc_write(priv_rx->desc, 0, word); |
1006 | } | 1032 | } |
1007 | 1033 | ||
1008 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 1034 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
1009 | struct data_entry *entry) | 1035 | struct queue_entry *entry) |
1010 | { | 1036 | { |
1011 | __le32 *txd = entry->priv; | 1037 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
1012 | u32 word; | 1038 | u32 word; |
1013 | 1039 | ||
1014 | rt2x00_desc_read(txd, 1, &word); | 1040 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
1015 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); | 1041 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); |
1016 | rt2x00_desc_write(txd, 1, word); | 1042 | rt2x00_desc_write(priv_tx->desc, 1, word); |
1017 | 1043 | ||
1018 | rt2x00_desc_read(txd, 5, &word); | 1044 | rt2x00_desc_read(priv_tx->desc, 5, &word); |
1019 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->ring->queue_idx); | 1045 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid); |
1020 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx); | 1046 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx); |
1021 | rt2x00_desc_write(txd, 5, word); | 1047 | rt2x00_desc_write(priv_tx->desc, 5, word); |
1022 | 1048 | ||
1023 | rt2x00_desc_read(txd, 6, &word); | 1049 | rt2x00_desc_read(priv_tx->desc, 6, &word); |
1024 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | 1050 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, |
1025 | entry->data_dma); | 1051 | priv_tx->data_dma); |
1026 | rt2x00_desc_write(txd, 6, word); | 1052 | rt2x00_desc_write(priv_tx->desc, 6, word); |
1027 | 1053 | ||
1028 | rt2x00_desc_read(txd, 0, &word); | 1054 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1029 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 1055 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
1030 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 1056 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
1031 | rt2x00_desc_write(txd, 0, word); | 1057 | rt2x00_desc_write(priv_tx->desc, 0, word); |
1032 | } | 1058 | } |
1033 | 1059 | ||
1034 | static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | 1060 | static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) |
1035 | { | 1061 | { |
1062 | struct queue_entry_priv_pci_rx *priv_rx; | ||
1063 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1036 | u32 reg; | 1064 | u32 reg; |
1037 | 1065 | ||
1038 | /* | 1066 | /* |
@@ -1040,59 +1068,55 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1040 | */ | 1068 | */ |
1041 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); | 1069 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); |
1042 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, | 1070 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, |
1043 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | 1071 | rt2x00dev->tx[0].limit); |
1044 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, | 1072 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, |
1045 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 1073 | rt2x00dev->tx[1].limit); |
1046 | rt2x00_set_field32(®, TX_RING_CSR0_AC2_RING_SIZE, | 1074 | rt2x00_set_field32(®, TX_RING_CSR0_AC2_RING_SIZE, |
1047 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].stats.limit); | 1075 | rt2x00dev->tx[2].limit); |
1048 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, | 1076 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, |
1049 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].stats.limit); | 1077 | rt2x00dev->tx[3].limit); |
1050 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); | 1078 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); |
1051 | 1079 | ||
1052 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); | 1080 | 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, | 1081 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, |
1056 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size / | 1082 | rt2x00dev->tx[0].desc_size / 4); |
1057 | 4); | ||
1058 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); | 1083 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); |
1059 | 1084 | ||
1085 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
1060 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); | 1086 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); |
1061 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, | 1087 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, |
1062 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 1088 | priv_tx->desc_dma); |
1063 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); | 1089 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); |
1064 | 1090 | ||
1091 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
1065 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); | 1092 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); |
1066 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, | 1093 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, |
1067 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 1094 | priv_tx->desc_dma); |
1068 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); | 1095 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); |
1069 | 1096 | ||
1097 | priv_tx = rt2x00dev->tx[2].entries[0].priv_data; | ||
1070 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); | 1098 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); |
1071 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, | 1099 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, |
1072 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].data_dma); | 1100 | priv_tx->desc_dma); |
1073 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); | 1101 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); |
1074 | 1102 | ||
1103 | priv_tx = rt2x00dev->tx[3].entries[0].priv_data; | ||
1075 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); | 1104 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); |
1076 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, | 1105 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, |
1077 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].data_dma); | 1106 | priv_tx->desc_dma); |
1078 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); | 1107 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); |
1079 | 1108 | ||
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, ®); | 1109 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); |
1086 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, | 1110 | 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, | 1111 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, |
1089 | rt2x00dev->rx->desc_size / 4); | 1112 | rt2x00dev->rx->desc_size / 4); |
1090 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); | 1113 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); |
1091 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); | 1114 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); |
1092 | 1115 | ||
1116 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
1093 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); | 1117 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); |
1094 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, | 1118 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, |
1095 | rt2x00dev->rx->data_dma); | 1119 | priv_rx->desc_dma); |
1096 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); | 1120 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); |
1097 | 1121 | ||
1098 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); | 1122 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); |
@@ -1100,7 +1124,6 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1100 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); | 1124 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); |
1101 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); | 1125 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); |
1102 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); | 1126 | 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); | 1127 | rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); |
1105 | 1128 | ||
1106 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); | 1129 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); |
@@ -1108,7 +1131,6 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1108 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); | 1131 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); |
1109 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); | 1132 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); |
1110 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); | 1133 | 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); | 1134 | rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); |
1113 | 1135 | ||
1114 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); | 1136 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); |
@@ -1224,6 +1246,17 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1224 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | 1246 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); |
1225 | 1247 | ||
1226 | /* | 1248 | /* |
1249 | * Clear all beacons | ||
1250 | * For the Beacon base registers we only need to clear | ||
1251 | * the first byte since that byte contains the VALID and OWNER | ||
1252 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1253 | */ | ||
1254 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1255 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1256 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1257 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1258 | |||
1259 | /* | ||
1227 | * We must clear the error counters. | 1260 | * We must clear the error counters. |
1228 | * These registers are cleared on read, | 1261 | * These registers are cleared on read, |
1229 | * so we may pass a useless variable to store the value. | 1262 | * so we may pass a useless variable to store the value. |
@@ -1296,19 +1329,15 @@ continue_csr_init: | |||
1296 | rt61pci_bbp_write(rt2x00dev, 102, 0x16); | 1329 | rt61pci_bbp_write(rt2x00dev, 102, 0x16); |
1297 | rt61pci_bbp_write(rt2x00dev, 107, 0x04); | 1330 | rt61pci_bbp_write(rt2x00dev, 107, 0x04); |
1298 | 1331 | ||
1299 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
1300 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 1332 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
1301 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 1333 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
1302 | 1334 | ||
1303 | if (eeprom != 0xffff && eeprom != 0x0000) { | 1335 | if (eeprom != 0xffff && eeprom != 0x0000) { |
1304 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 1336 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
1305 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 1337 | 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); | 1338 | rt61pci_bbp_write(rt2x00dev, reg_id, value); |
1309 | } | 1339 | } |
1310 | } | 1340 | } |
1311 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
1312 | 1341 | ||
1313 | return 0; | 1342 | return 0; |
1314 | } | 1343 | } |
@@ -1375,7 +1404,7 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1375 | /* | 1404 | /* |
1376 | * Initialize all registers. | 1405 | * Initialize all registers. |
1377 | */ | 1406 | */ |
1378 | if (rt61pci_init_rings(rt2x00dev) || | 1407 | if (rt61pci_init_queues(rt2x00dev) || |
1379 | rt61pci_init_registers(rt2x00dev) || | 1408 | rt61pci_init_registers(rt2x00dev) || |
1380 | rt61pci_init_bbp(rt2x00dev)) { | 1409 | rt61pci_init_bbp(rt2x00dev)) { |
1381 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 1410 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -1394,11 +1423,6 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1394 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); | 1423 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); |
1395 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); | 1424 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); |
1396 | 1425 | ||
1397 | /* | ||
1398 | * Enable LED | ||
1399 | */ | ||
1400 | rt61pci_enable_led(rt2x00dev); | ||
1401 | |||
1402 | return 0; | 1426 | return 0; |
1403 | } | 1427 | } |
1404 | 1428 | ||
@@ -1406,11 +1430,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1406 | { | 1430 | { |
1407 | u32 reg; | 1431 | u32 reg; |
1408 | 1432 | ||
1409 | /* | ||
1410 | * Disable LED | ||
1411 | */ | ||
1412 | rt61pci_disable_led(rt2x00dev); | ||
1413 | |||
1414 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | 1433 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
1415 | 1434 | ||
1416 | /* | 1435 | /* |
@@ -1426,7 +1445,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1426 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); | 1445 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); |
1427 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); | 1446 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); |
1428 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); | 1447 | 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); | 1448 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1431 | 1449 | ||
1432 | /* | 1450 | /* |
@@ -1508,10 +1526,10 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1508 | */ | 1526 | */ |
1509 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1527 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1510 | struct sk_buff *skb, | 1528 | struct sk_buff *skb, |
1511 | struct txdata_entry_desc *desc, | 1529 | struct txentry_desc *txdesc, |
1512 | struct ieee80211_tx_control *control) | 1530 | struct ieee80211_tx_control *control) |
1513 | { | 1531 | { |
1514 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1532 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1515 | __le32 *txd = skbdesc->desc; | 1533 | __le32 *txd = skbdesc->desc; |
1516 | u32 word; | 1534 | u32 word; |
1517 | 1535 | ||
@@ -1519,50 +1537,52 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1519 | * Start writing the descriptor words. | 1537 | * Start writing the descriptor words. |
1520 | */ | 1538 | */ |
1521 | rt2x00_desc_read(txd, 1, &word); | 1539 | rt2x00_desc_read(txd, 1, &word); |
1522 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | 1540 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); |
1523 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | 1541 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1524 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1542 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1525 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1543 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1526 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1544 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1527 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1545 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); |
1528 | rt2x00_desc_write(txd, 1, word); | 1546 | rt2x00_desc_write(txd, 1, word); |
1529 | 1547 | ||
1530 | rt2x00_desc_read(txd, 2, &word); | 1548 | rt2x00_desc_read(txd, 2, &word); |
1531 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1549 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1532 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1550 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1533 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1551 | 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); | 1552 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1535 | rt2x00_desc_write(txd, 2, word); | 1553 | rt2x00_desc_write(txd, 2, word); |
1536 | 1554 | ||
1537 | rt2x00_desc_read(txd, 5, &word); | 1555 | rt2x00_desc_read(txd, 5, &word); |
1538 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1556 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1539 | TXPOWER_TO_DEV(control->power_level)); | 1557 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); |
1540 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1558 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1541 | rt2x00_desc_write(txd, 5, word); | 1559 | rt2x00_desc_write(txd, 5, word); |
1542 | 1560 | ||
1543 | rt2x00_desc_read(txd, 11, &word); | 1561 | if (skbdesc->desc_len > TXINFO_SIZE) { |
1544 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); | 1562 | rt2x00_desc_read(txd, 11, &word); |
1545 | rt2x00_desc_write(txd, 11, word); | 1563 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); |
1564 | rt2x00_desc_write(txd, 11, word); | ||
1565 | } | ||
1546 | 1566 | ||
1547 | rt2x00_desc_read(txd, 0, &word); | 1567 | rt2x00_desc_read(txd, 0, &word); |
1548 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1568 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1549 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1569 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1550 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1570 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1551 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1571 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1552 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1572 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1553 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1573 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1554 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1574 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1555 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1575 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1556 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1576 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1557 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1577 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1558 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1578 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1559 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1579 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1560 | !!(control->flags & | 1580 | !!(control->flags & |
1561 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1581 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
1562 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1582 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1563 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1583 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1564 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1584 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1565 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1585 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1566 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1586 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1567 | rt2x00_desc_write(txd, 0, word); | 1587 | rt2x00_desc_write(txd, 0, word); |
1568 | } | 1588 | } |
@@ -1571,11 +1591,11 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1571 | * TX data initialization | 1591 | * TX data initialization |
1572 | */ | 1592 | */ |
1573 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1593 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1574 | unsigned int queue) | 1594 | const unsigned int queue) |
1575 | { | 1595 | { |
1576 | u32 reg; | 1596 | u32 reg; |
1577 | 1597 | ||
1578 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1598 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1579 | /* | 1599 | /* |
1580 | * For Wi-Fi faily generated beacons between participating | 1600 | * For Wi-Fi faily generated beacons between participating |
1581 | * stations. Set TBTT phase adaptive adjustment step to 8us. | 1601 | * stations. Set TBTT phase adaptive adjustment step to 8us. |
@@ -1584,6 +1604,8 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1584 | 1604 | ||
1585 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 1605 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); |
1586 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { | 1606 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { |
1607 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1608 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1587 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1609 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
1588 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 1610 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); |
1589 | } | 1611 | } |
@@ -1599,8 +1621,6 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1599 | (queue == IEEE80211_TX_QUEUE_DATA2)); | 1621 | (queue == IEEE80211_TX_QUEUE_DATA2)); |
1600 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, | 1622 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, |
1601 | (queue == IEEE80211_TX_QUEUE_DATA3)); | 1623 | (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); | 1624 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1605 | } | 1625 | } |
1606 | 1626 | ||
@@ -1628,7 +1648,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1628 | return 0; | 1648 | return 0; |
1629 | } | 1649 | } |
1630 | 1650 | ||
1631 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 1651 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
1632 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | 1652 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) |
1633 | offset += 14; | 1653 | offset += 14; |
1634 | 1654 | ||
@@ -1648,28 +1668,35 @@ 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; | 1668 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; |
1649 | } | 1669 | } |
1650 | 1670 | ||
1651 | static void rt61pci_fill_rxdone(struct data_entry *entry, | 1671 | static void rt61pci_fill_rxdone(struct queue_entry *entry, |
1652 | struct rxdata_entry_desc *desc) | 1672 | struct rxdone_entry_desc *rxdesc) |
1653 | { | 1673 | { |
1654 | __le32 *rxd = entry->priv; | 1674 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1655 | u32 word0; | 1675 | u32 word0; |
1656 | u32 word1; | 1676 | u32 word1; |
1657 | 1677 | ||
1658 | rt2x00_desc_read(rxd, 0, &word0); | 1678 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1659 | rt2x00_desc_read(rxd, 1, &word1); | 1679 | rt2x00_desc_read(priv_rx->desc, 1, &word1); |
1660 | 1680 | ||
1661 | desc->flags = 0; | 1681 | rxdesc->flags = 0; |
1662 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1682 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1663 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1683 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1664 | 1684 | ||
1665 | /* | 1685 | /* |
1666 | * Obtain the status about this packet. | 1686 | * Obtain the status about this packet. |
1667 | */ | 1687 | * When frame was received with an OFDM bitrate, |
1668 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1688 | * the signal is the PLCP value. If it was received with |
1669 | desc->rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1); | 1689 | * a CCK bitrate the signal is the rate in 100kbit/s. |
1670 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1690 | */ |
1671 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1691 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1672 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1692 | rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1); |
1693 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
1694 | |||
1695 | rxdesc->dev_flags = 0; | ||
1696 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | ||
1697 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; | ||
1698 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | ||
1699 | rxdesc->dev_flags |= RXDONE_MY_BSS; | ||
1673 | } | 1700 | } |
1674 | 1701 | ||
1675 | /* | 1702 | /* |
@@ -1677,17 +1704,16 @@ static void rt61pci_fill_rxdone(struct data_entry *entry, | |||
1677 | */ | 1704 | */ |
1678 | static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | 1705 | static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) |
1679 | { | 1706 | { |
1680 | struct data_ring *ring; | 1707 | struct data_queue *queue; |
1681 | struct data_entry *entry; | 1708 | struct queue_entry *entry; |
1682 | struct data_entry *entry_done; | 1709 | struct queue_entry *entry_done; |
1683 | __le32 *txd; | 1710 | struct queue_entry_priv_pci_tx *priv_tx; |
1711 | struct txdone_entry_desc txdesc; | ||
1684 | u32 word; | 1712 | u32 word; |
1685 | u32 reg; | 1713 | u32 reg; |
1686 | u32 old_reg; | 1714 | u32 old_reg; |
1687 | int type; | 1715 | int type; |
1688 | int index; | 1716 | int index; |
1689 | int tx_status; | ||
1690 | int retry; | ||
1691 | 1717 | ||
1692 | /* | 1718 | /* |
1693 | * During each loop we will compare the freshly read | 1719 | * During each loop we will compare the freshly read |
@@ -1710,11 +1736,11 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1710 | 1736 | ||
1711 | /* | 1737 | /* |
1712 | * Skip this entry when it contains an invalid | 1738 | * Skip this entry when it contains an invalid |
1713 | * ring identication number. | 1739 | * queue identication number. |
1714 | */ | 1740 | */ |
1715 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); | 1741 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); |
1716 | ring = rt2x00lib_get_ring(rt2x00dev, type); | 1742 | queue = rt2x00queue_get_queue(rt2x00dev, type); |
1717 | if (unlikely(!ring)) | 1743 | if (unlikely(!queue)) |
1718 | continue; | 1744 | continue; |
1719 | 1745 | ||
1720 | /* | 1746 | /* |
@@ -1722,36 +1748,40 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1722 | * index number. | 1748 | * index number. |
1723 | */ | 1749 | */ |
1724 | index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); | 1750 | index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); |
1725 | if (unlikely(index >= ring->stats.limit)) | 1751 | if (unlikely(index >= queue->limit)) |
1726 | continue; | 1752 | continue; |
1727 | 1753 | ||
1728 | entry = &ring->entry[index]; | 1754 | entry = &queue->entries[index]; |
1729 | txd = entry->priv; | 1755 | priv_tx = entry->priv_data; |
1730 | rt2x00_desc_read(txd, 0, &word); | 1756 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1731 | 1757 | ||
1732 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1758 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1733 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1759 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
1734 | return; | 1760 | return; |
1735 | 1761 | ||
1736 | entry_done = rt2x00_get_data_entry_done(ring); | 1762 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1737 | while (entry != entry_done) { | 1763 | while (entry != entry_done) { |
1738 | /* Catch up. Just report any entries we missed as | 1764 | /* Catch up. |
1739 | * failed. */ | 1765 | * Just report any entries we missed as failed. |
1766 | */ | ||
1740 | WARNING(rt2x00dev, | 1767 | WARNING(rt2x00dev, |
1741 | "TX status report missed for entry %p\n", | 1768 | "TX status report missed for entry %d\n", |
1742 | entry_done); | 1769 | entry_done->entry_idx); |
1743 | rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER, | 1770 | |
1744 | 0); | 1771 | txdesc.status = TX_FAIL_OTHER; |
1745 | entry_done = rt2x00_get_data_entry_done(ring); | 1772 | txdesc.retry = 0; |
1773 | |||
1774 | rt2x00pci_txdone(rt2x00dev, entry_done, &txdesc); | ||
1775 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
1746 | } | 1776 | } |
1747 | 1777 | ||
1748 | /* | 1778 | /* |
1749 | * Obtain the status about this packet. | 1779 | * Obtain the status about this packet. |
1750 | */ | 1780 | */ |
1751 | tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); | 1781 | txdesc.status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); |
1752 | retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); | 1782 | txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); |
1753 | 1783 | ||
1754 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1784 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1755 | } | 1785 | } |
1756 | } | 1786 | } |
1757 | 1787 | ||
@@ -1906,7 +1936,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1906 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 1936 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
1907 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 1937 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
1908 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 1938 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
1909 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 1939 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
1910 | } else { | 1940 | } else { |
1911 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 1941 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
1912 | if (value < -10 || value > 10) | 1942 | if (value < -10 || value > 10) |
@@ -2035,35 +2065,61 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2035 | * If the eeprom value is invalid, | 2065 | * If the eeprom value is invalid, |
2036 | * switch to default led mode. | 2066 | * switch to default led mode. |
2037 | */ | 2067 | */ |
2068 | #ifdef CONFIG_RT61PCI_LEDS | ||
2038 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 2069 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
2070 | value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); | ||
2071 | |||
2072 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | ||
2073 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | ||
2074 | rt2x00dev->led_radio.led_dev.brightness_set = | ||
2075 | rt61pci_brightness_set; | ||
2076 | rt2x00dev->led_radio.led_dev.blink_set = | ||
2077 | rt61pci_blink_set; | ||
2078 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
2079 | |||
2080 | rt2x00dev->led_assoc.rt2x00dev = rt2x00dev; | ||
2081 | rt2x00dev->led_assoc.type = LED_TYPE_ASSOC; | ||
2082 | rt2x00dev->led_assoc.led_dev.brightness_set = | ||
2083 | rt61pci_brightness_set; | ||
2084 | rt2x00dev->led_assoc.led_dev.blink_set = | ||
2085 | rt61pci_blink_set; | ||
2086 | rt2x00dev->led_assoc.flags = LED_INITIALIZED; | ||
2087 | |||
2088 | if (value == LED_MODE_SIGNAL_STRENGTH) { | ||
2089 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
2090 | rt2x00dev->led_radio.type = LED_TYPE_QUALITY; | ||
2091 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
2092 | rt61pci_brightness_set; | ||
2093 | rt2x00dev->led_qual.led_dev.blink_set = | ||
2094 | rt61pci_blink_set; | ||
2095 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
2096 | } | ||
2039 | 2097 | ||
2040 | rt2x00dev->led_mode = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); | 2098 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); |
2041 | 2099 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, | |
2042 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | ||
2043 | rt2x00dev->led_mode); | ||
2044 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
2045 | rt2x00_get_field16(eeprom, | 2100 | rt2x00_get_field16(eeprom, |
2046 | EEPROM_LED_POLARITY_GPIO_0)); | 2101 | EEPROM_LED_POLARITY_GPIO_0)); |
2047 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | 2102 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1, |
2048 | rt2x00_get_field16(eeprom, | 2103 | rt2x00_get_field16(eeprom, |
2049 | EEPROM_LED_POLARITY_GPIO_1)); | 2104 | EEPROM_LED_POLARITY_GPIO_1)); |
2050 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | 2105 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2, |
2051 | rt2x00_get_field16(eeprom, | 2106 | rt2x00_get_field16(eeprom, |
2052 | EEPROM_LED_POLARITY_GPIO_2)); | 2107 | EEPROM_LED_POLARITY_GPIO_2)); |
2053 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | 2108 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3, |
2054 | rt2x00_get_field16(eeprom, | 2109 | rt2x00_get_field16(eeprom, |
2055 | EEPROM_LED_POLARITY_GPIO_3)); | 2110 | EEPROM_LED_POLARITY_GPIO_3)); |
2056 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | 2111 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4, |
2057 | rt2x00_get_field16(eeprom, | 2112 | rt2x00_get_field16(eeprom, |
2058 | EEPROM_LED_POLARITY_GPIO_4)); | 2113 | EEPROM_LED_POLARITY_GPIO_4)); |
2059 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | 2114 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT, |
2060 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | 2115 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); |
2061 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | 2116 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG, |
2062 | rt2x00_get_field16(eeprom, | 2117 | rt2x00_get_field16(eeprom, |
2063 | EEPROM_LED_POLARITY_RDY_G)); | 2118 | EEPROM_LED_POLARITY_RDY_G)); |
2064 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | 2119 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, |
2065 | rt2x00_get_field16(eeprom, | 2120 | rt2x00_get_field16(eeprom, |
2066 | EEPROM_LED_POLARITY_RDY_A)); | 2121 | EEPROM_LED_POLARITY_RDY_A)); |
2122 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
2067 | 2123 | ||
2068 | return 0; | 2124 | return 0; |
2069 | } | 2125 | } |
@@ -2197,7 +2253,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2197 | rt2x00dev->hw->extra_tx_headroom = 0; | 2253 | rt2x00dev->hw->extra_tx_headroom = 0; |
2198 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | 2254 | rt2x00dev->hw->max_signal = MAX_SIGNAL; |
2199 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | 2255 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; |
2200 | rt2x00dev->hw->queues = 5; | 2256 | rt2x00dev->hw->queues = 4; |
2201 | 2257 | ||
2202 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 2258 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); |
2203 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 2259 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -2214,8 +2270,8 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2214 | /* | 2270 | /* |
2215 | * Initialize hw_mode information. | 2271 | * Initialize hw_mode information. |
2216 | */ | 2272 | */ |
2217 | spec->num_modes = 2; | 2273 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
2218 | spec->num_rates = 12; | 2274 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
2219 | spec->tx_power_a = NULL; | 2275 | spec->tx_power_a = NULL; |
2220 | spec->tx_power_bg = txpower; | 2276 | spec->tx_power_bg = txpower; |
2221 | spec->tx_power_default = DEFAULT_TXPOWER; | 2277 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -2230,7 +2286,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2230 | 2286 | ||
2231 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 2287 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || |
2232 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { | 2288 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { |
2233 | spec->num_modes = 3; | 2289 | spec->supported_bands |= SUPPORT_BAND_5GHZ; |
2234 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); | 2290 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); |
2235 | 2291 | ||
2236 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2292 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
@@ -2262,7 +2318,7 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2262 | rt61pci_probe_hw_mode(rt2x00dev); | 2318 | rt61pci_probe_hw_mode(rt2x00dev); |
2263 | 2319 | ||
2264 | /* | 2320 | /* |
2265 | * This device requires firmware | 2321 | * This device requires firmware. |
2266 | */ | 2322 | */ |
2267 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 2323 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
2268 | 2324 | ||
@@ -2277,70 +2333,6 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2277 | /* | 2333 | /* |
2278 | * IEEE80211 stack callback functions. | 2334 | * IEEE80211 stack callback functions. |
2279 | */ | 2335 | */ |
2280 | static void rt61pci_configure_filter(struct ieee80211_hw *hw, | ||
2281 | unsigned int changed_flags, | ||
2282 | unsigned int *total_flags, | ||
2283 | int mc_count, | ||
2284 | struct dev_addr_list *mc_list) | ||
2285 | { | ||
2286 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2287 | u32 reg; | ||
2288 | |||
2289 | /* | ||
2290 | * Mask off any flags we are going to ignore from | ||
2291 | * the total_flags field. | ||
2292 | */ | ||
2293 | *total_flags &= | ||
2294 | FIF_ALLMULTI | | ||
2295 | FIF_FCSFAIL | | ||
2296 | FIF_PLCPFAIL | | ||
2297 | FIF_CONTROL | | ||
2298 | FIF_OTHER_BSS | | ||
2299 | FIF_PROMISC_IN_BSS; | ||
2300 | |||
2301 | /* | ||
2302 | * Apply some rules to the filters: | ||
2303 | * - Some filters imply different filters to be set. | ||
2304 | * - Some things we can't filter out at all. | ||
2305 | * - Multicast filter seems to kill broadcast traffic so never use it. | ||
2306 | */ | ||
2307 | *total_flags |= FIF_ALLMULTI; | ||
2308 | if (*total_flags & FIF_OTHER_BSS || | ||
2309 | *total_flags & FIF_PROMISC_IN_BSS) | ||
2310 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
2311 | |||
2312 | /* | ||
2313 | * Check if there is any work left for us. | ||
2314 | */ | ||
2315 | if (rt2x00dev->packet_filter == *total_flags) | ||
2316 | return; | ||
2317 | rt2x00dev->packet_filter = *total_flags; | ||
2318 | |||
2319 | /* | ||
2320 | * Start configuration steps. | ||
2321 | * Note that the version error will always be dropped | ||
2322 | * and broadcast frames will always be accepted since | ||
2323 | * there is no filter for it at this time. | ||
2324 | */ | ||
2325 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
2326 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, | ||
2327 | !(*total_flags & FIF_FCSFAIL)); | ||
2328 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, | ||
2329 | !(*total_flags & FIF_PLCPFAIL)); | ||
2330 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, | ||
2331 | !(*total_flags & FIF_CONTROL)); | ||
2332 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, | ||
2333 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
2334 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, | ||
2335 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
2336 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
2337 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | ||
2338 | !(*total_flags & FIF_ALLMULTI)); | ||
2339 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BORADCAST, 0); | ||
2340 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | ||
2341 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
2342 | } | ||
2343 | |||
2344 | static int rt61pci_set_retry_limit(struct ieee80211_hw *hw, | 2336 | static int rt61pci_set_retry_limit(struct ieee80211_hw *hw, |
2345 | u32 short_retry, u32 long_retry) | 2337 | u32 short_retry, u32 long_retry) |
2346 | { | 2338 | { |
@@ -2369,66 +2361,72 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | |||
2369 | return tsf; | 2361 | return tsf; |
2370 | } | 2362 | } |
2371 | 2363 | ||
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, | 2364 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
2381 | struct ieee80211_tx_control *control) | 2365 | struct ieee80211_tx_control *control) |
2382 | { | 2366 | { |
2383 | struct rt2x00_dev *rt2x00dev = hw->priv; | 2367 | struct rt2x00_dev *rt2x00dev = hw->priv; |
2384 | struct skb_desc *desc; | 2368 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
2385 | struct data_ring *ring; | 2369 | struct skb_frame_desc *skbdesc; |
2386 | struct data_entry *entry; | 2370 | unsigned int beacon_base; |
2371 | u32 reg; | ||
2387 | 2372 | ||
2388 | /* | 2373 | if (unlikely(!intf->beacon)) |
2389 | * Just in case the ieee80211 doesn't set this, | 2374 | 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 | 2375 | ||
2397 | /* | 2376 | /* |
2398 | * We need to append the descriptor in front of the | 2377 | * We need to append the descriptor in front of the |
2399 | * beacon frame. | 2378 | * beacon frame. |
2400 | */ | 2379 | */ |
2401 | if (skb_headroom(skb) < TXD_DESC_SIZE) { | 2380 | if (skb_headroom(skb) < intf->beacon->queue->desc_size) { |
2402 | if (pskb_expand_head(skb, TXD_DESC_SIZE, 0, GFP_ATOMIC)) | 2381 | if (pskb_expand_head(skb, intf->beacon->queue->desc_size, |
2382 | 0, GFP_ATOMIC)) | ||
2403 | return -ENOMEM; | 2383 | return -ENOMEM; |
2404 | } | 2384 | } |
2405 | 2385 | ||
2406 | /* | 2386 | /* |
2407 | * Add the descriptor in front of the skb. | 2387 | * Add the descriptor in front of the skb. |
2408 | */ | 2388 | */ |
2409 | skb_push(skb, ring->desc_size); | 2389 | skb_push(skb, intf->beacon->queue->desc_size); |
2410 | memset(skb->data, 0, ring->desc_size); | 2390 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
2411 | 2391 | ||
2412 | /* | 2392 | /* |
2413 | * Fill in skb descriptor | 2393 | * Fill in skb descriptor |
2414 | */ | 2394 | */ |
2415 | desc = get_skb_desc(skb); | 2395 | skbdesc = get_skb_frame_desc(skb); |
2416 | desc->desc_len = ring->desc_size; | 2396 | memset(skbdesc, 0, sizeof(*skbdesc)); |
2417 | desc->data_len = skb->len - ring->desc_size; | 2397 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
2418 | desc->desc = skb->data; | 2398 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
2419 | desc->data = skb->data + ring->desc_size; | 2399 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
2420 | desc->ring = ring; | 2400 | skbdesc->desc = skb->data; |
2421 | desc->entry = entry; | 2401 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2402 | skbdesc->entry = intf->beacon; | ||
2403 | |||
2404 | /* | ||
2405 | * Disable beaconing while we are reloading the beacon data, | ||
2406 | * otherwise we might be sending out invalid data. | ||
2407 | */ | ||
2408 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2409 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2410 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2411 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2412 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2422 | 2413 | ||
2414 | /* | ||
2415 | * mac80211 doesn't provide the control->queue variable | ||
2416 | * for beacons. Set our own queue identification so | ||
2417 | * it can be used during descriptor initialization. | ||
2418 | */ | ||
2419 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2423 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2420 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2424 | 2421 | ||
2425 | /* | 2422 | /* |
2426 | * Write entire beacon with descriptor to register, | 2423 | * Write entire beacon with descriptor to register, |
2427 | * and kick the beacon generator. | 2424 | * and kick the beacon generator. |
2428 | */ | 2425 | */ |
2429 | rt2x00pci_register_multiwrite(rt2x00dev, HW_BEACON_BASE0, | 2426 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); |
2427 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | ||
2430 | skb->data, skb->len); | 2428 | skb->data, skb->len); |
2431 | rt61pci_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2429 | rt61pci_kick_tx_queue(rt2x00dev, control->queue); |
2432 | 2430 | ||
2433 | return 0; | 2431 | return 0; |
2434 | } | 2432 | } |
@@ -2441,14 +2439,13 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2441 | .remove_interface = rt2x00mac_remove_interface, | 2439 | .remove_interface = rt2x00mac_remove_interface, |
2442 | .config = rt2x00mac_config, | 2440 | .config = rt2x00mac_config, |
2443 | .config_interface = rt2x00mac_config_interface, | 2441 | .config_interface = rt2x00mac_config_interface, |
2444 | .configure_filter = rt61pci_configure_filter, | 2442 | .configure_filter = rt2x00mac_configure_filter, |
2445 | .get_stats = rt2x00mac_get_stats, | 2443 | .get_stats = rt2x00mac_get_stats, |
2446 | .set_retry_limit = rt61pci_set_retry_limit, | 2444 | .set_retry_limit = rt61pci_set_retry_limit, |
2447 | .bss_info_changed = rt2x00mac_bss_info_changed, | 2445 | .bss_info_changed = rt2x00mac_bss_info_changed, |
2448 | .conf_tx = rt2x00mac_conf_tx, | 2446 | .conf_tx = rt2x00mac_conf_tx, |
2449 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2447 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2450 | .get_tsf = rt61pci_get_tsf, | 2448 | .get_tsf = rt61pci_get_tsf, |
2451 | .reset_tsf = rt61pci_reset_tsf, | ||
2452 | .beacon_update = rt61pci_beacon_update, | 2449 | .beacon_update = rt61pci_beacon_update, |
2453 | }; | 2450 | }; |
2454 | 2451 | ||
@@ -2456,6 +2453,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2456 | .irq_handler = rt61pci_interrupt, | 2453 | .irq_handler = rt61pci_interrupt, |
2457 | .probe_hw = rt61pci_probe_hw, | 2454 | .probe_hw = rt61pci_probe_hw, |
2458 | .get_firmware_name = rt61pci_get_firmware_name, | 2455 | .get_firmware_name = rt61pci_get_firmware_name, |
2456 | .get_firmware_crc = rt61pci_get_firmware_crc, | ||
2459 | .load_firmware = rt61pci_load_firmware, | 2457 | .load_firmware = rt61pci_load_firmware, |
2460 | .initialize = rt2x00pci_initialize, | 2458 | .initialize = rt2x00pci_initialize, |
2461 | .uninitialize = rt2x00pci_uninitialize, | 2459 | .uninitialize = rt2x00pci_uninitialize, |
@@ -2470,19 +2468,42 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2470 | .write_tx_data = rt2x00pci_write_tx_data, | 2468 | .write_tx_data = rt2x00pci_write_tx_data, |
2471 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2469 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2472 | .fill_rxdone = rt61pci_fill_rxdone, | 2470 | .fill_rxdone = rt61pci_fill_rxdone, |
2473 | .config_mac_addr = rt61pci_config_mac_addr, | 2471 | .config_filter = rt61pci_config_filter, |
2474 | .config_bssid = rt61pci_config_bssid, | 2472 | .config_intf = rt61pci_config_intf, |
2475 | .config_type = rt61pci_config_type, | 2473 | .config_erp = rt61pci_config_erp, |
2476 | .config_preamble = rt61pci_config_preamble, | ||
2477 | .config = rt61pci_config, | 2474 | .config = rt61pci_config, |
2478 | }; | 2475 | }; |
2479 | 2476 | ||
2477 | static const struct data_queue_desc rt61pci_queue_rx = { | ||
2478 | .entry_num = RX_ENTRIES, | ||
2479 | .data_size = DATA_FRAME_SIZE, | ||
2480 | .desc_size = RXD_DESC_SIZE, | ||
2481 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
2482 | }; | ||
2483 | |||
2484 | static const struct data_queue_desc rt61pci_queue_tx = { | ||
2485 | .entry_num = TX_ENTRIES, | ||
2486 | .data_size = DATA_FRAME_SIZE, | ||
2487 | .desc_size = TXD_DESC_SIZE, | ||
2488 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
2489 | }; | ||
2490 | |||
2491 | static const struct data_queue_desc rt61pci_queue_bcn = { | ||
2492 | .entry_num = 4 * BEACON_ENTRIES, | ||
2493 | .data_size = MGMT_FRAME_SIZE, | ||
2494 | .desc_size = TXINFO_SIZE, | ||
2495 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
2496 | }; | ||
2497 | |||
2480 | static const struct rt2x00_ops rt61pci_ops = { | 2498 | static const struct rt2x00_ops rt61pci_ops = { |
2481 | .name = KBUILD_MODNAME, | 2499 | .name = KBUILD_MODNAME, |
2482 | .rxd_size = RXD_DESC_SIZE, | 2500 | .max_sta_intf = 1, |
2483 | .txd_size = TXD_DESC_SIZE, | 2501 | .max_ap_intf = 4, |
2484 | .eeprom_size = EEPROM_SIZE, | 2502 | .eeprom_size = EEPROM_SIZE, |
2485 | .rf_size = RF_SIZE, | 2503 | .rf_size = RF_SIZE, |
2504 | .rx = &rt61pci_queue_rx, | ||
2505 | .tx = &rt61pci_queue_tx, | ||
2506 | .bcn = &rt61pci_queue_bcn, | ||
2486 | .lib = &rt61pci_rt2x00_ops, | 2507 | .lib = &rt61pci_rt2x00_ops, |
2487 | .hw = &rt61pci_mac80211_ops, | 2508 | .hw = &rt61pci_mac80211_ops, |
2488 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 2509 | #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 3909cf42f472..a9efe25f1ea7 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,85 +279,158 @@ 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_brightness_set(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 | 287 | container_of(led_cdev, struct rt2x00_led, led_dev); | |
288 | tmp = le32_to_cpu(mac[1]); | 288 | unsigned int enabled = brightness != LED_OFF; |
289 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | 289 | unsigned int a_mode = |
290 | mac[1] = cpu_to_le32(tmp); | 290 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); |
291 | 291 | unsigned int bg_mode = | |
292 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 292 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); |
293 | (2 * sizeof(__le32))); | 293 | |
294 | if (led->type == LED_TYPE_RADIO) { | ||
295 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
296 | MCU_LEDCS_RADIO_STATUS, enabled); | ||
297 | |||
298 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
299 | 0, led->rt2x00dev->led_mcu_reg, | ||
300 | REGISTER_TIMEOUT); | ||
301 | } else if (led->type == LED_TYPE_ASSOC) { | ||
302 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
303 | MCU_LEDCS_LINK_BG_STATUS, bg_mode); | ||
304 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
305 | MCU_LEDCS_LINK_A_STATUS, a_mode); | ||
306 | |||
307 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
308 | 0, led->rt2x00dev->led_mcu_reg, | ||
309 | REGISTER_TIMEOUT); | ||
310 | } else if (led->type == LED_TYPE_QUALITY) { | ||
311 | /* | ||
312 | * The brightness is divided into 6 levels (0 - 5), | ||
313 | * this means we need to convert the brightness | ||
314 | * argument into the matching level within that range. | ||
315 | */ | ||
316 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
317 | brightness / (LED_FULL / 6), | ||
318 | led->rt2x00dev->led_mcu_reg, | ||
319 | REGISTER_TIMEOUT); | ||
320 | } | ||
294 | } | 321 | } |
295 | 322 | ||
296 | static void rt73usb_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 323 | static int rt73usb_blink_set(struct led_classdev *led_cdev, |
324 | unsigned long *delay_on, | ||
325 | unsigned long *delay_off) | ||
297 | { | 326 | { |
298 | u32 tmp; | 327 | struct rt2x00_led *led = |
328 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
329 | u32 reg; | ||
299 | 330 | ||
300 | tmp = le32_to_cpu(bssid[1]); | 331 | rt73usb_register_read(led->rt2x00dev, MAC_CSR14, ®); |
301 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 332 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, *delay_on); |
302 | bssid[1] = cpu_to_le32(tmp); | 333 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, *delay_off); |
334 | rt73usb_register_write(led->rt2x00dev, MAC_CSR14, reg); | ||
303 | 335 | ||
304 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 336 | return 0; |
305 | (2 * sizeof(__le32))); | ||
306 | } | 337 | } |
338 | #endif /* CONFIG_RT73USB_LEDS */ | ||
307 | 339 | ||
308 | static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 340 | /* |
309 | const int tsf_sync) | 341 | * Configuration handlers. |
342 | */ | ||
343 | static void rt73usb_config_filter(struct rt2x00_dev *rt2x00dev, | ||
344 | const unsigned int filter_flags) | ||
310 | { | 345 | { |
311 | u32 reg; | 346 | u32 reg; |
312 | 347 | ||
313 | /* | 348 | /* |
314 | * Clear current synchronisation setup. | 349 | * Start configuration steps. |
315 | * For the Beacon base registers we only need to clear | 350 | * Note that the version error will always be dropped |
316 | * the first byte since that byte contains the VALID and OWNER | 351 | * and broadcast frames will always be accepted since |
317 | * bits which (when set to 0) will invalidate the entire beacon. | 352 | * there is no filter for it at this time. |
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 | |||
325 | /* | ||
326 | * Enable synchronisation. | ||
327 | */ | 353 | */ |
328 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 354 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
329 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | 355 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, |
330 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | 356 | !(filter_flags & FIF_FCSFAIL)); |
331 | (tsf_sync == TSF_SYNC_BEACON)); | 357 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, |
332 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 358 | !(filter_flags & FIF_PLCPFAIL)); |
333 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | 359 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, |
334 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 360 | !(filter_flags & FIF_CONTROL)); |
361 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, | ||
362 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
363 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, | ||
364 | !(filter_flags & FIF_PROMISC_IN_BSS) && | ||
365 | !rt2x00dev->intf_ap_count); | ||
366 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
367 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | ||
368 | !(filter_flags & FIF_ALLMULTI)); | ||
369 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | ||
370 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, | ||
371 | !(filter_flags & FIF_CONTROL)); | ||
372 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
335 | } | 373 | } |
336 | 374 | ||
337 | static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 375 | static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 376 | struct rt2x00_intf *intf, |
339 | const int ack_timeout, | 377 | struct rt2x00intf_conf *conf, |
340 | const int ack_consume_time) | 378 | const unsigned int flags) |
341 | { | 379 | { |
380 | unsigned int beacon_base; | ||
342 | u32 reg; | 381 | u32 reg; |
343 | 382 | ||
344 | /* | 383 | if (flags & CONFIG_UPDATE_TYPE) { |
345 | * When in atomic context, reschedule and let rt2x00lib | 384 | /* |
346 | * call this function again. | 385 | * Clear current synchronisation setup. |
347 | */ | 386 | * For the Beacon base registers we only need to clear |
348 | if (in_atomic()) { | 387 | * the first byte since that byte contains the VALID and OWNER |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 388 | * bits which (when set to 0) will invalidate the entire beacon. |
350 | return; | 389 | */ |
390 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
391 | rt73usb_register_write(rt2x00dev, beacon_base, 0); | ||
392 | |||
393 | /* | ||
394 | * Enable synchronisation. | ||
395 | */ | ||
396 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
397 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
398 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
399 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
400 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
351 | } | 401 | } |
352 | 402 | ||
403 | if (flags & CONFIG_UPDATE_MAC) { | ||
404 | reg = le32_to_cpu(conf->mac[1]); | ||
405 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
406 | conf->mac[1] = cpu_to_le32(reg); | ||
407 | |||
408 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, | ||
409 | conf->mac, sizeof(conf->mac)); | ||
410 | } | ||
411 | |||
412 | if (flags & CONFIG_UPDATE_BSSID) { | ||
413 | reg = le32_to_cpu(conf->bssid[1]); | ||
414 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); | ||
415 | conf->bssid[1] = cpu_to_le32(reg); | ||
416 | |||
417 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, | ||
418 | conf->bssid, sizeof(conf->bssid)); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, | ||
423 | struct rt2x00lib_erp *erp) | ||
424 | { | ||
425 | u32 reg; | ||
426 | |||
353 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 427 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
354 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); | 428 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout); |
355 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 429 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
356 | 430 | ||
357 | rt73usb_register_read(rt2x00dev, TXRX_CSR4, ®); | 431 | rt73usb_register_read(rt2x00dev, TXRX_CSR4, ®); |
358 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 432 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 433 | !!erp->short_preamble); |
360 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | 434 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); |
361 | } | 435 | } |
362 | 436 | ||
@@ -442,28 +516,22 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
442 | case ANTENNA_HW_DIVERSITY: | 516 | case ANTENNA_HW_DIVERSITY: |
443 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); | 517 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
444 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) | 518 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) |
445 | && (rt2x00dev->curr_hwmode != HWMODE_A); | 519 | && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); |
446 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); | 520 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); |
447 | break; | 521 | break; |
448 | case ANTENNA_A: | 522 | case ANTENNA_A: |
449 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 523 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
450 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 524 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
451 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 525 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
452 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 526 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
453 | else | 527 | else |
454 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 528 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
455 | break; | 529 | 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: | 530 | case ANTENNA_B: |
531 | default: | ||
464 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 532 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
465 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 533 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
466 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 534 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
467 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 535 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
468 | else | 536 | else |
469 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 537 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
@@ -501,14 +569,8 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | |||
501 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 569 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
502 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 570 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
503 | break; | 571 | 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: | 572 | case ANTENNA_B: |
573 | default: | ||
512 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 574 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
513 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 575 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
514 | break; | 576 | break; |
@@ -558,7 +620,14 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
558 | unsigned int i; | 620 | unsigned int i; |
559 | u32 reg; | 621 | u32 reg; |
560 | 622 | ||
561 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | 623 | /* |
624 | * We should never come here because rt2x00lib is supposed | ||
625 | * to catch this and send us the correct antenna explicitely. | ||
626 | */ | ||
627 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
628 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
629 | |||
630 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { | ||
562 | sel = antenna_sel_a; | 631 | sel = antenna_sel_a; |
563 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 632 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); |
564 | } else { | 633 | } else { |
@@ -572,10 +641,9 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
572 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); | 641 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); |
573 | 642 | ||
574 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 643 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
575 | (rt2x00dev->curr_hwmode == HWMODE_B || | 644 | (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ)); |
576 | rt2x00dev->curr_hwmode == HWMODE_G)); | ||
577 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 645 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
578 | (rt2x00dev->curr_hwmode == HWMODE_A)); | 646 | (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)); |
579 | 647 | ||
580 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); | 648 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); |
581 | 649 | ||
@@ -617,8 +685,8 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
617 | } | 685 | } |
618 | 686 | ||
619 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | 687 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, |
620 | const unsigned int flags, | 688 | struct rt2x00lib_conf *libconf, |
621 | struct rt2x00lib_conf *libconf) | 689 | const unsigned int flags) |
622 | { | 690 | { |
623 | if (flags & CONFIG_UPDATE_PHYMODE) | 691 | if (flags & CONFIG_UPDATE_PHYMODE) |
624 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); | 692 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -634,68 +702,6 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | |||
634 | } | 702 | } |
635 | 703 | ||
636 | /* | 704 | /* |
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 | 705 | * Link tuning |
700 | */ | 706 | */ |
701 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, | 707 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -729,17 +735,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
729 | u8 up_bound; | 735 | u8 up_bound; |
730 | u8 low_bound; | 736 | u8 low_bound; |
731 | 737 | ||
732 | /* | ||
733 | * Update Led strength | ||
734 | */ | ||
735 | rt73usb_activity_led(rt2x00dev, rssi); | ||
736 | |||
737 | rt73usb_bbp_read(rt2x00dev, 17, &r17); | 738 | rt73usb_bbp_read(rt2x00dev, 17, &r17); |
738 | 739 | ||
739 | /* | 740 | /* |
740 | * Determine r17 bounds. | 741 | * Determine r17 bounds. |
741 | */ | 742 | */ |
742 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 743 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
743 | low_bound = 0x28; | 744 | low_bound = 0x28; |
744 | up_bound = 0x48; | 745 | up_bound = 0x48; |
745 | 746 | ||
@@ -766,6 +767,13 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
766 | } | 767 | } |
767 | 768 | ||
768 | /* | 769 | /* |
770 | * If we are not associated, we should go straight to the | ||
771 | * dynamic CCA tuning. | ||
772 | */ | ||
773 | if (!rt2x00dev->intf_associated) | ||
774 | goto dynamic_cca_tune; | ||
775 | |||
776 | /* | ||
769 | * Special big-R17 for very short distance | 777 | * Special big-R17 for very short distance |
770 | */ | 778 | */ |
771 | if (rssi > -35) { | 779 | if (rssi > -35) { |
@@ -815,6 +823,8 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
815 | return; | 823 | return; |
816 | } | 824 | } |
817 | 825 | ||
826 | dynamic_cca_tune: | ||
827 | |||
818 | /* | 828 | /* |
819 | * r17 does not yet exceed upper limit, continue and base | 829 | * r17 does not yet exceed upper limit, continue and base |
820 | * the r17 tuning on the false CCA count. | 830 | * the r17 tuning on the false CCA count. |
@@ -833,16 +843,30 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
833 | } | 843 | } |
834 | 844 | ||
835 | /* | 845 | /* |
836 | * Firmware name function. | 846 | * Firmware functions |
837 | */ | 847 | */ |
838 | static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 848 | static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) |
839 | { | 849 | { |
840 | return FIRMWARE_RT2571; | 850 | return FIRMWARE_RT2571; |
841 | } | 851 | } |
842 | 852 | ||
843 | /* | 853 | static u16 rt73usb_get_firmware_crc(void *data, const size_t len) |
844 | * Initialization functions. | 854 | { |
845 | */ | 855 | u16 crc; |
856 | |||
857 | /* | ||
858 | * Use the crc itu-t algorithm. | ||
859 | * The last 2 bytes in the firmware array are the crc checksum itself, | ||
860 | * this means that we should never pass those 2 bytes to the crc | ||
861 | * algorithm. | ||
862 | */ | ||
863 | crc = crc_itu_t(0, data, len - 2); | ||
864 | crc = crc_itu_t_byte(crc, 0); | ||
865 | crc = crc_itu_t_byte(crc, 0); | ||
866 | |||
867 | return crc; | ||
868 | } | ||
869 | |||
846 | static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | 870 | static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, |
847 | const size_t len) | 871 | const size_t len) |
848 | { | 872 | { |
@@ -889,7 +913,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
889 | 913 | ||
890 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 914 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
891 | USB_VENDOR_REQUEST_OUT, | 915 | USB_VENDOR_REQUEST_OUT, |
892 | FIRMWARE_IMAGE_BASE + i, 0x0000, | 916 | FIRMWARE_IMAGE_BASE + i, 0, |
893 | cache, buflen, timeout); | 917 | cache, buflen, timeout); |
894 | 918 | ||
895 | ptr += buflen; | 919 | ptr += buflen; |
@@ -902,18 +926,19 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
902 | * we need to specify a long timeout time. | 926 | * we need to specify a long timeout time. |
903 | */ | 927 | */ |
904 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, | 928 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, |
905 | 0x0000, USB_MODE_FIRMWARE, | 929 | 0, USB_MODE_FIRMWARE, |
906 | REGISTER_TIMEOUT_FIRMWARE); | 930 | REGISTER_TIMEOUT_FIRMWARE); |
907 | if (status < 0) { | 931 | if (status < 0) { |
908 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); | 932 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); |
909 | return status; | 933 | return status; |
910 | } | 934 | } |
911 | 935 | ||
912 | rt73usb_disable_led(rt2x00dev); | ||
913 | |||
914 | return 0; | 936 | return 0; |
915 | } | 937 | } |
916 | 938 | ||
939 | /* | ||
940 | * Initialization functions. | ||
941 | */ | ||
917 | static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | 942 | static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) |
918 | { | 943 | { |
919 | u32 reg; | 944 | u32 reg; |
@@ -1021,6 +1046,17 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1021 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); | 1046 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); |
1022 | 1047 | ||
1023 | /* | 1048 | /* |
1049 | * Clear all beacons | ||
1050 | * For the Beacon base registers we only need to clear | ||
1051 | * the first byte since that byte contains the VALID and OWNER | ||
1052 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1053 | */ | ||
1054 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1055 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1056 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1057 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1058 | |||
1059 | /* | ||
1024 | * We must clear the error counters. | 1060 | * We must clear the error counters. |
1025 | * These registers are cleared on read, | 1061 | * These registers are cleared on read, |
1026 | * so we may pass a useless variable to store the value. | 1062 | * so we may pass a useless variable to store the value. |
@@ -1094,19 +1130,15 @@ continue_csr_init: | |||
1094 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); | 1130 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); |
1095 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); | 1131 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); |
1096 | 1132 | ||
1097 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
1098 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 1133 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
1099 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 1134 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
1100 | 1135 | ||
1101 | if (eeprom != 0xffff && eeprom != 0x0000) { | 1136 | if (eeprom != 0xffff && eeprom != 0x0000) { |
1102 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 1137 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
1103 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 1138 | 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); | 1139 | rt73usb_bbp_write(rt2x00dev, reg_id, value); |
1107 | } | 1140 | } |
1108 | } | 1141 | } |
1109 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
1110 | 1142 | ||
1111 | return 0; | 1143 | return 0; |
1112 | } | 1144 | } |
@@ -1136,21 +1168,11 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1136 | return -EIO; | 1168 | return -EIO; |
1137 | } | 1169 | } |
1138 | 1170 | ||
1139 | /* | ||
1140 | * Enable LED | ||
1141 | */ | ||
1142 | rt73usb_enable_led(rt2x00dev); | ||
1143 | |||
1144 | return 0; | 1171 | return 0; |
1145 | } | 1172 | } |
1146 | 1173 | ||
1147 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 1174 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
1148 | { | 1175 | { |
1149 | /* | ||
1150 | * Disable LED | ||
1151 | */ | ||
1152 | rt73usb_disable_led(rt2x00dev); | ||
1153 | |||
1154 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | 1176 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
1155 | 1177 | ||
1156 | /* | 1178 | /* |
@@ -1234,10 +1256,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1234 | */ | 1256 | */ |
1235 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1257 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1236 | struct sk_buff *skb, | 1258 | struct sk_buff *skb, |
1237 | struct txdata_entry_desc *desc, | 1259 | struct txentry_desc *txdesc, |
1238 | struct ieee80211_tx_control *control) | 1260 | struct ieee80211_tx_control *control) |
1239 | { | 1261 | { |
1240 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1262 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1241 | __le32 *txd = skbdesc->desc; | 1263 | __le32 *txd = skbdesc->desc; |
1242 | u32 word; | 1264 | u32 word; |
1243 | 1265 | ||
@@ -1245,47 +1267,47 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1245 | * Start writing the descriptor words. | 1267 | * Start writing the descriptor words. |
1246 | */ | 1268 | */ |
1247 | rt2x00_desc_read(txd, 1, &word); | 1269 | rt2x00_desc_read(txd, 1, &word); |
1248 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | 1270 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); |
1249 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | 1271 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1250 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1272 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1251 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1273 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1252 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1274 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1253 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1275 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); |
1254 | rt2x00_desc_write(txd, 1, word); | 1276 | rt2x00_desc_write(txd, 1, word); |
1255 | 1277 | ||
1256 | rt2x00_desc_read(txd, 2, &word); | 1278 | rt2x00_desc_read(txd, 2, &word); |
1257 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1279 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1258 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1280 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1259 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1281 | 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); | 1282 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1261 | rt2x00_desc_write(txd, 2, word); | 1283 | rt2x00_desc_write(txd, 2, word); |
1262 | 1284 | ||
1263 | rt2x00_desc_read(txd, 5, &word); | 1285 | rt2x00_desc_read(txd, 5, &word); |
1264 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1286 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1265 | TXPOWER_TO_DEV(control->power_level)); | 1287 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); |
1266 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1288 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1267 | rt2x00_desc_write(txd, 5, word); | 1289 | rt2x00_desc_write(txd, 5, word); |
1268 | 1290 | ||
1269 | rt2x00_desc_read(txd, 0, &word); | 1291 | rt2x00_desc_read(txd, 0, &word); |
1270 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1292 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1271 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1293 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1272 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1294 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1273 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1295 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1274 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1296 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1275 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1297 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1276 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1298 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1277 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1299 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1278 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1300 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1279 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1301 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1280 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1302 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1281 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1303 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1282 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1304 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1283 | !!(control->flags & | 1305 | !!(control->flags & |
1284 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1306 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
1285 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1307 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1286 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1308 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1287 | rt2x00_set_field32(&word, TXD_W0_BURST2, | 1309 | rt2x00_set_field32(&word, TXD_W0_BURST2, |
1288 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1310 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1289 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1311 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1290 | rt2x00_desc_write(txd, 0, word); | 1312 | rt2x00_desc_write(txd, 0, word); |
1291 | } | 1313 | } |
@@ -1309,11 +1331,11 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1309 | * TX data initialization | 1331 | * TX data initialization |
1310 | */ | 1332 | */ |
1311 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1333 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1312 | unsigned int queue) | 1334 | const unsigned int queue) |
1313 | { | 1335 | { |
1314 | u32 reg; | 1336 | u32 reg; |
1315 | 1337 | ||
1316 | if (queue != IEEE80211_TX_QUEUE_BEACON) | 1338 | if (queue != RT2X00_BCN_QUEUE_BEACON) |
1317 | return; | 1339 | return; |
1318 | 1340 | ||
1319 | /* | 1341 | /* |
@@ -1324,6 +1346,8 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1324 | 1346 | ||
1325 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 1347 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
1326 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { | 1348 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { |
1349 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1350 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1327 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1351 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
1328 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 1352 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
1329 | } | 1353 | } |
@@ -1353,7 +1377,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1353 | return 0; | 1377 | return 0; |
1354 | } | 1378 | } |
1355 | 1379 | ||
1356 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 1380 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
1357 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 1381 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
1358 | if (lna == 3 || lna == 2) | 1382 | if (lna == 3 || lna == 2) |
1359 | offset += 10; | 1383 | offset += 10; |
@@ -1377,37 +1401,62 @@ 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; | 1401 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; |
1378 | } | 1402 | } |
1379 | 1403 | ||
1380 | static void rt73usb_fill_rxdone(struct data_entry *entry, | 1404 | static void rt73usb_fill_rxdone(struct queue_entry *entry, |
1381 | struct rxdata_entry_desc *desc) | 1405 | struct rxdone_entry_desc *rxdesc) |
1382 | { | 1406 | { |
1383 | struct skb_desc *skbdesc = get_skb_desc(entry->skb); | 1407 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1384 | __le32 *rxd = (__le32 *)entry->skb->data; | 1408 | __le32 *rxd = (__le32 *)entry->skb->data; |
1409 | unsigned int offset = entry->queue->desc_size + 2; | ||
1385 | u32 word0; | 1410 | u32 word0; |
1386 | u32 word1; | 1411 | u32 word1; |
1387 | 1412 | ||
1413 | /* | ||
1414 | * Copy descriptor to the available headroom inside the skbuffer. | ||
1415 | */ | ||
1416 | skb_push(entry->skb, offset); | ||
1417 | memcpy(entry->skb->data, rxd, entry->queue->desc_size); | ||
1418 | rxd = (__le32 *)entry->skb->data; | ||
1419 | |||
1420 | /* | ||
1421 | * The descriptor is now aligned to 4 bytes and thus it is | ||
1422 | * now safe to read it on all architectures. | ||
1423 | */ | ||
1388 | rt2x00_desc_read(rxd, 0, &word0); | 1424 | rt2x00_desc_read(rxd, 0, &word0); |
1389 | rt2x00_desc_read(rxd, 1, &word1); | 1425 | rt2x00_desc_read(rxd, 1, &word1); |
1390 | 1426 | ||
1391 | desc->flags = 0; | 1427 | rxdesc->flags = 0; |
1392 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1428 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1393 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1429 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1394 | 1430 | ||
1395 | /* | 1431 | /* |
1396 | * Obtain the status about this packet. | 1432 | * Obtain the status about this packet. |
1433 | * When frame was received with an OFDM bitrate, | ||
1434 | * the signal is the PLCP value. If it was received with | ||
1435 | * a CCK bitrate the signal is the rate in 100kbit/s. | ||
1397 | */ | 1436 | */ |
1398 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1437 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1399 | desc->rssi = rt73usb_agc_to_rssi(entry->ring->rt2x00dev, word1); | 1438 | rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1); |
1400 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1439 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1401 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1440 | |
1402 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1441 | rxdesc->dev_flags = 0; |
1442 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | ||
1443 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; | ||
1444 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | ||
1445 | rxdesc->dev_flags |= RXDONE_MY_BSS; | ||
1446 | |||
1447 | /* | ||
1448 | * Adjust the skb memory window to the frame boundaries. | ||
1449 | */ | ||
1450 | skb_pull(entry->skb, offset + entry->queue->desc_size); | ||
1451 | skb_trim(entry->skb, rxdesc->size); | ||
1403 | 1452 | ||
1404 | /* | 1453 | /* |
1405 | * Set descriptor and data pointer. | 1454 | * Set descriptor and data pointer. |
1406 | */ | 1455 | */ |
1407 | skbdesc->desc = entry->skb->data; | 1456 | skbdesc->data = entry->skb->data; |
1408 | skbdesc->desc_len = entry->ring->desc_size; | 1457 | skbdesc->data_len = rxdesc->size; |
1409 | skbdesc->data = entry->skb->data + entry->ring->desc_size; | 1458 | skbdesc->desc = rxd; |
1410 | skbdesc->data_len = desc->size; | 1459 | skbdesc->desc_len = entry->queue->desc_size; |
1411 | } | 1460 | } |
1412 | 1461 | ||
1413 | /* | 1462 | /* |
@@ -1499,7 +1548,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1499 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 1548 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
1500 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 1549 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
1501 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 1550 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
1502 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 1551 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
1503 | } else { | 1552 | } else { |
1504 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 1553 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
1505 | if (value < -10 || value > 10) | 1554 | if (value < -10 || value > 10) |
@@ -1577,33 +1626,60 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1577 | /* | 1626 | /* |
1578 | * Store led settings, for correct led behaviour. | 1627 | * Store led settings, for correct led behaviour. |
1579 | */ | 1628 | */ |
1629 | #ifdef CONFIG_RT73USB_LEDS | ||
1580 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 1630 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
1581 | 1631 | ||
1582 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | 1632 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; |
1583 | rt2x00dev->led_mode); | 1633 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; |
1584 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | 1634 | rt2x00dev->led_radio.led_dev.brightness_set = |
1635 | rt73usb_brightness_set; | ||
1636 | rt2x00dev->led_radio.led_dev.blink_set = | ||
1637 | rt73usb_blink_set; | ||
1638 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
1639 | |||
1640 | rt2x00dev->led_assoc.rt2x00dev = rt2x00dev; | ||
1641 | rt2x00dev->led_assoc.type = LED_TYPE_ASSOC; | ||
1642 | rt2x00dev->led_assoc.led_dev.brightness_set = | ||
1643 | rt73usb_brightness_set; | ||
1644 | rt2x00dev->led_assoc.led_dev.blink_set = | ||
1645 | rt73usb_blink_set; | ||
1646 | rt2x00dev->led_assoc.flags = LED_INITIALIZED; | ||
1647 | |||
1648 | if (value == LED_MODE_SIGNAL_STRENGTH) { | ||
1649 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
1650 | rt2x00dev->led_radio.type = LED_TYPE_QUALITY; | ||
1651 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
1652 | rt73usb_brightness_set; | ||
1653 | rt2x00dev->led_qual.led_dev.blink_set = | ||
1654 | rt73usb_blink_set; | ||
1655 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
1656 | } | ||
1657 | |||
1658 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); | ||
1659 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
1585 | rt2x00_get_field16(eeprom, | 1660 | rt2x00_get_field16(eeprom, |
1586 | EEPROM_LED_POLARITY_GPIO_0)); | 1661 | EEPROM_LED_POLARITY_GPIO_0)); |
1587 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | 1662 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1, |
1588 | rt2x00_get_field16(eeprom, | 1663 | rt2x00_get_field16(eeprom, |
1589 | EEPROM_LED_POLARITY_GPIO_1)); | 1664 | EEPROM_LED_POLARITY_GPIO_1)); |
1590 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | 1665 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2, |
1591 | rt2x00_get_field16(eeprom, | 1666 | rt2x00_get_field16(eeprom, |
1592 | EEPROM_LED_POLARITY_GPIO_2)); | 1667 | EEPROM_LED_POLARITY_GPIO_2)); |
1593 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | 1668 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3, |
1594 | rt2x00_get_field16(eeprom, | 1669 | rt2x00_get_field16(eeprom, |
1595 | EEPROM_LED_POLARITY_GPIO_3)); | 1670 | EEPROM_LED_POLARITY_GPIO_3)); |
1596 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | 1671 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4, |
1597 | rt2x00_get_field16(eeprom, | 1672 | rt2x00_get_field16(eeprom, |
1598 | EEPROM_LED_POLARITY_GPIO_4)); | 1673 | EEPROM_LED_POLARITY_GPIO_4)); |
1599 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | 1674 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT, |
1600 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | 1675 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); |
1601 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | 1676 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG, |
1602 | rt2x00_get_field16(eeprom, | 1677 | rt2x00_get_field16(eeprom, |
1603 | EEPROM_LED_POLARITY_RDY_G)); | 1678 | EEPROM_LED_POLARITY_RDY_G)); |
1604 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | 1679 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, |
1605 | rt2x00_get_field16(eeprom, | 1680 | rt2x00_get_field16(eeprom, |
1606 | EEPROM_LED_POLARITY_RDY_A)); | 1681 | EEPROM_LED_POLARITY_RDY_A)); |
1682 | #endif /* CONFIG_RT73USB_LEDS */ | ||
1607 | 1683 | ||
1608 | return 0; | 1684 | return 0; |
1609 | } | 1685 | } |
@@ -1759,7 +1835,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1759 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1835 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1760 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | 1836 | rt2x00dev->hw->max_signal = MAX_SIGNAL; |
1761 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | 1837 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; |
1762 | rt2x00dev->hw->queues = 5; | 1838 | rt2x00dev->hw->queues = 4; |
1763 | 1839 | ||
1764 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1840 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); |
1765 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1841 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -1776,8 +1852,8 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1776 | /* | 1852 | /* |
1777 | * Initialize hw_mode information. | 1853 | * Initialize hw_mode information. |
1778 | */ | 1854 | */ |
1779 | spec->num_modes = 2; | 1855 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1780 | spec->num_rates = 12; | 1856 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1781 | spec->tx_power_a = NULL; | 1857 | spec->tx_power_a = NULL; |
1782 | spec->tx_power_bg = txpower; | 1858 | spec->tx_power_bg = txpower; |
1783 | spec->tx_power_default = DEFAULT_TXPOWER; | 1859 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1786,20 +1862,20 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1786 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); | 1862 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); |
1787 | spec->channels = rf_vals_bg_2528; | 1863 | spec->channels = rf_vals_bg_2528; |
1788 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { | 1864 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { |
1865 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1789 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); | 1866 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); |
1790 | spec->channels = rf_vals_5226; | 1867 | spec->channels = rf_vals_5226; |
1791 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { | 1868 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { |
1792 | spec->num_channels = 14; | 1869 | spec->num_channels = 14; |
1793 | spec->channels = rf_vals_5225_2527; | 1870 | spec->channels = rf_vals_5225_2527; |
1794 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { | 1871 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { |
1872 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1795 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); | 1873 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); |
1796 | spec->channels = rf_vals_5225_2527; | 1874 | spec->channels = rf_vals_5225_2527; |
1797 | } | 1875 | } |
1798 | 1876 | ||
1799 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 1877 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || |
1800 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { | 1878 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { |
1801 | spec->num_modes = 3; | ||
1802 | |||
1803 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 1879 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
1804 | for (i = 0; i < 14; i++) | 1880 | for (i = 0; i < 14; i++) |
1805 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | 1881 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); |
@@ -1829,9 +1905,10 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1829 | rt73usb_probe_hw_mode(rt2x00dev); | 1905 | rt73usb_probe_hw_mode(rt2x00dev); |
1830 | 1906 | ||
1831 | /* | 1907 | /* |
1832 | * This device requires firmware | 1908 | * This device requires firmware. |
1833 | */ | 1909 | */ |
1834 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 1910 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
1911 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); | ||
1835 | 1912 | ||
1836 | /* | 1913 | /* |
1837 | * Set the rssi offset. | 1914 | * Set the rssi offset. |
@@ -1844,79 +1921,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1844 | /* | 1921 | /* |
1845 | * IEEE80211 stack callback functions. | 1922 | * IEEE80211 stack callback functions. |
1846 | */ | 1923 | */ |
1847 | static void rt73usb_configure_filter(struct ieee80211_hw *hw, | ||
1848 | unsigned int changed_flags, | ||
1849 | unsigned int *total_flags, | ||
1850 | int mc_count, | ||
1851 | struct dev_addr_list *mc_list) | ||
1852 | { | ||
1853 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1854 | u32 reg; | ||
1855 | |||
1856 | /* | ||
1857 | * Mask off any flags we are going to ignore from | ||
1858 | * the total_flags field. | ||
1859 | */ | ||
1860 | *total_flags &= | ||
1861 | FIF_ALLMULTI | | ||
1862 | FIF_FCSFAIL | | ||
1863 | FIF_PLCPFAIL | | ||
1864 | FIF_CONTROL | | ||
1865 | FIF_OTHER_BSS | | ||
1866 | FIF_PROMISC_IN_BSS; | ||
1867 | |||
1868 | /* | ||
1869 | * Apply some rules to the filters: | ||
1870 | * - Some filters imply different filters to be set. | ||
1871 | * - Some things we can't filter out at all. | ||
1872 | * - Multicast filter seems to kill broadcast traffic so never use it. | ||
1873 | */ | ||
1874 | *total_flags |= FIF_ALLMULTI; | ||
1875 | if (*total_flags & FIF_OTHER_BSS || | ||
1876 | *total_flags & FIF_PROMISC_IN_BSS) | ||
1877 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
1878 | |||
1879 | /* | ||
1880 | * Check if there is any work left for us. | ||
1881 | */ | ||
1882 | if (rt2x00dev->packet_filter == *total_flags) | ||
1883 | return; | ||
1884 | rt2x00dev->packet_filter = *total_flags; | ||
1885 | |||
1886 | /* | ||
1887 | * When in atomic context, reschedule and let rt2x00lib | ||
1888 | * call this function again. | ||
1889 | */ | ||
1890 | if (in_atomic()) { | ||
1891 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); | ||
1892 | return; | ||
1893 | } | ||
1894 | |||
1895 | /* | ||
1896 | * Start configuration steps. | ||
1897 | * Note that the version error will always be dropped | ||
1898 | * and broadcast frames will always be accepted since | ||
1899 | * there is no filter for it at this time. | ||
1900 | */ | ||
1901 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
1902 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, | ||
1903 | !(*total_flags & FIF_FCSFAIL)); | ||
1904 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, | ||
1905 | !(*total_flags & FIF_PLCPFAIL)); | ||
1906 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, | ||
1907 | !(*total_flags & FIF_CONTROL)); | ||
1908 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, | ||
1909 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1910 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, | ||
1911 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1912 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
1913 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | ||
1914 | !(*total_flags & FIF_ALLMULTI)); | ||
1915 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | ||
1916 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | ||
1917 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
1918 | } | ||
1919 | |||
1920 | static int rt73usb_set_retry_limit(struct ieee80211_hw *hw, | 1924 | static int rt73usb_set_retry_limit(struct ieee80211_hw *hw, |
1921 | u32 short_retry, u32 long_retry) | 1925 | u32 short_retry, u32 long_retry) |
1922 | { | 1926 | { |
@@ -1955,61 +1959,65 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) | |||
1955 | #define rt73usb_get_tsf NULL | 1959 | #define rt73usb_get_tsf NULL |
1956 | #endif | 1960 | #endif |
1957 | 1961 | ||
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, | 1962 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1967 | struct ieee80211_tx_control *control) | 1963 | struct ieee80211_tx_control *control) |
1968 | { | 1964 | { |
1969 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1965 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1970 | struct skb_desc *desc; | 1966 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1971 | struct data_ring *ring; | 1967 | struct skb_frame_desc *skbdesc; |
1972 | struct data_entry *entry; | 1968 | unsigned int beacon_base; |
1973 | int timeout; | 1969 | unsigned int timeout; |
1970 | u32 reg; | ||
1974 | 1971 | ||
1975 | /* | 1972 | if (unlikely(!intf->beacon)) |
1976 | * Just in case the ieee80211 doesn't set this, | 1973 | 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 | 1974 | ||
1984 | /* | 1975 | /* |
1985 | * Add the descriptor in front of the skb. | 1976 | * Add the descriptor in front of the skb. |
1986 | */ | 1977 | */ |
1987 | skb_push(skb, ring->desc_size); | 1978 | skb_push(skb, intf->beacon->queue->desc_size); |
1988 | memset(skb->data, 0, ring->desc_size); | 1979 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
1989 | 1980 | ||
1990 | /* | 1981 | /* |
1991 | * Fill in skb descriptor | 1982 | * Fill in skb descriptor |
1992 | */ | 1983 | */ |
1993 | desc = get_skb_desc(skb); | 1984 | skbdesc = get_skb_frame_desc(skb); |
1994 | desc->desc_len = ring->desc_size; | 1985 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1995 | desc->data_len = skb->len - ring->desc_size; | 1986 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
1996 | desc->desc = skb->data; | 1987 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
1997 | desc->data = skb->data + ring->desc_size; | 1988 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
1998 | desc->ring = ring; | 1989 | skbdesc->desc = skb->data; |
1999 | desc->entry = entry; | 1990 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
1991 | skbdesc->entry = intf->beacon; | ||
2000 | 1992 | ||
1993 | /* | ||
1994 | * Disable beaconing while we are reloading the beacon data, | ||
1995 | * otherwise we might be sending out invalid data. | ||
1996 | */ | ||
1997 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1998 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1999 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2000 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2001 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2002 | |||
2003 | /* | ||
2004 | * mac80211 doesn't provide the control->queue variable | ||
2005 | * for beacons. Set our own queue identification so | ||
2006 | * it can be used during descriptor initialization. | ||
2007 | */ | ||
2008 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2001 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2009 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2002 | 2010 | ||
2003 | /* | 2011 | /* |
2004 | * Write entire beacon with descriptor to register, | 2012 | * Write entire beacon with descriptor to register, |
2005 | * and kick the beacon generator. | 2013 | * and kick the beacon generator. |
2006 | */ | 2014 | */ |
2015 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2007 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); | 2016 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); |
2008 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 2017 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
2009 | USB_VENDOR_REQUEST_OUT, | 2018 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, |
2010 | HW_BEACON_BASE0, 0x0000, | ||
2011 | skb->data, skb->len, timeout); | 2019 | skb->data, skb->len, timeout); |
2012 | rt73usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2020 | rt73usb_kick_tx_queue(rt2x00dev, control->queue); |
2013 | 2021 | ||
2014 | return 0; | 2022 | return 0; |
2015 | } | 2023 | } |
@@ -2022,20 +2030,20 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2022 | .remove_interface = rt2x00mac_remove_interface, | 2030 | .remove_interface = rt2x00mac_remove_interface, |
2023 | .config = rt2x00mac_config, | 2031 | .config = rt2x00mac_config, |
2024 | .config_interface = rt2x00mac_config_interface, | 2032 | .config_interface = rt2x00mac_config_interface, |
2025 | .configure_filter = rt73usb_configure_filter, | 2033 | .configure_filter = rt2x00mac_configure_filter, |
2026 | .get_stats = rt2x00mac_get_stats, | 2034 | .get_stats = rt2x00mac_get_stats, |
2027 | .set_retry_limit = rt73usb_set_retry_limit, | 2035 | .set_retry_limit = rt73usb_set_retry_limit, |
2028 | .bss_info_changed = rt2x00mac_bss_info_changed, | 2036 | .bss_info_changed = rt2x00mac_bss_info_changed, |
2029 | .conf_tx = rt2x00mac_conf_tx, | 2037 | .conf_tx = rt2x00mac_conf_tx, |
2030 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2038 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2031 | .get_tsf = rt73usb_get_tsf, | 2039 | .get_tsf = rt73usb_get_tsf, |
2032 | .reset_tsf = rt73usb_reset_tsf, | ||
2033 | .beacon_update = rt73usb_beacon_update, | 2040 | .beacon_update = rt73usb_beacon_update, |
2034 | }; | 2041 | }; |
2035 | 2042 | ||
2036 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | 2043 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { |
2037 | .probe_hw = rt73usb_probe_hw, | 2044 | .probe_hw = rt73usb_probe_hw, |
2038 | .get_firmware_name = rt73usb_get_firmware_name, | 2045 | .get_firmware_name = rt73usb_get_firmware_name, |
2046 | .get_firmware_crc = rt73usb_get_firmware_crc, | ||
2039 | .load_firmware = rt73usb_load_firmware, | 2047 | .load_firmware = rt73usb_load_firmware, |
2040 | .initialize = rt2x00usb_initialize, | 2048 | .initialize = rt2x00usb_initialize, |
2041 | .uninitialize = rt2x00usb_uninitialize, | 2049 | .uninitialize = rt2x00usb_uninitialize, |
@@ -2050,19 +2058,42 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2050 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2058 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2051 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2059 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2052 | .fill_rxdone = rt73usb_fill_rxdone, | 2060 | .fill_rxdone = rt73usb_fill_rxdone, |
2053 | .config_mac_addr = rt73usb_config_mac_addr, | 2061 | .config_filter = rt73usb_config_filter, |
2054 | .config_bssid = rt73usb_config_bssid, | 2062 | .config_intf = rt73usb_config_intf, |
2055 | .config_type = rt73usb_config_type, | 2063 | .config_erp = rt73usb_config_erp, |
2056 | .config_preamble = rt73usb_config_preamble, | ||
2057 | .config = rt73usb_config, | 2064 | .config = rt73usb_config, |
2058 | }; | 2065 | }; |
2059 | 2066 | ||
2067 | static const struct data_queue_desc rt73usb_queue_rx = { | ||
2068 | .entry_num = RX_ENTRIES, | ||
2069 | .data_size = DATA_FRAME_SIZE, | ||
2070 | .desc_size = RXD_DESC_SIZE, | ||
2071 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | ||
2072 | }; | ||
2073 | |||
2074 | static const struct data_queue_desc rt73usb_queue_tx = { | ||
2075 | .entry_num = TX_ENTRIES, | ||
2076 | .data_size = DATA_FRAME_SIZE, | ||
2077 | .desc_size = TXD_DESC_SIZE, | ||
2078 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
2079 | }; | ||
2080 | |||
2081 | static const struct data_queue_desc rt73usb_queue_bcn = { | ||
2082 | .entry_num = 4 * BEACON_ENTRIES, | ||
2083 | .data_size = MGMT_FRAME_SIZE, | ||
2084 | .desc_size = TXINFO_SIZE, | ||
2085 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
2086 | }; | ||
2087 | |||
2060 | static const struct rt2x00_ops rt73usb_ops = { | 2088 | static const struct rt2x00_ops rt73usb_ops = { |
2061 | .name = KBUILD_MODNAME, | 2089 | .name = KBUILD_MODNAME, |
2062 | .rxd_size = RXD_DESC_SIZE, | 2090 | .max_sta_intf = 1, |
2063 | .txd_size = TXD_DESC_SIZE, | 2091 | .max_ap_intf = 4, |
2064 | .eeprom_size = EEPROM_SIZE, | 2092 | .eeprom_size = EEPROM_SIZE, |
2065 | .rf_size = RF_SIZE, | 2093 | .rf_size = RF_SIZE, |
2094 | .rx = &rt73usb_queue_rx, | ||
2095 | .tx = &rt73usb_queue_tx, | ||
2096 | .bcn = &rt73usb_queue_bcn, | ||
2066 | .lib = &rt73usb_rt2x00_ops, | 2097 | .lib = &rt73usb_rt2x00_ops, |
2067 | .hw = &rt73usb_mac80211_ops, | 2098 | .hw = &rt73usb_mac80211_ops, |
2068 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 2099 | #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 |