aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-scan.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 4f3a108fa990..a2b2b8315ff9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -27,7 +27,6 @@
27 *****************************************************************************/ 27 *****************************************************************************/
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/etherdevice.h> 29#include <linux/etherdevice.h>
30#include <net/lib80211.h>
31#include <net/mac80211.h> 30#include <net/mac80211.h>
32 31
33#include "iwl-eeprom.h" 32#include "iwl-eeprom.h"
@@ -112,7 +111,7 @@ EXPORT_SYMBOL(iwl_scan_cancel_timeout);
112static int iwl_send_scan_abort(struct iwl_priv *priv) 111static int iwl_send_scan_abort(struct iwl_priv *priv)
113{ 112{
114 int ret = 0; 113 int ret = 0;
115 struct iwl_rx_packet *res; 114 struct iwl_rx_packet *pkt;
116 struct iwl_host_cmd cmd = { 115 struct iwl_host_cmd cmd = {
117 .id = REPLY_SCAN_ABORT_CMD, 116 .id = REPLY_SCAN_ABORT_CMD,
118 .flags = CMD_WANT_SKB, 117 .flags = CMD_WANT_SKB,
@@ -132,21 +131,21 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
132 return ret; 131 return ret;
133 } 132 }
134 133
135 res = (struct iwl_rx_packet *)cmd.reply_skb->data; 134 pkt = (struct iwl_rx_packet *)cmd.reply_page;
136 if (res->u.status != CAN_ABORT_STATUS) { 135 if (pkt->u.status != CAN_ABORT_STATUS) {
137 /* The scan abort will return 1 for success or 136 /* The scan abort will return 1 for success or
138 * 2 for "failure". A failure condition can be 137 * 2 for "failure". A failure condition can be
139 * due to simply not being in an active scan which 138 * due to simply not being in an active scan which
140 * can occur if we send the scan abort before we 139 * can occur if we send the scan abort before we
141 * the microcode has notified us that a scan is 140 * the microcode has notified us that a scan is
142 * completed. */ 141 * completed. */
143 IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", res->u.status); 142 IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status);
144 clear_bit(STATUS_SCAN_ABORTING, &priv->status); 143 clear_bit(STATUS_SCAN_ABORTING, &priv->status);
145 clear_bit(STATUS_SCAN_HW, &priv->status); 144 clear_bit(STATUS_SCAN_HW, &priv->status);
146 } 145 }
147 146
148 priv->alloc_rxb_skb--; 147 priv->alloc_rxb_page--;
149 dev_kfree_skb_any(cmd.reply_skb); 148 free_pages(cmd.reply_page, priv->hw_params.rx_page_order);
150 149
151 return ret; 150 return ret;
152} 151}
@@ -156,7 +155,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
156 struct iwl_rx_mem_buffer *rxb) 155 struct iwl_rx_mem_buffer *rxb)
157{ 156{
158#ifdef CONFIG_IWLWIFI_DEBUG 157#ifdef CONFIG_IWLWIFI_DEBUG
159 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 158 struct iwl_rx_packet *pkt = rxb_addr(rxb);
160 struct iwl_scanreq_notification *notif = 159 struct iwl_scanreq_notification *notif =
161 (struct iwl_scanreq_notification *)pkt->u.raw; 160 (struct iwl_scanreq_notification *)pkt->u.raw;
162 161
@@ -168,7 +167,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
168static void iwl_rx_scan_start_notif(struct iwl_priv *priv, 167static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
169 struct iwl_rx_mem_buffer *rxb) 168 struct iwl_rx_mem_buffer *rxb)
170{ 169{
171 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 170 struct iwl_rx_packet *pkt = rxb_addr(rxb);
172 struct iwl_scanstart_notification *notif = 171 struct iwl_scanstart_notification *notif =
173 (struct iwl_scanstart_notification *)pkt->u.raw; 172 (struct iwl_scanstart_notification *)pkt->u.raw;
174 priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); 173 priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
@@ -187,7 +186,7 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
187 struct iwl_rx_mem_buffer *rxb) 186 struct iwl_rx_mem_buffer *rxb)
188{ 187{
189#ifdef CONFIG_IWLWIFI_DEBUG 188#ifdef CONFIG_IWLWIFI_DEBUG
190 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 189 struct iwl_rx_packet *pkt = rxb_addr(rxb);
191 struct iwl_scanresults_notification *notif = 190 struct iwl_scanresults_notification *notif =
192 (struct iwl_scanresults_notification *)pkt->u.raw; 191 (struct iwl_scanresults_notification *)pkt->u.raw;
193 192
@@ -214,7 +213,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
214 struct iwl_rx_mem_buffer *rxb) 213 struct iwl_rx_mem_buffer *rxb)
215{ 214{
216#ifdef CONFIG_IWLWIFI_DEBUG 215#ifdef CONFIG_IWLWIFI_DEBUG
217 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 216 struct iwl_rx_packet *pkt = rxb_addr(rxb);
218 struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; 217 struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
219 218
220 IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", 219 IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
@@ -402,6 +401,7 @@ void iwl_init_scan_params(struct iwl_priv *priv)
402 if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) 401 if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ])
403 priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx; 402 priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx;
404} 403}
404EXPORT_SYMBOL(iwl_init_scan_params);
405 405
406static int iwl_scan_initiate(struct iwl_priv *priv) 406static int iwl_scan_initiate(struct iwl_priv *priv)
407{ 407{
@@ -581,6 +581,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
581 u8 rate; 581 u8 rate;
582 bool is_active = false; 582 bool is_active = false;
583 int chan_mod; 583 int chan_mod;
584 u8 active_chains;
584 585
585 conf = ieee80211_get_hw_conf(priv->hw); 586 conf = ieee80211_get_hw_conf(priv->hw);
586 587
@@ -734,9 +735,22 @@ static void iwl_bg_request_scan(struct work_struct *data)
734 rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); 735 rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
735 scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags); 736 scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
736 737
738 /* In power save mode use one chain, otherwise use all chains */
739 if (test_bit(STATUS_POWER_PMI, &priv->status)) {
740 /* rx_ant has been set to all valid chains previously */
741 active_chains = rx_ant &
742 ((u8)(priv->chain_noise_data.active_chains));
743 if (!active_chains)
744 active_chains = rx_ant;
745
746 IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
747 priv->chain_noise_data.active_chains);
748
749 rx_ant = first_antenna(active_chains);
750 }
737 /* MIMO is not used here, but value is required */ 751 /* MIMO is not used here, but value is required */
738 rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS; 752 rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
739 rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; 753 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
740 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; 754 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
741 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; 755 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
742 scan->rx_chain = cpu_to_le16(rx_chain); 756 scan->rx_chain = cpu_to_le16(rx_chain);