aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@intel.com>2015-02-10 06:03:38 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-03-01 09:55:10 -0500
commit1f9403863c080478ad78247c89b018e95bdfb027 (patch)
tree8a860ae49cdb7aab6c990b12f098660da63360f9
parent1e2c24f0f10f1b170a0840a5a54a912785ee2f6a (diff)
iwlwifi: mvm: remove deprecated scan API code
The legacy scan API is deprecated and not used anymore with 10 and higher firmware versions. Since we deprecated firmware version 9, we can remove a whole lot of unused code. Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h191
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c23
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h16
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c585
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c19
7 files changed, 20 insertions, 818 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 8b9040ef20e0..be4393e2c19c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -237,7 +237,6 @@ enum iwl_ucode_tlv_flag {
237 * enum iwl_ucode_tlv_api - ucode api 237 * enum iwl_ucode_tlv_api - ucode api
238 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex 238 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
239 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. 239 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
240 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
241 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. 240 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
242 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time 241 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
243 * longer than the passive one, which is essential for fragmented scan. 242 * longer than the passive one, which is essential for fragmented scan.
@@ -255,7 +254,6 @@ enum iwl_ucode_tlv_flag {
255enum iwl_ucode_tlv_api { 254enum iwl_ucode_tlv_api {
256 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), 255 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
257 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), 256 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
258 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
259 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), 257 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
260 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), 258 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
261 IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10), 259 IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10),
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index cfc0e65b34a5..a5fbbd637070 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -70,55 +70,10 @@
70 70
71/* Scan Commands, Responses, Notifications */ 71/* Scan Commands, Responses, Notifications */
72 72
73/* Masks for iwl_scan_channel.type flags */
74#define SCAN_CHANNEL_TYPE_ACTIVE BIT(0)
75#define SCAN_CHANNEL_NARROW_BAND BIT(22)
76
77/* Max number of IEs for direct SSID scans in a command */ 73/* Max number of IEs for direct SSID scans in a command */
78#define PROBE_OPTION_MAX 20 74#define PROBE_OPTION_MAX 20
79 75
80/** 76/**
81 * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table
82 * @channel: band is selected by iwl_scan_cmd "flags" field
83 * @tx_gain: gain for analog radio
84 * @dsp_atten: gain for DSP
85 * @active_dwell: dwell time for active scan in TU, typically 5-50
86 * @passive_dwell: dwell time for passive scan in TU, typically 20-500
87 * @type: type is broken down to these bits:
88 * bit 0: 0 = passive, 1 = active
89 * bits 1-20: SSID direct bit map. If any of these bits is set then
90 * the corresponding SSID IE is transmitted in probe request
91 * (bit i adds IE in position i to the probe request)
92 * bit 22: channel width, 0 = regular, 1 = TGj narrow channel
93 *
94 * @iteration_count:
95 * @iteration_interval:
96 * This struct is used once for each channel in the scan list.
97 * Each channel can independently select:
98 * 1) SSID for directed active scans
99 * 2) Txpower setting (for rate specified within Tx command)
100 * 3) How long to stay on-channel (behavior may be modified by quiet_time,
101 * quiet_plcp_th, good_CRC_th)
102 *
103 * To avoid uCode errors, make sure the following are true (see comments
104 * under struct iwl_scan_cmd about max_out_time and quiet_time):
105 * 1) If using passive_dwell (i.e. passive_dwell != 0):
106 * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
107 * 2) quiet_time <= active_dwell
108 * 3) If restricting off-channel time (i.e. max_out_time !=0):
109 * passive_dwell < max_out_time
110 * active_dwell < max_out_time
111 */
112struct iwl_scan_channel {
113 __le32 type;
114 __le16 channel;
115 __le16 iteration_count;
116 __le32 iteration_interval;
117 __le16 active_dwell;
118 __le16 passive_dwell;
119} __packed; /* SCAN_CHANNEL_CONTROL_API_S_VER_1 */
120
121/**
122 * struct iwl_ssid_ie - directed scan network information element 77 * struct iwl_ssid_ie - directed scan network information element
123 * 78 *
124 * Up to 20 of these may appear in REPLY_SCAN_CMD, 79 * Up to 20 of these may appear in REPLY_SCAN_CMD,
@@ -132,152 +87,6 @@ struct iwl_ssid_ie {
132 u8 ssid[IEEE80211_MAX_SSID_LEN]; 87 u8 ssid[IEEE80211_MAX_SSID_LEN];
133} __packed; /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */ 88} __packed; /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */
134 89
135/**
136 * iwl_scan_flags - masks for scan command flags
137 *@SCAN_FLAGS_PERIODIC_SCAN:
138 *@SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX:
139 *@SCAN_FLAGS_DELAYED_SCAN_LOWBAND:
140 *@SCAN_FLAGS_DELAYED_SCAN_HIGHBAND:
141 *@SCAN_FLAGS_FRAGMENTED_SCAN:
142 *@SCAN_FLAGS_PASSIVE2ACTIVE: use active scan on channels that was active
143 * in the past hour, even if they are marked as passive.
144 */
145enum iwl_scan_flags {
146 SCAN_FLAGS_PERIODIC_SCAN = BIT(0),
147 SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX = BIT(1),
148 SCAN_FLAGS_DELAYED_SCAN_LOWBAND = BIT(2),
149 SCAN_FLAGS_DELAYED_SCAN_HIGHBAND = BIT(3),
150 SCAN_FLAGS_FRAGMENTED_SCAN = BIT(4),
151 SCAN_FLAGS_PASSIVE2ACTIVE = BIT(5),
152};
153
154/**
155 * enum iwl_scan_type - Scan types for scan command
156 * @SCAN_TYPE_FORCED:
157 * @SCAN_TYPE_BACKGROUND:
158 * @SCAN_TYPE_OS:
159 * @SCAN_TYPE_ROAMING:
160 * @SCAN_TYPE_ACTION:
161 * @SCAN_TYPE_DISCOVERY:
162 * @SCAN_TYPE_DISCOVERY_FORCED:
163 */
164enum iwl_scan_type {
165 SCAN_TYPE_FORCED = 0,
166 SCAN_TYPE_BACKGROUND = 1,
167 SCAN_TYPE_OS = 2,
168 SCAN_TYPE_ROAMING = 3,
169 SCAN_TYPE_ACTION = 4,
170 SCAN_TYPE_DISCOVERY = 5,
171 SCAN_TYPE_DISCOVERY_FORCED = 6,
172}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */
173
174/**
175 * struct iwl_scan_cmd - scan request command
176 * ( SCAN_REQUEST_CMD = 0x80 )
177 * @len: command length in bytes
178 * @scan_flags: scan flags from SCAN_FLAGS_*
179 * @channel_count: num of channels in channel list
180 * (1 - ucode_capa.n_scan_channels)
181 * @quiet_time: in msecs, dwell this time for active scan on quiet channels
182 * @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
183 * this number of packets were received (typically 1)
184 * @passive2active: is auto switching from passive to active during scan allowed
185 * @rxchain_sel_flags: RXON_RX_CHAIN_*
186 * @max_out_time: in TUs, max out of serving channel time
187 * @suspend_time: how long to pause scan when returning to service channel:
188 * bits 0-19: beacon interal in TUs (suspend before executing)
189 * bits 20-23: reserved
190 * bits 24-31: number of beacons (suspend between channels)
191 * @rxon_flags: RXON_FLG_*
192 * @filter_flags: RXON_FILTER_*
193 * @tx_cmd: for active scans (zero for passive), w/o payload,
194 * no RS so specify TX rate
195 * @direct_scan: direct scan SSIDs
196 * @type: one of SCAN_TYPE_*
197 * @repeats: how many time to repeat the scan
198 */
199struct iwl_scan_cmd {
200 __le16 len;
201 u8 scan_flags;
202 u8 channel_count;
203 __le16 quiet_time;
204 __le16 quiet_plcp_th;
205 __le16 passive2active;
206 __le16 rxchain_sel_flags;
207 __le32 max_out_time;
208 __le32 suspend_time;
209 /* RX_ON_FLAGS_API_S_VER_1 */
210 __le32 rxon_flags;
211 __le32 filter_flags;
212 struct iwl_tx_cmd tx_cmd;
213 struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
214 __le32 type;
215 __le32 repeats;
216
217 /*
218 * Probe request frame, followed by channel list.
219 *
220 * Size of probe request frame is specified by byte count in tx_cmd.
221 * Channel list follows immediately after probe request frame.
222 * Number of channels in list is specified by channel_count.
223 * Each channel in list is of type:
224 *
225 * struct iwl_scan_channel channels[0];
226 *
227 * NOTE: Only one band of channels can be scanned per pass. You
228 * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
229 * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
230 * before requesting another scan.
231 */
232 u8 data[0];
233} __packed; /* SCAN_REQUEST_FIXED_PART_API_S_VER_5 */
234
235/* Response to scan request contains only status with one of these values */
236#define SCAN_RESPONSE_OK 0x1
237#define SCAN_RESPONSE_ERROR 0x2
238
239/*
240 * SCAN_ABORT_CMD = 0x81
241 * When scan abort is requested, the command has no fields except the common
242 * header. The response contains only a status with one of these values.
243 */
244#define SCAN_ABORT_POSSIBLE 0x1
245#define SCAN_ABORT_IGNORED 0x2 /* no pending scans */
246
247/* TODO: complete documentation */
248#define SCAN_OWNER_STATUS 0x1
249#define MEASURE_OWNER_STATUS 0x2
250
251/**
252 * struct iwl_scan_start_notif - notifies start of scan in the device
253 * ( SCAN_START_NOTIFICATION = 0x82 )
254 * @tsf_low: TSF timer (lower half) in usecs
255 * @tsf_high: TSF timer (higher half) in usecs
256 * @beacon_timer: structured as follows:
257 * bits 0:19 - beacon interval in usecs
258 * bits 20:23 - reserved (0)
259 * bits 24:31 - number of beacons
260 * @channel: which channel is scanned
261 * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
262 * @status: one of *_OWNER_STATUS
263 */
264struct iwl_scan_start_notif {
265 __le32 tsf_low;
266 __le32 tsf_high;
267 __le32 beacon_timer;
268 u8 channel;
269 u8 band;
270 u8 reserved[2];
271 __le32 status;
272} __packed; /* SCAN_START_NTF_API_S_VER_1 */
273
274/* scan results probe_status first bit indicates success */
275#define SCAN_PROBE_STATUS_OK 0
276#define SCAN_PROBE_STATUS_TX_FAILED BIT(0)
277/* error statuses combined with TX_FAILED */
278#define SCAN_PROBE_STATUS_FAIL_TTL BIT(1)
279#define SCAN_PROBE_STATUS_FAIL_BT BIT(2)
280
281/* How many statistics are gathered for each channel */ 90/* How many statistics are gathered for each channel */
282#define SCAN_RESULTS_STATISTICS 1 91#define SCAN_RESULTS_STATISTICS 1
283 92
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 20e1e898e815..0f986d7840b5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -339,13 +339,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
339 !iwlwifi_mod_params.sw_crypto) 339 !iwlwifi_mod_params.sw_crypto)
340 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 340 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
341 341
342 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN || 342 hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS;
343 mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { 343 hw->wiphy->features |=
344 hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS; 344 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
345 hw->wiphy->features |= 345 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
346 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
347 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
348 }
349 346
350 hw->sta_data_size = sizeof(struct iwl_mvm_sta); 347 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
351 hw->vif_data_size = sizeof(struct iwl_mvm_vif); 348 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
@@ -2204,10 +2201,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
2204 2201
2205 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) 2202 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)
2206 ret = iwl_mvm_scan_umac(mvm, vif, hw_req); 2203 ret = iwl_mvm_scan_umac(mvm, vif, hw_req);
2207 else if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
2208 ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req);
2209 else 2204 else
2210 ret = iwl_mvm_scan_request(mvm, vif, req); 2205 ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req);
2211 2206
2212 if (ret) 2207 if (ret)
2213 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 2208 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
@@ -2535,13 +2530,7 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
2535 2530
2536 mutex_lock(&mvm->mutex); 2531 mutex_lock(&mvm->mutex);
2537 2532
2538 /* Newest FW fixes sched scan while connected on another interface */ 2533 if (!vif->bss_conf.idle) {
2539 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) {
2540 if (!vif->bss_conf.idle) {
2541 ret = -EBUSY;
2542 goto out;
2543 }
2544 } else if (!iwl_mvm_is_idle(mvm)) {
2545 ret = -EBUSY; 2534 ret = -EBUSY;
2546 goto out; 2535 goto out;
2547 } 2536 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index d4f3b8400ccc..90a1ea3e6507 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -1080,13 +1080,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
1080 1080
1081/* Scanning */ 1081/* Scanning */
1082int iwl_mvm_scan_size(struct iwl_mvm *mvm); 1082int iwl_mvm_scan_size(struct iwl_mvm *mvm);
1083int iwl_mvm_scan_request(struct iwl_mvm *mvm,
1084 struct ieee80211_vif *vif,
1085 struct cfg80211_scan_request *req);
1086int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
1087 struct iwl_device_cmd *cmd);
1088int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
1089 struct iwl_device_cmd *cmd);
1090int iwl_mvm_cancel_scan(struct iwl_mvm *mvm); 1083int iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
1091int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan); 1084int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan);
1092 1085
@@ -1097,14 +1090,8 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
1097int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, 1090int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
1098 struct iwl_rx_cmd_buffer *rxb, 1091 struct iwl_rx_cmd_buffer *rxb,
1099 struct iwl_device_cmd *cmd); 1092 struct iwl_device_cmd *cmd);
1100int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
1101 struct ieee80211_vif *vif,
1102 struct cfg80211_sched_scan_request *req,
1103 struct ieee80211_scan_ies *ies);
1104int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, 1093int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
1105 struct cfg80211_sched_scan_request *req); 1094 struct cfg80211_sched_scan_request *req);
1106int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
1107 struct cfg80211_sched_scan_request *req);
1108int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, 1095int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm,
1109 struct ieee80211_vif *vif, 1096 struct ieee80211_vif *vif,
1110 struct cfg80211_sched_scan_request *req, 1097 struct cfg80211_sched_scan_request *req,
@@ -1359,9 +1346,6 @@ static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue,
1359 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg, wdg_timeout); 1346 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg, wdg_timeout);
1360} 1347}
1361 1348
1362/* Assoc status */
1363bool iwl_mvm_is_idle(struct iwl_mvm *mvm);
1364
1365/* Thermal management and CT-kill */ 1349/* Thermal management and CT-kill */
1366void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); 1350void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff);
1367void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp); 1351void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp);
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 7a045330ab59..1f64d23e7590 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -237,8 +237,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
237 237
238 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false), 238 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false),
239 239
240 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
241 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
242 RX_HANDLER(SCAN_ITERATION_COMPLETE, 240 RX_HANDLER(SCAN_ITERATION_COMPLETE,
243 iwl_mvm_rx_scan_offload_iter_complete_notif, false), 241 iwl_mvm_rx_scan_offload_iter_complete_notif, false),
244 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 242 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 7e9aa3cb3254..ca3a18764ab1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -191,101 +191,6 @@ static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm,
191 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; 191 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10;
192} 192}
193 193
194static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
195 struct cfg80211_scan_request *req,
196 bool basic_ssid,
197 struct iwl_mvm_scan_params *params)
198{
199 struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
200 (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
201 int i;
202 int type = BIT(req->n_ssids) - 1;
203 enum ieee80211_band band = req->channels[0]->band;
204
205 if (!basic_ssid)
206 type |= BIT(req->n_ssids);
207
208 for (i = 0; i < cmd->channel_count; i++) {
209 chan->channel = cpu_to_le16(req->channels[i]->hw_value);
210 chan->type = cpu_to_le32(type);
211 if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
212 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
213 chan->active_dwell = cpu_to_le16(params->dwell[band].active);
214 chan->passive_dwell = cpu_to_le16(params->dwell[band].passive);
215 chan->iteration_count = cpu_to_le16(1);
216 chan++;
217 }
218}
219
220/*
221 * Fill in probe request with the following parameters:
222 * TA is our vif HW address, which mac80211 ensures we have.
223 * Packet is broadcasted, so this is both SA and DA.
224 * The probe request IE is made out of two: first comes the most prioritized
225 * SSID if a directed scan is requested. Second comes whatever extra
226 * information was given to us as the scan request IE.
227 */
228static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
229 int n_ssids, const u8 *ssid, int ssid_len,
230 const u8 *band_ie, int band_ie_len,
231 const u8 *common_ie, int common_ie_len,
232 int left)
233{
234 int len = 0;
235 u8 *pos = NULL;
236
237 /* Make sure there is enough space for the probe request,
238 * two mandatory IEs and the data */
239 left -= 24;
240 if (left < 0)
241 return 0;
242
243 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
244 eth_broadcast_addr(frame->da);
245 memcpy(frame->sa, ta, ETH_ALEN);
246 eth_broadcast_addr(frame->bssid);
247 frame->seq_ctrl = 0;
248
249 len += 24;
250
251 /* for passive scans, no need to fill anything */
252 if (n_ssids == 0)
253 return (u16)len;
254
255 /* points to the payload of the request */
256 pos = &frame->u.probe_req.variable[0];
257
258 /* fill in our SSID IE */
259 left -= ssid_len + 2;
260 if (left < 0)
261 return 0;
262 *pos++ = WLAN_EID_SSID;
263 *pos++ = ssid_len;
264 if (ssid && ssid_len) { /* ssid_len may be == 0 even if ssid is valid */
265 memcpy(pos, ssid, ssid_len);
266 pos += ssid_len;
267 }
268
269 len += ssid_len + 2;
270
271 if (WARN_ON(left < band_ie_len + common_ie_len))
272 return len;
273
274 if (band_ie && band_ie_len) {
275 memcpy(pos, band_ie, band_ie_len);
276 pos += band_ie_len;
277 len += band_ie_len;
278 }
279
280 if (common_ie && common_ie_len) {
281 memcpy(pos, common_ie, common_ie_len);
282 pos += common_ie_len;
283 len += common_ie_len;
284 }
285
286 return (u16)len;
287}
288
289static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac, 194static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
290 struct ieee80211_vif *vif) 195 struct ieee80211_vif *vif)
291{ 196{
@@ -379,20 +284,11 @@ static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm,
379{ 284{
380 int max_probe_len; 285 int max_probe_len;
381 286
382 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) 287 max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE;
383 max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE;
384 else
385 max_probe_len = mvm->fw->ucode_capa.max_probe_length;
386 288
387 /* we create the 802.11 header and SSID element */ 289 /* we create the 802.11 header and SSID element */
388 max_probe_len -= 24 + 2; 290 max_probe_len -= 24 + 2;
389 291
390 /* basic ssid is added only for hw_scan with and old api */
391 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID) &&
392 !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) &&
393 !is_sched_scan)
394 max_probe_len -= 32;
395
396 /* DS parameter set element is added on 2.4GHZ band if required */ 292 /* DS parameter set element is added on 2.4GHZ band if required */
397 if (iwl_mvm_rrm_scan_needed(mvm)) 293 if (iwl_mvm_rrm_scan_needed(mvm))
398 max_probe_len -= 3; 294 max_probe_len -= 3;
@@ -404,9 +300,6 @@ int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan)
404{ 300{
405 int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan); 301 int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan);
406 302
407 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN))
408 return max_ie_len;
409
410 /* TODO: [BUG] This function should return the maximum allowed size of 303 /* TODO: [BUG] This function should return the maximum allowed size of
411 * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs 304 * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs
412 * in the same command. So the correct implementation of this function 305 * in the same command. So the correct implementation of this function
@@ -420,129 +313,6 @@ int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan)
420 return max_ie_len; 313 return max_ie_len;
421} 314}
422 315
423int iwl_mvm_scan_request(struct iwl_mvm *mvm,
424 struct ieee80211_vif *vif,
425 struct cfg80211_scan_request *req)
426{
427 struct iwl_host_cmd hcmd = {
428 .id = SCAN_REQUEST_CMD,
429 .len = { 0, },
430 .data = { mvm->scan_cmd, },
431 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
432 };
433 struct iwl_scan_cmd *cmd = mvm->scan_cmd;
434 int ret;
435 u32 status;
436 int ssid_len = 0;
437 u8 *ssid = NULL;
438 bool basic_ssid = !(mvm->fw->ucode_capa.flags &
439 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
440 struct iwl_mvm_scan_params params = {};
441
442 lockdep_assert_held(&mvm->mutex);
443
444 /* we should have failed registration if scan_cmd was NULL */
445 if (WARN_ON(mvm->scan_cmd == NULL))
446 return -ENOMEM;
447
448 IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n");
449 mvm->scan_status = IWL_MVM_SCAN_OS;
450 memset(cmd, 0, ksize(cmd));
451
452 cmd->channel_count = (u8)req->n_channels;
453 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
454 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
455 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
456
457 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, req->flags, &params);
458 cmd->max_out_time = cpu_to_le32(params.max_out_time);
459 cmd->suspend_time = cpu_to_le32(params.suspend_time);
460 if (params.passive_fragmented)
461 cmd->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
462
463 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
464 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
465 MAC_FILTER_IN_BEACON);
466
467 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
468 cmd->type = cpu_to_le32(SCAN_TYPE_DISCOVERY_FORCED);
469 else
470 cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
471
472 cmd->repeats = cpu_to_le32(1);
473
474 /*
475 * If the user asked for passive scan, don't change to active scan if
476 * you see any activity on the channel - remain passive.
477 */
478 if (req->n_ssids > 0) {
479 cmd->passive2active = cpu_to_le16(1);
480 cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE;
481 if (basic_ssid) {
482 ssid = req->ssids[0].ssid;
483 ssid_len = req->ssids[0].ssid_len;
484 }
485 } else {
486 cmd->passive2active = 0;
487 cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE;
488 }
489
490 iwl_mvm_scan_fill_ssids(cmd->direct_scan, req->ssids, req->n_ssids,
491 basic_ssid ? 1 : 0);
492
493 cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
494 3 << TX_CMD_FLG_BT_PRIO_POS);
495
496 cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id;
497 cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
498 cmd->tx_cmd.rate_n_flags =
499 iwl_mvm_scan_rate_n_flags(mvm, req->channels[0]->band,
500 req->no_cck);
501
502 cmd->tx_cmd.len =
503 cpu_to_le16(iwl_mvm_fill_probe_req(
504 (struct ieee80211_mgmt *)cmd->data,
505 vif->addr,
506 req->n_ssids, ssid, ssid_len,
507 req->ie, req->ie_len, NULL, 0,
508 mvm->fw->ucode_capa.max_probe_length));
509
510 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, &params);
511
512 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) +
513 le16_to_cpu(cmd->tx_cmd.len) +
514 (cmd->channel_count * sizeof(struct iwl_scan_channel)));
515 hcmd.len[0] = le16_to_cpu(cmd->len);
516
517 status = SCAN_RESPONSE_OK;
518 ret = iwl_mvm_send_cmd_status(mvm, &hcmd, &status);
519 if (!ret && status == SCAN_RESPONSE_OK) {
520 IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
521 } else {
522 /*
523 * If the scan failed, it usually means that the FW was unable
524 * to allocate the time events. Warn on it, but maybe we
525 * should try to send the command again with different params.
526 */
527 IWL_ERR(mvm, "Scan failed! status 0x%x ret %d\n",
528 status, ret);
529 mvm->scan_status = IWL_MVM_SCAN_NONE;
530 ret = -EIO;
531 }
532 return ret;
533}
534
535int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
536 struct iwl_device_cmd *cmd)
537{
538 struct iwl_rx_packet *pkt = rxb_addr(rxb);
539 struct iwl_cmd_response *resp = (void *)pkt->data;
540
541 IWL_DEBUG_SCAN(mvm, "Scan response received. status 0x%x\n",
542 le32_to_cpu(resp->status));
543 return 0;
544}
545
546int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, 316int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
547 struct iwl_rx_cmd_buffer *rxb, 317 struct iwl_rx_cmd_buffer *rxb,
548 struct iwl_device_cmd *cmd) 318 struct iwl_device_cmd *cmd)
@@ -556,130 +326,25 @@ int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
556 return 0; 326 return 0;
557} 327}
558 328
559int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
560 struct iwl_device_cmd *cmd)
561{
562 struct iwl_rx_packet *pkt = rxb_addr(rxb);
563 struct iwl_scan_complete_notif *notif = (void *)pkt->data;
564
565 lockdep_assert_held(&mvm->mutex);
566
567 IWL_DEBUG_SCAN(mvm, "Scan complete: status=0x%x scanned channels=%d\n",
568 notif->status, notif->scanned_channels);
569
570 if (mvm->scan_status == IWL_MVM_SCAN_OS)
571 mvm->scan_status = IWL_MVM_SCAN_NONE;
572 ieee80211_scan_completed(mvm->hw, notif->status != SCAN_COMP_STATUS_OK);
573
574 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
575
576 return 0;
577}
578
579int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm, 329int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm,
580 struct iwl_rx_cmd_buffer *rxb, 330 struct iwl_rx_cmd_buffer *rxb,
581 struct iwl_device_cmd *cmd) 331 struct iwl_device_cmd *cmd)
582{ 332{
583 struct iwl_rx_packet *pkt = rxb_addr(rxb);
584
585 if (!(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) &&
586 !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) {
587 struct iwl_sched_scan_results *notif = (void *)pkt->data;
588
589 if (!(notif->client_bitmap & SCAN_CLIENT_SCHED_SCAN))
590 return 0;
591 }
592
593 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n"); 333 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n");
594 ieee80211_sched_scan_results(mvm->hw); 334 ieee80211_sched_scan_results(mvm->hw);
595 335
596 return 0; 336 return 0;
597} 337}
598 338
599static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
600 struct iwl_rx_packet *pkt, void *data)
601{
602 struct iwl_mvm *mvm =
603 container_of(notif_wait, struct iwl_mvm, notif_wait);
604 struct iwl_scan_complete_notif *notif;
605 u32 *resp;
606
607 switch (pkt->hdr.cmd) {
608 case SCAN_ABORT_CMD:
609 resp = (void *)pkt->data;
610 if (*resp == CAN_ABORT_STATUS) {
611 IWL_DEBUG_SCAN(mvm,
612 "Scan can be aborted, wait until completion\n");
613 return false;
614 }
615
616 /*
617 * If scan cannot be aborted, it means that we had a
618 * SCAN_COMPLETE_NOTIFICATION in the pipe and it called
619 * ieee80211_scan_completed already.
620 */
621 IWL_DEBUG_SCAN(mvm, "Scan cannot be aborted, exit now: %d\n",
622 *resp);
623 return true;
624
625 case SCAN_COMPLETE_NOTIFICATION:
626 notif = (void *)pkt->data;
627 IWL_DEBUG_SCAN(mvm, "Scan aborted: status 0x%x\n",
628 notif->status);
629 return true;
630
631 default:
632 WARN_ON(1);
633 return false;
634 };
635}
636
637static int iwl_mvm_cancel_regular_scan(struct iwl_mvm *mvm)
638{
639 struct iwl_notification_wait wait_scan_abort;
640 static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD,
641 SCAN_COMPLETE_NOTIFICATION };
642 int ret;
643
644 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
645 scan_abort_notif,
646 ARRAY_SIZE(scan_abort_notif),
647 iwl_mvm_scan_abort_notif, NULL);
648
649 ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, 0, 0, NULL);
650 if (ret) {
651 IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret);
652 /* mac80211's state will be cleaned in the nic_restart flow */
653 goto out_remove_notif;
654 }
655
656 return iwl_wait_notification(&mvm->notif_wait, &wait_scan_abort, HZ);
657
658out_remove_notif:
659 iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort);
660 return ret;
661}
662
663int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, 339int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
664 struct iwl_rx_cmd_buffer *rxb, 340 struct iwl_rx_cmd_buffer *rxb,
665 struct iwl_device_cmd *cmd) 341 struct iwl_device_cmd *cmd)
666{ 342{
667 struct iwl_rx_packet *pkt = rxb_addr(rxb); 343 struct iwl_rx_packet *pkt = rxb_addr(rxb);
668 u8 status, ebs_status; 344 struct iwl_periodic_scan_complete *scan_notif;
669
670 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) {
671 struct iwl_periodic_scan_complete *scan_notif;
672 345
673 scan_notif = (void *)pkt->data; 346 scan_notif = (void *)pkt->data;
674 status = scan_notif->status;
675 ebs_status = scan_notif->ebs_status;
676 } else {
677 struct iwl_scan_offload_complete *scan_notif;
678 347
679 scan_notif = (void *)pkt->data;
680 status = scan_notif->status;
681 ebs_status = scan_notif->ebs_status;
682 }
683 /* scan status must be locked for proper checking */ 348 /* scan status must be locked for proper checking */
684 lockdep_assert_held(&mvm->mutex); 349 lockdep_assert_held(&mvm->mutex);
685 350
@@ -687,9 +352,9 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
687 "%s completed, status %s, EBS status %s\n", 352 "%s completed, status %s, EBS status %s\n",
688 mvm->scan_status == IWL_MVM_SCAN_SCHED ? 353 mvm->scan_status == IWL_MVM_SCAN_SCHED ?
689 "Scheduled scan" : "Scan", 354 "Scheduled scan" : "Scan",
690 status == IWL_SCAN_OFFLOAD_COMPLETED ? 355 scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
691 "completed" : "aborted", 356 "completed" : "aborted",
692 ebs_status == IWL_SCAN_EBS_SUCCESS ? 357 scan_notif->ebs_status == IWL_SCAN_EBS_SUCCESS ?
693 "success" : "failed"); 358 "success" : "failed");
694 359
695 360
@@ -700,64 +365,16 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
700 } else if (mvm->scan_status == IWL_MVM_SCAN_OS) { 365 } else if (mvm->scan_status == IWL_MVM_SCAN_OS) {
701 mvm->scan_status = IWL_MVM_SCAN_NONE; 366 mvm->scan_status = IWL_MVM_SCAN_NONE;
702 ieee80211_scan_completed(mvm->hw, 367 ieee80211_scan_completed(mvm->hw,
703 status == IWL_SCAN_OFFLOAD_ABORTED); 368 scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED);
704 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 369 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
705 } 370 }
706 371
707 if (ebs_status) 372 if (scan_notif->ebs_status)
708 mvm->last_ebs_successful = false; 373 mvm->last_ebs_successful = false;
709 374
710 return 0; 375 return 0;
711} 376}
712 377
713static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
714 struct ieee80211_vif *vif,
715 struct ieee80211_scan_ies *ies,
716 enum ieee80211_band band,
717 struct iwl_tx_cmd *cmd,
718 u8 *data)
719{
720 u16 cmd_len;
721
722 cmd->tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL);
723 cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
724 cmd->sta_id = mvm->aux_sta.sta_id;
725
726 cmd->rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm, band, false);
727
728 cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data,
729 vif->addr,
730 1, NULL, 0,
731 ies->ies[band], ies->len[band],
732 ies->common_ies, ies->common_ie_len,
733 SCAN_OFFLOAD_PROBE_REQ_SIZE);
734 cmd->len = cpu_to_le16(cmd_len);
735}
736
737static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
738 struct ieee80211_vif *vif,
739 struct cfg80211_sched_scan_request *req,
740 struct iwl_scan_offload_cmd *scan,
741 struct iwl_mvm_scan_params *params)
742{
743 scan->channel_count = req->n_channels;
744 scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
745 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
746 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
747 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
748
749 scan->max_out_time = cpu_to_le32(params->max_out_time);
750 scan->suspend_time = cpu_to_le32(params->suspend_time);
751
752 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
753 MAC_FILTER_IN_BEACON);
754 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);
755 scan->rep_count = cpu_to_le32(1);
756
757 if (params->passive_fragmented)
758 scan->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
759}
760
761static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list) 378static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
762{ 379{
763 int i; 380 int i;
@@ -815,127 +432,6 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
815 } 432 }
816} 433}
817 434
818static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
819 struct cfg80211_sched_scan_request *req,
820 u8 *channels_buffer,
821 enum ieee80211_band band,
822 int *head,
823 u32 ssid_bitmap,
824 struct iwl_mvm_scan_params *params)
825{
826 u32 n_channels = mvm->fw->ucode_capa.n_scan_channels;
827 __le32 *type = (__le32 *)channels_buffer;
828 __le16 *channel_number = (__le16 *)(type + n_channels);
829 __le16 *iter_count = channel_number + n_channels;
830 __le32 *iter_interval = (__le32 *)(iter_count + n_channels);
831 u8 *active_dwell = (u8 *)(iter_interval + n_channels);
832 u8 *passive_dwell = active_dwell + n_channels;
833 int i, index = 0;
834
835 for (i = 0; i < req->n_channels; i++) {
836 struct ieee80211_channel *chan = req->channels[i];
837
838 if (chan->band != band)
839 continue;
840
841 index = *head;
842 (*head)++;
843
844 channel_number[index] = cpu_to_le16(chan->hw_value);
845 active_dwell[index] = params->dwell[band].active;
846 passive_dwell[index] = params->dwell[band].passive;
847
848 iter_count[index] = cpu_to_le16(1);
849 iter_interval[index] = 0;
850
851 if (!(chan->flags & IEEE80211_CHAN_NO_IR))
852 type[index] |=
853 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
854
855 type[index] |= cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL |
856 IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL);
857
858 if (chan->flags & IEEE80211_CHAN_NO_HT40)
859 type[index] |=
860 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW);
861
862 /* scan for all SSIDs from req->ssids */
863 type[index] |= cpu_to_le32(ssid_bitmap);
864 }
865}
866
867int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
868 struct ieee80211_vif *vif,
869 struct cfg80211_sched_scan_request *req,
870 struct ieee80211_scan_ies *ies)
871{
872 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
873 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
874 int head = 0;
875 u32 ssid_bitmap;
876 int cmd_len;
877 int ret;
878 u8 *probes;
879 bool basic_ssid = !(mvm->fw->ucode_capa.flags &
880 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
881
882 struct iwl_scan_offload_cfg *scan_cfg;
883 struct iwl_host_cmd cmd = {
884 .id = SCAN_OFFLOAD_CONFIG_CMD,
885 };
886 struct iwl_mvm_scan_params params = {};
887
888 lockdep_assert_held(&mvm->mutex);
889
890 cmd_len = sizeof(struct iwl_scan_offload_cfg) +
891 mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE +
892 2 * SCAN_OFFLOAD_PROBE_REQ_SIZE;
893
894 scan_cfg = kzalloc(cmd_len, GFP_KERNEL);
895 if (!scan_cfg)
896 return -ENOMEM;
897
898 probes = scan_cfg->data +
899 mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE;
900
901 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);
902 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, &params);
903 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len);
904
905 iwl_scan_offload_build_ssid(req, scan_cfg->scan_cmd.direct_scan,
906 &ssid_bitmap, basic_ssid);
907 /* build tx frames for supported bands */
908 if (band_2ghz) {
909 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
910 IEEE80211_BAND_2GHZ,
911 &scan_cfg->scan_cmd.tx_cmd[0],
912 probes);
913 iwl_build_channel_cfg(mvm, req, scan_cfg->data,
914 IEEE80211_BAND_2GHZ, &head,
915 ssid_bitmap, &params);
916 }
917 if (band_5ghz) {
918 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
919 IEEE80211_BAND_5GHZ,
920 &scan_cfg->scan_cmd.tx_cmd[1],
921 probes +
922 SCAN_OFFLOAD_PROBE_REQ_SIZE);
923 iwl_build_channel_cfg(mvm, req, scan_cfg->data,
924 IEEE80211_BAND_5GHZ, &head,
925 ssid_bitmap, &params);
926 }
927
928 cmd.data[0] = scan_cfg;
929 cmd.len[0] = cmd_len;
930 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
931
932 IWL_DEBUG_SCAN(mvm, "Sending scheduled scan config\n");
933
934 ret = iwl_mvm_send_cmd(mvm, &cmd);
935 kfree(scan_cfg);
936 return ret;
937}
938
939int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, 435int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
940 struct cfg80211_sched_scan_request *req) 436 struct cfg80211_sched_scan_request *req)
941{ 437{
@@ -1018,33 +514,6 @@ static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm,
1018 return true; 514 return true;
1019} 515}
1020 516
1021int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
1022 struct cfg80211_sched_scan_request *req)
1023{
1024 struct iwl_scan_offload_req scan_req = {
1025 .watchdog = IWL_SCHED_SCAN_WATCHDOG,
1026
1027 .schedule_line[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS,
1028 .schedule_line[0].delay = cpu_to_le16(req->interval / 1000),
1029 .schedule_line[0].full_scan_mul = 1,
1030
1031 .schedule_line[1].iterations = 0xff,
1032 .schedule_line[1].delay = cpu_to_le16(req->interval / 1000),
1033 .schedule_line[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER,
1034 };
1035
1036 if (iwl_mvm_scan_pass_all(mvm, req))
1037 scan_req.flags |= cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_PASS_ALL);
1038
1039 if (mvm->last_ebs_successful &&
1040 mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT)
1041 scan_req.flags |=
1042 cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_EBS_ACCURATE_MODE);
1043
1044 return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, 0,
1045 sizeof(scan_req), &scan_req);
1046}
1047
1048int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, 517int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm,
1049 struct ieee80211_vif *vif, 518 struct ieee80211_vif *vif,
1050 struct cfg80211_sched_scan_request *req, 519 struct cfg80211_sched_scan_request *req,
@@ -1057,21 +526,12 @@ int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm,
1057 if (ret) 526 if (ret)
1058 return ret; 527 return ret;
1059 ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies); 528 ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies);
1060 } else if ((mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) {
1061 mvm->scan_status = IWL_MVM_SCAN_SCHED;
1062 ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
1063 if (ret)
1064 return ret;
1065 ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies);
1066 } else { 529 } else {
1067 mvm->scan_status = IWL_MVM_SCAN_SCHED; 530 mvm->scan_status = IWL_MVM_SCAN_SCHED;
1068 ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies);
1069 if (ret)
1070 return ret;
1071 ret = iwl_mvm_config_sched_scan_profiles(mvm, req); 531 ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
1072 if (ret) 532 if (ret)
1073 return ret; 533 return ret;
1074 ret = iwl_mvm_sched_scan_start(mvm, req); 534 ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies);
1075 } 535 }
1076 536
1077 return ret; 537 return ret;
@@ -1088,9 +548,7 @@ static int iwl_mvm_send_scan_offload_abort(struct iwl_mvm *mvm)
1088 /* Exit instantly with error when device is not ready 548 /* Exit instantly with error when device is not ready
1089 * to receive scan abort command or it does not perform 549 * to receive scan abort command or it does not perform
1090 * scheduled scan currently */ 550 * scheduled scan currently */
1091 if (mvm->scan_status != IWL_MVM_SCAN_SCHED && 551 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
1092 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
1093 mvm->scan_status != IWL_MVM_SCAN_OS))
1094 return -EIO; 552 return -EIO;
1095 553
1096 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status); 554 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
@@ -1131,13 +589,6 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
1131 if (iwl_mvm_is_radio_killed(mvm)) 589 if (iwl_mvm_is_radio_killed(mvm))
1132 goto out; 590 goto out;
1133 591
1134 if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
1135 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
1136 mvm->scan_status != IWL_MVM_SCAN_OS)) {
1137 IWL_DEBUG_SCAN(mvm, "No scan to stop\n");
1138 return 0;
1139 }
1140
1141 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done, 592 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done,
1142 scan_done_notif, 593 scan_done_notif,
1143 ARRAY_SIZE(scan_done_notif), 594 ARRAY_SIZE(scan_done_notif),
@@ -1580,9 +1031,7 @@ int iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
1580 return 0; 1031 return 0;
1581 } 1032 }
1582 1033
1583 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) 1034 return iwl_mvm_scan_offload_stop(mvm, true);
1584 return iwl_mvm_scan_offload_stop(mvm, true);
1585 return iwl_mvm_cancel_regular_scan(mvm);
1586} 1035}
1587 1036
1588/* UMAC scan API */ 1037/* UMAC scan API */
@@ -2159,14 +1608,8 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm)
2159 mvm->fw->ucode_capa.n_scan_channels + 1608 mvm->fw->ucode_capa.n_scan_channels +
2160 sizeof(struct iwl_scan_req_umac_tail); 1609 sizeof(struct iwl_scan_req_umac_tail);
2161 1610
2162 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) 1611 return sizeof(struct iwl_scan_req_unified_lmac) +
2163 return sizeof(struct iwl_scan_req_unified_lmac) + 1612 sizeof(struct iwl_scan_channel_cfg_lmac) *
2164 sizeof(struct iwl_scan_channel_cfg_lmac) * 1613 mvm->fw->ucode_capa.n_scan_channels +
2165 mvm->fw->ucode_capa.n_scan_channels + 1614 sizeof(struct iwl_scan_probe_req);
2166 sizeof(struct iwl_scan_probe_req);
2167
2168 return sizeof(struct iwl_scan_cmd) +
2169 mvm->fw->ucode_capa.max_probe_length +
2170 mvm->fw->ucode_capa.n_scan_channels *
2171 sizeof(struct iwl_scan_channel);
2172} 1615}
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 2b75a0d6d41e..8bdfb8bc7ff3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -746,25 +746,6 @@ bool iwl_mvm_low_latency(struct iwl_mvm *mvm)
746 return result; 746 return result;
747} 747}
748 748
749static void iwl_mvm_idle_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
750{
751 bool *idle = _data;
752
753 if (!vif->bss_conf.idle)
754 *idle = false;
755}
756
757bool iwl_mvm_is_idle(struct iwl_mvm *mvm)
758{
759 bool idle = true;
760
761 ieee80211_iterate_active_interfaces_atomic(
762 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
763 iwl_mvm_idle_iter, &idle);
764
765 return idle;
766}
767
768struct iwl_bss_iter_data { 749struct iwl_bss_iter_data {
769 struct ieee80211_vif *vif; 750 struct ieee80211_vif *vif;
770 bool error; 751 bool error;