/*----------------------------------------------------------------------------*/ BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter) { WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; UINT_32 u4Value = 0, u4WHISR = 0; UINT_8 aucTxCount[8]; UINT_32 i; #if CFG_ENABLE_FW_DOWNLOAD UINT_32 u4FwImgLength, u4FwLoadAddr, u4ImgSecSize; PVOID prFwMappingHandle; PVOID pvFwImageMapFile = NULL; #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD UINT_32 j; P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; BOOLEAN fgValidHead; const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); #endif #endif DEBUGFUNC("nicpmSetAcpiPowerD0"); ASSERT(prAdapter); do { /* 0. Reset variables in ADAPTER_T */ prAdapter->fgIsFwOwn = TRUE; prAdapter->fgWiFiInSleepyState = FALSE; prAdapter->rAcpiState = ACPI_STATE_D0; prAdapter->fgIsEnterD3ReqIssued = FALSE; #if defined(MT6620) || defined(MT6628) /* 1. Request Ownership to enter F/W download state */ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); #if !CFG_ENABLE_FULL_PM nicpmSetDriverOwn(prAdapter); #endif /* 2. Initialize the Adapter */ if ((u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n")); u4Status = WLAN_STATUS_FAILURE; break; } #endif #if CFG_ENABLE_FW_DOWNLOAD prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength); if (!prFwMappingHandle) { DBGLOG(INIT, ERROR, ("Fail to load FW image from file!\n")); pvFwImageMapFile = NULL; } #if defined(MT6620) || defined(MT6628) if (pvFwImageMapFile) { /* 3.1 disable interrupt, download is done by polling mode only */ nicDisableInterrupt(prAdapter); /* 3.2 Initialize Tx Resource to fw download state */ nicTxInitResetResource(prAdapter); /* 3.3 FW download here */ u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo); #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD /* 3a. parse file header for decision of divided firmware download or not */ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, u4FwImgLength - u4CRCOffset)) { fgValidHead = TRUE; } else { fgValidHead = FALSE; } /* 3b. engage divided firmware downloading */ if (fgValidHead == TRUE) { for (i = 0; i < prFwHead->u4NumOfEntries; i++) { #if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION if (wlanImageSectionDownloadAggregated (prAdapter, prFwHead->arSection[i].u4DestAddr, prFwHead->arSection[i].u4Length, (PUINT_8) pvFwImageMapFile + prFwHead->arSection[i].u4Offset) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("Firmware scatter download failed!\n")); u4Status = WLAN_STATUS_FAILURE; } #else for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead-> arSection[i].u4Length) u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; else u4ImgSecSize = prFwHead->arSection [i].u4Length - j; if (wlanImageSectionDownload (prAdapter, prFwHead-> arSection[i].u4DestAddr + j, u4ImgSecSize, (PUINT_8) pvFwImageMapFile + prFwHead->arSection[i]. u4Offset + j) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("Firmware scatter download failed!\n")); u4Status = WLAN_STATUS_FAILURE; break; } } #endif /* escape from loop if any pending error occurs */ if (u4Status == WLAN_STATUS_FAILURE) { break; } } } else #endif #if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION if (wlanImageSectionDownloadAggregated (prAdapter, u4FwLoadAddr, u4FwImgLength, (PUINT_8) pvFwImageMapFile) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("Firmware scatter download failed!\n")); u4Status = WLAN_STATUS_FAILURE; } #else for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) { if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength) u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; else u4ImgSecSize = u4FwImgLength - i; if (wlanImageSectionDownload(prAdapter, u4FwLoadAddr + i, u4ImgSecSize, (PUINT_8) pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("wlanImageSectionDownload failed!\n")); u4Status = WLAN_STATUS_FAILURE; break; } } #endif if (u4Status != WLAN_STATUS_SUCCESS) { kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); break; } #if !CFG_ENABLE_FW_DOWNLOAD_ACK /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); u4Status = WLAN_STATUS_FAILURE; break; } #endif kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); } else { u4Status = WLAN_STATUS_FAILURE; break; } /* 4. send Wi-Fi Start command */ #if CFG_OVERRIDE_FW_START_ADDRESS wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo)); #else wlanConfigWifiFunc(prAdapter, FALSE, 0); #endif #elif defined(MT5931) if (pvFwImageMapFile) { DBGLOG(INIT, TRACE, ("Download Address: 0x%08X\n", kalGetFwLoadAddress(prAdapter->prGlueInfo))); DBGLOG(INIT, TRACE, ("Firmware Length: 0x%08X\n", u4FwImgLength)); do { /* 1.0 whole-chip reset except HIFSYS */ HAL_MCR_WR(prAdapter, MCR_WMCSR, WMCSR_CHIP_RST); HAL_MCR_WR(prAdapter, MCR_WMCSR, 0); /* 1.1 wait for INIT_RDY */ i = 0; while (1) { HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value); if (u4Value & WMCSR_INI_RDY) { DBGLOG(INIT, TRACE, ("INIT-RDY detected\n")); break; } else if (kalIsCardRemoved (prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { u4Status = WLAN_STATUS_FAILURE; break; } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { DBGLOG(INIT, ERROR, ("Waiting for Init Ready bit: Timeout\n")); u4Status = WLAN_STATUS_FAILURE; break; } else { i++; kalMsleep(10); } } /* 1.2 set KSEL/FLEN */ HAL_MCR_WR(prAdapter, MCR_FWCFG, u4FwImgLength >> 6); /* 1.3 enable FWDL_EN */ HAL_MCR_WR(prAdapter, MCR_WMCSR, WMCSR_FWDLEN); /* 1.4 wait for PLL_RDY */ i = 0; while (1) { HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value); if (u4Value & WMCSR_PLLRDY) { DBGLOG(INIT, TRACE, ("PLL-RDY detected\n")); break; } else if (kalIsCardRemoved (prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { u4Status = WLAN_STATUS_FAILURE; break; } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { DBGLOG(INIT, ERROR, ("Waiting for PLL Ready bit: Timeout\n")); u4Status = WLAN_STATUS_FAILURE; break; } else { i++; kalMsleep(10); } } /* 2.1 turn on HIFSYS firmware download mode */ HAL_MCR_WR(prAdapter, MCR_FWDLSR, FWDLSR_FWDL_MODE); /* 2.2 set starting address */ u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo); HAL_MCR_WR(prAdapter, MCR_FWDLDSAR, u4FwLoadAddr); /* 3. upload firmware */ for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) { if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength) u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; else u4ImgSecSize = u4FwImgLength - i; if (wlanImageSectionDownload(prAdapter, u4FwLoadAddr + i, u4ImgSecSize, (PUINT_8) pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("Firmware scatter download failed!\n")); u4Status = WLAN_STATUS_FAILURE; break; } } /* 4.1 poll FWDL_OK & FWDL_FAIL bits */ i = 0; while (1) { HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value); if (u4Value & WMCSR_DL_OK) { DBGLOG(INIT, TRACE, ("DL_OK detected\n")); break; } else if (kalIsCardRemoved (prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || (u4Value & WMCSR_DL_FAIL)) { DBGLOG(INIT, ERROR, ("DL_FAIL detected: 0x%08X\n", u4Value)); u4Status = WLAN_STATUS_FAILURE; break; } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { DBGLOG(INIT, ERROR, ("Waiting for DL_OK/DL_FAIL bit: Timeout\n")); u4Status = WLAN_STATUS_FAILURE; break; } else { i++; kalMsleep(10); } } /* 4.2 turn off HIFSYS download mode */ HAL_MCR_WR(prAdapter, MCR_FWDLSR, 0); } while (FALSE); } else { DBGLOG(INIT, ERROR, ("No Firmware found!\n")); u4Status = WLAN_STATUS_FAILURE; break; } #endif #endif /* 5. check Wi-Fi FW asserts ready bit */ DBGLOG(INIT, TRACE, ("wlanAdapterStart(): Waiting for Ready bit..\n")); i = 0; while (1) { HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); if (u4Value & WCIR_WLAN_READY) { DBGLOG(INIT, TRACE, ("Ready bit asserted\n")); break; } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { u4Status = WLAN_STATUS_FAILURE; break; } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { DBGLOG(INIT, ERROR, ("Waiting for Ready bit: Timeout\n")); u4Status = WLAN_STATUS_FAILURE; break; } else { i++; kalMsleep(10); } } #if defined(MT5931) /* Acquire LP-OWN */ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); #if !CFG_ENABLE_FULL_PM nicpmSetDriverOwn(prAdapter); #endif /* 2. Initialize the Adapter */ if ((u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n")); u4Status = WLAN_STATUS_FAILURE; break; } #endif if (u4Status == WLAN_STATUS_SUCCESS) { /* 6.1 reset interrupt status */ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8) & u4WHISR); if (HAL_IS_TX_DONE_INTR(u4WHISR)) { HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); } /* 6.2 reset TX Resource for normal operation */ nicTxResetResource(prAdapter); /* 6.3 Enable interrupt */ nicEnableInterrupt(prAdapter); /* 6.4 Override network address */ wlanUpdateNetworkAddress(prAdapter); /* 6.5 indicate disconnection as default status */ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); } RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); /* MGMT Initialization */ nicInitMGMT(prAdapter, NULL); } while (FALSE);
/*----------------------------------------------------------------------------*/ BOOLEAN nicpmSetAcpiPowerD0 ( IN P_ADAPTER_T prAdapter ) { WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; UINT_32 u4Value = 0, u4WHISR = 0; UINT_16 au2TxCount[16]; UINT_32 i; #if CFG_ENABLE_FW_DOWNLOAD UINT_32 u4FwImgLength, u4FwLoadAddr, u4ImgSecSize; PVOID prFwMappingHandle; PVOID pvFwImageMapFile = NULL; #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD UINT_32 j; P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; BOOLEAN fgValidHead; const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); #endif #endif DEBUGFUNC("nicpmSetAcpiPowerD0"); ASSERT(prAdapter); do { /* 0. Reset variables in ADAPTER_T */ prAdapter->fgIsFwOwn = TRUE; prAdapter->fgWiFiInSleepyState = FALSE; prAdapter->rAcpiState = ACPI_STATE_D0; prAdapter->fgIsEnterD3ReqIssued = FALSE; #if defined(MT6630) /* 1. Request Ownership to enter F/W download state */ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); #if !CFG_ENABLE_FULL_PM nicpmSetDriverOwn(prAdapter); #endif /* 2. Initialize the Adapter */ if ( (u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS ) { DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n")); u4Status = WLAN_STATUS_FAILURE; break; } #endif #if CFG_ENABLE_FW_DOWNLOAD prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength); if(!prFwMappingHandle) { DBGLOG(INIT, ERROR,("Fail to load FW image from file!\n")); pvFwImageMapFile = NULL; } #if defined(MT6630) if (pvFwImageMapFile) { /* 3.1 disable interrupt, download is done by polling mode only */ nicDisableInterrupt(prAdapter); /* 3.2 Initialize Tx Resource to fw download state */ nicTxInitResetResource(prAdapter); /* 3.3 FW download here */ u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo); #if CFG_ENABLE_FW_DIVIDED_DOWNLOAD // 3a. parse file header for decision of divided firmware download or not prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T)pvFwImageMapFile; if(prFwHead->u4Signature == MTK_WIFI_SIGNATURE && prFwHead->u4CRC == wlanCRC32((PUINT_8)pvFwImageMapFile + u4CRCOffset, u4FwImgLength - u4CRCOffset)) { fgValidHead = TRUE; } else { fgValidHead = FALSE; } /* 3b. engage divided firmware downloading */ if(fgValidHead == TRUE) { for(i = 0 ; i < prFwHead->u4NumOfEntries ; i++) { if(wlanImageSectionConfig(prAdapter, prFwHead->arSection[i].u4DestAddr, prFwHead->arSection[i].u4Length, i == 0 ? TRUE : FALSE) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("Firmware download configuration failed!\n")); u4Status = WLAN_STATUS_FAILURE; break; } else { for(j = 0 ; j < prFwHead->arSection[i].u4Length ; j += CMD_PKT_SIZE_FOR_IMAGE) { if(j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; else u4ImgSecSize = prFwHead->arSection[i].u4Length - j; if(wlanImageSectionDownload(prAdapter, u4ImgSecSize, (PUINT_8)pvFwImageMapFile + prFwHead->arSection[i].u4Offset + j) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("Firmware scatter download failed!\n")); u4Status = WLAN_STATUS_FAILURE; break; } } /* escape from loop if any pending error occurs */ if(u4Status == WLAN_STATUS_FAILURE) { break; } } } } else #endif { if(wlanImageSectionConfig(prAdapter, u4FwLoadAddr, u4FwImgLength, TRUE) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("Firmware download configuration failed!\n")); u4Status = WLAN_STATUS_FAILURE; break; } else { for (i = 0; i < u4FwImgLength ; i += CMD_PKT_SIZE_FOR_IMAGE) { if(i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength) u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; else u4ImgSecSize = u4FwImgLength - i; if(wlanImageSectionDownload(prAdapter, u4ImgSecSize, (PUINT_8)pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, ERROR, ("wlanImageSectionDownload failed!\n")); u4Status = WLAN_STATUS_FAILURE; break; } } } } /* escape to top */ if(u4Status != WLAN_STATUS_SUCCESS) { kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); break; } #if !CFG_ENABLE_FW_DOWNLOAD_ACK // Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response if(wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); u4Status = WLAN_STATUS_FAILURE; break; } #endif kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); } else { u4Status = WLAN_STATUS_FAILURE; break; } /* 4. send Wi-Fi Start command */ #if CFG_OVERRIDE_FW_START_ADDRESS wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo)); #else wlanConfigWifiFunc(prAdapter, FALSE, 0); #endif #endif #endif /* 5. check Wi-Fi FW asserts ready bit */ DBGLOG(INIT, TRACE, ("wlanAdapterStart(): Waiting for Ready bit..\n")); i = 0; while(1) { HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); if (u4Value & WCIR_WLAN_READY) { DBGLOG(INIT, TRACE, ("Ready bit asserted\n")); break; } else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { u4Status = WLAN_STATUS_FAILURE; break; } else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) { DBGLOG(INIT, ERROR, ("Waiting for Ready bit: Timeout\n")); u4Status = WLAN_STATUS_FAILURE; break; } else { i++; kalMsleep(10); } } if(u4Status == WLAN_STATUS_SUCCESS) { // 6.1 reset interrupt status HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); if(HAL_IS_TX_DONE_INTR(u4WHISR)) { HAL_READ_TX_RELEASED_COUNT(prAdapter, au2TxCount); } /* 6.2 reset TX Resource for normal operation */ nicTxResetResource(prAdapter); /* 6.3 Enable interrupt */ nicEnableInterrupt(prAdapter); /* 6.4 Update basic configuration */ wlanUpdateBasicConfig(prAdapter); /* 6.5 Apply Network Address */ nicApplyNetworkAddress(prAdapter); /* 6.6 indicate disconnection as default status */ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); } RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); /* MGMT Initialization */ nicInitMGMT(prAdapter, NULL); } while(FALSE); if(u4Status != WLAN_STATUS_SUCCESS) { return FALSE; } else { return TRUE; } }