Skip to content

Commit 3a07887

Browse files
bcopelandlinvjw
authored andcommitted
ath5k: convert LED code to use mac80211 triggers
This change cleans up the ath5k LED code and converts it to use the standard LED device class along with the rx/tx LED triggers provided by mac80211. Signed-off-by: Bob Copeland <[email protected]> Signed-off-by: John W. Linville <[email protected]>
1 parent ffd7891 commit 3a07887

File tree

3 files changed

+132
-154
lines changed

3 files changed

+132
-154
lines changed

drivers/net/wireless/ath5k/Kconfig

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
config ATH5K
22
tristate "Atheros 5xxx wireless cards support"
33
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
4+
select MAC80211_LEDS
5+
select LEDS_CLASS
6+
select NEW_LEDS
47
---help---
58
This module adds support for wireless adapters based on
69
Atheros 5xxx chipset.

drivers/net/wireless/ath5k/base.c

+111-140
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,6 @@
5858
#include "reg.h"
5959
#include "debug.h"
6060

61-
enum {
62-
ATH_LED_TX,
63-
ATH_LED_RX,
64-
};
65-
6661
static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
6762

6863

@@ -309,13 +304,10 @@ static void ath5k_tasklet_reset(unsigned long data);
309304

310305
static void ath5k_calibrate(unsigned long data);
311306
/* LED functions */
312-
static void ath5k_led_off(unsigned long data);
313-
static void ath5k_led_blink(struct ath5k_softc *sc,
314-
unsigned int on,
315-
unsigned int off);
316-
static void ath5k_led_event(struct ath5k_softc *sc,
317-
int event);
318-
307+
static int ath5k_init_leds(struct ath5k_softc *sc);
308+
static void ath5k_led_enable(struct ath5k_softc *sc);
309+
static void ath5k_led_off(struct ath5k_softc *sc);
310+
static void ath5k_unregister_leds(struct ath5k_softc *sc);
319311

320312
/*
321313
* Module init/exit functions
@@ -596,8 +588,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
596588
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
597589
struct ath5k_softc *sc = hw->priv;
598590

599-
if (test_bit(ATH_STAT_LEDSOFT, sc->status))
600-
ath5k_hw_set_gpio(sc->ah, sc->led_pin, 1);
591+
ath5k_led_off(sc);
601592

602593
ath5k_stop_hw(sc);
603594
pci_save_state(pdev);
@@ -632,10 +623,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
632623
pci_write_config_byte(pdev, 0x41, 0);
633624

634625
ath5k_init(sc);
635-
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
636-
ath5k_hw_set_gpio_output(ah, sc->led_pin);
637-
ath5k_hw_set_gpio(ah, sc->led_pin, 0);
638-
}
626+
ath5k_led_enable(sc);
639627

640628
/*
641629
* Reset the key cache since some parts do not
@@ -742,27 +730,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
742730
tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
743731
tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
744732
setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
745-
setup_timer(&sc->led_tim, ath5k_led_off, (unsigned long)sc);
746-
747-
sc->led_on = 0; /* low true */
748-
/*
749-
* Auto-enable soft led processing for IBM cards and for
750-
* 5211 minipci cards.
751-
*/
752-
if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
753-
pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
754-
__set_bit(ATH_STAT_LEDSOFT, sc->status);
755-
sc->led_pin = 0;
756-
}
757-
/* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
758-
if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
759-
__set_bit(ATH_STAT_LEDSOFT, sc->status);
760-
sc->led_pin = 0;
761-
}
762-
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
763-
ath5k_hw_set_gpio_output(ah, sc->led_pin);
764-
ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on);
765-
}
766733

767734
ath5k_hw_get_lladdr(ah, mac);
768735
SET_IEEE80211_PERM_ADDR(hw, mac);
@@ -776,6 +743,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
776743
goto err_queues;
777744
}
778745

746+
ath5k_init_leds(sc);
747+
779748
return 0;
780749
err_queues:
781750
ath5k_txq_release(sc);
@@ -809,6 +778,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
809778
ath5k_desc_free(sc, pdev);
810779
ath5k_txq_release(sc);
811780
ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
781+
ath5k_unregister_leds(sc);
812782

813783
/*
814784
* NB: can't reclaim these until after ieee80211_ifdetach
@@ -1060,65 +1030,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
10601030
return 0;
10611031
}
10621032

1063-
/*
1064-
* TODO: CLEAN THIS !!!
1065-
*/
10661033
static void
10671034
ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
10681035
{
1069-
if (unlikely(test_bit(ATH_STAT_LEDSOFT, sc->status))) {
1070-
/* from Atheros NDIS driver, w/ permission */
1071-
static const struct {
1072-
u16 rate; /* tx/rx 802.11 rate */
1073-
u16 timeOn; /* LED on time (ms) */
1074-
u16 timeOff; /* LED off time (ms) */
1075-
} blinkrates[] = {
1076-
{ 108, 40, 10 },
1077-
{ 96, 44, 11 },
1078-
{ 72, 50, 13 },
1079-
{ 48, 57, 14 },
1080-
{ 36, 67, 16 },
1081-
{ 24, 80, 20 },
1082-
{ 22, 100, 25 },
1083-
{ 18, 133, 34 },
1084-
{ 12, 160, 40 },
1085-
{ 10, 200, 50 },
1086-
{ 6, 240, 58 },
1087-
{ 4, 267, 66 },
1088-
{ 2, 400, 100 },
1089-
{ 0, 500, 130 }
1090-
};
1091-
const struct ath5k_rate_table *rt =
1092-
ath5k_hw_get_rate_table(sc->ah, mode);
1093-
unsigned int i, j;
1094-
1095-
BUG_ON(rt == NULL);
1096-
1097-
memset(sc->hwmap, 0, sizeof(sc->hwmap));
1098-
for (i = 0; i < 32; i++) {
1099-
u8 ix = rt->rate_code_to_index[i];
1100-
if (ix == 0xff) {
1101-
sc->hwmap[i].ledon = msecs_to_jiffies(500);
1102-
sc->hwmap[i].ledoff = msecs_to_jiffies(130);
1103-
continue;
1104-
}
1105-
sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD;
1106-
/* receive frames include FCS */
1107-
sc->hwmap[i].rxflags = sc->hwmap[i].txflags |
1108-
IEEE80211_RADIOTAP_F_FCS;
1109-
/* setup blink rate table to avoid per-packet lookup */
1110-
for (j = 0; j < ARRAY_SIZE(blinkrates) - 1; j++)
1111-
if (blinkrates[j].rate == /* XXX why 7f? */
1112-
(rt->rates[ix].dot11_rate&0x7f))
1113-
break;
1114-
1115-
sc->hwmap[i].ledon = msecs_to_jiffies(blinkrates[j].
1116-
timeOn);
1117-
sc->hwmap[i].ledoff = msecs_to_jiffies(blinkrates[j].
1118-
timeOff);
1119-
}
1120-
}
1121-
11221036
sc->curmode = mode;
11231037

11241038
if (mode == AR5K_MODE_11A) {
@@ -1900,8 +1814,6 @@ ath5k_tasklet_rx(unsigned long data)
19001814
ath5k_check_ibss_tsf(sc, skb, &rxs);
19011815

19021816
__ieee80211_rx(sc->hw, skb, &rxs);
1903-
sc->led_rxrate = rs.rs_rate;
1904-
ath5k_led_event(sc, ATH_LED_RX);
19051817
next:
19061818
list_move_tail(&bf->list, &sc->rxbuf);
19071819
} while (ath5k_rxbuf_setup(sc, bf) == 0);
@@ -1982,13 +1894,9 @@ ath5k_tasklet_tx(unsigned long data)
19821894
struct ath5k_softc *sc = (void *)data;
19831895

19841896
ath5k_tx_processq(sc, sc->txq);
1985-
1986-
ath5k_led_event(sc, ATH_LED_TX);
19871897
}
19881898

19891899

1990-
1991-
19921900
/*****************\
19931901
* Beacon handling *
19941902
\*****************/
@@ -2363,11 +2271,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
23632271
ieee80211_stop_queues(sc->hw);
23642272

23652273
if (!test_bit(ATH_STAT_INVALID, sc->status)) {
2366-
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
2367-
del_timer_sync(&sc->led_tim);
2368-
ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on);
2369-
__clear_bit(ATH_STAT_LEDBLINKING, sc->status);
2370-
}
2274+
ath5k_led_off(sc);
23712275
ath5k_hw_set_intr(ah, 0);
23722276
}
23732277
ath5k_txq_cleanup(sc);
@@ -2563,54 +2467,123 @@ ath5k_calibrate(unsigned long data)
25632467
\***************/
25642468

25652469
static void
2566-
ath5k_led_off(unsigned long data)
2470+
ath5k_led_enable(struct ath5k_softc *sc)
25672471
{
2568-
struct ath5k_softc *sc = (void *)data;
2569-
2570-
if (test_bit(ATH_STAT_LEDENDBLINK, sc->status))
2571-
__clear_bit(ATH_STAT_LEDBLINKING, sc->status);
2572-
else {
2573-
__set_bit(ATH_STAT_LEDENDBLINK, sc->status);
2574-
ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
2575-
mod_timer(&sc->led_tim, jiffies + sc->led_off);
2472+
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
2473+
ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
2474+
ath5k_led_off(sc);
25762475
}
25772476
}
25782477

2579-
/*
2580-
* Blink the LED according to the specified on/off times.
2581-
*/
25822478
static void
2583-
ath5k_led_blink(struct ath5k_softc *sc, unsigned int on,
2584-
unsigned int off)
2479+
ath5k_led_on(struct ath5k_softc *sc)
25852480
{
2586-
ATH5K_DBG(sc, ATH5K_DEBUG_LED, "on %u off %u\n", on, off);
2481+
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
2482+
return;
25872483
ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
2588-
__set_bit(ATH_STAT_LEDBLINKING, sc->status);
2589-
__clear_bit(ATH_STAT_LEDENDBLINK, sc->status);
2590-
sc->led_off = off;
2591-
mod_timer(&sc->led_tim, jiffies + on);
25922484
}
25932485

25942486
static void
2595-
ath5k_led_event(struct ath5k_softc *sc, int event)
2487+
ath5k_led_off(struct ath5k_softc *sc)
25962488
{
2597-
if (likely(!test_bit(ATH_STAT_LEDSOFT, sc->status)))
2489+
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
25982490
return;
2599-
if (unlikely(test_bit(ATH_STAT_LEDBLINKING, sc->status)))
2600-
return; /* don't interrupt active blink */
2601-
switch (event) {
2602-
case ATH_LED_TX:
2603-
ath5k_led_blink(sc, sc->hwmap[sc->led_txrate].ledon,
2604-
sc->hwmap[sc->led_txrate].ledoff);
2605-
break;
2606-
case ATH_LED_RX:
2607-
ath5k_led_blink(sc, sc->hwmap[sc->led_rxrate].ledon,
2608-
sc->hwmap[sc->led_rxrate].ledoff);
2609-
break;
2491+
ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
2492+
}
2493+
2494+
static void
2495+
ath5k_led_brightness_set(struct led_classdev *led_dev,
2496+
enum led_brightness brightness)
2497+
{
2498+
struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
2499+
led_dev);
2500+
2501+
if (brightness == LED_OFF)
2502+
ath5k_led_off(led->sc);
2503+
else
2504+
ath5k_led_on(led->sc);
2505+
}
2506+
2507+
static int
2508+
ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
2509+
const char *name, char *trigger)
2510+
{
2511+
int err;
2512+
2513+
led->sc = sc;
2514+
strncpy(led->name, name, sizeof(led->name));
2515+
led->led_dev.name = led->name;
2516+
led->led_dev.default_trigger = trigger;
2517+
led->led_dev.brightness_set = ath5k_led_brightness_set;
2518+
2519+
err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
2520+
if (err)
2521+
{
2522+
ATH5K_WARN(sc, "could not register LED %s\n", name);
2523+
led->sc = NULL;
26102524
}
2525+
return err;
2526+
}
2527+
2528+
static void
2529+
ath5k_unregister_led(struct ath5k_led *led)
2530+
{
2531+
if (!led->sc)
2532+
return;
2533+
led_classdev_unregister(&led->led_dev);
2534+
ath5k_led_off(led->sc);
2535+
led->sc = NULL;
2536+
}
2537+
2538+
static void
2539+
ath5k_unregister_leds(struct ath5k_softc *sc)
2540+
{
2541+
ath5k_unregister_led(&sc->rx_led);
2542+
ath5k_unregister_led(&sc->tx_led);
26112543
}
26122544

26132545

2546+
static int
2547+
ath5k_init_leds(struct ath5k_softc *sc)
2548+
{
2549+
int ret = 0;
2550+
struct ieee80211_hw *hw = sc->hw;
2551+
struct pci_dev *pdev = sc->pdev;
2552+
char name[ATH5K_LED_MAX_NAME_LEN + 1];
2553+
2554+
sc->led_on = 0; /* active low */
2555+
2556+
/*
2557+
* Auto-enable soft led processing for IBM cards and for
2558+
* 5211 minipci cards.
2559+
*/
2560+
if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
2561+
pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
2562+
__set_bit(ATH_STAT_LEDSOFT, sc->status);
2563+
sc->led_pin = 0;
2564+
}
2565+
/* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
2566+
if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
2567+
__set_bit(ATH_STAT_LEDSOFT, sc->status);
2568+
sc->led_pin = 1;
2569+
}
2570+
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
2571+
goto out;
2572+
2573+
ath5k_led_enable(sc);
2574+
2575+
snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
2576+
ret = ath5k_register_led(sc, &sc->rx_led, name,
2577+
ieee80211_get_rx_led_name(hw));
2578+
if (ret)
2579+
goto out;
2580+
2581+
snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
2582+
ret = ath5k_register_led(sc, &sc->tx_led, name,
2583+
ieee80211_get_tx_led_name(hw));
2584+
out:
2585+
return ret;
2586+
}
26142587

26152588

26162589
/********************\
@@ -2648,8 +2621,6 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
26482621
memmove(skb->data, skb->data+pad, hdrlen);
26492622
}
26502623

2651-
sc->led_txrate = ieee80211_get_tx_rate(hw, info)->hw_value;
2652-
26532624
spin_lock_irqsave(&sc->txbuflock, flags);
26542625
if (list_empty(&sc->txbuf)) {
26552626
ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");

0 commit comments

Comments
 (0)