Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp339899pxa; Wed, 12 Aug 2020 03:29:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw5leyADTLxeuNwT3KGOuztyJ2ajxUW4LPkkmaQXTNts47zKj0ymhuUuxd/CnQsesYAvCYr X-Received: by 2002:aa7:cd08:: with SMTP id b8mr30881873edw.228.1597228191823; Wed, 12 Aug 2020 03:29:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597228191; cv=none; d=google.com; s=arc-20160816; b=nof282mWf4XLAe3ZrT5B+m3eMSzfP7N2Db3ogO5k8eXDhWcPuxzTplQ2UnCHX9imPT F7w0YmhgtcStgf5TFOQui9+059UQ8aNUjIssuMdhCEL4ehFBQ3zGaNTBwVqkheB8JVnu VeC1c7atJzkIr6lVoJCUrzhsF85Y86ajaxWGo5GEXTkyT5p6f6N3AUpeqCpASp2y/pSb QfULQFOJ8xiO85WPnePkwYQAcnv+KNcm7es9InghvDt7MD0Ozp9+A5qCWOF1xZbAbcNc Lm9LNKzskcwmF2KUxmORSq9NruY3oQ0imOd4Bd/FfjV/2y/5Hlb6WYTp/uPVzRNJwXz0 ZAkA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=JWF9/oFHDxfPYYLK7AG6E20bDakuCcNeYj29fnQTI90=; b=sr7QJRqw8hhO0tnFz8gHN6xqBpY4JOw2TgLF8LIbfmWNzUrUBqKzENXjuWAA7tPRm9 nJ+XkQb+gfp0KTLMkP079la+qpA+Yvgfv8HqMNKPi4rgzulrOyq31GRBzPjAS4zTH/nh 67vVlNL/0+vUUcLiPLfUQFEOmJqgcD8WoH+0uOl4/jwW8cuYoF6LqNVn+twfR9vwmbcW QAMadt6V8lmMYcCeEmK4EVTXhqBetOi+4zkebKOG5Eg8Yb5ZWhKCuq1XTtlz2qqJQx9n hg9AjpEYER8/dlzIr6msrImL/lIN6RumwCyBTC7z7MFQwiNqEETHOdl/39dltMZxv+aC DAKw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@nbd.name header.s=20160729 header.b=t5RKoS2F; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id x2si870759ejj.386.2020.08.12.03.29.27; Wed, 12 Aug 2020 03:29:51 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=fail header.i=@nbd.name header.s=20160729 header.b=t5RKoS2F; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727826AbgHLK2h (ORCPT + 99 others); Wed, 12 Aug 2020 06:28:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37684 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727801AbgHLK2f (ORCPT ); Wed, 12 Aug 2020 06:28:35 -0400 Received: from nbd.name (nbd.name [IPv6:2a01:4f8:221:3d45::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 92067C06174A for ; Wed, 12 Aug 2020 03:28:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=JWF9/oFHDxfPYYLK7AG6E20bDakuCcNeYj29fnQTI90=; b=t5RKoS2FEs69nLnzgSj3ZDbri1 9qUU9/NZPnYnggeAOFRvqTKAiOhXItMl+7gZNdc5LghKxT7Gf+VFKGvtP9DNVN0upsjy5wge0ylC5 wR9jyUhFum0G49oOyVr/c0p5KbIHeWk1cMs0h4qan/hQpL8DCV6yd2CVoNFVEBypJXKY=; Received: from p54ae996c.dip0.t-ipconnect.de ([84.174.153.108] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.89) (envelope-from ) id 1k5nzl-0002U3-5Y; Wed, 12 Aug 2020 12:28:33 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: Ryder Lee , Yiwei Chung , YF Luo Subject: [PATCH 8/8] mt76: mt7915: add Tx A-MSDU offloading support Date: Wed, 12 Aug 2020 12:28:31 +0200 Message-Id: <20200812102831.11991-8-nbd@nbd.name> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812102831.11991-1-nbd@nbd.name> References: <20200812102831.11991-1-nbd@nbd.name> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Ryder Lee This disables the software A-MSDU aggregation in mac80211 and enables hardware offloading Suggested-by: Yiwei Chung Suggested-by: YF Luo Signed-off-by: Ryder Lee Signed-off-by: Shayne Chen Co-developed-by: Felix Fietkau Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mac80211.c | 11 +++-- drivers/net/wireless/mediatek/mt76/mt76.h | 2 + .../net/wireless/mediatek/mt76/mt7915/mac.c | 2 + .../net/wireless/mediatek/mt76/mt7915/mcu.c | 42 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7915/mcu.h | 21 ++++++++++ .../net/wireless/mediatek/mt76/mt7915/pci.c | 3 +- 6 files changed, 76 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 3d4bf72700a5..8b41558c7855 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -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); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index f11978f2bd8f..3d5037afd5ea 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -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; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index df9131d7af3d..9e17be5005e9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -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); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 86eb24e90775..655e3bd84b19 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -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,25 @@ 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 = min_t(int, IEEE80211_MAX_MPDU_LEN_VHT_7991, + sta->max_amsdu_len); + msta->wcid.amsdu = true; +} + static void mt7915_mcu_sta_tlv(struct mt7915_dev *dev, struct sk_buff *skb, struct ieee80211_sta *sta, struct ieee80211_vif *vif) @@ -1559,6 +1599,8 @@ 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); + + mt7915_mcu_sta_amsdu_tlv(skb, sta); } /* starec vht */ diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index a4600860fbf7..c656d66385c4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -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) +\ diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c index 520dea15c449..e0d853bca52a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c @@ -78,7 +78,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, -- 2.28.0