Merge branch 'for-linus' of git://www.jni.nu/cris
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / otus / 80211core / ledmgr.c
1 /*
2 * Copyright (c) 2007-2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include "cprecomp.h"
18
19 /************************************************************************/
20 /* */
21 /* FUNCTION DESCRIPTION zfLedCtrlType1 */
22 /* Traditional single-LED state */
23 /* */
24 /* INPUTS */
25 /* dev : device pointer */
26 /* */
27 /* OUTPUTS */
28 /* None */
29 /* */
30 /* AUTHOR */
31 /* Stephen Chen Atheros Communications, INC. 2007.6 */
32 /* */
33 /************************************************************************/
34 // bit 15-12 : Toff for Scan state
35 // 11-8 : Ton for Scan state
36 // 7 : Reserved
37 // 6 : mode
38 //--------------------------------------
39 // bit 6 = 0
40 // 5-4 : Connect state
41 // 00 => always off
42 // 01 => always on
43 // 10 => Idle off, acitve on
44 // 11 => Idle on, active off
45 //--------------------------------------
46 // bit 6 = 1
47 // 5-4 : freq
48 // 00 => 1Hz
49 // 01 => 0.5Hz
50 // 10 => 0.25Hz
51 // 11 => 0.125Hz
52 //--------------------------------------
53 // 3 : Power save state
54 // 0 => always off in power save state
55 // 1 => works as connect state
56 // 2 : Disable state
57 // 1 : Reserved
58 // 0 : Power-on state
59 void zfLedCtrlType1(zdev_t* dev)
60 {
61 u16_t i;
62 u32_t ton, toff, tmp, period;
63 zmw_get_wlan_dev(dev);
64
65 for (i=0; i<ZM_MAX_LED_NUMBER; i++)
66 {
67 if (zfStaIsConnected(dev) != TRUE)
68 {
69 //Scan state
70 ton = ((wd->ledStruct.ledMode[i] & 0xf00) >> 8) * 5;
71 toff = ((wd->ledStruct.ledMode[i] & 0xf000) >> 12) * 5;
72
73 if ((ton + toff) != 0)
74 {
75 tmp = wd->ledStruct.counter / (ton+toff);
76 tmp = wd->ledStruct.counter - (tmp * (ton+toff));
77 if (tmp < ton)
78 {
79 zfHpLedCtrl(dev, i, 1);
80 }
81 else
82 {
83 zfHpLedCtrl(dev, i, 0);
84 }
85 }
86 }
87 else
88 {
89 if ((zfPowerSavingMgrIsSleeping(dev)) && ((wd->ledStruct.ledMode[i] & 0x8) == 0))
90 {
91 zfHpLedCtrl(dev, i, 0);
92 }
93 else
94 {
95 //Connect state
96 if ((wd->ledStruct.ledMode[i] & 0x40) == 0)
97 {
98 if ((wd->ledStruct.counter & 1) == 0)
99 {
100 zfHpLedCtrl(dev, i, (wd->ledStruct.ledMode[i] & 0x10) >> 4);
101 }
102 else
103 {
104 if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0))
105 {
106 wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0;
107 if ((wd->ledStruct.ledMode[i] & 0x20) != 0)
108 {
109 zfHpLedCtrl(dev, i, ((wd->ledStruct.ledMode[i] & 0x10) >> 4)^1);
110 }
111 }
112 }
113 }// if ((wd->ledStruct.ledMode[i] & 0x40) == 0)
114 else
115 {
116 period = 5 * (1 << ((wd->ledStruct.ledMode[i] & 0x30) >> 4));
117 tmp = wd->ledStruct.counter / (period*2);
118 tmp = wd->ledStruct.counter - (tmp * (period*2));
119 if (tmp < period)
120 {
121 if ((wd->ledStruct.counter & 1) == 0)
122 {
123 zfHpLedCtrl(dev, i, 0);
124 }
125 else
126 {
127 if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0))
128 {
129 wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0;
130 zfHpLedCtrl(dev, i, 1);
131 }
132 }
133 }
134 else
135 {
136 if ((wd->ledStruct.counter & 1) == 0)
137 {
138 zfHpLedCtrl(dev, i, 1);
139 }
140 else
141 {
142 if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0))
143 {
144 wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0;
145 zfHpLedCtrl(dev, i, 0);
146 }
147 }
148 }
149 } //else, if ((wd->ledStruct.ledMode[i] & 0x40) == 0)
150 } //else, if (zfPowerSavingMgrIsSleeping(dev))
151 } //else : if (zfStaIsConnected(dev) != TRUE)
152 } //for (i=0; i<ZM_MAX_LED_NUMBER; i++)
153 }
154
155 /******************************************************************************/
156 /* */
157 /* FUNCTION DESCRIPTION zfLedCtrlType2 */
158 /* Customize for Netgear Dual-LED state ((bug#31292)) */
159 /* */
160 /* 1. Status: When dongle does not connect to 2.4G or 5G but in site */
161 /* survey/association */
162 /* LED status: Slow blinking, Amber then Blue per 500ms */
163 /* 2. Status: Connection at 2.4G in site survey/association */
164 /* LED status: Slow blinking, Amber/off per 500ms */
165 /* 3. Status: Connection at 5G in site survey/association */
166 /* LED status: Slow blinking, Blue/off per 500ms */
167 /* 4. Status: When transfer the packet */
168 /* LED status: Blink per packet, including TX and RX */
169 /* 5. Status: When linking is established but no traffic */
170 /* LED status: Always on */
171 /* 6. Status: When linking is dropped but no re-connection */
172 /* LED status: Always off */
173 /* 7. Status: From one connection(2.4G or 5G) to change to another band */
174 /* LED status: Amber/Blue =>Slow blinking, Amber then Blue per 500ms */
175 /* */
176 /* INPUTS */
177 /* dev : device pointer */
178 /* */
179 /* OUTPUTS */
180 /* None */
181 /* */
182 /* AUTHOR */
183 /* Shang-Chun Liu Atheros Communications, INC. 2007.11 */
184 /* */
185 /******************************************************************************/
186 void zfLedCtrlType2_scan(zdev_t* dev);
187
188 void zfLedCtrlType2(zdev_t* dev)
189 {
190 u16_t OperateLED;
191 zmw_get_wlan_dev(dev);
192
193 if (zfStaIsConnected(dev) != TRUE)
194 {
195 // Disconnect state
196 if(wd->ledStruct.counter % 4 != 0)
197 {
198 // Update LED each 400ms(4*100)
199 // Prevent this situation
200 // _______ ___
201 // LED[0] ON | | | x |
202 // ------ OFF->+-+-+-+-+-+-+-+-+-+-+-+->>>...
203 // LED[1] ON
204 //
205 return;
206 }
207
208 if (((wd->state == ZM_WLAN_STATE_DISABLED) && (wd->sta.bChannelScan))
209 || ((wd->state != ZM_WLAN_STATE_DISABLED) && (wd->sta.bAutoReconnect)))
210 {
211 // Scan/AutoReconnect state
212 zfLedCtrlType2_scan(dev);
213 }
214 else
215 {
216 // Neither Connected nor Scan
217 zfHpLedCtrl(dev, 0, 0);
218 zfHpLedCtrl(dev, 1, 0);
219 }
220 }
221 else
222 {
223 if( wd->sta.bChannelScan )
224 {
225 // Scan state
226 if(wd->ledStruct.counter % 4 != 0)
227 return;
228 zfLedCtrlType2_scan(dev);
229 return;
230 }
231
232 if(wd->frequency < 3000)
233 {
234 OperateLED = 0; // LED[0]: work on 2.4G (b/g band)
235 zfHpLedCtrl(dev, 1, 0);
236 }
237 else
238 {
239 OperateLED = 1; // LED[1]: work on 5G (a band)
240 zfHpLedCtrl(dev, 0, 0);
241 }
242
243 if ((zfPowerSavingMgrIsSleeping(dev)) && ((wd->ledStruct.ledMode[OperateLED] & 0x8) == 0))
244 {
245 // If Sleeping, turn OFF
246 zfHpLedCtrl(dev, OperateLED, 0);
247 }
248 else
249 {
250 //Connect state
251 if ((wd->ledStruct.counter & 1) == 0) // even
252 {
253 // No traffic, always ON
254 zfHpLedCtrl(dev, OperateLED, 1);
255 }
256 else // odd
257 {
258 if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0))
259 {
260 // If have traffic, turn OFF
261 // _____ _ _ _ _____
262 // LED[Operate] ON | | | | | | | |
263 // ------------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+->>>...
264 //
265 wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0;
266 zfHpLedCtrl(dev, OperateLED, 0);
267 }
268 }
269 }
270 }
271 }
272
273 void zfLedCtrlType2_scan(zdev_t* dev)
274 {
275 zmw_get_wlan_dev(dev);
276
277 // When doing scan, blink(Amber/Blue) and off per 500ms (about 400ms in our driver)
278 // _______ _______
279 // LED[0] ON | | 8 12 | |
280 // ------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+->>>...
281 // LED[1] ON 0 4 |_______| 0 3
282 //
283
284 switch(wd->ledStruct.counter % 16)
285 {
286 case 0: // case 0~3, LED[0] on
287 if(wd->supportMode & ZM_WIRELESS_MODE_24)
288 {
289 zfHpLedCtrl(dev, 0, 1);
290 zfHpLedCtrl(dev, 1, 0);
291 }
292 else
293 {
294 zfHpLedCtrl(dev, 1, 1);
295 zfHpLedCtrl(dev, 0, 0);
296 }
297 break;
298
299 case 8: // case 8~11, LED[1] on
300 if(wd->supportMode & ZM_WIRELESS_MODE_5)
301 {
302 zfHpLedCtrl(dev, 1, 1);
303 zfHpLedCtrl(dev, 0, 0);
304 }
305 else
306 {
307 zfHpLedCtrl(dev, 0, 1);
308 zfHpLedCtrl(dev, 1, 0);
309 }
310 break;
311
312 default: // others, all off
313 zfHpLedCtrl(dev, 0, 0);
314 zfHpLedCtrl(dev, 1, 0);
315 break;
316 }
317 }
318
319 /**********************************************************************************/
320 /* */
321 /* FUNCTION DESCRIPTION zfLedCtrlType3 */
322 /* Customize for Netgear Single-LED state ((bug#32243)) */
323 /* */
324 /* ¡EOff: when the adapter is disabled or hasn't started to associate with AP */
325 /* yet. */
326 /* ¡EOn: Once adpater associate with AP successfully */
327 /* ¡ESlow blinking: whenever adapters do site-survey or try to associate with AP */
328 /* - If there is a connection already, and adapters do site-survey or */
329 /* re-associate action, the LED should keep LED backgraoud as ON, thus */
330 /* the blinking behavior SHOULD be OFF (200ms) - ON (800ms) and continue this*/
331 /* cycle. */
332 /* - If there is no connection yet, and adapters start to do site-survey or */
333 /* associate action, the LED should keep LED background as OFF, thus the */
334 /* blinking behavior SHOULD be ON (200ms) - OFF (800ms) and continue this */
335 /* cycle. */
336 /* - For the case that associate fail, adpater should keep associating, and the*/
337 /* LED should also keep slow blinking. */
338 /* ¡EQuick blinking: to blink OFF-ON cycle for each time that traffic packet is */
339 /* received or is transmitted. */
340 /* */
341 /* INPUTS */
342 /* dev : device pointer */
343 /* */
344 /* OUTPUTS */
345 /* None */
346 /* */
347 /* AUTHOR */
348 /* Shang-Chun Liu Atheros Communications, INC. 2008.01 */
349 /* */
350 /**********************************************************************************/
351 void zfLedCtrlType3_scan(zdev_t* dev, u16_t isConnect);
352
353 void zfLedCtrlType3(zdev_t* dev)
354 {
355 zmw_get_wlan_dev(dev);
356
357 if (zfStaIsConnected(dev) != TRUE)
358 {
359 // Disconnect state
360 if(wd->ledStruct.counter % 2 != 0)
361 {
362 // Update LED each 200ms(2*100)
363 // Prevent this situation
364 // ___ _
365 // LED[0] ON | | |x|
366 // ------ OFF->+-+-+-+-+-+-+->>>...
367 //
368 return;
369 }
370
371 if (((wd->state == ZM_WLAN_STATE_DISABLED) && (wd->sta.bChannelScan))
372 || ((wd->state != ZM_WLAN_STATE_DISABLED) && (wd->sta.bAutoReconnect)))
373 {
374 // Scan/AutoReconnect state
375 zfLedCtrlType3_scan(dev, 0);
376 }
377 else
378 {
379 // Neither Connected nor Scan
380 zfHpLedCtrl(dev, 0, 0);
381 zfHpLedCtrl(dev, 1, 0);
382 }
383 }
384 else
385 {
386 if( wd->sta.bChannelScan )
387 {
388 // Scan state
389 if(wd->ledStruct.counter % 2 != 0)
390 return;
391 zfLedCtrlType3_scan(dev, 1);
392 return;
393 }
394
395 if ((zfPowerSavingMgrIsSleeping(dev)) && ((wd->ledStruct.ledMode[0] & 0x8) == 0))
396 {
397 // If Sleeping, turn OFF
398 zfHpLedCtrl(dev, 0, 0);
399 zfHpLedCtrl(dev, 1, 0);
400 }
401 else
402 {
403 //Connect state
404 if ((wd->ledStruct.counter & 1) == 0) // even
405 {
406 // No traffic, always ON
407 zfHpLedCtrl(dev, 0, 1);
408 zfHpLedCtrl(dev, 1, 1);
409 }
410 else // odd
411 {
412 if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0))
413 {
414 // If have traffic, turn OFF
415 // _____ _ _ _ _____
416 // LED[Operate] ON | | | | | | | |
417 // ------------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+->>>...
418 //
419 wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0;
420 zfHpLedCtrl(dev, 0, 0);
421 zfHpLedCtrl(dev, 1, 0);
422 }
423 }
424 }
425 }
426 }
427
428 void zfLedCtrlType3_scan(zdev_t* dev, u16_t isConnect)
429 {
430 u32_t ton, toff, tmp;
431 zmw_get_wlan_dev(dev);
432
433 // Doing scan when :
434 // 1. Disconnected: ON (200ms) - OFF (800ms) (200ms-600ms in our driver)
435 // ___ ___ ___
436 // LED[0] ON | | | | | |
437 // ------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+->>>...
438 // 0 2 4 6 8 10 12 14 16
439 // 2. Connected: ON (800ms) - OFF (200ms) (600ms-200ms in our driver)
440 // ___________ ___________ ______
441 // LED[0] ON | | | | |
442 // ------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+->>>...
443 // 0 2 4 6 8 10 12 14 16
444
445 //Scan state
446 if(!isConnect)
447 ton = 2, toff = 6;
448 else
449 ton = 6, toff = 2;
450
451 if ((ton + toff) != 0)
452 {
453 tmp = wd->ledStruct.counter % (ton+toff);
454 if (tmp < ton)
455 {
456 zfHpLedCtrl(dev, 0, 1);
457 zfHpLedCtrl(dev, 1, 1);
458 }
459 else
460 {
461 zfHpLedCtrl(dev, 0, 0);
462 zfHpLedCtrl(dev, 1, 0);
463 }
464 }
465 }
466
467 /******************************************************************************/
468 /* */
469 /* FUNCTION DESCRIPTION zfLedCtrl_BlinkWhenScan_Alpha */
470 /* Customize for Alpha/DLink LED */
471 /* - Blink LED 12 times within 3 seconds when doing Active Scan */
472 /* ___ ___ ___ ___ */
473 /* LED[0] ON | | | | | | | | */
474 /* -------OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+--+-->>>... */
475 /* */
476 /* INPUTS */
477 /* dev : device pointer */
478 /* */
479 /* OUTPUTS */
480 /* None */
481 /* */
482 /* AUTHOR */
483 /* Shang-Chun Liu Atheros Communications, INC. 2007.11 */
484 /* */
485 /******************************************************************************/
486 void zfLedCtrl_BlinkWhenScan_Alpha(zdev_t* dev)
487 {
488 static u32_t counter = 0;
489 zmw_get_wlan_dev(dev);
490
491 if(counter > 34) // counter for 3 sec
492 {
493 wd->ledStruct.LEDCtrlFlag &= ~(u8_t)ZM_LED_CTRL_FLAG_ALPHA;
494 counter = 0;
495 }
496
497 if( (counter % 3) < 2)
498 zfHpLedCtrl(dev, 0, 1);
499 else
500 zfHpLedCtrl(dev, 0, 0);
501
502 counter++;
503 }
504
505
506 /************************************************************************/
507 /* */
508 /* FUNCTION DESCRIPTION zfLed100msCtrl */
509 /* LED 100 milliseconds timer. */
510 /* */
511 /* INPUTS */
512 /* dev : device pointer */
513 /* */
514 /* OUTPUTS */
515 /* None */
516 /* */
517 /* AUTHOR */
518 /* Stephen Chen Atheros Communications, INC. 2007.6 */
519 /* */
520 /************************************************************************/
521 void zfLed100msCtrl(zdev_t* dev)
522 {
523 zmw_get_wlan_dev(dev);
524
525 wd->ledStruct.counter++;
526
527 if(wd->ledStruct.LEDCtrlFlag)
528 {
529 switch(wd->ledStruct.LEDCtrlFlag) {
530 case ZM_LED_CTRL_FLAG_ALPHA:
531 zfLedCtrl_BlinkWhenScan_Alpha(dev);
532 break;
533 }
534 }
535 else
536 {
537 switch(wd->ledStruct.LEDCtrlType) {
538 case 1: // Traditional 1 LED
539 zfLedCtrlType1(dev);
540 break;
541
542 case 2: // Dual-LEDs for Netgear
543 zfLedCtrlType2(dev);
544 break;
545
546 case 3: // Single-LED for Netgear (WN111v2)
547 zfLedCtrlType3(dev);
548 break;
549
550 default:
551 zfLedCtrlType1(dev);
552 break;
553 }
554 }
555 }
556