diff options
author | Abhijeet Kolekar <abhijeet.kolekar@intel.com> | 2008-07-10 23:53:41 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-07-14 14:53:00 -0400 |
commit | 9a9ad0cda72a651fc6b99fa9ec040a5d41005a88 (patch) | |
tree | f3188b3415088de1744280723e0d640428fba2a4 /drivers/net/wireless | |
parent | 36da7d70e307f8650db1b1c7350d2161ca3829ef (diff) |
iwlwifi: Fix LEDs for 3945
The patch fixes LEDs problem for 3945.
Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@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')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945-led.c | 146 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945-led.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.h | 1 |
3 files changed, 64 insertions, 85 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c index 8b1528e52d43..6be1fe13fa57 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c | |||
@@ -42,14 +42,11 @@ | |||
42 | #include "iwl-3945.h" | 42 | #include "iwl-3945.h" |
43 | #include "iwl-helpers.h" | 43 | #include "iwl-helpers.h" |
44 | 44 | ||
45 | #define IWL_1MB_RATE (128 * 1024) | ||
46 | #define IWL_LED_THRESHOLD (16) | ||
47 | #define IWL_MAX_BLINK_TBL (10) | ||
48 | 45 | ||
49 | static const struct { | 46 | static const struct { |
50 | u16 brightness; | 47 | u16 brightness; |
51 | u8 on_time; | 48 | u8 on_time; |
52 | u8 of_time; | 49 | u8 off_time; |
53 | } blink_tbl[] = | 50 | } blink_tbl[] = |
54 | { | 51 | { |
55 | {300, 25, 25}, | 52 | {300, 25, 25}, |
@@ -61,9 +58,16 @@ static const struct { | |||
61 | {15, 95, 95 }, | 58 | {15, 95, 95 }, |
62 | {10, 110, 110}, | 59 | {10, 110, 110}, |
63 | {5, 130, 130}, | 60 | {5, 130, 130}, |
64 | {0, 167, 167} | 61 | {0, 167, 167}, |
62 | /*SOLID_ON*/ | ||
63 | {-1, IWL_LED_SOLID, 0} | ||
65 | }; | 64 | }; |
66 | 65 | ||
66 | #define IWL_1MB_RATE (128 * 1024) | ||
67 | #define IWL_LED_THRESHOLD (16) | ||
68 | #define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/ | ||
69 | #define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1) | ||
70 | |||
67 | static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv, | 71 | static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv, |
68 | struct iwl3945_cmd *cmd, | 72 | struct iwl3945_cmd *cmd, |
69 | struct sk_buff *skb) | 73 | struct sk_buff *skb) |
@@ -71,6 +75,10 @@ static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv, | |||
71 | return 1; | 75 | return 1; |
72 | } | 76 | } |
73 | 77 | ||
78 | static inline int iwl3945_brightness_to_idx(enum led_brightness brightness) | ||
79 | { | ||
80 | return fls(0x000000FF & (u32)brightness); | ||
81 | } | ||
74 | 82 | ||
75 | /* Send led command */ | 83 | /* Send led command */ |
76 | static int iwl_send_led_cmd(struct iwl3945_priv *priv, | 84 | static int iwl_send_led_cmd(struct iwl3945_priv *priv, |
@@ -81,49 +89,45 @@ static int iwl_send_led_cmd(struct iwl3945_priv *priv, | |||
81 | .len = sizeof(struct iwl3945_led_cmd), | 89 | .len = sizeof(struct iwl3945_led_cmd), |
82 | .data = led_cmd, | 90 | .data = led_cmd, |
83 | .meta.flags = CMD_ASYNC, | 91 | .meta.flags = CMD_ASYNC, |
84 | .meta.u.callback = iwl3945_led_cmd_callback | 92 | .meta.u.callback = iwl3945_led_cmd_callback, |
85 | }; | 93 | }; |
86 | 94 | ||
87 | return iwl3945_send_cmd(priv, &cmd); | 95 | return iwl3945_send_cmd(priv, &cmd); |
88 | } | 96 | } |
89 | 97 | ||
90 | 98 | ||
99 | |||
91 | /* Set led on command */ | 100 | /* Set led on command */ |
92 | static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id) | 101 | static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id, |
102 | unsigned int idx) | ||
93 | { | 103 | { |
94 | struct iwl3945_led_cmd led_cmd = { | 104 | struct iwl3945_led_cmd led_cmd = { |
95 | .id = led_id, | 105 | .id = led_id, |
96 | .on = IWL_LED_SOLID, | ||
97 | .off = 0, | ||
98 | .interval = IWL_DEF_LED_INTRVL | 106 | .interval = IWL_DEF_LED_INTRVL |
99 | }; | 107 | }; |
108 | |||
109 | BUG_ON(idx > IWL_MAX_BLINK_TBL); | ||
110 | |||
111 | led_cmd.on = blink_tbl[idx].on_time; | ||
112 | led_cmd.off = blink_tbl[idx].off_time; | ||
113 | |||
100 | return iwl_send_led_cmd(priv, &led_cmd); | 114 | return iwl_send_led_cmd(priv, &led_cmd); |
101 | } | 115 | } |
102 | 116 | ||
117 | |||
118 | #if 1 | ||
103 | /* Set led on command */ | 119 | /* Set led on command */ |
104 | static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id, | 120 | static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id) |
105 | enum led_brightness brightness) | ||
106 | { | 121 | { |
107 | struct iwl3945_led_cmd led_cmd = { | 122 | struct iwl3945_led_cmd led_cmd = { |
108 | .id = led_id, | 123 | .id = led_id, |
109 | .on = brightness, | 124 | .on = IWL_LED_SOLID, |
110 | .off = brightness, | 125 | .off = 0, |
111 | .interval = IWL_DEF_LED_INTRVL | 126 | .interval = IWL_DEF_LED_INTRVL |
112 | }; | 127 | }; |
113 | if (brightness == LED_FULL) { | ||
114 | led_cmd.on = IWL_LED_SOLID; | ||
115 | led_cmd.off = 0; | ||
116 | } | ||
117 | return iwl_send_led_cmd(priv, &led_cmd); | 128 | return iwl_send_led_cmd(priv, &led_cmd); |
118 | } | 129 | } |
119 | 130 | ||
120 | /* Set led register off */ | ||
121 | static int iwl3945_led_on_reg(struct iwl3945_priv *priv, int led_id) | ||
122 | { | ||
123 | IWL_DEBUG_LED("led on %d\n", led_id); | ||
124 | return iwl3945_led_on(priv, led_id); | ||
125 | } | ||
126 | |||
127 | /* Set led off command */ | 131 | /* Set led off command */ |
128 | static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id) | 132 | static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id) |
129 | { | 133 | { |
@@ -136,27 +140,7 @@ static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id) | |||
136 | IWL_DEBUG_LED("led off %d\n", led_id); | 140 | IWL_DEBUG_LED("led off %d\n", led_id); |
137 | return iwl_send_led_cmd(priv, &led_cmd); | 141 | return iwl_send_led_cmd(priv, &led_cmd); |
138 | } | 142 | } |
139 | 143 | #endif | |
140 | /* Set led register off */ | ||
141 | static int iwl3945_led_off_reg(struct iwl3945_priv *priv, int led_id) | ||
142 | { | ||
143 | iwl3945_led_off(priv, led_id); | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | /* Set led blink command */ | ||
148 | static int iwl3945_led_not_solid(struct iwl3945_priv *priv, int led_id, | ||
149 | u8 brightness) | ||
150 | { | ||
151 | struct iwl3945_led_cmd led_cmd = { | ||
152 | .id = led_id, | ||
153 | .on = brightness, | ||
154 | .off = brightness, | ||
155 | .interval = IWL_DEF_LED_INTRVL | ||
156 | }; | ||
157 | |||
158 | return iwl_send_led_cmd(priv, &led_cmd); | ||
159 | } | ||
160 | 144 | ||
161 | 145 | ||
162 | /* | 146 | /* |
@@ -206,8 +190,10 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev, | |||
206 | led->led_off(priv, IWL_LED_LINK); | 190 | led->led_off(priv, IWL_LED_LINK); |
207 | break; | 191 | break; |
208 | default: | 192 | default: |
209 | if (led->led_pattern) | 193 | if (led->led_pattern) { |
210 | led->led_pattern(priv, IWL_LED_LINK, brightness); | 194 | int idx = iwl3945_brightness_to_idx(brightness); |
195 | led->led_pattern(priv, IWL_LED_LINK, idx); | ||
196 | } | ||
211 | break; | 197 | break; |
212 | } | 198 | } |
213 | } | 199 | } |
@@ -252,24 +238,20 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv, | |||
252 | static inline u8 get_blink_rate(struct iwl3945_priv *priv) | 238 | static inline u8 get_blink_rate(struct iwl3945_priv *priv) |
253 | { | 239 | { |
254 | int index; | 240 | int index; |
255 | u8 blink_rate; | 241 | u64 current_tpt = priv->rxtxpackets; |
256 | 242 | s64 tpt = current_tpt - priv->led_tpt; | |
257 | if (priv->rxtxpackets < IWL_LED_THRESHOLD) | ||
258 | index = 10; | ||
259 | else { | ||
260 | for (index = 0; index < IWL_MAX_BLINK_TBL; index++) { | ||
261 | if (priv->rxtxpackets > (blink_tbl[index].brightness * | ||
262 | IWL_1MB_RATE)) | ||
263 | break; | ||
264 | } | ||
265 | } | ||
266 | /* if 0 frame is transfered */ | ||
267 | if ((index == IWL_MAX_BLINK_TBL) || !priv->allow_blinking) | ||
268 | blink_rate = IWL_LED_SOLID; | ||
269 | else | ||
270 | blink_rate = blink_tbl[index].on_time; | ||
271 | 243 | ||
272 | return blink_rate; | 244 | if (tpt < 0) |
245 | tpt = -tpt; | ||
246 | priv->led_tpt = current_tpt; | ||
247 | |||
248 | if (!priv->allow_blinking) | ||
249 | index = IWL_MAX_BLINK_TBL; | ||
250 | else | ||
251 | for (index = 0; index < IWL_MAX_BLINK_TBL; index++) | ||
252 | if (tpt > (blink_tbl[index].brightness * IWL_1MB_RATE)) | ||
253 | break; | ||
254 | return index; | ||
273 | } | 255 | } |
274 | 256 | ||
275 | static inline int is_rf_kill(struct iwl3945_priv *priv) | 257 | static inline int is_rf_kill(struct iwl3945_priv *priv) |
@@ -285,7 +267,7 @@ static inline int is_rf_kill(struct iwl3945_priv *priv) | |||
285 | */ | 267 | */ |
286 | void iwl3945_led_background(struct iwl3945_priv *priv) | 268 | void iwl3945_led_background(struct iwl3945_priv *priv) |
287 | { | 269 | { |
288 | u8 blink_rate; | 270 | u8 blink_idx; |
289 | 271 | ||
290 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 272 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
291 | priv->last_blink_time = 0; | 273 | priv->last_blink_time = 0; |
@@ -298,9 +280,10 @@ void iwl3945_led_background(struct iwl3945_priv *priv) | |||
298 | 280 | ||
299 | if (!priv->allow_blinking) { | 281 | if (!priv->allow_blinking) { |
300 | priv->last_blink_time = 0; | 282 | priv->last_blink_time = 0; |
301 | if (priv->last_blink_rate != IWL_LED_SOLID) { | 283 | if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) { |
302 | priv->last_blink_rate = IWL_LED_SOLID; | 284 | priv->last_blink_rate = IWL_SOLID_BLINK_IDX; |
303 | iwl3945_led_on(priv, IWL_LED_LINK); | 285 | iwl3945_led_pattern(priv, IWL_LED_LINK, |
286 | IWL_SOLID_BLINK_IDX); | ||
304 | } | 287 | } |
305 | return; | 288 | return; |
306 | } | 289 | } |
@@ -309,21 +292,14 @@ void iwl3945_led_background(struct iwl3945_priv *priv) | |||
309 | msecs_to_jiffies(1000))) | 292 | msecs_to_jiffies(1000))) |
310 | return; | 293 | return; |
311 | 294 | ||
312 | blink_rate = get_blink_rate(priv); | 295 | blink_idx = get_blink_rate(priv); |
313 | 296 | ||
314 | /* call only if blink rate change */ | 297 | /* call only if blink rate change */ |
315 | if (blink_rate != priv->last_blink_rate) { | 298 | if (blink_idx != priv->last_blink_rate) |
316 | if (blink_rate != IWL_LED_SOLID) { | 299 | iwl3945_led_pattern(priv, IWL_LED_LINK, blink_idx); |
317 | priv->last_blink_time = jiffies + | ||
318 | msecs_to_jiffies(1000); | ||
319 | iwl3945_led_not_solid(priv, IWL_LED_LINK, blink_rate); | ||
320 | } else { | ||
321 | priv->last_blink_time = 0; | ||
322 | iwl3945_led_on(priv, IWL_LED_LINK); | ||
323 | } | ||
324 | } | ||
325 | 300 | ||
326 | priv->last_blink_rate = blink_rate; | 301 | priv->last_blink_time = jiffies; |
302 | priv->last_blink_rate = blink_idx; | ||
327 | priv->rxtxpackets = 0; | 303 | priv->rxtxpackets = 0; |
328 | } | 304 | } |
329 | 305 | ||
@@ -337,6 +313,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv) | |||
337 | 313 | ||
338 | priv->last_blink_rate = 0; | 314 | priv->last_blink_rate = 0; |
339 | priv->rxtxpackets = 0; | 315 | priv->rxtxpackets = 0; |
316 | priv->led_tpt = 0; | ||
340 | priv->last_blink_time = 0; | 317 | priv->last_blink_time = 0; |
341 | priv->allow_blinking = 0; | 318 | priv->allow_blinking = 0; |
342 | 319 | ||
@@ -344,8 +321,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv) | |||
344 | snprintf(name, sizeof(name), "iwl-%s:radio", | 321 | snprintf(name, sizeof(name), "iwl-%s:radio", |
345 | wiphy_name(priv->hw->wiphy)); | 322 | wiphy_name(priv->hw->wiphy)); |
346 | 323 | ||
347 | priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on_reg; | 324 | priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on; |
348 | priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off_reg; | 325 | priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off; |
349 | priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; | 326 | priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; |
350 | 327 | ||
351 | ret = iwl3945_led_register_led(priv, | 328 | ret = iwl3945_led_register_led(priv, |
@@ -364,8 +341,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv) | |||
364 | IWL_LED_TRG_ASSOC, 0, | 341 | IWL_LED_TRG_ASSOC, 0, |
365 | name, trigger); | 342 | name, trigger); |
366 | /* for assoc always turn led on */ | 343 | /* for assoc always turn led on */ |
367 | priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on_reg; | 344 | priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on; |
368 | priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on_reg; | 345 | priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on; |
369 | priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL; | 346 | priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL; |
370 | 347 | ||
371 | if (ret) | 348 | if (ret) |
@@ -391,6 +368,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv) | |||
391 | trigger = ieee80211_get_tx_led_name(priv->hw); | 368 | trigger = ieee80211_get_tx_led_name(priv->hw); |
392 | snprintf(name, sizeof(name), "iwl-%s:TX", | 369 | snprintf(name, sizeof(name), "iwl-%s:TX", |
393 | wiphy_name(priv->hw->wiphy)); | 370 | wiphy_name(priv->hw->wiphy)); |
371 | |||
394 | ret = iwl3945_led_register_led(priv, | 372 | ret = iwl3945_led_register_led(priv, |
395 | &priv->led[IWL_LED_TRG_TX], | 373 | &priv->led[IWL_LED_TRG_TX], |
396 | IWL_LED_TRG_TX, 0, | 374 | IWL_LED_TRG_TX, 0, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h index b1d2f6b8b259..6463e6e34aaa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h | |||
@@ -54,7 +54,7 @@ struct iwl3945_led { | |||
54 | int (*led_on) (struct iwl3945_priv *priv, int led_id); | 54 | int (*led_on) (struct iwl3945_priv *priv, int led_id); |
55 | int (*led_off) (struct iwl3945_priv *priv, int led_id); | 55 | int (*led_off) (struct iwl3945_priv *priv, int led_id); |
56 | int (*led_pattern) (struct iwl3945_priv *priv, int led_id, | 56 | int (*led_pattern) (struct iwl3945_priv *priv, int led_id, |
57 | enum led_brightness brightness); | 57 | int idx); |
58 | 58 | ||
59 | enum led_type type; | 59 | enum led_type type; |
60 | unsigned int registered; | 60 | unsigned int registered; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index a7ef59bd1943..fa81ba1af3d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -794,6 +794,7 @@ struct iwl3945_priv { | |||
794 | u8 last_blink_rate; | 794 | u8 last_blink_rate; |
795 | u8 allow_blinking; | 795 | u8 allow_blinking; |
796 | unsigned int rxtxpackets; | 796 | unsigned int rxtxpackets; |
797 | u64 led_tpt; | ||
797 | #endif | 798 | #endif |
798 | 799 | ||
799 | 800 | ||