aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-03-31 09:53:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-01 17:14:09 -0400
commita2e1d52a32eab53f8ab03c4023310f65aaa054a7 (patch)
tree93f5f5692f220afbedc4512bdd372084097e5e54 /drivers/net/wireless/rt2x00
parente0b005fa1479045fe879944036268af3ebcd1835 (diff)
rt2x00: Remove MAC80211_LEDS dependency
Implement triggers inside rt2x00 itself based on input from mac80211. This replaces the method of using the mac80211 trigger events which do not work for USB drivers due to the scheduling requirement. After this patch RT2500USB_LEDS and RT73USB_LEDS no longer need to be tagged as broken since they now support LED handling again without having to check for in_atomic(). Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig14
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c63
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c63
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c85
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.c131
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.h21
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c64
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c70
12 files changed, 297 insertions, 247 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index ad1549592c00..a1e3938cba9b 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -38,10 +38,6 @@ config RT2X00_LIB_RFKILL
38config RT2X00_LIB_LEDS 38config RT2X00_LIB_LEDS
39 boolean 39 boolean
40 depends on RT2X00_LIB 40 depends on RT2X00_LIB
41 select NEW_LEDS
42 select LEDS_CLASS
43 select LEDS_TRIGGERS
44 select MAC80211_LEDS
45 41
46config RT2400PCI 42config RT2400PCI
47 tristate "Ralink rt2400 pci/pcmcia support" 43 tristate "Ralink rt2400 pci/pcmcia support"
@@ -64,7 +60,7 @@ config RT2400PCI_RFKILL
64 60
65config RT2400PCI_LEDS 61config RT2400PCI_LEDS
66 bool "RT2400 leds support" 62 bool "RT2400 leds support"
67 depends on RT2400PCI 63 depends on RT2400PCI && LEDS_CLASS
68 select RT2X00_LIB_LEDS 64 select RT2X00_LIB_LEDS
69 ---help--- 65 ---help---
70 This adds support for led triggers provided my mac80211. 66 This adds support for led triggers provided my mac80211.
@@ -90,7 +86,7 @@ config RT2500PCI_RFKILL
90 86
91config RT2500PCI_LEDS 87config RT2500PCI_LEDS
92 bool "RT2500 leds support" 88 bool "RT2500 leds support"
93 depends on RT2500PCI 89 depends on RT2500PCI && LEDS_CLASS
94 select RT2X00_LIB_LEDS 90 select RT2X00_LIB_LEDS
95 ---help--- 91 ---help---
96 This adds support for led triggers provided my mac80211. 92 This adds support for led triggers provided my mac80211.
@@ -118,7 +114,7 @@ config RT61PCI_RFKILL
118 114
119config RT61PCI_LEDS 115config RT61PCI_LEDS
120 bool "RT61 leds support" 116 bool "RT61 leds support"
121 depends on RT61PCI 117 depends on RT61PCI && LEDS_CLASS
122 select RT2X00_LIB_LEDS 118 select RT2X00_LIB_LEDS
123 ---help--- 119 ---help---
124 This adds support for led triggers provided my mac80211. 120 This adds support for led triggers provided my mac80211.
@@ -134,7 +130,7 @@ config RT2500USB
134 130
135config RT2500USB_LEDS 131config RT2500USB_LEDS
136 bool "RT2500 leds support" 132 bool "RT2500 leds support"
137 depends on RT2500USB && BROKEN 133 depends on RT2500USB && LEDS_CLASS
138 select RT2X00_LIB_LEDS 134 select RT2X00_LIB_LEDS
139 ---help--- 135 ---help---
140 This adds support for led triggers provided my mac80211. 136 This adds support for led triggers provided my mac80211.
@@ -152,7 +148,7 @@ config RT73USB
152 148
153config RT73USB_LEDS 149config RT73USB_LEDS
154 bool "RT73 leds support" 150 bool "RT73 leds support"
155 depends on RT73USB && BROKEN 151 depends on RT73USB && LEDS_CLASS
156 select RT2X00_LIB_LEDS 152 select RT2X00_LIB_LEDS
157 ---help--- 153 ---help---
158 This adds support for led triggers provided my mac80211. 154 This adds support for led triggers provided my mac80211.
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 9abdfb84697c..b41187af1306 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -244,27 +244,39 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
244#endif /* CONFIG_RT2400PCI_RFKILL */ 244#endif /* CONFIG_RT2400PCI_RFKILL */
245 245
246#ifdef CONFIG_RT2400PCI_LEDS 246#ifdef CONFIG_RT2400PCI_LEDS
247static void rt2400pci_led_brightness(struct led_classdev *led_cdev, 247static void rt2400pci_brightness_set(struct led_classdev *led_cdev,
248 enum led_brightness brightness) 248 enum led_brightness brightness)
249{ 249{
250 struct rt2x00_led *led = 250 struct rt2x00_led *led =
251 container_of(led_cdev, struct rt2x00_led, led_dev); 251 container_of(led_cdev, struct rt2x00_led, led_dev);
252 unsigned int enabled = brightness != LED_OFF; 252 unsigned int enabled = brightness != LED_OFF;
253 unsigned int activity =
254 led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY;
255 u32 reg; 253 u32 reg;
256 254
257 rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg); 255 rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg);
258 256
259 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { 257 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC)
260 rt2x00_set_field32(&reg, LEDCSR_LINK, enabled); 258 rt2x00_set_field32(&reg, LEDCSR_LINK, enabled);
261 rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled && activity); 259 else if (led->type == LED_TYPE_ACTIVITY)
262 } 260 rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled);
263 261
264 rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); 262 rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg);
265} 263}
266#else 264
267#define rt2400pci_led_brightness NULL 265static int rt2400pci_blink_set(struct led_classdev *led_cdev,
266 unsigned long *delay_on,
267 unsigned long *delay_off)
268{
269 struct rt2x00_led *led =
270 container_of(led_cdev, struct rt2x00_led, led_dev);
271 u32 reg;
272
273 rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg);
274 rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, *delay_on);
275 rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, *delay_off);
276 rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg);
277
278 return 0;
279}
268#endif /* CONFIG_RT2400PCI_LEDS */ 280#endif /* CONFIG_RT2400PCI_LEDS */
269 281
270/* 282/*
@@ -719,11 +731,6 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev)
719 (rt2x00dev->rx->data_size / 128)); 731 (rt2x00dev->rx->data_size / 128));
720 rt2x00pci_register_write(rt2x00dev, CSR9, reg); 732 rt2x00pci_register_write(rt2x00dev, CSR9, reg);
721 733
722 rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
723 rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
724 rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
725 rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
726
727 rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); 734 rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000);
728 735
729 rt2x00pci_register_read(rt2x00dev, ARCSR0, &reg); 736 rt2x00pci_register_read(rt2x00dev, ARCSR0, &reg);
@@ -1291,19 +1298,22 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
1291#ifdef CONFIG_RT2400PCI_LEDS 1298#ifdef CONFIG_RT2400PCI_LEDS
1292 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); 1299 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
1293 1300
1294 switch (value) { 1301 rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
1295 case LED_MODE_ASUS: 1302 rt2x00dev->led_radio.type = LED_TYPE_RADIO;
1296 case LED_MODE_ALPHA: 1303 rt2x00dev->led_radio.led_dev.brightness_set =
1297 case LED_MODE_DEFAULT: 1304 rt2400pci_brightness_set;
1298 rt2x00dev->led_flags = LED_SUPPORT_RADIO; 1305 rt2x00dev->led_radio.led_dev.blink_set =
1299 break; 1306 rt2400pci_blink_set;
1300 case LED_MODE_TXRX_ACTIVITY: 1307 rt2x00dev->led_radio.flags = LED_INITIALIZED;
1301 rt2x00dev->led_flags = 1308
1302 LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; 1309 if (value == LED_MODE_TXRX_ACTIVITY) {
1303 break; 1310 rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
1304 case LED_MODE_SIGNAL_STRENGTH: 1311 rt2x00dev->led_radio.type = LED_TYPE_ACTIVITY;
1305 rt2x00dev->led_flags = LED_SUPPORT_RADIO; 1312 rt2x00dev->led_qual.led_dev.brightness_set =
1306 break; 1313 rt2400pci_brightness_set;
1314 rt2x00dev->led_qual.led_dev.blink_set =
1315 rt2400pci_blink_set;
1316 rt2x00dev->led_qual.flags = LED_INITIALIZED;
1307 } 1317 }
1308#endif /* CONFIG_RT2400PCI_LEDS */ 1318#endif /* CONFIG_RT2400PCI_LEDS */
1309 1319
@@ -1569,7 +1579,6 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
1569 .link_stats = rt2400pci_link_stats, 1579 .link_stats = rt2400pci_link_stats,
1570 .reset_tuner = rt2400pci_reset_tuner, 1580 .reset_tuner = rt2400pci_reset_tuner,
1571 .link_tuner = rt2400pci_link_tuner, 1581 .link_tuner = rt2400pci_link_tuner,
1572 .led_brightness = rt2400pci_led_brightness,
1573 .write_tx_desc = rt2400pci_write_tx_desc, 1582 .write_tx_desc = rt2400pci_write_tx_desc,
1574 .write_tx_data = rt2x00pci_write_tx_data, 1583 .write_tx_data = rt2x00pci_write_tx_data,
1575 .kick_tx_queue = rt2400pci_kick_tx_queue, 1584 .kick_tx_queue = rt2400pci_kick_tx_queue,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 54c9a75b549b..5ade097ed45e 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -244,27 +244,39 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
244#endif /* CONFIG_RT2500PCI_RFKILL */ 244#endif /* CONFIG_RT2500PCI_RFKILL */
245 245
246#ifdef CONFIG_RT2500PCI_LEDS 246#ifdef CONFIG_RT2500PCI_LEDS
247static void rt2500pci_led_brightness(struct led_classdev *led_cdev, 247static void rt2500pci_brightness_set(struct led_classdev *led_cdev,
248 enum led_brightness brightness) 248 enum led_brightness brightness)
249{ 249{
250 struct rt2x00_led *led = 250 struct rt2x00_led *led =
251 container_of(led_cdev, struct rt2x00_led, led_dev); 251 container_of(led_cdev, struct rt2x00_led, led_dev);
252 unsigned int enabled = brightness != LED_OFF; 252 unsigned int enabled = brightness != LED_OFF;
253 unsigned int activity =
254 led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY;
255 u32 reg; 253 u32 reg;
256 254
257 rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg); 255 rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg);
258 256
259 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { 257 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC)
260 rt2x00_set_field32(&reg, LEDCSR_LINK, enabled); 258 rt2x00_set_field32(&reg, LEDCSR_LINK, enabled);
261 rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled && activity); 259 else if (led->type == LED_TYPE_ACTIVITY)
262 } 260 rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled);
263 261
264 rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); 262 rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg);
265} 263}
266#else 264
267#define rt2500pci_led_brightness NULL 265static int rt2500pci_blink_set(struct led_classdev *led_cdev,
266 unsigned long *delay_on,
267 unsigned long *delay_off)
268{
269 struct rt2x00_led *led =
270 container_of(led_cdev, struct rt2x00_led, led_dev);
271 u32 reg;
272
273 rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg);
274 rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, *delay_on);
275 rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, *delay_off);
276 rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg);
277
278 return 0;
279}
268#endif /* CONFIG_RT2500PCI_LEDS */ 280#endif /* CONFIG_RT2500PCI_LEDS */
269 281
270/* 282/*
@@ -812,11 +824,6 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev)
812 rt2x00_set_field32(&reg, CSR11_CW_SELECT, 0); 824 rt2x00_set_field32(&reg, CSR11_CW_SELECT, 0);
813 rt2x00pci_register_write(rt2x00dev, CSR11, reg); 825 rt2x00pci_register_write(rt2x00dev, CSR11, reg);
814 826
815 rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
816 rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
817 rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
818 rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
819
820 rt2x00pci_register_write(rt2x00dev, CNT3, 0); 827 rt2x00pci_register_write(rt2x00dev, CNT3, 0);
821 828
822 rt2x00pci_register_read(rt2x00dev, TXCSR8, &reg); 829 rt2x00pci_register_read(rt2x00dev, TXCSR8, &reg);
@@ -1468,19 +1475,22 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
1468#ifdef CONFIG_RT2500PCI_LEDS 1475#ifdef CONFIG_RT2500PCI_LEDS
1469 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); 1476 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
1470 1477
1471 switch (value) { 1478 rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
1472 case LED_MODE_ASUS: 1479 rt2x00dev->led_radio.type = LED_TYPE_RADIO;
1473 case LED_MODE_ALPHA: 1480 rt2x00dev->led_radio.led_dev.brightness_set =
1474 case LED_MODE_DEFAULT: 1481 rt2500pci_brightness_set;
1475 rt2x00dev->led_flags = LED_SUPPORT_RADIO; 1482 rt2x00dev->led_radio.led_dev.blink_set =
1476 break; 1483 rt2500pci_blink_set;
1477 case LED_MODE_TXRX_ACTIVITY: 1484 rt2x00dev->led_radio.flags = LED_INITIALIZED;
1478 rt2x00dev->led_flags = 1485
1479 LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; 1486 if (value == LED_MODE_TXRX_ACTIVITY) {
1480 break; 1487 rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
1481 case LED_MODE_SIGNAL_STRENGTH: 1488 rt2x00dev->led_radio.type = LED_TYPE_ACTIVITY;
1482 rt2x00dev->led_flags = LED_SUPPORT_RADIO; 1489 rt2x00dev->led_qual.led_dev.brightness_set =
1483 break; 1490 rt2500pci_brightness_set;
1491 rt2x00dev->led_qual.led_dev.blink_set =
1492 rt2500pci_blink_set;
1493 rt2x00dev->led_qual.flags = LED_INITIALIZED;
1484 } 1494 }
1485#endif /* CONFIG_RT2500PCI_LEDS */ 1495#endif /* CONFIG_RT2500PCI_LEDS */
1486 1496
@@ -1882,7 +1892,6 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
1882 .link_stats = rt2500pci_link_stats, 1892 .link_stats = rt2500pci_link_stats,
1883 .reset_tuner = rt2500pci_reset_tuner, 1893 .reset_tuner = rt2500pci_reset_tuner,
1884 .link_tuner = rt2500pci_link_tuner, 1894 .link_tuner = rt2500pci_link_tuner,
1885 .led_brightness = rt2500pci_led_brightness,
1886 .write_tx_desc = rt2500pci_write_tx_desc, 1895 .write_tx_desc = rt2500pci_write_tx_desc,
1887 .write_tx_data = rt2x00pci_write_tx_data, 1896 .write_tx_data = rt2x00pci_write_tx_data,
1888 .kick_tx_queue = rt2500pci_kick_tx_queue, 1897 .kick_tx_queue = rt2500pci_kick_tx_queue,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 28fdf191e956..6bb07b339325 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -283,34 +283,39 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = {
283#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 283#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
284 284
285#ifdef CONFIG_RT2500USB_LEDS 285#ifdef CONFIG_RT2500USB_LEDS
286static void rt2500usb_led_brightness(struct led_classdev *led_cdev, 286static void rt2500usb_brightness_set(struct led_classdev *led_cdev,
287 enum led_brightness brightness) 287 enum led_brightness brightness)
288{ 288{
289 struct rt2x00_led *led = 289 struct rt2x00_led *led =
290 container_of(led_cdev, struct rt2x00_led, led_dev); 290 container_of(led_cdev, struct rt2x00_led, led_dev);
291 unsigned int enabled = brightness != LED_OFF; 291 unsigned int enabled = brightness != LED_OFF;
292 unsigned int activity = 292 u16 reg;
293 led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY;
294 293
295 if (in_atomic()) { 294 rt2500usb_register_read(led->rt2x00dev, MAC_CSR20, &reg);
296 NOTICE(led->rt2x00dev,
297 "Ignoring LED brightness command for led %d\n",
298 led->type);
299 return;
300 }
301 295
302 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { 296 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC)
303 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, 297 rt2x00_set_field16(&reg, MAC_CSR20_LINK, enabled);
304 MAC_CSR20_LINK, enabled); 298 else if (led->type == LED_TYPE_ACTIVITY)
305 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, 299 rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY, enabled);
306 MAC_CSR20_ACTIVITY, enabled && activity); 300
307 } 301 rt2500usb_register_write(led->rt2x00dev, MAC_CSR20, reg);
302}
303
304static int rt2500usb_blink_set(struct led_classdev *led_cdev,
305 unsigned long *delay_on,
306 unsigned long *delay_off)
307{
308 struct rt2x00_led *led =
309 container_of(led_cdev, struct rt2x00_led, led_dev);
310 u16 reg;
311
312 rt2500usb_register_read(led->rt2x00dev, MAC_CSR21, &reg);
313 rt2x00_set_field16(&reg, MAC_CSR21_ON_PERIOD, *delay_on);
314 rt2x00_set_field16(&reg, MAC_CSR21_OFF_PERIOD, *delay_off);
315 rt2500usb_register_write(led->rt2x00dev, MAC_CSR21, reg);
308 316
309 rt2500usb_register_write(led->rt2x00dev, MAC_CSR20, 317 return 0;
310 led->rt2x00dev->led_mcu_reg);
311} 318}
312#else
313#define rt2500usb_led_brightness NULL
314#endif /* CONFIG_RT2500USB_LEDS */ 319#endif /* CONFIG_RT2500USB_LEDS */
315 320
316/* 321/*
@@ -762,11 +767,6 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
762 rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 0); 767 rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 0);
763 rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); 768 rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);
764 769
765 rt2500usb_register_read(rt2x00dev, MAC_CSR21, &reg);
766 rt2x00_set_field16(&reg, MAC_CSR21_ON_PERIOD, 70);
767 rt2x00_set_field16(&reg, MAC_CSR21_OFF_PERIOD, 30);
768 rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg);
769
770 rt2500usb_register_read(rt2x00dev, TXRX_CSR5, &reg); 770 rt2500usb_register_read(rt2x00dev, TXRX_CSR5, &reg);
771 rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0, 13); 771 rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0, 13);
772 rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0_VALID, 1); 772 rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0_VALID, 1);
@@ -1384,27 +1384,23 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1384#ifdef CONFIG_RT2500USB_LEDS 1384#ifdef CONFIG_RT2500USB_LEDS
1385 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); 1385 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
1386 1386
1387 switch (value) { 1387 rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
1388 case LED_MODE_ASUS: 1388 rt2x00dev->led_radio.type = LED_TYPE_RADIO;
1389 case LED_MODE_ALPHA: 1389 rt2x00dev->led_radio.led_dev.brightness_set =
1390 case LED_MODE_DEFAULT: 1390 rt2500usb_brightness_set;
1391 rt2x00dev->led_flags = LED_SUPPORT_RADIO; 1391 rt2x00dev->led_radio.led_dev.blink_set =
1392 break; 1392 rt2500usb_blink_set;
1393 case LED_MODE_TXRX_ACTIVITY: 1393 rt2x00dev->led_radio.flags = LED_INITIALIZED;
1394 rt2x00dev->led_flags = 1394
1395 LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; 1395 if (value == LED_MODE_TXRX_ACTIVITY) {
1396 break; 1396 rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
1397 case LED_MODE_SIGNAL_STRENGTH: 1397 rt2x00dev->led_radio.type = LED_TYPE_ACTIVITY;
1398 rt2x00dev->led_flags = LED_SUPPORT_RADIO; 1398 rt2x00dev->led_qual.led_dev.brightness_set =
1399 break; 1399 rt2500usb_brightness_set;
1400 rt2x00dev->led_qual.led_dev.blink_set =
1401 rt2500usb_blink_set;
1402 rt2x00dev->led_qual.flags = LED_INITIALIZED;
1400 } 1403 }
1401
1402 /*
1403 * Store the current led register value, we need it later
1404 * in set_brightness but that is called in irq context which
1405 * means we can't use rt2500usb_register_read() at that time.
1406 */
1407 rt2500usb_register_read(rt2x00dev, MAC_CSR20, &rt2x00dev->led_mcu_reg);
1408#endif /* CONFIG_RT2500USB_LEDS */ 1404#endif /* CONFIG_RT2500USB_LEDS */
1409 1405
1410 /* 1406 /*
@@ -1792,7 +1788,6 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
1792 .link_stats = rt2500usb_link_stats, 1788 .link_stats = rt2500usb_link_stats,
1793 .reset_tuner = rt2500usb_reset_tuner, 1789 .reset_tuner = rt2500usb_reset_tuner,
1794 .link_tuner = rt2500usb_link_tuner, 1790 .link_tuner = rt2500usb_link_tuner,
1795 .led_brightness = rt2500usb_led_brightness,
1796 .write_tx_desc = rt2500usb_write_tx_desc, 1791 .write_tx_desc = rt2500usb_write_tx_desc,
1797 .write_tx_data = rt2x00usb_write_tx_data, 1792 .write_tx_data = rt2x00usb_write_tx_data,
1798 .get_tx_data_len = rt2500usb_get_tx_data_len, 1793 .get_tx_data_len = rt2500usb_get_tx_data_len,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 30f9f3afdaef..57bdc153952f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -385,6 +385,7 @@ struct rt2x00_intf {
385 unsigned int delayed_flags; 385 unsigned int delayed_flags;
386#define DELAYED_UPDATE_BEACON 0x00000001 386#define DELAYED_UPDATE_BEACON 0x00000001
387#define DELAYED_CONFIG_ERP 0x00000002 387#define DELAYED_CONFIG_ERP 0x00000002
388#define DELAYED_LED_ASSOC 0x00000004
388}; 389};
389 390
390static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) 391static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
@@ -533,8 +534,6 @@ struct rt2x00lib_ops {
533 struct link_qual *qual); 534 struct link_qual *qual);
534 void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); 535 void (*reset_tuner) (struct rt2x00_dev *rt2x00dev);
535 void (*link_tuner) (struct rt2x00_dev *rt2x00dev); 536 void (*link_tuner) (struct rt2x00_dev *rt2x00dev);
536 void (*led_brightness) (struct led_classdev *led_cdev,
537 enum led_brightness brightness);
538 537
539 /* 538 /*
540 * TX control handlers 539 * TX control handlers
@@ -694,8 +693,6 @@ struct rt2x00_dev {
694 * by mac8011 or the kernel. 693 * by mac8011 or the kernel.
695 */ 694 */
696#ifdef CONFIG_RT2X00_LIB_LEDS 695#ifdef CONFIG_RT2X00_LIB_LEDS
697 unsigned int led_flags;
698 struct rt2x00_trigger trigger_qual;
699 struct rt2x00_led led_radio; 696 struct rt2x00_led led_radio;
700 struct rt2x00_led led_assoc; 697 struct rt2x00_led led_assoc;
701 struct rt2x00_led led_qual; 698 struct rt2x00_led led_qual;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index d2c096708e8c..62b58a6261fe 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -108,11 +108,13 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
108 /* 108 /*
109 * Enable radio. 109 * Enable radio.
110 */ 110 */
111 status = rt2x00dev->ops->lib->set_device_state(rt2x00dev, 111 status =
112 STATE_RADIO_ON); 112 rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_ON);
113 if (status) 113 if (status)
114 return status; 114 return status;
115 115
116 rt2x00leds_led_radio(rt2x00dev, true);
117
116 __set_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags); 118 __set_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags);
117 119
118 /* 120 /*
@@ -155,6 +157,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
155 * Disable radio. 157 * Disable radio.
156 */ 158 */
157 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);
158} 161}
159 162
160void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) 163void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
@@ -449,6 +452,9 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
449 452
450 if (delayed_flags & DELAYED_CONFIG_ERP) 453 if (delayed_flags & DELAYED_CONFIG_ERP)
451 rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf); 454 rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf);
455
456 if (delayed_flags & DELAYED_LED_ASSOC)
457 rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
452} 458}
453 459
454static void rt2x00lib_intf_scheduled(struct work_struct *work) 460static void rt2x00lib_intf_scheduled(struct work_struct *work)
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c
index ca2d282a9f75..40c1f5c1b805 100644
--- a/drivers/net/wireless/rt2x00/rt2x00leds.c
+++ b/drivers/net/wireless/rt2x00/rt2x00leds.c
@@ -31,7 +31,10 @@
31 31
32void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi) 32void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi)
33{ 33{
34 if (!rt2x00dev->trigger_qual.registered) 34 struct rt2x00_led *led = &rt2x00dev->led_qual;
35 unsigned int brightness;
36
37 if ((led->type != LED_TYPE_QUALITY) || !(led->flags & LED_REGISTERED))
35 return; 38 return;
36 39
37 /* 40 /*
@@ -62,39 +65,51 @@ void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi)
62 * is going to calculate the value and might use it in a 65 * is going to calculate the value and might use it in a
63 * division. 66 * division.
64 */ 67 */
65 led_trigger_event(&rt2x00dev->trigger_qual.trigger, 68 brightness = ((LED_FULL / 6) * rssi) + 1;
66 ((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 }
67} 73}
68 74
69static int rt2x00leds_register_trigger(struct rt2x00_dev *rt2x00dev, 75void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled)
70 struct rt2x00_trigger *trigger,
71 const char *name)
72{ 76{
73 int retval; 77 struct rt2x00_led *led = &rt2x00dev->led_assoc;
78 unsigned int brightness;
74 79
75 trigger->trigger.name = name; 80 if ((led->type != LED_TYPE_ASSOC) || !(led->flags & LED_REGISTERED))
76 retval = led_trigger_register(&trigger->trigger); 81 return;
77 if (retval) { 82
78 ERROR(rt2x00dev, "Failed to register led trigger.\n"); 83 brightness = enabled ? LED_FULL : LED_OFF;
79 return retval; 84 if (brightness != led->led_dev.brightness) {
85 led->led_dev.brightness_set(&led->led_dev, brightness);
86 led->led_dev.brightness = brightness;
80 } 87 }
88}
81 89
82 trigger->registered = 1; 90void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled)
91{
92 struct rt2x00_led *led = &rt2x00dev->led_radio;
93 unsigned int brightness;
83 94
84 return 0; 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 }
85} 103}
86 104
87static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, 105static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
88 struct rt2x00_led *led, 106 struct rt2x00_led *led,
89 enum led_type type, 107 const char *name)
90 const char *name, char *trigger)
91{ 108{
92 struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); 109 struct device *device = wiphy_dev(rt2x00dev->hw->wiphy);
93 int retval; 110 int retval;
94 111
95 led->led_dev.name = name; 112 led->led_dev.name = name;
96 led->led_dev.brightness_set = rt2x00dev->ops->lib->led_brightness;
97 led->led_dev.default_trigger = trigger;
98 113
99 retval = led_classdev_register(device, &led->led_dev); 114 retval = led_classdev_register(device, &led->led_dev);
100 if (retval) { 115 if (retval) {
@@ -102,115 +117,103 @@ static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
102 return retval; 117 return retval;
103 } 118 }
104 119
105 led->rt2x00dev = rt2x00dev; 120 led->flags |= LED_REGISTERED;
106 led->type = type;
107 led->registered = 1;
108 121
109 return 0; 122 return 0;
110} 123}
111 124
112void rt2x00leds_register(struct rt2x00_dev *rt2x00dev) 125void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
113{ 126{
114 char *trigger;
115 char dev_name[16]; 127 char dev_name[16];
116 char name[32]; 128 char name[32];
117 int retval; 129 int retval;
118 130 unsigned long on_period;
119 if (!rt2x00dev->ops->lib->led_brightness) 131 unsigned long off_period;
120 return;
121 132
122 snprintf(dev_name, sizeof(dev_name), "%s-%s", 133 snprintf(dev_name, sizeof(dev_name), "%s-%s",
123 rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy)); 134 rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy));
124 135
125 if (rt2x00dev->led_flags & LED_SUPPORT_RADIO) { 136 if (rt2x00dev->led_radio.flags & LED_INITIALIZED) {
126 trigger = ieee80211_get_radio_led_name(rt2x00dev->hw);
127 snprintf(name, sizeof(name), "%s:radio", dev_name); 137 snprintf(name, sizeof(name), "%s:radio", dev_name);
128 138
129 retval = rt2x00leds_register_led(rt2x00dev, 139 retval = rt2x00leds_register_led(rt2x00dev,
130 &rt2x00dev->led_radio, 140 &rt2x00dev->led_radio,
131 LED_TYPE_RADIO, 141 name);
132 name, trigger);
133 if (retval) 142 if (retval)
134 goto exit_fail; 143 goto exit_fail;
135 } 144 }
136 145
137 if (rt2x00dev->led_flags & LED_SUPPORT_ASSOC) { 146 if (rt2x00dev->led_assoc.flags & LED_INITIALIZED) {
138 trigger = ieee80211_get_assoc_led_name(rt2x00dev->hw);
139 snprintf(name, sizeof(name), "%s:assoc", dev_name); 147 snprintf(name, sizeof(name), "%s:assoc", dev_name);
140 148
141 retval = rt2x00leds_register_led(rt2x00dev, 149 retval = rt2x00leds_register_led(rt2x00dev,
142 &rt2x00dev->led_assoc, 150 &rt2x00dev->led_assoc,
143 LED_TYPE_ASSOC, 151 name);
144 name, trigger);
145 if (retval) 152 if (retval)
146 goto exit_fail; 153 goto exit_fail;
147 } 154 }
148 155
149 if (rt2x00dev->led_flags & LED_SUPPORT_QUALITY) { 156 if (rt2x00dev->led_qual.flags & LED_INITIALIZED) {
150 snprintf(name, sizeof(name), "%s:quality", dev_name); 157 snprintf(name, sizeof(name), "%s:quality", dev_name);
151 158
152 retval = rt2x00leds_register_trigger(rt2x00dev,
153 &rt2x00dev->trigger_qual,
154 name);
155
156 retval = rt2x00leds_register_led(rt2x00dev, 159 retval = rt2x00leds_register_led(rt2x00dev,
157 &rt2x00dev->led_qual, 160 &rt2x00dev->led_qual,
158 LED_TYPE_QUALITY, 161 name);
159 name, name);
160 if (retval) 162 if (retval)
161 goto exit_fail; 163 goto exit_fail;
162 } 164 }
163 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
164 return; 178 return;
165 179
166exit_fail: 180exit_fail:
167 rt2x00leds_unregister(rt2x00dev); 181 rt2x00leds_unregister(rt2x00dev);
168} 182}
169 183
170static void rt2x00leds_unregister_trigger(struct rt2x00_trigger *trigger)
171{
172 if (!trigger->registered)
173 return;
174
175 led_trigger_unregister(&trigger->trigger);
176 trigger->registered = 0;
177}
178
179static void rt2x00leds_unregister_led(struct rt2x00_led *led) 184static void rt2x00leds_unregister_led(struct rt2x00_led *led)
180{ 185{
181 if (!led->registered)
182 return;
183
184 led_classdev_unregister(&led->led_dev); 186 led_classdev_unregister(&led->led_dev);
185
186 led->led_dev.brightness_set(&led->led_dev, LED_OFF); 187 led->led_dev.brightness_set(&led->led_dev, LED_OFF);
187 led->registered = 0; 188 led->flags &= ~LED_REGISTERED;
188} 189}
189 190
190void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) 191void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev)
191{ 192{
192 rt2x00leds_unregister_trigger(&rt2x00dev->trigger_qual); 193 if (rt2x00dev->led_qual.flags & LED_REGISTERED)
193 rt2x00leds_unregister_led(&rt2x00dev->led_qual); 194 rt2x00leds_unregister_led(&rt2x00dev->led_qual);
194 rt2x00leds_unregister_led(&rt2x00dev->led_assoc); 195 if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
195 rt2x00leds_unregister_led(&rt2x00dev->led_radio); 196 rt2x00leds_unregister_led(&rt2x00dev->led_assoc);
197 if (rt2x00dev->led_radio.flags & LED_REGISTERED)
198 rt2x00leds_unregister_led(&rt2x00dev->led_radio);
196} 199}
197 200
198void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) 201void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev)
199{ 202{
200 if (rt2x00dev->led_qual.registered) 203 if (rt2x00dev->led_qual.flags & LED_REGISTERED)
201 led_classdev_suspend(&rt2x00dev->led_qual.led_dev); 204 led_classdev_suspend(&rt2x00dev->led_qual.led_dev);
202 if (rt2x00dev->led_assoc.registered) 205 if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
203 led_classdev_suspend(&rt2x00dev->led_assoc.led_dev); 206 led_classdev_suspend(&rt2x00dev->led_assoc.led_dev);
204 if (rt2x00dev->led_radio.registered) 207 if (rt2x00dev->led_radio.flags & LED_REGISTERED)
205 led_classdev_suspend(&rt2x00dev->led_radio.led_dev); 208 led_classdev_suspend(&rt2x00dev->led_radio.led_dev);
206} 209}
207 210
208void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) 211void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev)
209{ 212{
210 if (rt2x00dev->led_radio.registered) 213 if (rt2x00dev->led_radio.flags & LED_REGISTERED)
211 led_classdev_resume(&rt2x00dev->led_radio.led_dev); 214 led_classdev_resume(&rt2x00dev->led_radio.led_dev);
212 if (rt2x00dev->led_assoc.registered) 215 if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
213 led_classdev_resume(&rt2x00dev->led_assoc.led_dev); 216 led_classdev_resume(&rt2x00dev->led_assoc.led_dev);
214 if (rt2x00dev->led_qual.registered) 217 if (rt2x00dev->led_qual.flags & LED_REGISTERED)
215 led_classdev_resume(&rt2x00dev->led_qual.led_dev); 218 led_classdev_resume(&rt2x00dev->led_qual.led_dev);
216} 219}
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.h b/drivers/net/wireless/rt2x00/rt2x00leds.h
index 11e71e9ce853..9df4a49bdcad 100644
--- a/drivers/net/wireless/rt2x00/rt2x00leds.h
+++ b/drivers/net/wireless/rt2x00/rt2x00leds.h
@@ -26,18 +26,10 @@
26#ifndef RT2X00LEDS_H 26#ifndef RT2X00LEDS_H
27#define RT2X00LEDS_H 27#define RT2X00LEDS_H
28 28
29/*
30* Flags used by driver to indicate which
31 * which led types are supported.
32 */
33#define LED_SUPPORT_RADIO 0x000001
34#define LED_SUPPORT_ASSOC 0x000002
35#define LED_SUPPORT_ACTIVITY 0x000004
36#define LED_SUPPORT_QUALITY 0x000008
37
38enum led_type { 29enum led_type {
39 LED_TYPE_RADIO, 30 LED_TYPE_RADIO,
40 LED_TYPE_ASSOC, 31 LED_TYPE_ASSOC,
32 LED_TYPE_ACTIVITY,
41 LED_TYPE_QUALITY, 33 LED_TYPE_QUALITY,
42}; 34};
43 35
@@ -48,14 +40,9 @@ struct rt2x00_led {
48 struct led_classdev led_dev; 40 struct led_classdev led_dev;
49 41
50 enum led_type type; 42 enum led_type type;
51 unsigned int registered; 43 unsigned int flags;
52}; 44#define LED_INITIALIZED ( 1 << 0 )
53 45#define LED_REGISTERED ( 1 << 1 )
54struct rt2x00_trigger {
55 struct led_trigger trigger;
56
57 enum led_type type;
58 unsigned int registered;
59}; 46};
60 47
61#endif /* CONFIG_RT2X00_LIB_LEDS */ 48#endif /* CONFIG_RT2X00_LIB_LEDS */
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 64fae7e3f73b..5be32fffc74c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -185,6 +185,8 @@ static inline void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev)
185 */ 185 */
186#ifdef CONFIG_RT2X00_LIB_LEDS 186#ifdef CONFIG_RT2X00_LIB_LEDS
187void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi); 187void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi);
188void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled);
189void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled);
188void rt2x00leds_register(struct rt2x00_dev *rt2x00dev); 190void rt2x00leds_register(struct rt2x00_dev *rt2x00dev);
189void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev); 191void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev);
190void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev); 192void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev);
@@ -195,6 +197,16 @@ static inline void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev,
195{ 197{
196} 198}
197 199
200static inline void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev,
201 bool enabled)
202{
203}
204
205static inline void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev,
206 bool enabled)
207{
208}
209
198static inline void rt2x00leds_register(struct rt2x00_dev *rt2x00dev) 210static inline void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
199{ 211{
200} 212}
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index dc70e7aedfff..c206b5092070 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -485,6 +485,12 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
485 rt2x00dev->intf_associated++; 485 rt2x00dev->intf_associated++;
486 else 486 else
487 rt2x00dev->intf_associated--; 487 rt2x00dev->intf_associated--;
488
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;
488 } 494 }
489 495
490 /* 496 /*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index c5c625143335..1cb056be4489 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -277,7 +277,7 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
277#endif /* CONFIG_RT61PCI_RFKILL */ 277#endif /* CONFIG_RT61PCI_RFKILL */
278 278
279#ifdef CONFIG_RT61PCI_LEDS 279#ifdef CONFIG_RT61PCI_LEDS
280static void rt61pci_led_brightness(struct led_classdev *led_cdev, 280static void rt61pci_brightness_set(struct led_classdev *led_cdev,
281 enum led_brightness brightness) 281 enum led_brightness brightness)
282{ 282{
283 struct rt2x00_led *led = 283 struct rt2x00_led *led =
@@ -314,8 +314,22 @@ static void rt61pci_led_brightness(struct led_classdev *led_cdev,
314 brightness / (LED_FULL / 6), 0); 314 brightness / (LED_FULL / 6), 0);
315 } 315 }
316} 316}
317#else 317
318#define rt61pci_led_brightness NULL 318static int rt61pci_blink_set(struct led_classdev *led_cdev,
319 unsigned long *delay_on,
320 unsigned long *delay_off)
321{
322 struct rt2x00_led *led =
323 container_of(led_cdev, struct rt2x00_led, led_dev);
324 u32 reg;
325
326 rt2x00pci_register_read(led->rt2x00dev, MAC_CSR14, &reg);
327 rt2x00_set_field32(&reg, MAC_CSR14_ON_PERIOD, *delay_on);
328 rt2x00_set_field32(&reg, MAC_CSR14_OFF_PERIOD, *delay_off);
329 rt2x00pci_register_write(led->rt2x00dev, MAC_CSR14, reg);
330
331 return 0;
332}
319#endif /* CONFIG_RT61PCI_LEDS */ 333#endif /* CONFIG_RT61PCI_LEDS */
320 334
321/* 335/*
@@ -1202,11 +1216,6 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev)
1202 1216
1203 rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); 1217 rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000);
1204 1218
1205 rt2x00pci_register_read(rt2x00dev, MAC_CSR14, &reg);
1206 rt2x00_set_field32(&reg, MAC_CSR14_ON_PERIOD, 70);
1207 rt2x00_set_field32(&reg, MAC_CSR14_OFF_PERIOD, 30);
1208 rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg);
1209
1210 /* 1219 /*
1211 * Invalidate all Shared Keys (SEC_CSR0), 1220 * Invalidate all Shared Keys (SEC_CSR0),
1212 * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) 1221 * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5)
@@ -2058,22 +2067,32 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
2058 */ 2067 */
2059#ifdef CONFIG_RT61PCI_LEDS 2068#ifdef CONFIG_RT61PCI_LEDS
2060 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); 2069 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);
2061
2062 value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); 2070 value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE);
2063 2071
2064 switch (value) { 2072 rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
2065 case LED_MODE_TXRX_ACTIVITY: 2073 rt2x00dev->led_radio.type = LED_TYPE_RADIO;
2066 case LED_MODE_ASUS: 2074 rt2x00dev->led_radio.led_dev.brightness_set =
2067 case LED_MODE_ALPHA: 2075 rt61pci_brightness_set;
2068 case LED_MODE_DEFAULT: 2076 rt2x00dev->led_radio.led_dev.blink_set =
2069 rt2x00dev->led_flags = 2077 rt61pci_blink_set;
2070 LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC; 2078 rt2x00dev->led_radio.flags = LED_INITIALIZED;
2071 break; 2079
2072 case LED_MODE_SIGNAL_STRENGTH: 2080 rt2x00dev->led_assoc.rt2x00dev = rt2x00dev;
2073 rt2x00dev->led_flags = 2081 rt2x00dev->led_assoc.type = LED_TYPE_ASSOC;
2074 LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC | 2082 rt2x00dev->led_assoc.led_dev.brightness_set =
2075 LED_SUPPORT_QUALITY; 2083 rt61pci_brightness_set;
2076 break; 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;
2077 } 2096 }
2078 2097
2079 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); 2098 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value);
@@ -2447,7 +2466,6 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2447 .link_stats = rt61pci_link_stats, 2466 .link_stats = rt61pci_link_stats,
2448 .reset_tuner = rt61pci_reset_tuner, 2467 .reset_tuner = rt61pci_reset_tuner,
2449 .link_tuner = rt61pci_link_tuner, 2468 .link_tuner = rt61pci_link_tuner,
2450 .led_brightness = rt61pci_led_brightness,
2451 .write_tx_desc = rt61pci_write_tx_desc, 2469 .write_tx_desc = rt61pci_write_tx_desc,
2452 .write_tx_data = rt2x00pci_write_tx_data, 2470 .write_tx_data = rt2x00pci_write_tx_data,
2453 .kick_tx_queue = rt61pci_kick_tx_queue, 2471 .kick_tx_queue = rt61pci_kick_tx_queue,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 796cf2990b72..a9efe25f1ea7 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -280,7 +280,7 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
280#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 280#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
281 281
282#ifdef CONFIG_RT73USB_LEDS 282#ifdef CONFIG_RT73USB_LEDS
283static void rt73usb_led_brightness(struct led_classdev *led_cdev, 283static void rt73usb_brightness_set(struct led_classdev *led_cdev,
284 enum led_brightness brightness) 284 enum led_brightness brightness)
285{ 285{
286 struct rt2x00_led *led = 286 struct rt2x00_led *led =
@@ -291,13 +291,6 @@ static void rt73usb_led_brightness(struct led_classdev *led_cdev,
291 unsigned int bg_mode = 291 unsigned int bg_mode =
292 (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); 292 (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
293 293
294 if (in_atomic()) {
295 NOTICE(led->rt2x00dev,
296 "Ignoring LED brightness command for led %d\n",
297 led->type);
298 return;
299 }
300
301 if (led->type == LED_TYPE_RADIO) { 294 if (led->type == LED_TYPE_RADIO) {
302 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, 295 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
303 MCU_LEDCS_RADIO_STATUS, enabled); 296 MCU_LEDCS_RADIO_STATUS, enabled);
@@ -326,8 +319,22 @@ static void rt73usb_led_brightness(struct led_classdev *led_cdev,
326 REGISTER_TIMEOUT); 319 REGISTER_TIMEOUT);
327 } 320 }
328} 321}
329#else 322
330#define rt73usb_led_brightness NULL 323static int rt73usb_blink_set(struct led_classdev *led_cdev,
324 unsigned long *delay_on,
325 unsigned long *delay_off)
326{
327 struct rt2x00_led *led =
328 container_of(led_cdev, struct rt2x00_led, led_dev);
329 u32 reg;
330
331 rt73usb_register_read(led->rt2x00dev, MAC_CSR14, &reg);
332 rt2x00_set_field32(&reg, MAC_CSR14_ON_PERIOD, *delay_on);
333 rt2x00_set_field32(&reg, MAC_CSR14_OFF_PERIOD, *delay_off);
334 rt73usb_register_write(led->rt2x00dev, MAC_CSR14, reg);
335
336 return 0;
337}
331#endif /* CONFIG_RT73USB_LEDS */ 338#endif /* CONFIG_RT73USB_LEDS */
332 339
333/* 340/*
@@ -1006,11 +1013,6 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
1006 1013
1007 rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00); 1014 rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00);
1008 1015
1009 rt73usb_register_read(rt2x00dev, MAC_CSR14, &reg);
1010 rt2x00_set_field32(&reg, MAC_CSR14_ON_PERIOD, 70);
1011 rt2x00_set_field32(&reg, MAC_CSR14_OFF_PERIOD, 30);
1012 rt73usb_register_write(rt2x00dev, MAC_CSR14, reg);
1013
1014 /* 1016 /*
1015 * Invalidate all Shared Keys (SEC_CSR0), 1017 * Invalidate all Shared Keys (SEC_CSR0),
1016 * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) 1018 * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5)
@@ -1627,19 +1629,30 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1627#ifdef CONFIG_RT73USB_LEDS 1629#ifdef CONFIG_RT73USB_LEDS
1628 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); 1630 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);
1629 1631
1630 switch (value) { 1632 rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
1631 case LED_MODE_TXRX_ACTIVITY: 1633 rt2x00dev->led_radio.type = LED_TYPE_RADIO;
1632 case LED_MODE_ASUS: 1634 rt2x00dev->led_radio.led_dev.brightness_set =
1633 case LED_MODE_ALPHA: 1635 rt73usb_brightness_set;
1634 case LED_MODE_DEFAULT: 1636 rt2x00dev->led_radio.led_dev.blink_set =
1635 rt2x00dev->led_flags = 1637 rt73usb_blink_set;
1636 LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC; 1638 rt2x00dev->led_radio.flags = LED_INITIALIZED;
1637 break; 1639
1638 case LED_MODE_SIGNAL_STRENGTH: 1640 rt2x00dev->led_assoc.rt2x00dev = rt2x00dev;
1639 rt2x00dev->led_flags = 1641 rt2x00dev->led_assoc.type = LED_TYPE_ASSOC;
1640 LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC | 1642 rt2x00dev->led_assoc.led_dev.brightness_set =
1641 LED_SUPPORT_QUALITY; 1643 rt73usb_brightness_set;
1642 break; 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;
1643 } 1656 }
1644 1657
1645 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); 1658 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value);
@@ -2040,7 +2053,6 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
2040 .link_stats = rt73usb_link_stats, 2053 .link_stats = rt73usb_link_stats,
2041 .reset_tuner = rt73usb_reset_tuner, 2054 .reset_tuner = rt73usb_reset_tuner,
2042 .link_tuner = rt73usb_link_tuner, 2055 .link_tuner = rt73usb_link_tuner,
2043 .led_brightness = rt73usb_led_brightness,
2044 .write_tx_desc = rt73usb_write_tx_desc, 2056 .write_tx_desc = rt73usb_write_tx_desc,
2045 .write_tx_data = rt2x00usb_write_tx_data, 2057 .write_tx_data = rt2x00usb_write_tx_data,
2046 .get_tx_data_len = rt73usb_get_tx_data_len, 2058 .get_tx_data_len = rt73usb_get_tx_data_len,