nic_pwr_mgt.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. /*
  2. ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_pwr_mgt.c#1
  3. */
  4. /*! \file "nic_pwr_mgt.c"
  5. \brief In this file we define the STATE and EVENT for Power Management FSM.
  6. The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter
  7. ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail
  8. description.
  9. */
  10. /*
  11. ** Log: nic_pwr_mgt.c
  12. **
  13. ** 06 19 2013 cp.wu
  14. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  15. ** update MAC address handling logic
  16. **
  17. ** 02 06 2013 cp.wu
  18. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  19. ** add reset option for firmware download configuration
  20. **
  21. ** 02 01 2013 cp.wu
  22. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  23. ** 1. eliminate MT5931/MT6620/MT6628 logic
  24. ** 2. add firmware download control sequence
  25. **
  26. ** 10 25 2012 cp.wu
  27. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  28. ** sync with MT6630 HIFSYS update.
  29. **
  30. ** 09 17 2012 cm.chang
  31. ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
  32. ** Duplicate source from MT6620 v2.3 driver branch
  33. ** (Davinci label: MT6620_WIFI_Driver_V2_3_120913_1942_As_MT6630_Base)
  34. *
  35. * 11 28 2011 cp.wu
  36. * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when
  37. * returining to ROM code
  38. * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware
  39. * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not
  40. *
  41. * 10 03 2011 cp.wu
  42. * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
  43. * add firmware download path in divided scatters.
  44. *
  45. * 08 15 2011 cp.wu
  46. * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
  47. * reuse firmware download logic of MT6620 for MT6628.
  48. *
  49. * 05 11 2011 cp.wu
  50. * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
  51. * ACPI APIs migrate to wlan_lib.c for glue layer to invoke.
  52. *
  53. * 04 29 2011 cp.wu
  54. * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h)
  55. * fix for compilation error when applied with FW_DOWNLOAD = 0
  56. *
  57. * 04 18 2011 cp.wu
  58. * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h)
  59. * 1) add API for glue layer to query ACPI state
  60. * 2) Windows glue should not access to hardware after switched into D3 state
  61. *
  62. * 04 13 2011 cp.wu
  63. * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete
  64. * refine for MT5931/MT6620 logic separation.
  65. *
  66. * 04 13 2011 cp.wu
  67. * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete
  68. * bugfix: firmware download procedure for ACPI state transition is not complete.
  69. *
  70. * 03 15 2011 cp.wu
  71. * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
  72. * memory consumption
  73. * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
  74. * 2. Use common coalescing buffer for both TX/RX directions
  75. *
  76. *
  77. * 03 07 2011 terry.wu
  78. * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
  79. * Toggle non-standard debug messages to comments.
  80. *
  81. * 12 31 2010 cp.wu
  82. * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system
  83. * scheduling
  84. * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being
  85. * loaded
  86. *
  87. * 12 31 2010 cp.wu
  88. * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
  89. * check success or failure for setting fw-own
  90. *
  91. * 12 30 2010 cp.wu
  92. * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
  93. * host driver not to set FW-own when there is still pending interrupts
  94. *
  95. * 10 07 2010 cp.wu
  96. * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
  97. * add firmware download for MT5931.
  98. *
  99. * 09 21 2010 cp.wu
  100. * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS
  101. * associated
  102. * Do a complete reset with STA-REC null checking for RF test re-entry
  103. *
  104. * 08 30 2010 cp.wu
  105. * NULL
  106. * eliminate klockwork errors
  107. *
  108. * 08 30 2010 cp.wu
  109. * NULL
  110. * reset ACPI power state before waking up MT6620 Wi-Fi firmware.
  111. *
  112. * 08 12 2010 cp.wu
  113. * NULL
  114. * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G)
  115. *
  116. * 08 03 2010 cp.wu
  117. * NULL
  118. * Centralize mgmt/system service procedures into independent calls.
  119. *
  120. * 07 22 2010 cp.wu
  121. *
  122. * 1) refine AIS-FSM indent.
  123. * 2) when entering RF Test mode, flush 802.1X frames as well
  124. * 3) when entering D3 state, flush 802.1X frames as well
  125. *
  126. * 07 08 2010 cp.wu
  127. *
  128. * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
  129. *
  130. * 06 21 2010 cp.wu
  131. * [WPD00003833][MT6620 and MT5931] Driver migration
  132. * change MAC address updating logic.
  133. *
  134. * 06 06 2010 kevin.huang
  135. * [WPD00003832][MT6620 5931] Create driver base
  136. * [MT6620 5931] Create driver base
  137. *
  138. * 05 24 2010 cp.wu
  139. * [WPD00001943]Create WiFi test driver framework on WinXP
  140. * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll
  141. * 2) correct address list parsing
  142. *
  143. * 05 22 2010 cp.wu
  144. * [WPD00001943]Create WiFi test driver framework on WinXP
  145. * sleepy notify is only used for sleepy state,
  146. * while wake-up state is automatically set when host needs to access device
  147. *
  148. * 05 19 2010 cp.wu
  149. * [WPD00001943]Create WiFi test driver framework on WinXP
  150. * correct hibernation problem.
  151. *
  152. * 04 26 2010 cp.wu
  153. * [WPD00001943]Create WiFi test driver framework on WinXP
  154. * 1) surpress compiler warning
  155. * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet
  156. *
  157. * 04 23 2010 cp.wu
  158. * [WPD00001943]Create WiFi test driver framework on WinXP
  159. * surpress compiler warning
  160. *
  161. * 04 22 2010 cp.wu
  162. * [WPD00001943]Create WiFi test driver framework on WinXP
  163. * when acquiring driver-own, wait for up to 8 seconds.
  164. *
  165. * 04 21 2010 jeffrey.chang
  166. * [WPD00003826]Initial import for Linux port
  167. * add for private ioctl support
  168. *
  169. * 04 20 2010 cp.wu
  170. * [WPD00001943]Create WiFi test driver framework on WinXP
  171. * 1) remove redundant firmware image unloading
  172. * * 2) use compile-time macros to separate logic related to accquiring own
  173. *
  174. * 04 16 2010 cp.wu
  175. * [WPD00001943]Create WiFi test driver framework on WinXP
  176. * treat BUS access failure as kind of card removal.
  177. *
  178. * 04 07 2010 cp.wu
  179. * [WPD00001943]Create WiFi test driver framework on WinXP
  180. * accessing to firmware load/start address, and access to OID handling information
  181. * * are now handled in glue layer
  182. *
  183. * 04 06 2010 cp.wu
  184. * [WPD00001943]Create WiFi test driver framework on WinXP
  185. * ePowerCtrl is not necessary as a glue variable.
  186. *
  187. * 04 06 2010 cp.wu
  188. * [WPD00001943]Create WiFi test driver framework on WinXP
  189. * add KAL API: kalFlushPendingTxPackets(), and take use of the API
  190. *
  191. * 04 06 2010 cp.wu
  192. * [WPD00001943]Create WiFi test driver framework on WinXP
  193. * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
  194. *
  195. * 03 24 2010 jeffrey.chang
  196. * [WPD00003826]Initial import for Linux port
  197. * initial import for Linux port
  198. *
  199. * 03 22 2010 cp.wu
  200. * [WPD00001943]Create WiFi test driver framework on WinXP
  201. * always send CMD_NIC_POWER_CTRL packet when nic is being halted
  202. *
  203. * 03 19 2010 cp.wu
  204. * [WPD00001943]Create WiFi test driver framework on WinXP
  205. * correct typo.
  206. *
  207. * 03 19 2010 cp.wu
  208. * [WPD00001943]Create WiFi test driver framework on WinXP
  209. * 1) add ACPI D0/D3 state switching support
  210. * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX
  211. * response
  212. *
  213. * 03 08 2010 cp.wu
  214. * [WPD00001943]Create WiFi test driver framework on WinXP
  215. * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread.
  216. * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds
  217. ** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-13 21:59:15 GMT mtk01084
  218. ** update for new HW design
  219. ** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-09-09 17:26:36 GMT mtk01084
  220. ** remove CMD52 access
  221. ** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-18 14:50:29 GMT mtk01084
  222. ** modify lines in nicpmSetDriverOwn()
  223. ** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:55:37 GMT mtk01084
  224. ** modify nicpmSetDriverOwn()
  225. ** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:33:00 GMT mtk01084
  226. ** update for basic power management functions
  227. ** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:32 GMT mtk01084
  228. ** Initial version
  229. **
  230. */
  231. /*******************************************************************************
  232. * C O M P I L E R F L A G S
  233. ********************************************************************************
  234. */
  235. /*******************************************************************************
  236. * E X T E R N A L R E F E R E N C E S
  237. ********************************************************************************
  238. */
  239. #include "precomp.h"
  240. /*******************************************************************************
  241. * C O N S T A N T S
  242. ********************************************************************************
  243. */
  244. /*******************************************************************************
  245. * D A T A T Y P E S
  246. ********************************************************************************
  247. */
  248. /*******************************************************************************
  249. * P U B L I C D A T A
  250. ********************************************************************************
  251. */
  252. /*******************************************************************************
  253. * P R I V A T E D A T A
  254. ********************************************************************************
  255. */
  256. /*******************************************************************************
  257. * M A C R O S
  258. ********************************************************************************
  259. */
  260. /*******************************************************************************
  261. * F U N C T I O N D E C L A R A T I O N S
  262. ********************************************************************************
  263. */
  264. /*******************************************************************************
  265. * F U N C T I O N S
  266. ********************************************************************************
  267. */
  268. /*----------------------------------------------------------------------------*/
  269. /*!
  270. * \brief This routine is used to process the POWER ON procedure.
  271. *
  272. * \param[in] pvAdapter Pointer to the Adapter structure.
  273. *
  274. * \return (none)
  275. */
  276. /*----------------------------------------------------------------------------*/
  277. VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt)
  278. {
  279. UINT_32 u4RegValue;
  280. ASSERT(prAdapter);
  281. if (prAdapter->fgIsFwOwn == TRUE)
  282. return;
  283. if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
  284. DBGLOG(NIC, INFO, "FW OWN Failed due to pending INT\n");
  285. /* pending interrupts */
  286. return;
  287. }
  288. if (fgEnableGlobalInt) {
  289. DBGLOG(NIC, INFO, "FW OWN, fgEnableGlobalInt=TRUE\n");
  290. prAdapter->fgIsIntEnableWithLPOwnSet = TRUE;
  291. return;
  292. }
  293. HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET);
  294. HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
  295. if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
  296. /* if set firmware own not successful (possibly pending interrupts), */
  297. /* indicate an own clear event */
  298. HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
  299. DBGLOG(NIC, INFO, "FW OWN fail\n");
  300. return;
  301. }
  302. prAdapter->fgIsFwOwn = TRUE;
  303. DBGLOG(NIC, INFO, "FW OWN\n");
  304. }
  305. VOID nicPmTriggerDriverOwn(IN P_ADAPTER_T prAdapter)
  306. {
  307. UINT_32 u4RegValue = 0;
  308. HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
  309. if (u4RegValue & WHLPCR_FW_OWN_REQ_SET)
  310. prAdapter->fgIsFwOwn = FALSE;
  311. else
  312. HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
  313. }
  314. /*----------------------------------------------------------------------------*/
  315. /*!
  316. * \brief This routine is used to process the POWER OFF procedure.
  317. *
  318. * \param[in] pvAdapter Pointer to the Adapter structure.
  319. *
  320. * \return (none)
  321. */
  322. /*----------------------------------------------------------------------------*/
  323. BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter)
  324. {
  325. #define LP_OWN_BACK_TOTAL_DELAY_MS 2048 /* exponential of 2 */
  326. #define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */
  327. #define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */
  328. #define LP_OWN_BACK_FAILED_RETRY_CNT 5
  329. #define LP_OWN_BACK_FAILED_LOG_SKIP_MS 2000
  330. #define LP_OWN_BACK_FAILED_RESET_CNT 5
  331. BOOLEAN fgStatus = TRUE;
  332. UINT_32 i, u4CurrTick, u4RegValue = 0;
  333. BOOLEAN fgTimeout;
  334. ASSERT(prAdapter);
  335. if (prAdapter->fgIsFwOwn == FALSE)
  336. return fgStatus;
  337. DBGLOG(INIT, INFO, "DRIVER OWN\n");
  338. u4CurrTick = kalGetTimeTick();
  339. i = 0;
  340. while (1) {
  341. HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
  342. fgTimeout = ((kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS) ? TRUE : FALSE;
  343. if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
  344. prAdapter->fgIsFwOwn = FALSE;
  345. prAdapter->u4OwnFailedCount = 0;
  346. prAdapter->u4OwnFailedLogCount = 0;
  347. break;
  348. } else if ((i > LP_OWN_BACK_FAILED_RETRY_CNT) &&
  349. (kalIsCardRemoved(prAdapter->prGlueInfo) || fgIsBusAccessFailed || fgTimeout
  350. || wlanIsChipNoAck(prAdapter))) {
  351. if ((prAdapter->u4OwnFailedCount == 0) ||
  352. CHECK_FOR_TIMEOUT(u4CurrTick, prAdapter->rLastOwnFailedLogTime,
  353. MSEC_TO_SYSTIME(LP_OWN_BACK_FAILED_LOG_SKIP_MS))) {
  354. DBGLOG(NIC, ERROR,
  355. "LP fail, Timeout(%ums) Bus Error[%u] Resetting[%u] NoAck[%u] Cnt[%u]",
  356. kalGetTimeTick() - u4CurrTick, fgIsBusAccessFailed, kalIsResetting(),
  357. wlanIsChipNoAck(prAdapter), prAdapter->u4OwnFailedCount);
  358. prAdapter->u4OwnFailedLogCount++;
  359. if (prAdapter->u4OwnFailedLogCount > LP_OWN_BACK_FAILED_RESET_CNT) {
  360. /* Trigger RESET */
  361. #if CFG_CHIP_RESET_SUPPORT
  362. glResetTrigger(prAdapter);
  363. #endif
  364. }
  365. GET_CURRENT_SYSTIME(&prAdapter->rLastOwnFailedLogTime);
  366. }
  367. prAdapter->u4OwnFailedCount++;
  368. fgStatus = FALSE;
  369. break;
  370. }
  371. if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) {
  372. /* Software get LP ownership - per 256 iterations */
  373. HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
  374. }
  375. /* Delay for LP engine to complete its operation. */
  376. kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS);
  377. i++;
  378. }
  379. DBGLOG(NIC, INFO, "DRIVER OWN, status=%d\n", fgStatus);
  380. return fgStatus;
  381. }
  382. /*----------------------------------------------------------------------------*/
  383. /*!
  384. * \brief This routine is used to set ACPI power mode to D0.
  385. *
  386. * \param[in] pvAdapter Pointer to the Adapter structure.
  387. *
  388. * \return (none)
  389. */
  390. /*----------------------------------------------------------------------------*/
  391. BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter)
  392. {
  393. WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
  394. UINT_32 u4Value = 0, u4WHISR = 0;
  395. UINT_16 au2TxCount[16];
  396. UINT_32 i;
  397. #if CFG_ENABLE_FW_DOWNLOAD
  398. UINT_32 u4FwImgLength, u4FwLoadAddr;
  399. PVOID prFwMappingHandle;
  400. PVOID pvFwImageMapFile = NULL;
  401. #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
  402. P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead;
  403. BOOLEAN fgValidHead;
  404. const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries);
  405. #endif
  406. #endif
  407. DEBUGFUNC("nicpmSetAcpiPowerD0");
  408. ASSERT(prAdapter);
  409. do {
  410. /* 0. Reset variables in ADAPTER_T */
  411. prAdapter->fgIsFwOwn = TRUE;
  412. prAdapter->fgWiFiInSleepyState = FALSE;
  413. prAdapter->rAcpiState = ACPI_STATE_D0;
  414. prAdapter->fgIsEnterD3ReqIssued = FALSE;
  415. #if defined(MT6630)
  416. /* 1. Request Ownership to enter F/W download state */
  417. ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
  418. #if !CFG_ENABLE_FULL_PM
  419. nicpmSetDriverOwn(prAdapter);
  420. #endif
  421. /* 2. Initialize the Adapter */
  422. u4Status = nicInitializeAdapter(prAdapter);
  423. if (u4Status != WLAN_STATUS_SUCCESS) {
  424. DBGLOG(NIC, ERROR, "nicInitializeAdapter failed!\n");
  425. u4Status = WLAN_STATUS_FAILURE;
  426. break;
  427. }
  428. #endif
  429. #if CFG_ENABLE_FW_DOWNLOAD
  430. prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength);
  431. if (!prFwMappingHandle) {
  432. DBGLOG(NIC, ERROR, "Fail to load FW image from file!\n");
  433. pvFwImageMapFile = NULL;
  434. }
  435. #if defined(MT6630)
  436. if (pvFwImageMapFile) {
  437. /* 3.1 disable interrupt, download is done by polling mode only */
  438. nicDisableInterrupt(prAdapter);
  439. /* 3.2 Initialize Tx Resource to fw download state */
  440. nicTxInitResetResource(prAdapter);
  441. /* 3.3 FW download here */
  442. u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo);
  443. #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
  444. /* 3a. parse file header for decision of divided firmware download or not */
  445. prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile;
  446. if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE &&
  447. prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset,
  448. u4FwImgLength - u4CRCOffset)) {
  449. fgValidHead = TRUE;
  450. } else {
  451. fgValidHead = FALSE;
  452. }
  453. /* 3b. engage divided firmware downloading */
  454. if (fgValidHead == TRUE) {
  455. wlanFwDvdDwnloadHandler(prAdapter, prFwHead, pvFwImageMapFile, &u4Status);
  456. } else
  457. #endif
  458. {
  459. if (wlanImageSectionConfig(prAdapter,
  460. u4FwLoadAddr, u4FwImgLength, TRUE) != WLAN_STATUS_SUCCESS) {
  461. DBGLOG(NIC, ERROR, "Firmware download configuration failed!\n");
  462. u4Status = WLAN_STATUS_FAILURE;
  463. break;
  464. }
  465. wlanFwDwnloadHandler(prAdapter, u4FwImgLength, pvFwImageMapFile, &u4Status);
  466. }
  467. /* escape to top */
  468. if (u4Status != WLAN_STATUS_SUCCESS) {
  469. kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
  470. break;
  471. }
  472. #if !CFG_ENABLE_FW_DOWNLOAD_ACK
  473. /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */
  474. if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) {
  475. kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
  476. u4Status = WLAN_STATUS_FAILURE;
  477. break;
  478. }
  479. #endif
  480. kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
  481. } else {
  482. u4Status = WLAN_STATUS_FAILURE;
  483. break;
  484. }
  485. /* 4. send Wi-Fi Start command */
  486. #if CFG_OVERRIDE_FW_START_ADDRESS
  487. wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo));
  488. #else
  489. wlanConfigWifiFunc(prAdapter, FALSE, 0);
  490. #endif
  491. #endif
  492. #endif
  493. /* 5. check Wi-Fi FW asserts ready bit */
  494. DBGLOG(NIC, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n");
  495. i = 0;
  496. while (1) {
  497. HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
  498. if (u4Value & WCIR_WLAN_READY) {
  499. DBGLOG(NIC, TRACE, "Ready bit asserted\n");
  500. break;
  501. } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
  502. u4Status = WLAN_STATUS_FAILURE;
  503. break;
  504. } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) {
  505. DBGLOG(NIC, ERROR, "Waiting for Ready bit: Timeout\n");
  506. u4Status = WLAN_STATUS_FAILURE;
  507. break;
  508. }
  509. i++;
  510. kalMsleep(10);
  511. }
  512. if (u4Status == WLAN_STATUS_SUCCESS) {
  513. /* 6.1 reset interrupt status */
  514. HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR);
  515. if (HAL_IS_TX_DONE_INTR(u4WHISR))
  516. HAL_READ_TX_RELEASED_COUNT(prAdapter, au2TxCount);
  517. /* 6.2 reset TX Resource for normal operation */
  518. nicTxResetResource(prAdapter);
  519. /* 6.3 Enable interrupt */
  520. nicEnableInterrupt(prAdapter);
  521. /* 6.4 Update basic configuration */
  522. wlanUpdateBasicConfig(prAdapter);
  523. /* 6.5 Apply Network Address */
  524. nicApplyNetworkAddress(prAdapter);
  525. /* 6.6 indicate disconnection as default status */
  526. kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
  527. }
  528. RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
  529. /* MGMT Initialization */
  530. nicInitMGMT(prAdapter, NULL);
  531. } while (FALSE);
  532. if (u4Status != WLAN_STATUS_SUCCESS)
  533. return FALSE;
  534. else
  535. return TRUE;
  536. }
  537. /*----------------------------------------------------------------------------*/
  538. /*!
  539. * @brief This routine is used to set ACPI power mode to D3.
  540. *
  541. * @param prAdapter pointer to the Adapter handler
  542. *
  543. * @return (none)
  544. */
  545. /*----------------------------------------------------------------------------*/
  546. BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter)
  547. {
  548. UINT_32 i;
  549. ASSERT(prAdapter);
  550. /* 1. MGMT - unitialization */
  551. nicUninitMGMT(prAdapter);
  552. /* 2. Disable Interrupt */
  553. nicDisableInterrupt(prAdapter);
  554. /* 3. emit CMD_NIC_POWER_CTRL command packet */
  555. wlanSendNicPowerCtrlCmd(prAdapter, 1);
  556. /* 4. Clear Interrupt Status */
  557. i = 0;
  558. while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
  559. i++;
  560. };
  561. /* 5. Remove pending TX */
  562. nicTxRelease(prAdapter, TRUE);
  563. /* 5.1 clear pending Security / Management Frames */
  564. kalClearSecurityFrames(prAdapter->prGlueInfo);
  565. kalClearMgmtFrames(prAdapter->prGlueInfo);
  566. /* 5.2 clear pending TX packet queued in glue layer */
  567. kalFlushPendingTxPackets(prAdapter->prGlueInfo);
  568. /* 6. Set Onwership to F/W */
  569. nicpmSetFWOwn(prAdapter, FALSE);
  570. /* 7. Set variables */
  571. prAdapter->rAcpiState = ACPI_STATE_D3;
  572. return TRUE;
  573. }