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(&notify_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(&notify_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