aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,