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;
 
                       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__ */
 
        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;
 }
 
 {
        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;
        }
 
        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)) {
 
                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;
+}