void LPS_Leave(PADAPTER padapter, const char *msg) { #define LPS_LEAVE_TIMEOUT_MS 100 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); char buf[32] = {0}; /* DBG_871X("+LeisurePSLeave\n"); */ if (rtw_btcoex_IsBtControlLps(padapter) == true) return; if (pwrpriv->bLeisurePs) { if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) { sprintf(buf, "WIFI-%s", msg); rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, buf); if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS); } } pwrpriv->bpower_saving = false; /* DBG_871X("-LeisurePSLeave\n"); */ }
static int rtw_gspi_resume(struct spi_device *spi) { struct dvobj_priv *dvobj = spi_get_drvdata(spi); PADAPTER padapter = dvobj->if1; struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); int ret = 0; DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); if(pwrpriv->bInternalAutoSuspend ){ ret = rtw_resume_process(padapter); } else { #ifdef CONFIG_RESUME_IN_WORKQUEUE rtw_resume_in_workqueue(pwrpriv); #else if(rtw_is_earlysuspend_registered(pwrpriv)) { /* jeff: bypass resume here, do in late_resume */ rtw_set_do_late_resume(pwrpriv, _TRUE); } else { ret = rtw_resume_process(padapter); } #endif /* CONFIG_RESUME_IN_WORKQUEUE */ } DBG_871X("<======== %s return %d\n", __FUNCTION__, ret); return ret; }
static u32 usb_bulkout_zero(struct intf_hdl *pintfhdl, u32 addr) { int pipe, status, len; u32 ret; unsigned char *pbuf; struct zero_bulkout_context *pcontext; PURB purb = NULL; _adapter *padapter = (_adapter *)pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); struct usb_device *pusbd = pdvobj->pusbdev; /* RTW_INFO("%s\n", __func__); */ if (RTW_CANNOT_TX(padapter)) return _FAIL; pcontext = (struct zero_bulkout_context *)rtw_zmalloc(sizeof(struct zero_bulkout_context)); if (pcontext == NULL) return _FAIL; pbuf = (unsigned char *)rtw_zmalloc(sizeof(int)); purb = usb_alloc_urb(0, GFP_ATOMIC); /* translate DMA FIFO addr to pipehandle */ pipe = ffaddr2pipehdl(pdvobj, addr); len = 0; pcontext->pbuf = pbuf; pcontext->purb = purb; pcontext->pirp = NULL; pcontext->padapter = padapter; /* translate DMA FIFO addr to pipehandle */ /* pipe = ffaddr2pipehdl(pdvobj, addr); */ usb_fill_bulk_urb(purb, pusbd, pipe, pbuf, len, usb_bulkout_zero_complete, pcontext);/* context is pcontext */ status = usb_submit_urb(purb, GFP_ATOMIC); if (!status) ret = _SUCCESS; else ret = _FAIL; return _SUCCESS; }
static u32 usb_bulkout_zero(struct intf_hdl *pintfhdl, u32 addr) { int pipe, status, len; u32 ret; unsigned char *pbuf; struct zero_bulkout_context *pcontext; PURB purb = NULL; _adapter *padapter = (_adapter *)pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); struct usb_device *pusbd = pdvobj->pusbdev; //DBG_871X("%s\n", __func__); if((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(dvobj_to_pwrctl(pdvobj)->pnp_bstop_trx)) { return _FAIL; } pcontext = (struct zero_bulkout_context *)rtw_zmalloc(sizeof(struct zero_bulkout_context)); pbuf = (unsigned char *)rtw_zmalloc(sizeof(int)); purb = usb_alloc_urb(0, GFP_ATOMIC); len = 0; pcontext->pbuf = pbuf; pcontext->purb = purb; pcontext->pirp = NULL; pcontext->padapter = padapter; //translate DMA FIFO addr to pipehandle //pipe = ffaddr2pipehdl(pdvobj, addr); usb_fill_bulk_urb(purb, pusbd, pipe, pbuf, len, usb_bulkout_zero_complete, pcontext);//context is pcontext status = usb_submit_urb(purb, GFP_ATOMIC); if (!status) { ret= _SUCCESS; } else { ret= _FAIL; } return _SUCCESS; }
u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) { int err; unsigned int pipe; u32 ret = _SUCCESS; PURB purb = NULL; struct recv_buf *precvbuf = (struct recv_buf *)rmem; _adapter *adapter = pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); struct recv_priv *precvpriv = &adapter->recvpriv; struct usb_device *pusbd = pdvobj->pusbdev; _func_enter_; if (RTW_CANNOT_RX(adapter) || (precvbuf == NULL)) { RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( RTW_CANNOT_RX ) || precvbuf == NULL!!!\n")); return _FAIL; } usb_init_recvbuf(adapter, precvbuf); if(precvbuf->pbuf) { ATOMIC_INC(&(precvpriv->rx_pending_cnt)); purb = precvbuf->purb; //translate DMA FIFO addr to pipehandle pipe = ffaddr2pipehdl(pdvobj, addr); usb_fill_bulk_urb(purb, pusbd, pipe, precvbuf->pbuf, MAX_RECVBUF_SZ, usb_read_port_complete, precvbuf);//context is precvbuf purb->transfer_dma = precvbuf->dma_transfer_addr; purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; err = usb_submit_urb(purb, GFP_ATOMIC); if((err) && (err != (-EPERM))) { RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x", err, purb->status)); DBG_8192C("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",err,purb->status); ret = _FAIL; } } _func_exit_; return ret; }
void LPS_Enter(PADAPTER padapter, const char *msg) { struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); int n_assoc_iface = 0; int i; char buf[32] = {0}; /* DBG_871X("+LeisurePSEnter\n"); */ if (rtw_btcoex_IsBtControlLps(padapter) == true) return; /* Skip lps enter request if number of assocated adapters is not 1 */ for (i = 0; i < dvobj->iface_nums; i++) { if (check_fwstate(&(dvobj->padapters[i]->mlmepriv), WIFI_ASOC_STATE)) n_assoc_iface++; } if (n_assoc_iface != 1) return; /* Skip lps enter request for adapter not port0 */ if (get_iface_type(padapter) != IFACE_PORT0) return; for (i = 0; i < dvobj->iface_nums; i++) { if (PS_RDY_CHECK(dvobj->padapters[i]) == false) return; } if (pwrpriv->bLeisurePs) { /* Idle for a while if we connect to AP a while ago. */ if (pwrpriv->LpsIdleCount >= 2) /* 4 Sec */ { if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) { sprintf(buf, "WIFI-%s", msg); pwrpriv->bpower_saving = true; rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, padapter->registrypriv.smart_ps, 0, buf); } } else pwrpriv->LpsIdleCount++; } /* DBG_871X("-LeisurePSEnter\n"); */ }
static int /*__devexit*/ rtw_dev_remove(struct spi_device *spi) { struct dvobj_priv *dvobj = spi_get_drvdata(spi); PADAPTER padapter = dvobj->if1; _func_enter_; RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+rtw_dev_remove\n")); dvobj->processing_dev_remove = _TRUE; rtw_unregister_netdevs(dvobj); #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) rtw_unregister_early_suspend(dvobj_to_pwrctl(dvobj)); #endif rtw_pm_set_ips(padapter, IPS_NONE); rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); LeaveAllPowerSaveMode(padapter); #ifdef CONFIG_CONCURRENT_MODE rtw_drv_if2_stop(dvobj->if2); #endif rtw_gspi_if1_deinit(padapter); #ifdef CONFIG_CONCURRENT_MODE rtw_drv_if2_free(dvobj->if2); #endif gspi_dvobj_deinit(spi); RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("-rtw_dev_remove\n")); _func_exit_; return 0; }
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 int rtw_gspi_suspend(struct spi_device *spi, pm_message_t mesg) { struct dvobj_priv *dvobj = spi_get_drvdata(spi); PADAPTER padapter = dvobj->if1; struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct net_device *pnetdev = padapter->pnetdev; int ret = 0; u32 start_time = rtw_get_current_time(); _func_enter_; DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); pwrpriv->bInSuspend = _TRUE; while (pwrpriv->bips_processing == _TRUE) rtw_msleep_os(1); if((!padapter->bup) || (padapter->bDriverStopped)||(padapter->bSurpriseRemoved)) { DBG_871X("%s bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", __FUNCTION__ ,padapter->bup, padapter->bDriverStopped,padapter->bSurpriseRemoved); goto exit; } rtw_cancel_all_timer(padapter); LeaveAllPowerSaveMode(padapter); //padapter->net_closed = _TRUE; //s1. if(pnetdev) { netif_carrier_off(pnetdev); rtw_netif_stop_queue(pnetdev); } #ifdef CONFIG_WOWLAN pwrpriv->bSupportRemoteWakeup=_TRUE; #else //s2. rtw_disassoc_cmd(padapter, 0, _FALSE); #endif #ifdef CONFIG_LAYER2_ROAMING_RESUME if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED) ) { DBG_871X("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n",__FUNCTION__, pmlmepriv->cur_network.network.Ssid.Ssid, MAC_ARG(pmlmepriv->cur_network.network.MacAddress), pmlmepriv->cur_network.network.Ssid.SsidLength, pmlmepriv->assoc_ssid.SsidLength); rtw_set_roaming(padapter, 1); } #endif //s2-2. indicate disconnect to os rtw_indicate_disconnect(padapter); //s2-3. rtw_free_assoc_resources(padapter, 1); //s2-4. rtw_free_network_queue(padapter, _TRUE); rtw_led_control(padapter, LED_CTL_POWER_OFF); rtw_dev_unload(padapter); if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) rtw_indicate_scan_done(padapter, 1); if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) rtw_indicate_disconnect(padapter); // interface deinit gspi_deinit(dvobj); RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("%s: deinit GSPI complete!\n", __FUNCTION__)); rtw_wifi_gpio_wlan_ctrl(WLAN_PWDN_OFF); rtw_mdelay_os(1); exit: DBG_871X("<=== %s return %d.............. in %dms\n", __FUNCTION__ , ret, rtw_get_passing_time_ms(start_time)); _func_exit_; return ret; }
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"); } }
u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) { int err; unsigned int pipe; u32 ret = _FAIL; PURB purb = NULL; struct recv_buf *precvbuf = (struct recv_buf *)rmem; _adapter *adapter = pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); struct recv_priv *precvpriv = &adapter->recvpriv; struct usb_device *pusbd = pdvobj->pusbdev; if (RTW_CANNOT_RX(adapter) || (precvbuf == NULL)) { goto exit; } usb_init_recvbuf(adapter, precvbuf); if (precvbuf->pskb == NULL) { SIZE_PTR tmpaddr = 0; SIZE_PTR alignment = 0; precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); if (NULL != precvbuf->pskb) goto recv_buf_hook; #ifndef CONFIG_FIX_NR_BULKIN_BUFFER precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); #endif if (precvbuf->pskb == NULL) { if (0) RTW_INFO("usb_read_port() enqueue precvbuf=%p\n", precvbuf); /* enqueue precvbuf and wait for free skb */ rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue); goto exit; } tmpaddr = (SIZE_PTR)precvbuf->pskb->data; alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); } recv_buf_hook: precvbuf->phead = precvbuf->pskb->head; precvbuf->pdata = precvbuf->pskb->data; precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); precvbuf->pend = skb_end_pointer(precvbuf->pskb); precvbuf->pbuf = precvbuf->pskb->data; purb = precvbuf->purb; /* translate DMA FIFO addr to pipehandle */ pipe = ffaddr2pipehdl(pdvobj, addr); usb_fill_bulk_urb(purb, pusbd, pipe, precvbuf->pbuf, MAX_RECVBUF_SZ, usb_read_port_complete, precvbuf); err = usb_submit_urb(purb, GFP_ATOMIC); if (err && err != (-EPERM)) { RTW_INFO("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n" , err, purb->status); goto exit; } ATOMIC_INC(&(precvpriv->rx_pending_cnt)); ret = _SUCCESS; exit: return ret; }
u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) { _irqL irqL; unsigned int pipe; int status; u32 ret = _FAIL, bwritezero = _FALSE; PURB purb = NULL; _adapter *padapter = (_adapter *)pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem; struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data; struct usb_device *pusbd = pdvobj->pusbdev; struct pkt_attrib *pattrib = &pxmitframe->attrib; if (RTW_CANNOT_TX(padapter)) { #ifdef DBG_TX RTW_INFO(" DBG_TX %s:%d bDriverStopped%s, bSurpriseRemoved:%s\n", __func__, __LINE__ , rtw_is_drv_stopped(padapter) ? "True" : "False" , rtw_is_surprise_removed(padapter) ? "True" : "False"); #endif rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY); goto exit; } _enter_critical(&pxmitpriv->lock, &irqL); switch (addr) { case VO_QUEUE_INX: pxmitpriv->voq_cnt++; pxmitbuf->flags = VO_QUEUE_INX; break; case VI_QUEUE_INX: pxmitpriv->viq_cnt++; pxmitbuf->flags = VI_QUEUE_INX; break; case BE_QUEUE_INX: pxmitpriv->beq_cnt++; pxmitbuf->flags = BE_QUEUE_INX; break; case BK_QUEUE_INX: pxmitpriv->bkq_cnt++; pxmitbuf->flags = BK_QUEUE_INX; break; case HIGH_QUEUE_INX: pxmitbuf->flags = HIGH_QUEUE_INX; break; default: pxmitbuf->flags = MGT_QUEUE_INX; break; } _exit_critical(&pxmitpriv->lock, &irqL); purb = pxmitbuf->pxmit_urb[0]; /* translate DMA FIFO addr to pipehandle */ #ifdef RTW_HALMAC pipe = ffaddr2pipehdl(pdvobj, pxmitbuf->bulkout_id); #else pipe = ffaddr2pipehdl(pdvobj, addr); #endif #ifdef CONFIG_REDUCE_USB_TX_INT if ((pxmitpriv->free_xmitbuf_cnt % NR_XMITBUFF == 0) || (pxmitbuf->buf_tag > XMITBUF_DATA)) purb->transfer_flags &= (~URB_NO_INTERRUPT); else { purb->transfer_flags |= URB_NO_INTERRUPT; /* RTW_INFO("URB_NO_INTERRUPT "); */ } #endif usb_fill_bulk_urb(purb, pusbd, pipe, pxmitframe->buf_addr, /* = pxmitbuf->pbuf */ cnt, usb_write_port_complete, pxmitbuf);/* context is pxmitbuf */ #ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX purb->transfer_dma = pxmitbuf->dma_transfer_addr; purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; purb->transfer_flags |= URB_ZERO_PACKET; #endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */ #ifdef USB_PACKET_OFFSET_SZ #if (USB_PACKET_OFFSET_SZ == 0) purb->transfer_flags |= URB_ZERO_PACKET; #endif #endif #if 0 if (bwritezero) purb->transfer_flags |= URB_ZERO_PACKET; #endif status = usb_submit_urb(purb, GFP_ATOMIC); if (!status) { #ifdef DBG_CONFIG_ERROR_DETECT { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); pHalData->srestpriv.last_tx_time = rtw_get_current_time(); } #endif } else { rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR); RTW_INFO("usb_write_port, status=%d\n", status); switch (status) { case -ENODEV: rtw_set_drv_stopped(padapter); break; default: break; } goto exit; } ret = _SUCCESS; /* Commented by Albert 2009/10/13 * We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. */ /* if(bwritezero == _TRUE) { usb_bulkout_zero(pintfhdl, addr); } */ exit: if (ret != _SUCCESS) rtw_free_xmitbuf(pxmitpriv, pxmitbuf); return ret; }
int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype) { _adapter *padapter = pintfhdl->padapter; struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobjpriv); struct usb_device *udev = pdvobjpriv->pusbdev; unsigned int pipe; int status = 0; u32 tmp_buflen = 0; u8 reqtype; u8 *pIo_buf; int vendorreq_times = 0; #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE u8 *tmp_buf; #else /* use stack memory */ u8 tmp_buf[MAX_USB_IO_CTL_SIZE]; #endif /* RTW_INFO("%s %s:%d\n",__FUNCTION__, current->comm, current->pid); */ if (RTW_CANNOT_IO(padapter)) { status = -EPERM; goto exit; } if (len > MAX_VENDOR_REQ_CMD_SIZE) { RTW_INFO("[%s] Buffer len error ,vendor request failed\n", __FUNCTION__); status = -EINVAL; goto exit; } #ifdef CONFIG_USB_VENDOR_REQ_MUTEX _enter_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL); #endif /* Acquire IO memory for vendorreq */ #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC pIo_buf = pdvobjpriv->usb_vendor_req_buf; #else #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE tmp_buf = rtw_malloc((u32) len + ALIGNMENT_UNIT); tmp_buflen = (u32)len + ALIGNMENT_UNIT; #else /* use stack memory */ tmp_buflen = MAX_USB_IO_CTL_SIZE; #endif /* Added by Albert 2010/02/09 */ /* For mstar platform, mstar suggests the address for USB IO should be 16 bytes alignment. */ /* Trying to fix it here. */ pIo_buf = (tmp_buf == NULL) ? NULL : tmp_buf + ALIGNMENT_UNIT - ((SIZE_PTR)(tmp_buf) & 0x0f); #endif if (pIo_buf == NULL) { RTW_INFO("[%s] pIo_buf == NULL\n", __FUNCTION__); status = -ENOMEM; goto release_mutex; } while (++vendorreq_times <= MAX_USBCTRL_VENDORREQ_TIMES) { _rtw_memset(pIo_buf, 0, len); if (requesttype == 0x01) { pipe = usb_rcvctrlpipe(udev, 0);/* read_in */ reqtype = REALTEK_USB_VENQT_READ; } else { pipe = usb_sndctrlpipe(udev, 0);/* write_out */ reqtype = REALTEK_USB_VENQT_WRITE; _rtw_memcpy(pIo_buf, pdata, len); } status = rtw_usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT); if (status == len) { /* Success this control transfer. */ rtw_reset_continual_io_error(pdvobjpriv); if (requesttype == 0x01) { /* For Control read transfer, we have to copy the read data from pIo_buf to pdata. */ _rtw_memcpy(pdata, pIo_buf, len); } } else { /* error cases */ RTW_INFO("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n" , value, (requesttype == 0x01) ? "read" : "write" , len, status, *(u32 *)pdata, vendorreq_times); if (status < 0) { if (status == (-ESHUTDOWN) || status == -ENODEV) rtw_set_surprise_removed(padapter); else { #ifdef DBG_CONFIG_ERROR_DETECT { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); pHalData->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL; } #endif } } else { /* status != len && status >= 0 */ if (status > 0) { if (requesttype == 0x01) { /* For Control read transfer, we have to copy the read data from pIo_buf to pdata. */ _rtw_memcpy(pdata, pIo_buf, len); } } } if (rtw_inc_and_chk_continual_io_error(pdvobjpriv) == _TRUE) { rtw_set_surprise_removed(padapter); break; } } /* firmware download is checksumed, don't retry */ if ((value >= FW_START_ADDRESS) || status == len) break; } /* release IO memory used by vendorreq */ #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE rtw_mfree(tmp_buf, tmp_buflen); #endif release_mutex: #ifdef CONFIG_USB_VENDOR_REQ_MUTEX _exit_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL); #endif exit: return status; }
int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller) { struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); struct mlme_priv *pmlmepriv; int ret = _SUCCESS; unsigned long start = jiffies; unsigned long deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms); /* for LPS */ LeaveAllPowerSaveMode(padapter); /* IPS still bound with primary adapter */ padapter = GET_PRIMARY_ADAPTER(padapter); pmlmepriv = &padapter->mlmepriv; if (time_before(pwrpriv->ips_deny_time, deny_time)) pwrpriv->ips_deny_time = deny_time; if (pwrpriv->ps_processing) { DBG_871X("%s wait ps_processing...\n", __func__); while (pwrpriv->ps_processing && jiffies_to_msecs(jiffies - start) <= 3000) msleep(10); if (pwrpriv->ps_processing) DBG_871X("%s wait ps_processing timeout\n", __func__); else DBG_871X("%s wait ps_processing done\n", __func__); } if (pwrpriv->bInternalAutoSuspend == false && pwrpriv->bInSuspend) { DBG_871X("%s wait bInSuspend...\n", __func__); while (pwrpriv->bInSuspend && jiffies_to_msecs(jiffies - start) <= 3000 ) { msleep(10); } if (pwrpriv->bInSuspend) DBG_871X("%s wait bInSuspend timeout\n", __func__); else DBG_871X("%s wait bInSuspend done\n", __func__); } /* System suspend is not allowed to wakeup */ if ((pwrpriv->bInternalAutoSuspend == false) && (true == pwrpriv->bInSuspend)){ ret = _FAIL; goto exit; } /* block??? */ if ((pwrpriv->bInternalAutoSuspend == true) && (padapter->net_closed == true)) { ret = _FAIL; goto exit; } /* I think this should be check in IPS, LPS, autosuspend functions... */ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { ret = _SUCCESS; goto exit; } if (rf_off == pwrpriv->rf_pwrstate) { { DBG_8192C("%s call ips_leave....\n", __FUNCTION__); if (_FAIL == ips_leave(padapter)) { DBG_8192C("======> ips_leave fail.............\n"); ret = _FAIL; goto exit; } } } /* TODO: the following checking need to be merged... */ if (padapter->bDriverStopped || !padapter->bup || !padapter->hw_init_completed ){ DBG_8192C("%s: bDriverStopped =%d, bup =%d, hw_init_completed =%u\n" , caller , padapter->bDriverStopped , padapter->bup , padapter->hw_init_completed); ret = false; goto exit; } exit: deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms); if (time_before(pwrpriv->ips_deny_time, deny_time)) pwrpriv->ips_deny_time = deny_time; return ret; }
u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) { _irqL irqL; unsigned int pipe; int status; u32 ret = _FAIL, bwritezero = _FALSE; PURB purb = NULL; _adapter *padapter = (_adapter *)pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem; struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data; struct usb_device *pusbd = pdvobj->pusbdev; struct pkt_attrib *pattrib = &pxmitframe->attrib; _func_enter_; RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("+usb_write_port\n")); if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(dvobj_to_pwrctl(pdvobj)->pnp_bstop_trx)) { #ifdef DBG_TX DBG_871X(" DBG_TX %s:%d bDriverStopped%d, bSurpriseRemoved:%d, pnp_bstop_trx:%d\n",__FUNCTION__, __LINE__ ,padapter->bDriverStopped, padapter->bSurpriseRemoved, dvobj_to_pwrctl(pdvobj)->pnp_bstop_trx ); #endif RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||pwrctl->pnp_bstop_trx)!!!\n")); rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY); goto exit; } _enter_critical(&pxmitpriv->lock, &irqL); switch(addr) { case VO_QUEUE_INX: pxmitpriv->voq_cnt++; pxmitbuf->flags = VO_QUEUE_INX; break; case VI_QUEUE_INX: pxmitpriv->viq_cnt++; pxmitbuf->flags = VI_QUEUE_INX; break; case BE_QUEUE_INX: pxmitpriv->beq_cnt++; pxmitbuf->flags = BE_QUEUE_INX; break; case BK_QUEUE_INX: pxmitpriv->bkq_cnt++; pxmitbuf->flags = BK_QUEUE_INX; break; case HIGH_QUEUE_INX: pxmitbuf->flags = HIGH_QUEUE_INX; break; default: pxmitbuf->flags = MGT_QUEUE_INX; break; } _exit_critical(&pxmitpriv->lock, &irqL); #ifdef DBG_TRX_STA_PKTS { struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; int bmcast = IS_MCAST(pattrib->dst); u8 agg_num = 1; #ifdef CONFIG_USB_HCI #ifdef CONFIG_USB_TX_AGGREGATION if(pxmitframe->agg_num>1) agg_num = pxmitframe->agg_num; #endif #endif #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) if(pxmitframe->agg_num>1) agg_num = pxmitframe->agg_num; #endif if(bmcast) { psta = rtw_get_bcmc_stainfo(padapter); } else { psta = rtw_get_stainfo(pstapriv, pattrib->dst); } if(psta) { switch(pattrib->priority) { case 1: case 2: psta->tx_bk_cnt += agg_num; break; case 4: case 5: psta->tx_vi_cnt += agg_num; break; case 6: case 7: psta->tx_vo_cnt += agg_num; break; case 0: case 3: default: psta->tx_be_cnt += agg_num; break; } } } #endif purb = pxmitbuf->pxmit_urb[0]; #if 0 if(pdvobj->ishighspeed) { if(cnt> 0 && cnt%512 == 0) { //DBG_8192C("ishighspeed, cnt=%d\n", cnt); bwritezero = _TRUE; } } else { if(cnt > 0 && cnt%64 == 0) { //DBG_8192C("cnt=%d\n", cnt); bwritezero = _TRUE; } } #endif //translate DMA FIFO addr to pipehandle pipe = ffaddr2pipehdl(pdvobj, addr); #ifdef CONFIG_REDUCE_USB_TX_INT if ( (pxmitpriv->free_xmitbuf_cnt%NR_XMITBUFF == 0) || (pxmitbuf->ext_tag == _TRUE) ) { purb->transfer_flags &= (~URB_NO_INTERRUPT); } else { purb->transfer_flags |= URB_NO_INTERRUPT; //DBG_8192C("URB_NO_INTERRUPT "); } #endif usb_fill_bulk_urb(purb, pusbd, pipe, pxmitframe->buf_addr, //= pxmitbuf->pbuf cnt, usb_write_port_complete, pxmitbuf);//context is pxmitbuf #ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX purb->transfer_dma = pxmitbuf->dma_transfer_addr; purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; purb->transfer_flags |= URB_ZERO_PACKET; #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX #ifdef USB_PACKET_OFFSET_SZ #if (USB_PACKET_OFFSET_SZ == 0) purb->transfer_flags |= URB_ZERO_PACKET; #endif #endif #if 0 if (bwritezero) { purb->transfer_flags |= URB_ZERO_PACKET; } #endif status = usb_submit_urb(purb, GFP_ATOMIC); if (!status) { #ifdef DBG_CONFIG_ERROR_DETECT { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); pHalData->srestpriv.last_tx_time = rtw_get_current_time(); } #endif } else { rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR); DBG_871X("usb_write_port, status=%d\n", status); RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port(): usb_submit_urb, status=%x\n", status)); switch (status) { case -ENODEV: padapter->bDriverStopped=_TRUE; break; default: break; } goto exit; } ret= _SUCCESS; // Commented by Albert 2009/10/13 // We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. /* if(bwritezero == _TRUE) { usb_bulkout_zero(pintfhdl, addr); } */ RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("-usb_write_port\n")); exit: if (ret != _SUCCESS) rtw_free_xmitbuf(pxmitpriv, pxmitbuf); _func_exit_; return ret; }
u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) { _irqL irqL; unsigned int pipe; int status; u32 ret = _FAIL, bwritezero = _FALSE; PURB purb = NULL; _adapter *padapter = (_adapter *)pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem; struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data; struct usb_device *pusbd = pdvobj->pusbdev; struct pkt_attrib *pattrib = &pxmitframe->attrib; RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("+usb_write_port\n")); if (RTW_CANNOT_TX(padapter)) { #ifdef DBG_TX DBG_871X(" DBG_TX %s:%d bDriverStopped%d, bSurpriseRemoved:%d\n",__FUNCTION__, __LINE__ ,padapter->bDriverStopped, padapter->bSurpriseRemoved); #endif RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved )!!!\n")); rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY); goto exit; } SPIN_LOCK_IRQ(pxmitpriv->lock, &irqL); switch(addr) { case VO_QUEUE_INX: pxmitpriv->voq_cnt++; pxmitbuf->flags = VO_QUEUE_INX; break; case VI_QUEUE_INX: pxmitpriv->viq_cnt++; pxmitbuf->flags = VI_QUEUE_INX; break; case BE_QUEUE_INX: pxmitpriv->beq_cnt++; pxmitbuf->flags = BE_QUEUE_INX; break; case BK_QUEUE_INX: pxmitpriv->bkq_cnt++; pxmitbuf->flags = BK_QUEUE_INX; break; case HIGH_QUEUE_INX: pxmitbuf->flags = HIGH_QUEUE_INX; break; default: pxmitbuf->flags = MGT_QUEUE_INX; break; } SPIN_UNLOCK_IRQ(pxmitpriv->lock, &irqL); purb = pxmitbuf->pxmit_urb[0]; //translate DMA FIFO addr to pipehandle pipe = ffaddr2pipehdl(pdvobj, addr); #ifdef CONFIG_REDUCE_USB_TX_INT if ( (pxmitpriv->free_xmitbuf_cnt%NR_XMITBUFF == 0) || (pxmitbuf->buf_tag > XMITBUF_DATA) ) { purb->transfer_flags &= (~URB_NO_INTERRUPT); } else { purb->transfer_flags |= URB_NO_INTERRUPT; //DBG_8192C("URB_NO_INTERRUPT "); } #endif usb_fill_bulk_urb(purb, pusbd, pipe, pxmitframe->buf_addr, //= pxmitbuf->pbuf cnt, usb_write_port_complete, pxmitbuf);//context is pxmitbuf #ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX purb->transfer_dma = pxmitbuf->dma_transfer_addr; purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; purb->transfer_flags |= URB_ZERO_PACKET; #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX #ifdef USB_PACKET_OFFSET_SZ #if (USB_PACKET_OFFSET_SZ == 0) purb->transfer_flags |= URB_ZERO_PACKET; #endif #endif status = usb_submit_urb(purb, GFP_ATOMIC); if (!status) { #ifdef DBG_CONFIG_ERROR_DETECT { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); pHalData->srestpriv.last_tx_time = rtw_get_current_time(); } #endif } else { rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR); DBG_871X("usb_write_port, status=%d\n", status); RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port(): usb_submit_urb, status=%x\n", status)); switch (status) { case -ENODEV: padapter->bDriverStopped=_TRUE; break; default: break; } goto exit; } ret= _SUCCESS; RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("-usb_write_port\n")); exit: if (ret != _SUCCESS) rtw_free_xmitbuf(pxmitpriv, pxmitbuf); return ret; }