3 #define STATUS_IMAGE_CHECKSUM_MISMATCH -199
4 #define EVENT_SIGNALED 1
6 static B_UINT16
CFG_CalculateChecksum(B_UINT8
*pu8Buffer
, B_UINT32 u32Size
)
8 B_UINT16 u16CheckSum
= 0;
10 u16CheckSum
+= (B_UINT8
)~(*pu8Buffer
);
16 BOOLEAN
IsReqGpioIsLedInNVM(struct bcm_mini_adapter
*Adapter
, UINT gpios
)
19 Status
= (Adapter
->gpioBitMap
& gpios
) ^ gpios
;
26 static INT
LED_Blink(struct bcm_mini_adapter
*Adapter
, UINT GPIO_Num
, UCHAR uiLedIndex
,
27 ULONG timeout
, INT num_of_time
, enum bcm_led_events currdriverstate
)
29 int Status
= STATUS_SUCCESS
;
30 BOOLEAN bInfinite
= FALSE
;
32 /* Check if num_of_time is -ve. If yes, blink led in infinite loop */
33 if (num_of_time
< 0) {
38 if (currdriverstate
== Adapter
->DriverState
)
39 TURN_ON_LED(GPIO_Num
, uiLedIndex
);
41 /* Wait for timeout after setting on the LED */
42 Status
= wait_event_interruptible_timeout(
43 Adapter
->LEDInfo
.notify_led_event
,
44 currdriverstate
!= Adapter
->DriverState
||
45 kthread_should_stop(),
46 msecs_to_jiffies(timeout
));
48 if (kthread_should_stop()) {
49 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
51 "Led thread got signal to exit..hence exiting");
52 Adapter
->LEDInfo
.led_thread_running
=
53 BCM_LED_THREAD_DISABLED
;
54 TURN_OFF_LED(GPIO_Num
, uiLedIndex
);
55 Status
= EVENT_SIGNALED
;
59 TURN_OFF_LED(GPIO_Num
, uiLedIndex
);
60 Status
= EVENT_SIGNALED
;
64 TURN_OFF_LED(GPIO_Num
, uiLedIndex
);
65 Status
= wait_event_interruptible_timeout(
66 Adapter
->LEDInfo
.notify_led_event
,
67 currdriverstate
!= Adapter
->DriverState
||
68 kthread_should_stop(),
69 msecs_to_jiffies(timeout
));
70 if (bInfinite
== FALSE
)
76 static INT
ScaleRateofTransfer(ULONG rate
)
80 else if ((rate
> 3) && (rate
<= 100))
82 else if ((rate
> 100) && (rate
<= 200))
84 else if ((rate
> 200) && (rate
<= 300))
86 else if ((rate
> 300) && (rate
<= 400))
88 else if ((rate
> 400) && (rate
<= 500))
90 else if ((rate
> 500) && (rate
<= 600))
93 return MAX_NUM_OF_BLINKS
;
98 static INT
LED_Proportional_Blink(struct bcm_mini_adapter
*Adapter
, UCHAR GPIO_Num_tx
,
99 UCHAR uiTxLedIndex
, UCHAR GPIO_Num_rx
, UCHAR uiRxLedIndex
,
100 enum bcm_led_events currdriverstate
)
102 /* Initial values of TX and RX packets */
103 ULONG64 Initial_num_of_packts_tx
= 0, Initial_num_of_packts_rx
= 0;
104 /* values of TX and RX packets after 1 sec */
105 ULONG64 Final_num_of_packts_tx
= 0, Final_num_of_packts_rx
= 0;
106 /* Rate of transfer of Tx and Rx in 1 sec */
107 ULONG64 rate_of_transfer_tx
= 0, rate_of_transfer_rx
= 0;
108 int Status
= STATUS_SUCCESS
;
109 INT num_of_time
= 0, num_of_time_tx
= 0, num_of_time_rx
= 0;
111 BOOLEAN bBlinkBothLED
= TRUE
;
112 /* UINT GPIO_num = DISABLE_GPIO_NUM; */
115 /* Read initial value of packets sent/received */
116 Initial_num_of_packts_tx
= Adapter
->dev
->stats
.tx_packets
;
117 Initial_num_of_packts_rx
= Adapter
->dev
->stats
.rx_packets
;
119 /* Scale the rate of transfer to no of blinks. */
120 num_of_time_tx
= ScaleRateofTransfer((ULONG
)rate_of_transfer_tx
);
121 num_of_time_rx
= ScaleRateofTransfer((ULONG
)rate_of_transfer_rx
);
123 while ((Adapter
->device_removed
== FALSE
)) {
126 * Blink Tx and Rx LED when both Tx and Rx is
127 * in normal bandwidth
131 * Assign minimum number of blinks of
134 if (num_of_time_tx
> num_of_time_rx
)
135 num_of_time
= num_of_time_rx
;
137 num_of_time
= num_of_time_tx
;
138 if (num_of_time
> 0) {
139 /* Blink both Tx and Rx LEDs */
140 if (LED_Blink(Adapter
, 1 << GPIO_Num_tx
,
141 uiTxLedIndex
, timeout
,
142 num_of_time
, currdriverstate
)
144 return EVENT_SIGNALED
;
146 if (LED_Blink(Adapter
, 1 << GPIO_Num_rx
,
147 uiRxLedIndex
, timeout
,
148 num_of_time
, currdriverstate
)
150 return EVENT_SIGNALED
;
154 if (num_of_time
== num_of_time_tx
) {
155 /* Blink pending rate of Rx */
156 if (LED_Blink(Adapter
, (1 << GPIO_Num_rx
),
157 uiRxLedIndex
, timeout
,
158 num_of_time_rx
-num_of_time
,
161 return EVENT_SIGNALED
;
163 num_of_time
= num_of_time_rx
;
165 /* Blink pending rate of Tx */
166 if (LED_Blink(Adapter
, 1 << GPIO_Num_tx
,
167 uiTxLedIndex
, timeout
,
168 num_of_time_tx
-num_of_time
,
171 return EVENT_SIGNALED
;
173 num_of_time
= num_of_time_tx
;
176 if (num_of_time
== num_of_time_tx
) {
177 /* Blink pending rate of Rx */
178 if (LED_Blink(Adapter
, 1 << GPIO_Num_tx
,
179 uiTxLedIndex
, timeout
,
180 num_of_time
, currdriverstate
)
182 return EVENT_SIGNALED
;
184 /* Blink pending rate of Tx */
185 if (LED_Blink(Adapter
, 1 << GPIO_Num_rx
,
186 uiRxLedIndex
, timeout
,
187 num_of_time
, currdriverstate
)
189 return EVENT_SIGNALED
;
194 * If Tx/Rx rate is less than maximum blinks per second,
195 * wait till delay completes to 1 second
197 remDelay
= MAX_NUM_OF_BLINKS
- num_of_time
;
199 timeout
= 100 * remDelay
;
200 Status
= wait_event_interruptible_timeout(
201 Adapter
->LEDInfo
.notify_led_event
,
202 currdriverstate
!= Adapter
->DriverState
203 || kthread_should_stop(),
204 msecs_to_jiffies(timeout
));
206 if (kthread_should_stop()) {
207 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
,
208 LED_DUMP_INFO
, DBG_LVL_ALL
,
209 "Led thread got signal to exit..hence exiting");
210 Adapter
->LEDInfo
.led_thread_running
=
211 BCM_LED_THREAD_DISABLED
;
212 return EVENT_SIGNALED
;
215 return EVENT_SIGNALED
;
218 /* Turn off both Tx and Rx LEDs before next second */
219 TURN_OFF_LED(1 << GPIO_Num_tx
, uiTxLedIndex
);
220 TURN_OFF_LED(1 << GPIO_Num_rx
, uiTxLedIndex
);
223 * Read the Tx & Rx packets transmission after 1 second and
224 * calculate rate of transfer
226 Final_num_of_packts_tx
= Adapter
->dev
->stats
.tx_packets
;
227 Final_num_of_packts_rx
= Adapter
->dev
->stats
.rx_packets
;
229 rate_of_transfer_tx
= Final_num_of_packts_tx
-
230 Initial_num_of_packts_tx
;
231 rate_of_transfer_rx
= Final_num_of_packts_rx
-
232 Initial_num_of_packts_rx
;
234 /* Read initial value of packets sent/received */
235 Initial_num_of_packts_tx
= Final_num_of_packts_tx
;
236 Initial_num_of_packts_rx
= Final_num_of_packts_rx
;
238 /* Scale the rate of transfer to no of blinks. */
240 ScaleRateofTransfer((ULONG
)rate_of_transfer_tx
);
242 ScaleRateofTransfer((ULONG
)rate_of_transfer_rx
);
249 * -----------------------------------------------------------------------------
250 * Procedure: ValidateDSDParamsChecksum
252 * Description: Reads DSD Params and validates checkusm.
255 * Adapter - Pointer to Adapter structure.
256 * ulParamOffset - Start offset of the DSD parameter to be read and
258 * usParamLen - Length of the DSD Parameter.
262 * -----------------------------------------------------------------------------
264 static INT
ValidateDSDParamsChecksum(struct bcm_mini_adapter
*Adapter
, ULONG ulParamOffset
,
267 INT Status
= STATUS_SUCCESS
;
268 PUCHAR puBuffer
= NULL
;
269 USHORT usChksmOrg
= 0;
270 USHORT usChecksumCalculated
= 0;
272 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
, DBG_LVL_ALL
,
273 "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",
274 ulParamOffset
, usParamLen
);
276 puBuffer
= kmalloc(usParamLen
, GFP_KERNEL
);
278 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
280 "LED Thread: ValidateDSDParamsChecksum Allocation failed");
285 /* Read the DSD data from the parameter offset. */
286 if (STATUS_SUCCESS
!= BeceemNVMRead(Adapter
, (PUINT
)puBuffer
,
287 ulParamOffset
, usParamLen
)) {
288 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
290 "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
291 Status
= STATUS_IMAGE_CHECKSUM_MISMATCH
;
295 /* Calculate the checksum of the data read from the DSD parameter. */
296 usChecksumCalculated
= CFG_CalculateChecksum(puBuffer
, usParamLen
);
297 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
, DBG_LVL_ALL
,
298 "LED Thread: usCheckSumCalculated = 0x%x\n",
299 usChecksumCalculated
);
302 * End of the DSD parameter will have a TWO bytes checksum stored in it.
303 * Read it and compare with the calculated Checksum.
305 if (STATUS_SUCCESS
!= BeceemNVMRead(Adapter
, (PUINT
)&usChksmOrg
,
306 ulParamOffset
+usParamLen
, 2)) {
307 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
309 "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
310 Status
= STATUS_IMAGE_CHECKSUM_MISMATCH
;
313 usChksmOrg
= ntohs(usChksmOrg
);
314 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
, DBG_LVL_ALL
,
315 "LED Thread: usChksmOrg = 0x%x", usChksmOrg
);
318 * Compare the checksum calculated with the checksum read
321 if (usChecksumCalculated
^ usChksmOrg
) {
322 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
324 "LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
325 Status
= STATUS_IMAGE_CHECKSUM_MISMATCH
;
336 * -----------------------------------------------------------------------------
337 * Procedure: ValidateHWParmStructure
339 * Description: Validates HW Parameters.
342 * Adapter - Pointer to Adapter structure.
343 * ulHwParamOffset - Start offset of the HW parameter Section to be read
348 * -----------------------------------------------------------------------------
350 static INT
ValidateHWParmStructure(struct bcm_mini_adapter
*Adapter
, ULONG ulHwParamOffset
)
353 INT Status
= STATUS_SUCCESS
;
354 USHORT HwParamLen
= 0;
356 * Add DSD start offset to the hwParamOffset to get
357 * the actual address.
359 ulHwParamOffset
+= DSD_START_OFFSET
;
361 /* Read the Length of HW_PARAM structure */
362 BeceemNVMRead(Adapter
, (PUINT
)&HwParamLen
, ulHwParamOffset
, 2);
363 HwParamLen
= ntohs(HwParamLen
);
364 if (0 == HwParamLen
|| HwParamLen
> Adapter
->uiNVMDSDSize
)
365 return STATUS_IMAGE_CHECKSUM_MISMATCH
;
367 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
, DBG_LVL_ALL
,
368 "LED Thread:HwParamLen = 0x%x", HwParamLen
);
369 Status
= ValidateDSDParamsChecksum(Adapter
, ulHwParamOffset
,
372 } /* ValidateHWParmStructure() */
374 static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter
*Adapter
,
377 int Status
= STATUS_SUCCESS
;
379 ULONG dwReadValue
= 0;
380 USHORT usHwParamData
= 0;
381 USHORT usEEPROMVersion
= 0;
383 UCHAR ucGPIOInfo
[32] = {0};
385 BeceemNVMRead(Adapter
, (PUINT
)&usEEPROMVersion
,
386 EEPROM_VERSION_OFFSET
, 2);
388 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
, DBG_LVL_ALL
,
389 "usEEPROMVersion: Minor:0x%X Major:0x%x",
390 usEEPROMVersion
&0xFF, ((usEEPROMVersion
>>8)&0xFF));
393 if (((usEEPROMVersion
>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION
) {
394 BeceemNVMRead(Adapter
, (PUINT
)&usHwParamData
,
395 EEPROM_HW_PARAM_POINTER_ADDRESS
, 2);
396 usHwParamData
= ntohs(usHwParamData
);
397 dwReadValue
= usHwParamData
;
400 * Validate Compatibility section and then read HW param
401 * if compatibility section is valid.
403 Status
= ValidateDSDParamsChecksum(Adapter
,
405 COMPATIBILITY_SECTION_LENGTH_MAP5
);
407 if (Status
!= STATUS_SUCCESS
)
410 BeceemNVMRead(Adapter
, (PUINT
)&dwReadValue
,
411 EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5
, 4);
412 dwReadValue
= ntohl(dwReadValue
);
416 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
, DBG_LVL_ALL
,
417 "LED Thread: Start address of HW_PARAM structure = 0x%lx",
421 * Validate if the address read out is within the DSD.
422 * Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
423 * lower limit should be above DSD_START_OFFSET and
424 * upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
426 if (dwReadValue
< DSD_START_OFFSET
||
427 dwReadValue
> (Adapter
->uiNVMDSDSize
-DSD_START_OFFSET
))
428 return STATUS_IMAGE_CHECKSUM_MISMATCH
;
430 Status
= ValidateHWParmStructure(Adapter
, dwReadValue
);
435 * Add DSD_START_OFFSET to the offset read from the EEPROM.
436 * This will give the actual start HW Parameters start address.
437 * To read GPIO section, add GPIO offset further.
441 DSD_START_OFFSET
; /* = start address of hw param section. */
442 dwReadValue
+= GPIO_SECTION_START_OFFSET
;
443 /* = GPIO start offset within HW Param section. */
446 * Read the GPIO values for 32 GPIOs from EEPROM and map the function
447 * number to GPIO pin number to GPIO_Array
449 BeceemNVMRead(Adapter
, (UINT
*)ucGPIOInfo
, dwReadValue
, 32);
450 for (ucIndex
= 0; ucIndex
< 32; ucIndex
++) {
452 switch (ucGPIOInfo
[ucIndex
]) {
454 GPIO_Array
[RED_LED
] = ucIndex
;
455 Adapter
->gpioBitMap
|= (1 << ucIndex
);
458 GPIO_Array
[BLUE_LED
] = ucIndex
;
459 Adapter
->gpioBitMap
|= (1 << ucIndex
);
462 GPIO_Array
[YELLOW_LED
] = ucIndex
;
463 Adapter
->gpioBitMap
|= (1 << ucIndex
);
466 GPIO_Array
[GREEN_LED
] = ucIndex
;
467 Adapter
->gpioBitMap
|= (1 << ucIndex
);
474 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
, DBG_LVL_ALL
,
475 "GPIO's bit map correspond to LED :0x%X", Adapter
->gpioBitMap
);
480 static int ReadConfigFileStructure(struct bcm_mini_adapter
*Adapter
,
481 BOOLEAN
*bEnableThread
)
483 int Status
= STATUS_SUCCESS
;
484 /* Array to store GPIO numbers from EEPROM */
485 UCHAR GPIO_Array
[NUM_OF_LEDS
+1];
487 UINT uiNum_of_LED_Type
= 0;
488 PUCHAR puCFGData
= NULL
;
490 memset(GPIO_Array
, DISABLE_GPIO_NUM
, NUM_OF_LEDS
+1);
492 if (!Adapter
->pstargetparams
|| IS_ERR(Adapter
->pstargetparams
)) {
493 BCM_DEBUG_PRINT (Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
494 DBG_LVL_ALL
, "Target Params not Avail.\n");
498 /* Populate GPIO_Array with GPIO numbers for LED functions */
499 /* Read the GPIO numbers from EEPROM */
500 Status
= ReadLEDInformationFromEEPROM(Adapter
, GPIO_Array
);
501 if (Status
== STATUS_IMAGE_CHECKSUM_MISMATCH
) {
502 *bEnableThread
= FALSE
;
503 return STATUS_SUCCESS
;
505 *bEnableThread
= FALSE
;
510 * CONFIG file read successfully. Deallocate the memory of
511 * uiFileNameBufferSize
513 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
, DBG_LVL_ALL
,
514 "LED Thread: Config file read successfully\n");
515 puCFGData
= (PUCHAR
) &Adapter
->pstargetparams
->HostDrvrConfig1
;
518 * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
519 * will have the information of LED type, LED on state for different
520 * driver state and LED blink state.
523 for (uiIndex
= 0; uiIndex
< NUM_OF_LEDS
; uiIndex
++) {
527 * Check Bit 8 for polarity. If it is set,
528 * polarity is reverse polarity
531 Adapter
->LEDInfo
.LEDState
[uiIndex
].BitPolarity
= 0;
532 /* unset the bit 8 */
533 bData
= bData
& 0x7f;
536 Adapter
->LEDInfo
.LEDState
[uiIndex
].LED_Type
= bData
;
537 if (bData
<= NUM_OF_LEDS
)
538 Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
=
541 Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
=
546 Adapter
->LEDInfo
.LEDState
[uiIndex
].LED_On_State
= bData
;
549 Adapter
->LEDInfo
.LEDState
[uiIndex
].LED_Blink_State
= bData
;
554 * Check if all the LED settings are disabled. If it is disabled,
555 * dont launch the LED control thread.
557 for (uiIndex
= 0; uiIndex
< NUM_OF_LEDS
; uiIndex
++) {
558 if ((Adapter
->LEDInfo
.LEDState
[uiIndex
].LED_Type
== DISABLE_GPIO_NUM
) ||
559 (Adapter
->LEDInfo
.LEDState
[uiIndex
].LED_Type
== 0x7f) ||
560 (Adapter
->LEDInfo
.LEDState
[uiIndex
].LED_Type
== 0))
563 if (uiNum_of_LED_Type
>= NUM_OF_LEDS
)
564 *bEnableThread
= FALSE
;
570 * -----------------------------------------------------------------------------
571 * Procedure: LedGpioInit
573 * Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode
574 * and make the initial state to be OFF.
577 * Adapter - Pointer to MINI_ADAPTER structure.
581 * -----------------------------------------------------------------------------
583 static VOID
LedGpioInit(struct bcm_mini_adapter
*Adapter
)
585 UINT uiResetValue
= 0;
588 /* Set all LED GPIO Mode to output mode */
589 if (rdmalt(Adapter
, GPIO_MODE_REGISTER
, &uiResetValue
,
590 sizeof(uiResetValue
)) < 0)
591 BCM_DEBUG_PRINT (Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
592 DBG_LVL_ALL
, "LED Thread: RDM Failed\n");
593 for (uiIndex
= 0; uiIndex
< NUM_OF_LEDS
; uiIndex
++) {
594 if (Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
!=
596 uiResetValue
|= (1 << Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
);
597 TURN_OFF_LED(1 << Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
,
600 if (wrmalt(Adapter
, GPIO_MODE_REGISTER
, &uiResetValue
,
601 sizeof(uiResetValue
)) < 0)
602 BCM_DEBUG_PRINT (Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
603 DBG_LVL_ALL
, "LED Thread: WRM Failed\n");
605 Adapter
->LEDInfo
.bIdle_led_off
= FALSE
;
608 static INT
BcmGetGPIOPinInfo(struct bcm_mini_adapter
*Adapter
, UCHAR
*GPIO_num_tx
,
609 UCHAR
*GPIO_num_rx
, UCHAR
*uiLedTxIndex
, UCHAR
*uiLedRxIndex
,
610 enum bcm_led_events currdriverstate
)
614 *GPIO_num_tx
= DISABLE_GPIO_NUM
;
615 *GPIO_num_rx
= DISABLE_GPIO_NUM
;
617 for (uiIndex
= 0; uiIndex
< NUM_OF_LEDS
; uiIndex
++) {
619 if ((currdriverstate
== NORMAL_OPERATION
) ||
620 (currdriverstate
== IDLEMODE_EXIT
) ||
621 (currdriverstate
== FW_DOWNLOAD
)) {
622 if (Adapter
->LEDInfo
.LEDState
[uiIndex
].LED_Blink_State
&
624 if (Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
625 != DISABLE_GPIO_NUM
) {
626 if (*GPIO_num_tx
== DISABLE_GPIO_NUM
) {
627 *GPIO_num_tx
= Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
;
628 *uiLedTxIndex
= uiIndex
;
630 *GPIO_num_rx
= Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
;
631 *uiLedRxIndex
= uiIndex
;
636 if (Adapter
->LEDInfo
.LEDState
[uiIndex
].LED_On_State
638 if (Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
639 != DISABLE_GPIO_NUM
) {
640 *GPIO_num_tx
= Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
;
641 *uiLedTxIndex
= uiIndex
;
646 return STATUS_SUCCESS
;
648 static VOID
LEDControlThread(struct bcm_mini_adapter
*Adapter
)
652 UCHAR uiLedIndex
= 0;
653 UINT uiResetValue
= 0;
654 enum bcm_led_events currdriverstate
= 0;
659 UCHAR dummyGPIONum
= 0;
660 UCHAR dummyIndex
= 0;
662 /* currdriverstate = Adapter->DriverState; */
663 Adapter
->LEDInfo
.bIdleMode_tx_from_host
= FALSE
;
666 * Wait till event is triggered
668 * wait_event(Adapter->LEDInfo.notify_led_event,
669 * currdriverstate!= Adapter->DriverState);
672 GPIO_num
= DISABLE_GPIO_NUM
;
675 /* Wait till event is triggered */
676 if ((GPIO_num
== DISABLE_GPIO_NUM
)
678 ((currdriverstate
!= FW_DOWNLOAD
) &&
679 (currdriverstate
!= NORMAL_OPERATION
) &&
680 (currdriverstate
!= LOWPOWER_MODE_ENTER
))
682 (currdriverstate
== LED_THREAD_INACTIVE
))
683 Status
= wait_event_interruptible(
684 Adapter
->LEDInfo
.notify_led_event
,
685 currdriverstate
!= Adapter
->DriverState
686 || kthread_should_stop());
688 if (kthread_should_stop() || Adapter
->device_removed
) {
689 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
691 "Led thread got signal to exit..hence exiting");
692 Adapter
->LEDInfo
.led_thread_running
=
693 BCM_LED_THREAD_DISABLED
;
694 TURN_OFF_LED(1 << GPIO_num
, uiLedIndex
);
695 return; /* STATUS_FAILURE; */
698 if (GPIO_num
!= DISABLE_GPIO_NUM
)
699 TURN_OFF_LED(1 << GPIO_num
, uiLedIndex
);
701 if (Adapter
->LEDInfo
.bLedInitDone
== FALSE
) {
702 LedGpioInit(Adapter
);
703 Adapter
->LEDInfo
.bLedInitDone
= TRUE
;
706 switch (Adapter
->DriverState
) {
708 currdriverstate
= DRIVER_INIT
;
709 /* Adapter->DriverState; */
710 BcmGetGPIOPinInfo(Adapter
, &GPIO_num
, &dummyGPIONum
,
711 &uiLedIndex
, &dummyIndex
, currdriverstate
);
713 if (GPIO_num
!= DISABLE_GPIO_NUM
)
714 TURN_ON_LED(1 << GPIO_num
, uiLedIndex
);
719 * BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
720 * LED_DUMP_INFO, DBG_LVL_ALL,
721 * "LED Thread: FW_DN_DONE called\n");
723 currdriverstate
= FW_DOWNLOAD
;
724 BcmGetGPIOPinInfo(Adapter
, &GPIO_num
, &dummyGPIONum
,
725 &uiLedIndex
, &dummyIndex
, currdriverstate
);
727 if (GPIO_num
!= DISABLE_GPIO_NUM
) {
729 LED_Blink(Adapter
, 1 << GPIO_num
, uiLedIndex
,
730 timeout
, -1, currdriverstate
);
733 case FW_DOWNLOAD_DONE
:
734 currdriverstate
= FW_DOWNLOAD_DONE
;
735 BcmGetGPIOPinInfo(Adapter
, &GPIO_num
, &dummyGPIONum
,
736 &uiLedIndex
, &dummyIndex
, currdriverstate
);
737 if (GPIO_num
!= DISABLE_GPIO_NUM
)
738 TURN_ON_LED(1 << GPIO_num
, uiLedIndex
);
743 * no break, continue to NO_NETWORK_ENTRY
746 case NO_NETWORK_ENTRY
:
747 currdriverstate
= NO_NETWORK_ENTRY
;
748 BcmGetGPIOPinInfo(Adapter
, &GPIO_num
, &dummyGPIONum
,
749 &uiLedIndex
, &dummyGPIONum
, currdriverstate
);
750 if (GPIO_num
!= DISABLE_GPIO_NUM
)
751 TURN_ON_LED(1 << GPIO_num
, uiLedIndex
);
753 case NORMAL_OPERATION
:
755 UCHAR GPIO_num_tx
= DISABLE_GPIO_NUM
;
756 UCHAR GPIO_num_rx
= DISABLE_GPIO_NUM
;
759 currdriverstate
= NORMAL_OPERATION
;
760 Adapter
->LEDInfo
.bIdle_led_off
= FALSE
;
762 BcmGetGPIOPinInfo(Adapter
, &GPIO_num_tx
,
763 &GPIO_num_rx
, &uiLEDTx
, &uiLEDRx
,
765 if ((GPIO_num_tx
== DISABLE_GPIO_NUM
) &&
768 GPIO_num
= DISABLE_GPIO_NUM
;
771 * If single LED is selected, use same
774 if (GPIO_num_tx
== DISABLE_GPIO_NUM
) {
775 GPIO_num_tx
= GPIO_num_rx
;
777 } else if (GPIO_num_rx
==
779 GPIO_num_rx
= GPIO_num_tx
;
783 * Blink the LED in proportionate
784 * to Tx and Rx transmissions.
786 LED_Proportional_Blink(Adapter
,
787 GPIO_num_tx
, uiLEDTx
,
788 GPIO_num_rx
, uiLEDRx
,
793 case LOWPOWER_MODE_ENTER
:
794 currdriverstate
= LOWPOWER_MODE_ENTER
;
795 if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING
==
796 Adapter
->ulPowerSaveMode
) {
797 /* Turn OFF all the LED */
799 for (uiIndex
= 0; uiIndex
< NUM_OF_LEDS
; uiIndex
++) {
800 if (Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
!= DISABLE_GPIO_NUM
)
801 TURN_OFF_LED((1 << Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
), uiIndex
);
805 /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
806 Adapter
->LEDInfo
.bLedInitDone
= FALSE
;
807 Adapter
->LEDInfo
.bIdle_led_off
= TRUE
;
808 wake_up(&Adapter
->LEDInfo
.idleModeSyncEvent
);
809 GPIO_num
= DISABLE_GPIO_NUM
;
811 case IDLEMODE_CONTINUE
:
812 currdriverstate
= IDLEMODE_CONTINUE
;
813 GPIO_num
= DISABLE_GPIO_NUM
;
818 currdriverstate
= DRIVER_HALT
;
819 GPIO_num
= DISABLE_GPIO_NUM
;
820 for (uiIndex
= 0; uiIndex
< NUM_OF_LEDS
; uiIndex
++) {
821 if (Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
823 TURN_OFF_LED((1 << Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
), uiIndex
);
825 /* Adapter->DriverState = DRIVER_INIT; */
827 case LED_THREAD_INACTIVE
:
828 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
829 DBG_LVL_ALL
, "InActivating LED thread...");
830 currdriverstate
= LED_THREAD_INACTIVE
;
831 Adapter
->LEDInfo
.led_thread_running
=
832 BCM_LED_THREAD_RUNNING_INACTIVELY
;
833 Adapter
->LEDInfo
.bLedInitDone
= FALSE
;
834 /* disable ALL LED */
835 for (uiIndex
= 0; uiIndex
< NUM_OF_LEDS
; uiIndex
++) {
836 if (Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
838 TURN_OFF_LED((1 << Adapter
->LEDInfo
.LEDState
[uiIndex
].GPIO_Num
), uiIndex
);
841 case LED_THREAD_ACTIVE
:
842 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
843 DBG_LVL_ALL
, "Activating LED thread again...");
844 if (Adapter
->LinkUpStatus
== FALSE
)
845 Adapter
->DriverState
= NO_NETWORK_ENTRY
;
847 Adapter
->DriverState
= NORMAL_OPERATION
;
849 Adapter
->LEDInfo
.led_thread_running
=
850 BCM_LED_THREAD_RUNNING_ACTIVELY
;
857 Adapter
->LEDInfo
.led_thread_running
= BCM_LED_THREAD_DISABLED
;
860 int InitLedSettings(struct bcm_mini_adapter
*Adapter
)
862 int Status
= STATUS_SUCCESS
;
863 BOOLEAN bEnableThread
= TRUE
;
867 * Initially set BitPolarity to normal polarity. The bit 8 of LED type
868 * is used to change the polarity of the LED.
871 for (uiIndex
= 0; uiIndex
< NUM_OF_LEDS
; uiIndex
++)
872 Adapter
->LEDInfo
.LEDState
[uiIndex
].BitPolarity
= 1;
875 * Read the LED settings of CONFIG file and map it
876 * to GPIO numbers in EEPROM
878 Status
= ReadConfigFileStructure(Adapter
, &bEnableThread
);
879 if (STATUS_SUCCESS
!= Status
) {
880 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
882 "LED Thread: FAILED in ReadConfigFileStructure\n");
886 if (Adapter
->LEDInfo
.led_thread_running
) {
890 Adapter
->DriverState
= DRIVER_HALT
;
891 wake_up(&Adapter
->LEDInfo
.notify_led_event
);
892 Adapter
->LEDInfo
.led_thread_running
=
893 BCM_LED_THREAD_DISABLED
;
896 } else if (bEnableThread
) {
897 /* Create secondary thread to handle the LEDs */
898 init_waitqueue_head(&Adapter
->LEDInfo
.notify_led_event
);
899 init_waitqueue_head(&Adapter
->LEDInfo
.idleModeSyncEvent
);
900 Adapter
->LEDInfo
.led_thread_running
=
901 BCM_LED_THREAD_RUNNING_ACTIVELY
;
902 Adapter
->LEDInfo
.bIdle_led_off
= FALSE
;
903 Adapter
->LEDInfo
.led_cntrl_threadid
=
904 kthread_run((int (*)(void *)) LEDControlThread
,
905 Adapter
, "led_control_thread");
906 if (IS_ERR(Adapter
->LEDInfo
.led_cntrl_threadid
)) {
907 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, LED_DUMP_INFO
,
909 "Not able to spawn Kernel Thread\n");
910 Adapter
->LEDInfo
.led_thread_running
=
911 BCM_LED_THREAD_DISABLED
;
912 return PTR_ERR(Adapter
->LEDInfo
.led_cntrl_threadid
);