mt76: mt7915: add Tx A-MSDU offloading support
This disables the software A-MSDU aggregation in mac80211 and enables hardware offloading Suggested-by: Yiwei Chung <yiwei.chung@mediatek.com> Suggested-by: YF Luo <yf.luo@mediatek.com> Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> Co-developed-by: Felix Fietkau <nbd@nbd.name> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
2a3412061a
commit
b443e55fb5
@ -304,11 +304,14 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
|
||||
ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
|
||||
ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
|
||||
ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
|
||||
ieee80211_hw_set(hw, TX_AMSDU);
|
||||
|
||||
/* TODO: avoid linearization for SDIO */
|
||||
if (!mt76_is_sdio(dev))
|
||||
ieee80211_hw_set(hw, TX_FRAG_LIST);
|
||||
if (!(dev->drv->drv_flags & MT_DRV_AMSDU_OFFLOAD)) {
|
||||
ieee80211_hw_set(hw, TX_AMSDU);
|
||||
|
||||
/* TODO: avoid linearization for SDIO */
|
||||
if (!mt76_is_sdio(dev))
|
||||
ieee80211_hw_set(hw, TX_FRAG_LIST);
|
||||
}
|
||||
|
||||
ieee80211_hw_set(hw, MFP_CAPABLE);
|
||||
ieee80211_hw_set(hw, AP_LINK_PS);
|
||||
|
@ -216,6 +216,7 @@ struct mt76_wcid {
|
||||
|
||||
u8 sta:1;
|
||||
u8 ext_phy:1;
|
||||
u8 amsdu:1;
|
||||
|
||||
u8 rx_check_pn;
|
||||
u8 rx_key_pn[IEEE80211_NUM_TIDS][6];
|
||||
@ -311,6 +312,7 @@ struct mt76_hw_cap {
|
||||
#define MT_DRV_SW_RX_AIRTIME BIT(2)
|
||||
#define MT_DRV_RX_DMA_HDR BIT(3)
|
||||
#define MT_DRV_HW_MGMT_TXQ BIT(4)
|
||||
#define MT_DRV_AMSDU_OFFLOAD BIT(5)
|
||||
|
||||
struct mt76_driver_ops {
|
||||
u32 drv_flags;
|
||||
|
@ -680,6 +680,8 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
|
||||
|
||||
val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
|
||||
FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
|
||||
if (wcid->amsdu)
|
||||
val |= MT_TXD7_HW_AMSDU;
|
||||
txwi[7] = cpu_to_le32(val);
|
||||
|
||||
val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count);
|
||||
|
@ -949,6 +949,23 @@ mt7915_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
|
||||
he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_mcu_bss_hw_amsdu_tlv(struct sk_buff *skb)
|
||||
{
|
||||
#define TXD_CMP_MAP1 GENMASK(15, 0)
|
||||
#define TXD_CMP_MAP2 (GENMASK(31, 0) & ~BIT(23))
|
||||
struct bss_info_hw_amsdu *amsdu;
|
||||
struct tlv *tlv;
|
||||
|
||||
tlv = mt7915_mcu_add_tlv(skb, BSS_INFO_HW_AMSDU, sizeof(*amsdu));
|
||||
|
||||
amsdu = (struct bss_info_hw_amsdu *)tlv;
|
||||
amsdu->cmp_bitmap_0 = cpu_to_le32(TXD_CMP_MAP1);
|
||||
amsdu->cmp_bitmap_1 = cpu_to_le32(TXD_CMP_MAP2);
|
||||
amsdu->trig_thres = cpu_to_le16(2);
|
||||
amsdu->enable = true;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt7915_vif *mvif)
|
||||
{
|
||||
@ -1023,6 +1040,7 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
|
||||
mt7915_mcu_bss_rfch_tlv(skb, vif, phy);
|
||||
mt7915_mcu_bss_bmc_tlv(skb, phy);
|
||||
mt7915_mcu_bss_ra_tlv(skb, vif, phy);
|
||||
mt7915_mcu_bss_hw_amsdu_tlv(skb);
|
||||
|
||||
if (vif->bss_conf.he_support)
|
||||
mt7915_mcu_bss_he_tlv(skb, vif, phy);
|
||||
@ -1181,6 +1199,9 @@ mt7915_mcu_sta_ba(struct mt7915_dev *dev,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
if (enable && tx && !params->amsdu)
|
||||
msta->wcid.amsdu = false;
|
||||
|
||||
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
|
||||
MT7915_STA_UPDATE_MAX_SIZE);
|
||||
if (IS_ERR(skb))
|
||||
@ -1546,6 +1567,37 @@ mt7915_mcu_add_mu(struct mt7915_dev *dev, struct ieee80211_vif *vif,
|
||||
MCU_EXT_CMD_STA_REC_UPDATE, true);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
|
||||
{
|
||||
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
|
||||
struct sta_rec_amsdu *amsdu;
|
||||
struct tlv *tlv;
|
||||
|
||||
if (!sta->max_amsdu_len)
|
||||
return;
|
||||
|
||||
tlv = mt7915_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));
|
||||
amsdu = (struct sta_rec_amsdu *)tlv;
|
||||
amsdu->max_amsdu_num = 8;
|
||||
amsdu->amsdu_en = true;
|
||||
amsdu->max_mpdu_size = sta->max_amsdu_len >=
|
||||
IEEE80211_MAX_MPDU_LEN_VHT_7991;
|
||||
msta->wcid.amsdu = true;
|
||||
}
|
||||
|
||||
static bool
|
||||
mt7915_hw_amsdu_supported(struct ieee80211_vif *vif)
|
||||
{
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_mcu_sta_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
|
||||
struct ieee80211_sta *sta, struct ieee80211_vif *vif)
|
||||
@ -1559,6 +1611,9 @@ mt7915_mcu_sta_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
|
||||
tlv = mt7915_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
|
||||
ht = (struct sta_rec_ht *)tlv;
|
||||
ht->ht_cap = cpu_to_le16(sta->ht_cap.cap);
|
||||
|
||||
if (mt7915_hw_amsdu_supported(vif))
|
||||
mt7915_mcu_sta_amsdu_tlv(skb, sta);
|
||||
}
|
||||
|
||||
/* starec vht */
|
||||
|
@ -402,6 +402,16 @@ struct bss_info_ra {
|
||||
__le32 fast_interval;
|
||||
} __packed;
|
||||
|
||||
struct bss_info_hw_amsdu {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le32 cmp_bitmap_0;
|
||||
__le32 cmp_bitmap_1;
|
||||
__le16 trig_thres;
|
||||
u8 enable;
|
||||
u8 rsv;
|
||||
} __packed;
|
||||
|
||||
struct bss_info_he {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
@ -736,6 +746,15 @@ struct sta_rec_ba {
|
||||
__le16 winsize;
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_amsdu {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 max_amsdu_num;
|
||||
u8 max_mpdu_size;
|
||||
u8 amsdu_en;
|
||||
u8 rsv;
|
||||
} __packed;
|
||||
|
||||
struct sec_key {
|
||||
u8 cipher_id;
|
||||
u8 cipher_len;
|
||||
@ -963,6 +982,7 @@ enum {
|
||||
sizeof(struct sta_rec_ba) + \
|
||||
sizeof(struct sta_rec_vht) + \
|
||||
sizeof(struct sta_rec_uapsd) + \
|
||||
sizeof(struct sta_rec_amsdu) + \
|
||||
sizeof(struct tlv) + \
|
||||
MT7915_WTBL_UPDATE_MAX_SIZE)
|
||||
|
||||
@ -974,6 +994,7 @@ enum {
|
||||
sizeof(struct bss_info_basic) +\
|
||||
sizeof(struct bss_info_rf_ch) +\
|
||||
sizeof(struct bss_info_ra) + \
|
||||
sizeof(struct bss_info_hw_amsdu) +\
|
||||
sizeof(struct bss_info_he) + \
|
||||
sizeof(struct bss_info_bmc_rate) +\
|
||||
sizeof(struct bss_info_ext_bss) +\
|
||||
|
@ -100,7 +100,8 @@ static int mt7915_pci_probe(struct pci_dev *pdev,
|
||||
static const struct mt76_driver_ops drv_ops = {
|
||||
/* txwi_size = txd size + txp size */
|
||||
.txwi_size = MT_TXD_SIZE + sizeof(struct mt7915_txp),
|
||||
.drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ,
|
||||
.drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ |
|
||||
MT_DRV_AMSDU_OFFLOAD,
|
||||
.survey_flags = SURVEY_INFO_TIME_TX |
|
||||
SURVEY_INFO_TIME_RX |
|
||||
SURVEY_INFO_TIME_BSS_RX,
|
||||
|
Loading…
x
Reference in New Issue
Block a user