/*------------------------------------------- | Name:dev_sd_read | Description: | Parameters: | Return Type: | Comments: | See: ---------------------------------------------*/ int dev_sd_read(desc_t desc, char* buf,int cb) { int dev_current_addr = 0; kernel_pthread_mutex_lock(&g_sd_mutex); dev_current_addr = (int)ofile_lst[desc].offset; if(cb > SD_BUFFER_SIZE_NO_CACHE_RCV) { cb = SD_BUFFER_SIZE_NO_CACHE_RCV; } if ((dev_current_addr + (long)cb) > ((board_inf_sd_t *)ofile_lst[desc].p)->total_size) { if(!(cb = ((board_inf_sd_t *)ofile_lst[desc].p)->total_size-dev_current_addr)) kernel_pthread_mutex_unlock(&g_sd_mutex); return 0; //end of device. } // Call sdcard driver if(_sd_read(desc, buf, cb, 0) != 0) { kernel_pthread_mutex_unlock(&g_sd_mutex); return -1; } dev_current_addr += cb; ofile_lst[desc].offset = dev_current_addr; kernel_pthread_mutex_unlock(&g_sd_mutex); return cb; }
/* * Description: * Read from RX FIFO * Round read size to block size, * and make sure data transfer will be done in one command. * * Parameters: * pintfhdl a pointer of intf_hdl * addr port ID * cnt size to read * rmem address to put data * * Return: * _SUCCESS(1) Success * _FAIL(0) Fail */ static u32 sdio_read_port( struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *mem) { PADAPTER padapter = pintfhdl->padapter; PSDIO_DATA psdio= &adapter_to_dvobj(padapter)->intf_data; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); s32 err; HalSdioGetCmdAddr8723ASdio(padapter, addr, pHalData->SdioRxFIFOCnt++, &addr); cnt = _RND4(cnt); if (cnt > psdio->block_transfer_len) cnt = _RND(cnt, psdio->block_transfer_len); // cnt = sdio_align_size(cnt); err = _sd_read(pintfhdl, addr, cnt, mem); //err = sd_read(pintfhdl, addr, cnt, mem); if (err) return _FAIL; return _SUCCESS; }
/* * Use CMD53 to read data from SDIO device. * * Parameters: *psdio pointer of SDIO_DATA *addr address to read *cnt amount to read *pdata pointer to put data, this should be a "DMA:able scratch buffer"! * * Return: *0 Success *others Fail */ s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) { struct adapter *padapter; struct dvobj_priv *psdiodev; PSDIO_DATA psdio; struct sdio_func *func; bool claim_needed; s32 err = -EPERM; padapter = pintfhdl->padapter; psdiodev = pintfhdl->pintf_dev; psdio = &psdiodev->intf_data; if (padapter->bSurpriseRemoved) { /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ return err; } func = psdio->func; claim_needed = rtw_sdio_claim_host_needed(func); if (claim_needed) sdio_claim_host(func); err = _sd_read(pintfhdl, addr, cnt, pdata); if (claim_needed) sdio_release_host(func); return err; }
/* * Todo: align address to 4 bytes. */ static s32 _sdio_local_read( struct adapter *adapter, u32 addr, u32 cnt, u8 *buf ) { struct intf_hdl *intfhdl; u8 mac_pwr_ctrl_on; s32 err; u8 *tmpbuf; u32 n; intfhdl = &adapter->iopriv.intf; HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on); if (!mac_pwr_ctrl_on) return _sd_cmd52_read(intfhdl, addr, cnt, buf); n = RND4(cnt); tmpbuf = rtw_malloc(n); if (!tmpbuf) return (-1); err = _sd_read(intfhdl, addr, n, tmpbuf); if (!err) memcpy(buf, tmpbuf, cnt); kfree(tmpbuf); return err; }
/* * Use CMD53 to read data from SDIO device. * * Parameters: * psdio pointer of SDIO_DATA * addr address to read * cnt amount to read * pdata pointer to put data, this should be a "DMA:able scratch buffer"! * * Return: * 0 Success * others Fail */ s32 sd_read(struct intf_hdl * pintfhdl, u32 addr, u32 cnt, void *pdata) { PADAPTER padapter; struct dvobj_priv *psdiodev; PSDIO_DATA psdio; struct sdio_func *func; bool claim_needed; s32 err= -EPERM; _func_enter_; padapter = pintfhdl->padapter; psdiodev = pintfhdl->pintf_dev; psdio = &psdiodev->intf_data; if(padapter->bSurpriseRemoved){ //DBG_871X(" %s (padapter->bSurpriseRemoved )!!!\n",__FUNCTION__); return err; } func = psdio->func; claim_needed = rtw_sdio_claim_host_needed(func); if (claim_needed) sdio_claim_host(func); err = _sd_read(pintfhdl, addr, cnt, pdata); if (claim_needed) sdio_release_host(func); _func_exit_; return err; }
/* * Description: * Read from RX FIFO * Round read size to block size, * and make sure data transfer will be done in one command. * * Parameters: * pintfhdl a pointer of intf_hdl * addr port ID * cnt size to read * rmem address to put data * * Return: * _SUCCESS(1) Success * _FAIL(0) Fail */ static u32 sdio_read_port( struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *mem) { PADAPTER padapter; PSDIO_DATA psdio; PHAL_DATA_TYPE phal; u32 oldcnt; #ifdef SDIO_DYNAMIC_ALLOC_MEM u8 *oldmem; #endif s32 err; padapter = pintfhdl->padapter; psdio = &adapter_to_dvobj(padapter)->intf_data; phal = GET_HAL_DATA(padapter); HalSdioGetCmdAddr8723BSdio(padapter, addr, phal->SdioRxFIFOCnt++, &addr); oldcnt = cnt; if (cnt > psdio->block_transfer_len) cnt = _RND(cnt, psdio->block_transfer_len); // cnt = sdio_align_size(cnt); if (oldcnt != cnt) { #ifdef SDIO_DYNAMIC_ALLOC_MEM oldmem = mem; mem = rtw_malloc(cnt); if (mem == NULL) { DBG_8192C(KERN_WARNING "%s: allocate memory %d bytes fail!\n", __func__, cnt); mem = oldmem; oldmem == NULL; } #else // in this case, caller should gurante the buffer is big enough // to receive data after alignment #endif } err = _sd_read(pintfhdl, addr, cnt, mem); #ifdef SDIO_DYNAMIC_ALLOC_MEM if ((oldcnt != cnt) && (oldmem)) { _rtw_memcpy(oldmem, mem, oldcnt); rtw_mfree(mem, cnt); } #endif if (err) return _FAIL; return _SUCCESS; }
/* * Use CMD53 to read data from SDIO device. * * Parameters: * psdio pointer of SDIO_DATA * addr address to read * cnt amount to read * pdata pointer to put data, this should be a "DMA:able scratch buffer"! * * Return: * 0 Success * others Fail */ s32 sd_read(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata) { s32 err; struct sdio_func *func; func = psdio->func; sdio_claim_host(func); err = _sd_read(psdio, addr, cnt, pdata); sdio_release_host(func); return err; }
/* * Use CMD53 to read data from SDIO device. * * Parameters: * psdio pointer of SDIO_DATA * addr address to read * cnt amount to read * pdata pointer to put data, this should be a "DMA:able scratch buffer"! * * Return: * 0 Success * others Fail */ s32 sd_read(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata) { s32 err; struct sdio_func *func; bool claim_needed; func = psdio->func; claim_needed = rtw_sdio_claim_host_needed(func); if (claim_needed) sdio_claim_host(func); err = _sd_read(psdio, addr, cnt, pdata); if (claim_needed) sdio_release_host(func); return err; }
/* * Todo: align address to 4 bytes. */ s32 _sdio_local_read( PADAPTER padapter, u32 addr, u32 cnt, u8 *pbuf) { PSDIO_DATA psdio; u8 bMacPwrCtrlOn; s32 err; u8 *ptmpbuf; u32 n; psdio = &adapter_to_dvobj(padapter)->intf_data; HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); if ((_FALSE == bMacPwrCtrlOn) #ifdef CONFIG_LPS_LCLK // || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode) #endif ) { err = _sd_cmd52_read(psdio, addr, cnt, pbuf); return err; } n = RND4(cnt); ptmpbuf = (u8*)rtw_malloc(n); if(!ptmpbuf) return (-1); err = _sd_read(psdio, addr, n, ptmpbuf); if (!err) _rtw_memcpy(pbuf, ptmpbuf, cnt); if(ptmpbuf) rtw_mfree(ptmpbuf, n); return err; }
/* * Description: *Read from RX FIFO *Round read size to block size, *and make sure data transfer will be done in one command. * * Parameters: *intfhdl a pointer of intf_hdl *addr port ID *cnt size to read *rmem address to put data * * Return: *_SUCCESS(1) Success *_FAIL(0) Fail */ static u32 sdio_read_port( struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *mem ) { struct adapter *adapter; PSDIO_DATA psdio; struct hal_com_data *hal; u32 oldcnt; #ifdef SDIO_DYNAMIC_ALLOC_MEM u8 *oldmem; #endif s32 err; adapter = intfhdl->padapter; psdio = &adapter_to_dvobj(adapter)->intf_data; hal = GET_HAL_DATA(adapter); HalSdioGetCmdAddr8723BSdio(adapter, addr, hal->SdioRxFIFOCnt++, &addr); oldcnt = cnt; if (cnt > psdio->block_transfer_len) cnt = _RND(cnt, psdio->block_transfer_len); /* cnt = sdio_align_size(cnt); */ err = _sd_read(intfhdl, addr, cnt, mem); #ifdef SDIO_DYNAMIC_ALLOC_MEM if ((oldcnt != cnt) && (oldmem)) { memcpy(oldmem, mem, oldcnt); kfree(mem); } #endif if (err) return _FAIL; return _SUCCESS; }
/* * Todo: align address to 4 bytes. */ s32 _sdio_local_read( PADAPTER padapter, u32 addr, u32 cnt, u8 *pbuf) { struct intf_hdl * pintfhdl; u8 bMacPwrCtrlOn; s32 err; u8 *ptmpbuf; u32 n; pintfhdl=&padapter->iopriv.intf; HalSdioGetCmdAddr8195ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); // rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); // if ((_FALSE == bMacPwrCtrlOn) // #ifdef CONFIG_LPS_LCLK // // || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) // #endif // ) // { // err = _sd_cmd52_read(pintfhdl, addr, cnt, pbuf); // return err; // } n = RND4(cnt); ptmpbuf = (u8*)rtw_malloc(n); if(!ptmpbuf) return (-1); err = _sd_read(pintfhdl, addr, n, ptmpbuf); if (!err) _rtw_memcpy(pbuf, ptmpbuf, cnt); if(ptmpbuf) rtw_mfree(ptmpbuf, n); return err; }
/* * Todo: align address to 4 bytes. */ s32 _sdio_local_read( PADAPTER padapter, u32 addr, u32 cnt, u8 *pbuf) { struct intf_hdl * pintfhdl; u8 bMacPwrCtrlOn; s32 err; u8 *ptmpbuf; u32 n; pintfhdl=&padapter->iopriv.intf; HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); if (_FALSE == bMacPwrCtrlOn) { err = _sd_cmd52_read(pintfhdl, addr, cnt, pbuf); return err; } n = RND4(cnt); ptmpbuf = (u8*)rtw_malloc(n); if (!ptmpbuf) return (-1); err = _sd_read(pintfhdl, addr, n, ptmpbuf); if (!err) _rtw_memcpy(pbuf, ptmpbuf, cnt); if (ptmpbuf) rtw_mfree(ptmpbuf, n); return err; }
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"); } }
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"); } }
void sd_int_dpc(PADAPTER padapter) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct intf_hdl * pintfhdl=&padapter->iopriv.intf; #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT if (pHalData->sdio_hisr & SDIO_HISR_AVAL) { //_irqL irql; u8 freepage[4]; _sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 4, freepage); //_enter_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql); //_rtw_memcpy(pHalData->SdioTxFIFOFreePage, freepage, 4); //_exit_critical_bh(&pHalData->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 (pHalData->sdio_hisr & SDIO_HISR_CPWM1) { struct reportpwrstate_parm report; #ifdef CONFIG_LPS_RPWM_TIMER u8 bcancelled; _cancel_timer(&(adapter_to_pwrctl(padapter)->pwr_rpwm_timer), &bcancelled); #endif // CONFIG_LPS_RPWM_TIMER _sdio_local_read(padapter, SDIO_REG_HCPWM1, 1, &report.state); #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 { 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(&(pwrpriv->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; //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); #endif #endif }
void sd_int_dpc(PADAPTER padapter) { HAL_DATA_TYPE *phal; struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); phal = GET_HAL_DATA(padapter); if (phal->sdio_hisr & SDIO_HISR_CPWM1) { struct reportpwrstate_parm report; #ifdef CONFIG_LPS_RPWM_TIMER u8 bcancelled; _cancel_timer(&padapter->pwrctrlpriv.pwr_rpwm_timer, &bcancelled); #endif // CONFIG_LPS_RPWM_TIMER _sdio_local_read(padapter, SDIO_REG_HCPWM1, 1, &report.state); #ifdef CONFIG_LPS_LCLK //cpwm_int_hdl(padapter, &report); _set_workitem(&padapter->pwrctrlpriv.cpwm_event); #endif } if (phal->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(&dvobj->intf_data, addr, 4, status); _sd_write(&dvobj->intf_data, 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__); } if (phal->sdio_hisr & SDIO_HISR_C2HCMD) { struct c2h_evt_hdr *c2h_evt; if ((c2h_evt = (struct c2h_evt_hdr *)rtw_zmalloc(16)) != NULL) { if (c2h_evt_read(padapter, (u8 *)c2h_evt) == _SUCCESS) { if (c2h_id_filter_ccx_8723a(c2h_evt->id)) { /* Handle CCX report here */ rtw_hal_c2h_handler(padapter, c2h_evt); rtw_mfree((u8*)c2h_evt, 16); } else { rtw_c2h_wk_cmd(padapter, (u8 *)c2h_evt); } } else { rtw_mfree((u8*)c2h_evt, 16); } } 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); } } if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST) { struct recv_buf *precvbuf; u16 val=0; // DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize); phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST; do{ if (phal->SdioRxFIFOSize == 0) { _sdio_local_read(padapter, SDIO_REG_RX0_REQ_LEN, 2, (u8*)&val); phal->SdioRxFIFOSize = le16_to_cpu(val); DBG_8192C("%s: RX_REQUEST, read RXFIFOsize again size=%d\n", __func__, phal->SdioRxFIFOSize); } 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 break; #endif } _sdio_local_read(padapter, SDIO_REG_RX0_REQ_LEN, 2, (u8*)&val); phal->SdioRxFIFOSize = le16_to_cpu(val); }while(phal->SdioRxFIFOSize !=0); } }
u32 _sdio_read32(PADAPTER padapter, u32 addr) { //PADAPTER padapter; struct intf_hdl * pintfhdl; u8 bMacPwrCtrlOn; u8 deviceId; u16 offset; u32 ftaddr; u8 shift; u32 val; s32 err; _func_enter_; //padapter = pintfhdl->padapter; //psdiodev = pintfhdl->pintf_dev; pintfhdl=&padapter->iopriv.intf; ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || (_FALSE == bMacPwrCtrlOn) #ifdef CONFIG_LPS_LCLK || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) #endif ) { err = _sd_cmd52_read(pintfhdl, ftaddr, 4, (u8*)&val); #ifdef SDIO_DEBUG_IO if (!err) { #endif val = le32_to_cpu(val); return val; #ifdef SDIO_DEBUG_IO } DBG_871X(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, err, addr); return SDIO_ERR_VAL32; #endif } // 4 bytes alignment shift = ftaddr & 0x3; if (shift == 0) { val = _sd_read32(pintfhdl, ftaddr, NULL); } else { u8 *ptmpbuf; ptmpbuf = (u8*)rtw_malloc(8); if (NULL == ptmpbuf) { DBG_871X(KERN_ERR "%s: Allocate memory FAIL!(size=8) addr=0x%x\n", __func__, addr); return SDIO_ERR_VAL32; } ftaddr &= ~(u16)0x3; _sd_read(pintfhdl, ftaddr, 8, ptmpbuf); _rtw_memcpy(&val, ptmpbuf+shift, 4); val = le32_to_cpu(val); rtw_mfree(ptmpbuf, 8); } _func_exit_; return val; }
void sd_int_dpc(PADAPTER padapter) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); if (pHalData->sdio_hisr & SDIO_HISR_CPWM1) { struct reportpwrstate_parm report; _sdio_local_read(padapter, SDIO_REG_HCPWM1, 1, &report.state); #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. report.state |= PS_STATE_S2; //cpwm_int_hdl(padapter, &report); _set_workitem(&padapter->pwrctrlpriv.cpwm_event); #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(&padapter->dvobjpriv.intf_data, addr, 4, status); _sd_write(&padapter->dvobjpriv.intf_data, addr, 4, status); printk("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32*)status)); _rtw_mfree(status, 4); } else { printk("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__); } } if (pHalData->sdio_hisr & SDIO_HISR_TXBCNOK) { printk("%s: SDIO_HISR_TXBCNOK\n", __func__); } if (pHalData->sdio_hisr & SDIO_HISR_TXBCNERR) { printk("%s: SDIO_HISR_TXBCNERR\n", __func__); } if (pHalData->sdio_hisr & SDIO_HISR_C2HCMD) { printk("%s: C2H Command\n", __func__); } if (pHalData->sdio_hisr & SDIO_HISR_RX_REQUEST) { struct recv_buf *precvbuf; //printk("%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 //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); if (precvbuf) sd_rxhandler(padapter, precvbuf); pHalData->SdioRxFIFOSize = 0; } #endif } }