/****************************************************************************** * * 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 #include #include #include #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(struct 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(struct 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; u32 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 ) { //struct 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;indexagg_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;indexagg_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