1 /*
2 * Copyright (c) 2020, 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 any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 /*
19 * DOC: contains tdls link teardown definitions
20 */
21
22 #include "wlan_objmgr_psoc_obj.h"
23 #include "wlan_objmgr_pdev_obj.h"
24 #include "wlan_objmgr_vdev_obj.h"
25 #include "wlan_tdls_api.h"
26 #include "../../core/src/wlan_tdls_main.h"
27 #include "../../core/src/wlan_tdls_ct.h"
28 #include "../../core/src/wlan_tdls_mgmt.h"
29 #include "wlan_tdls_peer.h"
30 #include <wlan_objmgr_global_obj.h>
31 #include <wlan_objmgr_cmn.h>
32 #include "wlan_tdls_cfg_api.h"
33 #include "wlan_policy_mgr_api.h"
34 #include "wlan_mlo_mgr_sta.h"
35
tdls_teardown_flush_cb(struct scheduler_msg * msg)36 static QDF_STATUS tdls_teardown_flush_cb(struct scheduler_msg *msg)
37 {
38 struct tdls_link_teardown *tdls_teardown = msg->bodyptr;
39 struct wlan_objmgr_psoc *psoc = tdls_teardown->psoc;
40
41 wlan_objmgr_psoc_release_ref(psoc, WLAN_TDLS_SB_ID);
42 qdf_mem_free(tdls_teardown);
43
44 return QDF_STATUS_SUCCESS;
45 }
46
wlan_tdls_teardown_links(struct wlan_objmgr_psoc * psoc)47 QDF_STATUS wlan_tdls_teardown_links(struct wlan_objmgr_psoc *psoc)
48 {
49 QDF_STATUS status;
50 struct scheduler_msg msg = {0, };
51 struct tdls_link_teardown *link_teardown;
52
53 link_teardown = qdf_mem_malloc(sizeof(*link_teardown));
54 if (!link_teardown)
55 return QDF_STATUS_E_NOMEM;
56
57 wlan_objmgr_psoc_get_ref(psoc, WLAN_TDLS_SB_ID);
58 link_teardown->psoc = psoc;
59 msg.bodyptr = link_teardown;
60 msg.callback = tdls_process_cmd;
61 msg.flush_callback = tdls_teardown_flush_cb;
62 msg.type = TDLS_CMD_TEARDOWN_LINKS;
63
64 status = scheduler_post_message(QDF_MODULE_ID_HDD,
65 QDF_MODULE_ID_TDLS,
66 QDF_MODULE_ID_OS_IF, &msg);
67 if (QDF_IS_STATUS_ERROR(status)) {
68 tdls_err("post msg fail, %d", status);
69 wlan_objmgr_psoc_release_ref(psoc, WLAN_TDLS_SB_ID);
70 qdf_mem_free(link_teardown);
71 }
72
73 return status;
74 }
75
76 #ifdef WLAN_FEATURE_11BE_MLO
wlan_tdls_is_fw_11be_mlo_capable(struct wlan_objmgr_psoc * psoc)77 bool wlan_tdls_is_fw_11be_mlo_capable(struct wlan_objmgr_psoc *psoc)
78 {
79 struct tdls_soc_priv_obj *soc_obj;
80
81 soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
82 WLAN_UMAC_COMP_TDLS);
83 if (!soc_obj) {
84 tdls_err("Failed to get tdls psoc component");
85 return false;
86 }
87 tdls_debug("FW 11BE capability %d", soc_obj->fw_tdls_mlo_capable);
88
89 return soc_obj->fw_tdls_mlo_capable;
90 }
91 #endif
92
wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)93 static void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc,
94 struct wlan_objmgr_vdev *vdev)
95 {
96 struct tdls_vdev_priv_obj *vdev_priv_obj;
97 QDF_STATUS status;
98 struct wlan_objmgr_vdev *tdls_vdev;
99
100 tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
101 if (!tdls_vdev)
102 return;
103
104 vdev_priv_obj = wlan_vdev_get_tdls_vdev_obj(tdls_vdev);
105 if (!vdev_priv_obj) {
106 tdls_err("vdev priv is NULL");
107 goto release_ref;
108 }
109
110 qdf_event_reset(&vdev_priv_obj->tdls_teardown_comp);
111
112 status = wlan_tdls_teardown_links(psoc);
113 if (QDF_IS_STATUS_ERROR(status)) {
114 tdls_err("wlan_tdls_teardown_links failed err %d", status);
115 goto release_ref;
116 }
117
118 tdls_debug("vdev:%d Wait for tdls teardown completion. Timeout %u ms",
119 wlan_vdev_get_id(tdls_vdev),
120 WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS);
121
122 status = qdf_wait_for_event_completion(
123 &vdev_priv_obj->tdls_teardown_comp,
124 WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS);
125 if (QDF_IS_STATUS_ERROR(status)) {
126 tdls_err(" Teardown Completion timed out %d", status);
127 goto release_ref;
128 }
129
130 tdls_debug("TDLS teardown completion status %d ", status);
131
132 release_ref:
133 wlan_objmgr_vdev_release_ref(tdls_vdev,
134 WLAN_TDLS_NB_ID);
135 }
136
wlan_tdls_check_and_teardown_links_sync(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)137 void wlan_tdls_check_and_teardown_links_sync(struct wlan_objmgr_psoc *psoc,
138 struct wlan_objmgr_vdev *vdev)
139 {
140 uint8_t sta_count;
141 enum QDF_OPMODE opmode;
142 bool tgt_tdls_concurrency_supported;
143
144 tgt_tdls_concurrency_supported =
145 wlan_psoc_nif_fw_ext2_cap_get(psoc,
146 WLAN_TDLS_CONCURRENCIES_SUPPORT);
147 /* Don't initiate teardown in case of STA + P2P Client concurreny */
148 sta_count = policy_mgr_mode_specific_connection_count(psoc,
149 PM_STA_MODE,
150 NULL);
151 opmode = wlan_vdev_mlme_get_opmode(vdev);
152 if (tgt_tdls_concurrency_supported && opmode == QDF_P2P_CLIENT_MODE &&
153 sta_count) {
154 tdls_debug("Don't teardown tdls for existing STA vdev");
155 return;
156 }
157
158 wlan_tdls_teardown_links_sync(psoc, vdev);
159 }
160
161 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
wlan_tdls_handle_sap_start(struct wlan_objmgr_psoc * psoc)162 static void wlan_tdls_handle_sap_start(struct wlan_objmgr_psoc *psoc)
163 {
164 QDF_STATUS status;
165 struct scheduler_msg msg = {0};
166
167 msg.callback = tdls_process_cmd;
168 msg.type = TDLS_CMD_START_BSS;
169 msg.bodyptr = psoc;
170 status = scheduler_post_message(QDF_MODULE_ID_TDLS,
171 QDF_MODULE_ID_TDLS,
172 QDF_MODULE_ID_TARGET_IF, &msg);
173 if (QDF_IS_STATUS_ERROR(status)) {
174 tdls_err("post start bss msg fail");
175 return;
176 }
177 }
178
wlan_tdls_notify_channel_switch_complete(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)179 void wlan_tdls_notify_channel_switch_complete(struct wlan_objmgr_psoc *psoc,
180 uint8_t vdev_id)
181 {
182 struct wlan_objmgr_vdev *tdls_vdev;
183 struct tdls_vdev_priv_obj *tdls_vdev_priv;
184 struct tdls_soc_priv_obj *tdls_soc_priv;
185 QDF_STATUS status;
186
187 tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
188 if (!tdls_vdev)
189 return;
190
191 status = tdls_get_vdev_objects(tdls_vdev, &tdls_vdev_priv,
192 &tdls_soc_priv);
193 if (QDF_IS_STATUS_ERROR(status)) {
194 tdls_err("Failed to get TDLS objects");
195 goto exit;
196 }
197
198 tdls_debug("CSA complete");
199 /*
200 * Channel Switch can cause SCC -> MCC switch on
201 * STA vdev. Disable TDLS if CSA causes STA vdev to be in MCC with
202 * other vdev.
203 */
204 if (!tdls_is_concurrency_allowed(psoc)) {
205 tdls_disable_offchan_and_teardown_links(tdls_vdev);
206 tdls_debug("Disable the tdls in FW after CSA");
207 } else {
208 tdls_process_enable_for_vdev(tdls_vdev);
209 tdls_set_tdls_offchannelmode(tdls_vdev, ENABLE_CHANSWITCH);
210 }
211
212 exit:
213 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
214 }
215
216 static QDF_STATUS
wlan_tdls_post_set_off_channel_mode(struct wlan_objmgr_psoc * psoc,uint8_t off_chan_mode)217 wlan_tdls_post_set_off_channel_mode(struct wlan_objmgr_psoc *psoc,
218 uint8_t off_chan_mode)
219 {
220 struct wlan_objmgr_vdev *tdls_vdev;
221 struct tdls_vdev_priv_obj *tdls_vdev_priv;
222 struct tdls_soc_priv_obj *tdls_soc_priv;
223 struct tdls_set_offchanmode *req;
224 struct scheduler_msg msg = {0};
225 QDF_STATUS status;
226
227 tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
228 if (!tdls_vdev)
229 return QDF_STATUS_E_FAILURE;
230
231 status = tdls_get_vdev_objects(tdls_vdev, &tdls_vdev_priv,
232 &tdls_soc_priv);
233 if (QDF_IS_STATUS_ERROR(status)) {
234 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
235 tdls_err("Failed to get TDLS objects");
236 return QDF_STATUS_E_FAILURE;
237 }
238
239 req = qdf_mem_malloc(sizeof(*req));
240 if (!req) {
241 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
242 return QDF_STATUS_E_NOMEM;
243 }
244
245 req->offchan_mode = off_chan_mode;
246 req->vdev = tdls_vdev;
247 req->callback = wlan_tdls_offchan_parms_callback;
248
249 msg.callback = tdls_process_cmd;
250 msg.type = TDLS_CMD_SET_OFFCHANMODE;
251 msg.bodyptr = req;
252
253 status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS,
254 QDF_MODULE_ID_TARGET_IF, &msg);
255 if (QDF_IS_STATUS_ERROR(status)) {
256 tdls_err("post set offchanmode msg fail");
257 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
258 qdf_mem_free(req);
259 }
260
261 return QDF_STATUS_SUCCESS;
262 }
263
wlan_tdls_notify_channel_switch_start(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)264 void wlan_tdls_notify_channel_switch_start(struct wlan_objmgr_psoc *psoc,
265 struct wlan_objmgr_vdev *vdev)
266 {
267 tdls_debug("Send Channel Switch start to TDLS module");
268 wlan_tdls_post_set_off_channel_mode(psoc, DISABLE_ACTIVE_CHANSWITCH);
269 }
270
wlan_tdls_handle_p2p_client_connect(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)271 void wlan_tdls_handle_p2p_client_connect(struct wlan_objmgr_psoc *psoc,
272 struct wlan_objmgr_vdev *vdev)
273 {
274 if (!policy_mgr_get_connection_count(psoc))
275 return;
276
277 /*
278 * Disable TDLS off-channel when P2P CLI comes up as
279 * 3rd interface. It will be re-enabled based on the
280 * concurrency once P2P connection is complete
281 */
282 wlan_tdls_post_set_off_channel_mode(psoc, DISABLE_ACTIVE_CHANSWITCH);
283 }
284 #else
285 static inline void
wlan_tdls_handle_sap_start(struct wlan_objmgr_psoc * psoc)286 wlan_tdls_handle_sap_start(struct wlan_objmgr_psoc *psoc)
287 {}
288 #endif
289
290 #ifdef WLAN_FEATURE_11BE_MLO
291 static QDF_STATUS
wlan_mlo_is_tdls_session_present(struct wlan_objmgr_vdev * vdev)292 wlan_mlo_is_tdls_session_present(struct wlan_objmgr_vdev *vdev)
293 {
294 uint8_t i;
295 struct wlan_mlo_dev_context *ml_dev = vdev->mlo_dev_ctx;
296
297 if (!ml_dev) {
298 tdls_err("MLO dev ctx is null");
299 return QDF_STATUS_E_FAILURE;
300 }
301
302 for (i = 0; i < ml_dev->wlan_vdev_count; i++) {
303 vdev = ml_dev->wlan_vdev_list[i];
304 if (tdls_get_connected_peer_count_from_vdev(vdev) > 0) {
305 tdls_debug("TDLS session is present");
306 return QDF_STATUS_SUCCESS;
307 }
308 }
309
310 return QDF_STATUS_E_INVAL;
311 }
312 #else
313 static QDF_STATUS
wlan_mlo_is_tdls_session_present(struct wlan_objmgr_vdev * vdev)314 wlan_mlo_is_tdls_session_present(struct wlan_objmgr_vdev *vdev)
315 {
316 return QDF_STATUS_E_INVAL;
317 }
318 #endif
319
320 QDF_STATUS
wlan_is_tdls_session_present(struct wlan_objmgr_vdev * vdev)321 wlan_is_tdls_session_present(struct wlan_objmgr_vdev *vdev)
322 {
323 if (mlo_is_mld_sta(vdev))
324 return wlan_mlo_is_tdls_session_present(vdev);
325
326 if (tdls_get_connected_peer_count_from_vdev(vdev) > 0) {
327 tdls_debug("TDLS session is present");
328 return QDF_STATUS_SUCCESS;
329 }
330
331 return QDF_STATUS_E_INVAL;
332 }
333
wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)334 void wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc *psoc,
335 struct wlan_objmgr_vdev *vdev)
336 {
337 if (tdls_is_concurrency_allowed(psoc)) {
338 wlan_tdls_handle_sap_start(psoc);
339 return;
340 }
341
342 wlan_tdls_check_and_teardown_links_sync(psoc, vdev);
343 }
344
wlan_tdls_notify_start_bss_failure(struct wlan_objmgr_psoc * psoc)345 void wlan_tdls_notify_start_bss_failure(struct wlan_objmgr_psoc *psoc)
346 {
347 tdls_notify_decrement_session(psoc);
348 }
349
tdls_notify_flush_cb(struct scheduler_msg * msg)350 static QDF_STATUS tdls_notify_flush_cb(struct scheduler_msg *msg)
351 {
352 struct tdls_sta_notify_params *notify = msg->bodyptr;
353 struct wlan_objmgr_vdev *vdev = notify->vdev;
354
355 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
356 qdf_mem_free(notify);
357
358 return QDF_STATUS_SUCCESS;
359 }
360
361 static QDF_STATUS
tdls_notify_disconnect(struct tdls_sta_notify_params * notify_info)362 tdls_notify_disconnect(struct tdls_sta_notify_params *notify_info)
363 {
364 struct scheduler_msg msg = {0, };
365 struct tdls_sta_notify_params *notify;
366 QDF_STATUS status;
367
368 if (!notify_info || !notify_info->vdev) {
369 tdls_err("notify_info %pK", notify_info);
370 return QDF_STATUS_E_NULL_VALUE;
371 }
372
373 tdls_debug("Enter ");
374
375 notify = qdf_mem_malloc(sizeof(*notify));
376 if (!notify) {
377 wlan_objmgr_vdev_release_ref(notify_info->vdev, WLAN_TDLS_NB_ID);
378 return QDF_STATUS_E_NULL_VALUE;
379 }
380
381 *notify = *notify_info;
382
383 msg.bodyptr = notify;
384 msg.callback = tdls_process_cmd;
385 msg.type = TDLS_NOTIFY_STA_DISCONNECTION;
386 msg.flush_callback = tdls_notify_flush_cb;
387 status = scheduler_post_message(QDF_MODULE_ID_HDD,
388 QDF_MODULE_ID_TDLS,
389 QDF_MODULE_ID_TARGET_IF, &msg);
390 if (QDF_IS_STATUS_ERROR(status)) {
391 wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
392 qdf_mem_free(notify);
393 }
394
395 tdls_debug("Exit ");
396
397 return QDF_STATUS_SUCCESS;
398 }
399
wlan_tdls_notify_sta_disconnect(uint8_t vdev_id,bool lfr_roam,bool user_disconnect,struct wlan_objmgr_vdev * vdev)400 void wlan_tdls_notify_sta_disconnect(uint8_t vdev_id,
401 bool lfr_roam, bool user_disconnect,
402 struct wlan_objmgr_vdev *vdev)
403 {
404 struct tdls_sta_notify_params notify_info = {0};
405 QDF_STATUS status;
406
407 if (!vdev) {
408 tdls_err("vdev is NULL");
409 return;
410 }
411
412 status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
413 if (QDF_IS_STATUS_ERROR(status)) {
414 tdls_err("can't get vdev");
415 return;
416 }
417
418 notify_info.session_id = vdev_id;
419 notify_info.lfr_roam = lfr_roam;
420 notify_info.tdls_chan_swit_prohibited = false;
421 notify_info.tdls_prohibited = false;
422 notify_info.vdev = vdev;
423 notify_info.user_disconnect = user_disconnect;
424 tdls_notify_disconnect(¬ify_info);
425 }
426
427 static QDF_STATUS
tdls_notify_connect(struct tdls_sta_notify_params * notify_info)428 tdls_notify_connect(struct tdls_sta_notify_params *notify_info)
429 {
430 struct scheduler_msg msg = {0, };
431 struct tdls_sta_notify_params *notify;
432 QDF_STATUS status;
433
434 if (!notify_info || !notify_info->vdev) {
435 tdls_err("notify_info %pK", notify_info);
436 return QDF_STATUS_E_NULL_VALUE;
437 }
438 tdls_debug("Enter ");
439
440 notify = qdf_mem_malloc(sizeof(*notify));
441 if (!notify) {
442 wlan_objmgr_vdev_release_ref(notify_info->vdev,
443 WLAN_TDLS_NB_ID);
444 return QDF_STATUS_E_NULL_VALUE;
445 }
446
447 *notify = *notify_info;
448
449 msg.bodyptr = notify;
450 msg.callback = tdls_process_cmd;
451 msg.type = TDLS_NOTIFY_STA_CONNECTION;
452 msg.flush_callback = tdls_notify_flush_cb;
453 status = scheduler_post_message(QDF_MODULE_ID_HDD,
454 QDF_MODULE_ID_TDLS,
455 QDF_MODULE_ID_TARGET_IF, &msg);
456 if (QDF_IS_STATUS_ERROR(status)) {
457 wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
458 qdf_mem_free(notify);
459 }
460
461 tdls_debug("Exit ");
462 return status;
463 }
464
465 void
wlan_tdls_notify_sta_connect(uint8_t session_id,bool tdls_chan_swit_prohibited,bool tdls_prohibited,struct wlan_objmgr_vdev * vdev)466 wlan_tdls_notify_sta_connect(uint8_t session_id,
467 bool tdls_chan_swit_prohibited,
468 bool tdls_prohibited,
469 struct wlan_objmgr_vdev *vdev)
470 {
471 struct tdls_sta_notify_params notify_info = {0};
472 QDF_STATUS status;
473
474 if (!vdev) {
475 tdls_err("vdev is NULL");
476 return;
477 }
478 status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
479 if (QDF_IS_STATUS_ERROR(status)) {
480 tdls_err("can't get vdev");
481 return;
482 }
483
484 notify_info.session_id = session_id;
485 notify_info.vdev = vdev;
486 notify_info.tdls_chan_swit_prohibited = tdls_chan_swit_prohibited;
487 notify_info.tdls_prohibited = tdls_prohibited;
488 tdls_notify_connect(¬ify_info);
489 }
490
491 #ifdef FEATURE_SET
wlan_tdls_get_features_info(struct wlan_objmgr_psoc * psoc,struct wlan_tdls_features * tdls_feature_set)492 void wlan_tdls_get_features_info(struct wlan_objmgr_psoc *psoc,
493 struct wlan_tdls_features *tdls_feature_set)
494 {
495 cfg_tdls_get_support_enable(psoc, &tdls_feature_set->enable_tdls);
496 if (tdls_feature_set->enable_tdls) {
497 cfg_tdls_get_off_channel_enable(
498 psoc,
499 &tdls_feature_set->enable_tdls_offchannel);
500 tdls_feature_set->max_tdls_peers =
501 cfg_tdls_get_max_peer_count(psoc);
502 tdls_feature_set->enable_tdls_capability_enhance = true;
503 }
504 }
505 #endif
506
wlan_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * mac_addr)507 void wlan_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
508 struct qdf_mac_addr *mac_addr)
509 {
510 tdls_update_tx_pkt_cnt(vdev, mac_addr);
511 }
512
wlan_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * mac_addr,struct qdf_mac_addr * dest_mac_addr)513 void wlan_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
514 struct qdf_mac_addr *mac_addr,
515 struct qdf_mac_addr *dest_mac_addr)
516 {
517 tdls_update_rx_pkt_cnt(vdev, mac_addr, dest_mac_addr);
518 }
519
wlan_tdls_increment_discovery_attempts(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t * peer_addr)520 void wlan_tdls_increment_discovery_attempts(struct wlan_objmgr_psoc *psoc,
521 uint8_t vdev_id,
522 uint8_t *peer_addr)
523 {
524 struct tdls_soc_priv_obj *tdls_soc_obj;
525 struct tdls_vdev_priv_obj *tdls_vdev_obj;
526 struct tdls_peer *peer;
527 struct wlan_objmgr_vdev *vdev;
528 QDF_STATUS status;
529
530 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
531 WLAN_TDLS_NB_ID);
532 if (!vdev)
533 return;
534
535 status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
536 if (QDF_IS_STATUS_ERROR(status)) {
537 tdls_err("Failed to get TDLS objects");
538 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
539 return;
540 }
541
542 peer = tdls_get_peer(tdls_vdev_obj, peer_addr);
543 if (!peer) {
544 tdls_err("tdls_peer is NULL");
545 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
546 return;
547 }
548
549 peer->discovery_attempt++;
550 tdls_debug("vdev:%d peer: " QDF_MAC_ADDR_FMT " discovery attempts:%d ", vdev_id,
551 QDF_MAC_ADDR_REF(peer_addr), peer->discovery_attempt);
552
553 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
554 }
555