BOOL If_WlanImageProg(PBYTE pImage, int nImgSize) { WORD nLen; DWORD nCnt = 0; do { nLen = 0; Sleep(2); If_ReadRegister(SCRATCH_1_REG, &nLen); if (++nCnt > 100) { TRACE("WlanImageProg: Cann't get the packet size\r\n"); return FALSE; } } while (!nLen); nCnt = 0; while (1) { if (!If_WaitforHostIntr(200)) { TRACE("Firmware download died ......\r\n"); return FALSE; } If_ReadRegister(SCRATCH_1_REG, &nLen); if (nLen == 0) break; if (nLen > DLIMAGE_LEN) { TRACE("WlanImageProg: PacketSize(%d) error\r\n", nLen); return FALSE; } if (nLen & 1) { TRACE("WlanImageProg: CRC error(nLen=%d)\r\n", nLen); nLen &= ~1; } If_WriteRegister2(CMD_RDWRPORT_REG, (pImage + nCnt), nLen); If_WriteRegister(HOST_INT_STATUS_REG, 0x0000); If_WriteRegister(CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr); nCnt += nLen; } if (nImgSize != nCnt) { TRACE("WlanImageProg: nImgSize[%d]!=nWriteLen[%d])\r\n", nImgSize, nLen); return FALSE; } TRACE("Download %d bytes of Wlan Image\r\n", nImgSize); return TRUE; }
BOOL If_FirmwareDownload(void) { BOOL rc; If_HostIntrDisable(); Hw_CloseInterrupts(); #ifdef FIRMWARE_IN_FLASH rc = If_FirmwareImageProg((PBYTE)WIFI_FW_HELPER_ADDR, sizeof(helperimage)); if (rc) { Sleep(10); rc = If_WlanImageProg((PBYTE)WIFI_FW_FW_ADDR, sizeof(fmimage)); } #else rc = If_FirmwareImageProg((PBYTE)helperimage, sizeof(helperimage)); if (rc) { Sleep(10); rc = If_WlanImageProg((PBYTE)fmimage, sizeof(fmimage)); } #endif if (rc) { int i = 10; do { Sleep(10); rc = If_IsFirmwareLoaded(); } while (!rc && --i >= 0); if (!rc) { TRACE("Image Down has some error\r\n"); } } if (rc) { WORD nValue; If_ReadRegister(HOST_INT_STATUS_REG, &nValue); If_WriteRegister(HOST_INT_STATUS_REG, ~nValue); If_ReadRegister(HOST_INT_STATUS_REG, &nValue); If_ReadRegister(HOST_INT_CAUSE_REG, &nValue); If_HostIntrEnable(); Hw_OpenInterrupts(); } TRACE("FirmwareDownlown rc=%d\r\n", rc); return rc; }
//-------------------------------------------------------------------- // Functions exported //-------------------------------------------------------------------- void CmdOnCmdUpLdRdy(PWLAN_ADAPTER pAdapter) { if (pAdapter->m_cmd.pRxBuffer) { WORD nSize; BOOL rc = If_ReadRegister(SCRATCH_2_REG, &nSize) == sizeof(WORD); if (rc) { WORD nSize2; ZeroMemory(pAdapter->m_cmd.pRxBuffer, pAdapter->m_cmd.nRxSize); if (nSize > pAdapter->m_cmd.nRxSize) nSize = pAdapter->m_cmd.nRxSize; nSize2 = nSize & 1 ? nSize + 1 : nSize; rc = If_ReadRegister2(CMD_RDWRPORT_REG, pAdapter->m_cmd.pRxBuffer, nSize2) == nSize2; //rc = Hw_ReadData(CMD_RDWRPORT_REG, (WORD*)pAdapter->m_cmd.pRxBuffer, nSize2); } if (rc) pAdapter->m_cmd.nRxSize = nSize; else { pAdapter->m_cmd.nRxSize = nSize; pAdapter->m_cmd.pRxBuffer = NULL; } } If_WriteRegister(CARD_INT_CAUSE_REG, CIC_CmdUpLdOvr); }
void If_OnIoIntr(PWLAN_ADAPTER Adapter) { WORD nIntrStatus; If_WriteRegister(HOST_INT_STATUS_MASK_REG, 0); if (!If_ReadRegister(HOST_INT_STATUS_REG, &nIntrStatus) || nIntrStatus == MAXWORD) nIntrStatus = 0; TRACE("If_OnIoIntr: IoIntr %04x\r\n", nIntrStatus); if (nIntrStatus) { If_WriteRegister(HOST_INT_STATUS_REG, ~nIntrStatus & 0x1f); if (nIntrStatus & HIS_TxDnLdRdy) WlanPkt_OnPktSend(Adapter); if (nIntrStatus & HIS_RxUpLdRdy) WlanPkt_OnPktRcve(Adapter); if (nIntrStatus & HIS_CmdDnLdRdy) ;//CmdOnIntrCmdSent(); if (nIntrStatus & HIS_CardEvent) CeOnIntrCardEvent(); if (nIntrStatus & HIS_CmdUpLdRdy) CmdOnCmdUpLdRdy(Adapter); WIFI_SET_FLAG(Adapter, FLAG_INTRETURN); } If_WriteRegister(HOST_INT_STATUS_MASK_REG, WLAN_INTR_ENABLE_BITS); }
void If_HostIntrEnable() { WORD i; If_WriteRegister(HOST_INT_STATUS_MASK_REG, 0x1f); If_ReadRegister(HOST_INT_CTRL_REG, &i); If_WriteRegister(HOST_INT_CTRL_REG, i&~(0x01e0)); }
BOOL If_IsFirmwareLoaded() { WORD nValue = 0; If_ReadRegister(SCRATCH_4_REG, &nValue); return (nValue == (WORD)FIRMWARE_DNLD_OK); }
BOOL If_WaitforHostIntr(int nTimeOut) { int i; WORD nState; for (i = 0; i < nTimeOut; i++) { nState = 0xffff; If_ReadRegister(HOST_INT_STATUS_REG, &nState); if (nState != 0xffff && (nState & CIC_CmdDnLdOvr)) return TRUE; Sleep(1);// stall for 100 us } return FALSE; }
/****************************************************************************** * * Name: MrvDrvCheckForHang() * * Description: * NDIS miniport check for hang routine. * * Conditions for Use: * Will be called by NDIS wrapper to determine current station operation status. * If the station is not responding, NDIS wrapper will call MrvDrvReset() to reset * the station. Driver first check and use current HW status stored in device * object to report system then update the status and send command to query HW status. * * Arguments: * IN NDIS_HANDLE MiniportAdapterContext * * Return Value: * TRUE if the NIC HW is not operating properly * FALSE if the NIC HW is OK * * Notes: According to Microsoft NDIS document, this function is normally called * by NDIS wrapper approximately every 2 seconds. * *****************************************************************************/ BOOLEAN MrvDrvCheckForHang( IN NDIS_HANDLE MiniportAdapterContext ) { PMRVDRV_ADAPTER Adapter; UCHAR ucHostIntStatus; UCHAR ucCardStatus; SD_API_STATUS status; DBGPRINT(DBG_LOAD|DBG_WARNING,(L"INIT - Enter MrvDrvCheckForHang\n")); //return FALSE; //tt ra fail Adapter = (PMRVDRV_ADAPTER)MiniportAdapterContext; if ( Adapter->SurpriseRemoved ) { DBGPRINT(DBG_WARNING, (L"[MRVL] in CheckForHang, card is removed, return FALSE directly\n") ); return FALSE; } if ( Adapter->SentPacket ) { Adapter->dwTxTimeoutCount ++; if ( Adapter->dwTxTimeoutCount > MRVDRV_TX_TIMEOUT_COUNT_THRESHOLD ) { DBGPRINT( DBG_ERROR, (L"Tx timeout!\n") ); Adapter->TxPktTimerIsSet=TRUE; NdisMSetTimer(&Adapter->MrvDrvTxPktTimer, 0); Adapter->dwTxTimeoutCount = 0; } } //012207 // We won't check in deepsleep, ps mode, HostSleep and D3 state. // In Deep Sleep Mode no packet can be sent out if( !IsThisDsState(Adapter, DS_STATE_NONE) ) return FALSE; if( (!IsThisHostPowerState(Adapter, HTWK_STATE_FULL_POWER)) || (Adapter->psState == PS_STATE_SLEEP) || (Adapter->CurPowerState != NdisDeviceStateD0) ) return FALSE; if ( Adapter->IntWARTimeoutCount ) AutoDeepSleepCounter(Adapter); else Adapter->AutoDsRec.timer = 0; //060407 flag to start auto deep sleep counter //This flag also used to interrupt missing. if(((++Adapter->IntWARTimeoutCount) & 0x1) == 0 ) return FALSE; //Adapter->IntWARTimeoutCount = 0; if( IsThisDsState(Adapter, DS_STATE_SLEEP) ) return FALSE; status = If_ReadRegister(Adapter, //SD_IO_READ , 1, // function 1 HCR_HOST_INT_STATUS_REGISTER, FALSE, &ucHostIntStatus, sizeof(ucHostIntStatus)); if (!SD_API_SUCCESS(status)) { DBGPRINT(DBG_ERROR, (L"Read error in CheckForHang()\r\n") ); return FALSE; } if( ucHostIntStatus & (UPLOAD_HOST_INT_STATUS_RDY | DOWNLOAD_HOST_INT_STATUS_RDY) ) { EnterCriticalSection(&Adapter->IntCriticalSection); Adapter->ucGHostIntStatus |= ucHostIntStatus; LeaveCriticalSection(&Adapter->IntCriticalSection); ucCardStatus = ~ucHostIntStatus; ucCardStatus &= 0x1f; status = If_WriteRegister(Adapter, //SD_IO_WRITE, 1, HCR_HOST_INT_STATUS_REGISTER, FALSE, &ucCardStatus, // reg sizeof(ucCardStatus)); if (!SD_API_SUCCESS(status)) { DBGPRINT(DBG_ISR,(L"Unable to clear Host interrupt status register\r\n")); return FALSE; } SetEvent(Adapter->hControllerInterruptEvent); } return FALSE; }