From patchwork Fri Apr 10 08:54:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryder Lee X-Patchwork-Id: 216061 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, MIME_BASE64_TEXT, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNPARSEABLE_RELAY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4691AC2BB55 for ; Fri, 10 Apr 2020 08:55:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 083B220787 for ; Fri, 10 Apr 2020 08:55:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="M6FhhXmN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726184AbgDJIzK (ORCPT ); Fri, 10 Apr 2020 04:55:10 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:30602 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1725912AbgDJIzJ (ORCPT ); Fri, 10 Apr 2020 04:55:09 -0400 X-UUID: aa1154e6129d45cfbf1dcc4cfd9e64ec-20200410 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=AC/2zCkdulGB75Nmrt0AqeQETE4fZ3CMa6Mi4b3Ulo0=; b=M6FhhXmNBvH4J/qUvZP+cyPsdx/GN8w6J5t9NnzOxw/mMpvLBnilHvBE7TZfNTXIBIlncnAe/Hp6Z5QinpZkqZiyksyrXH/+YHcGFQrf1gAM+Ii11XAPE/0qHPWZ0YPtD/cLYIiz8u2Zek0RePmD1wbEe/+t2aDdllD/XkB5zUg=; X-UUID: aa1154e6129d45cfbf1dcc4cfd9e64ec-20200410 Received: from mtkexhb01.mediatek.inc [(172.21.101.102)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1439465506; Fri, 10 Apr 2020 16:55:03 +0800 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs02n1.mediatek.inc (172.21.101.77) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 10 Apr 2020 16:54:58 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 10 Apr 2020 16:54:58 +0800 From: Ryder Lee To: Felix Fietkau , Lorenzo Bianconi CC: Shayne Chen , YF Luo , Yiwei Chung , Chih-Min Chen , Evelyn Tsai , Sean Wang , , , Ryder Lee Subject: [PATCH 08/16] mt76: mt7915: add offloading Tx AMSDU support Date: Fri, 10 Apr 2020 16:54:45 +0800 Message-ID: <0cf99a5f317b0d41cd4832b14c99b6b9b8e5fefc.1586507878.git.ryder.lee@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: References: MIME-Version: 1.0 X-MTK: N Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Add module parameter to enable hw_tx_amsdu. Signed-off-by: Ryder Lee Signed-off-by: Shayne Chen Tested-by: Chih-Min Chen Tested-by: Evelyn Tsai Suggested-by: Yiwei Chung Suggested-by: YF Luo --- .../net/wireless/mediatek/mt76/mt7915/init.c | 5 ++- .../net/wireless/mediatek/mt76/mt7915/mac.c | 4 +- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 40 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7915/mcu.h | 20 ++++++++++ .../wireless/mediatek/mt76/mt7915/mt7915.h | 1 + .../net/wireless/mediatek/mt76/mt7915/pci.c | 8 ++++ 6 files changed, 76 insertions(+), 2 deletions(-) -- 2.18.0 diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index cba9dfb83e19..59b3ffae7917 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -236,7 +236,10 @@ mt7915_init_wiphy(struct ieee80211_hw *hw) ieee80211_hw_set(hw, HAS_RATE_CONTROL); - hw->max_tx_fragments = 4; + if (phy->dev->hw_tx_amsdu) + hw->max_tx_fragments = 1; + else + hw->max_tx_fragments = 4; } static void diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index 349215dd417c..f0604bb6d644 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -524,7 +524,9 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, txwi[7] = cpu_to_le32(val); val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count); - if (ieee80211_is_data_qos(fc)) { + if (dev->hw_tx_amsdu && ieee80211_is_data_qos(fc)) { + txwi[7] |= MT_TXD7_HW_AMSDU; + } else if (ieee80211_is_data_qos(fc)) { seqno = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); val |= MT_TXD3_SN_VALID; } else if (ieee80211_is_back_req(fc)) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 59cd50db2ecf..5e70f7f24fb7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -85,6 +85,8 @@ struct mt7915_fw_region { #define to_wcid_lo(id) FIELD_GET(GENMASK(7, 0), (u16)id) #define to_wcid_hi(id) FIELD_GET(GENMASK(9, 8), (u16)id) +#define HW_TX_AMSDU_MAX_NUM 8 + static enum mt7915_cipher_type mt7915_mcu_get_cipher(int cipher) { @@ -786,6 +788,23 @@ mt7915_mcu_bss_ra_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, ra->fast_interval = cpu_to_le32(100); } +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) { @@ -861,6 +880,9 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy, mt7915_mcu_bss_bmc_tlv(skb, phy); mt7915_mcu_bss_ra_tlv(skb, vif, phy); + if (phy->dev->hw_tx_amsdu) + mt7915_mcu_bss_hw_amsdu_tlv(skb); + if (mvif->omac_idx > HW_BSSID_MAX) mt7915_mcu_bss_ext_tlv(skb, mvif); else @@ -1145,6 +1167,24 @@ 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); + + /* starec hw amsdu */ + if (dev->hw_tx_amsdu) { + struct sta_rec_amsdu *amsdu; + int max_amsdu_len = sta->max_amsdu_len; + + tlv = mt7915_mcu_add_tlv(skb, STA_REC_HW_AMSDU, + sizeof(*amsdu)); + amsdu = (struct sta_rec_amsdu *)tlv; + amsdu->max_amsdu_num = HW_TX_AMSDU_MAX_NUM; + amsdu->amsdu_en = true; + + if (sta->max_rc_amsdu_len) + max_amsdu_len = min_t(int, max_amsdu_len, + sta->max_rc_amsdu_len); + + amsdu->max_mpdu_size = max_amsdu_len; + } } /* starec vht */ diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index d9c9aab7e6dc..867cab7cf145 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -396,6 +396,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_bcn { __le16 tag; __le16 len; @@ -659,6 +669,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; @@ -796,6 +815,7 @@ enum { sizeof(struct sta_rec_ba) + \ sizeof(struct sta_rec_vht) + \ sizeof(struct tlv) + \ + sizeof(struct sta_rec_amsdu) + \ sizeof(struct sta_rec_sec) + \ sizeof(struct sta_rec_ra) + \ MT7915_WTBL_UPDATE_MAX_SIZE) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index b502bcc985ec..7f569a7a0c9b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -167,6 +167,7 @@ struct mt7915_dev { u8 mac_work_count; bool fw_debug; + bool hw_tx_amsdu; }; enum { diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c index d349561e4598..75f72ae104db 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c @@ -12,6 +12,10 @@ #include "mac.h" #include "../trace.h" +static bool hw_tx_amsdu; +module_param_named(enable_hw_tx_amsdu, hw_tx_amsdu, bool, 0644); +MODULE_PARM_DESC(enable_hw_tx_amsdu, "enable Hardware Tx AMSDU"); + static const struct pci_device_id mt7915_pci_device_table[] = { { PCI_DEVICE(0x14c3, 0x7915) }, { }, @@ -149,6 +153,10 @@ static int mt7915_pci_probe(struct pci_dev *pdev, (mt7915_l1_rr(dev, MT_HW_REV) & 0xff); dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev); + /* TODO: more hw capabilities */ + if (hw_tx_amsdu) + dev->hw_tx_amsdu = true; + /* master switch of PCIe tnterrupt enable */ mt7915_l1_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);