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