diff options
Diffstat (limited to 'drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/rtl8188e_xmit.c')
-rwxr-xr-x | drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/rtl8188e_xmit.c | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/rtl8188e_xmit.c b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/rtl8188e_xmit.c new file mode 100755 index 00000000..55c1ca55 --- /dev/null +++ b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/rtl8188e_xmit.c @@ -0,0 +1,293 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * 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 _RTL8188E_XMIT_C_ + +#include <drv_conf.h> +#include <osdep_service.h> +#include <drv_types.h> +#include <sdio_ops.h> +#include <rtl8188e_hal.h> + +#ifdef CONFIG_XMIT_ACK +void dump_txrpt_ccx_88e(void *buf) +{ + struct txrpt_ccx_88e *txrpt_ccx = (struct txrpt_ccx_88e *)buf; + + DBG_871X("%s:\n" + "tag1:%u, pkt_num:%u, txdma_underflow:%u, int_bt:%u, int_tri:%u, int_ccx:%u\n" + "mac_id:%u, pkt_ok:%u, bmc:%u\n" + "retry_cnt:%u, lifetime_over:%u, retry_over:%u\n" + "ccx_qtime:%u\n" + "final_data_rate:0x%02x\n" + "qsel:%u, sw:0x%03x\n" + , __func__ + , txrpt_ccx->tag1, txrpt_ccx->pkt_num, txrpt_ccx->txdma_underflow, txrpt_ccx->int_bt, txrpt_ccx->int_tri, txrpt_ccx->int_ccx + , txrpt_ccx->mac_id, txrpt_ccx->pkt_ok, txrpt_ccx->bmc + , txrpt_ccx->retry_cnt, txrpt_ccx->lifetime_over, txrpt_ccx->retry_over + , txrpt_ccx_qtime_88e(txrpt_ccx) + , txrpt_ccx->final_data_rate + , txrpt_ccx->qsel, txrpt_ccx_sw_88e(txrpt_ccx) + ); +} + +void handle_txrpt_ccx_88e(_adapter *adapter, u8 *buf) +{ + struct txrpt_ccx_88e *txrpt_ccx = (struct txrpt_ccx_88e *)buf; + + #ifdef DBG_CCX + dump_txrpt_ccx_88e(buf); + #endif + + if (txrpt_ccx->int_ccx) { + if (txrpt_ccx->pkt_ok) + rtw_ack_tx_done(&adapter->xmitpriv, RTW_SCTX_DONE_SUCCESS); + else + rtw_ack_tx_done(&adapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL); + } +} +#endif //CONFIG_XMIT_ACK + +void _dbg_dump_tx_info(_adapter *padapter,int frame_tag,struct tx_desc *ptxdesc) +{ + u8 bDumpTxPkt; + u8 bDumpTxDesc = _FALSE; + rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(bDumpTxPkt)); + + if(bDumpTxPkt ==1){//dump txdesc for data frame + DBG_871X("dump tx_desc for data frame\n"); + if((frame_tag&0x0f) == DATA_FRAMETAG){ + bDumpTxDesc = _TRUE; + } + } + else if(bDumpTxPkt ==2){//dump txdesc for mgnt frame + DBG_871X("dump tx_desc for mgnt frame\n"); + if((frame_tag&0x0f) == MGNT_FRAMETAG){ + bDumpTxDesc = _TRUE; + } + } + else if(bDumpTxPkt ==3){//dump early info + } + + if(bDumpTxDesc){ + // ptxdesc->txdw4 = cpu_to_le32(0x00001006);//RTS Rate=24M + // ptxdesc->txdw6 = 0x6666f800; + DBG_8192C("=====================================\n"); + DBG_8192C("txdw0(0x%08x)\n",ptxdesc->txdw0); + DBG_8192C("txdw1(0x%08x)\n",ptxdesc->txdw1); + DBG_8192C("txdw2(0x%08x)\n",ptxdesc->txdw2); + DBG_8192C("txdw3(0x%08x)\n",ptxdesc->txdw3); + DBG_8192C("txdw4(0x%08x)\n",ptxdesc->txdw4); + DBG_8192C("txdw5(0x%08x)\n",ptxdesc->txdw5); + DBG_8192C("txdw6(0x%08x)\n",ptxdesc->txdw6); + DBG_8192C("txdw7(0x%08x)\n",ptxdesc->txdw7); + DBG_8192C("=====================================\n"); + } + +} + +/* + * Description: + * Aggregation packets and send to hardware + * + * Return: + * 0 Success + * -1 Hardware resource(TX FIFO) not ready + * -2 Software resource(xmitbuf) not ready + */ +#ifdef CONFIG_TX_EARLY_MODE + +//#define DBG_EMINFO + +#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1 + #define EARLY_MODE_MAX_PKT_NUM 10 +#else + #define EARLY_MODE_MAX_PKT_NUM 5 +#endif + + +struct EMInfo{ + u8 EMPktNum; + u16 EMPktLen[EARLY_MODE_MAX_PKT_NUM]; +}; + + +void +InsertEMContent_8188E( + struct EMInfo *pEMInfo, + IN pu1Byte VirtualAddress) +{ + +#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1 + u1Byte index=0; + u4Byte dwtmp=0; +#endif + + _rtw_memset(VirtualAddress, 0, EARLY_MODE_INFO_SIZE); + if(pEMInfo->EMPktNum==0) + return; + + #ifdef DBG_EMINFO + { + int i; + DBG_8192C("\n%s ==> pEMInfo->EMPktNum =%d\n",__FUNCTION__,pEMInfo->EMPktNum); + for(i=0;i< EARLY_MODE_MAX_PKT_NUM;i++){ + DBG_8192C("%s ==> pEMInfo->EMPktLen[%d] =%d\n",__FUNCTION__,i,pEMInfo->EMPktLen[i]); + } + + } + #endif + +#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1 + SET_EARLYMODE_PKTNUM(VirtualAddress, pEMInfo->EMPktNum); + + if(pEMInfo->EMPktNum == 1){ + dwtmp = pEMInfo->EMPktLen[0]; + }else{ + dwtmp = pEMInfo->EMPktLen[0]; + dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4; + dwtmp += pEMInfo->EMPktLen[1]; + } + SET_EARLYMODE_LEN0(VirtualAddress, dwtmp); + if(pEMInfo->EMPktNum <= 3){ + dwtmp = pEMInfo->EMPktLen[2]; + }else{ + dwtmp = pEMInfo->EMPktLen[2]; + dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4; + dwtmp += pEMInfo->EMPktLen[3]; + } + SET_EARLYMODE_LEN1(VirtualAddress, dwtmp); + if(pEMInfo->EMPktNum <= 5){ + dwtmp = pEMInfo->EMPktLen[4]; + }else{ + dwtmp = pEMInfo->EMPktLen[4]; + dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4; + dwtmp += pEMInfo->EMPktLen[5]; + } + SET_EARLYMODE_LEN2_1(VirtualAddress, dwtmp&0xF); + SET_EARLYMODE_LEN2_2(VirtualAddress, dwtmp>>4); + if(pEMInfo->EMPktNum <= 7){ + dwtmp = pEMInfo->EMPktLen[6]; + }else{ + dwtmp = pEMInfo->EMPktLen[6]; + dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4; + dwtmp += pEMInfo->EMPktLen[7]; + } + SET_EARLYMODE_LEN3(VirtualAddress, dwtmp); + if(pEMInfo->EMPktNum <= 9){ + dwtmp = pEMInfo->EMPktLen[8]; + }else{ + dwtmp = pEMInfo->EMPktLen[8]; + dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4; + dwtmp += pEMInfo->EMPktLen[9]; + } + SET_EARLYMODE_LEN4(VirtualAddress, dwtmp); +#else + SET_EARLYMODE_PKTNUM(VirtualAddress, pEMInfo->EMPktNum); + SET_EARLYMODE_LEN0(VirtualAddress, pEMInfo->EMPktLen[0]); + SET_EARLYMODE_LEN1(VirtualAddress, pEMInfo->EMPktLen[1]); + SET_EARLYMODE_LEN2_1(VirtualAddress, pEMInfo->EMPktLen[2]&0xF); + SET_EARLYMODE_LEN2_2(VirtualAddress, pEMInfo->EMPktLen[2]>>4); + SET_EARLYMODE_LEN3(VirtualAddress, pEMInfo->EMPktLen[3]); + SET_EARLYMODE_LEN4(VirtualAddress, pEMInfo->EMPktLen[4]); +#endif + //RT_PRINT_DATA(COMP_SEND, DBG_LOUD, "EMHdr:", VirtualAddress, 8); + +} + + + +void UpdateEarlyModeInfo8188E(struct xmit_priv *pxmitpriv,struct xmit_buf *pxmitbuf ) +{ + //_adapter *padapter, struct xmit_frame *pxmitframe,struct tx_servq *ptxservq + int index,j; + u16 offset,pktlen; + PTXDESC ptxdesc; + + u8 *pmem,*pEMInfo_mem; + s8 node_num_0=0,node_num_1=0; + struct EMInfo eminfo; + struct agg_pkt_info *paggpkt; + struct xmit_frame *pframe = (struct xmit_frame*)pxmitbuf->priv_data; + pmem= pframe->buf_addr; + + #ifdef DBG_EMINFO + DBG_8192C("\n%s ==> agg_num:%d\n",__FUNCTION__, pframe->agg_num); + for(index=0;index<pframe->agg_num;index++){ + offset = pxmitpriv->agg_pkt[index].offset; + pktlen = pxmitpriv->agg_pkt[index].pkt_len; + DBG_8192C("%s ==> agg_pkt[%d].offset=%d\n",__FUNCTION__,index,offset); + DBG_8192C("%s ==> agg_pkt[%d].pkt_len=%d\n",__FUNCTION__,index,pktlen); + } + #endif + + if( pframe->agg_num > EARLY_MODE_MAX_PKT_NUM) + { + node_num_0 = pframe->agg_num; + node_num_1= EARLY_MODE_MAX_PKT_NUM-1; + } + + for(index=0;index<pframe->agg_num;index++){ + + offset = pxmitpriv->agg_pkt[index].offset; + pktlen = pxmitpriv->agg_pkt[index].pkt_len; + + _rtw_memset(&eminfo,0,sizeof(struct EMInfo)); + if( pframe->agg_num > EARLY_MODE_MAX_PKT_NUM){ + if(node_num_0 > EARLY_MODE_MAX_PKT_NUM){ + eminfo.EMPktNum = EARLY_MODE_MAX_PKT_NUM; + node_num_0--; + } + else{ + eminfo.EMPktNum = node_num_1; + node_num_1--; + } + } + else{ + eminfo.EMPktNum = pframe->agg_num-(index+1); + } + for(j=0;j< eminfo.EMPktNum ;j++){ + eminfo.EMPktLen[j] = pxmitpriv->agg_pkt[index+1+j].pkt_len+4;// 4 bytes CRC + } + + if(pmem){ + if(index==0){ + ptxdesc = (PTXDESC)(pmem); + pEMInfo_mem = ((u8 *)ptxdesc)+TXDESC_SIZE; + } + else{ + pmem = pmem + pxmitpriv->agg_pkt[index-1].offset; + ptxdesc = (PTXDESC)(pmem); + pEMInfo_mem = ((u8 *)ptxdesc)+TXDESC_SIZE; + } + + #ifdef DBG_EMINFO + DBG_8192C("%s ==> desc.pkt_len=%d\n",__FUNCTION__,ptxdesc->pktlen); + #endif + InsertEMContent_8188E(&eminfo,pEMInfo_mem); + } + + + } + _rtw_memset(pxmitpriv->agg_pkt,0,sizeof(struct agg_pkt_info)*MAX_AGG_PKT_NUM); + +} +#endif + + |