Commit ee95ed37 authored by Avri Altman's avatar Avri Altman Committed by Emmanuel Grumbach
Browse files

iwlwifi: mvm: Add P2P client snoozing



Enable snoozing and U-APSD on P2P client. The firwmare will
support this only if the BSS vif is not associated.
Make this configurable by a constant variable and disable
it by default.

Signed-off-by: default avatarAvri Altman <avri.altman@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 25657fec
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -302,6 +302,7 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
 * @IWL_UCODE_TLV_CAPA_DC2DC_SUPPORT: supports DC2DC Command
 * @IWL_UCODE_TLV_CAPA_CSUM_SUPPORT: supports TCP Checksum Offload
 * @IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS: support radio and beacon statistics
 * @IWL_UCODE_TLV_CAPA_P2P_STANDALONE_UAPSD: support p2p standalone U-APSD
 * @IWL_UCODE_TLV_CAPA_BT_COEX_PLCR: enabled BT Coex packet level co-running
 * @IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC: ucode supports LAR updates with different
 *	sources for the MCC. This TLV bit is a future replacement to
@@ -336,6 +337,7 @@ enum iwl_ucode_tlv_capa {
	IWL_UCODE_TLV_CAPA_DC2DC_CONFIG_SUPPORT		= (__force iwl_ucode_tlv_capa_t)19,
	IWL_UCODE_TLV_CAPA_CSUM_SUPPORT			= (__force iwl_ucode_tlv_capa_t)21,
	IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS		= (__force iwl_ucode_tlv_capa_t)22,
	IWL_UCODE_TLV_CAPA_P2P_STANDALONE_UAPSD		= (__force iwl_ucode_tlv_capa_t)26,
	IWL_UCODE_TLV_CAPA_BT_COEX_PLCR			= (__force iwl_ucode_tlv_capa_t)28,
	IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC		= (__force iwl_ucode_tlv_capa_t)29,
	IWL_UCODE_TLV_CAPA_BT_COEX_RRC			= (__force iwl_ucode_tlv_capa_t)30,
+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@
#define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT	(10 * USEC_PER_MSEC)
#define IWL_MVM_SHORT_PS_TX_DATA_TIMEOUT	(2 * 1024) /* defined in TU */
#define IWL_MVM_SHORT_PS_RX_DATA_TIMEOUT	(40 * 1024) /* defined in TU */
#define IWL_MVM_P2P_UAPSD_STANDALONE		0
#define IWL_MVM_P2P_LOWLATENCY_PS_ENABLE	0
#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT		(50 * USEC_PER_MSEC)
#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT		(50 * USEC_PER_MSEC)
+8 −0
Original line number Diff line number Diff line
@@ -1005,6 +1005,14 @@ static inline bool iwl_mvm_is_mplut_supported(struct iwl_mvm *mvm)
		IWL_MVM_BT_COEX_MPLUT;
}

static inline
bool iwl_mvm_is_p2p_standalone_uapsd_supported(struct iwl_mvm *mvm)
{
	return fw_has_capa(&mvm->fw->ucode_capa,
			   IWL_UCODE_TLV_CAPA_P2P_STANDALONE_UAPSD) &&
		IWL_MVM_P2P_UAPSD_STANDALONE;
}

static inline bool iwl_mvm_has_new_rx_api(struct iwl_mvm *mvm)
{
	/* firmware flag isn't defined yet */
+36 −3
Original line number Diff line number Diff line
@@ -259,6 +259,26 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
		IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
}

static void iwl_mvm_p2p_standalone_iterator(void *_data, u8 *mac,
					    struct ieee80211_vif *vif)
{
	bool *is_p2p_standalone = _data;

	switch (ieee80211_vif_type_p2p(vif)) {
	case NL80211_IFTYPE_P2P_GO:
	case NL80211_IFTYPE_AP:
		*is_p2p_standalone = false;
		break;
	case NL80211_IFTYPE_STATION:
		if (vif->bss_conf.assoc)
			*is_p2p_standalone = false;
		break;

	default:
		break;
	}
}

static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
				       struct ieee80211_vif *vif)
{
@@ -268,9 +288,6 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
		    ETH_ALEN))
		return false;

	if (vif->p2p &&
	    !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD))
		return false;
	/*
	 * Avoid using uAPSD if P2P client is associated to GO that uses
	 * opportunistic power save. This is due to current FW limitation.
@@ -287,6 +304,22 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
	if (iwl_mvm_phy_ctx_count(mvm) >= 2)
		return false;

	if (vif->p2p) {
		/* Allow U-APSD only if p2p is stand alone */
		bool is_p2p_standalone = true;

		if (!iwl_mvm_is_p2p_standalone_uapsd_supported(mvm))
			return false;

		ieee80211_iterate_active_interfaces_atomic(mvm->hw,
					IEEE80211_IFACE_ITER_NORMAL,
					iwl_mvm_p2p_standalone_iterator,
					&is_p2p_standalone);

		if (!is_p2p_standalone)
			return false;
	}

	return true;
}