1 /*
2 * Copyright (c) 2017-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: declares driver functions interfacing with linux kernel
22 */
23
24
25 #ifndef _WLAN_CFG80211_SCAN_H_
26 #define _WLAN_CFG80211_SCAN_H_
27
28 #include <linux/version.h>
29 #include <linux/netdevice.h>
30 #include <net/cfg80211.h>
31 #include <qca_vendor.h>
32 #include <wlan_scan_public_structs.h>
33 #include <qdf_list.h>
34 #include <qdf_types.h>
35 #include <wlan_scan_ucfg_api.h>
36 #include <wlan_mgmt_txrx_utils_api.h>
37
38 /* Max number of scans allowed from userspace */
39 #define WLAN_MAX_SCAN_COUNT 8
40
41 extern const struct nla_policy cfg80211_scan_policy[
42 QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
43
44 #define FEATURE_ABORT_SCAN_VENDOR_COMMANDS \
45 { \
46 .info.vendor_id = QCA_NL80211_VENDOR_ID, \
47 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN, \
48 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
49 WIPHY_VENDOR_CMD_NEED_NETDEV | \
50 WIPHY_VENDOR_CMD_NEED_RUNNING, \
51 .doit = wlan_hdd_vendor_abort_scan, \
52 vendor_command_policy(cfg80211_scan_policy, \
53 QCA_WLAN_VENDOR_ATTR_SCAN_MAX) \
54 },
55
56 #define SCAN_DONE_EVENT_BUF_SIZE 4096
57 #define SCAN_WAKE_LOCK_CONNECT_DURATION (1 * 1000) /* in msec */
58 #define SCAN_WAKE_LOCK_SCAN_DURATION (5 * 1000) /* in msec */
59
60 /**
61 * struct osif_scan_pdev - OS scan private structure
62 * @scan_req_q: Scan request queue
63 * @scan_req_q_lock: Protect scan request queue
64 * @req_id: Scan request Id
65 * @runtime_pm_lock: Runtime suspend lock
66 * @scan_wake_lock: Scan wake lock
67 */
68 struct osif_scan_pdev{
69 qdf_list_t scan_req_q;
70 qdf_mutex_t scan_req_q_lock;
71 wlan_scan_requester req_id;
72 qdf_runtime_lock_t runtime_pm_lock;
73 qdf_wake_lock_t scan_wake_lock;
74 };
75
76 /*
77 * enum scan_source - scan request source
78 * @NL_SCAN: Scan initiated from NL
79 * @VENDOR_SCAN: Scan intiated from vendor command
80 */
81 enum scan_source {
82 NL_SCAN,
83 VENDOR_SCAN,
84 };
85
86 /**
87 * struct scan_req - Scan Request entry
88 * @node : List entry element
89 * @scan_request: scan request holder
90 * @scan_id: scan identifier used across host layers which is generated at WMI
91 * @source: scan request originator (NL/Vendor scan)
92 * @dev: net device (same as what is in scan_request)
93 * @scan_start_timestamp: scan start time
94 *
95 * Scan request linked list element
96 */
97 struct scan_req {
98 qdf_list_node_t node;
99 struct cfg80211_scan_request *scan_request;
100 uint32_t scan_id;
101 uint8_t source;
102 struct net_device *dev;
103 qdf_time_t scan_start_timestamp;
104 };
105
106 /**
107 * struct scan_params - Scan params
108 * @source: scan request source
109 * @default_ie: default scan ie
110 * @vendor_ie: vendor ie
111 * @priority: scan priority
112 * @half_rate: Half rate flag
113 * @quarter_rate: Quarter rate flag
114 * @strict_pscan: strict passive scan flag
115 * @dwell_time_active: Active dwell time. Ignored if zero or inapplicable.
116 * @dwell_time_active_2g: 2.4 GHz specific active dwell time. Ignored if zero or
117 * inapplicable.
118 * @dwell_time_passive: Passive dwell time. Ignored if zero or inapplicable.
119 * @dwell_time_active_6g: 6 GHz specific active dwell time. Ignored if zero or
120 * inapplicable.
121 * @dwell_time_passive_6g: 6 GHz specific passive dwell time. Ignored if zero or
122 * inapplicable.
123 * @scan_probe_unicast_ra: Use BSSID in probe request frame RA.
124 * @scan_f_2ghz: Scan only 2GHz channels
125 * @scan_f_5ghz: Scan only 5+6GHz channels
126 * @mld_id: MLD ID of the requested BSS within ML probe request
127 */
128 struct scan_params {
129 uint8_t source;
130 struct element_info default_ie;
131 struct element_info vendor_ie;
132 enum scan_priority priority;
133 bool half_rate;
134 bool quarter_rate;
135 bool strict_pscan;
136 uint32_t dwell_time_active;
137 uint32_t dwell_time_active_2g;
138 uint32_t dwell_time_passive;
139 uint32_t dwell_time_active_6g;
140 uint32_t dwell_time_passive_6g;
141 bool scan_probe_unicast_ra;
142 bool scan_f_2ghz;
143 bool scan_f_5ghz;
144 uint8_t mld_id;
145 };
146
147 /**
148 * struct wlan_cfg80211_inform_bss - BSS inform data
149 * @chan: channel the frame was received on
150 * @mgmt: beacon/probe resp frame
151 * @frame_len: frame length
152 * @rssi: signal strength in mBm (100*dBm)
153 * @boottime_ns: timestamp (CLOCK_BOOTTIME) when the information was received.
154 * @per_chain_rssi: per chain rssi received
155 */
156 struct wlan_cfg80211_inform_bss {
157 struct ieee80211_channel *chan;
158 struct ieee80211_mgmt *mgmt;
159 size_t frame_len;
160 int rssi;
161 uint64_t boottime_ns;
162 uint8_t per_chain_rssi[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA];
163 };
164
165
166 #ifdef FEATURE_WLAN_SCAN_PNO
167 /**
168 * wlan_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
169 * @vdev: vdev pointer
170 * @request: Pointer to cfg80211 scheduled scan start request
171 * @scan_backoff_multiplier: multiply scan period by this after max cycles
172 *
173 * Return: 0 for success, non zero for failure
174 */
175 int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev,
176 struct cfg80211_sched_scan_request *request,
177 uint8_t scan_backoff_multiplier);
178
179 /**
180 * wlan_cfg80211_sched_scan_stop() - cfg80211 scheduled scan(pno) stop
181 * @vdev: vdev pointer
182 *
183 * Return: 0 for success, non zero for failure
184 */
185 int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_vdev *vdev);
186 #endif
187
188 /**
189 * wlan_scan_runtime_pm_init() - API to initialize runtime pm context for scan
190 * @pdev: Pointer to pdev
191 *
192 * This will help to initialize scan runtime pm context separately.
193 *
194 * Return: QDF_STATUS
195 */
196 QDF_STATUS wlan_scan_runtime_pm_init(struct wlan_objmgr_pdev *pdev);
197
198 /**
199 * wlan_scan_runtime_pm_deinit() - API to deinitialize runtime pm
200 * for scan.
201 * @pdev: Pointer to pdev
202 *
203 * This will help to deinitialize scan runtime pm before deinitialize
204 * HIF
205 *
206 * Return: void
207 */
208 void wlan_scan_runtime_pm_deinit(struct wlan_objmgr_pdev *pdev);
209
210 /**
211 * wlan_cfg80211_scan_priv_init() - API to initialize cfg80211 scan
212 * @pdev: Pointer to net device
213 *
214 * API to initialize cfg80211 scan module.
215 *
216 * Return: QDF_STATUS
217 */
218 QDF_STATUS wlan_cfg80211_scan_priv_init(struct wlan_objmgr_pdev *pdev);
219
220 /**
221 * wlan_cfg80211_scan_priv_deinit() - API to deinitialize cfg80211 scan
222 * @pdev: Pointer to net device
223 *
224 * API to deinitialize cfg80211 scan module.
225 *
226 * Return: QDF_STATUS
227 */
228 QDF_STATUS wlan_cfg80211_scan_priv_deinit(
229 struct wlan_objmgr_pdev *pdev);
230
231 /**
232 * wlan_cfg80211_scan() - API to process cfg80211 scan request
233 * @vdev: Pointer to vdev
234 * @request: Pointer to scan request
235 * @params: scan params
236 *
237 * API to trigger scan and update cfg80211 scan database.
238 * scan dump command can be used to fetch scan results
239 * on receipt of scan complete event.
240 *
241 * Return: 0 for success, non zero for failure
242 */
243 int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev,
244 struct cfg80211_scan_request *request,
245 struct scan_params *params);
246
247 /**
248 * wlan_cfg80211_inform_bss_frame_data() - API to inform beacon to cfg80211
249 * @wiphy: wiphy
250 * @bss: bss data
251 *
252 * API to inform beacon to cfg80211
253 *
254 * Return: pointer to bss entry
255 */
256 struct cfg80211_bss *
257 wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
258 struct wlan_cfg80211_inform_bss *bss);
259
260 /**
261 * wlan_cfg80211_inform_bss_frame() - API to inform beacon to cfg80211
262 * @pdev: Pointer to pdev
263 * @scan_params: scan entry
264 *
265 * API to inform beacon to cfg80211
266 *
267 * Return: void
268 */
269 void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
270 struct scan_cache_entry *scan_params);
271
272 /**
273 * __wlan_cfg80211_unlink_bss_list() - flush bss from the kernel cache
274 * @wiphy: wiphy
275 * @pdev: pdev object
276 * @bssid: bssid of the BSS to find
277 * @ssid: ssid of the BSS to find
278 * @ssid_len: ssid len of of the BSS to find
279 *
280 * Return: QDF_STATUS
281 */
282 QDF_STATUS __wlan_cfg80211_unlink_bss_list(struct wiphy *wiphy,
283 struct wlan_objmgr_pdev *pdev,
284 uint8_t *bssid, uint8_t *ssid,
285 uint8_t ssid_len);
286
287 /**
288 * wlan_cfg80211_get_bss() - Get the bss entry matching the chan, bssid and ssid
289 * @wiphy: wiphy
290 * @channel: channel of the BSS to find
291 * @bssid: bssid of the BSS to find
292 * @ssid: ssid of the BSS to find
293 * @ssid_len: ssid len of of the BSS to find
294 *
295 * The API is a wrapper to get bss from kernel matching the chan,
296 * bssid and ssid
297 *
298 * Return: bss structure if found else NULL
299 */
300 struct cfg80211_bss *wlan_cfg80211_get_bss(struct wiphy *wiphy,
301 struct ieee80211_channel *channel,
302 const u8 *bssid,
303 const u8 *ssid, size_t ssid_len);
304
305 /*
306 * wlan_cfg80211_unlink_bss_list : flush bss from the kernel cache
307 * @pdev: Pointer to pdev
308 * @scan_entry: scan entry
309 *
310 * Return: bss which is unlinked from kernel cache
311 */
312 void wlan_cfg80211_unlink_bss_list(struct wlan_objmgr_pdev *pdev,
313 struct scan_cache_entry *scan_entry);
314
315 /**
316 * wlan_vendor_abort_scan() - API to vendor abort scan
317 * @pdev: Pointer to pdev
318 * @data: pointer to data
319 * @data_len: Data length
320 *
321 * API to abort scan through vendor command
322 *
323 * Return: 0 for success, non zero for failure
324 */
325 int wlan_vendor_abort_scan(struct wlan_objmgr_pdev *pdev,
326 const void *data, int data_len);
327
328 /**
329 * wlan_cfg80211_abort_scan() - API to abort scan through cfg80211
330 * @pdev: Pointer to pdev
331 *
332 * API to abort scan through cfg80211 request
333 *
334 * Return: 0 for success, non zero for failure
335 */
336 int wlan_cfg80211_abort_scan(struct wlan_objmgr_pdev *pdev);
337
338 /**
339 * wlan_abort_scan() - Generic API to abort scan request
340 * @pdev: Pointer to pdev
341 * @pdev_id: pdev id
342 * @vdev_id: vdev id
343 * @scan_id: scan id
344 * @sync: if wait for scan complete is required
345 *
346 * Generic API to abort scans
347 *
348 * Return: 0 for success, non zero for failure
349 */
350 QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev,
351 uint32_t pdev_id,
352 uint32_t vdev_id,
353 wlan_scan_id scan_id,
354 bool sync);
355
356 /**
357 * wlan_cfg80211_cleanup_scan_queue() - remove entries in scan queue
358 * @pdev: pdev pointer
359 * @dev: net device pointer
360 *
361 * Removes entries in scan queue depending on dev provided and sends scan
362 * complete event to NL.
363 * Removes all entries in scan queue, if dev provided is NULL
364 *
365 * Return: None
366 */
367 void wlan_cfg80211_cleanup_scan_queue(struct wlan_objmgr_pdev *pdev,
368 struct net_device *dev);
369
370 /**
371 * wlan_scan_cfg80211_add_connected_pno_support() - Set connected PNO support
372 * @wiphy: Pointer to wireless phy
373 *
374 * This function is used to set connected PNO support to kernel
375 *
376 * Return: None
377 */
378 #if defined(CFG80211_REPORT_BETTER_BSS_IN_SCHED_SCAN) || \
379 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
380 void wlan_scan_cfg80211_add_connected_pno_support(struct wiphy *wiphy);
381
382 #else
383 static inline
wlan_scan_cfg80211_add_connected_pno_support(struct wiphy * wiphy)384 void wlan_scan_cfg80211_add_connected_pno_support(struct wiphy *wiphy)
385 {
386 }
387 #endif
388
389 #if ((LINUX_VERSION_CODE > KERNEL_VERSION(4, 4, 0)) || \
390 defined(CFG80211_MULTI_SCAN_PLAN_BACKPORT)) && \
391 defined(FEATURE_WLAN_SCAN_PNO)
392 /**
393 * wlan_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
394 * @wiphy: pointer to wiphy
395 * @psoc: pointer to psoc object
396 *
397 * Return: None
398 */
399 void wlan_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
400 struct wlan_objmgr_psoc *psoc);
401 #else
402 static inline
wlan_config_sched_scan_plans_to_wiphy(struct wiphy * wiphy,struct wlan_objmgr_psoc * psoc)403 void wlan_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
404 struct wlan_objmgr_psoc *psoc)
405 {
406 }
407 #endif /* FEATURE_WLAN_SCAN_PNO */
408
409 /**
410 * wlan_cfg80211_scan_done() - Scan completed callback to cfg80211
411 * @netdev: Net device
412 * @req : Scan request
413 * @aborted : true scan aborted false scan success
414 * @osif_priv: OS private structure
415 *
416 * This function notifies scan done to cfg80211
417 *
418 * Return: none
419 */
420 void wlan_cfg80211_scan_done(struct net_device *netdev,
421 struct cfg80211_scan_request *req,
422 bool aborted, struct pdev_osif_priv *osif_priv);
423
424 /**
425 * convert_nl_scan_priority_to_internal() - Convert NL80211 based scan prioirty
426 * value to internal scan priority value
427 * @nl_scan_priority : Scan priority value received in vendor attribute
428 *
429 * Return: Internal scan priority value
430 */
431 enum scan_priority convert_nl_scan_priority_to_internal(
432 enum qca_wlan_vendor_scan_priority nl_scan_priority);
433
434 /**
435 * wlan_is_scan_allowed() - Allow/reject scan if any scan is running
436 * @vdev: vdev on which current scan issued
437 *
438 * Check if any other scan is in queue and decide whether to allow or reject
439 * current scan based on simultaneous_scan feature support
440 *
441 * Return: True if current scan can be allowed
442 */
443 bool wlan_is_scan_allowed(struct wlan_objmgr_vdev *vdev);
444 #endif
445