static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt) { int pull = 0; uint qsel; u8 data_rate, pwr_status, offset; struct adapter *adapt = pxmitframe->padapter; struct pkt_attrib *pattrib = &pxmitframe->attrib; struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); struct tx_desc *ptxdesc = (struct tx_desc *)pmem; struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); int bmcst = IS_MCAST(pattrib->ra); if (adapt->registrypriv.mp_mode == 0) { if ((!bagg_pkt) && (urb_zero_packet_chk(adapt, sz) == 0)) { ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ); pull = 1; } } memset(ptxdesc, 0, sizeof(struct tx_desc)); /* 4 offset 0 */ ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff);/* update TXPKTSIZE */ offset = TXDESC_SIZE + OFFSET_SZ; ptxdesc->txdw0 |= cpu_to_le32(((offset) << OFFSET_SHT) & 0x00ff0000);/* 32 bytes for TX Desc */ if (bmcst) ptxdesc->txdw0 |= cpu_to_le32(BMC); if (adapt->registrypriv.mp_mode == 0) { if (!bagg_pkt) { if ((pull) && (pxmitframe->pkt_offset > 0)) pxmitframe->pkt_offset = pxmitframe->pkt_offset - 1; } } /* pkt_offset, unit:8 bytes padding */ if (pxmitframe->pkt_offset > 0) ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000); /* driver uses rate */ ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */ if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) { /* offset 4 */ ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3F); qsel = (uint)(pattrib->qsel & 0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000); fill_txdesc_sectype(pattrib, ptxdesc); if (pattrib->ampdu_en) { ptxdesc->txdw2 |= cpu_to_le32(AGG_EN);/* AGG EN */ ptxdesc->txdw6 = cpu_to_le32(0x6666f800); } else { ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */ } /* offset 8 */ /* offset 12 */ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000); /* offset 16 , offset 20 */ if (pattrib->qos_en) ptxdesc->txdw4 |= cpu_to_le32(QOS);/* QoS */ /* offset 20 */ if (pxmitframe->agg_num > 1) ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << USB_TXAGG_NUM_SHT) & 0xFF000000); if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->ether_type != 0x88b4) && (pattrib->dhcp_pkt != 1)) { /* Non EAP & ARP & DHCP type data packet */ fill_txdesc_vcs(pattrib, &ptxdesc->txdw4); fill_txdesc_phy(pattrib, &ptxdesc->txdw4); ptxdesc->txdw4 |= cpu_to_le32(0x00000008);/* RTS Rate=24M */ ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);/* DATA/RTS Rate FB LMT */ if (pattrib->ht_en) { if (ODM_RA_GetShortGI_8188E(&haldata->odmpriv, pattrib->mac_id)) ptxdesc->txdw5 |= cpu_to_le32(SGI);/* SGI */ } data_rate = ODM_RA_GetDecisionRate_8188E(&haldata->odmpriv, pattrib->mac_id); ptxdesc->txdw5 |= cpu_to_le32(data_rate & 0x3F); pwr_status = ODM_RA_GetHwPwrStatus_8188E(&haldata->odmpriv, pattrib->mac_id); ptxdesc->txdw4 |= cpu_to_le32((pwr_status & 0x7) << PWR_STATUS_SHT); } 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. */ ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */ if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) ptxdesc->txdw4 |= cpu_to_le32(BIT(24));/* DATA_SHORT */ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); } } else if ((pxmitframe->frame_tag&0x0f) == MGNT_FRAMETAG) { /* offset 4 */ ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3f); qsel = (uint)(pattrib->qsel&0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000f0000); /* offset 8 */ /* CCX-TXRPT ack for xmit mgmt frames. */ if (pxmitframe->ack_report) ptxdesc->txdw2 |= cpu_to_le32(BIT(19)); /* offset 12 */ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<SEQ_SHT)&0x0FFF0000); /* offset 20 */ ptxdesc->txdw5 |= cpu_to_le32(RTY_LMT_EN);/* retry limit enable */ if (pattrib->retry_ctrl) ptxdesc->txdw5 |= cpu_to_le32(0x00180000);/* retry limit = 6 */ else ptxdesc->txdw5 |= cpu_to_le32(0x00300000);/* retry limit = 12 */ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); } else if ((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG) { DBG_88E("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); } else { DBG_88E("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); /* offset 4 */ ptxdesc->txdw1 |= cpu_to_le32((4) & 0x3f);/* CAM_ID(MAC_ID) */ ptxdesc->txdw1 |= cpu_to_le32((6 << RATE_ID_SHT) & 0x000f0000);/* raid */ /* offset 8 */ /* offset 12 */ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<SEQ_SHT)&0x0fff0000); /* offset 20 */ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); } /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */ /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */ /* mgnt frame should be controlled by Hw because Fw will also send null data */ /* which we cannot control when Fw LPS enable. */ /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */ /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */ /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */ /* 2010.06.23. Added by tynli. */ if (!pattrib->qos_en) { ptxdesc->txdw3 |= cpu_to_le32(EN_HWSEQ); /* Hw set sequence number */ ptxdesc->txdw4 |= cpu_to_le32(HW_SSN); /* Hw set sequence number */ } rtl88eu_dm_set_tx_ant_by_tx_info(&haldata->odmpriv, pmem, pattrib->mac_id); rtl8188eu_cal_txdesc_chksum(ptxdesc); _dbg_dump_tx_info(adapt, pxmitframe->frame_tag, ptxdesc); return pull; }
static s32 update_txdesc(struct xmit_frame *pxmitframe, u32 *pmem, s32 sz) { uint qsel; _adapter *padapter = pxmitframe->padapter; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv; struct pkt_attrib *pattrib = &pxmitframe->attrib; struct ht_priv *phtpriv = &pmlmepriv->htpriv; struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; struct tx_desc *ptxdesc = (struct tx_desc *)pmem; sint bmcst = IS_MCAST(pattrib->ra); #ifdef CONFIG_P2P struct wifidirect_info* pwdinfo = &padapter->wdinfo; #endif //CONFIG_P2P dma_addr_t mapping = pci_map_single(pdvobjpriv->ppcidev, pxmitframe->buf_addr , sz, PCI_DMA_TODEVICE); _rtw_memset(ptxdesc, 0, TX_DESC_NEXT_DESC_OFFSET); if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n"); //offset 4 ptxdesc->txdw1 |= cpu_to_le32((pattrib->mac_id)&0x1f); qsel = (uint)(pattrib->qsel & 0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000); fill_txdesc_sectype(pattrib, ptxdesc); if(pattrib->ampdu_en==_TRUE) ptxdesc->txdw1 |= cpu_to_le32(BIT(5));//AGG EN else ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK //offset 8 //offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); //offset 16 , offset 20 if (pattrib->qos_en) ptxdesc->txdw4 |= cpu_to_le32(BIT(6));//QoS if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1)) { //Non EAP & ARP & DHCP type data packet fill_txdesc_vcs(pattrib, &ptxdesc->txdw4); fill_txdesc_phy(pattrib, &ptxdesc->txdw4); ptxdesc->txdw4 |= cpu_to_le32(0x00000008);//RTS Rate=24M ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);// //ptxdesc->txdw5 |= cpu_to_le32(0x0000000b);//DataRate - 54M //use REG_INIDATA_RATE_SEL value ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]); if(0)//for driver dbg { ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate if(pattrib->ht_en) ptxdesc->txdw5 |= cpu_to_le32(BIT(6));//SGI ptxdesc->txdw5 |= cpu_to_le32(0x00000013);//init rate - mcs7 } } else { // EAP data packet and ARP packet. // Use the 1M data rate to send the EAP/ARP packet. // This will maybe make the handshake smooth. ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) ptxdesc->txdw4 |= cpu_to_le32(BIT(24));// DATA_SHORT } //offset 24 #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX if ( pattrib->hw_tcp_csum == 1 ) { // ptxdesc->txdw6 = 0; // clear TCP_CHECKSUM and IP_CHECKSUM. It's zero already!! u8 ip_hdr_offset = 32 + pattrib->hdrlen + pattrib->iv_len + 8; ptxdesc->txdw7 = (1 << 31) | (ip_hdr_offset << 16); DBG_8192C("ptxdesc->txdw7 = %08x\n", ptxdesc->txdw7); } #endif } else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG) { //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n"); //offset 4 ptxdesc->txdw1 |= cpu_to_le32((pattrib->mac_id)&0x1f); qsel = (uint)(pattrib->qsel&0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000); //fill_txdesc_sectype(pattrib, ptxdesc); //offset 8 //offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); //offset 16 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate //offset 20 } else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG) { DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); } #ifdef CONFIG_MP_INCLUDED else if((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG) { fill_txdesc_for_mp(padapter, ptxdesc); } #endif else { DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); //offset 4 ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);//CAM_ID(MAC_ID) ptxdesc->txdw1 |= cpu_to_le32((6<< 16) & 0x000f0000);//raid //offset 8 //offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); //offset 16 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate //offset 20 ptxdesc->txdw5 |= cpu_to_le32(BIT(17));//retry limit enable ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6 #ifdef CONFIG_P2P // Added by Albert 2011/03/17 // In the P2P mode, the driver should not support the b mode. // So, the Tx packet shouldn't use the CCK rate if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ptxdesc->txdw5 |= cpu_to_le32( 0x04 ); // Use the 6M data rate. } #endif //CONFIG_P2P } //offset 28 ptxdesc->txdw7 |= cpu_to_le32(sz&0x0000ffff); //offset 32 ptxdesc->txdw8 = cpu_to_le32(mapping); // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. // (1) The sequence number of each non-Qos frame / broadcast / multicast / // mgnt frame should be controled by Hw because Fw will also send null data // which we cannot control when Fw LPS enable. // --> default enable non-Qos data sequense number. 2010.06.23. by tynli. // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. // 2010.06.23. Added by tynli. if(!pattrib->qos_en) { 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. } //offset 0 if(bmcst) { ptxdesc->txdw0 |= cpu_to_le32(BIT(24)); } ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff); ptxdesc->txdw0 |= cpu_to_le32(FSG | LSG); ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//32 bytes for TX Desc // ptxdesc->txdw0 |= cpu_to_le32(OWN); RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("offset0-txdesc=0x%x\n", ptxdesc->txdw0)); return 0; }
void rtl8188es_fill_default_txdesc( struct xmit_frame *pxmitframe, u8 *pbuf) { PADAPTER padapter; HAL_DATA_TYPE *pHalData; struct mlme_ext_priv *pmlmeext; struct mlme_ext_info *pmlmeinfo; struct dm_priv *pdmpriv; struct pkt_attrib *pattrib; PTXDESC_8188E ptxdesc; s32 bmcst; padapter = pxmitframe->padapter; pHalData = GET_HAL_DATA(padapter); //pdmpriv = &pHalData->dmpriv; pmlmeext = &padapter->mlmeextpriv; pmlmeinfo = &(pmlmeext->mlmext_info); pattrib = &pxmitframe->attrib; bmcst = IS_MCAST(pattrib->ra); ptxdesc = (PTXDESC_8188E)pbuf; if (pxmitframe->frame_tag == DATA_FRAMETAG) { ptxdesc->macid = pattrib->mac_id; // CAM_ID(MAC_ID) if (pattrib->ampdu_en == _TRUE) ptxdesc->agg_en = 1; // AGG EN else ptxdesc->bk = 1; // AGG BK ptxdesc->qsel = pattrib->qsel; ptxdesc->rate_id = pattrib->raid; fill_txdesc_sectype(pattrib, ptxdesc); ptxdesc->seq = pattrib->seqnum; //todo: qos_en ptxdesc->userate = 1; // driver uses rate if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1)) { // Non EAP & ARP & DHCP type data packet fill_txdesc_vcs(pattrib, ptxdesc); fill_txdesc_phy(pattrib, ptxdesc); ptxdesc->rtsrate = 8; // RTS Rate=24M ptxdesc->data_ratefb_lmt = 0x1F; ptxdesc->rts_ratefb_lmt = 0xF; #if (RATE_ADAPTIVE_SUPPORT == 1) /* driver-based RA*/ if (pattrib->ht_en) ptxdesc->sgi = ODM_RA_GetShortGI_8188E(&pHalData->odmpriv,pattrib->mac_id); ptxdesc->datarate = ODM_RA_GetDecisionRate_8188E(&pHalData->odmpriv,pattrib->mac_id); #if (POWER_TRAINING_ACTIVE==1) ptxdesc->pwr_status = ODM_RA_GetHwPwrStatus_8188E(&pHalData->odmpriv,pattrib->mac_id); #endif #else /* (RATE_ADAPTIVE_SUPPORT == 1) */ /* FW-based RA, TODO */ if(pattrib->ht_en) ptxdesc->sgi = 1; ptxdesc->datarate = 0x13; //MCS7 #endif /* (RATE_ADAPTIVE_SUPPORT == 1) */ if (padapter->fix_rate != 0xFF) { ptxdesc->userate = 1; ptxdesc->datarate = padapter->fix_rate; ptxdesc->disdatafb = 1; ptxdesc->sgi = (padapter->fix_rate & BIT(7))?1:0; } } else { // EAP data packet and ARP and DHCP packet. // Use the 1M or 6M data rate to send the EAP/ARP packet. // This will maybe make the handshake smooth. ptxdesc->bk = 1; // AGG BK if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) ptxdesc->data_short = 1;// DATA_SHORT ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate); } ptxdesc->usb_txagg_num = pxmitframe->agg_num; } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { // RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MGNT_FRAMETAG\n", __FUNCTION__)); ptxdesc->macid = pattrib->mac_id; // CAM_ID(MAC_ID) ptxdesc->qsel = pattrib->qsel; ptxdesc->rate_id = pattrib->raid; // Rate ID ptxdesc->seq = pattrib->seqnum; ptxdesc->userate = 1; // driver uses rate, 1M ptxdesc->rty_lmt_en = 1; // retry limit enable ptxdesc->data_rt_lmt = 6; // retry limit = 6 #ifdef CONFIG_XMIT_ACK //CCX-TXRPT ack for xmit mgmt frames. if (pxmitframe->ack_report) { #ifdef DBG_CCX static u16 ccx_sw = 0x123; txdesc_set_ccx_sw_88e(ptxdesc, ccx_sw); DBG_871X("%s set ccx, sw:0x%03x\n", __func__, ccx_sw); ccx_sw = (ccx_sw+1)%0xfff; #endif ptxdesc->ccx = 1; } #endif //CONFIG_XMIT_ACK #ifdef CONFIG_INTEL_PROXIM if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){ DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate); ptxdesc->datarate = pattrib->rate; } else #endif { ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate); } } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) { RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: TXAGG_FRAMETAG\n", __FUNCTION__)); } #ifdef CONFIG_MP_INCLUDED else if (pxmitframe->frame_tag == MP_FRAMETAG) { struct tx_desc *pdesc; pdesc = (struct tx_desc*)ptxdesc; RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MP_FRAMETAG\n", __FUNCTION__)); fill_txdesc_for_mp(padapter, (u8 *)pdesc); pdesc->txdw0 = le32_to_cpu(pdesc->txdw0); pdesc->txdw1 = le32_to_cpu(pdesc->txdw1); pdesc->txdw2 = le32_to_cpu(pdesc->txdw2); pdesc->txdw3 = le32_to_cpu(pdesc->txdw3); pdesc->txdw4 = le32_to_cpu(pdesc->txdw4); pdesc->txdw5 = le32_to_cpu(pdesc->txdw5); pdesc->txdw6 = le32_to_cpu(pdesc->txdw6); pdesc->txdw7 = le32_to_cpu(pdesc->txdw7); } #endif // CONFIG_MP_INCLUDED else { RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: frame_tag=0x%x\n", __FUNCTION__, pxmitframe->frame_tag)); ptxdesc->macid = 4; // CAM_ID(MAC_ID) ptxdesc->rate_id = 6; // Rate ID ptxdesc->seq = pattrib->seqnum; ptxdesc->userate = 1; // driver uses rate ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate); } ptxdesc->pktlen = pattrib->last_txcmdsz; if (pxmitframe->frame_tag == DATA_FRAMETAG){ #ifdef CONFIG_TX_EARLY_MODE ptxdesc->offset = TXDESC_SIZE +EARLY_MODE_INFO_SIZE ; ptxdesc->pkt_offset = 0x01; #else ptxdesc->offset = TXDESC_SIZE ; ptxdesc->pkt_offset = 0; #endif } else{ ptxdesc->offset = TXDESC_SIZE ; } if (bmcst) ptxdesc->bmc = 1; ptxdesc->ls = 1; ptxdesc->fs = 1; ptxdesc->own = 1; // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. // (1) The sequence number of each non-Qos frame / broadcast / multicast / // mgnt frame should be controled by Hw because Fw will also send null data // which we cannot control when Fw LPS enable. // --> default enable non-Qos data sequense number. 2010.06.23. by tynli. // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. // 2010.06.23. Added by tynli. if (!pattrib->qos_en) { // Hw set sequence number ptxdesc->hwseq_en = 1; // HWSEQ_EN ptxdesc->hwseq_sel = 0; // HWSEQ_SEL } }
static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt) { int pull=0; uint qsel; _adapter *padapter = pxmitframe->padapter; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct pkt_attrib *pattrib = &pxmitframe->attrib; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; struct tx_desc *ptxdesc = (struct tx_desc *)pmem; struct ht_priv *phtpriv = &pmlmepriv->htpriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); sint bmcst = IS_MCAST(pattrib->ra); #ifdef CONFIG_P2P struct wifidirect_info* pwdinfo = &padapter->wdinfo; #endif //CONFIG_P2P #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0)) { ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ); pull = 1; pxmitframe->pkt_offset --; } #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc)); if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n"); //offset 4 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f); qsel = (uint)(pattrib->qsel & 0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000); fill_txdesc_sectype(pattrib, ptxdesc); if(pattrib->ampdu_en==_TRUE) ptxdesc->txdw1 |= cpu_to_le32(BIT(5));//AGG EN else ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK //offset 8 //offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); //offset 16 , offset 20 if (pattrib->qos_en) ptxdesc->txdw4 |= cpu_to_le32(BIT(6));//QoS if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1)) { //Non EAP & ARP & DHCP type data packet fill_txdesc_vcs(pattrib, &ptxdesc->txdw4); fill_txdesc_phy(pattrib, &ptxdesc->txdw4); ptxdesc->txdw4 |= cpu_to_le32(0x00000008);//RTS Rate=24M ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);// //ptxdesc->txdw5 |= cpu_to_le32(0x0000000b);//DataRate - 54M //use REG_INIDATA_RATE_SEL value ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]); if(0)//for driver dbg { ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate if(pattrib->ht_en) ptxdesc->txdw5 |= cpu_to_le32(BIT(6));//SGI ptxdesc->txdw5 |= cpu_to_le32(0x00000013);//init rate - mcs7 } } else { // EAP data packet and ARP packet. // Use the 1M data rate to send the EAP/ARP packet. // This will maybe make the handshake smooth. ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) ptxdesc->txdw4 |= cpu_to_le32(BIT(24));// DATA_SHORT ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); } //offset 24 #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX if ( pattrib->hw_tcp_csum == 1 ) { // ptxdesc->txdw6 = 0; // clear TCP_CHECKSUM and IP_CHECKSUM. It's zero already!! u8 ip_hdr_offset = 32 + pattrib->hdrlen + pattrib->iv_len + 8; ptxdesc->txdw7 = (1 << 31) | (ip_hdr_offset << 16); DBG_8192C("ptxdesc->txdw7 = %08x\n", ptxdesc->txdw7); } #endif } else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG) { //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n"); //offset 4 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f); qsel = (uint)(pattrib->qsel&0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000); //fill_txdesc_sectype(pattrib, ptxdesc); //offset 8 #ifdef CONFIG_XMIT_ACK //CCX-TXRPT ack for xmit mgmt frames. if (pxmitframe->ack_report) { ptxdesc->txdw2 |= cpu_to_le32(BIT(19)); #ifdef DBG_CCX DBG_871X("%s set ccx\n", __func__); #endif } #endif //CONFIG_XMIT_ACK //offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); //offset 16 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate //offset 20 ptxdesc->txdw5 |= cpu_to_le32(BIT(17));//retry limit enable if(pattrib->retry_ctrl == _TRUE) { #ifdef CONFIG_P2P if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ptxdesc->txdw5 |= cpu_to_le32(0x00080000);//retry limit = 2 } else #endif //CONFIG_P2P ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6 } else ptxdesc->txdw5 |= cpu_to_le32(0x00300000);//retry limit = 12 #ifdef CONFIG_INTEL_PROXIM if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){ printk("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate); ptxdesc->txdw5 |= cpu_to_le32( pattrib->rate); } else #endif { ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); } } else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG) { DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); } #ifdef CONFIG_MP_INCLUDED else if((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG) { fill_txdesc_for_mp(padapter, ptxdesc); } #endif else { DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); //offset 4 ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);//CAM_ID(MAC_ID) ptxdesc->txdw1 |= cpu_to_le32((6<< 16) & 0x000f0000);//raid //offset 8 //offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); //offset 16 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate //offset 20 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); } // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. // (1) The sequence number of each non-Qos frame / broadcast / multicast / // mgnt frame should be controled by Hw because Fw will also send null data // which we cannot control when Fw LPS enable. // --> default enable non-Qos data sequense number. 2010.06.23. by tynli. // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. // 2010.06.23. Added by tynli. if(!pattrib->qos_en) { 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. } //offset 0 ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff); ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//32 bytes for TX Desc if(bmcst) { ptxdesc->txdw0 |= cpu_to_le32(BIT(24)); } RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("offset0-txdesc=0x%x\n", ptxdesc->txdw0)); //offset 4 // pkt_offset, unit:8 bytes padding if (pxmitframe->pkt_offset > 0) ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000); #ifdef CONFIG_USB_TX_AGGREGATION if (pxmitframe->agg_num > 1) ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << 24) & 0xff000000); #endif rtl8192cu_cal_txdesc_chksum(ptxdesc); return pull; }
static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz ,u8 bagg_pkt) { int pull=0; uint qsel; u8 data_rate,pwr_status,offset; _adapter *padapter = pxmitframe->padapter; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct pkt_attrib *pattrib = &pxmitframe->attrib; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); //struct dm_priv *pdmpriv = &pHalData->dmpriv; u8 *ptxdesc = pmem; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); sint bmcst = IS_MCAST(pattrib->ra); #ifdef CONFIG_P2P struct wifidirect_info* pwdinfo = &padapter->wdinfo; #endif //CONFIG_P2P #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX if (padapter->registrypriv.mp_mode == 0) { //if((!bagg_pkt) &&(urb_zero_packet_chk(padapter, sz)==0))//(sz %512) != 0 if((PACKET_OFFSET_SZ != 0) && (!bagg_pkt) && (rtw_usb_bulk_size_boundary(padapter,TXDESC_SIZE+sz)==_FALSE)) { ptxdesc = (pmem+PACKET_OFFSET_SZ); //DBG_8192C("==> non-agg-pkt,shift pointer...\n"); pull = 1; } } #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX _rtw_memset(ptxdesc, 0, TXDESC_SIZE); //4 offset 0 //DBG_8192C("%s==> pkt_len=%d,bagg_pkt=%02x\n",__FUNCTION__,sz,bagg_pkt); SET_TX_DESC_PKT_SIZE_92E(ptxdesc, sz); offset = TXDESC_SIZE + OFFSET_SZ; #ifdef CONFIG_TX_EARLY_MODE if(bagg_pkt){ offset += EARLY_MODE_INFO_SIZE ;//0x28 } #endif //DBG_8192C("%s==>offset(0x%02x) \n",__FUNCTION__,offset); SET_TX_DESC_OFFSET_92E(ptxdesc, offset); if (bmcst) { SET_TX_DESC_BMC_92E(ptxdesc, 1); } #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX 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; } } } #endif //DBG_8192C("%s, pkt_offset=0x%02x\n",__FUNCTION__,pxmitframe->pkt_offset); // pkt_offset, unit:8 bytes padding if (pxmitframe->pkt_offset > 0) { SET_TX_DESC_PKT_OFFSET_92E(ptxdesc, pxmitframe->pkt_offset); } SET_TX_DESC_MACID_92E(ptxdesc, pattrib->mac_id); SET_TX_DESC_RATE_ID_92E(ptxdesc, pattrib->raid); SET_TX_DESC_QUEUE_SEL_92E(ptxdesc, pattrib->qsel); //offset 12 if (!pattrib->qos_en) { SET_TX_DESC_EN_HWSEQ_92E(ptxdesc, 1); // Hw set sequence number } else { SET_TX_DESC_SEQ_92E(ptxdesc, pattrib->seqnum); } if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n"); fill_txdesc_sectype(pattrib, ptxdesc); if (pattrib->ampdu_en==_TRUE) { SET_TX_DESC_AGG_ENABLE_92E(ptxdesc, 1); SET_TX_DESC_MAX_AGG_NUM_92E(ptxdesc, 0x1f); // Set A-MPDU aggregation. SET_TX_DESC_AMPDU_DENSITY_92E(ptxdesc, pHalData->AMPDUDensity); } else { SET_TX_DESC_BK_92E(ptxdesc, 1); } //offset 20 #ifdef CONFIG_USB_TX_AGGREGATION if (pxmitframe->agg_num > 1){ //DBG_8192C("%s agg_num:%d\n",__FUNCTION__,pxmitframe->agg_num ); SET_TX_DESC_USB_TXAGG_NUM_92E(ptxdesc, pxmitframe->agg_num); } #endif 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 ) { //Non EAP & ARP & DHCP type data packet fill_txdesc_vcs(pattrib, ptxdesc); fill_txdesc_phy(padapter, pattrib, ptxdesc); SET_TX_DESC_RTS_RATE_92E(ptxdesc, 0x8);//RTS Rate=24M //DATA/RTS Rate FB LMT SET_TX_DESC_DATA_RATE_FB_LIMIT_92E(ptxdesc, 0x1f); SET_TX_DESC_RTS_RATE_FB_LIMIT_92E(ptxdesc, 0xf); if(pHalData->fw_ractrl == _FALSE) { struct dm_priv *pdmpriv = &pHalData->dmpriv; SET_TX_DESC_USE_RATE_92E(ptxdesc, 1); if(pdmpriv->INIDATA_RATE[pattrib->mac_id] & BIT(7)) SET_TX_DESC_DATA_SHORT_92E(ptxdesc, 1); SET_TX_DESC_TX_RATE_92E(ptxdesc, (pdmpriv->INIDATA_RATE[pattrib->mac_id] & 0x7F)); } //for debug #if 1 if(padapter->fix_rate!= 0xFF){ struct dm_priv *pdmpriv = &pHalData->dmpriv; SET_TX_DESC_USE_RATE_92E(ptxdesc, 1); //if(pdmpriv->INIDATA_RATE[pattrib->mac_id] & BIT(7)) { if(padapter->fix_rate & BIT(7)) SET_TX_DESC_DATA_SHORT_92E(ptxdesc, 1); } SET_TX_DESC_TX_RATE_92E(ptxdesc, (padapter->fix_rate & 0x7F)); SET_TX_DESC_DISABLE_FB_92E(ptxdesc,1); //ptxdesc->datarate = padapter->fix_rate; } #endif } 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. SET_TX_DESC_USE_RATE_92E(ptxdesc, 1); SET_TX_DESC_BK_92E(ptxdesc, 1); // HW will ignore this setting if the transmission rate is legacy OFDM. if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) { SET_TX_DESC_DATA_SHORT_92E(ptxdesc, 1); } SET_TX_DESC_TX_RATE_92E(ptxdesc, MRateToHwRate(pmlmeext->tx_rate)); } } else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG) { //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n"); SET_TX_DESC_MBSSID_92E(ptxdesc, pattrib->mbssid);//for issue port1/mbssid beacon //offset 20 SET_TX_DESC_RETRY_LIMIT_ENABLE_92E(ptxdesc, 1); if (pattrib->retry_ctrl == _TRUE) { SET_TX_DESC_DATA_RETRY_LIMIT_92E(ptxdesc, 6); } else { SET_TX_DESC_DATA_RETRY_LIMIT_92E(ptxdesc, 12); } SET_TX_DESC_USE_RATE_92E(ptxdesc, 1); #ifdef CONFIG_INTEL_PROXIM if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){ DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate); SET_TX_DESC_TX_RATE_92E(ptxdesc, pattrib->rate); } else #endif { SET_TX_DESC_TX_RATE_92E(ptxdesc, MRateToHwRate(pmlmeext->tx_rate)); } #ifdef CONFIG_XMIT_ACK //CCX-TXRPT ack for xmit mgmt frames. if (pxmitframe->ack_report) { SET_TX_DESC_SPE_RPT_92E(ptxdesc, 1); #ifdef DBG_CCX DBG_871X("%s set tx report\n", __func__); #endif } #endif //CONFIG_XMIT_ACK } else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG) { DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); } #ifdef CONFIG_MP_INCLUDED else if(((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG) && (padapter->registrypriv.mp_mode == 1)) { fill_txdesc_for_mp(padapter, ptxdesc); } #endif else { DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); SET_TX_DESC_USE_RATE_92E(ptxdesc, 1); SET_TX_DESC_TX_RATE_92E(ptxdesc, MRateToHwRate(pmlmeext->tx_rate)); } rtl8192e_cal_txdesc_chksum(ptxdesc); _dbg_dump_tx_info(padapter,pxmitframe->frame_tag,ptxdesc); return pull; }
static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz ,u8 bagg_pkt) { int pull=0; uint qsel; u8 data_rate,pwr_status,offset; _adapter *padapter = pxmitframe->padapter; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct pkt_attrib *pattrib = &pxmitframe->attrib; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); //struct dm_priv *pdmpriv = &pHalData->dmpriv; struct tx_desc *ptxdesc = (struct tx_desc *)pmem; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); sint bmcst = IS_MCAST(pattrib->ra); #ifdef CONFIG_P2P struct wifidirect_info* pwdinfo = &padapter->wdinfo; #endif //CONFIG_P2P #ifdef CONFIG_CONCURRENT_MODE if(rtw_buddy_adapter_up(padapter) && padapter->adapter_type > PRIMARY_ADAPTER) pHalData = GET_HAL_DATA(padapter->pbuddy_adapter); #endif //CONFIG_CONCURRENT_MODE #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX if (padapter->registrypriv.mp_mode == 0) { if((!bagg_pkt) &&(urb_zero_packet_chk(padapter, sz)==0))//(sz %512) != 0 //if((!bagg_pkt) &&(rtw_usb_bulk_size_boundary(padapter,TXDESC_SIZE+sz)==_FALSE)) { ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ); //DBG_8192C("==> non-agg-pkt,shift pointer...\n"); pull = 1; } } #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc)); //4 offset 0 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); //DBG_8192C("%s==> pkt_len=%d,bagg_pkt=%02x\n",__FUNCTION__,sz,bagg_pkt); ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff);//update TXPKTSIZE offset = TXDESC_SIZE + OFFSET_SZ; #ifdef CONFIG_TX_EARLY_MODE if(bagg_pkt){ offset += EARLY_MODE_INFO_SIZE ;//0x28 } #endif //DBG_8192C("%s==>offset(0x%02x) \n",__FUNCTION__,offset); ptxdesc->txdw0 |= cpu_to_le32(((offset) << OFFSET_SHT) & 0x00ff0000);//32 bytes for TX Desc if (bmcst) ptxdesc->txdw0 |= cpu_to_le32(BMC); #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX if (padapter->registrypriv.mp_mode == 0) { if(!bagg_pkt){ if((pull) && (pxmitframe->pkt_offset>0)) { pxmitframe->pkt_offset = pxmitframe->pkt_offset -1; } } } #endif //DBG_8192C("%s, pkt_offset=0x%02x\n",__FUNCTION__,pxmitframe->pkt_offset); // pkt_offset, unit:8 bytes padding if (pxmitframe->pkt_offset > 0) ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000); //driver uses rate ptxdesc->txdw4 |= cpu_to_le32(USERATE);//rate control always by driver if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n"); //offset 4 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x3F); qsel = (uint)(pattrib->qsel & 0x0000001f); //DBG_8192C("==> macid(%d) qsel:0x%02x \n",pattrib->mac_id,qsel); ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< RATE_ID_SHT) & 0x000F0000); fill_txdesc_sectype(pattrib, ptxdesc); if(pattrib->ampdu_en==_TRUE){ ptxdesc->txdw2 |= cpu_to_le32(AGG_EN);//AGG EN //SET_TX_DESC_MAX_AGG_NUM_88E(pDesc, 0x1F); //SET_TX_DESC_MCSG1_MAX_LEN_88E(pDesc, 0x6); //SET_TX_DESC_MCSG2_MAX_LEN_88E(pDesc, 0x6); //SET_TX_DESC_MCSG3_MAX_LEN_88E(pDesc, 0x6); //SET_TX_DESC_MCS7_SGI_MAX_LEN_88E(pDesc, 0x6); ptxdesc->txdw6 = 0x6666f800; } else{ ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);//AGG BK } //offset 8 //offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<< SEQ_SHT)&0x0FFF0000); //offset 16 , offset 20 if (pattrib->qos_en) ptxdesc->txdw4 |= cpu_to_le32(QOS);//QoS //offset 20 #ifdef CONFIG_USB_TX_AGGREGATION if (pxmitframe->agg_num > 1){ //DBG_8192C("%s agg_num:%d\n",__FUNCTION__,pxmitframe->agg_num ); ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << USB_TXAGG_NUM_SHT) & 0xFF000000); } #endif if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->ether_type != 0x88b4) && (pattrib->dhcp_pkt != 1)) { //Non EAP & ARP & DHCP type data packet fill_txdesc_vcs(pattrib, &ptxdesc->txdw4); fill_txdesc_phy(pattrib, &ptxdesc->txdw4); ptxdesc->txdw4 |= cpu_to_le32(0x00000008);//RTS Rate=24M ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);//DATA/RTS Rate FB LMT #if (RATE_ADAPTIVE_SUPPORT == 1) if(pattrib->ht_en){ if( ODM_RA_GetShortGI_8188E(&pHalData->odmpriv,pattrib->mac_id)) ptxdesc->txdw5 |= cpu_to_le32(SGI);//SGI } data_rate =ODM_RA_GetDecisionRate_8188E(&pHalData->odmpriv,pattrib->mac_id); ptxdesc->txdw5 |= cpu_to_le32(data_rate & 0x3F); //for debug #if 0 if(padapter->fix_rate!= 0xFF){ ptxdesc->datarate = padapter->fix_rate; } #endif #if (POWER_TRAINING_ACTIVE==1) pwr_status = ODM_RA_GetHwPwrStatus_8188E(&pHalData->odmpriv,pattrib->mac_id); ptxdesc->txdw4 |=cpu_to_le32( (pwr_status & 0x7)<< PWR_STATUS_SHT); #endif //(POWER_TRAINING_ACTIVE==1) #else//if (RATE_ADAPTIVE_SUPPORT == 1) if(pattrib->ht_en) ptxdesc->txdw5 |= cpu_to_le32(SGI);//SGI data_rate = 0x13; //default rate: MCS7 if(padapter->fix_rate!= 0xFF){//rate control by iwpriv data_rate = padapter->fix_rate; } ptxdesc->txdw5 |= cpu_to_le32(data_rate & 0x3F); #endif//if (RATE_ADAPTIVE_SUPPORT == 1) } 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. ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);//AGG BK if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) ptxdesc->txdw4 |= cpu_to_le32(BIT(24));// DATA_SHORT ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); } #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX //offset 24 if ( pattrib->hw_tcp_csum == 1 ) { // ptxdesc->txdw6 = 0; // clear TCP_CHECKSUM and IP_CHECKSUM. It's zero already!! u8 ip_hdr_offset = 32 + pattrib->hdrlen + pattrib->iv_len + 8; ptxdesc->txdw7 = (1 << 31) | (ip_hdr_offset << 16); DBG_8192C("ptxdesc->txdw7 = %08x\n", ptxdesc->txdw7); } #endif } else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG) { //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n"); //offset 4 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x3f); qsel = (uint)(pattrib->qsel&0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< RATE_ID_SHT) & 0x000f0000); //fill_txdesc_sectype(pattrib, ptxdesc); //offset 8 #ifdef CONFIG_XMIT_ACK //CCX-TXRPT ack for xmit mgmt frames. if (pxmitframe->ack_report) { #ifdef DBG_CCX static u16 ccx_sw = 0x123; ptxdesc->txdw7 |= cpu_to_le32(((ccx_sw)<<16)&0x0fff0000); DBG_871X("%s set ccx, sw:0x%03x\n", __func__, ccx_sw); ccx_sw = (ccx_sw+1)%0xfff; #endif ptxdesc->txdw2 |= cpu_to_le32(BIT(19)); } #endif //CONFIG_XMIT_ACK //offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<SEQ_SHT)&0x0FFF0000); //offset 20 ptxdesc->txdw5 |= cpu_to_le32(RTY_LMT_EN);//retry limit enable if(pattrib->retry_ctrl == _TRUE) ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6 else ptxdesc->txdw5 |= cpu_to_le32(0x00300000);//retry limit = 12 #ifdef CONFIG_INTEL_PROXIM if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){ DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate); ptxdesc->txdw5 |= cpu_to_le32( pattrib->rate); } else #endif { ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); } } else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG) { DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); } #ifdef CONFIG_MP_INCLUDED else if(((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG) && (padapter->registrypriv.mp_mode == 1)) { fill_txdesc_for_mp(padapter, ptxdesc); } #endif else { DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); //offset 4 ptxdesc->txdw1 |= cpu_to_le32((4)&0x3f);//CAM_ID(MAC_ID) ptxdesc->txdw1 |= cpu_to_le32((6<< RATE_ID_SHT) & 0x000f0000);//raid //offset 8 //offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<SEQ_SHT)&0x0fff0000); //offset 20 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); } // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. // (1) The sequence number of each non-Qos frame / broadcast / multicast / // mgnt frame should be controled by Hw because Fw will also send null data // which we cannot control when Fw LPS enable. // --> default enable non-Qos data sequense number. 2010.06.23. by tynli. // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. // 2010.06.23. Added by tynli. if(!pattrib->qos_en) { //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. ptxdesc->txdw3 |= cpu_to_le32(EN_HWSEQ); // Hw set sequence number ptxdesc->txdw4 |= cpu_to_le32(HW_SSN); // Hw set sequence number } #ifdef CONFIG_HW_ANTENNA_DIVERSITY //CONFIG_ANTENNA_DIVERSITY ODM_SetTxAntByTxInfo_88E(&pHalData->odmpriv, pmem, pattrib->mac_id); #endif rtl8188eu_cal_txdesc_chksum(ptxdesc); _dbg_dump_tx_info(padapter,pxmitframe->frame_tag,ptxdesc); return pull; }
static void _update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, int sz) { uint qsel; _adapter *padapter = pxmitframe->padapter; struct ht_priv *phtpriv = &padapter->mlmepriv.htpriv; struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info; struct pkt_attrib *pattrib = &pxmitframe->attrib; sint bmcst = IS_MCAST(pattrib->ra); struct tx_desc *ptxdesc = (struct tx_desc*)pmem; _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc)); //4 offset 0 ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff); ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000);//32 bytes for TX Desc if (bmcst) ptxdesc->txdw0 |= cpu_to_le32(BIT(24)); RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_update_txdesc: offset0=0x%08x\n", ptxdesc->txdw0)); //4 offset 4 // pkt_offset, unit:8 bytes padding if (pxmitframe->pkt_offset > 0) ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000); #if USB_TX_AGGREGATION_92C if (pxmitframe->agg_num > 0) ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << 24) & 0xff000000); #endif if (pxmitframe->frame_tag == DATA_FRAMETAG) { //4 offset 4 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x1f);//CAM_ID(MAC_ID) qsel = (uint)(pattrib->qsel & 0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << 16) & 0x000f0000); fill_txdesc_sectype(pattrib, ptxdesc); if(pattrib->ampdu_en==_TRUE) ptxdesc->txdw1 |= cpu_to_le32(BIT(5));//AGG EN else ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK //4 offset 8 //4 offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << 16) & 0xffff0000); //4 offset 16 , offset 20 if (pattrib->qos_en) ptxdesc->txdw4 |= cpu_to_le32(BIT(6));//QoS if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1)) { //Non EAP & ARP & DHCP type data packet fill_txdesc_vcs(pattrib, &ptxdesc->txdw4); fill_txdesc_phy(pattrib, &ptxdesc->txdw4); ptxdesc->txdw4 |= cpu_to_le32(0x00000008);//RTS Rate=24M ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00); ptxdesc->txdw5 |= cpu_to_le32(0x0000000b);//DataRate - 54M if (0)//for driver dbg { ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate if (pattrib->ht_en) ptxdesc->txdw5 |= cpu_to_le32(BIT(6));//SGI ptxdesc->txdw5 |= cpu_to_le32(0x00000013);//init rate - mcs7 } } else { // EAP data packet and ARP packet. // Use the 1M data rate to send the EAP/ARP packet. // This will maybe make the handshake smooth. ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate } //4 offset 24 #ifdef CONFIG_RTL8712_TCP_CSUM_OFFLOAD_TX if (pattrib->hw_tcp_csum == 1) { // ptxdesc->txdw6 = 0; // clear TCP_CHECKSUM and IP_CHECKSUM. It's zero already!! u8 ip_hdr_offset = 32 + pattrib->hdrlen + pattrib->iv_len + 8; ptxdesc->txdw7 = (1 << 31) | (ip_hdr_offset << 16); printk("ptxdesc->txdw7 = %08x\n", ptxdesc->txdw7); } #endif fill_txdesc_for_mp(pxmitframe, ptxdesc); } else if(pxmitframe->frame_tag == MGNT_FRAMETAG) { //printk("pxmitframe->frame_tag == MGNT_FRAMETAG\n"); //4 offset 4 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x1f);//(MAC_ID) qsel = (uint)(pattrib->qsel&0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000); //fill_txdesc_sectype(pattrib, ptxdesc); //4 offset 8 //4 offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); //4 offset 16 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate //4 offset 20 } else if(pxmitframe->frame_tag == TXAGG_FRAMETAG) { DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); } else { DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); //4 offset 4 ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);//CAM_ID(MAC_ID) ptxdesc->txdw1 |= cpu_to_le32((6<< 16) & 0x000f0000);//raid //4 offset 8 //4 offset 12 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << 16) & 0xffff0000); //4 offset 16 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate //4 offset 20 } // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. // (1) The sequence number of each non-Qos frame / broadcast / multicast / // mgnt frame should be controled by Hw because Fw will also send null data // which we cannot control when Fw LPS enable. // --> default enable non-Qos data sequense number. 2010.06.23. by tynli. // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. // 2010.06.23. Added by tynli. if(!pattrib->qos_en) { 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. } cal_txdesc_chksum(ptxdesc); }