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