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