* @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
  * @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command
  *     containing CAM (Continuous Active Mode) indication.
- * @IWL_UCODE_TLV_FLAGS_P2P_PS: P2P client power save is supported (only on a
- *     single bound interface).
+ * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and
+ *     P2P client interfaces simultaneously if they are in different bindings.
  * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
  * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
  * @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
        IWL_UCODE_TLV_FLAGS_SCHED_SCAN          = BIT(17),
        IWL_UCODE_TLV_FLAGS_STA_KEY_CMD         = BIT(19),
        IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD       = BIT(20),
-       IWL_UCODE_TLV_FLAGS_P2P_PS              = BIT(21),
+       IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM      = BIT(22),
        IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT       = BIT(24),
        IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD        = BIT(26),
        IWL_UCODE_TLV_FLAGS_BCAST_FILTERING     = BIT(29),
 
        mvmvif->ap_ibss_active = true;
 
        /* power updated needs to be done before quotas */
-       mvm->bound_vif_cnt++;
        iwl_mvm_power_update_mac(mvm, vif);
 
        ret = iwl_mvm_update_quotas(mvm, vif);
        return 0;
 
 out_quota_failed:
-       mvm->bound_vif_cnt--;
        iwl_mvm_power_update_mac(mvm, vif);
        mvmvif->ap_ibss_active = false;
        iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
        iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
        iwl_mvm_binding_remove_vif(mvm, vif);
 
-       mvm->bound_vif_cnt--;
        iwl_mvm_power_update_mac(mvm, vif);
 
        iwl_mvm_mac_ctxt_remove(mvm, vif);
         * Power state must be updated before quotas,
         * otherwise fw will complain.
         */
-       mvm->bound_vif_cnt++;
        iwl_mvm_power_update_mac(mvm, vif);
 
        /* Setting the quota at this stage is only required for monitor
 
  out_remove_binding:
        iwl_mvm_binding_remove_vif(mvm, vif);
-       mvm->bound_vif_cnt--;
        iwl_mvm_power_update_mac(mvm, vif);
  out_unlock:
        mutex_unlock(&mvm->mutex);
        }
 
        iwl_mvm_binding_remove_vif(mvm, vif);
-       mvm->bound_vif_cnt--;
        iwl_mvm_power_update_mac(mvm, vif);
 
 out_unlock:
 
                return 0;
 
        if (vif->p2p &&
-           !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))
+           !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM))
                return 0;
 
        iwl_mvm_power_build_cmd(mvm, vif, &cmd);
 struct iwl_power_constraint {
        struct ieee80211_vif *bf_vif;
        struct ieee80211_vif *bss_vif;
+       u16 bss_phyctx_id;
+       u16 p2p_phyctx_id;
        bool pm_disabled;
        bool ps_disabled;
+       struct iwl_mvm *mvm;
 };
 
 static void iwl_mvm_power_iterator(void *_data, u8 *mac,
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        struct iwl_power_constraint *power_iterator = _data;
+       struct iwl_mvm *mvm = power_iterator->mvm;
 
        switch (ieee80211_vif_type_p2p(vif)) {
        case NL80211_IFTYPE_P2P_DEVICE:
                break;
 
        case NL80211_IFTYPE_P2P_CLIENT:
-               /* no BSS power mgmt if we have a P2P client*/
-               power_iterator->pm_disabled = true;
+               if (mvmvif->phy_ctxt)
+                       power_iterator->p2p_phyctx_id = mvmvif->phy_ctxt->id;
+
+               IWL_DEBUG_POWER(mvm, "p2p: p2p_id=%d, bss_id=%d\n",
+                               power_iterator->p2p_phyctx_id,
+                               power_iterator->bss_phyctx_id);
+               if (!(mvm->fw->ucode_capa.flags &
+                     IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)) {
+                       /* no BSS power mgmt if we have a P2P client*/
+                       power_iterator->pm_disabled = true;
+               } else if (power_iterator->p2p_phyctx_id < MAX_PHYS &&
+                          power_iterator->bss_phyctx_id < MAX_PHYS &&
+                          power_iterator->p2p_phyctx_id ==
+                          power_iterator->bss_phyctx_id) {
+                       power_iterator->pm_disabled = true;
+               }
                break;
 
        case NL80211_IFTYPE_STATION:
+               if (mvmvif->phy_ctxt)
+                       power_iterator->bss_phyctx_id = mvmvif->phy_ctxt->id;
+
                /* we should have only one BSS vif */
                WARN_ON(power_iterator->bss_vif);
                power_iterator->bss_vif = vif;
                if (mvmvif->bf_data.bf_enabled &&
                    !WARN_ON(power_iterator->bf_vif))
                        power_iterator->bf_vif = vif;
+
+               IWL_DEBUG_POWER(mvm, "bss: p2p_id=%d, bss_id=%d\n",
+                               power_iterator->p2p_phyctx_id,
+                               power_iterator->bss_phyctx_id);
+               if (mvm->fw->ucode_capa.flags &
+                   IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM &&
+                       (power_iterator->p2p_phyctx_id < MAX_PHYS &&
+                        power_iterator->bss_phyctx_id < MAX_PHYS &&
+                        power_iterator->p2p_phyctx_id ==
+                        power_iterator->bss_phyctx_id))
+                       power_iterator->pm_disabled = true;
                break;
 
        default:
        ieee80211_iterate_active_interfaces_atomic(mvm->hw,
                                            IEEE80211_IFACE_ITER_NORMAL,
                                            iwl_mvm_power_iterator, constraint);
-
-       /* TODO: remove this and determine this variable in the iterator */
-       if (mvm->bound_vif_cnt > 1)
-               constraint->pm_disabled = true;
 }
 
 int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       struct iwl_power_constraint constraint = {};
+       struct iwl_power_constraint constraint = {
+                   .p2p_phyctx_id = MAX_PHYS,
+                   .bss_phyctx_id = MAX_PHYS,
+                   .mvm = mvm,
+       };
        bool ba_enable;
        int ret;