3 Broadcom B43 wireless driver
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mb@bu3sch.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; see the file COPYING. If not, write to
23 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
24 Boston, MA 02110-1301, USA.
32 static void b43_led_changestate(struct b43_led
*led
)
34 struct b43_wldev
*dev
= led
->dev
;
35 const int index
= b43_led_index(led
);
36 const u16 mask
= (1 << index
);
39 B43_WARN_ON(!(index
>= 0 && index
< B43_NR_LEDS
));
40 B43_WARN_ON(!led
->blink_interval
);
41 ledctl
= b43_read16(dev
, B43_MMIO_GPIO_CONTROL
);
42 ledctl
= (ledctl
& mask
) ? (ledctl
& ~mask
) : (ledctl
| mask
);
43 b43_write16(dev
, B43_MMIO_GPIO_CONTROL
, ledctl
);
46 static void b43_led_blink(unsigned long d
)
48 struct b43_led
*led
= (struct b43_led
*)d
;
49 struct b43_wldev
*dev
= led
->dev
;
52 spin_lock_irqsave(&dev
->wl
->leds_lock
, flags
);
53 if (led
->blink_interval
) {
54 b43_led_changestate(led
);
55 mod_timer(&led
->blink_timer
, jiffies
+ led
->blink_interval
);
57 spin_unlock_irqrestore(&dev
->wl
->leds_lock
, flags
);
60 static void b43_led_blink_start(struct b43_led
*led
, unsigned long interval
)
62 if (led
->blink_interval
)
64 led
->blink_interval
= interval
;
65 b43_led_changestate(led
);
66 led
->blink_timer
.expires
= jiffies
+ interval
;
67 add_timer(&led
->blink_timer
);
70 static void b43_led_blink_stop(struct b43_led
*led
, int sync
)
72 struct b43_wldev
*dev
= led
->dev
;
73 const int index
= b43_led_index(led
);
76 if (!led
->blink_interval
)
79 del_timer_sync(&led
->blink_timer
);
81 del_timer(&led
->blink_timer
);
82 led
->blink_interval
= 0;
84 /* Make sure the LED is turned off. */
85 B43_WARN_ON(!(index
>= 0 && index
< B43_NR_LEDS
));
86 ledctl
= b43_read16(dev
, B43_MMIO_GPIO_CONTROL
);
88 ledctl
|= (1 << index
);
90 ledctl
&= ~(1 << index
);
91 b43_write16(dev
, B43_MMIO_GPIO_CONTROL
, ledctl
);
94 static void b43_led_init_hardcoded(struct b43_wldev
*dev
,
95 struct b43_led
*led
, int led_index
)
97 struct ssb_bus
*bus
= dev
->dev
->bus
;
99 /* This function is called, if the behaviour (and activelow)
100 * information for a LED is missing in the SPROM.
101 * We hardcode the behaviour values for various devices here.
102 * Note that the B43_LED_TEST_XXX behaviour values can
103 * be used to figure out which led is mapped to which index.
108 led
->behaviour
= B43_LED_ACTIVITY
;
110 if (bus
->boardinfo
.vendor
== PCI_VENDOR_ID_COMPAQ
)
111 led
->behaviour
= B43_LED_RADIO_ALL
;
114 led
->behaviour
= B43_LED_RADIO_B
;
115 if (bus
->boardinfo
.vendor
== PCI_VENDOR_ID_ASUSTEK
)
116 led
->behaviour
= B43_LED_ASSOC
;
119 led
->behaviour
= B43_LED_RADIO_A
;
122 led
->behaviour
= B43_LED_OFF
;
129 int b43_leds_init(struct b43_wldev
*dev
)
135 sprom
[0] = dev
->dev
->bus
->sprom
.r1
.gpio0
;
136 sprom
[1] = dev
->dev
->bus
->sprom
.r1
.gpio1
;
137 sprom
[2] = dev
->dev
->bus
->sprom
.r1
.gpio2
;
138 sprom
[3] = dev
->dev
->bus
->sprom
.r1
.gpio3
;
140 for (i
= 0; i
< B43_NR_LEDS
; i
++) {
141 led
= &(dev
->leds
[i
]);
143 setup_timer(&led
->blink_timer
,
144 b43_led_blink
, (unsigned long)led
);
146 if (sprom
[i
] == 0xFF) {
147 b43_led_init_hardcoded(dev
, led
, i
);
149 led
->behaviour
= sprom
[i
] & B43_LED_BEHAVIOUR
;
150 led
->activelow
= !!(sprom
[i
] & B43_LED_ACTIVELOW
);
157 void b43_leds_exit(struct b43_wldev
*dev
)
162 for (i
= 0; i
< B43_NR_LEDS
; i
++) {
163 led
= &(dev
->leds
[i
]);
164 b43_led_blink_stop(led
, 1);
166 b43_leds_switch_all(dev
, 0);
169 void b43_leds_update(struct b43_wldev
*dev
, int activity
)
172 struct b43_phy
*phy
= &dev
->phy
;
173 const int transferring
=
174 (jiffies
- dev
->stats
.last_tx
) < B43_LED_XFER_THRES
;
176 unsigned long interval
= 0;
180 spin_lock_irqsave(&dev
->wl
->leds_lock
, flags
);
181 ledctl
= b43_read16(dev
, B43_MMIO_GPIO_CONTROL
);
182 for (i
= 0; i
< B43_NR_LEDS
; i
++) {
183 led
= &(dev
->leds
[i
]);
186 switch (led
->behaviour
) {
187 case B43_LED_INACTIVE
:
194 case B43_LED_ACTIVITY
:
197 case B43_LED_RADIO_ALL
:
198 turn_on
= phy
->radio_on
&& b43_is_hw_radio_enabled(dev
);
200 case B43_LED_RADIO_A
:
201 turn_on
= (phy
->radio_on
&& b43_is_hw_radio_enabled(dev
)
202 && phy
->type
== B43_PHYTYPE_A
);
204 case B43_LED_RADIO_B
:
205 turn_on
= (phy
->radio_on
&& b43_is_hw_radio_enabled(dev
)
206 && (phy
->type
== B43_PHYTYPE_B
207 || phy
->type
== B43_PHYTYPE_G
));
209 case B43_LED_MODE_BG
:
210 if (phy
->type
== B43_PHYTYPE_G
211 && b43_is_hw_radio_enabled(dev
)
212 && 1 /*FIXME: using G rates. */ )
215 case B43_LED_TRANSFER
:
217 b43_led_blink_start(led
, B43_LEDBLINK_MEDIUM
);
219 b43_led_blink_stop(led
, 0);
221 case B43_LED_APTRANSFER
:
222 if (b43_is_mode(dev
->wl
, IEEE80211_IF_TYPE_AP
)) {
224 interval
= B43_LEDBLINK_FAST
;
229 if (0 /*TODO: not assoc */ )
230 interval
= B43_LEDBLINK_SLOW
;
231 else if (transferring
)
232 interval
= B43_LEDBLINK_FAST
;
237 b43_led_blink_start(led
, interval
);
239 b43_led_blink_stop(led
, 0);
245 if (1 /*dev->softmac->associated */ )
248 #ifdef CONFIG_B43_DEBUG
249 case B43_LED_TEST_BLINKSLOW
:
250 b43_led_blink_start(led
, B43_LEDBLINK_SLOW
);
252 case B43_LED_TEST_BLINKMEDIUM
:
253 b43_led_blink_start(led
, B43_LEDBLINK_MEDIUM
);
255 case B43_LED_TEST_BLINKFAST
:
256 b43_led_blink_start(led
, B43_LEDBLINK_FAST
);
258 #endif /* CONFIG_B43_DEBUG */
270 b43_write16(dev
, B43_MMIO_GPIO_CONTROL
, ledctl
);
271 spin_unlock_irqrestore(&dev
->wl
->leds_lock
, flags
);
274 void b43_leds_switch_all(struct b43_wldev
*dev
, int on
)
282 spin_lock_irqsave(&dev
->wl
->leds_lock
, flags
);
283 ledctl
= b43_read16(dev
, B43_MMIO_GPIO_CONTROL
);
284 for (i
= 0; i
< B43_NR_LEDS
; i
++) {
285 led
= &(dev
->leds
[i
]);
286 if (led
->behaviour
== B43_LED_INACTIVE
)
289 bit_on
= led
->activelow
? 0 : 1;
291 bit_on
= led
->activelow
? 1 : 0;
297 b43_write16(dev
, B43_MMIO_GPIO_CONTROL
, ledctl
);
298 spin_unlock_irqrestore(&dev
->wl
->leds_lock
, flags
);
This page took 0.039148 seconds and 5 git commands to generate.