aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm
diff options
context:
space:
mode:
authorHaim Dreyfuss <haim.dreyfuss@intel.com>2013-11-03 16:02:59 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2013-12-09 15:29:45 -0500
commit61f6325d3e453fc3523d5891f9641d0af5e3ceaf (patch)
tree9642a56fc738b32f153c5710c789e54c7f277c41 /drivers/net/wireless/iwlwifi/mvm
parentde33fb5e80a62a3dfb50ab4d498db9b978c6c07f (diff)
iwlwifi: mvm: Implement low-priority scan
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>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c52
2 files changed, 41 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 6b3273d82157..afc4419be46d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -256,7 +256,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
256 } 256 }
257 257
258 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | 258 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
259 NL80211_FEATURE_P2P_GO_OPPPS; 259 NL80211_FEATURE_P2P_GO_OPPPS |
260 NL80211_FEATURE_LOW_PRIORITY_SCAN;
260 261
261 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 262 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
262 263
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 67d7b8defa0d..4ce9bb581144 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -70,6 +70,9 @@
70 70
71#define IWL_PLCP_QUIET_THRESH 1 71#define IWL_PLCP_QUIET_THRESH 1
72#define IWL_ACTIVE_QUIET_TIME 10 72#define IWL_ACTIVE_QUIET_TIME 10
73#define LONG_OUT_TIME_PERIOD 600
74#define SHORT_OUT_TIME_PERIOD 200
75#define SUSPEND_TIME_PERIOD 100
73 76
74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 77static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
75{ 78{
@@ -87,20 +90,22 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
87 return cpu_to_le16(rx_chain); 90 return cpu_to_le16(rx_chain);
88} 91}
89 92
90static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif) 93static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif,
94 u32 flags, bool is_assoc)
91{ 95{
92 if (vif->bss_conf.assoc) 96 if (!is_assoc)
93 return cpu_to_le32(200 * 1024);
94 else
95 return 0; 97 return 0;
98 if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
99 return cpu_to_le32(ieee80211_tu_to_usec(SHORT_OUT_TIME_PERIOD));
100 return cpu_to_le32(ieee80211_tu_to_usec(LONG_OUT_TIME_PERIOD));
96} 101}
97 102
98static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif) 103static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif,
104 bool is_assoc)
99{ 105{
100 if (!vif->bss_conf.assoc) 106 if (!is_assoc)
101 return 0; 107 return 0;
102 108 return cpu_to_le32(ieee80211_tu_to_usec(SUSPEND_TIME_PERIOD));
103 return cpu_to_le32(ieee80211_tu_to_usec(vif->bss_conf.beacon_int));
104} 109}
105 110
106static inline __le32 111static inline __le32
@@ -262,6 +267,15 @@ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
262 return (u16)len; 267 return (u16)len;
263} 268}
264 269
270static void iwl_mvm_vif_assoc_iterator(void *data, u8 *mac,
271 struct ieee80211_vif *vif)
272{
273 bool *is_assoc = data;
274
275 if (vif->bss_conf.assoc)
276 *is_assoc = true;
277}
278
265int iwl_mvm_scan_request(struct iwl_mvm *mvm, 279int iwl_mvm_scan_request(struct iwl_mvm *mvm,
266 struct ieee80211_vif *vif, 280 struct ieee80211_vif *vif,
267 struct cfg80211_scan_request *req) 281 struct cfg80211_scan_request *req)
@@ -274,6 +288,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
274 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 288 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
275 }; 289 };
276 struct iwl_scan_cmd *cmd = mvm->scan_cmd; 290 struct iwl_scan_cmd *cmd = mvm->scan_cmd;
291 bool is_assoc = false;
277 int ret; 292 int ret;
278 u32 status; 293 u32 status;
279 int ssid_len = 0; 294 int ssid_len = 0;
@@ -289,13 +304,17 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
289 memset(cmd, 0, sizeof(struct iwl_scan_cmd) + 304 memset(cmd, 0, sizeof(struct iwl_scan_cmd) +
290 mvm->fw->ucode_capa.max_probe_length + 305 mvm->fw->ucode_capa.max_probe_length +
291 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel))); 306 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)));
292 307 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
308 IEEE80211_IFACE_ITER_NORMAL,
309 iwl_mvm_vif_assoc_iterator,
310 &is_assoc);
293 cmd->channel_count = (u8)req->n_channels; 311 cmd->channel_count = (u8)req->n_channels;
294 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); 312 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
295 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 313 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
296 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm); 314 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
297 cmd->max_out_time = iwl_mvm_scan_max_out_time(vif); 315 cmd->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags,
298 cmd->suspend_time = iwl_mvm_scan_suspend_time(vif); 316 is_assoc);
317 cmd->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc);
299 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req); 318 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
300 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 319 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
301 MAC_FILTER_IN_BEACON); 320 MAC_FILTER_IN_BEACON);
@@ -522,6 +541,12 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
522 struct cfg80211_sched_scan_request *req, 541 struct cfg80211_sched_scan_request *req,
523 struct iwl_scan_offload_cmd *scan) 542 struct iwl_scan_offload_cmd *scan)
524{ 543{
544 bool is_assoc = false;
545
546 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
547 IEEE80211_IFACE_ITER_NORMAL,
548 iwl_mvm_vif_assoc_iterator,
549 &is_assoc);
525 scan->channel_count = 550 scan->channel_count =
526 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels + 551 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
527 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 552 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
@@ -529,8 +554,9 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
529 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 554 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
530 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT; 555 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
531 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm); 556 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
532 scan->max_out_time = cpu_to_le32(200 * 1024); 557 scan->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags,
533 scan->suspend_time = iwl_mvm_scan_suspend_time(vif); 558 is_assoc);
559 scan->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc);
534 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 560 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
535 MAC_FILTER_IN_BEACON); 561 MAC_FILTER_IN_BEACON);
536 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND); 562 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);