From patchwork Mon Apr 5 12:40:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 416162 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=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 BCF9BC433B4 for ; Mon, 5 Apr 2021 12:40:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 90ABB613A5 for ; Mon, 5 Apr 2021 12:40:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235399AbhDEMkv (ORCPT ); Mon, 5 Apr 2021 08:40:51 -0400 Received: from mail.kernel.org ([198.145.29.99]:43682 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235289AbhDEMkv (ORCPT ); Mon, 5 Apr 2021 08:40:51 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 90CAA613A7; Mon, 5 Apr 2021 12:40:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617626445; bh=gH8Vg05NoIbo+2nK3Pz6VTvJppFutEeqZ+HhOdzn4IY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pKIazAPdeadBu3sFSydRk5i53GGpo55p+Qgkk7H6/oSZeDMyVpJXW+SfOzTMwg7S4 nT+TQMgNEfpf+pp6vrAne/vzAYyWLdMOpbtB7xYgw4P0ge+EaXZRrYaxixXN8qRZ0s mkO4UrptlA6ziMIPsKkXu+MbwxAAn6n1hMwXPE3ctPEhzoGB8hpW1E3ewZ82tQQfTs K0mt+GLLAUdVDG1DLEbO95gX8bSLwa5m32qVtp8ej5PtJKCr8lseoVvxB/eZJFulAP 8ID5H6k1nGW9Ubpbj4ajMfGRaoGCHIUZ7NVc6P5ZpPiidoQCW7A+NWgAnee7DT8eL+ aodo5hidBEafg== From: Lorenzo Bianconi To: nbd@nbd.name Cc: linux-wireless@vger.kernel.org, lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, ryder.lee@mediatek.com, shayne.chen@mediatek.com, devicetree@vger.kernel.org, robh@kernel.org Subject: [PATCH 1/8] dt-bindings:net:wireless:ieee80211: introduce regdomain property Date: Mon, 5 Apr 2021 14:40:25 +0200 Message-Id: <1ff764d84e1fb83768c2e9d233c27b0ed1ef4294.1617625912.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add regdomain property to ieee80211 binding Signed-off-by: Lorenzo Bianconi --- .../devicetree/bindings/net/wireless/ieee80211.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/net/wireless/ieee80211.yaml b/Documentation/devicetree/bindings/net/wireless/ieee80211.yaml index d58e1571df9b..6557c6348cac 100644 --- a/Documentation/devicetree/bindings/net/wireless/ieee80211.yaml +++ b/Documentation/devicetree/bindings/net/wireless/ieee80211.yaml @@ -30,6 +30,15 @@ properties: different 5 GHz subbands. Using them incorrectly could not work or decrease performance noticeably + regdomain: + minItems: 1 + maxItems: 1 + contains: + enum: + - FCC + - ETSI + - JP + additionalProperties: true examples: From patchwork Mon Apr 5 12:40:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 415436 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=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 6963CC433B4 for ; Mon, 5 Apr 2021 12:40:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 40F94613A3 for ; Mon, 5 Apr 2021 12:40:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235507AbhDEMky (ORCPT ); Mon, 5 Apr 2021 08:40:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:43730 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235289AbhDEMkx (ORCPT ); Mon, 5 Apr 2021 08:40:53 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 33F956138A; Mon, 5 Apr 2021 12:40:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617626447; bh=m353sHpeQCluanv88FhS5CJ1v+41g7avREx4FPyjSdA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W9FlBrkJ/CkoNLrNbHwXN1aAB9GPqUWeHrHvRqHSifUcYflmoRu1CJjvmKulq9Ol/ vriLb+nOPFRzVXVGVNPnSz88ZcloLU+NF6OPzxQhilCfUyhKeCoJqU8IqHZxQttuiw lbo1qeNysmdsXOakSEr0KQJzh4jIk0M/G+inFIn74lcUnpqTMbr2r145mV1jJCYlK+ lxfWqdko8ShzqkOjatuzER0c3mGj6GAoyMPcf6xk7GJoTsAGfF75cpFWLrYpBvsT9k A8CNmxlMinPmCF3zXL2qLbFXw6lJTlaTUWJhXtpuWp/oSyc1y46jNb7MOpSHDRNtmb znnFglEDdvcwA== From: Lorenzo Bianconi To: nbd@nbd.name Cc: linux-wireless@vger.kernel.org, lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, ryder.lee@mediatek.com, shayne.chen@mediatek.com, devicetree@vger.kernel.org, robh@kernel.org Subject: [PATCH 2/8] dt-bindings:net:wireless:mediatek, mt76: introduce power-limits node Date: Mon, 5 Apr 2021 14:40:26 +0200 Message-Id: X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Introduce power-limits node in mt76 binding in order to specify per-rate power limit values for each 802.11n/802.11ac rate Signed-off-by: Lorenzo Bianconi --- .../bindings/net/wireless/mediatek,mt76.yaml | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml index d6f835d17d66..6ede331e3e52 100644 --- a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml +++ b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml @@ -72,6 +72,62 @@ properties: led-sources: maxItems: 1 + power-limits: + type: object + properties: + regdomain: true + + patternProperties: + "^r[0-9]+": + type: object + patternProperties: + "^txpower-[256]g$": + type: object + patternProperties: + "^b[0-9]+$": + type: object + properties: + channels: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 2 + maxItems: 2 + description: + Pairs of first and last channel number of the selected + band + + cck: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 4 + maxItems: 4 + description: + 4 half-dBm per-rate power limit values + + mcs: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + description: + Sets of per-rate power limit values for 802.11n/802.11ac + rates for multiple channel bandwidth settings. + Each set starts with the number of channel bandwidth + settings for which the rate set applies, followed by + either 8 or 10 power limit values. The order of the + channel bandwidth settings is 20, 40, 80 and 160 MHz. + + ru: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + description: + Sets of per-rate power limit values for 802.11ax rates + for multiple channel bandwidth or resource unit settings. + Each set starts with the number of channel bandwidth or + resource unit settings for which the rate set applies, + followed by 12 power limit values. The order of the + channel resource unit settings is RU26, RU52, RU106, + RU242/SU20, RU484/SU40, RU996/SU80 and RU2x996/SU160. + + txs-delta: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: + Half-dBm power delta for different numbers of antennas + required: - compatible - reg @@ -93,6 +149,29 @@ examples: led { led-sources = <2>; }; + + power-limits { + r0 { + txpower-5g { + regdomain = "FCC"; + b0 { + channels = <36 48>; + ofdm = <23 23 23 23 23 23 23 23>; + mcs = <1 23 23 23 23 23 23 23 23 23 23>, + <3 22 22 22 22 22 22 22 22 22 22>; + ru = <3 22 22 22 22 22 22 22 22 22 22 22 22>, + <4 20 20 20 20 20 20 20 20 20 20 20 20>; + }; + b1 { + channels = <100 181>; + ofdm = <14 14 14 14 14 14 14 14>; + mcs = <4 14 14 14 14 14 14 14 14 14 14>; + txs-delta = <12 9 6>; + ru = <7 14 14 14 14 14 14 14 14 14 14 14 14>; + }; + }; + }; + }; }; }; From patchwork Mon Apr 5 12:40:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 416161 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=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 2EF00C433B4 for ; Mon, 5 Apr 2021 12:40:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 02315613A3 for ; Mon, 5 Apr 2021 12:40:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235289AbhDEMk4 (ORCPT ); Mon, 5 Apr 2021 08:40:56 -0400 Received: from mail.kernel.org ([198.145.29.99]:43772 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235571AbhDEMk4 (ORCPT ); Mon, 5 Apr 2021 08:40:56 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 032E1613A7; Mon, 5 Apr 2021 12:40:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617626450; bh=GqofjK0Whl49RK+n+VLDvEPqIE7RJZKnzgjMq1o+l4s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VFlwnGczs2zX/gAT+vj7dJyxFCNbUx6L4vREZ+OlIiJyx6XS4j7Fpvr3tuuhl14bb 2svcDyOJSCsC/XwFRpV01ofexw65FPcmeQTq3ZAWbBApocwInZzhrAEuoGch2WtyVu mnhsa34MXMHl2vnNv2c3T/d8YkRSU4wi4bWkM3d22fMX6nhMXv+8UU0riIx7OUBheq 9KIEmPcPBqhSramo8BcfxPrmWS3qAlspGXuxtxORUzBXsPqEkoH4qZiveSrXsMFJN4 dkPePrrIy2YlX2QYeNwECyV4Jrbv3Hr4n8qTp97oPrOPPLk/i/GIJ4No86OXgwSJjU hK3RoSfc4JYAg== From: Lorenzo Bianconi To: nbd@nbd.name Cc: linux-wireless@vger.kernel.org, lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, ryder.lee@mediatek.com, shayne.chen@mediatek.com, devicetree@vger.kernel.org, robh@kernel.org Subject: [PATCH 3/8] mt76: add functions for parsing rate power limits from DT Date: Mon, 5 Apr 2021 14:40:27 +0200 Message-Id: X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Felix Fietkau This subnode can be used to set per-rate tx power limits either per country code / regdomain or globally. These limits are typically provided by the device manufacturers and are used to limit sideband emissions and stay within regulatory limits Signed-off-by: Felix Fietkau Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/eeprom.c | 203 ++++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt76.h | 12 ++ 2 files changed, 215 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c index 665b54c5c8ae..9e2f4a11493b 100644 --- a/drivers/net/wireless/mediatek/mt76/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c @@ -111,6 +111,209 @@ mt76_eeprom_override(struct mt76_phy *phy) } EXPORT_SYMBOL_GPL(mt76_eeprom_override); +static bool mt76_string_prop_find(struct property *prop, const char *str) +{ + const char *cp = NULL; + + if (!prop || !str || !str[0]) + return false; + + while ((cp = of_prop_next_string(prop, cp)) != NULL) + if (!strcasecmp(cp, str)) + return true; + + return false; +} + +static struct device_node * +mt76_find_power_limits_node(struct mt76_dev *dev) +{ + struct device_node *np = dev->dev->of_node; + const char *const region_names[] = { + [NL80211_DFS_ETSI] = "etsi", + [NL80211_DFS_FCC] = "fcc", + [NL80211_DFS_JP] = "jp", + }; + struct device_node *cur, *fallback = NULL; + const char *region_name = NULL; + + if (dev->region < ARRAY_SIZE(region_names)) + region_name = region_names[dev->region]; + + np = of_get_child_by_name(np, "power-limits"); + if (!np) + return NULL; + + for_each_child_of_node(np, cur) { + struct property *country = of_find_property(cur, "country", NULL); + struct property *regd = of_find_property(cur, "regdomain", NULL); + + if (!country && !regd) { + fallback = cur; + continue; + } + + if (mt76_string_prop_find(country, dev->alpha2) || + mt76_string_prop_find(regd, region_name)) + return cur; + } + + return fallback; +} + +static const __be32 * +mt76_get_of_array(struct device_node *np, char *name, size_t *len, int min) +{ + struct property *prop = of_find_property(np, name, NULL); + + if (!prop || !prop->value || prop->length < min * 4) + return NULL; + + *len = prop->length; + + return prop->value; +} + +static struct device_node * +mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan) +{ + struct device_node *cur; + const __be32 *val; + size_t len; + + for_each_child_of_node(np, cur) { + val = mt76_get_of_array(cur, "channels", &len, 2); + if (!val) + continue; + + while (len >= 2 * sizeof(*val)) { + if (chan->hw_value >= be32_to_cpu(val[0]) && + chan->hw_value <= be32_to_cpu(val[1])) + return cur; + + val += 2; + len -= 2 * sizeof(*val); + } + } + + return NULL; +} + +static s8 +mt76_get_txs_delta(struct device_node *np, u8 nss) +{ + const __be32 *val; + size_t len; + + val = mt76_get_of_array(np, "txs-delta", &len, nss); + if (!val) + return 0; + + return be32_to_cpu(val[nss - 1]); +} + +static void +mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data, + s8 target_power, s8 nss_delta, s8 *max_power) +{ + int i; + + if (!data) + return; + + for (i = 0; i < pwr_len; i++) { + pwr[i] = min_t(s8, target_power, + be32_to_cpu(data[i]) + nss_delta); + *max_power = max(*max_power, pwr[i]); + } +} + +s8 mt76_get_rate_power_limits(struct mt76_phy *phy, + struct ieee80211_channel *chan, + struct mt76_power_limits *dest, + s8 target_power) +{ + struct mt76_dev *dev = phy->dev; + struct device_node *np; + const __be32 *val; + char name[16]; + u32 mcs_rates = dev->drv->mcs_rates; + char band; + size_t len; + int i, cur; + s8 max_power = 0; + s8 txs_delta; + + if (!mcs_rates) + mcs_rates = 10; + + memset(dest, target_power, sizeof(*dest)); + + if (!IS_ENABLED(CONFIG_OF)) + return target_power; + + np = mt76_find_power_limits_node(dev); + if (!np) + return target_power; + + switch (chan->band) { + case NL80211_BAND_2GHZ: + band = '2'; + break; + case NL80211_BAND_5GHZ: + band = '5'; + break; + default: + return target_power; + } + + snprintf(name, sizeof(name), "txpower-%cg", band); + np = of_get_child_by_name(np, name); + if (!np) + return target_power; + + np = mt76_find_channel_node(np, chan); + if (!np) + return target_power; + + txs_delta = mt76_get_txs_delta(np, hweight8(phy->antenna_mask)); + + val = mt76_get_of_array(np, "cck", &len, ARRAY_SIZE(dest->cck)); + mt76_apply_array_limit(dest->cck, ARRAY_SIZE(dest->cck), val, + target_power, txs_delta, &max_power); + + val = mt76_get_of_array(np, "ofdm", &len, ARRAY_SIZE(dest->ofdm)); + mt76_apply_array_limit(dest->ofdm, ARRAY_SIZE(dest->ofdm), val, + target_power, txs_delta, &max_power); + + val = mt76_get_of_array(np, "mcs", &len, mcs_rates + 1); + if (!val) + return max_power; + + len /= 4; + cur = be32_to_cpu(val[0]); + for (i = 0; i < ARRAY_SIZE(dest->mcs); i++) { + if (len < mcs_rates + 1) + break; + + mt76_apply_array_limit(dest->mcs[i], ARRAY_SIZE(dest->mcs[i]), + val + 1, target_power, txs_delta, + &max_power); + if (--cur > 0) + continue; + + val += mcs_rates + 1; + len -= mcs_rates + 1; + if (!len) + break; + + cur = be32_to_cpu(val[0]); + } + + return max_power; +} +EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits); + int mt76_eeprom_init(struct mt76_dev *dev, int len) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index b09b0f5ffd6d..0d2eeb37129c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -331,6 +331,7 @@ struct mt76_driver_ops { u32 drv_flags; u32 survey_flags; u16 txwi_size; + u8 mcs_rates; void (*update_survey)(struct mt76_dev *dev); @@ -710,6 +711,12 @@ struct mt76_dev { }; }; +struct mt76_power_limits { + s8 cck[4]; + s8 ofdm[8]; + s8 mcs[4][10]; +}; + enum mt76_phy_type { MT_PHY_TYPE_CCK, MT_PHY_TYPE_OFDM, @@ -1193,4 +1200,9 @@ mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set); +s8 mt76_get_rate_power_limits(struct mt76_phy *phy, + struct ieee80211_channel *chan, + struct mt76_power_limits *dest, + s8 target_power); + #endif From patchwork Mon Apr 5 12:40:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 415435 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=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 8FA11C433B4 for ; Mon, 5 Apr 2021 12:40:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4F9BA613A7 for ; Mon, 5 Apr 2021 12:40:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235317AbhDEMk7 (ORCPT ); Mon, 5 Apr 2021 08:40:59 -0400 Received: from mail.kernel.org ([198.145.29.99]:43814 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235571AbhDEMk7 (ORCPT ); Mon, 5 Apr 2021 08:40:59 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 86D666138A; Mon, 5 Apr 2021 12:40:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617626453; bh=A1AV/GITF4BxzEDJLzlJcRYg3vsn0gWnsgCgm5qngMU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c8Zfl3yF7a429f6JEanmIrZOaRTuwtFhbXKhvrFiyQVZNtnXpBJQnisVJ1NnJOUdx 1HTqQSF21J6PIr3ke0rxEsbBtmJQPvZ91oVsexwmNuQXOkKLSnH/OUNupdJOrk/4dF +oh2YDCZw3cYHAIO/1EHxeZvc6XhG3NkHcnYGFVfzEJS1laDMuqpJdv2eaq/yB5CMg 4ZmV4Isxy5s5ClFZ6J0WpY9B963eaY0auc58N/aBBweliPXbjvzpwrhmgTxDP622vQ h48WWqeNi4huLCwkd2FpS8Hj0QW3r39fl1z5o6LwgnXFljnQM/3y2VxzwbE7Tg5jQk DNk/cWQfpjbpA== From: Lorenzo Bianconi To: nbd@nbd.name Cc: linux-wireless@vger.kernel.org, lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, ryder.lee@mediatek.com, shayne.chen@mediatek.com, devicetree@vger.kernel.org, robh@kernel.org Subject: [PATCH 4/8] mt76: extend DT rate power limits to support 11ax devices Date: Mon, 5 Apr 2021 14:40:28 +0200 Message-Id: <0452c805cd1108a3f32780f31b1d028d78991ded.1617625912.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Shayne Chen Enable parsing per-rate txpower limits from DT for 11ax chipsets. Co-developed-by: Felix Fietkau Signed-off-by: Felix Fietkau Tested-by: Evelyn Tsai Signed-off-by: Shayne Chen Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/eeprom.c | 62 +++++++++++++-------- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c index 9e2f4a11493b..65813f19e2ee 100644 --- a/drivers/net/wireless/mediatek/mt76/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c @@ -228,6 +228,36 @@ mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data, } } +static void +mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num, + const __be32 *data, size_t len, s8 target_power, + s8 nss_delta, s8 *max_power) +{ + int i, cur; + + if (!data) + return; + + len /= 4; + cur = be32_to_cpu(data[0]); + for (i = 0; i < pwr_num; i++) { + if (len < pwr_len + 1) + break; + + mt76_apply_array_limit(pwr + pwr_len * i, pwr_len, data + 1, + target_power, nss_delta, max_power); + if (--cur > 0) + continue; + + data += pwr_len + 1; + len -= pwr_len + 1; + if (!len) + break; + + cur = be32_to_cpu(data[0]); + } +} + s8 mt76_get_rate_power_limits(struct mt76_phy *phy, struct ieee80211_channel *chan, struct mt76_power_limits *dest, @@ -238,9 +268,9 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy, const __be32 *val; char name[16]; u32 mcs_rates = dev->drv->mcs_rates; + u32 ru_rates = ARRAY_SIZE(dest->ru[0]); char band; size_t len; - int i, cur; s8 max_power = 0; s8 txs_delta; @@ -287,28 +317,14 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy, target_power, txs_delta, &max_power); val = mt76_get_of_array(np, "mcs", &len, mcs_rates + 1); - if (!val) - return max_power; - - len /= 4; - cur = be32_to_cpu(val[0]); - for (i = 0; i < ARRAY_SIZE(dest->mcs); i++) { - if (len < mcs_rates + 1) - break; - - mt76_apply_array_limit(dest->mcs[i], ARRAY_SIZE(dest->mcs[i]), - val + 1, target_power, txs_delta, - &max_power); - if (--cur > 0) - continue; - - val += mcs_rates + 1; - len -= mcs_rates + 1; - if (!len) - break; - - cur = be32_to_cpu(val[0]); - } + mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]), + ARRAY_SIZE(dest->mcs), val, len, + target_power, txs_delta, &max_power); + + val = mt76_get_of_array(np, "ru", &len, ru_rates + 1); + mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]), + ARRAY_SIZE(dest->ru), val, len, + target_power, txs_delta, &max_power); return max_power; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 0d2eeb37129c..2cfe5584f33f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -715,6 +715,7 @@ struct mt76_power_limits { s8 cck[4]; s8 ofdm[8]; s8 mcs[4][10]; + s8 ru[7][12]; }; enum mt76_phy_type { From patchwork Mon Apr 5 12:40:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 416160 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=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 4C121C43460 for ; Mon, 5 Apr 2021 12:40:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 275D5613A9 for ; Mon, 5 Apr 2021 12:40:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235602AbhDEMlC (ORCPT ); Mon, 5 Apr 2021 08:41:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:43846 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235591AbhDEMlB (ORCPT ); Mon, 5 Apr 2021 08:41:01 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 0D105613A3; Mon, 5 Apr 2021 12:40:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617626455; bh=ELOFEaMfEAUn7FroifoxbdxJDwFpaQk13xCF3MVQb2A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Gijkrm6Tvzg3Rj961IfrvYE4HvBOxiTJPIZk5I63OeGYvzE37TbSCCMZ235v6Ex4B A2Di22tthz8NdydWd1JcSyXWrGc3ytlBbmwbRPskEtExgMETYpqMyz1GguxIzFHAEX Ftn7IRf2RZkayH7lhpmoKBY52iOariE/Pk8Z6M4t63nwC6YGt8dDdlFG/ozjJ1jhw1 3Ca1nhqJgBK8xwBzRpvcXbP0vY1moOuAWo0HvUIwOfK2k9I19p6+HHQQQXGFBAeNPp 7sxhDB9PHPqF21U3VluALw7ui9fjjhhHossIAvBxf3hXH4TYq8UKyN4rStef0mp3/R HFNyBrHQD3K3A== From: Lorenzo Bianconi To: nbd@nbd.name Cc: linux-wireless@vger.kernel.org, lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, ryder.lee@mediatek.com, shayne.chen@mediatek.com, devicetree@vger.kernel.org, robh@kernel.org Subject: [PATCH 5/8] mt76: mt7615: implement support for using DT rate power limits Date: Mon, 5 Apr 2021 14:40:29 +0200 Message-Id: X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Felix Fietkau Limits are used to update the channel max_power settings and also passed to the firmware on channel changes Signed-off-by: Felix Fietkau Signed-off-by: Lorenzo Bianconi --- .../net/wireless/mediatek/mt76/mt7615/init.c | 10 ++- .../net/wireless/mediatek/mt76/mt7615/mcu.c | 61 ++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c index 857fb4918975..e23898365166 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c @@ -252,6 +252,7 @@ void mt7615_init_txpower(struct mt7615_dev *dev, int delta_idx, delta = mt76_tx_power_nss_delta(n_chains); u8 *eep = (u8 *)dev->mt76.eeprom.data; enum nl80211_band band = sband->band; + struct mt76_power_limits limits; u8 rate_val; delta_idx = mt7615_eeprom_get_power_delta_index(dev, band); @@ -280,7 +281,11 @@ void mt7615_init_txpower(struct mt7615_dev *dev, target_power = max(target_power, eep[index]); } - target_power = DIV_ROUND_UP(target_power + delta, 2); + target_power = mt76_get_rate_power_limits(&dev->mphy, chan, + &limits, + target_power); + target_power += delta; + target_power = DIV_ROUND_UP(target_power, 2); chan->max_power = min_t(int, chan->max_reg_power, target_power); chan->orig_mpwr = target_power; @@ -311,6 +316,9 @@ mt7615_regd_notifier(struct wiphy *wiphy, memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2)); dev->mt76.region = request->dfs_region; + mt7615_init_txpower(dev, &mphy->sband_2g.sband); + mt7615_init_txpower(dev, &mphy->sband_5g.sband); + mt7615_mutex_acquire(dev); if (chandef->chan->flags & IEEE80211_CHAN_RADAR) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index 600c5366c099..7ca7d239b53d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -2127,16 +2127,75 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku) { struct mt76_phy *mphy = phy->mt76; struct ieee80211_hw *hw = mphy->hw; + struct mt76_power_limits limits; + s8 *limits_array = (s8 *)&limits; int n_chains = hweight8(mphy->antenna_mask); int tx_power; int i; + static const u8 sku_mapping[] = { +#define SKU_FIELD(_type, _field) \ + [MT_SKU_##_type] = offsetof(struct mt76_power_limits, _field) + SKU_FIELD(CCK_1_2, cck[0]), + SKU_FIELD(CCK_55_11, cck[2]), + SKU_FIELD(OFDM_6_9, ofdm[0]), + SKU_FIELD(OFDM_12_18, ofdm[2]), + SKU_FIELD(OFDM_24_36, ofdm[4]), + SKU_FIELD(OFDM_48, ofdm[6]), + SKU_FIELD(OFDM_54, ofdm[7]), + SKU_FIELD(HT20_0_8, mcs[0][0]), + SKU_FIELD(HT20_32, ofdm[0]), + SKU_FIELD(HT20_1_2_9_10, mcs[0][1]), + SKU_FIELD(HT20_3_4_11_12, mcs[0][3]), + SKU_FIELD(HT20_5_13, mcs[0][5]), + SKU_FIELD(HT20_6_14, mcs[0][6]), + SKU_FIELD(HT20_7_15, mcs[0][7]), + SKU_FIELD(HT40_0_8, mcs[1][0]), + SKU_FIELD(HT40_32, ofdm[0]), + SKU_FIELD(HT40_1_2_9_10, mcs[1][1]), + SKU_FIELD(HT40_3_4_11_12, mcs[1][3]), + SKU_FIELD(HT40_5_13, mcs[1][5]), + SKU_FIELD(HT40_6_14, mcs[1][6]), + SKU_FIELD(HT40_7_15, mcs[1][7]), + SKU_FIELD(VHT20_0, mcs[0][0]), + SKU_FIELD(VHT20_1_2, mcs[0][1]), + SKU_FIELD(VHT20_3_4, mcs[0][3]), + SKU_FIELD(VHT20_5_6, mcs[0][5]), + SKU_FIELD(VHT20_7, mcs[0][7]), + SKU_FIELD(VHT20_8, mcs[0][8]), + SKU_FIELD(VHT20_9, mcs[0][9]), + SKU_FIELD(VHT40_0, mcs[1][0]), + SKU_FIELD(VHT40_1_2, mcs[1][1]), + SKU_FIELD(VHT40_3_4, mcs[1][3]), + SKU_FIELD(VHT40_5_6, mcs[1][5]), + SKU_FIELD(VHT40_7, mcs[1][7]), + SKU_FIELD(VHT40_8, mcs[1][8]), + SKU_FIELD(VHT40_9, mcs[1][9]), + SKU_FIELD(VHT80_0, mcs[2][0]), + SKU_FIELD(VHT80_1_2, mcs[2][1]), + SKU_FIELD(VHT80_3_4, mcs[2][3]), + SKU_FIELD(VHT80_5_6, mcs[2][5]), + SKU_FIELD(VHT80_7, mcs[2][7]), + SKU_FIELD(VHT80_8, mcs[2][8]), + SKU_FIELD(VHT80_9, mcs[2][9]), + SKU_FIELD(VHT160_0, mcs[3][0]), + SKU_FIELD(VHT160_1_2, mcs[3][1]), + SKU_FIELD(VHT160_3_4, mcs[3][3]), + SKU_FIELD(VHT160_5_6, mcs[3][5]), + SKU_FIELD(VHT160_7, mcs[3][7]), + SKU_FIELD(VHT160_8, mcs[3][8]), + SKU_FIELD(VHT160_9, mcs[3][9]), +#undef SKU_FIELD + }; tx_power = hw->conf.power_level * 2 - mt76_tx_power_nss_delta(n_chains); + + tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan, + &limits, tx_power); mphy->txpower_cur = tx_power; for (i = 0; i < MT_SKU_1SS_DELTA; i++) - sku[i] = tx_power; + sku[i] = limits_array[sku_mapping[i]]; for (i = 0; i < 4; i++) { int delta = 0; From patchwork Mon Apr 5 12:40:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 415434 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=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 F202CC433ED for ; Mon, 5 Apr 2021 12:41:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C629A613AF for ; Mon, 5 Apr 2021 12:40:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235621AbhDEMlE (ORCPT ); Mon, 5 Apr 2021 08:41:04 -0400 Received: from mail.kernel.org ([198.145.29.99]:43882 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235591AbhDEMlE (ORCPT ); Mon, 5 Apr 2021 08:41:04 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 90B4C6138A; Mon, 5 Apr 2021 12:40:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617626458; bh=TmNJI++LcbfC5qLEvfmyL6EFaNTAGjCF3JiB5uUpYW4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R4wn7aB4CowjbkH5AH8NXP/Y152Sfsw//hQhEUlAMXes1j3plgyv0EoumSVs0dbo+ zDVNm8QM8AyFmK9Gdp9sYwJcoSerPO0X6xonFSWP0Di7qXD6EtZ9fdzfMO0aoKneM4 QtIST4igP1uB0ftQecuw7eP2zZD2gbdzCPj60joN7WAqfcKPDwp4JrUt55xvaqdu7k srjsQ1q8ECGBwYWR1jWTcl80RyG20zaYU6DBS/TiTxzbfbrDWDVbO1hTDa9NbKb1BN oQ4g3LeX/7pR7ZFY9F45uWeSb4UbIIPK6qlsS37UvTSwb5/RXGiAuQS9oY8o1yc5Vf WJf5Dp8uITsrg== From: Lorenzo Bianconi To: nbd@nbd.name Cc: linux-wireless@vger.kernel.org, lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, ryder.lee@mediatek.com, shayne.chen@mediatek.com, devicetree@vger.kernel.org, robh@kernel.org Subject: [PATCH 6/8] mt76: mt7615: do not use mt7615 single-sku values for mt7663 Date: Mon, 5 Apr 2021 14:40:30 +0200 Message-Id: <068ed97fb7c7e51b13aefc9be4127e9b2f831904.1617625912.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org mt7663 mcu relies on different APIs to configure APIs per-rate power limit respect to mt7615 driver. Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index 7ca7d239b53d..19b408b6badb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -2194,6 +2194,11 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku) &limits, tx_power); mphy->txpower_cur = tx_power; + if (is_mt7663(mphy->dev)) { + memset(sku, tx_power, MT_SKU_4SS_DELTA + 1); + return; + } + for (i = 0; i < MT_SKU_1SS_DELTA; i++) sku[i] = limits_array[sku_mapping[i]]; From patchwork Mon Apr 5 12:40:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 416159 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=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 386B8C43470 for ; Mon, 5 Apr 2021 12:41:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1ACE2613B0 for ; Mon, 5 Apr 2021 12:41:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237144AbhDEMlH (ORCPT ); Mon, 5 Apr 2021 08:41:07 -0400 Received: from mail.kernel.org ([198.145.29.99]:43946 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235651AbhDEMlG (ORCPT ); Mon, 5 Apr 2021 08:41:06 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 25F45613AE; Mon, 5 Apr 2021 12:40:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617626460; bh=W2IE4GWQzLdua4ARXu8YKmoXlLeDRkRYWKPi6Mw4fmw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bGz1PL7+OmxxGya4hXH+GtpvQV8mABCkuMy1xy8ihSnXuwj/PBq97Chm/7MML4qFr 0kCQPABVFAY1hX4GHVVLQptdfYd7ewRyQbw2MBlFEm0jom2MadwNfM8Q3CyoKziI/m hSBzhznpfexQcVxdYxLlEO8OiCb0X/wxk5CXs+uMGVpgIaaqdbH+RMWXbcbSc9JP+n AJyLTpP8gdJYgk3n+eNKO3qQoMCKn7nNxGp9vcVir37X4Gyn+AfPyXzY96gJ4D/ekl 87JCHHWk9OtRENBDDKgonlQlrnJEv04mXjwP9ZJrLL7c4GhCdiPMkuSY5pJ5sRY2qt VoheYrRw8cNkg== From: Lorenzo Bianconi To: nbd@nbd.name Cc: linux-wireless@vger.kernel.org, lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, ryder.lee@mediatek.com, shayne.chen@mediatek.com, devicetree@vger.kernel.org, robh@kernel.org Subject: [PATCH 7/8] mt76: introduce single-sku support for mt7663/mt7921 Date: Mon, 5 Apr 2021 14:40:31 +0200 Message-Id: <879de5b9f2cb391b55deeae443543a79055e34c9.1617625912.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Introduce support for rate-txpower compensation for mt7663/mt7921 chipsets. Rate-txpower limit is specified through dts Signed-off-by: Lorenzo Bianconi --- .../net/wireless/mediatek/mt76/mt7615/init.c | 5 +- .../net/wireless/mediatek/mt76/mt7615/main.c | 4 + .../wireless/mediatek/mt76/mt76_connac_mcu.c | 133 ++++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac_mcu.h | 23 +++ .../net/wireless/mediatek/mt76/mt7921/init.c | 2 + .../net/wireless/mediatek/mt76/mt7921/main.c | 4 + 6 files changed, 170 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c index e23898365166..d2eb8e9fb7f1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c @@ -323,8 +323,11 @@ mt7615_regd_notifier(struct wiphy *wiphy, if (chandef->chan->flags & IEEE80211_CHAN_RADAR) mt7615_dfs_init_radar_detector(phy); - if (mt7615_firmware_offload(phy->dev)) + + if (mt7615_firmware_offload(phy->dev)) { mt76_connac_mcu_set_channel_domain(mphy); + mt76_connac_mcu_set_rate_txpower(mphy); + } mt7615_mutex_release(dev); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index e30b256784e0..62d9df47a1f6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -66,6 +66,10 @@ static int mt7615_start(struct ieee80211_hw *hw) ret = mt76_connac_mcu_set_channel_domain(phy->mt76); if (ret) goto out; + + ret = mt76_connac_mcu_set_rate_txpower(phy->mt76); + if (ret) + goto out; } ret = mt7615_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH); diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c index bafe95210807..2b62d2a0fd67 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -1560,6 +1560,139 @@ void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb, } EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event); +static void +mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku, + struct mt76_power_limits *limits, + enum nl80211_band band) +{ + int max_power = is_mt7921(dev) ? 127 : 63; + int i, offset = sizeof(limits->cck); + + memset(sku, max_power, MT_SKU_POWER_LIMIT); + + if (band == NL80211_BAND_2GHZ) { + /* cck */ + memcpy(sku, limits->cck, sizeof(limits->cck)); + } + + /* ofdm */ + memcpy(&sku[offset], limits->ofdm, sizeof(limits->ofdm)); + offset += sizeof(limits->ofdm); + + /* ht */ + for (i = 0; i < 2; i++) { + memcpy(&sku[offset], limits->mcs[i], 8); + offset += 8; + } + sku[offset++] = limits->mcs[0][0]; + + /* vht */ + for (i = 0; i < ARRAY_SIZE(limits->mcs); i++) { + memcpy(&sku[offset], limits->mcs[i], + ARRAY_SIZE(limits->mcs[i])); + offset += 12; + } + + if (!is_mt7921(dev)) + return; + + /* he */ + for (i = 0; i < ARRAY_SIZE(limits->ru); i++) { + memcpy(&sku[offset], limits->ru[i], ARRAY_SIZE(limits->ru[i])); + offset += ARRAY_SIZE(limits->ru[i]); + } +} + +static int +mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy, + enum nl80211_band band) +{ + struct mt76_dev *dev = phy->dev; + int sku_len, batch_len = is_mt7921(dev) ? 8 : 16; + static const u8 chan_list_2ghz[] = { + 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14 + }; + static const u8 chan_list_5ghz[] = { + 36, 38, 40, 42, 44, 46, 48, + 50, 52, 54, 56, 58, 60, 62, + 64, 100, 102, 104, 106, 108, 110, + 112, 114, 116, 118, 120, 122, 124, + 126, 128, 132, 134, 136, 138, 140, + 142, 144, 149, 151, 153, 155, 157, + 159, 161, 165 + }; + struct mt76_connac_sku_tlv sku_tlbv; + int i, n_chan, batch_size, idx = 0; + struct mt76_power_limits limits; + const u8 *ch_list; + + sku_len = is_mt7921(dev) ? sizeof(sku_tlbv) : sizeof(sku_tlbv) - 92; + + if (band == NL80211_BAND_2GHZ) { + n_chan = ARRAY_SIZE(chan_list_2ghz); + ch_list = chan_list_2ghz; + } else { + n_chan = ARRAY_SIZE(chan_list_5ghz); + ch_list = chan_list_5ghz; + } + batch_size = DIV_ROUND_UP(n_chan, batch_len); + + for (i = 0; i < batch_size; i++) { + bool last_msg = i == batch_size - 1; + int num_ch = last_msg ? n_chan % batch_len : batch_len; + struct mt76_connac_tx_power_limit_tlv tx_power_tlv = { + .band = band == NL80211_BAND_2GHZ ? 1 : 2, + .n_chan = num_ch, + .last_msg = last_msg, + }; + struct sk_buff *skb; + int j, err, msg_len; + + msg_len = sizeof(tx_power_tlv) + num_ch * sizeof(sku_tlbv); + skb = mt76_mcu_msg_alloc(dev, NULL, msg_len); + if (!skb) + return -ENOMEM; + + BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(tx_power_tlv.alpha2)); + memcpy(tx_power_tlv.alpha2, dev->alpha2, sizeof(dev->alpha2)); + + skb_put_data(skb, &tx_power_tlv, sizeof(tx_power_tlv)); + for (j = 0; j < num_ch; j++, idx++) { + struct ieee80211_channel chan = { + .hw_value = ch_list[idx], + .band = band, + }; + + mt76_get_rate_power_limits(phy, &chan, &limits, 127); + + sku_tlbv.channel = ch_list[idx]; + mt76_connac_mcu_build_sku(dev, sku_tlbv.pwr_limit, + &limits, band); + skb_put_data(skb, &sku_tlbv, sku_len); + } + + err = mt76_mcu_skb_send_msg(dev, skb, + MCU_CMD_SET_RATE_TX_POWER, false); + if (err < 0) + return err; + } + + return 0; +} + +int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy) +{ + int err; + + err = mt76_connac_mcu_rate_txpower_band(phy, NL80211_BAND_2GHZ); + if (err < 0) + return err; + + return mt76_connac_mcu_rate_txpower_band(phy, NL80211_BAND_5GHZ); +} +EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower); + #ifdef CONFIG_PM const struct wiphy_wowlan_support mt76_connac_wowlan_support = { diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h index 5a3efd744546..c397adb817f2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -892,6 +892,28 @@ struct mt76_sta_cmd_info { u8 rcpi; }; +#define MT_SKU_POWER_LIMIT 161 + +struct mt76_connac_sku_tlv { + u8 channel; + s8 pwr_limit[MT_SKU_POWER_LIMIT]; +} __packed; + +struct mt76_connac_tx_power_limit_tlv { + /* DW0 - common info*/ + u8 ver; + u8 pad0; + __le16 len; + /* DW1 - cmd hint */ + u8 n_chan; /* # channel */ + u8 band; /* 2.4GHz - 5GHz */ + u8 last_msg; + u8 pad1; + /* DW3 */ + u8 alpha2[4]; /* regulatory_request.alpha2 */ + u8 pad2[32]; +} __packed; + #define to_wcid_lo(id) FIELD_GET(GENMASK(7, 0), (u16)id) #define to_wcid_hi(id) FIELD_GET(GENMASK(9, 8), (u16)id) @@ -994,4 +1016,5 @@ void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac, int mt76_connac_mcu_chip_config(struct mt76_dev *dev); void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb, struct mt76_connac_coredump *coredump); +int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy); #endif /* __MT76_CONNAC_MCU_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index 262c9d150bf0..82ef6c6c6cd2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -58,12 +58,14 @@ mt7921_regd_notifier(struct wiphy *wiphy, { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt7921_phy *phy = mt7921_hw_phy(hw); memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2)); dev->mt76.region = request->dfs_region; mt7921_mutex_acquire(dev); mt76_connac_mcu_set_channel_domain(hw->priv); + mt76_connac_mcu_set_rate_txpower(phy->mt76); mt7921_mutex_release(dev); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 06a47cab494e..be7e314023bd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -186,6 +186,10 @@ int __mt7921_start(struct mt7921_phy *phy) if (err) return err; + err = mt76_connac_mcu_set_rate_txpower(phy->mt76); + if (err) + return err; + mt7921_mac_reset_counters(phy); set_bit(MT76_STATE_RUNNING, &mphy->state); From patchwork Mon Apr 5 12:40:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 415433 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=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 E63EAC433ED for ; Mon, 5 Apr 2021 12:41:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B244E613A3 for ; Mon, 5 Apr 2021 12:41:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235591AbhDEMlK (ORCPT ); Mon, 5 Apr 2021 08:41:10 -0400 Received: from mail.kernel.org ([198.145.29.99]:43988 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235651AbhDEMlJ (ORCPT ); Mon, 5 Apr 2021 08:41:09 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9362C613A9; Mon, 5 Apr 2021 12:41:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617626463; bh=sAzbDRGBF0P9UO61PnCIiMh4UYURzBH4AHMv2rDgbys=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UmoYZ9rWWZPL4eQuMQ6YNji1FJ2AxJv6x/VVYAN49zB9Z/4bLSP+m8FE4pFHJJ2mW 8YdMv8MFdaLSTR+MBeB/THJgudMDLx58vrhK6RojJtuqR8F9pOVgfkYU95G3n+F4Op aksxGWaI5zeZPX0rva52zwBBa2ehwSVUeFPfwVazahnHV1jLHm9drtPAO/Mewwlpl/ wWUkb6JGI2s0OlMAsVzwFw3v69XlQ9xNCKrJelD/vomFEGIscK1pw9yqqxZpp2GqB5 zVakfQ/nwza/smJA5RBjkhUjAfb61KKGZAqmsQQ32ndfC49El/TMfK4EXD+f/W3Ygn vZXXrhgFVQ/YQ== From: Lorenzo Bianconi To: nbd@nbd.name Cc: linux-wireless@vger.kernel.org, lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, ryder.lee@mediatek.com, shayne.chen@mediatek.com, devicetree@vger.kernel.org, robh@kernel.org Subject: [PATCH 8/8] mt76: mt7921: add dumping Tx power table Date: Mon, 5 Apr 2021 14:40:32 +0200 Message-Id: <7046f040d5ba6410820b12e2ef9a6e8d514d6d7e.1617625912.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Sean Wang Dump the tx power table saved in offload firmware. Signed-off-by: Sean Wang Signed-off-by: Lorenzo Bianconi --- .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 + .../wireless/mediatek/mt76/mt7921/debugfs.c | 79 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7921/mcu.c | 23 ++++++ .../net/wireless/mediatek/mt76/mt7921/mcu.h | 17 ++++ .../wireless/mediatek/mt76/mt7921/mt7921.h | 31 ++++++++ 5 files changed, 151 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h index c397adb817f2..11bee1972534 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -561,6 +561,7 @@ enum { MCU_CMD_CHIP_CONFIG = MCU_CE_PREFIX | 0xca, MCU_CMD_FWLOG_2_HOST = MCU_CE_PREFIX | 0xc5, MCU_CMD_GET_WTBL = MCU_CE_PREFIX | 0xcd, + MCU_CMD_GET_TXPWR = MCU_CE_PREFIX | 0xd0, }; enum { diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c index b2e8d698e019..024524173115 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c @@ -158,6 +158,83 @@ mt7921_queues_read(struct seq_file *s, void *data) return 0; } +static void +mt7921_seq_puts_array(struct seq_file *file, const char *str, + s8 *val, int len) +{ + int i; + + seq_printf(file, "%-16s:", str); + for (i = 0; i < len; i++) + if (val[i] == 127) + seq_printf(file, " %6s", "N.A"); + else + seq_printf(file, " %6d", val[i]); + seq_puts(file, "\n"); +} + +#define mt7921_print_txpwr_entry(prefix, rate) \ +({ \ + mt7921_seq_puts_array(s, #prefix " (user)", \ + txpwr.data[TXPWR_USER].rate, \ + ARRAY_SIZE(txpwr.data[TXPWR_USER].rate)); \ + mt7921_seq_puts_array(s, #prefix " (eeprom)", \ + txpwr.data[TXPWR_EEPROM].rate, \ + ARRAY_SIZE(txpwr.data[TXPWR_EEPROM].rate)); \ + mt7921_seq_puts_array(s, #prefix " (tmac)", \ + txpwr.data[TXPWR_MAC].rate, \ + ARRAY_SIZE(txpwr.data[TXPWR_MAC].rate)); \ +}) + +static int +mt7921_txpwr(struct seq_file *s, void *data) +{ + struct mt7921_dev *dev = dev_get_drvdata(s->private); + struct mt7921_txpwr txpwr; + int ret; + + ret = mt7921_get_txpwr_info(dev, &txpwr); + if (ret) + return ret; + + seq_printf(s, "Tx power table (channel %d)\n", txpwr.ch); + seq_printf(s, "%-16s %6s %6s %6s %6s\n", + " ", "1m", "2m", "5m", "11m"); + mt7921_print_txpwr_entry(CCK, cck); + + seq_printf(s, "%-16s %6s %6s %6s %6s %6s %6s %6s %6s\n", + " ", "6m", "9m", "12m", "18m", "24m", "36m", + "48m", "54m"); + mt7921_print_txpwr_entry(OFDM, ofdm); + + seq_printf(s, "%-16s %6s %6s %6s %6s %6s %6s %6s %6s\n", + " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5", + "mcs6", "mcs7"); + mt7921_print_txpwr_entry(HT20, ht20); + + seq_printf(s, "%-16s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n", + " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5", + "mcs6", "mcs7", "mcs32"); + mt7921_print_txpwr_entry(HT40, ht40); + + seq_printf(s, "%-16s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n", + " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5", + "mcs6", "mcs7", "mcs8", "mcs9", "mcs10", "mcs11"); + mt7921_print_txpwr_entry(VHT20, vht20); + mt7921_print_txpwr_entry(VHT40, vht40); + mt7921_print_txpwr_entry(VHT80, vht80); + mt7921_print_txpwr_entry(VHT160, vht160); + mt7921_print_txpwr_entry(HE26, he26); + mt7921_print_txpwr_entry(HE52, he52); + mt7921_print_txpwr_entry(HE106, he106); + mt7921_print_txpwr_entry(HE242, he242); + mt7921_print_txpwr_entry(HE484, he484); + mt7921_print_txpwr_entry(HE996, he996); + mt7921_print_txpwr_entry(HE996x2, he996x2); + + return 0; +} + static int mt7921_pm_set(void *data, u64 val) { @@ -237,6 +314,8 @@ int mt7921_init_debugfs(struct mt7921_dev *dev) mt7921_queues_read); debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir, mt7921_queues_acq); + debugfs_create_devm_seqfile(dev->mt76.dev, "txpower_sku", dir, + mt7921_txpwr); debugfs_create_file("tx_stats", 0400, dir, dev, &fops_tx_stats); debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug); debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 9283f9865ad5..0ae0a22ca966 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -1325,3 +1325,26 @@ mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) mt76_clear(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON); } } + +int mt7921_get_txpwr_info(struct mt7921_dev *dev, struct mt7921_txpwr *txpwr) +{ + struct mt7921_txpwr_event *event; + struct mt7921_txpwr_req req = { + .dbdc_idx = 0, + }; + struct sk_buff *skb; + int ret; + + ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_CMD_GET_TXPWR, + &req, sizeof(req), true, &skb); + if (ret) + return ret; + + event = (struct mt7921_txpwr_event *)skb->data; + WARN_ON(skb->len != le16_to_cpu(event->len)); + memcpy(txpwr, &event->txpwr, sizeof(event->txpwr)); + + dev_kfree_skb(skb); + + return 0; +} diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h index af8b42983a00..d980e92028ba 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h @@ -85,6 +85,7 @@ enum { MCU_EVENT_CH_PRIVILEGE = 0x18, MCU_EVENT_SCHED_SCAN_DONE = 0x23, MCU_EVENT_DBG_MSG = 0x27, + MCU_EVENT_TXPWR = 0xd0, MCU_EVENT_COREDUMP = 0xf0, }; @@ -389,4 +390,20 @@ struct mt7921_mcu_wlan_info { __le32 wlan_idx; struct mt7921_mcu_wlan_info_event event; } __packed; + +struct mt7921_txpwr_req { + u8 ver; + u8 action; + __le16 len; + u8 dbdc_idx; + u8 rsv[3]; +} __packed; + +struct mt7921_txpwr_event { + u8 ver; + u8 action; + __le16 len; + struct mt7921_txpwr txpwr; +} __packed; + #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 5cedefc41416..ad5c5f51ee19 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -172,6 +172,36 @@ struct mt7921_dev { struct mt76_connac_coredump coredump; }; +enum { + TXPWR_USER, + TXPWR_EEPROM, + TXPWR_MAC, + TXPWR_MAX_NUM, +}; + +struct mt7921_txpwr { + u8 ch; + u8 rsv[3]; + struct { + u8 ch; + u8 cck[4]; + u8 ofdm[8]; + u8 ht20[8]; + u8 ht40[9]; + u8 vht20[12]; + u8 vht40[12]; + u8 vht80[12]; + u8 vht160[12]; + u8 he26[12]; + u8 he52[12]; + u8 he106[12]; + u8 he242[12]; + u8 he484[12]; + u8 he996[12]; + u8 he996x2[12]; + } data[TXPWR_MAX_NUM]; +}; + enum { MT_LMAC_AC00, MT_LMAC_AC01, @@ -348,4 +378,5 @@ int mt7921_mac_set_beacon_filter(struct mt7921_phy *phy, bool enable); void mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif); void mt7921_coredump_work(struct work_struct *work); +int mt7921_get_txpwr_info(struct mt7921_dev *dev, struct mt7921_txpwr *txpwr); #endif