diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-02-27 16:26:40 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-28 14:06:55 -0500 |
commit | 0cf55c21ec401632043db2b8acb7cd3bef64c9e6 (patch) | |
tree | 7ce7bf6ec5fd0b9e8588b464d192bf232c7cef51 /drivers/net/wireless/ath | |
parent | a5a7103fe18eb4312bd89c9f136fb850af58faf4 (diff) |
ath9k: use generic mac80211 LED blinking code
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 42 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/gpio.c | 164 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 3 |
4 files changed, 61 insertions, 170 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index f9f0389b92ab..367b51430ff0 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -449,26 +449,20 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); | |||
449 | 449 | ||
450 | #define ATH_LED_PIN_DEF 1 | 450 | #define ATH_LED_PIN_DEF 1 |
451 | #define ATH_LED_PIN_9287 8 | 451 | #define ATH_LED_PIN_9287 8 |
452 | #define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ | ||
453 | #define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */ | ||
454 | |||
455 | enum ath_led_type { | ||
456 | ATH_LED_RADIO, | ||
457 | ATH_LED_ASSOC, | ||
458 | ATH_LED_TX, | ||
459 | ATH_LED_RX | ||
460 | }; | ||
461 | |||
462 | struct ath_led { | ||
463 | struct ath_softc *sc; | ||
464 | struct led_classdev led_cdev; | ||
465 | enum ath_led_type led_type; | ||
466 | char name[32]; | ||
467 | bool registered; | ||
468 | }; | ||
469 | 452 | ||
453 | #ifdef CONFIG_MAC80211_LEDS | ||
470 | void ath_init_leds(struct ath_softc *sc); | 454 | void ath_init_leds(struct ath_softc *sc); |
471 | void ath_deinit_leds(struct ath_softc *sc); | 455 | void ath_deinit_leds(struct ath_softc *sc); |
456 | #else | ||
457 | static inline void ath_init_leds(struct ath_softc *sc) | ||
458 | { | ||
459 | } | ||
460 | |||
461 | static inline void ath_deinit_leds(struct ath_softc *sc) | ||
462 | { | ||
463 | } | ||
464 | #endif | ||
465 | |||
472 | 466 | ||
473 | /* Antenna diversity/combining */ | 467 | /* Antenna diversity/combining */ |
474 | #define ATH_ANT_RX_CURRENT_SHIFT 4 | 468 | #define ATH_ANT_RX_CURRENT_SHIFT 4 |
@@ -620,15 +614,11 @@ struct ath_softc { | |||
620 | struct ath_beacon beacon; | 614 | struct ath_beacon beacon; |
621 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | 615 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; |
622 | 616 | ||
623 | struct ath_led radio_led; | 617 | #ifdef CONFIG_MAC80211_LEDS |
624 | struct ath_led assoc_led; | 618 | bool led_registered; |
625 | struct ath_led tx_led; | 619 | char led_name[32]; |
626 | struct ath_led rx_led; | 620 | struct led_classdev led_cdev; |
627 | struct delayed_work ath_led_blink_work; | 621 | #endif |
628 | int led_on_duration; | ||
629 | int led_off_duration; | ||
630 | int led_on_cnt; | ||
631 | int led_off_cnt; | ||
632 | 622 | ||
633 | struct ath9k_hw_cal_data caldata; | 623 | struct ath9k_hw_cal_data caldata; |
634 | int last_rssi; | 624 | int last_rssi; |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index fb4f17a5183d..e369bf7e575f 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -20,117 +20,25 @@ | |||
20 | /* LED functions */ | 20 | /* LED functions */ |
21 | /********************************/ | 21 | /********************************/ |
22 | 22 | ||
23 | static void ath_led_blink_work(struct work_struct *work) | 23 | #ifdef CONFIG_MAC80211_LEDS |
24 | { | ||
25 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
26 | ath_led_blink_work.work); | ||
27 | |||
28 | if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED)) | ||
29 | return; | ||
30 | |||
31 | if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||
32 | (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||
33 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
34 | else | ||
35 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
36 | (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); | ||
37 | |||
38 | ieee80211_queue_delayed_work(sc->hw, | ||
39 | &sc->ath_led_blink_work, | ||
40 | (sc->sc_flags & SC_OP_LED_ON) ? | ||
41 | msecs_to_jiffies(sc->led_off_duration) : | ||
42 | msecs_to_jiffies(sc->led_on_duration)); | ||
43 | |||
44 | sc->led_on_duration = sc->led_on_cnt ? | ||
45 | max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : | ||
46 | ATH_LED_ON_DURATION_IDLE; | ||
47 | sc->led_off_duration = sc->led_off_cnt ? | ||
48 | max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) : | ||
49 | ATH_LED_OFF_DURATION_IDLE; | ||
50 | sc->led_on_cnt = sc->led_off_cnt = 0; | ||
51 | if (sc->sc_flags & SC_OP_LED_ON) | ||
52 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
53 | else | ||
54 | sc->sc_flags |= SC_OP_LED_ON; | ||
55 | } | ||
56 | |||
57 | static void ath_led_brightness(struct led_classdev *led_cdev, | 24 | static void ath_led_brightness(struct led_classdev *led_cdev, |
58 | enum led_brightness brightness) | 25 | enum led_brightness brightness) |
59 | { | 26 | { |
60 | struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | 27 | struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); |
61 | struct ath_softc *sc = led->sc; | 28 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF)); |
62 | |||
63 | switch (brightness) { | ||
64 | case LED_OFF: | ||
65 | if (led->led_type == ATH_LED_ASSOC || | ||
66 | led->led_type == ATH_LED_RADIO) { | ||
67 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
68 | (led->led_type == ATH_LED_RADIO)); | ||
69 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
70 | if (led->led_type == ATH_LED_RADIO) | ||
71 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
72 | } else { | ||
73 | sc->led_off_cnt++; | ||
74 | } | ||
75 | break; | ||
76 | case LED_FULL: | ||
77 | if (led->led_type == ATH_LED_ASSOC) { | ||
78 | sc->sc_flags |= SC_OP_LED_ASSOCIATED; | ||
79 | if (led_blink) | ||
80 | ieee80211_queue_delayed_work(sc->hw, | ||
81 | &sc->ath_led_blink_work, 0); | ||
82 | } else if (led->led_type == ATH_LED_RADIO) { | ||
83 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
84 | sc->sc_flags |= SC_OP_LED_ON; | ||
85 | } else { | ||
86 | sc->led_on_cnt++; | ||
87 | } | ||
88 | break; | ||
89 | default: | ||
90 | break; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | static int ath_register_led(struct ath_softc *sc, struct ath_led *led, | ||
95 | char *trigger) | ||
96 | { | ||
97 | int ret; | ||
98 | |||
99 | led->sc = sc; | ||
100 | led->led_cdev.name = led->name; | ||
101 | led->led_cdev.default_trigger = trigger; | ||
102 | led->led_cdev.brightness_set = ath_led_brightness; | ||
103 | |||
104 | ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); | ||
105 | if (ret) | ||
106 | ath_err(ath9k_hw_common(sc->sc_ah), | ||
107 | "Failed to register led:%s", led->name); | ||
108 | else | ||
109 | led->registered = 1; | ||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | static void ath_unregister_led(struct ath_led *led) | ||
114 | { | ||
115 | if (led->registered) { | ||
116 | led_classdev_unregister(&led->led_cdev); | ||
117 | led->registered = 0; | ||
118 | } | ||
119 | } | 29 | } |
120 | 30 | ||
121 | void ath_deinit_leds(struct ath_softc *sc) | 31 | void ath_deinit_leds(struct ath_softc *sc) |
122 | { | 32 | { |
123 | ath_unregister_led(&sc->assoc_led); | 33 | if (!sc->led_registered) |
124 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | 34 | return; |
125 | ath_unregister_led(&sc->tx_led); | 35 | |
126 | ath_unregister_led(&sc->rx_led); | 36 | ath_led_brightness(&sc->led_cdev, LED_OFF); |
127 | ath_unregister_led(&sc->radio_led); | 37 | led_classdev_unregister(&sc->led_cdev); |
128 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
129 | } | 38 | } |
130 | 39 | ||
131 | void ath_init_leds(struct ath_softc *sc) | 40 | void ath_init_leds(struct ath_softc *sc) |
132 | { | 41 | { |
133 | char *trigger; | ||
134 | int ret; | 42 | int ret; |
135 | 43 | ||
136 | if (AR_SREV_9287(sc->sc_ah)) | 44 | if (AR_SREV_9287(sc->sc_ah)) |
@@ -144,48 +52,22 @@ void ath_init_leds(struct ath_softc *sc) | |||
144 | /* LED off, active low */ | 52 | /* LED off, active low */ |
145 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | 53 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); |
146 | 54 | ||
147 | if (led_blink) | 55 | if (!led_blink) |
148 | INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); | 56 | sc->led_cdev.default_trigger = |
149 | 57 | ieee80211_get_radio_led_name(sc->hw); | |
150 | trigger = ieee80211_get_radio_led_name(sc->hw); | 58 | |
151 | snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), | 59 | snprintf(sc->led_name, sizeof(sc->led_name), |
152 | "ath9k-%s::radio", wiphy_name(sc->hw->wiphy)); | 60 | "ath9k-%s", wiphy_name(sc->hw->wiphy)); |
153 | ret = ath_register_led(sc, &sc->radio_led, trigger); | 61 | sc->led_cdev.name = sc->led_name; |
154 | sc->radio_led.led_type = ATH_LED_RADIO; | 62 | sc->led_cdev.brightness_set = ath_led_brightness; |
155 | if (ret) | 63 | |
156 | goto fail; | 64 | ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev); |
157 | 65 | if (ret < 0) | |
158 | trigger = ieee80211_get_assoc_led_name(sc->hw); | 66 | return; |
159 | snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name), | 67 | |
160 | "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy)); | 68 | sc->led_registered = true; |
161 | ret = ath_register_led(sc, &sc->assoc_led, trigger); | ||
162 | sc->assoc_led.led_type = ATH_LED_ASSOC; | ||
163 | if (ret) | ||
164 | goto fail; | ||
165 | |||
166 | trigger = ieee80211_get_tx_led_name(sc->hw); | ||
167 | snprintf(sc->tx_led.name, sizeof(sc->tx_led.name), | ||
168 | "ath9k-%s::tx", wiphy_name(sc->hw->wiphy)); | ||
169 | ret = ath_register_led(sc, &sc->tx_led, trigger); | ||
170 | sc->tx_led.led_type = ATH_LED_TX; | ||
171 | if (ret) | ||
172 | goto fail; | ||
173 | |||
174 | trigger = ieee80211_get_rx_led_name(sc->hw); | ||
175 | snprintf(sc->rx_led.name, sizeof(sc->rx_led.name), | ||
176 | "ath9k-%s::rx", wiphy_name(sc->hw->wiphy)); | ||
177 | ret = ath_register_led(sc, &sc->rx_led, trigger); | ||
178 | sc->rx_led.led_type = ATH_LED_RX; | ||
179 | if (ret) | ||
180 | goto fail; | ||
181 | |||
182 | return; | ||
183 | |||
184 | fail: | ||
185 | if (led_blink) | ||
186 | cancel_delayed_work_sync(&sc->ath_led_blink_work); | ||
187 | ath_deinit_leds(sc); | ||
188 | } | 69 | } |
70 | #endif | ||
189 | 71 | ||
190 | /*******************/ | 72 | /*******************/ |
191 | /* Rfkill */ | 73 | /* Rfkill */ |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index f66c882a39e2..79aec983279f 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -140,6 +140,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = { | |||
140 | RATE(540, 0x0c, 0), | 140 | RATE(540, 0x0c, 0), |
141 | }; | 141 | }; |
142 | 142 | ||
143 | #ifdef CONFIG_MAC80211_LEDS | ||
144 | static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = { | ||
145 | { .throughput = 0 * 1024, .blink_time = 334 }, | ||
146 | { .throughput = 1 * 1024, .blink_time = 260 }, | ||
147 | { .throughput = 5 * 1024, .blink_time = 220 }, | ||
148 | { .throughput = 10 * 1024, .blink_time = 190 }, | ||
149 | { .throughput = 20 * 1024, .blink_time = 170 }, | ||
150 | { .throughput = 50 * 1024, .blink_time = 150 }, | ||
151 | { .throughput = 70 * 1024, .blink_time = 130 }, | ||
152 | { .throughput = 100 * 1024, .blink_time = 110 }, | ||
153 | { .throughput = 200 * 1024, .blink_time = 80 }, | ||
154 | { .throughput = 300 * 1024, .blink_time = 50 }, | ||
155 | }; | ||
156 | #endif | ||
157 | |||
143 | static void ath9k_deinit_softc(struct ath_softc *sc); | 158 | static void ath9k_deinit_softc(struct ath_softc *sc); |
144 | 159 | ||
145 | /* | 160 | /* |
@@ -731,6 +746,13 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
731 | 746 | ||
732 | ath9k_init_txpower_limits(sc); | 747 | ath9k_init_txpower_limits(sc); |
733 | 748 | ||
749 | #ifdef CONFIG_MAC80211_LEDS | ||
750 | /* must be initialized before ieee80211_register_hw */ | ||
751 | sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, | ||
752 | IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, | ||
753 | ARRAY_SIZE(ath9k_tpt_blink)); | ||
754 | #endif | ||
755 | |||
734 | /* Register with mac80211 */ | 756 | /* Register with mac80211 */ |
735 | error = ieee80211_register_hw(hw); | 757 | error = ieee80211_register_hw(hw); |
736 | if (error) | 758 | if (error) |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 97830c7f62c9..2e228aada1a9 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1216,9 +1216,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1216 | 1216 | ||
1217 | mutex_lock(&sc->mutex); | 1217 | mutex_lock(&sc->mutex); |
1218 | 1218 | ||
1219 | if (led_blink) | ||
1220 | cancel_delayed_work_sync(&sc->ath_led_blink_work); | ||
1221 | |||
1222 | cancel_delayed_work_sync(&sc->tx_complete_work); | 1219 | cancel_delayed_work_sync(&sc->tx_complete_work); |
1223 | cancel_delayed_work_sync(&sc->hw_pll_work); | 1220 | cancel_delayed_work_sync(&sc->hw_pll_work); |
1224 | cancel_work_sync(&sc->paprd_work); | 1221 | cancel_work_sync(&sc->paprd_work); |