[PATCH v1 1/2] wifi: mt76: mt7996: refresh power limits on txpower changes

Yanghan Ye yyh94306 at gmail.com
Wed Jun 24 07:45:15 PDT 2026


mt7996_config() currently ignores mac80211 configuration changes. As a
result, user txpower updates may change the cfg80211 visible power level
without refreshing the firmware SKU table used by mt7996.

Refresh the SKU table when mac80211 reports power or channel changes. Only
copy hw->conf.power_level into the cached PHY txpower on global power
changes so channel-only updates do not overwrite a BSS txpower limit.

Also refresh the SKU table and channel information for BSS txpower changes,
and report MCU failures instead of silently ignoring them.

Signed-off-by: Yanghan Ye <yyh94306 at gmail.com>
---
 mt7996/main.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 2 deletions(-)

diff --git a/mt7996/main.c b/mt7996/main.c
index 560fe30d..c32e7819 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
@@ -736,7 +736,50 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
 static int mt7996_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
 {
-	return 0;
+	struct mt7996_dev *dev = mt7996_hw_dev(hw);
+	struct mt7996_phy *phy;
+	int ret = 0;
+
+	if (!(changed & (IEEE80211_CONF_CHANGE_POWER |
+			 IEEE80211_CONF_CHANGE_CHANNEL)))
+		return 0;
+
+	mutex_lock(&dev->mt76.mutex);
+
+	if (radio_idx >= 0) {
+		if (radio_idx >= ARRAY_SIZE(dev->radio_phy)) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		phy = dev->radio_phy[radio_idx];
+		if (phy) {
+			if (changed & IEEE80211_CONF_CHANGE_POWER)
+				phy->txpower = hw->conf.power_level;
+
+			ret = mt7996_mcu_set_txpower_sku(phy);
+			if (!ret && (changed & IEEE80211_CONF_CHANGE_POWER))
+				ret = mt7996_mcu_set_chan_info(phy,
+							       UNI_CHANNEL_SWITCH);
+		}
+	} else {
+		mt7996_for_each_phy(dev, phy) {
+			if (changed & IEEE80211_CONF_CHANGE_POWER)
+				phy->txpower = hw->conf.power_level;
+
+			ret = mt7996_mcu_set_txpower_sku(phy);
+			if (!ret && (changed & IEEE80211_CONF_CHANGE_POWER))
+				ret = mt7996_mcu_set_chan_info(phy,
+							       UNI_CHANNEL_SWITCH);
+			if (ret)
+				break;
+		}
+	}
+
+out:
+	mutex_unlock(&dev->mt76.mutex);
+
+	return ret;
 }
 
 static int
@@ -1025,9 +1068,24 @@ mt7996_link_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		mt7996_update_mu_group(hw, link, info);
 
 	if (changed & BSS_CHANGED_TXPOWER &&
+	    info->txpower != INT_MIN &&
 	    info->txpower != phy->txpower) {
+		int ret;
+
 		phy->txpower = info->txpower;
-		mt7996_mcu_set_txpower_sku(phy);
+		ret = mt7996_mcu_set_txpower_sku(phy);
+		if (ret) {
+			dev_err_ratelimited(dev->mt76.dev,
+					    "failed to update txpower SKU: %d\n",
+					    ret);
+			goto out;
+		}
+
+		ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_SWITCH);
+		if (ret)
+			dev_err_ratelimited(dev->mt76.dev,
+					    "failed to update txpower channel info: %d\n",
+					    ret);
 	}
 
 out:
-- 
2.43.0




More information about the Linux-mediatek mailing list