aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-02-03 09:53:40 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:37:00 -0500
commita9450b70a755abf093600035ef5361c53343fe9a (patch)
tree94b509ea1e73454d327f805273a1fce994d95b1b /drivers/net/wireless
parentf2a3c7f5c8e3c1356dbbce1e9ac2e7f4d5365ba9 (diff)
rt2x00: Make use of MAC80211_LED_TRIGGERS
Make use of the led triggers provided by mac80211 to control the led status. This can be enabled through a per-driver configuration option which will automatically enable the generic handler in rt2x00lib. This has been enabled for rt2500usb and rt73usb for the moment since the led class will call set_brightness in irq context which will not work correctly with the usb drivers who need to sleep. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig28
-rw-r--r--drivers/net/wireless/rt2x00/Makefile4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c88
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c88
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c91
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h27
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c19
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h33
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c180
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c165
10 files changed, 403 insertions, 320 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 28f3e5e94ab6..88a6ef693862 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -38,6 +38,13 @@ config RT2X00_LIB_RFKILL
38 select RFKILL 38 select RFKILL
39 select INPUT_POLLDEV 39 select INPUT_POLLDEV
40 40
41config RT2X00_LIB_LEDS
42 boolean
43 depends on RT2X00_LIB
44 select LEDS_CLASS
45 select LEDS_TRIGGERS
46 select MAC80211_LEDS
47
41config RT2400PCI 48config RT2400PCI
42 tristate "Ralink rt2400 pci/pcmcia support" 49 tristate "Ralink rt2400 pci/pcmcia support"
43 depends on RT2X00 && PCI 50 depends on RT2X00 && PCI
@@ -57,6 +64,13 @@ config RT2400PCI_RFKILL
57 hardware button to control the radio state. 64 hardware button to control the radio state.
58 This feature depends on the RF switch subsystem rfkill. 65 This feature depends on the RF switch subsystem rfkill.
59 66
67config RT2400PCI_LEDS
68 bool "RT2400 leds support"
69 depends on RT2400PCI
70 select RT2X00_LIB_LEDS
71 ---help---
72 This adds support for led triggers provided my mac80211.
73
60config RT2500PCI 74config RT2500PCI
61 tristate "Ralink rt2500 pci/pcmcia support" 75 tristate "Ralink rt2500 pci/pcmcia support"
62 depends on RT2X00 && PCI 76 depends on RT2X00 && PCI
@@ -76,6 +90,13 @@ config RT2500PCI_RFKILL
76 hardware button to control the radio state. 90 hardware button to control the radio state.
77 This feature depends on the RF switch subsystem rfkill. 91 This feature depends on the RF switch subsystem rfkill.
78 92
93config RT2500PCI_LEDS
94 bool "RT2500 leds support"
95 depends on RT2500PCI
96 select RT2X00_LIB_LEDS
97 ---help---
98 This adds support for led triggers provided my mac80211.
99
79config RT61PCI 100config RT61PCI
80 tristate "Ralink rt61 pci/pcmcia support" 101 tristate "Ralink rt61 pci/pcmcia support"
81 depends on RT2X00 && PCI 102 depends on RT2X00 && PCI
@@ -96,6 +117,13 @@ config RT61PCI_RFKILL
96 hardware button to control the radio state. 117 hardware button to control the radio state.
97 This feature depends on the RF switch subsystem rfkill. 118 This feature depends on the RF switch subsystem rfkill.
98 119
120config RT61PCI_LEDS
121 bool "RT61 leds support"
122 depends on RT61PCI
123 select RT2X00_LIB_LEDS
124 ---help---
125 This adds support for led triggers provided my mac80211.
126
99config RT2500USB 127config RT2500USB
100 tristate "Ralink rt2500 usb support" 128 tristate "Ralink rt2500 usb support"
101 depends on RT2X00 && USB 129 depends on RT2X00 && USB
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index ab40e1f6b303..757bbc077d93 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -12,6 +12,10 @@ ifeq ($(CONFIG_RT2X00_LIB_FIRMWARE),y)
12 rt2x00lib-objs += rt2x00firmware.o 12 rt2x00lib-objs += rt2x00firmware.o
13endif 13endif
14 14
15ifeq ($(CONFIG_RT2X00_LIB_LEDS),y)
16 rt2x00lib-objs += rt2x00leds.o
17endif
18
15obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o 19obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o
16obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o 20obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
17obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o 21obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index feb8c09a33ad..69b4852d4c7f 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -243,6 +243,30 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
243#define rt2400pci_rfkill_poll NULL 243#define rt2400pci_rfkill_poll NULL
244#endif /* CONFIG_RT2400PCI_RFKILL */ 244#endif /* CONFIG_RT2400PCI_RFKILL */
245 245
246#ifdef CONFIG_RT2400PCI_LEDS
247static void rt2400pci_led_brightness(struct led_classdev *led_cdev,
248 enum led_brightness brightness)
249{
250 struct rt2x00_led *led =
251 container_of(led_cdev, struct rt2x00_led, led_dev);
252 unsigned int enabled = brightness != LED_OFF;
253 unsigned int activity =
254 led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY;
255 u32 reg;
256
257 rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg);
258
259 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) {
260 rt2x00_set_field32(&reg, LEDCSR_LINK, enabled);
261 rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled && activity);
262 }
263
264 rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg);
265}
266#else
267#define rt2400pci_led_brightness NULL
268#endif /* CONFIG_RT2400PCI_LEDS */
269
246/* 270/*
247 * Configuration handlers. 271 * Configuration handlers.
248 */ 272 */
@@ -511,34 +535,6 @@ static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev,
511} 535}
512 536
513/* 537/*
514 * LED functions.
515 */
516static void rt2400pci_enable_led(struct rt2x00_dev *rt2x00dev)
517{
518 u32 reg;
519
520 rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
521
522 rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
523 rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
524 rt2x00_set_field32(&reg, LEDCSR_LINK,
525 (rt2x00dev->led_mode != LED_MODE_ASUS));
526 rt2x00_set_field32(&reg, LEDCSR_ACTIVITY,
527 (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
528 rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
529}
530
531static void rt2400pci_disable_led(struct rt2x00_dev *rt2x00dev)
532{
533 u32 reg;
534
535 rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
536 rt2x00_set_field32(&reg, LEDCSR_LINK, 0);
537 rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, 0);
538 rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
539}
540
541/*
542 * Link tuning 538 * Link tuning
543 */ 539 */
544static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, 540static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev,
@@ -703,6 +699,11 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev)
703 (rt2x00dev->rx->data_size / 128)); 699 (rt2x00dev->rx->data_size / 128));
704 rt2x00pci_register_write(rt2x00dev, CSR9, reg); 700 rt2x00pci_register_write(rt2x00dev, CSR9, reg);
705 701
702 rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
703 rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
704 rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
705 rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
706
706 rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); 707 rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000);
707 708
708 rt2x00pci_register_read(rt2x00dev, ARCSR0, &reg); 709 rt2x00pci_register_read(rt2x00dev, ARCSR0, &reg);
@@ -872,11 +873,6 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev)
872 */ 873 */
873 rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); 874 rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);
874 875
875 /*
876 * Enable LED
877 */
878 rt2400pci_enable_led(rt2x00dev);
879
880 return 0; 876 return 0;
881} 877}
882 878
@@ -884,11 +880,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
884{ 880{
885 u32 reg; 881 u32 reg;
886 882
887 /*
888 * Disable LED
889 */
890 rt2400pci_disable_led(rt2x00dev);
891
892 rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); 883 rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
893 884
894 /* 885 /*
@@ -1273,8 +1264,24 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
1273 /* 1264 /*
1274 * Store led mode, for correct led behaviour. 1265 * Store led mode, for correct led behaviour.
1275 */ 1266 */
1276 rt2x00dev->led_mode = 1267#ifdef CONFIG_RT2400PCI_LEDS
1277 rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); 1268 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
1269
1270 switch (value) {
1271 case LED_MODE_ASUS:
1272 case LED_MODE_ALPHA:
1273 case LED_MODE_DEFAULT:
1274 rt2x00dev->led_flags = LED_SUPPORT_RADIO;
1275 break;
1276 case LED_MODE_TXRX_ACTIVITY:
1277 rt2x00dev->led_flags =
1278 LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY;
1279 break;
1280 case LED_MODE_SIGNAL_STRENGTH:
1281 rt2x00dev->led_flags = LED_SUPPORT_RADIO;
1282 break;
1283 }
1284#endif /* CONFIG_RT2400PCI_LEDS */
1278 1285
1279 /* 1286 /*
1280 * Detect if this device has an hardware controlled radio. 1287 * Detect if this device has an hardware controlled radio.
@@ -1594,6 +1601,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
1594 .link_stats = rt2400pci_link_stats, 1601 .link_stats = rt2400pci_link_stats,
1595 .reset_tuner = rt2400pci_reset_tuner, 1602 .reset_tuner = rt2400pci_reset_tuner,
1596 .link_tuner = rt2400pci_link_tuner, 1603 .link_tuner = rt2400pci_link_tuner,
1604 .led_brightness = rt2400pci_led_brightness,
1597 .write_tx_desc = rt2400pci_write_tx_desc, 1605 .write_tx_desc = rt2400pci_write_tx_desc,
1598 .write_tx_data = rt2x00pci_write_tx_data, 1606 .write_tx_data = rt2x00pci_write_tx_data,
1599 .kick_tx_queue = rt2400pci_kick_tx_queue, 1607 .kick_tx_queue = rt2400pci_kick_tx_queue,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 36c64f751b1d..bb359a14b4ae 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -243,6 +243,30 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
243#define rt2500pci_rfkill_poll NULL 243#define rt2500pci_rfkill_poll NULL
244#endif /* CONFIG_RT2500PCI_RFKILL */ 244#endif /* CONFIG_RT2500PCI_RFKILL */
245 245
246#ifdef CONFIG_RT2500PCI_LEDS
247static void rt2500pci_led_brightness(struct led_classdev *led_cdev,
248 enum led_brightness brightness)
249{
250 struct rt2x00_led *led =
251 container_of(led_cdev, struct rt2x00_led, led_dev);
252 unsigned int enabled = brightness != LED_OFF;
253 unsigned int activity =
254 led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY;
255 u32 reg;
256
257 rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg);
258
259 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) {
260 rt2x00_set_field32(&reg, LEDCSR_LINK, enabled);
261 rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled && activity);
262 }
263
264 rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg);
265}
266#else
267#define rt2500pci_led_brightness NULL
268#endif /* CONFIG_RT2500PCI_LEDS */
269
246/* 270/*
247 * Configuration handlers. 271 * Configuration handlers.
248 */ 272 */
@@ -549,34 +573,6 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
549} 573}
550 574
551/* 575/*
552 * LED functions.
553 */
554static void rt2500pci_enable_led(struct rt2x00_dev *rt2x00dev)
555{
556 u32 reg;
557
558 rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
559
560 rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
561 rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
562 rt2x00_set_field32(&reg, LEDCSR_LINK,
563 (rt2x00dev->led_mode != LED_MODE_ASUS));
564 rt2x00_set_field32(&reg, LEDCSR_ACTIVITY,
565 (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
566 rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
567}
568
569static void rt2500pci_disable_led(struct rt2x00_dev *rt2x00dev)
570{
571 u32 reg;
572
573 rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
574 rt2x00_set_field32(&reg, LEDCSR_LINK, 0);
575 rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, 0);
576 rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
577}
578
579/*
580 * Link tuning 576 * Link tuning
581 */ 577 */
582static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, 578static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev,
@@ -795,6 +791,11 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev)
795 rt2x00_set_field32(&reg, CSR11_CW_SELECT, 0); 791 rt2x00_set_field32(&reg, CSR11_CW_SELECT, 0);
796 rt2x00pci_register_write(rt2x00dev, CSR11, reg); 792 rt2x00pci_register_write(rt2x00dev, CSR11, reg);
797 793
794 rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
795 rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
796 rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
797 rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
798
798 rt2x00pci_register_write(rt2x00dev, CNT3, 0); 799 rt2x00pci_register_write(rt2x00dev, CNT3, 0);
799 800
800 rt2x00pci_register_read(rt2x00dev, TXCSR8, &reg); 801 rt2x00pci_register_read(rt2x00dev, TXCSR8, &reg);
@@ -1026,11 +1027,6 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev)
1026 */ 1027 */
1027 rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); 1028 rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);
1028 1029
1029 /*
1030 * Enable LED
1031 */
1032 rt2500pci_enable_led(rt2x00dev);
1033
1034 return 0; 1030 return 0;
1035} 1031}
1036 1032
@@ -1038,11 +1034,6 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
1038{ 1034{
1039 u32 reg; 1035 u32 reg;
1040 1036
1041 /*
1042 * Disable LED
1043 */
1044 rt2500pci_disable_led(rt2x00dev);
1045
1046 rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); 1037 rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
1047 1038
1048 /* 1039 /*
@@ -1445,8 +1436,24 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
1445 /* 1436 /*
1446 * Store led mode, for correct led behaviour. 1437 * Store led mode, for correct led behaviour.
1447 */ 1438 */
1448 rt2x00dev->led_mode = 1439#ifdef CONFIG_RT2500PCI_LEDS
1449 rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); 1440 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
1441
1442 switch (value) {
1443 case LED_MODE_ASUS:
1444 case LED_MODE_ALPHA:
1445 case LED_MODE_DEFAULT:
1446 rt2x00dev->led_flags = LED_SUPPORT_RADIO;
1447 break;
1448 case LED_MODE_TXRX_ACTIVITY:
1449 rt2x00dev->led_flags =
1450 LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY;
1451 break;
1452 case LED_MODE_SIGNAL_STRENGTH:
1453 rt2x00dev->led_flags = LED_SUPPORT_RADIO;
1454 break;
1455 }
1456#endif /* CONFIG_RT2500PCI_LEDS */
1450 1457
1451 /* 1458 /*
1452 * Detect if this device has an hardware controlled radio. 1459 * Detect if this device has an hardware controlled radio.
@@ -1906,6 +1913,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
1906 .link_stats = rt2500pci_link_stats, 1913 .link_stats = rt2500pci_link_stats,
1907 .reset_tuner = rt2500pci_reset_tuner, 1914 .reset_tuner = rt2500pci_reset_tuner,
1908 .link_tuner = rt2500pci_link_tuner, 1915 .link_tuner = rt2500pci_link_tuner,
1916 .led_brightness = rt2500pci_led_brightness,
1909 .write_tx_desc = rt2500pci_write_tx_desc, 1917 .write_tx_desc = rt2500pci_write_tx_desc,
1910 .write_tx_data = rt2x00pci_write_tx_data, 1918 .write_tx_data = rt2x00pci_write_tx_data,
1911 .kick_tx_queue = rt2500pci_kick_tx_queue, 1919 .kick_tx_queue = rt2500pci_kick_tx_queue,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index df176cd2ef42..6352ebe8cb43 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -282,6 +282,31 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = {
282}; 282};
283#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 283#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
284 284
285#ifdef CONFIG_RT2500USB_LEDS
286static void rt2500usb_led_brightness(struct led_classdev *led_cdev,
287 enum led_brightness brightness)
288{
289 struct rt2x00_led *led =
290 container_of(led_cdev, struct rt2x00_led, led_dev);
291 unsigned int enabled = brightness != LED_OFF;
292 unsigned int activity =
293 led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY;
294 u16 reg;
295
296 rt2500usb_register_read(led->rt2x00dev, MAC_CSR20, &reg);
297
298 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) {
299 rt2x00_set_field16(&reg, MAC_CSR20_LINK, enabled);
300 rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY,
301 enabled && activity);
302 }
303
304 rt2500usb_register_write(led->rt2x00dev, MAC_CSR20, reg);
305}
306#else
307#define rt2500usb_led_brightness NULL
308#endif /* CONFIG_RT2500USB_LEDS */
309
285/* 310/*
286 * Configuration handlers. 311 * Configuration handlers.
287 */ 312 */
@@ -526,36 +551,6 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
526} 551}
527 552
528/* 553/*
529 * LED functions.
530 */
531static void rt2500usb_enable_led(struct rt2x00_dev *rt2x00dev)
532{
533 u16 reg;
534
535 rt2500usb_register_read(rt2x00dev, MAC_CSR21, &reg);
536 rt2x00_set_field16(&reg, MAC_CSR21_ON_PERIOD, 70);
537 rt2x00_set_field16(&reg, MAC_CSR21_OFF_PERIOD, 30);
538 rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg);
539
540 rt2500usb_register_read(rt2x00dev, MAC_CSR20, &reg);
541 rt2x00_set_field16(&reg, MAC_CSR20_LINK,
542 (rt2x00dev->led_mode != LED_MODE_ASUS));
543 rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY,
544 (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
545 rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg);
546}
547
548static void rt2500usb_disable_led(struct rt2x00_dev *rt2x00dev)
549{
550 u16 reg;
551
552 rt2500usb_register_read(rt2x00dev, MAC_CSR20, &reg);
553 rt2x00_set_field16(&reg, MAC_CSR20_LINK, 0);
554 rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY, 0);
555 rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg);
556}
557
558/*
559 * Link tuning 554 * Link tuning
560 */ 555 */
561static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, 556static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev,
@@ -751,6 +746,11 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
751 rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 0); 746 rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 0);
752 rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); 747 rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);
753 748
749 rt2500usb_register_read(rt2x00dev, MAC_CSR21, &reg);
750 rt2x00_set_field16(&reg, MAC_CSR21_ON_PERIOD, 70);
751 rt2x00_set_field16(&reg, MAC_CSR21_OFF_PERIOD, 30);
752 rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg);
753
754 rt2500usb_register_read(rt2x00dev, TXRX_CSR5, &reg); 754 rt2500usb_register_read(rt2x00dev, TXRX_CSR5, &reg);
755 rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0, 13); 755 rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0, 13);
756 rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0_VALID, 1); 756 rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0_VALID, 1);
@@ -924,21 +924,11 @@ static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev)
924 return -EIO; 924 return -EIO;
925 } 925 }
926 926
927 /*
928 * Enable LED
929 */
930 rt2500usb_enable_led(rt2x00dev);
931
932 return 0; 927 return 0;
933} 928}
934 929
935static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev) 930static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev)
936{ 931{
937 /*
938 * Disable LED
939 */
940 rt2500usb_disable_led(rt2x00dev);
941
942 rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121); 932 rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121);
943 rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121); 933 rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121);
944 934
@@ -1370,8 +1360,24 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1370 /* 1360 /*
1371 * Store led mode, for correct led behaviour. 1361 * Store led mode, for correct led behaviour.
1372 */ 1362 */
1373 rt2x00dev->led_mode = 1363#ifdef CONFIG_RT2500USB_LEDS
1374 rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); 1364 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
1365
1366 switch (value) {
1367 case LED_MODE_ASUS:
1368 case LED_MODE_ALPHA:
1369 case LED_MODE_DEFAULT:
1370 rt2x00dev->led_flags = LED_SUPPORT_RADIO;
1371 break;
1372 case LED_MODE_TXRX_ACTIVITY:
1373 rt2x00dev->led_flags =
1374 LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY;
1375 break;
1376 case LED_MODE_SIGNAL_STRENGTH:
1377 rt2x00dev->led_flags = LED_SUPPORT_RADIO;
1378 break;
1379 }
1380#endif /* CONFIG_RT2500USB_LEDS */
1375 1381
1376 /* 1382 /*
1377 * Check if the BBP tuning should be disabled. 1383 * Check if the BBP tuning should be disabled.
@@ -1817,6 +1823,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
1817 .link_stats = rt2500usb_link_stats, 1823 .link_stats = rt2500usb_link_stats,
1818 .reset_tuner = rt2500usb_reset_tuner, 1824 .reset_tuner = rt2500usb_reset_tuner,
1819 .link_tuner = rt2500usb_link_tuner, 1825 .link_tuner = rt2500usb_link_tuner,
1826 .led_brightness = rt2500usb_led_brightness,
1820 .write_tx_desc = rt2500usb_write_tx_desc, 1827 .write_tx_desc = rt2500usb_write_tx_desc,
1821 .write_tx_data = rt2x00usb_write_tx_data, 1828 .write_tx_data = rt2x00usb_write_tx_data,
1822 .get_tx_data_len = rt2500usb_get_tx_data_len, 1829 .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 93dbe2b286d5..76270e9c31ff 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -30,12 +30,14 @@
30#include <linux/skbuff.h> 30#include <linux/skbuff.h>
31#include <linux/workqueue.h> 31#include <linux/workqueue.h>
32#include <linux/firmware.h> 32#include <linux/firmware.h>
33#include <linux/leds.h>
33#include <linux/mutex.h> 34#include <linux/mutex.h>
34#include <linux/etherdevice.h> 35#include <linux/etherdevice.h>
35 36
36#include <net/mac80211.h> 37#include <net/mac80211.h>
37 38
38#include "rt2x00debug.h" 39#include "rt2x00debug.h"
40#include "rt2x00leds.h"
39#include "rt2x00reg.h" 41#include "rt2x00reg.h"
40#include "rt2x00queue.h" 42#include "rt2x00queue.h"
41 43
@@ -512,6 +514,8 @@ struct rt2x00lib_ops {
512 struct link_qual *qual); 514 struct link_qual *qual);
513 void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); 515 void (*reset_tuner) (struct rt2x00_dev *rt2x00dev);
514 void (*link_tuner) (struct rt2x00_dev *rt2x00dev); 516 void (*link_tuner) (struct rt2x00_dev *rt2x00dev);
517 void (*led_brightness) (struct led_classdev *led_cdev,
518 enum led_brightness brightness);
515 519
516 /* 520 /*
517 * TX control handlers 521 * TX control handlers
@@ -665,6 +669,19 @@ struct rt2x00_dev {
665#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 669#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
666 670
667 /* 671 /*
672 * LED structure for changing the LED status
673 * by mac8011 or the kernel.
674 */
675#ifdef CONFIG_RT2X00_LIB_LEDS
676 unsigned int led_flags;
677 struct rt2x00_trigger trigger_qual;
678 struct rt2x00_led led_radio;
679 struct rt2x00_led led_assoc;
680 struct rt2x00_led led_qual;
681 u16 led_mcu_reg;
682#endif /* CONFIG_RT2X00_LIB_LEDS */
683
684 /*
668 * Device flags. 685 * Device flags.
669 * In these flags the current status and some 686 * In these flags the current status and some
670 * of the device capabilities are stored. 687 * of the device capabilities are stored.
@@ -756,16 +773,6 @@ struct rt2x00_dev {
756 u16 tx_power; 773 u16 tx_power;
757 774
758 /* 775 /*
759 * LED register (for rt61pci & rt73usb).
760 */
761 u16 led_reg;
762
763 /*
764 * Led mode (LED_MODE_*)
765 */
766 u8 led_mode;
767
768 /*
769 * Rssi <-> Dbm offset 776 * Rssi <-> Dbm offset
770 */ 777 */
771 u8 rssi_offset; 778 u8 rssi_offset;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 2b99f22ef036..23dc566b26fd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -379,6 +379,11 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
379 rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); 379 rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual);
380 380
381 /* 381 /*
382 * Send a signal to the led to update the led signal strength.
383 */
384 rt2x00leds_led_quality(rt2x00dev, rt2x00dev->link.qual.avg_rssi);
385
386 /*
382 * Evaluate antenna setup, make this the last step since this could 387 * Evaluate antenna setup, make this the last step since this could
383 * possibly reset some statistics. 388 * possibly reset some statistics.
384 */ 389 */
@@ -1140,6 +1145,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1140 } 1145 }
1141 1146
1142 /* 1147 /*
1148 * Register LED.
1149 */
1150 rt2x00leds_register(rt2x00dev);
1151
1152 /*
1143 * Allocatie rfkill. 1153 * Allocatie rfkill.
1144 */ 1154 */
1145 retval = rt2x00rfkill_allocate(rt2x00dev); 1155 retval = rt2x00rfkill_allocate(rt2x00dev);
@@ -1187,6 +1197,11 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1187 rt2x00rfkill_free(rt2x00dev); 1197 rt2x00rfkill_free(rt2x00dev);
1188 1198
1189 /* 1199 /*
1200 * Free LED.
1201 */
1202 rt2x00leds_unregister(rt2x00dev);
1203
1204 /*
1190 * Free ieee80211_hw memory. 1205 * Free ieee80211_hw memory.
1191 */ 1206 */
1192 rt2x00lib_remove_hw(rt2x00dev); 1207 rt2x00lib_remove_hw(rt2x00dev);
@@ -1227,6 +1242,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
1227 */ 1242 */
1228 rt2x00lib_stop(rt2x00dev); 1243 rt2x00lib_stop(rt2x00dev);
1229 rt2x00lib_uninitialize(rt2x00dev); 1244 rt2x00lib_uninitialize(rt2x00dev);
1245 rt2x00leds_suspend(rt2x00dev);
1230 rt2x00debug_deregister(rt2x00dev); 1246 rt2x00debug_deregister(rt2x00dev);
1231 1247
1232exit: 1248exit:
@@ -1270,9 +1286,10 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1270 NOTICE(rt2x00dev, "Waking up.\n"); 1286 NOTICE(rt2x00dev, "Waking up.\n");
1271 1287
1272 /* 1288 /*
1273 * Open the debugfs entry. 1289 * Open the debugfs entry and restore led handling.
1274 */ 1290 */
1275 rt2x00debug_register(rt2x00dev); 1291 rt2x00debug_register(rt2x00dev);
1292 rt2x00leds_resume(rt2x00dev);
1276 1293
1277 /* 1294 /*
1278 * Only continue if mac80211 had open interfaces. 1295 * Only continue if mac80211 had open interfaces.
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index ca9630c75520..2a611e4366b5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -183,4 +183,37 @@ static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
183} 183}
184#endif /* CONFIG_RT2X00_LIB_RFKILL */ 184#endif /* CONFIG_RT2X00_LIB_RFKILL */
185 185
186/*
187 * LED handlers
188 */
189#ifdef CONFIG_RT2X00_LIB_LEDS
190void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi);
191int rt2x00leds_register(struct rt2x00_dev *rt2x00dev);
192void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev);
193void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev);
194void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev);
195#else
196static inline void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev,
197 int rssi)
198{
199}
200
201static inline int rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
202{
203 return 0;
204}
205
206static inline void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev)
207{
208}
209
210static inline void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev)
211{
212}
213
214static inline void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev)
215{
216}
217#endif /* CONFIG_RT2X00_LIB_LEDS */
218
186#endif /* RT2X00LIB_H */ 219#endif /* RT2X00LIB_H */
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 1dd30510ed1e..a049ff62e791 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -155,6 +155,12 @@ rf_write:
155 rt2x00_rf_write(rt2x00dev, word, value); 155 rt2x00_rf_write(rt2x00dev, word, value);
156} 156}
157 157
158#ifdef CONFIG_RT61PCI_LEDS
159/*
160 * This function is only called from rt61pci_led_brightness()
161 * make gcc happy by placing this function inside the
162 * same ifdef statement as the caller.
163 */
158static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, 164static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
159 const u8 command, const u8 token, 165 const u8 command, const u8 token,
160 const u8 arg0, const u8 arg1) 166 const u8 arg0, const u8 arg1)
@@ -181,6 +187,7 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
181 rt2x00_set_field32(&reg, HOST_CMD_CSR_INTERRUPT_MCU, 1); 187 rt2x00_set_field32(&reg, HOST_CMD_CSR_INTERRUPT_MCU, 1);
182 rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); 188 rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg);
183} 189}
190#endif /* CONFIG_RT61PCI_LEDS */
184 191
185static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) 192static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
186{ 193{
@@ -268,6 +275,48 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
268#define rt61pci_rfkill_poll NULL 275#define rt61pci_rfkill_poll NULL
269#endif /* CONFIG_RT61PCI_RFKILL */ 276#endif /* CONFIG_RT61PCI_RFKILL */
270 277
278#ifdef CONFIG_RT61PCI_LEDS
279static void rt61pci_led_brightness(struct led_classdev *led_cdev,
280 enum led_brightness brightness)
281{
282 struct rt2x00_led *led =
283 container_of(led_cdev, struct rt2x00_led, led_dev);
284 unsigned int enabled = brightness != LED_OFF;
285 unsigned int a_mode =
286 (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ);
287 unsigned int bg_mode =
288 (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
289
290 if (led->type == LED_TYPE_RADIO) {
291 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
292 MCU_LEDCS_RADIO_STATUS, enabled);
293
294 rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff,
295 (led->rt2x00dev->led_mcu_reg & 0xff),
296 ((led->rt2x00dev->led_mcu_reg >> 8)));
297 } else if (led->type == LED_TYPE_ASSOC) {
298 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
299 MCU_LEDCS_LINK_BG_STATUS, bg_mode);
300 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
301 MCU_LEDCS_LINK_A_STATUS, a_mode);
302
303 rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff,
304 (led->rt2x00dev->led_mcu_reg & 0xff),
305 ((led->rt2x00dev->led_mcu_reg >> 8)));
306 } else if (led->type == LED_TYPE_QUALITY) {
307 /*
308 * The brightness is divided into 6 levels (0 - 5),
309 * this means we need to convert the brightness
310 * argument into the matching level within that range.
311 */
312 rt61pci_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
313 brightness / (LED_FULL / 6), 0);
314 }
315}
316#else
317#define rt61pci_led_brightness NULL
318#endif /* CONFIG_RT61PCI_LEDS */
319
271/* 320/*
272 * Configuration handlers. 321 * Configuration handlers.
273 */ 322 */
@@ -682,78 +731,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
682} 731}
683 732
684/* 733/*
685 * LED functions.
686 */
687static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev)
688{
689 u32 reg;
690 u8 arg0;
691 u8 arg1;
692
693 rt2x00pci_register_read(rt2x00dev, MAC_CSR14, &reg);
694 rt2x00_set_field32(&reg, MAC_CSR14_ON_PERIOD, 70);
695 rt2x00_set_field32(&reg, MAC_CSR14_OFF_PERIOD, 30);
696 rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg);
697
698 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1);
699 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS,
700 rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ);
701 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS,
702 rt2x00dev->rx_status.band != IEEE80211_BAND_5GHZ);
703
704 arg0 = rt2x00dev->led_reg & 0xff;
705 arg1 = (rt2x00dev->led_reg >> 8) & 0xff;
706
707 rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1);
708}
709
710static void rt61pci_disable_led(struct rt2x00_dev *rt2x00dev)
711{
712 u16 led_reg;
713 u8 arg0;
714 u8 arg1;
715
716 led_reg = rt2x00dev->led_reg;
717 rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 0);
718 rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 0);
719 rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 0);
720
721 arg0 = led_reg & 0xff;
722 arg1 = (led_reg >> 8) & 0xff;
723
724 rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1);
725}
726
727static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi)
728{
729 u8 led;
730
731 if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH)
732 return;
733
734 /*
735 * Led handling requires a positive value for the rssi,
736 * to do that correctly we need to add the correction.
737 */
738 rssi += rt2x00dev->rssi_offset;
739
740 if (rssi <= 30)
741 led = 0;
742 else if (rssi <= 39)
743 led = 1;
744 else if (rssi <= 49)
745 led = 2;
746 else if (rssi <= 53)
747 led = 3;
748 else if (rssi <= 63)
749 led = 4;
750 else
751 led = 5;
752
753 rt61pci_mcu_request(rt2x00dev, MCU_LED_STRENGTH, 0xff, led, 0);
754}
755
756/*
757 * Link tuning 734 * Link tuning
758 */ 735 */
759static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, 736static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev,
@@ -787,11 +764,6 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
787 u8 up_bound; 764 u8 up_bound;
788 u8 low_bound; 765 u8 low_bound;
789 766
790 /*
791 * Update Led strength
792 */
793 rt61pci_activity_led(rt2x00dev, rssi);
794
795 rt61pci_bbp_read(rt2x00dev, 17, &r17); 767 rt61pci_bbp_read(rt2x00dev, 17, &r17);
796 768
797 /* 769 /*
@@ -1192,6 +1164,11 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev)
1192 1164
1193 rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); 1165 rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000);
1194 1166
1167 rt2x00pci_register_read(rt2x00dev, MAC_CSR14, &reg);
1168 rt2x00_set_field32(&reg, MAC_CSR14_ON_PERIOD, 70);
1169 rt2x00_set_field32(&reg, MAC_CSR14_OFF_PERIOD, 30);
1170 rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg);
1171
1195 /* 1172 /*
1196 * Invalidate all Shared Keys (SEC_CSR0), 1173 * Invalidate all Shared Keys (SEC_CSR0),
1197 * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) 1174 * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5)
@@ -1403,11 +1380,6 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev)
1403 rt2x00_set_field32(&reg, RX_CNTL_CSR_ENABLE_RX_DMA, 1); 1380 rt2x00_set_field32(&reg, RX_CNTL_CSR_ENABLE_RX_DMA, 1);
1404 rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); 1381 rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg);
1405 1382
1406 /*
1407 * Enable LED
1408 */
1409 rt61pci_enable_led(rt2x00dev);
1410
1411 return 0; 1383 return 0;
1412} 1384}
1413 1385
@@ -1415,11 +1387,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev)
1415{ 1387{
1416 u32 reg; 1388 u32 reg;
1417 1389
1418 /*
1419 * Disable LED
1420 */
1421 rt61pci_disable_led(rt2x00dev);
1422
1423 rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); 1390 rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
1424 1391
1425 /* 1392 /*
@@ -2048,35 +2015,51 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
2048 * If the eeprom value is invalid, 2015 * If the eeprom value is invalid,
2049 * switch to default led mode. 2016 * switch to default led mode.
2050 */ 2017 */
2018#ifdef CONFIG_RT61PCI_LEDS
2051 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); 2019 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);
2052 2020
2053 rt2x00dev->led_mode = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); 2021 value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE);
2022
2023 switch (value) {
2024 case LED_MODE_TXRX_ACTIVITY:
2025 case LED_MODE_ASUS:
2026 case LED_MODE_ALPHA:
2027 case LED_MODE_DEFAULT:
2028 rt2x00dev->led_flags =
2029 LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC;
2030 break;
2031 case LED_MODE_SIGNAL_STRENGTH:
2032 rt2x00dev->led_flags =
2033 LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC |
2034 LED_SUPPORT_QUALITY;
2035 break;
2036 }
2054 2037
2055 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, 2038 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value);
2056 rt2x00dev->led_mode); 2039 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0,
2057 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0,
2058 rt2x00_get_field16(eeprom, 2040 rt2x00_get_field16(eeprom,
2059 EEPROM_LED_POLARITY_GPIO_0)); 2041 EEPROM_LED_POLARITY_GPIO_0));
2060 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, 2042 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1,
2061 rt2x00_get_field16(eeprom, 2043 rt2x00_get_field16(eeprom,
2062 EEPROM_LED_POLARITY_GPIO_1)); 2044 EEPROM_LED_POLARITY_GPIO_1));
2063 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, 2045 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2,
2064 rt2x00_get_field16(eeprom, 2046 rt2x00_get_field16(eeprom,
2065 EEPROM_LED_POLARITY_GPIO_2)); 2047 EEPROM_LED_POLARITY_GPIO_2));
2066 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, 2048 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3,
2067 rt2x00_get_field16(eeprom, 2049 rt2x00_get_field16(eeprom,
2068 EEPROM_LED_POLARITY_GPIO_3)); 2050 EEPROM_LED_POLARITY_GPIO_3));
2069 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, 2051 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4,
2070 rt2x00_get_field16(eeprom, 2052 rt2x00_get_field16(eeprom,
2071 EEPROM_LED_POLARITY_GPIO_4)); 2053 EEPROM_LED_POLARITY_GPIO_4));
2072 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, 2054 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT,
2073 rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); 2055 rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT));
2074 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, 2056 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG,
2075 rt2x00_get_field16(eeprom, 2057 rt2x00_get_field16(eeprom,
2076 EEPROM_LED_POLARITY_RDY_G)); 2058 EEPROM_LED_POLARITY_RDY_G));
2077 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, 2059 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A,
2078 rt2x00_get_field16(eeprom, 2060 rt2x00_get_field16(eeprom,
2079 EEPROM_LED_POLARITY_RDY_A)); 2061 EEPROM_LED_POLARITY_RDY_A));
2062#endif /* CONFIG_RT61PCI_LEDS */
2080 2063
2081 return 0; 2064 return 0;
2082} 2065}
@@ -2484,6 +2467,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2484 .link_stats = rt61pci_link_stats, 2467 .link_stats = rt61pci_link_stats,
2485 .reset_tuner = rt61pci_reset_tuner, 2468 .reset_tuner = rt61pci_reset_tuner,
2486 .link_tuner = rt61pci_link_tuner, 2469 .link_tuner = rt61pci_link_tuner,
2470 .led_brightness = rt61pci_led_brightness,
2487 .write_tx_desc = rt61pci_write_tx_desc, 2471 .write_tx_desc = rt61pci_write_tx_desc,
2488 .write_tx_data = rt2x00pci_write_tx_data, 2472 .write_tx_data = rt2x00pci_write_tx_data,
2489 .kick_tx_queue = rt61pci_kick_tx_queue, 2473 .kick_tx_queue = rt61pci_kick_tx_queue,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 9cbc879da037..ca5a9855adbd 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -278,6 +278,50 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
278}; 278};
279#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 279#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
280 280
281#ifdef CONFIG_RT73USB_LEDS
282static void rt73usb_led_brightness(struct led_classdev *led_cdev,
283 enum led_brightness brightness)
284{
285 struct rt2x00_led *led =
286 container_of(led_cdev, struct rt2x00_led, led_dev);
287 unsigned int enabled = brightness != LED_OFF;
288 unsigned int a_mode =
289 (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ);
290 unsigned int bg_mode =
291 (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
292
293 if (led->type == LED_TYPE_RADIO) {
294 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
295 MCU_LEDCS_RADIO_STATUS, enabled);
296
297 rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, 0,
298 led->rt2x00dev->led_mcu_reg,
299 REGISTER_TIMEOUT);
300 } else if (led->type == LED_TYPE_ASSOC) {
301 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
302 MCU_LEDCS_LINK_BG_STATUS, bg_mode);
303 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
304 MCU_LEDCS_LINK_A_STATUS, a_mode);
305
306 rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, 0,
307 led->rt2x00dev->led_mcu_reg,
308 REGISTER_TIMEOUT);
309 } else if (led->type == LED_TYPE_QUALITY) {
310 /*
311 * The brightness is divided into 6 levels (0 - 5),
312 * this means we need to convert the brightness
313 * argument into the matching level within that range.
314 */
315 rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL,
316 brightness / (LED_FULL / 6),
317 led->rt2x00dev->led_mcu_reg,
318 REGISTER_TIMEOUT);
319 }
320}
321#else
322#define rt73usb_led_brightness NULL
323#endif /* CONFIG_RT73USB_LEDS */
324
281/* 325/*
282 * Configuration handlers. 326 * Configuration handlers.
283 */ 327 */
@@ -630,68 +674,6 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
630} 674}
631 675
632/* 676/*
633 * LED functions.
634 */
635static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev)
636{
637 u32 reg;
638
639 rt73usb_register_read(rt2x00dev, MAC_CSR14, &reg);
640 rt2x00_set_field32(&reg, MAC_CSR14_ON_PERIOD, 70);
641 rt2x00_set_field32(&reg, MAC_CSR14_OFF_PERIOD, 30);
642 rt73usb_register_write(rt2x00dev, MAC_CSR14, reg);
643
644 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1);
645 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS,
646 (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ));
647 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS,
648 (rt2x00dev->rx_status.band != IEEE80211_BAND_5GHZ));
649
650 rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000,
651 rt2x00dev->led_reg, REGISTER_TIMEOUT);
652}
653
654static void rt73usb_disable_led(struct rt2x00_dev *rt2x00dev)
655{
656 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 0);
657 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, 0);
658 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, 0);
659
660 rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000,
661 rt2x00dev->led_reg, REGISTER_TIMEOUT);
662}
663
664static void rt73usb_activity_led(struct rt2x00_dev *rt2x00dev, int rssi)
665{
666 u32 led;
667
668 if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH)
669 return;
670
671 /*
672 * Led handling requires a positive value for the rssi,
673 * to do that correctly we need to add the correction.
674 */
675 rssi += rt2x00dev->rssi_offset;
676
677 if (rssi <= 30)
678 led = 0;
679 else if (rssi <= 39)
680 led = 1;
681 else if (rssi <= 49)
682 led = 2;
683 else if (rssi <= 53)
684 led = 3;
685 else if (rssi <= 63)
686 led = 4;
687 else
688 led = 5;
689
690 rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, led,
691 rt2x00dev->led_reg, REGISTER_TIMEOUT);
692}
693
694/*
695 * Link tuning 677 * Link tuning
696 */ 678 */
697static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, 679static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev,
@@ -725,11 +707,6 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
725 u8 up_bound; 707 u8 up_bound;
726 u8 low_bound; 708 u8 low_bound;
727 709
728 /*
729 * Update Led strength
730 */
731 rt73usb_activity_led(rt2x00dev, rssi);
732
733 rt73usb_bbp_read(rt2x00dev, 17, &r17); 710 rt73usb_bbp_read(rt2x00dev, 17, &r17);
734 711
735 /* 712 /*
@@ -914,8 +891,6 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
914 return status; 891 return status;
915 } 892 }
916 893
917 rt73usb_disable_led(rt2x00dev);
918
919 return 0; 894 return 0;
920} 895}
921 896
@@ -993,6 +968,11 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
993 968
994 rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00); 969 rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00);
995 970
971 rt73usb_register_read(rt2x00dev, MAC_CSR14, &reg);
972 rt2x00_set_field32(&reg, MAC_CSR14_ON_PERIOD, 70);
973 rt2x00_set_field32(&reg, MAC_CSR14_OFF_PERIOD, 30);
974 rt73usb_register_write(rt2x00dev, MAC_CSR14, reg);
975
996 /* 976 /*
997 * Invalidate all Shared Keys (SEC_CSR0), 977 * Invalidate all Shared Keys (SEC_CSR0),
998 * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) 978 * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5)
@@ -1152,21 +1132,11 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)
1152 return -EIO; 1132 return -EIO;
1153 } 1133 }
1154 1134
1155 /*
1156 * Enable LED
1157 */
1158 rt73usb_enable_led(rt2x00dev);
1159
1160 return 0; 1135 return 0;
1161} 1136}
1162 1137
1163static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) 1138static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev)
1164{ 1139{
1165 /*
1166 * Disable LED
1167 */
1168 rt73usb_disable_led(rt2x00dev);
1169
1170 rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); 1140 rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
1171 1141
1172 /* 1142 /*
@@ -1615,33 +1585,49 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1615 /* 1585 /*
1616 * Store led settings, for correct led behaviour. 1586 * Store led settings, for correct led behaviour.
1617 */ 1587 */
1588#ifdef CONFIG_RT73USB_LEDS
1618 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); 1589 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);
1619 1590
1620 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, 1591 switch (value) {
1621 rt2x00dev->led_mode); 1592 case LED_MODE_TXRX_ACTIVITY:
1622 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, 1593 case LED_MODE_ASUS:
1594 case LED_MODE_ALPHA:
1595 case LED_MODE_DEFAULT:
1596 rt2x00dev->led_flags =
1597 LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC;
1598 break;
1599 case LED_MODE_SIGNAL_STRENGTH:
1600 rt2x00dev->led_flags =
1601 LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC |
1602 LED_SUPPORT_QUALITY;
1603 break;
1604 }
1605
1606 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value);
1607 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0,
1623 rt2x00_get_field16(eeprom, 1608 rt2x00_get_field16(eeprom,
1624 EEPROM_LED_POLARITY_GPIO_0)); 1609 EEPROM_LED_POLARITY_GPIO_0));
1625 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, 1610 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1,
1626 rt2x00_get_field16(eeprom, 1611 rt2x00_get_field16(eeprom,
1627 EEPROM_LED_POLARITY_GPIO_1)); 1612 EEPROM_LED_POLARITY_GPIO_1));
1628 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, 1613 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2,
1629 rt2x00_get_field16(eeprom, 1614 rt2x00_get_field16(eeprom,
1630 EEPROM_LED_POLARITY_GPIO_2)); 1615 EEPROM_LED_POLARITY_GPIO_2));
1631 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, 1616 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3,
1632 rt2x00_get_field16(eeprom, 1617 rt2x00_get_field16(eeprom,
1633 EEPROM_LED_POLARITY_GPIO_3)); 1618 EEPROM_LED_POLARITY_GPIO_3));
1634 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, 1619 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4,
1635 rt2x00_get_field16(eeprom, 1620 rt2x00_get_field16(eeprom,
1636 EEPROM_LED_POLARITY_GPIO_4)); 1621 EEPROM_LED_POLARITY_GPIO_4));
1637 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, 1622 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT,
1638 rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); 1623 rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT));
1639 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, 1624 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG,
1640 rt2x00_get_field16(eeprom, 1625 rt2x00_get_field16(eeprom,
1641 EEPROM_LED_POLARITY_RDY_G)); 1626 EEPROM_LED_POLARITY_RDY_G));
1642 rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, 1627 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A,
1643 rt2x00_get_field16(eeprom, 1628 rt2x00_get_field16(eeprom,
1644 EEPROM_LED_POLARITY_RDY_A)); 1629 EEPROM_LED_POLARITY_RDY_A));
1630#endif /* CONFIG_RT73USB_LEDS */
1645 1631
1646 return 0; 1632 return 0;
1647} 1633}
@@ -2084,6 +2070,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
2084 .link_stats = rt73usb_link_stats, 2070 .link_stats = rt73usb_link_stats,
2085 .reset_tuner = rt73usb_reset_tuner, 2071 .reset_tuner = rt73usb_reset_tuner,
2086 .link_tuner = rt73usb_link_tuner, 2072 .link_tuner = rt73usb_link_tuner,
2073 .led_brightness = rt73usb_led_brightness,
2087 .write_tx_desc = rt73usb_write_tx_desc, 2074 .write_tx_desc = rt73usb_write_tx_desc,
2088 .write_tx_data = rt2x00usb_write_tx_data, 2075 .write_tx_data = rt2x00usb_write_tx_data,
2089 .get_tx_data_len = rt73usb_get_tx_data_len, 2076 .get_tx_data_len = rt73usb_get_tx_data_len,