aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-07-10 23:53:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-14 14:52:59 -0400
commitec1a746042ea4c1c93065185897d6e8d3e7de894 (patch)
tree64f001e7acf86b48a6020990635b0830e1dcfaee /drivers/net/wireless/iwlwifi
parent0eee612731e133604023bfa8d20047e98160845e (diff)
iwlwifi: LED use correctly blink table
This patch makes correct usage of the LED blink table. 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')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c125
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h3
4 files changed, 61 insertions, 71 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 92754ee49e45..3e96df8e8108 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2926,7 +2926,7 @@ struct iwl5000_calibration_chain_noise_gain_cmd {
2926 * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field), 2926 * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field),
2927 * this command turns it on or off, or sets up a periodic blinking cycle. 2927 * this command turns it on or off, or sets up a periodic blinking cycle.
2928 */ 2928 */
2929struct iwl4965_led_cmd { 2929struct iwl_led_cmd {
2930 __le32 interval; /* "interval" in uSec */ 2930 __le32 interval; /* "interval" in uSec */
2931 u8 id; /* 1: Activity, 2: Link, 3: Tech */ 2931 u8 id; /* 1: Activity, 2: Link, 3: Tech */
2932 u8 off; /* # intervals off while blinking; 2932 u8 off; /* # intervals off while blinking;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index bd06e0f87113..84a3ecfec484 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -282,7 +282,7 @@ struct iwl_cmd {
282 struct iwl_cmd_header hdr; /* uCode API */ 282 struct iwl_cmd_header hdr; /* uCode API */
283 union { 283 union {
284 struct iwl_addsta_cmd addsta; 284 struct iwl_addsta_cmd addsta;
285 struct iwl4965_led_cmd led; 285 struct iwl_led_cmd led;
286 u32 flags; 286 u32 flags;
287 u8 val8; 287 u8 val8;
288 u16 val16; 288 u16 val16;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index afd10758c037..0c09b901a253 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -44,10 +44,6 @@
44#include "iwl-io.h" 44#include "iwl-io.h"
45#include "iwl-helpers.h" 45#include "iwl-helpers.h"
46 46
47#define IWL_1MB_RATE (128 * 1024)
48#define IWL_LED_THRESHOLD (16)
49#define IWL_MAX_BLINK_TBL (10)
50
51#ifdef CONFIG_IWLWIFI_DEBUG 47#ifdef CONFIG_IWLWIFI_DEBUG
52static const char *led_type_str[] = { 48static const char *led_type_str[] = {
53 __stringify(IWL_LED_TRG_TX), 49 __stringify(IWL_LED_TRG_TX),
@@ -74,26 +70,31 @@ static const struct {
74 {15, 95, 95 }, 70 {15, 95, 95 },
75 {10, 110, 110}, 71 {10, 110, 110},
76 {5, 130, 130}, 72 {5, 130, 130},
77 {0, 167, 167} 73 {0, 167, 167},
74/* SOLID_ON */
75 {-1, IWL_LED_SOLID, 0}
78}; 76};
79 77
80static int iwl_led_cmd_callback(struct iwl_priv *priv, 78#define IWL_1MB_RATE (128 * 1024)
81 struct iwl_cmd *cmd, struct sk_buff *skb) 79#define IWL_LED_THRESHOLD (16)
80#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /* exclude SOLID_ON */
81#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
82
83/* [0-256] -> [0..8] FIXME: we need [0..10] */
84static inline int iwl_brightness_to_idx(enum led_brightness brightness)
82{ 85{
83 return 1; 86 return fls(0x000000FF & (u32)brightness);
84} 87}
85 88
86
87/* Send led command */ 89/* Send led command */
88static int iwl_send_led_cmd(struct iwl_priv *priv, 90static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
89 struct iwl4965_led_cmd *led_cmd)
90{ 91{
91 struct iwl_host_cmd cmd = { 92 struct iwl_host_cmd cmd = {
92 .id = REPLY_LEDS_CMD, 93 .id = REPLY_LEDS_CMD,
93 .len = sizeof(struct iwl4965_led_cmd), 94 .len = sizeof(struct iwl_led_cmd),
94 .data = led_cmd, 95 .data = led_cmd,
95 .meta.flags = CMD_ASYNC, 96 .meta.flags = CMD_ASYNC,
96 .meta.u.callback = iwl_led_cmd_callback 97 .meta.u.callback = NULL,
97 }; 98 };
98 u32 reg; 99 u32 reg;
99 100
@@ -104,33 +105,19 @@ static int iwl_send_led_cmd(struct iwl_priv *priv,
104 return iwl_send_cmd(priv, &cmd); 105 return iwl_send_cmd(priv, &cmd);
105} 106}
106 107
107 108/* Set led pattern command */
108/* Set led on command */ 109static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id, int idx)
109static int iwl4965_led_on(struct iwl_priv *priv, int led_id)
110{ 110{
111 struct iwl4965_led_cmd led_cmd = { 111 struct iwl_led_cmd led_cmd = {
112 .id = led_id, 112 .id = led_id,
113 .on = IWL_LED_SOLID,
114 .off = 0,
115 .interval = IWL_DEF_LED_INTRVL 113 .interval = IWL_DEF_LED_INTRVL
116 }; 114 };
117 return iwl_send_led_cmd(priv, &led_cmd);
118}
119 115
120/* Set led on command */ 116 BUG_ON(idx > IWL_MAX_BLINK_TBL);
121static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id, 117
122 enum led_brightness brightness) 118 led_cmd.on = blink_tbl[idx].on_time;
123{ 119 led_cmd.off = blink_tbl[idx].off_time;
124 struct iwl4965_led_cmd led_cmd = { 120
125 .id = led_id,
126 .on = brightness,
127 .off = brightness,
128 .interval = IWL_DEF_LED_INTRVL
129 };
130 if (brightness == LED_FULL) {
131 led_cmd.on = IWL_LED_SOLID;
132 led_cmd.off = 0;
133 }
134 return iwl_send_led_cmd(priv, &led_cmd); 121 return iwl_send_led_cmd(priv, &led_cmd);
135} 122}
136 123
@@ -143,10 +130,22 @@ static int iwl4965_led_on_reg(struct iwl_priv *priv, int led_id)
143} 130}
144 131
145#if 0 132#if 0
133/* Set led on command */
134static int iwl4965_led_on(struct iwl_priv *priv, int led_id)
135{
136 struct iwl_led_cmd led_cmd = {
137 .id = led_id,
138 .on = IWL_LED_SOLID,
139 .off = 0,
140 .interval = IWL_DEF_LED_INTRVL
141 };
142 return iwl_send_led_cmd(priv, &led_cmd);
143}
144
146/* Set led off command */ 145/* Set led off command */
147int iwl4965_led_off(struct iwl_priv *priv, int led_id) 146int iwl4965_led_off(struct iwl_priv *priv, int led_id)
148{ 147{
149 struct iwl4965_led_cmd led_cmd = { 148 struct iwl_led_cmd led_cmd = {
150 .id = led_id, 149 .id = led_id,
151 .on = 0, 150 .on = 0,
152 .off = 0, 151 .off = 0,
@@ -169,7 +168,7 @@ static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
169/* 168/*
170 * brightness call back function for Tx/Rx LED 169 * brightness call back function for Tx/Rx LED
171 */ 170 */
172static int iwl4965_led_associated(struct iwl_priv *priv, int led_id) 171static int iwl_led_associated(struct iwl_priv *priv, int led_id)
173{ 172{
174 if (test_bit(STATUS_EXIT_PENDING, &priv->status) || 173 if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
175 !test_bit(STATUS_READY, &priv->status)) 174 !test_bit(STATUS_READY, &priv->status))
@@ -213,8 +212,10 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
213 led->led_off(priv, IWL_LED_LINK); 212 led->led_off(priv, IWL_LED_LINK);
214 break; 213 break;
215 default: 214 default:
216 if (led->led_pattern) 215 if (led->led_pattern) {
217 led->led_pattern(priv, IWL_LED_LINK, brightness); 216 int idx = iwl_brightness_to_idx(brightness);
217 led->led_pattern(priv, IWL_LED_LINK, idx);
218 }
218 break; 219 break;
219 } 220 }
220} 221}
@@ -256,10 +257,9 @@ static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
256/* 257/*
257 * calculate blink rate according to last 2 sec Tx/Rx activities 258 * calculate blink rate according to last 2 sec Tx/Rx activities
258 */ 259 */
259static inline u8 get_blink_rate(struct iwl_priv *priv) 260static int iwl_get_blink_rate(struct iwl_priv *priv)
260{ 261{
261 int i; 262 int i;
262 u8 blink_rate;
263 u64 current_tpt = priv->tx_stats[2].bytes; 263 u64 current_tpt = priv->tx_stats[2].bytes;
264 /* FIXME: + priv->rx_stats[2].bytes; */ 264 /* FIXME: + priv->rx_stats[2].bytes; */
265 s64 tpt = current_tpt - priv->led_tpt; 265 s64 tpt = current_tpt - priv->led_tpt;
@@ -270,20 +270,15 @@ static inline u8 get_blink_rate(struct iwl_priv *priv)
270 IWL_DEBUG_LED("tpt %lld current_tpt %lld\n", tpt, current_tpt); 270 IWL_DEBUG_LED("tpt %lld current_tpt %lld\n", tpt, current_tpt);
271 priv->led_tpt = current_tpt; 271 priv->led_tpt = current_tpt;
272 272
273 if (tpt < IWL_LED_THRESHOLD) { 273 if (!priv->allow_blinking)
274 i = IWL_MAX_BLINK_TBL; 274 i = IWL_MAX_BLINK_TBL;
275 } else { 275 else
276 for (i = 0; i < IWL_MAX_BLINK_TBL; i++) 276 for (i = 0; i < IWL_MAX_BLINK_TBL; i++)
277 if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE)) 277 if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE))
278 break; 278 break;
279 }
280 /* if 0 frame is transfered */
281 if ((i == IWL_MAX_BLINK_TBL) || !priv->allow_blinking)
282 blink_rate = IWL_LED_SOLID;
283 else
284 blink_rate = blink_tbl[i].on_time;
285 279
286 return blink_rate; 280 IWL_DEBUG_LED("LED BLINK IDX=%d", i);
281 return i;
287} 282}
288 283
289static inline int is_rf_kill(struct iwl_priv *priv) 284static inline int is_rf_kill(struct iwl_priv *priv)
@@ -299,7 +294,7 @@ static inline int is_rf_kill(struct iwl_priv *priv)
299 */ 294 */
300void iwl_leds_background(struct iwl_priv *priv) 295void iwl_leds_background(struct iwl_priv *priv)
301{ 296{
302 u8 blink_rate; 297 u8 blink_idx;
303 298
304 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { 299 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
305 priv->last_blink_time = 0; 300 priv->last_blink_time = 0;
@@ -312,9 +307,10 @@ void iwl_leds_background(struct iwl_priv *priv)
312 307
313 if (!priv->allow_blinking) { 308 if (!priv->allow_blinking) {
314 priv->last_blink_time = 0; 309 priv->last_blink_time = 0;
315 if (priv->last_blink_rate != IWL_LED_SOLID) { 310 if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) {
316 priv->last_blink_rate = IWL_LED_SOLID; 311 priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
317 iwl4965_led_on(priv, IWL_LED_LINK); 312 iwl4965_led_pattern(priv, IWL_LED_LINK,
313 IWL_SOLID_BLINK_IDX);
318 } 314 }
319 return; 315 return;
320 } 316 }
@@ -323,19 +319,14 @@ void iwl_leds_background(struct iwl_priv *priv)
323 msecs_to_jiffies(1000))) 319 msecs_to_jiffies(1000)))
324 return; 320 return;
325 321
326 blink_rate = get_blink_rate(priv); 322 blink_idx = iwl_get_blink_rate(priv);
327 323
328 /* call only if blink rate change */ 324 /* call only if blink rate change */
329 if (blink_rate != priv->last_blink_rate) { 325 if (blink_idx != priv->last_blink_rate)
330 if (blink_rate != IWL_LED_SOLID) { 326 iwl4965_led_pattern(priv, IWL_LED_LINK, blink_idx);
331 iwl4965_led_pattern(priv, IWL_LED_LINK, blink_rate);
332 } else {
333 iwl4965_led_on(priv, IWL_LED_LINK);
334 }
335 }
336 327
337 priv->last_blink_time = jiffies; 328 priv->last_blink_time = jiffies;
338 priv->last_blink_rate = blink_rate; 329 priv->last_blink_rate = blink_idx;
339} 330}
340EXPORT_SYMBOL(iwl_leds_background); 331EXPORT_SYMBOL(iwl_leds_background);
341 332
@@ -386,8 +377,8 @@ int iwl_leds_register(struct iwl_priv *priv)
386 ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX], 377 ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
387 IWL_LED_TRG_RX, 0, name, trigger); 378 IWL_LED_TRG_RX, 0, name, trigger);
388 379
389 priv->led[IWL_LED_TRG_RX].led_on = iwl4965_led_associated; 380 priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
390 priv->led[IWL_LED_TRG_RX].led_off = iwl4965_led_associated; 381 priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
391 priv->led[IWL_LED_TRG_RX].led_pattern = iwl4965_led_pattern; 382 priv->led[IWL_LED_TRG_RX].led_pattern = iwl4965_led_pattern;
392 383
393 if (ret) 384 if (ret)
@@ -398,8 +389,8 @@ int iwl_leds_register(struct iwl_priv *priv)
398 ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX], 389 ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
399 IWL_LED_TRG_TX, 0, name, trigger); 390 IWL_LED_TRG_TX, 0, name, trigger);
400 391
401 priv->led[IWL_LED_TRG_TX].led_on = iwl4965_led_associated; 392 priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
402 priv->led[IWL_LED_TRG_TX].led_off = iwl4965_led_associated; 393 priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;
403 priv->led[IWL_LED_TRG_TX].led_pattern = iwl4965_led_pattern; 394 priv->led[IWL_LED_TRG_TX].led_pattern = iwl4965_led_pattern;
404 395
405 if (ret) 396 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index c9466d5373e0..05e6a6113b74 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -55,8 +55,7 @@ struct iwl_led {
55 55
56 int (*led_on) (struct iwl_priv *priv, int led_id); 56 int (*led_on) (struct iwl_priv *priv, int led_id);
57 int (*led_off) (struct iwl_priv *priv, int led_id); 57 int (*led_off) (struct iwl_priv *priv, int led_id);
58 int (*led_pattern) (struct iwl_priv *priv, int led_id, 58 int (*led_pattern) (struct iwl_priv *priv, int led_id, int idx);
59 enum led_brightness brightness);
60 59
61 enum led_type type; 60 enum led_type type;
62 unsigned int registered; 61 unsigned int registered;