wifi: mac80211: make some SMPS code MLD-aware
authorJohannes Berg <johannes.berg@intel.com>
Mon, 30 May 2022 21:45:04 +0000 (23:45 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 20 Jun 2022 10:55:30 +0000 (12:55 +0200)
Start making some SMPS related code MLD-aware. This isn't
really done yet, but again cuts down our 'deflink' reliance.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/dvm/lib.c
drivers/net/wireless/intel/iwlwifi/mvm/utils.c
drivers/net/wireless/realtek/rtw88/main.c
include/net/mac80211.h
net/mac80211/cfg.c
net/mac80211/debugfs_netdev.c
net/mac80211/ht.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/mlme.c
net/mac80211/util.c

index 40d790b36d85b88a3bea4db3a40833d8d9a27378..1dc974e2c511f02f7055e481a6b5d5b374cb4ee4 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /******************************************************************************
  *
- * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2014, 2022 Intel Corporation. All rights reserved.
  *****************************************************************************/
 #include <linux/etherdevice.h>
 #include <linux/kernel.h>
@@ -441,7 +441,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
                priv->current_ht_config.smps = smps_request;
                for_each_context(priv, ctx) {
                        if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION)
-                               ieee80211_request_smps(ctx->vif, smps_request);
+                               ieee80211_request_smps(ctx->vif, 0, smps_request);
                }
        }
 
index 3ee5ea3484be896c4cc7d63c42c78eecd72e21b3..14b2de65bd8432720ee75c23de757152b5a09a41 100644 (file)
@@ -304,7 +304,7 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                        smps_mode = IEEE80211_SMPS_DYNAMIC;
        }
 
-       ieee80211_request_smps(vif, smps_mode);
+       ieee80211_request_smps(vif, 0, smps_mode);
 }
 
 static bool iwl_wait_stats_complete(struct iwl_notif_wait_data *notif_wait,
index f78b9f28d5f6cd15b48f7b8b2e203bf474fd4242..985ee36efc0f34d3775af04c923a9c0bcb650dcc 100644 (file)
@@ -1600,9 +1600,9 @@ static void rtw_vif_smps_iter(void *data, u8 *mac,
                return;
 
        if (rtwdev->hal.txrx_1ss)
-               ieee80211_request_smps(vif, IEEE80211_SMPS_STATIC);
+               ieee80211_request_smps(vif, 0, IEEE80211_SMPS_STATIC);
        else
-               ieee80211_request_smps(vif, IEEE80211_SMPS_OFF);
+               ieee80211_request_smps(vif, 0, IEEE80211_SMPS_OFF);
 }
 
 void rtw_set_txrx_1ss(struct rtw_dev *rtwdev, bool txrx_1ss)
index 0a26cb2871d67ebb06ec34d6a2f05edf9b53771b..302340f6fa08faf92d98b7f859487c25d71b3477 100644 (file)
@@ -6210,13 +6210,14 @@ void ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif,
 /**
  * ieee80211_request_smps - request SM PS transition
  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @link_id: link ID for MLO, or 0
  * @smps_mode: new SM PS mode
  *
  * This allows the driver to request an SM PS transition in managed
  * mode. This is useful when the driver has more information than
  * the stack about possible interference, for example by bluetooth.
  */
-void ieee80211_request_smps(struct ieee80211_vif *vif,
+void ieee80211_request_smps(struct ieee80211_vif *vif, unsigned int link_id,
                            enum ieee80211_smps_mode smps_mode);
 
 /**
index d7f2eb7421c385a55d0be5c451fbf85e1e24d94f..2c9554174bcfd8275c44235a4bd1b9fc59d5bf2a 100644 (file)
@@ -2913,6 +2913,7 @@ static int ieee80211_testmode_dump(struct wiphy *wiphy,
 #endif
 
 int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
+                                unsigned int link_id,
                                 enum ieee80211_smps_mode smps_mode)
 {
        const u8 *ap;
@@ -2926,8 +2927,8 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
        if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION))
                return -EINVAL;
 
-       old_req = sdata->deflink.u.mgd.req_smps;
-       sdata->deflink.u.mgd.req_smps = smps_mode;
+       old_req = sdata->link[link_id]->u.mgd.req_smps;
+       sdata->link[link_id]->u.mgd.req_smps = smps_mode;
 
        if (old_req == smps_mode &&
            smps_mode != IEEE80211_SMPS_AUTOMATIC)
@@ -2939,10 +2940,10 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
         * the new value until we associate.
         */
        if (!sdata->u.mgd.associated ||
-           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
+           sdata->vif.link_conf[link_id]->chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
                return 0;
 
-       ap = sdata->deflink.u.mgd.bssid;
+       ap = sdata->link[link_id]->u.mgd.bssid;
 
        rcu_read_lock();
        list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
@@ -2966,7 +2967,7 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
        err = ieee80211_send_smps_action(sdata, smps_mode,
                                         ap, ap);
        if (err)
-               sdata->deflink.u.mgd.req_smps = old_req;
+               sdata->link[link_id]->u.mgd.req_smps = old_req;
        else if (smps_mode != IEEE80211_SMPS_OFF && tdls_peer_found)
                ieee80211_teardown_tdls_peers(sdata);
 
@@ -2978,6 +2979,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       unsigned int link_id;
 
        if (sdata->vif.type != NL80211_IFTYPE_STATION)
                return -EOPNOTSUPP;
@@ -2994,7 +2996,12 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
 
        /* no change, but if automatic follow powersave */
        sdata_lock(sdata);
-       __ieee80211_request_smps_mgd(sdata, sdata->deflink.u.mgd.req_smps);
+       for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) {
+               if (!sdata->link[link_id])
+                       continue;
+               __ieee80211_request_smps_mgd(sdata, link_id,
+                                            sdata->link[link_id]->u.mgd.req_smps);
+       }
        sdata_unlock(sdata);
 
        if (ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
index bd398b6317636a2b52e8eeccff310c3158b3e2b0..dfb194e1501818f1dc08b7c752aba9fc3ee483f3 100644 (file)
@@ -256,7 +256,7 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
                return -EOPNOTSUPP;
 
        sdata_lock(sdata);
-       err = __ieee80211_request_smps_mgd(sdata, smps_mode);
+       err = __ieee80211_request_smps_mgd(sdata, 0, smps_mode);
        sdata_unlock(sdata);
 
        return err;
index 22677df83ed8b35e287cff2436bda3f66d4eaf54..111828b559a025b433c3dae27fa8aaaacea9f312 100644 (file)
@@ -542,30 +542,33 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
 
 void ieee80211_request_smps_mgd_work(struct work_struct *work)
 {
-       struct ieee80211_sub_if_data *sdata =
-               container_of(work, struct ieee80211_sub_if_data,
-                            deflink.u.mgd.request_smps_work);
-
-       sdata_lock(sdata);
-       __ieee80211_request_smps_mgd(sdata,
-                                    sdata->deflink.u.mgd.driver_smps_mode);
-       sdata_unlock(sdata);
+       struct ieee80211_link_data *link =
+               container_of(work, struct ieee80211_link_data,
+                            u.mgd.request_smps_work);
+
+       sdata_lock(link->sdata);
+       __ieee80211_request_smps_mgd(link->sdata, link->link_id,
+                                    link->u.mgd.driver_smps_mode);
+       sdata_unlock(link->sdata);
 }
 
-void ieee80211_request_smps(struct ieee80211_vif *vif,
+void ieee80211_request_smps(struct ieee80211_vif *vif, unsigned int link_id,
                            enum ieee80211_smps_mode smps_mode)
 {
        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+       struct ieee80211_link_data *link = sdata->link[link_id];
 
        if (WARN_ON_ONCE(vif->type != NL80211_IFTYPE_STATION))
                return;
 
-       if (sdata->deflink.u.mgd.driver_smps_mode == smps_mode)
+       if (WARN_ON(!link))
                return;
 
-       sdata->deflink.u.mgd.driver_smps_mode = smps_mode;
-       ieee80211_queue_work(&sdata->local->hw,
-                            &sdata->deflink.u.mgd.request_smps_work);
+       if (link->u.mgd.driver_smps_mode == smps_mode)
+               return;
+
+       link->u.mgd.driver_smps_mode = smps_mode;
+       ieee80211_queue_work(&sdata->local->hw, &link->u.mgd.request_smps_work);
 }
 /* this might change ... don't want non-open drivers using it */
 EXPORT_SYMBOL_GPL(ieee80211_request_smps);
index e75496a99299e09bca4cf0ee4d1f73df99574af2..0948d074c4b9bfa608dd847715f78558ae99e457 100644 (file)
@@ -2422,8 +2422,10 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
                            struct ieee802_11_elems *elems,
                            enum nl80211_band band, u32 *basic_rates);
 int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
+                                unsigned int link_id,
                                 enum ieee80211_smps_mode smps_mode);
-void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata);
+void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata,
+                          unsigned int link_id);
 void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata);
 
 size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
index c5be60ee12d884ac834fbbc15359d93a771a07e7..ea75d5d5cb6afe7c911159a2c6e9bdfd133efa35 100644 (file)
@@ -1657,7 +1657,7 @@ static void ieee80211_recalc_smps_work(struct work_struct *work)
        struct ieee80211_sub_if_data *sdata =
                container_of(work, struct ieee80211_sub_if_data, recalc_smps);
 
-       ieee80211_recalc_smps(sdata);
+       ieee80211_recalc_smps(sdata, 0);
 }
 
 /*
index 30423b2d4eee5bd15ba33a5eff336450c5a6f52f..cdbf7a5dc2ba759cf396d9bb28c2b15c671c6e70 100644 (file)
@@ -2337,7 +2337,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
        ieee80211_recalc_ps(local);
        mutex_unlock(&local->iflist_mtx);
 
-       ieee80211_recalc_smps(sdata);
+       ieee80211_recalc_smps(sdata, 0);
        ieee80211_recalc_ps_vif(sdata);
 
        netif_carrier_on(sdata->dev);
index 4ec96170a67937df3fcad28d086a3d92ac8c5eca..ecda655e748146613ee64e3f77678e241e984bc1 100644 (file)
@@ -2803,7 +2803,8 @@ void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
 }
 EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect);
 
-void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata)
+void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata,
+                          unsigned int link_id)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_chanctx_conf *chanctx_conf;
@@ -2811,7 +2812,7 @@ void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata)
 
        mutex_lock(&local->chanctx_mtx);
 
-       chanctx_conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf,
+       chanctx_conf = rcu_dereference_protected(sdata->vif.link_conf[link_id]->chanctx_conf,
                                                 lockdep_is_held(&local->chanctx_mtx));
 
        /*