public inbox for linux-wireless@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] wifi: mt76: fix backoff fields and max_power calculation
@ 2026-01-27 23:55 Ryder Lee
  2026-02-02  8:14 ` Sven Eckelmann
  0 siblings, 1 reply; 6+ messages in thread
From: Ryder Lee @ 2026-01-27 23:55 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, linux-mediatek, Allen Ye, Ryder Lee

From: Allen Ye <allen.ye@mediatek.com>

The maximum power value may exist in either the data or backoff field.
Previously, backoff power limits were not considered in txpower reporting.
This patch ensures mt76 also considers backoff values in the SKU table.

For connac2 devices,
- paths-ru = RU26, RU52, RU106, BW20, BW40, BW80, BW160
- paths-ru-bf = RU26, RU52, RU106, BW20, BW40, BW80, BW160

Only the first three entries use 1T1S and do not need index adjustment;
the remaining four require index offset.

Fixes: b05ab4be9fd7 ("wifi: mt76: mt7915: add bf backoff limit table support")
Signed-off-by: Allen Ye <allen.ye@mediatek.com>
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
v1:
- Add "wifi:" prefix to the subject.

v2:
- Fix checkpatch errors.
- Remove unnecessary style changes.
- Add explanation for connac2 index adjustment.
---
 drivers/net/wireless/mediatek/mt76/eeprom.c | 180 +++++++++++++-------
 drivers/net/wireless/mediatek/mt76/mt76.h   |   1 -
 2 files changed, 122 insertions(+), 59 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
index 573400d57..6ca0274b4 100644
--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
@@ -9,6 +9,13 @@
 #include <linux/nvmem-consumer.h>
 #include <linux/etherdevice.h>
 #include "mt76.h"
+#include "mt76_connac.h"
+
+enum mt76_sku_type {
+	MT76_SKU_RATE,
+	MT76_SKU_BACKOFF,
+	MT76_SKU_BACKOFF_BF_OFFSET,
+};
 
 static int mt76_get_of_eeprom_data(struct mt76_dev *dev, void *eep, int len)
 {
@@ -292,7 +299,6 @@ mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan)
 }
 EXPORT_SYMBOL_GPL(mt76_find_channel_node);
 
-
 static s8
 mt76_get_txs_delta(struct device_node *np, u8 nss)
 {
@@ -306,9 +312,24 @@ mt76_get_txs_delta(struct device_node *np, u8 nss)
 	return be32_to_cpu(val[nss - 1]);
 }
 
+static inline u8 mt76_backoff_n_chains(struct mt76_dev *dev, u8 idx)
+{
+	/* 0:1T1ss, 1:2T1ss, ..., 14:5T5ss */
+	static const u8 connac3_table[] = {
+		1, 2, 3, 4, 5, 2, 3, 4, 5, 3, 4, 5, 4, 5, 5};
+	static const u8 connac2_table[] = {
+		1, 2, 3, 4, 2, 3, 4, 3, 4, 4, 0, 0, 0, 0, 0};
+
+	if (idx < 0 || idx >= ARRAY_SIZE(connac3_table))
+		return 0;
+
+	return is_mt799x(dev) ? connac3_table[idx] : connac2_table[idx];
+}
+
 static void
-mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const s8 *data,
-		       s8 target_power, s8 nss_delta, s8 *max_power)
+mt76_apply_array_limit(struct mt76_dev *dev, s8 *pwr, size_t pwr_len,
+		       const s8 *data, s8 target_power, s8 nss_delta,
+		       s8 *max_power, int n_chains, enum mt76_sku_type type)
 {
 	int i;
 
@@ -316,18 +337,51 @@ mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const s8 *data,
 		return;
 
 	for (i = 0; i < pwr_len; i++) {
-		pwr[i] = min_t(s8, target_power, data[i] + nss_delta);
+		u8 backoff_chain_idx = i;
+		int backoff_n_chains;
+		s8 backoff_delta;
+		s8 delta;
+
+		switch (type) {
+		case MT76_SKU_RATE:
+			delta = 0;
+			backoff_delta = 0;
+			backoff_n_chains = 0;
+			break;
+		case MT76_SKU_BACKOFF:
+			backoff_chain_idx += 1;
+			fallthrough;
+		case MT76_SKU_BACKOFF_BF_OFFSET:
+			delta = mt76_tx_power_path_delta(n_chains);
+			backoff_n_chains = mt76_backoff_n_chains(dev, backoff_chain_idx);
+			backoff_delta = mt76_tx_power_path_delta(backoff_n_chains);
+			break;
+		default:
+			return;
+		}
+
+		pwr[i] = min_t(s8, target_power + delta - backoff_delta, data[i] + nss_delta);
+
+		/* used for padding, doesn't need to be considered */
+		if (data[i] >= S8_MAX - 1)
+			continue;
+
+		/* only consider backoff value for the configured chain number */
+		if (type != MT76_SKU_RATE && n_chains != backoff_n_chains)
+			continue;
+
 		*max_power = max(*max_power, pwr[i]);
 	}
 }
 
 static void
-mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
-			     const s8 *data, size_t len, s8 target_power,
-			     s8 nss_delta)
+mt76_apply_multi_array_limit(struct mt76_dev *dev, s8 *pwr, size_t pwr_len,
+			     s8 pwr_num, const s8 *data, size_t len,
+			     s8 target_power, s8 nss_delta, s8 *max_power,
+			     int n_chains, enum mt76_sku_type type)
 {
+	static const int connac2_backoff_ru_idx = 2;
 	int i, cur;
-	s8 max_power = -128;
 
 	if (!data)
 		return;
@@ -337,8 +391,19 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
 		if (len < pwr_len + 1)
 			break;
 
-		mt76_apply_array_limit(pwr + pwr_len * i, pwr_len, data + 1,
-				       target_power, nss_delta, &max_power);
+		/* For connac2 devices,
+		 * - paths-ru = RU26, RU52, RU106, BW20, BW40, BW80, BW160
+		 * - paths-ru-bf = RU26, RU52, RU106, BW20, BW40, BW80, BW160
+		 * Only the first three entries use 1T1ss and do not need index
+		 * adjustment; the remaining four require index offset.
+		 */
+		if (!is_mt799x(dev) && type == MT76_SKU_BACKOFF &&
+		    i > connac2_backoff_ru_idx)
+			type = MT76_SKU_BACKOFF_BF_OFFSET;
+
+		mt76_apply_array_limit(dev, pwr + pwr_len * i, pwr_len, data + 1,
+				       target_power, nss_delta, max_power,
+				       n_chains, type);
 		if (--cur > 0)
 			continue;
 
@@ -360,18 +425,11 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
 	struct device_node *np;
 	const s8 *val;
 	char name[16];
-	u32 mcs_rates = dev->drv->mcs_rates;
-	u32 ru_rates = ARRAY_SIZE(dest->ru[0]);
 	char band;
 	size_t len;
-	s8 max_power = 0;
-	s8 max_power_backoff = -127;
+	s8 max_power = -127;
 	s8 txs_delta;
 	int n_chains = hweight16(phy->chainmask);
-	s8 target_power_combine = target_power + mt76_tx_power_path_delta(n_chains);
-
-	if (!mcs_rates)
-		mcs_rates = 10;
 
 	memset(dest, target_power, sizeof(*dest) - sizeof(dest->path));
 	memset(&dest->path, 0, sizeof(dest->path));
@@ -409,46 +467,52 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
 	txs_delta = mt76_get_txs_delta(np, hweight16(phy->chainmask));
 
 	val = mt76_get_of_array_s8(np, "rates-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_s8(np, "rates-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_s8(np, "rates-mcs", &len, mcs_rates + 1);
-	mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]),
-				     ARRAY_SIZE(dest->mcs), val, len,
-				     target_power, txs_delta);
-
-	val = mt76_get_of_array_s8(np, "rates-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_backoff = max_power;
-	val = mt76_get_of_array_s8(np, "paths-cck", &len, ARRAY_SIZE(dest->path.cck));
-	mt76_apply_array_limit(dest->path.cck, ARRAY_SIZE(dest->path.cck), val,
-			       target_power_combine, txs_delta, &max_power_backoff);
-
-	val = mt76_get_of_array_s8(np, "paths-ofdm", &len, ARRAY_SIZE(dest->path.ofdm));
-	mt76_apply_array_limit(dest->path.ofdm, ARRAY_SIZE(dest->path.ofdm), val,
-			       target_power_combine, txs_delta, &max_power_backoff);
-
-	val = mt76_get_of_array_s8(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest->path.ofdm_bf));
-	mt76_apply_array_limit(dest->path.ofdm_bf, ARRAY_SIZE(dest->path.ofdm_bf), val,
-			       target_power_combine, txs_delta, &max_power_backoff);
-
-	val = mt76_get_of_array_s8(np, "paths-ru", &len, ARRAY_SIZE(dest->path.ru[0]) + 1);
-	mt76_apply_multi_array_limit(dest->path.ru[0], ARRAY_SIZE(dest->path.ru[0]),
-				     ARRAY_SIZE(dest->path.ru), val, len,
-				     target_power_combine, txs_delta);
-
-	val = mt76_get_of_array_s8(np, "paths-ru-bf", &len, ARRAY_SIZE(dest->path.ru_bf[0]) + 1);
-	mt76_apply_multi_array_limit(dest->path.ru_bf[0], ARRAY_SIZE(dest->path.ru_bf[0]),
-				     ARRAY_SIZE(dest->path.ru_bf), val, len,
-				     target_power_combine, txs_delta);
+	mt76_apply_array_limit(dev, dest->cck, ARRAY_SIZE(dest->cck), val,
+			       target_power, txs_delta, &max_power, n_chains, MT76_SKU_RATE);
+
+	val = mt76_get_of_array_s8(np, "rates-ofdm", &len, ARRAY_SIZE(dest->ofdm));
+	mt76_apply_array_limit(dev, dest->ofdm, ARRAY_SIZE(dest->ofdm), val,
+			       target_power, txs_delta, &max_power, n_chains, MT76_SKU_RATE);
+
+	val = mt76_get_of_array_s8(np, "rates-mcs", &len,
+				   ARRAY_SIZE(dest->mcs[0]) + 1);
+	mt76_apply_multi_array_limit(dev, dest->mcs[0], ARRAY_SIZE(dest->mcs[0]),
+				     ARRAY_SIZE(dest->mcs), val, len, target_power,
+				     txs_delta, &max_power, n_chains, MT76_SKU_RATE);
+
+	val = mt76_get_of_array_s8(np, "rates-ru", &len,
+				   ARRAY_SIZE(dest->ru[0]) + 1);
+	mt76_apply_multi_array_limit(dev, dest->ru[0], ARRAY_SIZE(dest->ru[0]),
+				     ARRAY_SIZE(dest->ru), val, len, target_power,
+				     txs_delta, &max_power, n_chains, MT76_SKU_RATE);
+
+	val = mt76_get_of_array_s8(np, "paths-cck", &len,
+				   ARRAY_SIZE(dest->path.cck));
+	mt76_apply_array_limit(dev, dest->path.cck, ARRAY_SIZE(dest->path.cck), val,
+			       target_power, txs_delta, &max_power, n_chains, MT76_SKU_BACKOFF);
+
+	val = mt76_get_of_array_s8(np, "paths-ofdm", &len,
+				   ARRAY_SIZE(dest->path.ofdm));
+	mt76_apply_array_limit(dev, dest->path.ofdm, ARRAY_SIZE(dest->path.ofdm), val,
+			       target_power, txs_delta, &max_power, n_chains, MT76_SKU_BACKOFF);
+
+	val = mt76_get_of_array_s8(np, "paths-ofdm-bf", &len,
+				   ARRAY_SIZE(dest->path.ofdm_bf));
+	mt76_apply_array_limit(dev, dest->path.ofdm_bf, ARRAY_SIZE(dest->path.ofdm_bf), val,
+			       target_power, txs_delta, &max_power, n_chains,
+			       MT76_SKU_BACKOFF_BF_OFFSET);
+
+	val = mt76_get_of_array_s8(np, "paths-ru", &len,
+				   ARRAY_SIZE(dest->path.ru[0]) + 1);
+	mt76_apply_multi_array_limit(dev, dest->path.ru[0], ARRAY_SIZE(dest->path.ru[0]),
+				     ARRAY_SIZE(dest->path.ru), val, len, target_power,
+				     txs_delta, &max_power, n_chains, MT76_SKU_BACKOFF);
+
+	val = mt76_get_of_array_s8(np, "paths-ru-bf", &len,
+				   ARRAY_SIZE(dest->path.ru_bf[0]) + 1);
+	mt76_apply_multi_array_limit(dev, dest->path.ru_bf[0], ARRAY_SIZE(dest->path.ru_bf[0]),
+				     ARRAY_SIZE(dest->path.ru_bf), val, len, target_power,
+				     txs_delta, &max_power, n_chains, MT76_SKU_BACKOFF);
 
 	return max_power;
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index d05e83ea1..32876eab2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -540,7 +540,6 @@ struct mt76_driver_ops {
 	u32 survey_flags;
 	u16 txwi_size;
 	u16 token_size;
-	u8 mcs_rates;
 
 	unsigned int link_data_size;
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] wifi: mt76: fix backoff fields and max_power calculation
  2026-01-27 23:55 [PATCH v2] wifi: mt76: fix backoff fields and max_power calculation Ryder Lee
@ 2026-02-02  8:14 ` Sven Eckelmann
  2026-02-09  7:48   ` Ryder Lee
  0 siblings, 1 reply; 6+ messages in thread
From: Sven Eckelmann @ 2026-02-02  8:14 UTC (permalink / raw)
  To: Ryder Lee, Rob Herring
  Cc: Felix Fietkau, linux-wireless, linux-mediatek, Allen Ye,
	Saravana Kannan

[-- Attachment #1: Type: text/plain, Size: 2558 bytes --]

On Wednesday, 28 January 2026 00:55:57 CET Ryder Lee wrote:
> +               case MT76_SKU_BACKOFF:
> +                       backoff_chain_idx += 1;
> +                       fallthrough;
> +               case MT76_SKU_BACKOFF_BF_OFFSET:
> +                       delta = mt76_tx_power_path_delta(n_chains);
> +                       backoff_n_chains = mt76_backoff_n_chains(dev, backoff_chain_idx);
> +                       backoff_delta = mt76_tx_power_path_delta(backoff_n_chains);
> +                       break;
> +               default:

Please double check whether the "case"s for MT76_SKU_BACKOFF_BF_OFFSET and 
MT76_SKU_BACKOFF should actually be swapped. I think I've originally 
introduced this mistake when trying to demonstrate different ways to write the
switch block.


> +               /* For connac2 devices,
> +                * - paths-ru = RU26, RU52, RU106, BW20, BW40, BW80, BW160
> +                * - paths-ru-bf = RU26, RU52, RU106, BW20, BW40, BW80, BW160
> +                * Only the first three entries use 1T1ss and do not need index
> +                * adjustment; the remaining four require index offset.
> +                */


Hm, I doubt that anyone can understand this (same for the commit message).
You basically just showed a list of two equal "array"s.

Actually important here is that, RU26, RU52, RU106, ... stand here for 10
different values:

1T1ss, 2T1ss, 3T1ss, 4T1ss, 2T2ss, 3T2ss, 4T2ss, 3T3ss, 4T3ss, 4T4ss

For paths-ru-bf, also 10 values are stored in the DT for each of these
(RU26, ..., BW160) - but only the non-1T1ss are relevant for this
calculation for BW20, ..., BW160.

These 1T1ss beamforming values for BW20, ..., BW160 were (if I understand it 
correctly) removed for connac3. 

If you introduce some change in the DT interpretation, then you must also 
inform the DT maintainers (Rob Herring <robh@kernel.org>, 
Saravana Kannan <saravanak@kernel.org>, devicetree@vger.kernel.org) while 
updatingDocumentation/devicetree/bindings/net/wireless/mediatek%2Cmt76.yaml. 
The latter is currently still expecting 1 ("rates multiplier") + 10 values
(limits). And DTs with only 1 + 9 values per rate would therefore fail to be
validated.

At the moment, your connac3 code is basically conflicting with the devicetree
documentation. I will leave it to the experts to figure out if the devicetree
should have two different interpretations for the same property or whether
the property should be the same and the code must handle the differences
before sending these values to the HW.

Regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] wifi: mt76: fix backoff fields and max_power calculation
  2026-02-02  8:14 ` Sven Eckelmann
@ 2026-02-09  7:48   ` Ryder Lee
  2026-02-09  9:17     ` Sven Eckelmann
  0 siblings, 1 reply; 6+ messages in thread
From: Ryder Lee @ 2026-02-09  7:48 UTC (permalink / raw)
  To: robh@kernel.org, sven@narfation.org
  Cc: linux-wireless@vger.kernel.org, nbd@nbd.name,
	linux-mediatek@lists.infradead.org,
	Allen Ye (葉芷勳), saravanak@kernel.org

On Mon, 2026-02-02 at 09:14 +0100, Sven Eckelmann wrote:
> On Wednesday, 28 January 2026 00:55:57 CET Ryder Lee wrote:
> > +               case MT76_SKU_BACKOFF:
> > +                       backoff_chain_idx += 1;
> > +                       fallthrough;
> > +               case MT76_SKU_BACKOFF_BF_OFFSET:
> > +                       delta = mt76_tx_power_path_delta(n_chains);
> > +                       backoff_n_chains =
> > mt76_backoff_n_chains(dev, backoff_chain_idx);
> > +                       backoff_delta =
> > mt76_tx_power_path_delta(backoff_n_chains);
> > +                       break;
> > +               default:
> 
> Please double check whether the "case"s for
> MT76_SKU_BACKOFF_BF_OFFSET and 
> MT76_SKU_BACKOFF should actually be swapped. I think I've originally 
> introduced this mistake when trying to demonstrate different ways to
> write the
> switch block.
> 
> 
> > +               /* For connac2 devices,
> > +                * - paths-ru = RU26, RU52, RU106, BW20, BW40,
> > BW80, BW160
> > +                * - paths-ru-bf = RU26, RU52, RU106, BW20, BW40,
> > BW80, BW160
> > +                * Only the first three entries use 1T1ss and do
> > not need index
> > +                * adjustment; the remaining four require index
> > offset.
> > +                */
> 
> 
> Hm, I doubt that anyone can understand this (same for the commit
> message).
> You basically just showed a list of two equal "array"s.
> 
> Actually important here is that, RU26, RU52, RU106, ... stand here
> for 10
> different values:
> 
> 1T1ss, 2T1ss, 3T1ss, 4T1ss, 2T2ss, 3T2ss, 4T2ss, 3T3ss, 4T3ss, 4T4ss
> 
> For paths-ru-bf, also 10 values are stored in the DT for each of
> these
> (RU26, ..., BW160) - but only the non-1T1ss are relevant for this
> calculation for BW20, ..., BW160.
> 
> These 1T1ss beamforming values for BW20, ..., BW160 were (if I
> understand it 
> correctly) removed for connac3. 
> 
> If you introduce some change in the DT interpretation, then you must
> also 
> inform the DT maintainers (Rob Herring <robh@kernel.org>, 
> Saravana Kannan <saravanak@kernel.org>, devicetree@vger.kernel.org)
> while 
> updatingDocumentation/devicetree/bindings/net/wireless/mediatek%2Cmt7
> 6.yaml. 
> The latter is currently still expecting 1 ("rates multiplier") + 10
> values
> (limits). And DTs with only 1 + 9 values per rate would therefore
> fail to be
> validated.
> 
> At the moment, your connac3 code is basically conflicting with the
> devicetree
> documentation. I will leave it to the experts to figure out if the
> devicetree
> should have two different interpretations for the same property or
> whether
> the property should be the same and the code must handle the
> differences
> before sending these values to the HW.
> 
> Regards,
> 	Sven
> 
I think the DTS format for connac3 is also 1 multiplier plus 10 values,
not 1+9. The key should be:

For beamforming tables:

- In connac2, beamforming entries for BW20~BW160 and OFDM do not
include 1T1ss.
- In connac3, beamforming entries for BW20~BW160 and RU include 1T1ss,
but OFDM beamforming does not include 1T1ss.

Non-beamforming and RU entries for both connac2 and connac3 include
1T1ss.

I will add this explanation to patch v3, and I have already fixed the
copy-paste error above.

Ryder


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] wifi: mt76: fix backoff fields and max_power calculation
  2026-02-09  7:48   ` Ryder Lee
@ 2026-02-09  9:17     ` Sven Eckelmann
  2026-02-10  6:38       ` Ryder Lee
  0 siblings, 1 reply; 6+ messages in thread
From: Sven Eckelmann @ 2026-02-09  9:17 UTC (permalink / raw)
  To: robh@kernel.org, Ryder Lee
  Cc: linux-wireless@vger.kernel.org, nbd@nbd.name,
	linux-mediatek@lists.infradead.org,
	Allen Ye (葉芷勳), saravanak@kernel.org

[-- Attachment #1: Type: text/plain, Size: 1718 bytes --]

On Monday, 9 February 2026 08:48:50 CET Ryder Lee wrote:
> - In connac2, beamforming entries for BW20~BW160 and OFDM do not
> include 1T1ss.
> - In connac3, beamforming entries for BW20~BW160 and RU include 1T1ss,
> but OFDM beamforming does not include 1T1ss.

This doesn't seem to match the documentation [1]:

                  paths-ofdm-bf:
                    $ref: /schemas/types.yaml#/definitions/uint8-array
                    minItems: 4
                    maxItems: 4
                    description:
                      4 half-dBm backoff values for beamforming
                      (1 - 4 antennas, single spacial stream)
...
                  paths-ru-bf:
                    $ref: /schemas/types.yaml#/definitions/uint8-matrix
                    description:
                      Sets of half-dBm backoff (beamforming) values for 802.11ax
                      rates for 1T1ss (aka 1 transmitting antenna with 1 spacial
                      stream), 2T1ss, 3T1ss, 4T1ss, 2T2ss, 3T2ss, 4T2ss, 3T3ss,
                      4T3ss and 4T4ss.
                      Each set starts with the number of channel bandwidth or
                      resource unit settings for which the rate set applies,
                      followed by 10 power limit values. The order of the
                      channel resource unit settings is RU26, RU52, RU106,
                      RU242/SU20, RU484/SU40, RU996/SU80 and RU2x996/SU160.
                    minItems: 1
                    maxItems: 7
                    items:
                      minItems: 11
                      maxItems: 11

Regards,
	Sven
	
[1] https://www.kernel.org/doc/Documentation/devicetree/bindings/net/wireless/mediatek%2Cmt76.yaml

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] wifi: mt76: fix backoff fields and max_power calculation
  2026-02-09  9:17     ` Sven Eckelmann
@ 2026-02-10  6:38       ` Ryder Lee
  2026-02-10  7:01         ` Sven Eckelmann
  0 siblings, 1 reply; 6+ messages in thread
From: Ryder Lee @ 2026-02-10  6:38 UTC (permalink / raw)
  To: robh@kernel.org, sven@narfation.org
  Cc: linux-wireless@vger.kernel.org, nbd@nbd.name,
	linux-mediatek@lists.infradead.org,
	Allen Ye (葉芷勳), saravanak@kernel.org

On Mon, 2026-02-09 at 10:17 +0100, Sven Eckelmann wrote:
> On Monday, 9 February 2026 08:48:50 CET Ryder Lee wrote:
> > - In connac2, beamforming entries for BW20~BW160 and OFDM do not
> > include 1T1ss.
> > - In connac3, beamforming entries for BW20~BW160 and RU include
> > 1T1ss,
> > but OFDM beamforming does not include 1T1ss.
> 
> This doesn't seem to match the documentation [1]:
> 
>                   paths-ofdm-bf:
>                     $ref: /schemas/types.yaml#/definitions/uint8-
> array
>                     minItems: 4
>                     maxItems: 4
>                     description:
>                       4 half-dBm backoff values for beamforming
>                       (1 - 4 antennas, single spacial stream)
> ...
>                   paths-ru-bf:
>                     $ref: /schemas/types.yaml#/definitions/uint8-
> matrix
>                     description:
>                       Sets of half-dBm backoff (beamforming) values
> for 802.11ax
>                       rates for 1T1ss (aka 1 transmitting antenna
> with 1 spacial
>                       stream), 2T1ss, 3T1ss, 4T1ss, 2T2ss, 3T2ss,
> 4T2ss, 3T3ss,
>                       4T3ss and 4T4ss.
>                       Each set starts with the number of channel
> bandwidth or
>                       resource unit settings for which the rate set
> applies,
>                       followed by 10 power limit values. The order of
> the
>                       channel resource unit settings is RU26, RU52,
> RU106,
>                       RU242/SU20, RU484/SU40, RU996/SU80 and
> RU2x996/SU160.
>                     minItems: 1
>                     maxItems: 7
>                     items:
>                       minItems: 11
>                       maxItems: 11
> 
> Regards,
> 	Sven
> 	
> [1]
> https://www.kernel.org/doc/Documentation/devicetree/bindings/net/wireless/mediatek%2Cmt76.yaml

Hmm...If we really want to dig it out, this document is indeed not
precise enough.

This is for the 7915 when filling in the Bw20/40/80/160 power values.

In mt7915_mcu_set_txpower_sku()
....
        for (i = 0; i < 8; i++) {
                bool bf = i % 2;
                u8 idx = (i + 6) / 2;
                s8 *buf = bf ? la.path.ru_bf[idx] : la.path.ru[idx];
                /* The non-bf fields of RU26 to RU106 are special cases
*/
                if (bf)
                        skb_put_data(skb, buf + 1, 9);
                else
                        skb_put_data(skb, buf, 10);
        }

The skb order is filled according to the firmware requirements.

Each field corresponds to: 1T1ss, 2T1ss, 3T1ss, 4T1ss, 2T2ss, 3T2ss,
4T2ss, 3T3ss, 4T3ss, and 4T4ss, for a total of 10 values.

For beamform case, mt76 does not need to fill in the value for 1T1ss,
so the length is 9.

For non-beamform case, mt76 needs to fill in the value for 1T1ss, so
the length is 10.

The DTS still needs to provide 1 + 10 because mt76 does not
specifically check for this when parsing DTS.

So a connac2 DTS would be filled like this:

paths-ru-bf =
<1 20 22 38 36 24 30 23 21 28 29>,
<1 20 39 31 25 26 25 28 30 39 39>,
<1 37 34 26 26 25 21 34 23 34 24>,
<1 0 20 23 31 23 30 39 28 29 36>,
<1 0 27 34 33 34 29 38 33 33 22>,
<1 0 30 23 39 28 21 25 29 28 21>,
<1 0 34 20 38 32 35 33 37 26 36>;

When 1T1ss is not used, it should be filled with 0. For connac3, since
1T1ss is taken into account, we don’t need to fill it with 0.

The unused 1T1ss still needs to be written in the DTS. This is to make
parsing easier.

So the number indicated in the current document is correct; it’s just
that the description isn’t precise enough.

Of course, I can revise the description for connac3. I just wanted to
say that there’s no need to change the min and max values, which should
make things much simpler.


Ryder


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] wifi: mt76: fix backoff fields and max_power calculation
  2026-02-10  6:38       ` Ryder Lee
@ 2026-02-10  7:01         ` Sven Eckelmann
  0 siblings, 0 replies; 6+ messages in thread
From: Sven Eckelmann @ 2026-02-10  7:01 UTC (permalink / raw)
  To: robh@kernel.org, Ryder Lee
  Cc: linux-wireless@vger.kernel.org, nbd@nbd.name,
	linux-mediatek@lists.infradead.org,
	Allen Ye (葉芷勳), saravanak@kernel.org

[-- Attachment #1: Type: text/plain, Size: 270 bytes --]

On Tuesday, 10 February 2026 07:38:24 CET Ryder Lee wrote:
> Of course, I can revise the description for connac3. I just wanted to
> say that there’s no need to change the min and max values, which should
> make things much simpler.

Ok, thanks

Regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-02-10  7:01 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-27 23:55 [PATCH v2] wifi: mt76: fix backoff fields and max_power calculation Ryder Lee
2026-02-02  8:14 ` Sven Eckelmann
2026-02-09  7:48   ` Ryder Lee
2026-02-09  9:17     ` Sven Eckelmann
2026-02-10  6:38       ` Ryder Lee
2026-02-10  7:01         ` Sven Eckelmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox