aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-06-19 16:52:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 15:01:56 -0400
commit4e05c2347a50f1d0892ff3475d7609eec428f781 (patch)
tree023ecf1104a7b819d08d11a02517eb8488999213
parent45af81956e990440fe78d6d41f847664cb620609 (diff)
iwlwifi: scan requested channels only
When userspace requests only certain channels to be scanned, we currently ignore that request entirely. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c14
3 files changed, 21 insertions, 26 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index dabf663e36e5..356d4e3aec7e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -384,7 +384,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
384void iwl_init_scan_params(struct iwl_priv *priv); 384void iwl_init_scan_params(struct iwl_priv *priv);
385int iwl_scan_cancel(struct iwl_priv *priv); 385int iwl_scan_cancel(struct iwl_priv *priv);
386int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); 386int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
387int iwl_scan_initiate(struct iwl_priv *priv);
388int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); 387int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
389u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, 388u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
390 const u8 *ie, int ie_len, int left); 389 const u8 *ie, int ie_len, int left);
@@ -398,7 +397,6 @@ void iwl_bg_scan_check(struct work_struct *data);
398void iwl_bg_abort_scan(struct work_struct *work); 397void iwl_bg_abort_scan(struct work_struct *work);
399void iwl_bg_scan_completed(struct work_struct *work); 398void iwl_bg_scan_completed(struct work_struct *work);
400void iwl_setup_scan_deferred_work(struct iwl_priv *priv); 399void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
401int iwl_send_scan_abort(struct iwl_priv *priv);
402 400
403/* For faster active scanning, scan will move to the next channel if fewer than 401/* For faster active scanning, scan will move to the next channel if fewer than
404 * PLCP_QUIET_THRESH packets are heard on this channel within 402 * PLCP_QUIET_THRESH packets are heard on this channel within
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index e26875dbe859..00398d973a07 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -109,7 +109,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
109} 109}
110EXPORT_SYMBOL(iwl_scan_cancel_timeout); 110EXPORT_SYMBOL(iwl_scan_cancel_timeout);
111 111
112int iwl_send_scan_abort(struct iwl_priv *priv) 112static int iwl_send_scan_abort(struct iwl_priv *priv)
113{ 113{
114 int ret = 0; 114 int ret = 0;
115 struct iwl_rx_packet *res; 115 struct iwl_rx_packet *res;
@@ -150,7 +150,6 @@ int iwl_send_scan_abort(struct iwl_priv *priv)
150 150
151 return ret; 151 return ret;
152} 152}
153EXPORT_SYMBOL(iwl_send_scan_abort);
154 153
155/* Service response to REPLY_SCAN_CMD (0x80) */ 154/* Service response to REPLY_SCAN_CMD (0x80) */
156static void iwl_rx_reply_scan(struct iwl_priv *priv, 155static void iwl_rx_reply_scan(struct iwl_priv *priv,
@@ -322,7 +321,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
322 u8 is_active, u8 n_probes, 321 u8 is_active, u8 n_probes,
323 struct iwl_scan_channel *scan_ch) 322 struct iwl_scan_channel *scan_ch)
324{ 323{
325 const struct ieee80211_channel *channels = NULL; 324 struct ieee80211_channel *chan;
326 const struct ieee80211_supported_band *sband; 325 const struct ieee80211_supported_band *sband;
327 const struct iwl_channel_info *ch_info; 326 const struct iwl_channel_info *ch_info;
328 u16 passive_dwell = 0; 327 u16 passive_dwell = 0;
@@ -334,20 +333,19 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
334 if (!sband) 333 if (!sband)
335 return 0; 334 return 0;
336 335
337 channels = sband->channels;
338
339 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); 336 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
340 passive_dwell = iwl_get_passive_dwell_time(priv, band); 337 passive_dwell = iwl_get_passive_dwell_time(priv, band);
341 338
342 if (passive_dwell <= active_dwell) 339 if (passive_dwell <= active_dwell)
343 passive_dwell = active_dwell + 1; 340 passive_dwell = active_dwell + 1;
344 341
345 for (i = 0, added = 0; i < sband->n_channels; i++) { 342 for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
346 if (channels[i].flags & IEEE80211_CHAN_DISABLED) 343 chan = priv->scan_request->channels[i];
344
345 if (chan->band != band)
347 continue; 346 continue;
348 347
349 channel = 348 channel = ieee80211_frequency_to_channel(chan->center_freq);
350 ieee80211_frequency_to_channel(channels[i].center_freq);
351 scan_ch->channel = cpu_to_le16(channel); 349 scan_ch->channel = cpu_to_le16(channel);
352 350
353 ch_info = iwl_get_channel_info(priv, band, channel); 351 ch_info = iwl_get_channel_info(priv, band, channel);
@@ -358,7 +356,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
358 } 356 }
359 357
360 if (!is_active || is_channel_passive(ch_info) || 358 if (!is_active || is_channel_passive(ch_info) ||
361 (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) 359 (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
362 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; 360 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
363 else 361 else
364 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; 362 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
@@ -405,7 +403,7 @@ void iwl_init_scan_params(struct iwl_priv *priv)
405 priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx; 403 priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx;
406} 404}
407 405
408int iwl_scan_initiate(struct iwl_priv *priv) 406static int iwl_scan_initiate(struct iwl_priv *priv)
409{ 407{
410 if (!iwl_is_ready_rf(priv)) { 408 if (!iwl_is_ready_rf(priv)) {
411 IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n"); 409 IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n");
@@ -423,10 +421,6 @@ int iwl_scan_initiate(struct iwl_priv *priv)
423 } 421 }
424 422
425 IWL_DEBUG_INFO(priv, "Starting scan...\n"); 423 IWL_DEBUG_INFO(priv, "Starting scan...\n");
426 if (priv->cfg->sku & IWL_SKU_G)
427 priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
428 if (priv->cfg->sku & IWL_SKU_A)
429 priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
430 set_bit(STATUS_SCANNING, &priv->status); 424 set_bit(STATUS_SCANNING, &priv->status);
431 priv->scan_start = jiffies; 425 priv->scan_start = jiffies;
432 priv->scan_pass_start = priv->scan_start; 426 priv->scan_pass_start = priv->scan_start;
@@ -435,7 +429,6 @@ int iwl_scan_initiate(struct iwl_priv *priv)
435 429
436 return 0; 430 return 0;
437} 431}
438EXPORT_SYMBOL(iwl_scan_initiate);
439 432
440#define IWL_DELAY_NEXT_SCAN (HZ*2) 433#define IWL_DELAY_NEXT_SCAN (HZ*2)
441 434
@@ -444,7 +437,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
444{ 437{
445 unsigned long flags; 438 unsigned long flags;
446 struct iwl_priv *priv = hw->priv; 439 struct iwl_priv *priv = hw->priv;
447 int ret; 440 int ret, i;
448 441
449 IWL_DEBUG_MAC80211(priv, "enter\n"); 442 IWL_DEBUG_MAC80211(priv, "enter\n");
450 443
@@ -478,6 +471,10 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
478 goto out_unlock; 471 goto out_unlock;
479 } 472 }
480 473
474 priv->scan_bands = 0;
475 for (i = 0; i < req->n_channels; i++)
476 priv->scan_bands |= BIT(req->channels[i]->band);
477
481 priv->scan_request = req; 478 priv->scan_request = req;
482 479
483 ret = iwl_scan_initiate(priv); 480 ret = iwl_scan_initiate(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index cb9bd4c8f25e..016567f3e88e 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1844,7 +1844,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1844 u8 is_active, u8 n_probes, 1844 u8 is_active, u8 n_probes,
1845 struct iwl3945_scan_channel *scan_ch) 1845 struct iwl3945_scan_channel *scan_ch)
1846{ 1846{
1847 const struct ieee80211_channel *channels = NULL; 1847 struct ieee80211_channel *chan;
1848 const struct ieee80211_supported_band *sband; 1848 const struct ieee80211_supported_band *sband;
1849 const struct iwl_channel_info *ch_info; 1849 const struct iwl_channel_info *ch_info;
1850 u16 passive_dwell = 0; 1850 u16 passive_dwell = 0;
@@ -1855,19 +1855,19 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1855 if (!sband) 1855 if (!sband)
1856 return 0; 1856 return 0;
1857 1857
1858 channels = sband->channels;
1859
1860 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); 1858 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
1861 passive_dwell = iwl_get_passive_dwell_time(priv, band); 1859 passive_dwell = iwl_get_passive_dwell_time(priv, band);
1862 1860
1863 if (passive_dwell <= active_dwell) 1861 if (passive_dwell <= active_dwell)
1864 passive_dwell = active_dwell + 1; 1862 passive_dwell = active_dwell + 1;
1865 1863
1866 for (i = 0, added = 0; i < sband->n_channels; i++) { 1864 for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
1867 if (channels[i].flags & IEEE80211_CHAN_DISABLED) 1865 chan = priv->scan_request->channels[i];
1866
1867 if (chan->band != band)
1868 continue; 1868 continue;
1869 1869
1870 scan_ch->channel = channels[i].hw_value; 1870 scan_ch->channel = chan->hw_value;
1871 1871
1872 ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); 1872 ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
1873 if (!is_channel_valid(ch_info)) { 1873 if (!is_channel_valid(ch_info)) {
@@ -1882,7 +1882,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1882 * and use long active_dwell time. 1882 * and use long active_dwell time.
1883 */ 1883 */
1884 if (!is_active || is_channel_passive(ch_info) || 1884 if (!is_active || is_channel_passive(ch_info) ||
1885 (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) { 1885 (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
1886 scan_ch->type = 0; /* passive */ 1886 scan_ch->type = 0; /* passive */
1887 if (IWL_UCODE_API(priv->ucode_ver) == 1) 1887 if (IWL_UCODE_API(priv->ucode_ver) == 1)
1888 scan_ch->active_dwell = cpu_to_le16(passive_dwell - 1); 1888 scan_ch->active_dwell = cpu_to_le16(passive_dwell - 1);