nic_pwr_mgt.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  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. * 11 28 2011 cp.wu
  14. * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when
  15. * returining to ROM code
  16. * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware
  17. * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not
  18. *
  19. * 10 03 2011 cp.wu
  20. * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
  21. * add firmware download path in divided scatters.
  22. *
  23. * 08 15 2011 cp.wu
  24. * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
  25. * reuse firmware download logic of MT6620 for MT6628.
  26. *
  27. * 05 11 2011 cp.wu
  28. * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
  29. * ACPI APIs migrate to wlan_lib.c for glue layer to invoke.
  30. *
  31. * 04 29 2011 cp.wu
  32. * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h)
  33. * fix for compilation error when applied with FW_DOWNLOAD = 0
  34. *
  35. * 04 18 2011 cp.wu
  36. * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h)
  37. * 1) add API for glue layer to query ACPI state
  38. * 2) Windows glue should not access to hardware after switched into D3 state
  39. *
  40. * 04 13 2011 cp.wu
  41. * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete
  42. * refine for MT5931/MT6620 logic separation.
  43. *
  44. * 04 13 2011 cp.wu
  45. * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete
  46. * bugfix: firmware download procedure for ACPI state transition is not complete.
  47. *
  48. * 03 15 2011 cp.wu
  49. * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
  50. * memory consumption
  51. * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
  52. * 2. Use common coalescing buffer for both TX/RX directions
  53. *
  54. *
  55. * 03 07 2011 terry.wu
  56. * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
  57. * Toggle non-standard debug messages to comments.
  58. *
  59. * 12 31 2010 cp.wu
  60. * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system
  61. * scheduling
  62. * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being
  63. * loaded
  64. *
  65. * 12 31 2010 cp.wu
  66. * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
  67. * check success or failure for setting fw-own
  68. *
  69. * 12 30 2010 cp.wu
  70. * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
  71. * host driver not to set FW-own when there is still pending interrupts
  72. *
  73. * 10 07 2010 cp.wu
  74. * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
  75. * add firmware download for MT5931.
  76. *
  77. * 09 21 2010 cp.wu
  78. * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS
  79. * 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
  189. * response
  190. *
  191. * 03 08 2010 cp.wu
  192. * [WPD00001943]Create WiFi test driver framework on WinXP
  193. * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread.
  194. * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds
  195. ** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-13 21:59:15 GMT mtk01084
  196. ** update for new HW design
  197. ** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-09-09 17:26:36 GMT mtk01084
  198. ** remove CMD52 access
  199. ** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-18 14:50:29 GMT mtk01084
  200. ** modify lines in nicpmSetDriverOwn()
  201. ** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:55:37 GMT mtk01084
  202. ** modify nicpmSetDriverOwn()
  203. ** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:33:00 GMT mtk01084
  204. ** update for basic power management functions
  205. ** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:32 GMT mtk01084
  206. ** Initial version
  207. **
  208. */
  209. /*******************************************************************************
  210. * C O M P I L E R F L A G S
  211. ********************************************************************************
  212. */
  213. /*******************************************************************************
  214. * E X T E R N A L R E F E R E N C E S
  215. ********************************************************************************
  216. */
  217. #include "precomp.h"
  218. /*******************************************************************************
  219. * C O N S T A N T S
  220. ********************************************************************************
  221. */
  222. /*******************************************************************************
  223. * D A T A T Y P E S
  224. ********************************************************************************
  225. */
  226. /*******************************************************************************
  227. * P U B L I C D A T A
  228. ********************************************************************************
  229. */
  230. /*******************************************************************************
  231. * P R I V A T E D A T A
  232. ********************************************************************************
  233. */
  234. /*******************************************************************************
  235. * M A C R O S
  236. ********************************************************************************
  237. */
  238. /*******************************************************************************
  239. * F U N C T I O N D E C L A R A T I O N S
  240. ********************************************************************************
  241. */
  242. /*******************************************************************************
  243. * F U N C T I O N S
  244. ********************************************************************************
  245. */
  246. /*----------------------------------------------------------------------------*/
  247. /*!
  248. * \brief This routine is used to process the POWER ON procedure.
  249. *
  250. * \param[in] pvAdapter Pointer to the Adapter structure.
  251. *
  252. * \return (none)
  253. */
  254. /*----------------------------------------------------------------------------*/
  255. VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt)
  256. {
  257. UINT_32 u4RegValue = 0;
  258. ASSERT(prAdapter);
  259. if (prAdapter->fgIsFwOwn == TRUE)
  260. return;
  261. if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
  262. /* pending interrupts */
  263. return;
  264. }
  265. if (fgEnableGlobalInt) {
  266. prAdapter->fgIsIntEnableWithLPOwnSet = TRUE;
  267. } else {
  268. HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET);
  269. HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
  270. if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
  271. /* if set firmware own not successful (possibly pending interrupts), */
  272. /* indicate an own clear event */
  273. HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
  274. return;
  275. }
  276. prAdapter->fgIsFwOwn = TRUE;
  277. }
  278. }
  279. /*----------------------------------------------------------------------------*/
  280. /*!
  281. * \brief This routine is used to process the POWER OFF procedure.
  282. *
  283. * \param[in] pvAdapter Pointer to the Adapter structure.
  284. *
  285. * \return (none)
  286. */
  287. /*----------------------------------------------------------------------------*/
  288. UINT_32 u4OriRegValue = 0;
  289. BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter)
  290. {
  291. #define LP_OWN_BACK_TOTAL_DELAY_MS 2000 /* exponential of 2 */
  292. #define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */
  293. #define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */
  294. BOOLEAN fgStatus = TRUE;
  295. UINT_32 i, u4CurrTick;
  296. UINT_32 u4RegValue = 0;
  297. GL_HIF_INFO_T *HifInfo;
  298. ASSERT(prAdapter);
  299. if (prAdapter->fgIsFwOwn == FALSE)
  300. return fgStatus;
  301. HifInfo = &prAdapter->prGlueInfo->rHifInfo;
  302. u4CurrTick = kalGetTimeTick();
  303. STATS_DRIVER_OWN_START_RECORD();
  304. i = 0;
  305. while (1) {
  306. HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
  307. if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
  308. HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue);
  309. prAdapter->fgIsFwOwn = FALSE;
  310. break;
  311. } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
  312. || fgIsBusAccessFailed == TRUE
  313. || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS || fgIsResetting == TRUE) {
  314. /* ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); */
  315. fgStatus = FALSE;
  316. if (fgIsResetting != TRUE) {
  317. UINT_32 u4FwCnt;
  318. static unsigned int u4OwnCnt;
  319. /* MCR_D2HRM2R: low 4 bit means interrupt times,
  320. * high 4 bit means firmware response times.
  321. * ORI_MCR_D2HRM2R: the last successful value.
  322. * for example:
  323. * MCR_D2HRM2R = 0x44, ORI_MCR_D2HRM2R = 0x44
  324. * means firmware no receive interrupt form hardware.
  325. * MCR_D2HRM2R = 0x45, ORI_MCR_D2HRM2R = 0x44
  326. * means firmware no send response.
  327. * MCR_D2HRM2R = 0x55, ORI_MCR_D2HRM2R = 0x44
  328. * means firmware send response, but driver no receive. */
  329. HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue);
  330. DBGLOG(NIC, WARN, "<WiFi> [1]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n",
  331. u4RegValue, u4OriRegValue);
  332. HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
  333. HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
  334. if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
  335. HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue);
  336. prAdapter->fgIsFwOwn = FALSE;
  337. break;
  338. }
  339. HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue);
  340. DBGLOG(NIC, WARN, "<WiFi> [2]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n",
  341. u4RegValue, u4OriRegValue);
  342. DBGLOG(NIC, WARN,
  343. "<WiFi> Fatal error! Driver own fail!!!!!!!!!!!! %d, fgIsBusAccessFailed: %d\n",
  344. u4OwnCnt++, fgIsBusAccessFailed);
  345. DBGLOG(NIC, WARN, "CONNSYS FW CPUINFO:\n");
  346. for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++)
  347. DBGLOG(NIC, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR));
  348. /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */
  349. kalSendAeeWarning("[Fatal error! Driver own fail!]", __func__);
  350. glDoChipReset();
  351. }
  352. break;
  353. }
  354. if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) {
  355. /* Software get LP ownership - per 256 iterations */
  356. HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
  357. }
  358. /* Delay for LP engine to complete its operation. */
  359. kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS);
  360. i++;
  361. }
  362. STATS_DRIVER_OWN_END_RECORD();
  363. STATS_DRIVER_OWN_STOP();
  364. return fgStatus;
  365. }
  366. /*----------------------------------------------------------------------------*/
  367. /*!
  368. * \brief This routine is used to set ACPI power mode to D0.
  369. *
  370. * \param[in] pvAdapter Pointer to the Adapter structure.
  371. *
  372. * \return (none)
  373. */
  374. /*----------------------------------------------------------------------------*/
  375. BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter)
  376. {
  377. WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
  378. UINT_32 u4Value = 0, u4WHISR = 0;
  379. UINT_8 aucTxCount[8];
  380. UINT_32 i;
  381. #if CFG_ENABLE_FW_DOWNLOAD
  382. UINT_32 u4FwImgLength, u4FwLoadAddr, u4ImgSecSize;
  383. PVOID prFwMappingHandle;
  384. PVOID pvFwImageMapFile = NULL;
  385. #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
  386. UINT_32 j;
  387. P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead;
  388. BOOLEAN fgValidHead;
  389. const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries);
  390. #endif
  391. #endif
  392. DEBUGFUNC("nicpmSetAcpiPowerD0");
  393. ASSERT(prAdapter);
  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. /* 1. Request Ownership to enter F/W download state */
  401. ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
  402. #if !CFG_ENABLE_FULL_PM
  403. nicpmSetDriverOwn(prAdapter);
  404. #endif
  405. /* 2. Initialize the Adapter */
  406. u4Status = nicInitializeAdapter(prAdapter);
  407. if (u4Status != WLAN_STATUS_SUCCESS) {
  408. DBGLOG(NIC, ERROR, "nicInitializeAdapter failed!\n");
  409. u4Status = WLAN_STATUS_FAILURE;
  410. break;
  411. }
  412. #if CFG_ENABLE_FW_DOWNLOAD
  413. prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength);
  414. if (!prFwMappingHandle) {
  415. DBGLOG(NIC, ERROR, "Fail to load FW image from file!\n");
  416. pvFwImageMapFile = NULL;
  417. }
  418. if (pvFwImageMapFile == NULL) {
  419. u4Status = WLAN_STATUS_FAILURE;
  420. break;
  421. }
  422. /* 3.1 disable interrupt, download is done by polling mode only */
  423. nicDisableInterrupt(prAdapter);
  424. /* 3.2 Initialize Tx Resource to fw download state */
  425. nicTxInitResetResource(prAdapter);
  426. /* 3.3 FW download here */
  427. u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo);
  428. #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
  429. /* 3a. parse file header for decision of divided firmware download or not */
  430. prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile;
  431. if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE &&
  432. prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset,
  433. u4FwImgLength - u4CRCOffset)) {
  434. fgValidHead = TRUE;
  435. } else {
  436. fgValidHead = FALSE;
  437. }
  438. /* 3b. engage divided firmware downloading */
  439. if (fgValidHead == TRUE) {
  440. for (i = 0; i < prFwHead->u4NumOfEntries; i++) {
  441. #if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
  442. if (wlanImageSectionDownloadAggregated(prAdapter,
  443. prFwHead->arSection[i].u4DestAddr,
  444. prFwHead->arSection[i].u4Length,
  445. (PUINT_8) pvFwImageMapFile +
  446. prFwHead->arSection[i].u4Offset) !=
  447. WLAN_STATUS_SUCCESS) {
  448. DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n");
  449. u4Status = WLAN_STATUS_FAILURE;
  450. }
  451. #else
  452. for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) {
  453. if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length)
  454. u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
  455. else
  456. u4ImgSecSize = prFwHead->arSection[i].u4Length - j;
  457. if (wlanImageSectionDownload(prAdapter,
  458. prFwHead->arSection[i].u4DestAddr + j,
  459. u4ImgSecSize,
  460. (PUINT_8) pvFwImageMapFile +
  461. prFwHead->arSection[i].u4Offset + j) != WLAN_STATUS_SUCCESS) {
  462. DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n");
  463. u4Status = WLAN_STATUS_FAILURE;
  464. break;
  465. }
  466. }
  467. #endif
  468. /* escape from loop if any pending error occurs */
  469. if (u4Status == WLAN_STATUS_FAILURE)
  470. break;
  471. }
  472. } else
  473. #endif
  474. #if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
  475. if (wlanImageSectionDownloadAggregated(prAdapter,
  476. u4FwLoadAddr,
  477. u4FwImgLength,
  478. (PUINT_8) pvFwImageMapFile) != WLAN_STATUS_SUCCESS) {
  479. DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n");
  480. u4Status = WLAN_STATUS_FAILURE;
  481. }
  482. #else
  483. for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) {
  484. if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength)
  485. u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
  486. else
  487. u4ImgSecSize = u4FwImgLength - i;
  488. if (wlanImageSectionDownload(prAdapter,
  489. u4FwLoadAddr + i,
  490. u4ImgSecSize,
  491. (PUINT_8) pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) {
  492. DBGLOG(NIC, ERROR, "wlanImageSectionDownload failed!\n");
  493. u4Status = WLAN_STATUS_FAILURE;
  494. break;
  495. }
  496. }
  497. #endif
  498. if (u4Status != WLAN_STATUS_SUCCESS) {
  499. kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
  500. break;
  501. }
  502. #if !CFG_ENABLE_FW_DOWNLOAD_ACK
  503. /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */
  504. if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) {
  505. kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
  506. u4Status = WLAN_STATUS_FAILURE;
  507. break;
  508. }
  509. #endif
  510. kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
  511. /* 4. send Wi-Fi Start command */
  512. #if CFG_OVERRIDE_FW_START_ADDRESS
  513. wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo));
  514. #else
  515. wlanConfigWifiFunc(prAdapter, FALSE, 0);
  516. #endif
  517. #endif /* if CFG_ENABLE_FW_DOWNLOAD */
  518. /* 5. check Wi-Fi FW asserts ready bit */
  519. DBGLOG(NIC, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n");
  520. i = 0;
  521. while (1) {
  522. HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
  523. if (u4Value & WCIR_WLAN_READY) {
  524. DBGLOG(NIC, TRACE, "Ready bit asserted\n");
  525. break;
  526. } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
  527. u4Status = WLAN_STATUS_FAILURE;
  528. break;
  529. } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) {
  530. DBGLOG(NIC, ERROR, "Waiting for Ready bit: Timeout\n");
  531. u4Status = WLAN_STATUS_FAILURE;
  532. break;
  533. }
  534. i++;
  535. kalMsleep(10);
  536. }
  537. if (u4Status == WLAN_STATUS_SUCCESS) {
  538. /* 6.1 reset interrupt status */
  539. HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)(&u4WHISR));
  540. if (HAL_IS_TX_DONE_INTR(u4WHISR))
  541. HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount);
  542. /* 6.2 reset TX Resource for normal operation */
  543. nicTxResetResource(prAdapter);
  544. /* 6.3 Enable interrupt */
  545. nicEnableInterrupt(prAdapter);
  546. /* 6.4 Override network address */
  547. wlanUpdateNetworkAddress(prAdapter);
  548. /* 6.5 indicate disconnection as default status */
  549. kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
  550. }
  551. RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
  552. /* MGMT Initialization */
  553. nicInitMGMT(prAdapter, NULL);
  554. } while (FALSE);
  555. if (u4Status != WLAN_STATUS_SUCCESS)
  556. return FALSE;
  557. else
  558. return TRUE;
  559. }
  560. /*----------------------------------------------------------------------------*/
  561. /*!
  562. * @brief This routine is used to set ACPI power mode to D3.
  563. *
  564. * @param prAdapter pointer to the Adapter handler
  565. *
  566. * @return (none)
  567. */
  568. /*----------------------------------------------------------------------------*/
  569. BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter)
  570. {
  571. UINT_32 i;
  572. ASSERT(prAdapter);
  573. /* 1. MGMT - unitialization */
  574. nicUninitMGMT(prAdapter);
  575. /* 2. Disable Interrupt */
  576. nicDisableInterrupt(prAdapter);
  577. /* 3. emit CMD_NIC_POWER_CTRL command packet */
  578. wlanSendNicPowerCtrlCmd(prAdapter, 1);
  579. /* 4. Clear Interrupt Status */
  580. i = 0;
  581. while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
  582. i++;
  583. };
  584. /* 5. Remove pending TX */
  585. nicTxRelease(prAdapter);
  586. /* 5.1 clear pending Security / Management Frames */
  587. kalClearSecurityFrames(prAdapter->prGlueInfo);
  588. kalClearMgmtFrames(prAdapter->prGlueInfo);
  589. /* 5.2 clear pending TX packet queued in glue layer */
  590. kalFlushPendingTxPackets(prAdapter->prGlueInfo);
  591. /* 6. Set Onwership to F/W */
  592. nicpmSetFWOwn(prAdapter, FALSE);
  593. /* 7. Set variables */
  594. prAdapter->rAcpiState = ACPI_STATE_D3;
  595. return TRUE;
  596. }