]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
wifi: mac80211: update the right link for tx power
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 7 Oct 2024 12:00:52 +0000 (15:00 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 23 Oct 2024 14:43:22 +0000 (16:43 +0200)
Stop looking at deflink and start using the actual link.
Initialize the power settings upon link init.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20241007144851.2685dab8e1ab.I1d82cbdb2dda020aee4a225bd9a134f7d82dd810@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/mac80211/chan.c
net/mac80211/iface.c
net/mac80211/link.c

index 27468a463d8bf2a16e1cf708f2280b2a9f015789..ca4fd217be3eeb5caed9ae4329686f3f79bc87b6 100644 (file)
@@ -3061,9 +3061,25 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
        enum nl80211_tx_power_setting txp_type = type;
        bool update_txp_type = false;
        bool has_monitor = false;
+       int user_power_level;
 
        lockdep_assert_wiphy(local->hw.wiphy);
 
+       switch (type) {
+       case NL80211_TX_POWER_AUTOMATIC:
+               user_power_level = IEEE80211_UNSET_POWER_LEVEL;
+               txp_type = NL80211_TX_POWER_LIMITED;
+               break;
+       case NL80211_TX_POWER_LIMITED:
+       case NL80211_TX_POWER_FIXED:
+               if (mbm < 0 || (mbm % 100))
+                       return -EOPNOTSUPP;
+               user_power_level = MBM_TO_DBM(mbm);
+               break;
+       default:
+               return -EINVAL;
+       }
+
        if (wdev) {
                sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
 
@@ -3077,57 +3093,65 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
                                return -EOPNOTSUPP;
                }
 
-               switch (type) {
-               case NL80211_TX_POWER_AUTOMATIC:
-                       sdata->deflink.user_power_level =
-                               IEEE80211_UNSET_POWER_LEVEL;
-                       txp_type = NL80211_TX_POWER_LIMITED;
-                       break;
-               case NL80211_TX_POWER_LIMITED:
-               case NL80211_TX_POWER_FIXED:
-                       if (mbm < 0 || (mbm % 100))
-                               return -EOPNOTSUPP;
-                       sdata->deflink.user_power_level = MBM_TO_DBM(mbm);
-                       break;
-               }
+               for (int link_id = 0;
+                    link_id < ARRAY_SIZE(sdata->link);
+                    link_id++) {
+                       struct ieee80211_link_data *link =
+                               wiphy_dereference(wiphy, sdata->link[link_id]);
 
-               if (txp_type != sdata->vif.bss_conf.txpower_type) {
-                       update_txp_type = true;
-                       sdata->vif.bss_conf.txpower_type = txp_type;
-               }
+                       if (!link)
+                               continue;
+
+                       link->user_power_level = user_power_level;
 
-               ieee80211_recalc_txpower(&sdata->deflink, update_txp_type);
+                       if (txp_type != link->conf->txpower_type) {
+                               update_txp_type = true;
+                               link->conf->txpower_type = txp_type;
+                       }
 
+                       ieee80211_recalc_txpower(link, update_txp_type);
+               }
                return 0;
        }
 
-       switch (type) {
-       case NL80211_TX_POWER_AUTOMATIC:
-               local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
-               txp_type = NL80211_TX_POWER_LIMITED;
-               break;
-       case NL80211_TX_POWER_LIMITED:
-       case NL80211_TX_POWER_FIXED:
-               if (mbm < 0 || (mbm % 100))
-                       return -EOPNOTSUPP;
-               local->user_power_level = MBM_TO_DBM(mbm);
-               break;
-       }
+       local->user_power_level = user_power_level;
 
        list_for_each_entry(sdata, &local->interfaces, list) {
                if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
                        has_monitor = true;
                        continue;
                }
-               sdata->deflink.user_power_level = local->user_power_level;
-               if (txp_type != sdata->vif.bss_conf.txpower_type)
-                       update_txp_type = true;
-               sdata->vif.bss_conf.txpower_type = txp_type;
+
+               for (int link_id = 0;
+                    link_id < ARRAY_SIZE(sdata->link);
+                    link_id++) {
+                       struct ieee80211_link_data *link =
+                               wiphy_dereference(wiphy, sdata->link[link_id]);
+
+                       if (!link)
+                               continue;
+
+                       link->user_power_level = local->user_power_level;
+                       if (txp_type != link->conf->txpower_type)
+                               update_txp_type = true;
+                       link->conf->txpower_type = txp_type;
+               }
        }
        list_for_each_entry(sdata, &local->interfaces, list) {
                if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
                        continue;
-               ieee80211_recalc_txpower(&sdata->deflink, update_txp_type);
+
+               for (int link_id = 0;
+                    link_id < ARRAY_SIZE(sdata->link);
+                    link_id++) {
+                       struct ieee80211_link_data *link =
+                               wiphy_dereference(wiphy, sdata->link[link_id]);
+
+                       if (!link)
+                               continue;
+
+                       ieee80211_recalc_txpower(link, update_txp_type);
+               }
        }
 
        if (has_monitor) {
index 426ae5c066c9c222bac5379dcfdba6782f0973d7..b355e9af268d7611052c332b4ddd69808aee2298 100644 (file)
@@ -905,7 +905,7 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
        }
 
        if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
-               ieee80211_recalc_txpower(&sdata->deflink, false);
+               ieee80211_recalc_txpower(link, false);
                ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL, false);
        }
 
@@ -1712,7 +1712,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
                                                                  link,
                                                                  changed);
 
-                       ieee80211_recalc_txpower(&sdata->deflink, false);
+                       ieee80211_recalc_txpower(link, false);
                }
 
                ieee80211_recalc_chanctx_chantype(local, ctx);
index 138ba30e23ba52c6720b44c25694fe8bb97d39c7..7a99fa057cd9481db7d58ecd60491cadaae80202 100644 (file)
@@ -46,12 +46,11 @@ static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work);
 
 bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link)
 {
-       struct ieee80211_sub_if_data *sdata = link->sdata;
        struct ieee80211_chanctx_conf *chanctx_conf;
        int power;
 
        rcu_read_lock();
-       chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+       chanctx_conf = rcu_dereference(link->conf->chanctx_conf);
        if (!chanctx_conf) {
                rcu_read_unlock();
                return false;
@@ -60,15 +59,15 @@ bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link)
        power = ieee80211_chandef_max_power(&chanctx_conf->def);
        rcu_read_unlock();
 
-       if (sdata->deflink.user_power_level != IEEE80211_UNSET_POWER_LEVEL)
-               power = min(power, sdata->deflink.user_power_level);
+       if (link->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
+               power = min(power, link->user_power_level);
 
-       if (sdata->deflink.ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
-               power = min(power, sdata->deflink.ap_power_level);
+       if (link->ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
+               power = min(power, link->ap_power_level);
 
-       if (power != sdata->vif.bss_conf.txpower) {
-               sdata->vif.bss_conf.txpower = power;
-               ieee80211_hw_config(sdata->local, 0);
+       if (power != link->conf->txpower) {
+               link->conf->txpower = power;
+               ieee80211_hw_config(link->sdata->local, 0);
                return true;
        }
 
@@ -2177,9 +2176,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 
        ieee80211_set_default_queues(sdata);
 
-       sdata->deflink.ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
-       sdata->deflink.user_power_level = local->user_power_level;
-
        /* setup type-dependent data */
        ieee80211_setup_sdata(sdata, type);
 
index 0bbac64d5fa0132b748f775256d9c93b55ecc07d..503bdea904bc77db3ae6fc47e22a1f9955fd658a 100644 (file)
@@ -36,6 +36,9 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
        link->conf = link_conf;
        link_conf->link_id = link_id;
        link_conf->vif = &sdata->vif;
+       link->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
+       link->user_power_level = sdata->local->user_power_level;
+       link_conf->txpower = INT_MIN;
 
        wiphy_work_init(&link->csa.finalize_work,
                        ieee80211_csa_finalize_work);