1 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
2 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
3 @@ -438,26 +438,20 @@ void ath9k_btcoex_timer_pause(struct ath
5 #define ATH_LED_PIN_DEF 1
6 #define ATH_LED_PIN_9287 8
7 -#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
8 -#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
18 - struct ath_softc *sc;
19 - struct led_classdev led_cdev;
20 - enum ath_led_type led_type;
25 +#ifdef CONFIG_MAC80211_LEDS
26 void ath_init_leds(struct ath_softc *sc);
27 void ath_deinit_leds(struct ath_softc *sc);
29 +static inline void ath_init_leds(struct ath_softc *sc)
33 +static inline void ath_deinit_leds(struct ath_softc *sc)
39 /* Antenna diversity/combining */
40 #define ATH_ANT_RX_CURRENT_SHIFT 4
41 @@ -608,15 +602,11 @@ struct ath_softc {
42 struct ath_beacon beacon;
43 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
45 - struct ath_led radio_led;
46 - struct ath_led assoc_led;
47 - struct ath_led tx_led;
48 - struct ath_led rx_led;
49 - struct delayed_work ath_led_blink_work;
50 - int led_on_duration;
51 - int led_off_duration;
54 +#ifdef CONFIG_MAC80211_LEDS
55 + bool led_registered;
57 + struct led_classdev led_cdev;
62 --- a/drivers/net/wireless/ath/ath9k/gpio.c
63 +++ b/drivers/net/wireless/ath/ath9k/gpio.c
66 /********************************/
68 -static void ath_led_blink_work(struct work_struct *work)
70 - struct ath_softc *sc = container_of(work, struct ath_softc,
71 - ath_led_blink_work.work);
73 - if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
76 - if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
77 - (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
78 - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
80 - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
81 - (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
83 - ieee80211_queue_delayed_work(sc->hw,
84 - &sc->ath_led_blink_work,
85 - (sc->sc_flags & SC_OP_LED_ON) ?
86 - msecs_to_jiffies(sc->led_off_duration) :
87 - msecs_to_jiffies(sc->led_on_duration));
89 - sc->led_on_duration = sc->led_on_cnt ?
90 - max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
91 - ATH_LED_ON_DURATION_IDLE;
92 - sc->led_off_duration = sc->led_off_cnt ?
93 - max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
94 - ATH_LED_OFF_DURATION_IDLE;
95 - sc->led_on_cnt = sc->led_off_cnt = 0;
96 - if (sc->sc_flags & SC_OP_LED_ON)
97 - sc->sc_flags &= ~SC_OP_LED_ON;
99 - sc->sc_flags |= SC_OP_LED_ON;
102 +#ifdef CONFIG_MAC80211_LEDS
103 static void ath_led_brightness(struct led_classdev *led_cdev,
104 enum led_brightness brightness)
106 - struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
107 - struct ath_softc *sc = led->sc;
109 - switch (brightness) {
111 - if (led->led_type == ATH_LED_ASSOC ||
112 - led->led_type == ATH_LED_RADIO) {
113 - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
114 - (led->led_type == ATH_LED_RADIO));
115 - sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
116 - if (led->led_type == ATH_LED_RADIO)
117 - sc->sc_flags &= ~SC_OP_LED_ON;
123 - if (led->led_type == ATH_LED_ASSOC) {
124 - sc->sc_flags |= SC_OP_LED_ASSOCIATED;
126 - ieee80211_queue_delayed_work(sc->hw,
127 - &sc->ath_led_blink_work, 0);
128 - } else if (led->led_type == ATH_LED_RADIO) {
129 - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
130 - sc->sc_flags |= SC_OP_LED_ON;
140 -static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
146 - led->led_cdev.name = led->name;
147 - led->led_cdev.default_trigger = trigger;
148 - led->led_cdev.brightness_set = ath_led_brightness;
150 - ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
152 - ath_err(ath9k_hw_common(sc->sc_ah),
153 - "Failed to register led:%s", led->name);
155 - led->registered = 1;
159 -static void ath_unregister_led(struct ath_led *led)
161 - if (led->registered) {
162 - led_classdev_unregister(&led->led_cdev);
163 - led->registered = 0;
165 + struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
166 + ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF));
169 void ath_deinit_leds(struct ath_softc *sc)
171 - if (AR_SREV_9100(sc->sc_ah))
172 + if (!sc->led_registered)
175 - ath_unregister_led(&sc->assoc_led);
176 - sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
177 - ath_unregister_led(&sc->tx_led);
178 - ath_unregister_led(&sc->rx_led);
179 - ath_unregister_led(&sc->radio_led);
180 - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
181 + ath_led_brightness(&sc->led_cdev, LED_OFF);
182 + led_classdev_unregister(&sc->led_cdev);
185 void ath_init_leds(struct ath_softc *sc)
190 if (AR_SREV_9100(sc->sc_ah))
191 @@ -152,48 +57,22 @@ void ath_init_leds(struct ath_softc *sc)
192 /* LED off, active low */
193 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
196 - INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
198 + sc->led_cdev.default_trigger =
199 + ieee80211_get_radio_led_name(sc->hw);
201 + snprintf(sc->led_name, sizeof(sc->led_name),
202 + "ath9k-%s", wiphy_name(sc->hw->wiphy));
203 + sc->led_cdev.name = sc->led_name;
204 + sc->led_cdev.brightness_set = ath_led_brightness;
206 + ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
210 - trigger = ieee80211_get_radio_led_name(sc->hw);
211 - snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
212 - "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
213 - ret = ath_register_led(sc, &sc->radio_led, trigger);
214 - sc->radio_led.led_type = ATH_LED_RADIO;
218 - trigger = ieee80211_get_assoc_led_name(sc->hw);
219 - snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
220 - "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
221 - ret = ath_register_led(sc, &sc->assoc_led, trigger);
222 - sc->assoc_led.led_type = ATH_LED_ASSOC;
226 - trigger = ieee80211_get_tx_led_name(sc->hw);
227 - snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
228 - "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
229 - ret = ath_register_led(sc, &sc->tx_led, trigger);
230 - sc->tx_led.led_type = ATH_LED_TX;
234 - trigger = ieee80211_get_rx_led_name(sc->hw);
235 - snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
236 - "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
237 - ret = ath_register_led(sc, &sc->rx_led, trigger);
238 - sc->rx_led.led_type = ATH_LED_RX;
246 - cancel_delayed_work_sync(&sc->ath_led_blink_work);
247 - ath_deinit_leds(sc);
248 + sc->led_registered = true;
252 /*******************/
254 --- a/drivers/net/wireless/ath/ath9k/main.c
255 +++ b/drivers/net/wireless/ath/ath9k/main.c
256 @@ -1275,9 +1275,6 @@ static void ath9k_stop(struct ieee80211_
258 aphy->state = ATH_WIPHY_INACTIVE;
261 - cancel_delayed_work_sync(&sc->ath_led_blink_work);
263 cancel_delayed_work_sync(&sc->tx_complete_work);
264 cancel_work_sync(&sc->paprd_work);
265 cancel_work_sync(&sc->hw_check_work);
266 --- a/drivers/net/wireless/ath/ath9k/init.c
267 +++ b/drivers/net/wireless/ath/ath9k/init.c
268 @@ -139,6 +139,21 @@ static struct ieee80211_rate ath9k_legac
272 +#ifdef CONFIG_MAC80211_LEDS
273 +static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
274 + { .throughput = 0 * 1024, .blink_time = 334 },
275 + { .throughput = 1 * 1024, .blink_time = 260 },
276 + { .throughput = 5 * 1024, .blink_time = 220 },
277 + { .throughput = 10 * 1024, .blink_time = 190 },
278 + { .throughput = 20 * 1024, .blink_time = 170 },
279 + { .throughput = 50 * 1024, .blink_time = 150 },
280 + { .throughput = 70 * 1024, .blink_time = 130 },
281 + { .throughput = 100 * 1024, .blink_time = 110 },
282 + { .throughput = 200 * 1024, .blink_time = 80 },
283 + { .throughput = 300 * 1024, .blink_time = 50 },
287 static void ath9k_deinit_softc(struct ath_softc *sc);
290 @@ -742,6 +757,12 @@ int ath9k_init_device(u16 devid, struct
292 ath9k_init_txpower_limits(sc);
294 +#ifdef CONFIG_MAC80211_LEDS
295 + /* must be initialized before ieee80211_register_hw */
296 + sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
297 + ath9k_tpt_blink, ARRAY_SIZE(ath9k_tpt_blink));
300 /* Register with mac80211 */
301 error = ieee80211_register_hw(hw);