blob: d9d5fbf2c86d78faa193228712f05550590f0344 [file] [log] [blame]
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001#include "headers.h"
2
3#define STATUS_IMAGE_CHECKSUM_MISMATCH -199
4#define EVENT_SIGNALED 1
5
6static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size)
7{
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +01008 B_UINT16 u16CheckSum = 0;
9 while (u32Size--) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070010 u16CheckSum += (B_UINT8)~(*pu8Buffer);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010011 pu8Buffer++;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070012 }
13 return u16CheckSum;
14}
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010015
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070016BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios)
17{
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010018 INT Status;
19 Status = (Adapter->gpioBitMap & gpios) ^ gpios;
20 if (Status)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070021 return FALSE;
22 else
23 return TRUE;
24}
25
Arnd Bergmann44a17eff2010-09-30 10:24:12 +020026static INT LED_Blink(PMINI_ADAPTER Adapter, UINT GPIO_Num, UCHAR uiLedIndex, ULONG timeout, INT num_of_time, LedEventInfo_t currdriverstate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070027{
28 int Status = STATUS_SUCCESS;
29 BOOLEAN bInfinite = FALSE;
30
31 /*Check if num_of_time is -ve. If yes, blink led in infinite loop*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010032 if (num_of_time < 0)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070033 {
34 bInfinite = TRUE;
35 num_of_time = 1;
36 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010037 while (num_of_time)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070038 {
39
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010040 if (currdriverstate == Adapter->DriverState)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070041 TURN_ON_LED(GPIO_Num, uiLedIndex);
42
43 /*Wait for timeout after setting on the LED*/
44 Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
45 currdriverstate != Adapter->DriverState || kthread_should_stop(),
46 msecs_to_jiffies(timeout));
47
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010048 if (kthread_should_stop())
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070049 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010050 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
51 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070052 TURN_OFF_LED(GPIO_Num, uiLedIndex);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010053 Status = EVENT_SIGNALED;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070054 break;
55 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010056 if (Status)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070057 {
58 TURN_OFF_LED(GPIO_Num, uiLedIndex);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010059 Status = EVENT_SIGNALED;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070060 break;
61 }
62
63 TURN_OFF_LED(GPIO_Num, uiLedIndex);
64 Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010065 currdriverstate != Adapter->DriverState || kthread_should_stop(),
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070066 msecs_to_jiffies(timeout));
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010067 if (bInfinite == FALSE)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070068 num_of_time--;
69 }
70 return Status;
71}
72
Arnd Bergmann44a17eff2010-09-30 10:24:12 +020073static INT ScaleRateofTransfer(ULONG rate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070074{
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010075 if (rate <= 3)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070076 return rate;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010077 else if ((rate > 3) && (rate <= 100))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070078 return 5;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010079 else if ((rate > 100) && (rate <= 200))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070080 return 6;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010081 else if ((rate > 200) && (rate <= 300))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070082 return 7;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010083 else if ((rate > 300) && (rate <= 400))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070084 return 8;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010085 else if ((rate > 400) && (rate <= 500))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070086 return 9;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010087 else if ((rate > 500) && (rate <= 600))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070088 return 10;
89 else
90 return MAX_NUM_OF_BLINKS;
91}
92
93
94
Arnd Bergmann44a17eff2010-09-30 10:24:12 +020095static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx,
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070096 UCHAR uiTxLedIndex, UCHAR GPIO_Num_rx, UCHAR uiRxLedIndex, LedEventInfo_t currdriverstate)
97{
98 /* Initial values of TX and RX packets*/
99 ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0;
100 /*values of TX and RX packets after 1 sec*/
101 ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0;
102 /*Rate of transfer of Tx and Rx in 1 sec*/
103 ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0;
104 int Status = STATUS_SUCCESS;
105 INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
106 UINT remDelay = 0;
107 BOOLEAN bBlinkBothLED = TRUE;
108 //UINT GPIO_num = DISABLE_GPIO_NUM;
109 ulong timeout = 0;
110
111 /*Read initial value of packets sent/received */
Stephen Hemmingercacd9222010-11-01 13:34:35 -0400112 Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets;
113 Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets;
114
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700115 /*Scale the rate of transfer to no of blinks.*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100116 num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
117 num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700118
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100119 while ((Adapter->device_removed == FALSE))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700120 {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700121 timeout = 50;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700122 /*Blink Tx and Rx LED when both Tx and Rx is in normal bandwidth*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100123 if (bBlinkBothLED)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700124 {
125 /*Assign minimum number of blinks of either Tx or Rx.*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100126 if (num_of_time_tx > num_of_time_rx)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700127 num_of_time = num_of_time_rx;
128 else
129 num_of_time = num_of_time_tx;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100130 if (num_of_time > 0)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700131 {
132 /*Blink both Tx and Rx LEDs*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100133 if (LED_Blink(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex, timeout, num_of_time, currdriverstate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700134 == EVENT_SIGNALED)
135 {
136 return EVENT_SIGNALED;
137 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100138 if (LED_Blink(Adapter, 1 << GPIO_Num_rx, uiRxLedIndex, timeout, num_of_time, currdriverstate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700139 == EVENT_SIGNALED)
140 {
141 return EVENT_SIGNALED;
142 }
143
144 }
145
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100146 if (num_of_time == num_of_time_tx)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700147 {
148 /*Blink pending rate of Rx*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100149 if (LED_Blink(Adapter, (1 << GPIO_Num_rx), uiRxLedIndex, timeout,
150 num_of_time_rx-num_of_time, currdriverstate) == EVENT_SIGNALED)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700151 {
152 return EVENT_SIGNALED;
153 }
154 num_of_time = num_of_time_rx;
155 }
156 else
157 {
158 /*Blink pending rate of Tx*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100159 if (LED_Blink(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex, timeout,
160 num_of_time_tx-num_of_time, currdriverstate) == EVENT_SIGNALED)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700161 {
162 return EVENT_SIGNALED;
163 }
164 num_of_time = num_of_time_tx;
165 }
166 }
167 else
168 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100169 if (num_of_time == num_of_time_tx)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700170 {
171 /*Blink pending rate of Rx*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100172 if (LED_Blink(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex, timeout, num_of_time, currdriverstate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700173 == EVENT_SIGNALED)
174 {
175 return EVENT_SIGNALED;
176 }
177 }
178 else
179 {
180 /*Blink pending rate of Tx*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100181 if (LED_Blink(Adapter, 1 << GPIO_Num_rx, uiRxLedIndex, timeout,
182 num_of_time, currdriverstate) == EVENT_SIGNALED)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700183 {
184 return EVENT_SIGNALED;
185 }
186 }
187 }
188 /* If Tx/Rx rate is less than maximum blinks per second,
189 * wait till delay completes to 1 second
190 */
191 remDelay = MAX_NUM_OF_BLINKS - num_of_time;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100192 if (remDelay > 0)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700193 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100194 timeout = 100 * remDelay;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700195 Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100196 currdriverstate != Adapter->DriverState || kthread_should_stop(),
197 msecs_to_jiffies(timeout));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700198
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100199 if (kthread_should_stop())
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700200 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100201 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
202 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700203 return EVENT_SIGNALED;
204 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100205 if (Status)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700206 return EVENT_SIGNALED;
207 }
208
209 /*Turn off both Tx and Rx LEDs before next second*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100210 TURN_OFF_LED(1 << GPIO_Num_tx, uiTxLedIndex);
211 TURN_OFF_LED(1 << GPIO_Num_rx, uiTxLedIndex);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700212
213 /*
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100214 * Read the Tx & Rx packets transmission after 1 second and
215 * calculate rate of transfer
216 */
Stephen Hemmingercacd9222010-11-01 13:34:35 -0400217 Final_num_of_packts_tx = Adapter->dev->stats.tx_packets;
218 Final_num_of_packts_rx = Adapter->dev->stats.rx_packets;
219
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700220 rate_of_transfer_tx = Final_num_of_packts_tx - Initial_num_of_packts_tx;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700221 rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx;
222
223 /*Read initial value of packets sent/received */
224 Initial_num_of_packts_tx = Final_num_of_packts_tx;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100225 Initial_num_of_packts_rx = Final_num_of_packts_rx;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700226
227 /*Scale the rate of transfer to no of blinks.*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100228 num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
229 num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700230
231 }
232 return Status;
233}
234
235
236//-----------------------------------------------------------------------------
237// Procedure: ValidateDSDParamsChecksum
238//
239// Description: Reads DSD Params and validates checkusm.
240//
241// Arguments:
242// Adapter - Pointer to Adapter structure.
243// ulParamOffset - Start offset of the DSD parameter to be read and validated.
244// usParamLen - Length of the DSD Parameter.
245//
246// Returns:
247// <OSAL_STATUS_CODE>
248//-----------------------------------------------------------------------------
249
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100250static INT ValidateDSDParamsChecksum(PMINI_ADAPTER Adapter, ULONG ulParamOffset, USHORT usParamLen)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700251{
252 INT Status = STATUS_SUCCESS;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100253 PUCHAR puBuffer = NULL;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100254 USHORT usChksmOrg = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700255 USHORT usChecksumCalculated = 0;
256
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100257 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X", ulParamOffset, usParamLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700258
Stephen Hemminger082e8892010-11-01 09:35:21 -0400259 puBuffer = kmalloc(usParamLen, GFP_KERNEL);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100260 if (!puBuffer)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700261 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100262 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: ValidateDSDParamsChecksum Allocation failed");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700263 return -ENOMEM;
264
265 }
266
267 //
268 // Read the DSD data from the parameter offset.
269 //
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100270 if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)puBuffer, ulParamOffset, usParamLen))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700271 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100272 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
273 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700274 goto exit;
275 }
276
277 //
278 // Calculate the checksum of the data read from the DSD parameter.
279 //
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100280 usChecksumCalculated = CFG_CalculateChecksum(puBuffer, usParamLen);
281 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: usCheckSumCalculated = 0x%x\n", usChecksumCalculated);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700282
283 //
284 // End of the DSD parameter will have a TWO bytes checksum stored in it. Read it and compare with the calculated
285 // Checksum.
286 //
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100287 if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)&usChksmOrg, ulParamOffset+usParamLen, 2))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700288 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100289 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
290 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700291 goto exit;
292 }
293 usChksmOrg = ntohs(usChksmOrg);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100294 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: usChksmOrg = 0x%x", usChksmOrg);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700295
296 //
297 // Compare the checksum calculated with the checksum read from DSD section
298 //
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100299 if (usChecksumCalculated ^ usChksmOrg)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700300 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100301 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700302 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
303 goto exit;
304 }
305
306exit:
Stephen Hemminger082e8892010-11-01 09:35:21 -0400307 kfree(puBuffer);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700308 return Status;
309}
310
311
312//-----------------------------------------------------------------------------
313// Procedure: ValidateHWParmStructure
314//
315// Description: Validates HW Parameters.
316//
317// Arguments:
318// Adapter - Pointer to Adapter structure.
319// ulHwParamOffset - Start offset of the HW parameter Section to be read and validated.
320//
321// Returns:
322// <OSAL_STATUS_CODE>
323//-----------------------------------------------------------------------------
324
Arnd Bergmann44a17eff2010-09-30 10:24:12 +0200325static INT ValidateHWParmStructure(PMINI_ADAPTER Adapter, ULONG ulHwParamOffset)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700326{
327
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100328 INT Status = STATUS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700329 USHORT HwParamLen = 0;
330 // Add DSD start offset to the hwParamOffset to get the actual address.
331 ulHwParamOffset += DSD_START_OFFSET;
332
333 /*Read the Length of HW_PARAM structure*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100334 BeceemNVMRead(Adapter, (PUINT)&HwParamLen, ulHwParamOffset, 2);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700335 HwParamLen = ntohs(HwParamLen);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100336 if (0 == HwParamLen || HwParamLen > Adapter->uiNVMDSDSize)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700337 {
338 return STATUS_IMAGE_CHECKSUM_MISMATCH;
339 }
340
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100341 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread:HwParamLen = 0x%x", HwParamLen);
342 Status = ValidateDSDParamsChecksum(Adapter, ulHwParamOffset, HwParamLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700343 return Status;
344} /* ValidateHWParmStructure() */
345
Arnd Bergmann44a17eff2010-09-30 10:24:12 +0200346static int ReadLEDInformationFromEEPROM(PMINI_ADAPTER Adapter, UCHAR GPIO_Array[])
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700347{
348 int Status = STATUS_SUCCESS;
349
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100350 ULONG dwReadValue = 0;
351 USHORT usHwParamData = 0;
352 USHORT usEEPROMVersion = 0;
353 UCHAR ucIndex = 0;
354 UCHAR ucGPIOInfo[32] = {0};
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700355
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100356 BeceemNVMRead(Adapter, (PUINT)&usEEPROMVersion, EEPROM_VERSION_OFFSET, 2);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700357
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100358 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));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700359
360
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100361 if (((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700362 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100363 BeceemNVMRead(Adapter, (PUINT)&usHwParamData, EEPROM_HW_PARAM_POINTER_ADDRESS, 2);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700364 usHwParamData = ntohs(usHwParamData);
365 dwReadValue = usHwParamData;
366 }
367 else
368 {
369 //
370 // Validate Compatibility section and then read HW param if compatibility section is valid.
371 //
372 Status = ValidateDSDParamsChecksum(Adapter,
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100373 DSD_START_OFFSET,
374 COMPATIBILITY_SECTION_LENGTH_MAP5);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700375
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100376 if (Status != STATUS_SUCCESS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700377 {
378 return Status;
379 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100380 BeceemNVMRead(Adapter, (PUINT)&dwReadValue, EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700381 dwReadValue = ntohl(dwReadValue);
382 }
383
384
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100385 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: Start address of HW_PARAM structure = 0x%lx", dwReadValue);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700386
387 //
388 // Validate if the address read out is within the DSD.
389 // Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
390 // lower limit should be above DSD_START_OFFSET and
391 // upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
392 //
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100393 if (dwReadValue < DSD_START_OFFSET ||
394 dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700395 {
396 return STATUS_IMAGE_CHECKSUM_MISMATCH;
397 }
398
399 Status = ValidateHWParmStructure(Adapter, dwReadValue);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100400 if (Status) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700401 return Status;
402 }
403
404 /*
405 Add DSD_START_OFFSET to the offset read from the EEPROM.
406 This will give the actual start HW Parameters start address.
407 To read GPIO section, add GPIO offset further.
408 */
409
410 dwReadValue += DSD_START_OFFSET; // = start address of hw param section.
411 dwReadValue += GPIO_SECTION_START_OFFSET; // = GPIO start offset within HW Param section.
412
413 /* Read the GPIO values for 32 GPIOs from EEPROM and map the function
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100414 * number to GPIO pin number to GPIO_Array
415 */
416 BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo, dwReadValue, 32);
417 for (ucIndex = 0; ucIndex < 32; ucIndex++)
418 {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700419
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100420 switch (ucGPIOInfo[ucIndex])
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100421 {
422 case RED_LED:
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700423 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100424 GPIO_Array[RED_LED] = ucIndex;
425 Adapter->gpioBitMap |= (1 << ucIndex);
426 break;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700427 }
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100428 case BLUE_LED:
429 {
430 GPIO_Array[BLUE_LED] = ucIndex;
431 Adapter->gpioBitMap |= (1 << ucIndex);
432 break;
433 }
434 case YELLOW_LED:
435 {
436 GPIO_Array[YELLOW_LED] = ucIndex;
437 Adapter->gpioBitMap |= (1 << ucIndex);
438 break;
439 }
440 case GREEN_LED:
441 {
442 GPIO_Array[GREEN_LED] = ucIndex;
443 Adapter->gpioBitMap |= (1 << ucIndex);
444 break;
445 }
446 default:
447 break;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700448 }
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100449
450 }
451 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "GPIO's bit map correspond to LED :0x%X", Adapter->gpioBitMap);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100452 return Status;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700453}
454
455
Arnd Bergmann44a17eff2010-09-30 10:24:12 +0200456static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700457{
458 int Status = STATUS_SUCCESS;
459 UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700460 UINT uiIndex = 0;
461 UINT uiNum_of_LED_Type = 0;
462 PUCHAR puCFGData = NULL;
463 UCHAR bData = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700464 memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
465
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100466 if (!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700467 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100468 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Target Params not Avail.\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700469 return -ENOENT;
470 }
471
472 /*Populate GPIO_Array with GPIO numbers for LED functions*/
473 /*Read the GPIO numbers from EEPROM*/
474 Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100475 if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700476 {
477 *bEnableThread = FALSE;
478 return STATUS_SUCCESS;
479 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100480 else if (Status)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700481 {
482 *bEnableThread = FALSE;
483 return Status;
484 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700485 /*
486 * CONFIG file read successfully. Deallocate the memory of
487 * uiFileNameBufferSize
488 */
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100489 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: Config file read successfully\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700490 puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1;
491
492 /*
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100493 * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
494 * will have the information of LED type, LED on state for different
495 * driver state and LED blink state.
496 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700497
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100498 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700499 {
500 bData = *puCFGData;
501
502 /*Check Bit 8 for polarity. If it is set, polarity is reverse polarity*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100503 if (bData & 0x80)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700504 {
505 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 0;
506 /*unset the bit 8*/
507 bData = bData & 0x7f;
508 }
509
510 Adapter->LEDInfo.LEDState[uiIndex].LED_Type = bData;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100511 if (bData <= NUM_OF_LEDS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700512 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = GPIO_Array[bData];
513 else
514 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = DISABLE_GPIO_NUM;
515
516 puCFGData++;
517 bData = *puCFGData;
518 Adapter->LEDInfo.LEDState[uiIndex].LED_On_State = bData;
519 puCFGData++;
520 bData = *puCFGData;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100521 Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State = bData;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700522 puCFGData++;
523 }
524
525 /*Check if all the LED settings are disabled. If it is disabled, dont launch the LED control thread.*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100526 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700527 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100528 if ((Adapter->LEDInfo.LEDState[uiIndex].LED_Type == DISABLE_GPIO_NUM) ||
529 (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0x7f) ||
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700530 (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0))
531 uiNum_of_LED_Type++;
532 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100533 if (uiNum_of_LED_Type >= NUM_OF_LEDS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700534 *bEnableThread = FALSE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700535
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700536 return Status;
537}
538//--------------------------------------------------------------------------
539// Procedure: LedGpioInit
540//
541// Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode and make the
542// initial state to be OFF.
543//
544// Arguments:
545// Adapter - Pointer to MINI_ADAPTER structure.
546//
547// Returns: VOID
548//
549//-----------------------------------------------------------------------------
550
Arnd Bergmann44a17eff2010-09-30 10:24:12 +0200551static VOID LedGpioInit(PMINI_ADAPTER Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700552{
553 UINT uiResetValue = 0;
554 UINT uiIndex = 0;
555
556 /* Set all LED GPIO Mode to output mode */
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100557 if (rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) < 0)
558 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: RDM Failed\n");
559 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700560 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100561 if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700562 uiResetValue |= (1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100563 TURN_OFF_LED(1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num, uiIndex);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700564 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100565 if (wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) < 0)
566 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: WRM Failed\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700567
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100568 Adapter->LEDInfo.bIdle_led_off = FALSE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700569}
570//-----------------------------------------------------------------------------
571
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100572static INT BcmGetGPIOPinInfo(PMINI_ADAPTER Adapter, UCHAR *GPIO_num_tx, UCHAR *GPIO_num_rx, UCHAR *uiLedTxIndex, UCHAR *uiLedRxIndex, LedEventInfo_t currdriverstate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700573{
574 UINT uiIndex = 0;
575
576 *GPIO_num_tx = DISABLE_GPIO_NUM;
577 *GPIO_num_rx = DISABLE_GPIO_NUM;
578
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100579 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700580 {
581
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100582 if ((currdriverstate == NORMAL_OPERATION) ||
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100583 (currdriverstate == IDLEMODE_EXIT) ||
584 (currdriverstate == FW_DOWNLOAD))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700585 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100586 if (Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State & currdriverstate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700587 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100588 if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700589 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100590 if (*GPIO_num_tx == DISABLE_GPIO_NUM)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700591 {
592 *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
593 *uiLedTxIndex = uiIndex;
594 }
595 else
596 {
597 *GPIO_num_rx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
598 *uiLedRxIndex = uiIndex;
599 }
600 }
601 }
602 }
603 else
604 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100605 if (Adapter->LEDInfo.LEDState[uiIndex].LED_On_State & currdriverstate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700606 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100607 if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700608 {
609 *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
610 *uiLedTxIndex = uiIndex;
611 }
612 }
613 }
614 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100615 return STATUS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700616}
Arnd Bergmann44a17eff2010-09-30 10:24:12 +0200617static VOID LEDControlThread(PMINI_ADAPTER Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700618{
619 UINT uiIndex = 0;
620 UCHAR GPIO_num = 0;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100621 UCHAR uiLedIndex = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700622 UINT uiResetValue = 0;
623 LedEventInfo_t currdriverstate = 0;
624 ulong timeout = 0;
625
626 INT Status = 0;
627
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100628 UCHAR dummyGPIONum = 0;
629 UCHAR dummyIndex = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700630
631 //currdriverstate = Adapter->DriverState;
632 Adapter->LEDInfo.bIdleMode_tx_from_host = FALSE;
633
634 /*Wait till event is triggered*/
635 //wait_event(Adapter->LEDInfo.notify_led_event,
636 // currdriverstate!= Adapter->DriverState);
637
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100638 GPIO_num = DISABLE_GPIO_NUM;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700639
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100640 while (TRUE)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700641 {
642 /*Wait till event is triggered*/
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100643 if ((GPIO_num == DISABLE_GPIO_NUM)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700644 ||
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100645 ((currdriverstate != FW_DOWNLOAD) &&
646 (currdriverstate != NORMAL_OPERATION) &&
647 (currdriverstate != LOWPOWER_MODE_ENTER))
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100648 ||
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100649 (currdriverstate == LED_THREAD_INACTIVE))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700650 {
651 Status = wait_event_interruptible(Adapter->LEDInfo.notify_led_event,
652 currdriverstate != Adapter->DriverState || kthread_should_stop());
653 }
654
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100655 if (kthread_should_stop() || Adapter->device_removed)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700656 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100657 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700658 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100659 TURN_OFF_LED(1 << GPIO_num, uiLedIndex);
660 return;//STATUS_FAILURE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700661 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700662
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100663 if (GPIO_num != DISABLE_GPIO_NUM)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700664 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100665 TURN_OFF_LED(1 << GPIO_num, uiLedIndex);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700666 }
667
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100668 if (Adapter->LEDInfo.bLedInitDone == FALSE)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700669 {
670 LedGpioInit(Adapter);
671 Adapter->LEDInfo.bLedInitDone = TRUE;
672 }
673
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100674 switch (Adapter->DriverState)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700675 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100676 case DRIVER_INIT:
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700677 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100678 currdriverstate = DRIVER_INIT;//Adapter->DriverState;
679 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700680
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100681 if (GPIO_num != DISABLE_GPIO_NUM)
682 {
683 TURN_ON_LED(1 << GPIO_num, uiLedIndex);
684 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700685 }
686 break;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100687 case FW_DOWNLOAD:
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700688 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100689 //BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FW_DN_DONE called\n");
690 currdriverstate = FW_DOWNLOAD;
691 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700692
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100693 if (GPIO_num != DISABLE_GPIO_NUM)
694 {
695 timeout = 50;
696 LED_Blink(Adapter, 1 << GPIO_num, uiLedIndex, timeout, -1, currdriverstate);
697 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700698 }
699 break;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100700 case FW_DOWNLOAD_DONE:
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700701 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100702 currdriverstate = FW_DOWNLOAD_DONE;
703 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
704 if (GPIO_num != DISABLE_GPIO_NUM)
705 {
706 TURN_ON_LED(1 << GPIO_num, uiLedIndex);
707 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700708 }
709 break;
710
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100711 case SHUTDOWN_EXIT:
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700712 //no break, continue to NO_NETWORK_ENTRY state as well.
713
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100714 case NO_NETWORK_ENTRY:
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700715 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100716 currdriverstate = NO_NETWORK_ENTRY;
717 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyGPIONum, currdriverstate);
718 if (GPIO_num != DISABLE_GPIO_NUM)
719 {
720 TURN_ON_LED(1 << GPIO_num, uiLedIndex);
721 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700722 }
723 break;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100724 case NORMAL_OPERATION:
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700725 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100726 UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
727 UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
728 UCHAR uiLEDTx = 0;
729 UCHAR uiLEDRx = 0;
730 currdriverstate = NORMAL_OPERATION;
731 Adapter->LEDInfo.bIdle_led_off = FALSE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700732
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100733 BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiLEDTx, &uiLEDRx, currdriverstate);
734 if ((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM))
735 {
736 GPIO_num = DISABLE_GPIO_NUM;
737 }
738 else
739 {
740 /*If single LED is selected, use same for both Tx and Rx*/
741 if (GPIO_num_tx == DISABLE_GPIO_NUM)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700742 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100743 GPIO_num_tx = GPIO_num_rx;
744 uiLEDTx = uiLEDRx;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700745 }
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100746 else if (GPIO_num_rx == DISABLE_GPIO_NUM)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700747 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100748 GPIO_num_rx = GPIO_num_tx;
749 uiLEDRx = uiLEDTx;
750 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700751 /*Blink the LED in proportionate to Tx and Rx transmissions.*/
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100752 LED_Proportional_Blink(Adapter, GPIO_num_tx, uiLEDTx, GPIO_num_rx, uiLEDRx, currdriverstate);
753 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700754 }
755 break;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100756 case LOWPOWER_MODE_ENTER:
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700757 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100758 currdriverstate = LOWPOWER_MODE_ENTER;
759 if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING == Adapter->ulPowerSaveMode)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700760 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100761 /* Turn OFF all the LED */
762 uiResetValue = 0;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100763 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700764 {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100765 if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100766 TURN_OFF_LED((1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num), uiIndex);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700767 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700768
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100769 }
770 /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
771 Adapter->LEDInfo.bLedInitDone = FALSE;
772 Adapter->LEDInfo.bIdle_led_off = TRUE;
773 wake_up(&Adapter->LEDInfo.idleModeSyncEvent);
774 GPIO_num = DISABLE_GPIO_NUM;
775 break;
776 }
777 case IDLEMODE_CONTINUE:
778 {
779 currdriverstate = IDLEMODE_CONTINUE;
780 GPIO_num = DISABLE_GPIO_NUM;
781 }
782 break;
783 case IDLEMODE_EXIT:
784 {
785 }
786 break;
787 case DRIVER_HALT:
788 {
789 currdriverstate = DRIVER_HALT;
790 GPIO_num = DISABLE_GPIO_NUM;
791 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
792 {
793 if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
794 DISABLE_GPIO_NUM)
795 TURN_OFF_LED((1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num), uiIndex);
796 }
797 //Adapter->DriverState = DRIVER_INIT;
798 }
799 break;
800 case LED_THREAD_INACTIVE:
801 {
802 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "InActivating LED thread...");
803 currdriverstate = LED_THREAD_INACTIVE;
804 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_INACTIVELY;
805 Adapter->LEDInfo.bLedInitDone = FALSE;
806 //disable ALL LED
807 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
808 {
809 if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
810 DISABLE_GPIO_NUM)
811 TURN_OFF_LED((1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num), uiIndex);
812 }
813 }
814 break;
815 case LED_THREAD_ACTIVE:
816 {
817 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Activating LED thread again...");
818 if (Adapter->LinkUpStatus == FALSE)
819 Adapter->DriverState = NO_NETWORK_ENTRY;
820 else
821 Adapter->DriverState = NORMAL_OPERATION;
822
823 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700824 }
825 break;
826 //return;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100827 default:
828 break;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700829 }
830 }
831 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
832}
833
834int InitLedSettings(PMINI_ADAPTER Adapter)
835{
836 int Status = STATUS_SUCCESS;
837 BOOLEAN bEnableThread = TRUE;
838 UCHAR uiIndex = 0;
839
840 /*Initially set BitPolarity to normal polarity. The bit 8 of LED type
841 * is used to change the polarity of the LED.*/
842
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100843 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700844 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1;
845 }
846
847 /*Read the LED settings of CONFIG file and map it to GPIO numbers in EEPROM*/
848 Status = ReadConfigFileStructure(Adapter, &bEnableThread);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100849 if (STATUS_SUCCESS != Status)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700850 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100851 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread: FAILED in ReadConfigFileStructure\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700852 return Status;
853 }
854
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100855 if (Adapter->LEDInfo.led_thread_running)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700856 {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100857 if (bEnableThread)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700858 ;
859 else
860 {
861 Adapter->DriverState = DRIVER_HALT;
862 wake_up(&Adapter->LEDInfo.notify_led_event);
863 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
864 }
865
866 }
867
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100868 else if (bEnableThread)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700869 {
870 /*Create secondary thread to handle the LEDs*/
871 init_waitqueue_head(&Adapter->LEDInfo.notify_led_event);
872 init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent);
873 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100874 Adapter->LEDInfo.bIdle_led_off = FALSE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700875 Adapter->LEDInfo.led_cntrl_threadid = kthread_run((int (*)(void *))
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100876 LEDControlThread, Adapter, "led_control_thread");
877 if (IS_ERR(Adapter->LEDInfo.led_cntrl_threadid))
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100878 {
879 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Not able to spawn Kernel Thread\n");
880 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
881 return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);
882 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700883 }
884 return Status;
885}