diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-07-10 23:53:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-07-14 14:52:59 -0400 |
commit | 0eee612731e133604023bfa8d20047e98160845e (patch) | |
tree | ae9cf4291493c65925727bf3591fe3dbff4f1a4d /drivers/net/wireless/iwlwifi/iwl-led.c | |
parent | 9f17b318a1e2335b45cf35ad6509b90e972c0e6b (diff) |
iwlwifi: fix LED stall
This patch fixes LED stall. last_blink_time was updated only if LED command
was sent, causing wrong computation of the througput.
Some code cleanup comes with this patch as well
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-led.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-led.c | 85 |
1 files changed, 37 insertions, 48 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index aa6ad18494ce..afd10758c037 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -48,10 +48,21 @@ | |||
48 | #define IWL_LED_THRESHOLD (16) | 48 | #define IWL_LED_THRESHOLD (16) |
49 | #define IWL_MAX_BLINK_TBL (10) | 49 | #define IWL_MAX_BLINK_TBL (10) |
50 | 50 | ||
51 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
52 | static const char *led_type_str[] = { | ||
53 | __stringify(IWL_LED_TRG_TX), | ||
54 | __stringify(IWL_LED_TRG_RX), | ||
55 | __stringify(IWL_LED_TRG_ASSOC), | ||
56 | __stringify(IWL_LED_TRG_RADIO), | ||
57 | NULL | ||
58 | }; | ||
59 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
60 | |||
61 | |||
51 | static const struct { | 62 | static const struct { |
52 | u16 tpt; | 63 | u16 tpt; |
53 | u8 on_time; | 64 | u8 on_time; |
54 | u8 of_time; | 65 | u8 off_time; |
55 | } blink_tbl[] = | 66 | } blink_tbl[] = |
56 | { | 67 | { |
57 | {300, 25, 25}, | 68 | {300, 25, 25}, |
@@ -155,21 +166,6 @@ static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id) | |||
155 | return 0; | 166 | return 0; |
156 | } | 167 | } |
157 | 168 | ||
158 | /* Set led blink command */ | ||
159 | static int iwl4965_led_not_solid(struct iwl_priv *priv, int led_id, | ||
160 | u8 brightness) | ||
161 | { | ||
162 | struct iwl4965_led_cmd led_cmd = { | ||
163 | .id = led_id, | ||
164 | .on = brightness, | ||
165 | .off = brightness, | ||
166 | .interval = IWL_DEF_LED_INTRVL | ||
167 | }; | ||
168 | |||
169 | return iwl_send_led_cmd(priv, &led_cmd); | ||
170 | } | ||
171 | |||
172 | |||
173 | /* | 169 | /* |
174 | * brightness call back function for Tx/Rx LED | 170 | * brightness call back function for Tx/Rx LED |
175 | */ | 171 | */ |
@@ -189,16 +185,18 @@ static int iwl4965_led_associated(struct iwl_priv *priv, int led_id) | |||
189 | /* | 185 | /* |
190 | * brightness call back for association and radio | 186 | * brightness call back for association and radio |
191 | */ | 187 | */ |
192 | static void iwl4965_led_brightness_set(struct led_classdev *led_cdev, | 188 | static void iwl_led_brightness_set(struct led_classdev *led_cdev, |
193 | enum led_brightness brightness) | 189 | enum led_brightness brightness) |
194 | { | 190 | { |
195 | struct iwl4965_led *led = container_of(led_cdev, | 191 | struct iwl_led *led = container_of(led_cdev, struct iwl_led, led_dev); |
196 | struct iwl4965_led, led_dev); | ||
197 | struct iwl_priv *priv = led->priv; | 192 | struct iwl_priv *priv = led->priv; |
198 | 193 | ||
199 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 194 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
200 | return; | 195 | return; |
201 | 196 | ||
197 | |||
198 | IWL_DEBUG_LED("Led type = %s brightness = %d\n", | ||
199 | led_type_str[led->type], brightness); | ||
202 | switch (brightness) { | 200 | switch (brightness) { |
203 | case LED_FULL: | 201 | case LED_FULL: |
204 | if (led->type == IWL_LED_TRG_ASSOC) | 202 | if (led->type == IWL_LED_TRG_ASSOC) |
@@ -226,8 +224,7 @@ static void iwl4965_led_brightness_set(struct led_classdev *led_cdev, | |||
226 | /* | 224 | /* |
227 | * Register led class with the system | 225 | * Register led class with the system |
228 | */ | 226 | */ |
229 | static int iwl_leds_register_led(struct iwl_priv *priv, | 227 | static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led, |
230 | struct iwl4965_led *led, | ||
231 | enum led_type type, u8 set_led, | 228 | enum led_type type, u8 set_led, |
232 | const char *name, char *trigger) | 229 | const char *name, char *trigger) |
233 | { | 230 | { |
@@ -235,7 +232,7 @@ static int iwl_leds_register_led(struct iwl_priv *priv, | |||
235 | int ret; | 232 | int ret; |
236 | 233 | ||
237 | led->led_dev.name = name; | 234 | led->led_dev.name = name; |
238 | led->led_dev.brightness_set = iwl4965_led_brightness_set; | 235 | led->led_dev.brightness_set = iwl_led_brightness_set; |
239 | led->led_dev.default_trigger = trigger; | 236 | led->led_dev.default_trigger = trigger; |
240 | 237 | ||
241 | led->priv = priv; | 238 | led->priv = priv; |
@@ -263,12 +260,14 @@ static inline u8 get_blink_rate(struct iwl_priv *priv) | |||
263 | { | 260 | { |
264 | int i; | 261 | int i; |
265 | u8 blink_rate; | 262 | u8 blink_rate; |
266 | u64 current_tpt = priv->tx_stats[2].bytes + priv->rx_stats[2].bytes; | 263 | u64 current_tpt = priv->tx_stats[2].bytes; |
264 | /* FIXME: + priv->rx_stats[2].bytes; */ | ||
267 | s64 tpt = current_tpt - priv->led_tpt; | 265 | s64 tpt = current_tpt - priv->led_tpt; |
268 | 266 | ||
269 | if (tpt < 0) /* wrapparound */ | 267 | if (tpt < 0) /* wrapparound */ |
270 | tpt = -tpt; | 268 | tpt = -tpt; |
271 | 269 | ||
270 | IWL_DEBUG_LED("tpt %lld current_tpt %lld\n", tpt, current_tpt); | ||
272 | priv->led_tpt = current_tpt; | 271 | priv->led_tpt = current_tpt; |
273 | 272 | ||
274 | if (tpt < IWL_LED_THRESHOLD) { | 273 | if (tpt < IWL_LED_THRESHOLD) { |
@@ -329,15 +328,13 @@ void iwl_leds_background(struct iwl_priv *priv) | |||
329 | /* call only if blink rate change */ | 328 | /* call only if blink rate change */ |
330 | if (blink_rate != priv->last_blink_rate) { | 329 | if (blink_rate != priv->last_blink_rate) { |
331 | if (blink_rate != IWL_LED_SOLID) { | 330 | if (blink_rate != IWL_LED_SOLID) { |
332 | priv->last_blink_time = jiffies + | 331 | iwl4965_led_pattern(priv, IWL_LED_LINK, blink_rate); |
333 | msecs_to_jiffies(1000); | ||
334 | iwl4965_led_not_solid(priv, IWL_LED_LINK, blink_rate); | ||
335 | } else { | 332 | } else { |
336 | priv->last_blink_time = 0; | ||
337 | iwl4965_led_on(priv, IWL_LED_LINK); | 333 | iwl4965_led_on(priv, IWL_LED_LINK); |
338 | } | 334 | } |
339 | } | 335 | } |
340 | 336 | ||
337 | priv->last_blink_time = jiffies; | ||
341 | priv->last_blink_rate = blink_rate; | 338 | priv->last_blink_rate = blink_rate; |
342 | } | 339 | } |
343 | EXPORT_SYMBOL(iwl_leds_background); | 340 | EXPORT_SYMBOL(iwl_leds_background); |
@@ -362,10 +359,8 @@ int iwl_leds_register(struct iwl_priv *priv) | |||
362 | priv->led[IWL_LED_TRG_RADIO].led_off = iwl4965_led_off_reg; | 359 | priv->led[IWL_LED_TRG_RADIO].led_off = iwl4965_led_off_reg; |
363 | priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; | 360 | priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; |
364 | 361 | ||
365 | ret = iwl_leds_register_led(priv, | 362 | ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO], |
366 | &priv->led[IWL_LED_TRG_RADIO], | 363 | IWL_LED_TRG_RADIO, 1, name, trigger); |
367 | IWL_LED_TRG_RADIO, 1, | ||
368 | name, trigger); | ||
369 | if (ret) | 364 | if (ret) |
370 | goto exit_fail; | 365 | goto exit_fail; |
371 | 366 | ||
@@ -373,10 +368,9 @@ int iwl_leds_register(struct iwl_priv *priv) | |||
373 | snprintf(name, sizeof(name), "iwl-%s:assoc", | 368 | snprintf(name, sizeof(name), "iwl-%s:assoc", |
374 | wiphy_name(priv->hw->wiphy)); | 369 | wiphy_name(priv->hw->wiphy)); |
375 | 370 | ||
376 | ret = iwl_leds_register_led(priv, | 371 | ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC], |
377 | &priv->led[IWL_LED_TRG_ASSOC], | 372 | IWL_LED_TRG_ASSOC, 0, name, trigger); |
378 | IWL_LED_TRG_ASSOC, 0, | 373 | |
379 | name, trigger); | ||
380 | /* for assoc always turn led on */ | 374 | /* for assoc always turn led on */ |
381 | priv->led[IWL_LED_TRG_ASSOC].led_on = iwl4965_led_on_reg; | 375 | priv->led[IWL_LED_TRG_ASSOC].led_on = iwl4965_led_on_reg; |
382 | priv->led[IWL_LED_TRG_ASSOC].led_off = iwl4965_led_on_reg; | 376 | priv->led[IWL_LED_TRG_ASSOC].led_off = iwl4965_led_on_reg; |
@@ -386,14 +380,11 @@ int iwl_leds_register(struct iwl_priv *priv) | |||
386 | goto exit_fail; | 380 | goto exit_fail; |
387 | 381 | ||
388 | trigger = ieee80211_get_rx_led_name(priv->hw); | 382 | trigger = ieee80211_get_rx_led_name(priv->hw); |
389 | snprintf(name, sizeof(name), "iwl-%s:RX", | 383 | snprintf(name, sizeof(name), "iwl-%s:RX", wiphy_name(priv->hw->wiphy)); |
390 | wiphy_name(priv->hw->wiphy)); | ||
391 | 384 | ||
392 | 385 | ||
393 | ret = iwl_leds_register_led(priv, | 386 | ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX], |
394 | &priv->led[IWL_LED_TRG_RX], | 387 | IWL_LED_TRG_RX, 0, name, trigger); |
395 | IWL_LED_TRG_RX, 0, | ||
396 | name, trigger); | ||
397 | 388 | ||
398 | priv->led[IWL_LED_TRG_RX].led_on = iwl4965_led_associated; | 389 | priv->led[IWL_LED_TRG_RX].led_on = iwl4965_led_associated; |
399 | priv->led[IWL_LED_TRG_RX].led_off = iwl4965_led_associated; | 390 | priv->led[IWL_LED_TRG_RX].led_off = iwl4965_led_associated; |
@@ -403,12 +394,10 @@ int iwl_leds_register(struct iwl_priv *priv) | |||
403 | goto exit_fail; | 394 | goto exit_fail; |
404 | 395 | ||
405 | trigger = ieee80211_get_tx_led_name(priv->hw); | 396 | trigger = ieee80211_get_tx_led_name(priv->hw); |
406 | snprintf(name, sizeof(name), "iwl-%s:TX", | 397 | snprintf(name, sizeof(name), "iwl-%s:TX", wiphy_name(priv->hw->wiphy)); |
407 | wiphy_name(priv->hw->wiphy)); | 398 | ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX], |
408 | ret = iwl_leds_register_led(priv, | 399 | IWL_LED_TRG_TX, 0, name, trigger); |
409 | &priv->led[IWL_LED_TRG_TX], | 400 | |
410 | IWL_LED_TRG_TX, 0, | ||
411 | name, trigger); | ||
412 | priv->led[IWL_LED_TRG_TX].led_on = iwl4965_led_associated; | 401 | priv->led[IWL_LED_TRG_TX].led_on = iwl4965_led_associated; |
413 | priv->led[IWL_LED_TRG_TX].led_off = iwl4965_led_associated; | 402 | priv->led[IWL_LED_TRG_TX].led_off = iwl4965_led_associated; |
414 | priv->led[IWL_LED_TRG_TX].led_pattern = iwl4965_led_pattern; | 403 | priv->led[IWL_LED_TRG_TX].led_pattern = iwl4965_led_pattern; |
@@ -425,7 +414,7 @@ exit_fail: | |||
425 | EXPORT_SYMBOL(iwl_leds_register); | 414 | EXPORT_SYMBOL(iwl_leds_register); |
426 | 415 | ||
427 | /* unregister led class */ | 416 | /* unregister led class */ |
428 | static void iwl_leds_unregister_led(struct iwl4965_led *led, u8 set_led) | 417 | static void iwl_leds_unregister_led(struct iwl_led *led, u8 set_led) |
429 | { | 418 | { |
430 | if (!led->registered) | 419 | if (!led->registered) |
431 | return; | 420 | return; |