Beispiel #1
0
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);
	
}
Beispiel #5
0
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;
}