diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debug.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debugfs.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 155 |
6 files changed, 193 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index bb3ed25f8438..645bc133577a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -3343,6 +3343,30 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) | |||
3343 | } | 3343 | } |
3344 | EXPORT_SYMBOL(iwl_dump_fh); | 3344 | EXPORT_SYMBOL(iwl_dump_fh); |
3345 | 3345 | ||
3346 | void iwl_force_rf_reset(struct iwl_priv *priv) | ||
3347 | { | ||
3348 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
3349 | return; | ||
3350 | |||
3351 | if (!iwl_is_associated(priv)) { | ||
3352 | IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); | ||
3353 | return; | ||
3354 | } | ||
3355 | /* | ||
3356 | * There is no easy and better way to force reset the radio, | ||
3357 | * the only known method is switching channel which will force to | ||
3358 | * reset and tune the radio. | ||
3359 | * Use internal short scan (single channel) operation to should | ||
3360 | * achieve this objective. | ||
3361 | * Driver should reset the radio when number of consecutive missed | ||
3362 | * beacon, or any other uCode error condition detected. | ||
3363 | */ | ||
3364 | IWL_DEBUG_INFO(priv, "perform radio reset.\n"); | ||
3365 | iwl_internal_short_hw_scan(priv); | ||
3366 | return; | ||
3367 | } | ||
3368 | EXPORT_SYMBOL(iwl_force_rf_reset); | ||
3369 | |||
3346 | #ifdef CONFIG_PM | 3370 | #ifdef CONFIG_PM |
3347 | 3371 | ||
3348 | int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 3372 | int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 785331a98aa5..6de83d1e1eb8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -494,6 +494,8 @@ void iwl_init_scan_params(struct iwl_priv *priv); | |||
494 | int iwl_scan_cancel(struct iwl_priv *priv); | 494 | int iwl_scan_cancel(struct iwl_priv *priv); |
495 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | 495 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); |
496 | int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); | 496 | int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); |
497 | int iwl_internal_short_hw_scan(struct iwl_priv *priv); | ||
498 | void iwl_force_rf_reset(struct iwl_priv *priv); | ||
497 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | 499 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, |
498 | const u8 *ie, int ie_len, int left); | 500 | const u8 *ie, int ie_len, int left); |
499 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); | 501 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 36b558f23325..d81b4f39bb1d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -113,6 +113,7 @@ struct iwl_debugfs { | |||
113 | struct dentry *file_ucode_tracing; | 113 | struct dentry *file_ucode_tracing; |
114 | struct dentry *file_fh_reg; | 114 | struct dentry *file_fh_reg; |
115 | struct dentry *file_missed_beacon; | 115 | struct dentry *file_missed_beacon; |
116 | struct dentry *file_internal_scan; | ||
116 | } dbgfs_debug_files; | 117 | } dbgfs_debug_files; |
117 | u32 sram_offset; | 118 | u32 sram_offset; |
118 | u32 sram_len; | 119 | u32 sram_len; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 02f80bc21307..4944fdb31ba8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -2174,6 +2174,27 @@ static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, | |||
2174 | return count; | 2174 | return count; |
2175 | } | 2175 | } |
2176 | 2176 | ||
2177 | static ssize_t iwl_dbgfs_internal_scan_write(struct file *file, | ||
2178 | const char __user *user_buf, | ||
2179 | size_t count, loff_t *ppos) | ||
2180 | { | ||
2181 | struct iwl_priv *priv = file->private_data; | ||
2182 | char buf[8]; | ||
2183 | int buf_size; | ||
2184 | int scan; | ||
2185 | |||
2186 | memset(buf, 0, sizeof(buf)); | ||
2187 | buf_size = min(count, sizeof(buf) - 1); | ||
2188 | if (copy_from_user(buf, user_buf, buf_size)) | ||
2189 | return -EFAULT; | ||
2190 | if (sscanf(buf, "%d", &scan) != 1) | ||
2191 | return -EINVAL; | ||
2192 | |||
2193 | iwl_internal_short_hw_scan(priv); | ||
2194 | |||
2195 | return count; | ||
2196 | } | ||
2197 | |||
2177 | DEBUGFS_READ_FILE_OPS(rx_statistics); | 2198 | DEBUGFS_READ_FILE_OPS(rx_statistics); |
2178 | DEBUGFS_READ_FILE_OPS(tx_statistics); | 2199 | DEBUGFS_READ_FILE_OPS(tx_statistics); |
2179 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); | 2200 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); |
@@ -2192,6 +2213,7 @@ DEBUGFS_WRITE_FILE_OPS(csr); | |||
2192 | DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); | 2213 | DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); |
2193 | DEBUGFS_READ_FILE_OPS(fh_reg); | 2214 | DEBUGFS_READ_FILE_OPS(fh_reg); |
2194 | DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); | 2215 | DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); |
2216 | DEBUGFS_WRITE_FILE_OPS(internal_scan); | ||
2195 | 2217 | ||
2196 | /* | 2218 | /* |
2197 | * Create the debugfs files and directories | 2219 | * Create the debugfs files and directories |
@@ -2245,6 +2267,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2245 | DEBUGFS_ADD_FILE(csr, debug, S_IWUSR); | 2267 | DEBUGFS_ADD_FILE(csr, debug, S_IWUSR); |
2246 | DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR); | 2268 | DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR); |
2247 | DEBUGFS_ADD_FILE(missed_beacon, debug, S_IWUSR); | 2269 | DEBUGFS_ADD_FILE(missed_beacon, debug, S_IWUSR); |
2270 | DEBUGFS_ADD_FILE(internal_scan, debug, S_IWUSR); | ||
2248 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { | 2271 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { |
2249 | DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); | 2272 | DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); |
2250 | DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); | 2273 | DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); |
@@ -2306,6 +2329,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
2306 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr); | 2329 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr); |
2307 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg); | 2330 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg); |
2308 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_missed_beacon); | 2331 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_missed_beacon); |
2332 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_internal_scan); | ||
2309 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { | 2333 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { |
2310 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. | 2334 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. |
2311 | file_ucode_rx_stats); | 2335 | file_ucode_rx_stats); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 5e06e666f176..502d7a6b0904 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1080,6 +1080,7 @@ struct iwl_priv { | |||
1080 | void *scan; | 1080 | void *scan; |
1081 | int scan_bands; | 1081 | int scan_bands; |
1082 | struct cfg80211_scan_request *scan_request; | 1082 | struct cfg80211_scan_request *scan_request; |
1083 | bool is_internal_short_scan; | ||
1083 | u8 scan_tx_ant[IEEE80211_NUM_BANDS]; | 1084 | u8 scan_tx_ant[IEEE80211_NUM_BANDS]; |
1084 | u8 mgmt_tx_ant; | 1085 | u8 mgmt_tx_ant; |
1085 | 1086 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index ceb91f969e45..fd6bafbddfca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -314,6 +314,72 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, | |||
314 | } | 314 | } |
315 | EXPORT_SYMBOL(iwl_get_passive_dwell_time); | 315 | EXPORT_SYMBOL(iwl_get_passive_dwell_time); |
316 | 316 | ||
317 | static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, | ||
318 | enum ieee80211_band band, | ||
319 | struct iwl_scan_channel *scan_ch) | ||
320 | { | ||
321 | const struct ieee80211_supported_band *sband; | ||
322 | const struct iwl_channel_info *ch_info; | ||
323 | u16 passive_dwell = 0; | ||
324 | u16 active_dwell = 0; | ||
325 | int i, added = 0; | ||
326 | u16 channel = 0; | ||
327 | |||
328 | sband = iwl_get_hw_mode(priv, band); | ||
329 | if (!sband) { | ||
330 | IWL_ERR(priv, "invalid band\n"); | ||
331 | return added; | ||
332 | } | ||
333 | |||
334 | active_dwell = iwl_get_active_dwell_time(priv, band, 0); | ||
335 | passive_dwell = iwl_get_passive_dwell_time(priv, band); | ||
336 | |||
337 | if (passive_dwell <= active_dwell) | ||
338 | passive_dwell = active_dwell + 1; | ||
339 | |||
340 | /* only scan single channel, good enough to reset the RF */ | ||
341 | /* pick the first valid not in-use channel */ | ||
342 | if (band == IEEE80211_BAND_5GHZ) { | ||
343 | for (i = 14; i < priv->channel_count; i++) { | ||
344 | if (priv->channel_info[i].channel != | ||
345 | le16_to_cpu(priv->staging_rxon.channel)) { | ||
346 | channel = priv->channel_info[i].channel; | ||
347 | ch_info = iwl_get_channel_info(priv, | ||
348 | band, channel); | ||
349 | if (is_channel_valid(ch_info)) | ||
350 | break; | ||
351 | } | ||
352 | } | ||
353 | } else { | ||
354 | for (i = 0; i < 14; i++) { | ||
355 | if (priv->channel_info[i].channel != | ||
356 | le16_to_cpu(priv->staging_rxon.channel)) { | ||
357 | channel = | ||
358 | priv->channel_info[i].channel; | ||
359 | ch_info = iwl_get_channel_info(priv, | ||
360 | band, channel); | ||
361 | if (is_channel_valid(ch_info)) | ||
362 | break; | ||
363 | } | ||
364 | } | ||
365 | } | ||
366 | if (channel) { | ||
367 | scan_ch->channel = cpu_to_le16(channel); | ||
368 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; | ||
369 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | ||
370 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | ||
371 | /* Set txpower levels to defaults */ | ||
372 | scan_ch->dsp_atten = 110; | ||
373 | if (band == IEEE80211_BAND_5GHZ) | ||
374 | scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; | ||
375 | else | ||
376 | scan_ch->tx_gain = ((1 << 5) | (5 << 3)); | ||
377 | added++; | ||
378 | } else | ||
379 | IWL_ERR(priv, "no valid channel found\n"); | ||
380 | return added; | ||
381 | } | ||
382 | |||
317 | static int iwl_get_channels_for_scan(struct iwl_priv *priv, | 383 | static int iwl_get_channels_for_scan(struct iwl_priv *priv, |
318 | enum ieee80211_band band, | 384 | enum ieee80211_band band, |
319 | u8 is_active, u8 n_probes, | 385 | u8 is_active, u8 n_probes, |
@@ -421,6 +487,7 @@ static int iwl_scan_initiate(struct iwl_priv *priv) | |||
421 | 487 | ||
422 | IWL_DEBUG_INFO(priv, "Starting scan...\n"); | 488 | IWL_DEBUG_INFO(priv, "Starting scan...\n"); |
423 | set_bit(STATUS_SCANNING, &priv->status); | 489 | set_bit(STATUS_SCANNING, &priv->status); |
490 | priv->is_internal_short_scan = false; | ||
424 | priv->scan_start = jiffies; | 491 | priv->scan_start = jiffies; |
425 | priv->scan_pass_start = priv->scan_start; | 492 | priv->scan_pass_start = priv->scan_start; |
426 | 493 | ||
@@ -488,6 +555,45 @@ out_unlock: | |||
488 | } | 555 | } |
489 | EXPORT_SYMBOL(iwl_mac_hw_scan); | 556 | EXPORT_SYMBOL(iwl_mac_hw_scan); |
490 | 557 | ||
558 | /* | ||
559 | * internal short scan, this function should only been called while associated. | ||
560 | * It will reset and tune the radio to prevent possible RF related problem | ||
561 | */ | ||
562 | int iwl_internal_short_hw_scan(struct iwl_priv *priv) | ||
563 | { | ||
564 | int ret = 0; | ||
565 | |||
566 | if (!iwl_is_ready_rf(priv)) { | ||
567 | ret = -EIO; | ||
568 | IWL_DEBUG_SCAN(priv, "not ready or exit pending\n"); | ||
569 | goto out; | ||
570 | } | ||
571 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
572 | IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); | ||
573 | ret = -EAGAIN; | ||
574 | goto out; | ||
575 | } | ||
576 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
577 | IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); | ||
578 | ret = -EAGAIN; | ||
579 | goto out; | ||
580 | } | ||
581 | priv->scan_bands = 0; | ||
582 | if (priv->band == IEEE80211_BAND_5GHZ) | ||
583 | priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); | ||
584 | else | ||
585 | priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); | ||
586 | |||
587 | IWL_DEBUG_SCAN(priv, "Start internal short scan...\n"); | ||
588 | set_bit(STATUS_SCANNING, &priv->status); | ||
589 | priv->is_internal_short_scan = true; | ||
590 | queue_work(priv->workqueue, &priv->request_scan); | ||
591 | |||
592 | out: | ||
593 | return ret; | ||
594 | } | ||
595 | EXPORT_SYMBOL(iwl_internal_short_hw_scan); | ||
596 | |||
491 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 597 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) |
492 | 598 | ||
493 | void iwl_bg_scan_check(struct work_struct *data) | 599 | void iwl_bg_scan_check(struct work_struct *data) |
@@ -551,7 +657,8 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | |||
551 | if (WARN_ON(left < ie_len)) | 657 | if (WARN_ON(left < ie_len)) |
552 | return len; | 658 | return len; |
553 | 659 | ||
554 | memcpy(pos, ies, ie_len); | 660 | if (ies) |
661 | memcpy(pos, ies, ie_len); | ||
555 | len += ie_len; | 662 | len += ie_len; |
556 | left -= ie_len; | 663 | left -= ie_len; |
557 | 664 | ||
@@ -654,7 +761,6 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
654 | unsigned long flags; | 761 | unsigned long flags; |
655 | 762 | ||
656 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); | 763 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); |
657 | |||
658 | spin_lock_irqsave(&priv->lock, flags); | 764 | spin_lock_irqsave(&priv->lock, flags); |
659 | interval = priv->beacon_int; | 765 | interval = priv->beacon_int; |
660 | spin_unlock_irqrestore(&priv->lock, flags); | 766 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -672,7 +778,9 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
672 | scan_suspend_time, interval); | 778 | scan_suspend_time, interval); |
673 | } | 779 | } |
674 | 780 | ||
675 | if (priv->scan_request->n_ssids) { | 781 | if (priv->is_internal_short_scan) { |
782 | IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); | ||
783 | } else if (priv->scan_request->n_ssids) { | ||
676 | int i, p = 0; | 784 | int i, p = 0; |
677 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); | 785 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); |
678 | for (i = 0; i < priv->scan_request->n_ssids; i++) { | 786 | for (i = 0; i < priv->scan_request->n_ssids; i++) { |
@@ -753,24 +861,38 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
753 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; | 861 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; |
754 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; | 862 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; |
755 | scan->rx_chain = cpu_to_le16(rx_chain); | 863 | scan->rx_chain = cpu_to_le16(rx_chain); |
756 | cmd_len = iwl_fill_probe_req(priv, | 864 | if (!priv->is_internal_short_scan) { |
757 | (struct ieee80211_mgmt *)scan->data, | 865 | cmd_len = iwl_fill_probe_req(priv, |
758 | priv->scan_request->ie, | 866 | (struct ieee80211_mgmt *)scan->data, |
759 | priv->scan_request->ie_len, | 867 | priv->scan_request->ie, |
760 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); | 868 | priv->scan_request->ie_len, |
869 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); | ||
870 | } else { | ||
871 | cmd_len = iwl_fill_probe_req(priv, | ||
872 | (struct ieee80211_mgmt *)scan->data, | ||
873 | NULL, 0, | ||
874 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); | ||
761 | 875 | ||
876 | } | ||
762 | scan->tx_cmd.len = cpu_to_le16(cmd_len); | 877 | scan->tx_cmd.len = cpu_to_le16(cmd_len); |
763 | |||
764 | if (iwl_is_monitor_mode(priv)) | 878 | if (iwl_is_monitor_mode(priv)) |
765 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; | 879 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; |
766 | 880 | ||
767 | scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | | 881 | scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | |
768 | RXON_FILTER_BCON_AWARE_MSK); | 882 | RXON_FILTER_BCON_AWARE_MSK); |
769 | 883 | ||
770 | scan->channel_count = | 884 | if (priv->is_internal_short_scan) { |
771 | iwl_get_channels_for_scan(priv, band, is_active, n_probes, | 885 | scan->channel_count = |
772 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 886 | iwl_get_single_channel_for_scan(priv, band, |
773 | 887 | (void *)&scan->data[le16_to_cpu( | |
888 | scan->tx_cmd.len)]); | ||
889 | } else { | ||
890 | scan->channel_count = | ||
891 | iwl_get_channels_for_scan(priv, band, | ||
892 | is_active, n_probes, | ||
893 | (void *)&scan->data[le16_to_cpu( | ||
894 | scan->tx_cmd.len)]); | ||
895 | } | ||
774 | if (scan->channel_count == 0) { | 896 | if (scan->channel_count == 0) { |
775 | IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); | 897 | IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); |
776 | goto done; | 898 | goto done; |
@@ -831,7 +953,12 @@ void iwl_bg_scan_completed(struct work_struct *work) | |||
831 | 953 | ||
832 | cancel_delayed_work(&priv->scan_check); | 954 | cancel_delayed_work(&priv->scan_check); |
833 | 955 | ||
834 | ieee80211_scan_completed(priv->hw, false); | 956 | if (!priv->is_internal_short_scan) |
957 | ieee80211_scan_completed(priv->hw, false); | ||
958 | else { | ||
959 | priv->is_internal_short_scan = false; | ||
960 | IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); | ||
961 | } | ||
835 | 962 | ||
836 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 963 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
837 | return; | 964 | return; |