xref: /wlan-driver/qcacld-3.0/core/hdd/src/wlan_hdd_scan.c (revision 5113495b16420b49004c444715d2daae2066e7dc) !
1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: wlan_hdd_scan.c
22  *
23  * WLAN Host Device Driver scan implementation
24  */
25 
26 #include <linux/wireless.h>
27 #include <net/cfg80211.h>
28 
29 #include "wlan_hdd_includes.h"
30 #include "cds_api.h"
31 #include "cds_api.h"
32 #include "ani_global.h"
33 #include "dot11f.h"
34 #include "cds_sched.h"
35 #include "osif_sync.h"
36 #include "wlan_hdd_p2p.h"
37 #include "wlan_hdd_trace.h"
38 #include "wlan_hdd_scan.h"
39 #include "wlan_policy_mgr_api.h"
40 #include "wlan_hdd_power.h"
41 #include "wma_api.h"
42 #include "cds_utils.h"
43 #include "wlan_p2p_ucfg_api.h"
44 #include "cfg_ucfg_api.h"
45 
46 #include <qca_vendor.h>
47 #include <wlan_cfg80211_scan.h>
48 #include "wlan_utility.h"
49 #include "wlan_hdd_object_manager.h"
50 #include "nan_ucfg_api.h"
51 
52 #define SCAN_DONE_EVENT_BUF_SIZE 4096
53 #define RATE_MASK 0x7f
54 
55 /**
56  * hdd_vendor_scan_callback() - Scan completed callback event
57  * @adapter: HDD adapter
58  * @req: Scan request
59  * @aborted: true scan aborted false scan success
60  *
61  * This function sends scan completed callback event to NL.
62  *
63  * Return: none
64  */
hdd_vendor_scan_callback(struct hdd_adapter * adapter,struct cfg80211_scan_request * req,bool aborted)65 static void hdd_vendor_scan_callback(struct hdd_adapter *adapter,
66 					struct cfg80211_scan_request *req,
67 					bool aborted)
68 {
69 	struct hdd_context *hddctx = WLAN_HDD_GET_CTX(adapter);
70 	struct sk_buff *skb;
71 	struct nlattr *attr;
72 	int i;
73 	uint8_t scan_status;
74 	uint64_t cookie;
75 	enum qca_nl80211_vendor_subcmds_index index =
76 		QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX;
77 
78 	hdd_enter();
79 
80 	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
81 		hdd_err("Invalid adapter magic");
82 		qdf_mem_free(req);
83 		return;
84 	}
85 	skb = wlan_cfg80211_vendor_event_alloc(hddctx->wiphy, &adapter->wdev,
86 					       SCAN_DONE_EVENT_BUF_SIZE +
87 					       4 + NLMSG_HDRLEN,
88 					       index, GFP_KERNEL);
89 	if (!skb) {
90 		hdd_err("skb alloc failed");
91 		qdf_mem_free(req);
92 		return;
93 	}
94 
95 	cookie = (uintptr_t)req;
96 	attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS);
97 	if (!attr)
98 		goto nla_put_failure;
99 	for (i = 0; i < req->n_ssids; i++) {
100 		if (nla_put(skb, i, req->ssids[i].ssid_len,
101 			req->ssids[i].ssid)) {
102 			hdd_err("Failed to add ssid");
103 			goto nla_put_failure;
104 		}
105 	}
106 	nla_nest_end(skb, attr);
107 	attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES);
108 	if (!attr)
109 		goto nla_put_failure;
110 	for (i = 0; i < req->n_channels; i++) {
111 		if (nla_put_u32(skb, i, req->channels[i]->center_freq)) {
112 			hdd_err("Failed to add channel");
113 			goto nla_put_failure;
114 		}
115 	}
116 	nla_nest_end(skb, attr);
117 
118 	if (req->ie &&
119 		nla_put(skb, QCA_WLAN_VENDOR_ATTR_SCAN_IE, req->ie_len,
120 			req->ie)) {
121 		hdd_err("Failed to add scan ie");
122 		goto nla_put_failure;
123 	}
124 	if (req->flags &&
125 		nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS, req->flags)) {
126 		hdd_err("Failed to add scan flags");
127 		goto nla_put_failure;
128 	}
129 	if (hdd_wlan_nla_put_u64(skb,
130 				  QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
131 				  cookie)) {
132 		hdd_err("Failed to add scan cookie");
133 		goto nla_put_failure;
134 	}
135 	scan_status = (aborted == true) ? VENDOR_SCAN_STATUS_ABORTED :
136 		VENDOR_SCAN_STATUS_NEW_RESULTS;
137 	if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_SCAN_STATUS, scan_status)) {
138 		hdd_err("Failed to add scan status");
139 		goto nla_put_failure;
140 	}
141 	wlan_cfg80211_vendor_event(skb, GFP_KERNEL);
142 	hdd_info("scan complete event sent to NL");
143 	qdf_mem_free(req);
144 	return;
145 
146 nla_put_failure:
147 	wlan_cfg80211_vendor_free_skb(skb);
148 	qdf_mem_free(req);
149 }
150 
151 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
152 /**
153  * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
154  * @adapter: Pointer to the adapter
155  * @req : Scan request
156  * @aborted : true scan aborted false scan success
157  *
158  * This function notifies scan done to cfg80211
159  *
160  * Return: none
161  */
hdd_cfg80211_scan_done(struct hdd_adapter * adapter,struct cfg80211_scan_request * req,bool aborted)162 static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
163 				   struct cfg80211_scan_request *req,
164 				   bool aborted)
165 {
166 	struct cfg80211_scan_info info = {
167 		.aborted = aborted
168 	};
169 
170 	if (adapter->dev->flags & IFF_UP)
171 		cfg80211_scan_done(req, &info);
172 }
173 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
174 /**
175  * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
176  * @adapter: Pointer to the adapter
177  * @req : Scan request
178  * @aborted : true scan aborted false scan success
179  *
180  * This function notifies scan done to cfg80211
181  *
182  * Return: none
183  */
hdd_cfg80211_scan_done(struct hdd_adapter * adapter,struct cfg80211_scan_request * req,bool aborted)184 static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
185 				   struct cfg80211_scan_request *req,
186 				   bool aborted)
187 {
188 	if (adapter->dev->flags & IFF_UP)
189 		cfg80211_scan_done(req, aborted);
190 }
191 #else
192 /**
193  * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
194  * @adapter: Pointer to the adapter
195  * @req : Scan request
196  * @aborted : true scan aborted false scan success
197  *
198  * This function notifies scan done to cfg80211
199  *
200  * Return: none
201  */
hdd_cfg80211_scan_done(struct hdd_adapter * adapter,struct cfg80211_scan_request * req,bool aborted)202 static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
203 				   struct cfg80211_scan_request *req,
204 				   bool aborted)
205 {
206 	cfg80211_scan_done(req, aborted);
207 }
208 #endif
209 
210 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
211 /**
212  * wlan_hdd_sap_skip_scan_check() - The function will check OBSS
213  *         scan skip or not for SAP.
214  * @hdd_ctx: pointer to hdd context.
215  * @request: pointer to scan request.
216  *
217  * This function will check the scan request's chan list against the
218  * previous ACS scan chan list. If all the chan are covered by
219  * previous ACS scan, we can skip the scan and return scan complete
220  * to save the SAP starting time.
221  *
222  * Return: true to skip the scan,
223  *            false to continue the scan
224  */
wlan_hdd_sap_skip_scan_check(struct hdd_context * hdd_ctx,struct cfg80211_scan_request * request)225 static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx,
226 	struct cfg80211_scan_request *request)
227 {
228 	int i, j;
229 	bool skip;
230 
231 	hdd_debug("HDD_ACS_SKIP_STATUS = %d",
232 		hdd_ctx->skip_acs_scan_status);
233 	if (hdd_ctx->skip_acs_scan_status != eSAP_SKIP_ACS_SCAN)
234 		return false;
235 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
236 	if (!hdd_ctx->last_acs_freq_list ||
237 	    hdd_ctx->num_of_channels == 0 ||
238 	    request->n_channels == 0) {
239 		qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
240 		return false;
241 	}
242 	skip = true;
243 	for (i = 0; i < request->n_channels ; i++) {
244 		bool find = false;
245 
246 		for (j = 0; j < hdd_ctx->num_of_channels; j++) {
247 			if (hdd_ctx->last_acs_freq_list[j] ==
248 			    request->channels[i]->center_freq) {
249 				find = true;
250 				break;
251 			}
252 		}
253 		if (!find) {
254 			skip = false;
255 			hdd_debug("Freq %d isn't in ACS freq list",
256 				  request->channels[i]->center_freq);
257 			break;
258 		}
259 	}
260 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
261 	return skip;
262 }
263 #else
wlan_hdd_sap_skip_scan_check(struct hdd_context * hdd_ctx,struct cfg80211_scan_request * request)264 static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx,
265 	struct cfg80211_scan_request *request)
266 {
267 	return false;
268 }
269 #endif
270 
wlan_hdd_cfg80211_scan_block(struct hdd_adapter * adapter)271 void wlan_hdd_cfg80211_scan_block(struct hdd_adapter *adapter)
272 {
273 	struct cfg80211_scan_request *request;
274 	struct scan_req *blocked_scan_req;
275 	qdf_list_node_t *node;
276 
277 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
278 		hdd_err("HDD adapter context is invalid");
279 		return;
280 	}
281 
282 	qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock);
283 
284 	while (!qdf_list_empty(&adapter->blocked_scan_request_q)) {
285 		qdf_list_remove_front(&adapter->blocked_scan_request_q,
286 				      &node);
287 		blocked_scan_req = qdf_container_of(node, struct scan_req,
288 						    node);
289 		request = blocked_scan_req->scan_request;
290 		request->n_ssids = 0;
291 		request->n_channels = 0;
292 		if (blocked_scan_req->source == NL_SCAN) {
293 			hdd_err("Scan aborted. Null result sent");
294 			hdd_cfg80211_scan_done(adapter, request, true);
295 		} else {
296 			hdd_err("Vendor scan aborted. Null result sent");
297 			hdd_vendor_scan_callback(adapter, request, true);
298 		}
299 		qdf_mem_free(blocked_scan_req);
300 	}
301 
302 	qdf_mutex_release(&adapter->blocked_scan_request_q_lock);
303 }
304 
hdd_init_scan_reject_params(struct hdd_context * hdd_ctx)305 void hdd_init_scan_reject_params(struct hdd_context *hdd_ctx)
306 {
307 	if (hdd_ctx) {
308 		hdd_ctx->last_scan_reject_timestamp = 0;
309 		hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
310 		hdd_ctx->last_scan_reject_reason = 0;
311 		hdd_ctx->scan_reject_cnt = 0;
312 	}
313 }
314 
315 /*
316  * wlan_hdd_update_scan_ies() - API to update the scan IEs of scan request
317  * with already stored default scan IEs
318  *
319  * @adapter: Pointer to HDD adapter
320  * @scan_info: Pointer to scan info in HDD adapter
321  * @scan_ie: Pointer to scan IE in scan request
322  * @scan_ie_len: Pointer to scan IE length in scan request
323  *
324  * Return: 0 on success; error number otherwise
325  */
wlan_hdd_update_scan_ies(struct hdd_adapter * adapter,struct hdd_scan_info * scan_info,uint8_t * scan_ie,uint16_t * scan_ie_len)326 static int wlan_hdd_update_scan_ies(struct hdd_adapter *adapter,
327 			struct hdd_scan_info *scan_info, uint8_t *scan_ie,
328 			uint16_t *scan_ie_len)
329 {
330 	uint16_t rem_len = scan_info->default_scan_ies_len;
331 	uint8_t *temp_ie = scan_info->default_scan_ies;
332 	uint8_t *current_ie;
333 	const uint8_t *mbo_ie;
334 	uint8_t elem_id;
335 	uint16_t elem_len;
336 	bool add_ie = false;
337 
338 	if (!scan_info->default_scan_ies_len || !scan_info->default_scan_ies)
339 		return 0;
340 
341 	mbo_ie = wlan_get_vendor_ie_ptr_from_oui(MBO_OUI_TYPE,
342 						 MBO_OUI_TYPE_SIZE, scan_ie,
343 						 *scan_ie_len);
344 	while (rem_len >= 2) {
345 		current_ie = temp_ie;
346 		elem_id = *temp_ie++;
347 		elem_len = *temp_ie++;
348 		rem_len -= 2;
349 
350 		if (elem_len > rem_len) {
351 			hdd_err("Invalid element len %d for elem %d", elem_len,
352 				elem_id);
353 			return 0;
354 		}
355 
356 		switch (elem_id) {
357 		case DOT11F_EID_EXTCAP:
358 			if (!wlan_get_ie_ptr_from_eid(DOT11F_EID_EXTCAP,
359 						      scan_ie, *scan_ie_len))
360 				add_ie = true;
361 			break;
362 		case WLAN_ELEMID_VENDOR:
363 			/* Donot add MBO IE if its already present */
364 			if ((!mbo_ie &&
365 			     0 == qdf_mem_cmp(&temp_ie[0], MBO_OUI_TYPE,
366 					      MBO_OUI_TYPE_SIZE)) ||
367 			    (0 == qdf_mem_cmp(&temp_ie[0], QCN_OUI_TYPE,
368 					      QCN_OUI_TYPE_SIZE)))
369 				add_ie = true;
370 			break;
371 		}
372 
373 		if (add_ie && (((*scan_ie_len) + elem_len) >
374 					SIR_MAC_MAX_ADD_IE_LENGTH)){
375 			hdd_err("Not enough buffer to save default scan IE's");
376 			return 0;
377 		}
378 
379 		if (add_ie) {
380 			qdf_mem_copy(scan_ie + (*scan_ie_len),
381 						current_ie, elem_len + 2);
382 			(*scan_ie_len) += (elem_len + 2);
383 			add_ie = false;
384 		}
385 
386 		temp_ie += elem_len;
387 		rem_len -= elem_len;
388 	}
389 	return 0;
390 }
391 
392 static int
wlan_hdd_enqueue_blocked_scan_request(struct net_device * dev,struct cfg80211_scan_request * request,uint8_t source)393 wlan_hdd_enqueue_blocked_scan_request(struct net_device *dev,
394 				      struct cfg80211_scan_request *request,
395 				      uint8_t source)
396 {
397 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
398 	struct scan_req *blocked_scan_req =
399 		qdf_mem_malloc(sizeof(*blocked_scan_req));
400 	int ret = 0;
401 
402 	if (!blocked_scan_req)
403 		return -EINVAL;
404 
405 	blocked_scan_req->dev = dev;
406 	blocked_scan_req->scan_request = request;
407 	blocked_scan_req->source = source;
408 	blocked_scan_req->scan_id = 0;
409 
410 	qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock);
411 	if (qdf_list_size(&adapter->blocked_scan_request_q) <
412 		WLAN_MAX_SCAN_COUNT)
413 		qdf_list_insert_back(&adapter->blocked_scan_request_q,
414 				     &blocked_scan_req->node);
415 	else
416 		ret = -EINVAL;
417 	qdf_mutex_release(&adapter->blocked_scan_request_q_lock);
418 
419 	if (ret) {
420 		hdd_err("Maximum number of block scan request reached!");
421 		qdf_mem_free(blocked_scan_req);
422 	}
423 
424 	return ret;
425 }
426 
427 /* Define short name to use in cds_trigger_recovery */
428 #define SCAN_FAILURE QDF_SCAN_ATTEMPT_FAILURES
429 
430 /**
431  * __wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request
432  * @wiphy: Pointer to wiphy
433  * @request: Pointer to scan request
434  * @source: scan request source(NL/Vendor scan)
435  *
436  * This API responds to scan trigger and update cfg80211 scan database
437  * later, scan dump command can be used to receive scan results
438  *
439  * Return: 0 for success, non zero for failure
440  */
__wlan_hdd_cfg80211_scan(struct wiphy * wiphy,struct cfg80211_scan_request * request,uint8_t source)441 static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
442 				    struct cfg80211_scan_request *request,
443 				    uint8_t source)
444 {
445 	struct net_device *dev = request->wdev->netdev;
446 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
447 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
448 	int status;
449 	struct hdd_scan_info *scan_info = NULL;
450 	struct hdd_adapter *con_sap_adapter;
451 	struct hdd_ap_ctx *ap_ctx;
452 	qdf_freq_t con_dfs_ch_freq;
453 	uint8_t curr_vdev_id;
454 	enum scan_reject_states curr_reason;
455 	static uint32_t scan_ebusy_cnt;
456 	struct scan_params params = {0};
457 	bool self_recovery;
458 	struct wlan_objmgr_vdev *vdev;
459 	QDF_STATUS qdf_status;
460 	bool enable_connected_scan;
461 	enum phy_ch_width con_dfs_ch_width;
462 
463 	if (cds_is_fw_down()) {
464 		hdd_err("firmware is down, scan cmd cannot be processed");
465 		return -EINVAL;
466 	}
467 
468 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
469 		hdd_err("Command not allowed in FTM mode");
470 		return -EINVAL;
471 	}
472 
473 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
474 		return -EINVAL;
475 
476 	status = wlan_hdd_validate_context(hdd_ctx);
477 	if (0 != status)
478 		return status;
479 
480 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
481 		   TRACE_CODE_HDD_CFG80211_SCAN,
482 		   adapter->deflink->vdev_id, request->n_channels);
483 
484 	if (!sme_is_session_id_valid(hdd_ctx->mac_handle,
485 				     adapter->deflink->vdev_id))
486 		return -EINVAL;
487 
488 	qdf_status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
489 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
490 		hdd_err("Failed to get self recovery ini config");
491 		return -EIO;
492 	}
493 
494 	enable_connected_scan = ucfg_scan_is_connected_scan_enabled(
495 							hdd_ctx->psoc);
496 	if (!enable_connected_scan &&
497 	    hdd_cm_is_vdev_associated(adapter->deflink)) {
498 		hdd_info("enable_connected_scan is false, Aborting scan");
499 		if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source))
500 			return -EAGAIN;
501 		schedule_work(&adapter->scan_block_work);
502 		return 0;
503 	}
504 
505 	/*
506 	 * NDI and monitor mode don't need scan from userspace to establish
507 	 * connection and it does not support scan request either.
508 	 */
509 	if (QDF_NDI_MODE == adapter->device_mode ||
510 	    QDF_MONITOR_MODE == adapter->device_mode) {
511 		hdd_err("Scan not supported for %s",
512 			qdf_opmode_str(adapter->device_mode));
513 		return -EINVAL;
514 	}
515 
516 	scan_info = &adapter->scan_info;
517 
518 	/* Block All Scan during DFS operation and send null scan result */
519 
520 	con_sap_adapter = hdd_get_con_sap_adapter(adapter, true);
521 	if (con_sap_adapter) {
522 		ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(con_sap_adapter->deflink);
523 		con_dfs_ch_freq = ap_ctx->sap_config.chan_freq;
524 		con_dfs_ch_width = ap_ctx->sap_config.ch_params.ch_width;
525 		if (con_dfs_ch_freq == AUTO_CHANNEL_SELECT)
526 			con_dfs_ch_freq = ap_ctx->operating_chan_freq;
527 
528 		if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) &&
529 		    !policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
530 		    hdd_ctx->psoc) &&
531 		    (wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, con_dfs_ch_freq) ||
532 		    (wlan_reg_is_5ghz_ch_freq(con_dfs_ch_freq) &&
533 		     con_dfs_ch_width == CH_WIDTH_160MHZ))) {
534 			/* Provide empty scan result during DFS operation since
535 			 * scanning not supported during DFS. Reason is
536 			 * following case:
537 			 * DFS is supported only in SCC for MBSSID Mode.
538 			 * We shall not return EBUSY or ENOTSUPP as when Primary
539 			 * AP is operating in DFS channel and secondary AP is
540 			 * started. Though we force SCC in driver, the hostapd
541 			 * issues obss scan before starting secAP. This results
542 			 * in MCC in DFS mode. Thus we return null scan result.
543 			 * If we return scan failure hostapd fails secondary AP
544 			 * startup.
545 			 */
546 			hdd_err("##In DFS Master mode. Scan aborted");
547 			if (wlan_hdd_enqueue_blocked_scan_request(dev, request,
548 								  source))
549 				return -EAGAIN;
550 			schedule_work(&adapter->scan_block_work);
551 			return 0;
552 		}
553 	}
554 
555 	/* Check if scan is allowed at this point of time */
556 	if (hdd_is_connection_in_progress(&curr_vdev_id, &curr_reason)) {
557 		scan_ebusy_cnt++;
558 		hdd_err_rl("Scan not allowed. scan_ebusy_cnt: %d Session %d Reason %d",
559 			   scan_ebusy_cnt, curr_vdev_id, curr_reason);
560 		if (hdd_ctx->last_scan_reject_vdev_id != curr_vdev_id ||
561 		    hdd_ctx->last_scan_reject_reason != curr_reason ||
562 		    !hdd_ctx->last_scan_reject_timestamp) {
563 			hdd_ctx->last_scan_reject_vdev_id = curr_vdev_id;
564 			hdd_ctx->last_scan_reject_reason = curr_reason;
565 			hdd_ctx->last_scan_reject_timestamp = jiffies +
566 				msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
567 			hdd_ctx->scan_reject_cnt = 0;
568 		} else {
569 			hdd_ctx->scan_reject_cnt++;
570 			if ((hdd_ctx->scan_reject_cnt >=
571 			   SCAN_REJECT_THRESHOLD) &&
572 			   qdf_system_time_after(jiffies,
573 			   hdd_ctx->last_scan_reject_timestamp)) {
574 				hdd_err("scan reject threshold reached Session %d Reason %d count %d reject timestamp %lu jiffies %lu",
575 					curr_vdev_id, curr_reason,
576 					hdd_ctx->scan_reject_cnt,
577 					hdd_ctx->last_scan_reject_timestamp,
578 					jiffies);
579 				hdd_ctx->last_scan_reject_timestamp = 0;
580 				hdd_ctx->scan_reject_cnt = 0;
581 				if (cds_is_fatal_event_enabled()) {
582 					cds_flush_logs(WLAN_LOG_TYPE_FATAL,
583 					   WLAN_LOG_INDICATOR_HOST_DRIVER,
584 					   WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
585 					   false,
586 					   self_recovery);
587 				} else {
588 					hdd_err("Triggering SSR due to scan stuck");
589 					cds_trigger_recovery(SCAN_FAILURE);
590 				}
591 			}
592 		}
593 		return -EBUSY;
594 	}
595 
596 	hdd_init_scan_reject_params(hdd_ctx);
597 
598 	/* Check whether SAP scan can be skipped or not */
599 	if (adapter->device_mode == QDF_SAP_MODE &&
600 	   wlan_hdd_sap_skip_scan_check(hdd_ctx, request)) {
601 		hdd_debug("sap scan skipped");
602 		if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source))
603 			return -EAGAIN;
604 		schedule_work(&adapter->scan_block_work);
605 		return 0;
606 	}
607 
608 	params.source = source;
609 	params.default_ie.len = 0;
610 	/* Store the Scan IE's in Adapter*/
611 	if (request->ie_len) {
612 		if (request->ie_len > SIR_MAC_MAX_ADD_IE_LENGTH) {
613 			hdd_debug("Invalid ie_len: %zu", request->ie_len);
614 			return -EINVAL;
615 		}
616 
617 		/* save this for future association (join requires this) */
618 		memset(&scan_info->scan_add_ie, 0, sizeof(scan_info->scan_add_ie));
619 		memcpy(scan_info->scan_add_ie.addIEdata, request->ie,
620 		       request->ie_len);
621 		scan_info->scan_add_ie.length = request->ie_len;
622 
623 		wlan_hdd_update_scan_ies(adapter, scan_info,
624 				scan_info->scan_add_ie.addIEdata,
625 				&scan_info->scan_add_ie.length);
626 	} else {
627 		if (scan_info->default_scan_ies &&
628 		    scan_info->default_scan_ies_len) {
629 			qdf_mem_copy(scan_info->scan_add_ie.addIEdata,
630 				     scan_info->default_scan_ies,
631 				     scan_info->default_scan_ies_len);
632 			scan_info->scan_add_ie.length =
633 				scan_info->default_scan_ies_len;
634 			params.default_ie.ptr =
635 				qdf_mem_malloc(scan_info->default_scan_ies_len);
636 			if (params.default_ie.ptr) {
637 				qdf_mem_copy(params.default_ie.ptr,
638 					     scan_info->default_scan_ies,
639 					     scan_info->default_scan_ies_len);
640 				params.default_ie.len =
641 						scan_info->default_scan_ies_len;
642 			}
643 		}
644 	}
645 
646 	if (QDF_P2P_CLIENT_MODE == adapter->device_mode ||
647 	    QDF_P2P_DEVICE_MODE == adapter->device_mode) {
648 		/* Disable NAN Discovery if enabled */
649 		ucfg_nan_disable_concurrency(hdd_ctx->psoc);
650 	}
651 
652 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID);
653 	if (!vdev) {
654 		status = -EINVAL;
655 		goto error;
656 	}
657 
658 	if ((request->n_ssids == 1) && (request->ssids) &&
659 	    (request->ssids[0].ssid_len > 7) &&
660 	     !qdf_mem_cmp(&request->ssids[0], "DIRECT-", 7))
661 		ucfg_p2p_status_scan(vdev);
662 
663 	/* If this a scan on SAP adapter, use scan priority high */
664 	if (adapter->device_mode == QDF_SAP_MODE)
665 		params.priority = SCAN_PRIORITY_HIGH;
666 	else
667 		/* Use default scan priority */
668 		params.priority = SCAN_PRIORITY_COUNT;
669 
670 	status = ucfg_mlme_get_scan_probe_unicast_ra(
671 						hdd_ctx->psoc,
672 						&params.scan_probe_unicast_ra);
673 	if (QDF_IS_STATUS_ERROR(status))
674 		hdd_err("Failed to get unicast probe req ra cfg");
675 
676 	params.mld_id = ucfg_mlme_get_eht_mld_id(hdd_ctx->psoc);
677 	hdd_debug("MLD ID: %d", params.mld_id);
678 
679 	status = wlan_cfg80211_scan(vdev, request, &params);
680 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
681 error:
682 	if (params.default_ie.ptr)
683 		qdf_mem_free(params.default_ie.ptr);
684 
685 	return status;
686 }
687 
688 #undef SCAN_FAILURE
689 
690 /**
691  * wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request
692  * @wiphy: Pointer to wiphy
693  * @request: Pointer to scan request
694  *
695  * This API responds to scan trigger and update cfg80211 scan database
696  * later, scan dump command can be used to receive scan results
697  *
698  * Return: 0 for success, non zero for failure
699  */
wlan_hdd_cfg80211_scan(struct wiphy * wiphy,struct cfg80211_scan_request * request)700 int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
701 			   struct cfg80211_scan_request *request)
702 {
703 	int errno;
704 	struct osif_vdev_sync *vdev_sync;
705 
706 	errno = osif_vdev_sync_op_start(request->wdev->netdev, &vdev_sync);
707 	if (errno)
708 		return errno;
709 
710 	errno = __wlan_hdd_cfg80211_scan(wiphy, request, NL_SCAN);
711 
712 	osif_vdev_sync_op_stop(vdev_sync);
713 
714 	return errno;
715 }
716 
717 /**
718  * wlan_hdd_get_rates() -API to get the rates from scan request
719  * @wiphy: Pointer to wiphy
720  * @band: Band
721  * @rates: array of rates
722  * @rate_count: number of rates
723  *
724  * Return: o for failure, rate bitmap for success
725  */
wlan_hdd_get_rates(struct wiphy * wiphy,enum nl80211_band band,const u8 * rates,unsigned int rate_count)726 static uint32_t wlan_hdd_get_rates(struct wiphy *wiphy,
727 	enum nl80211_band band,
728 	const u8 *rates, unsigned int rate_count)
729 {
730 	uint32_t j, count, rate_bitmap = 0;
731 	uint32_t rate;
732 	bool found;
733 
734 	for (count = 0; count < rate_count; count++) {
735 		rate = ((rates[count]) & RATE_MASK) * 5;
736 		found = false;
737 		for (j = 0; j < wiphy->bands[band]->n_bitrates; j++) {
738 			if (wiphy->bands[band]->bitrates[j].bitrate == rate) {
739 				found = true;
740 				rate_bitmap |= (1 << j);
741 				break;
742 			}
743 		}
744 		if (!found)
745 			return 0;
746 	}
747 	return rate_bitmap;
748 }
749 
750 /**
751  * wlan_hdd_send_scan_start_event() -API to send the scan start event
752  * @wiphy: Pointer to wiphy
753  * @wdev: Pointer to net device
754  * @cookie: scan identifier
755  *
756  * Return: return 0 on success and negative error code on failure
757  */
wlan_hdd_send_scan_start_event(struct wiphy * wiphy,struct wireless_dev * wdev,uint64_t cookie)758 static int wlan_hdd_send_scan_start_event(struct wiphy *wiphy,
759 		struct wireless_dev *wdev, uint64_t cookie)
760 {
761 	struct sk_buff *skb;
762 	int ret;
763 	enum qca_nl80211_vendor_subcmds_index index =
764 		QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX;
765 
766 	skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u64) +
767 			NLA_HDRLEN + NLMSG_HDRLEN);
768 	if (!skb) {
769 		hdd_err(" reply skb alloc failed");
770 		return -ENOMEM;
771 	}
772 
773 	if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
774 				 cookie)) {
775 		hdd_err("nla put fail");
776 		wlan_cfg80211_vendor_free_skb(skb);
777 		return -EINVAL;
778 	}
779 
780 	ret = wlan_cfg80211_vendor_cmd_reply(skb);
781 
782 	/* Send a scan started event to supplicant */
783 	skb = wlan_cfg80211_vendor_event_alloc(wiphy, wdev,
784 					       sizeof(u64) + 4 + NLMSG_HDRLEN,
785 					       index, GFP_KERNEL);
786 	if (!skb) {
787 		hdd_err("skb alloc failed");
788 		return -ENOMEM;
789 	}
790 
791 	if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
792 				 cookie)) {
793 		wlan_cfg80211_vendor_free_skb(skb);
794 		return -EINVAL;
795 	}
796 
797 	wlan_cfg80211_vendor_event(skb, GFP_KERNEL);
798 	return ret;
799 }
800 
801 /**
802  * wlan_hdd_copy_bssid() - API to copy the bssid to vendor Scan request
803  * @request: Pointer to vendor scan request
804  * @bssid: Pointer to BSSID
805  *
806  * This API copies the specific BSSID received from Supplicant and copies it to
807  * the vendor Scan request
808  *
809  * Return: None
810  */
811 #if defined(CFG80211_SCAN_BSSID) || \
812 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
wlan_hdd_copy_bssid(struct cfg80211_scan_request * request,uint8_t * bssid)813 static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request,
814 					uint8_t *bssid)
815 {
816 	qdf_mem_copy(request->bssid, bssid, QDF_MAC_ADDR_SIZE);
817 }
818 #else
wlan_hdd_copy_bssid(struct cfg80211_scan_request * request,uint8_t * bssid)819 static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request,
820 					uint8_t *bssid)
821 {
822 }
823 #endif
824 
hdd_process_vendor_acs_response(struct hdd_adapter * adapter)825 static void hdd_process_vendor_acs_response(struct hdd_adapter *adapter)
826 {
827 	qdf_mc_timer_t *vendor_acs_timer;
828 
829 	if (!test_bit(VENDOR_ACS_RESPONSE_PENDING,
830 		      &adapter->deflink->link_flags)) {
831 		return;
832 	}
833 
834 	vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer;
835 	if (QDF_TIMER_STATE_RUNNING ==
836 	    qdf_mc_timer_get_current_state(vendor_acs_timer)) {
837 		qdf_mc_timer_stop(vendor_acs_timer);
838 	}
839 }
840 
841 #if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
842 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
843 /**
844  * wlan_hdd_vendor_scan_random_attr() - check and fill scan randomization attrs
845  * @wiphy: Pointer to wiphy
846  * @request: Pointer to scan request
847  * @adapter: Pointer to hdd adapter
848  * @tb: Pointer to nl attributes
849  *
850  * This function is invoked to check whether vendor scan needs
851  * probe req source addr, if so populates mac_addr and mac_addr_mask
852  * in scan request with nl attrs.
853  *
854  * Return: 0 - on success, negative value on failure
855  */
wlan_hdd_vendor_scan_random_attr(struct wiphy * wiphy,struct cfg80211_scan_request * request,struct hdd_adapter * adapter,struct nlattr ** tb)856 static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy,
857 					struct cfg80211_scan_request *request,
858 					struct hdd_adapter *adapter,
859 					struct nlattr **tb)
860 {
861 	uint32_t i;
862 	int32_t len = QDF_MAC_ADDR_SIZE;
863 
864 	if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
865 		return 0;
866 
867 	if (!(wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR) ||
868 	    (hdd_cm_is_vdev_connected(adapter->deflink))) {
869 		hdd_err("SCAN RANDOMIZATION not supported");
870 		return -EOPNOTSUPP;
871 	}
872 
873 	if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] &&
874 	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) {
875 		qdf_mem_zero(request->mac_addr, len);
876 		qdf_mem_zero(request->mac_addr_mask, len);
877 		request->mac_addr[0] = 0x2;
878 		request->mac_addr_mask[0] = 0x3;
879 
880 		return 0;
881 	}
882 
883 	if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] ||
884 	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK])
885 		return -EINVAL;
886 
887 	if ((nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]) != len) ||
888 	    (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) != len))
889 		return -EINVAL;
890 
891 	qdf_mem_copy(request->mac_addr,
892 		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]), len);
893 
894 	qdf_mem_copy(request->mac_addr_mask,
895 		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]), len);
896 
897 	/* avoid configure on multicast address */
898 	if (!cds_is_group_addr(request->mac_addr_mask) ||
899 	    cds_is_group_addr(request->mac_addr))
900 		return -EINVAL;
901 
902 	for (i = 0; i < ETH_ALEN; i++)
903 		request->mac_addr[i] &= request->mac_addr_mask[i];
904 
905 	return 0;
906 }
907 #else
wlan_hdd_vendor_scan_random_attr(struct wiphy * wiphy,struct cfg80211_scan_request * request,struct hdd_adapter * adapter,struct nlattr ** tb)908 static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy,
909 					struct cfg80211_scan_request *request,
910 					struct hdd_adapter *adapter,
911 					struct nlattr **tb)
912 {
913 	return 0;
914 }
915 #endif
916 
917 const
918 struct nla_policy scan_policy[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1] = {
919 	[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS] = {.type = NLA_U32},
920 	[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE] = {.type = NLA_FLAG},
921 	[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64},
922 	[QCA_WLAN_VENDOR_ATTR_SCAN_IE] = {.type = NLA_BINARY,
923 					  .len = MAX_DEFAULT_SCAN_IE_LEN},
924 	[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] = VENDOR_NLA_POLICY_MAC_ADDR,
925 	[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK] = VENDOR_NLA_POLICY_MAC_ADDR,
926 	[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES] = {.type = NLA_NESTED},
927 	[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS] = {.type = NLA_NESTED},
928 	[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES] = {.type = NLA_NESTED},
929 	[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID] = {.type = NLA_BINARY},
930 };
931 
932 /**
933  * __wlan_hdd_cfg80211_vendor_scan() - API to process venor scan request
934  * @wiphy: Pointer to wiphy
935  * @wdev: Pointer to net device
936  * @data : Pointer to the data
937  * @data_len : length of the data
938  *
939  * API to process venor scan request.
940  *
941  * Return: return 0 on success and negative error code on failure
942  */
__wlan_hdd_cfg80211_vendor_scan(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)943 static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
944 		struct wireless_dev *wdev, const void *data,
945 		int data_len)
946 {
947 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
948 	struct cfg80211_scan_request *request = NULL;
949 	struct nlattr *attr;
950 	enum nl80211_band band;
951 	uint32_t n_channels = 0, n_ssid = 0;
952 	uint32_t count, j;
953 	int tmp;
954 	size_t len, ie_len = 0;
955 	struct ieee80211_channel *chan;
956 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
957 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
958 	int ret;
959 
960 	hdd_enter_dev(wdev->netdev);
961 
962 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
963 		hdd_err("Command not allowed in FTM mode");
964 		return -EPERM;
965 	}
966 
967 	ret = wlan_hdd_validate_context(hdd_ctx);
968 	if (ret) {
969 		/*
970 		 * During SSR, if -EBUSY is returned then OBSS vendor scan is
971 		 * not issued immediately.
972 		 */
973 		if (ret == -EAGAIN)
974 			return -EBUSY;
975 
976 		return ret;
977 	}
978 
979 	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
980 				    data, data_len, scan_policy)) {
981 		hdd_err("Invalid ATTR");
982 		return -EINVAL;
983 	}
984 
985 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
986 		nla_for_each_nested(attr,
987 			tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES], tmp)
988 			n_channels++;
989 	} else {
990 		for (band = 0; band < HDD_NUM_NL80211_BANDS; band++)
991 			if (wiphy->bands[band])
992 				n_channels += wiphy->bands[band]->n_channels;
993 	}
994 
995 	if (n_channels > NUM_CHANNELS) {
996 		hdd_err("Exceed max number of channels: %d", n_channels);
997 		return -EINVAL;
998 	}
999 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS])
1000 		nla_for_each_nested(attr,
1001 			tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], tmp)
1002 			n_ssid++;
1003 
1004 	if (MAX_SCAN_SSID < n_ssid) {
1005 		hdd_err("Exceed max number of SSID: %d", n_ssid);
1006 		return -EINVAL;
1007 	}
1008 
1009 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE])
1010 		ie_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]);
1011 
1012 	len = sizeof(*request) + (sizeof(*request->ssids) * n_ssid) +
1013 			(sizeof(*request->channels) * n_channels) + ie_len;
1014 
1015 	request = qdf_mem_malloc(len);
1016 	if (!request)
1017 		goto error;
1018 	if (n_ssid)
1019 		request->ssids = (void *)&request->channels[n_channels];
1020 	request->n_ssids = n_ssid;
1021 	if (ie_len) {
1022 		if (request->ssids)
1023 			request->ie = (void *)(request->ssids + n_ssid);
1024 		else
1025 			request->ie = (void *)(request->channels + n_channels);
1026 	}
1027 
1028 	request->ie_len = ie_len;
1029 	count = 0;
1030 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
1031 		nla_for_each_nested(attr,
1032 				    tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES],
1033 				    tmp) {
1034 			if (nla_len(attr) != sizeof(uint32_t)) {
1035 				hdd_err("len is not correct for frequency %d",
1036 					count);
1037 				goto error;
1038 			}
1039 			chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
1040 			if (!chan)
1041 				goto error;
1042 			if (chan->flags & IEEE80211_CHAN_DISABLED)
1043 				continue;
1044 			request->channels[count] = chan;
1045 			count++;
1046 		}
1047 	} else {
1048 		for (band = 0; band < HDD_NUM_NL80211_BANDS; band++) {
1049 			if (!wiphy->bands[band])
1050 				continue;
1051 			for (j = 0; j < wiphy->bands[band]->n_channels;
1052 				j++) {
1053 				chan = &wiphy->bands[band]->channels[j];
1054 				if (chan->flags & IEEE80211_CHAN_DISABLED)
1055 					continue;
1056 				request->channels[count] = chan;
1057 				count++;
1058 			}
1059 		}
1060 	}
1061 
1062 	if (!count)
1063 		goto error;
1064 
1065 	request->n_channels = count;
1066 	count = 0;
1067 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
1068 		int ssid_length;
1069 
1070 		nla_for_each_nested(attr, tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS],
1071 				tmp) {
1072 			ssid_length = nla_len(attr);
1073 			if ((ssid_length > WLAN_SSID_MAX_LEN) ||
1074 			    (ssid_length < 0)) {
1075 				hdd_err("SSID Len %d is not correct for network %d",
1076 					 ssid_length, count);
1077 				goto error;
1078 			}
1079 
1080 			request->ssids[count].ssid_len = ssid_length;
1081 			memcpy(request->ssids[count].ssid, nla_data(attr),
1082 					ssid_length);
1083 			count++;
1084 		}
1085 	}
1086 
1087 	if (ie_len)
1088 		nla_memcpy((void *)request->ie,
1089 			   tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE], ie_len);
1090 
1091 	for (count = 0; count < HDD_NUM_NL80211_BANDS; count++)
1092 		if (wiphy->bands[count])
1093 			request->rates[count] =
1094 				(1 << wiphy->bands[count]->n_bitrates) - 1;
1095 
1096 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES]) {
1097 		nla_for_each_nested(attr,
1098 				    tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES],
1099 				    tmp) {
1100 			band = nla_type(attr);
1101 			if (band >= HDD_NUM_NL80211_BANDS)
1102 				continue;
1103 			if (!wiphy->bands[band])
1104 				continue;
1105 			request->rates[band] =
1106 				wlan_hdd_get_rates(wiphy,
1107 						   band, nla_data(attr),
1108 						   nla_len(attr));
1109 		}
1110 	}
1111 
1112 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]) {
1113 		request->flags =
1114 			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]);
1115 		if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
1116 		    !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
1117 			hdd_err("LOW PRIORITY SCAN not supported");
1118 			goto error;
1119 		}
1120 
1121 		if (wlan_hdd_vendor_scan_random_attr(wiphy, request,
1122 						     adapter, tb))
1123 			goto error;
1124 	}
1125 
1126 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) {
1127 		if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) <
1128 		    QDF_MAC_ADDR_SIZE) {
1129 			hdd_err("invalid bssid length");
1130 			goto error;
1131 		}
1132 		wlan_hdd_copy_bssid(request,
1133 			nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]));
1134 	}
1135 
1136 	/* Check if external acs was requested on this adapter */
1137 	hdd_process_vendor_acs_response(adapter);
1138 
1139 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE])
1140 		request->no_cck =
1141 		   nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE]);
1142 	request->wdev = wdev;
1143 	request->wiphy = wiphy;
1144 	request->scan_start = jiffies;
1145 
1146 	ret = __wlan_hdd_cfg80211_scan(wiphy, request, VENDOR_SCAN);
1147 	if (0 != ret) {
1148 		hdd_err("Scan Failed. Ret = %d", ret);
1149 		qdf_mem_free(request);
1150 		return ret;
1151 	}
1152 	ret = wlan_hdd_send_scan_start_event(wiphy, wdev, (uintptr_t)request);
1153 
1154 	return ret;
1155 error:
1156 	hdd_err("Scan Request Failed");
1157 	qdf_mem_free(request);
1158 	return -EINVAL;
1159 }
1160 
1161 /**
1162  * wlan_hdd_cfg80211_vendor_scan() -API to process venor scan request
1163  * @wiphy: Pointer to wiphy
1164  * @wdev: Pointer to wireless device
1165  * @data: Pointer to the data
1166  * @data_len: length of the data
1167  *
1168  * This is called from userspace to request scan.
1169  *
1170  * Return: Return the Success or Failure code.
1171  */
wlan_hdd_cfg80211_vendor_scan(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)1172 int wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
1173 		struct wireless_dev *wdev, const void *data,
1174 		int data_len)
1175 {
1176 	int errno;
1177 	struct osif_vdev_sync *vdev_sync;
1178 
1179 	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
1180 	if (errno)
1181 		return errno;
1182 
1183 	errno = __wlan_hdd_cfg80211_vendor_scan(wiphy, wdev, data, data_len);
1184 
1185 	osif_vdev_sync_op_stop(vdev_sync);
1186 
1187 	return errno;
1188 }
1189 
1190 /**
1191  * __wlan_hdd_vendor_abort_scan() - API to process vendor command for
1192  * abort scan
1193  * @wiphy: Pointer to wiphy
1194  * @data: Pointer to the data
1195  * @data_len: length of the data
1196  *
1197  * API to process vendor abort scan
1198  *
1199  * Return: zero for success and non zero for failure
1200  */
__wlan_hdd_vendor_abort_scan(struct wiphy * wiphy,const void * data,int data_len)1201 static int __wlan_hdd_vendor_abort_scan(
1202 		struct wiphy *wiphy, const void *data,
1203 		int data_len)
1204 {
1205 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
1206 	int ret;
1207 
1208 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1209 		hdd_err("Command not allowed in FTM mode");
1210 		return -EINVAL;
1211 	}
1212 
1213 	ret = wlan_hdd_validate_context(hdd_ctx);
1214 	if (0 != ret)
1215 		return ret;
1216 
1217 	wlan_vendor_abort_scan(hdd_ctx->pdev, data, data_len);
1218 
1219 	return ret;
1220 }
1221 
1222 /**
1223  * wlan_hdd_vendor_abort_scan() - API to process vendor command for
1224  * abort scan
1225  * @wiphy: Pointer to wiphy
1226  * @wdev: Pointer to net device
1227  * @data : Pointer to the data
1228  * @data_len : length of the data
1229  *
1230  * This is called from supplicant to abort scan
1231  *
1232  * Return: zero for success and non zero for failure
1233  */
wlan_hdd_vendor_abort_scan(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)1234 int wlan_hdd_vendor_abort_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
1235 			       const void *data, int data_len)
1236 {
1237 	struct osif_vdev_sync *vdev_sync;
1238 	int errno;
1239 
1240 	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
1241 	if (errno)
1242 		return errno;
1243 
1244 	errno = __wlan_hdd_vendor_abort_scan(wiphy, data, data_len);
1245 
1246 	osif_vdev_sync_op_stop(vdev_sync);
1247 
1248 	return errno;
1249 }
1250 
wlan_hdd_scan_abort(struct wlan_hdd_link_info * link_info)1251 int wlan_hdd_scan_abort(struct wlan_hdd_link_info *link_info)
1252 {
1253 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
1254 
1255 	wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
1256 			link_info->vdev_id, INVALID_SCAN_ID, true);
1257 
1258 	return 0;
1259 }
1260 
1261 #ifdef FEATURE_WLAN_SCAN_PNO
1262 /**
1263  * __wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
1264  * @wiphy: Pointer to wiphy
1265  * @dev: Pointer network device
1266  * @request: Pointer to cfg80211 scheduled scan start request
1267  *
1268  * Return: 0 for success, non zero for failure
1269  */
__wlan_hdd_cfg80211_sched_scan_start(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_sched_scan_request * request)1270 static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
1271 						struct net_device *dev,
1272 						struct
1273 						cfg80211_sched_scan_request
1274 						*request)
1275 {
1276 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1277 	struct hdd_context *hdd_ctx;
1278 	struct wlan_objmgr_vdev *vdev;
1279 	int ret;
1280 	bool pno_offload_enabled;
1281 	uint8_t scan_backoff_multiplier;
1282 	bool enable_connected_scan;
1283 	enum QDF_GLOBAL_MODE curr_mode;
1284 
1285 	curr_mode = hdd_get_conparam();
1286 
1287 	if (QDF_GLOBAL_FTM_MODE == curr_mode ||
1288 	    QDF_GLOBAL_MONITOR_MODE == curr_mode) {
1289 		hdd_err_rl("Command not allowed in FTM/Monitor mode");
1290 		return -EINVAL;
1291 	}
1292 
1293 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
1294 		return -EINVAL;
1295 
1296 	if (adapter->device_mode != QDF_STA_MODE) {
1297 		hdd_info("Sched scans only supported on STA ifaces");
1298 		return -EINVAL;
1299 	}
1300 
1301 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1302 	ret = wlan_hdd_validate_context(hdd_ctx);
1303 	if (ret)
1304 		return ret;
1305 
1306 	pno_offload_enabled = ucfg_scan_is_pno_offload_enabled(hdd_ctx->psoc);
1307 	if (!pno_offload_enabled) {
1308 		hdd_debug("Pno Offload is not enabled");
1309 		return -EINVAL;
1310 	}
1311 
1312 	enable_connected_scan = ucfg_scan_is_connected_scan_enabled(
1313 							hdd_ctx->psoc);
1314 	if (!enable_connected_scan &&
1315 	    hdd_cm_is_vdev_associated(adapter->deflink)) {
1316 		hdd_info("enable_connected_scan is false, Aborting scan");
1317 		return -EBUSY;
1318 	}
1319 
1320 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID);
1321 	if (!vdev)
1322 		return -EINVAL;
1323 
1324 	scan_backoff_multiplier =
1325 			ucfg_get_scan_backoff_multiplier(hdd_ctx->psoc);
1326 	ret = wlan_cfg80211_sched_scan_start(vdev, request,
1327 					     scan_backoff_multiplier);
1328 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
1329 
1330 	return ret;
1331 }
1332 
1333 /**
1334  * wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
1335  * @wiphy: Pointer to wiphy
1336  * @dev: Pointer network device
1337  * @request: Pointer to cfg80211 scheduled scan start request
1338  *
1339  * Return: 0 for success, non zero for failure
1340  */
wlan_hdd_cfg80211_sched_scan_start(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_sched_scan_request * request)1341 int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
1342 				       struct net_device *dev,
1343 				       struct cfg80211_sched_scan_request
1344 				       *request)
1345 {
1346 	int errno;
1347 	struct osif_vdev_sync *vdev_sync;
1348 
1349 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1350 	if (errno)
1351 		return errno;
1352 
1353 	errno = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
1354 
1355 	osif_vdev_sync_op_stop(vdev_sync);
1356 
1357 	return errno;
1358 }
1359 
wlan_hdd_sched_scan_stop(struct net_device * dev)1360 int wlan_hdd_sched_scan_stop(struct net_device *dev)
1361 {
1362 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1363 	struct hdd_context *hdd_ctx;
1364 	struct wlan_objmgr_vdev *vdev;
1365 	int ret;
1366 	bool pno_offload_enabled;
1367 
1368 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1369 		hdd_err("Command not allowed in FTM mode");
1370 		return -EINVAL;
1371 	}
1372 
1373 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
1374 		return -EINVAL;
1375 
1376 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1377 	if (!hdd_ctx) {
1378 		hdd_err("HDD context is Null");
1379 		return -EINVAL;
1380 	}
1381 
1382 	pno_offload_enabled = ucfg_scan_is_pno_offload_enabled(hdd_ctx->psoc);
1383 	if (!pno_offload_enabled) {
1384 		hdd_debug("PnoOffload is not enabled!!!");
1385 		return -EINVAL;
1386 	}
1387 
1388 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID);
1389 	if (!vdev)
1390 		return -EINVAL;
1391 	ret = wlan_cfg80211_sched_scan_stop(vdev);
1392 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
1393 
1394 	return ret;
1395 }
1396 
1397 /**
1398  * __wlan_hdd_cfg80211_sched_scan_stop() - stop cfg80211 scheduled scan(pno)
1399  * @dev: Pointer network device
1400  *
1401  * This is a wrapper around wlan_hdd_sched_scan_stop() that returns success
1402  * in the event that the driver is currently recovering or unloading. This
1403  * prevents a race condition where we get a scan stop from kernel during
1404  * a driver unload from PLD.
1405  *
1406  * Return: 0 for success, non zero for failure
1407  */
__wlan_hdd_cfg80211_sched_scan_stop(struct net_device * dev)1408 static int __wlan_hdd_cfg80211_sched_scan_stop(struct net_device *dev)
1409 {
1410 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1411 	int errno;
1412 	enum QDF_GLOBAL_MODE curr_mode;
1413 
1414 	curr_mode = hdd_get_conparam();
1415 
1416 	if (QDF_GLOBAL_FTM_MODE == curr_mode ||
1417 	    QDF_GLOBAL_MONITOR_MODE == curr_mode) {
1418 		hdd_err_rl("Command not allowed in FTM/Monitor mode");
1419 		return -EINVAL;
1420 	}
1421 
1422 	/* The return 0 is intentional when Recovery and Load/Unload in
1423 	 * progress. We did observe a crash due to a return of
1424 	 * failure in sched_scan_stop , especially for a case where the unload
1425 	 * of the happens at the same time. The function
1426 	 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only
1427 	 * when the sched_scan_stop returns success. If it returns a failure ,
1428 	 * then its next invocation due to the clean up of the second interface
1429 	 * will have the dev pointer corresponding to the first one leading to
1430 	 * a crash.
1431 	 */
1432 	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
1433 		hdd_info("Recovery in Progress. State: 0x%x Ignore!!!",
1434 			 cds_get_driver_state());
1435 		return 0;
1436 	}
1437 
1438 	if (cds_is_load_or_unload_in_progress()) {
1439 		hdd_info("Unload/Load in Progress, state: 0x%x.  Ignore!!!",
1440 			cds_get_driver_state());
1441 		return 0;
1442 	}
1443 
1444 	errno = hdd_validate_adapter(adapter);
1445 	if (errno)
1446 		return errno;
1447 
1448 	if (adapter->device_mode != QDF_STA_MODE) {
1449 		hdd_info("Sched scans only supported on STA ifaces");
1450 		return -EINVAL;
1451 	}
1452 
1453 	errno = wlan_hdd_validate_context(WLAN_HDD_GET_CTX(adapter));
1454 	if (errno)
1455 		return errno;
1456 
1457 	errno = wlan_hdd_sched_scan_stop(dev);
1458 
1459 	return errno;
1460 }
1461 
1462 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
wlan_hdd_cfg80211_sched_scan_stop(struct wiphy * wiphy,struct net_device * dev)1463 int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
1464 				      struct net_device *dev)
1465 {
1466 	int errno;
1467 	struct osif_vdev_sync *vdev_sync;
1468 
1469 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1470 	if (errno)
1471 		return errno;
1472 
1473 	errno = __wlan_hdd_cfg80211_sched_scan_stop(dev);
1474 
1475 	osif_vdev_sync_op_stop(vdev_sync);
1476 
1477 	/* The return 0 is intentional. We observed a crash due to a return of
1478 	 * failure in sched_scan_stop , especially for a case where the unload
1479 	 * of the happens at the same time. The function
1480 	 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only
1481 	 * when the sched_scan_stop returns success. If it returns a failure ,
1482 	 * then its next invocation due to the clean up of the second interface
1483 	 * will have the dev pointer corresponding to the first one leading to
1484 	 * a crash.
1485 	 */
1486 	return 0;
1487 }
1488 #else
wlan_hdd_cfg80211_sched_scan_stop(struct wiphy * wiphy,struct net_device * dev,uint64_t reqid)1489 int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
1490 				      struct net_device *dev,
1491 				      uint64_t reqid)
1492 {
1493 	int errno;
1494 	struct osif_vdev_sync *vdev_sync;
1495 
1496 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1497 	if (errno)
1498 		return errno;
1499 
1500 	errno = __wlan_hdd_cfg80211_sched_scan_stop(dev);
1501 
1502 	osif_vdev_sync_op_stop(vdev_sync);
1503 
1504 	/* The return 0 is intentional. We observed a crash due to a return of
1505 	 * failure in sched_scan_stop , especially for a case where the unload
1506 	 * of the happens at the same time. The function
1507 	 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only
1508 	 * when the sched_scan_stop returns success. If it returns a failure ,
1509 	 * then its next invocation due to the clean up of the second interface
1510 	 * will have the dev pointer corresponding to the first one leading to
1511 	 * a crash.
1512 	 */
1513 	return 0;
1514 }
1515 #endif /* KERNEL_VERSION(4, 12, 0) */
1516 #endif /*FEATURE_WLAN_SCAN_PNO */
1517 
1518 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \
1519 	defined(CFG80211_ABORT_SCAN)
1520 /**
1521  * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
1522  * @wiphy: Pointer to wiphy
1523  * @wdev: Pointer to wireless device structure
1524  *
1525  * This function is used to abort an ongoing scan
1526  *
1527  * Return: None
1528  */
__wlan_hdd_cfg80211_abort_scan(struct wiphy * wiphy,struct wireless_dev * wdev)1529 static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
1530 					   struct wireless_dev *wdev)
1531 {
1532 	struct net_device *dev = wdev->netdev;
1533 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1534 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
1535 	int ret;
1536 
1537 	hdd_enter_dev(dev);
1538 
1539 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1540 		hdd_err("Command not allowed in FTM mode");
1541 		return;
1542 	}
1543 
1544 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
1545 		return;
1546 
1547 	ret = wlan_hdd_validate_context(hdd_ctx);
1548 	if (ret)
1549 		return;
1550 
1551 	wlan_cfg80211_abort_scan(hdd_ctx->pdev);
1552 
1553 	hdd_exit();
1554 }
1555 
1556 /**
1557  * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
1558  * @wiphy: Pointer to wiphy
1559  * @wdev: Pointer to wireless device structure
1560  *
1561  * Wrapper to __wlan_hdd_cfg80211_abort_scan() -
1562  * function is used to abort an ongoing scan
1563  *
1564  * Return: None
1565  */
wlan_hdd_cfg80211_abort_scan(struct wiphy * wiphy,struct wireless_dev * wdev)1566 void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
1567 				  struct wireless_dev *wdev)
1568 {
1569 	struct osif_psoc_sync *psoc_sync;
1570 	int errno;
1571 
1572 	errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
1573 	if (errno)
1574 		return;
1575 
1576 	__wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
1577 
1578 	osif_psoc_sync_op_stop(psoc_sync);
1579 }
1580 #endif
1581 
1582 /**
1583  * hdd_scan_context_destroy() - Destroy scan context
1584  * @hdd_ctx:	HDD context.
1585  *
1586  * Destroy scan context.
1587  *
1588  * Return: None.
1589  */
hdd_scan_context_destroy(struct hdd_context * hdd_ctx)1590 void hdd_scan_context_destroy(struct hdd_context *hdd_ctx)
1591 {
1592 }
1593 
1594 /**
1595  * hdd_scan_context_init() - Initialize scan context
1596  * @hdd_ctx:	HDD context.
1597  *
1598  * Initialize scan related resources like spin lock and lists.
1599  *
1600  * Return: 0 on success and errno on failure.
1601  */
hdd_scan_context_init(struct hdd_context * hdd_ctx)1602 int hdd_scan_context_init(struct hdd_context *hdd_ctx)
1603 {
1604 	return 0;
1605 }
1606