//todo: static s32 rtl8188es_dequeue_writeport(PADAPTER padapter, u8 *freePage) { 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; 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 == rtl8188es_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; } 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); #ifdef CONFIG_SDIO_TX_TASKLET tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); #endif return _FAIL; }
void rtl8723bu_xmit_tasklet(void *priv) { int ret = _FALSE; _adapter *padapter = (_adapter*)priv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; while(1) { if (RTW_CANNOT_TX(padapter)) { DBG_8192C("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n"); break; } if(check_fwstate(&padapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE #ifdef CONFIG_CONCURRENT_MODE || check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE #endif ) { break; } ret = rtl8723bu_xmitframe_complete(padapter, pxmitpriv, NULL); if(ret==_FALSE) break; } }
/* * Return * _TRUE dump packet directly * _FALSE enqueue packet */ static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe) { _irqL irqL; s32 res; struct xmit_buf *pxmitbuf = NULL; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct pkt_attrib *pattrib = &pxmitframe->attrib; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; _enter_critical_bh(&pxmitpriv->lock, &irqL); //DBG_8192C("==> %s \n",__FUNCTION__); if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0) { //DBG_8192C("enqueue AC(%d)\n",pattrib->priority); goto enqueue; } if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) goto enqueue; #ifdef CONFIG_CONCURRENT_MODE if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) goto enqueue; #endif pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); if (pxmitbuf == NULL) goto enqueue; _exit_critical_bh(&pxmitpriv->lock, &irqL); pxmitframe->pxmitbuf = pxmitbuf; pxmitframe->buf_addr = pxmitbuf->pbuf; pxmitbuf->priv_data = pxmitframe; if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) { rtw_free_xmitbuf(pxmitpriv, pxmitbuf); rtw_free_xmitframe(pxmitpriv, pxmitframe); } return _TRUE; enqueue: res = rtw_xmitframe_enqueue(padapter, pxmitframe); _exit_critical_bh(&pxmitpriv->lock, &irqL); if (res != _SUCCESS) { RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n")); rtw_free_xmitframe(pxmitpriv, pxmitframe); pxmitpriv->tx_drop++; return _TRUE; } return _FALSE; }
void interrupt_handler_8723bu(_adapter *padapter,u16 pkt_len,u8 *pbuf) { HAL_DATA_TYPE *pHalData=GET_HAL_DATA(padapter); struct reportpwrstate_parm pwr_rpt; if ( pkt_len != INTERRUPT_MSG_FORMAT_LEN ) { DBG_8192C("%s Invalid interrupt content length (%d)!\n", __FUNCTION__, pkt_len); return ; } // HISR _rtw_memcpy(&(pHalData->IntArray[0]), &(pbuf[USB_INTR_CONTENT_HISR_OFFSET]), 4); _rtw_memcpy(&(pHalData->IntArray[1]), &(pbuf[USB_INTR_CONTENT_HISRE_OFFSET]), 4); #if 0 //DBG { u32 hisr=0 ,hisr_ex=0; _rtw_memcpy(&hisr,&(pHalData->IntArray[0]),4); hisr = le32_to_cpu(hisr); _rtw_memcpy(&hisr_ex,&(pHalData->IntArray[1]),4); hisr_ex = le32_to_cpu(hisr_ex); if((hisr != 0) || (hisr_ex!=0)) DBG_871X("===> %s hisr:0x%08x ,hisr_ex:0x%08x \n",__FUNCTION__,hisr,hisr_ex); } #endif #ifdef CONFIG_LPS_LCLK if( pHalData->IntArray[0] & IMR_CPWM_88E ) { _rtw_memcpy(&pwr_rpt.state, &(pbuf[USB_INTR_CONTENT_CPWM1_OFFSET]), 1); //_rtw_memcpy(&pwr_rpt.state2, &(pbuf[USB_INTR_CONTENT_CPWM2_OFFSET]), 1); //88e's cpwm value only change BIT0, so driver need to add PS_STATE_S2 for LPS flow. pwr_rpt.state |= PS_STATE_S2; _set_workitem(&(adapter_to_pwrctl(padapter)->cpwm_event)); } #endif//CONFIG_LPS_LCLK #ifdef CONFIG_INTERRUPT_BASED_TXBCN #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT if (pHalData->IntArray[0] & IMR_BCNDMAINT0_88E) #endif #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR if (pHalData->IntArray[0] & (IMR_TBDER_88E|IMR_TBDOK_88E)) #endif { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; #if 0 if(pHalData->IntArray[0] & IMR_BCNDMAINT0_88E) DBG_8192C("%s: HISR_BCNERLY_INT\n", __func__); if(pHalData->IntArray[0] & IMR_TBDOK_88E) DBG_8192C("%s: HISR_TXBCNOK\n", __func__); if(pHalData->IntArray[0] & IMR_TBDER_88E) DBG_8192C("%s: 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 DBG_CONFIG_ERROR_DETECT_INT if( pHalData->IntArray[1] & IMR_TXERR_8723B ) DBG_871X("===> %s Tx Error Flag Interrupt Status \n",__FUNCTION__); if( pHalData->IntArray[1] & IMR_RXERR_8723B ) DBG_871X("===> %s Rx Error Flag INT Status \n",__FUNCTION__); if( pHalData->IntArray[1] & IMR_TXFOVW_8723B ) DBG_871X("===> %s Transmit FIFO Overflow \n",__FUNCTION__); if( pHalData->IntArray[1] & IMR_RXFOVW_8723B ) DBG_871X("===> %s Receive FIFO Overflow \n",__FUNCTION__); #endif//DBG_CONFIG_ERROR_DETECT_INT // C2H Event if(pbuf[0]!= 0){ _rtw_memcpy(&(pHalData->C2hArray[0]), &(pbuf[USB_INTR_CONTENT_C2H_OFFSET]), 16); //rtw_c2h_wk_cmd(padapter); to do.. } }
//todo: static s32 rtl8188es_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; s32 ret = 0; u8 PageIdx = 0; u32 deviceId; #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT u8 bUpdatePageNum = _FALSE; #else u32 polling_num = 0; #endif #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; } deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr); // translate fifo addr to queue index switch (deviceId) { case WLAN_TX_HIQ_DEVICE_ID: PageIdx = HI_QUEUE_IDX; break; case WLAN_TX_MIQ_DEVICE_ID: PageIdx = MID_QUEUE_IDX; break; case WLAN_TX_LOQ_DEVICE_ID: PageIdx = LOW_QUEUE_IDX; break; } query_free_page: // check if hardware tx fifo page is enough if( _FALSE == rtw_hal_sdio_query_tx_freepage(pri_padapter, PageIdx, pxmitbuf->pg_num)) { #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT if (!bUpdatePageNum) { // Total number of page is NOT available, so update current FIFO status HalQueryTxBufferStatus8189ESdio(padapter); bUpdatePageNum = _TRUE; goto query_free_page; } else { bUpdatePageNum = _FALSE; enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf); return _TRUE; } #else //CONFIG_SDIO_TX_ENABLE_AVAL_INT polling_num++; if ((polling_num % 60) == 0) {//or 80 //DBG_871X("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n", // __func__, n, pxmitbuf->len, pxmitbuf->agg_num, pframe->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]); rtw_msleep_os(1); } // Total number of page is NOT available, so update current FIFO status HalQueryTxBufferStatus8189ESdio(padapter); goto query_free_page; #endif //CONFIG_SDIO_TX_ENABLE_AVAL_INT } 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; } if (rtw_sdio_wait_enough_TxOQT_space(padapter, pxmitbuf->agg_num) == _FALSE) { goto free_xmitbuf; } rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8 *)pxmitbuf); rtw_hal_sdio_update_tx_freepage(pri_padapter, PageIdx, pxmitbuf->pg_num); free_xmitbuf: //rtw_free_xmitframe(pxmitpriv, pframe); //pxmitbuf->priv_data = NULL; rtw_free_xmitbuf(pxmitpriv, pxmitbuf); #ifdef CONFIG_SDIO_TX_TASKLET tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); #endif return _FAIL; }
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; }
s32 rtl8723_dequeue_writeport(PADAPTER padapter, u8 *freePage) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); struct xmit_buf *pxmitbuf; //struct xmit_frame *pframe; PADAPTER pri_padapter = padapter; u32 deviceId; u32 requiredPage; u8 PageIdx; _irqL irql; u32 n; s32 ret = 0; //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); #ifdef CONFIG_CONCURRENT_MODE s32 buddy_rm_stop = _FAIL; #endif #ifdef CONFIG_CONCURRENT_MODE 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; //pframe = (struct xmit_frame*)pxmitbuf->priv_data; //requiredPage = pframe->pg_num; requiredPage = pxmitbuf->pg_num; //translate queue index to sdio fifo addr deviceId = pdvobjpriv->Queue2Pipe[pxmitbuf->ff_hwaddr]; // translate sdio fifo addr to tx fifo page index switch (deviceId) { case WLAN_TX_HIQ_DEVICE_ID: PageIdx = HI_QUEUE_IDX; break; case WLAN_TX_MIQ_DEVICE_ID: PageIdx = MID_QUEUE_IDX; break; case WLAN_TX_LOQ_DEVICE_ID: PageIdx = LOW_QUEUE_IDX; break; } // check if hardware tx fifo page is enough n = 0; // _enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); do { if (requiredPage <= freePage[PageIdx]) { freePage[PageIdx] -= requiredPage; break; } // The number of page which public page included is available. if ((freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]) > (requiredPage + 1)) { u8 requiredPublicPage; requiredPublicPage = requiredPage - freePage[PageIdx]; freePage[PageIdx] = 0; freePage[PUBLIC_QUEUE_IDX] -= requiredPublicPage; break; } // _exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE); if (ret) { RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: bSurpriseRemoved(update TX FIFO page)\n", __func__)); goto free_xmitbuf; } n++; //if ((n & 0x3FF) == 0) if ((n % 2) == 0) { if (n > 5000) { DBG_8192C(KERN_NOTICE "%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n", __func__, n, pxmitbuf->len, pxmitbuf->agg_num, pxmitbuf->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]); } else { //RT_TRACE(_module_hal_xmit_c_, _drv_notice_, // ("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n", // __FUNCTION__, n, pxmitbuf->len, pxmitbuf->agg_num, pxmitbuf->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX])); } //rtw_yield_os(); rtw_msleep_os(1); } // Total number of page is NOT available, so update current FIFO status #ifdef CONFIG_CONCURRENT_MODE if (padapter->adapter_type > 0) pri_padapter = padapter->pbuddy_adapter; #endif HalQueryTxBufferStatus8723ASdio(pri_padapter); } while (1); if ((padapter->bSurpriseRemoved == _TRUE) #ifdef CONFIG_CONCURRENT_MODE ||((padapter->pbuddy_adapter)&& (padapter->pbuddy_adapter->bSurpriseRemoved)) #endif ){ RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: bSurpriseRemoved(wirte port)\n", __FUNCTION__)); goto free_xmitbuf; } rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8 *)pxmitbuf); free_xmitbuf: //rtw_free_xmitframe(pxmitpriv, pframe); //pxmitbuf->priv_data = NULL; rtw_free_xmitbuf(pxmitpriv, pxmitbuf); return _FAIL; }
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 }