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;
11 u16CheckSum += (B_UINT8)~(*pu8Buffer);
17 bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios)
21 Status = (Adapter->gpioBitMap & gpios) ^ gpios;
28 static INT LED_Blink(struct bcm_mini_adapter *Adapter,
33 enum bcm_led_events currdriverstate)
35 int Status = STATUS_SUCCESS;
36 bool bInfinite = false;
38 /* Check if num_of_time is -ve. If yes, blink led in infinite loop */
39 if (num_of_time < 0) {
44 if (currdriverstate == Adapter->DriverState)
45 TURN_ON_LED(Adapter, GPIO_Num, uiLedIndex);
47 /* Wait for timeout after setting on the LED */
48 Status = wait_event_interruptible_timeout(
49 Adapter->LEDInfo.notify_led_event,
50 currdriverstate != Adapter->DriverState ||
51 kthread_should_stop(),
52 msecs_to_jiffies(timeout));
54 if (kthread_should_stop()) {
55 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
57 "Led thread got signal to exit..hence exiting");
58 Adapter->LEDInfo.led_thread_running =
59 BCM_LED_THREAD_DISABLED;
60 TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
61 Status = EVENT_SIGNALED;
65 TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
66 Status = EVENT_SIGNALED;
70 TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
71 Status = wait_event_interruptible_timeout(
72 Adapter->LEDInfo.notify_led_event,
73 currdriverstate != Adapter->DriverState ||
74 kthread_should_stop(),
75 msecs_to_jiffies(timeout));
76 if (bInfinite == false)
82 static INT ScaleRateofTransfer(ULONG rate)
86 else if ((rate > 3) && (rate <= 100))
88 else if ((rate > 100) && (rate <= 200))
90 else if ((rate > 200) && (rate <= 300))
92 else if ((rate > 300) && (rate <= 400))
94 else if ((rate > 400) && (rate <= 500))
96 else if ((rate > 500) && (rate <= 600))
98 return MAX_NUM_OF_BLINKS;
101 static INT blink_in_normal_bandwidth(struct bcm_mini_adapter *ad,
109 enum bcm_led_events currdriverstate,
113 * Assign minimum number of blinks of
116 *time = (*time_tx > *time_rx ? *time_rx : *time_tx);
119 /* Blink both Tx and Rx LEDs */
120 if ((LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout,
121 *time, currdriverstate) == EVENT_SIGNALED) ||
122 (LED_Blink(ad, 1 << GPIO_Num_rx, uiRxLedIndex, *timeout,
123 *time, currdriverstate) == EVENT_SIGNALED))
124 return EVENT_SIGNALED;
127 if (*time == *time_tx) {
128 /* Blink pending rate of Rx */
129 if (LED_Blink(ad, (1 << GPIO_Num_rx), uiRxLedIndex, *timeout,
131 currdriverstate) == EVENT_SIGNALED)
132 return EVENT_SIGNALED;
136 /* Blink pending rate of Tx */
137 if (LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout,
139 currdriverstate) == EVENT_SIGNALED)
140 return EVENT_SIGNALED;
148 static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter,
153 enum bcm_led_events currdriverstate)
155 /* Initial values of TX and RX packets */
156 ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0;
157 /* values of TX and RX packets after 1 sec */
158 ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0;
159 /* Rate of transfer of Tx and Rx in 1 sec */
160 ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0;
161 int Status = STATUS_SUCCESS;
162 INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
164 /* UINT GPIO_num = DISABLE_GPIO_NUM; */
167 /* Read initial value of packets sent/received */
168 Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets;
169 Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets;
171 /* Scale the rate of transfer to no of blinks. */
172 num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
173 num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
175 while ((Adapter->device_removed == false)) {
178 if (EVENT_SIGNALED == blink_in_normal_bandwidth(Adapter,
188 return EVENT_SIGNALED;
192 * If Tx/Rx rate is less than maximum blinks per second,
193 * wait till delay completes to 1 second
195 remDelay = MAX_NUM_OF_BLINKS - num_of_time;
197 timeout = 100 * remDelay;
198 Status = wait_event_interruptible_timeout(
199 Adapter->LEDInfo.notify_led_event,
200 currdriverstate != Adapter->DriverState
201 || kthread_should_stop(),
202 msecs_to_jiffies(timeout));
204 if (kthread_should_stop()) {
205 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
206 LED_DUMP_INFO, DBG_LVL_ALL,
207 "Led thread got signal to exit..hence exiting");
208 Adapter->LEDInfo.led_thread_running =
209 BCM_LED_THREAD_DISABLED;
210 return EVENT_SIGNALED;
213 return EVENT_SIGNALED;
216 /* Turn off both Tx and Rx LEDs before next second */
217 TURN_OFF_LED(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex);
218 TURN_OFF_LED(Adapter, 1 << GPIO_Num_rx, uiTxLedIndex);
221 * Read the Tx & Rx packets transmission after 1 second and
222 * calculate rate of transfer
224 Final_num_of_packts_tx = Adapter->dev->stats.tx_packets;
225 Final_num_of_packts_rx = Adapter->dev->stats.rx_packets;
227 rate_of_transfer_tx = Final_num_of_packts_tx -
228 Initial_num_of_packts_tx;
229 rate_of_transfer_rx = Final_num_of_packts_rx -
230 Initial_num_of_packts_rx;
232 /* Read initial value of packets sent/received */
233 Initial_num_of_packts_tx = Final_num_of_packts_tx;
234 Initial_num_of_packts_rx = Final_num_of_packts_rx;
236 /* Scale the rate of transfer to no of blinks. */
238 ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
240 ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
247 * -----------------------------------------------------------------------------
248 * Procedure: ValidateDSDParamsChecksum
250 * Description: Reads DSD Params and validates checkusm.
253 * Adapter - Pointer to Adapter structure.
254 * ulParamOffset - Start offset of the DSD parameter to be read and
256 * usParamLen - Length of the DSD Parameter.
260 * -----------------------------------------------------------------------------
262 static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter,
266 INT Status = STATUS_SUCCESS;
267 PUCHAR puBuffer = NULL;
268 USHORT usChksmOrg = 0;
269 USHORT usChecksumCalculated = 0;
271 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
272 "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",
273 ulParamOffset, usParamLen);
275 puBuffer = kmalloc(usParamLen, GFP_KERNEL);
277 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
279 "LED Thread: ValidateDSDParamsChecksum Allocation failed");
284 /* Read the DSD data from the parameter offset. */
285 if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)puBuffer,
286 ulParamOffset, usParamLen)) {
287 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
289 "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
290 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
294 /* Calculate the checksum of the data read from the DSD parameter. */
295 usChecksumCalculated = CFG_CalculateChecksum(puBuffer, usParamLen);
296 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
297 "LED Thread: usCheckSumCalculated = 0x%x\n",
298 usChecksumCalculated);
301 * End of the DSD parameter will have a TWO bytes checksum stored in it.
302 * Read it and compare with the calculated Checksum.
304 if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)&usChksmOrg,
305 ulParamOffset+usParamLen, 2)) {
306 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
308 "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
309 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
312 usChksmOrg = ntohs(usChksmOrg);
313 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
314 "LED Thread: usChksmOrg = 0x%x", usChksmOrg);
317 * Compare the checksum calculated with the checksum read
320 if (usChecksumCalculated ^ usChksmOrg) {
321 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
323 "LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
324 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
335 * -----------------------------------------------------------------------------
336 * Procedure: ValidateHWParmStructure
338 * Description: Validates HW Parameters.
341 * Adapter - Pointer to Adapter structure.
342 * ulHwParamOffset - Start offset of the HW parameter Section to be read
347 * -----------------------------------------------------------------------------
349 static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter,
350 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,
391 ((usEEPROMVersion >> 8) & 0xFF));
394 if (((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION) {
395 BeceemNVMRead(Adapter, (PUINT)&usHwParamData,
396 EEPROM_HW_PARAM_POINTER_ADDRESS, 2);
397 usHwParamData = ntohs(usHwParamData);
398 dwReadValue = usHwParamData;
401 * Validate Compatibility section and then read HW param
402 * if compatibility section is valid.
404 Status = ValidateDSDParamsChecksum(Adapter,
406 COMPATIBILITY_SECTION_LENGTH_MAP5);
408 if (Status != STATUS_SUCCESS)
411 BeceemNVMRead(Adapter, (PUINT)&dwReadValue,
412 EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4);
413 dwReadValue = ntohl(dwReadValue);
417 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
418 "LED Thread: Start address of HW_PARAM structure = 0x%lx",
422 * Validate if the address read out is within the DSD.
423 * Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
424 * lower limit should be above DSD_START_OFFSET and
425 * upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
427 if (dwReadValue < DSD_START_OFFSET ||
428 dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET))
429 return STATUS_IMAGE_CHECKSUM_MISMATCH;
431 Status = ValidateHWParmStructure(Adapter, dwReadValue);
436 * Add DSD_START_OFFSET to the offset read from the EEPROM.
437 * This will give the actual start HW Parameters start address.
438 * To read GPIO section, add GPIO offset further.
441 dwReadValue += DSD_START_OFFSET;
442 /* = start address of hw param section. */
443 dwReadValue += GPIO_SECTION_START_OFFSET;
444 /* = GPIO start offset within HW Param section. */
447 * Read the GPIO values for 32 GPIOs from EEPROM and map the function
448 * number to GPIO pin number to GPIO_Array
450 BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo, dwReadValue, 32);
451 for (ucIndex = 0; ucIndex < 32; ucIndex++) {
453 switch (ucGPIOInfo[ucIndex]) {
455 GPIO_Array[RED_LED] = ucIndex;
456 Adapter->gpioBitMap |= (1 << ucIndex);
459 GPIO_Array[BLUE_LED] = ucIndex;
460 Adapter->gpioBitMap |= (1 << ucIndex);
463 GPIO_Array[YELLOW_LED] = ucIndex;
464 Adapter->gpioBitMap |= (1 << ucIndex);
467 GPIO_Array[GREEN_LED] = ucIndex;
468 Adapter->gpioBitMap |= (1 << ucIndex);
475 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
476 "GPIO's bit map correspond to LED :0x%X",
477 Adapter->gpioBitMap);
482 static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
485 int Status = STATUS_SUCCESS;
486 /* Array to store GPIO numbers from EEPROM */
487 UCHAR GPIO_Array[NUM_OF_LEDS+1];
489 UINT uiNum_of_LED_Type = 0;
490 PUCHAR puCFGData = NULL;
492 struct bcm_led_state_info *curr_led_state;
494 memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
496 if (!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) {
497 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
498 DBG_LVL_ALL, "Target Params not Avail.\n");
502 /* Populate GPIO_Array with GPIO numbers for LED functions */
503 /* Read the GPIO numbers from EEPROM */
504 Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array);
505 if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) {
506 *bEnableThread = false;
507 return STATUS_SUCCESS;
509 *bEnableThread = false;
514 * CONFIG file read successfully. Deallocate the memory of
515 * uiFileNameBufferSize
517 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
518 "LED Thread: Config file read successfully\n");
519 puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1;
522 * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
523 * will have the information of LED type, LED on state for different
524 * driver state and LED blink state.
527 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
529 curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex];
532 * Check Bit 8 for polarity. If it is set,
533 * polarity is reverse polarity
536 curr_led_state->BitPolarity = 0;
537 /* unset the bit 8 */
538 bData = bData & 0x7f;
541 curr_led_state->LED_Type = bData;
542 if (bData <= NUM_OF_LEDS)
543 curr_led_state->GPIO_Num = GPIO_Array[bData];
545 curr_led_state->GPIO_Num = DISABLE_GPIO_NUM;
549 curr_led_state->LED_On_State = bData;
552 curr_led_state->LED_Blink_State = bData;
557 * Check if all the LED settings are disabled. If it is disabled,
558 * dont launch the LED control thread.
560 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
561 curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex];
563 if ((curr_led_state->LED_Type == DISABLE_GPIO_NUM) ||
564 (curr_led_state->LED_Type == 0x7f) ||
565 (curr_led_state->LED_Type == 0))
568 if (uiNum_of_LED_Type >= NUM_OF_LEDS)
569 *bEnableThread = false;
575 * -----------------------------------------------------------------------------
576 * Procedure: LedGpioInit
578 * Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode
579 * and make the initial state to be OFF.
582 * Adapter - Pointer to MINI_ADAPTER structure.
586 * -----------------------------------------------------------------------------
588 static VOID LedGpioInit(struct bcm_mini_adapter *Adapter)
590 UINT uiResetValue = 0;
592 struct bcm_led_state_info *curr_led_state;
594 /* Set all LED GPIO Mode to output mode */
595 if (rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
596 sizeof(uiResetValue)) < 0)
597 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
598 DBG_LVL_ALL, "LED Thread: RDM Failed\n");
599 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
600 curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex];
602 if (curr_led_state->GPIO_Num != DISABLE_GPIO_NUM)
603 uiResetValue |= (1 << curr_led_state->GPIO_Num);
605 TURN_OFF_LED(Adapter, 1 << curr_led_state->GPIO_Num, uiIndex);
608 if (wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
609 sizeof(uiResetValue)) < 0)
610 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
611 DBG_LVL_ALL, "LED Thread: WRM Failed\n");
613 Adapter->LEDInfo.bIdle_led_off = false;
616 static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter,
621 enum bcm_led_events currdriverstate)
624 struct bcm_led_state_info *led_state_info;
626 *GPIO_num_tx = DISABLE_GPIO_NUM;
627 *GPIO_num_rx = DISABLE_GPIO_NUM;
629 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
630 led_state_info = &Adapter->LEDInfo.LEDState[uiIndex];
632 if (((currdriverstate == NORMAL_OPERATION) ||
633 (currdriverstate == IDLEMODE_EXIT) ||
634 (currdriverstate == FW_DOWNLOAD)) &&
635 (led_state_info->LED_Blink_State & currdriverstate) &&
636 (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) {
637 if (*GPIO_num_tx == DISABLE_GPIO_NUM) {
638 *GPIO_num_tx = led_state_info->GPIO_Num;
639 *uiLedTxIndex = uiIndex;
641 *GPIO_num_rx = led_state_info->GPIO_Num;
642 *uiLedRxIndex = uiIndex;
645 if ((led_state_info->LED_On_State & currdriverstate) &&
646 (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) {
647 *GPIO_num_tx = led_state_info->GPIO_Num;
648 *uiLedTxIndex = uiIndex;
652 return STATUS_SUCCESS;
655 static void handle_adapter_driver_state(struct bcm_mini_adapter *ad,
656 enum bcm_led_events currdriverstate,
665 switch (ad->DriverState) {
667 currdriverstate = DRIVER_INIT;
668 /* ad->DriverState; */
669 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
670 &uiLedIndex, &dummyIndex,
673 if (GPIO_num != DISABLE_GPIO_NUM)
674 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
679 * BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
680 * LED_DUMP_INFO, DBG_LVL_ALL,
681 * "LED Thread: FW_DN_DONE called\n");
683 currdriverstate = FW_DOWNLOAD;
684 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
685 &uiLedIndex, &dummyIndex,
688 if (GPIO_num != DISABLE_GPIO_NUM) {
690 LED_Blink(ad, 1 << GPIO_num, uiLedIndex, timeout,
691 -1, currdriverstate);
694 case FW_DOWNLOAD_DONE:
695 currdriverstate = FW_DOWNLOAD_DONE;
696 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
697 &uiLedIndex, &dummyIndex, currdriverstate);
698 if (GPIO_num != DISABLE_GPIO_NUM)
699 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
704 * no break, continue to NO_NETWORK_ENTRY
707 case NO_NETWORK_ENTRY:
708 currdriverstate = NO_NETWORK_ENTRY;
709 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
710 &uiLedIndex, &dummyGPIONum, currdriverstate);
711 if (GPIO_num != DISABLE_GPIO_NUM)
712 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
714 case NORMAL_OPERATION:
716 UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
717 UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
721 currdriverstate = NORMAL_OPERATION;
722 ad->LEDInfo.bIdle_led_off = false;
724 BcmGetGPIOPinInfo(ad, &GPIO_num_tx, &GPIO_num_rx,
725 &uiLEDTx, &uiLEDRx, currdriverstate);
726 if ((GPIO_num_tx == DISABLE_GPIO_NUM) &&
727 (GPIO_num_rx == DISABLE_GPIO_NUM)) {
728 GPIO_num = DISABLE_GPIO_NUM;
731 * If single LED is selected, use same
734 if (GPIO_num_tx == DISABLE_GPIO_NUM) {
735 GPIO_num_tx = GPIO_num_rx;
737 } else if (GPIO_num_rx == DISABLE_GPIO_NUM) {
738 GPIO_num_rx = GPIO_num_tx;
742 * Blink the LED in proportionate
743 * to Tx and Rx transmissions.
745 LED_Proportional_Blink(ad,
746 GPIO_num_tx, uiLEDTx,
747 GPIO_num_rx, uiLEDRx,
752 case LOWPOWER_MODE_ENTER:
753 currdriverstate = LOWPOWER_MODE_ENTER;
754 if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING ==
755 ad->ulPowerSaveMode) {
756 /* Turn OFF all the LED */
758 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
759 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
761 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
766 /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
767 ad->LEDInfo.bLedInitDone = false;
768 ad->LEDInfo.bIdle_led_off = TRUE;
769 wake_up(&ad->LEDInfo.idleModeSyncEvent);
770 GPIO_num = DISABLE_GPIO_NUM;
772 case IDLEMODE_CONTINUE:
773 currdriverstate = IDLEMODE_CONTINUE;
774 GPIO_num = DISABLE_GPIO_NUM;
779 currdriverstate = DRIVER_HALT;
780 GPIO_num = DISABLE_GPIO_NUM;
781 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
782 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num !=
785 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
788 /* ad->DriverState = DRIVER_INIT; */
790 case LED_THREAD_INACTIVE:
791 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO,
792 DBG_LVL_ALL, "InActivating LED thread...");
793 currdriverstate = LED_THREAD_INACTIVE;
794 ad->LEDInfo.led_thread_running =
795 BCM_LED_THREAD_RUNNING_INACTIVELY;
796 ad->LEDInfo.bLedInitDone = false;
797 /* disable ALL LED */
798 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
799 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num !=
802 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
806 case LED_THREAD_ACTIVE:
807 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO,
808 DBG_LVL_ALL, "Activating LED thread again...");
809 if (ad->LinkUpStatus == false)
810 ad->DriverState = NO_NETWORK_ENTRY;
812 ad->DriverState = NORMAL_OPERATION;
814 ad->LEDInfo.led_thread_running =
815 BCM_LED_THREAD_RUNNING_ACTIVELY;
823 static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
827 UCHAR uiLedIndex = 0;
828 UINT uiResetValue = 0;
829 enum bcm_led_events currdriverstate = 0;
834 UCHAR dummyGPIONum = 0;
835 UCHAR dummyIndex = 0;
837 /* currdriverstate = Adapter->DriverState; */
838 Adapter->LEDInfo.bIdleMode_tx_from_host = false;
841 * Wait till event is triggered
843 * wait_event(Adapter->LEDInfo.notify_led_event,
844 * currdriverstate!= Adapter->DriverState);
847 GPIO_num = DISABLE_GPIO_NUM;
850 /* Wait till event is triggered */
851 if ((GPIO_num == DISABLE_GPIO_NUM)
853 ((currdriverstate != FW_DOWNLOAD) &&
854 (currdriverstate != NORMAL_OPERATION) &&
855 (currdriverstate != LOWPOWER_MODE_ENTER))
857 (currdriverstate == LED_THREAD_INACTIVE))
858 Status = wait_event_interruptible(
859 Adapter->LEDInfo.notify_led_event,
860 currdriverstate != Adapter->DriverState
861 || kthread_should_stop());
863 if (kthread_should_stop() || Adapter->device_removed) {
864 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
866 "Led thread got signal to exit..hence exiting");
867 Adapter->LEDInfo.led_thread_running =
868 BCM_LED_THREAD_DISABLED;
869 TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex);
870 return; /* STATUS_FAILURE; */
873 if (GPIO_num != DISABLE_GPIO_NUM)
874 TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex);
876 if (Adapter->LEDInfo.bLedInitDone == false) {
877 LedGpioInit(Adapter);
878 Adapter->LEDInfo.bLedInitDone = TRUE;
881 handle_adapter_driver_state(Adapter,
892 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
895 int InitLedSettings(struct bcm_mini_adapter *Adapter)
897 int Status = STATUS_SUCCESS;
898 bool bEnableThread = TRUE;
902 * Initially set BitPolarity to normal polarity. The bit 8 of LED type
903 * is used to change the polarity of the LED.
906 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
907 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1;
910 * Read the LED settings of CONFIG file and map it
911 * to GPIO numbers in EEPROM
913 Status = ReadConfigFileStructure(Adapter, &bEnableThread);
914 if (STATUS_SUCCESS != Status) {
915 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
917 "LED Thread: FAILED in ReadConfigFileStructure\n");
921 if (Adapter->LEDInfo.led_thread_running) {
925 Adapter->DriverState = DRIVER_HALT;
926 wake_up(&Adapter->LEDInfo.notify_led_event);
927 Adapter->LEDInfo.led_thread_running =
928 BCM_LED_THREAD_DISABLED;
931 } else if (bEnableThread) {
932 /* Create secondary thread to handle the LEDs */
933 init_waitqueue_head(&Adapter->LEDInfo.notify_led_event);
934 init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent);
935 Adapter->LEDInfo.led_thread_running =
936 BCM_LED_THREAD_RUNNING_ACTIVELY;
937 Adapter->LEDInfo.bIdle_led_off = false;
938 Adapter->LEDInfo.led_cntrl_threadid =
939 kthread_run((int (*)(void *)) LEDControlThread,
940 Adapter, "led_control_thread");
941 if (IS_ERR(Adapter->LEDInfo.led_cntrl_threadid)) {
942 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
944 "Not able to spawn Kernel Thread\n");
945 Adapter->LEDInfo.led_thread_running =
946 BCM_LED_THREAD_DISABLED;
947 return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);