diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-scan.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 40 |
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); | |||
112 | static int iwl_send_scan_abort(struct iwl_priv *priv) | 111 | static 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, | |||
168 | static void iwl_rx_scan_start_notif(struct iwl_priv *priv, | 167 | static 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 | } |
404 | EXPORT_SYMBOL(iwl_init_scan_params); | ||
405 | 405 | ||
406 | static int iwl_scan_initiate(struct iwl_priv *priv) | 406 | static 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); |