xref: /wlan-driver/qcacld-3.0/components/tdls/core/src/wlan_tdls_main.c (revision 5113495b16420b49004c444715d2daae2066e7dc) !
1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2024 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  */
tdls_get_cmd_type_str(enum tdls_command_type cmd_type)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  */
tdls_get_event_type_str(enum tdls_event_type event_type)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
tdls_get_cmd_type_str(enum tdls_command_type cmd_type)114 static char *tdls_get_cmd_type_str(enum tdls_command_type cmd_type)
115 {
116 	return "";
117 }
118 
tdls_get_event_type_str(enum tdls_event_type event_type)119 static char *tdls_get_event_type_str(enum tdls_event_type event_type)
120 {
121 	return "";
122 }
123 #endif
124 
tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)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 
tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)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 
tdls_vdev_init(struct tdls_vdev_priv_obj * vdev_obj)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 
tdls_vdev_deinit(struct tdls_vdev_priv_obj * vdev_obj)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 
tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev * vdev,void * arg)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 
tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev * vdev,void * arg)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  */
__tdls_get_all_peers_from_list(struct tdls_get_all_peers * get_tdls_peers)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  */
tdls_get_all_peers_from_list(struct tdls_get_all_peers * get_tdls_peers)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 
tdls_process_reset_all_peers(struct wlan_objmgr_vdev * vdev)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  */
tdls_reset_all_peers(struct tdls_delete_all_peers_params * delete_all_peers_ind)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
tdls_handle_start_bss(struct wlan_objmgr_psoc * psoc)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 
tdls_handle_link_unforce(struct wlan_objmgr_vdev * vdev)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 
tdls_process_cmd(struct scheduler_msg * msg)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 %s is NULL", !msg ? "" : "body ptr");
603 		QDF_ASSERT(0);
604 		return QDF_STATUS_E_NULL_VALUE;
605 	}
606 
607 	tdls_debug(" %s(%d)", 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 
tdls_process_evt(struct scheduler_msg * msg)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(" %s(%d)", tdls_get_event_type_str(event->message_type),
713 		   event->message_type);
714 
715 	switch (event->message_type) {
716 	case TDLS_SHOULD_DISCOVER:
717 		tdls_process_should_discover(vdev, event);
718 		break;
719 	case TDLS_SHOULD_TEARDOWN:
720 	case TDLS_PEER_DISCONNECTED:
721 		tdls_process_should_teardown(vdev, event);
722 		break;
723 	case TDLS_CONNECTION_TRACKER_NOTIFY:
724 		tdls_process_connection_tracker_notify(vdev, event);
725 		break;
726 	default:
727 		break;
728 	}
729 
730 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
731 	qdf_mem_free(notify);
732 
733 	return QDF_STATUS_SUCCESS;
734 }
735 
tdls_timer_restart(struct wlan_objmgr_vdev * vdev,qdf_mc_timer_t * timer,uint32_t expiration_time)736 void tdls_timer_restart(struct wlan_objmgr_vdev *vdev,
737 			qdf_mc_timer_t *timer, uint32_t expiration_time)
738 {
739 	if (!wlan_cm_is_vdev_connected(vdev)) {
740 		tdls_debug("vdev:%d is not connected. Can't restart timer",
741 			   wlan_vdev_get_id(vdev));
742 		return;
743 	}
744 
745 	if (QDF_TIMER_STATE_RUNNING !=
746 	    qdf_mc_timer_get_current_state(timer))
747 		qdf_mc_timer_start(timer, expiration_time);
748 }
749 
750 /**
751  * tdls_monitor_timers_stop() - stop all monitoring timers
752  * @tdls_vdev: TDLS vdev object
753  *
754  * Return: none
755  */
tdls_monitor_timers_stop(struct tdls_vdev_priv_obj * tdls_vdev)756 static void tdls_monitor_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev)
757 {
758 	if (!wlan_vdev_mlme_is_mlo_vdev(tdls_vdev->vdev))
759 		qdf_mc_timer_stop_sync(&tdls_vdev->peer_discovery_timer);
760 }
761 
762 /**
763  * tdls_peer_idle_timers_stop() - stop peer idle timers
764  * @tdls_vdev: TDLS vdev object
765  *
766  * Loop through the idle peer list and stop their timers
767  *
768  * Return: None
769  */
tdls_peer_idle_timers_stop(struct tdls_vdev_priv_obj * tdls_vdev)770 static void tdls_peer_idle_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev)
771 {
772 	int i;
773 	qdf_list_t *head;
774 	qdf_list_node_t *p_node;
775 	struct tdls_peer *curr_peer;
776 	QDF_STATUS status;
777 
778 	tdls_vdev->discovery_peer_cnt = 0;
779 
780 	for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
781 		head = &tdls_vdev->peer_list[i];
782 		status = qdf_list_peek_front(head, &p_node);
783 		while (QDF_IS_STATUS_SUCCESS(status)) {
784 			curr_peer = qdf_container_of(p_node, struct tdls_peer,
785 						     node);
786 			if (curr_peer->is_peer_idle_timer_initialised)
787 				qdf_mc_timer_stop_sync(&curr_peer->peer_idle_timer);
788 			status = qdf_list_peek_next(head, p_node, &p_node);
789 		}
790 	}
791 
792 }
793 
794 /**
795  * tdls_ct_timers_stop() - stop tdls connection tracker timers
796  * @tdls_vdev: TDLS vdev
797  *
798  * Return: None
799  */
tdls_ct_timers_stop(struct tdls_vdev_priv_obj * tdls_vdev)800 static void tdls_ct_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev)
801 {
802 	qdf_mc_timer_stop_sync(&tdls_vdev->peer_update_timer);
803 
804 	tdls_peer_idle_timers_stop(tdls_vdev);
805 }
806 
807 /**
808  * tdls_timers_stop() - stop all the tdls timers running
809  * @tdls_vdev: TDLS vdev
810  *
811  * Return: none
812  */
tdls_timers_stop(struct tdls_vdev_priv_obj * tdls_vdev)813 void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev)
814 {
815 	tdls_debug("Stop TDLS timers");
816 	tdls_monitor_timers_stop(tdls_vdev);
817 	tdls_ct_timers_stop(tdls_vdev);
818 }
819 
tdls_get_vdev_objects(struct wlan_objmgr_vdev * vdev,struct tdls_vdev_priv_obj ** tdls_vdev_obj,struct tdls_soc_priv_obj ** tdls_soc_obj)820 QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev,
821 				   struct tdls_vdev_priv_obj **tdls_vdev_obj,
822 				   struct tdls_soc_priv_obj **tdls_soc_obj)
823 {
824 	enum QDF_OPMODE device_mode;
825 
826 	if (!vdev)
827 		return QDF_STATUS_E_FAILURE;
828 
829 	*tdls_vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev);
830 	if (NULL == (*tdls_vdev_obj))
831 		return QDF_STATUS_E_FAILURE;
832 
833 	*tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev);
834 	if (NULL == (*tdls_soc_obj))
835 		return QDF_STATUS_E_FAILURE;
836 
837 	device_mode = wlan_vdev_mlme_get_opmode(vdev);
838 
839 	if (device_mode != QDF_STA_MODE &&
840 	    device_mode != QDF_P2P_CLIENT_MODE)
841 		return QDF_STATUS_E_FAILURE;
842 
843 	return QDF_STATUS_SUCCESS;
844 }
845 
846 #ifdef WLAN_FEATURE_11AX
tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq,enum supported_6g_pwr_types pwr_typ)847 uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev,
848 					qdf_freq_t freq,
849 					enum supported_6g_pwr_types pwr_typ)
850 {
851 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
852 	struct regulatory_channel *chan;
853 	uint8_t chn_idx, num_chan;
854 	uint8_t band_mask = BIT(REG_BAND_6G);
855 	uint32_t tx_power = 0;
856 
857 	if (!pdev)
858 		return 0;
859 
860 	/* No power check is required for non 6 Ghz channel */
861 	if (!wlan_reg_is_6ghz_chan_freq(freq))
862 		return 0;
863 
864 	chan = qdf_mem_malloc(sizeof(struct regulatory_channel) * NUM_CHANNELS);
865 	if (!chan)
866 		return 0;
867 
868 	num_chan = wlan_reg_get_band_channel_list_for_pwrmode(pdev,
869 							      band_mask,
870 							      chan,
871 							      REG_CLI_DEF_VLP);
872 
873 	for (chn_idx = 0; chn_idx < num_chan; chn_idx++) {
874 		if (chan[chn_idx].center_freq == freq) {
875 			tdls_debug("VLP power for channel %d is %d",
876 				   chan[chn_idx].center_freq,
877 				   chan[chn_idx].tx_power);
878 			tx_power = chan[chn_idx].tx_power;
879 		}
880 	}
881 
882 	qdf_mem_free(chan);
883 	return tx_power;
884 }
885 
tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq)886 bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
887 			     qdf_freq_t freq)
888 {
889 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
890 	struct regulatory_channel *chan;
891 	bool is_allowed = false;
892 	uint8_t country_code[REG_ALPHA2_LEN + 1];
893 	uint8_t chn_idx, num_chan = 0;
894 	uint8_t band_mask = BIT(REG_BAND_6G);
895 
896 	/* Return if freq is not 6 Ghz freq */
897 	if (!wlan_reg_is_6ghz_chan_freq(freq))
898 		return false;
899 
900 	if (!wlan_cfg80211_tdls_is_fw_6ghz_capable(vdev))
901 		return false;
902 
903 	if (!pdev)
904 		return false;
905 
906 	wlan_cm_get_country_code(pdev, wlan_vdev_get_id(vdev), country_code);
907 	if (!wlan_reg_ctry_support_vlp(country_code))
908 		return false;
909 
910 	chan = qdf_mem_malloc(sizeof(struct regulatory_channel) * NUM_CHANNELS);
911 	if (!chan)
912 		return false;
913 
914 	num_chan = wlan_reg_get_band_channel_list_for_pwrmode(pdev,
915 							      band_mask,
916 							      chan,
917 							      REG_CLI_DEF_VLP);
918 	tdls_debug("Country IE:%c%c freq %d num_chan %d", country_code[0],
919 			   country_code[1], freq, num_chan);
920 	if (!num_chan)
921 		goto error;
922 
923 	for (chn_idx = 0; chn_idx < num_chan; chn_idx++) {
924 		if (chan[chn_idx].center_freq == freq) {
925 			tdls_debug("TDLS 6ghz freq: %d supports VLP power",
926 				   chan[chn_idx].center_freq);
927 			is_allowed = true;
928 			break;
929 		}
930 	}
931 
932 error:
933 	qdf_mem_free(chan);
934 	return is_allowed;
935 }
936 #else
tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq)937 bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
938 				    qdf_freq_t freq)
939 {
940 	return false;
941 }
942 
tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq,enum supported_6g_pwr_types pwr_typ)943 uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev,
944 					qdf_freq_t freq,
945 					enum supported_6g_pwr_types pwr_typ)
946 {
947 	return 0;
948 }
949 #endif
950 
tdls_check_is_user_tdls_enable(struct tdls_soc_priv_obj * tdls_soc_obj)951 bool tdls_check_is_user_tdls_enable(struct tdls_soc_priv_obj *tdls_soc_obj)
952 {
953 	return tdls_soc_obj->is_user_tdls_enable;
954 }
955 
tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev * vdev)956 bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev)
957 {
958 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
959 	struct tdls_soc_priv_obj *tdls_soc_obj;
960 	bool state = false;
961 	qdf_freq_t ch_freq;
962 	QDF_STATUS status;
963 	uint32_t connection_count;
964 	uint8_t sta_count, p2p_cli_count;
965 
966 	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
967 	if (QDF_IS_STATUS_ERROR(status))
968 		return state;
969 
970 	status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
971 	if (QDF_IS_STATUS_ERROR(status)) {
972 		tdls_err("Failed to get TDLS objects");
973 		goto exit;
974 	}
975 
976 	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
977 	    !wlan_tdls_is_fw_11be_mlo_capable(tdls_soc_obj->soc)) {
978 		tdls_debug("TDLS not supported on MLO vdev");
979 		goto exit;
980 	}
981 
982 	if (wlan_nan_is_disc_active(tdls_soc_obj->soc)) {
983 		tdls_err("NAN active. NAN+TDLS not supported");
984 		goto exit;
985 	}
986 
987 	if (!tdls_check_is_user_tdls_enable(tdls_soc_obj)) {
988 		tdls_err("TDLS Disabled from userspace");
989 		goto exit;
990 	}
991 
992 	connection_count =
993 		policy_mgr_get_connection_count_with_mlo(tdls_soc_obj->soc);
994 	sta_count =
995 		policy_mgr_mode_specific_connection_count(tdls_soc_obj->soc,
996 							  PM_STA_MODE, NULL);
997 	p2p_cli_count =
998 		policy_mgr_mode_specific_connection_count(tdls_soc_obj->soc,
999 							  PM_P2P_CLIENT_MODE,
1000 							  NULL);
1001 	if ((connection_count == 1 && (sta_count || p2p_cli_count)) ||
1002 	    (connection_count > 1 &&
1003 	     tdls_is_concurrency_allowed(tdls_soc_obj->soc))) {
1004 		state = true;
1005 	} else {
1006 		tdls_warn("vdev:%d Concurrent sessions exist disable TDLS",
1007 			  wlan_vdev_get_id(vdev));
1008 		state = false;
1009 		goto exit;
1010 	}
1011 
1012 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE && sta_count) {
1013 		tdls_warn("vdev:%d Concurrent STA exists. TDLS not allowed for P2P vdev",
1014 			  wlan_vdev_get_id(vdev));
1015 		state = false;
1016 		goto exit;
1017 	}
1018 
1019 	ch_freq = wlan_get_operation_chan_freq(vdev);
1020 	if (wlan_reg_is_6ghz_chan_freq(ch_freq) &&
1021 	    !tdls_is_6g_freq_allowed(vdev, ch_freq)) {
1022 		tdls_debug("6GHz freq:%d not allowed for TDLS", ch_freq);
1023 		state = false;
1024 	}
1025 
1026 exit:
1027 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1028 
1029 	return state;
1030 }
1031 
1032 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
tdls_is_concurrency_allowed(struct wlan_objmgr_psoc * psoc)1033 bool tdls_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc)
1034 {
1035 	if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, NULL)) {
1036 		tdls_debug("eMLSR STA present. Don't allow TDLS");
1037 		return false;
1038 	}
1039 
1040 	if (!wlan_psoc_nif_fw_ext2_cap_get(psoc,
1041 					   WLAN_TDLS_CONCURRENCIES_SUPPORT)) {
1042 		tdls_debug("fw cap is not advertised");
1043 		return false;
1044 	}
1045 
1046 	if (policy_mgr_get_connection_count_with_mlo(psoc) >
1047 	    WLAN_TDLS_MAX_CONCURRENT_VDEV_SUPPORTED)
1048 		return false;
1049 
1050 	if (policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1051 						      NULL) > 1) {
1052 		tdls_debug("More than one STA exist. Don't allow TDLS");
1053 		return false;
1054 	}
1055 
1056 	if (policy_mgr_is_mcc_on_any_sta_vdev(psoc)) {
1057 		tdls_debug("Base channel MCC. Don't allow TDLS");
1058 		return false;
1059 	}
1060 
1061 	/*
1062 	 * Don't enable TDLS for P2P_CLI in concurrency cases
1063 	 */
1064 	if (policy_mgr_get_connection_count_with_mlo(psoc) > 1 &&
1065 	    !policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1066 						       NULL))
1067 		return false;
1068 
1069 	return true;
1070 }
1071 #endif
1072 
tdls_set_ct_mode(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)1073 void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc,
1074 		      struct wlan_objmgr_vdev *vdev)
1075 {
1076 	struct tdls_soc_priv_obj *tdls_soc_obj;
1077 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
1078 	uint32_t tdls_feature_flags = 0, sta_count, p2p_count;
1079 	bool state = false;
1080 	bool tdls_mlo;
1081 	QDF_STATUS status;
1082 
1083 	if (!tdls_check_is_tdls_allowed(vdev))
1084 		return;
1085 
1086 	status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
1087 	if (QDF_IS_STATUS_ERROR(status)) {
1088 		tdls_err("Failed to get TDLS objects");
1089 		return;
1090 	}
1091 
1092 	qdf_atomic_set(&tdls_soc_obj->timer_cnt, 0);
1093 	tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags;
1094 	if (TDLS_SUPPORT_DISABLED == tdls_soc_obj->tdls_current_mode ||
1095 	    TDLS_SUPPORT_SUSPENDED == tdls_soc_obj->tdls_current_mode ||
1096 	    !TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) {
1097 		state = false;
1098 		goto set_state;
1099 	}
1100 
1101 	sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1102 							      NULL);
1103 	p2p_count =
1104 		policy_mgr_mode_specific_connection_count(psoc,
1105 							  PM_P2P_CLIENT_MODE,
1106 							  NULL);
1107 	tdls_mlo = wlan_tdls_is_fw_11be_mlo_capable(psoc);
1108 	if (sta_count == 1 || (sta_count >= 2 && tdls_mlo) ||
1109 	    (policy_mgr_get_connection_count_with_mlo(psoc) == 1 &&
1110 	     p2p_count == 1)) {
1111 		state = true;
1112 		/*
1113 		 * In case of TDLS external control, peer should be added
1114 		 * by the user space to start connection tracker.
1115 		 */
1116 		if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags) &&
1117 		    !tdls_soc_obj->tdls_external_peer_count)
1118 			state = false;
1119 
1120 		goto set_state;
1121 	}
1122 
1123 	state = false;
1124 
1125 set_state:
1126 	tdls_soc_obj->enable_tdls_connection_tracker = state;
1127 	if (tdls_soc_obj->enable_tdls_connection_tracker)
1128 		tdls_implicit_enable(tdls_vdev_obj);
1129 	else
1130 		tdls_implicit_disable(tdls_vdev_obj);
1131 
1132 	tdls_debug("vdev:%d enable_tdls_connection_tracker %d current_mode:%d feature_flags:0x%x",
1133 		   wlan_vdev_get_id(vdev),
1134 		   tdls_soc_obj->enable_tdls_connection_tracker,
1135 		   tdls_soc_obj->tdls_current_mode, tdls_feature_flags);
1136 }
1137 
tdls_set_user_tdls_enable(struct wlan_objmgr_vdev * vdev,bool is_user_tdls_enable)1138 void tdls_set_user_tdls_enable(struct wlan_objmgr_vdev *vdev,
1139 			       bool is_user_tdls_enable)
1140 {
1141 	QDF_STATUS status;
1142 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
1143 	struct tdls_soc_priv_obj *tdls_soc_obj;
1144 
1145 	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
1146 	if (QDF_IS_STATUS_ERROR(status))
1147 		return;
1148 
1149 	status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
1150 	if (QDF_IS_STATUS_ERROR(status)) {
1151 		tdls_err("Failed to get TDLS objects");
1152 		goto exit;
1153 	}
1154 
1155 	tdls_soc_obj->is_user_tdls_enable = is_user_tdls_enable;
1156 	tdls_debug("TDLS enable:%d via userspace",
1157 		   tdls_soc_obj->is_user_tdls_enable);
1158 
1159 exit:
1160 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1161 }
1162 
1163 QDF_STATUS
tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc * psoc)1164 tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc)
1165 {
1166 	struct wlan_objmgr_vdev *tdls_vdev;
1167 	struct tdls_vdev_priv_obj *tdls_priv_vdev;
1168 	struct tdls_soc_priv_obj *tdls_priv_soc;
1169 	QDF_STATUS status;
1170 
1171 	if (!psoc) {
1172 		tdls_err("psoc is NULL");
1173 		return QDF_STATUS_E_NULL_VALUE;
1174 	}
1175 
1176 	tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
1177 	if (!tdls_vdev) {
1178 		tdls_debug("No TDLS vdev");
1179 		return QDF_STATUS_E_NULL_VALUE;
1180 	}
1181 
1182 	status = tdls_get_vdev_objects(tdls_vdev, &tdls_priv_vdev,
1183 				       &tdls_priv_soc);
1184 	if (QDF_IS_STATUS_ERROR(status)) {
1185 		tdls_debug("TDLS vdev objects NULL");
1186 		wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
1187 		return QDF_STATUS_E_NULL_VALUE;
1188 	}
1189 
1190 	if (!tdls_check_is_tdls_allowed(tdls_vdev)) {
1191 		tdls_debug("Disable the tdls in FW due to concurrency");
1192 		if (wlan_vdev_mlme_is_mlo_vdev(tdls_vdev))
1193 			tdls_process_enable_disable_for_ml_vdev(tdls_vdev,
1194 								false);
1195 		else
1196 			tdls_disable_offchan_and_teardown_links(tdls_vdev);
1197 
1198 		wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
1199 		return QDF_STATUS_E_NULL_VALUE;
1200 	}
1201 
1202 	tdls_debug("vdev:%d enter", wlan_vdev_get_id(tdls_vdev));
1203 
1204 	tdls_set_tdls_offchannelmode(tdls_vdev, ENABLE_CHANSWITCH);
1205 	tdls_set_ct_mode(psoc, tdls_vdev);
1206 
1207 	wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
1208 	tdls_debug("exit ");
1209 
1210 	return QDF_STATUS_SUCCESS;
1211 }
1212 
1213 QDF_STATUS
tdls_process_decrement_active_session(struct wlan_objmgr_psoc * psoc)1214 tdls_process_decrement_active_session(struct wlan_objmgr_psoc *psoc)
1215 {
1216 	struct wlan_objmgr_vdev *tdls_obj_vdev;
1217 
1218 	tdls_debug("Enter");
1219 	if (!psoc)
1220 		return QDF_STATUS_E_NULL_VALUE;
1221 
1222 	if(!policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
1223 	   !policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G) &&
1224 	   policy_mgr_is_current_hwmode_dbs(psoc)) {
1225 		tdls_debug("Current HW mode is 1*1 DBS. Wait for Opportunistic timer to expire to enable TDLS in FW");
1226 		return QDF_STATUS_SUCCESS;
1227 	}
1228 
1229 	tdls_obj_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
1230 	if (!tdls_obj_vdev)
1231 		return QDF_STATUS_E_FAILURE;
1232 
1233 	if (!tdls_check_is_tdls_allowed(tdls_obj_vdev))
1234 		goto release_ref;
1235 
1236 	/*
1237 	 * 2 Port MCC -> 1 port scenario or
1238 	 * 3 Port MCC -> 2 port SCC scenario or
1239 	 * 4 Port -> 3 Port SCC scenario
1240 	 * So enable TDLS in firmware
1241 	 */
1242 	tdls_debug("Enable TDLS as active sta/p2p_cli interface is present");
1243 	if (wlan_vdev_mlme_is_mlo_vdev(tdls_obj_vdev))
1244 		tdls_process_enable_disable_for_ml_vdev(tdls_obj_vdev, true);
1245 	else
1246 		tdls_process_enable_for_vdev(tdls_obj_vdev);
1247 
1248 release_ref:
1249 	wlan_objmgr_vdev_release_ref(tdls_obj_vdev, WLAN_TDLS_NB_ID);
1250 
1251 	return QDF_STATUS_SUCCESS;
1252 }
1253 
1254 #ifdef WLAN_FEATURE_11BE_MLO
wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev * vdev,uint8_t index,wlan_objmgr_ref_dbgid dbg_id)1255 struct wlan_objmgr_vdev *wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev *vdev,
1256 						uint8_t index,
1257 						wlan_objmgr_ref_dbgid dbg_id)
1258 {
1259 	struct wlan_mlo_dev_context *mlo_dev_ctx;
1260 	struct wlan_objmgr_vdev *mlo_vdev;
1261 
1262 	if (!vdev)
1263 		return NULL;
1264 
1265 	mlo_dev_ctx = vdev->mlo_dev_ctx;
1266 	if (!mlo_dev_ctx)
1267 		return NULL;
1268 
1269 	mlo_vdev = mlo_dev_ctx->wlan_vdev_list[index];
1270 	if (mlo_vdev &&
1271 	    wlan_objmgr_vdev_try_get_ref(mlo_vdev, dbg_id) ==
1272 							QDF_STATUS_SUCCESS)
1273 		return mlo_vdev;
1274 
1275 	return NULL;
1276 }
1277 
wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid dbg_id)1278 void wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev *vdev,
1279 				wlan_objmgr_ref_dbgid dbg_id)
1280 {
1281 	if (!vdev)
1282 		return;
1283 
1284 	wlan_objmgr_vdev_release_ref(vdev, dbg_id);
1285 }
1286 #else
wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev * vdev,uint8_t index,wlan_objmgr_ref_dbgid dbg_id)1287 struct wlan_objmgr_vdev *wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev *vdev,
1288 						uint8_t index,
1289 						wlan_objmgr_ref_dbgid dbg_id)
1290 {
1291 	return NULL;
1292 }
1293 
wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid dbg_id)1294 void wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev *vdev,
1295 				wlan_objmgr_ref_dbgid dbg_id)
1296 {
1297 }
1298 #endif
1299 /**
1300  * tdls_get_vdev() - Get tdls specific vdev object manager
1301  * @psoc: wlan psoc object manager
1302  * @dbg_id: debug id
1303  *
1304  * If TDLS possible, return the corresponding vdev
1305  * to enable TDLS in the system.
1306  *
1307  * Return: vdev manager pointer or NULL.
1308  */
tdls_get_vdev(struct wlan_objmgr_psoc * psoc,wlan_objmgr_ref_dbgid dbg_id)1309 struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc,
1310 					  wlan_objmgr_ref_dbgid dbg_id)
1311 {
1312 	uint32_t vdev_id;
1313 
1314 	vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_STA_MODE);
1315 	if (WLAN_INVALID_VDEV_ID != vdev_id)
1316 		return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1317 							    dbg_id);
1318 	/*
1319 	 * For P2P_Client mode, TDLS is not supported on concurrency
1320 	 * so return P2P_client vdev only if P2P client mode exists without
1321 	 * any concurreny
1322 	 */
1323 	vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_P2P_CLIENT_MODE);
1324 	if (WLAN_INVALID_VDEV_ID != vdev_id &&
1325 	    policy_mgr_get_connection_count_with_mlo(psoc) == 1)
1326 		return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1327 							    dbg_id);
1328 
1329 	return NULL;
1330 }
1331 
tdls_post_msg_flush_cb(struct scheduler_msg * msg)1332 static QDF_STATUS tdls_post_msg_flush_cb(struct scheduler_msg *msg)
1333 {
1334 	void *ptr = msg->bodyptr;
1335 	struct wlan_objmgr_vdev *vdev = NULL;
1336 
1337 	switch (msg->type) {
1338 	case TDLS_NOTIFY_STA_DISCONNECTION:
1339 		vdev = ((struct tdls_sta_notify_params *)ptr)->vdev;
1340 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1341 		qdf_mem_free(ptr);
1342 		break;
1343 
1344 	case TDLS_DELETE_ALL_PEERS_INDICATION:
1345 		vdev = ((struct tdls_delete_all_peers_params *)ptr)->vdev;
1346 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
1347 		qdf_mem_free(ptr);
1348 		break;
1349 
1350 	case TDLS_CMD_SCAN_DONE:
1351 	case TDLS_CMD_SESSION_INCREMENT:
1352 	case TDLS_CMD_SESSION_DECREMENT:
1353 		break;
1354 	}
1355 
1356 	return QDF_STATUS_SUCCESS;
1357 }
1358 
1359 /**
1360  * tdls_process_session_update() - update session count information
1361  * @psoc: soc object
1362  * @cmd_type: type of command
1363  *
1364  * update the session information in connection tracker
1365  *
1366  * Return: None
1367  */
tdls_process_session_update(struct wlan_objmgr_psoc * psoc,enum tdls_command_type cmd_type)1368 static void tdls_process_session_update(struct wlan_objmgr_psoc *psoc,
1369 				 enum tdls_command_type cmd_type)
1370 {
1371 	struct scheduler_msg msg = {0};
1372 	QDF_STATUS status;
1373 
1374 	msg.bodyptr = psoc;
1375 	msg.callback = tdls_process_cmd;
1376 	msg.flush_callback = tdls_post_msg_flush_cb;
1377 	msg.type = (uint16_t)cmd_type;
1378 
1379 	status = scheduler_post_message(QDF_MODULE_ID_TDLS,
1380 					QDF_MODULE_ID_TDLS,
1381 					QDF_MODULE_ID_OS_IF, &msg);
1382 	if (QDF_IS_STATUS_ERROR(status))
1383 		tdls_alert("message post failed ");
1384 }
1385 
tdls_notify_increment_session(struct wlan_objmgr_psoc * psoc)1386 void tdls_notify_increment_session(struct wlan_objmgr_psoc *psoc)
1387 {
1388 	tdls_process_session_update(psoc, TDLS_CMD_SESSION_INCREMENT);
1389 }
1390 
tdls_notify_decrement_session(struct wlan_objmgr_psoc * psoc)1391 void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc)
1392 {
1393 	tdls_process_session_update(psoc, TDLS_CMD_SESSION_DECREMENT);
1394 }
1395 
tdls_send_update_to_fw(struct tdls_vdev_priv_obj * tdls_vdev_obj,struct tdls_soc_priv_obj * tdls_soc_obj,bool tdls_prohibited,bool tdls_chan_swit_prohibited,bool sta_connect_event,uint8_t session_id)1396 void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj,
1397 			    struct tdls_soc_priv_obj *tdls_soc_obj,
1398 			    bool tdls_prohibited,
1399 			    bool tdls_chan_swit_prohibited,
1400 			    bool sta_connect_event,
1401 			    uint8_t session_id)
1402 {
1403 	struct tdls_info *tdls_info_to_fw;
1404 	struct tdls_config_params *threshold_params;
1405 	uint32_t tdls_feature_flags;
1406 	QDF_STATUS status;
1407 	bool tdls_mlo;
1408 
1409 	tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags;
1410 	if (!TDLS_IS_ENABLED(tdls_feature_flags)) {
1411 		tdls_debug("TDLS mode is not enabled");
1412 		return;
1413 	}
1414 
1415 	tdls_mlo = wlan_tdls_is_fw_11be_mlo_capable(tdls_soc_obj->soc);
1416 
1417 	/* If AP or caller indicated TDLS Prohibited then disable tdls mode */
1418 	if (sta_connect_event) {
1419 		if (tdls_prohibited) {
1420 			tdls_soc_obj->tdls_current_mode =
1421 					TDLS_SUPPORT_DISABLED;
1422 		} else {
1423 			if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags))
1424 				tdls_soc_obj->tdls_current_mode =
1425 					TDLS_SUPPORT_EXP_TRIG_ONLY;
1426 			else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(
1427 				tdls_feature_flags))
1428 				tdls_soc_obj->tdls_current_mode =
1429 					TDLS_SUPPORT_EXT_CONTROL;
1430 			else
1431 				tdls_soc_obj->tdls_current_mode =
1432 					TDLS_SUPPORT_IMP_MODE;
1433 		}
1434 	} else {
1435 		tdls_soc_obj->tdls_current_mode =
1436 				TDLS_SUPPORT_DISABLED;
1437 	}
1438 
1439 	tdls_info_to_fw = qdf_mem_malloc(sizeof(struct tdls_info));
1440 	if (!tdls_info_to_fw)
1441 		return;
1442 
1443 	threshold_params = &tdls_vdev_obj->threshold_config;
1444 
1445 	tdls_info_to_fw->notification_interval_ms =
1446 		threshold_params->tx_period_t;
1447 	tdls_info_to_fw->tx_discovery_threshold =
1448 		threshold_params->tx_packet_n;
1449 	tdls_info_to_fw->tx_teardown_threshold =
1450 		threshold_params->idle_packet_n;
1451 	tdls_info_to_fw->rssi_teardown_threshold =
1452 		threshold_params->rssi_teardown_threshold;
1453 	tdls_info_to_fw->rssi_delta = threshold_params->rssi_delta;
1454 	tdls_info_to_fw->vdev_id = session_id;
1455 
1456 	/* record the session id in vdev context */
1457 	tdls_vdev_obj->session_id = session_id;
1458 	tdls_info_to_fw->tdls_state = tdls_soc_obj->tdls_current_mode;
1459 	tdls_info_to_fw->tdls_options = 0;
1460 
1461 	/*
1462 	 * Do not enable TDLS offchannel, if AP prohibited TDLS
1463 	 * channel switch
1464 	 */
1465 	if (TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) &&
1466 	    (!tdls_chan_swit_prohibited))
1467 		tdls_info_to_fw->tdls_options = ENA_TDLS_OFFCHAN;
1468 
1469 	if (TDLS_IS_BUFFER_STA_ENABLED(tdls_feature_flags))
1470 		tdls_info_to_fw->tdls_options |= ENA_TDLS_BUFFER_STA;
1471 	if (TDLS_IS_SLEEP_STA_ENABLED(tdls_feature_flags))
1472 		tdls_info_to_fw->tdls_options |=  ENA_TDLS_SLEEP_STA;
1473 
1474 
1475 	tdls_info_to_fw->peer_traffic_ind_window =
1476 		tdls_soc_obj->tdls_configs.tdls_uapsd_pti_window;
1477 	tdls_info_to_fw->peer_traffic_response_timeout =
1478 		tdls_soc_obj->tdls_configs.tdls_uapsd_ptr_timeout;
1479 	tdls_info_to_fw->puapsd_mask =
1480 		tdls_soc_obj->tdls_configs.tdls_uapsd_mask;
1481 	tdls_info_to_fw->puapsd_inactivity_time =
1482 		tdls_soc_obj->tdls_configs.tdls_uapsd_inactivity_time;
1483 	tdls_info_to_fw->puapsd_rx_frame_threshold =
1484 		tdls_soc_obj->tdls_configs.tdls_rx_pkt_threshold;
1485 	tdls_info_to_fw->teardown_notification_ms =
1486 		tdls_soc_obj->tdls_configs.tdls_idle_timeout;
1487 	tdls_info_to_fw->tdls_peer_kickout_threshold =
1488 		tdls_soc_obj->tdls_configs.tdls_peer_kickout_threshold;
1489 	tdls_info_to_fw->tdls_discovery_wake_timeout =
1490 		tdls_soc_obj->tdls_configs.tdls_discovery_wake_timeout;
1491 
1492 	status = tgt_tdls_set_fw_state(tdls_soc_obj->soc, tdls_info_to_fw);
1493 	if (QDF_IS_STATUS_ERROR(status))
1494 		goto done;
1495 
1496 	if (sta_connect_event) {
1497 		tdls_soc_obj->set_state_info.vdev_id = session_id;
1498 	}
1499 
1500 	tdls_debug("FW tdls state sent for vdev id %d", session_id);
1501 done:
1502 	qdf_mem_free(tdls_info_to_fw);
1503 	return;
1504 }
1505 
tdls_process_enable_for_vdev(struct wlan_objmgr_vdev * vdev)1506 void tdls_process_enable_for_vdev(struct wlan_objmgr_vdev *vdev)
1507 {
1508 	struct wlan_objmgr_psoc *psoc;
1509 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
1510 	struct tdls_soc_priv_obj *tdls_soc_obj;
1511 	enum QDF_OPMODE opmode;
1512 	QDF_STATUS status;
1513 	uint8_t sta_count;
1514 
1515 	psoc = wlan_vdev_get_psoc(vdev);
1516 	if (!psoc)
1517 		return;
1518 
1519 	sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1520 							      NULL);
1521 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1522 	if (opmode == QDF_P2P_CLIENT_MODE && sta_count) {
1523 		tdls_debug("STA + P2P concurrency. Don't allow TDLS on P2P vdev:%d",
1524 			   wlan_vdev_get_id(vdev));
1525 		return;
1526 	}
1527 
1528 	status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
1529 	if (QDF_IS_STATUS_ERROR(status))
1530 		return;
1531 
1532 	tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj,
1533 			       mlme_get_tdls_prohibited(vdev),
1534 			       mlme_get_tdls_chan_switch_prohibited(vdev),
1535 			       true, wlan_vdev_get_id(vdev));
1536 
1537 	/* check and set the connection tracker */
1538 	tdls_set_ct_mode(tdls_soc_obj->soc, vdev);
1539 }
1540 
1541 #ifdef WLAN_FEATURE_11BE_MLO
tdls_process_enable_disable_for_ml_vdev(struct wlan_objmgr_vdev * vdev,bool is_enable)1542 void tdls_process_enable_disable_for_ml_vdev(struct wlan_objmgr_vdev *vdev,
1543 					     bool is_enable)
1544 {
1545 	struct wlan_mlo_dev_context *ml_dev_ctx;
1546 	QDF_STATUS status;
1547 	uint8_t i;
1548 	struct wlan_objmgr_vdev *vdev_iter;
1549 
1550 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
1551 		return;
1552 
1553 	ml_dev_ctx = vdev->mlo_dev_ctx;
1554 	if (!ml_dev_ctx)
1555 		return;
1556 
1557 	for (i =  0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
1558 		if (!ml_dev_ctx->wlan_vdev_list[i])
1559 			continue;
1560 
1561 		vdev_iter = ml_dev_ctx->wlan_vdev_list[i];
1562 		status = wlan_objmgr_vdev_try_get_ref(vdev_iter,
1563 						      WLAN_TDLS_NB_ID);
1564 		if (QDF_IS_STATUS_ERROR(status))
1565 			continue;
1566 
1567 		if (is_enable)
1568 			tdls_process_enable_for_vdev(vdev_iter);
1569 		else
1570 			tdls_disable_offchan_and_teardown_links(vdev_iter);
1571 
1572 		wlan_objmgr_vdev_release_ref(vdev_iter, WLAN_TDLS_NB_ID);
1573 	}
1574 }
1575 #endif
1576 
1577 static QDF_STATUS
tdls_process_sta_connect(struct tdls_sta_notify_params * notify)1578 tdls_process_sta_connect(struct tdls_sta_notify_params *notify)
1579 {
1580 	if (!tdls_check_is_tdls_allowed(notify->vdev))
1581 		return QDF_STATUS_E_NOSUPPORT;
1582 
1583 	tdls_process_enable_for_vdev(notify->vdev);
1584 
1585 	return QDF_STATUS_SUCCESS;
1586 }
1587 
1588 static void
tdls_update_discovery_tries(struct wlan_objmgr_vdev * vdev)1589 tdls_update_discovery_tries(struct wlan_objmgr_vdev *vdev)
1590 {
1591 	struct tdls_soc_priv_obj *soc_obj;
1592 	struct tdls_vdev_priv_obj *vdev_obj;
1593 	struct tdls_user_config *tdls_config;
1594 	struct tdls_config_params *vdev_config;
1595 	QDF_STATUS status;
1596 
1597 	status = tdls_get_vdev_objects(vdev, &vdev_obj, &soc_obj);
1598 	if (QDF_IS_STATUS_ERROR(status)) {
1599 		tdls_err("can't get vdev_obj & soc_obj");
1600 		return;
1601 	}
1602 
1603 	vdev_config = &vdev_obj->threshold_config;
1604 	tdls_config = &soc_obj->tdls_configs;
1605 
1606 	vdev_config->discovery_tries_n =
1607 			tdls_config->tdls_max_discovery_attempt;
1608 }
1609 
tdls_notify_sta_connect(struct tdls_sta_notify_params * notify)1610 QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify)
1611 {
1612 	QDF_STATUS status;
1613 
1614 	if (!notify) {
1615 		tdls_err("invalid param");
1616 		return QDF_STATUS_E_INVAL;
1617 	}
1618 
1619 	if (!notify->vdev) {
1620 		tdls_err("invalid param");
1621 		qdf_mem_free(notify);
1622 		return QDF_STATUS_E_INVAL;
1623 	}
1624 
1625 	status = tdls_process_sta_connect(notify);
1626 	if (QDF_IS_STATUS_SUCCESS(status))
1627 		tdls_update_discovery_tries(notify->vdev);
1628 
1629 	wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
1630 	qdf_mem_free(notify);
1631 
1632 	return status;
1633 }
1634 
1635 static QDF_STATUS
tdls_process_sta_disconnect(struct tdls_sta_notify_params * notify)1636 tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify)
1637 {
1638 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
1639 	struct tdls_soc_priv_obj *tdls_soc_obj;
1640 	struct wlan_objmgr_vdev *temp_vdev = NULL;
1641 	QDF_STATUS status;
1642 
1643 	status = tdls_get_vdev_objects(notify->vdev, &tdls_vdev_obj,
1644 				       &tdls_soc_obj);
1645 	if (QDF_IS_STATUS_ERROR(status))
1646 		return status;
1647 
1648 	/* if the disconnect comes from user space, we have to delete all the
1649 	 * tdls peers before sending the set state cmd.
1650 	 */
1651 	if (notify->user_disconnect)
1652 		return tdls_delete_all_tdls_peers(notify->vdev, tdls_soc_obj);
1653 
1654 	tdls_debug("Check and update TDLS state for vdev:%d",
1655 		   notify->session_id);
1656 
1657 	/* Disassociation event */
1658 	tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj, false,
1659 			       false, false, notify->session_id);
1660 
1661 	tdls_timers_stop(tdls_vdev_obj);
1662 
1663 	/*
1664 	 * If concurrency is not marked, then we have to
1665 	 * check, whether TDLS could be enabled in the
1666 	 * system after this disassoc event.
1667 	 */
1668 	if (notify->lfr_roam)
1669 		return status;
1670 
1671 	temp_vdev = tdls_get_vdev(tdls_soc_obj->soc, WLAN_TDLS_NB_ID);
1672 	if (!temp_vdev)
1673 		return status;
1674 
1675 	if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev))
1676 		tdls_process_enable_disable_for_ml_vdev(temp_vdev, true);
1677 	else
1678 		tdls_process_enable_for_vdev(temp_vdev);
1679 
1680 	wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_TDLS_NB_ID);
1681 
1682 	wlan_vdev_mlme_feat_ext2_cap_clear(notify->vdev,
1683 					   WLAN_VDEV_FEXT2_MLO_STA_TDLS);
1684 
1685 	return status;
1686 }
1687 
tdls_notify_sta_disconnect(struct tdls_sta_notify_params * notify)1688 QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify)
1689 {
1690 	QDF_STATUS status;
1691 	struct wlan_objmgr_vdev *vdev;
1692 	enum QDF_OPMODE opmode;
1693 	struct wlan_objmgr_psoc *psoc;
1694 	uint8_t sta_count;
1695 
1696 	if (!notify) {
1697 		tdls_err("invalid param");
1698 		return QDF_STATUS_E_INVAL;
1699 	}
1700 
1701 	vdev = notify->vdev;
1702 	if (!vdev) {
1703 		tdls_err("invalid param");
1704 		qdf_mem_free(notify);
1705 		return QDF_STATUS_E_INVAL;
1706 	}
1707 
1708 	psoc = wlan_vdev_get_psoc(vdev);
1709 	if (!psoc) {
1710 		wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
1711 		qdf_mem_free(notify);
1712 		return QDF_STATUS_E_INVAL;
1713 	}
1714 
1715 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1716 	sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1717 							      NULL);
1718 	if (opmode == QDF_P2P_CLIENT_MODE && sta_count) {
1719 		tdls_debug("STA + P2P concurrency. No action on P2P vdev");
1720 		wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
1721 		qdf_mem_free(notify);
1722 		return QDF_STATUS_E_INVAL;
1723 	}
1724 
1725 	status = tdls_process_sta_disconnect(notify);
1726 
1727 	wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
1728 	qdf_mem_free(notify);
1729 
1730 	return status;
1731 }
1732 
tdls_process_reset_adapter(struct wlan_objmgr_vdev * vdev)1733 static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev)
1734 {
1735 	struct tdls_vdev_priv_obj *tdls_vdev;
1736 
1737 	tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
1738 	if (!tdls_vdev)
1739 		return;
1740 	tdls_timers_stop(tdls_vdev);
1741 }
1742 
tdls_notify_reset_adapter(struct wlan_objmgr_vdev * vdev)1743 void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev)
1744 {
1745 	if (!vdev) {
1746 		QDF_ASSERT(0);
1747 		return;
1748 	}
1749 
1750 	if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev,
1751 						WLAN_TDLS_NB_ID))
1752 		return;
1753 
1754 	tdls_process_reset_adapter(vdev);
1755 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1756 }
1757 
tdls_peers_deleted_notification(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)1758 QDF_STATUS tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc,
1759 					   uint8_t vdev_id)
1760 {
1761 	struct scheduler_msg msg = {0, };
1762 	struct tdls_sta_notify_params *notify;
1763 	QDF_STATUS status;
1764 	struct wlan_objmgr_vdev *vdev;
1765 
1766 	notify = qdf_mem_malloc(sizeof(*notify));
1767 	if (!notify)
1768 		return QDF_STATUS_E_NULL_VALUE;
1769 
1770 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
1771 						    vdev_id,
1772 						    WLAN_TDLS_NB_ID);
1773 
1774 	if (!vdev) {
1775 		tdls_err("vdev not exist for the vdev id %d",
1776 			 vdev_id);
1777 		qdf_mem_free(notify);
1778 		return QDF_STATUS_E_INVAL;
1779 	}
1780 
1781 	notify->lfr_roam = true;
1782 	notify->tdls_chan_swit_prohibited = false;
1783 	notify->tdls_prohibited = false;
1784 	notify->session_id = vdev_id;
1785 	notify->vdev = vdev;
1786 	notify->user_disconnect = false;
1787 
1788 	msg.bodyptr = notify;
1789 	msg.callback = tdls_process_cmd;
1790 	msg.flush_callback = tdls_post_msg_flush_cb;
1791 	msg.type = TDLS_NOTIFY_STA_DISCONNECTION;
1792 
1793 	status = scheduler_post_message(QDF_MODULE_ID_TDLS,
1794 					QDF_MODULE_ID_TDLS,
1795 					QDF_MODULE_ID_OS_IF, &msg);
1796 	if (QDF_IS_STATUS_ERROR(status)) {
1797 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
1798 		qdf_mem_free(notify);
1799 		tdls_alert("message post failed ");
1800 
1801 		return QDF_STATUS_E_FAILURE;
1802 	}
1803 
1804 	return QDF_STATUS_SUCCESS;
1805 }
1806 
1807 static
tdls_delete_all_peers_indication(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)1808 QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
1809 					    uint8_t vdev_id)
1810 {
1811 	struct scheduler_msg msg = {0, };
1812 	struct tdls_delete_all_peers_params *indication;
1813 	QDF_STATUS status;
1814 	struct wlan_objmgr_vdev *vdev;
1815 
1816 	indication = qdf_mem_malloc(sizeof(*indication));
1817 	if (!indication)
1818 		return QDF_STATUS_E_NULL_VALUE;
1819 
1820 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1821 						    WLAN_TDLS_SB_ID);
1822 	if (!vdev) {
1823 		tdls_err("vdev:%d does not exist", vdev_id);
1824 		qdf_mem_free(indication);
1825 		return QDF_STATUS_E_INVAL;
1826 	}
1827 
1828 	indication->vdev = vdev;
1829 
1830 	msg.bodyptr = indication;
1831 	msg.callback = tdls_process_cmd;
1832 	msg.type = TDLS_DELETE_ALL_PEERS_INDICATION;
1833 	msg.flush_callback = tdls_post_msg_flush_cb;
1834 
1835 	status = scheduler_post_message(QDF_MODULE_ID_TDLS,
1836 					QDF_MODULE_ID_TDLS,
1837 					QDF_MODULE_ID_OS_IF, &msg);
1838 	if (QDF_IS_STATUS_ERROR(status)) {
1839 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
1840 		qdf_mem_free(indication);
1841 		tdls_alert("message post failed ");
1842 		return QDF_STATUS_E_FAILURE;
1843 	}
1844 
1845 	return QDF_STATUS_SUCCESS;
1846 }
1847 
1848 QDF_STATUS
tdls_check_and_indicate_delete_all_peers(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)1849 tdls_check_and_indicate_delete_all_peers(struct wlan_objmgr_psoc *psoc,
1850 					 uint8_t vdev_id)
1851 {
1852 	struct wlan_objmgr_pdev *pdev;
1853 	uint32_t pdev_id;
1854 	enum QDF_OPMODE opmode;
1855 	uint8_t sta_count =
1856 		policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1857 							  NULL);
1858 
1859 	pdev_id = wlan_get_pdev_id_from_vdev_id(psoc, vdev_id, WLAN_TDLS_SB_ID);
1860 	if (pdev_id == WLAN_INVALID_PDEV_ID) {
1861 		tdls_debug("Invalid pdev id");
1862 		return QDF_STATUS_E_INVAL;
1863 	}
1864 
1865 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, WLAN_TDLS_SB_ID);
1866 	if (!pdev) {
1867 		tdls_debug("pdev is NULL");
1868 		return QDF_STATUS_E_INVAL;
1869 	}
1870 
1871 	opmode = wlan_get_opmode_from_vdev_id(pdev, vdev_id);
1872 	wlan_objmgr_pdev_release_ref(pdev, WLAN_TDLS_SB_ID);
1873 
1874 	if (opmode == QDF_P2P_CLIENT_MODE && sta_count) {
1875 		tdls_debug("STA + P2P concurrency. No action on P2P vdev");
1876 		return QDF_STATUS_E_INVAL;
1877 	}
1878 
1879 	return tdls_delete_all_peers_indication(psoc, vdev_id);
1880 }
1881 
1882 /**
1883  * tdls_set_mode_in_vdev() - set TDLS mode
1884  * @tdls_vdev: tdls vdev object
1885  * @tdls_soc: tdls soc object
1886  * @tdls_mode: TDLS mode
1887  * @source: TDLS disable source enum values
1888  *
1889  * Return: Void
1890  */
tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj * tdls_vdev,struct tdls_soc_priv_obj * tdls_soc,enum tdls_feature_mode tdls_mode,enum tdls_disable_sources source)1891 static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev,
1892 				  struct tdls_soc_priv_obj *tdls_soc,
1893 				  enum tdls_feature_mode tdls_mode,
1894 				  enum tdls_disable_sources source)
1895 {
1896 	tdls_debug("set tdls mode: %d source:%d", tdls_mode,
1897 		   source);
1898 
1899 	switch (tdls_mode) {
1900 	case TDLS_SUPPORT_IMP_MODE:
1901 		fallthrough;
1902 	case TDLS_SUPPORT_EXT_CONTROL:
1903 		clear_bit((unsigned long)source, &tdls_soc->tdls_source_bitmap);
1904 		/*
1905 		 * Check if any TDLS source bit is set and if
1906 		 * bitmap is not zero then we should not enable TDLS
1907 		 */
1908 		if (tdls_soc->tdls_source_bitmap) {
1909 			tdls_notice("Don't enable TDLS, source bitmap: %lu",
1910 				tdls_soc->tdls_source_bitmap);
1911 			return;
1912 		}
1913 		tdls_implicit_enable(tdls_vdev);
1914 		/*
1915 		 * tdls implicit mode is enabled, so enable the connection
1916 		 * tracker
1917 		 */
1918 		tdls_soc->enable_tdls_connection_tracker = true;
1919 
1920 		return;
1921 
1922 	case TDLS_SUPPORT_DISABLED:
1923 		set_bit((unsigned long)source,
1924 			&tdls_soc->tdls_source_bitmap);
1925 		tdls_implicit_disable(tdls_vdev);
1926 		/* If tdls implicit mode is disabled, then
1927 		 * stop the connection tracker.
1928 		 */
1929 		tdls_soc->enable_tdls_connection_tracker = false;
1930 
1931 		return;
1932 
1933 	case TDLS_SUPPORT_EXP_TRIG_ONLY:
1934 		clear_bit((unsigned long)source,
1935 			  &tdls_soc->tdls_source_bitmap);
1936 		tdls_implicit_disable(tdls_vdev);
1937 		/* If tdls implicit mode is disabled, then
1938 		 * stop the connection tracker.
1939 		 */
1940 		tdls_soc->enable_tdls_connection_tracker = false;
1941 
1942 		/*
1943 		 * Check if any TDLS source bit is set and if
1944 		 * bitmap is not zero then we should not
1945 		 * enable TDLS
1946 		 */
1947 		if (tdls_soc->tdls_source_bitmap)
1948 			return;
1949 
1950 		return;
1951 	default:
1952 		return;
1953 	}
1954 }
1955 
1956 /**
1957  * tdls_set_current_mode() - set TDLS mode
1958  * @tdls_soc: tdls soc object
1959  * @tdls_mode: TDLS mode
1960  * @update_last: indicate to record the last tdls mode
1961  * @source: TDLS disable source enum values
1962  *
1963  * Return: Void
1964  */
tdls_set_current_mode(struct tdls_soc_priv_obj * tdls_soc,enum tdls_feature_mode tdls_mode,bool update_last,enum tdls_disable_sources source)1965 static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc,
1966 				   enum tdls_feature_mode tdls_mode,
1967 				   bool update_last,
1968 				   enum tdls_disable_sources source)
1969 {
1970 	struct wlan_objmgr_vdev *vdev;
1971 	struct tdls_vdev_priv_obj *tdls_vdev;
1972 
1973 	if (!tdls_soc)
1974 		return;
1975 
1976 	tdls_debug("mode %d", (int)tdls_mode);
1977 
1978 	if (update_last)
1979 		tdls_soc->tdls_last_mode = tdls_mode;
1980 
1981 	if (tdls_soc->tdls_current_mode == tdls_mode) {
1982 		tdls_debug("already in mode %d", tdls_mode);
1983 
1984 		switch (tdls_mode) {
1985 		/* TDLS is already enabled hence clear source mask, return */
1986 		case TDLS_SUPPORT_IMP_MODE:
1987 		case TDLS_SUPPORT_EXP_TRIG_ONLY:
1988 		case TDLS_SUPPORT_EXT_CONTROL:
1989 			clear_bit((unsigned long)source,
1990 				  &tdls_soc->tdls_source_bitmap);
1991 			tdls_debug("clear source mask:%d", source);
1992 			return;
1993 		/* TDLS is already disabled hence set source mask, return */
1994 		case TDLS_SUPPORT_DISABLED:
1995 			set_bit((unsigned long)source,
1996 				&tdls_soc->tdls_source_bitmap);
1997 			tdls_debug("set source mask:%d", source);
1998 			return;
1999 		default:
2000 			return;
2001 		}
2002 	}
2003 
2004 	/* get sta vdev */
2005 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc,
2006 							QDF_STA_MODE,
2007 							WLAN_TDLS_NB_ID);
2008 	if (vdev) {
2009 		tdls_debug("set mode in tdls STA vdev:%d",
2010 			   wlan_vdev_get_id(vdev));
2011 		tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
2012 		if (tdls_vdev)
2013 			tdls_set_mode_in_vdev(tdls_vdev, tdls_soc,
2014 					      tdls_mode, source);
2015 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
2016 
2017 		goto exit;
2018 	}
2019 
2020 	/* get p2p client vdev */
2021 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc,
2022 							QDF_P2P_CLIENT_MODE,
2023 							WLAN_TDLS_NB_ID);
2024 	if (vdev) {
2025 		tdls_debug("set mode in tdls P2P cli vdev:%d",
2026 			   wlan_vdev_get_id(vdev));
2027 		tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
2028 		if (tdls_vdev)
2029 			tdls_set_mode_in_vdev(tdls_vdev, tdls_soc,
2030 					      tdls_mode, source);
2031 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
2032 	}
2033 
2034 exit:
2035 	if (!update_last)
2036 		tdls_soc->tdls_last_mode = tdls_soc->tdls_current_mode;
2037 
2038 	tdls_soc->tdls_current_mode = tdls_mode;
2039 }
2040 
tdls_set_operation_mode(struct tdls_set_mode_params * tdls_set_mode)2041 QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode)
2042 {
2043 	struct tdls_soc_priv_obj *tdls_soc;
2044 	struct tdls_vdev_priv_obj *tdls_vdev;
2045 	QDF_STATUS status;
2046 
2047 	if (!tdls_set_mode)
2048 		return QDF_STATUS_E_INVAL;
2049 
2050 	if (!tdls_set_mode->vdev) {
2051 		qdf_mem_free(tdls_set_mode);
2052 		return QDF_STATUS_E_INVAL;
2053 	}
2054 
2055 	status = tdls_get_vdev_objects(tdls_set_mode->vdev,
2056 				       &tdls_vdev, &tdls_soc);
2057 
2058 	if (QDF_IS_STATUS_ERROR(status))
2059 		goto release_mode_ref;
2060 
2061 	tdls_set_current_mode(tdls_soc,
2062 			      tdls_set_mode->tdls_mode,
2063 			      tdls_set_mode->update_last,
2064 			      tdls_set_mode->source);
2065 
2066 release_mode_ref:
2067 	wlan_objmgr_vdev_release_ref(tdls_set_mode->vdev, WLAN_TDLS_NB_ID);
2068 	qdf_mem_free(tdls_set_mode);
2069 	return status;
2070 }
2071 
2072 /**
2073  * tdls_scan_done_callback() - callback for tdls scan done event
2074  * @tdls_soc: tdls soc object
2075  *
2076  * Return: Void
2077  */
tdls_scan_done_callback(struct tdls_soc_priv_obj * tdls_soc)2078 void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc)
2079 {
2080 	if (!tdls_soc)
2081 		return;
2082 
2083 	/* if tdls was enabled before scan, re-enable tdls mode */
2084 	if (TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_last_mode ||
2085 	    TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_last_mode ||
2086 	    TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_last_mode)
2087 		tdls_set_current_mode(tdls_soc, tdls_soc->tdls_last_mode,
2088 				      false, TDLS_SET_MODE_SOURCE_SCAN);
2089 }
2090 
2091 /**
2092  * tdls_post_scan_done_msg() - post scan done message to tdls cmd queue
2093  * @tdls_soc: tdls soc object
2094  *
2095  * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_NULL_VALUE
2096  */
tdls_post_scan_done_msg(struct tdls_soc_priv_obj * tdls_soc)2097 static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc)
2098 {
2099 	struct scheduler_msg msg = {0, };
2100 
2101 	if (!tdls_soc) {
2102 		tdls_err("tdls_soc: %pK ", tdls_soc);
2103 		return QDF_STATUS_E_NULL_VALUE;
2104 	}
2105 
2106 	msg.bodyptr = tdls_soc;
2107 	msg.callback = tdls_process_cmd;
2108 	msg.flush_callback = tdls_post_msg_flush_cb;
2109 	msg.type = TDLS_CMD_SCAN_DONE;
2110 
2111 	return scheduler_post_message(QDF_MODULE_ID_TDLS,
2112 				      QDF_MODULE_ID_TDLS,
2113 				      QDF_MODULE_ID_OS_IF, &msg);
2114 }
2115 
tdls_scan_complete_event_handler(struct wlan_objmgr_vdev * vdev,struct scan_event * event,void * arg)2116 void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev,
2117 			struct scan_event *event,
2118 			void *arg)
2119 {
2120 	enum QDF_OPMODE device_mode;
2121 	struct tdls_soc_priv_obj *tdls_soc;
2122 
2123 	if (!vdev || !event || !arg)
2124 		return;
2125 
2126 	if (SCAN_EVENT_TYPE_COMPLETED != event->type)
2127 		return;
2128 
2129 	device_mode = wlan_vdev_mlme_get_opmode(vdev);
2130 
2131 	tdls_soc = (struct tdls_soc_priv_obj *) arg;
2132 	tdls_post_scan_done_msg(tdls_soc);
2133 }
2134 
tdls_set_link_unforce(struct wlan_objmgr_vdev * vdev)2135 void tdls_set_link_unforce(struct wlan_objmgr_vdev *vdev)
2136 {
2137 	QDF_STATUS status;
2138 	struct scheduler_msg msg = {0};
2139 
2140 	msg.callback = tdls_process_cmd;
2141 	msg.type = TDLS_CMD_SET_LINK_UNFORCE;
2142 	msg.bodyptr = vdev;
2143 	status = scheduler_post_message(QDF_MODULE_ID_TDLS,
2144 					QDF_MODULE_ID_TDLS,
2145 					QDF_MODULE_ID_OS_IF, &msg);
2146 	if (QDF_IS_STATUS_ERROR(status))
2147 		tdls_err("failed to set tdls link mode");
2148 }
2149 
2150 /**
2151  * tdls_check_peer_buf_capable() - Check buffer sta capable of tdls peers
2152  * @tdls_vdev: TDLS vdev object
2153  *
2154  * Used in scheduler thread context, no lock needed.
2155  *
2156  * Return: false if there is connected peer and not support buffer sta.
2157  */
tdls_check_peer_buf_capable(struct tdls_vdev_priv_obj * tdls_vdev)2158 static bool tdls_check_peer_buf_capable(struct tdls_vdev_priv_obj *tdls_vdev)
2159 {
2160 	uint16_t i;
2161 	struct tdls_peer *peer;
2162 	qdf_list_t *head;
2163 	qdf_list_node_t *p_node;
2164 	QDF_STATUS status;
2165 
2166 	if (!tdls_vdev) {
2167 		tdls_err("invalid tdls vdev object");
2168 		return false;
2169 	}
2170 
2171 	for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
2172 		head = &tdls_vdev->peer_list[i];
2173 
2174 		status = qdf_list_peek_front(head, &p_node);
2175 		while (QDF_IS_STATUS_SUCCESS(status)) {
2176 			peer = qdf_container_of(p_node, struct tdls_peer, node);
2177 
2178 			if (peer &&
2179 			    (TDLS_LINK_CONNECTED == peer->link_status) &&
2180 			    (!peer->buf_sta_capable))
2181 				return false;
2182 
2183 			status = qdf_list_peek_next(head, p_node, &p_node);
2184 		}
2185 	}
2186 
2187 	return true;
2188 }
2189 
tdls_scan_callback(struct tdls_soc_priv_obj * tdls_soc)2190 QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc)
2191 {
2192 	struct tdls_vdev_priv_obj *tdls_vdev;
2193 	struct wlan_objmgr_vdev *vdev;
2194 	uint16_t tdls_peer_count;
2195 	uint32_t feature;
2196 	bool peer_buf_capable;
2197 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2198 
2199 	/* if tdls is not enabled, then continue scan */
2200 	if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode)
2201 		return status;
2202 
2203 	/* Get the vdev based on vdev operating mode*/
2204 	vdev = tdls_get_vdev(tdls_soc->soc, WLAN_TDLS_NB_ID);
2205 	if (!vdev)
2206 		return status;
2207 
2208 	tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
2209 	if (!tdls_vdev)
2210 		goto  return_success;
2211 
2212 	if (tdls_is_progress(tdls_vdev, NULL, 0)) {
2213 		if (tdls_soc->scan_reject_count++ >= TDLS_SCAN_REJECT_MAX) {
2214 			tdls_notice("Allow this scan req. as already max no of scan's are rejected");
2215 			tdls_soc->scan_reject_count = 0;
2216 			status = QDF_STATUS_SUCCESS;
2217 
2218 		} else {
2219 			tdls_warn("tdls in progress. scan rejected %d",
2220 				  tdls_soc->scan_reject_count);
2221 			status = QDF_STATUS_E_BUSY;
2222 		}
2223 	}
2224 
2225 	tdls_peer_count = tdls_soc->connected_peer_count;
2226 	if (!tdls_peer_count)
2227 		goto disable_tdls;
2228 
2229 	feature = tdls_soc->tdls_configs.tdls_feature_flags;
2230 	if (TDLS_IS_SCAN_ENABLED(feature)) {
2231 		tdls_debug("TDLS Scan enabled, keep tdls link and allow scan, connected tdls peers: %d",
2232 			   tdls_peer_count);
2233 		goto disable_tdls;
2234 	}
2235 
2236 	if (TDLS_IS_BUFFER_STA_ENABLED(feature) &&
2237 	    (tdls_peer_count <= TDLS_MAX_CONNECTED_PEERS_TO_ALLOW_SCAN)) {
2238 		peer_buf_capable = tdls_check_peer_buf_capable(tdls_vdev);
2239 		if (peer_buf_capable) {
2240 			tdls_debug("All peers (num %d) bufSTAs, we can be sleep sta, so allow scan, tdls mode changed to %d",
2241 				   tdls_peer_count,
2242 				   tdls_soc->tdls_current_mode);
2243 			goto disable_tdls;
2244 		}
2245 	}
2246 
2247 	tdls_disable_offchan_and_teardown_links(vdev);
2248 
2249 disable_tdls:
2250 	tdls_set_current_mode(tdls_soc, TDLS_SUPPORT_DISABLED,
2251 			      false, TDLS_SET_MODE_SOURCE_SCAN);
2252 
2253 return_success:
2254 	wlan_objmgr_vdev_release_ref(vdev,
2255 				     WLAN_TDLS_NB_ID);
2256 	return status;
2257 }
2258 
tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev * vdev,union wlan_serialization_rules_info * comp_info,struct wlan_serialization_command * cmd)2259 void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev,
2260 		union wlan_serialization_rules_info *comp_info,
2261 		struct wlan_serialization_command *cmd)
2262 {
2263 	struct tdls_soc_priv_obj *tdls_soc;
2264 	QDF_STATUS status;
2265 	if (!comp_info)
2266 		return;
2267 
2268 	tdls_soc = tdls_soc_global;
2269 	comp_info->scan_info.is_tdls_in_progress = false;
2270 	status = tdls_scan_callback(tdls_soc);
2271 	if (QDF_STATUS_E_BUSY == status)
2272 		comp_info->scan_info.is_tdls_in_progress = true;
2273 }
2274 
tdls_find_opclass_frm_freq(struct wlan_objmgr_vdev * vdev,qdf_freq_t ch_freq,uint8_t bw_offset,uint16_t behav_limit)2275 static uint8_t tdls_find_opclass_frm_freq(struct wlan_objmgr_vdev *vdev,
2276 				   qdf_freq_t ch_freq, uint8_t bw_offset,
2277 				   uint16_t behav_limit)
2278 {
2279 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
2280 	uint8_t channel, opclass;
2281 
2282 	if (!pdev) {
2283 		tdls_err("pdev is NULL");
2284 		return 0;
2285 	}
2286 
2287 	wlan_reg_freq_width_to_chan_op_class(pdev, ch_freq, bw_offset, false,
2288 					     BIT(behav_limit), &opclass,
2289 					     &channel);
2290 
2291 	return opclass;
2292 }
2293 
tdls_get_opclass_from_bandwidth(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq,uint8_t bw_offset,uint8_t * reg_bw_offset)2294 uint8_t tdls_get_opclass_from_bandwidth(struct wlan_objmgr_vdev *vdev,
2295 					qdf_freq_t freq, uint8_t bw_offset,
2296 					uint8_t *reg_bw_offset)
2297 {
2298 	uint8_t opclass;
2299 
2300 	if (bw_offset &  (1 << BW_160_OFFSET_BIT)) {
2301 		opclass = tdls_find_opclass_frm_freq(vdev,
2302 						     freq, BW_160_MHZ,
2303 						     BEHAV_NONE);
2304 		*reg_bw_offset = BWALL;
2305 	} else if (bw_offset & (1 << BW_80_OFFSET_BIT)) {
2306 		opclass = tdls_find_opclass_frm_freq(vdev,
2307 						     freq, BW_80_MHZ,
2308 						     BEHAV_NONE);
2309 		*reg_bw_offset = BW80;
2310 	} else if (bw_offset & (1 << BW_40_OFFSET_BIT)) {
2311 		opclass = tdls_find_opclass_frm_freq(vdev,
2312 						     freq, BW_40_MHZ,
2313 						     BEHAV_BW40_LOW_PRIMARY);
2314 		*reg_bw_offset = BW40_LOW_PRIMARY;
2315 		if (!opclass) {
2316 			opclass = tdls_find_opclass_frm_freq(vdev,
2317 						     freq,
2318 						     BW_40_MHZ,
2319 						     BEHAV_BW40_HIGH_PRIMARY);
2320 			*reg_bw_offset = BW40_HIGH_PRIMARY;
2321 		}
2322 	} else if (bw_offset & (1 << BW_20_OFFSET_BIT)) {
2323 		opclass = tdls_find_opclass_frm_freq(vdev,
2324 						     freq, BW_20_MHZ,
2325 						     BEHAV_NONE);
2326 		*reg_bw_offset = BW20;
2327 	} else {
2328 		opclass = tdls_find_opclass_frm_freq(vdev,
2329 						     freq, BW_160_MHZ,
2330 						     BEHAV_NONE);
2331 		*reg_bw_offset = BWALL;
2332 	}
2333 
2334 	return opclass;
2335 }
2336