iwlwifi: disable PSM on vifs with associated TDLS peers

The FW does not support PSM on a vif with associated TDLS peers. Disable
PSM when the first peer joins and re-enable it when the last leaves.

Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 3b582dd..2b2d108 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -483,6 +483,7 @@
 }
 
 struct iwl_power_vifs {
+	struct iwl_mvm *mvm;
 	struct ieee80211_vif *bf_vif;
 	struct ieee80211_vif *bss_vif;
 	struct ieee80211_vif *p2p_vif;
@@ -492,6 +493,8 @@
 	bool bss_active;
 	bool ap_active;
 	bool monitor_active;
+	bool bss_tdls;
+	bool p2p_tdls;
 };
 
 static void iwl_mvm_power_iterator(void *_data, u8 *mac,
@@ -528,6 +531,8 @@
 		/* only a single MAC of the same type */
 		WARN_ON(power_iterator->p2p_vif);
 		power_iterator->p2p_vif = vif;
+		power_iterator->p2p_tdls =
+			!!iwl_mvm_tdls_sta_count(power_iterator->mvm, vif);
 		if (mvmvif->phy_ctxt)
 			if (mvmvif->phy_ctxt->id < MAX_PHYS)
 				power_iterator->p2p_active = true;
@@ -537,6 +542,8 @@
 		/* only a single MAC of the same type */
 		WARN_ON(power_iterator->bss_vif);
 		power_iterator->bss_vif = vif;
+		power_iterator->bss_tdls =
+			!!iwl_mvm_tdls_sta_count(power_iterator->mvm, vif);
 		if (mvmvif->phy_ctxt)
 			if (mvmvif->phy_ctxt->id < MAX_PHYS)
 				power_iterator->bss_active = true;
@@ -579,13 +586,15 @@
 		ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif);
 
 	/* enable PM on bss if bss stand alone */
-	if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active) {
+	if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active &&
+	    !vifs->bss_tdls) {
 		bss_mvmvif->pm_enabled = true;
 		return;
 	}
 
 	/* enable PM on p2p if p2p stand alone */
-	if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active) {
+	if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active &&
+	    !vifs->p2p_tdls) {
 		if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PM)
 			p2p_mvmvif->pm_enabled = true;
 		return;
@@ -811,7 +820,9 @@
 int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
 {
 	struct iwl_mvm_vif *mvmvif;
-	struct iwl_power_vifs vifs = {};
+	struct iwl_power_vifs vifs = {
+		.mvm = mvm,
+	};
 	bool ba_enable;
 	int ret;