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