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); } }
static void __r92su_tx_fill_header(tx_hdr *tx_hdr, unsigned int len, bool first, bool last, unsigned int qsel) { SET_TX_DESC_PKT_SIZE(tx_hdr, len); SET_TX_DESC_OFFSET(tx_hdr, TX_DESC_SIZE); SET_TX_DESC_LAST_SEG(tx_hdr, last); SET_TX_DESC_FIRST_SEG(tx_hdr, first); SET_TX_DESC_OWN(tx_hdr, 1); SET_TX_DESC_QUEUE_SEL(tx_hdr, qsel); }
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"); }