blob: 074fc39ed678ac1b8c353e99b8e8532ca3138a12 [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;
Pawel Lebioda89fa0372014-07-09 17:59:29 +02009
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010010 while (u32Size--) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070011 u16CheckSum += (B_UINT8)~(*pu8Buffer);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010012 pu8Buffer++;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070013 }
14 return u16CheckSum;
15}
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010016
Lisa Nguyen3abd6f12013-10-28 01:35:59 -070017bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070018{
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010019 INT Status;
Pawel Lebioda89fa0372014-07-09 17:59:29 +020020
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010021 Status = (Adapter->gpioBitMap & gpios) ^ gpios;
22 if (Status)
Lisa Nguyenf70c8a92013-10-28 01:36:19 -070023 return false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070024 else
25 return TRUE;
26}
27
Matthias Beyer9bcfab202014-06-23 21:18:17 +020028static INT LED_Blink(struct bcm_mini_adapter *Adapter,
29 UINT GPIO_Num,
30 UCHAR uiLedIndex,
31 ULONG timeout,
32 INT num_of_time,
33 enum bcm_led_events currdriverstate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070034{
35 int Status = STATUS_SUCCESS;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -070036 bool bInfinite = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070037
Johannes Tenschertf5d8c262011-12-07 18:25:08 +010038 /* Check if num_of_time is -ve. If yes, blink led in infinite loop */
Johannes Tenschertd9ce3532011-12-07 18:25:09 +010039 if (num_of_time < 0) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070040 bInfinite = TRUE;
41 num_of_time = 1;
42 }
Johannes Tenschertd9ce3532011-12-07 18:25:09 +010043 while (num_of_time) {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010044 if (currdriverstate == Adapter->DriverState)
Matthias Beyera1082a42014-06-23 21:18:19 +020045 TURN_ON_LED(Adapter, GPIO_Num, uiLedIndex);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070046
Johannes Tenschertf5d8c262011-12-07 18:25:08 +010047 /* Wait for timeout after setting on the LED */
Johannes Tenschert42190012011-12-07 18:25:10 +010048 Status = wait_event_interruptible_timeout(
49 Adapter->LEDInfo.notify_led_event,
50 currdriverstate != Adapter->DriverState ||
51 kthread_should_stop(),
52 msecs_to_jiffies(timeout));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070053
Johannes Tenschertd9ce3532011-12-07 18:25:09 +010054 if (kthread_should_stop()) {
Johannes Tenschert42190012011-12-07 18:25:10 +010055 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
56 DBG_LVL_ALL,
57 "Led thread got signal to exit..hence exiting");
58 Adapter->LEDInfo.led_thread_running =
59 BCM_LED_THREAD_DISABLED;
Matthias Beyera1082a42014-06-23 21:18:19 +020060 TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010061 Status = EVENT_SIGNALED;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070062 break;
63 }
Johannes Tenschertd9ce3532011-12-07 18:25:09 +010064 if (Status) {
Matthias Beyera1082a42014-06-23 21:18:19 +020065 TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010066 Status = EVENT_SIGNALED;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070067 break;
68 }
69
Matthias Beyera1082a42014-06-23 21:18:19 +020070 TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
Johannes Tenschert42190012011-12-07 18:25:10 +010071 Status = wait_event_interruptible_timeout(
72 Adapter->LEDInfo.notify_led_event,
73 currdriverstate != Adapter->DriverState ||
74 kthread_should_stop(),
75 msecs_to_jiffies(timeout));
Lisa Nguyenf70c8a92013-10-28 01:36:19 -070076 if (bInfinite == false)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070077 num_of_time--;
78 }
79 return Status;
80}
81
Arnd Bergmann44a17eff2010-09-30 10:24:12 +020082static INT ScaleRateofTransfer(ULONG rate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070083{
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010084 if (rate <= 3)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070085 return rate;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010086 else if ((rate > 3) && (rate <= 100))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070087 return 5;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010088 else if ((rate > 100) && (rate <= 200))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070089 return 6;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010090 else if ((rate > 200) && (rate <= 300))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070091 return 7;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010092 else if ((rate > 300) && (rate <= 400))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070093 return 8;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010094 else if ((rate > 400) && (rate <= 500))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070095 return 9;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +010096 else if ((rate > 500) && (rate <= 600))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070097 return 10;
98 else
99 return MAX_NUM_OF_BLINKS;
100}
101
Matthias Beyer60654a82014-06-23 21:18:23 +0200102static INT blink_in_normal_bandwidth(struct bcm_mini_adapter *ad,
Matthias Beyer9c805bd2014-06-23 21:18:26 +0200103 INT *time,
104 INT *time_tx,
105 INT *time_rx,
Matthias Beyer4fb9ab42014-06-23 21:18:22 +0200106 UCHAR GPIO_Num_tx,
107 UCHAR uiTxLedIndex,
108 UCHAR GPIO_Num_rx,
109 UCHAR uiRxLedIndex,
110 enum bcm_led_events currdriverstate,
111 ulong *timeout)
112{
Matthias Beyer4fb9ab42014-06-23 21:18:22 +0200113 /*
Matthias Beyerea205482014-06-23 21:18:24 +0200114 * Assign minimum number of blinks of
115 * either Tx or Rx.
Matthias Beyer4fb9ab42014-06-23 21:18:22 +0200116 */
Matthias Beyer89550512014-06-23 21:18:27 +0200117 *time = (*time_tx > *time_rx ? *time_rx : *time_tx);
118
Matthias Beyer9c805bd2014-06-23 21:18:26 +0200119 if (*time > 0) {
Matthias Beyerea205482014-06-23 21:18:24 +0200120 /* Blink both Tx and Rx LEDs */
Matthias Beyera143aa22014-06-23 21:18:28 +0200121 if ((LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout,
122 *time, currdriverstate) == EVENT_SIGNALED) ||
123 (LED_Blink(ad, 1 << GPIO_Num_rx, uiRxLedIndex, *timeout,
124 *time, currdriverstate) == EVENT_SIGNALED))
Matthias Beyerea205482014-06-23 21:18:24 +0200125 return EVENT_SIGNALED;
Matthias Beyerea205482014-06-23 21:18:24 +0200126 }
Matthias Beyer4fb9ab42014-06-23 21:18:22 +0200127
Matthias Beyer9c805bd2014-06-23 21:18:26 +0200128 if (*time == *time_tx) {
Matthias Beyerea205482014-06-23 21:18:24 +0200129 /* Blink pending rate of Rx */
Matthias Beyer60e66d82014-06-23 21:18:25 +0200130 if (LED_Blink(ad, (1 << GPIO_Num_rx), uiRxLedIndex, *timeout,
Matthias Beyer9c805bd2014-06-23 21:18:26 +0200131 *time_rx - *time,
Matthias Beyer60e66d82014-06-23 21:18:25 +0200132 currdriverstate) == EVENT_SIGNALED)
Matthias Beyerea205482014-06-23 21:18:24 +0200133 return EVENT_SIGNALED;
Matthias Beyer4fb9ab42014-06-23 21:18:22 +0200134
Matthias Beyer9c805bd2014-06-23 21:18:26 +0200135 *time = *time_rx;
Matthias Beyer4fb9ab42014-06-23 21:18:22 +0200136 } else {
Matthias Beyerea205482014-06-23 21:18:24 +0200137 /* Blink pending rate of Tx */
Matthias Beyer60e66d82014-06-23 21:18:25 +0200138 if (LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout,
Matthias Beyer9c805bd2014-06-23 21:18:26 +0200139 *time_tx - *time,
Matthias Beyer60e66d82014-06-23 21:18:25 +0200140 currdriverstate) == EVENT_SIGNALED)
Matthias Beyerea205482014-06-23 21:18:24 +0200141 return EVENT_SIGNALED;
142
Matthias Beyer9c805bd2014-06-23 21:18:26 +0200143 *time = *time_tx;
Matthias Beyer4fb9ab42014-06-23 21:18:22 +0200144 }
145
146 return 0;
147}
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700148
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200149static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter,
150 UCHAR GPIO_Num_tx,
151 UCHAR uiTxLedIndex,
152 UCHAR GPIO_Num_rx,
153 UCHAR uiRxLedIndex,
154 enum bcm_led_events currdriverstate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700155{
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100156 /* Initial values of TX and RX packets */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700157 ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0;
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100158 /* values of TX and RX packets after 1 sec */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700159 ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0;
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100160 /* Rate of transfer of Tx and Rx in 1 sec */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700161 ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0;
162 int Status = STATUS_SUCCESS;
163 INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
164 UINT remDelay = 0;
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100165 /* UINT GPIO_num = DISABLE_GPIO_NUM; */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700166 ulong timeout = 0;
167
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100168 /* Read initial value of packets sent/received */
Stephen Hemmingercacd9222010-11-01 13:34:35 -0400169 Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets;
170 Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets;
171
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100172 /* Scale the rate of transfer to no of blinks. */
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100173 num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
174 num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700175
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700176 while ((Adapter->device_removed == false)) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700177 timeout = 50;
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100178
Matthias Beyer4fb9ab42014-06-23 21:18:22 +0200179 if (EVENT_SIGNALED == blink_in_normal_bandwidth(Adapter,
180 &num_of_time,
181 &num_of_time_tx,
182 &num_of_time_rx,
183 GPIO_Num_tx,
184 uiTxLedIndex,
185 GPIO_Num_rx,
186 uiRxLedIndex,
187 currdriverstate,
188 &timeout))
189 return EVENT_SIGNALED;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700190
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100191
192 /*
193 * If Tx/Rx rate is less than maximum blinks per second,
194 * wait till delay completes to 1 second
195 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700196 remDelay = MAX_NUM_OF_BLINKS - num_of_time;
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100197 if (remDelay > 0) {
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100198 timeout = 100 * remDelay;
Johannes Tenschert42190012011-12-07 18:25:10 +0100199 Status = wait_event_interruptible_timeout(
200 Adapter->LEDInfo.notify_led_event,
201 currdriverstate != Adapter->DriverState
202 || kthread_should_stop(),
203 msecs_to_jiffies(timeout));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700204
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100205 if (kthread_should_stop()) {
Johannes Tenschert42190012011-12-07 18:25:10 +0100206 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
207 LED_DUMP_INFO, DBG_LVL_ALL,
208 "Led thread got signal to exit..hence exiting");
209 Adapter->LEDInfo.led_thread_running =
210 BCM_LED_THREAD_DISABLED;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700211 return EVENT_SIGNALED;
212 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100213 if (Status)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700214 return EVENT_SIGNALED;
215 }
216
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100217 /* Turn off both Tx and Rx LEDs before next second */
Matthias Beyera1082a42014-06-23 21:18:19 +0200218 TURN_OFF_LED(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex);
219 TURN_OFF_LED(Adapter, 1 << GPIO_Num_rx, uiTxLedIndex);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700220
221 /*
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100222 * Read the Tx & Rx packets transmission after 1 second and
223 * calculate rate of transfer
224 */
Stephen Hemmingercacd9222010-11-01 13:34:35 -0400225 Final_num_of_packts_tx = Adapter->dev->stats.tx_packets;
226 Final_num_of_packts_rx = Adapter->dev->stats.rx_packets;
227
Johannes Tenschert42190012011-12-07 18:25:10 +0100228 rate_of_transfer_tx = Final_num_of_packts_tx -
229 Initial_num_of_packts_tx;
230 rate_of_transfer_rx = Final_num_of_packts_rx -
231 Initial_num_of_packts_rx;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700232
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100233 /* Read initial value of packets sent/received */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700234 Initial_num_of_packts_tx = Final_num_of_packts_tx;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100235 Initial_num_of_packts_rx = Final_num_of_packts_rx;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700236
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100237 /* Scale the rate of transfer to no of blinks. */
Johannes Tenschert42190012011-12-07 18:25:10 +0100238 num_of_time_tx =
239 ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
240 num_of_time_rx =
241 ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700242
243 }
244 return Status;
245}
246
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100247/*
248 * -----------------------------------------------------------------------------
249 * Procedure: ValidateDSDParamsChecksum
250 *
251 * Description: Reads DSD Params and validates checkusm.
252 *
253 * Arguments:
254 * Adapter - Pointer to Adapter structure.
255 * ulParamOffset - Start offset of the DSD parameter to be read and
256 * validated.
257 * usParamLen - Length of the DSD Parameter.
258 *
259 * Returns:
260 * <OSAL_STATUS_CODE>
261 * -----------------------------------------------------------------------------
262 */
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200263static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter,
264 ULONG ulParamOffset,
265 USHORT usParamLen)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700266{
267 INT Status = STATUS_SUCCESS;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100268 PUCHAR puBuffer = NULL;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100269 USHORT usChksmOrg = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700270 USHORT usChecksumCalculated = 0;
271
Johannes Tenschert42190012011-12-07 18:25:10 +0100272 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200273 "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",
274 ulParamOffset, usParamLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700275
Stephen Hemminger082e8892010-11-01 09:35:21 -0400276 puBuffer = kmalloc(usParamLen, GFP_KERNEL);
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100277 if (!puBuffer) {
Johannes Tenschert42190012011-12-07 18:25:10 +0100278 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200279 DBG_LVL_ALL,
280 "LED Thread: ValidateDSDParamsChecksum Allocation failed");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700281 return -ENOMEM;
282
283 }
284
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100285 /* Read the DSD data from the parameter offset. */
Johannes Tenschert42190012011-12-07 18:25:10 +0100286 if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)puBuffer,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200287 ulParamOffset, usParamLen)) {
Johannes Tenschert42190012011-12-07 18:25:10 +0100288 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200289 DBG_LVL_ALL,
290 "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100291 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700292 goto exit;
293 }
294
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100295 /* Calculate the checksum of the data read from the DSD parameter. */
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100296 usChecksumCalculated = CFG_CalculateChecksum(puBuffer, usParamLen);
Johannes Tenschert42190012011-12-07 18:25:10 +0100297 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200298 "LED Thread: usCheckSumCalculated = 0x%x\n",
299 usChecksumCalculated);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700300
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100301 /*
302 * End of the DSD parameter will have a TWO bytes checksum stored in it.
303 * Read it and compare with the calculated Checksum.
304 */
Johannes Tenschert42190012011-12-07 18:25:10 +0100305 if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)&usChksmOrg,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200306 ulParamOffset+usParamLen, 2)) {
Johannes Tenschert42190012011-12-07 18:25:10 +0100307 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200308 DBG_LVL_ALL,
309 "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100310 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700311 goto exit;
312 }
313 usChksmOrg = ntohs(usChksmOrg);
Johannes Tenschert42190012011-12-07 18:25:10 +0100314 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200315 "LED Thread: usChksmOrg = 0x%x", usChksmOrg);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700316
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100317 /*
318 * Compare the checksum calculated with the checksum read
319 * from DSD section
320 */
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100321 if (usChecksumCalculated ^ usChksmOrg) {
Johannes Tenschert42190012011-12-07 18:25:10 +0100322 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200323 DBG_LVL_ALL,
324 "LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700325 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
326 goto exit;
327 }
328
329exit:
Stephen Hemminger082e8892010-11-01 09:35:21 -0400330 kfree(puBuffer);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700331 return Status;
332}
333
334
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100335/*
336 * -----------------------------------------------------------------------------
337 * Procedure: ValidateHWParmStructure
338 *
339 * Description: Validates HW Parameters.
340 *
341 * Arguments:
342 * Adapter - Pointer to Adapter structure.
343 * ulHwParamOffset - Start offset of the HW parameter Section to be read
344 * and validated.
345 *
346 * Returns:
347 * <OSAL_STATUS_CODE>
348 * -----------------------------------------------------------------------------
349 */
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200350static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter,
351 ULONG ulHwParamOffset)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700352{
353
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100354 INT Status = STATUS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700355 USHORT HwParamLen = 0;
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100356 /*
357 * Add DSD start offset to the hwParamOffset to get
358 * the actual address.
359 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700360 ulHwParamOffset += DSD_START_OFFSET;
361
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100362 /* Read the Length of HW_PARAM structure */
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100363 BeceemNVMRead(Adapter, (PUINT)&HwParamLen, ulHwParamOffset, 2);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700364 HwParamLen = ntohs(HwParamLen);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100365 if (0 == HwParamLen || HwParamLen > Adapter->uiNVMDSDSize)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700366 return STATUS_IMAGE_CHECKSUM_MISMATCH;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700367
Johannes Tenschert42190012011-12-07 18:25:10 +0100368 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200369 "LED Thread:HwParamLen = 0x%x", HwParamLen);
Johannes Tenschert42190012011-12-07 18:25:10 +0100370 Status = ValidateDSDParamsChecksum(Adapter, ulHwParamOffset,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200371 HwParamLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700372 return Status;
373} /* ValidateHWParmStructure() */
374
Kevin McKinney29794602012-05-26 12:05:12 -0400375static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter,
Johannes Tenschert42190012011-12-07 18:25:10 +0100376 UCHAR GPIO_Array[])
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700377{
378 int Status = STATUS_SUCCESS;
379
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100380 ULONG dwReadValue = 0;
381 USHORT usHwParamData = 0;
382 USHORT usEEPROMVersion = 0;
383 UCHAR ucIndex = 0;
384 UCHAR ucGPIOInfo[32] = {0};
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700385
Johannes Tenschert42190012011-12-07 18:25:10 +0100386 BeceemNVMRead(Adapter, (PUINT)&usEEPROMVersion,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200387 EEPROM_VERSION_OFFSET, 2);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700388
Johannes Tenschert42190012011-12-07 18:25:10 +0100389 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200390 "usEEPROMVersion: Minor:0x%X Major:0x%x",
391 usEEPROMVersion & 0xFF,
392 ((usEEPROMVersion >> 8) & 0xFF));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700393
394
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100395 if (((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION) {
Johannes Tenschert42190012011-12-07 18:25:10 +0100396 BeceemNVMRead(Adapter, (PUINT)&usHwParamData,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200397 EEPROM_HW_PARAM_POINTER_ADDRESS, 2);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700398 usHwParamData = ntohs(usHwParamData);
399 dwReadValue = usHwParamData;
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100400 } else {
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100401 /*
402 * Validate Compatibility section and then read HW param
403 * if compatibility section is valid.
404 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700405 Status = ValidateDSDParamsChecksum(Adapter,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200406 DSD_START_OFFSET,
407 COMPATIBILITY_SECTION_LENGTH_MAP5);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700408
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100409 if (Status != STATUS_SUCCESS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700410 return Status;
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100411
Johannes Tenschert42190012011-12-07 18:25:10 +0100412 BeceemNVMRead(Adapter, (PUINT)&dwReadValue,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200413 EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700414 dwReadValue = ntohl(dwReadValue);
415 }
416
417
Johannes Tenschert42190012011-12-07 18:25:10 +0100418 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200419 "LED Thread: Start address of HW_PARAM structure = 0x%lx",
420 dwReadValue);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700421
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100422 /*
423 * Validate if the address read out is within the DSD.
424 * Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
425 * lower limit should be above DSD_START_OFFSET and
426 * upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
427 */
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100428 if (dwReadValue < DSD_START_OFFSET ||
429 dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700430 return STATUS_IMAGE_CHECKSUM_MISMATCH;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700431
432 Status = ValidateHWParmStructure(Adapter, dwReadValue);
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100433 if (Status)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700434 return Status;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700435
436 /*
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100437 * Add DSD_START_OFFSET to the offset read from the EEPROM.
438 * This will give the actual start HW Parameters start address.
439 * To read GPIO section, add GPIO offset further.
440 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700441
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200442 dwReadValue += DSD_START_OFFSET;
443 /* = start address of hw param section. */
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100444 dwReadValue += GPIO_SECTION_START_OFFSET;
445 /* = GPIO start offset within HW Param section. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700446
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100447 /*
448 * Read the GPIO values for 32 GPIOs from EEPROM and map the function
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100449 * number to GPIO pin number to GPIO_Array
450 */
451 BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo, dwReadValue, 32);
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100452 for (ucIndex = 0; ucIndex < 32; ucIndex++) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700453
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100454 switch (ucGPIOInfo[ucIndex]) {
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100455 case RED_LED:
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100456 GPIO_Array[RED_LED] = ucIndex;
457 Adapter->gpioBitMap |= (1 << ucIndex);
458 break;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100459 case BLUE_LED:
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100460 GPIO_Array[BLUE_LED] = ucIndex;
461 Adapter->gpioBitMap |= (1 << ucIndex);
462 break;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100463 case YELLOW_LED:
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100464 GPIO_Array[YELLOW_LED] = ucIndex;
465 Adapter->gpioBitMap |= (1 << ucIndex);
466 break;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100467 case GREEN_LED:
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100468 GPIO_Array[GREEN_LED] = ucIndex;
469 Adapter->gpioBitMap |= (1 << ucIndex);
470 break;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100471 default:
472 break;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700473 }
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100474
475 }
Johannes Tenschert42190012011-12-07 18:25:10 +0100476 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200477 "GPIO's bit map correspond to LED :0x%X",
478 Adapter->gpioBitMap);
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100479 return Status;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700480}
481
482
Kevin McKinney29794602012-05-26 12:05:12 -0400483static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200484 bool *bEnableThread)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700485{
486 int Status = STATUS_SUCCESS;
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100487 /* Array to store GPIO numbers from EEPROM */
488 UCHAR GPIO_Array[NUM_OF_LEDS+1];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700489 UINT uiIndex = 0;
490 UINT uiNum_of_LED_Type = 0;
491 PUCHAR puCFGData = NULL;
492 UCHAR bData = 0;
Matthias Beyer76a60d52014-06-23 21:18:29 +0200493 struct bcm_led_state_info *curr_led_state;
Pawel Lebioda89fa0372014-07-09 17:59:29 +0200494
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700495 memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
496
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100497 if (!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) {
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200498 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
499 DBG_LVL_ALL, "Target Params not Avail.\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700500 return -ENOENT;
501 }
502
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100503 /* Populate GPIO_Array with GPIO numbers for LED functions */
504 /* Read the GPIO numbers from EEPROM */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700505 Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array);
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100506 if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) {
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700507 *bEnableThread = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700508 return STATUS_SUCCESS;
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100509 } else if (Status) {
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700510 *bEnableThread = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700511 return Status;
512 }
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100513
514 /*
515 * CONFIG file read successfully. Deallocate the memory of
516 * uiFileNameBufferSize
517 */
Johannes Tenschert42190012011-12-07 18:25:10 +0100518 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200519 "LED Thread: Config file read successfully\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700520 puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1;
521
522 /*
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100523 * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
524 * will have the information of LED type, LED on state for different
525 * driver state and LED blink state.
526 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700527
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100528 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700529 bData = *puCFGData;
Matthias Beyer76a60d52014-06-23 21:18:29 +0200530 curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700531
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100532 /*
533 * Check Bit 8 for polarity. If it is set,
534 * polarity is reverse polarity
535 */
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100536 if (bData & 0x80) {
Matthias Beyer76a60d52014-06-23 21:18:29 +0200537 curr_led_state->BitPolarity = 0;
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100538 /* unset the bit 8 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700539 bData = bData & 0x7f;
540 }
541
Matthias Beyer76a60d52014-06-23 21:18:29 +0200542 curr_led_state->LED_Type = bData;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100543 if (bData <= NUM_OF_LEDS)
Matthias Beyer76a60d52014-06-23 21:18:29 +0200544 curr_led_state->GPIO_Num = GPIO_Array[bData];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700545 else
Matthias Beyer76a60d52014-06-23 21:18:29 +0200546 curr_led_state->GPIO_Num = DISABLE_GPIO_NUM;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700547
548 puCFGData++;
549 bData = *puCFGData;
Matthias Beyer76a60d52014-06-23 21:18:29 +0200550 curr_led_state->LED_On_State = bData;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700551 puCFGData++;
552 bData = *puCFGData;
Matthias Beyer76a60d52014-06-23 21:18:29 +0200553 curr_led_state->LED_Blink_State = bData;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700554 puCFGData++;
555 }
556
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100557 /*
558 * Check if all the LED settings are disabled. If it is disabled,
559 * dont launch the LED control thread.
560 */
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100561 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
Matthias Beyer76a60d52014-06-23 21:18:29 +0200562 curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex];
563
564 if ((curr_led_state->LED_Type == DISABLE_GPIO_NUM) ||
565 (curr_led_state->LED_Type == 0x7f) ||
566 (curr_led_state->LED_Type == 0))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700567 uiNum_of_LED_Type++;
568 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100569 if (uiNum_of_LED_Type >= NUM_OF_LEDS)
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700570 *bEnableThread = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700571
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700572 return Status;
573}
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700574
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100575/*
576 * -----------------------------------------------------------------------------
577 * Procedure: LedGpioInit
578 *
579 * Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode
580 * and make the initial state to be OFF.
581 *
582 * Arguments:
583 * Adapter - Pointer to MINI_ADAPTER structure.
584 *
585 * Returns: VOID
586 *
587 * -----------------------------------------------------------------------------
588 */
Kevin McKinney29794602012-05-26 12:05:12 -0400589static VOID LedGpioInit(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700590{
591 UINT uiResetValue = 0;
592 UINT uiIndex = 0;
Matthias Beyer2d2ea212014-06-23 21:18:30 +0200593 struct bcm_led_state_info *curr_led_state;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700594
595 /* Set all LED GPIO Mode to output mode */
Johannes Tenschert42190012011-12-07 18:25:10 +0100596 if (rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200597 sizeof(uiResetValue)) < 0)
Johannes Tenschert42190012011-12-07 18:25:10 +0100598 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
599 DBG_LVL_ALL, "LED Thread: RDM Failed\n");
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100600 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
Matthias Beyer2d2ea212014-06-23 21:18:30 +0200601 curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex];
602
603 if (curr_led_state->GPIO_Num != DISABLE_GPIO_NUM)
604 uiResetValue |= (1 << curr_led_state->GPIO_Num);
605
606 TURN_OFF_LED(Adapter, 1 << curr_led_state->GPIO_Num, uiIndex);
607
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700608 }
Johannes Tenschert42190012011-12-07 18:25:10 +0100609 if (wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200610 sizeof(uiResetValue)) < 0)
611 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
612 DBG_LVL_ALL, "LED Thread: WRM Failed\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700613
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700614 Adapter->LEDInfo.bIdle_led_off = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700615}
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700616
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200617static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter,
618 UCHAR *GPIO_num_tx,
619 UCHAR *GPIO_num_rx,
620 UCHAR *uiLedTxIndex,
621 UCHAR *uiLedRxIndex,
622 enum bcm_led_events currdriverstate)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700623{
624 UINT uiIndex = 0;
Matthias Beyere4e9d832014-06-23 21:18:21 +0200625 struct bcm_led_state_info *led_state_info;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700626
627 *GPIO_num_tx = DISABLE_GPIO_NUM;
628 *GPIO_num_rx = DISABLE_GPIO_NUM;
629
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100630 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
Matthias Beyere4e9d832014-06-23 21:18:21 +0200631 led_state_info = &Adapter->LEDInfo.LEDState[uiIndex];
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700632
Matthias Beyer7a0304c2014-06-23 21:18:20 +0200633 if (((currdriverstate == NORMAL_OPERATION) ||
634 (currdriverstate == IDLEMODE_EXIT) ||
635 (currdriverstate == FW_DOWNLOAD)) &&
Matthias Beyerf4367df2014-06-23 21:18:31 +0200636 (led_state_info->LED_Blink_State & currdriverstate) &&
637 (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) {
638 if (*GPIO_num_tx == DISABLE_GPIO_NUM) {
639 *GPIO_num_tx = led_state_info->GPIO_Num;
640 *uiLedTxIndex = uiIndex;
641 } else {
642 *GPIO_num_rx = led_state_info->GPIO_Num;
643 *uiLedRxIndex = uiIndex;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700644 }
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100645 } else {
Matthias Beyere4e9d832014-06-23 21:18:21 +0200646 if ((led_state_info->LED_On_State & currdriverstate) &&
647 (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) {
648 *GPIO_num_tx = led_state_info->GPIO_Num;
Matthias Beyer7a0304c2014-06-23 21:18:20 +0200649 *uiLedTxIndex = uiIndex;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700650 }
651 }
652 }
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100653 return STATUS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700654}
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200655
Matthias Beyerce2705c2014-06-23 21:18:18 +0200656static void handle_adapter_driver_state(struct bcm_mini_adapter *ad,
657 enum bcm_led_events currdriverstate,
658 UCHAR GPIO_num,
659 UCHAR dummyGPIONum,
660 UCHAR uiLedIndex,
661 UCHAR dummyIndex,
662 ulong timeout,
663 UINT uiResetValue,
664 UINT uiIndex)
665{
666 switch (ad->DriverState) {
667 case DRIVER_INIT:
668 currdriverstate = DRIVER_INIT;
669 /* ad->DriverState; */
670 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
671 &uiLedIndex, &dummyIndex,
672 currdriverstate);
673
674 if (GPIO_num != DISABLE_GPIO_NUM)
Matthias Beyera1082a42014-06-23 21:18:19 +0200675 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
Matthias Beyerce2705c2014-06-23 21:18:18 +0200676
677 break;
678 case FW_DOWNLOAD:
679 /*
680 * BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
681 * LED_DUMP_INFO, DBG_LVL_ALL,
682 * "LED Thread: FW_DN_DONE called\n");
683 */
684 currdriverstate = FW_DOWNLOAD;
685 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
686 &uiLedIndex, &dummyIndex,
687 currdriverstate);
688
689 if (GPIO_num != DISABLE_GPIO_NUM) {
690 timeout = 50;
691 LED_Blink(ad, 1 << GPIO_num, uiLedIndex, timeout,
692 -1, currdriverstate);
693 }
694 break;
695 case FW_DOWNLOAD_DONE:
696 currdriverstate = FW_DOWNLOAD_DONE;
697 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
698 &uiLedIndex, &dummyIndex, currdriverstate);
699 if (GPIO_num != DISABLE_GPIO_NUM)
Matthias Beyera1082a42014-06-23 21:18:19 +0200700 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
Matthias Beyerce2705c2014-06-23 21:18:18 +0200701 break;
702
703 case SHUTDOWN_EXIT:
704 /*
705 * no break, continue to NO_NETWORK_ENTRY
706 * state as well.
707 */
708 case NO_NETWORK_ENTRY:
709 currdriverstate = NO_NETWORK_ENTRY;
710 BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
711 &uiLedIndex, &dummyGPIONum, currdriverstate);
712 if (GPIO_num != DISABLE_GPIO_NUM)
Matthias Beyera1082a42014-06-23 21:18:19 +0200713 TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
Matthias Beyerce2705c2014-06-23 21:18:18 +0200714 break;
715 case NORMAL_OPERATION:
716 {
717 UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
718 UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
719 UCHAR uiLEDTx = 0;
720 UCHAR uiLEDRx = 0;
Pawel Lebioda89fa0372014-07-09 17:59:29 +0200721
Matthias Beyerce2705c2014-06-23 21:18:18 +0200722 currdriverstate = NORMAL_OPERATION;
723 ad->LEDInfo.bIdle_led_off = false;
724
725 BcmGetGPIOPinInfo(ad, &GPIO_num_tx, &GPIO_num_rx,
726 &uiLEDTx, &uiLEDRx, currdriverstate);
727 if ((GPIO_num_tx == DISABLE_GPIO_NUM) &&
728 (GPIO_num_rx == DISABLE_GPIO_NUM)) {
729 GPIO_num = DISABLE_GPIO_NUM;
730 } else {
731 /*
732 * If single LED is selected, use same
733 * for both Tx and Rx
734 */
735 if (GPIO_num_tx == DISABLE_GPIO_NUM) {
736 GPIO_num_tx = GPIO_num_rx;
737 uiLEDTx = uiLEDRx;
738 } else if (GPIO_num_rx == DISABLE_GPIO_NUM) {
739 GPIO_num_rx = GPIO_num_tx;
740 uiLEDRx = uiLEDTx;
741 }
742 /*
743 * Blink the LED in proportionate
744 * to Tx and Rx transmissions.
745 */
746 LED_Proportional_Blink(ad,
747 GPIO_num_tx, uiLEDTx,
748 GPIO_num_rx, uiLEDRx,
749 currdriverstate);
750 }
751 }
752 break;
753 case LOWPOWER_MODE_ENTER:
754 currdriverstate = LOWPOWER_MODE_ENTER;
755 if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING ==
756 ad->ulPowerSaveMode) {
757 /* Turn OFF all the LED */
758 uiResetValue = 0;
759 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
760 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
Matthias Beyera1082a42014-06-23 21:18:19 +0200761 TURN_OFF_LED(ad,
762 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
763 uiIndex);
Matthias Beyerce2705c2014-06-23 21:18:18 +0200764 }
765
766 }
767 /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
768 ad->LEDInfo.bLedInitDone = false;
769 ad->LEDInfo.bIdle_led_off = TRUE;
770 wake_up(&ad->LEDInfo.idleModeSyncEvent);
771 GPIO_num = DISABLE_GPIO_NUM;
772 break;
773 case IDLEMODE_CONTINUE:
774 currdriverstate = IDLEMODE_CONTINUE;
775 GPIO_num = DISABLE_GPIO_NUM;
776 break;
777 case IDLEMODE_EXIT:
778 break;
779 case DRIVER_HALT:
780 currdriverstate = DRIVER_HALT;
781 GPIO_num = DISABLE_GPIO_NUM;
782 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
783 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num !=
784 DISABLE_GPIO_NUM)
Matthias Beyera1082a42014-06-23 21:18:19 +0200785 TURN_OFF_LED(ad,
786 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
787 uiIndex);
Matthias Beyerce2705c2014-06-23 21:18:18 +0200788 }
789 /* ad->DriverState = DRIVER_INIT; */
790 break;
791 case LED_THREAD_INACTIVE:
792 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO,
793 DBG_LVL_ALL, "InActivating LED thread...");
794 currdriverstate = LED_THREAD_INACTIVE;
795 ad->LEDInfo.led_thread_running =
796 BCM_LED_THREAD_RUNNING_INACTIVELY;
797 ad->LEDInfo.bLedInitDone = false;
798 /* disable ALL LED */
799 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
800 if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num !=
801 DISABLE_GPIO_NUM)
Matthias Beyera1082a42014-06-23 21:18:19 +0200802 TURN_OFF_LED(ad,
803 (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
804 uiIndex);
Matthias Beyerce2705c2014-06-23 21:18:18 +0200805 }
806 break;
807 case LED_THREAD_ACTIVE:
808 BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO,
809 DBG_LVL_ALL, "Activating LED thread again...");
810 if (ad->LinkUpStatus == false)
811 ad->DriverState = NO_NETWORK_ENTRY;
812 else
813 ad->DriverState = NORMAL_OPERATION;
814
815 ad->LEDInfo.led_thread_running =
816 BCM_LED_THREAD_RUNNING_ACTIVELY;
817 break;
818 /* return; */
819 default:
820 break;
821 }
822}
823
Kevin McKinney29794602012-05-26 12:05:12 -0400824static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700825{
826 UINT uiIndex = 0;
827 UCHAR GPIO_num = 0;
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100828 UCHAR uiLedIndex = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700829 UINT uiResetValue = 0;
Kevin McKinneyb3d9a8f2012-12-14 19:26:52 -0500830 enum bcm_led_events currdriverstate = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700831 ulong timeout = 0;
832
833 INT Status = 0;
834
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100835 UCHAR dummyGPIONum = 0;
836 UCHAR dummyIndex = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700837
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100838 /* currdriverstate = Adapter->DriverState; */
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700839 Adapter->LEDInfo.bIdleMode_tx_from_host = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700840
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100841 /*
842 * Wait till event is triggered
843 *
844 * wait_event(Adapter->LEDInfo.notify_led_event,
845 * currdriverstate!= Adapter->DriverState);
846 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700847
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100848 GPIO_num = DISABLE_GPIO_NUM;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700849
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100850 while (TRUE) {
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100851 /* Wait till event is triggered */
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100852 if ((GPIO_num == DISABLE_GPIO_NUM)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700853 ||
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100854 ((currdriverstate != FW_DOWNLOAD) &&
855 (currdriverstate != NORMAL_OPERATION) &&
856 (currdriverstate != LOWPOWER_MODE_ENTER))
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100857 ||
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100858 (currdriverstate == LED_THREAD_INACTIVE))
Johannes Tenschert42190012011-12-07 18:25:10 +0100859 Status = wait_event_interruptible(
860 Adapter->LEDInfo.notify_led_event,
861 currdriverstate != Adapter->DriverState
862 || kthread_should_stop());
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700863
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100864 if (kthread_should_stop() || Adapter->device_removed) {
Johannes Tenschert42190012011-12-07 18:25:10 +0100865 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
866 DBG_LVL_ALL,
867 "Led thread got signal to exit..hence exiting");
868 Adapter->LEDInfo.led_thread_running =
869 BCM_LED_THREAD_DISABLED;
Matthias Beyera1082a42014-06-23 21:18:19 +0200870 TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex);
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100871 return; /* STATUS_FAILURE; */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700872 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700873
Johannes Tenschertc1eb22d2011-12-07 18:25:06 +0100874 if (GPIO_num != DISABLE_GPIO_NUM)
Matthias Beyera1082a42014-06-23 21:18:19 +0200875 TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700876
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700877 if (Adapter->LEDInfo.bLedInitDone == false) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700878 LedGpioInit(Adapter);
879 Adapter->LEDInfo.bLedInitDone = TRUE;
880 }
881
Matthias Beyerce2705c2014-06-23 21:18:18 +0200882 handle_adapter_driver_state(Adapter,
883 currdriverstate,
884 GPIO_num,
885 dummyGPIONum,
886 uiLedIndex,
887 dummyIndex,
888 timeout,
889 uiResetValue,
890 uiIndex
891 );
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700892 }
893 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
894}
895
Kevin McKinney29794602012-05-26 12:05:12 -0400896int InitLedSettings(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700897{
898 int Status = STATUS_SUCCESS;
Lisa Nguyen3abd6f12013-10-28 01:35:59 -0700899 bool bEnableThread = TRUE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700900 UCHAR uiIndex = 0;
901
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100902 /*
903 * Initially set BitPolarity to normal polarity. The bit 8 of LED type
904 * is used to change the polarity of the LED.
905 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700906
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100907 for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700908 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700909
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100910 /*
911 * Read the LED settings of CONFIG file and map it
912 * to GPIO numbers in EEPROM
913 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700914 Status = ReadConfigFileStructure(Adapter, &bEnableThread);
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100915 if (STATUS_SUCCESS != Status) {
Johannes Tenschert42190012011-12-07 18:25:10 +0100916 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200917 DBG_LVL_ALL,
918 "LED Thread: FAILED in ReadConfigFileStructure\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700919 return Status;
920 }
921
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100922 if (Adapter->LEDInfo.led_thread_running) {
923 if (bEnableThread) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700924 ;
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100925 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700926 Adapter->DriverState = DRIVER_HALT;
927 wake_up(&Adapter->LEDInfo.notify_led_event);
Johannes Tenschert42190012011-12-07 18:25:10 +0100928 Adapter->LEDInfo.led_thread_running =
929 BCM_LED_THREAD_DISABLED;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700930 }
931
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100932 } else if (bEnableThread) {
Johannes Tenschertf5d8c262011-12-07 18:25:08 +0100933 /* Create secondary thread to handle the LEDs */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700934 init_waitqueue_head(&Adapter->LEDInfo.notify_led_event);
935 init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent);
Johannes Tenschert42190012011-12-07 18:25:10 +0100936 Adapter->LEDInfo.led_thread_running =
937 BCM_LED_THREAD_RUNNING_ACTIVELY;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700938 Adapter->LEDInfo.bIdle_led_off = false;
Johannes Tenschert42190012011-12-07 18:25:10 +0100939 Adapter->LEDInfo.led_cntrl_threadid =
940 kthread_run((int (*)(void *)) LEDControlThread,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200941 Adapter, "led_control_thread");
Johannes Tenschertd9ce3532011-12-07 18:25:09 +0100942 if (IS_ERR(Adapter->LEDInfo.led_cntrl_threadid)) {
Johannes Tenschert42190012011-12-07 18:25:10 +0100943 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
Matthias Beyer9bcfab202014-06-23 21:18:17 +0200944 DBG_LVL_ALL,
945 "Not able to spawn Kernel Thread\n");
Johannes Tenschert42190012011-12-07 18:25:10 +0100946 Adapter->LEDInfo.led_thread_running =
947 BCM_LED_THREAD_DISABLED;
Johannes Tenschert34e98e72011-12-07 18:25:07 +0100948 return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);
949 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700950 }
951 return Status;
952}