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(¬ify_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(¬ify_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