aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-led.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-07-10 23:53:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-14 14:52:59 -0400
commit0eee612731e133604023bfa8d20047e98160845e (patch)
treeae9cf4291493c65925727bf3591fe3dbff4f1a4d /drivers/net/wireless/iwlwifi/iwl-led.c
parent9f17b318a1e2335b45cf35ad6509b90e972c0e6b (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.c85
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
52static 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
51static const struct { 62static 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 */
159static 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 */
192static void iwl4965_led_brightness_set(struct led_classdev *led_cdev, 188static 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 */
229static int iwl_leds_register_led(struct iwl_priv *priv, 227static 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}
343EXPORT_SYMBOL(iwl_leds_background); 340EXPORT_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:
425EXPORT_SYMBOL(iwl_leds_register); 414EXPORT_SYMBOL(iwl_leds_register);
426 415
427/* unregister led class */ 416/* unregister led class */
428static void iwl_leds_unregister_led(struct iwl4965_led *led, u8 set_led) 417static 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;