struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter) { struct xmit_frame *xmit_frame; struct xmit_buf *xmitbuf; struct pkt_attrib *pattrib; struct xmit_priv *pxmitpriv = &(adapter->xmitpriv); #if 1 if ((xmit_frame = rtw_alloc_xmitframe(pxmitpriv)) == NULL) { DBG_871X("%s rtw_alloc_xmitframe return null\n", __FUNCTION__); goto exit; } if ((xmitbuf = rtw_alloc_xmitbuf(pxmitpriv)) == NULL) { DBG_871X("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__); rtw_free_xmitframe_ex(pxmitpriv, xmit_frame); xmit_frame=NULL; goto exit; } xmit_frame->frame_tag = MGNT_FRAMETAG; xmit_frame->pxmitbuf = xmitbuf; xmit_frame->buf_addr = xmitbuf->pbuf; xmitbuf->priv_data = xmit_frame; pattrib = &xmit_frame->attrib; update_mgntframe_attrib(adapter, pattrib); pattrib->qsel = 0x10; pattrib->pktlen = pattrib->last_txcmdsz = 0; #else if ((xmit_frame = alloc_mgtxmitframe(pxmitpriv)) == NULL) { DBG_871X("%s alloc_mgtxmitframe return null\n", __FUNCTION__); } else { pattrib = &xmit_frame->attrib; update_mgntframe_attrib(adapter, pattrib); pattrib->qsel = 0x10; pattrib->pktlen = pattrib->last_txcmdsz = 0; } #endif exit: return xmit_frame; }
/* * 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; #ifdef CONFIG_CONCURRENT_MODE PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); #endif // CONFIG_CONCURRENT_MODE _enter_critical_bh(&pxmitpriv->lock, &irqL); if ( (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0) || (check_nic_enough_desc(padapter, pattrib) == _FALSE)) goto enqueue; if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) goto enqueue; #ifdef CONFIG_CONCURRENT_MODE if (check_fwstate(pbuddy_mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) goto enqueue; #endif // CONFIG_CONCURRENT_MODE 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_ex(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_ex(pxmitpriv, pxmitframe); // Trick, make the statistics correct pxmitpriv->tx_pkts--; pxmitpriv->tx_drop++; return _TRUE; } return _FALSE; }
void rtl8192ce_xmitframe_resume(_adapter *padapter) { struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct xmit_frame *pxmitframe = NULL; struct xmit_buf *pxmitbuf = NULL; int res=_SUCCESS, xcnt = 0; RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtl8192ce_xmitframe_resume()\n")); while(1) { if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE)) { DBG_8192C("rtl8192ce_xmitframe_resume => bDriverStopped or bSurpriseRemoved \n"); break; } pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); if(!pxmitbuf) { break; } pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); if(pxmitframe) { pxmitframe->pxmitbuf = pxmitbuf; pxmitframe->buf_addr = pxmitbuf->pbuf; pxmitbuf->priv_data = pxmitframe; if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { if(pxmitframe->attrib.priority<=15)//TID0~15 { res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); } rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce } RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtl8192ce_xmitframe_resume(): rtw_dump_xframe\n")); if(res == _SUCCESS) { rtw_dump_xframe(padapter, pxmitframe); } else { rtw_free_xmitbuf(pxmitpriv, pxmitbuf); rtw_free_xmitframe_ex(pxmitpriv, pxmitframe); } xcnt++; } else { rtw_free_xmitbuf(pxmitpriv, pxmitbuf); break; } } }
void rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe) { _irqL irqL; int t, sz, w_sz, pull=0; //u8 *mem_addr; u32 ff_hwaddr; struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; struct pkt_attrib *pattrib = &pxmitframe->attrib; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct tx_desc *ptxdesc; if ((pxmitframe->frame_tag == DATA_FRAMETAG) && (pxmitframe->attrib.ether_type != 0x0806) && (pxmitframe->attrib.ether_type != 0x888e) && (pxmitframe->attrib.dhcp_pkt != 1)) { rtw_issue_addbareq_cmd(padapter, pxmitframe); } //mem_addr = pxmitframe->buf_addr; RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n")); for (t = 0; t < pattrib->nr_frags; t++) { if (t != (pattrib->nr_frags - 1)) { RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags)); sz = pxmitpriv->frag_len; sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len); } else //no frag { sz = pattrib->last_txcmdsz; } ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe); #ifdef CONFIG_CONCURRENT_MODE if(!rtw_buddy_adapter_up(padapter)) goto skip_if2_tx; if(padapter->adapter_type > PRIMARY_ADAPTER) { _adapter *pri_adapter = padapter->pbuddy_adapter; struct dvobj_priv *pri_dvobjpriv = &pri_adapter->dvobjpriv; _enter_critical(&(pri_dvobjpriv->irq_th_lock), &irqL); ptxdesc = get_txdesc(pri_adapter, ff_hwaddr); if(ptxdesc == NULL) { _exit_critical(&pri_dvobjpriv->irq_th_lock, &irqL); rtw_free_xmitbuf(pxmitpriv, pxmitbuf); DBG_8192C("##### Tx desc unavailable !#####\n"); break; } update_txdesc(pxmitframe, (uint*)ptxdesc, sz); rtl8192ce_enqueue_xmitbuf(&(pri_adapter->xmitpriv.tx_ring[ff_hwaddr]), pxmitbuf); pxmitbuf->len = sz; w_sz = sz; wmb(); ptxdesc->txdw0 |= cpu_to_le32(OWN); _exit_critical(&pri_dvobjpriv->irq_th_lock, &irqL); rtw_write16(pri_adapter, REG_PCIE_CTRL_REG, ffaddr2dma(ff_hwaddr)); rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf); } else skip_if2_tx: #endif { _enter_critical(&pdvobjpriv->irq_th_lock, &irqL); ptxdesc = get_txdesc(pxmitframe->padapter, ff_hwaddr); if(ptxdesc == NULL) { _exit_critical(&pdvobjpriv->irq_th_lock, &irqL); rtw_free_xmitbuf(pxmitpriv, pxmitbuf); DBG_8192C("##### Tx desc unavailable !#####\n"); break; } update_txdesc(pxmitframe, (uint*)ptxdesc, sz); rtl8192ce_enqueue_xmitbuf(&pxmitpriv->tx_ring[ff_hwaddr], pxmitbuf); pxmitbuf->len = sz; w_sz = sz; wmb(); ptxdesc->txdw0 |= cpu_to_le32(OWN); _exit_critical(&pdvobjpriv->irq_th_lock, &irqL); rtw_write16(padapter, REG_PCIE_CTRL_REG, ffaddr2dma(ff_hwaddr)); rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf); } rtw_count_tx_stats(padapter, pxmitframe, sz); RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_write_port, w_sz=%d\n", w_sz)); //DBG_8192C("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority); //mem_addr += w_sz; //mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr))); } rtw_free_xmitframe_ex(pxmitpriv, pxmitframe); }
DWORD usb_write_port_complete( LPVOID Context ) { // u8 *ptr; struct xmit_frame * pxmitframe = (struct xmit_frame *) Context; _adapter * padapter = pxmitframe->padapter; struct dvobj_priv * pdvobj_priv = (struct dvobj_priv *)&padapter->dvobjpriv; struct xmit_priv * pxmitpriv = &padapter->xmitpriv; struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; LPCUSB_FUNCS usb_funcs_vp = pdvobj_priv->usb_extension._lpUsbFuncs; int fComplete =_FALSE; DWORD dwBytesTransferred = 0; DWORD dwErr = USB_CANCELED_ERROR; RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u), pxmitframe %X\n",__FUNCTION__, __LINE__, Context)); _func_enter_; RT_TRACE(_module_hci_ops_os_c_,_drv_info_,("+usb_write_port_complete\n")); _rtw_spinlock_ex(&pxmitpriv->lock); pxmitpriv->txirp_cnt--; _rtw_spinunlock_ex(&pxmitpriv->lock); if(pxmitpriv->txirp_cnt==0){ RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: txirp_cnt== 0, set allrxreturnevt!\n")); _rtw_up_sema(&(pxmitpriv->tx_retevt)); } //not to consider tx fragment rtw_free_xmitframe_ex(pxmitpriv, pxmitframe); #if 1 (*usb_funcs_vp->lpGetTransferStatus)(pxmitpriv->usb_transfer_write_port, &dwBytesTransferred, &dwErr); fComplete = (*usb_funcs_vp->lpIsTransferComplete)(pxmitpriv->usb_transfer_write_port); if(fComplete!=_TRUE) { RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_write_port_complete CloseTransfer before complete\n")); } (*usb_funcs_vp->lpCloseTransfer)(pxmitpriv->usb_transfer_write_port); #else if((*usb_funcs_vp->lpIsTransferComplete)(pxmitpriv->usb_transfer_write_port)) { (*usb_funcs_vp->lpCloseTransfer)(pxmitpriv->usb_transfer_write_port); } #endif RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u): pxmitpriv %X pxmitpriv->free_xmitframe_cnt %X pxmitframe->padapter %X pxmitframe->padapter %X\n", __LINE__, pxmitpriv, pxmitpriv->free_xmitframe_cnt, pxmitframe->padapter)); rtw_xmitframe_complete(padapter, pxmitpriv, pxmitbuf); _func_exit_; return STATUS_SUCCESS; }