mac80211: sync with trunk (as of r25965)
[openwrt-10.03/.git] / package / mac80211 / patches / 510-ath9k_led_cleanup.patch
1 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
2 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
3 @@ -449,26 +449,20 @@ void ath9k_btcoex_timer_pause(struct ath
4  
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 */
9 -
10 -enum ath_led_type {
11 -       ATH_LED_RADIO,
12 -       ATH_LED_ASSOC,
13 -       ATH_LED_TX,
14 -       ATH_LED_RX
15 -};
16 -
17 -struct ath_led {
18 -       struct ath_softc *sc;
19 -       struct led_classdev led_cdev;
20 -       enum ath_led_type led_type;
21 -       char name[32];
22 -       bool registered;
23 -};
24  
25 +#ifdef CONFIG_MAC80211_LEDS
26  void ath_init_leds(struct ath_softc *sc);
27  void ath_deinit_leds(struct ath_softc *sc);
28 +#else
29 +static inline void ath_init_leds(struct ath_softc *sc)
30 +{
31 +}
32 +
33 +static inline void ath_deinit_leds(struct ath_softc *sc)
34 +{
35 +}
36 +#endif
37 +
38  
39  /* Antenna diversity/combining */
40  #define ATH_ANT_RX_CURRENT_SHIFT 4
41 @@ -620,15 +614,11 @@ struct ath_softc {
42         struct ath_beacon beacon;
43         struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
44  
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;
52 -       int led_on_cnt;
53 -       int led_off_cnt;
54 +#ifdef CONFIG_MAC80211_LEDS
55 +       bool led_registered;
56 +       char led_name[32];
57 +       struct led_classdev led_cdev;
58 +#endif
59  
60         struct ath9k_hw_cal_data caldata;
61         int last_rssi;
62 --- a/drivers/net/wireless/ath/ath9k/gpio.c
63 +++ b/drivers/net/wireless/ath/ath9k/gpio.c
64 @@ -20,120 +20,25 @@
65  /*      LED functions          */
66  /********************************/
67  
68 -static void ath_led_blink_work(struct work_struct *work)
69 -{
70 -       struct ath_softc *sc = container_of(work, struct ath_softc,
71 -                                           ath_led_blink_work.work);
72 -
73 -       if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
74 -               return;
75 -
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);
79 -       else
80 -               ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
81 -                                 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
82 -
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));
88 -
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;
98 -       else
99 -               sc->sc_flags |= SC_OP_LED_ON;
100 -}
101 -
102 +#ifdef CONFIG_MAC80211_LEDS
103  static void ath_led_brightness(struct led_classdev *led_cdev,
104                                enum led_brightness brightness)
105  {
106 -       struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
107 -       struct ath_softc *sc = led->sc;
108 -
109 -       switch (brightness) {
110 -       case LED_OFF:
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;
118 -               } else {
119 -                       sc->led_off_cnt++;
120 -               }
121 -               break;
122 -       case LED_FULL:
123 -               if (led->led_type == ATH_LED_ASSOC) {
124 -                       sc->sc_flags |= SC_OP_LED_ASSOCIATED;
125 -                       if (led_blink)
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;
131 -               } else {
132 -                       sc->led_on_cnt++;
133 -               }
134 -               break;
135 -       default:
136 -               break;
137 -       }
138 -}
139 -
140 -static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
141 -                           char *trigger)
142 -{
143 -       int ret;
144 -
145 -       led->sc = sc;
146 -       led->led_cdev.name = led->name;
147 -       led->led_cdev.default_trigger = trigger;
148 -       led->led_cdev.brightness_set = ath_led_brightness;
149 -
150 -       ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
151 -       if (ret)
152 -               ath_err(ath9k_hw_common(sc->sc_ah),
153 -                       "Failed to register led:%s", led->name);
154 -       else
155 -               led->registered = 1;
156 -       return ret;
157 -}
158 -
159 -static void ath_unregister_led(struct ath_led *led)
160 -{
161 -       if (led->registered) {
162 -               led_classdev_unregister(&led->led_cdev);
163 -               led->registered = 0;
164 -       }
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));
167  }
168  
169  void ath_deinit_leds(struct ath_softc *sc)
170  {
171 -       if (AR_SREV_9100(sc->sc_ah))
172 +       if (!sc->led_registered)
173                 return;
174  
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);
183  }
184  
185  void ath_init_leds(struct ath_softc *sc)
186  {
187 -       char *trigger;
188         int ret;
189  
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);
194  
195 -       if (led_blink)
196 -               INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
197 +       if (!led_blink)
198 +               sc->led_cdev.default_trigger =
199 +                       ieee80211_get_radio_led_name(sc->hw);
200 +
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;
205 +
206 +       ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
207 +       if (ret < 0)
208 +               return;
209  
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;
215 -       if (ret)
216 -               goto fail;
217 -
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;
223 -       if (ret)
224 -               goto fail;
225 -
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;
231 -       if (ret)
232 -               goto fail;
233 -
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;
239 -       if (ret)
240 -               goto fail;
241 -
242 -       return;
243 -
244 -fail:
245 -       if (led_blink)
246 -               cancel_delayed_work_sync(&sc->ath_led_blink_work);
247 -       ath_deinit_leds(sc);
248 +       sc->led_registered = true;
249  }
250 +#endif
251  
252  /*******************/
253  /*     Rfkill     */
254 --- a/drivers/net/wireless/ath/ath9k/main.c
255 +++ b/drivers/net/wireless/ath/ath9k/main.c
256 @@ -1216,9 +1216,6 @@ static void ath9k_stop(struct ieee80211_
257  
258         mutex_lock(&sc->mutex);
259  
260 -       if (led_blink)
261 -               cancel_delayed_work_sync(&sc->ath_led_blink_work);
262 -
263         cancel_delayed_work_sync(&sc->tx_complete_work);
264         cancel_delayed_work_sync(&sc->hw_pll_work);
265         cancel_work_sync(&sc->paprd_work);
266 --- a/drivers/net/wireless/ath/ath9k/init.c
267 +++ b/drivers/net/wireless/ath/ath9k/init.c
268 @@ -141,6 +141,21 @@ static struct ieee80211_rate ath9k_legac
269         RATE(540, 0x0c, 0),
270  };
271  
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 },
284 +};
285 +#endif
286 +
287  static void ath9k_deinit_softc(struct ath_softc *sc);
288  
289  /*
290 @@ -742,6 +757,13 @@ int ath9k_init_device(u16 devid, struct 
291  
292         ath9k_init_txpower_limits(sc);
293  
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 +               IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
298 +               ARRAY_SIZE(ath9k_tpt_blink));
299 +#endif
300 +
301         /* Register with mac80211 */
302         error = ieee80211_register_hw(hw);
303         if (error)