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;
}
Beispiel #2
0
/*----------------------------------------------------------------------------*/
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);
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;
}
Beispiel #4
0
/*----------------------------------------------------------------------------*/
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;
    }
}