import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / drv_wlan / mt6628 / wlan / nic / nic_pwr_mgt.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_pwr_mgt.c#1 $
3 */
4
5 /*! \file "nic_pwr_mgt.c"
6 \brief In this file we define the STATE and EVENT for Power Management FSM.
7
8 The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter
9 ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail
10 description.
11 */
12
13
14
15 /*
16 ** $Log: nic_pwr_mgt.c $
17 *
18 * 11 28 2011 cp.wu
19 * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when returining to ROM code
20 * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware
21 * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not
22 *
23 * 10 03 2011 cp.wu
24 * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
25 * add firmware download path in divided scatters.
26 *
27 * 08 15 2011 cp.wu
28 * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
29 * reuse firmware download logic of MT6620 for MT6628.
30 *
31 * 05 11 2011 cp.wu
32 * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
33 * ACPI APIs migrate to wlan_lib.c for glue layer to invoke.
34 *
35 * 04 29 2011 cp.wu
36 * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h)
37 * fix for compilation error when applied with FW_DOWNLOAD = 0
38 *
39 * 04 18 2011 cp.wu
40 * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h)
41 * 1) add API for glue layer to query ACPI state
42 * 2) Windows glue should not access to hardware after switched into D3 state
43 *
44 * 04 13 2011 cp.wu
45 * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete
46 * refine for MT5931/MT6620 logic separation.
47 *
48 * 04 13 2011 cp.wu
49 * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete
50 * bugfix: firmware download procedure for ACPI state transition is not complete.
51 *
52 * 03 15 2011 cp.wu
53 * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous memory consumption
54 * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
55 * 2. Use common coalescing buffer for both TX/RX directions
56 *
57 *
58 * 03 07 2011 terry.wu
59 * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
60 * Toggle non-standard debug messages to comments.
61 *
62 * 12 31 2010 cp.wu
63 * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system scheduling
64 * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being loaded
65 *
66 * 12 31 2010 cp.wu
67 * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
68 * check success or failure for setting fw-own
69 *
70 * 12 30 2010 cp.wu
71 * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
72 * host driver not to set FW-own when there is still pending interrupts
73 *
74 * 10 07 2010 cp.wu
75 * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
76 * add firmware download for MT5931.
77 *
78 * 09 21 2010 cp.wu
79 * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
80 * Do a complete reset with STA-REC null checking for RF test re-entry
81 *
82 * 08 30 2010 cp.wu
83 * NULL
84 * eliminate klockwork errors
85 *
86 * 08 30 2010 cp.wu
87 * NULL
88 * reset ACPI power state before waking up MT6620 Wi-Fi firmware.
89 *
90 * 08 12 2010 cp.wu
91 * NULL
92 * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G)
93 *
94 * 08 03 2010 cp.wu
95 * NULL
96 * Centralize mgmt/system service procedures into independent calls.
97 *
98 * 07 22 2010 cp.wu
99 *
100 * 1) refine AIS-FSM indent.
101 * 2) when entering RF Test mode, flush 802.1X frames as well
102 * 3) when entering D3 state, flush 802.1X frames as well
103 *
104 * 07 08 2010 cp.wu
105 *
106 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
107 *
108 * 06 21 2010 cp.wu
109 * [WPD00003833][MT6620 and MT5931] Driver migration
110 * change MAC address updating logic.
111 *
112 * 06 06 2010 kevin.huang
113 * [WPD00003832][MT6620 5931] Create driver base
114 * [MT6620 5931] Create driver base
115 *
116 * 05 24 2010 cp.wu
117 * [WPD00001943]Create WiFi test driver framework on WinXP
118 * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll
119 * 2) correct address list parsing
120 *
121 * 05 22 2010 cp.wu
122 * [WPD00001943]Create WiFi test driver framework on WinXP
123 * sleepy notify is only used for sleepy state,
124 * while wake-up state is automatically set when host needs to access device
125 *
126 * 05 19 2010 cp.wu
127 * [WPD00001943]Create WiFi test driver framework on WinXP
128 * correct hibernation problem.
129 *
130 * 04 26 2010 cp.wu
131 * [WPD00001943]Create WiFi test driver framework on WinXP
132 * 1) surpress compiler warning
133 * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet
134 *
135 * 04 23 2010 cp.wu
136 * [WPD00001943]Create WiFi test driver framework on WinXP
137 * surpress compiler warning
138 *
139 * 04 22 2010 cp.wu
140 * [WPD00001943]Create WiFi test driver framework on WinXP
141 * when acquiring driver-own, wait for up to 8 seconds.
142 *
143 * 04 21 2010 jeffrey.chang
144 * [WPD00003826]Initial import for Linux port
145 * add for private ioctl support
146 *
147 * 04 20 2010 cp.wu
148 * [WPD00001943]Create WiFi test driver framework on WinXP
149 * 1) remove redundant firmware image unloading
150 * * 2) use compile-time macros to separate logic related to accquiring own
151 *
152 * 04 16 2010 cp.wu
153 * [WPD00001943]Create WiFi test driver framework on WinXP
154 * treat BUS access failure as kind of card removal.
155 *
156 * 04 07 2010 cp.wu
157 * [WPD00001943]Create WiFi test driver framework on WinXP
158 * accessing to firmware load/start address, and access to OID handling information
159 * * are now handled in glue layer
160 *
161 * 04 06 2010 cp.wu
162 * [WPD00001943]Create WiFi test driver framework on WinXP
163 * ePowerCtrl is not necessary as a glue variable.
164 *
165 * 04 06 2010 cp.wu
166 * [WPD00001943]Create WiFi test driver framework on WinXP
167 * add KAL API: kalFlushPendingTxPackets(), and take use of the API
168 *
169 * 04 06 2010 cp.wu
170 * [WPD00001943]Create WiFi test driver framework on WinXP
171 * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
172 *
173 * 03 24 2010 jeffrey.chang
174 * [WPD00003826]Initial import for Linux port
175 * initial import for Linux port
176 *
177 * 03 22 2010 cp.wu
178 * [WPD00001943]Create WiFi test driver framework on WinXP
179 * always send CMD_NIC_POWER_CTRL packet when nic is being halted
180 *
181 * 03 19 2010 cp.wu
182 * [WPD00001943]Create WiFi test driver framework on WinXP
183 * correct typo.
184 *
185 * 03 19 2010 cp.wu
186 * [WPD00001943]Create WiFi test driver framework on WinXP
187 * 1) add ACPI D0/D3 state switching support
188 * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response
189 *
190 * 03 08 2010 cp.wu
191 * [WPD00001943]Create WiFi test driver framework on WinXP
192 * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread.
193 * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds
194 ** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-13 21:59:15 GMT mtk01084
195 ** update for new HW design
196 ** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-09-09 17:26:36 GMT mtk01084
197 ** remove CMD52 access
198 ** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-18 14:50:29 GMT mtk01084
199 ** modify lines in nicpmSetDriverOwn()
200 ** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:55:37 GMT mtk01084
201 ** modify nicpmSetDriverOwn()
202 ** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:33:00 GMT mtk01084
203 ** update for basic power management functions
204 ** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:32 GMT mtk01084
205 ** Initial version
206 **
207 */
208
209 /*******************************************************************************
210 * C O M P I L E R F L A G S
211 ********************************************************************************
212 */
213
214 /*******************************************************************************
215 * E X T E R N A L R E F E R E N C E S
216 ********************************************************************************
217 */
218 #include "precomp.h"
219
220 /*******************************************************************************
221 * C O N S T A N T S
222 ********************************************************************************
223 */
224
225 /*******************************************************************************
226 * D A T A T Y P E S
227 ********************************************************************************
228 */
229
230 /*******************************************************************************
231 * P U B L I C D A T A
232 ********************************************************************************
233 */ extern BOOLEAN fgIsResetting;
234
235 /*******************************************************************************
236 * P R I V A T E D A T A
237 ********************************************************************************
238 */
239
240 /*******************************************************************************
241 * M A C R O S
242 ********************************************************************************
243 */
244
245 /*******************************************************************************
246 * F U N C T I O N D E C L A R A T I O N S
247 ********************************************************************************
248 */
249
250 /*******************************************************************************
251 * F U N C T I O N S
252 ********************************************************************************
253 */
254
255 /*----------------------------------------------------------------------------*/
256 /*!
257 * \brief This routine is used to process the POWER ON procedure.
258 *
259 * \param[in] pvAdapter Pointer to the Adapter structure.
260 *
261 * \return (none)
262 */
263 /*----------------------------------------------------------------------------*/
264 VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt)
265 {
266 UINT_32 u4RegValue;
267
268 ASSERT(prAdapter);
269
270 if (prAdapter->fgIsFwOwn == TRUE) {
271 return;
272 } else {
273 if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
274 /* pending interrupts */
275 return;
276 }
277 }
278
279 if (fgEnableGlobalInt) {
280 prAdapter->fgIsIntEnableWithLPOwnSet = TRUE;
281 } else {
282 HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET);
283
284 HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
285 if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
286 /* if set firmware own not successful (possibly pending interrupts), */
287 /* indicate an own clear event */
288 HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
289
290 return;
291 }
292
293 prAdapter->fgIsFwOwn = TRUE;
294 }
295 }
296
297 /*----------------------------------------------------------------------------*/
298 /*!
299 * \brief This routine is used to process the POWER OFF procedure.
300 *
301 * \param[in] pvAdapter Pointer to the Adapter structure.
302 *
303 * \return (none)
304 */
305 /*----------------------------------------------------------------------------*/
306 BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter)
307 {
308 #define LP_OWN_BACK_TOTAL_DELAY_MS 8192 /* exponential of 2 */
309 #define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */
310 #define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */
311
312 BOOLEAN fgStatus = TRUE;
313 UINT_32 i, u4CurrTick, u4RegValue = 0;
314
315 ASSERT(prAdapter);
316
317 if (prAdapter->fgIsFwOwn == FALSE)
318 return fgStatus;
319
320 u4CurrTick = kalGetTimeTick();
321 i = 0;
322 while (1) {
323 HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
324
325 if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
326 prAdapter->fgIsFwOwn = FALSE;
327 break;
328 } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
329 || fgIsBusAccessFailed == TRUE
330 || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS
331 || fgIsResetting == TRUE) {
332 /* ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); */
333 fgStatus = FALSE;
334 break;
335 } else {
336 if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) {
337 /* Software get LP ownership - per 256 iterations */
338 HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
339 }
340
341 /* Delay for LP engine to complete its operation. */
342 kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS);
343 i++;
344 }
345 }
346
347 return fgStatus;
348 }
349
350 /*----------------------------------------------------------------------------*/
351 /*!
352 * \brief This routine is used to set ACPI power mode to D0.
353 *
354 * \param[in] pvAdapter Pointer to the Adapter structure.
355 *
356 * \return (none)
357 */
358 /*----------------------------------------------------------------------------*/
359 BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter)
360 {
361 WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
362 UINT_32 u4Value = 0, u4WHISR = 0;
363 UINT_8 aucTxCount[8];
364 UINT_32 i;
365 #if CFG_ENABLE_FW_DOWNLOAD
366 UINT_32 u4FwImgLength, u4FwLoadAddr, u4ImgSecSize;
367 PVOID prFwMappingHandle;
368 PVOID pvFwImageMapFile = NULL;
369 #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
370 UINT_32 j;
371 P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead;
372 BOOLEAN fgValidHead;
373 const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries);
374 #endif
375 #endif
376
377 DEBUGFUNC("nicpmSetAcpiPowerD0");
378
379 ASSERT(prAdapter);
380
381 do {
382 /* 0. Reset variables in ADAPTER_T */
383 prAdapter->fgIsFwOwn = TRUE;
384 prAdapter->fgWiFiInSleepyState = FALSE;
385 prAdapter->rAcpiState = ACPI_STATE_D0;
386 prAdapter->fgIsEnterD3ReqIssued = FALSE;
387
388 #if defined(MT6620) || defined(MT6628)
389 /* 1. Request Ownership to enter F/W download state */
390 ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
391 #if !CFG_ENABLE_FULL_PM
392 nicpmSetDriverOwn(prAdapter);
393 #endif
394
395 /* 2. Initialize the Adapter */
396 if ((u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS) {
397 DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n"));
398 u4Status = WLAN_STATUS_FAILURE;
399 break;
400 }
401 #endif
402
403 #if CFG_ENABLE_FW_DOWNLOAD
404 prFwMappingHandle =
405 kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile,
406 &u4FwImgLength);
407 if (!prFwMappingHandle) {
408 DBGLOG(INIT, ERROR, ("Fail to load FW image from file!\n"));
409 pvFwImageMapFile = NULL;
410 }
411 #if defined(MT6620) || defined(MT6628)
412 if (pvFwImageMapFile) {
413 /* 3.1 disable interrupt, download is done by polling mode only */
414 nicDisableInterrupt(prAdapter);
415
416 /* 3.2 Initialize Tx Resource to fw download state */
417 nicTxInitResetResource(prAdapter);
418
419 /* 3.3 FW download here */
420 u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo);
421
422 #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
423 /* 3a. parse file header for decision of divided firmware download or not */
424 prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile;
425
426 if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE &&
427 prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset,
428 u4FwImgLength - u4CRCOffset)) {
429 fgValidHead = TRUE;
430 } else {
431 fgValidHead = FALSE;
432 }
433
434 /* 3b. engage divided firmware downloading */
435 if (fgValidHead == TRUE) {
436 for (i = 0; i < prFwHead->u4NumOfEntries; i++) {
437 #if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
438 if (wlanImageSectionDownloadAggregated(prAdapter,
439 prFwHead->
440 arSection[i].
441 u4DestAddr,
442 prFwHead->
443 arSection[i].
444 u4Length,
445 (PUINT_8)
446 pvFwImageMapFile +
447 prFwHead->
448 arSection[i].
449 u4Offset) !=
450 WLAN_STATUS_SUCCESS) {
451 DBGLOG(INIT, ERROR,
452 ("Firmware scatter download failed!\n"));
453 u4Status = WLAN_STATUS_FAILURE;
454 }
455 #else
456 for (j = 0; j < prFwHead->arSection[i].u4Length;
457 j += CMD_PKT_SIZE_FOR_IMAGE) {
458 if (j + CMD_PKT_SIZE_FOR_IMAGE <
459 prFwHead->arSection[i].u4Length)
460 u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
461 else
462 u4ImgSecSize =
463 prFwHead->arSection[i].u4Length - j;
464
465 if (wlanImageSectionDownload(prAdapter,
466 prFwHead->arSection[i].
467 u4DestAddr + j,
468 u4ImgSecSize,
469 (PUINT_8)
470 pvFwImageMapFile +
471 prFwHead->arSection[i].
472 u4Offset + j) !=
473 WLAN_STATUS_SUCCESS) {
474 DBGLOG(INIT, ERROR,
475 ("Firmware scatter download failed!\n"));
476 u4Status = WLAN_STATUS_FAILURE;
477 break;
478 }
479 }
480 #endif
481 /* escape from loop if any pending error occurs */
482 if (u4Status == WLAN_STATUS_FAILURE) {
483 break;
484 }
485 }
486 } else
487 #endif
488 #if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
489 if (wlanImageSectionDownloadAggregated(prAdapter,
490 u4FwLoadAddr,
491 u4FwImgLength,
492 (PUINT_8)
493 pvFwImageMapFile) !=
494 WLAN_STATUS_SUCCESS) {
495 DBGLOG(INIT, ERROR, ("Firmware scatter download failed!\n"));
496 u4Status = WLAN_STATUS_FAILURE;
497 }
498 #else
499 for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) {
500 if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength)
501 u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
502 else
503 u4ImgSecSize = u4FwImgLength - i;
504
505 if (wlanImageSectionDownload(prAdapter,
506 u4FwLoadAddr + i,
507 u4ImgSecSize,
508 (PUINT_8) pvFwImageMapFile +
509 i) != WLAN_STATUS_SUCCESS) {
510 DBGLOG(INIT, ERROR,
511 ("wlanImageSectionDownload failed!\n"));
512 u4Status = WLAN_STATUS_FAILURE;
513 break;
514 }
515 }
516 #endif
517
518 if (u4Status != WLAN_STATUS_SUCCESS) {
519 kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle,
520 pvFwImageMapFile);
521 break;
522 }
523 #if !CFG_ENABLE_FW_DOWNLOAD_ACK
524 /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */
525 if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) {
526 kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle,
527 pvFwImageMapFile);
528 u4Status = WLAN_STATUS_FAILURE;
529 break;
530 }
531 #endif
532
533 kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle,
534 pvFwImageMapFile);
535 } else {
536 u4Status = WLAN_STATUS_FAILURE;
537 break;
538 }
539
540 /* 4. send Wi-Fi Start command */
541 #if CFG_OVERRIDE_FW_START_ADDRESS
542 wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo));
543 #else
544 wlanConfigWifiFunc(prAdapter, FALSE, 0);
545 #endif
546
547 #elif defined(MT5931)
548 if (pvFwImageMapFile) {
549 DBGLOG(INIT, TRACE,
550 ("Download Address: 0x%08X\n",
551 kalGetFwLoadAddress(prAdapter->prGlueInfo)));
552 DBGLOG(INIT, TRACE, ("Firmware Length: 0x%08X\n", u4FwImgLength));
553
554 do {
555 /* 1.0 whole-chip reset except HIFSYS */
556 HAL_MCR_WR(prAdapter, MCR_WMCSR, WMCSR_CHIP_RST);
557 HAL_MCR_WR(prAdapter, MCR_WMCSR, 0);
558
559 /* 1.1 wait for INIT_RDY */
560 i = 0;
561 while (1) {
562 HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
563
564 if (u4Value & WMCSR_INI_RDY) {
565 DBGLOG(INIT, TRACE, ("INIT-RDY detected\n"));
566 break;
567 } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
568 || fgIsBusAccessFailed == TRUE) {
569 u4Status = WLAN_STATUS_FAILURE;
570 break;
571 } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) {
572 DBGLOG(INIT, ERROR,
573 ("Waiting for Init Ready bit: Timeout\n"));
574 u4Status = WLAN_STATUS_FAILURE;
575 break;
576 } else {
577 i++;
578 kalMsleep(10);
579 }
580 }
581
582 /* 1.2 set KSEL/FLEN */
583 HAL_MCR_WR(prAdapter, MCR_FWCFG, u4FwImgLength >> 6);
584
585 /* 1.3 enable FWDL_EN */
586 HAL_MCR_WR(prAdapter, MCR_WMCSR, WMCSR_FWDLEN);
587
588 /* 1.4 wait for PLL_RDY */
589 i = 0;
590 while (1) {
591 HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
592
593 if (u4Value & WMCSR_PLLRDY) {
594 DBGLOG(INIT, TRACE, ("PLL-RDY detected\n"));
595 break;
596 } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
597 || fgIsBusAccessFailed == TRUE) {
598 u4Status = WLAN_STATUS_FAILURE;
599 break;
600 } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) {
601 DBGLOG(INIT, ERROR,
602 ("Waiting for PLL Ready bit: Timeout\n"));
603 u4Status = WLAN_STATUS_FAILURE;
604 break;
605 } else {
606 i++;
607 kalMsleep(10);
608 }
609 }
610
611 /* 2.1 turn on HIFSYS firmware download mode */
612 HAL_MCR_WR(prAdapter, MCR_FWDLSR, FWDLSR_FWDL_MODE);
613
614 /* 2.2 set starting address */
615 u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo);
616 HAL_MCR_WR(prAdapter, MCR_FWDLDSAR, u4FwLoadAddr);
617
618 /* 3. upload firmware */
619 for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) {
620 if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength)
621 u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
622 else
623 u4ImgSecSize = u4FwImgLength - i;
624
625 if (wlanImageSectionDownload(prAdapter,
626 u4FwLoadAddr + i,
627 u4ImgSecSize,
628 (PUINT_8) pvFwImageMapFile +
629 i) != WLAN_STATUS_SUCCESS) {
630 DBGLOG(INIT, ERROR,
631 ("Firmware scatter download failed!\n"));
632 u4Status = WLAN_STATUS_FAILURE;
633 break;
634 }
635 }
636
637 /* 4.1 poll FWDL_OK & FWDL_FAIL bits */
638 i = 0;
639 while (1) {
640 HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
641
642 if (u4Value & WMCSR_DL_OK) {
643 DBGLOG(INIT, TRACE, ("DL_OK detected\n"));
644 break;
645 } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
646 || fgIsBusAccessFailed == TRUE
647 || (u4Value & WMCSR_DL_FAIL)) {
648 DBGLOG(INIT, ERROR,
649 ("DL_FAIL detected: 0x%08X\n", u4Value));
650 u4Status = WLAN_STATUS_FAILURE;
651 break;
652 } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) {
653 DBGLOG(INIT, ERROR,
654 ("Waiting for DL_OK/DL_FAIL bit: Timeout\n"));
655 u4Status = WLAN_STATUS_FAILURE;
656 break;
657 } else {
658 i++;
659 kalMsleep(10);
660 }
661 }
662
663 /* 4.2 turn off HIFSYS download mode */
664 HAL_MCR_WR(prAdapter, MCR_FWDLSR, 0);
665
666 } while (FALSE);
667 } else {
668 DBGLOG(INIT, ERROR, ("No Firmware found!\n"));
669 u4Status = WLAN_STATUS_FAILURE;
670 break;
671 }
672
673 #endif
674 #endif
675
676 /* 5. check Wi-Fi FW asserts ready bit */
677 DBGLOG(INIT, TRACE, ("wlanAdapterStart(): Waiting for Ready bit..\n"));
678 i = 0;
679 while (1) {
680 HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
681
682 if (u4Value & WCIR_WLAN_READY) {
683 DBGLOG(INIT, TRACE, ("Ready bit asserted\n"));
684 break;
685 } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
686 || fgIsBusAccessFailed == TRUE) {
687 u4Status = WLAN_STATUS_FAILURE;
688 break;
689 } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) {
690 DBGLOG(INIT, ERROR, ("Waiting for Ready bit: Timeout\n"));
691 u4Status = WLAN_STATUS_FAILURE;
692 break;
693 } else {
694 i++;
695 kalMsleep(10);
696 }
697 }
698
699 #if defined(MT5931)
700 /* Acquire LP-OWN */
701 ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
702 #if !CFG_ENABLE_FULL_PM
703 nicpmSetDriverOwn(prAdapter);
704 #endif
705
706 /* 2. Initialize the Adapter */
707 if ((u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS) {
708 DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n"));
709 u4Status = WLAN_STATUS_FAILURE;
710 break;
711 }
712 #endif
713
714 if (u4Status == WLAN_STATUS_SUCCESS) {
715 /* 6.1 reset interrupt status */
716 HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8) & u4WHISR);
717 if (HAL_IS_TX_DONE_INTR(u4WHISR)) {
718 HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount);
719 }
720
721 /* 6.2 reset TX Resource for normal operation */
722 nicTxResetResource(prAdapter);
723
724 /* 6.3 Enable interrupt */
725 nicEnableInterrupt(prAdapter);
726
727 /* 6.4 Override network address */
728 wlanUpdateNetworkAddress(prAdapter);
729
730 /* 6.5 indicate disconnection as default status */
731 kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
732 WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
733 }
734
735 RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
736
737 /* MGMT Initialization */
738 nicInitMGMT(prAdapter, NULL);
739
740 } while (FALSE);
741
742 if (u4Status != WLAN_STATUS_SUCCESS) {
743 return FALSE;
744 } else {
745 return TRUE;
746 }
747 }
748
749 /*----------------------------------------------------------------------------*/
750 /*!
751 * @brief This routine is used to set ACPI power mode to D3.
752 *
753 * @param prAdapter pointer to the Adapter handler
754 *
755 * @return (none)
756 */
757 /*----------------------------------------------------------------------------*/
758 BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter)
759 {
760 UINT_32 i;
761
762 ASSERT(prAdapter);
763
764 /* 1. MGMT - unitialization */
765 nicUninitMGMT(prAdapter);
766
767 /* 2. Disable Interrupt */
768 nicDisableInterrupt(prAdapter);
769
770 /* 3. emit CMD_NIC_POWER_CTRL command packet */
771 wlanSendNicPowerCtrlCmd(prAdapter, 1);
772
773 /* 4. Clear Interrupt Status */
774 i = 0;
775 while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
776 i++;
777 };
778
779 /* 5. Remove pending TX */
780 nicTxRelease(prAdapter);
781
782 /* 5.1 clear pending Security / Management Frames */
783 kalClearSecurityFrames(prAdapter->prGlueInfo);
784 kalClearMgmtFrames(prAdapter->prGlueInfo);
785
786 /* 5.2 clear pending TX packet queued in glue layer */
787 kalFlushPendingTxPackets(prAdapter->prGlueInfo);
788
789 /* 6. Set Onwership to F/W */
790 nicpmSetFWOwn(prAdapter, FALSE);
791
792 /* 7. Set variables */
793 prAdapter->rAcpiState = ACPI_STATE_D3;
794
795 return TRUE;
796 }