2016-03-27 17:56:02 +00:00
/******************************************************************************
*
* Copyright ( c ) 2007 - 2011 Realtek Corporation . All rights reserved .
2017-04-07 11:39:45 +00:00
*
2016-03-27 17:56:02 +00:00
* This program is free software ; you can redistribute it and / or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 , USA
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define _RTL8812AU_XMIT_C_
2017-04-07 11:39:45 +00:00
/* #include <drv_types.h> */
2016-03-27 17:56:02 +00:00
# include <rtl8812a_hal.h>
s32 rtl8812au_init_xmit_priv ( _adapter * padapter )
{
struct xmit_priv * pxmitpriv = & padapter - > xmitpriv ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
# ifdef PLATFORM_LINUX
tasklet_init ( & pxmitpriv - > xmit_tasklet ,
2017-04-07 11:39:45 +00:00
( void ( * ) ( unsigned long ) ) rtl8812au_xmit_tasklet ,
( unsigned long ) padapter ) ;
2016-03-27 17:56:02 +00:00
# endif
# ifdef CONFIG_TX_EARLY_MODE
pHalData - > bEarlyModeEnable = padapter - > registrypriv . early_mode ;
# endif
return _SUCCESS ;
}
void rtl8812au_free_xmit_priv ( _adapter * padapter )
{
}
2017-04-07 11:39:45 +00:00
static s32 update_txdesc ( struct xmit_frame * pxmitframe , u8 * pmem , s32 sz , u8 bagg_pkt )
{
int pull = 0 ;
2016-03-27 17:56:02 +00:00
uint qsel ;
2017-04-07 11:39:45 +00:00
u8 data_rate , pwr_status , offset ;
2016-03-27 17:56:02 +00:00
_adapter * padapter = pxmitframe - > padapter ;
2017-04-07 11:39:45 +00:00
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
2016-03-27 17:56:02 +00:00
struct pkt_attrib * pattrib = & pxmitframe - > attrib ;
2017-04-07 11:39:45 +00:00
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
2016-03-27 17:56:02 +00:00
u8 * ptxdesc = pmem ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
sint bmcst = IS_MCAST ( pattrib - > ra ) ;
2017-04-07 11:39:45 +00:00
# ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
if ( padapter - > registrypriv . mp_mode = = 0 ) {
if ( ( PACKET_OFFSET_SZ ! = 0 ) & & ( ! bagg_pkt ) & & ( rtw_usb_bulk_size_boundary ( padapter , TXDESC_SIZE + sz ) = = _FALSE ) ) {
ptxdesc = ( pmem + PACKET_OFFSET_SZ ) ;
/* RTW_INFO("==> non-agg-pkt,shift pointer...\n"); */
2016-03-27 17:56:02 +00:00
pull = 1 ;
}
}
2017-04-07 11:39:45 +00:00
# endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
2016-03-27 17:56:02 +00:00
_rtw_memset ( ptxdesc , 0 , TXDESC_SIZE ) ;
2017-04-07 11:39:45 +00:00
/* 4 offset 0 */
2016-03-27 17:56:02 +00:00
SET_TX_DESC_FIRST_SEG_8812 ( ptxdesc , 1 ) ;
SET_TX_DESC_LAST_SEG_8812 ( ptxdesc , 1 ) ;
SET_TX_DESC_OWN_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
/* RTW_INFO("%s==> pkt_len=%d,bagg_pkt=%02x\n",__FUNCTION__,sz,bagg_pkt); */
2016-03-27 17:56:02 +00:00
SET_TX_DESC_PKT_SIZE_8812 ( ptxdesc , sz ) ;
2017-04-07 11:39:45 +00:00
offset = TXDESC_SIZE + OFFSET_SZ ;
# ifdef CONFIG_TX_EARLY_MODE
if ( bagg_pkt ) {
offset + = EARLY_MODE_INFO_SIZE ; /* 0x28 */
2016-03-27 17:56:02 +00:00
}
# endif
2017-04-07 11:39:45 +00:00
/* RTW_INFO("%s==>offset(0x%02x)\n",__FUNCTION__,offset); */
2016-03-27 17:56:02 +00:00
SET_TX_DESC_OFFSET_8812 ( ptxdesc , offset ) ;
2017-04-07 11:39:45 +00:00
if ( bmcst )
2016-03-27 17:56:02 +00:00
SET_TX_DESC_BMC_8812 ( ptxdesc , 1 ) ;
# ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
2017-04-07 11:39:45 +00:00
if ( padapter - > registrypriv . mp_mode = = 0 ) {
if ( ( PACKET_OFFSET_SZ ! = 0 ) & & ( ! bagg_pkt ) ) {
if ( ( pull ) & & ( pxmitframe - > pkt_offset > 0 ) )
pxmitframe - > pkt_offset = pxmitframe - > pkt_offset - 1 ;
2016-03-27 17:56:02 +00:00
}
2017-04-07 11:39:45 +00:00
}
2016-03-27 17:56:02 +00:00
# endif
2017-04-07 11:39:45 +00:00
/* RTW_INFO("%s, pkt_offset=0x%02x\n",__FUNCTION__,pxmitframe->pkt_offset); */
/* pkt_offset, unit:8 bytes padding */
if ( pxmitframe - > pkt_offset > 0 )
2016-03-27 17:56:02 +00:00
SET_TX_DESC_PKT_OFFSET_8812 ( ptxdesc , pxmitframe - > pkt_offset ) ;
SET_TX_DESC_MACID_8812 ( ptxdesc , pattrib - > mac_id ) ;
SET_TX_DESC_RATE_ID_8812 ( ptxdesc , pattrib - > raid ) ;
SET_TX_DESC_QUEUE_SEL_8812 ( ptxdesc , pattrib - > qsel ) ;
2017-04-07 11:39:45 +00:00
/* offset 12 */
2016-03-27 17:56:02 +00:00
2017-09-21 19:43:47 +00:00
if ( ! pattrib - > qos_en & & pattrib - > sw_seq = = _FALSE ) {
2017-04-07 11:39:45 +00:00
SET_TX_DESC_HWSEQ_EN_8812 ( ptxdesc , 1 ) ; /* Hw set sequence number */
} else
2016-03-27 17:56:02 +00:00
SET_TX_DESC_SEQ_8812 ( ptxdesc , pattrib - > seqnum ) ;
2017-04-07 11:39:45 +00:00
if ( ( pxmitframe - > frame_tag & 0x0f ) = = DATA_FRAMETAG ) {
/* RTW_INFO("pxmitframe->frame_tag == DATA_FRAMETAG\n"); */
2016-03-27 17:56:02 +00:00
rtl8812a_fill_txdesc_sectype ( pattrib , ptxdesc ) ;
2017-04-07 11:39:45 +00:00
# if defined(CONFIG_CONCURRENT_MODE)
if ( bmcst )
fill_txdesc_force_bmc_camid ( pattrib , ptxdesc ) ;
# endif
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* offset 20 */
2016-03-27 17:56:02 +00:00
# ifdef CONFIG_USB_TX_AGGREGATION
2017-04-07 11:39:45 +00:00
if ( pxmitframe - > agg_num > 1 ) {
/* RTW_INFO("%s agg_num:%d\n",__FUNCTION__,pxmitframe->agg_num ); */
2016-03-27 17:56:02 +00:00
SET_TX_DESC_USB_TXAGG_NUM_8812 ( ptxdesc , pxmitframe - > agg_num ) ;
}
# endif
rtl8812a_fill_txdesc_vcs ( padapter , pattrib , ptxdesc ) ;
if ( ( pattrib - > ether_type ! = 0x888e ) & &
( pattrib - > ether_type ! = 0x0806 ) & &
( pattrib - > ether_type ! = 0x88b4 ) & &
( pattrib - > dhcp_pkt ! = 1 )
# ifdef CONFIG_AUTO_AP_MODE
& & ( pattrib - > pctrl ! = _TRUE )
# endif
2017-04-07 11:39:45 +00:00
) {
/* Non EAP & ARP & DHCP type data packet */
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
if ( pattrib - > ampdu_en = = _TRUE ) {
2016-03-27 17:56:02 +00:00
SET_TX_DESC_AGG_ENABLE_8812 ( ptxdesc , 1 ) ;
SET_TX_DESC_MAX_AGG_NUM_8812 ( ptxdesc , 0x1f ) ;
2017-04-07 11:39:45 +00:00
/* Set A-MPDU aggregation. */
2016-03-27 17:56:02 +00:00
SET_TX_DESC_AMPDU_DENSITY_8812 ( ptxdesc , pattrib - > ampdu_spacing ) ;
2017-04-07 11:39:45 +00:00
} else
2016-03-27 17:56:02 +00:00
SET_TX_DESC_AGG_BREAK_8812 ( ptxdesc , 1 ) ;
rtl8812a_fill_txdesc_phy ( padapter , pattrib , ptxdesc ) ;
2017-04-07 11:39:45 +00:00
/* DATA Rate FB LMT */
2016-03-27 17:56:02 +00:00
SET_TX_DESC_DATA_RATE_FB_LIMIT_8812 ( ptxdesc , 0x1f ) ;
if ( pHalData - > fw_ractrl = = _FALSE ) {
SET_TX_DESC_USE_RATE_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
if ( pHalData - > INIDATA_RATE [ pattrib - > mac_id ] & BIT ( 7 ) )
SET_TX_DESC_DATA_SHORT_8812 ( ptxdesc , 1 ) ;
2016-03-27 17:56:02 +00:00
SET_TX_DESC_TX_RATE_8812 ( ptxdesc , ( pHalData - > INIDATA_RATE [ pattrib - > mac_id ] & 0x7F ) ) ;
}
2017-04-07 11:39:45 +00:00
if ( padapter - > fix_rate ! = 0xFF ) { /* modify data rate by iwpriv */
2016-03-27 17:56:02 +00:00
SET_TX_DESC_USE_RATE_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
if ( padapter - > fix_rate & BIT ( 7 ) )
SET_TX_DESC_DATA_SHORT_8812 ( ptxdesc , 1 ) ;
2016-03-27 17:56:02 +00:00
SET_TX_DESC_TX_RATE_8812 ( ptxdesc , ( padapter - > fix_rate & 0x7F ) ) ;
if ( ! padapter - > data_fb )
2017-04-07 11:39:45 +00:00
SET_TX_DESC_DISABLE_FB_8812 ( ptxdesc , 1 ) ;
2016-03-27 17:56:02 +00:00
}
if ( pattrib - > ldpc )
SET_TX_DESC_DATA_LDPC_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
if ( pattrib - > stbc )
2016-03-27 17:56:02 +00:00
SET_TX_DESC_DATA_STBC_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
} else {
/* EAP data packet and ARP packet and DHCP. */
/* Use the 1M data rate to send the EAP/ARP packet. */
/* This will maybe make the handshake smooth. */
2016-03-27 17:56:02 +00:00
SET_TX_DESC_USE_RATE_8812 ( ptxdesc , 1 ) ;
SET_TX_DESC_AGG_BREAK_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
/* HW will ignore this setting if the transmission rate is legacy OFDM. */
if ( pmlmeinfo - > preamble_mode = = PREAMBLE_SHORT )
2016-03-27 17:56:02 +00:00
SET_TX_DESC_DATA_SHORT_8812 ( ptxdesc , 1 ) ;
SET_TX_DESC_TX_RATE_8812 ( ptxdesc , MRateToHwRate ( pmlmeext - > tx_rate ) ) ;
}
# ifdef CONFIG_TDLS
# ifdef CONFIG_XMIT_ACK
/* CCX-TXRPT ack for xmit mgmt frames. */
if ( pxmitframe - > ack_report ) {
SET_TX_DESC_SPE_RPT_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
# ifdef DBG_CCX
RTW_INFO ( " %s set tx report \n " , __func__ ) ;
# endif
2016-03-27 17:56:02 +00:00
}
# endif /* CONFIG_XMIT_ACK */
# endif
2017-04-07 11:39:45 +00:00
} else if ( ( pxmitframe - > frame_tag & 0x0f ) = = MGNT_FRAMETAG ) {
/* RTW_INFO("pxmitframe->frame_tag == MGNT_FRAMETAG\n"); */
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
if ( IS_HARDWARE_TYPE_8821 ( padapter ) )
2016-03-27 17:56:02 +00:00
SET_TX_DESC_MBSSID_8821 ( ptxdesc , pattrib - > mbssid ) ;
SET_TX_DESC_USE_RATE_8812 ( ptxdesc , 1 ) ;
# ifdef CONFIG_INTEL_PROXIM
2017-04-07 11:39:45 +00:00
if ( ( padapter - > proximity . proxim_on = = _TRUE ) & & ( pattrib - > intel_proxim = = _TRUE ) ) {
RTW_INFO ( " \n %s pattrib->rate=%d \n " , __FUNCTION__ , pattrib - > rate ) ;
2016-03-27 17:56:02 +00:00
SET_TX_DESC_TX_RATE_8812 ( ptxdesc , pattrib - > rate ) ;
2017-04-07 11:39:45 +00:00
} else
2016-03-27 17:56:02 +00:00
# endif
{
SET_TX_DESC_TX_RATE_8812 ( ptxdesc , MRateToHwRate ( pattrib - > rate ) ) ;
}
2017-04-07 11:39:45 +00:00
/* VHT NDPA or HT NDPA Packet for Beamformer. */
# ifdef CONFIG_BEAMFORMING
if ( ( pattrib - > subtype = = WIFI_NDPA ) | |
( ( pattrib - > subtype = = WIFI_ACTION_NOACK ) & & ( pattrib - > order = = 1 ) ) ) {
2016-03-27 17:56:02 +00:00
SET_TX_DESC_NAV_USE_HDR_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
SET_TX_DESC_DATA_BW_8812 ( ptxdesc , BWMapping_8812 ( padapter , pattrib ) ) ;
SET_TX_DESC_RTS_SC_8812 ( ptxdesc , SCMapping_8812 ( padapter , pattrib ) ) ;
2016-03-27 17:56:02 +00:00
SET_TX_DESC_RETRY_LIMIT_ENABLE_8812 ( ptxdesc , 1 ) ;
SET_TX_DESC_DATA_RETRY_LIMIT_8812 ( ptxdesc , 5 ) ;
SET_TX_DESC_DISABLE_FB_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
/* if(pattrib->rts_cca) */
/* { */
/* SET_TX_DESC_NDPA_8812(ptxdesc, 2); */
/* } */
/* else */
2016-03-27 17:56:02 +00:00
{
SET_TX_DESC_NDPA_8812 ( ptxdesc , 1 ) ;
}
2017-04-07 11:39:45 +00:00
} else
# endif
2016-03-27 17:56:02 +00:00
{
SET_TX_DESC_RETRY_LIMIT_ENABLE_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
if ( pattrib - > retry_ctrl = = _TRUE )
2016-03-27 17:56:02 +00:00
SET_TX_DESC_DATA_RETRY_LIMIT_8812 ( ptxdesc , 6 ) ;
2017-04-07 11:39:45 +00:00
else
2016-03-27 17:56:02 +00:00
SET_TX_DESC_DATA_RETRY_LIMIT_8812 ( ptxdesc , 12 ) ;
}
# ifdef CONFIG_XMIT_ACK
2017-04-07 11:39:45 +00:00
/* CCX-TXRPT ack for xmit mgmt frames. */
2016-03-27 17:56:02 +00:00
if ( pxmitframe - > ack_report ) {
SET_TX_DESC_SPE_RPT_8812 ( ptxdesc , 1 ) ;
2017-04-07 11:39:45 +00:00
# ifdef DBG_CCX
RTW_INFO ( " %s set tx report \n " , __func__ ) ;
# endif
2016-03-27 17:56:02 +00:00
}
2017-04-07 11:39:45 +00:00
# endif /* CONFIG_XMIT_ACK */
} else if ( ( pxmitframe - > frame_tag & 0x0f ) = = TXAGG_FRAMETAG )
RTW_INFO ( " pxmitframe->frame_tag == TXAGG_FRAMETAG \n " ) ;
2016-03-27 17:56:02 +00:00
# ifdef CONFIG_MP_INCLUDED
2017-04-07 11:39:45 +00:00
else if ( ( ( pxmitframe - > frame_tag & 0x0f ) = = MP_FRAMETAG ) & &
( padapter - > registrypriv . mp_mode = = 1 ) )
2016-03-27 17:56:02 +00:00
fill_txdesc_for_mp ( padapter , ptxdesc ) ;
# endif
2017-04-07 11:39:45 +00:00
else {
RTW_INFO ( " pxmitframe->frame_tag = %d \n " , pxmitframe - > frame_tag ) ;
2016-03-27 17:56:02 +00:00
SET_TX_DESC_USE_RATE_8812 ( ptxdesc , 1 ) ;
SET_TX_DESC_TX_RATE_8812 ( ptxdesc , MRateToHwRate ( pmlmeext - > tx_rate ) ) ;
}
2017-04-07 11:39:45 +00:00
# ifdef CONFIG_ANTENNA_DIVERSITY
ODM_SetTxAntByTxInfo ( & pHalData - > odmpriv , ptxdesc , pxmitframe - > attrib . mac_id ) ;
# endif
# ifdef CONFIG_BEAMFORMING
2016-03-27 17:56:02 +00:00
SET_TX_DESC_GID_8812 ( ptxdesc , pattrib - > txbf_g_id ) ;
SET_TX_DESC_PAID_8812 ( ptxdesc , pattrib - > txbf_p_aid ) ;
2017-04-07 11:39:45 +00:00
# endif
2017-04-09 08:42:39 +00:00
/* injected frame */
if ( pattrib - > inject = = 0xa5 ) {
SET_TX_DESC_RETRY_LIMIT_ENABLE_8812 ( ptxdesc , 1 ) ;
if ( pattrib - > retry_ctrl = = _TRUE ) {
SET_TX_DESC_DATA_RETRY_LIMIT_8812 ( ptxdesc , 6 ) ;
} else {
SET_TX_DESC_DATA_RETRY_LIMIT_8812 ( ptxdesc , 0 ) ;
}
if ( pattrib - > sgi = = _TRUE ) {
SET_TX_DESC_DATA_SHORT_8812 ( ptxdesc , 1 ) ;
} else {
SET_TX_DESC_DATA_SHORT_8812 ( ptxdesc , 0 ) ;
}
SET_TX_DESC_USE_RATE_8812 ( ptxdesc , 1 ) ;
SET_TX_DESC_TX_RATE_8812 ( ptxdesc , MRateToHwRate ( pattrib - > rate ) ) ;
if ( pattrib - > ldpc )
SET_TX_DESC_DATA_LDPC_8812 ( ptxdesc , 1 ) ;
SET_TX_DESC_DATA_STBC_8812 ( ptxdesc , pattrib - > stbc & 3 ) ;
//SET_TX_DESC_GF_8812(ptxdesc, 1); // no MCS rates if sets, GreenField?
//SET_TX_DESC_LSIG_TXOP_EN_8812(ptxdesc, 1);
//SET_TX_DESC_HTC_8812(ptxdesc, 1);
//SET_TX_DESC_NO_ACM_8812(ptxdesc, 1);
SET_TX_DESC_DATA_BW_8812 ( ptxdesc , pattrib - > bwmode ) ; // 0 - 20 MHz, 1 - 40 MHz, 2 - 80 MHz
}
2016-03-27 17:56:02 +00:00
rtl8812a_cal_txdesc_chksum ( ptxdesc ) ;
2017-04-07 11:39:45 +00:00
_dbg_dump_tx_info ( padapter , pxmitframe - > frame_tag , ptxdesc ) ;
2016-03-27 17:56:02 +00:00
return pull ;
}
# ifdef CONFIG_XMIT_THREAD_MODE
/*
* Description
* Transmit xmitbuf to hardware tx fifo
*
* Return
* _SUCCESS ok
* _FAIL something error
*/
s32 rtl8812au_xmit_buf_handler ( PADAPTER padapter )
{
PHAL_DATA_TYPE phal ;
struct xmit_priv * pxmitpriv ;
struct xmit_buf * pxmitbuf ;
s32 ret ;
phal = GET_HAL_DATA ( padapter ) ;
pxmitpriv = & padapter - > xmitpriv ;
ret = _rtw_down_sema ( & pxmitpriv - > xmit_sema ) ;
if ( _FAIL = = ret ) {
return _FAIL ;
}
if ( RTW_CANNOT_RUN ( padapter ) ) {
return _FAIL ;
}
2017-04-07 11:39:45 +00:00
if ( rtw_mi_check_pending_xmitbuf ( padapter ) = = 0 )
2016-03-27 17:56:02 +00:00
return _SUCCESS ;
# ifdef CONFIG_LPS_LCLK
ret = rtw_register_tx_alive ( padapter ) ;
if ( ret ! = _SUCCESS ) {
return _SUCCESS ;
}
# endif
do {
pxmitbuf = dequeue_pending_xmitbuf ( pxmitpriv ) ;
2017-04-07 11:39:45 +00:00
if ( pxmitbuf = = NULL )
break ;
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
rtw_write_port ( padapter , pxmitbuf - > ff_hwaddr , pxmitbuf - > len , ( unsigned char * ) pxmitbuf ) ;
2016-03-27 17:56:02 +00:00
} while ( 1 ) ;
# ifdef CONFIG_LPS_LCLK
rtw_unregister_tx_alive ( padapter ) ;
# endif
return _SUCCESS ;
}
# endif
2017-04-07 11:39:45 +00:00
/* for non-agg data frame or management frame */
2016-03-27 17:56:02 +00:00
static s32 rtw_dump_xframe ( _adapter * padapter , struct xmit_frame * pxmitframe )
{
s32 ret = _SUCCESS ;
s32 inner_ret = _SUCCESS ;
2017-04-07 11:39:45 +00:00
int t , sz , w_sz , pull = 0 ;
2016-03-27 17:56:02 +00:00
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 security_priv * psecuritypriv = & padapter - > securitypriv ;
# ifdef CONFIG_80211N_HT
if ( ( pxmitframe - > frame_tag = = DATA_FRAMETAG ) & &
( pxmitframe - > attrib . ether_type ! = 0x0806 ) & &
( pxmitframe - > attrib . ether_type ! = 0x888e ) & &
( pxmitframe - > attrib . ether_type ! = 0x88b4 ) & &
( pxmitframe - > attrib . dhcp_pkt ! = 1 ) )
rtw_issue_addbareq_cmd ( padapter , pxmitframe ) ;
2017-04-07 11:39:45 +00:00
# endif /* CONFIG_80211N_HT */
2016-03-27 17:56:02 +00:00
mem_addr = pxmitframe - > buf_addr ;
2017-04-07 11:39:45 +00:00
for ( t = 0 ; t < pattrib - > nr_frags ; t + + ) {
2016-03-27 17:56:02 +00:00
if ( inner_ret ! = _SUCCESS & & ret = = _SUCCESS )
ret = _FAIL ;
2017-04-07 11:39:45 +00:00
if ( t ! = ( pattrib - > nr_frags - 1 ) ) {
2016-03-27 17:56:02 +00:00
sz = pxmitpriv - > frag_len ;
2017-04-07 11:39:45 +00:00
sz = sz - 4 - ( psecuritypriv - > sw_encrypt ? 0 : pattrib - > icv_len ) ;
} else /* no frag */
2016-03-27 17:56:02 +00:00
sz = pattrib - > last_txcmdsz ;
pull = update_txdesc ( pxmitframe , mem_addr , sz , _FALSE ) ;
2017-04-07 11:39:45 +00:00
if ( pull ) {
mem_addr + = PACKET_OFFSET_SZ ; /* pull txdesc head */
/* pxmitbuf->pbuf = mem_addr; */
2016-03-27 17:56:02 +00:00
pxmitframe - > buf_addr = mem_addr ;
w_sz = sz + TXDESC_SIZE ;
2017-04-07 11:39:45 +00:00
} else
2016-03-27 17:56:02 +00:00
w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ ;
ff_hwaddr = rtw_get_ff_hwaddr ( pxmitframe ) ;
# ifdef CONFIG_XMIT_THREAD_MODE
pxmitbuf - > len = w_sz ;
pxmitbuf - > ff_hwaddr = ff_hwaddr ;
enqueue_pending_xmitbuf ( pxmitpriv , pxmitbuf ) ;
# else
2017-04-07 11:39:45 +00:00
inner_ret = rtw_write_port ( padapter , ff_hwaddr , w_sz , ( unsigned char * ) pxmitbuf ) ;
2016-03-27 17:56:02 +00:00
# endif
rtw_count_tx_stats ( padapter , pxmitframe , sz ) ;
2017-04-07 11:39:45 +00:00
/* RTW_INFO("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority); */
2017-04-09 08:42:39 +00:00
RT_TRACE ( _module_rtl871x_xmit_c_ , _drv_info_ , ( " rtw_write_port, w_sz=%d \n " , w_sz ) ) ;
2016-03-27 17:56:02 +00:00
mem_addr + = w_sz ;
mem_addr = ( u8 * ) RND4 ( ( ( SIZE_PTR ) ( mem_addr ) ) ) ;
}
2017-04-07 11:39:45 +00:00
2016-03-27 17:56:02 +00:00
rtw_free_xmitframe ( pxmitpriv , pxmitframe ) ;
2017-04-07 11:39:45 +00:00
if ( ret ! = _SUCCESS )
2016-03-27 17:56:02 +00:00
rtw_sctx_done_err ( & pxmitbuf - > sctx , RTW_SCTX_DONE_UNKNOWN ) ;
2017-04-07 11:39:45 +00:00
2016-03-27 17:56:02 +00:00
return ret ;
}
# ifdef CONFIG_USB_TX_AGGREGATION
static u32 xmitframe_need_length ( struct xmit_frame * pxmitframe )
{
struct pkt_attrib * pattrib = & pxmitframe - > attrib ;
u32 len = 0 ;
2017-04-07 11:39:45 +00:00
/* no consider fragement */
2016-03-27 17:56:02 +00:00
len = pattrib - > hdrlen + pattrib - > iv_len +
2017-04-07 11:39:45 +00:00
SNAP_SIZE + sizeof ( u16 ) +
pattrib - > pktlen +
( ( pattrib - > bswenc ) ? pattrib - > icv_len : 0 ) ;
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
if ( pattrib - > encrypt = = _TKIP_ )
2016-03-27 17:56:02 +00:00
len + = 8 ;
return len ;
}
2017-04-07 11:39:45 +00:00
# define IDEA_CONDITION 1 /* check all packets before enqueue */
2016-03-27 17:56:02 +00:00
s32 rtl8812au_xmitframe_complete ( _adapter * padapter , struct xmit_priv * pxmitpriv , struct xmit_buf * pxmitbuf )
{
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
struct xmit_frame * pxmitframe = NULL ;
struct xmit_frame * pfirstframe = NULL ;
2017-04-07 11:39:45 +00:00
/* aggregate variable */
2016-03-27 17:56:02 +00:00
struct hw_xmit * phwxmit ;
struct sta_info * psta = NULL ;
struct tx_servq * ptxservq = NULL ;
_irqL irqL ;
_list * xmitframe_plist = NULL , * xmitframe_phead = NULL ;
2017-04-07 11:39:45 +00:00
u32 pbuf ; /* next pkt address */
u32 pbuf_tail ; /* last pkt tail */
u32 len ; /* packet length, except TXDESC_SIZE and PKT_OFFSET */
2016-03-27 17:56:02 +00:00
u32 bulkSize = pHalData - > UsbBulkOutSize ;
u8 descCount ;
u32 bulkPtr ;
2017-04-07 11:39:45 +00:00
/* dump frame variable */
2016-03-27 17:56:02 +00:00
u32 ff_hwaddr ;
_list * sta_plist , * sta_phead ;
u8 single_sta_in_queue = _FALSE ;
# ifndef IDEA_CONDITION
int res = _SUCCESS ;
# endif
2017-04-07 11:39:45 +00:00
/* check xmitbuffer is ok */
2016-03-27 17:56:02 +00:00
if ( pxmitbuf = = NULL ) {
pxmitbuf = rtw_alloc_xmitbuf ( pxmitpriv ) ;
2017-04-07 11:39:45 +00:00
if ( pxmitbuf = = NULL ) {
/* RTW_INFO("%s #1, connot alloc xmitbuf!!!!\n",__FUNCTION__); */
2016-03-27 17:56:02 +00:00
return _FALSE ;
}
}
2017-04-07 11:39:45 +00:00
/* RTW_INFO("%s =====================================\n",__FUNCTION__); */
/* 3 1. pick up first frame */
2016-03-27 17:56:02 +00:00
do {
rtw_free_xmitframe ( pxmitpriv , pxmitframe ) ;
2017-04-07 11:39:45 +00:00
2016-03-27 17:56:02 +00:00
pxmitframe = rtw_dequeue_xframe ( pxmitpriv , pxmitpriv - > hwxmits , pxmitpriv - > hwxmit_entry ) ;
if ( pxmitframe = = NULL ) {
2017-04-07 11:39:45 +00:00
/* no more xmit frame, release xmit buffer */
/* RTW_INFO("no more xmit frame ,return\n"); */
2016-03-27 17:56:02 +00:00
rtw_free_xmitbuf ( pxmitpriv , pxmitbuf ) ;
return _FALSE ;
}
# ifndef IDEA_CONDITION
if ( pxmitframe - > frame_tag ! = DATA_FRAMETAG ) {
2017-04-07 11:39:45 +00:00
/* rtw_free_xmitframe(pxmitpriv, pxmitframe); */
2016-03-27 17:56:02 +00:00
continue ;
}
2017-04-07 11:39:45 +00:00
/* TID 0~15 */
2016-03-27 17:56:02 +00:00
if ( ( pxmitframe - > attrib . priority < 0 ) | |
( pxmitframe - > attrib . priority > 15 ) ) {
2017-04-07 11:39:45 +00:00
/* rtw_free_xmitframe(pxmitpriv, pxmitframe); */
2016-03-27 17:56:02 +00:00
continue ;
}
# endif
2017-04-07 11:39:45 +00:00
/* RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority); */
2016-03-27 17:56:02 +00:00
pxmitframe - > pxmitbuf = pxmitbuf ;
pxmitframe - > buf_addr = pxmitbuf - > pbuf ;
pxmitbuf - > priv_data = pxmitframe ;
2017-04-07 11:39:45 +00:00
pxmitframe - > agg_num = 1 ; /* alloc xmitframe should assign to 1. */
# ifdef CONFIG_TX_EARLY_MODE
pxmitframe - > pkt_offset = ( PACKET_OFFSET_SZ / 8 ) + 1 ; /* 2; */ /* first frame of aggregation, reserve one offset for EM info ,another for usb bulk-out block check */
# else
pxmitframe - > pkt_offset = ( PACKET_OFFSET_SZ / 8 ) ; /* 1; */ /* first frame of aggregation, reserve offset */
# endif
2016-03-27 17:56:02 +00:00
if ( rtw_xmitframe_coalesce ( padapter , pxmitframe - > pkt , pxmitframe ) = = _FALSE ) {
2017-04-07 11:39:45 +00:00
RTW_INFO ( " %s coalesce 1st xmitframe failed \n " , __FUNCTION__ ) ;
2016-03-27 17:56:02 +00:00
continue ;
}
2017-04-07 11:39:45 +00:00
# ifdef CONFIG_MCC_MODE
/* to calculate packet to write port */
rtw_hal_mcc_calc_tx_bytes_to_port ( padapter , pxmitframe - > pkt - > len ) ;
# endif
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* always return ndis_packet after rtw_xmitframe_coalesce */
2016-03-27 17:56:02 +00:00
rtw_os_xmit_complete ( padapter , pxmitframe ) ;
break ;
} while ( 1 ) ;
2017-04-07 11:39:45 +00:00
/* 3 2. aggregate same priority and same DA(AP or STA) frames */
2016-03-27 17:56:02 +00:00
pfirstframe = pxmitframe ;
2017-04-07 11:39:45 +00:00
len = xmitframe_need_length ( pfirstframe ) + TXDESC_SIZE + ( pfirstframe - > pkt_offset * PACKET_OFFSET_SZ ) ;
2016-03-27 17:56:02 +00:00
pbuf_tail = len ;
pbuf = _RND8 ( pbuf_tail ) ;
2017-04-07 11:39:45 +00:00
/* check pkt amount in one bulk */
2016-03-27 17:56:02 +00:00
descCount = 0 ;
bulkPtr = bulkSize ;
if ( pbuf < bulkPtr )
descCount + + ;
2017-04-07 11:39:45 +00:00
if ( descCount = = pHalData - > UsbTxAggDescNum )
goto agg_end ;
2016-03-27 17:56:02 +00:00
else {
descCount = 0 ;
2017-04-07 11:39:45 +00:00
bulkPtr = ( ( pbuf / bulkSize ) + 1 ) * bulkSize ; /* round to next bulkSize */
2016-03-27 17:56:02 +00:00
}
2017-04-07 11:39:45 +00:00
/* dequeue same priority packet from station tx queue */
2016-03-27 17:56:02 +00:00
psta = pfirstframe - > attrib . psta ;
switch ( pfirstframe - > attrib . priority ) {
2017-04-07 11:39:45 +00:00
case 1 :
case 2 :
ptxservq = & ( psta - > sta_xmitpriv . bk_q ) ;
phwxmit = pxmitpriv - > hwxmits + 3 ;
break ;
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
case 4 :
case 5 :
ptxservq = & ( psta - > sta_xmitpriv . vi_q ) ;
phwxmit = pxmitpriv - > hwxmits + 1 ;
break ;
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
case 6 :
case 7 :
ptxservq = & ( psta - > sta_xmitpriv . vo_q ) ;
phwxmit = pxmitpriv - > hwxmits ;
break ;
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
case 0 :
case 3 :
default :
ptxservq = & ( psta - > sta_xmitpriv . be_q ) ;
phwxmit = pxmitpriv - > hwxmits + 2 ;
break ;
2016-03-27 17:56:02 +00:00
}
2017-04-07 11:39:45 +00:00
/* RTW_INFO("==> pkt_no=%d,pkt_len=%d,len=%d,RND8_LEN=%d,pkt_offset=0x%02x\n", */
/* pxmitframe->agg_num,pxmitframe->attrib.last_txcmdsz,len,pbuf,pxmitframe->pkt_offset ); */
2016-03-27 17:56:02 +00:00
_enter_critical_bh ( & pxmitpriv - > lock , & irqL ) ;
sta_phead = get_list_head ( phwxmit - > sta_queue ) ;
sta_plist = get_next ( sta_phead ) ;
single_sta_in_queue = rtw_end_of_queue_search ( sta_phead , get_next ( sta_plist ) ) ;
xmitframe_phead = get_list_head ( & ptxservq - > sta_pending ) ;
xmitframe_plist = get_next ( xmitframe_phead ) ;
2017-04-07 11:39:45 +00:00
while ( rtw_end_of_queue_search ( xmitframe_phead , xmitframe_plist ) = = _FALSE ) {
2016-03-27 17:56:02 +00:00
pxmitframe = LIST_CONTAINOR ( xmitframe_plist , struct xmit_frame , list ) ;
xmitframe_plist = get_next ( xmitframe_plist ) ;
2017-04-07 11:39:45 +00:00
if ( _FAIL = = rtw_hal_busagg_qsel_check ( padapter , pfirstframe - > attrib . qsel , pxmitframe - > attrib . qsel ) )
2016-03-27 17:56:02 +00:00
break ;
2017-04-07 11:39:45 +00:00
pxmitframe - > agg_num = 0 ; /* not first frame of aggregation */
# ifdef CONFIG_TX_EARLY_MODE
pxmitframe - > pkt_offset = 1 ; /* not first frame of aggregation,reserve offset for EM Info */
# else
pxmitframe - > pkt_offset = 0 ; /* not first frame of aggregation, no need to reserve offset */
# endif
len = xmitframe_need_length ( pxmitframe ) + TXDESC_SIZE + ( pxmitframe - > pkt_offset * PACKET_OFFSET_SZ ) ;
2016-03-27 17:56:02 +00:00
if ( _RND8 ( pbuf + len ) > MAX_XMITBUF_SZ )
2017-04-07 11:39:45 +00:00
/* if (_RND8(pbuf + len) > (MAX_XMITBUF_SZ/2))//to do : for TX TP finial tune , Georgia 2012-0323 */
2016-03-27 17:56:02 +00:00
{
2017-04-07 11:39:45 +00:00
/* RTW_INFO("%s....len> MAX_XMITBUF_SZ\n",__FUNCTION__); */
2016-03-27 17:56:02 +00:00
pxmitframe - > agg_num = 1 ;
2017-04-07 11:39:45 +00:00
pxmitframe - > pkt_offset = 1 ;
break ;
2016-03-27 17:56:02 +00:00
}
rtw_list_delete ( & pxmitframe - > list ) ;
ptxservq - > qcnt - - ;
phwxmit - > accnt - - ;
# ifndef IDEA_CONDITION
2017-04-07 11:39:45 +00:00
/* suppose only data frames would be in queue */
2016-03-27 17:56:02 +00:00
if ( pxmitframe - > frame_tag ! = DATA_FRAMETAG ) {
rtw_free_xmitframe ( pxmitpriv , pxmitframe ) ;
continue ;
}
2017-04-07 11:39:45 +00:00
/* TID 0~15 */
2016-03-27 17:56:02 +00:00
if ( ( pxmitframe - > attrib . priority < 0 ) | |
( pxmitframe - > attrib . priority > 15 ) ) {
rtw_free_xmitframe ( pxmitpriv , pxmitframe ) ;
continue ;
}
# endif
2017-04-07 11:39:45 +00:00
/* pxmitframe->pxmitbuf = pxmitbuf; */
2016-03-27 17:56:02 +00:00
pxmitframe - > buf_addr = pxmitbuf - > pbuf + pbuf ;
2017-04-07 11:39:45 +00:00
2016-03-27 17:56:02 +00:00
if ( rtw_xmitframe_coalesce ( padapter , pxmitframe - > pkt , pxmitframe ) = = _FALSE ) {
2017-04-07 11:39:45 +00:00
RTW_INFO ( " %s coalesce failed \n " , __FUNCTION__ ) ;
2016-03-27 17:56:02 +00:00
rtw_free_xmitframe ( pxmitpriv , pxmitframe ) ;
continue ;
}
2017-04-07 11:39:45 +00:00
# ifdef CONFIG_MCC_MODE
/* to calculate packet to write port */
rtw_hal_mcc_calc_tx_bytes_to_port ( padapter , pxmitframe - > pkt - > len ) ;
# endif
/* RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority); */
/* always return ndis_packet after rtw_xmitframe_coalesce */
2016-03-27 17:56:02 +00:00
rtw_os_xmit_complete ( padapter , pxmitframe ) ;
2017-04-07 11:39:45 +00:00
/* (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz */
update_txdesc ( pxmitframe , pxmitframe - > buf_addr , pxmitframe - > attrib . last_txcmdsz , _TRUE ) ;
/* don't need xmitframe any more */
2016-03-27 17:56:02 +00:00
rtw_free_xmitframe ( pxmitpriv , pxmitframe ) ;
2017-04-07 11:39:45 +00:00
/* handle pointer and stop condition */
2016-03-27 17:56:02 +00:00
pbuf_tail = pbuf + len ;
pbuf = _RND8 ( pbuf_tail ) ;
pfirstframe - > agg_num + + ;
2017-04-07 11:39:45 +00:00
# ifdef CONFIG_TX_EARLY_MODE
pxmitpriv - > agg_pkt [ pfirstframe - > agg_num - 1 ] . offset = _RND8 ( len ) ;
pxmitpriv - > agg_pkt [ pfirstframe - > agg_num - 1 ] . pkt_len = pxmitframe - > attrib . last_txcmdsz ;
2016-03-27 17:56:02 +00:00
# endif
2017-04-07 11:39:45 +00:00
# ifdef CONFIG_MCC_MODE
if ( rtw_hal_mcc_stop_tx_bytes_to_port ( padapter ) )
break ;
# endif
2016-03-27 17:56:02 +00:00
if ( MAX_TX_AGG_PACKET_NUMBER = = pfirstframe - > agg_num )
break ;
if ( pbuf < bulkPtr ) {
descCount + + ;
if ( descCount = = pHalData - > UsbTxAggDescNum )
break ;
} else {
descCount = 0 ;
bulkPtr = ( ( pbuf / bulkSize ) + 1 ) * bulkSize ;
}
2017-04-07 11:39:45 +00:00
} /* end while( aggregate same priority and same DA(AP or STA) frames) */
2016-03-27 17:56:02 +00:00
if ( _rtw_queue_empty ( & ptxservq - > sta_pending ) = = _TRUE )
rtw_list_delete ( & ptxservq - > tx_pending ) ;
else if ( single_sta_in_queue = = _FALSE ) {
/* Re-arrange the order of stations in this ac queue to balance the service for these stations */
rtw_list_delete ( & ptxservq - > tx_pending ) ;
rtw_list_insert_tail ( & ptxservq - > tx_pending , get_list_head ( phwxmit - > sta_queue ) ) ;
}
_exit_critical_bh ( & pxmitpriv - > lock , & irqL ) ;
agg_end :
# ifdef CONFIG_80211N_HT
if ( ( pfirstframe - > attrib . ether_type ! = 0x0806 ) & &
( pfirstframe - > attrib . ether_type ! = 0x888e ) & &
( pfirstframe - > attrib . ether_type ! = 0x88b4 ) & &
( pfirstframe - > attrib . dhcp_pkt ! = 1 ) )
rtw_issue_addbareq_cmd ( padapter , pfirstframe ) ;
2017-04-07 11:39:45 +00:00
# endif /* CONFIG_80211N_HT */
2016-03-27 17:56:02 +00:00
# ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
2017-04-07 11:39:45 +00:00
/* 3 3. update first frame txdesc */
2016-03-27 17:56:02 +00:00
if ( ( PACKET_OFFSET_SZ ! = 0 ) & & ( ( pbuf_tail % bulkSize ) = = 0 ) ) {
2017-04-07 11:39:45 +00:00
/* remove pkt_offset */
2016-03-27 17:56:02 +00:00
pbuf_tail - = PACKET_OFFSET_SZ ;
pfirstframe - > buf_addr + = PACKET_OFFSET_SZ ;
pfirstframe - > pkt_offset - - ;
2017-04-07 11:39:45 +00:00
/* RTW_INFO("$$$$$ buf size equal to USB block size $$$$$$\n"); */
2016-03-27 17:56:02 +00:00
}
2017-04-07 11:39:45 +00:00
# endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
update_txdesc ( pfirstframe , pfirstframe - > buf_addr , pfirstframe - > attrib . last_txcmdsz , _TRUE ) ;
# ifdef CONFIG_TX_EARLY_MODE
/* prepare EM info for first frame, agg_num value start from 1 */
pxmitpriv - > agg_pkt [ 0 ] . offset = _RND8 ( pfirstframe - > attrib . last_txcmdsz + TXDESC_SIZE + ( pfirstframe - > pkt_offset * PACKET_OFFSET_SZ ) ) ;
pxmitpriv - > agg_pkt [ 0 ] . pkt_len = pfirstframe - > attrib . last_txcmdsz ; /* get from rtw_xmitframe_coalesce */
UpdateEarlyModeInfo8812 ( pxmitpriv , pxmitbuf ) ;
# endif
/* 3 4. write xmit buffer to USB FIFO */
2016-03-27 17:56:02 +00:00
ff_hwaddr = rtw_get_ff_hwaddr ( pfirstframe ) ;
2017-04-07 11:39:45 +00:00
/* RTW_INFO("%s ===================================== write port,buf_size(%d)\n",__FUNCTION__,pbuf_tail); */
/* xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr */
rtw_write_port ( padapter , ff_hwaddr , pbuf_tail , ( u8 * ) pxmitbuf ) ;
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* 3 5. update statisitc */
2016-03-27 17:56:02 +00:00
pbuf_tail - = ( pfirstframe - > agg_num * TXDESC_SIZE ) ;
pbuf_tail - = ( pfirstframe - > pkt_offset * PACKET_OFFSET_SZ ) ;
2017-04-07 11:39:45 +00:00
2016-03-27 17:56:02 +00:00
rtw_count_tx_stats ( padapter , pfirstframe , pbuf_tail ) ;
rtw_free_xmitframe ( pxmitpriv , pfirstframe ) ;
return _TRUE ;
}
# else
s32 rtl8812au_xmitframe_complete ( _adapter * padapter , struct xmit_priv * pxmitpriv , struct xmit_buf * pxmitbuf )
2017-04-07 11:39:45 +00:00
{
2016-03-27 17:56:02 +00:00
struct hw_xmit * phwxmits ;
sint hwentry ;
2017-04-07 11:39:45 +00:00
struct xmit_frame * pxmitframe = NULL ;
int res = _SUCCESS , xcnt = 0 ;
2016-03-27 17:56:02 +00:00
phwxmits = pxmitpriv - > hwxmits ;
hwentry = pxmitpriv - > hwxmit_entry ;
2017-04-07 11:39:45 +00:00
if ( pxmitbuf = = NULL ) {
pxmitbuf = rtw_alloc_xmitbuf ( pxmitpriv ) ;
if ( ! pxmitbuf )
2016-03-27 17:56:02 +00:00
return _FALSE ;
2017-04-07 11:39:45 +00:00
}
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
do {
2016-03-27 17:56:02 +00:00
pxmitframe = rtw_dequeue_xframe ( pxmitpriv , phwxmits , hwentry ) ;
2017-04-07 11:39:45 +00:00
if ( pxmitframe ) {
pxmitframe - > pxmitbuf = pxmitbuf ;
2016-03-27 17:56:02 +00:00
pxmitframe - > buf_addr = pxmitbuf - > pbuf ;
2017-04-07 11:39:45 +00:00
pxmitbuf - > priv_data = pxmitframe ;
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
if ( ( pxmitframe - > frame_tag & 0x0f ) = = DATA_FRAMETAG ) {
if ( pxmitframe - > attrib . priority < = 15 ) /* TID0~15 */
2016-03-27 17:56:02 +00:00
res = rtw_xmitframe_coalesce ( padapter , pxmitframe - > pkt , pxmitframe ) ;
2017-04-07 11:39:45 +00:00
/* RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority); */
rtw_os_xmit_complete ( padapter , pxmitframe ) ; /* always return ndis_packet after rtw_xmitframe_coalesce */
2016-03-27 17:56:02 +00:00
}
2017-04-07 11:39:45 +00:00
if ( res = = _SUCCESS )
rtw_dump_xframe ( padapter , pxmitframe ) ;
else {
2016-03-27 17:56:02 +00:00
rtw_free_xmitbuf ( pxmitpriv , pxmitbuf ) ;
2017-04-07 11:39:45 +00:00
rtw_free_xmitframe ( pxmitpriv , pxmitframe ) ;
2016-03-27 17:56:02 +00:00
}
2017-04-07 11:39:45 +00:00
2016-03-27 17:56:02 +00:00
xcnt + + ;
2017-04-07 11:39:45 +00:00
} else {
2016-03-27 17:56:02 +00:00
rtw_free_xmitbuf ( pxmitpriv , pxmitbuf ) ;
return _FALSE ;
}
break ;
2017-04-07 11:39:45 +00:00
} while ( 0 /*xcnt < (NR_XMITFRAME >> 3)*/ ) ;
2016-03-27 17:56:02 +00:00
return _TRUE ;
2017-04-07 11:39:45 +00:00
2016-03-27 17:56:02 +00:00
}
# endif
static s32 xmitframe_direct ( _adapter * padapter , struct xmit_frame * pxmitframe )
{
s32 res = _SUCCESS ;
2017-04-07 11:39:45 +00:00
/* RTW_INFO("==> %s\n",__FUNCTION__); */
2016-03-27 17:56:02 +00:00
res = rtw_xmitframe_coalesce ( padapter , pxmitframe - > pkt , pxmitframe ) ;
2017-04-07 11:39:45 +00:00
if ( res = = _SUCCESS )
2016-03-27 17:56:02 +00:00
rtw_dump_xframe ( padapter , pxmitframe ) ;
2017-04-07 11:39:45 +00:00
else
RTW_INFO ( " ==> %s xmitframe_coalsece failed \n " , __FUNCTION__ ) ;
2016-03-27 17:56:02 +00:00
return res ;
}
/*
* Return
* _TRUE dump packet directly
* _FALSE enqueue packet
*/
static s32 pre_xmitframe ( _adapter * padapter , struct xmit_frame * pxmitframe )
{
2017-04-07 11:39:45 +00:00
_irqL irqL ;
2016-03-27 17:56:02 +00:00
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 ) ;
2017-04-07 11:39:45 +00:00
if ( rtw_txframes_sta_ac_pending ( padapter , pattrib ) > 0 ) {
/* RTW_INFO("enqueue AC(%d)\n",pattrib->priority); */
2016-03-27 17:56:02 +00:00
goto enqueue ;
}
if ( rtw_xmit_ac_blocked ( padapter ) = = _TRUE )
goto enqueue ;
2017-04-07 11:39:45 +00:00
if ( padapter - > dvobj - > iface_state . lg_sta_num )
2016-03-27 17:56:02 +00:00
goto enqueue ;
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 ) {
rtw_free_xmitframe ( pxmitpriv , pxmitframe ) ;
pxmitpriv - > tx_drop + + ;
return _TRUE ;
}
return _FALSE ;
}
s32 rtl8812au_mgnt_xmit ( _adapter * padapter , struct xmit_frame * pmgntframe )
{
return rtw_dump_xframe ( padapter , pmgntframe ) ;
}
/*
* Return
* _TRUE dump packet directly ok
* _FALSE temporary can ' t transmit packets to hardware
*/
s32 rtl8812au_hal_xmit ( _adapter * padapter , struct xmit_frame * pxmitframe )
{
return pre_xmitframe ( padapter , pxmitframe ) ;
}
s32 rtl8812au_hal_xmitframe_enqueue ( _adapter * padapter , struct xmit_frame * pxmitframe )
{
2017-04-07 11:39:45 +00:00
struct xmit_priv * pxmitpriv = & padapter - > xmitpriv ;
2016-03-27 17:56:02 +00:00
s32 err ;
2017-04-07 11:39:45 +00:00
err = rtw_xmitframe_enqueue ( padapter , pxmitframe ) ;
if ( err ! = _SUCCESS ) {
2016-03-27 17:56:02 +00:00
rtw_free_xmitframe ( pxmitpriv , pxmitframe ) ;
2017-04-07 11:39:45 +00:00
pxmitpriv - > tx_drop + + ;
} else {
2016-03-27 17:56:02 +00:00
# ifdef PLATFORM_LINUX
tasklet_hi_schedule ( & pxmitpriv - > xmit_tasklet ) ;
# endif
}
2017-04-07 11:39:45 +00:00
2016-03-27 17:56:02 +00:00
return err ;
2017-04-07 11:39:45 +00:00
2016-03-27 17:56:02 +00:00
}
2017-04-07 11:39:45 +00:00
# ifdef CONFIG_HOSTAPD_MLME
2016-03-27 17:56:02 +00:00
static void rtl8812au_hostap_mgnt_xmit_cb ( struct urb * urb )
2017-04-07 11:39:45 +00:00
{
2016-03-27 17:56:02 +00:00
# ifdef PLATFORM_LINUX
struct sk_buff * skb = ( struct sk_buff * ) urb - > context ;
2017-04-07 11:39:45 +00:00
/* RTW_INFO("%s\n", __FUNCTION__); */
2016-03-27 17:56:02 +00:00
rtw_skb_free ( skb ) ;
2017-04-07 11:39:45 +00:00
# endif
2016-03-27 17:56:02 +00:00
}
s32 rtl8812au_hostap_mgnt_xmit_entry ( _adapter * padapter , _pkt * pkt )
{
# ifdef PLATFORM_LINUX
u16 fc ;
2017-04-07 11:39:45 +00:00
int rc , len , pipe ;
2016-03-27 17:56:02 +00:00
unsigned int bmcst , tid , qsel ;
struct sk_buff * skb , * pxmit_skb ;
struct urb * urb ;
unsigned char * pxmitbuf ;
struct tx_desc * ptxdesc ;
struct rtw_ieee80211_hdr * tx_hdr ;
2017-04-07 11:39:45 +00:00
struct hostapd_priv * phostapdpriv = padapter - > phostapdpriv ;
2016-03-27 17:56:02 +00:00
struct net_device * pnetdev = padapter - > pnetdev ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
2017-04-07 11:39:45 +00:00
struct dvobj_priv * pdvobj = adapter_to_dvobj ( padapter ) ;
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* RTW_INFO("%s\n", __FUNCTION__); */
2016-03-27 17:56:02 +00:00
skb = pkt ;
2017-04-07 11:39:45 +00:00
2016-03-27 17:56:02 +00:00
len = skb - > len ;
tx_hdr = ( struct rtw_ieee80211_hdr * ) ( skb - > data ) ;
fc = le16_to_cpu ( tx_hdr - > frame_ctl ) ;
bmcst = IS_MCAST ( tx_hdr - > addr1 ) ;
if ( ( fc & RTW_IEEE80211_FCTL_FTYPE ) ! = RTW_IEEE80211_FTYPE_MGMT )
goto _exit ;
pxmit_skb = rtw_skb_alloc ( len + TXDESC_SIZE ) ;
2017-04-07 11:39:45 +00:00
if ( ! pxmit_skb )
2016-03-27 17:56:02 +00:00
goto _exit ;
pxmitbuf = pxmit_skb - > data ;
urb = usb_alloc_urb ( 0 , GFP_ATOMIC ) ;
2017-04-07 11:39:45 +00:00
if ( ! urb )
2016-03-27 17:56:02 +00:00
goto _exit ;
2017-04-07 11:39:45 +00:00
/* ----- fill tx desc ----- */
ptxdesc = ( struct tx_desc * ) pxmitbuf ;
2016-03-27 17:56:02 +00:00
_rtw_memset ( ptxdesc , 0 , sizeof ( * ptxdesc ) ) ;
2017-04-07 11:39:45 +00:00
/* offset 0 */
ptxdesc - > txdw0 | = cpu_to_le32 ( len & 0x0000ffff ) ;
ptxdesc - > txdw0 | = cpu_to_le32 ( ( ( TXDESC_SIZE + OFFSET_SZ ) < < OFFSET_SHT ) & 0x00ff0000 ) ; /* default = 32 bytes for TX Desc */
2016-03-27 17:56:02 +00:00
ptxdesc - > txdw0 | = cpu_to_le32 ( OWN | FSG | LSG ) ;
2017-04-07 11:39:45 +00:00
if ( bmcst )
2016-03-27 17:56:02 +00:00
ptxdesc - > txdw0 | = cpu_to_le32 ( BIT ( 24 ) ) ;
2017-04-07 11:39:45 +00:00
/* offset 4 */
ptxdesc - > txdw1 | = cpu_to_le32 ( 0x00 ) ; /* MAC_ID */
ptxdesc - > txdw1 | = cpu_to_le32 ( ( 0x12 < < QSEL_SHT ) & 0x00001f00 ) ;
ptxdesc - > txdw1 | = cpu_to_le32 ( ( 0x06 < < 16 ) & 0x000f0000 ) ; /* b mode */
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* offset 8 */
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* offset 12 */
ptxdesc - > txdw3 | = cpu_to_le32 ( ( le16_to_cpu ( tx_hdr - > seq_ctl ) < < 16 ) & 0xffff0000 ) ;
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* offset 16 */
ptxdesc - > txdw4 | = cpu_to_le32 ( BIT ( 8 ) ) ; /* driver uses rate */
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* offset 20 */
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* HW append seq */
ptxdesc - > txdw4 | = cpu_to_le32 ( BIT ( 7 ) ) ; /* Hw set sequence number */
ptxdesc - > txdw3 | = cpu_to_le32 ( ( 8 < < 28 ) ) ; /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
2016-03-27 17:56:02 +00:00
2017-04-09 08:42:39 +00:00
//rtl8188eu_cal_txdesc_chksum(ptxdesc);
rtl8812au_cal_txdesc_chksum ( ptxdesc ) ;
// ----- end of fill tx desc -----
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* */
2016-03-27 17:56:02 +00:00
skb_put ( pxmit_skb , len + TXDESC_SIZE ) ;
pxmitbuf = pxmitbuf + TXDESC_SIZE ;
_rtw_memcpy ( pxmitbuf , skb - > data , len ) ;
2017-04-07 11:39:45 +00:00
/* RTW_INFO("mgnt_xmit, len=%x\n", pxmit_skb->len); */
/* ----- prepare urb for submit ----- */
2016-03-27 17:56:02 +00:00
2017-04-07 11:39:45 +00:00
/* translate DMA FIFO addr to pipehandle */
/* pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX); */
pipe = usb_sndbulkpipe ( pdvobj - > pusbdev , pHalData - > Queue2EPNum [ ( u8 ) MGT_QUEUE_INX ] & 0x0f ) ;
2016-03-27 17:56:02 +00:00
usb_fill_bulk_urb ( urb , pdvobj - > pusbdev , pipe ,
2017-04-09 08:42:39 +00:00
pxmit_skb - > data , pxmit_skb - > len , rtl8812au_hostap_mgnt_xmit_cb , pxmit_skb ) ;
2016-03-27 17:56:02 +00:00
urb - > transfer_flags | = URB_ZERO_PACKET ;
usb_anchor_urb ( urb , & phostapdpriv - > anchored ) ;
rc = usb_submit_urb ( urb , GFP_ATOMIC ) ;
if ( rc < 0 ) {
usb_unanchor_urb ( urb ) ;
kfree_skb ( skb ) ;
}
usb_free_urb ( urb ) ;
2017-04-07 11:39:45 +00:00
_exit :
2016-03-27 17:56:02 +00:00
rtw_skb_free ( skb ) ;
# endif
return 0 ;
}
# endif
2017-04-09 08:42:39 +00:00