static s32 ReadInterrupt8723BSdio(struct adapter *adapter, u32 *phisr) { u32 hisr, himr; u8 val8, hisr_len; if (!phisr) return false; himr = GET_HAL_DATA(adapter)->sdio_himr; /* decide how many bytes need to be read */ hisr_len = 0; while (himr) { hisr_len++; himr >>= 8; } hisr = 0; while (hisr_len != 0) { hisr_len--; val8 = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HISR+hisr_len); hisr |= (val8 << (8*hisr_len)); } *phisr = hisr; return true; }
static s32 ReadInterrupt8723BSdio(PADAPTER padapter, u32 *phisr) { u32 hisr, himr; u8 val8, hisr_len; if (phisr == NULL) return _FALSE; himr = GET_HAL_DATA(padapter)->sdio_himr; // decide how many bytes need to be read hisr_len = 0; while (himr) { hisr_len++; himr >>= 8; } hisr = 0; while (hisr_len != 0) { hisr_len--; val8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR+hisr_len); hisr |= (val8 << (8*hisr_len)); } *phisr = hisr; return _TRUE; }
u8 HalQueryTxOQTBufferStatus8723BSdio(struct adapter *adapter) { struct hal_com_data *haldata = GET_HAL_DATA(adapter); haldata->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_OQT_FREE_PG); return true; }
void sd_int_dpc(struct adapter *adapter) { struct hal_com_data *hal; struct dvobj_priv *dvobj; struct intf_hdl *intfhdl = &adapter->iopriv.intf; struct pwrctrl_priv *pwrctl; hal = GET_HAL_DATA(adapter); dvobj = adapter_to_dvobj(adapter); pwrctl = dvobj_to_pwrctl(dvobj); if (hal->sdio_hisr & SDIO_HISR_AVAL) { u8 freepage[4]; _sdio_local_read(adapter, SDIO_REG_FREE_TXPG, 4, freepage); up(&(adapter->xmitpriv.xmit_sema)); } if (hal->sdio_hisr & SDIO_HISR_CPWM1) { struct reportpwrstate_parm report; u8 bcancelled; _cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled); report.state = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HCPWM1_8723B); /* cpwm_int_hdl(adapter, &report); */ _set_workitem(&(pwrctl->cpwm_event)); } if (hal->sdio_hisr & SDIO_HISR_TXERR) { u8 *status; u32 addr; status = rtw_malloc(4); if (status) { addr = REG_TXDMA_STATUS; HalSdioGetCmdAddr8723BSdio(adapter, WLAN_IOREG_DEVICE_ID, addr, &addr); _sd_read(intfhdl, addr, 4, status); _sd_write(intfhdl, addr, 4, status); DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32 *)status)); kfree(status); } else { DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__); } } if (hal->sdio_hisr & SDIO_HISR_TXBCNOK) { DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__); } if (hal->sdio_hisr & SDIO_HISR_TXBCNERR) { DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__); } #ifndef CONFIG_C2H_PACKET_EN if (hal->sdio_hisr & SDIO_HISR_C2HCMD) { struct c2h_evt_hdr_88xx *c2h_evt; DBG_8192C("%s: C2H Command\n", __func__); c2h_evt = rtw_zmalloc(16); if (c2h_evt != NULL) { if (rtw_hal_c2h_evt_read(adapter, (u8 *)c2h_evt) == _SUCCESS) { if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) { /* Handle CCX report here */ rtw_hal_c2h_handler(adapter, (u8 *)c2h_evt); kfree((u8 *)c2h_evt); } else { rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt); } } } else { /* Error handling for malloc fail */ if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, NULL) != _SUCCESS) DBG_871X("%s rtw_cbuf_push fail\n", __func__); _set_workitem(&adapter->evtpriv.c2h_wk); } } #endif if (hal->sdio_hisr & SDIO_HISR_RXFOVW) { DBG_8192C("%s: Rx Overflow\n", __func__); } if (hal->sdio_hisr & SDIO_HISR_RXERR) { DBG_8192C("%s: Rx Error\n", __func__); } if (hal->sdio_hisr & SDIO_HISR_RX_REQUEST) { struct recv_buf *recvbuf; int alloc_fail_time = 0; u32 hisr; /* DBG_8192C("%s: RX Request, size =%d\n", __func__, hal->SdioRxFIFOSize); */ hal->sdio_hisr ^= SDIO_HISR_RX_REQUEST; do { hal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(adapter, SDIO_REG_RX0_REQ_LEN); if (hal->SdioRxFIFOSize != 0) { recvbuf = sd_recv_rxfifo(adapter, hal->SdioRxFIFOSize); if (recvbuf) sd_rxhandler(adapter, recvbuf); else { alloc_fail_time++; DBG_871X("recvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time); if (alloc_fail_time >= 10) break; } hal->SdioRxFIFOSize = 0; } else break; hisr = 0; ReadInterrupt8723BSdio(adapter, &hisr); hisr &= SDIO_HISR_RX_REQUEST; if (!hisr) break; } while (1); if (alloc_fail_time == 10) DBG_871X("exit because alloc memory failed more than 10 times\n"); } }
static s32 rtl8723_dequeue_writeport(PADAPTER padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); struct xmit_buf *pxmitbuf; PADAPTER pri_padapter = padapter; u32 deviceId; u32 requiredPage; u8 PageIdx=0; u8 *freePage; _irqL irql; u32 n; s32 ret = 0; #ifdef CONFIG_CONCURRENT_MODE if (padapter->adapter_type > 0) pri_padapter = padapter->pbuddy_adapter; if (rtw_buddy_adapter_up(padapter)) ret = check_buddy_fwstate(padapter, _FW_UNDER_SURVEY); #endif ret = ret || check_fwstate(pmlmepriv, _FW_UNDER_SURVEY); if (_TRUE == ret) pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv); else pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv); if (pxmitbuf == NULL) return _TRUE; query_free_page: // check if hardware tx fifo page is enough if( _FALSE == rtl8723bs_query_tx_freepage(pri_padapter, pxmitbuf)) { rtw_msleep_os(1); goto query_free_page; } if ((padapter->bSurpriseRemoved == _TRUE) || (padapter->bDriverStopped == _TRUE) #ifdef CONFIG_CONCURRENT_MODE ||((padapter->pbuddy_adapter) && ((padapter->pbuddy_adapter->bSurpriseRemoved) ||(padapter->pbuddy_adapter->bDriverStopped))) #endif ) { RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: bSurpriseRemoved(wirte port)\n", __FUNCTION__)); goto free_xmitbuf; } #ifdef CONFIG_CHECK_LEAVE_LPS traffic_check_for_leave_lps(padapter, _TRUE, pxmitbuf->agg_num); #endif rtw_write_port(padapter, ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr), pxmitbuf->len, (u8 *)pxmitbuf); free_xmitbuf: //rtw_free_xmitframe(pxmitpriv, pframe); //pxmitbuf->priv_data = NULL; rtw_free_xmitbuf(pxmitpriv, pxmitbuf); #if 0 // improve TX/RX throughput balance { PSDIO_DATA psdio; struct sdio_func *func; static u8 i = 0; u32 sdio_hisr; u8 j; psdio = &adapter_to_dvobj(padapter)->intf_data; func = psdio->func; if (i == 2) { j = 0; while (j < 10) { sdio_hisr = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR); sdio_hisr &= GET_HAL_DATA(padapter)->sdio_himr; if (sdio_hisr & SDIO_HISR_RX_REQUEST) { sdio_claim_host(func); sd_int_hdl(pri_padapter); sdio_release_host(func); } else { break; } j++; } i = 0; } else { i++; } } #endif #ifdef CONFIG_SDIO_TX_TASKLET tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); #endif return _FAIL; }
// // Description: // Query SDIO Local register to get the current number of TX OQT Free Space. // u8 HalQueryTxOQTBufferStatus8723BSdio(PADAPTER padapter) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); pHalData->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_OQT_FREE_PG); return _TRUE; }
void sd_int_dpc(PADAPTER padapter) { PHAL_DATA_TYPE phal; struct dvobj_priv *dvobj; struct intf_hdl * pintfhdl=&padapter->iopriv.intf; struct pwrctrl_priv *pwrctl; phal = GET_HAL_DATA(padapter); dvobj = adapter_to_dvobj(padapter); pwrctl = dvobj_to_pwrctl(dvobj); #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT if (phal->sdio_hisr & SDIO_HISR_AVAL) { //_irqL irql; u8 freepage[4]; _sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 4, freepage); //_enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); //_rtw_memcpy(phal->SdioTxFIFOFreePage, freepage, 4); //_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); //DBG_871X("SDIO_HISR_AVAL, Tx Free Page = 0x%x%x%x%x\n", // freepage[0], // freepage[1], // freepage[2], // freepage[3]); _rtw_up_sema(&(padapter->xmitpriv.xmit_sema)); } #endif if (phal->sdio_hisr & SDIO_HISR_CPWM1) { struct reportpwrstate_parm report; #ifdef CONFIG_LPS_RPWM_TIMER u8 bcancelled; _cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled); #endif // CONFIG_LPS_RPWM_TIMER report.state = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HCPWM1_8723B); #ifdef CONFIG_LPS_LCLK //cpwm_int_hdl(padapter, &report); _set_workitem(&(pwrctl->cpwm_event)); #endif } if (phal->sdio_hisr & SDIO_HISR_TXERR) { u8 *status; u32 addr; status = rtw_malloc(4); if (status) { addr = REG_TXDMA_STATUS; HalSdioGetCmdAddr8723BSdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr); _sd_read(pintfhdl, addr, 4, status); _sd_write(pintfhdl, addr, 4, status); DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32*)status)); rtw_mfree(status, 4); } else { DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__); } } if (phal->sdio_hisr & SDIO_HISR_TXBCNOK) { DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__); } if (phal->sdio_hisr & SDIO_HISR_TXBCNERR) { DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__); } #ifndef CONFIG_C2H_PACKET_EN if (phal->sdio_hisr & SDIO_HISR_C2HCMD) { struct c2h_evt_hdr_88xx *c2h_evt; DBG_8192C("%s: C2H Command\n", __func__); if ((c2h_evt = (struct c2h_evt_hdr_88xx*)rtw_zmalloc(16)) != NULL) { if (rtw_hal_c2h_evt_read(padapter, (u8 *)c2h_evt) == _SUCCESS) { if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) { /* Handle CCX report here */ rtw_hal_c2h_handler(padapter, (u8 *)c2h_evt); rtw_mfree((u8*)c2h_evt, 16); } else { rtw_c2h_wk_cmd(padapter, (u8 *)c2h_evt); } } } else { /* Error handling for malloc fail */ if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, (void*)NULL) != _SUCCESS) DBG_871X("%s rtw_cbuf_push fail\n", __func__); _set_workitem(&padapter->evtpriv.c2h_wk); } } #endif if (phal->sdio_hisr & SDIO_HISR_RXFOVW) { DBG_8192C("%s: Rx Overflow\n", __func__); } if (phal->sdio_hisr & SDIO_HISR_RXERR) { DBG_8192C("%s: Rx Error\n", __func__); } if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST) { struct recv_buf *precvbuf; int alloc_fail_time=0; u32 hisr; // DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize); phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST; do { phal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN); if (phal->SdioRxFIFOSize != 0) { #ifdef CONFIG_MAC_LOOPBACK_DRIVER sd_recv_loopback(padapter, phal->SdioRxFIFOSize); #else precvbuf = sd_recv_rxfifo(padapter, phal->SdioRxFIFOSize); if (precvbuf) sd_rxhandler(padapter, precvbuf); else { alloc_fail_time++; DBG_871X("precvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time); if (alloc_fail_time >= 10) break; } phal->SdioRxFIFOSize = 0; #endif } else break; hisr = 0; ReadInterrupt8723BSdio(padapter, &hisr); hisr &= SDIO_HISR_RX_REQUEST; if (!hisr) break; } while (1); if(alloc_fail_time==10) DBG_871X("exit because alloc memory failed more than 10 times \n"); } }
// // Description: // This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC. // // Assumption: // We should follow specific format which was released from HW SD. // // 2011.07.07, added by Roger. // u8 HalPwrSeqCmdParsing( PADAPTER padapter, u8 CutVersion, u8 FabVersion, u8 InterfaceType, WLAN_PWR_CFG PwrSeqCmd[]) { WLAN_PWR_CFG PwrCfgCmd = {0}; u8 bPollingBit = _FALSE; u32 AryIdx = 0; u8 value = 0; u32 offset = 0; u32 pollingCount = 0; // polling autoload done. u32 maxPollingCnt = 5000; do { PwrCfgCmd = PwrSeqCmd[AryIdx]; RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: offset(%#x) cut_msk(%#x) fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) msk(%#x) value(%#x)\n", GET_PWR_CFG_OFFSET(PwrCfgCmd), GET_PWR_CFG_CUT_MASK(PwrCfgCmd), GET_PWR_CFG_FAB_MASK(PwrCfgCmd), GET_PWR_CFG_INTF_MASK(PwrCfgCmd), GET_PWR_CFG_BASE(PwrCfgCmd), GET_PWR_CFG_CMD(PwrCfgCmd), GET_PWR_CFG_MASK(PwrCfgCmd), GET_PWR_CFG_VALUE(PwrCfgCmd))); //2 Only Handle the command whose FAB, CUT, and Interface are matched if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) && (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) && (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)) { switch (GET_PWR_CFG_CMD(PwrCfgCmd)) { case PWR_CMD_READ: RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_READ\n")); break; case PWR_CMD_WRITE: RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_WRITE\n")); offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); #ifdef CONFIG_SDIO_HCI // // <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface // 2011.07.07. // if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) { // Read Back SDIO Local value value = SdioLocalCmd52Read1Byte(padapter, offset); value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd)); value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)); // Write Back SDIO Local value SdioLocalCmd52Write1Byte(padapter, offset, value); } else #endif { #ifdef CONFIG_GSPI_HCI if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) offset = SPI_LOCAL_OFFSET | offset; #endif // Read the value from system register value = rtw_read8(padapter, offset); value=value&(~(GET_PWR_CFG_MASK(PwrCfgCmd))); value=value|(GET_PWR_CFG_VALUE(PwrCfgCmd)&GET_PWR_CFG_MASK(PwrCfgCmd)); // Write the value back to sytem register rtw_write8(padapter, offset, value); } break; case PWR_CMD_POLLING: RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_POLLING\n")); bPollingBit = _FALSE; offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); #ifdef CONFIG_GSPI_HCI if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) offset = SPI_LOCAL_OFFSET | offset; #endif do { #ifdef CONFIG_SDIO_HCI if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) value = SdioLocalCmd52Read1Byte(padapter, offset); else #endif value = rtw_read8(padapter, offset); value=value&GET_PWR_CFG_MASK(PwrCfgCmd); if (value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd))) bPollingBit = _TRUE; else rtw_udelay_os(10); if (pollingCount++ > maxPollingCnt) { DBG_871X("Fail to polling Offset[%#x]=%02x\n", offset, value); return _FALSE; } } while (!bPollingBit); break; case PWR_CMD_DELAY: RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_DELAY\n")); if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US) rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd)); else rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000); break; case PWR_CMD_END: // When this command is parsed, end the process RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_END\n")); return _TRUE; break; default: RT_TRACE(_module_hal_init_c_ , _drv_err_, ("HalPwrSeqCmdParsing: Unknown CMD!!\n")); break; } } AryIdx++;//Add Array Index }while(1); return _TRUE; }
/* * Description: * This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC. * * Assumption: * We should follow specific format which was released from HW SD. * * 2011.07.07, added by Roger. * */ u8 HalPwrSeqCmdParsing( PADAPTER padapter, u8 CutVersion, u8 FabVersion, u8 InterfaceType, WLAN_PWR_CFG PwrSeqCmd[]) { WLAN_PWR_CFG PwrCfgCmd = {0}; u8 bPollingBit = _FALSE; u32 AryIdx = 0; u8 value = 0; u32 offset = 0; u32 pollingCount = 0; /* polling autoload done. */ u32 maxPollingCnt = 5000; do { PwrCfgCmd = PwrSeqCmd[AryIdx]; /* 2 Only Handle the command whose FAB, CUT, and Interface are matched */ if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) && (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) && (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)) { switch (GET_PWR_CFG_CMD(PwrCfgCmd)) { case PWR_CMD_READ: break; case PWR_CMD_WRITE: offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); #ifdef CONFIG_SDIO_HCI /* */ /* <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface */ /* 2011.07.07. */ /* */ if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) { /* Read Back SDIO Local value */ value = SdioLocalCmd52Read1Byte(padapter, offset); value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd)); value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)); /* Write Back SDIO Local value */ SdioLocalCmd52Write1Byte(padapter, offset, value); } else #endif { #ifdef CONFIG_GSPI_HCI if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) offset = SPI_LOCAL_OFFSET | offset; #endif /* Read the value from system register */ value = rtw_read8(padapter, offset); value = value & (~(GET_PWR_CFG_MASK(PwrCfgCmd))); value = value | (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)); /* Write the value back to sytem register */ rtw_write8(padapter, offset, value); } break; case PWR_CMD_POLLING: bPollingBit = _FALSE; offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); #ifdef CONFIG_GSPI_HCI if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) offset = SPI_LOCAL_OFFSET | offset; #endif do { #ifdef CONFIG_SDIO_HCI if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) value = SdioLocalCmd52Read1Byte(padapter, offset); else #endif value = rtw_read8(padapter, offset); value = value & GET_PWR_CFG_MASK(PwrCfgCmd); if (value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd))) bPollingBit = _TRUE; else rtw_udelay_os(10); if (pollingCount++ > maxPollingCnt) { RTW_ERR("HalPwrSeqCmdParsing: Fail to polling Offset[%#x]=%02x\n", offset, value); return _FALSE; } } while (!bPollingBit); break; case PWR_CMD_DELAY: if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US) rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd)); else rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd) * 1000); break; case PWR_CMD_END: /* When this command is parsed, end the process */ return _TRUE; break; default: break; } } AryIdx++;/* Add Array Index */ } while (1); return _TRUE; }
// // Description: // This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC. // // Assumption: // We should follow specific format which was released from HW SD. // // 2011.07.07, added by Roger. // unsigned int HalPwrSeqCmdParsing(struct rtl8192cd_priv *priv, unsigned char CutVersion, unsigned char FabVersion, unsigned char InterfaceType, WLAN_PWR_CFG PwrSeqCmd[]) { WLAN_PWR_CFG PwrCfgCmd = {0}; unsigned int bPollingBit = FALSE; unsigned int AryIdx=0; unsigned char value = 0; unsigned int offset = 0; unsigned int pollingCount = 0; // polling autoload done. unsigned int maxPollingCnt = 5000; do { PwrCfgCmd=PwrSeqCmd[AryIdx]; DEBUG_INFO("%s %d, ENTRY, offset:0x%x, cut_msk:0x%x, fab_msk:0x%x, if_msk:0x%x, base:0x%x, cmd:0x%x, msk:0x%x, value:0x%x\n", __FUNCTION__, __LINE__, GET_PWR_CFG_OFFSET(PwrCfgCmd), GET_PWR_CFG_CUT_MASK(PwrCfgCmd), GET_PWR_CFG_FAB_MASK(PwrCfgCmd), GET_PWR_CFG_INTF_MASK(PwrCfgCmd), GET_PWR_CFG_BASE(PwrCfgCmd), GET_PWR_CFG_CMD(PwrCfgCmd), GET_PWR_CFG_MASK(PwrCfgCmd), GET_PWR_CFG_VALUE(PwrCfgCmd)); //2 Only Handle the command whose FAB, CUT, and Interface are matched if((GET_PWR_CFG_FAB_MASK(PwrCfgCmd)&FabVersion)&& (GET_PWR_CFG_CUT_MASK(PwrCfgCmd)&CutVersion)&& (GET_PWR_CFG_INTF_MASK(PwrCfgCmd)&InterfaceType)) { switch(GET_PWR_CFG_CMD(PwrCfgCmd)) { case PWR_CMD_READ: DEBUG_INFO("%s %d, PWR_CMD_READ\n", __FUNCTION__, __LINE__); break; case PWR_CMD_WRITE: DEBUG_INFO("%s %d, PWR_CMD_WRITE\n", __FUNCTION__, __LINE__); offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); #ifdef CONFIG_SDIO_HCI // // <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface // 2011.07.07. // if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) { // Read Back SDIO Local value value = SdioLocalCmd52Read1Byte(priv, offset); value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd)); value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)); // Write Back SDIO Local value SdioLocalCmd52Write1Byte(priv, offset, value); } else #endif { //Read the value from system register value = RTL_R8(offset); value = value&(~(GET_PWR_CFG_MASK(PwrCfgCmd))); value = value|(GET_PWR_CFG_VALUE(PwrCfgCmd)&GET_PWR_CFG_MASK(PwrCfgCmd)); //Write the value back to sytem register RTL_W8(offset, value); } break; case PWR_CMD_POLLING: DEBUG_INFO("%s %d, PWR_CMD_POLLING\n", __FUNCTION__, __LINE__); bPollingBit = FALSE; offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); do { #ifdef CONFIG_SDIO_HCI if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) value = SdioLocalCmd52Read1Byte(priv, offset); else #endif value = RTL_R8(offset); value=value&GET_PWR_CFG_MASK(PwrCfgCmd); if(value==(GET_PWR_CFG_VALUE(PwrCfgCmd)&GET_PWR_CFG_MASK(PwrCfgCmd))) bPollingBit=TRUE; else delay_us(10); if(pollingCount++ > maxPollingCnt){ DEBUG_WARN("%s %d, PWR_CMD_POLLING, Fail to polling Offset[0x%x]\n", __FUNCTION__, __LINE__, offset); return FALSE; } }while(!bPollingBit); break; case PWR_CMD_DELAY: DEBUG_INFO("%s %d, PWR_CMD_DELAY\n", __FUNCTION__, __LINE__); if(GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US) delay_us(GET_PWR_CFG_OFFSET(PwrCfgCmd)); else delay_us(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000); break; case PWR_CMD_END: // When this command is parsed, end the process DEBUG_INFO("%s %d, PWR_CMD_END\n", __FUNCTION__, __LINE__); return TRUE; break; default: DEBUG_ERR("%s %d, Unknown CMD!!\n", __FUNCTION__, __LINE__); break; } } AryIdx++;//Add Array Index }while(1); return TRUE; }
void sd_int_dpc(PADAPTER padapter) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct intf_hdl * pintfhdl=&padapter->iopriv.intf; if (pHalData->sdio_hisr & SDIO_HISR_CPWM1) { struct reportpwrstate_parm report; #ifdef CONFIG_USING_CMD52_READ_INT report.state = SdioLocalCmd52Read1Byte(padapter,SDIO_REG_HCPWM1); #else //CONFIG_USING_CMD52_READ_INT _sdio_local_read(padapter, SDIO_REG_HCPWM1, 1, &report.state); #endif #ifdef CONFIG_LPS_LCLK //88e's cpwm value only change BIT0, so driver need to add PS_STATE_S2 for LPS flow. //modify by Thomas. 2012/4/2. #ifdef CONFIG_EXT_CLK //for sprd if(report.state & BIT(4)) //indicate FW entering 32k { u8 chk_cnt = 0; do{ if(_sdio_read8(padapter, 0x90)&BIT(0))//FW in 32k already { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); if(pwrpriv->rpwm < PS_STATE_S2) { //DBG_871X("disable ext clk when FW in LPS-32K already!\n"); EnableGpio5ClockReq(padapter, _TRUE, 0); } break; } chk_cnt++; }while(chk_cnt<10); if(chk_cnt==10) { DBG_871X("polling fw in 32k already, fail!\n"); } } else //indicate fw leaving 32K #endif //CONFIG_EXT_CLK { report.state |= PS_STATE_S2; //cpwm_int_hdl(padapter, &report); _set_workitem(&(adapter_to_pwrctl(padapter)->cpwm_event)); } #endif } #ifdef CONFIG_WOWLAN if (pHalData->sdio_hisr & SDIO_HISR_CPWM2) { u32 value; value = rtw_read32(padapter, SDIO_LOCAL_BASE+SDIO_REG_HISR); DBG_871X_LEVEL(_drv_always_, "Reset SDIO HISR(0x%08x) original:0x%08x\n", SDIO_LOCAL_BASE+SDIO_REG_HISR, value); value |= BIT19; rtw_write32(padapter, SDIO_LOCAL_BASE+SDIO_REG_HISR, value); value = rtw_read8(padapter, SDIO_LOCAL_BASE+SDIO_REG_HIMR+2); DBG_871X_LEVEL(_drv_always_, "Reset SDIO HIMR CPWM2(0x%08x) original:0x%02x\n", SDIO_LOCAL_BASE+SDIO_REG_HIMR + 2, value); } #endif if (pHalData->sdio_hisr & SDIO_HISR_TXERR) { u8 *status; u32 addr; status = rtw_malloc(4); if (status) { addr = REG_TXDMA_STATUS; HalSdioGetCmdAddr8723ASdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr); _sd_read(pintfhdl, addr, 4, status); _sd_write(pintfhdl, addr, 4, status); DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32*)status)); rtw_mfree(status, 4); } else { DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__); } } #ifdef CONFIG_INTERRUPT_BASED_TXBCN #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT) #endif #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR if (pHalData->sdio_hisr & (SDIO_HISR_TXBCNOK|SDIO_HISR_TXBCNERR)) #endif { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; #if 0 //for debug if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT) DBG_8192C("%s: SDIO_HISR_BCNERLY_INT\n", __func__); if (pHalData->sdio_hisr & SDIO_HISR_TXBCNOK) DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__); if (pHalData->sdio_hisr & SDIO_HISR_TXBCNERR) DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__); #endif if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) { //send_beacon(padapter); if(pmlmepriv->update_bcn == _TRUE) { //tx_beacon_hdl(padapter, NULL); set_tx_beacon_cmd(padapter); } } #ifdef CONFIG_CONCURRENT_MODE if(check_buddy_fwstate(padapter, WIFI_AP_STATE)) { //send_beacon(padapter); if(padapter->pbuddy_adapter->mlmepriv.update_bcn == _TRUE) { //tx_beacon_hdl(padapter, NULL); set_tx_beacon_cmd(padapter->pbuddy_adapter); } } #endif } #endif //CONFIG_INTERRUPT_BASED_TXBCN #ifdef CONFIG_EXT_CLK if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if(check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { //DBG_8192C("BCNERLY_INT for enabling ext clk\n"); EnableGpio5ClockReq(padapter, _TRUE, 1); } } #endif //CONFIG_EXT_CLK if (pHalData->sdio_hisr & SDIO_HISR_C2HCMD) { DBG_8192C("%s: C2H Command\n", __func__); } if (pHalData->sdio_hisr & SDIO_HISR_RX_REQUEST) { struct recv_buf *precvbuf; #ifdef CONFIG_USING_CMD52_READ_INT u32 hisr; //DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize); pHalData->sdio_hisr ^= SDIO_HISR_RX_REQUEST; #ifdef CONFIG_MAC_LOOPBACK_DRIVER sd_recv_loopback(padapter, pHalData->SdioRxFIFOSize); #else do { pHalData->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN); if(pHalData->SdioRxFIFOSize != 0) { precvbuf = sd_recv_rxfifo(padapter, pHalData->SdioRxFIFOSize); pHalData->SdioRxFIFOSize = 0; if (precvbuf) sd_rxhandler(padapter, precvbuf); else break; } else { DBG_871X("%s, WARNING!!, SdioRxFIFOSize = 0!!\n", __func__); break; } hisr = 0; ReadInterrupt8188ESdio(padapter, &hisr); hisr &= SDIO_HISR_RX_REQUEST; if (!hisr) break; #ifdef CONFIG_SDIO_DISABLE_RXFIFO_POLLING_LOOP } while (0); #else } while (1); #endif //CONFIG_SDIO_DISABLE_RXFIFO_POLLING_LOOP #endif //CONFIG_MAC_LOOPBACK_DRIVER #else //!CONFIG_USING_CMD52_READ_INT //DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize); pHalData->sdio_hisr ^= SDIO_HISR_RX_REQUEST; #ifdef CONFIG_MAC_LOOPBACK_DRIVER sd_recv_loopback(padapter, pHalData->SdioRxFIFOSize); #else do { //Sometimes rx length will be zero. driver need to use cmd53 read again. if(pHalData->SdioRxFIFOSize == 0) { u8 data[4]; _sdio_local_read(padapter, SDIO_REG_RX0_REQ_LEN, 4, data); pHalData->SdioRxFIFOSize = le16_to_cpu(*(u16*)data); } if(pHalData->SdioRxFIFOSize) { precvbuf = sd_recv_rxfifo(padapter, pHalData->SdioRxFIFOSize); pHalData->SdioRxFIFOSize = 0; if (precvbuf) sd_rxhandler(padapter, precvbuf); else break; } else break; #ifdef CONFIG_SDIO_DISABLE_RXFIFO_POLLING_LOOP } while (0); #else } while (1);
u8 HalPwrSeqCmdParsing( struct adapter *padapter, u8 CutVersion, u8 FabVersion, u8 InterfaceType, WLAN_PWR_CFG PwrSeqCmd[] ) { WLAN_PWR_CFG PwrCfgCmd = {0}; u8 bPollingBit = false; u32 AryIdx = 0; u8 value = 0; u32 offset = 0; u32 pollingCount = 0; /* polling autoload done. */ u32 maxPollingCnt = 5000; do { PwrCfgCmd = PwrSeqCmd[AryIdx]; RT_TRACE( _module_hal_init_c_, _drv_info_, ( "HalPwrSeqCmdParsing: offset(%#x) cut_msk(%#x) fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) msk(%#x) value(%#x)\n", GET_PWR_CFG_OFFSET(PwrCfgCmd), GET_PWR_CFG_CUT_MASK(PwrCfgCmd), GET_PWR_CFG_FAB_MASK(PwrCfgCmd), GET_PWR_CFG_INTF_MASK(PwrCfgCmd), GET_PWR_CFG_BASE(PwrCfgCmd), GET_PWR_CFG_CMD(PwrCfgCmd), GET_PWR_CFG_MASK(PwrCfgCmd), GET_PWR_CFG_VALUE(PwrCfgCmd) ) ); /* 2 Only Handle the command whose FAB, CUT, and Interface are matched */ if ( (GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) && (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) && (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType) ) { switch (GET_PWR_CFG_CMD(PwrCfgCmd)) { case PWR_CMD_READ: RT_TRACE( _module_hal_init_c_, _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_READ\n") ); break; case PWR_CMD_WRITE: RT_TRACE( _module_hal_init_c_, _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_WRITE\n") ); offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); /* */ /* <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface */ /* 2011.07.07. */ /* */ if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) { /* Read Back SDIO Local value */ value = SdioLocalCmd52Read1Byte(padapter, offset); value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd)); value |= ( GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd) ); /* Write Back SDIO Local value */ SdioLocalCmd52Write1Byte(padapter, offset, value); } else { /* Read the value from system register */ value = rtw_read8(padapter, offset); value &= (~(GET_PWR_CFG_MASK(PwrCfgCmd))); value |= ( GET_PWR_CFG_VALUE(PwrCfgCmd) &GET_PWR_CFG_MASK(PwrCfgCmd) ); /* Write the value back to sytem register */ rtw_write8(padapter, offset, value); } break; case PWR_CMD_POLLING: RT_TRACE( _module_hal_init_c_, _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_POLLING\n") ); bPollingBit = false; offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); do { if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) value = SdioLocalCmd52Read1Byte(padapter, offset); else value = rtw_read8(padapter, offset); value = value&GET_PWR_CFG_MASK(PwrCfgCmd); if ( value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)) ) bPollingBit = true; else udelay(10); if (pollingCount++ > maxPollingCnt) { DBG_871X( "Fail to polling Offset[%#x]=%02x\n", offset, value ); return false; } } while (!bPollingBit); break; case PWR_CMD_DELAY: RT_TRACE( _module_hal_init_c_, _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_DELAY\n") ); if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US) udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd)); else udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000); break; case PWR_CMD_END: /* When this command is parsed, end the process */ RT_TRACE( _module_hal_init_c_, _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_END\n") ); return true; default: RT_TRACE( _module_hal_init_c_, _drv_err_, ("HalPwrSeqCmdParsing: Unknown CMD!!\n") ); break; } } AryIdx++;/* Add Array Index */ } while (1); return true; }