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 = ¬ify->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