iwlwifi: mvm: Implement low-priority scan
authorHaim Dreyfuss <haim.dreyfuss@intel.com>
Sun, 3 Nov 2013 21:02:59 +0000 (23:02 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 9 Dec 2013 20:29:45 +0000 (22:29 +0200)
Advertise driver's support for low priority scan.
Notice that this overwrites current setting by mac80211 which depends
only on hw scan support.
This scan priority  can be configured by user space application
and it affects scan continuity, low priority scan
will be more fragmented scan.

Signed-off-by: Haim Dreyfuss <haim.dreyfuss@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/scan.c

index 6b3273d82157a64c491df82eb12a182c0edc0927..afc4419be46dd1eaff2f1b419dae01e4b231b1cb 100644 (file)
@@ -256,7 +256,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
        }
 
        hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
-                              NL80211_FEATURE_P2P_GO_OPPPS;
+                              NL80211_FEATURE_P2P_GO_OPPPS |
+                              NL80211_FEATURE_LOW_PRIORITY_SCAN;
 
        mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
 
index 67d7b8defa0d8d66fb8e70db04210a0c9a87dedd..4ce9bb581144e4a64c8842980e41e0097a4da6e9 100644 (file)
@@ -70,6 +70,9 @@
 
 #define IWL_PLCP_QUIET_THRESH 1
 #define IWL_ACTIVE_QUIET_TIME 10
+#define LONG_OUT_TIME_PERIOD 600
+#define SHORT_OUT_TIME_PERIOD 200
+#define SUSPEND_TIME_PERIOD 100
 
 static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
 {
@@ -87,20 +90,22 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
        return cpu_to_le16(rx_chain);
 }
 
-static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif)
+static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif,
+                                              u32 flags, bool is_assoc)
 {
-       if (vif->bss_conf.assoc)
-               return cpu_to_le32(200 * 1024);
-       else
+       if (!is_assoc)
                return 0;
+       if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
+               return cpu_to_le32(ieee80211_tu_to_usec(SHORT_OUT_TIME_PERIOD));
+       return cpu_to_le32(ieee80211_tu_to_usec(LONG_OUT_TIME_PERIOD));
 }
 
-static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif)
+static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif,
+                                              bool is_assoc)
 {
-       if (!vif->bss_conf.assoc)
+       if (!is_assoc)
                return 0;
-
-       return cpu_to_le32(ieee80211_tu_to_usec(vif->bss_conf.beacon_int));
+       return cpu_to_le32(ieee80211_tu_to_usec(SUSPEND_TIME_PERIOD));
 }
 
 static inline __le32
@@ -262,6 +267,15 @@ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
        return (u16)len;
 }
 
+static void iwl_mvm_vif_assoc_iterator(void *data, u8 *mac,
+                                      struct ieee80211_vif *vif)
+{
+       bool *is_assoc = data;
+
+       if (vif->bss_conf.assoc)
+               *is_assoc = true;
+}
+
 int iwl_mvm_scan_request(struct iwl_mvm *mvm,
                         struct ieee80211_vif *vif,
                         struct cfg80211_scan_request *req)
@@ -274,6 +288,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
                .dataflags = { IWL_HCMD_DFL_NOCOPY, },
        };
        struct iwl_scan_cmd *cmd = mvm->scan_cmd;
+       bool is_assoc = false;
        int ret;
        u32 status;
        int ssid_len = 0;
@@ -289,13 +304,17 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
        memset(cmd, 0, sizeof(struct iwl_scan_cmd) +
               mvm->fw->ucode_capa.max_probe_length +
               (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)));
-
+       ieee80211_iterate_active_interfaces_atomic(mvm->hw,
+                                           IEEE80211_IFACE_ITER_NORMAL,
+                                           iwl_mvm_vif_assoc_iterator,
+                                           &is_assoc);
        cmd->channel_count = (u8)req->n_channels;
        cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
        cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
        cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
-       cmd->max_out_time = iwl_mvm_scan_max_out_time(vif);
-       cmd->suspend_time = iwl_mvm_scan_suspend_time(vif);
+       cmd->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags,
+                                                     is_assoc);
+       cmd->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc);
        cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
        cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
                                        MAC_FILTER_IN_BEACON);
@@ -522,6 +541,12 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
                               struct cfg80211_sched_scan_request *req,
                               struct iwl_scan_offload_cmd *scan)
 {
+       bool is_assoc = false;
+
+       ieee80211_iterate_active_interfaces_atomic(mvm->hw,
+                                           IEEE80211_IFACE_ITER_NORMAL,
+                                           iwl_mvm_vif_assoc_iterator,
+                                           &is_assoc);
        scan->channel_count =
                mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
                mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
@@ -529,8 +554,9 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
        scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
        scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
        scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
-       scan->max_out_time = cpu_to_le32(200 * 1024);
-       scan->suspend_time = iwl_mvm_scan_suspend_time(vif);
+       scan->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags,
+                                                      is_assoc);
+       scan->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc);
        scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
                                          MAC_FILTER_IN_BEACON);
        scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);