void rtl8822be_tx_fill_special_desc(struct ieee80211_hw *hw, u8 *pdesc, u8 *pbd_desc, struct sk_buff *skb, u8 hw_queue) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); u8 fw_queue; u8 txdesc_len = 48; dma_addr_t 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; } rtl8822be_pre_fill_tx_bd_desc(hw, pbd_desc, pdesc, hw_queue, skb, mapping); /* it should be BEACON_QUEUE or H2C_QUEUE, * so skb=NULL is safe to assert */ fw_queue = _rtl8822be_map_hwqueue_to_fwqueue(NULL, hw_queue); CLEAR_PCI_TX_DESC_CONTENT(pdesc, txdesc_len); /* common part for BEACON and H2C */ SET_TX_DESC_TXPKTSIZE((u8 *)pdesc, (u16)(skb->len)); SET_TX_DESC_QSEL(pdesc, fw_queue); if (hw_queue == H2C_QUEUE) { /* fill H2C */ SET_TX_DESC_OFFSET(pdesc, 0); } else { /* fill beacon */ SET_TX_DESC_OFFSET(pdesc, txdesc_len); SET_TX_DESC_DATARATE(pdesc, DESC_RATE1M); SET_TX_DESC_SW_SEQ(pdesc, 0); SET_TX_DESC_RATE_ID(pdesc, 7); SET_TX_DESC_MACID(pdesc, 0); SET_TX_DESC_LS(pdesc, 1); SET_TX_DESC_OFFSET(pdesc, 48); SET_TX_DESC_USE_RATE(pdesc, 1); } RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n", pdesc, txdesc_len); }
void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool firstseg, bool lastseg, struct sk_buff *skb) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb); dma_addr_t 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_TRACE, "DMA mapping error\n"); return; } /* Clear all status */ CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S); /* This bit indicate this packet is used for FW download. */ if (tcb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) { /* For firmware downlaod we only need to set LINIP */ SET_TX_DESC_LINIP(pdesc, tcb_desc->last_inipkt); /* 92SE must set as 1 for firmware download HW DMA error */ SET_TX_DESC_FIRST_SEG(pdesc, 1); SET_TX_DESC_LAST_SEG(pdesc, 1); /* 92SE need not to set TX packet size when firmware download */ SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len)); SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); wmb(); SET_TX_DESC_OWN(pdesc, 1); } else { /* H2C Command Desc format (Host TXCMD) */ /* 92SE must set as 1 for firmware download HW DMA error */ SET_TX_DESC_FIRST_SEG(pdesc, 1); SET_TX_DESC_LAST_SEG(pdesc, 1); SET_TX_DESC_OFFSET(pdesc, 0x20); /* Buffer size + command header */ SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len)); /* Fixed queue of H2C command */ SET_TX_DESC_QUEUE_SEL(pdesc, 0x13); SET_BITS_TO_LE_4BYTE(skb->data, 24, 7, rtlhal->h2c_txcmd_seq); SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); wmb(); SET_TX_DESC_OWN(pdesc, 1); } }
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_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, u8 *tx_bd_desc, u8 *desc, u8 queue_index, struct sk_buff *skb, dma_addr_t data_addr) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); u32 pkt_len = skb->len; u16 desc_size = 48; /*tx desc size*/ u32 psblen = 0; u32 total_packet_size = 0; u16 current_bd_desc; u8 i = 0; /*u16 real_desc_size = 0x28;*/ u16 append_early_mode_size = 0; u8 segmentnum = 1 << (RTL8822BE_SEG_NUM + 1); dma_addr_t desc_dma_addr; bool dma64 = rtlpriv->cfg->mod_params->dma64; current_bd_desc = rtlpci->tx_ring[queue_index].cur_tx_wp; total_packet_size = desc_size + pkt_len; if (rtlpriv->rtlhal.earlymode_enable) { if (queue_index < BEACON_QUEUE) { append_early_mode_size = 8; total_packet_size += append_early_mode_size; } } /* page number (round up) */ psblen = (total_packet_size - 1) / 128 + 1; /* tx desc addr */ desc_dma_addr = rtlpci->tx_ring[queue_index].dma + (current_bd_desc * TX_DESC_SIZE); /* Reset */ SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, 0); SET_TX_BUFF_DESC_PSB(tx_bd_desc, 0); SET_TX_BUFF_DESC_OWN(tx_bd_desc, 0); for (i = 1; i < segmentnum; i++) { SET_TXBUFFER_DESC_LEN_WITH_OFFSET(tx_bd_desc, i, 0); SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(tx_bd_desc, i, 0); SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(tx_bd_desc, i, 0); SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(tx_bd_desc, i, 0, dma64); } /* Clear all status */ CLEAR_PCI_TX_DESC_CONTENT(desc, TX_DESC_SIZE); if (rtlpriv->rtlhal.earlymode_enable) { if (queue_index < BEACON_QUEUE) SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size + 8); else SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size); } else { SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size); } SET_TX_BUFF_DESC_PSB(tx_bd_desc, psblen); SET_TX_BUFF_DESC_ADDR_LOW_0(tx_bd_desc, desc_dma_addr); SET_TX_BUFF_DESC_ADDR_HIGH_0(tx_bd_desc, ((u64)desc_dma_addr >> 32), dma64); SET_TXBUFFER_DESC_LEN_WITH_OFFSET(tx_bd_desc, 1, pkt_len); SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(tx_bd_desc, 1, 0); SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(tx_bd_desc, 1, data_addr); SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(tx_bd_desc, 1, ((u64)data_addr >> 32), dma64); SET_TX_DESC_TXPKTSIZE(desc, (u16)(pkt_len)); }