diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2007-10-13 00:04:51 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:03:26 -0500 |
commit | ba48f7bb8062982ec916868cc8c90360aad82e53 (patch) | |
tree | 9f19ae7146c895d09b01ef7d1bbec0d44666c0bf | |
parent | c8b0e6e19c0bcd30689cb6c6f64eb140f5d61894 (diff) |
b43legacy: LED triggers support
Drive the LEDs through the generic LED triggers.
The patch to b43 by Michael Buesch <mb@bu3sch.de> has been ported to b43legacy.
Signed-off-by: Larry Finger <larry.finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/b43legacy/Kconfig | 6 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/Makefile | 27 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/b43legacy.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/leds.c | 409 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/leds.h | 61 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 40 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/radio.c | 2 |
7 files changed, 241 insertions, 310 deletions
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index 7e23ec23fc98..1bf777578e5f 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig | |||
@@ -34,6 +34,12 @@ config B43LEGACY_PCICORE_AUTOSELECT | |||
34 | select SSB_DRIVER_PCICORE | 34 | select SSB_DRIVER_PCICORE |
35 | default y | 35 | default y |
36 | 36 | ||
37 | # LED support | ||
38 | config B43LEGACY_LEDS | ||
39 | bool | ||
40 | depends on MAC80211_LEDS | ||
41 | default y | ||
42 | |||
37 | config B43LEGACY_DEBUG | 43 | config B43LEGACY_DEBUG |
38 | bool "Broadcom 43xx-legacy debugging" | 44 | bool "Broadcom 43xx-legacy debugging" |
39 | depends on B43LEGACY | 45 | depends on B43LEGACY |
diff --git a/drivers/net/wireless/b43legacy/Makefile b/drivers/net/wireless/b43legacy/Makefile index ec3a2482bbad..abaa404bb148 100644 --- a/drivers/net/wireless/b43legacy/Makefile +++ b/drivers/net/wireless/b43legacy/Makefile | |||
@@ -1,14 +1,17 @@ | |||
1 | obj-$(CONFIG_B43LEGACY) += b43legacy.o | 1 | # b43legacy core |
2 | b43legacy-obj-$(CONFIG_B43LEGACY_DEBUG) += debugfs.o | 2 | b43legacy-y += main.o |
3 | b43legacy-y += ilt.o | ||
4 | b43legacy-y += phy.o | ||
5 | b43legacy-y += radio.o | ||
6 | b43legacy-y += sysfs.o | ||
7 | b43legacy-y += xmit.o | ||
8 | # b43legacy LED support | ||
9 | b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o | ||
10 | # b43legacy debugging | ||
11 | b43legacy-$(CONFIG_B43LEGACY_DEBUG) += debugfs.o | ||
12 | # b43legacy DMA and PIO | ||
13 | b43legacy-$(CONFIG_B43LEGACY_DMA) += dma.o | ||
14 | b43legacy-$(CONFIG_B43LEGACY_PIO) += pio.o | ||
3 | 15 | ||
4 | b43legacy-obj-$(CONFIG_B43LEGACY_DMA) += dma.o | 16 | obj-$(CONFIG_B43LEGACY) += b43legacy.o |
5 | b43legacy-obj-$(CONFIG_B43LEGACY_PIO) += pio.o | ||
6 | 17 | ||
7 | b43legacy-objs := main.o \ | ||
8 | ilt.o \ | ||
9 | leds.o \ | ||
10 | phy.o \ | ||
11 | radio.o \ | ||
12 | sysfs.o \ | ||
13 | xmit.o \ | ||
14 | $(b43legacy-obj-y) | ||
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index afe145cec067..41243ba821ac 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -663,8 +663,10 @@ struct b43legacy_wldev { | |||
663 | /* Various statistics about the physical device. */ | 663 | /* Various statistics about the physical device. */ |
664 | struct b43legacy_stats stats; | 664 | struct b43legacy_stats stats; |
665 | 665 | ||
666 | #define B43legacy_NR_LEDS 4 | 666 | /* The device LEDs. */ |
667 | struct b43legacy_led leds[B43legacy_NR_LEDS]; | 667 | struct b43legacy_led led_tx; |
668 | struct b43legacy_led led_rx; | ||
669 | struct b43legacy_led led_assoc; | ||
668 | 670 | ||
669 | /* Reason code of the last interrupt. */ | 671 | /* Reason code of the last interrupt. */ |
670 | u32 irq_reason; | 672 | u32 irq_reason; |
diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c index a584ea810502..1e30919582c5 100644 --- a/drivers/net/wireless/b43legacy/leds.c +++ b/drivers/net/wireless/b43legacy/leds.c | |||
@@ -1,13 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Broadcom B43legacy wireless driver | 3 | Broadcom B43 wireless driver |
4 | LED control | ||
4 | 5 | ||
5 | Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, | 6 | Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, |
6 | Stefano Brivio <st3@riseup.net> | 7 | Copyright (c) 2005 Stefano Brivio <st3@riseup.net> |
7 | Michael Buesch <mb@bu3sch.de> | 8 | Copyright (c) 2005-2007 Michael Buesch <mb@bu3sch.de> |
8 | Danny van Dyk <kugelfang@gentoo.org> | 9 | Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> |
9 | Andreas Jaggi <andreas.jaggi@waterwave.ch> | 10 | Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> |
10 | Copyright (c) 2007 Larry Finger <Larry.Finger@lwfinger.net> | ||
11 | 11 | ||
12 | This program is free software; you can redistribute it and/or modify | 12 | This program is free software; you can redistribute it and/or modify |
13 | it under the terms of the GNU General Public License as published by | 13 | it under the terms of the GNU General Public License as published by |
@@ -26,273 +26,208 @@ | |||
26 | 26 | ||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include "leds.h" | ||
30 | #include "b43legacy.h" | 29 | #include "b43legacy.h" |
31 | #include "main.h" | 30 | #include "leds.h" |
32 | |||
33 | static void b43legacy_led_changestate(struct b43legacy_led *led) | ||
34 | { | ||
35 | struct b43legacy_wldev *dev = led->dev; | ||
36 | const int index = led->index; | ||
37 | u16 ledctl; | ||
38 | 31 | ||
39 | B43legacy_WARN_ON(!(index >= 0 && index < B43legacy_NR_LEDS)); | ||
40 | B43legacy_WARN_ON(!led->blink_interval); | ||
41 | ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); | ||
42 | ledctl ^= (1 << index); | ||
43 | b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl); | ||
44 | } | ||
45 | 32 | ||
46 | static void b43legacy_led_blink(unsigned long d) | 33 | static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index, |
34 | bool activelow) | ||
47 | { | 35 | { |
48 | struct b43legacy_led *led = (struct b43legacy_led *)d; | 36 | struct b43legacy_wl *wl = dev->wl; |
49 | struct b43legacy_wldev *dev = led->dev; | ||
50 | unsigned long flags; | 37 | unsigned long flags; |
38 | u16 ctl; | ||
51 | 39 | ||
52 | spin_lock_irqsave(&dev->wl->leds_lock, flags); | 40 | spin_lock_irqsave(&wl->leds_lock, flags); |
53 | if (led->blink_interval) { | 41 | ctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); |
54 | b43legacy_led_changestate(led); | 42 | if (activelow) |
55 | mod_timer(&led->blink_timer, jiffies + led->blink_interval); | 43 | ctl &= ~(1 << led_index); |
56 | } | 44 | else |
57 | spin_unlock_irqrestore(&dev->wl->leds_lock, flags); | 45 | ctl |= (1 << led_index); |
46 | b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ctl); | ||
47 | spin_unlock_irqrestore(&wl->leds_lock, flags); | ||
58 | } | 48 | } |
59 | 49 | ||
60 | static void b43legacy_led_blink_start(struct b43legacy_led *led, | 50 | static void b43legacy_led_turn_off(struct b43legacy_wldev *dev, u8 led_index, |
61 | unsigned long interval) | 51 | bool activelow) |
62 | { | 52 | { |
63 | if (led->blink_interval) | 53 | struct b43legacy_wl *wl = dev->wl; |
64 | return; | 54 | unsigned long flags; |
65 | led->blink_interval = interval; | 55 | u16 ctl; |
66 | b43legacy_led_changestate(led); | 56 | |
67 | led->blink_timer.expires = jiffies + interval; | 57 | spin_lock_irqsave(&wl->leds_lock, flags); |
68 | add_timer(&led->blink_timer); | 58 | ctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); |
59 | if (activelow) | ||
60 | ctl |= (1 << led_index); | ||
61 | else | ||
62 | ctl &= ~(1 << led_index); | ||
63 | b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ctl); | ||
64 | spin_unlock_irqrestore(&wl->leds_lock, flags); | ||
69 | } | 65 | } |
70 | 66 | ||
71 | static void b43legacy_led_blink_stop(struct b43legacy_led *led, int sync) | 67 | /* Callback from the LED subsystem. */ |
68 | static void b43legacy_led_brightness_set(struct led_classdev *led_dev, | ||
69 | enum led_brightness brightness) | ||
72 | { | 70 | { |
71 | struct b43legacy_led *led = container_of(led_dev, struct b43legacy_led, | ||
72 | led_dev); | ||
73 | struct b43legacy_wldev *dev = led->dev; | 73 | struct b43legacy_wldev *dev = led->dev; |
74 | const int index = led->index; | 74 | bool radio_enabled; |
75 | u16 ledctl; | ||
76 | 75 | ||
77 | if (!led->blink_interval) | 76 | /* Checking the radio-enabled status here is slightly racy, |
78 | return; | 77 | * but we want to avoid the locking overhead and we don't care |
79 | if (unlikely(sync)) | 78 | * whether the LED has the wrong state for a second. */ |
80 | del_timer_sync(&led->blink_timer); | 79 | radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable); |
81 | else | ||
82 | del_timer(&led->blink_timer); | ||
83 | led->blink_interval = 0; | ||
84 | 80 | ||
85 | /* Make sure the LED is turned off. */ | 81 | if (brightness == LED_OFF || !radio_enabled) |
86 | B43legacy_WARN_ON(!(index >= 0 && index < B43legacy_NR_LEDS)); | 82 | b43legacy_led_turn_off(dev, led->index, led->activelow); |
87 | ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); | ||
88 | if (led->activelow) | ||
89 | ledctl |= (1 << index); | ||
90 | else | 83 | else |
91 | ledctl &= ~(1 << index); | 84 | b43legacy_led_turn_on(dev, led->index, led->activelow); |
92 | b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl); | ||
93 | } | 85 | } |
94 | 86 | ||
95 | static void b43legacy_led_init_hardcoded(struct b43legacy_wldev *dev, | 87 | static int b43legacy_register_led(struct b43legacy_wldev *dev, |
96 | struct b43legacy_led *led, | 88 | struct b43legacy_led *led, |
97 | int led_index) | 89 | const char *name, char *default_trigger, |
90 | u8 led_index, bool activelow) | ||
98 | { | 91 | { |
99 | struct ssb_bus *bus = dev->dev->bus; | 92 | int err; |
93 | |||
94 | b43legacy_led_turn_off(dev, led_index, activelow); | ||
95 | if (led->dev) | ||
96 | return -EEXIST; | ||
97 | if (!default_trigger) | ||
98 | return -EINVAL; | ||
99 | led->dev = dev; | ||
100 | led->index = led_index; | ||
101 | led->activelow = activelow; | ||
102 | strncpy(led->name, name, sizeof(led->name)); | ||
103 | |||
104 | led->led_dev.name = led->name; | ||
105 | led->led_dev.default_trigger = default_trigger; | ||
106 | led->led_dev.brightness_set = b43legacy_led_brightness_set; | ||
107 | |||
108 | err = led_classdev_register(dev->dev->dev, &led->led_dev); | ||
109 | if (err) { | ||
110 | b43legacywarn(dev->wl, "LEDs: Failed to register %s\n", name); | ||
111 | led->dev = NULL; | ||
112 | return err; | ||
113 | } | ||
114 | return 0; | ||
115 | } | ||
100 | 116 | ||
101 | /* This function is called, if the behaviour (and activelow) | 117 | static void b43legacy_unregister_led(struct b43legacy_led *led) |
102 | * information for a LED is missing in the SPROM. | 118 | { |
103 | * We hardcode the behaviour values for various devices here. | 119 | if (!led->dev) |
104 | * Note that the B43legacy_LED_TEST_XXX behaviour values can | 120 | return; |
105 | * be used to figure out which led is mapped to which index. | 121 | led_classdev_unregister(&led->led_dev); |
106 | */ | 122 | b43legacy_led_turn_off(led->dev, led->index, led->activelow); |
123 | led->dev = NULL; | ||
124 | } | ||
125 | |||
126 | static void b43legacy_map_led(struct b43legacy_wldev *dev, | ||
127 | u8 led_index, | ||
128 | enum b43legacy_led_behaviour behaviour, | ||
129 | bool activelow) | ||
130 | { | ||
131 | struct ieee80211_hw *hw = dev->wl->hw; | ||
132 | char name[B43legacy_LED_MAX_NAME_LEN + 1]; | ||
107 | 133 | ||
108 | switch (led_index) { | 134 | /* Map the b43 specific LED behaviour value to the |
109 | case 0: | 135 | * generic LED triggers. */ |
110 | led->behaviour = B43legacy_LED_ACTIVITY; | 136 | switch (behaviour) { |
111 | led->activelow = 1; | 137 | case B43legacy_LED_INACTIVE: |
112 | if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ) | ||
113 | led->behaviour = B43legacy_LED_RADIO_ALL; | ||
114 | break; | 138 | break; |
115 | case 1: | 139 | case B43legacy_LED_OFF: |
116 | led->behaviour = B43legacy_LED_RADIO_B; | 140 | b43legacy_led_turn_off(dev, led_index, activelow); |
117 | if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK) | ||
118 | led->behaviour = B43legacy_LED_ASSOC; | ||
119 | break; | 141 | break; |
120 | case 2: | 142 | case B43legacy_LED_ON: |
121 | led->behaviour = B43legacy_LED_RADIO_A; | 143 | b43legacy_led_turn_on(dev, led_index, activelow); |
122 | break; | 144 | break; |
123 | case 3: | 145 | case B43legacy_LED_ACTIVITY: |
124 | led->behaviour = B43legacy_LED_OFF; | 146 | case B43legacy_LED_TRANSFER: |
147 | case B43legacy_LED_APTRANSFER: | ||
148 | snprintf(name, sizeof(name), | ||
149 | "b43legacy-%s:tx", wiphy_name(hw->wiphy)); | ||
150 | b43legacy_register_led(dev, &dev->led_tx, name, | ||
151 | ieee80211_get_tx_led_name(hw), | ||
152 | led_index, activelow); | ||
153 | snprintf(name, sizeof(name), | ||
154 | "b43legacy-%s:rx", wiphy_name(hw->wiphy)); | ||
155 | b43legacy_register_led(dev, &dev->led_rx, name, | ||
156 | ieee80211_get_rx_led_name(hw), | ||
157 | led_index, activelow); | ||
158 | break; | ||
159 | /*FIXME: We need another trigger for the "radio-on" LEDs below. | ||
160 | * Wiggle that somehow into the rfkill subsystem. */ | ||
161 | case B43legacy_LED_RADIO_ALL: | ||
162 | case B43legacy_LED_RADIO_A: | ||
163 | case B43legacy_LED_RADIO_B: | ||
164 | case B43legacy_LED_MODE_BG: | ||
165 | case B43legacy_LED_WEIRD: | ||
166 | case B43legacy_LED_ASSOC: | ||
167 | snprintf(name, sizeof(name), | ||
168 | "b43legacy-%s:assoc", wiphy_name(hw->wiphy)); | ||
169 | b43legacy_register_led(dev, &dev->led_assoc, name, | ||
170 | ieee80211_get_assoc_led_name(hw), | ||
171 | led_index, activelow); | ||
125 | break; | 172 | break; |
126 | default: | 173 | default: |
127 | B43legacy_BUG_ON(1); | 174 | b43legacywarn(dev->wl, "LEDs: Unknown behaviour 0x%02X\n", |
175 | behaviour); | ||
176 | break; | ||
128 | } | 177 | } |
129 | } | 178 | } |
130 | 179 | ||
131 | int b43legacy_leds_init(struct b43legacy_wldev *dev) | 180 | void b43legacy_leds_init(struct b43legacy_wldev *dev) |
132 | { | 181 | { |
133 | struct b43legacy_led *led; | 182 | struct ssb_bus *bus = dev->dev->bus; |
134 | u8 sprom[4]; | 183 | u8 sprom[4]; |
135 | int i; | 184 | int i; |
136 | 185 | enum b43legacy_led_behaviour behaviour; | |
137 | sprom[0] = dev->dev->bus->sprom.r1.gpio0; | 186 | bool activelow; |
138 | sprom[1] = dev->dev->bus->sprom.r1.gpio1; | 187 | |
139 | sprom[2] = dev->dev->bus->sprom.r1.gpio2; | 188 | sprom[0] = bus->sprom.r1.gpio0; |
140 | sprom[3] = dev->dev->bus->sprom.r1.gpio3; | 189 | sprom[1] = bus->sprom.r1.gpio1; |
141 | 190 | sprom[2] = bus->sprom.r1.gpio2; | |
142 | for (i = 0; i < B43legacy_NR_LEDS; i++) { | 191 | sprom[3] = bus->sprom.r1.gpio3; |
143 | led = &(dev->leds[i]); | 192 | |
144 | led->index = i; | 193 | for (i = 0; i < 4; i++) { |
145 | led->dev = dev; | 194 | if (sprom[i] == 0xFF) { |
146 | setup_timer(&led->blink_timer, | 195 | /* There is no LED information in the SPROM |
147 | b43legacy_led_blink, | 196 | * for this LED. Hardcode it here. */ |
148 | (unsigned long)led); | 197 | activelow = 0; |
149 | 198 | switch (i) { | |
150 | if (sprom[i] == 0xFF) | 199 | case 0: |
151 | b43legacy_led_init_hardcoded(dev, led, i); | 200 | behaviour = B43legacy_LED_ACTIVITY; |
152 | else { | 201 | activelow = 1; |
153 | led->behaviour = sprom[i] & B43legacy_LED_BEHAVIOUR; | 202 | if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ) |
154 | led->activelow = !!(sprom[i] & | 203 | behaviour = B43legacy_LED_RADIO_ALL; |
155 | B43legacy_LED_ACTIVELOW); | 204 | break; |
205 | case 1: | ||
206 | behaviour = B43legacy_LED_RADIO_B; | ||
207 | if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK) | ||
208 | behaviour = B43legacy_LED_ASSOC; | ||
209 | break; | ||
210 | case 2: | ||
211 | behaviour = B43legacy_LED_RADIO_A; | ||
212 | break; | ||
213 | case 3: | ||
214 | behaviour = B43legacy_LED_OFF; | ||
215 | break; | ||
216 | default: | ||
217 | B43legacy_WARN_ON(1); | ||
218 | return; | ||
219 | } | ||
220 | } else { | ||
221 | behaviour = sprom[i] & B43legacy_LED_BEHAVIOUR; | ||
222 | activelow = !!(sprom[i] & B43legacy_LED_ACTIVELOW); | ||
156 | } | 223 | } |
224 | b43legacy_map_led(dev, i, behaviour, activelow); | ||
157 | } | 225 | } |
158 | |||
159 | return 0; | ||
160 | } | 226 | } |
161 | 227 | ||
162 | void b43legacy_leds_exit(struct b43legacy_wldev *dev) | 228 | void b43legacy_leds_exit(struct b43legacy_wldev *dev) |
163 | { | 229 | { |
164 | struct b43legacy_led *led; | 230 | b43legacy_unregister_led(&dev->led_tx); |
165 | int i; | 231 | b43legacy_unregister_led(&dev->led_rx); |
166 | 232 | b43legacy_unregister_led(&dev->led_assoc); | |
167 | for (i = 0; i < B43legacy_NR_LEDS; i++) { | ||
168 | led = &(dev->leds[i]); | ||
169 | b43legacy_led_blink_stop(led, 1); | ||
170 | } | ||
171 | b43legacy_leds_switch_all(dev, 0); | ||
172 | } | ||
173 | |||
174 | void b43legacy_leds_update(struct b43legacy_wldev *dev, int activity) | ||
175 | { | ||
176 | struct b43legacy_led *led; | ||
177 | struct b43legacy_phy *phy = &dev->phy; | ||
178 | const int transferring = (jiffies - dev->stats.last_tx) | ||
179 | < B43legacy_LED_XFER_THRES; | ||
180 | int i; | ||
181 | int turn_on; | ||
182 | unsigned long interval = 0; | ||
183 | u16 ledctl; | ||
184 | unsigned long flags; | ||
185 | bool radio_enabled = (phy->radio_on && dev->radio_hw_enable); | ||
186 | |||
187 | spin_lock_irqsave(&dev->wl->leds_lock, flags); | ||
188 | ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); | ||
189 | for (i = 0; i < B43legacy_NR_LEDS; i++) { | ||
190 | led = &(dev->leds[i]); | ||
191 | |||
192 | turn_on = 0; | ||
193 | switch (led->behaviour) { | ||
194 | case B43legacy_LED_INACTIVE: | ||
195 | continue; | ||
196 | case B43legacy_LED_OFF: | ||
197 | break; | ||
198 | case B43legacy_LED_ON: | ||
199 | turn_on = 1; | ||
200 | break; | ||
201 | case B43legacy_LED_ACTIVITY: | ||
202 | turn_on = activity; | ||
203 | break; | ||
204 | case B43legacy_LED_RADIO_ALL: | ||
205 | turn_on = radio_enabled; | ||
206 | break; | ||
207 | case B43legacy_LED_RADIO_A: | ||
208 | break; | ||
209 | case B43legacy_LED_RADIO_B: | ||
210 | turn_on = radio_enabled; | ||
211 | break; | ||
212 | case B43legacy_LED_MODE_BG: | ||
213 | if (phy->type == B43legacy_PHYTYPE_G && radio_enabled) | ||
214 | turn_on = 1; | ||
215 | break; | ||
216 | case B43legacy_LED_TRANSFER: | ||
217 | if (transferring) | ||
218 | b43legacy_led_blink_start(led, | ||
219 | B43legacy_LEDBLINK_MEDIUM); | ||
220 | else | ||
221 | b43legacy_led_blink_stop(led, 0); | ||
222 | continue; | ||
223 | case B43legacy_LED_APTRANSFER: | ||
224 | if (b43legacy_is_mode(dev->wl, | ||
225 | IEEE80211_IF_TYPE_AP)) { | ||
226 | if (transferring) { | ||
227 | interval = B43legacy_LEDBLINK_FAST; | ||
228 | turn_on = 1; | ||
229 | } | ||
230 | } else { | ||
231 | turn_on = 1; | ||
232 | if (transferring) | ||
233 | interval = B43legacy_LEDBLINK_FAST; | ||
234 | else | ||
235 | turn_on = 0; | ||
236 | } | ||
237 | if (turn_on) | ||
238 | b43legacy_led_blink_start(led, interval); | ||
239 | else | ||
240 | b43legacy_led_blink_stop(led, 0); | ||
241 | continue; | ||
242 | case B43legacy_LED_WEIRD: | ||
243 | break; | ||
244 | case B43legacy_LED_ASSOC: | ||
245 | turn_on = 1; | ||
246 | #ifdef CONFIG_B43LEGACY_DEBUG | ||
247 | case B43legacy_LED_TEST_BLINKSLOW: | ||
248 | b43legacy_led_blink_start(led, B43legacy_LEDBLINK_SLOW); | ||
249 | continue; | ||
250 | case B43legacy_LED_TEST_BLINKMEDIUM: | ||
251 | b43legacy_led_blink_start(led, | ||
252 | B43legacy_LEDBLINK_MEDIUM); | ||
253 | continue; | ||
254 | case B43legacy_LED_TEST_BLINKFAST: | ||
255 | b43legacy_led_blink_start(led, B43legacy_LEDBLINK_FAST); | ||
256 | continue; | ||
257 | #endif /* CONFIG_B43LEGACY_DEBUG */ | ||
258 | default: | ||
259 | B43legacy_BUG_ON(1); | ||
260 | }; | ||
261 | |||
262 | if (led->activelow) | ||
263 | turn_on = !turn_on; | ||
264 | if (turn_on) | ||
265 | ledctl |= (1 << i); | ||
266 | else | ||
267 | ledctl &= ~(1 << i); | ||
268 | } | ||
269 | b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl); | ||
270 | spin_unlock_irqrestore(&dev->wl->leds_lock, flags); | ||
271 | } | ||
272 | |||
273 | void b43legacy_leds_switch_all(struct b43legacy_wldev *dev, int on) | ||
274 | { | ||
275 | struct b43legacy_led *led; | ||
276 | u16 ledctl; | ||
277 | int i; | ||
278 | int bit_on; | ||
279 | unsigned long flags; | ||
280 | |||
281 | spin_lock_irqsave(&dev->wl->leds_lock, flags); | ||
282 | ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); | ||
283 | for (i = 0; i < B43legacy_NR_LEDS; i++) { | ||
284 | led = &(dev->leds[i]); | ||
285 | if (led->behaviour == B43legacy_LED_INACTIVE) | ||
286 | continue; | ||
287 | if (on) | ||
288 | bit_on = led->activelow ? 0 : 1; | ||
289 | else | ||
290 | bit_on = led->activelow ? 1 : 0; | ||
291 | if (bit_on) | ||
292 | ledctl |= (1 << i); | ||
293 | else | ||
294 | ledctl &= ~(1 << i); | ||
295 | } | ||
296 | b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl); | ||
297 | spin_unlock_irqrestore(&dev->wl->leds_lock, flags); | ||
298 | } | 233 | } |
diff --git a/drivers/net/wireless/b43legacy/leds.h b/drivers/net/wireless/b43legacy/leds.h index b989f503e684..82167a90088f 100644 --- a/drivers/net/wireless/b43legacy/leds.h +++ b/drivers/net/wireless/b43legacy/leds.h | |||
@@ -1,30 +1,33 @@ | |||
1 | #ifndef B43legacy_LEDS_H_ | 1 | #ifndef B43legacy_LEDS_H_ |
2 | #define B43legacy_LEDS_H_ | 2 | #define B43legacy_LEDS_H_ |
3 | 3 | ||
4 | struct b43legacy_wldev; | ||
5 | |||
6 | #ifdef CONFIG_B43LEGACY_LEDS | ||
7 | |||
4 | #include <linux/types.h> | 8 | #include <linux/types.h> |
5 | #include <linux/timer.h> | 9 | #include <linux/leds.h> |
6 | 10 | ||
7 | 11 | ||
12 | #define B43legacy_LED_MAX_NAME_LEN 31 | ||
13 | |||
8 | struct b43legacy_led { | 14 | struct b43legacy_led { |
9 | u8 behaviour; | ||
10 | bool activelow; | ||
11 | /* Index in the "leds" array in b43legacy_wldev */ | ||
12 | u8 index; | ||
13 | struct b43legacy_wldev *dev; | 15 | struct b43legacy_wldev *dev; |
14 | struct timer_list blink_timer; | 16 | /* The LED class device */ |
15 | unsigned long blink_interval; | 17 | struct led_classdev led_dev; |
18 | /* The index number of the LED. */ | ||
19 | u8 index; | ||
20 | /* If activelow is true, the LED is ON if the | ||
21 | * bit is switched off. */ | ||
22 | bool activelow; | ||
23 | /* The unique name string for this LED device. */ | ||
24 | char name[B43legacy_LED_MAX_NAME_LEN + 1]; | ||
16 | }; | 25 | }; |
17 | 26 | ||
18 | /* Delay between state changes when blinking in jiffies */ | ||
19 | #define B43legacy_LEDBLINK_SLOW (HZ / 1) | ||
20 | #define B43legacy_LEDBLINK_MEDIUM (HZ / 4) | ||
21 | #define B43legacy_LEDBLINK_FAST (HZ / 8) | ||
22 | |||
23 | #define B43legacy_LED_XFER_THRES (HZ / 100) | ||
24 | |||
25 | #define B43legacy_LED_BEHAVIOUR 0x7F | 27 | #define B43legacy_LED_BEHAVIOUR 0x7F |
26 | #define B43legacy_LED_ACTIVELOW 0x80 | 28 | #define B43legacy_LED_ACTIVELOW 0x80 |
27 | enum { /* LED behaviour values */ | 29 | /* LED behaviour values */ |
30 | enum b43legacy_led_behaviour { | ||
28 | B43legacy_LED_OFF, | 31 | B43legacy_LED_OFF, |
29 | B43legacy_LED_ON, | 32 | B43legacy_LED_ON, |
30 | B43legacy_LED_ACTIVITY, | 33 | B43legacy_LED_ACTIVITY, |
@@ -37,20 +40,24 @@ enum { /* LED behaviour values */ | |||
37 | B43legacy_LED_WEIRD, | 40 | B43legacy_LED_WEIRD, |
38 | B43legacy_LED_ASSOC, | 41 | B43legacy_LED_ASSOC, |
39 | B43legacy_LED_INACTIVE, | 42 | B43legacy_LED_INACTIVE, |
40 | |||
41 | /* Behaviour values for testing. | ||
42 | * With these values it is easier to figure out | ||
43 | * the real behaviour of leds, in case the SPROM | ||
44 | * is missing information. | ||
45 | */ | ||
46 | B43legacy_LED_TEST_BLINKSLOW, | ||
47 | B43legacy_LED_TEST_BLINKMEDIUM, | ||
48 | B43legacy_LED_TEST_BLINKFAST, | ||
49 | }; | 43 | }; |
50 | 44 | ||
51 | int b43legacy_leds_init(struct b43legacy_wldev *dev); | 45 | void b43legacy_leds_init(struct b43legacy_wldev *dev); |
52 | void b43legacy_leds_exit(struct b43legacy_wldev *dev); | 46 | void b43legacy_leds_exit(struct b43legacy_wldev *dev); |
53 | void b43legacy_leds_update(struct b43legacy_wldev *dev, int activity); | 47 | |
54 | void b43legacy_leds_switch_all(struct b43legacy_wldev *dev, int on); | 48 | #else /* CONFIG_B43EGACY_LEDS */ |
49 | /* LED support disabled */ | ||
50 | |||
51 | struct b43legacy_led { | ||
52 | /* empty */ | ||
53 | }; | ||
54 | |||
55 | static inline void b43legacy_leds_init(struct b43legacy_wldev *dev) | ||
56 | { | ||
57 | } | ||
58 | static inline void b43legacy_leds_exit(struct b43legacy_wldev *dev) | ||
59 | { | ||
60 | } | ||
61 | #endif /* CONFIG_B43LEGACY_LEDS */ | ||
55 | 62 | ||
56 | #endif /* B43legacy_LEDS_H_ */ | 63 | #endif /* B43legacy_LEDS_H_ */ |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 32d5e1785bda..43edd08297a4 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -83,10 +83,6 @@ static int modparam_long_retry = B43legacy_DEFAULT_LONG_RETRY_LIMIT; | |||
83 | module_param_named(long_retry, modparam_long_retry, int, 0444); | 83 | module_param_named(long_retry, modparam_long_retry, int, 0444); |
84 | MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)"); | 84 | MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)"); |
85 | 85 | ||
86 | static int modparam_noleds; | ||
87 | module_param_named(noleds, modparam_noleds, int, 0444); | ||
88 | MODULE_PARM_DESC(noleds, "Turn off all LED activity"); | ||
89 | |||
90 | static char modparam_fwpostfix[16]; | 86 | static char modparam_fwpostfix[16]; |
91 | module_param_string(fwpostfix, modparam_fwpostfix, 16, 0444); | 87 | module_param_string(fwpostfix, modparam_fwpostfix, 16, 0444); |
92 | MODULE_PARM_DESC(fwpostfix, "Postfix for the firmware files to load."); | 88 | MODULE_PARM_DESC(fwpostfix, "Postfix for the firmware files to load."); |
@@ -1217,7 +1213,6 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev) | |||
1217 | u32 dma_reason[ARRAY_SIZE(dev->dma_reason)]; | 1213 | u32 dma_reason[ARRAY_SIZE(dev->dma_reason)]; |
1218 | u32 merged_dma_reason = 0; | 1214 | u32 merged_dma_reason = 0; |
1219 | int i; | 1215 | int i; |
1220 | int activity = 0; | ||
1221 | unsigned long flags; | 1216 | unsigned long flags; |
1222 | 1217 | ||
1223 | spin_lock_irqsave(&dev->wl->irq_lock, flags); | 1218 | spin_lock_irqsave(&dev->wl->irq_lock, flags); |
@@ -1281,7 +1276,6 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev) | |||
1281 | b43legacy_pio_rx(dev->pio.queue0); | 1276 | b43legacy_pio_rx(dev->pio.queue0); |
1282 | else | 1277 | else |
1283 | b43legacy_dma_rx(dev->dma.rx_ring0); | 1278 | b43legacy_dma_rx(dev->dma.rx_ring0); |
1284 | /* We intentionally don't set "activity" to 1, here. */ | ||
1285 | } | 1279 | } |
1286 | B43legacy_WARN_ON(dma_reason[1] & B43legacy_DMAIRQ_RX_DONE); | 1280 | B43legacy_WARN_ON(dma_reason[1] & B43legacy_DMAIRQ_RX_DONE); |
1287 | B43legacy_WARN_ON(dma_reason[2] & B43legacy_DMAIRQ_RX_DONE); | 1281 | B43legacy_WARN_ON(dma_reason[2] & B43legacy_DMAIRQ_RX_DONE); |
@@ -1290,20 +1284,13 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev) | |||
1290 | b43legacy_pio_rx(dev->pio.queue3); | 1284 | b43legacy_pio_rx(dev->pio.queue3); |
1291 | else | 1285 | else |
1292 | b43legacy_dma_rx(dev->dma.rx_ring3); | 1286 | b43legacy_dma_rx(dev->dma.rx_ring3); |
1293 | activity = 1; | ||
1294 | } | 1287 | } |
1295 | B43legacy_WARN_ON(dma_reason[4] & B43legacy_DMAIRQ_RX_DONE); | 1288 | B43legacy_WARN_ON(dma_reason[4] & B43legacy_DMAIRQ_RX_DONE); |
1296 | B43legacy_WARN_ON(dma_reason[5] & B43legacy_DMAIRQ_RX_DONE); | 1289 | B43legacy_WARN_ON(dma_reason[5] & B43legacy_DMAIRQ_RX_DONE); |
1297 | 1290 | ||
1298 | if (reason & B43legacy_IRQ_TX_OK) { | 1291 | if (reason & B43legacy_IRQ_TX_OK) |
1299 | handle_irq_transmit_status(dev); | 1292 | handle_irq_transmit_status(dev); |
1300 | activity = 1; | ||
1301 | /* TODO: In AP mode, this also causes sending of powersave | ||
1302 | responses. */ | ||
1303 | } | ||
1304 | 1293 | ||
1305 | if (!modparam_noleds) | ||
1306 | b43legacy_leds_update(dev, activity); | ||
1307 | b43legacy_interrupt_enable(dev, dev->irq_savedstate); | 1294 | b43legacy_interrupt_enable(dev, dev->irq_savedstate); |
1308 | mmiowb(); | 1295 | mmiowb(); |
1309 | spin_unlock_irqrestore(&dev->wl->irq_lock, flags); | 1296 | spin_unlock_irqrestore(&dev->wl->irq_lock, flags); |
@@ -1755,7 +1742,6 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev) | |||
1755 | B43legacy_MMIO_STATUS_BITFIELD) | 1742 | B43legacy_MMIO_STATUS_BITFIELD) |
1756 | & 0xFFFF3FFF); | 1743 | & 0xFFFF3FFF); |
1757 | 1744 | ||
1758 | b43legacy_leds_switch_all(dev, 0); | ||
1759 | b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK, | 1745 | b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK, |
1760 | b43legacy_read16(dev, | 1746 | b43legacy_read16(dev, |
1761 | B43legacy_MMIO_GPIO_MASK) | 1747 | B43legacy_MMIO_GPIO_MASK) |
@@ -2008,8 +1994,7 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | |||
2008 | static void b43legacy_chip_exit(struct b43legacy_wldev *dev) | 1994 | static void b43legacy_chip_exit(struct b43legacy_wldev *dev) |
2009 | { | 1995 | { |
2010 | b43legacy_radio_turn_off(dev); | 1996 | b43legacy_radio_turn_off(dev); |
2011 | if (!modparam_noleds) | 1997 | b43legacy_leds_exit(dev); |
2012 | b43legacy_leds_exit(dev); | ||
2013 | b43legacy_gpio_cleanup(dev); | 1998 | b43legacy_gpio_cleanup(dev); |
2014 | /* firmware is released later */ | 1999 | /* firmware is released later */ |
2015 | } | 2000 | } |
@@ -2039,9 +2024,11 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) | |||
2039 | err = b43legacy_gpio_init(dev); | 2024 | err = b43legacy_gpio_init(dev); |
2040 | if (err) | 2025 | if (err) |
2041 | goto out; /* firmware is released later */ | 2026 | goto out; /* firmware is released later */ |
2027 | b43legacy_leds_init(dev); | ||
2028 | |||
2042 | err = b43legacy_upload_initvals(dev); | 2029 | err = b43legacy_upload_initvals(dev); |
2043 | if (err) | 2030 | if (err) |
2044 | goto err_gpio_cleanup; | 2031 | goto err_leds_exit; |
2045 | b43legacy_radio_turn_on(dev); | 2032 | b43legacy_radio_turn_on(dev); |
2046 | 2033 | ||
2047 | b43legacy_write16(dev, 0x03E6, 0x0000); | 2034 | b43legacy_write16(dev, 0x03E6, 0x0000); |
@@ -2120,7 +2107,8 @@ out: | |||
2120 | 2107 | ||
2121 | err_radio_off: | 2108 | err_radio_off: |
2122 | b43legacy_radio_turn_off(dev); | 2109 | b43legacy_radio_turn_off(dev); |
2123 | err_gpio_cleanup: | 2110 | err_leds_exit: |
2111 | b43legacy_leds_exit(dev); | ||
2124 | b43legacy_gpio_cleanup(dev); | 2112 | b43legacy_gpio_cleanup(dev); |
2125 | goto out; | 2113 | goto out; |
2126 | } | 2114 | } |
@@ -2168,7 +2156,6 @@ static void b43legacy_periodic_every1sec(struct b43legacy_wldev *dev) | |||
2168 | dev->radio_hw_enable = radio_hw_enable; | 2156 | dev->radio_hw_enable = radio_hw_enable; |
2169 | b43legacyinfo(dev->wl, "Radio hardware status changed to %s\n", | 2157 | b43legacyinfo(dev->wl, "Radio hardware status changed to %s\n", |
2170 | (radio_hw_enable) ? "enabled" : "disabled"); | 2158 | (radio_hw_enable) ? "enabled" : "disabled"); |
2171 | b43legacy_leds_update(dev, 0); | ||
2172 | } | 2159 | } |
2173 | } | 2160 | } |
2174 | 2161 | ||
@@ -3498,18 +3485,13 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev) | |||
3498 | else | 3485 | else |
3499 | have_bphy = 1; | 3486 | have_bphy = 1; |
3500 | 3487 | ||
3501 | /* Initialize LEDs structs. */ | ||
3502 | err = b43legacy_leds_init(dev); | ||
3503 | if (err) | ||
3504 | goto err_powerdown; | ||
3505 | |||
3506 | dev->phy.gmode = (have_gphy || have_bphy); | 3488 | dev->phy.gmode = (have_gphy || have_bphy); |
3507 | tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0; | 3489 | tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0; |
3508 | b43legacy_wireless_core_reset(dev, tmp); | 3490 | b43legacy_wireless_core_reset(dev, tmp); |
3509 | 3491 | ||
3510 | err = b43legacy_phy_versioning(dev); | 3492 | err = b43legacy_phy_versioning(dev); |
3511 | if (err) | 3493 | if (err) |
3512 | goto err_leds_exit; | 3494 | goto err_powerdown; |
3513 | /* Check if this device supports multiband. */ | 3495 | /* Check if this device supports multiband. */ |
3514 | if (!pdev || | 3496 | if (!pdev || |
3515 | (pdev->device != 0x4312 && | 3497 | (pdev->device != 0x4312 && |
@@ -3535,10 +3517,10 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev) | |||
3535 | 3517 | ||
3536 | err = b43legacy_validate_chipaccess(dev); | 3518 | err = b43legacy_validate_chipaccess(dev); |
3537 | if (err) | 3519 | if (err) |
3538 | goto err_leds_exit; | 3520 | goto err_powerdown; |
3539 | err = b43legacy_setup_modes(dev, have_bphy, have_gphy); | 3521 | err = b43legacy_setup_modes(dev, have_bphy, have_gphy); |
3540 | if (err) | 3522 | if (err) |
3541 | goto err_leds_exit; | 3523 | goto err_powerdown; |
3542 | 3524 | ||
3543 | /* Now set some default "current_dev" */ | 3525 | /* Now set some default "current_dev" */ |
3544 | if (!wl->current_dev) | 3526 | if (!wl->current_dev) |
@@ -3553,8 +3535,6 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev) | |||
3553 | out: | 3535 | out: |
3554 | return err; | 3536 | return err; |
3555 | 3537 | ||
3556 | err_leds_exit: | ||
3557 | b43legacy_leds_exit(dev); | ||
3558 | err_powerdown: | 3538 | err_powerdown: |
3559 | ssb_bus_may_powerdown(bus); | 3539 | ssb_bus_may_powerdown(bus); |
3560 | return err; | 3540 | return err; |
diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c index a361dee664af..34cb0d801ce1 100644 --- a/drivers/net/wireless/b43legacy/radio.c +++ b/drivers/net/wireless/b43legacy/radio.c | |||
@@ -2113,7 +2113,6 @@ void b43legacy_radio_turn_on(struct b43legacy_wldev *dev) | |||
2113 | B43legacy_BUG_ON(1); | 2113 | B43legacy_BUG_ON(1); |
2114 | } | 2114 | } |
2115 | phy->radio_on = 1; | 2115 | phy->radio_on = 1; |
2116 | b43legacy_leds_update(dev, 0); | ||
2117 | } | 2116 | } |
2118 | 2117 | ||
2119 | void b43legacy_radio_turn_off(struct b43legacy_wldev *dev) | 2118 | void b43legacy_radio_turn_off(struct b43legacy_wldev *dev) |
@@ -2135,7 +2134,6 @@ void b43legacy_radio_turn_off(struct b43legacy_wldev *dev) | |||
2135 | b43legacy_phy_write(dev, 0x0015, 0xAA00); | 2134 | b43legacy_phy_write(dev, 0x0015, 0xAA00); |
2136 | phy->radio_on = 0; | 2135 | phy->radio_on = 0; |
2137 | b43legacydbg(dev->wl, "Radio initialized\n"); | 2136 | b43legacydbg(dev->wl, "Radio initialized\n"); |
2138 | b43legacy_leds_update(dev, 0); | ||
2139 | } | 2137 | } |
2140 | 2138 | ||
2141 | void b43legacy_radio_clear_tssi(struct b43legacy_wldev *dev) | 2139 | void b43legacy_radio_clear_tssi(struct b43legacy_wldev *dev) |