void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc_tx, u8 *pbd_desc_tx, struct ieee80211_tx_info *info, struct ieee80211_sta *sta, struct sk_buff *skb, u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 *pdesc = pdesc_tx; u16 seq_number; __le16 fc = hdr->frame_control; u8 reserved_macid = 0; u8 fw_qsel = rtl92s_map_hwqueue_to_fwqueue(skb, hw_queue); bool firstseg = (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG))); bool lastseg = (!(hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS))); dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); u8 bw_40 = 0; if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "DMA mapping error\n"); return; } if (mac->opmode == NL80211_IFTYPE_STATION) { bw_40 = mac->bw_40; } else if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { if (sta) bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40; } seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S); if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { firstseg = true; lastseg = true; } if (firstseg) { if (rtlpriv->dm.useramask) { /* set txdesc macId */ if (ptcb_desc->mac_id < 32) { SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id); reserved_macid |= ptcb_desc->mac_id; } } SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid); SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >= DESC_RATEMCS0) ? 1 : 0)); if (rtlhal->version == VERSION_8192S_ACUT) { if (ptcb_desc->hw_rate == DESC_RATE1M || ptcb_desc->hw_rate == DESC_RATE2M || ptcb_desc->hw_rate == DESC_RATE5_5M || ptcb_desc->hw_rate == DESC_RATE11M) { ptcb_desc->hw_rate = DESC_RATE12M; } } SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate); if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble) SET_TX_DESC_TX_SHORT(pdesc, 0); /* Aggregation related */ if (info->flags & IEEE80211_TX_CTL_AMPDU) SET_TX_DESC_AGG_ENABLE(pdesc, 1); /* For AMPDU, we must insert SSN into TX_DESC */ SET_TX_DESC_SEQ(pdesc, seq_number); /* Protection mode related */ /* For 92S, if RTS/CTS are set, HW will execute RTS. */ /* We choose only one protection mode to execute */ SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable && !ptcb_desc->cts_enable) ? 1 : 0)); SET_TX_DESC_CTS_ENABLE(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0)); SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0)); SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate); SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0); SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc); SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <= DESC_RATE54M) ? (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : (ptcb_desc->rts_use_shortgi ? 1 : 0))); /* Set Bandwidth and sub-channel settings. */ if (bw_40) { if (ptcb_desc->packet_bw) { SET_TX_DESC_TX_BANDWIDTH(pdesc, 1); /* use duplicated mode */ SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); } else { SET_TX_DESC_TX_BANDWIDTH(pdesc, 0); SET_TX_DESC_TX_SUB_CARRIER(pdesc, mac->cur_40_prime_sc); } } else { SET_TX_DESC_TX_BANDWIDTH(pdesc, 0); SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); } /* 3 Fill necessary field in First Descriptor */ /*DWORD 0*/ SET_TX_DESC_LINIP(pdesc, 0); SET_TX_DESC_OFFSET(pdesc, 32); SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); /*DWORD 1*/ SET_TX_DESC_RA_BRSR_ID(pdesc, ptcb_desc->ratr_index); /* Fill security related */ if (info->control.hw_key) { struct ieee80211_key_conf *keyconf; keyconf = info->control.hw_key; switch (keyconf->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: SET_TX_DESC_SEC_TYPE(pdesc, 0x1); break; case WLAN_CIPHER_SUITE_TKIP: SET_TX_DESC_SEC_TYPE(pdesc, 0x2); break; case WLAN_CIPHER_SUITE_CCMP: SET_TX_DESC_SEC_TYPE(pdesc, 0x3); break; default: SET_TX_DESC_SEC_TYPE(pdesc, 0x0); break; } } /* Set Packet ID */ SET_TX_DESC_PACKET_ID(pdesc, 0); /* We will assign magement queue to BK. */ SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); /* Alwasy enable all rate fallback range */ SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); /* Fix: I don't know why hw use 6.5M to tx when set it */ SET_TX_DESC_USER_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); /* Set NON_QOS bit. */ if (!ieee80211_is_data_qos(fc)) SET_TX_DESC_NON_QOS(pdesc, 1); } /* Fill fields that are required to be initialized * in all of the descriptors */ /*DWORD 0 */ SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); /* DWORD 7 */ SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); /* DOWRD 8 */ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); }
void rtl8822be_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc_tx, u8 *pbd_desc_tx, struct ieee80211_tx_info *info, struct ieee80211_sta *sta, struct sk_buff *skb, u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_phy *rtlphy = &rtlpriv->phy; u8 *pdesc = (u8 *)pdesc_tx; u16 seq_number; __le16 fc = hdr->frame_control; u8 fw_qsel = _rtl8822be_map_hwqueue_to_fwqueue(skb, hw_queue); bool firstseg = ((hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); bool lastseg = ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); dma_addr_t mapping; u8 short_gi = 0; seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); /* reserve 8 byte for AMPDU early mode */ if (rtlhal->earlymode_enable) { skb_push(skb, EM_HDR_LEN); memset(skb->data, 0, EM_HDR_LEN); } mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "DMA mapping error"); return; } if (pbd_desc_tx) rtl8822be_pre_fill_tx_bd_desc(hw, pbd_desc_tx, pdesc, hw_queue, skb, mapping); if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { firstseg = true; lastseg = true; } if (firstseg) { if (rtlhal->earlymode_enable) { SET_TX_DESC_PKT_OFFSET(pdesc, 1); SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN + EM_HDR_LEN); if (ptcb_desc->empkt_num) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "Insert 8 byte.pTcb->EMPktNum:%d\n", ptcb_desc->empkt_num); _rtl8822be_insert_emcontent(ptcb_desc, (u8 *)(skb->data)); } } else { SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); } /* tx report */ rtl_get_tx_report(ptcb_desc, pdesc, hw); if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G && ptcb_desc->hw_rate < DESC_RATE6M) { RT_TRACE(rtlpriv, COMP_SEND, DBG_WARNING, "hw_rate=0x%X is invalid in 5G\n", ptcb_desc->hw_rate); ptcb_desc->hw_rate = DESC_RATE6M; } SET_TX_DESC_DATARATE(pdesc, ptcb_desc->hw_rate); if (ptcb_desc->hw_rate > DESC_RATEMCS0) short_gi = (ptcb_desc->use_shortgi) ? 1 : 0; else short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0; if (info->flags & IEEE80211_TX_CTL_AMPDU) { SET_TX_DESC_AGG_EN(pdesc, 1); SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x1F); } SET_TX_DESC_SW_SEQ(pdesc, seq_number); SET_TX_DESC_RTSEN(pdesc, ((ptcb_desc->rts_enable && !ptcb_desc->cts_enable) ? 1 : 0)); SET_TX_DESC_HW_RTS_EN(pdesc, 0); SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0)); SET_TX_DESC_RTSRATE(pdesc, ptcb_desc->rts_rate); SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc); SET_TX_DESC_RTS_SHORT( pdesc, ((ptcb_desc->rts_rate <= DESC_RATE54M) ? (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : (ptcb_desc->rts_use_shortgi ? 1 : 0))); if (ptcb_desc->tx_enable_sw_calc_duration) SET_TX_DESC_NAVUSEHDR(pdesc, 1); SET_TX_DESC_DATA_BW(pdesc, rtl8822be_bw_mapping(hw, ptcb_desc)); SET_TX_DESC_DATA_SC(pdesc, rtl8822be_sc_mapping(hw, ptcb_desc)); if (sta) { u8 ampdu_density = sta->ht_cap.ampdu_density; SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); } if (info->control.hw_key) { struct ieee80211_key_conf *key = info->control.hw_key; switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: case WLAN_CIPHER_SUITE_TKIP: SET_TX_DESC_SEC_TYPE(pdesc, 0x1); break; case WLAN_CIPHER_SUITE_CCMP: SET_TX_DESC_SEC_TYPE(pdesc, 0x3); break; default: SET_TX_DESC_SEC_TYPE(pdesc, 0x0); break; } } SET_TX_DESC_QSEL(pdesc, fw_qsel); if (rtlphy->current_channel > 14) { /* OFDM 6M */ SET_TX_DESC_DATA_RTY_LOWEST_RATE(pdesc, 4); SET_TX_DESC_RTS_RTY_LOWEST_RATE(pdesc, 4); } else { /* CCK 1M */ SET_TX_DESC_DATA_RTY_LOWEST_RATE(pdesc, 0); SET_TX_DESC_RTS_RTY_LOWEST_RATE(pdesc, 0); } SET_TX_DESC_DISDATAFB(pdesc, ptcb_desc->disable_ratefallback ? 1 : 0); SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); /*SET_TX_DESC_PWR_STATUS(pdesc, pwr_status);*/ /* Set TxRate and RTSRate in TxDesc */ /* This prevent Tx initial rate of new-coming packets */ /* from being overwritten by retried packet rate.*/ if (!ptcb_desc->use_driver_rate) { /*SET_TX_DESC_RTS_RATE(pdesc, 0x08); */ /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */ } if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "Enable RDG function.\n"); SET_TX_DESC_RDG_EN(pdesc, 1); SET_TX_DESC_HTC(pdesc, 1); } } SET_TX_DESC_PORT_ID(pdesc, 0); SET_TX_DESC_MULTIPLE_PORT(pdesc, 0); } SET_TX_DESC_LS(pdesc, (lastseg ? 1 : 0)); if (rtlpriv->dm.useramask) { SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index); SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id); } else { SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index); SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index); } SET_TX_DESC_MOREFRAG(pdesc, (lastseg ? 0 : 1)); if (ptcb_desc->multicast || ptcb_desc->broadcast) { SET_TX_DESC_BMC(pdesc, 1); /* BMC must be not AGG */ SET_TX_DESC_AGG_EN(pdesc, 0); } RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); /* debug purpose: used to check tx desc is correct or not */ /*rtlpriv->halmac.ops->halmac_chk_txdesc(rtlpriv, pdesc, * skb->len + USB_HWDESC_HEADER_LEN); */ }