aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.c88
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.h11
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c2
3 files changed, 68 insertions, 33 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
index 455a0c743f73..8f550c1a92ed 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
@@ -35,12 +35,13 @@ static void bcm43xx_led_changestate(struct bcm43xx_led *led)
35{ 35{
36 struct bcm43xx_private *bcm = led->bcm; 36 struct bcm43xx_private *bcm = led->bcm;
37 const int index = bcm43xx_led_index(led); 37 const int index = bcm43xx_led_index(led);
38 const u16 mask = (1 << index);
38 u16 ledctl; 39 u16 ledctl;
39 40
40 assert(index >= 0 && index < BCM43xx_NR_LEDS); 41 assert(index >= 0 && index < BCM43xx_NR_LEDS);
41 assert(led->blink_interval); 42 assert(led->blink_interval);
42 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); 43 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
43 __change_bit(index, (unsigned long *)(&ledctl)); 44 ledctl = (ledctl & mask) ? (ledctl & ~mask) : (ledctl | mask);
44 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); 45 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
45} 46}
46 47
@@ -61,6 +62,8 @@ static void bcm43xx_led_blink(unsigned long d)
61static void bcm43xx_led_blink_start(struct bcm43xx_led *led, 62static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
62 unsigned long interval) 63 unsigned long interval)
63{ 64{
65 if (led->blink_interval)
66 return;
64 led->blink_interval = interval; 67 led->blink_interval = interval;
65 bcm43xx_led_changestate(led); 68 bcm43xx_led_changestate(led);
66 led->blink_timer.expires = jiffies + interval; 69 led->blink_timer.expires = jiffies + interval;
@@ -91,6 +94,39 @@ static void bcm43xx_led_blink_stop(struct bcm43xx_led *led, int sync)
91 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); 94 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
92} 95}
93 96
97static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm,
98 struct bcm43xx_led *led,
99 int led_index)
100{
101 /* This function is called, if the behaviour (and activelow)
102 * information for a LED is missing in the SPROM.
103 * We hardcode the behaviour values for various devices here.
104 * Note that the BCM43xx_LED_TEST_XXX behaviour values can
105 * be used to figure out which led is mapped to which index.
106 */
107
108 switch (led_index) {
109 case 0:
110 led->behaviour = BCM43xx_LED_ACTIVITY;
111 if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
112 led->behaviour = BCM43xx_LED_RADIO_ALL;
113 break;
114 case 1:
115 led->behaviour = BCM43xx_LED_RADIO_B;
116 if (bcm->board_vendor == PCI_VENDOR_ID_ASUSTEK)
117 led->behaviour = BCM43xx_LED_ASSOC;
118 break;
119 case 2:
120 led->behaviour = BCM43xx_LED_RADIO_A;
121 break;
122 case 3:
123 led->behaviour = BCM43xx_LED_OFF;
124 break;
125 default:
126 assert(0);
127 }
128}
129
94int bcm43xx_leds_init(struct bcm43xx_private *bcm) 130int bcm43xx_leds_init(struct bcm43xx_private *bcm)
95{ 131{
96 struct bcm43xx_led *led; 132 struct bcm43xx_led *led;
@@ -105,31 +141,12 @@ int bcm43xx_leds_init(struct bcm43xx_private *bcm)
105 for (i = 0; i < BCM43xx_NR_LEDS; i++) { 141 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
106 led = &(bcm->leds[i]); 142 led = &(bcm->leds[i]);
107 led->bcm = bcm; 143 led->bcm = bcm;
108 init_timer(&led->blink_timer); 144 setup_timer(&led->blink_timer,
109 led->blink_timer.data = (unsigned long)led; 145 bcm43xx_led_blink,
110 led->blink_timer.function = bcm43xx_led_blink; 146 (unsigned long)led);
111 147
112 if (sprom[i] == 0xFF) { 148 if (sprom[i] == 0xFF) {
113 /* SPROM information not set. */ 149 bcm43xx_led_init_hardcoded(bcm, led, i);
114 switch (i) {
115 case 0:
116 if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
117 led->behaviour = BCM43xx_LED_RADIO_ALL;
118 else
119 led->behaviour = BCM43xx_LED_ACTIVITY;
120 break;
121 case 1:
122 led->behaviour = BCM43xx_LED_RADIO_B;
123 break;
124 case 2:
125 led->behaviour = BCM43xx_LED_RADIO_A;
126 break;
127 case 3:
128 led->behaviour = BCM43xx_LED_OFF;
129 break;
130 default:
131 assert(0);
132 }
133 } else { 150 } else {
134 led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR; 151 led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR;
135 led->activelow = !!(sprom[i] & BCM43xx_LED_ACTIVELOW); 152 led->activelow = !!(sprom[i] & BCM43xx_LED_ACTIVELOW);
@@ -157,19 +174,19 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
157 struct bcm43xx_radioinfo *radio = bcm->current_core->radio; 174 struct bcm43xx_radioinfo *radio = bcm->current_core->radio;
158 struct bcm43xx_phyinfo *phy = bcm->current_core->phy; 175 struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
159 const int transferring = (jiffies - bcm->stats.last_tx) < BCM43xx_LED_XFER_THRES; 176 const int transferring = (jiffies - bcm->stats.last_tx) < BCM43xx_LED_XFER_THRES;
160 int i, turn_on = 0; 177 int i, turn_on;
161 unsigned long interval = 0; 178 unsigned long interval = 0;
162 u16 ledctl; 179 u16 ledctl;
163 180
164 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); 181 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
165 for (i = 0; i < BCM43xx_NR_LEDS; i++) { 182 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
166 led = &(bcm->leds[i]); 183 led = &(bcm->leds[i]);
167 if (led->behaviour == BCM43xx_LED_INACTIVE)
168 continue;
169 184
185 turn_on = 0;
170 switch (led->behaviour) { 186 switch (led->behaviour) {
187 case BCM43xx_LED_INACTIVE:
188 continue;
171 case BCM43xx_LED_OFF: 189 case BCM43xx_LED_OFF:
172 turn_on = 0;
173 break; 190 break;
174 case BCM43xx_LED_ON: 191 case BCM43xx_LED_ON:
175 turn_on = 1; 192 turn_on = 1;
@@ -189,7 +206,6 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
189 phy->type == BCM43xx_PHYTYPE_G)); 206 phy->type == BCM43xx_PHYTYPE_G));
190 break; 207 break;
191 case BCM43xx_LED_MODE_BG: 208 case BCM43xx_LED_MODE_BG:
192 turn_on = 0;
193 if (phy->type == BCM43xx_PHYTYPE_G && 209 if (phy->type == BCM43xx_PHYTYPE_G &&
194 1/*FIXME: using G rates.*/) 210 1/*FIXME: using G rates.*/)
195 turn_on = 1; 211 turn_on = 1;
@@ -222,12 +238,22 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
222 continue; 238 continue;
223 case BCM43xx_LED_WEIRD: 239 case BCM43xx_LED_WEIRD:
224 //TODO 240 //TODO
225 turn_on = 0;
226 break; 241 break;
227 case BCM43xx_LED_ASSOC: 242 case BCM43xx_LED_ASSOC:
228 if (1/*TODO: associated*/) 243 if (bcm->softmac->associated)
229 turn_on = 1; 244 turn_on = 1;
230 break; 245 break;
246#ifdef CONFIG_BCM43XX_DEBUG
247 case BCM43xx_LED_TEST_BLINKSLOW:
248 bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_SLOW);
249 continue;
250 case BCM43xx_LED_TEST_BLINKMEDIUM:
251 bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM);
252 continue;
253 case BCM43xx_LED_TEST_BLINKFAST:
254 bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_FAST);
255 continue;
256#endif /* CONFIG_BCM43XX_DEBUG */
231 default: 257 default:
232 assert(0); 258 assert(0);
233 }; 259 };
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
index 489a2b1e9068..6f18e2f95db4 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
@@ -16,7 +16,7 @@ struct bcm43xx_led {
16#define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds)) 16#define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds))
17 17
18/* Delay between state changes when blinking in jiffies */ 18/* Delay between state changes when blinking in jiffies */
19#define BCM43xx_LEDBLINK_SLOW (HZ / 2) 19#define BCM43xx_LEDBLINK_SLOW (HZ / 1)
20#define BCM43xx_LEDBLINK_MEDIUM (HZ / 4) 20#define BCM43xx_LEDBLINK_MEDIUM (HZ / 4)
21#define BCM43xx_LEDBLINK_FAST (HZ / 8) 21#define BCM43xx_LEDBLINK_FAST (HZ / 8)
22 22
@@ -37,6 +37,15 @@ enum { /* LED behaviour values */
37 BCM43xx_LED_WEIRD,//FIXME 37 BCM43xx_LED_WEIRD,//FIXME
38 BCM43xx_LED_ASSOC, 38 BCM43xx_LED_ASSOC,
39 BCM43xx_LED_INACTIVE, 39 BCM43xx_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 BCM43xx_LED_TEST_BLINKSLOW,
47 BCM43xx_LED_TEST_BLINKMEDIUM,
48 BCM43xx_LED_TEST_BLINKFAST,
40}; 49};
41 50
42int bcm43xx_leds_init(struct bcm43xx_private *bcm); 51int bcm43xx_leds_init(struct bcm43xx_private *bcm);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 4e49da99818d..fbf931d4a135 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -1943,7 +1943,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1943 bcm43xx_pio_rx(bcm->current_core->pio->queue0); 1943 bcm43xx_pio_rx(bcm->current_core->pio->queue0);
1944 else 1944 else
1945 bcm43xx_dma_rx(bcm->current_core->dma->rx_ring0); 1945 bcm43xx_dma_rx(bcm->current_core->dma->rx_ring0);
1946 activity = 1; 1946 /* We intentionally don't set "activity" to 1, here. */
1947 } 1947 }
1948 if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) { 1948 if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
1949 if (likely(bcm->current_core->rev < 5)) { 1949 if (likely(bcm->current_core->rev < 5)) {