]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mt76: mt792x: report txpower for the requested vif link
authorSean Wang <sean.wang@mediatek.com>
Wed, 1 Apr 2026 18:23:22 +0000 (13:23 -0500)
committerFelix Fietkau <nbd@nbd.name>
Tue, 9 Jun 2026 10:15:22 +0000 (10:15 +0000)
mt792x currently reports txpower from the generic PHY cached state,
which may not match the requested vif/link context.

Resolve the requested link channel and derive txpower from that channel
instead, with fallback to the current PHY chandef if no valid chanctx is
available.

Reported-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Closes: https://lore.kernel.org/linux-wireless/20260130215839.53270-1-lucid_duck@justthetip.ca/
Tested-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Tested-by: Satadru Pramanik <satadru@gmail.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260401182322.64355-3-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7921/main.c
drivers/net/wireless/mediatek/mt76/mt7925/main.c
drivers/net/wireless/mediatek/mt76/mt792x.h
drivers/net/wireless/mediatek/mt76/mt792x_core.c

index adaf9a53f2962715d23c09cc170ca0377c9172b1..6ffccc023728033b789ed455cb96cc41bbd544f7 100644 (file)
@@ -1558,7 +1558,7 @@ const struct ieee80211_ops mt7921_ops = {
        .wake_tx_queue = mt76_wake_tx_queue,
        .release_buffered_frames = mt76_release_buffered_frames,
        .channel_switch_beacon = mt7921_channel_switch_beacon,
-       .get_txpower = mt76_get_txpower,
+       .get_txpower = mt792x_get_txpower,
        .get_stats = mt792x_get_stats,
        .get_et_sset_count = mt792x_get_et_sset_count,
        .get_et_strings = mt792x_get_et_strings,
index c20e5316fae07902a25982bc4cb754cfd3f001b7..a9059866b70161de6cf0ba6e49d1bb20f55d075a 100644 (file)
@@ -2504,7 +2504,7 @@ const struct ieee80211_ops mt7925_ops = {
        .wake_tx_queue = mt76_wake_tx_queue,
        .release_buffered_frames = mt76_release_buffered_frames,
        .channel_switch_beacon = mt7925_channel_switch_beacon,
-       .get_txpower = mt76_get_txpower,
+       .get_txpower = mt792x_get_txpower,
        .get_stats = mt792x_get_stats,
        .get_et_sset_count = mt792x_get_et_sset_count,
        .get_et_strings = mt792x_get_et_strings,
index 59562567cc139b216e635cf50ceb185fee72d584..4f823fb705d510e77363bbb975e644801841ac30 100644 (file)
@@ -416,6 +416,8 @@ void mt792x_roc_timer(struct timer_list *timer);
 void mt792x_csa_timer(struct timer_list *timer);
 void mt792x_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                  u32 queues, bool drop);
+int mt792x_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                      unsigned int link_id, int *dbm);
 int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw,
                              struct ieee80211_vif *vif,
                              struct ieee80211_bss_conf *link_conf,
index e5ef724dd2d3d395d7b96cafc77a6d5ecb85f535..b50825eccdafee3ee924b86403a0d40c5cbd8711 100644 (file)
@@ -330,6 +330,47 @@ void mt792x_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 }
 EXPORT_SYMBOL_GPL(mt792x_flush);
 
+int mt792x_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                      unsigned int link_id, int *dbm)
+{
+       struct mt76_power_limits limits = {};
+       struct ieee80211_bss_conf *link_conf;
+       struct ieee80211_channel *chan;
+       struct mt792x_bss_conf *mconf;
+       struct mt792x_vif *mvif;
+       struct mt76_phy *phy;
+       s8 max_power;
+
+       if (!vif)
+               return mt76_get_txpower(hw, vif, link_id, dbm);
+
+       mvif = (struct mt792x_vif *)vif->drv_priv;
+       phy = mvif->phy->mt76;
+
+       mt792x_mutex_acquire(mvif->phy->dev);
+
+       link_conf = mt792x_vif_to_bss_conf(vif, link_id);
+       mconf = link_conf ? mt792x_link_conf_to_mconf(link_conf) : NULL;
+       if (mconf && mconf->mt76.ctx && mconf->mt76.ctx->def.chan)
+               chan = mconf->mt76.ctx->def.chan;
+       else
+               /* Fall back to the current PHY chandef if the requested link
+                * does not have a valid channel context.
+                */
+               chan = phy->chandef.chan;
+
+       mt792x_mutex_release(mvif->phy->dev);
+
+       if (!chan)
+               return -EINVAL;
+
+       max_power = mt76_connac_get_rate_power_limit(phy, chan, &limits);
+       *dbm = DIV_ROUND_UP(max_power, 2);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mt792x_get_txpower);
+
 int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw,
                              struct ieee80211_vif *vif,
                              struct ieee80211_bss_conf *link_conf,