summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/rtl8188e_xmit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/rtl8188e_xmit.c')
-rwxr-xr-xdrivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/rtl8188e_xmit.c293
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
+
+