wifi: iwlwifi: mvm: adjust some PS and PM methods to MLD
authorGregory Greenman <gregory.greenman@intel.com>
Tue, 28 Mar 2023 07:58:58 +0000 (10:58 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 30 Mar 2023 10:07:54 +0000 (12:07 +0200)
When using mvm vif PS/PM related properties, consider all links.

Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230328104949.8d9e18f7d74b.I048fc17405ecdddc1f6fe72859013cc4878b2a3b@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/power.c
drivers/net/wireless/intel/iwlwifi/mvm/utils.c

index d9caf32..2989285 100644 (file)
@@ -1278,8 +1278,8 @@ struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
        return NULL;
 }
 
-static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
-                               s16 tx_power)
+int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+                        s16 tx_power)
 {
        u32 cmd_id = REDUCE_TX_POWER_CMD;
        int len;
index 9c5e772..ae9c165 100644 (file)
@@ -2599,4 +2599,10 @@ int iwl_mvm_start_pmsr(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                       struct cfg80211_pmsr_request *request);
 void iwl_mvm_abort_pmsr(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        struct cfg80211_pmsr_request *request);
+
+bool iwl_mvm_have_links_same_channel(struct iwl_mvm_vif *vif1,
+                                    struct iwl_mvm_vif *vif2);
+bool iwl_mvm_vif_is_active(struct iwl_mvm_vif *mvmvif);
+int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+                        s16 tx_power);
 #endif /* __IWL_MVM_H__ */
index 6e2e312..45a652c 100644 (file)
@@ -553,8 +553,7 @@ static void iwl_mvm_power_ps_disabled_iterator(void *_data, u8* mac,
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        bool *disable_ps = _data;
 
-       if (mvmvif->deflink.phy_ctxt &&
-           mvmvif->deflink.phy_ctxt->id < NUM_PHY_CTX)
+       if (iwl_mvm_vif_is_active(mvmvif))
                *disable_ps |= mvmvif->ps_disabled;
 }
 
@@ -563,11 +562,13 @@ static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac,
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        struct iwl_power_vifs *power_iterator = _data;
-       bool active = mvmvif->deflink.phy_ctxt && mvmvif->deflink.phy_ctxt->id < NUM_PHY_CTX;
+       bool active;
 
        if (!mvmvif->uploaded)
                return;
 
+       active = iwl_mvm_vif_is_active(mvmvif);
+
        switch (ieee80211_vif_type_p2p(vif)) {
        case NL80211_IFTYPE_P2P_DEVICE:
                break;
@@ -651,11 +652,12 @@ static void iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
        }
 
        if (vifs->bss_active && vifs->p2p_active)
-               client_same_channel = (bss_mvmvif->deflink.phy_ctxt->id ==
-                                      p2p_mvmvif->deflink.phy_ctxt->id);
+               client_same_channel =
+                       iwl_mvm_have_links_same_channel(bss_mvmvif, p2p_mvmvif);
+
        if (vifs->bss_active && vifs->ap_active)
-               ap_same_channel = (bss_mvmvif->deflink.phy_ctxt->id ==
-                                  ap_mvmvif->deflink.phy_ctxt->id);
+               ap_same_channel =
+                       iwl_mvm_have_links_same_channel(bss_mvmvif, ap_mvmvif);
 
        /* clients are not stand alone: enable PM if DCM */
        if (!(client_same_channel || ap_same_channel)) {
index c1f6dd8..026856c 100644 (file)
@@ -1138,3 +1138,36 @@ void iwl_mvm_get_sync_time(struct iwl_mvm *mvm, int clock_type,
                iwl_mvm_power_update_device(mvm);
        }
 }
+
+/* Find if at least two links from different vifs use same channel
+ * FIXME: consider having a refcount array in struct iwl_mvm_vif for
+ * used phy_ctxt ids.
+ */
+bool iwl_mvm_have_links_same_channel(struct iwl_mvm_vif *vif1,
+                                    struct iwl_mvm_vif *vif2)
+{
+       unsigned int i, j;
+
+       for_each_mvm_vif_valid_link(vif1, i) {
+               for_each_mvm_vif_valid_link(vif2, j) {
+                       if (vif1->link[i]->phy_ctxt == vif2->link[j]->phy_ctxt)
+                               return true;
+               }
+       }
+
+       return false;
+}
+
+bool iwl_mvm_vif_is_active(struct iwl_mvm_vif *mvmvif)
+{
+       unsigned int i;
+
+       /* FIXME: can it fail when phy_ctxt is assigned? */
+       for_each_mvm_vif_valid_link(mvmvif, i) {
+               if (mvmvif->link[i]->phy_ctxt &&
+                   mvmvif->link[i]->phy_ctxt->id < NUM_PHY_CTX)
+                       return true;
+       }
+
+       return false;
+}