xref: /wlan-dirver/qcacld-3.0/components/tdls/core/src/wlan_tdls_main.c (revision 4fa68113fe9b047323e28a9840602f3238e342dd)
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: wlan_tdls_main.c
22  *
23  * TDLS core function definitions
24  */
25 
26 #include "wlan_tdls_main.h"
27 #include "wlan_tdls_peer.h"
28 #include "wlan_tdls_ct.h"
29 #include "wlan_tdls_mgmt.h"
30 #include "wlan_tdls_api.h"
31 #include "wlan_tdls_tgt_api.h"
32 #include "wlan_policy_mgr_public_struct.h"
33 #include "wlan_policy_mgr_api.h"
34 #include "wlan_scan_ucfg_api.h"
35 #include "wlan_tdls_ucfg_api.h"
36 #include "wlan_cm_roam_api.h"
37 #include "wlan_cfg80211_tdls.h"
38 #include "wlan_nan_api_i.h"
39 #include "wlan_mlme_vdev_mgr_interface.h"
40 
41 /* Global tdls soc pvt object
42  * this is useful for some functions which does not receive either vdev or psoc
43  * objects.
44  */
45 static struct tdls_soc_priv_obj *tdls_soc_global;
46 
47 #ifdef WLAN_DEBUG
48 /**
49  * tdls_get_cmd_type_str() - parse cmd to string
50  * @cmd_type: tdls cmd type
51  *
52  * This function parse tdls cmd to string.
53  *
54  * Return: command string
55  */
56 static char *tdls_get_cmd_type_str(enum tdls_command_type cmd_type)
57 {
58 	switch (cmd_type) {
59 	CASE_RETURN_STRING(TDLS_CMD_TX_ACTION);
60 	CASE_RETURN_STRING(TDLS_CMD_ADD_STA);
61 	CASE_RETURN_STRING(TDLS_CMD_CHANGE_STA);
62 	CASE_RETURN_STRING(TDLS_CMD_ENABLE_LINK);
63 	CASE_RETURN_STRING(TDLS_CMD_DISABLE_LINK);
64 	CASE_RETURN_STRING(TDLS_CMD_CONFIG_FORCE_PEER);
65 	CASE_RETURN_STRING(TDLS_CMD_REMOVE_FORCE_PEER);
66 	CASE_RETURN_STRING(TDLS_CMD_STATS_UPDATE);
67 	CASE_RETURN_STRING(TDLS_CMD_CONFIG_UPDATE);
68 	CASE_RETURN_STRING(TDLS_CMD_SCAN_DONE);
69 	CASE_RETURN_STRING(TDLS_CMD_SET_RESPONDER);
70 	CASE_RETURN_STRING(TDLS_NOTIFY_STA_CONNECTION);
71 	CASE_RETURN_STRING(TDLS_NOTIFY_STA_DISCONNECTION);
72 	CASE_RETURN_STRING(TDLS_CMD_SET_TDLS_MODE);
73 	CASE_RETURN_STRING(TDLS_CMD_SESSION_INCREMENT);
74 	CASE_RETURN_STRING(TDLS_CMD_SESSION_DECREMENT);
75 	CASE_RETURN_STRING(TDLS_CMD_TEARDOWN_LINKS);
76 	CASE_RETURN_STRING(TDLS_NOTIFY_RESET_ADAPTERS);
77 	CASE_RETURN_STRING(TDLS_CMD_ANTENNA_SWITCH);
78 	CASE_RETURN_STRING(TDLS_CMD_SET_OFFCHANMODE);
79 	CASE_RETURN_STRING(TDLS_CMD_SET_OFFCHANNEL);
80 	CASE_RETURN_STRING(TDLS_CMD_SET_SECOFFCHANOFFSET);
81 	CASE_RETURN_STRING(TDLS_DELETE_ALL_PEERS_INDICATION);
82 	CASE_RETURN_STRING(TDLS_CMD_START_BSS);
83 	CASE_RETURN_STRING(TDLS_CMD_SET_LINK_UNFORCE);
84 	default:
85 		return "Invalid TDLS command";
86 	}
87 }
88 
89 /**
90  * tdls_get_event_type_str() - parase event to string
91  * @event_type: tdls event type
92  *
93  * This function parse tdls event to string.
94  *
95  * Return: event string
96  */
97 static char *tdls_get_event_type_str(enum tdls_event_type event_type)
98 {
99 	switch (event_type) {
100 	case TDLS_SHOULD_DISCOVER:
101 		return "TDLS_SHOULD_DISCOVER";
102 	case TDLS_SHOULD_TEARDOWN:
103 		return "TDLS_SHOULD_TEARDOWN";
104 	case TDLS_PEER_DISCONNECTED:
105 		return "TDLS_PEER_DISCONNECTED";
106 	case TDLS_CONNECTION_TRACKER_NOTIFY:
107 		return "TDLS_CONNECTION_TRACKER_NOTIFY";
108 
109 	default:
110 		return "Invalid TDLS event";
111 	}
112 }
113 #else
114 static char *tdls_get_cmd_type_str(enum tdls_command_type cmd_type)
115 {
116 	return "";
117 }
118 
119 static char *tdls_get_event_type_str(enum tdls_event_type event_type)
120 {
121 	return "";
122 }
123 #endif
124 
125 QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
126 					     void *arg_list)
127 {
128 	QDF_STATUS status;
129 	struct tdls_soc_priv_obj *tdls_soc_obj;
130 
131 	tdls_soc_obj = qdf_mem_malloc(sizeof(*tdls_soc_obj));
132 	if (!tdls_soc_obj)
133 		return QDF_STATUS_E_NOMEM;
134 
135 	tdls_soc_obj->soc = psoc;
136 
137 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
138 						       WLAN_UMAC_COMP_TDLS,
139 						       (void *)tdls_soc_obj,
140 						       QDF_STATUS_SUCCESS);
141 
142 	if (QDF_IS_STATUS_ERROR(status)) {
143 		tdls_err("Failed to attach psoc tdls component");
144 		qdf_mem_free(tdls_soc_obj);
145 		return status;
146 	}
147 
148 	tdls_soc_global = tdls_soc_obj;
149 	tdls_notice("TDLS obj attach to psoc successfully");
150 
151 	return status;
152 }
153 
154 QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc,
155 					      void *arg_list)
156 {
157 	QDF_STATUS status;
158 	struct tdls_soc_priv_obj *tdls_soc_obj;
159 
160 	tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
161 						WLAN_UMAC_COMP_TDLS);
162 	if (!tdls_soc_obj) {
163 		tdls_err("Failed to get tdls obj in psoc");
164 		return QDF_STATUS_E_FAILURE;
165 	}
166 
167 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
168 						       WLAN_UMAC_COMP_TDLS,
169 						       tdls_soc_obj);
170 
171 	if (QDF_IS_STATUS_ERROR(status))
172 		tdls_err("Failed to detach psoc tdls component");
173 	qdf_mem_free(tdls_soc_obj);
174 
175 	return status;
176 }
177 
178 static QDF_STATUS tdls_vdev_init(struct tdls_vdev_priv_obj *vdev_obj)
179 {
180 	uint8_t i;
181 	struct tdls_config_params *config;
182 	struct tdls_user_config *user_config;
183 	struct tdls_soc_priv_obj *soc_obj;
184 
185 	soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev);
186 	if (!soc_obj) {
187 		tdls_err("tdls soc obj NULL");
188 		return QDF_STATUS_E_FAILURE;
189 	}
190 
191 	config = &vdev_obj->threshold_config;
192 	user_config = &soc_obj->tdls_configs;
193 	config->tx_period_t = user_config->tdls_tx_states_period;
194 	config->tx_packet_n = user_config->tdls_tx_pkt_threshold;
195 	config->discovery_tries_n = user_config->tdls_max_discovery_attempt;
196 	config->idle_timeout_t = user_config->tdls_idle_timeout;
197 	config->idle_packet_n = user_config->tdls_idle_pkt_threshold;
198 	config->rssi_trigger_threshold =
199 		user_config->tdls_rssi_trigger_threshold;
200 	config->rssi_teardown_threshold =
201 		user_config->tdls_rssi_teardown_threshold;
202 	config->rssi_delta = user_config->tdls_rssi_delta;
203 
204 	for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
205 		qdf_list_create(&vdev_obj->peer_list[i],
206 				WLAN_TDLS_PEER_SUB_LIST_SIZE);
207 	}
208 	qdf_mc_timer_init(&vdev_obj->peer_update_timer, QDF_TIMER_TYPE_SW,
209 			  tdls_ct_handler, vdev_obj->vdev);
210 	qdf_mc_timer_init(&vdev_obj->peer_discovery_timer, QDF_TIMER_TYPE_SW,
211 			  tdls_discovery_timeout_peer_cb, vdev_obj->vdev);
212 
213 	return QDF_STATUS_SUCCESS;
214 }
215 
216 static void tdls_vdev_deinit(struct tdls_vdev_priv_obj *vdev_obj)
217 {
218 	qdf_mc_timer_stop_sync(&vdev_obj->peer_update_timer);
219 	qdf_mc_timer_stop_sync(&vdev_obj->peer_discovery_timer);
220 
221 	qdf_mc_timer_destroy(&vdev_obj->peer_update_timer);
222 	qdf_mc_timer_destroy(&vdev_obj->peer_discovery_timer);
223 
224 	tdls_peer_idle_timers_destroy(vdev_obj);
225 	tdls_free_peer_list(vdev_obj);
226 }
227 
228 QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev,
229 					     void *arg)
230 {
231 	QDF_STATUS status;
232 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
233 	struct wlan_objmgr_pdev *pdev;
234 	struct tdls_soc_priv_obj *tdls_soc_obj;
235 	uint32_t tdls_feature_flags;
236 
237 	tdls_debug("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev));
238 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE &&
239 	    wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE)
240 		return QDF_STATUS_SUCCESS;
241 
242 	tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev);
243 	if (!tdls_soc_obj) {
244 		tdls_err("get soc by vdev failed");
245 		return QDF_STATUS_E_NOMEM;
246 	}
247 
248 	tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags;
249 	if (!TDLS_IS_ENABLED(tdls_feature_flags)) {
250 		tdls_debug("disabled in ini");
251 		return QDF_STATUS_E_NOSUPPORT;
252 	}
253 
254 	if (tdls_soc_obj->tdls_osif_init_cb) {
255 		status = tdls_soc_obj->tdls_osif_init_cb(vdev);
256 		if (QDF_IS_STATUS_ERROR(status))
257 			return status;
258 	}
259 
260 	/* TODO: Add concurrency check */
261 
262 	tdls_vdev_obj = qdf_mem_malloc(sizeof(*tdls_vdev_obj));
263 	if (!tdls_vdev_obj) {
264 		status = QDF_STATUS_E_NOMEM;
265 		goto err_attach;
266 	}
267 
268 	status = wlan_objmgr_vdev_component_obj_attach(vdev,
269 						       WLAN_UMAC_COMP_TDLS,
270 						       (void *)tdls_vdev_obj,
271 						       QDF_STATUS_SUCCESS);
272 	if (QDF_IS_STATUS_ERROR(status)) {
273 		tdls_err("Failed to attach vdev tdls component");
274 		goto err_attach;
275 	}
276 	tdls_vdev_obj->vdev = vdev;
277 	status = tdls_vdev_init(tdls_vdev_obj);
278 	if (QDF_IS_STATUS_ERROR(status))
279 		goto err_vdev_init;
280 
281 	status = qdf_event_create(&tdls_vdev_obj->tdls_teardown_comp);
282 	if (QDF_IS_STATUS_ERROR(status))
283 		goto err_event_create;
284 
285 	pdev = wlan_vdev_get_pdev(vdev);
286 
287 	status = ucfg_scan_register_event_handler(pdev,
288 				tdls_scan_complete_event_handler,
289 				tdls_soc_obj);
290 
291 	if (QDF_STATUS_SUCCESS != status) {
292 		tdls_err("scan event register failed ");
293 		goto err_register;
294 	}
295 
296 	tdls_debug("tdls object attach to vdev successfully");
297 	return status;
298 
299 err_register:
300 	qdf_event_destroy(&tdls_vdev_obj->tdls_teardown_comp);
301 err_event_create:
302 	tdls_vdev_deinit(tdls_vdev_obj);
303 err_vdev_init:
304 	wlan_objmgr_vdev_component_obj_detach(vdev,
305 					      WLAN_UMAC_COMP_TDLS,
306 					      (void *)tdls_vdev_obj);
307 err_attach:
308 	if (tdls_soc_obj->tdls_osif_deinit_cb)
309 		tdls_soc_obj->tdls_osif_deinit_cb(vdev);
310 	if (tdls_vdev_obj) {
311 		qdf_mem_free(tdls_vdev_obj);
312 		tdls_vdev_obj = NULL;
313 	}
314 
315 	return status;
316 }
317 
318 QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev,
319 					      void *arg)
320 {
321 	QDF_STATUS status;
322 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
323 	struct tdls_soc_priv_obj *tdls_soc_obj;
324 	uint32_t tdls_feature_flags;
325 
326 	tdls_debug("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev));
327 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE &&
328 	    wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE)
329 		return QDF_STATUS_SUCCESS;
330 
331 	tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev);
332 	if (!tdls_soc_obj) {
333 		tdls_err("get soc by vdev failed");
334 		return QDF_STATUS_E_NOMEM;
335 	}
336 
337 	tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags;
338 	if (!TDLS_IS_ENABLED(tdls_feature_flags)) {
339 		tdls_debug("disabled in ini");
340 		return QDF_STATUS_E_NOSUPPORT;
341 	}
342 
343 	tdls_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
344 							WLAN_UMAC_COMP_TDLS);
345 	if (!tdls_vdev_obj) {
346 		tdls_err("Failed to get tdls vdev object");
347 		return QDF_STATUS_E_FAILURE;
348 	}
349 
350 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
351 		if (QDF_TIMER_STATE_STOPPED !=
352 		    qdf_mc_timer_get_current_state(
353 					&tdls_vdev_obj->peer_discovery_timer))
354 			qdf_mc_timer_stop(&tdls_vdev_obj->peer_discovery_timer);
355 	}
356 
357 	qdf_event_destroy(&tdls_vdev_obj->tdls_teardown_comp);
358 	tdls_vdev_deinit(tdls_vdev_obj);
359 
360 	status = wlan_objmgr_vdev_component_obj_detach(vdev,
361 						       WLAN_UMAC_COMP_TDLS,
362 						       tdls_vdev_obj);
363 	if (QDF_IS_STATUS_ERROR(status))
364 		tdls_err("Failed to detach vdev tdls component");
365 
366 	if (tdls_soc_obj->tdls_osif_deinit_cb)
367 		tdls_soc_obj->tdls_osif_deinit_cb(vdev);
368 	qdf_mem_free(tdls_vdev_obj);
369 
370 	return status;
371 }
372 
373 /**
374  * __tdls_get_all_peers_from_list() - get all the tdls peers from the list
375  * @get_tdls_peers: get_tdls_peers object
376  *
377  * Return: int
378  */
379 static int __tdls_get_all_peers_from_list(
380 			struct tdls_get_all_peers *get_tdls_peers)
381 {
382 	int i;
383 	int len, init_len;
384 	qdf_list_t *head;
385 	qdf_list_node_t *p_node;
386 	struct tdls_peer *curr_peer;
387 	char *buf;
388 	int buf_len;
389 	struct tdls_vdev_priv_obj *tdls_vdev;
390 	QDF_STATUS status;
391 
392 	tdls_notice("Enter ");
393 
394 	buf = get_tdls_peers->buf;
395 	buf_len = get_tdls_peers->buf_len;
396 
397 	if (wlan_vdev_is_up(get_tdls_peers->vdev) != QDF_STATUS_SUCCESS) {
398 		len = qdf_scnprintf(buf, buf_len,
399 				"\nSTA is not associated\n");
400 		return len;
401 	}
402 
403 	tdls_vdev = wlan_vdev_get_tdls_vdev_obj(get_tdls_peers->vdev);
404 
405 	if (!tdls_vdev) {
406 		len = qdf_scnprintf(buf, buf_len, "TDLS not enabled\n");
407 		return len;
408 	}
409 
410 	init_len = buf_len;
411 	len = qdf_scnprintf(buf, buf_len,
412 			"\n%-18s%-3s%-4s%-3s%-5s\n",
413 			"MAC", "Id", "cap", "up", "RSSI");
414 	buf += len;
415 	buf_len -= len;
416 	len = qdf_scnprintf(buf, buf_len,
417 			    "---------------------------------\n");
418 	buf += len;
419 	buf_len -= len;
420 
421 	for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
422 		head = &tdls_vdev->peer_list[i];
423 		status = qdf_list_peek_front(head, &p_node);
424 		while (QDF_IS_STATUS_SUCCESS(status)) {
425 			curr_peer = qdf_container_of(p_node,
426 						     struct tdls_peer, node);
427 			if (buf_len < 32 + 1)
428 				break;
429 			len = qdf_scnprintf(buf, buf_len,
430 				QDF_MAC_ADDR_FMT "%4s%3s%5d\n",
431 				QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes),
432 				(curr_peer->tdls_support ==
433 				 TDLS_CAP_SUPPORTED) ? "Y" : "N",
434 				TDLS_IS_LINK_CONNECTED(curr_peer) ? "Y" :
435 				"N", curr_peer->rssi);
436 			buf += len;
437 			buf_len -= len;
438 			status = qdf_list_peek_next(head, p_node, &p_node);
439 		}
440 	}
441 
442 	tdls_notice("Exit ");
443 	return init_len - buf_len;
444 }
445 
446 /**
447  * tdls_get_all_peers_from_list() - get all the tdls peers from the list
448  * @get_tdls_peers: get_tdls_peers object
449  *
450  * Return: None
451  */
452 static void tdls_get_all_peers_from_list(
453 			struct tdls_get_all_peers *get_tdls_peers)
454 {
455 	int32_t len;
456 	struct tdls_soc_priv_obj *tdls_soc_obj;
457 	struct tdls_osif_indication indication;
458 
459 	if (!get_tdls_peers->vdev) {
460 		qdf_mem_free(get_tdls_peers);
461 		return;
462 	}
463 	len = __tdls_get_all_peers_from_list(get_tdls_peers);
464 
465 	indication.status = len;
466 	indication.vdev = get_tdls_peers->vdev;
467 
468 	tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(get_tdls_peers->vdev);
469 	if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb)
470 		tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data,
471 			TDLS_EVENT_USER_CMD, &indication);
472 
473 	qdf_mem_free(get_tdls_peers);
474 }
475 
476 /**
477  * tdls_process_reset_all_peers() - Reset all tdls peers
478  * @vdev: vdev object
479  *
480  * This function is called to reset all tdls peers and
481  * notify upper layers of teardown inidcation
482  *
483  * Return: QDF_STATUS
484  */
485 
486 static QDF_STATUS tdls_process_reset_all_peers(struct wlan_objmgr_vdev *vdev)
487 {
488 	QDF_STATUS status = QDF_STATUS_SUCCESS;
489 	uint8_t staidx;
490 	struct tdls_peer *curr_peer = NULL;
491 	struct tdls_vdev_priv_obj *tdls_vdev;
492 	struct tdls_soc_priv_obj *tdls_soc;
493 	uint8_t reset_session_id;
494 
495 	status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc);
496 	if (QDF_STATUS_SUCCESS != status) {
497 		tdls_err("tdls objects are NULL ");
498 		return status;
499 	}
500 
501 	reset_session_id = tdls_vdev->session_id;
502 	for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta;
503 							staidx++) {
504 		if (!tdls_soc->tdls_conn_info[staidx].valid_entry)
505 			continue;
506 		if (tdls_soc->tdls_conn_info[staidx].session_id !=
507 		    reset_session_id)
508 			continue;
509 
510 		curr_peer =
511 		tdls_find_all_peer(tdls_soc,
512 				   tdls_soc->tdls_conn_info[staidx].
513 				   peer_mac.bytes);
514 		if (!curr_peer)
515 			continue;
516 
517 		tdls_notice("indicate TDLS teardown "QDF_MAC_ADDR_FMT,
518 			    QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes));
519 
520 		/* Indicate teardown to supplicant */
521 		tdls_indicate_teardown(tdls_vdev,
522 				       curr_peer,
523 				       TDLS_TEARDOWN_PEER_UNSPEC_REASON);
524 
525 		tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes);
526 
527 		tdls_decrement_peer_count(vdev, tdls_soc);
528 		tdls_soc->tdls_conn_info[staidx].valid_entry = false;
529 		tdls_soc->tdls_conn_info[staidx].session_id = 255;
530 		tdls_soc->tdls_conn_info[staidx].index =
531 					INVALID_TDLS_PEER_INDEX;
532 
533 		qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac,
534 			     sizeof(struct qdf_mac_addr));
535 	}
536 	return status;
537 }
538 
539 /**
540  * tdls_reset_all_peers() - Reset all tdls peers
541  * @delete_all_peers_ind: Delete all peers indication
542  *
543  * This function is called to reset all tdls peers and
544  * notify upper layers of teardown inidcation
545  *
546  * Return: QDF_STATUS
547  */
548 static QDF_STATUS tdls_reset_all_peers(
549 		struct tdls_delete_all_peers_params *delete_all_peers_ind)
550 {
551 	QDF_STATUS status;
552 
553 	if (!delete_all_peers_ind || !delete_all_peers_ind->vdev) {
554 		tdls_err("invalid param");
555 		qdf_mem_free(delete_all_peers_ind);
556 		return QDF_STATUS_E_INVAL;
557 	}
558 
559 	status = tdls_process_reset_all_peers(delete_all_peers_ind->vdev);
560 
561 	wlan_objmgr_vdev_release_ref(delete_all_peers_ind->vdev,
562 				     WLAN_TDLS_SB_ID);
563 	qdf_mem_free(delete_all_peers_ind);
564 
565 	return status;
566 }
567 
568 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
569 QDF_STATUS tdls_handle_start_bss(struct wlan_objmgr_psoc *psoc)
570 {
571 	struct wlan_objmgr_vdev *tdls_vdev;
572 
573 	tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
574 	if (!tdls_vdev) {
575 		tdls_err("Unable get the tdls vdev");
576 		return QDF_STATUS_E_FAILURE;
577 	}
578 
579 	tdls_set_tdls_offchannelmode(tdls_vdev, DISABLE_ACTIVE_CHANSWITCH);
580 	wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
581 
582 	return QDF_STATUS_SUCCESS;
583 }
584 #endif
585 
586 static void tdls_handle_link_unforce(struct wlan_objmgr_vdev *vdev)
587 {
588 	struct tdls_action_frame_request req = {0};
589 
590 	req.vdev = vdev;
591 	req.tdls_mgmt.frame_type = TDLS_MAX_ACTION_CODE;
592 
593 	tdls_debug("set vdev %d unforce", wlan_vdev_get_id(vdev));
594 	tdls_set_link_mode(&req);
595 }
596 
597 QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg)
598 {
599 	QDF_STATUS status = QDF_STATUS_SUCCESS;
600 
601 	if (!msg || !msg->bodyptr) {
602 		tdls_err("msg: 0x%pK", msg);
603 		QDF_ASSERT(0);
604 		return QDF_STATUS_E_NULL_VALUE;
605 	}
606 	tdls_debug("TDLS process command: %s(%d)",
607 		   tdls_get_cmd_type_str(msg->type), msg->type);
608 
609 	switch (msg->type) {
610 	case TDLS_CMD_TX_ACTION:
611 		tdls_process_mgmt_req(msg->bodyptr);
612 		break;
613 	case TDLS_CMD_ADD_STA:
614 		tdls_process_add_peer(msg->bodyptr);
615 		break;
616 	case TDLS_CMD_CHANGE_STA:
617 		tdls_process_update_peer(msg->bodyptr);
618 		break;
619 	case TDLS_CMD_ENABLE_LINK:
620 		tdls_process_enable_link(msg->bodyptr);
621 		break;
622 	case TDLS_CMD_DISABLE_LINK:
623 		tdls_process_del_peer(msg->bodyptr);
624 		break;
625 	case TDLS_CMD_CONFIG_FORCE_PEER:
626 		tdls_process_setup_peer(msg->bodyptr);
627 		break;
628 	case TDLS_CMD_REMOVE_FORCE_PEER:
629 		tdls_process_remove_force_peer(msg->bodyptr);
630 		break;
631 	case TDLS_CMD_STATS_UPDATE:
632 		break;
633 	case TDLS_CMD_CONFIG_UPDATE:
634 		break;
635 	case TDLS_CMD_SET_RESPONDER:
636 		tdls_set_responder(msg->bodyptr);
637 		break;
638 	case TDLS_CMD_SCAN_DONE:
639 		tdls_scan_done_callback(msg->bodyptr);
640 		break;
641 	case TDLS_NOTIFY_STA_CONNECTION:
642 		tdls_notify_sta_connect(msg->bodyptr);
643 		break;
644 	case TDLS_NOTIFY_STA_DISCONNECTION:
645 		tdls_notify_sta_disconnect(msg->bodyptr);
646 		break;
647 	case TDLS_CMD_SET_TDLS_MODE:
648 		tdls_set_operation_mode(msg->bodyptr);
649 		break;
650 	case TDLS_CMD_SESSION_DECREMENT:
651 		tdls_process_decrement_active_session(msg->bodyptr);
652 		break;
653 	case TDLS_CMD_SESSION_INCREMENT:
654 		tdls_process_policy_mgr_notification(msg->bodyptr);
655 		break;
656 	case TDLS_CMD_TEARDOWN_LINKS:
657 		tdls_teardown_connections(msg->bodyptr);
658 		break;
659 	case TDLS_NOTIFY_RESET_ADAPTERS:
660 		tdls_notify_reset_adapter(msg->bodyptr);
661 		break;
662 	case TDLS_CMD_ANTENNA_SWITCH:
663 		tdls_process_antenna_switch(msg->bodyptr);
664 		break;
665 	case TDLS_CMD_GET_ALL_PEERS:
666 		tdls_get_all_peers_from_list(msg->bodyptr);
667 		break;
668 	case TDLS_CMD_SET_OFFCHANNEL:
669 		tdls_process_set_offchannel(msg->bodyptr);
670 		break;
671 	case TDLS_CMD_SET_OFFCHANMODE:
672 		tdls_process_set_offchan_mode(msg->bodyptr);
673 		break;
674 	case TDLS_CMD_SET_SECOFFCHANOFFSET:
675 		tdls_process_set_secoffchanneloffset(msg->bodyptr);
676 		break;
677 	case TDLS_DELETE_ALL_PEERS_INDICATION:
678 		tdls_reset_all_peers(msg->bodyptr);
679 		break;
680 	case TDLS_CMD_START_BSS:
681 		tdls_handle_start_bss(msg->bodyptr);
682 		break;
683 	case TDLS_CMD_SET_LINK_UNFORCE:
684 		tdls_handle_link_unforce(msg->bodyptr);
685 		break;
686 	default:
687 		break;
688 	}
689 
690 	return status;
691 }
692 
693 QDF_STATUS tdls_process_evt(struct scheduler_msg *msg)
694 {
695 	struct wlan_objmgr_vdev *vdev;
696 	struct tdls_event_notify *notify;
697 	struct tdls_event_info *event;
698 
699 	if (!msg || !msg->bodyptr) {
700 		tdls_err("msg is not valid: %pK", msg);
701 		return QDF_STATUS_E_NULL_VALUE;
702 	}
703 	notify = msg->bodyptr;
704 	vdev = notify->vdev;
705 	if (!vdev) {
706 		tdls_err("NULL vdev object");
707 		qdf_mem_free(notify);
708 		return QDF_STATUS_E_NULL_VALUE;
709 	}
710 	event = &notify->event;
711 
712 	tdls_debug("evt type: %s(%d)",
713 		   tdls_get_event_type_str(event->message_type),
714 		   event->message_type);
715 
716 	switch (event->message_type) {
717 	case TDLS_SHOULD_DISCOVER:
718 		tdls_process_should_discover(vdev, event);
719 		break;
720 	case TDLS_SHOULD_TEARDOWN:
721 	case TDLS_PEER_DISCONNECTED:
722 		tdls_process_should_teardown(vdev, event);
723 		break;
724 	case TDLS_CONNECTION_TRACKER_NOTIFY:
725 		tdls_process_connection_tracker_notify(vdev, event);
726 		break;
727 	default:
728 		break;
729 	}
730 
731 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
732 	qdf_mem_free(notify);
733 
734 	return QDF_STATUS_SUCCESS;
735 }
736 
737 void tdls_timer_restart(struct wlan_objmgr_vdev *vdev,
738 				 qdf_mc_timer_t *timer,
739 				 uint32_t expiration_time)
740 {
741 	if (QDF_TIMER_STATE_RUNNING !=
742 	    qdf_mc_timer_get_current_state(timer))
743 		qdf_mc_timer_start(timer, expiration_time);
744 }
745 
746 /**
747  * tdls_monitor_timers_stop() - stop all monitoring timers
748  * @tdls_vdev: TDLS vdev object
749  *
750  * Return: none
751  */
752 static void tdls_monitor_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev)
753 {
754 	if (!wlan_vdev_mlme_is_mlo_vdev(tdls_vdev->vdev))
755 		qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer);
756 }
757 
758 /**
759  * tdls_peer_idle_timers_stop() - stop peer idle timers
760  * @tdls_vdev: TDLS vdev object
761  *
762  * Loop through the idle peer list and stop their timers
763  *
764  * Return: None
765  */
766 static void tdls_peer_idle_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev)
767 {
768 	int i;
769 	qdf_list_t *head;
770 	qdf_list_node_t *p_node;
771 	struct tdls_peer *curr_peer;
772 	QDF_STATUS status;
773 
774 	tdls_vdev->discovery_peer_cnt = 0;
775 
776 	for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
777 		head = &tdls_vdev->peer_list[i];
778 		status = qdf_list_peek_front(head, &p_node);
779 		while (QDF_IS_STATUS_SUCCESS(status)) {
780 			curr_peer = qdf_container_of(p_node, struct tdls_peer,
781 						     node);
782 			if (curr_peer->is_peer_idle_timer_initialised)
783 				qdf_mc_timer_stop(&curr_peer->peer_idle_timer);
784 			status = qdf_list_peek_next(head, p_node, &p_node);
785 		}
786 	}
787 
788 }
789 
790 /**
791  * tdls_ct_timers_stop() - stop tdls connection tracker timers
792  * @tdls_vdev: TDLS vdev
793  *
794  * Return: None
795  */
796 static void tdls_ct_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev)
797 {
798 	qdf_mc_timer_stop(&tdls_vdev->peer_update_timer);
799 	tdls_peer_idle_timers_stop(tdls_vdev);
800 }
801 
802 /**
803  * tdls_timers_stop() - stop all the tdls timers running
804  * @tdls_vdev: TDLS vdev
805  *
806  * Return: none
807  */
808 void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev)
809 {
810 	tdls_monitor_timers_stop(tdls_vdev);
811 	tdls_ct_timers_stop(tdls_vdev);
812 }
813 
814 QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev,
815 				   struct tdls_vdev_priv_obj **tdls_vdev_obj,
816 				   struct tdls_soc_priv_obj **tdls_soc_obj)
817 {
818 	enum QDF_OPMODE device_mode;
819 
820 	if (!vdev)
821 		return QDF_STATUS_E_FAILURE;
822 
823 	*tdls_vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev);
824 	if (NULL == (*tdls_vdev_obj))
825 		return QDF_STATUS_E_FAILURE;
826 
827 	*tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev);
828 	if (NULL == (*tdls_soc_obj))
829 		return QDF_STATUS_E_FAILURE;
830 
831 	device_mode = wlan_vdev_mlme_get_opmode(vdev);
832 
833 	if (device_mode != QDF_STA_MODE &&
834 	    device_mode != QDF_P2P_CLIENT_MODE)
835 		return QDF_STATUS_E_FAILURE;
836 
837 	return QDF_STATUS_SUCCESS;
838 }
839 
840 #ifdef WLAN_FEATURE_11AX
841 uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev,
842 					qdf_freq_t freq,
843 					enum supported_6g_pwr_types pwr_typ)
844 {
845 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
846 	struct regulatory_channel *chan;
847 	uint8_t chn_idx, num_chan;
848 	uint8_t band_mask = BIT(REG_BAND_6G);
849 	uint32_t tx_power = 0;
850 
851 	if (!pdev)
852 		return 0;
853 
854 	/* No power check is required for non 6 Ghz channel */
855 	if (!wlan_reg_is_6ghz_chan_freq(freq))
856 		return 0;
857 
858 	chan = qdf_mem_malloc(sizeof(struct regulatory_channel) * NUM_CHANNELS);
859 	if (!chan)
860 		return 0;
861 
862 	num_chan = wlan_reg_get_band_channel_list_for_pwrmode(pdev,
863 							      band_mask,
864 							      chan,
865 							      REG_CLI_DEF_VLP);
866 
867 	for (chn_idx = 0; chn_idx < num_chan; chn_idx++) {
868 		if (chan[chn_idx].center_freq == freq) {
869 			tdls_debug("VLP power for channel %d is %d",
870 				   chan[chn_idx].center_freq,
871 				   chan[chn_idx].tx_power);
872 			tx_power = chan[chn_idx].tx_power;
873 		}
874 	}
875 
876 	qdf_mem_free(chan);
877 	return tx_power;
878 }
879 
880 bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
881 			     qdf_freq_t freq)
882 {
883 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
884 	struct regulatory_channel *chan;
885 	bool is_allowed = false;
886 	uint8_t country_code[REG_ALPHA2_LEN + 1];
887 	uint8_t chn_idx, num_chan = 0;
888 	uint8_t band_mask = BIT(REG_BAND_6G);
889 
890 	/* Return if freq is not 6 Ghz freq */
891 	if (!wlan_reg_is_6ghz_chan_freq(freq))
892 		return false;
893 
894 	if (!wlan_cfg80211_tdls_is_fw_6ghz_capable(vdev))
895 		return false;
896 
897 	if (!pdev)
898 		return false;
899 
900 	wlan_cm_get_country_code(pdev, wlan_vdev_get_id(vdev), country_code);
901 	if (!wlan_reg_ctry_support_vlp(country_code))
902 		return false;
903 
904 	chan = qdf_mem_malloc(sizeof(struct regulatory_channel) * NUM_CHANNELS);
905 	if (!chan)
906 		return false;
907 
908 	num_chan = wlan_reg_get_band_channel_list_for_pwrmode(pdev,
909 							      band_mask,
910 							      chan,
911 							      REG_CLI_DEF_VLP);
912 	tdls_debug("Country IE:%c%c freq %d num_chan %d", country_code[0],
913 			   country_code[1], freq, num_chan);
914 	if (!num_chan)
915 		goto error;
916 
917 	for (chn_idx = 0; chn_idx < num_chan; chn_idx++) {
918 		if (chan[chn_idx].center_freq == freq) {
919 			tdls_debug("TDLS 6ghz freq: %d supports VLP power",
920 				   chan[chn_idx].center_freq);
921 			is_allowed = true;
922 			break;
923 		}
924 	}
925 
926 error:
927 	qdf_mem_free(chan);
928 	return is_allowed;
929 }
930 #else
931 bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
932 				    qdf_freq_t freq)
933 {
934 	return false;
935 }
936 
937 uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev,
938 					qdf_freq_t freq,
939 					enum supported_6g_pwr_types pwr_typ)
940 {
941 	return 0;
942 }
943 #endif
944 
945 bool tdls_check_is_user_tdls_enable(struct tdls_soc_priv_obj *tdls_soc_obj)
946 {
947 	return tdls_soc_obj->is_user_tdls_enable;
948 }
949 
950 bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev)
951 {
952 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
953 	struct tdls_soc_priv_obj *tdls_soc_obj;
954 	bool state = false;
955 	qdf_freq_t ch_freq;
956 	QDF_STATUS status;
957 	uint32_t connection_count;
958 	uint8_t sta_count, p2p_cli_count;
959 
960 	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
961 	if (QDF_IS_STATUS_ERROR(status))
962 		return state;
963 
964 	status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
965 	if (QDF_IS_STATUS_ERROR(status)) {
966 		tdls_err("Failed to get TDLS objects");
967 		goto exit;
968 	}
969 
970 	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
971 	    !wlan_tdls_is_fw_11be_mlo_capable(tdls_soc_obj->soc)) {
972 		tdls_debug("TDLS not supported on MLO vdev");
973 		goto exit;
974 	}
975 
976 	if (wlan_nan_is_disc_active(tdls_soc_obj->soc)) {
977 		tdls_err("NAN active. NAN+TDLS not supported");
978 		goto exit;
979 	}
980 
981 	if (!tdls_check_is_user_tdls_enable(tdls_soc_obj)) {
982 		tdls_err("TDLS Disabled from userspace");
983 		goto exit;
984 	}
985 
986 	connection_count =
987 		policy_mgr_get_connection_count_with_mlo(tdls_soc_obj->soc);
988 	sta_count =
989 		policy_mgr_mode_specific_connection_count(tdls_soc_obj->soc,
990 							  PM_STA_MODE, NULL);
991 	p2p_cli_count =
992 		policy_mgr_mode_specific_connection_count(tdls_soc_obj->soc,
993 							  PM_P2P_CLIENT_MODE,
994 							  NULL);
995 	if ((connection_count == 1 && (sta_count || p2p_cli_count)) ||
996 	    (connection_count > 1 &&
997 	     tdls_is_concurrency_allowed(tdls_soc_obj->soc))) {
998 		state = true;
999 	} else {
1000 		tdls_warn("vdev:%d Concurrent sessions exist disable TDLS",
1001 			  wlan_vdev_get_id(vdev));
1002 		state = false;
1003 		goto exit;
1004 	}
1005 
1006 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE && sta_count) {
1007 		tdls_warn("vdev:%d Concurrent STA exists. TDLS not allowed for P2P vdev",
1008 			  wlan_vdev_get_id(vdev));
1009 		state = false;
1010 		goto exit;
1011 	}
1012 
1013 	ch_freq = wlan_get_operation_chan_freq(vdev);
1014 	if (wlan_reg_is_6ghz_chan_freq(ch_freq) &&
1015 	    !tdls_is_6g_freq_allowed(vdev, ch_freq)) {
1016 		tdls_debug("6GHz freq:%d not allowed for TDLS", ch_freq);
1017 		state = false;
1018 	}
1019 
1020 exit:
1021 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1022 
1023 	return state;
1024 }
1025 
1026 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
1027 bool tdls_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc)
1028 {
1029 	if (!wlan_psoc_nif_fw_ext2_cap_get(psoc,
1030 					   WLAN_TDLS_CONCURRENCIES_SUPPORT)) {
1031 		tdls_debug("fw cap is not advertised");
1032 		return false;
1033 	}
1034 
1035 	if (policy_mgr_get_connection_count_with_mlo(psoc) >
1036 	    WLAN_TDLS_MAX_CONCURRENT_VDEV_SUPPORTED)
1037 		return false;
1038 
1039 	if (policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1040 						      NULL) > 1) {
1041 		tdls_debug("More than one STA exist. Don't allow TDLS");
1042 		return false;
1043 	}
1044 
1045 	if (policy_mgr_is_mcc_on_any_sta_vdev(psoc)) {
1046 		tdls_debug("Base channel MCC. Don't allow TDLS");
1047 		return false;
1048 	}
1049 
1050 	/*
1051 	 * Don't enable TDLS for P2P_CLI in concurrency cases
1052 	 */
1053 	if (policy_mgr_get_connection_count_with_mlo(psoc) > 1 &&
1054 	    !policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1055 						       NULL))
1056 		return false;
1057 
1058 	return true;
1059 }
1060 #endif
1061 
1062 void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc,
1063 		      struct wlan_objmgr_vdev *vdev)
1064 {
1065 	struct tdls_soc_priv_obj *tdls_soc_obj;
1066 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
1067 	uint32_t tdls_feature_flags = 0, sta_count, p2p_count;
1068 	bool state = false;
1069 	bool tdls_mlo;
1070 	QDF_STATUS status;
1071 
1072 	if (!tdls_check_is_tdls_allowed(vdev))
1073 		return;
1074 
1075 	status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
1076 	if (QDF_IS_STATUS_ERROR(status)) {
1077 		tdls_err("Failed to get TDLS objects");
1078 		return;
1079 	}
1080 
1081 	qdf_atomic_set(&tdls_soc_obj->timer_cnt, 0);
1082 	tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags;
1083 	if (TDLS_SUPPORT_DISABLED == tdls_soc_obj->tdls_current_mode ||
1084 	    TDLS_SUPPORT_SUSPENDED == tdls_soc_obj->tdls_current_mode ||
1085 	    !TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) {
1086 		state = false;
1087 		goto set_state;
1088 	}
1089 
1090 	sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1091 							      NULL);
1092 	p2p_count =
1093 		policy_mgr_mode_specific_connection_count(psoc,
1094 							  PM_P2P_CLIENT_MODE,
1095 							  NULL);
1096 	tdls_mlo = wlan_tdls_is_fw_11be_mlo_capable(psoc);
1097 	if (sta_count == 1 || (sta_count >= 2 && tdls_mlo) ||
1098 	    (policy_mgr_get_connection_count_with_mlo(psoc) == 1 &&
1099 	     p2p_count == 1)) {
1100 		state = true;
1101 		/*
1102 		 * In case of TDLS external control, peer should be added
1103 		 * by the user space to start connection tracker.
1104 		 */
1105 		if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags) &&
1106 		    !tdls_soc_obj->tdls_external_peer_count)
1107 			state = false;
1108 
1109 		goto set_state;
1110 	}
1111 
1112 	state = false;
1113 
1114 set_state:
1115 	tdls_soc_obj->enable_tdls_connection_tracker = state;
1116 	if (tdls_soc_obj->enable_tdls_connection_tracker)
1117 		tdls_implicit_enable(tdls_vdev_obj);
1118 	else
1119 		tdls_implicit_disable(tdls_vdev_obj);
1120 
1121 	tdls_debug("vdev:%d enable_tdls_connection_tracker %d current_mode:%d feature_flags:0x%x",
1122 		   wlan_vdev_get_id(vdev),
1123 		   tdls_soc_obj->enable_tdls_connection_tracker,
1124 		   tdls_soc_obj->tdls_current_mode, tdls_feature_flags);
1125 }
1126 
1127 void tdls_set_user_tdls_enable(struct wlan_objmgr_vdev *vdev,
1128 			       bool is_user_tdls_enable)
1129 {
1130 	QDF_STATUS status;
1131 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
1132 	struct tdls_soc_priv_obj *tdls_soc_obj;
1133 
1134 	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
1135 	if (QDF_IS_STATUS_ERROR(status))
1136 		return;
1137 
1138 	status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
1139 	if (QDF_IS_STATUS_ERROR(status)) {
1140 		tdls_err("Failed to get TDLS objects");
1141 		goto exit;
1142 	}
1143 
1144 	tdls_soc_obj->is_user_tdls_enable = is_user_tdls_enable;
1145 	tdls_debug("TDLS enable:%d via userspace",
1146 		   tdls_soc_obj->is_user_tdls_enable);
1147 
1148 exit:
1149 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1150 }
1151 
1152 QDF_STATUS
1153 tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc)
1154 {
1155 	struct wlan_objmgr_vdev *tdls_vdev;
1156 	struct tdls_vdev_priv_obj *tdls_priv_vdev;
1157 	struct tdls_soc_priv_obj *tdls_priv_soc;
1158 	QDF_STATUS status;
1159 
1160 	if (!psoc) {
1161 		tdls_err("psoc is NULL");
1162 		return QDF_STATUS_E_NULL_VALUE;
1163 	}
1164 
1165 	tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
1166 	if (!tdls_vdev) {
1167 		tdls_debug("No TDLS vdev");
1168 		return QDF_STATUS_E_NULL_VALUE;
1169 	}
1170 
1171 	status = tdls_get_vdev_objects(tdls_vdev, &tdls_priv_vdev,
1172 				       &tdls_priv_soc);
1173 	if (QDF_IS_STATUS_ERROR(status)) {
1174 		tdls_debug("TDLS vdev objects NULL");
1175 		wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
1176 		return QDF_STATUS_E_NULL_VALUE;
1177 	}
1178 
1179 	if (!tdls_check_is_tdls_allowed(tdls_vdev)) {
1180 		tdls_disable_offchan_and_teardown_links(tdls_vdev);
1181 		tdls_debug("Disable the tdls in FW due to concurrency");
1182 		wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
1183 		return QDF_STATUS_E_NULL_VALUE;
1184 	}
1185 
1186 	tdls_debug("vdev:%d enter", wlan_vdev_get_id(tdls_vdev));
1187 
1188 	tdls_set_tdls_offchannelmode(tdls_vdev, ENABLE_CHANSWITCH);
1189 	tdls_set_ct_mode(psoc, tdls_vdev);
1190 
1191 	wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
1192 	tdls_debug("exit ");
1193 
1194 	return QDF_STATUS_SUCCESS;
1195 }
1196 
1197 QDF_STATUS
1198 tdls_process_decrement_active_session(struct wlan_objmgr_psoc *psoc)
1199 {
1200 	struct tdls_soc_priv_obj *tdls_priv_soc;
1201 	struct tdls_vdev_priv_obj *tdls_priv_vdev;
1202 	struct wlan_objmgr_vdev *tdls_obj_vdev;
1203 	uint8_t vdev_id;
1204 	QDF_STATUS status;
1205 
1206 	tdls_debug("Enter");
1207 	if (!psoc)
1208 		return QDF_STATUS_E_NULL_VALUE;
1209 
1210 	if(!policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
1211 	   !policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G) &&
1212 	   policy_mgr_is_current_hwmode_dbs(psoc)) {
1213 		tdls_debug("Current HW mode is 1*1 DBS. Wait for Opportunistic timer to expire to enable TDLS in FW");
1214 		return QDF_STATUS_SUCCESS;
1215 	}
1216 
1217 	tdls_obj_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
1218 	if (!tdls_obj_vdev)
1219 		return QDF_STATUS_E_FAILURE;
1220 
1221 	if (!tdls_check_is_tdls_allowed(tdls_obj_vdev))
1222 		goto release_ref;
1223 
1224 	/*
1225 	 * 2 Port MCC -> 1 port scenario or
1226 	 * 3 Port MCC -> 2 port SCC scenario or
1227 	 * 4 Port -> 3 Port SCC scenario
1228 	 * So enable TDLS in firmware
1229 	 */
1230 	tdls_debug("Enable TDLS in FW and host as active sta/p2p_cli interface is present");
1231 	vdev_id = wlan_vdev_get_id(tdls_obj_vdev);
1232 	status = tdls_get_vdev_objects(tdls_obj_vdev, &tdls_priv_vdev,
1233 				       &tdls_priv_soc);
1234 	if (QDF_IS_STATUS_ERROR(status))
1235 		goto release_ref;
1236 
1237 	tdls_send_update_to_fw(tdls_priv_vdev, tdls_priv_soc,
1238 			       mlme_get_tdls_prohibited(tdls_obj_vdev),
1239 			       mlme_get_tdls_chan_switch_prohibited(tdls_obj_vdev),
1240 			       true, vdev_id);
1241 	if (tdls_priv_soc->connected_peer_count == 1)
1242 		tdls_set_tdls_offchannelmode(tdls_obj_vdev, ENABLE_CHANSWITCH);
1243 
1244 release_ref:
1245 	wlan_objmgr_vdev_release_ref(tdls_obj_vdev, WLAN_TDLS_NB_ID);
1246 
1247 	return QDF_STATUS_SUCCESS;
1248 }
1249 
1250 #ifdef WLAN_FEATURE_11BE_MLO
1251 struct wlan_objmgr_vdev *wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev *vdev,
1252 						uint8_t index,
1253 						wlan_objmgr_ref_dbgid dbg_id)
1254 {
1255 	struct wlan_mlo_dev_context *mlo_dev_ctx;
1256 	struct wlan_objmgr_vdev *mlo_vdev;
1257 
1258 	if (!vdev)
1259 		return NULL;
1260 
1261 	mlo_dev_ctx = vdev->mlo_dev_ctx;
1262 	if (!mlo_dev_ctx)
1263 		return NULL;
1264 
1265 	mlo_vdev = mlo_dev_ctx->wlan_vdev_list[index];
1266 	if (mlo_vdev &&
1267 	    wlan_objmgr_vdev_try_get_ref(mlo_vdev, dbg_id) ==
1268 							QDF_STATUS_SUCCESS)
1269 		return mlo_vdev;
1270 
1271 	return NULL;
1272 }
1273 
1274 void wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev *vdev,
1275 				wlan_objmgr_ref_dbgid dbg_id)
1276 {
1277 	if (!vdev)
1278 		return;
1279 
1280 	wlan_objmgr_vdev_release_ref(vdev, dbg_id);
1281 }
1282 #else
1283 struct wlan_objmgr_vdev *wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev *vdev,
1284 						uint8_t index,
1285 						wlan_objmgr_ref_dbgid dbg_id)
1286 {
1287 	return NULL;
1288 }
1289 
1290 void wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev *vdev,
1291 				wlan_objmgr_ref_dbgid dbg_id)
1292 {
1293 }
1294 #endif
1295 /**
1296  * tdls_get_vdev() - Get tdls specific vdev object manager
1297  * @psoc: wlan psoc object manager
1298  * @dbg_id: debug id
1299  *
1300  * If TDLS possible, return the corresponding vdev
1301  * to enable TDLS in the system.
1302  *
1303  * Return: vdev manager pointer or NULL.
1304  */
1305 struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc,
1306 					  wlan_objmgr_ref_dbgid dbg_id)
1307 {
1308 	uint32_t vdev_id;
1309 
1310 	vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_STA_MODE);
1311 	if (WLAN_INVALID_VDEV_ID != vdev_id)
1312 		return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1313 							    dbg_id);
1314 	/*
1315 	 * For P2P_Client mode, TDLS is not supported on concurrency
1316 	 * so return P2P_client vdev only if P2P client mode exists without
1317 	 * any concurreny
1318 	 */
1319 	vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_P2P_CLIENT_MODE);
1320 	if (WLAN_INVALID_VDEV_ID != vdev_id &&
1321 	    policy_mgr_get_connection_count_with_mlo(psoc) == 1)
1322 		return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1323 							    dbg_id);
1324 
1325 	return NULL;
1326 }
1327 
1328 static QDF_STATUS tdls_post_msg_flush_cb(struct scheduler_msg *msg)
1329 {
1330 	void *ptr = msg->bodyptr;
1331 	struct wlan_objmgr_vdev *vdev = NULL;
1332 
1333 	switch (msg->type) {
1334 	case TDLS_NOTIFY_STA_DISCONNECTION:
1335 		vdev = ((struct tdls_sta_notify_params *)ptr)->vdev;
1336 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1337 		qdf_mem_free(ptr);
1338 		break;
1339 
1340 	case TDLS_DELETE_ALL_PEERS_INDICATION:
1341 		vdev = ((struct tdls_delete_all_peers_params *)ptr)->vdev;
1342 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
1343 		qdf_mem_free(ptr);
1344 		break;
1345 
1346 	case TDLS_CMD_SCAN_DONE:
1347 	case TDLS_CMD_SESSION_INCREMENT:
1348 	case TDLS_CMD_SESSION_DECREMENT:
1349 		break;
1350 	}
1351 
1352 	return QDF_STATUS_SUCCESS;
1353 }
1354 
1355 /**
1356  * tdls_process_session_update() - update session count information
1357  * @psoc: soc object
1358  * @cmd_type: type of command
1359  *
1360  * update the session information in connection tracker
1361  *
1362  * Return: None
1363  */
1364 static void tdls_process_session_update(struct wlan_objmgr_psoc *psoc,
1365 				 enum tdls_command_type cmd_type)
1366 {
1367 	struct scheduler_msg msg = {0};
1368 	QDF_STATUS status;
1369 
1370 	msg.bodyptr = psoc;
1371 	msg.callback = tdls_process_cmd;
1372 	msg.flush_callback = tdls_post_msg_flush_cb;
1373 	msg.type = (uint16_t)cmd_type;
1374 
1375 	status = scheduler_post_message(QDF_MODULE_ID_TDLS,
1376 					QDF_MODULE_ID_TDLS,
1377 					QDF_MODULE_ID_OS_IF, &msg);
1378 	if (QDF_IS_STATUS_ERROR(status))
1379 		tdls_alert("message post failed ");
1380 }
1381 
1382 void tdls_notify_increment_session(struct wlan_objmgr_psoc *psoc)
1383 {
1384 	tdls_process_session_update(psoc, TDLS_CMD_SESSION_INCREMENT);
1385 }
1386 
1387 void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc)
1388 {
1389 	tdls_process_session_update(psoc, TDLS_CMD_SESSION_DECREMENT);
1390 }
1391 
1392 void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj,
1393 			    struct tdls_soc_priv_obj *tdls_soc_obj,
1394 			    bool tdls_prohibited,
1395 			    bool tdls_chan_swit_prohibited,
1396 			    bool sta_connect_event,
1397 			    uint8_t session_id)
1398 {
1399 	struct tdls_info *tdls_info_to_fw;
1400 	struct tdls_config_params *threshold_params;
1401 	uint32_t tdls_feature_flags;
1402 	QDF_STATUS status;
1403 	bool tdls_mlo;
1404 
1405 	tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags;
1406 	if (!TDLS_IS_ENABLED(tdls_feature_flags)) {
1407 		tdls_debug("TDLS mode is not enabled");
1408 		return;
1409 	}
1410 
1411 	tdls_mlo = wlan_tdls_is_fw_11be_mlo_capable(tdls_soc_obj->soc);
1412 
1413 	/* If AP or caller indicated TDLS Prohibited then disable tdls mode */
1414 	if (sta_connect_event) {
1415 		if (tdls_prohibited) {
1416 			tdls_soc_obj->tdls_current_mode =
1417 					TDLS_SUPPORT_DISABLED;
1418 		} else {
1419 			if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags))
1420 				tdls_soc_obj->tdls_current_mode =
1421 					TDLS_SUPPORT_EXP_TRIG_ONLY;
1422 			else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(
1423 				tdls_feature_flags))
1424 				tdls_soc_obj->tdls_current_mode =
1425 					TDLS_SUPPORT_EXT_CONTROL;
1426 			else
1427 				tdls_soc_obj->tdls_current_mode =
1428 					TDLS_SUPPORT_IMP_MODE;
1429 		}
1430 	} else {
1431 		tdls_soc_obj->tdls_current_mode =
1432 				TDLS_SUPPORT_DISABLED;
1433 	}
1434 
1435 	tdls_info_to_fw = qdf_mem_malloc(sizeof(struct tdls_info));
1436 	if (!tdls_info_to_fw)
1437 		return;
1438 
1439 	threshold_params = &tdls_vdev_obj->threshold_config;
1440 
1441 	tdls_info_to_fw->notification_interval_ms =
1442 		threshold_params->tx_period_t;
1443 	tdls_info_to_fw->tx_discovery_threshold =
1444 		threshold_params->tx_packet_n;
1445 	tdls_info_to_fw->tx_teardown_threshold =
1446 		threshold_params->idle_packet_n;
1447 	tdls_info_to_fw->rssi_teardown_threshold =
1448 		threshold_params->rssi_teardown_threshold;
1449 	tdls_info_to_fw->rssi_delta = threshold_params->rssi_delta;
1450 	tdls_info_to_fw->vdev_id = session_id;
1451 
1452 	/* record the session id in vdev context */
1453 	tdls_vdev_obj->session_id = session_id;
1454 	tdls_info_to_fw->tdls_state = tdls_soc_obj->tdls_current_mode;
1455 	tdls_info_to_fw->tdls_options = 0;
1456 
1457 	/*
1458 	 * Do not enable TDLS offchannel, if AP prohibited TDLS
1459 	 * channel switch
1460 	 */
1461 	if (TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) &&
1462 	    (!tdls_chan_swit_prohibited))
1463 		tdls_info_to_fw->tdls_options = ENA_TDLS_OFFCHAN;
1464 
1465 	if (TDLS_IS_BUFFER_STA_ENABLED(tdls_feature_flags))
1466 		tdls_info_to_fw->tdls_options |= ENA_TDLS_BUFFER_STA;
1467 	if (TDLS_IS_SLEEP_STA_ENABLED(tdls_feature_flags))
1468 		tdls_info_to_fw->tdls_options |=  ENA_TDLS_SLEEP_STA;
1469 
1470 
1471 	tdls_info_to_fw->peer_traffic_ind_window =
1472 		tdls_soc_obj->tdls_configs.tdls_uapsd_pti_window;
1473 	tdls_info_to_fw->peer_traffic_response_timeout =
1474 		tdls_soc_obj->tdls_configs.tdls_uapsd_ptr_timeout;
1475 	tdls_info_to_fw->puapsd_mask =
1476 		tdls_soc_obj->tdls_configs.tdls_uapsd_mask;
1477 	tdls_info_to_fw->puapsd_inactivity_time =
1478 		tdls_soc_obj->tdls_configs.tdls_uapsd_inactivity_time;
1479 	tdls_info_to_fw->puapsd_rx_frame_threshold =
1480 		tdls_soc_obj->tdls_configs.tdls_rx_pkt_threshold;
1481 	tdls_info_to_fw->teardown_notification_ms =
1482 		tdls_soc_obj->tdls_configs.tdls_idle_timeout;
1483 	tdls_info_to_fw->tdls_peer_kickout_threshold =
1484 		tdls_soc_obj->tdls_configs.tdls_peer_kickout_threshold;
1485 	tdls_info_to_fw->tdls_discovery_wake_timeout =
1486 		tdls_soc_obj->tdls_configs.tdls_discovery_wake_timeout;
1487 
1488 	status = tgt_tdls_set_fw_state(tdls_soc_obj->soc, tdls_info_to_fw);
1489 	if (QDF_IS_STATUS_ERROR(status))
1490 		goto done;
1491 
1492 	if (sta_connect_event) {
1493 		tdls_soc_obj->set_state_info.vdev_id = session_id;
1494 	}
1495 
1496 	tdls_debug("FW tdls state sent for vdev id %d", session_id);
1497 done:
1498 	qdf_mem_free(tdls_info_to_fw);
1499 	return;
1500 }
1501 
1502 void tdls_process_enable_for_vdev(struct wlan_objmgr_vdev *vdev)
1503 {
1504 	struct wlan_objmgr_psoc *psoc;
1505 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
1506 	struct tdls_soc_priv_obj *tdls_soc_obj;
1507 	enum QDF_OPMODE opmode;
1508 	QDF_STATUS status;
1509 	uint8_t sta_count;
1510 
1511 	psoc = wlan_vdev_get_psoc(vdev);
1512 	if (!psoc)
1513 		return;
1514 
1515 	sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1516 							      NULL);
1517 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1518 	if (opmode == QDF_P2P_CLIENT_MODE && sta_count) {
1519 		tdls_debug("STA + P2P concurrency. Don't allow TDLS on P2P vdev:%d",
1520 			   wlan_vdev_get_id(vdev));
1521 		return;
1522 	}
1523 
1524 	status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
1525 	if (QDF_IS_STATUS_ERROR(status))
1526 		return;
1527 
1528 	tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj,
1529 			       mlme_get_tdls_prohibited(vdev),
1530 			       mlme_get_tdls_chan_switch_prohibited(vdev),
1531 			       true, wlan_vdev_get_id(vdev));
1532 
1533 	/* check and set the connection tracker */
1534 	tdls_set_ct_mode(tdls_soc_obj->soc, vdev);
1535 }
1536 
1537 static QDF_STATUS
1538 tdls_process_sta_connect(struct tdls_sta_notify_params *notify)
1539 {
1540 	if (!tdls_check_is_tdls_allowed(notify->vdev))
1541 		return QDF_STATUS_E_NOSUPPORT;
1542 
1543 	tdls_process_enable_for_vdev(notify->vdev);
1544 
1545 	return QDF_STATUS_SUCCESS;
1546 }
1547 
1548 QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify)
1549 {
1550 	QDF_STATUS status;
1551 
1552 	if (!notify) {
1553 		tdls_err("invalid param");
1554 		return QDF_STATUS_E_INVAL;
1555 	}
1556 
1557 	if (!notify->vdev) {
1558 		tdls_err("invalid param");
1559 		qdf_mem_free(notify);
1560 		return QDF_STATUS_E_INVAL;
1561 	}
1562 
1563 	status = tdls_process_sta_connect(notify);
1564 
1565 	wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
1566 	qdf_mem_free(notify);
1567 
1568 	return status;
1569 }
1570 
1571 static QDF_STATUS
1572 tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify)
1573 {
1574 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
1575 	struct tdls_soc_priv_obj *tdls_soc_obj;
1576 	struct wlan_objmgr_vdev *temp_vdev = NULL;
1577 	uint8_t vdev_id;
1578 	QDF_STATUS status;
1579 
1580 	status = tdls_get_vdev_objects(notify->vdev, &tdls_vdev_obj,
1581 				       &tdls_soc_obj);
1582 	if (QDF_IS_STATUS_ERROR(status))
1583 		return status;
1584 
1585 	/* if the disconnect comes from user space, we have to delete all the
1586 	 * tdls peers before sending the set state cmd.
1587 	 */
1588 	if (notify->user_disconnect)
1589 		return tdls_delete_all_tdls_peers(notify->vdev, tdls_soc_obj);
1590 
1591 	tdls_debug("Check and update TDLS state for vdev:%d",
1592 		   notify->session_id);
1593 
1594 	/* Disassociation event */
1595 	tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj, false,
1596 			       false, false, notify->session_id);
1597 
1598 	/* If concurrency is not marked, then we have to
1599 	 * check, whether TDLS could be enabled in the
1600 	 * system after this disassoc event.
1601 	 */
1602 	if (notify->lfr_roam)
1603 		return status;
1604 
1605 	temp_vdev = tdls_get_vdev(tdls_soc_obj->soc, WLAN_TDLS_NB_ID);
1606 	if (!temp_vdev)
1607 		return status;
1608 
1609 	vdev_id = wlan_vdev_get_id(temp_vdev);
1610 	status = tdls_get_vdev_objects(temp_vdev, &tdls_vdev_obj,
1611 				       &tdls_soc_obj);
1612 	if (QDF_IS_STATUS_ERROR(status)) {
1613 		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_TDLS_NB_ID);
1614 		return status;
1615 	}
1616 
1617 	tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj,
1618 			       mlme_get_tdls_prohibited(temp_vdev),
1619 			       mlme_get_tdls_chan_switch_prohibited(temp_vdev),
1620 			       true, vdev_id);
1621 
1622 	/* Check and set the connection tracker and implicit timers */
1623 	tdls_set_ct_mode(tdls_soc_obj->soc, temp_vdev);
1624 	wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_TDLS_NB_ID);
1625 
1626 	wlan_vdev_mlme_feat_ext2_cap_clear(notify->vdev,
1627 					   WLAN_VDEV_FEXT2_MLO_STA_TDLS);
1628 
1629 	return status;
1630 }
1631 
1632 QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify)
1633 {
1634 	QDF_STATUS status;
1635 	struct wlan_objmgr_vdev *vdev;
1636 	enum QDF_OPMODE opmode;
1637 	struct wlan_objmgr_psoc *psoc;
1638 	uint8_t sta_count;
1639 
1640 	if (!notify) {
1641 		tdls_err("invalid param");
1642 		return QDF_STATUS_E_INVAL;
1643 	}
1644 
1645 	vdev = notify->vdev;
1646 	if (!vdev) {
1647 		tdls_err("invalid param");
1648 		qdf_mem_free(notify);
1649 		return QDF_STATUS_E_INVAL;
1650 	}
1651 
1652 	psoc = wlan_vdev_get_psoc(vdev);
1653 	if (!psoc) {
1654 		wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
1655 		qdf_mem_free(notify);
1656 		return QDF_STATUS_E_INVAL;
1657 	}
1658 
1659 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1660 	sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1661 							      NULL);
1662 	if (opmode == QDF_P2P_CLIENT_MODE && sta_count) {
1663 		tdls_debug("STA + P2P concurrency. No action on P2P vdev");
1664 		wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
1665 		qdf_mem_free(notify);
1666 		return QDF_STATUS_E_INVAL;
1667 	}
1668 
1669 	status = tdls_process_sta_disconnect(notify);
1670 
1671 	wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
1672 	qdf_mem_free(notify);
1673 
1674 	return status;
1675 }
1676 
1677 static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev)
1678 {
1679 	struct tdls_vdev_priv_obj *tdls_vdev;
1680 
1681 	tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
1682 	if (!tdls_vdev)
1683 		return;
1684 	tdls_timers_stop(tdls_vdev);
1685 }
1686 
1687 void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev)
1688 {
1689 	if (!vdev) {
1690 		QDF_ASSERT(0);
1691 		return;
1692 	}
1693 
1694 	if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev,
1695 						WLAN_TDLS_NB_ID))
1696 		return;
1697 
1698 	tdls_process_reset_adapter(vdev);
1699 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1700 }
1701 
1702 QDF_STATUS tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc,
1703 					   uint8_t vdev_id)
1704 {
1705 	struct scheduler_msg msg = {0, };
1706 	struct tdls_sta_notify_params *notify;
1707 	QDF_STATUS status;
1708 	struct wlan_objmgr_vdev *vdev;
1709 
1710 	notify = qdf_mem_malloc(sizeof(*notify));
1711 	if (!notify)
1712 		return QDF_STATUS_E_NULL_VALUE;
1713 
1714 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
1715 						    vdev_id,
1716 						    WLAN_TDLS_NB_ID);
1717 
1718 	if (!vdev) {
1719 		tdls_err("vdev not exist for the vdev id %d",
1720 			 vdev_id);
1721 		qdf_mem_free(notify);
1722 		return QDF_STATUS_E_INVAL;
1723 	}
1724 
1725 	notify->lfr_roam = true;
1726 	notify->tdls_chan_swit_prohibited = false;
1727 	notify->tdls_prohibited = false;
1728 	notify->session_id = vdev_id;
1729 	notify->vdev = vdev;
1730 	notify->user_disconnect = false;
1731 
1732 	msg.bodyptr = notify;
1733 	msg.callback = tdls_process_cmd;
1734 	msg.flush_callback = tdls_post_msg_flush_cb;
1735 	msg.type = TDLS_NOTIFY_STA_DISCONNECTION;
1736 
1737 	status = scheduler_post_message(QDF_MODULE_ID_TDLS,
1738 					QDF_MODULE_ID_TDLS,
1739 					QDF_MODULE_ID_OS_IF, &msg);
1740 	if (QDF_IS_STATUS_ERROR(status)) {
1741 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1742 		qdf_mem_free(notify);
1743 		tdls_alert("message post failed ");
1744 
1745 		return QDF_STATUS_E_FAILURE;
1746 	}
1747 
1748 	return QDF_STATUS_SUCCESS;
1749 }
1750 
1751 static
1752 QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
1753 					    uint8_t vdev_id)
1754 {
1755 	struct scheduler_msg msg = {0, };
1756 	struct tdls_delete_all_peers_params *indication;
1757 	QDF_STATUS status;
1758 	struct wlan_objmgr_vdev *vdev;
1759 
1760 	indication = qdf_mem_malloc(sizeof(*indication));
1761 	if (!indication)
1762 		return QDF_STATUS_E_NULL_VALUE;
1763 
1764 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1765 						    WLAN_TDLS_SB_ID);
1766 	if (!vdev) {
1767 		tdls_err("vdev:%d does not exist", vdev_id);
1768 		qdf_mem_free(indication);
1769 		return QDF_STATUS_E_INVAL;
1770 	}
1771 
1772 	indication->vdev = vdev;
1773 
1774 	msg.bodyptr = indication;
1775 	msg.callback = tdls_process_cmd;
1776 	msg.type = TDLS_DELETE_ALL_PEERS_INDICATION;
1777 	msg.flush_callback = tdls_post_msg_flush_cb;
1778 
1779 	status = scheduler_post_message(QDF_MODULE_ID_TDLS,
1780 					QDF_MODULE_ID_TDLS,
1781 					QDF_MODULE_ID_OS_IF, &msg);
1782 	if (QDF_IS_STATUS_ERROR(status)) {
1783 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
1784 		qdf_mem_free(indication);
1785 		tdls_alert("message post failed ");
1786 		return QDF_STATUS_E_FAILURE;
1787 	}
1788 
1789 	return QDF_STATUS_SUCCESS;
1790 }
1791 
1792 QDF_STATUS
1793 tdls_check_and_indicate_delete_all_peers(struct wlan_objmgr_psoc *psoc,
1794 					 uint8_t vdev_id)
1795 {
1796 	struct wlan_objmgr_pdev *pdev;
1797 	uint32_t pdev_id;
1798 	enum QDF_OPMODE opmode;
1799 	uint8_t sta_count =
1800 		policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1801 							  NULL);
1802 
1803 	pdev_id = wlan_get_pdev_id_from_vdev_id(psoc, vdev_id, WLAN_TDLS_SB_ID);
1804 	if (pdev_id == WLAN_INVALID_PDEV_ID) {
1805 		tdls_debug("Invalid pdev id");
1806 		return QDF_STATUS_E_INVAL;
1807 	}
1808 
1809 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, WLAN_TDLS_SB_ID);
1810 	if (!pdev) {
1811 		tdls_debug("pdev is NULL");
1812 		return QDF_STATUS_E_INVAL;
1813 	}
1814 
1815 	opmode = wlan_get_opmode_from_vdev_id(pdev, vdev_id);
1816 	wlan_objmgr_pdev_release_ref(pdev, WLAN_TDLS_SB_ID);
1817 
1818 	if (opmode == QDF_P2P_CLIENT_MODE && sta_count) {
1819 		tdls_debug("STA + P2P concurrency. No action on P2P vdev");
1820 		return QDF_STATUS_E_INVAL;
1821 	}
1822 
1823 	return tdls_delete_all_peers_indication(psoc, vdev_id);
1824 }
1825 
1826 /**
1827  * tdls_set_mode_in_vdev() - set TDLS mode
1828  * @tdls_vdev: tdls vdev object
1829  * @tdls_soc: tdls soc object
1830  * @tdls_mode: TDLS mode
1831  * @source: TDLS disable source enum values
1832  *
1833  * Return: Void
1834  */
1835 static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev,
1836 				  struct tdls_soc_priv_obj *tdls_soc,
1837 				  enum tdls_feature_mode tdls_mode,
1838 				  enum tdls_disable_sources source)
1839 {
1840 	tdls_debug("set tdls mode: %d source:%d", tdls_mode,
1841 		   source);
1842 
1843 	switch (tdls_mode) {
1844 	case TDLS_SUPPORT_IMP_MODE:
1845 		fallthrough;
1846 	case TDLS_SUPPORT_EXT_CONTROL:
1847 		clear_bit((unsigned long)source, &tdls_soc->tdls_source_bitmap);
1848 		/*
1849 		 * Check if any TDLS source bit is set and if
1850 		 * bitmap is not zero then we should not enable TDLS
1851 		 */
1852 		if (tdls_soc->tdls_source_bitmap) {
1853 			tdls_notice("Don't enable TDLS, source bitmap: %lu",
1854 				tdls_soc->tdls_source_bitmap);
1855 			return;
1856 		}
1857 		tdls_implicit_enable(tdls_vdev);
1858 		/*
1859 		 * tdls implicit mode is enabled, so enable the connection
1860 		 * tracker
1861 		 */
1862 		tdls_soc->enable_tdls_connection_tracker = true;
1863 
1864 		return;
1865 
1866 	case TDLS_SUPPORT_DISABLED:
1867 		set_bit((unsigned long)source,
1868 			&tdls_soc->tdls_source_bitmap);
1869 		tdls_implicit_disable(tdls_vdev);
1870 		/* If tdls implicit mode is disabled, then
1871 		 * stop the connection tracker.
1872 		 */
1873 		tdls_soc->enable_tdls_connection_tracker = false;
1874 
1875 		return;
1876 
1877 	case TDLS_SUPPORT_EXP_TRIG_ONLY:
1878 		clear_bit((unsigned long)source,
1879 			  &tdls_soc->tdls_source_bitmap);
1880 		tdls_implicit_disable(tdls_vdev);
1881 		/* If tdls implicit mode is disabled, then
1882 		 * stop the connection tracker.
1883 		 */
1884 		tdls_soc->enable_tdls_connection_tracker = false;
1885 
1886 		/*
1887 		 * Check if any TDLS source bit is set and if
1888 		 * bitmap is not zero then we should not
1889 		 * enable TDLS
1890 		 */
1891 		if (tdls_soc->tdls_source_bitmap)
1892 			return;
1893 
1894 		return;
1895 	default:
1896 		return;
1897 	}
1898 }
1899 
1900 /**
1901  * tdls_set_current_mode() - set TDLS mode
1902  * @tdls_soc: tdls soc object
1903  * @tdls_mode: TDLS mode
1904  * @update_last: indicate to record the last tdls mode
1905  * @source: TDLS disable source enum values
1906  *
1907  * Return: Void
1908  */
1909 static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc,
1910 				   enum tdls_feature_mode tdls_mode,
1911 				   bool update_last,
1912 				   enum tdls_disable_sources source)
1913 {
1914 	struct wlan_objmgr_vdev *vdev;
1915 	struct tdls_vdev_priv_obj *tdls_vdev;
1916 
1917 	if (!tdls_soc)
1918 		return;
1919 
1920 	tdls_debug("mode %d", (int)tdls_mode);
1921 
1922 	if (update_last)
1923 		tdls_soc->tdls_last_mode = tdls_mode;
1924 
1925 	if (tdls_soc->tdls_current_mode == tdls_mode) {
1926 		tdls_debug("already in mode %d", tdls_mode);
1927 
1928 		switch (tdls_mode) {
1929 		/* TDLS is already enabled hence clear source mask, return */
1930 		case TDLS_SUPPORT_IMP_MODE:
1931 		case TDLS_SUPPORT_EXP_TRIG_ONLY:
1932 		case TDLS_SUPPORT_EXT_CONTROL:
1933 			clear_bit((unsigned long)source,
1934 				  &tdls_soc->tdls_source_bitmap);
1935 			tdls_debug("clear source mask:%d", source);
1936 			return;
1937 		/* TDLS is already disabled hence set source mask, return */
1938 		case TDLS_SUPPORT_DISABLED:
1939 			set_bit((unsigned long)source,
1940 				&tdls_soc->tdls_source_bitmap);
1941 			tdls_debug("set source mask:%d", source);
1942 			return;
1943 		default:
1944 			return;
1945 		}
1946 	}
1947 
1948 	/* get sta vdev */
1949 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc,
1950 							QDF_STA_MODE,
1951 							WLAN_TDLS_NB_ID);
1952 	if (vdev) {
1953 		tdls_debug("set mode in tdls STA vdev:%d",
1954 			   wlan_vdev_get_id(vdev));
1955 		tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
1956 		if (tdls_vdev)
1957 			tdls_set_mode_in_vdev(tdls_vdev, tdls_soc,
1958 					      tdls_mode, source);
1959 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1960 
1961 		goto exit;
1962 	}
1963 
1964 	/* get p2p client vdev */
1965 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc,
1966 							QDF_P2P_CLIENT_MODE,
1967 							WLAN_TDLS_NB_ID);
1968 	if (vdev) {
1969 		tdls_debug("set mode in tdls P2P cli vdev:%d",
1970 			   wlan_vdev_get_id(vdev));
1971 		tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
1972 		if (tdls_vdev)
1973 			tdls_set_mode_in_vdev(tdls_vdev, tdls_soc,
1974 					      tdls_mode, source);
1975 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1976 	}
1977 
1978 exit:
1979 	if (!update_last)
1980 		tdls_soc->tdls_last_mode = tdls_soc->tdls_current_mode;
1981 
1982 	tdls_soc->tdls_current_mode = tdls_mode;
1983 }
1984 
1985 QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode)
1986 {
1987 	struct tdls_soc_priv_obj *tdls_soc;
1988 	struct tdls_vdev_priv_obj *tdls_vdev;
1989 	QDF_STATUS status;
1990 
1991 	if (!tdls_set_mode)
1992 		return QDF_STATUS_E_INVAL;
1993 
1994 	if (!tdls_set_mode->vdev) {
1995 		qdf_mem_free(tdls_set_mode);
1996 		return QDF_STATUS_E_INVAL;
1997 	}
1998 
1999 	status = tdls_get_vdev_objects(tdls_set_mode->vdev,
2000 				       &tdls_vdev, &tdls_soc);
2001 
2002 	if (QDF_IS_STATUS_ERROR(status))
2003 		goto release_mode_ref;
2004 
2005 	tdls_set_current_mode(tdls_soc,
2006 			      tdls_set_mode->tdls_mode,
2007 			      tdls_set_mode->update_last,
2008 			      tdls_set_mode->source);
2009 
2010 release_mode_ref:
2011 	wlan_objmgr_vdev_release_ref(tdls_set_mode->vdev, WLAN_TDLS_NB_ID);
2012 	qdf_mem_free(tdls_set_mode);
2013 	return status;
2014 }
2015 
2016 /**
2017  * tdls_scan_done_callback() - callback for tdls scan done event
2018  * @tdls_soc: tdls soc object
2019  *
2020  * Return: Void
2021  */
2022 void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc)
2023 {
2024 	if (!tdls_soc)
2025 		return;
2026 
2027 	/* if tdls was enabled before scan, re-enable tdls mode */
2028 	if (TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_last_mode ||
2029 	    TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_last_mode ||
2030 	    TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_last_mode)
2031 		tdls_set_current_mode(tdls_soc, tdls_soc->tdls_last_mode,
2032 				      false, TDLS_SET_MODE_SOURCE_SCAN);
2033 }
2034 
2035 /**
2036  * tdls_post_scan_done_msg() - post scan done message to tdls cmd queue
2037  * @tdls_soc: tdls soc object
2038  *
2039  * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_NULL_VALUE
2040  */
2041 static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc)
2042 {
2043 	struct scheduler_msg msg = {0, };
2044 
2045 	if (!tdls_soc) {
2046 		tdls_err("tdls_soc: %pK ", tdls_soc);
2047 		return QDF_STATUS_E_NULL_VALUE;
2048 	}
2049 
2050 	msg.bodyptr = tdls_soc;
2051 	msg.callback = tdls_process_cmd;
2052 	msg.flush_callback = tdls_post_msg_flush_cb;
2053 	msg.type = TDLS_CMD_SCAN_DONE;
2054 
2055 	return scheduler_post_message(QDF_MODULE_ID_TDLS,
2056 				      QDF_MODULE_ID_TDLS,
2057 				      QDF_MODULE_ID_OS_IF, &msg);
2058 }
2059 
2060 void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev,
2061 			struct scan_event *event,
2062 			void *arg)
2063 {
2064 	enum QDF_OPMODE device_mode;
2065 	struct tdls_soc_priv_obj *tdls_soc;
2066 
2067 	if (!vdev || !event || !arg)
2068 		return;
2069 
2070 	if (SCAN_EVENT_TYPE_COMPLETED != event->type)
2071 		return;
2072 
2073 	device_mode = wlan_vdev_mlme_get_opmode(vdev);
2074 
2075 	tdls_soc = (struct tdls_soc_priv_obj *) arg;
2076 	tdls_post_scan_done_msg(tdls_soc);
2077 }
2078 
2079 void tdls_set_link_unforce(struct wlan_objmgr_vdev *vdev)
2080 {
2081 	QDF_STATUS status;
2082 	struct scheduler_msg msg = {0};
2083 
2084 	msg.callback = tdls_process_cmd;
2085 	msg.type = TDLS_CMD_SET_LINK_UNFORCE;
2086 	msg.bodyptr = vdev;
2087 	status = scheduler_post_message(QDF_MODULE_ID_TDLS,
2088 					QDF_MODULE_ID_TDLS,
2089 					QDF_MODULE_ID_OS_IF, &msg);
2090 	if (QDF_IS_STATUS_ERROR(status))
2091 		tdls_err("failed to set tdls link mode");
2092 }
2093 
2094 /**
2095  * tdls_check_peer_buf_capable() - Check buffer sta capable of tdls peers
2096  * @tdls_vdev: TDLS vdev object
2097  *
2098  * Used in scheduler thread context, no lock needed.
2099  *
2100  * Return: false if there is connected peer and not support buffer sta.
2101  */
2102 static bool tdls_check_peer_buf_capable(struct tdls_vdev_priv_obj *tdls_vdev)
2103 {
2104 	uint16_t i;
2105 	struct tdls_peer *peer;
2106 	qdf_list_t *head;
2107 	qdf_list_node_t *p_node;
2108 	QDF_STATUS status;
2109 
2110 	if (!tdls_vdev) {
2111 		tdls_err("invalid tdls vdev object");
2112 		return false;
2113 	}
2114 
2115 	for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
2116 		head = &tdls_vdev->peer_list[i];
2117 
2118 		status = qdf_list_peek_front(head, &p_node);
2119 		while (QDF_IS_STATUS_SUCCESS(status)) {
2120 			peer = qdf_container_of(p_node, struct tdls_peer, node);
2121 
2122 			if (peer &&
2123 			    (TDLS_LINK_CONNECTED == peer->link_status) &&
2124 			    (!peer->buf_sta_capable))
2125 				return false;
2126 
2127 			status = qdf_list_peek_next(head, p_node, &p_node);
2128 		}
2129 	}
2130 
2131 	return true;
2132 }
2133 
2134 QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc)
2135 {
2136 	struct tdls_vdev_priv_obj *tdls_vdev;
2137 	struct wlan_objmgr_vdev *vdev;
2138 	uint16_t tdls_peer_count;
2139 	uint32_t feature;
2140 	bool peer_buf_capable;
2141 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2142 
2143 	/* if tdls is not enabled, then continue scan */
2144 	if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode)
2145 		return status;
2146 
2147 	/* Get the vdev based on vdev operating mode*/
2148 	vdev = tdls_get_vdev(tdls_soc->soc, WLAN_TDLS_NB_ID);
2149 	if (!vdev)
2150 		return status;
2151 
2152 	tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
2153 	if (!tdls_vdev)
2154 		goto  return_success;
2155 
2156 	if (tdls_is_progress(tdls_vdev, NULL, 0)) {
2157 		if (tdls_soc->scan_reject_count++ >= TDLS_SCAN_REJECT_MAX) {
2158 			tdls_notice("Allow this scan req. as already max no of scan's are rejected");
2159 			tdls_soc->scan_reject_count = 0;
2160 			status = QDF_STATUS_SUCCESS;
2161 
2162 		} else {
2163 			tdls_warn("tdls in progress. scan rejected %d",
2164 				  tdls_soc->scan_reject_count);
2165 			status = QDF_STATUS_E_BUSY;
2166 		}
2167 	}
2168 
2169 	tdls_peer_count = tdls_soc->connected_peer_count;
2170 	if (!tdls_peer_count)
2171 		goto disable_tdls;
2172 
2173 	feature = tdls_soc->tdls_configs.tdls_feature_flags;
2174 	if (TDLS_IS_SCAN_ENABLED(feature)) {
2175 		tdls_debug("TDLS Scan enabled, keep tdls link and allow scan, connected tdls peers: %d",
2176 			   tdls_peer_count);
2177 		goto disable_tdls;
2178 	}
2179 
2180 	if (TDLS_IS_BUFFER_STA_ENABLED(feature) &&
2181 	    (tdls_peer_count <= TDLS_MAX_CONNECTED_PEERS_TO_ALLOW_SCAN)) {
2182 		peer_buf_capable = tdls_check_peer_buf_capable(tdls_vdev);
2183 		if (peer_buf_capable) {
2184 			tdls_debug("All peers (num %d) bufSTAs, we can be sleep sta, so allow scan, tdls mode changed to %d",
2185 				   tdls_peer_count,
2186 				   tdls_soc->tdls_current_mode);
2187 			goto disable_tdls;
2188 		}
2189 	}
2190 
2191 	tdls_disable_offchan_and_teardown_links(vdev);
2192 
2193 disable_tdls:
2194 	tdls_set_current_mode(tdls_soc, TDLS_SUPPORT_DISABLED,
2195 			      false, TDLS_SET_MODE_SOURCE_SCAN);
2196 
2197 return_success:
2198 	wlan_objmgr_vdev_release_ref(vdev,
2199 				     WLAN_TDLS_NB_ID);
2200 	return status;
2201 }
2202 
2203 void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev,
2204 		union wlan_serialization_rules_info *comp_info,
2205 		struct wlan_serialization_command *cmd)
2206 {
2207 	struct tdls_soc_priv_obj *tdls_soc;
2208 	QDF_STATUS status;
2209 	if (!comp_info)
2210 		return;
2211 
2212 	tdls_soc = tdls_soc_global;
2213 	comp_info->scan_info.is_tdls_in_progress = false;
2214 	status = tdls_scan_callback(tdls_soc);
2215 	if (QDF_STATUS_E_BUSY == status)
2216 		comp_info->scan_info.is_tdls_in_progress = true;
2217 }
2218 
2219 static uint8_t tdls_find_opclass_frm_freq(struct wlan_objmgr_vdev *vdev,
2220 				   qdf_freq_t ch_freq, uint8_t bw_offset,
2221 				   uint16_t behav_limit)
2222 {
2223 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
2224 	uint8_t channel, opclass;
2225 
2226 	if (!pdev) {
2227 		tdls_err("pdev is NULL");
2228 		return 0;
2229 	}
2230 
2231 	wlan_reg_freq_width_to_chan_op_class(pdev, ch_freq, bw_offset, false,
2232 					     BIT(behav_limit), &opclass,
2233 					     &channel);
2234 
2235 	return opclass;
2236 }
2237 
2238 uint8_t tdls_get_opclass_from_bandwidth(struct wlan_objmgr_vdev *vdev,
2239 					qdf_freq_t freq, uint8_t bw_offset,
2240 					uint8_t *reg_bw_offset)
2241 {
2242 	uint8_t opclass;
2243 
2244 	if (bw_offset &  (1 << BW_160_OFFSET_BIT)) {
2245 		opclass = tdls_find_opclass_frm_freq(vdev,
2246 						     freq, BW_160_MHZ,
2247 						     BEHAV_NONE);
2248 		*reg_bw_offset = BWALL;
2249 	} else if (bw_offset & (1 << BW_80_OFFSET_BIT)) {
2250 		opclass = tdls_find_opclass_frm_freq(vdev,
2251 						     freq, BW_80_MHZ,
2252 						     BEHAV_NONE);
2253 		*reg_bw_offset = BW80;
2254 	} else if (bw_offset & (1 << BW_40_OFFSET_BIT)) {
2255 		opclass = tdls_find_opclass_frm_freq(vdev,
2256 						     freq, BW_40_MHZ,
2257 						     BEHAV_BW40_LOW_PRIMARY);
2258 		*reg_bw_offset = BW40_LOW_PRIMARY;
2259 		if (!opclass) {
2260 			opclass = tdls_find_opclass_frm_freq(vdev,
2261 						     freq,
2262 						     BW_40_MHZ,
2263 						     BEHAV_BW40_HIGH_PRIMARY);
2264 			*reg_bw_offset = BW40_HIGH_PRIMARY;
2265 		}
2266 	} else if (bw_offset & (1 << BW_20_OFFSET_BIT)) {
2267 		opclass = tdls_find_opclass_frm_freq(vdev,
2268 						     freq, BW_20_MHZ,
2269 						     BEHAV_NONE);
2270 		*reg_bw_offset = BW20;
2271 	} else {
2272 		opclass = tdls_find_opclass_frm_freq(vdev,
2273 						     freq, BW_160_MHZ,
2274 						     BEHAV_NONE);
2275 		*reg_bw_offset = BWALL;
2276 	}
2277 
2278 	return opclass;
2279 }
2280