f469057da479162eb885fb861b25c264b527fb83
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / 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
265 nicpmSetFWOwn (
266     IN P_ADAPTER_T prAdapter,
267     IN BOOLEAN     fgEnableGlobalInt
268     )
269 {
270     UINT_32 u4RegValue;
271
272     ASSERT(prAdapter);
273
274     if(prAdapter->fgIsFwOwn == TRUE) {
275         return;
276     }
277     else {
278         if(nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
279             // pending interrupts
280             return;
281         }
282     }
283
284     if (fgEnableGlobalInt) {
285         prAdapter->fgIsIntEnableWithLPOwnSet = TRUE;
286     }
287     else {
288         HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET);
289
290         HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
291         if(u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
292             // if set firmware own not successful (possibly pending interrupts),
293             // indicate an own clear event
294             HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
295
296             return;
297         }
298
299         prAdapter->fgIsFwOwn = TRUE;
300     }
301 }
302
303 /*----------------------------------------------------------------------------*/
304 /*!
305 * \brief This routine is used to process the POWER OFF procedure.
306 *
307 * \param[in] pvAdapter Pointer to the Adapter structure.
308 *
309 * \return (none)
310 */
311 /*----------------------------------------------------------------------------*/
312 BOOLEAN
313 nicpmSetDriverOwn (
314     IN P_ADAPTER_T prAdapter
315     )
316 {
317 #define LP_OWN_BACK_TOTAL_DELAY_MS      8192    //exponential of 2
318 #define LP_OWN_BACK_LOOP_DELAY_MS       1       //exponential of 2
319 #define LP_OWN_BACK_CLR_OWN_ITERATION   256     //exponential of 2
320
321     BOOLEAN fgStatus = TRUE;
322     UINT_32 i, u4CurrTick, u4RegValue = 0;
323
324     ASSERT(prAdapter);
325
326     if(prAdapter->fgIsFwOwn == FALSE)
327         return fgStatus;
328
329     u4CurrTick = kalGetTimeTick();
330     i = 0;
331     while(1) {
332         HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
333
334         if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
335             prAdapter->fgIsFwOwn = FALSE;
336             break;
337         }
338         else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
339                 || fgIsBusAccessFailed == TRUE
340                 || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS
341                 ||fgIsResetting ==TRUE) {
342             //ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick));
343             fgStatus = FALSE;
344             break;
345         }
346         else {
347             if((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) {
348                 /* Software get LP ownership - per 256 iterations */
349                 HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
350             }
351
352             /* Delay for LP engine to complete its operation. */
353             kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS);
354             i++;
355         }
356     }
357
358     return fgStatus;
359 }
360
361 /*----------------------------------------------------------------------------*/
362 /*!
363 * \brief This routine is used to set ACPI power mode to D0.
364 *
365 * \param[in] pvAdapter Pointer to the Adapter structure.
366 *
367 * \return (none)
368 */
369 /*----------------------------------------------------------------------------*/
370 BOOLEAN
371 nicpmSetAcpiPowerD0 (
372     IN P_ADAPTER_T prAdapter
373     )
374 {
375     WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
376     UINT_32     u4Value = 0, u4WHISR = 0;
377     UINT_8      aucTxCount[8];
378     UINT_32     i;
379 #if CFG_ENABLE_FW_DOWNLOAD
380     UINT_32     u4FwImgLength, u4FwLoadAddr, u4ImgSecSize;
381     PVOID       prFwMappingHandle;
382     PVOID       pvFwImageMapFile = NULL;
383     #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
384     UINT_32     j;
385     P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead;
386     BOOLEAN fgValidHead;
387     const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries);
388     #endif
389 #endif
390
391     DEBUGFUNC("nicpmSetAcpiPowerD0");
392
393     ASSERT(prAdapter);
394
395     do {
396         /* 0. Reset variables in ADAPTER_T */
397         prAdapter->fgIsFwOwn = TRUE;
398         prAdapter->fgWiFiInSleepyState = FALSE;
399         prAdapter->rAcpiState = ACPI_STATE_D0;
400         prAdapter->fgIsEnterD3ReqIssued = FALSE;
401
402 #if defined(MT6620) || defined(MT6628)
403         /* 1. Request Ownership to enter F/W download state */
404         ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
405     #if !CFG_ENABLE_FULL_PM
406         nicpmSetDriverOwn(prAdapter);
407     #endif
408
409         /* 2. Initialize the Adapter */
410         if ( (u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS ) {
411             DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n"));
412             u4Status = WLAN_STATUS_FAILURE;
413             break;
414         }
415 #endif
416
417     #if CFG_ENABLE_FW_DOWNLOAD
418         prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength);
419         if(!prFwMappingHandle) {
420             DBGLOG(INIT, ERROR,("Fail to load FW image from file!\n"));
421             pvFwImageMapFile = NULL;
422         }
423
424         #if defined(MT6620) || defined(MT6628)
425         if (pvFwImageMapFile) {
426             /* 3.1 disable interrupt, download is done by polling mode only */
427             nicDisableInterrupt(prAdapter);
428
429             /* 3.2 Initialize Tx Resource to fw download state */
430             nicTxInitResetResource(prAdapter);
431
432             /* 3.3 FW download here */
433             u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo);
434
435             #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
436             // 3a. parse file header for decision of divided firmware download or not
437             prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T)pvFwImageMapFile;
438
439             if(prFwHead->u4Signature == MTK_WIFI_SIGNATURE &&
440                     prFwHead->u4CRC == wlanCRC32((PUINT_8)pvFwImageMapFile + u4CRCOffset, u4FwImgLength - u4CRCOffset)) {
441                 fgValidHead = TRUE;
442             }
443             else {
444                 fgValidHead = FALSE;
445             }
446
447             /* 3b. engage divided firmware downloading */
448             if(fgValidHead == TRUE) {
449                 for(i = 0 ; i < prFwHead->u4NumOfEntries ; i++) {
450                 #if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
451                     if(wlanImageSectionDownloadAggregated(prAdapter,
452                                 prFwHead->arSection[i].u4DestAddr,
453                                 prFwHead->arSection[i].u4Length,
454                                 (PUINT_8)pvFwImageMapFile + prFwHead->arSection[i].u4Offset) != WLAN_STATUS_SUCCESS) {
455                         DBGLOG(INIT, ERROR, ("Firmware scatter download failed!\n"));
456                         u4Status = WLAN_STATUS_FAILURE;
457                     }
458                 #else
459                     for(j = 0 ; j < prFwHead->arSection[i].u4Length ; j += CMD_PKT_SIZE_FOR_IMAGE) {
460                         if(j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length)
461                             u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
462                         else
463                             u4ImgSecSize = prFwHead->arSection[i].u4Length - j;
464                         
465                         if(wlanImageSectionDownload(prAdapter,
466                                     prFwHead->arSection[i].u4DestAddr + j,
467                                     u4ImgSecSize,
468                                     (PUINT_8)pvFwImageMapFile + prFwHead->arSection[i].u4Offset + j) != WLAN_STATUS_SUCCESS) {
469                             DBGLOG(INIT, ERROR, ("Firmware scatter download failed!\n"));
470                             u4Status = WLAN_STATUS_FAILURE;
471                             break;
472                         }
473                     }
474                 #endif
475                     /* escape from loop if any pending error occurs */
476                     if(u4Status == WLAN_STATUS_FAILURE) {
477                             break;
478                     }
479                 }
480             }
481             else
482             #endif
483             #if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
484             if(wlanImageSectionDownloadAggregated(prAdapter,
485                         u4FwLoadAddr,
486                         u4FwImgLength,
487                         (PUINT_8)pvFwImageMapFile) != WLAN_STATUS_SUCCESS) {
488                 DBGLOG(INIT, ERROR, ("Firmware scatter download failed!\n"));
489                 u4Status = WLAN_STATUS_FAILURE;
490             }
491             #else
492             for (i = 0; i < u4FwImgLength ; i += CMD_PKT_SIZE_FOR_IMAGE) {
493                 if(i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength)
494                     u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
495                 else
496                     u4ImgSecSize = u4FwImgLength - i;
497
498                 if(wlanImageSectionDownload(prAdapter,
499                         u4FwLoadAddr + i,
500                         u4ImgSecSize,
501                         (PUINT_8)pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) {
502                     DBGLOG(INIT, ERROR, ("wlanImageSectionDownload failed!\n"));
503                     u4Status = WLAN_STATUS_FAILURE;
504                     break;
505                 }
506             }
507             #endif
508
509             if(u4Status != WLAN_STATUS_SUCCESS) {
510                 kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
511                 break;
512             }
513
514             #if !CFG_ENABLE_FW_DOWNLOAD_ACK
515             // Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response
516             if(wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) {
517                 kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
518                 u4Status = WLAN_STATUS_FAILURE;
519                 break;
520             }
521             #endif
522
523             kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
524         }
525         else {
526             u4Status = WLAN_STATUS_FAILURE;
527             break;
528         }
529
530         /* 4. send Wi-Fi Start command */
531             #if CFG_OVERRIDE_FW_START_ADDRESS
532         wlanConfigWifiFunc(prAdapter,
533                 TRUE,
534                 kalGetFwStartAddress(prAdapter->prGlueInfo));
535             #else
536         wlanConfigWifiFunc(prAdapter,
537                 FALSE,
538                 0);
539             #endif
540
541         #elif defined(MT5931)
542         if (pvFwImageMapFile) {
543             DBGLOG(INIT, TRACE, ("Download Address: 0x%08X\n", kalGetFwLoadAddress(prAdapter->prGlueInfo)));
544             DBGLOG(INIT, TRACE, ("Firmware Length:  0x%08X\n", u4FwImgLength));
545
546             do {
547                 /* 1.0 whole-chip reset except HIFSYS */
548                 HAL_MCR_WR(prAdapter, MCR_WMCSR, WMCSR_CHIP_RST);
549                 HAL_MCR_WR(prAdapter, MCR_WMCSR, 0);
550
551                 /* 1.1 wait for INIT_RDY */
552                 i = 0;
553                 while(1) {
554                     HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
555
556                     if (u4Value & WMCSR_INI_RDY) {
557                         DBGLOG(INIT, TRACE, ("INIT-RDY detected\n"));
558                         break;
559                     }
560                     else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
561                             || fgIsBusAccessFailed == TRUE) {
562                         u4Status = WLAN_STATUS_FAILURE;
563                         break;
564                     }
565                     else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) {
566                         DBGLOG(INIT, ERROR, ("Waiting for Init Ready bit: Timeout\n"));
567                         u4Status = WLAN_STATUS_FAILURE;
568                         break;
569                     }
570                     else {
571                         i++;
572                         kalMsleep(10);
573                     }
574                 }
575
576                 /* 1.2 set KSEL/FLEN */
577                 HAL_MCR_WR(prAdapter, MCR_FWCFG, u4FwImgLength >> 6);
578
579                 /* 1.3 enable FWDL_EN */
580                 HAL_MCR_WR(prAdapter, MCR_WMCSR, WMCSR_FWDLEN);
581
582                 /* 1.4 wait for PLL_RDY */
583                 i = 0;
584                 while(1) {
585                     HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
586
587                     if (u4Value & WMCSR_PLLRDY) {
588                         DBGLOG(INIT, TRACE, ("PLL-RDY detected\n"));
589                         break;
590                     }
591                     else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
592                             || fgIsBusAccessFailed == TRUE) {
593                         u4Status = WLAN_STATUS_FAILURE;
594                         break;
595                     }
596                     else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) {
597                         DBGLOG(INIT, ERROR, ("Waiting for PLL Ready bit: Timeout\n"));
598                         u4Status = WLAN_STATUS_FAILURE;
599                         break;
600                     }
601                     else {
602                         i++;
603                         kalMsleep(10);
604                     }
605                 }
606
607                 /* 2.1 turn on HIFSYS firmware download mode */
608                 HAL_MCR_WR(prAdapter, MCR_FWDLSR, FWDLSR_FWDL_MODE);
609
610                 /* 2.2 set starting address */
611                 u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo);
612                 HAL_MCR_WR(prAdapter, MCR_FWDLDSAR, u4FwLoadAddr);
613
614                 /* 3. upload firmware */
615                 for (i = 0; i < u4FwImgLength ; i += CMD_PKT_SIZE_FOR_IMAGE) {
616                     if(i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength)
617                         u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
618                     else
619                         u4ImgSecSize = u4FwImgLength - i;
620
621                     if(wlanImageSectionDownload(prAdapter,
622                                 u4FwLoadAddr + i,
623                                 u4ImgSecSize,
624                                 (PUINT_8)pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) {
625                         DBGLOG(INIT, ERROR, ("Firmware scatter download failed!\n"));
626                         u4Status = WLAN_STATUS_FAILURE;
627                         break;
628                     }
629                 }
630
631                 /* 4.1 poll FWDL_OK & FWDL_FAIL bits */
632                 i = 0;
633                 while(1) {
634                     HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
635
636                     if (u4Value & WMCSR_DL_OK) {
637                         DBGLOG(INIT, TRACE, ("DL_OK detected\n"));
638                         break;
639                     }
640                     else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
641                             || fgIsBusAccessFailed == TRUE
642                             || (u4Value & WMCSR_DL_FAIL)) {
643                         DBGLOG(INIT, ERROR, ("DL_FAIL detected: 0x%08X\n", u4Value));
644                         u4Status = WLAN_STATUS_FAILURE;
645                         break;
646                     }
647                     else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) {
648                         DBGLOG(INIT, ERROR, ("Waiting for DL_OK/DL_FAIL bit: Timeout\n"));
649                         u4Status = WLAN_STATUS_FAILURE;
650                         break;
651                     }
652                     else {
653                         i++;
654                         kalMsleep(10);
655                     }
656                 }
657
658                 /* 4.2 turn off HIFSYS download mode */
659                 HAL_MCR_WR(prAdapter, MCR_FWDLSR, 0);
660
661             } while (FALSE);
662         }
663         else {
664             DBGLOG(INIT, ERROR, ("No Firmware found!\n"));
665             u4Status = WLAN_STATUS_FAILURE;
666             break;
667         }
668
669         #endif
670     #endif
671
672         /* 5. check Wi-Fi FW asserts ready bit */
673         DBGLOG(INIT, TRACE, ("wlanAdapterStart(): Waiting for Ready bit..\n"));
674         i = 0;
675         while(1) {
676             HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
677
678             if (u4Value & WCIR_WLAN_READY) {
679                 DBGLOG(INIT, TRACE, ("Ready bit asserted\n"));
680                 break;
681             }
682             else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
683                     || fgIsBusAccessFailed == TRUE) {
684                 u4Status = WLAN_STATUS_FAILURE;
685                 break;
686             }
687             else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) {
688                 DBGLOG(INIT, ERROR, ("Waiting for Ready bit: Timeout\n"));
689                 u4Status = WLAN_STATUS_FAILURE;
690                 break;
691             }
692             else {
693                 i++;
694                 kalMsleep(10);
695             }
696         }
697
698 #if defined(MT5931)
699         // Acquire LP-OWN
700         ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
701     #if !CFG_ENABLE_FULL_PM
702         nicpmSetDriverOwn(prAdapter);
703     #endif
704
705         /* 2. Initialize the Adapter */
706         if ( (u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS ) {
707             DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n"));
708             u4Status = WLAN_STATUS_FAILURE;
709             break;
710         }
711 #endif
712
713         if(u4Status == WLAN_STATUS_SUCCESS) {
714             // 6.1 reset interrupt status
715             HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR);
716             if(HAL_IS_TX_DONE_INTR(u4WHISR)) {
717                 HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount);
718             }
719
720             /* 6.2 reset TX Resource for normal operation */
721             nicTxResetResource(prAdapter);
722
723             /* 6.3 Enable interrupt */
724             nicEnableInterrupt(prAdapter);
725
726             /* 6.4 Override network address */
727             wlanUpdateNetworkAddress(prAdapter);
728
729             /* 6.5 indicate disconnection as default status */
730             kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
731                     WLAN_STATUS_MEDIA_DISCONNECT,
732                     NULL,
733                     0);
734         }
735
736         RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
737
738         /* MGMT Initialization */
739         nicInitMGMT(prAdapter, NULL);
740
741     } while(FALSE);
742
743     if(u4Status != WLAN_STATUS_SUCCESS) {
744         return FALSE;
745     }
746     else {
747         return TRUE;
748     }
749 }
750
751 /*----------------------------------------------------------------------------*/
752 /*!
753 * @brief This routine is used to set ACPI power mode to D3.
754 *
755 * @param prAdapter pointer to the Adapter handler
756 *
757 * @return (none)
758 */
759 /*----------------------------------------------------------------------------*/
760 BOOLEAN
761 nicpmSetAcpiPowerD3 (
762     IN P_ADAPTER_T prAdapter
763     )
764 {
765     UINT_32 i;
766
767     ASSERT(prAdapter);
768
769     /* 1. MGMT - unitialization */
770     nicUninitMGMT(prAdapter);
771
772     /* 2. Disable Interrupt */
773     nicDisableInterrupt(prAdapter);
774
775     /* 3. emit CMD_NIC_POWER_CTRL command packet */
776     wlanSendNicPowerCtrlCmd(prAdapter, 1);
777
778     /* 4. Clear Interrupt Status */
779     i = 0;
780     while(i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
781         i++;
782     };
783
784     /* 5. Remove pending TX */
785     nicTxRelease(prAdapter);
786
787     // 5.1 clear pending Security / Management Frames
788     kalClearSecurityFrames(prAdapter->prGlueInfo);
789     kalClearMgmtFrames(prAdapter->prGlueInfo);
790
791     // 5.2 clear pending TX packet queued in glue layer
792     kalFlushPendingTxPackets(prAdapter->prGlueInfo);
793
794     /* 6. Set Onwership to F/W */
795     nicpmSetFWOwn(prAdapter, FALSE);
796
797     /* 7. Set variables */
798     prAdapter->rAcpiState = ACPI_STATE_D3;
799
800     return TRUE;
801 }
802