iwlwifi: mvm: Add P2P client snoozing
authorAvri Altman <avri.altman@intel.com>
Wed, 25 Nov 2015 11:17:10 +0000 (13:17 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 1 Feb 2016 14:40:20 +0000 (16:40 +0200)
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: Avri Altman <avri.altman@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
drivers/net/wireless/intel/iwlwifi/mvm/constants.h
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/power.c

index 4050b4af7e4565240880ae27525c38b8536c104f..dbf08c4936544fade60b9d650b89e9e59c22dcc8 100644 (file)
@@ -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,
index b00c03fcd4473cc670cd1489c3504c767de62c65..959fc4d33d160b6f59489b0afdc0211f11a767c7 100644 (file)
@@ -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)
index 5f3ac8cccf49d2c5a07644f894b1ba920dca8bfc..5a92ab1b37872a622fee26a5ae76b9acb7b60200 100644 (file)
@@ -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 */
index 9de159f1ef2dd366fbfeb67a75c1547952a26087..16b3e36fb1ba7cd9ad6d7a108c996d4a15b266bf 100644 (file)
@@ -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;
 }