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); #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); //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 SET_TX_DESC_FIRST_SEG_8812(ptxdesc, 1); SET_TX_DESC_LAST_SEG_8812(ptxdesc, 1); SET_TX_DESC_OWN_8812(ptxdesc, 1); //DBG_8192C("%s==> pkt_len=%d,bagg_pkt=%02x\n",__FUNCTION__,sz,bagg_pkt); SET_TX_DESC_PKT_SIZE_8812(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_8812(ptxdesc, offset); if (bmcst) { SET_TX_DESC_BMC_8812(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_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); //offset 12 if (!pattrib->qos_en) { SET_TX_DESC_HWSEQ_EN_8812(ptxdesc, 1); // Hw set sequence number } else { SET_TX_DESC_SEQ_8812(ptxdesc, pattrib->seqnum); } if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n"); rtl8812a_fill_txdesc_sectype(pattrib, ptxdesc); //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_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 ) { //Non EAP & ARP & DHCP type data packet if (pattrib->ampdu_en==_TRUE) { SET_TX_DESC_AGG_ENABLE_8812(ptxdesc, 1); SET_TX_DESC_MAX_AGG_NUM_8812(ptxdesc, 0x1f); // Set A-MPDU aggregation. SET_TX_DESC_AMPDU_DENSITY_8812(ptxdesc, pattrib->ampdu_spacing); } else { SET_TX_DESC_AGG_BREAK_8812(ptxdesc, 1); } rtl8812a_fill_txdesc_phy(padapter, pattrib, ptxdesc); //DATA Rate FB LMT SET_TX_DESC_DATA_RATE_FB_LIMIT_8812(ptxdesc, 0x1f); if (pHalData->fw_ractrl == _FALSE) { SET_TX_DESC_USE_RATE_8812(ptxdesc, 1); if(pdmpriv->INIDATA_RATE[pattrib->mac_id] & BIT(7)) SET_TX_DESC_DATA_SHORT_8812(ptxdesc, 1); SET_TX_DESC_TX_RATE_8812(ptxdesc, (pdmpriv->INIDATA_RATE[pattrib->mac_id] & 0x7F)); } if (padapter->fix_rate != 0xFF) { // modify data rate by iwpriv SET_TX_DESC_USE_RATE_8812(ptxdesc, 1); if(padapter->fix_rate & BIT(7)) SET_TX_DESC_DATA_SHORT_8812(ptxdesc, 1); SET_TX_DESC_TX_RATE_8812(ptxdesc, (padapter->fix_rate & 0x7F)); if (!padapter->data_fb) SET_TX_DESC_DISABLE_FB_8812(ptxdesc,1); } if (pattrib->ldpc) SET_TX_DESC_DATA_LDPC_8812(ptxdesc, 1); if (pattrib->stbc) SET_TX_DESC_DATA_STBC_8812(ptxdesc, 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. SET_TX_DESC_USE_RATE_8812(ptxdesc, 1); SET_TX_DESC_AGG_BREAK_8812(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_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); #ifdef DBG_CCX DBG_871X("%s set tx report\n", __func__); #endif } #endif /* CONFIG_XMIT_ACK */ #endif } else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG) { //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n"); if(IS_HARDWARE_TYPE_8821(padapter)) SET_TX_DESC_MBSSID_8821(ptxdesc, pattrib->mbssid); SET_TX_DESC_USE_RATE_8812(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_8812(ptxdesc, pattrib->rate); } else #endif { SET_TX_DESC_TX_RATE_8812(ptxdesc, MRateToHwRate(pattrib->rate)); } // VHT NDPA or HT NDPA Packet for Beamformer. if((pattrib->subtype == WIFI_NDPA) || ((pattrib->subtype == WIFI_ACTION_NOACK) && (pattrib->order == 1))) { SET_TX_DESC_NAV_USE_HDR_8812(ptxdesc, 1); SET_TX_DESC_DATA_BW_8812(ptxdesc, BWMapping_8812(padapter,pattrib)); SET_TX_DESC_RTS_SC_8812(ptxdesc, SCMapping_8812(padapter,pattrib)); 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); //if(pattrib->rts_cca) //{ // SET_TX_DESC_NDPA_8812(ptxdesc, 2); //} //else { SET_TX_DESC_NDPA_8812(ptxdesc, 1); } } else { 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, 12); } } #ifdef CONFIG_XMIT_ACK //CCX-TXRPT ack for xmit mgmt frames. if (pxmitframe->ack_report) { SET_TX_DESC_SPE_RPT_8812(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_8812(ptxdesc, 1); SET_TX_DESC_TX_RATE_8812(ptxdesc, MRateToHwRate(pmlmeext->tx_rate)); } rtl8812a_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; 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; 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, 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; }