1 #include "headers.h"
2
3 #define STATUS_IMAGE_CHECKSUM_MISMATCH -199
4 #define EVENT_SIGNALED 1
5
CFG_CalculateChecksum(B_UINT8 * pu8Buffer,B_UINT32 u32Size)6 static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size)
7 {
8 B_UINT16 u16CheckSum=0;
9 while(u32Size--) {
10 u16CheckSum += (B_UINT8)~(*pu8Buffer);
11 pu8Buffer++;
12 }
13 return u16CheckSum;
14 }
IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter,UINT gpios)15 BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios)
16 {
17 INT Status ;
18 Status = (Adapter->gpioBitMap & gpios) ^ gpios ;
19 if(Status)
20 return FALSE;
21 else
22 return TRUE;
23 }
24
LED_Blink(PMINI_ADAPTER Adapter,UINT GPIO_Num,UCHAR uiLedIndex,ULONG timeout,INT num_of_time,LedEventInfo_t currdriverstate)25 static INT LED_Blink(PMINI_ADAPTER Adapter, UINT GPIO_Num, UCHAR uiLedIndex, ULONG timeout, INT num_of_time, LedEventInfo_t currdriverstate)
26 {
27 int Status = STATUS_SUCCESS;
28 BOOLEAN bInfinite = FALSE;
29
30 /*Check if num_of_time is -ve. If yes, blink led in infinite loop*/
31 if(num_of_time < 0)
32 {
33 bInfinite = TRUE;
34 num_of_time = 1;
35 }
36 while(num_of_time)
37 {
38
39 if(currdriverstate == Adapter->DriverState)
40 TURN_ON_LED(GPIO_Num, uiLedIndex);
41
42 /*Wait for timeout after setting on the LED*/
43 Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
44 currdriverstate != Adapter->DriverState || kthread_should_stop(),
45 msecs_to_jiffies(timeout));
46
47 if(kthread_should_stop())
48 {
49 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
50 Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
51 TURN_OFF_LED(GPIO_Num, uiLedIndex);
52 Status=EVENT_SIGNALED;
53 break;
54 }
55 if(Status)
56 {
57 TURN_OFF_LED(GPIO_Num, uiLedIndex);
58 Status=EVENT_SIGNALED;
59 break;
60 }
61
62 TURN_OFF_LED(GPIO_Num, uiLedIndex);
63 Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
64 currdriverstate!= Adapter->DriverState || kthread_should_stop(),
65 msecs_to_jiffies(timeout));
66 if(bInfinite == FALSE)
67 num_of_time--;
68 }
69 return Status;
70 }
71
ScaleRateofTransfer(ULONG rate)72 static INT ScaleRateofTransfer(ULONG rate)
73 {
74 if(rate <= 3)
75 return rate;
76 else if((rate > 3) && (rate <= 100))
77 return 5;
78 else if((rate > 100) && (rate <= 200))
79 return 6;
80 else if((rate > 200) && (rate <= 300))
81 return 7;
82 else if((rate > 300) && (rate <= 400))
83 return 8;
84 else if((rate > 400) && (rate <= 500))
85 return 9;
86 else if((rate > 500) && (rate <= 600))
87 return 10;
88 else
89 return MAX_NUM_OF_BLINKS;
90 }
91
92
93
LED_Proportional_Blink(PMINI_ADAPTER Adapter,UCHAR GPIO_Num_tx,UCHAR uiTxLedIndex,UCHAR GPIO_Num_rx,UCHAR uiRxLedIndex,LedEventInfo_t currdriverstate)94 static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx,
95 UCHAR uiTxLedIndex, UCHAR GPIO_Num_rx, UCHAR uiRxLedIndex, LedEventInfo_t currdriverstate)
96 {
97 /* Initial values of TX and RX packets*/
98 ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0;
99 /*values of TX and RX packets after 1 sec*/
100 ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0;
101 /*Rate of transfer of Tx and Rx in 1 sec*/
102 ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0;
103 int Status = STATUS_SUCCESS;
104 INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
105 UINT remDelay = 0;
106 BOOLEAN bBlinkBothLED = TRUE;
107 //UINT GPIO_num = DISABLE_GPIO_NUM;
108 ulong timeout = 0;
109
110 /*Read initial value of packets sent/received */
111 Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets;
112 Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets;
113
114 /*Scale the rate of transfer to no of blinks.*/
115 num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
116 num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
117
118 while((Adapter->device_removed == FALSE))
119 {
120 timeout = 50;
121 /*Blink Tx and Rx LED when both Tx and Rx is in normal bandwidth*/
122 if(bBlinkBothLED)
123 {
124 /*Assign minimum number of blinks of either Tx or Rx.*/
125 if(num_of_time_tx > num_of_time_rx)
126 num_of_time = num_of_time_rx;
127 else
128 num_of_time = num_of_time_tx;
129 if(num_of_time > 0)
130 {
131 /*Blink both Tx and Rx LEDs*/
132 if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout, num_of_time,currdriverstate)
133 == EVENT_SIGNALED)
134 {
135 return EVENT_SIGNALED;
136 }
137 if(LED_Blink(Adapter, 1<<GPIO_Num_rx, uiRxLedIndex, timeout, num_of_time,currdriverstate)
138 == EVENT_SIGNALED)
139 {
140 return EVENT_SIGNALED;
141 }
142
143 }
144
145 if(num_of_time == num_of_time_tx)
146 {
147 /*Blink pending rate of Rx*/
148 if(LED_Blink(Adapter, (1 << GPIO_Num_rx), uiRxLedIndex, timeout,
149 num_of_time_rx-num_of_time,currdriverstate) == EVENT_SIGNALED)
150 {
151 return EVENT_SIGNALED;
152 }
153 num_of_time = num_of_time_rx;
154 }
155 else
156 {
157 /*Blink pending rate of Tx*/
158 if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout,
159 num_of_time_tx-num_of_time,currdriverstate) == EVENT_SIGNALED)
160 {
161 return EVENT_SIGNALED;
162 }
163 num_of_time = num_of_time_tx;
164 }
165 }
166 else
167 {
168 if(num_of_time == num_of_time_tx)
169 {
170 /*Blink pending rate of Rx*/
171 if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout, num_of_time,currdriverstate)
172 == EVENT_SIGNALED)
173 {
174 return EVENT_SIGNALED;
175 }
176 }
177 else
178 {
179 /*Blink pending rate of Tx*/
180 if(LED_Blink(Adapter, 1<<GPIO_Num_rx, uiRxLedIndex, timeout,
181 num_of_time,currdriverstate) == EVENT_SIGNALED)
182 {
183 return EVENT_SIGNALED;
184 }
185 }
186 }
187 /* If Tx/Rx rate is less than maximum blinks per second,
188 * wait till delay completes to 1 second
189 */
190 remDelay = MAX_NUM_OF_BLINKS - num_of_time;
191 if(remDelay > 0)
192 {
193 timeout= 100 * remDelay;
194 Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
195 currdriverstate!= Adapter->DriverState ||kthread_should_stop() ,
196 msecs_to_jiffies (timeout));
197
198 if(kthread_should_stop())
199 {
200 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
201 Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
202 return EVENT_SIGNALED;
203 }
204 if(Status)
205 return EVENT_SIGNALED;
206 }
207
208 /*Turn off both Tx and Rx LEDs before next second*/
209 TURN_OFF_LED(1<<GPIO_Num_tx, uiTxLedIndex);
210 TURN_OFF_LED(1<<GPIO_Num_rx, uiTxLedIndex);
211
212 /*
213 * Read the Tx & Rx packets transmission after 1 second and
214 * calculate rate of transfer
215 */
216 Final_num_of_packts_tx = Adapter->dev->stats.tx_packets;
217 Final_num_of_packts_rx = Adapter->dev->stats.rx_packets;
218
219 rate_of_transfer_tx = Final_num_of_packts_tx - Initial_num_of_packts_tx;
220 rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx;
221
222 /*Read initial value of packets sent/received */
223 Initial_num_of_packts_tx = Final_num_of_packts_tx;
224 Initial_num_of_packts_rx = Final_num_of_packts_rx ;
225
226 /*Scale the rate of transfer to no of blinks.*/
227 num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
228 num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
229
230 }
231 return Status;
232 }
233
234
235 //-----------------------------------------------------------------------------
236 // Procedure: ValidateDSDParamsChecksum
237 //
238 // Description: Reads DSD Params and validates checkusm.
239 //
240 // Arguments:
241 // Adapter - Pointer to Adapter structure.
242 // ulParamOffset - Start offset of the DSD parameter to be read and validated.
243 // usParamLen - Length of the DSD Parameter.
244 //
245 // Returns:
246 // <OSAL_STATUS_CODE>
247 //-----------------------------------------------------------------------------
248
ValidateDSDParamsChecksum(PMINI_ADAPTER Adapter,ULONG ulParamOffset,USHORT usParamLen)249 static INT ValidateDSDParamsChecksum(
250 PMINI_ADAPTER Adapter,
251 ULONG ulParamOffset,
252 USHORT usParamLen )
253 {
254 INT Status = STATUS_SUCCESS;
255 PUCHAR puBuffer = NULL;
256 USHORT usChksmOrg = 0;
257 USHORT usChecksumCalculated = 0;
258
259 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",ulParamOffset, usParamLen);
260
261 puBuffer = kmalloc(usParamLen, GFP_KERNEL);
262 if(!puBuffer)
263 {
264 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum Allocation failed");
265 return -ENOMEM;
266
267 }
268
269 //
270 // Read the DSD data from the parameter offset.
271 //
272 if(STATUS_SUCCESS != BeceemNVMRead(Adapter,(PUINT)puBuffer,ulParamOffset,usParamLen))
273 {
274 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
275 Status=STATUS_IMAGE_CHECKSUM_MISMATCH;
276 goto exit;
277 }
278
279 //
280 // Calculate the checksum of the data read from the DSD parameter.
281 //
282 usChecksumCalculated = CFG_CalculateChecksum(puBuffer,usParamLen);
283 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: usCheckSumCalculated = 0x%x\n", usChecksumCalculated);
284
285 //
286 // End of the DSD parameter will have a TWO bytes checksum stored in it. Read it and compare with the calculated
287 // Checksum.
288 //
289 if(STATUS_SUCCESS != BeceemNVMRead(Adapter,(PUINT)&usChksmOrg,ulParamOffset+usParamLen,2))
290 {
291 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
292 Status=STATUS_IMAGE_CHECKSUM_MISMATCH;
293 goto exit;
294 }
295 usChksmOrg = ntohs(usChksmOrg);
296 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: usChksmOrg = 0x%x", usChksmOrg);
297
298 //
299 // Compare the checksum calculated with the checksum read from DSD section
300 //
301 if(usChecksumCalculated ^ usChksmOrg)
302 {
303 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
304 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
305 goto exit;
306 }
307
308 exit:
309 kfree(puBuffer);
310 return Status;
311 }
312
313
314 //-----------------------------------------------------------------------------
315 // Procedure: ValidateHWParmStructure
316 //
317 // Description: Validates HW Parameters.
318 //
319 // Arguments:
320 // Adapter - Pointer to Adapter structure.
321 // ulHwParamOffset - Start offset of the HW parameter Section to be read and validated.
322 //
323 // Returns:
324 // <OSAL_STATUS_CODE>
325 //-----------------------------------------------------------------------------
326
ValidateHWParmStructure(PMINI_ADAPTER Adapter,ULONG ulHwParamOffset)327 static INT ValidateHWParmStructure(PMINI_ADAPTER Adapter, ULONG ulHwParamOffset)
328 {
329
330 INT Status = STATUS_SUCCESS ;
331 USHORT HwParamLen = 0;
332 // Add DSD start offset to the hwParamOffset to get the actual address.
333 ulHwParamOffset += DSD_START_OFFSET;
334
335 /*Read the Length of HW_PARAM structure*/
336 BeceemNVMRead(Adapter,(PUINT)&HwParamLen,ulHwParamOffset,2);
337 HwParamLen = ntohs(HwParamLen);
338 if(0==HwParamLen || HwParamLen > Adapter->uiNVMDSDSize)
339 {
340 return STATUS_IMAGE_CHECKSUM_MISMATCH;
341 }
342
343 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread:HwParamLen = 0x%x", HwParamLen);
344 Status =ValidateDSDParamsChecksum(Adapter,ulHwParamOffset,HwParamLen);
345 return Status;
346 } /* ValidateHWParmStructure() */
347
ReadLEDInformationFromEEPROM(PMINI_ADAPTER Adapter,UCHAR GPIO_Array[])348 static int ReadLEDInformationFromEEPROM(PMINI_ADAPTER Adapter, UCHAR GPIO_Array[])
349 {
350 int Status = STATUS_SUCCESS;
351
352 ULONG dwReadValue = 0;
353 USHORT usHwParamData = 0;
354 USHORT usEEPROMVersion = 0;
355 UCHAR ucIndex = 0;
356 UCHAR ucGPIOInfo[32] = {0};
357
358 BeceemNVMRead(Adapter,(PUINT)&usEEPROMVersion,EEPROM_VERSION_OFFSET,2);
359
360 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"usEEPROMVersion: Minor:0x%X Major:0x%x",usEEPROMVersion&0xFF, ((usEEPROMVersion>>8)&0xFF));
361
362
363 if(((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION)
364 {
365 BeceemNVMRead(Adapter,(PUINT)&usHwParamData,EEPROM_HW_PARAM_POINTER_ADDRESS,2);
366 usHwParamData = ntohs(usHwParamData);
367 dwReadValue = usHwParamData;
368 }
369 else
370 {
371 //
372 // Validate Compatibility section and then read HW param if compatibility section is valid.
373 //
374 Status = ValidateDSDParamsChecksum(Adapter,
375 DSD_START_OFFSET,
376 COMPATIBILITY_SECTION_LENGTH_MAP5);
377
378 if(Status != STATUS_SUCCESS)
379 {
380 return Status;
381 }
382 BeceemNVMRead(Adapter,(PUINT)&dwReadValue,EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5,4);
383 dwReadValue = ntohl(dwReadValue);
384 }
385
386
387 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Start address of HW_PARAM structure = 0x%lx",dwReadValue);
388
389 //
390 // Validate if the address read out is within the DSD.
391 // Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
392 // lower limit should be above DSD_START_OFFSET and
393 // upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
394 //
395 if(dwReadValue < DSD_START_OFFSET ||
396 dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET))
397 {
398 return STATUS_IMAGE_CHECKSUM_MISMATCH;
399 }
400
401 Status = ValidateHWParmStructure(Adapter, dwReadValue);
402 if(Status){
403 return Status;
404 }
405
406 /*
407 Add DSD_START_OFFSET to the offset read from the EEPROM.
408 This will give the actual start HW Parameters start address.
409 To read GPIO section, add GPIO offset further.
410 */
411
412 dwReadValue += DSD_START_OFFSET; // = start address of hw param section.
413 dwReadValue += GPIO_SECTION_START_OFFSET; // = GPIO start offset within HW Param section.
414
415 /* Read the GPIO values for 32 GPIOs from EEPROM and map the function
416 * number to GPIO pin number to GPIO_Array
417 */
418 BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo,dwReadValue,32);
419 for(ucIndex = 0; ucIndex < 32; ucIndex++)
420 {
421
422 switch(ucGPIOInfo[ucIndex])
423 {
424 case RED_LED:
425 {
426 GPIO_Array[RED_LED] = ucIndex;
427 Adapter->gpioBitMap |= (1<<ucIndex);
428 break;
429 }
430 case BLUE_LED:
431 {
432 GPIO_Array[BLUE_LED] = ucIndex;
433 Adapter->gpioBitMap |= (1<<ucIndex);
434 break;
435 }
436 case YELLOW_LED:
437 {
438 GPIO_Array[YELLOW_LED] = ucIndex;
439 Adapter->gpioBitMap |= (1<<ucIndex);
440 break;
441 }
442 case GREEN_LED:
443 {
444 GPIO_Array[GREEN_LED] = ucIndex;
445 Adapter->gpioBitMap |= (1<<ucIndex);
446 break;
447 }
448 default:
449 break;
450 }
451
452 }
453 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"GPIO's bit map correspond to LED :0x%X",Adapter->gpioBitMap);
454 return Status;
455 }
456
457
ReadConfigFileStructure(PMINI_ADAPTER Adapter,BOOLEAN * bEnableThread)458 static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread)
459 {
460 int Status = STATUS_SUCCESS;
461 UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/
462 UINT uiIndex = 0;
463 UINT uiNum_of_LED_Type = 0;
464 PUCHAR puCFGData = NULL;
465 UCHAR bData = 0;
466 memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
467
468 if(!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams))
469 {
470 BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Target Params not Avail.\n");
471 return -ENOENT;
472 }
473
474 /*Populate GPIO_Array with GPIO numbers for LED functions*/
475 /*Read the GPIO numbers from EEPROM*/
476 Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array);
477 if(Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
478 {
479 *bEnableThread = FALSE;
480 return STATUS_SUCCESS;
481 }
482 else if(Status)
483 {
484 *bEnableThread = FALSE;
485 return Status;
486 }
487 /*
488 * CONFIG file read successfully. Deallocate the memory of
489 * uiFileNameBufferSize
490 */
491 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Config file read successfully\n");
492 puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1;
493
494 /*
495 * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
496 * will have the information of LED type, LED on state for different
497 * driver state and LED blink state.
498 */
499
500 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
501 {
502 bData = *puCFGData;
503
504 /*Check Bit 8 for polarity. If it is set, polarity is reverse polarity*/
505 if(bData & 0x80)
506 {
507 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 0;
508 /*unset the bit 8*/
509 bData = bData & 0x7f;
510 }
511
512 Adapter->LEDInfo.LEDState[uiIndex].LED_Type = bData;
513 if(bData <= NUM_OF_LEDS)
514 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = GPIO_Array[bData];
515 else
516 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = DISABLE_GPIO_NUM;
517
518 puCFGData++;
519 bData = *puCFGData;
520 Adapter->LEDInfo.LEDState[uiIndex].LED_On_State = bData;
521 puCFGData++;
522 bData = *puCFGData;
523 Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State= bData;
524 puCFGData++;
525 }
526
527 /*Check if all the LED settings are disabled. If it is disabled, dont launch the LED control thread.*/
528 for(uiIndex = 0; uiIndex<NUM_OF_LEDS; uiIndex++)
529 {
530 if((Adapter->LEDInfo.LEDState[uiIndex].LED_Type == DISABLE_GPIO_NUM) ||
531 (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0x7f) ||
532 (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0))
533 uiNum_of_LED_Type++;
534 }
535 if(uiNum_of_LED_Type >= NUM_OF_LEDS)
536 *bEnableThread = FALSE;
537
538 return Status;
539 }
540 //--------------------------------------------------------------------------
541 // Procedure: LedGpioInit
542 //
543 // Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode and make the
544 // initial state to be OFF.
545 //
546 // Arguments:
547 // Adapter - Pointer to MINI_ADAPTER structure.
548 //
549 // Returns: VOID
550 //
551 //-----------------------------------------------------------------------------
552
LedGpioInit(PMINI_ADAPTER Adapter)553 static VOID LedGpioInit(PMINI_ADAPTER Adapter)
554 {
555 UINT uiResetValue = 0;
556 UINT uiIndex = 0;
557
558 /* Set all LED GPIO Mode to output mode */
559 if(rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) <0)
560 BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: RDM Failed\n");
561 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
562 {
563 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
564 uiResetValue |= (1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
565 TURN_OFF_LED(1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num,uiIndex);
566 }
567 if(wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) < 0)
568 BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: WRM Failed\n");
569
570 Adapter->LEDInfo.bIdle_led_off = FALSE;
571 }
572 //-----------------------------------------------------------------------------
573
BcmGetGPIOPinInfo(PMINI_ADAPTER Adapter,UCHAR * GPIO_num_tx,UCHAR * GPIO_num_rx,UCHAR * uiLedTxIndex,UCHAR * uiLedRxIndex,LedEventInfo_t currdriverstate)574 static INT BcmGetGPIOPinInfo(PMINI_ADAPTER Adapter, UCHAR *GPIO_num_tx, UCHAR *GPIO_num_rx ,UCHAR *uiLedTxIndex, UCHAR *uiLedRxIndex,LedEventInfo_t currdriverstate)
575 {
576 UINT uiIndex = 0;
577
578 *GPIO_num_tx = DISABLE_GPIO_NUM;
579 *GPIO_num_rx = DISABLE_GPIO_NUM;
580
581 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
582 {
583
584 if((currdriverstate == NORMAL_OPERATION)||
585 (currdriverstate == IDLEMODE_EXIT)||
586 (currdriverstate == FW_DOWNLOAD))
587 {
588 if(Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State & currdriverstate)
589 {
590 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
591 {
592 if(*GPIO_num_tx == DISABLE_GPIO_NUM)
593 {
594 *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
595 *uiLedTxIndex = uiIndex;
596 }
597 else
598 {
599 *GPIO_num_rx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
600 *uiLedRxIndex = uiIndex;
601 }
602 }
603 }
604 }
605 else
606 {
607 if(Adapter->LEDInfo.LEDState[uiIndex].LED_On_State & currdriverstate)
608 {
609 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
610 {
611 *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
612 *uiLedTxIndex = uiIndex;
613 }
614 }
615 }
616 }
617 return STATUS_SUCCESS ;
618 }
LEDControlThread(PMINI_ADAPTER Adapter)619 static VOID LEDControlThread(PMINI_ADAPTER Adapter)
620 {
621 UINT uiIndex = 0;
622 UCHAR GPIO_num = 0;
623 UCHAR uiLedIndex = 0 ;
624 UINT uiResetValue = 0;
625 LedEventInfo_t currdriverstate = 0;
626 ulong timeout = 0;
627
628 INT Status = 0;
629
630 UCHAR dummyGPIONum = 0;
631 UCHAR dummyIndex = 0;
632
633 //currdriverstate = Adapter->DriverState;
634 Adapter->LEDInfo.bIdleMode_tx_from_host = FALSE;
635
636 /*Wait till event is triggered*/
637 //wait_event(Adapter->LEDInfo.notify_led_event,
638 // currdriverstate!= Adapter->DriverState);
639
640 GPIO_num = DISABLE_GPIO_NUM ;
641
642 while(TRUE)
643 {
644 /*Wait till event is triggered*/
645 if( (GPIO_num == DISABLE_GPIO_NUM)
646 ||
647 ((currdriverstate != FW_DOWNLOAD) &&
648 (currdriverstate != NORMAL_OPERATION) &&
649 (currdriverstate != LOWPOWER_MODE_ENTER))
650 ||
651 (currdriverstate == LED_THREAD_INACTIVE) )
652 {
653 Status = wait_event_interruptible(Adapter->LEDInfo.notify_led_event,
654 currdriverstate != Adapter->DriverState || kthread_should_stop());
655 }
656
657 if(kthread_should_stop() || Adapter->device_removed )
658 {
659 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
660 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
661 TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
662 return ;//STATUS_FAILURE;
663 }
664
665 if(GPIO_num != DISABLE_GPIO_NUM)
666 {
667 TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
668 }
669
670 if(Adapter->LEDInfo.bLedInitDone == FALSE)
671 {
672 LedGpioInit(Adapter);
673 Adapter->LEDInfo.bLedInitDone = TRUE;
674 }
675
676 switch(Adapter->DriverState)
677 {
678 case DRIVER_INIT:
679 {
680 currdriverstate = DRIVER_INIT;//Adapter->DriverState;
681 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
682
683 if(GPIO_num != DISABLE_GPIO_NUM)
684 {
685 TURN_ON_LED(1<<GPIO_num, uiLedIndex);
686 }
687 }
688 break;
689 case FW_DOWNLOAD:
690 {
691 //BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FW_DN_DONE called\n");
692 currdriverstate = FW_DOWNLOAD;
693 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
694
695 if(GPIO_num != DISABLE_GPIO_NUM)
696 {
697 timeout = 50;
698 LED_Blink(Adapter, 1<<GPIO_num, uiLedIndex, timeout, -1,currdriverstate);
699 }
700 }
701 break;
702 case FW_DOWNLOAD_DONE:
703 {
704 currdriverstate = FW_DOWNLOAD_DONE;
705 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex,currdriverstate);
706 if(GPIO_num != DISABLE_GPIO_NUM)
707 {
708 TURN_ON_LED(1<<GPIO_num, uiLedIndex);
709 }
710 }
711 break;
712
713 case SHUTDOWN_EXIT:
714 //no break, continue to NO_NETWORK_ENTRY state as well.
715
716 case NO_NETWORK_ENTRY:
717 {
718 currdriverstate = NO_NETWORK_ENTRY;
719 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex,&dummyGPIONum,currdriverstate);
720 if(GPIO_num != DISABLE_GPIO_NUM)
721 {
722 TURN_ON_LED(1<<GPIO_num, uiLedIndex);
723 }
724 }
725 break;
726 case NORMAL_OPERATION:
727 {
728 UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
729 UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
730 UCHAR uiLEDTx = 0;
731 UCHAR uiLEDRx = 0;
732 currdriverstate = NORMAL_OPERATION;
733 Adapter->LEDInfo.bIdle_led_off = FALSE;
734
735 BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiLEDTx,&uiLEDRx,currdriverstate);
736 if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM))
737 {
738 GPIO_num = DISABLE_GPIO_NUM ;
739 }
740 else
741 {
742 /*If single LED is selected, use same for both Tx and Rx*/
743 if(GPIO_num_tx == DISABLE_GPIO_NUM)
744 {
745 GPIO_num_tx = GPIO_num_rx;
746 uiLEDTx = uiLEDRx;
747 }
748 else if(GPIO_num_rx == DISABLE_GPIO_NUM)
749 {
750 GPIO_num_rx = GPIO_num_tx;
751 uiLEDRx = uiLEDTx;
752 }
753 /*Blink the LED in proportionate to Tx and Rx transmissions.*/
754 LED_Proportional_Blink(Adapter, GPIO_num_tx, uiLEDTx, GPIO_num_rx, uiLEDRx,currdriverstate);
755 }
756 }
757 break;
758 case LOWPOWER_MODE_ENTER:
759 {
760 currdriverstate = LOWPOWER_MODE_ENTER;
761 if( DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING == Adapter->ulPowerSaveMode)
762 {
763 /* Turn OFF all the LED */
764 uiResetValue = 0;
765 for(uiIndex =0; uiIndex < NUM_OF_LEDS; uiIndex++)
766 {
767 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
768 TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
769 }
770
771 }
772 /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
773 Adapter->LEDInfo.bLedInitDone = FALSE;
774 Adapter->LEDInfo.bIdle_led_off = TRUE;
775 wake_up(&Adapter->LEDInfo.idleModeSyncEvent);
776 GPIO_num = DISABLE_GPIO_NUM;
777 break;
778 }
779 case IDLEMODE_CONTINUE:
780 {
781 currdriverstate = IDLEMODE_CONTINUE;
782 GPIO_num = DISABLE_GPIO_NUM;
783 }
784 break;
785 case IDLEMODE_EXIT:
786 {
787 }
788 break;
789 case DRIVER_HALT:
790 {
791 currdriverstate = DRIVER_HALT;
792 GPIO_num = DISABLE_GPIO_NUM;
793 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
794 {
795 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
796 DISABLE_GPIO_NUM)
797 TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
798 }
799 //Adapter->DriverState = DRIVER_INIT;
800 }
801 break;
802 case LED_THREAD_INACTIVE :
803 {
804 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"InActivating LED thread...");
805 currdriverstate = LED_THREAD_INACTIVE;
806 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_INACTIVELY ;
807 Adapter->LEDInfo.bLedInitDone = FALSE ;
808 //disable ALL LED
809 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
810 {
811 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
812 DISABLE_GPIO_NUM)
813 TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
814 }
815 }
816 break;
817 case LED_THREAD_ACTIVE :
818 {
819 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Activating LED thread again...");
820 if(Adapter->LinkUpStatus == FALSE)
821 Adapter->DriverState = NO_NETWORK_ENTRY;
822 else
823 Adapter->DriverState = NORMAL_OPERATION;
824
825 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY ;
826 }
827 break;
828 //return;
829 default:
830 break;
831 }
832 }
833 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
834 }
835
InitLedSettings(PMINI_ADAPTER Adapter)836 int InitLedSettings(PMINI_ADAPTER Adapter)
837 {
838 int Status = STATUS_SUCCESS;
839 BOOLEAN bEnableThread = TRUE;
840 UCHAR uiIndex = 0;
841
842 /*Initially set BitPolarity to normal polarity. The bit 8 of LED type
843 * is used to change the polarity of the LED.*/
844
845 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
846 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1;
847 }
848
849 /*Read the LED settings of CONFIG file and map it to GPIO numbers in EEPROM*/
850 Status = ReadConfigFileStructure(Adapter, &bEnableThread);
851 if(STATUS_SUCCESS != Status)
852 {
853 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FAILED in ReadConfigFileStructure\n");
854 return Status;
855 }
856
857 if(Adapter->LEDInfo.led_thread_running)
858 {
859 if(bEnableThread)
860 ;
861 else
862 {
863 Adapter->DriverState = DRIVER_HALT;
864 wake_up(&Adapter->LEDInfo.notify_led_event);
865 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
866 }
867
868 }
869
870 else if(bEnableThread)
871 {
872 /*Create secondary thread to handle the LEDs*/
873 init_waitqueue_head(&Adapter->LEDInfo.notify_led_event);
874 init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent);
875 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY;
876 Adapter->LEDInfo.bIdle_led_off = FALSE;
877 Adapter->LEDInfo.led_cntrl_threadid = kthread_run((int (*)(void *))
878 LEDControlThread, Adapter, "led_control_thread");
879 if(IS_ERR(Adapter->LEDInfo.led_cntrl_threadid))
880 {
881 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Not able to spawn Kernel Thread\n");
882 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
883 return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);
884 }
885 }
886 return Status;
887 }
888