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;
100 static INT blink_in_normal_bandwidth(struct bcm_mini_adapter *ad,
108 enum bcm_led_events currdriverstate,
111 bool bBlinkBothLED = TRUE;
114 * Blink Tx and Rx LED when both Tx and Rx is
115 * in normal bandwidth
119 * Assign minimum number of blinks of
122 if (*num_of_time_tx > *num_of_time_rx)
123 *num_of_time = *num_of_time_rx;
125 *num_of_time = *num_of_time_tx;
126 if (*num_of_time > 0) {
127 /* Blink both Tx and Rx LEDs */
128 if (LED_Blink(ad, 1 << GPIO_Num_tx,
129 uiTxLedIndex, *timeout,
130 *num_of_time, currdriverstate)
132 return EVENT_SIGNALED;
134 if (LED_Blink(ad, 1 << GPIO_Num_rx,
135 uiRxLedIndex, *timeout,
136 *num_of_time, currdriverstate)
138 return EVENT_SIGNALED;
142 if (*num_of_time == *num_of_time_tx) {
143 /* Blink pending rate of Rx */
144 if (LED_Blink(ad, (1 << GPIO_Num_rx),
145 uiRxLedIndex, *timeout,
146 *num_of_time_rx - *num_of_time,
149 return EVENT_SIGNALED;
151 *num_of_time = *num_of_time_rx;
153 /* Blink pending rate of Tx */
154 if (LED_Blink(ad, 1 << GPIO_Num_tx,
155 uiTxLedIndex, *timeout,
156 *num_of_time_tx - *num_of_time,
159 return EVENT_SIGNALED;
161 *num_of_time = *num_of_time_tx;
164 if (*num_of_time == *num_of_time_tx) {
165 /* Blink pending rate of Rx */
166 if (LED_Blink(ad, 1 << GPIO_Num_tx,
167 uiTxLedIndex, *timeout,
168 *num_of_time, currdriverstate)
170 return EVENT_SIGNALED;
172 /* Blink pending rate of Tx */
173 if (LED_Blink(ad, 1 << GPIO_Num_rx,
174 uiRxLedIndex, *timeout,
175 *num_of_time, currdriverstate)
177 return EVENT_SIGNALED;
184 static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter,
189 enum bcm_led_events currdriverstate)
191 /* Initial values of TX and RX packets */
192 ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0;
193 /* values of TX and RX packets after 1 sec */
194 ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0;
195 /* Rate of transfer of Tx and Rx in 1 sec */
196 ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0;
197 int Status = STATUS_SUCCESS;
198 INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
200 /* UINT GPIO_num = DISABLE_GPIO_NUM; */
203 /* Read initial value of packets sent/received */
204 Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets;
205 Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets;
207 /* Scale the rate of transfer to no of blinks. */
208 num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
209 num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
211 while ((Adapter->device_removed == false)) {
214 if (EVENT_SIGNALED == blink_in_normal_bandwidth(Adapter,
224 return EVENT_SIGNALED;
228 * If Tx/Rx rate is less than maximum blinks per second,
229 * wait till delay completes to 1 second
231 remDelay = MAX_NUM_OF_BLINKS - num_of_time;
233 timeout = 100 * remDelay;
234 Status = wait_event_interruptible_timeout(
235 Adapter->LEDInfo.notify_led_event,
236 currdriverstate != Adapter->DriverState
237 || kthread_should_stop(),
238 msecs_to_jiffies(timeout));
240 if (kthread_should_stop()) {
241 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
242 LED_DUMP_INFO, DBG_LVL_ALL,
243 "Led thread got signal to exit..hence exiting");
244 Adapter->LEDInfo.led_thread_running =
245 BCM_LED_THREAD_DISABLED;
246 return EVENT_SIGNALED;
249 return EVENT_SIGNALED;
252 /* Turn off both Tx and Rx LEDs before next second */
253 TURN_OFF_LED(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex);
254 TURN_OFF_LED(Adapter, 1 << GPIO_Num_rx, uiTxLedIndex);
257 * Read the Tx & Rx packets transmission after 1 second and
258 * calculate rate of transfer
260 Final_num_of_packts_tx = Adapter->dev->stats.tx_packets;
261 Final_num_of_packts_rx = Adapter->dev->stats.rx_packets;
263 rate_of_transfer_tx = Final_num_of_packts_tx -
264 Initial_num_of_packts_tx;
265 rate_of_transfer_rx = Final_num_of_packts_rx -
266 Initial_num_of_packts_rx;
268 /* Read initial value of packets sent/received */
269 Initial_num_of_packts_tx = Final_num_of_packts_tx;
270 Initial_num_of_packts_rx = Final_num_of_packts_rx;
272 /* Scale the rate of transfer to no of blinks. */
274 ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
276 ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
283 * -----------------------------------------------------------------------------
284 * Procedure: ValidateDSDParamsChecksum
286 * Description: Reads DSD Params and validates checkusm.
289 * Adapter - Pointer to Adapter structure.
290 * ulParamOffset - Start offset of the DSD parameter to be read and
292 * usParamLen - Length of the DSD Parameter.
296 * -----------------------------------------------------------------------------
298 static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter,
302 INT Status = STATUS_SUCCESS;
303 PUCHAR puBuffer = NULL;
304 USHORT usChksmOrg = 0;
305 USHORT usChecksumCalculated = 0;
307 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
308 "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",
309 ulParamOffset, usParamLen);
311 puBuffer = kmalloc(usParamLen, GFP_KERNEL);
313 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
315 "LED Thread: ValidateDSDParamsChecksum Allocation failed");
320 /* Read the DSD data from the parameter offset. */
321 if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)puBuffer,
322 ulParamOffset, usParamLen)) {
323 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
325 "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
326 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
330 /* Calculate the checksum of the data read from the DSD parameter. */
331 usChecksumCalculated = CFG_CalculateChecksum(puBuffer, usParamLen);
332 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
333 "LED Thread: usCheckSumCalculated = 0x%x\n",
334 usChecksumCalculated);
337 * End of the DSD parameter will have a TWO bytes checksum stored in it.
338 * Read it and compare with the calculated Checksum.
340 if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)&usChksmOrg,
341 ulParamOffset+usParamLen, 2)) {
342 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
344 "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
345 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
348 usChksmOrg = ntohs(usChksmOrg);
349 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
350 "LED Thread: usChksmOrg = 0x%x", usChksmOrg);
353 * Compare the checksum calculated with the checksum read
356 if (usChecksumCalculated ^ usChksmOrg) {
357 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
359 "LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
360 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
371 * -----------------------------------------------------------------------------
372 * Procedure: ValidateHWParmStructure
374 * Description: Validates HW Parameters.
377 * Adapter - Pointer to Adapter structure.
378 * ulHwParamOffset - Start offset of the HW parameter Section to be read
383 * -----------------------------------------------------------------------------
385 static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter,
386 ULONG ulHwParamOffset)
389 INT Status = STATUS_SUCCESS;
390 USHORT HwParamLen = 0;
392 * Add DSD start offset to the hwParamOffset to get
393 * the actual address.
395 ulHwParamOffset += DSD_START_OFFSET;
397 /* Read the Length of HW_PARAM structure */
398 BeceemNVMRead(Adapter, (PUINT)&HwParamLen, ulHwParamOffset, 2);
399 HwParamLen = ntohs(HwParamLen);
400 if (0 == HwParamLen || HwParamLen > Adapter->uiNVMDSDSize)
401 return STATUS_IMAGE_CHECKSUM_MISMATCH;
403 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
404 "LED Thread:HwParamLen = 0x%x", HwParamLen);
405 Status = ValidateDSDParamsChecksum(Adapter, ulHwParamOffset,
408 } /* ValidateHWParmStructure() */
410 static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter,
413 int Status = STATUS_SUCCESS;
415 ULONG dwReadValue = 0;
416 USHORT usHwParamData = 0;
417 USHORT usEEPROMVersion = 0;
419 UCHAR ucGPIOInfo[32] = {0};
421 BeceemNVMRead(Adapter, (PUINT)&usEEPROMVersion,
422 EEPROM_VERSION_OFFSET, 2);
424 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
425 "usEEPROMVersion: Minor:0x%X Major:0x%x",
426 usEEPROMVersion & 0xFF,
427 ((usEEPROMVersion >> 8) & 0xFF));
430 if (((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION) {
431 BeceemNVMRead(Adapter, (PUINT)&usHwParamData,
432 EEPROM_HW_PARAM_POINTER_ADDRESS, 2);
433 usHwParamData = ntohs(usHwParamData);
434 dwReadValue = usHwParamData;
437 * Validate Compatibility section and then read HW param
438 * if compatibility section is valid.
440 Status = ValidateDSDParamsChecksum(Adapter,
442 COMPATIBILITY_SECTION_LENGTH_MAP5);
444 if (Status != STATUS_SUCCESS)
447 BeceemNVMRead(Adapter, (PUINT)&dwReadValue,
448 EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4);
449 dwReadValue = ntohl(dwReadValue);
453 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
454 "LED Thread: Start address of HW_PARAM structure = 0x%lx",
458 * Validate if the address read out is within the DSD.
459 * Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
460 * lower limit should be above DSD_START_OFFSET and
461 * upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
463 if (dwReadValue < DSD_START_OFFSET ||
464 dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET))
465 return STATUS_IMAGE_CHECKSUM_MISMATCH;
467 Status = ValidateHWParmStructure(Adapter, dwReadValue);
472 * Add DSD_START_OFFSET to the offset read from the EEPROM.
473 * This will give the actual start HW Parameters start address.
474 * To read GPIO section, add GPIO offset further.
477 dwReadValue += DSD_START_OFFSET;
478 /* = start address of hw param section. */
479 dwReadValue += GPIO_SECTION_START_OFFSET;
480 /* = GPIO start offset within HW Param section. */
483 * Read the GPIO values for 32 GPIOs from EEPROM and map the function
484 * number to GPIO pin number to GPIO_Array
486 BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo, dwReadValue, 32);
487 for (ucIndex = 0; ucIndex < 32; ucIndex++) {
489 switch (ucGPIOInfo[ucIndex]) {
491 GPIO_Array[RED_LED] = ucIndex;
492 Adapter->gpioBitMap |= (1 << ucIndex);
495 GPIO_Array[BLUE_LED] = ucIndex;
496 Adapter->gpioBitMap |= (1 << ucIndex);
499 GPIO_Array[YELLOW_LED] = ucIndex;
500 Adapter->gpioBitMap |= (1 << ucIndex);
503 GPIO_Array[GREEN_LED] = ucIndex;
504 Adapter->gpioBitMap |= (1 << ucIndex);
511 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
512 "GPIO's bit map correspond to LED :0x%X",
513 Adapter->gpioBitMap);
518 static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
521 int Status = STATUS_SUCCESS;
522 /* Array to store GPIO numbers from EEPROM */
523 UCHAR GPIO_Array[NUM_OF_LEDS+1];
525 UINT uiNum_of_LED_Type = 0;
526 PUCHAR puCFGData = NULL;
528 memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
530 if (!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) {
531 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
532 DBG_LVL_ALL, "Target Params not Avail.\n");
536 /* Populate GPIO_Array with GPIO numbers for LED functions */
537 /* Read the GPIO numbers from EEPROM */
538 Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array);
539 if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) {
540 *bEnableThread = false;
541 return STATUS_SUCCESS;
543 *bEnableThread = false;
548 * CONFIG file read successfully. Deallocate the memory of
549 * uiFileNameBufferSize
551 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
552 "LED Thread: Config file read successfully\n");
553 puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1;
556 * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
557 * will have the information of LED type, LED on state for different
558 * driver state and LED blink state.
561 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
565 * Check Bit 8 for polarity. If it is set,
566 * polarity is reverse polarity
569 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 0;
570 /* unset the bit 8 */
571 bData = bData & 0x7f;
574 Adapter->LEDInfo.LEDState[uiIndex].LED_Type = bData;
575 if (bData <= NUM_OF_LEDS)
576 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num =
579 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num =
584 Adapter->LEDInfo.LEDState[uiIndex].LED_On_State = bData;
587 Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State = bData;
592 * Check if all the LED settings are disabled. If it is disabled,
593 * dont launch the LED control thread.
595 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
596 if ((Adapter->LEDInfo.LEDState[uiIndex].LED_Type ==
598 (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0x7f) ||
599 (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0))
602 if (uiNum_of_LED_Type >= NUM_OF_LEDS)
603 *bEnableThread = false;
609 * -----------------------------------------------------------------------------
610 * Procedure: LedGpioInit
612 * Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode
613 * and make the initial state to be OFF.
616 * Adapter - Pointer to MINI_ADAPTER structure.
620 * -----------------------------------------------------------------------------
622 static VOID LedGpioInit(struct bcm_mini_adapter *Adapter)
624 UINT uiResetValue = 0;
627 /* Set all LED GPIO Mode to output mode */
628 if (rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
629 sizeof(uiResetValue)) < 0)
630 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
631 DBG_LVL_ALL, "LED Thread: RDM Failed\n");
632 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
633 if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
635 uiResetValue |= (1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
636 TURN_OFF_LED(Adapter,
637 1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num,
640 if (wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
641 sizeof(uiResetValue)) < 0)
642 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
643 DBG_LVL_ALL, "LED Thread: WRM Failed\n");
645 Adapter->LEDInfo.bIdle_led_off = false;
648 static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter,
653 enum bcm_led_events currdriverstate)
656 struct bcm_led_state_info *led_state_info;
658 *GPIO_num_tx = DISABLE_GPIO_NUM;
659 *GPIO_num_rx = DISABLE_GPIO_NUM;
661 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
662 led_state_info = &Adapter->LEDInfo.LEDState[uiIndex];
664 if (((currdriverstate == NORMAL_OPERATION) ||
665 (currdriverstate == IDLEMODE_EXIT) ||
666 (currdriverstate == FW_DOWNLOAD)) &&
667 (led_state_info->LED_Blink_State & currdriverstate)) {
668 if (led_state_info->GPIO_Num != DISABLE_GPIO_NUM) {
669 if (*GPIO_num_tx == DISABLE_GPIO_NUM) {
670 *GPIO_num_tx = led_state_info->GPIO_Num;
671 *uiLedTxIndex = uiIndex;
673 *GPIO_num_rx = led_state_info->GPIO_Num;
674 *uiLedRxIndex = uiIndex;
678 if ((led_state_info->LED_On_State & currdriverstate) &&
679 (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) {
680 *GPIO_num_tx = led_state_info->GPIO_Num;
681 *uiLedTxIndex = uiIndex;
685 return STATUS_SUCCESS;
688 static void handle_adapter_driver_state(struct bcm_mini_adapter *ad,
689 enum bcm_led_events currdriverstate,
698 switch (ad->DriverState) {
700 currdriverstate = DRIVER_INIT;
701 /* ad->DriverState; */
702 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
703 &uiLedIndex, &dummyIndex,
706 if (GPIO_num != DISABLE_GPIO_NUM)
707 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
712 * BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
713 * LED_DUMP_INFO, DBG_LVL_ALL,
714 * "LED Thread: FW_DN_DONE called\n");
716 currdriverstate = FW_DOWNLOAD;
717 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
718 &uiLedIndex, &dummyIndex,
721 if (GPIO_num != DISABLE_GPIO_NUM) {
723 LED_Blink(ad, 1 << GPIO_num, uiLedIndex, timeout,
724 -1, currdriverstate);
727 case FW_DOWNLOAD_DONE:
728 currdriverstate = FW_DOWNLOAD_DONE;
729 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
730 &uiLedIndex, &dummyIndex, currdriverstate);
731 if (GPIO_num != DISABLE_GPIO_NUM)
732 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
737 * no break, continue to NO_NETWORK_ENTRY
740 case NO_NETWORK_ENTRY:
741 currdriverstate = NO_NETWORK_ENTRY;
742 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
743 &uiLedIndex, &dummyGPIONum, currdriverstate);
744 if (GPIO_num != DISABLE_GPIO_NUM)
745 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
747 case NORMAL_OPERATION:
749 UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
750 UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
753 currdriverstate = NORMAL_OPERATION;
754 ad->LEDInfo.bIdle_led_off = false;
756 BcmGetGPIOPinInfo(ad, &GPIO_num_tx, &GPIO_num_rx,
757 &uiLEDTx, &uiLEDRx, currdriverstate);
758 if ((GPIO_num_tx == DISABLE_GPIO_NUM) &&
759 (GPIO_num_rx == DISABLE_GPIO_NUM)) {
760 GPIO_num = DISABLE_GPIO_NUM;
763 * If single LED is selected, use same
766 if (GPIO_num_tx == DISABLE_GPIO_NUM) {
767 GPIO_num_tx = GPIO_num_rx;
769 } else if (GPIO_num_rx == DISABLE_GPIO_NUM) {
770 GPIO_num_rx = GPIO_num_tx;
774 * Blink the LED in proportionate
775 * to Tx and Rx transmissions.
777 LED_Proportional_Blink(ad,
778 GPIO_num_tx, uiLEDTx,
779 GPIO_num_rx, uiLEDRx,
784 case LOWPOWER_MODE_ENTER:
785 currdriverstate = LOWPOWER_MODE_ENTER;
786 if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING ==
787 ad->ulPowerSaveMode) {
788 /* Turn OFF all the LED */
790 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
791 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
793 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
798 /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
799 ad->LEDInfo.bLedInitDone = false;
800 ad->LEDInfo.bIdle_led_off = TRUE;
801 wake_up(&ad->LEDInfo.idleModeSyncEvent);
802 GPIO_num = DISABLE_GPIO_NUM;
804 case IDLEMODE_CONTINUE:
805 currdriverstate = IDLEMODE_CONTINUE;
806 GPIO_num = DISABLE_GPIO_NUM;
811 currdriverstate = DRIVER_HALT;
812 GPIO_num = DISABLE_GPIO_NUM;
813 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
814 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num !=
817 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
820 /* ad->DriverState = DRIVER_INIT; */
822 case LED_THREAD_INACTIVE:
823 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO,
824 DBG_LVL_ALL, "InActivating LED thread...");
825 currdriverstate = LED_THREAD_INACTIVE;
826 ad->LEDInfo.led_thread_running =
827 BCM_LED_THREAD_RUNNING_INACTIVELY;
828 ad->LEDInfo.bLedInitDone = false;
829 /* disable ALL LED */
830 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
831 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num !=
834 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
838 case LED_THREAD_ACTIVE:
839 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO,
840 DBG_LVL_ALL, "Activating LED thread again...");
841 if (ad->LinkUpStatus == false)
842 ad->DriverState = NO_NETWORK_ENTRY;
844 ad->DriverState = NORMAL_OPERATION;
846 ad->LEDInfo.led_thread_running =
847 BCM_LED_THREAD_RUNNING_ACTIVELY;
855 static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
859 UCHAR uiLedIndex = 0;
860 UINT uiResetValue = 0;
861 enum bcm_led_events currdriverstate = 0;
866 UCHAR dummyGPIONum = 0;
867 UCHAR dummyIndex = 0;
869 /* currdriverstate = Adapter->DriverState; */
870 Adapter->LEDInfo.bIdleMode_tx_from_host = false;
873 * Wait till event is triggered
875 * wait_event(Adapter->LEDInfo.notify_led_event,
876 * currdriverstate!= Adapter->DriverState);
879 GPIO_num = DISABLE_GPIO_NUM;
882 /* Wait till event is triggered */
883 if ((GPIO_num == DISABLE_GPIO_NUM)
885 ((currdriverstate != FW_DOWNLOAD) &&
886 (currdriverstate != NORMAL_OPERATION) &&
887 (currdriverstate != LOWPOWER_MODE_ENTER))
889 (currdriverstate == LED_THREAD_INACTIVE))
890 Status = wait_event_interruptible(
891 Adapter->LEDInfo.notify_led_event,
892 currdriverstate != Adapter->DriverState
893 || kthread_should_stop());
895 if (kthread_should_stop() || Adapter->device_removed) {
896 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
898 "Led thread got signal to exit..hence exiting");
899 Adapter->LEDInfo.led_thread_running =
900 BCM_LED_THREAD_DISABLED;
901 TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex);
902 return; /* STATUS_FAILURE; */
905 if (GPIO_num != DISABLE_GPIO_NUM)
906 TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex);
908 if (Adapter->LEDInfo.bLedInitDone == false) {
909 LedGpioInit(Adapter);
910 Adapter->LEDInfo.bLedInitDone = TRUE;
913 handle_adapter_driver_state(Adapter,
924 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
927 int InitLedSettings(struct bcm_mini_adapter *Adapter)
929 int Status = STATUS_SUCCESS;
930 bool bEnableThread = TRUE;
934 * Initially set BitPolarity to normal polarity. The bit 8 of LED type
935 * is used to change the polarity of the LED.
938 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
939 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1;
942 * Read the LED settings of CONFIG file and map it
943 * to GPIO numbers in EEPROM
945 Status = ReadConfigFileStructure(Adapter, &bEnableThread);
946 if (STATUS_SUCCESS != Status) {
947 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
949 "LED Thread: FAILED in ReadConfigFileStructure\n");
953 if (Adapter->LEDInfo.led_thread_running) {
957 Adapter->DriverState = DRIVER_HALT;
958 wake_up(&Adapter->LEDInfo.notify_led_event);
959 Adapter->LEDInfo.led_thread_running =
960 BCM_LED_THREAD_DISABLED;
963 } else if (bEnableThread) {
964 /* Create secondary thread to handle the LEDs */
965 init_waitqueue_head(&Adapter->LEDInfo.notify_led_event);
966 init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent);
967 Adapter->LEDInfo.led_thread_running =
968 BCM_LED_THREAD_RUNNING_ACTIVELY;
969 Adapter->LEDInfo.bIdle_led_off = false;
970 Adapter->LEDInfo.led_cntrl_threadid =
971 kthread_run((int (*)(void *)) LEDControlThread,
972 Adapter, "led_control_thread");
973 if (IS_ERR(Adapter->LEDInfo.led_cntrl_threadid)) {
974 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
976 "Not able to spawn Kernel Thread\n");
977 Adapter->LEDInfo.led_thread_running =
978 BCM_LED_THREAD_DISABLED;
979 return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);