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 bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios)
19 Status = (Adapter->gpioBitMap & gpios) ^ gpios;
26 static INT LED_Blink(struct bcm_mini_adapter *Adapter,
31 enum bcm_led_events currdriverstate)
33 int Status = STATUS_SUCCESS;
34 bool bInfinite = false;
36 /* Check if num_of_time is -ve. If yes, blink led in infinite loop */
37 if (num_of_time < 0) {
42 if (currdriverstate == Adapter->DriverState)
43 TURN_ON_LED(Adapter, GPIO_Num, uiLedIndex);
45 /* Wait for timeout after setting on the LED */
46 Status = wait_event_interruptible_timeout(
47 Adapter->LEDInfo.notify_led_event,
48 currdriverstate != Adapter->DriverState ||
49 kthread_should_stop(),
50 msecs_to_jiffies(timeout));
52 if (kthread_should_stop()) {
53 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
55 "Led thread got signal to exit..hence exiting");
56 Adapter->LEDInfo.led_thread_running =
57 BCM_LED_THREAD_DISABLED;
58 TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
59 Status = EVENT_SIGNALED;
63 TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
64 Status = EVENT_SIGNALED;
68 TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
69 Status = wait_event_interruptible_timeout(
70 Adapter->LEDInfo.notify_led_event,
71 currdriverstate != Adapter->DriverState ||
72 kthread_should_stop(),
73 msecs_to_jiffies(timeout));
74 if (bInfinite == false)
80 static INT ScaleRateofTransfer(ULONG rate)
84 else if ((rate > 3) && (rate <= 100))
86 else if ((rate > 100) && (rate <= 200))
88 else if ((rate > 200) && (rate <= 300))
90 else if ((rate > 300) && (rate <= 400))
92 else if ((rate > 400) && (rate <= 500))
94 else if ((rate > 500) && (rate <= 600))
97 return MAX_NUM_OF_BLINKS;
102 static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter,
107 enum bcm_led_events currdriverstate)
109 /* Initial values of TX and RX packets */
110 ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0;
111 /* values of TX and RX packets after 1 sec */
112 ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0;
113 /* Rate of transfer of Tx and Rx in 1 sec */
114 ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0;
115 int Status = STATUS_SUCCESS;
116 INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
118 bool bBlinkBothLED = TRUE;
119 /* UINT GPIO_num = DISABLE_GPIO_NUM; */
122 /* Read initial value of packets sent/received */
123 Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets;
124 Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets;
126 /* Scale the rate of transfer to no of blinks. */
127 num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
128 num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
130 while ((Adapter->device_removed == false)) {
133 * Blink Tx and Rx LED when both Tx and Rx is
134 * in normal bandwidth
138 * Assign minimum number of blinks of
141 if (num_of_time_tx > num_of_time_rx)
142 num_of_time = num_of_time_rx;
144 num_of_time = num_of_time_tx;
145 if (num_of_time > 0) {
146 /* Blink both Tx and Rx LEDs */
147 if (LED_Blink(Adapter, 1 << GPIO_Num_tx,
148 uiTxLedIndex, timeout,
149 num_of_time, currdriverstate)
151 return EVENT_SIGNALED;
153 if (LED_Blink(Adapter, 1 << GPIO_Num_rx,
154 uiRxLedIndex, timeout,
155 num_of_time, currdriverstate)
157 return EVENT_SIGNALED;
161 if (num_of_time == num_of_time_tx) {
162 /* Blink pending rate of Rx */
163 if (LED_Blink(Adapter, (1 << GPIO_Num_rx),
164 uiRxLedIndex, timeout,
165 num_of_time_rx-num_of_time,
168 return EVENT_SIGNALED;
170 num_of_time = num_of_time_rx;
172 /* Blink pending rate of Tx */
173 if (LED_Blink(Adapter, 1 << GPIO_Num_tx,
174 uiTxLedIndex, timeout,
175 num_of_time_tx-num_of_time,
178 return EVENT_SIGNALED;
180 num_of_time = num_of_time_tx;
183 if (num_of_time == num_of_time_tx) {
184 /* Blink pending rate of Rx */
185 if (LED_Blink(Adapter, 1 << GPIO_Num_tx,
186 uiTxLedIndex, timeout,
187 num_of_time, currdriverstate)
189 return EVENT_SIGNALED;
191 /* Blink pending rate of Tx */
192 if (LED_Blink(Adapter, 1 << GPIO_Num_rx,
193 uiRxLedIndex, timeout,
194 num_of_time, currdriverstate)
196 return EVENT_SIGNALED;
201 * If Tx/Rx rate is less than maximum blinks per second,
202 * wait till delay completes to 1 second
204 remDelay = MAX_NUM_OF_BLINKS - num_of_time;
206 timeout = 100 * remDelay;
207 Status = wait_event_interruptible_timeout(
208 Adapter->LEDInfo.notify_led_event,
209 currdriverstate != Adapter->DriverState
210 || kthread_should_stop(),
211 msecs_to_jiffies(timeout));
213 if (kthread_should_stop()) {
214 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
215 LED_DUMP_INFO, DBG_LVL_ALL,
216 "Led thread got signal to exit..hence exiting");
217 Adapter->LEDInfo.led_thread_running =
218 BCM_LED_THREAD_DISABLED;
219 return EVENT_SIGNALED;
222 return EVENT_SIGNALED;
225 /* Turn off both Tx and Rx LEDs before next second */
226 TURN_OFF_LED(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex);
227 TURN_OFF_LED(Adapter, 1 << GPIO_Num_rx, uiTxLedIndex);
230 * Read the Tx & Rx packets transmission after 1 second and
231 * calculate rate of transfer
233 Final_num_of_packts_tx = Adapter->dev->stats.tx_packets;
234 Final_num_of_packts_rx = Adapter->dev->stats.rx_packets;
236 rate_of_transfer_tx = Final_num_of_packts_tx -
237 Initial_num_of_packts_tx;
238 rate_of_transfer_rx = Final_num_of_packts_rx -
239 Initial_num_of_packts_rx;
241 /* Read initial value of packets sent/received */
242 Initial_num_of_packts_tx = Final_num_of_packts_tx;
243 Initial_num_of_packts_rx = Final_num_of_packts_rx;
245 /* Scale the rate of transfer to no of blinks. */
247 ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
249 ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
256 * -----------------------------------------------------------------------------
257 * Procedure: ValidateDSDParamsChecksum
259 * Description: Reads DSD Params and validates checkusm.
262 * Adapter - Pointer to Adapter structure.
263 * ulParamOffset - Start offset of the DSD parameter to be read and
265 * usParamLen - Length of the DSD Parameter.
269 * -----------------------------------------------------------------------------
271 static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter,
275 INT Status = STATUS_SUCCESS;
276 PUCHAR puBuffer = NULL;
277 USHORT usChksmOrg = 0;
278 USHORT usChecksumCalculated = 0;
280 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
281 "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",
282 ulParamOffset, usParamLen);
284 puBuffer = kmalloc(usParamLen, GFP_KERNEL);
286 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
288 "LED Thread: ValidateDSDParamsChecksum Allocation failed");
293 /* Read the DSD data from the parameter offset. */
294 if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)puBuffer,
295 ulParamOffset, usParamLen)) {
296 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
298 "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
299 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
303 /* Calculate the checksum of the data read from the DSD parameter. */
304 usChecksumCalculated = CFG_CalculateChecksum(puBuffer, usParamLen);
305 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
306 "LED Thread: usCheckSumCalculated = 0x%x\n",
307 usChecksumCalculated);
310 * End of the DSD parameter will have a TWO bytes checksum stored in it.
311 * Read it and compare with the calculated Checksum.
313 if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)&usChksmOrg,
314 ulParamOffset+usParamLen, 2)) {
315 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
317 "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
318 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
321 usChksmOrg = ntohs(usChksmOrg);
322 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
323 "LED Thread: usChksmOrg = 0x%x", usChksmOrg);
326 * Compare the checksum calculated with the checksum read
329 if (usChecksumCalculated ^ usChksmOrg) {
330 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
332 "LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
333 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
344 * -----------------------------------------------------------------------------
345 * Procedure: ValidateHWParmStructure
347 * Description: Validates HW Parameters.
350 * Adapter - Pointer to Adapter structure.
351 * ulHwParamOffset - Start offset of the HW parameter Section to be read
356 * -----------------------------------------------------------------------------
358 static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter,
359 ULONG ulHwParamOffset)
362 INT Status = STATUS_SUCCESS;
363 USHORT HwParamLen = 0;
365 * Add DSD start offset to the hwParamOffset to get
366 * the actual address.
368 ulHwParamOffset += DSD_START_OFFSET;
370 /* Read the Length of HW_PARAM structure */
371 BeceemNVMRead(Adapter, (PUINT)&HwParamLen, ulHwParamOffset, 2);
372 HwParamLen = ntohs(HwParamLen);
373 if (0 == HwParamLen || HwParamLen > Adapter->uiNVMDSDSize)
374 return STATUS_IMAGE_CHECKSUM_MISMATCH;
376 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
377 "LED Thread:HwParamLen = 0x%x", HwParamLen);
378 Status = ValidateDSDParamsChecksum(Adapter, ulHwParamOffset,
381 } /* ValidateHWParmStructure() */
383 static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter,
386 int Status = STATUS_SUCCESS;
388 ULONG dwReadValue = 0;
389 USHORT usHwParamData = 0;
390 USHORT usEEPROMVersion = 0;
392 UCHAR ucGPIOInfo[32] = {0};
394 BeceemNVMRead(Adapter, (PUINT)&usEEPROMVersion,
395 EEPROM_VERSION_OFFSET, 2);
397 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
398 "usEEPROMVersion: Minor:0x%X Major:0x%x",
399 usEEPROMVersion & 0xFF,
400 ((usEEPROMVersion >> 8) & 0xFF));
403 if (((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION) {
404 BeceemNVMRead(Adapter, (PUINT)&usHwParamData,
405 EEPROM_HW_PARAM_POINTER_ADDRESS, 2);
406 usHwParamData = ntohs(usHwParamData);
407 dwReadValue = usHwParamData;
410 * Validate Compatibility section and then read HW param
411 * if compatibility section is valid.
413 Status = ValidateDSDParamsChecksum(Adapter,
415 COMPATIBILITY_SECTION_LENGTH_MAP5);
417 if (Status != STATUS_SUCCESS)
420 BeceemNVMRead(Adapter, (PUINT)&dwReadValue,
421 EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4);
422 dwReadValue = ntohl(dwReadValue);
426 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
427 "LED Thread: Start address of HW_PARAM structure = 0x%lx",
431 * Validate if the address read out is within the DSD.
432 * Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
433 * lower limit should be above DSD_START_OFFSET and
434 * upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
436 if (dwReadValue < DSD_START_OFFSET ||
437 dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET))
438 return STATUS_IMAGE_CHECKSUM_MISMATCH;
440 Status = ValidateHWParmStructure(Adapter, dwReadValue);
445 * Add DSD_START_OFFSET to the offset read from the EEPROM.
446 * This will give the actual start HW Parameters start address.
447 * To read GPIO section, add GPIO offset further.
450 dwReadValue += DSD_START_OFFSET;
451 /* = start address of hw param section. */
452 dwReadValue += GPIO_SECTION_START_OFFSET;
453 /* = GPIO start offset within HW Param section. */
456 * Read the GPIO values for 32 GPIOs from EEPROM and map the function
457 * number to GPIO pin number to GPIO_Array
459 BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo, dwReadValue, 32);
460 for (ucIndex = 0; ucIndex < 32; ucIndex++) {
462 switch (ucGPIOInfo[ucIndex]) {
464 GPIO_Array[RED_LED] = ucIndex;
465 Adapter->gpioBitMap |= (1 << ucIndex);
468 GPIO_Array[BLUE_LED] = ucIndex;
469 Adapter->gpioBitMap |= (1 << ucIndex);
472 GPIO_Array[YELLOW_LED] = ucIndex;
473 Adapter->gpioBitMap |= (1 << ucIndex);
476 GPIO_Array[GREEN_LED] = ucIndex;
477 Adapter->gpioBitMap |= (1 << ucIndex);
484 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
485 "GPIO's bit map correspond to LED :0x%X",
486 Adapter->gpioBitMap);
491 static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
494 int Status = STATUS_SUCCESS;
495 /* Array to store GPIO numbers from EEPROM */
496 UCHAR GPIO_Array[NUM_OF_LEDS+1];
498 UINT uiNum_of_LED_Type = 0;
499 PUCHAR puCFGData = NULL;
501 memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
503 if (!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) {
504 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
505 DBG_LVL_ALL, "Target Params not Avail.\n");
509 /* Populate GPIO_Array with GPIO numbers for LED functions */
510 /* Read the GPIO numbers from EEPROM */
511 Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array);
512 if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) {
513 *bEnableThread = false;
514 return STATUS_SUCCESS;
516 *bEnableThread = false;
521 * CONFIG file read successfully. Deallocate the memory of
522 * uiFileNameBufferSize
524 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
525 "LED Thread: Config file read successfully\n");
526 puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1;
529 * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
530 * will have the information of LED type, LED on state for different
531 * driver state and LED blink state.
534 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
538 * Check Bit 8 for polarity. If it is set,
539 * polarity is reverse polarity
542 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 0;
543 /* unset the bit 8 */
544 bData = bData & 0x7f;
547 Adapter->LEDInfo.LEDState[uiIndex].LED_Type = bData;
548 if (bData <= NUM_OF_LEDS)
549 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num =
552 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num =
557 Adapter->LEDInfo.LEDState[uiIndex].LED_On_State = bData;
560 Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State = bData;
565 * Check if all the LED settings are disabled. If it is disabled,
566 * dont launch the LED control thread.
568 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
569 if ((Adapter->LEDInfo.LEDState[uiIndex].LED_Type ==
571 (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0x7f) ||
572 (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0))
575 if (uiNum_of_LED_Type >= NUM_OF_LEDS)
576 *bEnableThread = false;
582 * -----------------------------------------------------------------------------
583 * Procedure: LedGpioInit
585 * Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode
586 * and make the initial state to be OFF.
589 * Adapter - Pointer to MINI_ADAPTER structure.
593 * -----------------------------------------------------------------------------
595 static VOID LedGpioInit(struct bcm_mini_adapter *Adapter)
597 UINT uiResetValue = 0;
600 /* Set all LED GPIO Mode to output mode */
601 if (rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
602 sizeof(uiResetValue)) < 0)
603 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
604 DBG_LVL_ALL, "LED Thread: RDM Failed\n");
605 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
606 if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
608 uiResetValue |= (1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
609 TURN_OFF_LED(Adapter,
610 1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num,
613 if (wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
614 sizeof(uiResetValue)) < 0)
615 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
616 DBG_LVL_ALL, "LED Thread: WRM Failed\n");
618 Adapter->LEDInfo.bIdle_led_off = false;
621 static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter,
626 enum bcm_led_events currdriverstate)
630 *GPIO_num_tx = DISABLE_GPIO_NUM;
631 *GPIO_num_rx = DISABLE_GPIO_NUM;
633 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
635 if (((currdriverstate == NORMAL_OPERATION) ||
636 (currdriverstate == IDLEMODE_EXIT) ||
637 (currdriverstate == FW_DOWNLOAD)) &&
638 (Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State &
640 if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num
641 != DISABLE_GPIO_NUM) {
642 if (*GPIO_num_tx == DISABLE_GPIO_NUM) {
643 *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
644 *uiLedTxIndex = uiIndex;
646 *GPIO_num_rx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
647 *uiLedRxIndex = uiIndex;
651 if ((Adapter->LEDInfo.LEDState[uiIndex].LED_On_State &
653 (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
655 *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
656 *uiLedTxIndex = uiIndex;
660 return STATUS_SUCCESS;
663 static void handle_adapter_driver_state(struct bcm_mini_adapter *ad,
664 enum bcm_led_events currdriverstate,
673 switch (ad->DriverState) {
675 currdriverstate = DRIVER_INIT;
676 /* ad->DriverState; */
677 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
678 &uiLedIndex, &dummyIndex,
681 if (GPIO_num != DISABLE_GPIO_NUM)
682 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
687 * BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
688 * LED_DUMP_INFO, DBG_LVL_ALL,
689 * "LED Thread: FW_DN_DONE called\n");
691 currdriverstate = FW_DOWNLOAD;
692 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
693 &uiLedIndex, &dummyIndex,
696 if (GPIO_num != DISABLE_GPIO_NUM) {
698 LED_Blink(ad, 1 << GPIO_num, uiLedIndex, timeout,
699 -1, currdriverstate);
702 case FW_DOWNLOAD_DONE:
703 currdriverstate = FW_DOWNLOAD_DONE;
704 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
705 &uiLedIndex, &dummyIndex, currdriverstate);
706 if (GPIO_num != DISABLE_GPIO_NUM)
707 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
712 * no break, continue to NO_NETWORK_ENTRY
715 case NO_NETWORK_ENTRY:
716 currdriverstate = NO_NETWORK_ENTRY;
717 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
718 &uiLedIndex, &dummyGPIONum, currdriverstate);
719 if (GPIO_num != DISABLE_GPIO_NUM)
720 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
722 case NORMAL_OPERATION:
724 UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
725 UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
728 currdriverstate = NORMAL_OPERATION;
729 ad->LEDInfo.bIdle_led_off = false;
731 BcmGetGPIOPinInfo(ad, &GPIO_num_tx, &GPIO_num_rx,
732 &uiLEDTx, &uiLEDRx, currdriverstate);
733 if ((GPIO_num_tx == DISABLE_GPIO_NUM) &&
734 (GPIO_num_rx == DISABLE_GPIO_NUM)) {
735 GPIO_num = DISABLE_GPIO_NUM;
738 * If single LED is selected, use same
741 if (GPIO_num_tx == DISABLE_GPIO_NUM) {
742 GPIO_num_tx = GPIO_num_rx;
744 } else if (GPIO_num_rx == DISABLE_GPIO_NUM) {
745 GPIO_num_rx = GPIO_num_tx;
749 * Blink the LED in proportionate
750 * to Tx and Rx transmissions.
752 LED_Proportional_Blink(ad,
753 GPIO_num_tx, uiLEDTx,
754 GPIO_num_rx, uiLEDRx,
759 case LOWPOWER_MODE_ENTER:
760 currdriverstate = LOWPOWER_MODE_ENTER;
761 if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING ==
762 ad->ulPowerSaveMode) {
763 /* Turn OFF all the LED */
765 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
766 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
768 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
773 /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
774 ad->LEDInfo.bLedInitDone = false;
775 ad->LEDInfo.bIdle_led_off = TRUE;
776 wake_up(&ad->LEDInfo.idleModeSyncEvent);
777 GPIO_num = DISABLE_GPIO_NUM;
779 case IDLEMODE_CONTINUE:
780 currdriverstate = IDLEMODE_CONTINUE;
781 GPIO_num = DISABLE_GPIO_NUM;
786 currdriverstate = DRIVER_HALT;
787 GPIO_num = DISABLE_GPIO_NUM;
788 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
789 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num !=
792 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
795 /* ad->DriverState = DRIVER_INIT; */
797 case LED_THREAD_INACTIVE:
798 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO,
799 DBG_LVL_ALL, "InActivating LED thread...");
800 currdriverstate = LED_THREAD_INACTIVE;
801 ad->LEDInfo.led_thread_running =
802 BCM_LED_THREAD_RUNNING_INACTIVELY;
803 ad->LEDInfo.bLedInitDone = false;
804 /* disable ALL LED */
805 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
806 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num !=
809 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
813 case LED_THREAD_ACTIVE:
814 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO,
815 DBG_LVL_ALL, "Activating LED thread again...");
816 if (ad->LinkUpStatus == false)
817 ad->DriverState = NO_NETWORK_ENTRY;
819 ad->DriverState = NORMAL_OPERATION;
821 ad->LEDInfo.led_thread_running =
822 BCM_LED_THREAD_RUNNING_ACTIVELY;
830 static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
834 UCHAR uiLedIndex = 0;
835 UINT uiResetValue = 0;
836 enum bcm_led_events currdriverstate = 0;
841 UCHAR dummyGPIONum = 0;
842 UCHAR dummyIndex = 0;
844 /* currdriverstate = Adapter->DriverState; */
845 Adapter->LEDInfo.bIdleMode_tx_from_host = false;
848 * Wait till event is triggered
850 * wait_event(Adapter->LEDInfo.notify_led_event,
851 * currdriverstate!= Adapter->DriverState);
854 GPIO_num = DISABLE_GPIO_NUM;
857 /* Wait till event is triggered */
858 if ((GPIO_num == DISABLE_GPIO_NUM)
860 ((currdriverstate != FW_DOWNLOAD) &&
861 (currdriverstate != NORMAL_OPERATION) &&
862 (currdriverstate != LOWPOWER_MODE_ENTER))
864 (currdriverstate == LED_THREAD_INACTIVE))
865 Status = wait_event_interruptible(
866 Adapter->LEDInfo.notify_led_event,
867 currdriverstate != Adapter->DriverState
868 || kthread_should_stop());
870 if (kthread_should_stop() || Adapter->device_removed) {
871 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
873 "Led thread got signal to exit..hence exiting");
874 Adapter->LEDInfo.led_thread_running =
875 BCM_LED_THREAD_DISABLED;
876 TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex);
877 return; /* STATUS_FAILURE; */
880 if (GPIO_num != DISABLE_GPIO_NUM)
881 TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex);
883 if (Adapter->LEDInfo.bLedInitDone == false) {
884 LedGpioInit(Adapter);
885 Adapter->LEDInfo.bLedInitDone = TRUE;
888 handle_adapter_driver_state(Adapter,
899 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
902 int InitLedSettings(struct bcm_mini_adapter *Adapter)
904 int Status = STATUS_SUCCESS;
905 bool bEnableThread = TRUE;
909 * Initially set BitPolarity to normal polarity. The bit 8 of LED type
910 * is used to change the polarity of the LED.
913 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
914 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1;
917 * Read the LED settings of CONFIG file and map it
918 * to GPIO numbers in EEPROM
920 Status = ReadConfigFileStructure(Adapter, &bEnableThread);
921 if (STATUS_SUCCESS != Status) {
922 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
924 "LED Thread: FAILED in ReadConfigFileStructure\n");
928 if (Adapter->LEDInfo.led_thread_running) {
932 Adapter->DriverState = DRIVER_HALT;
933 wake_up(&Adapter->LEDInfo.notify_led_event);
934 Adapter->LEDInfo.led_thread_running =
935 BCM_LED_THREAD_DISABLED;
938 } else if (bEnableThread) {
939 /* Create secondary thread to handle the LEDs */
940 init_waitqueue_head(&Adapter->LEDInfo.notify_led_event);
941 init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent);
942 Adapter->LEDInfo.led_thread_running =
943 BCM_LED_THREAD_RUNNING_ACTIVELY;
944 Adapter->LEDInfo.bIdle_led_off = false;
945 Adapter->LEDInfo.led_cntrl_threadid =
946 kthread_run((int (*)(void *)) LEDControlThread,
947 Adapter, "led_control_thread");
948 if (IS_ERR(Adapter->LEDInfo.led_cntrl_threadid)) {
949 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
951 "Not able to spawn Kernel Thread\n");
952 Adapter->LEDInfo.led_thread_running =
953 BCM_LED_THREAD_DISABLED;
954 return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);