xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/utils/src/wlan_utility.c (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /**
18  * DOC: This file contains definition for mandatory legacy API
19  */
20 
21 #include "qdf_str.h"
22 #include "wlan_utility.h"
23 #include <wlan_cmn.h>
24 #include "wlan_osif_priv.h"
25 #include <net/cfg80211.h>
26 #include <qdf_module.h>
27 #include <wlan_vdev_mlme_api.h>
28 #include "cfg_ucfg_api.h"
29 #include <wlan_serialization_api.h>
30 
31 uint32_t wlan_chan_to_freq(uint8_t chan)
32 {
33 	if (chan == 0 )
34 		return 0;
35 
36 	if (chan < WLAN_24_GHZ_CHANNEL_14)
37 		return WLAN_24_GHZ_BASE_FREQ + chan * WLAN_CHAN_SPACING_5MHZ;
38 	else if (chan == WLAN_24_GHZ_CHANNEL_14)
39 		return WLAN_CHAN_14_FREQ;
40 	else if (chan < WLAN_24_GHZ_CHANNEL_27)
41 		/* ch 15 - ch 26 */
42 		return WLAN_CHAN_15_FREQ +
43 		  (chan - WLAN_24_GHZ_CHANNEL_15) * WLAN_CHAN_SPACING_20MHZ;
44 	else if (chan == WLAN_5_GHZ_CHANNEL_170)
45 		return WLAN_CHAN_170_FREQ;
46 	else
47 		return WLAN_5_GHZ_BASE_FREQ + chan * WLAN_CHAN_SPACING_5MHZ;
48 }
49 
50 uint8_t wlan_freq_to_chan(uint32_t freq)
51 {
52 	uint8_t chan;
53 
54 	if (freq == 0)
55 		return 0;
56 
57 	if (freq > WLAN_24_GHZ_BASE_FREQ && freq < WLAN_CHAN_14_FREQ)
58 		chan = ((freq - WLAN_24_GHZ_BASE_FREQ) /
59 			WLAN_CHAN_SPACING_5MHZ);
60 	else if (freq == WLAN_CHAN_14_FREQ)
61 		chan = WLAN_24_GHZ_CHANNEL_14;
62 	else if ((freq > WLAN_24_GHZ_BASE_FREQ) &&
63 		(freq < WLAN_5_GHZ_BASE_FREQ))
64 		chan = (((freq - WLAN_CHAN_15_FREQ) /
65 			WLAN_CHAN_SPACING_20MHZ) +
66 			WLAN_24_GHZ_CHANNEL_15);
67 	else
68 		chan = (freq - WLAN_5_GHZ_BASE_FREQ) /
69 			WLAN_CHAN_SPACING_5MHZ;
70 
71 	return chan;
72 }
73 
74 void
75 wlan_get_320_center_freq(qdf_freq_t freq,
76 			 qdf_freq_t *center_freq1,
77 			 qdf_freq_t *center_freq2)
78 {
79 	*center_freq1 = 0;
80 	*center_freq2 = 0;
81 
82 	if ((freq >= 5500) && (freq <= 5800)) {
83 		*center_freq1 = 5650;
84 	} else if ((freq >= 5955) && (freq <= 6095)) {
85 		*center_freq1 = 6105;
86 	} else if ((freq >= 6115) && (freq <= 6255)) {
87 		*center_freq1 = 6105;
88 		*center_freq2 = 6205;
89 	} else if ((freq >= 6275) && (freq <= 6415)) {
90 		*center_freq1 = 6265;
91 		*center_freq2 = 6425;
92 	} else if ((freq >= 6435) && (freq <= 6575)) {
93 		*center_freq1 = 6425;
94 		*center_freq2 = 6585;
95 	} else if ((freq >= 6595) && (freq <= 6735)) {
96 		*center_freq1 = 6585;
97 		*center_freq2 = 6745;
98 	} else if ((freq >= 6755) && (freq <= 6895)) {
99 		*center_freq1 = 6745;
100 		*center_freq2 = 6905;
101 	} else if ((freq >= 6915) && (freq <= 7055)) {
102 		*center_freq1 = 6905;
103 	}
104 }
105 
106 bool wlan_is_ie_valid(const uint8_t *ie, size_t ie_len)
107 {
108 	uint8_t elen;
109 
110 	while (ie_len) {
111 		if (ie_len < 2)
112 			return false;
113 
114 		elen = ie[1];
115 		ie_len -= 2;
116 		ie += 2;
117 		if (elen > ie_len)
118 			return false;
119 
120 		ie_len -= elen;
121 		ie += elen;
122 	}
123 
124 	return true;
125 }
126 
127 static const uint8_t *wlan_get_ie_ptr_from_eid_n_oui(uint8_t eid,
128 						     const uint8_t *oui,
129 						     uint8_t oui_size,
130 						     const uint8_t *ie,
131 						     uint16_t ie_len)
132 {
133 	int32_t left = ie_len;
134 	const uint8_t *ptr = ie;
135 	uint8_t elem_id, elem_len;
136 
137 	while (left >= 2) {
138 		elem_id  = ptr[0];
139 		elem_len = ptr[1];
140 		left -= 2;
141 
142 		if (elem_len > left)
143 			return NULL;
144 
145 		if (eid == elem_id) {
146 			/* if oui is not provide eid match is enough */
147 			if (!oui)
148 				return ptr;
149 
150 			/*
151 			 * if oui is provided and oui_size is more than left
152 			 * bytes, then we cannot have match
153 			 */
154 			if (oui_size > left)
155 				return NULL;
156 
157 			if (qdf_mem_cmp(&ptr[2], oui, oui_size) == 0)
158 				return ptr;
159 		}
160 
161 		left -= elem_len;
162 		ptr += (elem_len + 2);
163 	}
164 
165 	return NULL;
166 }
167 
168 const uint8_t *wlan_get_ie_ptr_from_eid(uint8_t eid,
169 					const uint8_t *ie,
170 					int ie_len)
171 {
172 	return wlan_get_ie_ptr_from_eid_n_oui(eid, NULL, 0, ie, ie_len);
173 }
174 
175 const uint8_t *wlan_get_vendor_ie_ptr_from_oui(const uint8_t *oui,
176 					       uint8_t oui_size,
177 					       const uint8_t *ie,
178 					       uint16_t ie_len)
179 {
180 	return wlan_get_ie_ptr_from_eid_n_oui(WLAN_MAC_EID_VENDOR,
181 					      oui, oui_size, ie, ie_len);
182 }
183 
184 const uint8_t *wlan_get_ext_ie_ptr_from_ext_id(const uint8_t *oui,
185 					       uint8_t oui_size,
186 					       const uint8_t *ie,
187 					       uint16_t ie_len)
188 {
189 	return wlan_get_ie_ptr_from_eid_n_oui(WLAN_MAC_EID_EXT,
190 					      oui, oui_size, ie, ie_len);
191 }
192 
193 bool wlan_is_emulation_platform(uint32_t phy_version)
194 {
195 	if ((phy_version == 0xABC0) || (phy_version == 0xABC1) ||
196 		(phy_version == 0xABC2) || (phy_version == 0xABC3) ||
197 		(phy_version == 0xFFFF) || (phy_version == 0xABCD))
198 		return true;
199 
200 	return false;
201 }
202 
203 uint32_t wlan_get_pdev_id_from_vdev_id(struct wlan_objmgr_psoc *psoc,
204 				      uint8_t vdev_id,
205 				      wlan_objmgr_ref_dbgid dbg_id)
206 {
207 	struct wlan_objmgr_vdev *vdev;
208 	struct wlan_objmgr_pdev *pdev = NULL;
209 	uint32_t pdev_id = WLAN_INVALID_PDEV_ID;
210 
211 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
212 						    vdev_id, dbg_id);
213 
214 	if (vdev) {
215 		pdev = wlan_vdev_get_pdev(vdev);
216 		if (pdev)
217 			pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
218 		wlan_objmgr_vdev_release_ref(vdev, dbg_id);
219 	}
220 
221 	return pdev_id;
222 }
223 qdf_export_symbol(wlan_get_pdev_id_from_vdev_id);
224 
225 static void wlan_vdev_active(struct wlan_objmgr_pdev *pdev, void *object,
226 			     void *arg)
227 {
228 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
229 	uint8_t *flag = (uint8_t *)arg;
230 
231 	wlan_vdev_obj_lock(vdev);
232 	if (wlan_vdev_mlme_is_active(vdev) == QDF_STATUS_SUCCESS)
233 		*flag = 1;
234 
235 	wlan_vdev_obj_unlock(vdev);
236 }
237 
238 QDF_STATUS wlan_vdev_is_up(struct wlan_objmgr_vdev *vdev)
239 {
240 	return wlan_vdev_allow_connect_n_tx(vdev);
241 }
242 qdf_export_symbol(wlan_vdev_is_up);
243 
244 QDF_STATUS wlan_util_is_vdev_active(struct wlan_objmgr_pdev *pdev,
245 				    wlan_objmgr_ref_dbgid dbg_id)
246 {
247 	uint8_t flag = 0;
248 
249 	if (!pdev)
250 		return QDF_STATUS_E_INVAL;
251 
252 	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, wlan_vdev_active,
253 					  &flag, 0, dbg_id);
254 
255 	if (flag == 1)
256 		return QDF_STATUS_SUCCESS;
257 
258 	return QDF_STATUS_E_INVAL;
259 }
260 
261 qdf_export_symbol(wlan_util_is_vdev_active);
262 
263 void wlan_util_change_map_index(unsigned long *map, uint8_t id, uint8_t set)
264 {
265 	if (set)
266 		qdf_set_bit(id, map);
267 	else
268 		qdf_clear_bit(id, map);
269 }
270 
271 bool wlan_util_map_index_is_set(unsigned long *map, uint8_t id)
272 {
273 	return qdf_test_bit(id, map);
274 }
275 
276 bool wlan_util_map_is_any_index_set(unsigned long *map, unsigned long nbytes)
277 {
278 	return !qdf_bitmap_empty(map, QDF_CHAR_BIT * nbytes);
279 }
280 
281 static void wlan_vdev_chan_change_pending(struct wlan_objmgr_pdev *pdev,
282 					  void *object, void *arg)
283 {
284 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
285 	unsigned long *vdev_id_map = (unsigned long *)arg;
286 	uint8_t id = 0;
287 	struct wlan_objmgr_psoc *psoc;
288 
289 	psoc = wlan_pdev_get_psoc(pdev);
290 	if (!psoc)
291 		return;
292 
293 	wlan_vdev_obj_lock(vdev);
294 	if (wlan_vdev_chan_config_valid(vdev) == QDF_STATUS_SUCCESS) {
295 		id = wlan_vdev_get_id(vdev);
296 		/* Invalid vdev id */
297 		if (id >= wlan_psoc_get_max_vdev_count(psoc)) {
298 			wlan_vdev_obj_unlock(vdev);
299 			return;
300 		}
301 
302 		wlan_util_change_map_index(vdev_id_map, id, 1);
303 	}
304 
305 	wlan_vdev_obj_unlock(vdev);
306 }
307 
308 QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev,
309 					       unsigned long *vdev_id_map,
310 					       wlan_objmgr_ref_dbgid dbg_id)
311 {
312 	if (!pdev)
313 		return QDF_STATUS_E_INVAL;
314 
315 	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
316 					  wlan_vdev_chan_change_pending,
317 					  vdev_id_map, 0, dbg_id);
318 
319 	return QDF_STATUS_SUCCESS;
320 }
321 
322 static void wlan_vdev_down_pending(struct wlan_objmgr_pdev *pdev,
323 				   void *object, void *arg)
324 {
325 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
326 	unsigned long *vdev_id_map = (unsigned long *)arg;
327 	uint8_t id = 0;
328 	struct wlan_objmgr_psoc *psoc;
329 	enum wlan_serialization_cmd_type cmd_type;
330 
331 	psoc = wlan_pdev_get_psoc(pdev);
332 	if (!psoc)
333 		return;
334 
335 	cmd_type = wlan_serialization_get_vdev_active_cmd_type(vdev);
336 	wlan_vdev_obj_lock(vdev);
337 	if ((wlan_vdev_mlme_is_init_state(vdev) != QDF_STATUS_SUCCESS) ||
338 	    (cmd_type == WLAN_SER_CMD_VDEV_START_BSS)) {
339 		id = wlan_vdev_get_id(vdev);
340 		/* Invalid vdev id */
341 		if (id >= wlan_psoc_get_max_vdev_count(psoc)) {
342 			wlan_vdev_obj_unlock(vdev);
343 			return;
344 		}
345 		wlan_util_change_map_index(vdev_id_map, id, 1);
346 	}
347 
348 	wlan_vdev_obj_unlock(vdev);
349 }
350 
351 static void wlan_vdev_ap_down_pending(struct wlan_objmgr_pdev *pdev,
352 				      void *object, void *arg)
353 {
354 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
355 	unsigned long *vdev_id_map = (unsigned long *)arg;
356 	uint8_t id = 0;
357 	struct wlan_objmgr_psoc *psoc;
358 	enum wlan_serialization_cmd_type cmd_type;
359 
360 	psoc = wlan_pdev_get_psoc(pdev);
361 	if (!psoc)
362 		return;
363 
364 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE)
365 		return;
366 
367 	cmd_type = wlan_serialization_get_vdev_active_cmd_type(vdev);
368 	wlan_vdev_obj_lock(vdev);
369 	if ((wlan_vdev_mlme_is_init_state(vdev) != QDF_STATUS_SUCCESS) ||
370 	    (cmd_type == WLAN_SER_CMD_VDEV_START_BSS)) {
371 		id = wlan_vdev_get_id(vdev);
372 		/* Invalid vdev id */
373 		if (id >= wlan_psoc_get_max_vdev_count(psoc)) {
374 			wlan_vdev_obj_unlock(vdev);
375 			return;
376 		}
377 		wlan_util_change_map_index(vdev_id_map, id, 1);
378 	}
379 
380 	wlan_vdev_obj_unlock(vdev);
381 }
382 
383 QDF_STATUS wlan_pdev_chan_change_pending_vdevs_down(
384 					struct wlan_objmgr_pdev *pdev,
385 					unsigned long *vdev_id_map,
386 					wlan_objmgr_ref_dbgid dbg_id)
387 {
388 	if (!pdev)
389 		return QDF_STATUS_E_INVAL;
390 
391 	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
392 					  wlan_vdev_down_pending,
393 					  vdev_id_map, 0, dbg_id);
394 
395 	return QDF_STATUS_SUCCESS;
396 }
397 
398 QDF_STATUS wlan_pdev_chan_change_pending_ap_vdevs_down(
399 						struct wlan_objmgr_pdev *pdev,
400 						unsigned long *vdev_id_map,
401 						wlan_objmgr_ref_dbgid dbg_id)
402 {
403 	if (!pdev)
404 		return QDF_STATUS_E_INVAL;
405 
406 	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
407 					  wlan_vdev_ap_down_pending,
408 					  vdev_id_map, 0, dbg_id);
409 
410 	return QDF_STATUS_SUCCESS;
411 }
412 
413 #ifdef WLAN_FEATURE_11BE
414 static inline bool
415 wlan_chan_puncture_eq(struct wlan_channel *chan1, struct wlan_channel *chan2)
416 {
417 	if (chan1->puncture_bitmap == chan2->puncture_bitmap)
418 		return true;
419 
420 	return false;
421 }
422 #else
423 static inline bool
424 wlan_chan_puncture_eq(struct wlan_channel *chan1, struct wlan_channel *chan2)
425 {
426 	return true;
427 }
428 #endif /* WLAN_FEATURE_11BE */
429 
430 QDF_STATUS wlan_chan_eq(struct wlan_channel *chan1, struct wlan_channel *chan2)
431 {
432 	if ((chan1->ch_ieee == chan2->ch_ieee) &&
433 	    (chan1->ch_freq_seg2 == chan2->ch_freq_seg2) &&
434 	    wlan_chan_puncture_eq(chan1, chan2))
435 		return QDF_STATUS_SUCCESS;
436 
437 	return QDF_STATUS_E_FAILURE;
438 }
439 
440 void wlan_chan_copy(struct wlan_channel *tgt, struct wlan_channel *src)
441 {
442 	qdf_mem_copy(tgt, src, sizeof(struct wlan_channel));
443 }
444 
445 struct wlan_channel *wlan_vdev_get_active_channel(struct wlan_objmgr_vdev *vdev)
446 {
447 	struct wlan_channel *comp_vdev_chan = NULL;
448 
449 	if (wlan_vdev_chan_config_valid(vdev) == QDF_STATUS_SUCCESS) {
450 		/* compare with BSS channel, when vdev is active, since desired
451 		 * channel gets update, if channel is triggered in another path
452 		 */
453 		if (wlan_vdev_mlme_is_active(vdev) == QDF_STATUS_SUCCESS)
454 			comp_vdev_chan = wlan_vdev_mlme_get_bss_chan(vdev);
455 		else
456 			comp_vdev_chan = wlan_vdev_mlme_get_des_chan(vdev);
457 	}
458 
459 	return comp_vdev_chan;
460 }
461 
462 /**
463  * struct wlan_check_bssid_context - bssid check context
464  * @bssid: bssid to be checked
465  * @connected: connected by vdev or not
466  * @vdev_id: vdev id of connected vdev
467  */
468 struct wlan_check_bssid_context {
469 	struct qdf_mac_addr bssid;
470 	bool connected;
471 	uint8_t vdev_id;
472 };
473 
474 /**
475  * wlan_get_connected_vdev_handler() - check vdev connected on bssid
476  * @psoc: psoc object
477  * @obj: vdev object
478  * @args: handler context
479  *
480  * This function will check whether vdev is connected on bssid or not and
481  * update the result to handler context accordingly.
482  *
483  * Return: void
484  */
485 static void wlan_get_connected_vdev_handler(struct wlan_objmgr_psoc *psoc,
486 					    void *obj, void *args)
487 {
488 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj;
489 	struct wlan_check_bssid_context *context =
490 				(struct wlan_check_bssid_context *)args;
491 	struct qdf_mac_addr bss_peer_mac;
492 	enum QDF_OPMODE op_mode;
493 
494 	if (context->connected)
495 		return;
496 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
497 	if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE)
498 		return;
499 	if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS)
500 		return;
501 	if (wlan_vdev_get_bss_peer_mac(vdev, &bss_peer_mac) !=
502 	    QDF_STATUS_SUCCESS)
503 		return;
504 	if (qdf_is_macaddr_equal(&bss_peer_mac, &context->bssid)) {
505 		context->connected = true;
506 		context->vdev_id = wlan_vdev_get_id(vdev);
507 	}
508 }
509 
510 bool wlan_get_connected_vdev_by_bssid(struct wlan_objmgr_pdev *pdev,
511 				      uint8_t *bssid, uint8_t *vdev_id)
512 {
513 	struct wlan_objmgr_psoc *psoc;
514 	struct wlan_check_bssid_context context;
515 
516 	psoc = wlan_pdev_get_psoc(pdev);
517 	qdf_mem_zero(&context, sizeof(struct wlan_check_bssid_context));
518 	qdf_mem_copy(context.bssid.bytes, bssid, QDF_MAC_ADDR_SIZE);
519 	wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
520 				     wlan_get_connected_vdev_handler,
521 				     &context, true, WLAN_OSIF_SCAN_ID);
522 	if (context.connected)
523 		*vdev_id = context.vdev_id;
524 
525 	return context.connected;
526 }
527 
528 qdf_export_symbol(wlan_get_connected_vdev_by_bssid);
529 
530 static void wlan_pdev_chan_match(struct wlan_objmgr_pdev *pdev, void *object,
531 				 void *arg)
532 {
533 	struct wlan_objmgr_vdev *comp_vdev = (struct wlan_objmgr_vdev *)object;
534 	struct wlan_vdev_ch_check_filter *ch_filter = arg;
535 	struct wlan_channel vdev_chan, *chan;
536 	struct wlan_channel *iter_vdev_chan;
537 
538 	if (ch_filter->flag)
539 		return;
540 
541 	if (comp_vdev == ch_filter->vdev)
542 		return;
543 
544 	wlan_vdev_obj_lock(comp_vdev);
545 	chan = wlan_vdev_get_active_channel(comp_vdev);
546 	if (!chan) {
547 		wlan_vdev_obj_unlock(comp_vdev);
548 		return;
549 	}
550 	wlan_chan_copy(&vdev_chan, chan);
551 	wlan_vdev_obj_unlock(comp_vdev);
552 
553 	wlan_vdev_obj_lock(ch_filter->vdev);
554 	iter_vdev_chan = wlan_vdev_mlme_get_des_chan(ch_filter->vdev);
555 	if (wlan_chan_eq(&vdev_chan, iter_vdev_chan)
556 		!= QDF_STATUS_SUCCESS) {
557 		ch_filter->flag = 1;
558 		qdf_nofl_err("==> iter vdev id: %d: ieee %d, mode %d",
559 			     wlan_vdev_get_id(comp_vdev),
560 			     vdev_chan.ch_ieee,
561 			     vdev_chan.ch_phymode);
562 		qdf_nofl_err("fl %016llx, fl-ext %08x, s1 %d, s2 %d ",
563 			     vdev_chan.ch_flags, vdev_chan.ch_flagext,
564 			     vdev_chan.ch_freq_seg1,
565 			     vdev_chan.ch_freq_seg2);
566 		qdf_nofl_err("==> base vdev id: %d: ieee %d mode %d",
567 			     wlan_vdev_get_id(ch_filter->vdev),
568 			     iter_vdev_chan->ch_ieee,
569 			     iter_vdev_chan->ch_phymode);
570 		qdf_nofl_err("fl %016llx, fl-ext %08x s1 %d, s2 %d",
571 			     iter_vdev_chan->ch_flags,
572 			     iter_vdev_chan->ch_flagext,
573 			     iter_vdev_chan->ch_freq_seg1,
574 			     iter_vdev_chan->ch_freq_seg2);
575 	}
576 	wlan_vdev_obj_unlock(ch_filter->vdev);
577 }
578 
579 QDF_STATUS wlan_util_pdev_vdevs_deschan_match(struct wlan_objmgr_pdev *pdev,
580 					      struct wlan_objmgr_vdev *vdev,
581 					      wlan_objmgr_ref_dbgid dbg_id)
582 {
583 	struct wlan_vdev_ch_check_filter ch_filter;
584 
585 	if (!pdev)
586 		return QDF_STATUS_E_INVAL;
587 
588 	if (wlan_pdev_nif_feat_cap_get(pdev, WLAN_PDEV_F_CHAN_CONCURRENCY))
589 		return QDF_STATUS_SUCCESS;
590 
591 	if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == QDF_STATUS_SUCCESS) {
592 		ch_filter.flag = 0;
593 		ch_filter.vdev = vdev;
594 
595 		wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
596 						  wlan_pdev_chan_match,
597 						  &ch_filter, 0, dbg_id);
598 
599 		wlan_objmgr_vdev_release_ref(vdev, dbg_id);
600 
601 		if (ch_filter.flag == 0)
602 			return QDF_STATUS_SUCCESS;
603 	}
604 
605 	return QDF_STATUS_E_FAILURE;
606 }
607 
608 static void wlan_vdev_restart_progress(struct wlan_objmgr_pdev *pdev,
609 				       void *object, void *arg)
610 {
611 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
612 	uint8_t *flag = (uint8_t *)arg;
613 
614 	wlan_vdev_obj_lock(vdev);
615 	if (wlan_vdev_is_restart_progress(vdev) == QDF_STATUS_SUCCESS)
616 		*flag = 1;
617 
618 	wlan_vdev_obj_unlock(vdev);
619 }
620 
621 QDF_STATUS wlan_util_is_pdev_restart_progress(struct wlan_objmgr_pdev *pdev,
622 					      wlan_objmgr_ref_dbgid dbg_id)
623 {
624 	uint8_t flag = 0;
625 
626 	if (!pdev)
627 		return QDF_STATUS_E_INVAL;
628 
629 	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
630 					  wlan_vdev_restart_progress,
631 					  &flag, 0, dbg_id);
632 
633 	if (flag == 1)
634 		return QDF_STATUS_SUCCESS;
635 
636 	return QDF_STATUS_E_INVAL;
637 }
638 
639 static void wlan_vdev_scan_allowed(struct wlan_objmgr_pdev *pdev, void *object,
640 				   void *arg)
641 {
642 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
643 	uint8_t *flag = (uint8_t *)arg;
644 
645 	wlan_vdev_obj_lock(vdev);
646 	if (wlan_vdev_mlme_is_scan_allowed(vdev) != QDF_STATUS_SUCCESS)
647 		*flag = 1;
648 
649 	wlan_vdev_obj_unlock(vdev);
650 }
651 
652 QDF_STATUS wlan_util_is_pdev_scan_allowed(struct wlan_objmgr_pdev *pdev,
653 					  wlan_objmgr_ref_dbgid dbg_id)
654 {
655 	uint8_t flag = 0;
656 
657 	if (!pdev)
658 		return QDF_STATUS_E_INVAL;
659 
660 	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
661 					  wlan_vdev_scan_allowed,
662 					  &flag, 0, dbg_id);
663 
664 	if (flag == 1)
665 		return QDF_STATUS_E_FAILURE;
666 
667 	return QDF_STATUS_SUCCESS;
668 }
669 
670 void
671 wlan_util_stats_get_rssi(bool db2dbm_enabled, int32_t bcn_snr, int32_t dat_snr,
672 			 int8_t *rssi)
673 {
674 	uint32_t snr;
675 
676 	if (db2dbm_enabled) {
677 		if (TGT_IS_VALID_RSSI(bcn_snr))
678 			*rssi = bcn_snr;
679 		else if (TGT_IS_VALID_RSSI(dat_snr))
680 			*rssi = dat_snr;
681 		else
682 			*rssi = TGT_NOISE_FLOOR_DBM;
683 	} else {
684 		if (TGT_IS_VALID_SNR(bcn_snr))
685 			snr = bcn_snr;
686 		else if (TGT_IS_VALID_SNR(dat_snr))
687 			snr = dat_snr;
688 		else
689 			snr = TGT_INVALID_SNR;
690 
691 		/* Get the absolute rssi value from the current rssi value */
692 		*rssi = snr + TGT_NOISE_FLOOR_DBM;
693 	}
694 }
695 
696 /**
697  * wlan_util_get_mode_specific_peer_count - This api gives vdev mode specific
698  * peer count`
699  * @pdev: PDEV object
700  * @object: vdev object
701  * @arg: argument passed by caller
702  *
703  * Return: void
704  */
705 static void
706 wlan_util_get_mode_specific_peer_count(struct wlan_objmgr_pdev *pdev,
707 				       void *object, void *arg)
708 {
709 	struct wlan_objmgr_vdev *vdev = object;
710 	uint16_t temp_count = 0;
711 	struct wlan_op_mode_peer_count *count = arg;
712 
713 	wlan_vdev_obj_lock(vdev);
714 	if (wlan_vdev_mlme_get_opmode(vdev) == count->opmode) {
715 		temp_count = wlan_vdev_get_peer_count(vdev);
716 		/* Decrement the self peer count */
717 		if (temp_count > 1)
718 			count->peer_count += (temp_count - 1);
719 	}
720 	wlan_vdev_obj_unlock(vdev);
721 }
722 
723 uint16_t wlan_util_get_peer_count_for_mode(struct wlan_objmgr_pdev *pdev,
724 					   enum QDF_OPMODE mode)
725 {
726 	struct wlan_op_mode_peer_count count;
727 
728 	count.opmode = mode;
729 	count.peer_count = 0;
730 	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
731 				wlan_util_get_mode_specific_peer_count, &count,
732 				0, WLAN_OBJMGR_ID);
733 
734 	return count.peer_count;
735 }
736 
737 #ifdef CONFIG_QCA_MINIDUMP
738 static bool wlan_minidump_log_enabled(struct wlan_objmgr_psoc *psoc,
739 				      enum wlan_minidump_host_data type)
740 {
741 	bool setval = false;
742 
743 	switch (type) {
744 	case WLAN_MD_CP_EXT_PDEV:
745 		if (cfg_get(psoc, CFG_OL_MD_CP_EXT_PDEV))
746 			setval = true;
747 		break;
748 	case WLAN_MD_CP_EXT_PSOC:
749 		if (cfg_get(psoc, CFG_OL_MD_CP_EXT_PSOC))
750 			setval = true;
751 		break;
752 	case WLAN_MD_CP_EXT_VDEV:
753 		if (cfg_get(psoc, CFG_OL_MD_CP_EXT_VDEV))
754 			setval = true;
755 		break;
756 	case WLAN_MD_CP_EXT_PEER:
757 		if (cfg_get(psoc, CFG_OL_MD_CP_EXT_PEER))
758 			setval = true;
759 		break;
760 	case WLAN_MD_DP_SOC:
761 		if (cfg_get(psoc, CFG_OL_MD_DP_SOC))
762 			setval = true;
763 		break;
764 	case WLAN_MD_DP_PDEV:
765 		if (cfg_get(psoc, CFG_OL_MD_DP_PDEV))
766 			setval = true;
767 		break;
768 	case WLAN_MD_DP_PEER:
769 		if (cfg_get(psoc, CFG_OL_MD_DP_PEER))
770 			setval = true;
771 		break;
772 	case WLAN_MD_DP_SRNG_REO_DEST:
773 	case WLAN_MD_DP_SRNG_REO_EXCEPTION:
774 	case WLAN_MD_DP_SRNG_RX_REL:
775 	case WLAN_MD_DP_SRNG_REO_REINJECT:
776 	case WLAN_MD_DP_SRNG_REO_CMD:
777 	case WLAN_MD_DP_SRNG_REO_STATUS:
778 		if (cfg_get(psoc, CFG_OL_MD_DP_SRNG_REO))
779 			setval = true;
780 		break;
781 	case WLAN_MD_DP_SRNG_TCL_DATA:
782 	case WLAN_MD_DP_SRNG_TCL_CMD:
783 	case WLAN_MD_DP_SRNG_TCL_STATUS:
784 	case WLAN_MD_DP_SRNG_TX_COMP:
785 		if (cfg_get(psoc, CFG_OL_MD_DP_SRNG_TCL))
786 			setval = true;
787 		break;
788 	case WLAN_MD_DP_SRNG_WBM_DESC_REL:
789 	case WLAN_MD_DP_SRNG_WBM_IDLE_LINK:
790 		if (cfg_get(psoc, CFG_OL_MD_DP_SRNG_WBM))
791 			setval = true;
792 		break;
793 	case WLAN_MD_DP_LINK_DESC_BANK:
794 		if (cfg_get(psoc, CFG_OL_MD_DP_LINK_DESC_BANK))
795 			setval = true;
796 		break;
797 	case WLAN_MD_DP_SRNG_RXDMA_MON_BUF:
798 	case WLAN_MD_DP_SRNG_RXDMA_MON_DST:
799 	case WLAN_MD_DP_SRNG_RXDMA_MON_DESC:
800 	case WLAN_MD_DP_SRNG_RXDMA_ERR_DST:
801 	case WLAN_MD_DP_SRNG_RXDMA_MON_STATUS:
802 		if (cfg_get(psoc, CFG_OL_MD_DP_SRNG_RXDMA))
803 			setval = true;
804 		break;
805 	case WLAN_MD_DP_HAL_SOC:
806 		if (cfg_get(psoc, CFG_OL_MD_DP_HAL_SOC))
807 			setval = true;
808 		break;
809 	case WLAN_MD_OBJMGR_PSOC:
810 	case WLAN_MD_OBJMGR_PSOC_TGT_INFO:
811 		if (cfg_get(psoc, CFG_OL_MD_OBJMGR_PSOC))
812 			setval = true;
813 		break;
814 	case WLAN_MD_OBJMGR_PDEV:
815 	case WLAN_MD_OBJMGR_PDEV_MLME:
816 		if (cfg_get(psoc, CFG_OL_MD_OBJMGR_PDEV))
817 			setval = true;
818 		break;
819 	case WLAN_MD_OBJMGR_VDEV_MLME:
820 	case WLAN_MD_OBJMGR_VDEV_SM:
821 	case WLAN_MD_OBJMGR_VDEV:
822 		if (cfg_get(psoc, CFG_OL_MD_OBJMGR_VDEV))
823 			setval = true;
824 		break;
825 	default:
826 		qdf_debug("Minidump: Type not implemented");
827 	}
828 
829 	return setval;
830 }
831 #else /* CONFIG_QCA_MINIDUMP */
832 static bool wlan_minidump_log_enabled(struct wlan_objmgr_psoc *psoc,
833 				      enum wlan_minidump_host_data type)
834 {
835 	return false;
836 }
837 #endif
838 void wlan_minidump_log(void *start_addr, const size_t size,
839 		       void *psoc_obj,
840 		       enum wlan_minidump_host_data type,
841 		       const char *name)
842 {
843 	struct wlan_objmgr_psoc *psoc;
844 
845 	if (!psoc_obj) {
846 		qdf_debug("Minidump: Psoc is NULL");
847 		return;
848 	}
849 
850 	psoc = (struct wlan_objmgr_psoc *)psoc_obj;
851 
852 	if (psoc && wlan_minidump_log_enabled(psoc, type))
853 		qdf_minidump_log(start_addr, size, name);
854 }
855 qdf_export_symbol(wlan_minidump_log);
856 
857 void wlan_minidump_remove(void *start_addr, const size_t size,
858 			  void *psoc_obj,
859 			  enum wlan_minidump_host_data type,
860 			  const char *name)
861 {
862 	struct wlan_objmgr_psoc *psoc;
863 
864 	if (!psoc_obj) {
865 		qdf_debug("Minidump: Psoc is NULL");
866 		return;
867 	}
868 
869 	psoc = (struct wlan_objmgr_psoc *)psoc_obj;
870 
871 	if (psoc && wlan_minidump_log_enabled(psoc, type))
872 		qdf_minidump_remove(start_addr, size, name);
873 }
874 qdf_export_symbol(wlan_minidump_remove);
875