/*----------------------------------------------------------------------------*/ BOOLEAN nicpmSetDriverOwn ( IN P_ADAPTER_T prAdapter ) { #define LP_OWN_BACK_TOTAL_DELAY_MS 8192 //exponential of 2 #define LP_OWN_BACK_LOOP_DELAY_MS 1 //exponential of 2 #define LP_OWN_BACK_CLR_OWN_ITERATION 256 //exponential of 2 BOOLEAN fgStatus = TRUE; UINT32 i, u4CurrTick; UINT_32 u4RegValue = 0; ASSERT(prAdapter); if(prAdapter->fgIsFwOwn == FALSE) return fgStatus; u4CurrTick = kalGetTimeTick(); i = 0; while(1) { HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { prAdapter->fgIsFwOwn = FALSE; break; } else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS || fgIsResetting == TRUE) { //ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); fgStatus = FALSE; if (fgIsResetting != TRUE) { static unsigned int owncnt = 0; HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); printk("<WiFi> MCR_D2HRM2R = 0x%x\n", (UINT32)u4RegValue); printk("<WiFi> Fatal error! Driver own fail!!!!!!!!!!!! %d\n", owncnt++); } break; } else { if((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) { /* Software get LP ownership - per 256 iterations */ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); } /* Delay for LP engine to complete its operation. */ kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS); i++; } } return fgStatus; }
/*----------------------------------------------------------------------------*/ VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt) { UINT_32 u4RegValue; ASSERT(prAdapter); if (prAdapter->fgIsFwOwn == TRUE) { return; } else { if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { /* pending interrupts */ return; } } if (fgEnableGlobalInt) { prAdapter->fgIsIntEnableWithLPOwnSet = TRUE; } else { HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { /* if set firmware own not successful (possibly pending interrupts), */ /* indicate an own clear event */ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); return; } prAdapter->fgIsFwOwn = TRUE; } }
/*----------------------------------------------------------------------------*/ BOOLEAN nicpmSetDriverOwn ( IN P_ADAPTER_T prAdapter ) { #define LP_OWN_BACK_TOTAL_DELAY_MS 2048 //exponential of 2 #define LP_OWN_BACK_LOOP_DELAY_MS 1 //exponential of 2 #define LP_OWN_BACK_CLR_OWN_ITERATION 256 //exponential of 2 BOOLEAN fgStatus = TRUE; UINT_32 i, u4CurrTick, u4RegValue = 0; BOOLEAN fgTimeout; ASSERT(prAdapter); if(prAdapter->fgIsFwOwn == FALSE) return fgStatus; DBGLOG(INIT, INFO, ("DRIVER OWN\n")); u4CurrTick = kalGetTimeTick(); i = 0; while(1) { HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); fgTimeout = ((kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS)? TRUE:FALSE; if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { prAdapter->fgIsFwOwn = FALSE; break; } else if(kalIsCardRemoved(prAdapter->prGlueInfo) || fgIsBusAccessFailed || fgTimeout || wlanIsChipNoAck(prAdapter)) { DBGLOG(INIT, ERROR, ("LP cannot be own back, Timeout[%u](%ums), BusAccessError[%u], Reseting[%u], CardRemoved[%u] NoAck[%u]\n", fgTimeout, kalGetTimeTick() - u4CurrTick, fgIsBusAccessFailed, kalIsResetting(), kalIsCardRemoved(prAdapter->prGlueInfo), wlanIsChipNoAck(prAdapter))); fgStatus = FALSE; break; } else { if((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) { /* Software get LP ownership - per 256 iterations */ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); } /* Delay for LP engine to complete its operation. */ kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS); i++; } } return fgStatus; }
VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvaliable) { static UINT_16 u2CurEntry; P_TC_RES_RELEASE_ENTRY prCurBuf = &gprTcReleaseTraceBuffer[u2CurEntry]; HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &prCurBuf->u4RelCID); prCurBuf->u8RelaseTime = sched_clock(); prCurBuf->ucTc4RelCnt = aucTxRlsCnt[TC4_INDEX]; prCurBuf->ucAvailableTc4 = ucAvaliable; u2CurEntry++; if (u2CurEntry == TXED_CMD_TRACE_BUF_MAX_NUM) u2CurEntry = 0; }
VOID nicPmTriggerDriverOwn(IN P_ADAPTER_T prAdapter) { UINT_32 u4RegValue = 0; HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { prAdapter->fgIsFwOwn = FALSE; } else { HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); } }
/*----------------------------------------------------------------------------*/ BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter) { #define LP_OWN_BACK_TOTAL_DELAY_MS 8192 /* exponential of 2 */ #define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */ #define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */ BOOLEAN fgStatus = TRUE; UINT_32 i, u4CurrTick, u4RegValue = 0; ASSERT(prAdapter); if (prAdapter->fgIsFwOwn == FALSE) return fgStatus; u4CurrTick = kalGetTimeTick(); i = 0; while (1) { HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { prAdapter->fgIsFwOwn = FALSE; break; } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS || fgIsResetting == TRUE) { /* ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); */ fgStatus = FALSE; break; } else { if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) { /* Software get LP ownership - per 256 iterations */ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); } /* Delay for LP engine to complete its operation. */ kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS); i++; } } return fgStatus; }
VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) { UINT_32 u4WHISR = 0, u4Value = 0; UINT_8 aucTxCount[8]; ASSERT(prAdapter); ASSERT(prCmdInfo); /* 1. Disable Interrupt */ HAL_INTR_DISABLE(prAdapter); /* 2. Block til firmware completed leaving from RF test mode */ kalMsleep(500); while (1) { HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); if (u4Value & WCIR_WLAN_READY) { break; } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { if (prCmdInfo->fgIsOid) { /* Update Set Infomation Length */ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); } return; } else { kalMsleep(10); } } /* 3. Clear 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); } /* 4. Reset TX Counter */ nicTxResetResource(prAdapter); /* 5. Re-enable Interrupt */ HAL_INTR_ENABLE(prAdapter); /* 6. set driver-land variable */ prAdapter->fgTestMode = FALSE; /* 7. completion indication */ if (prCmdInfo->fgIsOid) { /* Update Set Infomation Length */ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); } /* 8. Indicate as disconnected */ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); } #if CFG_SUPPORT_NVRAM /* 9. load manufacture data */ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); #endif /* 10. Override network address */ wlanUpdateNetworkAddress(prAdapter); return; }
VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) { UINT_32 u4WHISR = 0, u4Value = 0; UINT_8 aucTxCount[8]; ASSERT(prAdapter); ASSERT(prCmdInfo); /* [driver-land] */ prAdapter->fgTestMode = TRUE; /* 0. always indicate disconnection */ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); } /* 1. Remove pending TX */ nicTxRelease(prAdapter); /* 1.1 clear pending Security / Management Frames */ kalClearSecurityFrames(prAdapter->prGlueInfo); kalClearMgmtFrames(prAdapter->prGlueInfo); /* 1.2 clear pending TX packet queued in glue layer */ kalFlushPendingTxPackets(prAdapter->prGlueInfo); /* 2. Reset driver-domain FSMs */ nicUninitMGMT(prAdapter); nicResetSystemService(prAdapter); nicInitMGMT(prAdapter, NULL); /* 3. Disable Interrupt */ HAL_INTR_DISABLE(prAdapter); /* 4. Block til firmware completed entering into RF test mode */ kalMsleep(500); while (1) { HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); if (u4Value & WCIR_WLAN_READY) { break; } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { if (prCmdInfo->fgIsOid) { /* Update Set Infomation Length */ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); } return; } else kalMsleep(10); } /* 5. Clear 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. Reset TX Counter */ nicTxResetResource(prAdapter); /* 7. Re-enable Interrupt */ HAL_INTR_ENABLE(prAdapter); /* 8. completion indication */ if (prCmdInfo->fgIsOid) { /* Update Set Infomation Length */ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); } #if CFG_SUPPORT_NVRAM /* 9. load manufacture data */ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); #endif return; }
/*----------------------------------------------------------------------------*/ 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 nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter) { #define LP_OWN_BACK_TOTAL_DELAY_MS 2000 /* exponential of 2 */ #define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */ #define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */ BOOLEAN fgStatus = TRUE; UINT_32 i, u4CurrTick; UINT_32 u4RegValue = 0; GL_HIF_INFO_T *HifInfo; ASSERT(prAdapter); if (prAdapter->fgIsFwOwn == FALSE) return fgStatus; HifInfo = &prAdapter->prGlueInfo->rHifInfo; u4CurrTick = kalGetTimeTick(); STATS_DRIVER_OWN_START_RECORD(); i = 0; while (1) { HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { prAdapter->fgIsFwOwn = FALSE; break; } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS || fgIsResetting == TRUE) { /* ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); */ fgStatus = FALSE; if (fgIsResetting != TRUE) { UINT_32 u4FwCnt; static unsigned int u4OwnCnt; HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); DBGLOG(NIC, WARN, "<WiFi> MCR_D2HRM2R = 0x%x\n", u4RegValue); DBGLOG(NIC, WARN, "<WiFi> Fatal error! Driver own fail!!!!!!!!!!!! %d\n", u4OwnCnt++); DBGLOG(NIC, WARN, "CONNSYS FW CPUINFO:\n"); for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) DBGLOG(NIC, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ } break; } else { if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) { /* Software get LP ownership - per 256 iterations */ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); } /* Delay for LP engine to complete its operation. */ kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS); i++; } } STATS_DRIVER_OWN_END_RECORD(); STATS_DRIVER_OWN_STOP(); return fgStatus; }
/*----------------------------------------------------------------------------*/ 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; } }
/*----------------------------------------------------------------------------*/ BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter) { #define LP_OWN_BACK_TOTAL_DELAY_MS 2048 /* exponential of 2 */ #define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */ #define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */ #define LP_OWN_BACK_FAILED_RETRY_CNT 5 #define LP_OWN_BACK_FAILED_LOG_SKIP_MS 2000 #define LP_OWN_BACK_FAILED_RESET_CNT 5 BOOLEAN fgStatus = TRUE; UINT_32 i, u4CurrTick, u4RegValue = 0; BOOLEAN fgTimeout; ASSERT(prAdapter); if (prAdapter->fgIsFwOwn == FALSE) return fgStatus; DBGLOG(INIT, INFO, ("DRIVER OWN\n")); u4CurrTick = kalGetTimeTick(); i = 0; while (1) { HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); fgTimeout = ((kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS) ? TRUE : FALSE; if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { prAdapter->fgIsFwOwn = FALSE; prAdapter->u4OwnFailedCount = 0; prAdapter->u4OwnFailedLogCount = 0; break; } else if((i > LP_OWN_BACK_FAILED_RETRY_CNT) && (kalIsCardRemoved(prAdapter->prGlueInfo) || fgIsBusAccessFailed || fgTimeout || wlanIsChipNoAck(prAdapter))) { if ((prAdapter->u4OwnFailedCount == 0) || CHECK_FOR_TIMEOUT(u4CurrTick, prAdapter->rLastOwnFailedLogTime, MSEC_TO_SYSTIME(LP_OWN_BACK_FAILED_LOG_SKIP_MS))) { DBGLOG(INIT, ERROR, ("LP cannot be own back, Timeout[%u](%ums), BusAccessError[%u], Reseting[%u], CardRemoved[%u] NoAck[%u] Cnt[%u]\n", fgTimeout, kalGetTimeTick() - u4CurrTick, fgIsBusAccessFailed, kalIsResetting(), kalIsCardRemoved(prAdapter->prGlueInfo), wlanIsChipNoAck(prAdapter), prAdapter->u4OwnFailedCount)); DBGLOG(INIT, INFO, ("Skip LP own back failed log for next %ums\n", LP_OWN_BACK_FAILED_LOG_SKIP_MS)); prAdapter->u4OwnFailedLogCount++; if(prAdapter->u4OwnFailedLogCount > LP_OWN_BACK_FAILED_RESET_CNT) { /* Trigger RESET */ #if CFG_CHIP_RESET_SUPPORT glResetTrigger(prAdapter); #endif } GET_CURRENT_SYSTIME(&prAdapter->rLastOwnFailedLogTime); } prAdapter->u4OwnFailedCount++; fgStatus = FALSE; break; } else { if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) { /* Software get LP ownership - per 256 iterations */ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); } /* Delay for LP engine to complete its operation. */ kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS); i++; } } return fgStatus; }