iwlwifi: mvm: enable passive fragmented scan changes
authorDavid Spinadel <david.spinadel@intel.com>
Tue, 22 Jul 2014 10:11:18 +0000 (13:11 +0300)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Wed, 3 Sep 2014 19:49:02 +0000 (22:49 +0300)
Enable fragmented scan that was diabled due to a FW bug.
New fixed FWs use a TLV bit to advertise fragmented scan support.

Signed-off-by: David Spinadel <david.spinadel@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/iwl-fw.h
drivers/net/wireless/iwlwifi/mvm/scan.c

index 1bb5193c5b1b5097c11bbf5a986f4c4d6e409c58..99e0ec4635eec971de6dbfa783511bda393bde5f 100644 (file)
@@ -125,6 +125,8 @@ enum iwl_ucode_tlv_flag {
  * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
  * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
  * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
+ * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
+ *     longer than the passive one, which is essential for fragmented scan.
  */
 enum iwl_ucode_tlv_api {
        IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID     = BIT(0),
@@ -133,6 +135,7 @@ enum iwl_ucode_tlv_api {
        IWL_UCODE_TLV_API_CSA_FLOW              = BIT(4),
        IWL_UCODE_TLV_API_DISABLE_STA_TX        = BIT(5),
        IWL_UCODE_TLV_API_LMAC_SCAN             = BIT(6),
+       IWL_UCODE_TLV_API_FRAGMENTED_SCAN       = BIT(8),
 };
 
 /**
index 004b1f5d031429a2798cc1d35464daa6ae59db00..d01954dcc75d2a90d4dc9566b47156d44868aa9f 100644 (file)
@@ -279,6 +279,7 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
 {
        bool global_bound = false;
        enum ieee80211_band band;
+       u8 frag_passive_dwell = 0;
 
        ieee80211_iterate_active_interfaces_atomic(mvm->hw,
                                            IEEE80211_IFACE_ITER_NORMAL,
@@ -288,12 +289,36 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
        if (!global_bound)
                goto not_bound;
 
-       params->suspend_time = 100;
-       params->max_out_time = 600;
+       params->suspend_time = 30;
+       params->max_out_time = 170;
 
        if (iwl_mvm_low_latency(mvm)) {
-               params->suspend_time = 250;
-               params->max_out_time = 250;
+               if (mvm->fw->ucode_capa.api[0] &
+                   IWL_UCODE_TLV_API_FRAGMENTED_SCAN) {
+                       params->suspend_time = 105;
+                       params->max_out_time = 70;
+                       frag_passive_dwell = 20;
+               } else {
+                       params->suspend_time = 120;
+                       params->max_out_time = 120;
+               }
+       }
+
+       if (frag_passive_dwell && (mvm->fw->ucode_capa.api[0] &
+                                  IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) {
+               /*
+                * P2P device scan should not be fragmented to avoid negative
+                * impact on P2P device discovery. Configure max_out_time to be
+                * equal to dwell time on passive channel. Take a longest
+                * possible value, one that corresponds to 2GHz band
+                */
+               if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
+                       u32 passive_dwell =
+                               iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ);
+                       params->max_out_time = passive_dwell;
+               } else {
+                       params->passive_fragmented = true;
+               }
        }
 
        if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
@@ -302,7 +327,11 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
 not_bound:
 
        for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
-               params->dwell[band].passive = iwl_mvm_get_passive_dwell(band);
+               if (params->passive_fragmented)
+                       params->dwell[band].passive = frag_passive_dwell;
+               else
+                       params->dwell[band].passive =
+                               iwl_mvm_get_passive_dwell(band);
                params->dwell[band].active = iwl_mvm_get_active_dwell(band,
                                                                      n_ssids);
        }
@@ -1100,10 +1129,11 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
                                       struct iwl_mvm_scan_params *params)
 {
        memset(cmd, 0, ksize(cmd));
-       cmd->active_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].active;
-       cmd->passive_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].passive;
-       /* TODO: Use params; now fragmented isn't used. */
-       cmd->fragmented_dwell = 0;
+       cmd->active_dwell = params->dwell[IEEE80211_BAND_2GHZ].active;
+       cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive;
+       if (params->passive_fragmented)
+               cmd->fragmented_dwell =
+                               params->dwell[IEEE80211_BAND_2GHZ].passive;
        cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
        cmd->max_out_time = cpu_to_le32(params->max_out_time);
        cmd->suspend_time = cpu_to_le32(params->suspend_time);