1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name *
5*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name * above copyright notice and this permission notice appear in all
8*5113495bSYour Name * copies.
9*5113495bSYour Name *
10*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name */
19*5113495bSYour Name
20*5113495bSYour Name /**
21*5113495bSYour Name * DOC: contains interface definitions for OS_IF layer
22*5113495bSYour Name */
23*5113495bSYour Name
24*5113495bSYour Name #include "nan_ucfg_api.h"
25*5113495bSYour Name #include "nan_public_structs.h"
26*5113495bSYour Name #include "wlan_nan_api.h"
27*5113495bSYour Name #include "../../core/src/nan_main_i.h"
28*5113495bSYour Name #include "scheduler_api.h"
29*5113495bSYour Name #include "wlan_objmgr_psoc_obj.h"
30*5113495bSYour Name #include "wlan_objmgr_pdev_obj.h"
31*5113495bSYour Name #include "wlan_objmgr_vdev_obj.h"
32*5113495bSYour Name #include "wlan_osif_request_manager.h"
33*5113495bSYour Name #include "wlan_policy_mgr_api.h"
34*5113495bSYour Name #include "cfg_ucfg_api.h"
35*5113495bSYour Name #include "cfg_nan.h"
36*5113495bSYour Name #include "wlan_mlme_api.h"
37*5113495bSYour Name #include "cfg_nan_api.h"
38*5113495bSYour Name #include "wlan_tdls_ucfg_api.h"
39*5113495bSYour Name #include "wlan_nan_api_i.h"
40*5113495bSYour Name
41*5113495bSYour Name struct wlan_objmgr_psoc;
42*5113495bSYour Name struct wlan_objmgr_vdev;
43*5113495bSYour Name
44*5113495bSYour Name #ifdef WLAN_FEATURE_NAN
45*5113495bSYour Name /**
46*5113495bSYour Name * nan_cfg_init() - Initialize NAN config params
47*5113495bSYour Name * @psoc: Pointer to PSOC Object
48*5113495bSYour Name * @nan_obj: Pointer to NAN private object
49*5113495bSYour Name *
50*5113495bSYour Name * This function initialize NAN config params
51*5113495bSYour Name */
nan_cfg_init(struct wlan_objmgr_psoc * psoc,struct nan_psoc_priv_obj * nan_obj)52*5113495bSYour Name static void nan_cfg_init(struct wlan_objmgr_psoc *psoc,
53*5113495bSYour Name struct nan_psoc_priv_obj *nan_obj)
54*5113495bSYour Name {
55*5113495bSYour Name nan_obj->cfg_param.enable = cfg_get(psoc, CFG_NAN_ENABLE);
56*5113495bSYour Name nan_obj->cfg_param.support_mp0_discovery =
57*5113495bSYour Name cfg_get(psoc,
58*5113495bSYour Name CFG_SUPPORT_MP0_DISCOVERY);
59*5113495bSYour Name nan_obj->cfg_param.ndp_keep_alive_period =
60*5113495bSYour Name cfg_get(psoc,
61*5113495bSYour Name CFG_NDP_KEEP_ALIVE_PERIOD);
62*5113495bSYour Name nan_obj->cfg_param.max_ndp_sessions = cfg_get(psoc,
63*5113495bSYour Name CFG_NDP_MAX_SESSIONS);
64*5113495bSYour Name nan_obj->cfg_param.max_ndi = cfg_get(psoc, CFG_NDI_MAX_SUPPORT);
65*5113495bSYour Name nan_obj->cfg_param.nan_feature_config =
66*5113495bSYour Name cfg_get(psoc, CFG_NAN_FEATURE_CONFIG);
67*5113495bSYour Name nan_obj->cfg_param.disable_6g_nan = cfg_get(psoc, CFG_DISABLE_6G_NAN);
68*5113495bSYour Name nan_obj->cfg_param.enable_nan_eht_cap =
69*5113495bSYour Name cfg_get(psoc, CFG_NAN_ENABLE_EHT_CAP);
70*5113495bSYour Name }
71*5113495bSYour Name
72*5113495bSYour Name /**
73*5113495bSYour Name * nan_cfg_dp_init() - Initialize NAN Datapath config params
74*5113495bSYour Name * @psoc: Pointer to PSOC Object
75*5113495bSYour Name * @nan_obj: Pointer to NAN private object
76*5113495bSYour Name *
77*5113495bSYour Name * This function initialize NAN config params
78*5113495bSYour Name */
nan_cfg_dp_init(struct wlan_objmgr_psoc * psoc,struct nan_psoc_priv_obj * nan_obj)79*5113495bSYour Name static void nan_cfg_dp_init(struct wlan_objmgr_psoc *psoc,
80*5113495bSYour Name struct nan_psoc_priv_obj *nan_obj)
81*5113495bSYour Name {
82*5113495bSYour Name nan_obj->cfg_param.dp_enable = cfg_get(psoc,
83*5113495bSYour Name CFG_NAN_DATAPATH_ENABLE);
84*5113495bSYour Name nan_obj->cfg_param.ndi_mac_randomize =
85*5113495bSYour Name cfg_get(psoc, CFG_NAN_RANDOMIZE_NDI_MAC);
86*5113495bSYour Name nan_obj->cfg_param.ndp_inactivity_timeout =
87*5113495bSYour Name cfg_get(psoc, CFG_NAN_NDP_INACTIVITY_TIMEOUT);
88*5113495bSYour Name nan_obj->cfg_param.nan_separate_iface_support =
89*5113495bSYour Name cfg_get(psoc, CFG_NAN_SEPARATE_IFACE_SUPP);
90*5113495bSYour Name
91*5113495bSYour Name }
92*5113495bSYour Name #else
nan_cfg_init(struct wlan_objmgr_psoc * psoc,struct nan_psoc_priv_obj * nan_obj)93*5113495bSYour Name static void nan_cfg_init(struct wlan_objmgr_psoc *psoc,
94*5113495bSYour Name struct nan_psoc_priv_obj *nan_obj)
95*5113495bSYour Name {
96*5113495bSYour Name }
97*5113495bSYour Name
nan_cfg_dp_init(struct wlan_objmgr_psoc * psoc,struct nan_psoc_priv_obj * nan_obj)98*5113495bSYour Name static void nan_cfg_dp_init(struct wlan_objmgr_psoc *psoc,
99*5113495bSYour Name struct nan_psoc_priv_obj *nan_obj)
100*5113495bSYour Name {
101*5113495bSYour Name }
102*5113495bSYour Name #endif
103*5113495bSYour Name
ucfg_get_disable_6g_nan(struct wlan_objmgr_psoc * psoc)104*5113495bSYour Name bool ucfg_get_disable_6g_nan(struct wlan_objmgr_psoc *psoc)
105*5113495bSYour Name {
106*5113495bSYour Name struct nan_psoc_priv_obj *nan_obj = nan_get_psoc_priv_obj(psoc);
107*5113495bSYour Name
108*5113495bSYour Name if (!nan_obj) {
109*5113495bSYour Name nan_err("nan psoc priv object is NULL");
110*5113495bSYour Name return cfg_default(CFG_DISABLE_6G_NAN);
111*5113495bSYour Name }
112*5113495bSYour Name
113*5113495bSYour Name return nan_obj->cfg_param.disable_6g_nan;
114*5113495bSYour Name }
115*5113495bSYour Name
ucfg_nan_psoc_open(struct wlan_objmgr_psoc * psoc)116*5113495bSYour Name QDF_STATUS ucfg_nan_psoc_open(struct wlan_objmgr_psoc *psoc)
117*5113495bSYour Name {
118*5113495bSYour Name struct nan_psoc_priv_obj *nan_obj = nan_get_psoc_priv_obj(psoc);
119*5113495bSYour Name
120*5113495bSYour Name if (!nan_obj) {
121*5113495bSYour Name nan_err("nan psoc priv object is NULL");
122*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
123*5113495bSYour Name }
124*5113495bSYour Name
125*5113495bSYour Name nan_cfg_init(psoc, nan_obj);
126*5113495bSYour Name nan_cfg_dp_init(psoc, nan_obj);
127*5113495bSYour Name
128*5113495bSYour Name return QDF_STATUS_SUCCESS;
129*5113495bSYour Name }
130*5113495bSYour Name
ucfg_nan_psoc_close(struct wlan_objmgr_psoc * psoc)131*5113495bSYour Name void ucfg_nan_psoc_close(struct wlan_objmgr_psoc *psoc)
132*5113495bSYour Name {
133*5113495bSYour Name /* No cleanup required on psoc close for NAN */
134*5113495bSYour Name }
135*5113495bSYour Name
__ucfg_nan_set_ndi_state(struct wlan_objmgr_vdev * vdev,enum nan_datapath_state state,const char * func)136*5113495bSYour Name inline QDF_STATUS __ucfg_nan_set_ndi_state(struct wlan_objmgr_vdev *vdev,
137*5113495bSYour Name enum nan_datapath_state state,
138*5113495bSYour Name const char *func)
139*5113495bSYour Name {
140*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
141*5113495bSYour Name enum nan_datapath_state current_state;
142*5113495bSYour Name
143*5113495bSYour Name if (!priv_obj) {
144*5113495bSYour Name nan_err("priv_obj is null");
145*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
146*5113495bSYour Name }
147*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
148*5113495bSYour Name current_state = priv_obj->state;
149*5113495bSYour Name priv_obj->state = state;
150*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
151*5113495bSYour Name nan_nofl_debug("%s: ndi state: current: %u, new: %u", func,
152*5113495bSYour Name current_state, state);
153*5113495bSYour Name
154*5113495bSYour Name return QDF_STATUS_SUCCESS;
155*5113495bSYour Name }
156*5113495bSYour Name
ucfg_nan_get_ndi_state(struct wlan_objmgr_vdev * vdev)157*5113495bSYour Name inline enum nan_datapath_state ucfg_nan_get_ndi_state(
158*5113495bSYour Name struct wlan_objmgr_vdev *vdev)
159*5113495bSYour Name {
160*5113495bSYour Name return wlan_nan_get_ndi_state(vdev);
161*5113495bSYour Name }
162*5113495bSYour Name
ucfg_nan_set_active_peers(struct wlan_objmgr_vdev * vdev,uint32_t val)163*5113495bSYour Name inline QDF_STATUS ucfg_nan_set_active_peers(struct wlan_objmgr_vdev *vdev,
164*5113495bSYour Name uint32_t val)
165*5113495bSYour Name {
166*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
167*5113495bSYour Name
168*5113495bSYour Name if (!priv_obj) {
169*5113495bSYour Name nan_err("priv_obj is null");
170*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
171*5113495bSYour Name }
172*5113495bSYour Name
173*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
174*5113495bSYour Name priv_obj->active_ndp_peers = val;
175*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
176*5113495bSYour Name
177*5113495bSYour Name return QDF_STATUS_SUCCESS;
178*5113495bSYour Name }
179*5113495bSYour Name
180*5113495bSYour Name /**
181*5113495bSYour Name * ucfg_nan_update_mc_list() - update the multicast list
182*5113495bSYour Name * @vdev: Pointer to VDEV Object
183*5113495bSYour Name *
184*5113495bSYour Name * This function will update the multicast list for NDP peer
185*5113495bSYour Name */
ucfg_nan_update_mc_list(struct wlan_objmgr_vdev * vdev)186*5113495bSYour Name static void ucfg_nan_update_mc_list(struct wlan_objmgr_vdev *vdev)
187*5113495bSYour Name {
188*5113495bSYour Name struct nan_callbacks cb_obj;
189*5113495bSYour Name QDF_STATUS status;
190*5113495bSYour Name struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
191*5113495bSYour Name
192*5113495bSYour Name if (!psoc) {
193*5113495bSYour Name nan_err("psoc is null");
194*5113495bSYour Name return;
195*5113495bSYour Name }
196*5113495bSYour Name
197*5113495bSYour Name status = ucfg_nan_get_callbacks(psoc, &cb_obj);
198*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
199*5113495bSYour Name nan_err("Couldn't get callback object");
200*5113495bSYour Name return;
201*5113495bSYour Name }
202*5113495bSYour Name
203*5113495bSYour Name if (!cb_obj.set_mc_list) {
204*5113495bSYour Name nan_err("set_mc_list callback not registered");
205*5113495bSYour Name return;
206*5113495bSYour Name }
207*5113495bSYour Name
208*5113495bSYour Name cb_obj.set_mc_list(vdev);
209*5113495bSYour Name }
210*5113495bSYour Name
ucfg_nan_set_peer_mc_list(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr peer_mac_addr)211*5113495bSYour Name inline void ucfg_nan_set_peer_mc_list(struct wlan_objmgr_vdev *vdev,
212*5113495bSYour Name struct qdf_mac_addr peer_mac_addr)
213*5113495bSYour Name {
214*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
215*5113495bSYour Name uint32_t max_ndp_sessions = 0;
216*5113495bSYour Name struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
217*5113495bSYour Name int i, list_idx = 0;
218*5113495bSYour Name
219*5113495bSYour Name if (!priv_obj) {
220*5113495bSYour Name nan_err("priv_obj is null");
221*5113495bSYour Name return;
222*5113495bSYour Name }
223*5113495bSYour Name
224*5113495bSYour Name if (!psoc) {
225*5113495bSYour Name nan_err("psoc is null");
226*5113495bSYour Name return;
227*5113495bSYour Name }
228*5113495bSYour Name
229*5113495bSYour Name cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions);
230*5113495bSYour Name
231*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
232*5113495bSYour Name for (i = 0; i < max_ndp_sessions; i++) {
233*5113495bSYour Name if (qdf_is_macaddr_zero(&priv_obj->peer_mc_addr_list[i])) {
234*5113495bSYour Name list_idx = i;
235*5113495bSYour Name break;
236*5113495bSYour Name }
237*5113495bSYour Name }
238*5113495bSYour Name if (list_idx == max_ndp_sessions) {
239*5113495bSYour Name nan_err("Peer multicast address list is full");
240*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
241*5113495bSYour Name }
242*5113495bSYour Name /* Derive peer multicast addr */
243*5113495bSYour Name peer_mac_addr.bytes[0] = 0x33;
244*5113495bSYour Name peer_mac_addr.bytes[1] = 0x33;
245*5113495bSYour Name peer_mac_addr.bytes[2] = 0xff;
246*5113495bSYour Name priv_obj->peer_mc_addr_list[list_idx] = peer_mac_addr;
247*5113495bSYour Name
248*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
249*5113495bSYour Name
250*5113495bSYour Name ucfg_nan_update_mc_list(vdev);
251*5113495bSYour Name }
252*5113495bSYour Name
ucfg_nan_get_peer_mc_list(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr ** peer_mc_addr_list)253*5113495bSYour Name inline void ucfg_nan_get_peer_mc_list(
254*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
255*5113495bSYour Name struct qdf_mac_addr **peer_mc_addr_list)
256*5113495bSYour Name {
257*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
258*5113495bSYour Name
259*5113495bSYour Name if (!priv_obj) {
260*5113495bSYour Name nan_err("priv_obj is null");
261*5113495bSYour Name return;
262*5113495bSYour Name }
263*5113495bSYour Name
264*5113495bSYour Name *peer_mc_addr_list = priv_obj->peer_mc_addr_list;
265*5113495bSYour Name }
266*5113495bSYour Name
ucfg_nan_clear_peer_mc_list(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * peer_mac_addr)267*5113495bSYour Name inline void ucfg_nan_clear_peer_mc_list(struct wlan_objmgr_psoc *psoc,
268*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
269*5113495bSYour Name struct qdf_mac_addr *peer_mac_addr)
270*5113495bSYour Name {
271*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
272*5113495bSYour Name int i;
273*5113495bSYour Name uint32_t max_ndp_sessions = 0;
274*5113495bSYour Name struct qdf_mac_addr derived_peer_mc_addr;
275*5113495bSYour Name
276*5113495bSYour Name if (!priv_obj) {
277*5113495bSYour Name nan_err("priv_obj is null");
278*5113495bSYour Name return;
279*5113495bSYour Name }
280*5113495bSYour Name
281*5113495bSYour Name /* Derive peer multicast addr */
282*5113495bSYour Name derived_peer_mc_addr = *peer_mac_addr;
283*5113495bSYour Name derived_peer_mc_addr.bytes[0] = 0x33;
284*5113495bSYour Name derived_peer_mc_addr.bytes[1] = 0x33;
285*5113495bSYour Name derived_peer_mc_addr.bytes[2] = 0xff;
286*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
287*5113495bSYour Name cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions);
288*5113495bSYour Name for (i = 0; i < max_ndp_sessions; i++) {
289*5113495bSYour Name if (qdf_is_macaddr_equal(&priv_obj->peer_mc_addr_list[i],
290*5113495bSYour Name &derived_peer_mc_addr)) {
291*5113495bSYour Name qdf_zero_macaddr(&priv_obj->peer_mc_addr_list[i]);
292*5113495bSYour Name break;
293*5113495bSYour Name }
294*5113495bSYour Name }
295*5113495bSYour Name
296*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
297*5113495bSYour Name
298*5113495bSYour Name ucfg_nan_update_mc_list(vdev);
299*5113495bSYour Name }
300*5113495bSYour Name
ucfg_nan_get_active_peers(struct wlan_objmgr_vdev * vdev)301*5113495bSYour Name inline uint32_t ucfg_nan_get_active_peers(struct wlan_objmgr_vdev *vdev)
302*5113495bSYour Name {
303*5113495bSYour Name uint32_t val;
304*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
305*5113495bSYour Name
306*5113495bSYour Name if (!priv_obj) {
307*5113495bSYour Name nan_err("priv_obj is null");
308*5113495bSYour Name return 0;
309*5113495bSYour Name }
310*5113495bSYour Name
311*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
312*5113495bSYour Name val = priv_obj->active_ndp_peers;
313*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
314*5113495bSYour Name
315*5113495bSYour Name return val;
316*5113495bSYour Name }
ucfg_nan_set_ndp_create_transaction_id(struct wlan_objmgr_vdev * vdev,uint16_t val)317*5113495bSYour Name inline QDF_STATUS ucfg_nan_set_ndp_create_transaction_id(
318*5113495bSYour Name struct wlan_objmgr_vdev *vdev, uint16_t val)
319*5113495bSYour Name {
320*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
321*5113495bSYour Name
322*5113495bSYour Name if (!priv_obj) {
323*5113495bSYour Name nan_err("priv_obj is null");
324*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
325*5113495bSYour Name }
326*5113495bSYour Name
327*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
328*5113495bSYour Name priv_obj->ndp_create_transaction_id = val;
329*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
330*5113495bSYour Name
331*5113495bSYour Name return QDF_STATUS_SUCCESS;
332*5113495bSYour Name }
333*5113495bSYour Name
ucfg_nan_get_ndp_create_transaction_id(struct wlan_objmgr_vdev * vdev)334*5113495bSYour Name inline uint16_t ucfg_nan_get_ndp_create_transaction_id(
335*5113495bSYour Name struct wlan_objmgr_vdev *vdev)
336*5113495bSYour Name {
337*5113495bSYour Name uint16_t val;
338*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
339*5113495bSYour Name
340*5113495bSYour Name if (!priv_obj) {
341*5113495bSYour Name nan_err("priv_obj is null");
342*5113495bSYour Name return 0;
343*5113495bSYour Name }
344*5113495bSYour Name
345*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
346*5113495bSYour Name val = priv_obj->ndp_create_transaction_id;
347*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
348*5113495bSYour Name
349*5113495bSYour Name return val;
350*5113495bSYour Name }
351*5113495bSYour Name
ucfg_nan_set_ndp_delete_transaction_id(struct wlan_objmgr_vdev * vdev,uint16_t val)352*5113495bSYour Name inline QDF_STATUS ucfg_nan_set_ndp_delete_transaction_id(
353*5113495bSYour Name struct wlan_objmgr_vdev *vdev, uint16_t val)
354*5113495bSYour Name {
355*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
356*5113495bSYour Name
357*5113495bSYour Name if (!priv_obj) {
358*5113495bSYour Name nan_err("priv_obj is null");
359*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
360*5113495bSYour Name }
361*5113495bSYour Name
362*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
363*5113495bSYour Name priv_obj->ndp_delete_transaction_id = val;
364*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
365*5113495bSYour Name
366*5113495bSYour Name return QDF_STATUS_SUCCESS;
367*5113495bSYour Name }
368*5113495bSYour Name
ucfg_nan_get_ndp_delete_transaction_id(struct wlan_objmgr_vdev * vdev)369*5113495bSYour Name inline uint16_t ucfg_nan_get_ndp_delete_transaction_id(
370*5113495bSYour Name struct wlan_objmgr_vdev *vdev)
371*5113495bSYour Name {
372*5113495bSYour Name uint16_t val;
373*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
374*5113495bSYour Name
375*5113495bSYour Name if (!priv_obj) {
376*5113495bSYour Name nan_err("priv_obj is null");
377*5113495bSYour Name return 0;
378*5113495bSYour Name }
379*5113495bSYour Name
380*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
381*5113495bSYour Name val = priv_obj->ndp_delete_transaction_id;
382*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
383*5113495bSYour Name
384*5113495bSYour Name return val;
385*5113495bSYour Name }
386*5113495bSYour Name
ucfg_nan_set_ndi_delete_rsp_reason(struct wlan_objmgr_vdev * vdev,uint32_t val)387*5113495bSYour Name inline QDF_STATUS ucfg_nan_set_ndi_delete_rsp_reason(
388*5113495bSYour Name struct wlan_objmgr_vdev *vdev, uint32_t val)
389*5113495bSYour Name {
390*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
391*5113495bSYour Name
392*5113495bSYour Name if (!priv_obj) {
393*5113495bSYour Name nan_err("priv_obj is null");
394*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
395*5113495bSYour Name }
396*5113495bSYour Name
397*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
398*5113495bSYour Name priv_obj->ndi_delete_rsp_reason = val;
399*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
400*5113495bSYour Name
401*5113495bSYour Name return QDF_STATUS_SUCCESS;
402*5113495bSYour Name }
403*5113495bSYour Name
ucfg_nan_get_ndi_delete_rsp_reason(struct wlan_objmgr_vdev * vdev)404*5113495bSYour Name inline uint32_t ucfg_nan_get_ndi_delete_rsp_reason(
405*5113495bSYour Name struct wlan_objmgr_vdev *vdev)
406*5113495bSYour Name {
407*5113495bSYour Name uint32_t val;
408*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
409*5113495bSYour Name
410*5113495bSYour Name if (!priv_obj) {
411*5113495bSYour Name nan_err("priv_obj is null");
412*5113495bSYour Name return 0;
413*5113495bSYour Name }
414*5113495bSYour Name
415*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
416*5113495bSYour Name val = priv_obj->ndi_delete_rsp_reason;
417*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
418*5113495bSYour Name
419*5113495bSYour Name return val;
420*5113495bSYour Name }
421*5113495bSYour Name
ucfg_nan_set_ndi_delete_rsp_status(struct wlan_objmgr_vdev * vdev,uint32_t val)422*5113495bSYour Name inline QDF_STATUS ucfg_nan_set_ndi_delete_rsp_status(
423*5113495bSYour Name struct wlan_objmgr_vdev *vdev, uint32_t val)
424*5113495bSYour Name {
425*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
426*5113495bSYour Name
427*5113495bSYour Name if (!priv_obj) {
428*5113495bSYour Name nan_err("priv_obj is null");
429*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
430*5113495bSYour Name }
431*5113495bSYour Name
432*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
433*5113495bSYour Name priv_obj->ndi_delete_rsp_status = val;
434*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
435*5113495bSYour Name
436*5113495bSYour Name return QDF_STATUS_SUCCESS;
437*5113495bSYour Name }
438*5113495bSYour Name
ucfg_nan_get_ndi_delete_rsp_status(struct wlan_objmgr_vdev * vdev)439*5113495bSYour Name inline uint32_t ucfg_nan_get_ndi_delete_rsp_status(
440*5113495bSYour Name struct wlan_objmgr_vdev *vdev)
441*5113495bSYour Name {
442*5113495bSYour Name uint32_t val;
443*5113495bSYour Name struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
444*5113495bSYour Name
445*5113495bSYour Name if (!priv_obj) {
446*5113495bSYour Name nan_err("priv_obj is null");
447*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
448*5113495bSYour Name }
449*5113495bSYour Name
450*5113495bSYour Name qdf_spin_lock_bh(&priv_obj->lock);
451*5113495bSYour Name val = priv_obj->ndi_delete_rsp_status;
452*5113495bSYour Name qdf_spin_unlock_bh(&priv_obj->lock);
453*5113495bSYour Name
454*5113495bSYour Name return val;
455*5113495bSYour Name }
456*5113495bSYour Name
ucfg_nan_get_callbacks(struct wlan_objmgr_psoc * psoc,struct nan_callbacks * cb_obj)457*5113495bSYour Name inline QDF_STATUS ucfg_nan_get_callbacks(struct wlan_objmgr_psoc *psoc,
458*5113495bSYour Name struct nan_callbacks *cb_obj)
459*5113495bSYour Name {
460*5113495bSYour Name struct nan_psoc_priv_obj *psoc_obj = nan_get_psoc_priv_obj(psoc);
461*5113495bSYour Name
462*5113495bSYour Name if (!psoc_obj) {
463*5113495bSYour Name nan_err("nan psoc priv object is NULL");
464*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
465*5113495bSYour Name }
466*5113495bSYour Name qdf_spin_lock_bh(&psoc_obj->lock);
467*5113495bSYour Name qdf_mem_copy(cb_obj, &psoc_obj->cb_obj, sizeof(*cb_obj));
468*5113495bSYour Name qdf_spin_unlock_bh(&psoc_obj->lock);
469*5113495bSYour Name
470*5113495bSYour Name return QDF_STATUS_SUCCESS;
471*5113495bSYour Name }
472*5113495bSYour Name
ucfg_nan_sch_msg_flush_cb(struct scheduler_msg * msg)473*5113495bSYour Name static QDF_STATUS ucfg_nan_sch_msg_flush_cb(struct scheduler_msg *msg)
474*5113495bSYour Name {
475*5113495bSYour Name struct wlan_objmgr_vdev *vdev = NULL;
476*5113495bSYour Name
477*5113495bSYour Name if (!msg || !msg->bodyptr)
478*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
479*5113495bSYour Name
480*5113495bSYour Name switch (msg->type) {
481*5113495bSYour Name case NDP_INITIATOR_REQ:
482*5113495bSYour Name vdev = ((struct nan_datapath_initiator_req *)
483*5113495bSYour Name msg->bodyptr)->vdev;
484*5113495bSYour Name break;
485*5113495bSYour Name case NDP_RESPONDER_REQ:
486*5113495bSYour Name vdev = ((struct nan_datapath_responder_req *)
487*5113495bSYour Name msg->bodyptr)->vdev;
488*5113495bSYour Name break;
489*5113495bSYour Name case NDP_END_REQ:
490*5113495bSYour Name vdev = ((struct nan_datapath_end_req *)msg->bodyptr)->vdev;
491*5113495bSYour Name break;
492*5113495bSYour Name case NDP_END_ALL:
493*5113495bSYour Name vdev = ((struct nan_datapath_end_all_ndps *)msg->bodyptr)->vdev;
494*5113495bSYour Name break;
495*5113495bSYour Name default:
496*5113495bSYour Name nan_err("Invalid NAN msg type during sch flush");
497*5113495bSYour Name return QDF_STATUS_E_INVAL;
498*5113495bSYour Name }
499*5113495bSYour Name
500*5113495bSYour Name if (vdev) {
501*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
502*5113495bSYour Name qdf_mem_free(msg->bodyptr);
503*5113495bSYour Name }
504*5113495bSYour Name
505*5113495bSYour Name return QDF_STATUS_SUCCESS;
506*5113495bSYour Name }
507*5113495bSYour Name
ucfg_nan_req_processor(struct wlan_objmgr_vdev * vdev,void * in_req,uint32_t req_type)508*5113495bSYour Name QDF_STATUS ucfg_nan_req_processor(struct wlan_objmgr_vdev *vdev,
509*5113495bSYour Name void *in_req, uint32_t req_type)
510*5113495bSYour Name {
511*5113495bSYour Name uint32_t len;
512*5113495bSYour Name QDF_STATUS status;
513*5113495bSYour Name struct scheduler_msg msg = {0};
514*5113495bSYour Name int err;
515*5113495bSYour Name struct nan_psoc_priv_obj *psoc_obj = NULL;
516*5113495bSYour Name struct osif_request *request = NULL;
517*5113495bSYour Name static const struct osif_request_params params = {
518*5113495bSYour Name .priv_size = 0,
519*5113495bSYour Name .timeout_ms = WLAN_WAIT_TIME_NDP_END,
520*5113495bSYour Name };
521*5113495bSYour Name
522*5113495bSYour Name if (!in_req) {
523*5113495bSYour Name nan_alert("req is null");
524*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
525*5113495bSYour Name }
526*5113495bSYour Name
527*5113495bSYour Name switch (req_type) {
528*5113495bSYour Name case NDP_INITIATOR_REQ:
529*5113495bSYour Name len = sizeof(struct nan_datapath_initiator_req);
530*5113495bSYour Name break;
531*5113495bSYour Name case NDP_RESPONDER_REQ:
532*5113495bSYour Name len = sizeof(struct nan_datapath_responder_req);
533*5113495bSYour Name break;
534*5113495bSYour Name case NDP_END_REQ:
535*5113495bSYour Name len = sizeof(struct nan_datapath_end_req);
536*5113495bSYour Name psoc_obj = nan_get_psoc_priv_obj(wlan_vdev_get_psoc(vdev));
537*5113495bSYour Name if (!psoc_obj) {
538*5113495bSYour Name nan_err("nan psoc priv object is NULL");
539*5113495bSYour Name return QDF_STATUS_E_INVAL;
540*5113495bSYour Name }
541*5113495bSYour Name request = osif_request_alloc(¶ms);
542*5113495bSYour Name if (!request) {
543*5113495bSYour Name nan_err("Request allocation failure");
544*5113495bSYour Name return QDF_STATUS_E_NOMEM;
545*5113495bSYour Name }
546*5113495bSYour Name psoc_obj->ndp_request_ctx = osif_request_cookie(request);
547*5113495bSYour Name break;
548*5113495bSYour Name case NDP_END_ALL:
549*5113495bSYour Name len = sizeof(struct nan_datapath_end_all_ndps);
550*5113495bSYour Name break;
551*5113495bSYour Name default:
552*5113495bSYour Name nan_err("in correct message req type: %d", req_type);
553*5113495bSYour Name return QDF_STATUS_E_INVAL;
554*5113495bSYour Name }
555*5113495bSYour Name
556*5113495bSYour Name msg.bodyptr = qdf_mem_malloc(len);
557*5113495bSYour Name if (!msg.bodyptr) {
558*5113495bSYour Name status = QDF_STATUS_E_NOMEM;
559*5113495bSYour Name goto fail;
560*5113495bSYour Name }
561*5113495bSYour Name
562*5113495bSYour Name qdf_mem_copy(msg.bodyptr, in_req, len);
563*5113495bSYour Name msg.type = req_type;
564*5113495bSYour Name msg.callback = nan_scheduled_msg_handler;
565*5113495bSYour Name msg.flush_callback = ucfg_nan_sch_msg_flush_cb;
566*5113495bSYour Name status = scheduler_post_message(QDF_MODULE_ID_HDD,
567*5113495bSYour Name QDF_MODULE_ID_NAN,
568*5113495bSYour Name QDF_MODULE_ID_OS_IF, &msg);
569*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
570*5113495bSYour Name nan_err("failed to post msg to NAN component, status: %d",
571*5113495bSYour Name status);
572*5113495bSYour Name goto fail;
573*5113495bSYour Name }
574*5113495bSYour Name
575*5113495bSYour Name if (req_type == NDP_END_REQ) {
576*5113495bSYour Name nan_debug("Wait for NDP END indication");
577*5113495bSYour Name err = osif_request_wait_for_response(request);
578*5113495bSYour Name if (err)
579*5113495bSYour Name nan_debug("NAN request timed out: %d", err);
580*5113495bSYour Name osif_request_put(request);
581*5113495bSYour Name psoc_obj->ndp_request_ctx = NULL;
582*5113495bSYour Name }
583*5113495bSYour Name
584*5113495bSYour Name return QDF_STATUS_SUCCESS;
585*5113495bSYour Name
586*5113495bSYour Name fail:
587*5113495bSYour Name qdf_mem_free(msg.bodyptr);
588*5113495bSYour Name if (req_type == NDP_END_REQ) {
589*5113495bSYour Name osif_request_put(request);
590*5113495bSYour Name psoc_obj->ndp_request_ctx = NULL;
591*5113495bSYour Name }
592*5113495bSYour Name return status;
593*5113495bSYour Name }
594*5113495bSYour Name
ucfg_nan_datapath_event_handler(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,uint32_t type,void * msg)595*5113495bSYour Name void ucfg_nan_datapath_event_handler(struct wlan_objmgr_psoc *psoc,
596*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
597*5113495bSYour Name uint32_t type, void *msg)
598*5113495bSYour Name {
599*5113495bSYour Name struct nan_psoc_priv_obj *psoc_obj = nan_get_psoc_priv_obj(psoc);
600*5113495bSYour Name
601*5113495bSYour Name if (!psoc_obj) {
602*5113495bSYour Name nan_err("nan psoc priv object is NULL");
603*5113495bSYour Name return;
604*5113495bSYour Name }
605*5113495bSYour Name
606*5113495bSYour Name psoc_obj->cb_obj.os_if_ndp_event_handler(psoc, vdev, type, msg);
607*5113495bSYour Name }
608*5113495bSYour Name
ucfg_nan_request_process_cb(void * cookie)609*5113495bSYour Name static void ucfg_nan_request_process_cb(void *cookie)
610*5113495bSYour Name {
611*5113495bSYour Name struct osif_request *request;
612*5113495bSYour Name
613*5113495bSYour Name request = osif_request_get(cookie);
614*5113495bSYour Name if (request) {
615*5113495bSYour Name osif_request_complete(request);
616*5113495bSYour Name osif_request_put(request);
617*5113495bSYour Name } else {
618*5113495bSYour Name nan_debug("Obsolete request (cookie:0x%pK), do nothing",
619*5113495bSYour Name cookie);
620*5113495bSYour Name }
621*5113495bSYour Name }
622*5113495bSYour Name
623*5113495bSYour Name #ifdef WLAN_FEATURE_SR
624*5113495bSYour Name static void
nan_register_sr_concurrency_callback(struct nan_psoc_priv_obj * psoc_obj,struct nan_callbacks * cb_obj)625*5113495bSYour Name nan_register_sr_concurrency_callback(struct nan_psoc_priv_obj *psoc_obj,
626*5113495bSYour Name struct nan_callbacks *cb_obj)
627*5113495bSYour Name {
628*5113495bSYour Name psoc_obj->cb_obj.nan_sr_concurrency_update =
629*5113495bSYour Name cb_obj->nan_sr_concurrency_update;
630*5113495bSYour Name }
631*5113495bSYour Name #else
632*5113495bSYour Name static inline void
nan_register_sr_concurrency_callback(struct nan_psoc_priv_obj * psoc_obj,struct nan_callbacks * cb_obj)633*5113495bSYour Name nan_register_sr_concurrency_callback(struct nan_psoc_priv_obj *psoc_obj,
634*5113495bSYour Name struct nan_callbacks *cb_obj)
635*5113495bSYour Name {}
636*5113495bSYour Name #endif
637*5113495bSYour Name
ucfg_nan_register_hdd_callbacks(struct wlan_objmgr_psoc * psoc,struct nan_callbacks * cb_obj)638*5113495bSYour Name int ucfg_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
639*5113495bSYour Name struct nan_callbacks *cb_obj)
640*5113495bSYour Name {
641*5113495bSYour Name struct nan_psoc_priv_obj *psoc_obj = nan_get_psoc_priv_obj(psoc);
642*5113495bSYour Name
643*5113495bSYour Name if (!psoc_obj) {
644*5113495bSYour Name nan_err("nan psoc priv object is NULL");
645*5113495bSYour Name return -EINVAL;
646*5113495bSYour Name }
647*5113495bSYour Name
648*5113495bSYour Name psoc_obj->cb_obj.ndi_open = cb_obj->ndi_open;
649*5113495bSYour Name psoc_obj->cb_obj.ndi_set_mode = cb_obj->ndi_set_mode;
650*5113495bSYour Name psoc_obj->cb_obj.ndi_start = cb_obj->ndi_start;
651*5113495bSYour Name psoc_obj->cb_obj.ndi_delete = cb_obj->ndi_delete;
652*5113495bSYour Name psoc_obj->cb_obj.ndi_close = cb_obj->ndi_close;
653*5113495bSYour Name psoc_obj->cb_obj.drv_ndi_create_rsp_handler =
654*5113495bSYour Name cb_obj->drv_ndi_create_rsp_handler;
655*5113495bSYour Name psoc_obj->cb_obj.drv_ndi_delete_rsp_handler =
656*5113495bSYour Name cb_obj->drv_ndi_delete_rsp_handler;
657*5113495bSYour Name
658*5113495bSYour Name psoc_obj->cb_obj.new_peer_ind = cb_obj->new_peer_ind;
659*5113495bSYour Name psoc_obj->cb_obj.peer_departed_ind = cb_obj->peer_departed_ind;
660*5113495bSYour Name psoc_obj->cb_obj.os_if_ndp_event_handler =
661*5113495bSYour Name cb_obj->os_if_ndp_event_handler;
662*5113495bSYour Name psoc_obj->cb_obj.os_if_nan_event_handler =
663*5113495bSYour Name cb_obj->os_if_nan_event_handler;
664*5113495bSYour Name psoc_obj->cb_obj.ucfg_nan_request_process_cb =
665*5113495bSYour Name ucfg_nan_request_process_cb;
666*5113495bSYour Name psoc_obj->cb_obj.nan_concurrency_update =
667*5113495bSYour Name cb_obj->nan_concurrency_update;
668*5113495bSYour Name psoc_obj->cb_obj.set_mc_list = cb_obj->set_mc_list;
669*5113495bSYour Name
670*5113495bSYour Name nan_register_sr_concurrency_callback(psoc_obj, cb_obj);
671*5113495bSYour Name return 0;
672*5113495bSYour Name }
673*5113495bSYour Name
ucfg_nan_register_lim_callbacks(struct wlan_objmgr_psoc * psoc,struct nan_callbacks * cb_obj)674*5113495bSYour Name int ucfg_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc,
675*5113495bSYour Name struct nan_callbacks *cb_obj)
676*5113495bSYour Name {
677*5113495bSYour Name struct nan_psoc_priv_obj *psoc_obj = nan_get_psoc_priv_obj(psoc);
678*5113495bSYour Name
679*5113495bSYour Name if (!psoc_obj) {
680*5113495bSYour Name nan_err("nan psoc priv object is NULL");
681*5113495bSYour Name return -EINVAL;
682*5113495bSYour Name }
683*5113495bSYour Name
684*5113495bSYour Name psoc_obj->cb_obj.add_ndi_peer = cb_obj->add_ndi_peer;
685*5113495bSYour Name psoc_obj->cb_obj.ndp_delete_peers = cb_obj->ndp_delete_peers;
686*5113495bSYour Name psoc_obj->cb_obj.delete_peers_by_addr = cb_obj->delete_peers_by_addr;
687*5113495bSYour Name
688*5113495bSYour Name return 0;
689*5113495bSYour Name }
690*5113495bSYour Name
ucfg_nan_register_wma_callbacks(struct wlan_objmgr_psoc * psoc,struct nan_callbacks * cb_obj)691*5113495bSYour Name int ucfg_nan_register_wma_callbacks(struct wlan_objmgr_psoc *psoc,
692*5113495bSYour Name struct nan_callbacks *cb_obj)
693*5113495bSYour Name {
694*5113495bSYour Name struct nan_psoc_priv_obj *psoc_obj = nan_get_psoc_priv_obj(psoc);
695*5113495bSYour Name
696*5113495bSYour Name if (!psoc_obj) {
697*5113495bSYour Name nan_err("nan psoc priv object is NULL");
698*5113495bSYour Name return -EINVAL;
699*5113495bSYour Name }
700*5113495bSYour Name
701*5113495bSYour Name psoc_obj->cb_obj.update_ndi_conn = cb_obj->update_ndi_conn;
702*5113495bSYour Name
703*5113495bSYour Name return 0;
704*5113495bSYour Name }
705*5113495bSYour Name
ucfg_nan_set_tgt_caps(struct wlan_objmgr_psoc * psoc,struct nan_tgt_caps * nan_caps)706*5113495bSYour Name void ucfg_nan_set_tgt_caps(struct wlan_objmgr_psoc *psoc,
707*5113495bSYour Name struct nan_tgt_caps *nan_caps)
708*5113495bSYour Name {
709*5113495bSYour Name struct nan_psoc_priv_obj *psoc_priv = nan_get_psoc_priv_obj(psoc);
710*5113495bSYour Name
711*5113495bSYour Name if (!psoc_priv) {
712*5113495bSYour Name nan_err("nan psoc priv object is NULL");
713*5113495bSYour Name return;
714*5113495bSYour Name }
715*5113495bSYour Name
716*5113495bSYour Name psoc_priv->nan_caps = *nan_caps;
717*5113495bSYour Name }
718*5113495bSYour Name
ucfg_is_nan_conc_control_supported(struct wlan_objmgr_psoc * psoc)719*5113495bSYour Name bool ucfg_is_nan_conc_control_supported(struct wlan_objmgr_psoc *psoc)
720*5113495bSYour Name {
721*5113495bSYour Name struct nan_psoc_priv_obj *psoc_priv;
722*5113495bSYour Name
723*5113495bSYour Name psoc_priv = nan_get_psoc_priv_obj(psoc);
724*5113495bSYour Name if (!psoc_priv) {
725*5113495bSYour Name nan_err("nan psoc priv object is NULL");
726*5113495bSYour Name return false;
727*5113495bSYour Name }
728*5113495bSYour Name
729*5113495bSYour Name return (psoc_priv->nan_caps.nan_conc_control == 1);
730*5113495bSYour Name }
731*5113495bSYour Name
ucfg_is_nan_dbs_supported(struct wlan_objmgr_psoc * psoc)732*5113495bSYour Name bool ucfg_is_nan_dbs_supported(struct wlan_objmgr_psoc *psoc)
733*5113495bSYour Name {
734*5113495bSYour Name struct nan_psoc_priv_obj *psoc_priv;
735*5113495bSYour Name
736*5113495bSYour Name psoc_priv = nan_get_psoc_priv_obj(psoc);
737*5113495bSYour Name if (!psoc_priv) {
738*5113495bSYour Name nan_err("nan psoc priv object is NULL");
739*5113495bSYour Name return false;
740*5113495bSYour Name }
741*5113495bSYour Name
742*5113495bSYour Name return (psoc_priv->nan_caps.nan_dbs_supported == 1);
743*5113495bSYour Name }
744*5113495bSYour Name
ucfg_is_ndi_dbs_supported(struct wlan_objmgr_psoc * psoc)745*5113495bSYour Name bool ucfg_is_ndi_dbs_supported(struct wlan_objmgr_psoc *psoc)
746*5113495bSYour Name {
747*5113495bSYour Name struct nan_psoc_priv_obj *psoc_priv;
748*5113495bSYour Name
749*5113495bSYour Name psoc_priv = nan_get_psoc_priv_obj(psoc);
750*5113495bSYour Name if (!psoc_priv) {
751*5113495bSYour Name nan_err("nan psoc priv object is NULL");
752*5113495bSYour Name return false;
753*5113495bSYour Name }
754*5113495bSYour Name
755*5113495bSYour Name return (psoc_priv->nan_caps.ndi_dbs_supported == 1);
756*5113495bSYour Name }
757*5113495bSYour Name
ucfg_is_nan_enable_allowed(struct wlan_objmgr_psoc * psoc,uint32_t nan_ch_freq,uint8_t vdev_id)758*5113495bSYour Name bool ucfg_is_nan_enable_allowed(struct wlan_objmgr_psoc *psoc,
759*5113495bSYour Name uint32_t nan_ch_freq, uint8_t vdev_id)
760*5113495bSYour Name {
761*5113495bSYour Name return nan_is_enable_allowed(psoc, nan_ch_freq, vdev_id);
762*5113495bSYour Name }
763*5113495bSYour Name
ucfg_is_nan_disc_active(struct wlan_objmgr_psoc * psoc)764*5113495bSYour Name bool ucfg_is_nan_disc_active(struct wlan_objmgr_psoc *psoc)
765*5113495bSYour Name {
766*5113495bSYour Name return nan_is_disc_active(psoc);
767*5113495bSYour Name }
768*5113495bSYour Name
ucfg_nan_discovery_req(void * in_req,uint32_t req_type)769*5113495bSYour Name QDF_STATUS ucfg_nan_discovery_req(void *in_req, uint32_t req_type)
770*5113495bSYour Name {
771*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
772*5113495bSYour Name struct scheduler_msg msg = {0};
773*5113495bSYour Name uint32_t len;
774*5113495bSYour Name QDF_STATUS status;
775*5113495bSYour Name struct nan_psoc_priv_obj *psoc_priv;
776*5113495bSYour Name struct osif_request *request = NULL;
777*5113495bSYour Name static const struct osif_request_params params = {
778*5113495bSYour Name .priv_size = 0,
779*5113495bSYour Name .timeout_ms = 4000,
780*5113495bSYour Name };
781*5113495bSYour Name int err = 0;
782*5113495bSYour Name bool recovery;
783*5113495bSYour Name
784*5113495bSYour Name if (!in_req) {
785*5113495bSYour Name nan_alert("NAN Discovery req is null");
786*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
787*5113495bSYour Name }
788*5113495bSYour Name
789*5113495bSYour Name switch (req_type) {
790*5113495bSYour Name case NAN_ENABLE_REQ: {
791*5113495bSYour Name struct nan_enable_req *req = in_req;
792*5113495bSYour Name
793*5113495bSYour Name psoc = req->psoc;
794*5113495bSYour Name psoc_priv = nan_get_psoc_priv_obj(psoc);
795*5113495bSYour Name if (!psoc_priv) {
796*5113495bSYour Name nan_err("nan psoc priv object is NULL");
797*5113495bSYour Name return QDF_STATUS_E_INVAL;
798*5113495bSYour Name }
799*5113495bSYour Name
800*5113495bSYour Name if (policy_mgr_is_sta_mon_concurrency(psoc))
801*5113495bSYour Name return QDF_STATUS_E_INVAL;
802*5113495bSYour Name
803*5113495bSYour Name /*
804*5113495bSYour Name * Take a psoc reference while it is being used by the
805*5113495bSYour Name * NAN requests.
806*5113495bSYour Name */
807*5113495bSYour Name status = wlan_objmgr_psoc_try_get_ref(psoc,
808*5113495bSYour Name WLAN_NAN_ID);
809*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
810*5113495bSYour Name nan_err("Couldn't obtain psoc ref");
811*5113495bSYour Name return status;
812*5113495bSYour Name }
813*5113495bSYour Name
814*5113495bSYour Name status = nan_discovery_pre_enable(req->pdev,
815*5113495bSYour Name req->social_chan_2g_freq);
816*5113495bSYour Name if (QDF_IS_STATUS_SUCCESS(status)) {
817*5113495bSYour Name len = sizeof(struct nan_enable_req) +
818*5113495bSYour Name req->params.request_data_len;
819*5113495bSYour Name } else {
820*5113495bSYour Name wlan_objmgr_psoc_release_ref(psoc,
821*5113495bSYour Name WLAN_NAN_ID);
822*5113495bSYour Name return status;
823*5113495bSYour Name }
824*5113495bSYour Name break;
825*5113495bSYour Name }
826*5113495bSYour Name case NAN_DISABLE_REQ: {
827*5113495bSYour Name struct nan_disable_req *req = in_req;
828*5113495bSYour Name
829*5113495bSYour Name psoc = req->psoc;
830*5113495bSYour Name psoc_priv = nan_get_psoc_priv_obj(psoc);
831*5113495bSYour Name if (!psoc_priv) {
832*5113495bSYour Name nan_err("nan psoc priv object is NULL");
833*5113495bSYour Name return QDF_STATUS_E_INVAL;
834*5113495bSYour Name }
835*5113495bSYour Name
836*5113495bSYour Name status = wlan_objmgr_psoc_try_get_ref(psoc,
837*5113495bSYour Name WLAN_NAN_ID);
838*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
839*5113495bSYour Name nan_err("Couldn't obtain psoc ref");
840*5113495bSYour Name return status;
841*5113495bSYour Name }
842*5113495bSYour Name
843*5113495bSYour Name status =
844*5113495bSYour Name nan_set_discovery_state(req->psoc,
845*5113495bSYour Name NAN_DISC_DISABLE_IN_PROGRESS);
846*5113495bSYour Name if (QDF_IS_STATUS_SUCCESS(status)) {
847*5113495bSYour Name len = sizeof(struct nan_disable_req) +
848*5113495bSYour Name req->params.request_data_len;
849*5113495bSYour Name } else {
850*5113495bSYour Name wlan_objmgr_psoc_release_ref(psoc,
851*5113495bSYour Name WLAN_NAN_ID);
852*5113495bSYour Name return status;
853*5113495bSYour Name }
854*5113495bSYour Name break;
855*5113495bSYour Name }
856*5113495bSYour Name case NAN_GENERIC_REQ: {
857*5113495bSYour Name struct nan_generic_req *req = in_req;
858*5113495bSYour Name
859*5113495bSYour Name psoc = req->psoc;
860*5113495bSYour Name psoc_priv = nan_get_psoc_priv_obj(psoc);
861*5113495bSYour Name if (!psoc_priv) {
862*5113495bSYour Name nan_err("nan psoc priv object is NULL");
863*5113495bSYour Name return QDF_STATUS_E_INVAL;
864*5113495bSYour Name }
865*5113495bSYour Name
866*5113495bSYour Name status = wlan_objmgr_psoc_try_get_ref(psoc,
867*5113495bSYour Name WLAN_NAN_ID);
868*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
869*5113495bSYour Name nan_err("Couldn't obtain psoc ref");
870*5113495bSYour Name return status;
871*5113495bSYour Name }
872*5113495bSYour Name len = sizeof(struct nan_generic_req) +
873*5113495bSYour Name req->params.request_data_len;
874*5113495bSYour Name break;
875*5113495bSYour Name }
876*5113495bSYour Name default:
877*5113495bSYour Name nan_err("in correct message req type: %d", req_type);
878*5113495bSYour Name return QDF_STATUS_E_INVAL;
879*5113495bSYour Name }
880*5113495bSYour Name
881*5113495bSYour Name msg.bodyptr = qdf_mem_malloc(len);
882*5113495bSYour Name if (!msg.bodyptr) {
883*5113495bSYour Name wlan_objmgr_psoc_release_ref(psoc, WLAN_NAN_ID);
884*5113495bSYour Name return QDF_STATUS_E_NOMEM;
885*5113495bSYour Name }
886*5113495bSYour Name
887*5113495bSYour Name qdf_mem_copy(msg.bodyptr, in_req, len);
888*5113495bSYour Name msg.type = req_type;
889*5113495bSYour Name msg.callback = nan_discovery_scheduled_handler;
890*5113495bSYour Name msg.flush_callback = nan_discovery_flush_callback;
891*5113495bSYour Name
892*5113495bSYour Name if (req_type == NAN_GENERIC_REQ)
893*5113495bSYour Name goto post_msg;
894*5113495bSYour Name
895*5113495bSYour Name request = osif_request_alloc(¶ms);
896*5113495bSYour Name if (!request) {
897*5113495bSYour Name nan_err("Request allocation failure");
898*5113495bSYour Name nan_discovery_flush_callback(&msg);
899*5113495bSYour Name return QDF_STATUS_E_NOMEM;
900*5113495bSYour Name }
901*5113495bSYour Name
902*5113495bSYour Name psoc_priv->nan_disc_request_ctx = osif_request_cookie(request);
903*5113495bSYour Name if (req_type == NAN_DISABLE_REQ)
904*5113495bSYour Name psoc_priv->is_explicit_disable = true;
905*5113495bSYour Name
906*5113495bSYour Name post_msg:
907*5113495bSYour Name status = scheduler_post_message(QDF_MODULE_ID_NAN,
908*5113495bSYour Name QDF_MODULE_ID_NAN,
909*5113495bSYour Name QDF_MODULE_ID_OS_IF, &msg);
910*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
911*5113495bSYour Name nan_err("failed to post msg to NAN component, status: %d",
912*5113495bSYour Name status);
913*5113495bSYour Name nan_discovery_flush_callback(&msg);
914*5113495bSYour Name }
915*5113495bSYour Name
916*5113495bSYour Name if (req_type != NAN_GENERIC_REQ) {
917*5113495bSYour Name recovery = cds_is_driver_recovering();
918*5113495bSYour Name if (!recovery)
919*5113495bSYour Name err = osif_request_wait_for_response(request);
920*5113495bSYour Name if (recovery || err) {
921*5113495bSYour Name nan_debug("NAN request: %u recovery %d or timed out %d",
922*5113495bSYour Name req_type, recovery, err);
923*5113495bSYour Name
924*5113495bSYour Name if (req_type == NAN_ENABLE_REQ) {
925*5113495bSYour Name nan_set_discovery_state(psoc,
926*5113495bSYour Name NAN_DISC_DISABLED);
927*5113495bSYour Name if (ucfg_is_nan_dbs_supported(psoc))
928*5113495bSYour Name policy_mgr_check_n_start_opportunistic_timer(psoc);
929*5113495bSYour Name nan_handle_emlsr_concurrency(psoc, false);
930*5113495bSYour Name
931*5113495bSYour Name /*
932*5113495bSYour Name * If FW respond with NAN enable failure, then
933*5113495bSYour Name * TDLS should be enable again if there is TDLS
934*5113495bSYour Name * connection exist earlier.
935*5113495bSYour Name * decrement the active TDLS session.
936*5113495bSYour Name */
937*5113495bSYour Name ucfg_tdls_notify_connect_failure(psoc);
938*5113495bSYour Name } else if (req_type == NAN_DISABLE_REQ) {
939*5113495bSYour Name nan_disable_cleanup(psoc);
940*5113495bSYour Name }
941*5113495bSYour Name }
942*5113495bSYour Name if (req_type == NAN_DISABLE_REQ)
943*5113495bSYour Name psoc_priv->is_explicit_disable = false;
944*5113495bSYour Name osif_request_put(request);
945*5113495bSYour Name }
946*5113495bSYour Name
947*5113495bSYour Name return status;
948*5113495bSYour Name }
949*5113495bSYour Name
ucfg_nan_disable_concurrency(struct wlan_objmgr_psoc * psoc)950*5113495bSYour Name void ucfg_nan_disable_concurrency(struct wlan_objmgr_psoc *psoc)
951*5113495bSYour Name {
952*5113495bSYour Name struct nan_disable_req nan_req = {0};
953*5113495bSYour Name enum nan_disc_state curr_nan_state;
954*5113495bSYour Name struct nan_psoc_priv_obj *psoc_priv;
955*5113495bSYour Name QDF_STATUS status;
956*5113495bSYour Name
957*5113495bSYour Name if (!psoc) {
958*5113495bSYour Name nan_err("psoc object is NULL, no action will be taken");
959*5113495bSYour Name return;
960*5113495bSYour Name }
961*5113495bSYour Name
962*5113495bSYour Name psoc_priv = nan_get_psoc_priv_obj(psoc);
963*5113495bSYour Name if (!psoc_priv) {
964*5113495bSYour Name nan_err("nan psoc priv object is NULL");
965*5113495bSYour Name return;
966*5113495bSYour Name }
967*5113495bSYour Name
968*5113495bSYour Name if (!ucfg_is_nan_conc_control_supported(psoc))
969*5113495bSYour Name return;
970*5113495bSYour Name
971*5113495bSYour Name qdf_spin_lock_bh(&psoc_priv->lock);
972*5113495bSYour Name curr_nan_state = nan_get_discovery_state(psoc);
973*5113495bSYour Name
974*5113495bSYour Name if (curr_nan_state == NAN_DISC_DISABLED ||
975*5113495bSYour Name curr_nan_state == NAN_DISC_DISABLE_IN_PROGRESS) {
976*5113495bSYour Name qdf_spin_unlock_bh(&psoc_priv->lock);
977*5113495bSYour Name return;
978*5113495bSYour Name }
979*5113495bSYour Name qdf_spin_unlock_bh(&psoc_priv->lock);
980*5113495bSYour Name
981*5113495bSYour Name nan_req.psoc = psoc;
982*5113495bSYour Name nan_req.disable_2g_discovery = true;
983*5113495bSYour Name nan_req.disable_5g_discovery = true;
984*5113495bSYour Name
985*5113495bSYour Name status = ucfg_nan_discovery_req(&nan_req, NAN_DISABLE_REQ);
986*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
987*5113495bSYour Name nan_err("Unable to disable NAN Discovery");
988*5113495bSYour Name return;
989*5113495bSYour Name }
990*5113495bSYour Name
991*5113495bSYour Name nan_debug("NAN Disabled successfully");
992*5113495bSYour Name }
993*5113495bSYour Name
994*5113495bSYour Name QDF_STATUS
ucfg_nan_disable_ndi(struct wlan_objmgr_psoc * psoc,uint32_t ndi_vdev_id)995*5113495bSYour Name ucfg_nan_disable_ndi(struct wlan_objmgr_psoc *psoc, uint32_t ndi_vdev_id)
996*5113495bSYour Name {
997*5113495bSYour Name enum nan_datapath_state curr_ndi_state;
998*5113495bSYour Name struct nan_vdev_priv_obj *ndi_vdev_priv;
999*5113495bSYour Name struct nan_datapath_end_all_ndps req = {0};
1000*5113495bSYour Name struct wlan_objmgr_vdev *ndi_vdev;
1001*5113495bSYour Name struct osif_request *request;
1002*5113495bSYour Name QDF_STATUS status;
1003*5113495bSYour Name int err;
1004*5113495bSYour Name static const struct osif_request_params params = {
1005*5113495bSYour Name .priv_size = 0,
1006*5113495bSYour Name .timeout_ms = 2000,
1007*5113495bSYour Name };
1008*5113495bSYour Name
1009*5113495bSYour Name if (!ucfg_is_ndi_dbs_supported(psoc))
1010*5113495bSYour Name return QDF_STATUS_SUCCESS;
1011*5113495bSYour Name
1012*5113495bSYour Name ndi_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, ndi_vdev_id,
1013*5113495bSYour Name WLAN_NAN_ID);
1014*5113495bSYour Name if (!ndi_vdev) {
1015*5113495bSYour Name nan_err("Cannot obtain NDI vdev object!");
1016*5113495bSYour Name return QDF_STATUS_E_INVAL;
1017*5113495bSYour Name }
1018*5113495bSYour Name
1019*5113495bSYour Name ndi_vdev_priv = nan_get_vdev_priv_obj(ndi_vdev);
1020*5113495bSYour Name if (!ndi_vdev_priv) {
1021*5113495bSYour Name nan_err("ndi vdev priv object is NULL");
1022*5113495bSYour Name wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
1023*5113495bSYour Name return QDF_STATUS_E_INVAL;
1024*5113495bSYour Name }
1025*5113495bSYour Name curr_ndi_state = ucfg_nan_get_ndi_state(ndi_vdev);
1026*5113495bSYour Name
1027*5113495bSYour Name /*
1028*5113495bSYour Name * Nothing to do if NDI is in DATA_END state.
1029*5113495bSYour Name * Continue cleanup in NAN_DATA_NDI_DELETING_STATE as this API
1030*5113495bSYour Name * can be called from hdd_ndi_delete.
1031*5113495bSYour Name */
1032*5113495bSYour Name if (curr_ndi_state == NAN_DATA_END_STATE) {
1033*5113495bSYour Name wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
1034*5113495bSYour Name return QDF_STATUS_SUCCESS;
1035*5113495bSYour Name }
1036*5113495bSYour Name ucfg_nan_set_ndi_state(ndi_vdev, NAN_DATA_END_STATE);
1037*5113495bSYour Name
1038*5113495bSYour Name request = osif_request_alloc(¶ms);
1039*5113495bSYour Name if (!request) {
1040*5113495bSYour Name nan_err("Request allocation failure");
1041*5113495bSYour Name status = QDF_STATUS_E_NOMEM;
1042*5113495bSYour Name goto cleanup;
1043*5113495bSYour Name }
1044*5113495bSYour Name ndi_vdev_priv->disable_context = osif_request_cookie(request);
1045*5113495bSYour Name
1046*5113495bSYour Name req.vdev = ndi_vdev;
1047*5113495bSYour Name status = ucfg_nan_req_processor(NULL, &req, NDP_END_ALL);
1048*5113495bSYour Name
1049*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
1050*5113495bSYour Name nan_err("Unable to disable NDP's on NDI");
1051*5113495bSYour Name wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
1052*5113495bSYour Name goto cleanup;
1053*5113495bSYour Name }
1054*5113495bSYour Name
1055*5113495bSYour Name nan_debug("Disabling all NDP's on NDI vdev id - %d", ndi_vdev_id);
1056*5113495bSYour Name
1057*5113495bSYour Name err = osif_request_wait_for_response(request);
1058*5113495bSYour Name if (err) {
1059*5113495bSYour Name nan_err("Disabling NDP's timed out waiting for confirmation");
1060*5113495bSYour Name status = QDF_STATUS_E_TIMEOUT;
1061*5113495bSYour Name }
1062*5113495bSYour Name
1063*5113495bSYour Name cleanup:
1064*5113495bSYour Name /*
1065*5113495bSYour Name * Host can assume NDP delete is successful and
1066*5113495bSYour Name * remove policy mgr entry
1067*5113495bSYour Name */
1068*5113495bSYour Name policy_mgr_decr_session_set_pcl(psoc, QDF_NDI_MODE, ndi_vdev_id);
1069*5113495bSYour Name
1070*5113495bSYour Name ucfg_nan_set_ndi_state(ndi_vdev, NAN_DATA_DISCONNECTED_STATE);
1071*5113495bSYour Name
1072*5113495bSYour Name if (request)
1073*5113495bSYour Name osif_request_put(request);
1074*5113495bSYour Name
1075*5113495bSYour Name return status;
1076*5113495bSYour Name }
1077*5113495bSYour Name
1078*5113495bSYour Name QDF_STATUS
ucfg_nan_check_and_disable_unsupported_ndi(struct wlan_objmgr_psoc * psoc,bool force)1079*5113495bSYour Name ucfg_nan_check_and_disable_unsupported_ndi(struct wlan_objmgr_psoc *psoc,
1080*5113495bSYour Name bool force)
1081*5113495bSYour Name {
1082*5113495bSYour Name uint32_t ndi_count, first_ndi_vdev_id, i;
1083*5113495bSYour Name QDF_STATUS status;
1084*5113495bSYour Name
1085*5113495bSYour Name if (!psoc) {
1086*5113495bSYour Name nan_err("psoc object is NULL, no action will be taken");
1087*5113495bSYour Name return QDF_STATUS_E_INVAL;
1088*5113495bSYour Name }
1089*5113495bSYour Name
1090*5113495bSYour Name if (!ucfg_is_ndi_dbs_supported(psoc))
1091*5113495bSYour Name return QDF_STATUS_SUCCESS;
1092*5113495bSYour Name
1093*5113495bSYour Name ndi_count = policy_mgr_mode_specific_connection_count(psoc, PM_NDI_MODE,
1094*5113495bSYour Name NULL);
1095*5113495bSYour Name /* NDP force disable is done for unsupported concurrencies: NDI+SAP */
1096*5113495bSYour Name if (force) {
1097*5113495bSYour Name nan_debug("Force disable all NDPs");
1098*5113495bSYour Name for (i = 0; i < ndi_count; i++) {
1099*5113495bSYour Name first_ndi_vdev_id =
1100*5113495bSYour Name policy_mgr_mode_specific_vdev_id(psoc,
1101*5113495bSYour Name PM_NDI_MODE);
1102*5113495bSYour Name status = ucfg_nan_disable_ndi(psoc, first_ndi_vdev_id);
1103*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
1104*5113495bSYour Name return status;
1105*5113495bSYour Name }
1106*5113495bSYour Name return QDF_STATUS_SUCCESS;
1107*5113495bSYour Name }
1108*5113495bSYour Name
1109*5113495bSYour Name if (ndi_count < 2) {
1110*5113495bSYour Name nan_debug("No more than one NDI is active, nothing to do...");
1111*5113495bSYour Name return QDF_STATUS_SUCCESS;
1112*5113495bSYour Name }
1113*5113495bSYour Name
1114*5113495bSYour Name /*
1115*5113495bSYour Name * At least 2 NDI active concurrencies exist. Disable all NDP's on the
1116*5113495bSYour Name * first NDI to support an incoming connection.
1117*5113495bSYour Name */
1118*5113495bSYour Name first_ndi_vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_NDI_MODE);
1119*5113495bSYour Name status = ucfg_nan_disable_ndi(psoc, first_ndi_vdev_id);
1120*5113495bSYour Name
1121*5113495bSYour Name return status;
1122*5113495bSYour Name }
1123*5113495bSYour Name
ucfg_ndi_remove_entry_from_policy_mgr(struct wlan_objmgr_vdev * vdev)1124*5113495bSYour Name QDF_STATUS ucfg_ndi_remove_entry_from_policy_mgr(struct wlan_objmgr_vdev *vdev)
1125*5113495bSYour Name {
1126*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
1127*5113495bSYour Name struct nan_psoc_priv_obj *psoc_priv_obj;
1128*5113495bSYour Name struct nan_vdev_priv_obj *vdev_priv_obj = nan_get_vdev_priv_obj(vdev);
1129*5113495bSYour Name enum nan_datapath_state state;
1130*5113495bSYour Name uint32_t active_ndp_peers;
1131*5113495bSYour Name
1132*5113495bSYour Name psoc = wlan_vdev_get_psoc(vdev);
1133*5113495bSYour Name if (!psoc) {
1134*5113495bSYour Name nan_err("can't get psoc");
1135*5113495bSYour Name return QDF_STATUS_E_FAILURE;
1136*5113495bSYour Name }
1137*5113495bSYour Name
1138*5113495bSYour Name psoc_priv_obj = nan_get_psoc_priv_obj(psoc);
1139*5113495bSYour Name if (!psoc_priv_obj) {
1140*5113495bSYour Name nan_err("psoc_priv_obj is null");
1141*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1142*5113495bSYour Name }
1143*5113495bSYour Name
1144*5113495bSYour Name if (!vdev_priv_obj) {
1145*5113495bSYour Name nan_err("priv_obj is null");
1146*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1147*5113495bSYour Name }
1148*5113495bSYour Name
1149*5113495bSYour Name qdf_spin_lock_bh(&vdev_priv_obj->lock);
1150*5113495bSYour Name state = vdev_priv_obj->state;
1151*5113495bSYour Name active_ndp_peers = vdev_priv_obj->active_ndp_peers;
1152*5113495bSYour Name qdf_spin_unlock_bh(&vdev_priv_obj->lock);
1153*5113495bSYour Name
1154*5113495bSYour Name if (state == NAN_DATA_NDI_DELETED_STATE &&
1155*5113495bSYour Name NDI_CONCURRENCY_SUPPORTED(psoc) &&
1156*5113495bSYour Name active_ndp_peers) {
1157*5113495bSYour Name nan_info("Delete NDP peers: %u and remove NDI from policy mgr",
1158*5113495bSYour Name active_ndp_peers);
1159*5113495bSYour Name policy_mgr_decr_session_set_pcl(psoc, QDF_NDI_MODE,
1160*5113495bSYour Name wlan_vdev_get_id(vdev));
1161*5113495bSYour Name }
1162*5113495bSYour Name
1163*5113495bSYour Name return QDF_STATUS_SUCCESS;
1164*5113495bSYour Name }
1165*5113495bSYour Name
ucfg_nan_is_enable_disable_in_progress(struct wlan_objmgr_psoc * psoc)1166*5113495bSYour Name bool ucfg_nan_is_enable_disable_in_progress(struct wlan_objmgr_psoc *psoc)
1167*5113495bSYour Name {
1168*5113495bSYour Name enum nan_disc_state nan_state;
1169*5113495bSYour Name
1170*5113495bSYour Name nan_state = nan_get_discovery_state(psoc);
1171*5113495bSYour Name if (nan_state == NAN_DISC_ENABLE_IN_PROGRESS ||
1172*5113495bSYour Name nan_state == NAN_DISC_DISABLE_IN_PROGRESS) {
1173*5113495bSYour Name nan_info("NAN enable/disable is in progress, state: %u",
1174*5113495bSYour Name nan_state);
1175*5113495bSYour Name return true;
1176*5113495bSYour Name }
1177*5113495bSYour Name
1178*5113495bSYour Name return false;
1179*5113495bSYour Name }
1180*5113495bSYour Name
1181*5113495bSYour Name #ifdef NDP_SAP_CONCURRENCY_ENABLE
1182*5113495bSYour Name /**
1183*5113495bSYour Name * is_sap_ndp_concurrency_allowed() - Is SAP+NDP allowed
1184*5113495bSYour Name *
1185*5113495bSYour Name * Return: True if the NDP_SAP_CONCURRENCY_ENABLE feature define
1186*5113495bSYour Name * is enabled, false otherwise.
1187*5113495bSYour Name */
is_sap_ndp_concurrency_allowed(void)1188*5113495bSYour Name static inline bool is_sap_ndp_concurrency_allowed(void)
1189*5113495bSYour Name {
1190*5113495bSYour Name return true;
1191*5113495bSYour Name }
1192*5113495bSYour Name #else
is_sap_ndp_concurrency_allowed(void)1193*5113495bSYour Name static inline bool is_sap_ndp_concurrency_allowed(void)
1194*5113495bSYour Name {
1195*5113495bSYour Name return false;
1196*5113495bSYour Name }
1197*5113495bSYour Name #endif
1198*5113495bSYour Name
ucfg_nan_is_sta_ndp_concurrency_allowed(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)1199*5113495bSYour Name bool ucfg_nan_is_sta_ndp_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
1200*5113495bSYour Name struct wlan_objmgr_vdev *vdev)
1201*5113495bSYour Name {
1202*5113495bSYour Name uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
1203*5113495bSYour Name uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
1204*5113495bSYour Name uint32_t ndi_cnt, id, conc_ext_flags;
1205*5113495bSYour Name
1206*5113495bSYour Name if (nan_is_sta_sta_concurrency_present(psoc)) {
1207*5113495bSYour Name nan_err("STA+STA+NDP concurrency is not allowed");
1208*5113495bSYour Name return false;
1209*5113495bSYour Name }
1210*5113495bSYour Name
1211*5113495bSYour Name /*
1212*5113495bSYour Name * SAP+NDP concurrency is already validated in hdd_is_ndp_allowed().
1213*5113495bSYour Name * If SAP+NDP concurrency is enabled, return true from here to avoid
1214*5113495bSYour Name * failure.
1215*5113495bSYour Name */
1216*5113495bSYour Name if (is_sap_ndp_concurrency_allowed())
1217*5113495bSYour Name return true;
1218*5113495bSYour Name
1219*5113495bSYour Name /* ML STA + NAN + NDP concurrency is allowed only if firmware
1220*5113495bSYour Name * support is present
1221*5113495bSYour Name */
1222*5113495bSYour Name if (policy_mgr_is_mlo_sta_present(psoc) &&
1223*5113495bSYour Name !wlan_is_mlo_sta_nan_ndi_allowed(psoc))
1224*5113495bSYour Name return false;
1225*5113495bSYour Name
1226*5113495bSYour Name ndi_cnt = policy_mgr_get_mode_specific_conn_info(psoc,
1227*5113495bSYour Name freq_list,
1228*5113495bSYour Name vdev_id_list,
1229*5113495bSYour Name PM_NDI_MODE);
1230*5113495bSYour Name
1231*5113495bSYour Name /* Allow if no other NDP peers are present on the NDIs */
1232*5113495bSYour Name if (!ndi_cnt)
1233*5113495bSYour Name return true;
1234*5113495bSYour Name
1235*5113495bSYour Name /*
1236*5113495bSYour Name * Allow NDP creation if the current NDP request is on
1237*5113495bSYour Name * the NDI which already has an NDP by checking the vdev id of
1238*5113495bSYour Name * the NDIs
1239*5113495bSYour Name */
1240*5113495bSYour Name for (id = 0; id < ndi_cnt; id++)
1241*5113495bSYour Name if (wlan_vdev_get_id(vdev) == vdev_id_list[id])
1242*5113495bSYour Name return true;
1243*5113495bSYour Name
1244*5113495bSYour Name /* If the flow reaches here then it is 4th NDI with STA */
1245*5113495bSYour Name if (!ucfg_nan_is_sta_nan_ndi_4_port_allowed(psoc))
1246*5113495bSYour Name return false;
1247*5113495bSYour Name
1248*5113495bSYour Name conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false);
1249*5113495bSYour Name
1250*5113495bSYour Name /* The final freq would be provided by FW, it is not known now */
1251*5113495bSYour Name return policy_mgr_allow_concurrency(psoc, PM_NDI_MODE, 0,
1252*5113495bSYour Name HW_MODE_20_MHZ, conc_ext_flags,
1253*5113495bSYour Name wlan_vdev_get_id(vdev));
1254*5113495bSYour Name }
1255*5113495bSYour Name
1256*5113495bSYour Name bool
ucfg_nan_is_sta_nan_ndi_4_port_allowed(struct wlan_objmgr_psoc * psoc)1257*5113495bSYour Name ucfg_nan_is_sta_nan_ndi_4_port_allowed(struct wlan_objmgr_psoc *psoc)
1258*5113495bSYour Name {
1259*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1260*5113495bSYour Name
1261*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1262*5113495bSYour Name if (!psoc_nan_obj) {
1263*5113495bSYour Name nan_err("psoc_nan_obj is null");
1264*5113495bSYour Name return false;
1265*5113495bSYour Name }
1266*5113495bSYour Name
1267*5113495bSYour Name return psoc_nan_obj->nan_caps.sta_nan_ndi_ndi_allowed;
1268*5113495bSYour Name }
1269*5113495bSYour Name
ucfg_nan_is_beamforming_supported(struct wlan_objmgr_psoc * psoc)1270*5113495bSYour Name bool ucfg_nan_is_beamforming_supported(struct wlan_objmgr_psoc *psoc)
1271*5113495bSYour Name {
1272*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1273*5113495bSYour Name
1274*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1275*5113495bSYour Name if (!psoc_nan_obj) {
1276*5113495bSYour Name nan_err("psoc_nan_obj is null");
1277*5113495bSYour Name return false;
1278*5113495bSYour Name }
1279*5113495bSYour Name
1280*5113495bSYour Name return psoc_nan_obj->nan_caps.ndi_txbf_supported;
1281*5113495bSYour Name }
1282*5113495bSYour Name
1283*5113495bSYour Name static inline bool
ucfg_is_nan_enabled(struct nan_psoc_priv_obj * psoc_nan_obj)1284*5113495bSYour Name ucfg_is_nan_enabled(struct nan_psoc_priv_obj *psoc_nan_obj)
1285*5113495bSYour Name {
1286*5113495bSYour Name return psoc_nan_obj->cfg_param.enable;
1287*5113495bSYour Name }
1288*5113495bSYour Name
1289*5113495bSYour Name static inline bool
ucfg_nan_is_vdev_creation_supp_by_fw(struct nan_psoc_priv_obj * psoc_nan_obj)1290*5113495bSYour Name ucfg_nan_is_vdev_creation_supp_by_fw(struct nan_psoc_priv_obj *psoc_nan_obj)
1291*5113495bSYour Name {
1292*5113495bSYour Name return psoc_nan_obj->nan_caps.nan_vdev_allowed;
1293*5113495bSYour Name }
1294*5113495bSYour Name
1295*5113495bSYour Name static inline bool
ucfg_nan_is_vdev_creation_supp_by_host(struct nan_psoc_priv_obj * nan_obj)1296*5113495bSYour Name ucfg_nan_is_vdev_creation_supp_by_host(struct nan_psoc_priv_obj *nan_obj)
1297*5113495bSYour Name {
1298*5113495bSYour Name return nan_obj->cfg_param.nan_separate_iface_support;
1299*5113495bSYour Name }
1300*5113495bSYour Name
ucfg_nan_cleanup_all_ndps(struct wlan_objmgr_psoc * psoc)1301*5113495bSYour Name static void ucfg_nan_cleanup_all_ndps(struct wlan_objmgr_psoc *psoc)
1302*5113495bSYour Name {
1303*5113495bSYour Name QDF_STATUS status;
1304*5113495bSYour Name uint32_t ndi_count, vdev_id, i;
1305*5113495bSYour Name
1306*5113495bSYour Name ndi_count = policy_mgr_mode_specific_connection_count(psoc, PM_NDI_MODE,
1307*5113495bSYour Name NULL);
1308*5113495bSYour Name for (i = 0; i < ndi_count; i++) {
1309*5113495bSYour Name vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_NDI_MODE);
1310*5113495bSYour Name status = ucfg_nan_disable_ndi(psoc, vdev_id);
1311*5113495bSYour Name if (status == QDF_STATUS_E_TIMEOUT)
1312*5113495bSYour Name policy_mgr_decr_session_set_pcl(psoc, QDF_NDI_MODE,
1313*5113495bSYour Name vdev_id);
1314*5113495bSYour Name }
1315*5113495bSYour Name }
1316*5113495bSYour Name
ucfg_disable_nan_discovery(struct wlan_objmgr_psoc * psoc,uint8_t * data,uint32_t data_len)1317*5113495bSYour Name QDF_STATUS ucfg_disable_nan_discovery(struct wlan_objmgr_psoc *psoc,
1318*5113495bSYour Name uint8_t *data, uint32_t data_len)
1319*5113495bSYour Name {
1320*5113495bSYour Name struct nan_disable_req *nan_req;
1321*5113495bSYour Name QDF_STATUS status;
1322*5113495bSYour Name
1323*5113495bSYour Name ucfg_nan_cleanup_all_ndps(psoc);
1324*5113495bSYour Name
1325*5113495bSYour Name nan_req = qdf_mem_malloc(sizeof(*nan_req) + data_len);
1326*5113495bSYour Name if (!nan_req)
1327*5113495bSYour Name return -ENOMEM;
1328*5113495bSYour Name qdf_mem_zero(nan_req, sizeof(*nan_req) + data_len);
1329*5113495bSYour Name
1330*5113495bSYour Name nan_req->psoc = psoc;
1331*5113495bSYour Name nan_req->disable_2g_discovery = true;
1332*5113495bSYour Name nan_req->disable_5g_discovery = true;
1333*5113495bSYour Name if (data_len && data) {
1334*5113495bSYour Name nan_req->params.request_data_len = data_len;
1335*5113495bSYour Name qdf_mem_copy(nan_req->params.request_data, data, data_len);
1336*5113495bSYour Name }
1337*5113495bSYour Name
1338*5113495bSYour Name status = ucfg_nan_discovery_req(nan_req, NAN_DISABLE_REQ);
1339*5113495bSYour Name
1340*5113495bSYour Name if (QDF_IS_STATUS_SUCCESS(status))
1341*5113495bSYour Name nan_debug("Successfully sent NAN Disable request");
1342*5113495bSYour Name else
1343*5113495bSYour Name nan_debug("Unable to send NAN Disable request: %u", status);
1344*5113495bSYour Name
1345*5113495bSYour Name qdf_mem_free(nan_req);
1346*5113495bSYour Name return status;
1347*5113495bSYour Name }
1348*5113495bSYour Name
ucfg_nan_is_vdev_creation_allowed(struct wlan_objmgr_psoc * psoc)1349*5113495bSYour Name bool ucfg_nan_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc)
1350*5113495bSYour Name {
1351*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1352*5113495bSYour Name bool host_support, fw_support;
1353*5113495bSYour Name
1354*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1355*5113495bSYour Name if (!psoc_nan_obj) {
1356*5113495bSYour Name nan_err("psoc_nan_obj is null");
1357*5113495bSYour Name return false;
1358*5113495bSYour Name }
1359*5113495bSYour Name
1360*5113495bSYour Name if (!ucfg_is_nan_enabled(psoc_nan_obj)) {
1361*5113495bSYour Name nan_debug("NAN is not enabled");
1362*5113495bSYour Name return false;
1363*5113495bSYour Name }
1364*5113495bSYour Name
1365*5113495bSYour Name host_support = ucfg_nan_is_vdev_creation_supp_by_host(psoc_nan_obj);
1366*5113495bSYour Name fw_support = ucfg_nan_is_vdev_creation_supp_by_fw(psoc_nan_obj);
1367*5113495bSYour Name if (!host_support || !fw_support) {
1368*5113495bSYour Name nan_debug("NAN separate vdev%s supported by host,%s supported by firmware",
1369*5113495bSYour Name host_support ? "" : " not", fw_support ? "" : " not");
1370*5113495bSYour Name return false;
1371*5113495bSYour Name }
1372*5113495bSYour Name
1373*5113495bSYour Name return true;
1374*5113495bSYour Name }
1375*5113495bSYour Name
1376*5113495bSYour Name void
ucfg_nan_set_vdev_creation_supp_by_fw(struct wlan_objmgr_psoc * psoc,bool set)1377*5113495bSYour Name ucfg_nan_set_vdev_creation_supp_by_fw(struct wlan_objmgr_psoc *psoc, bool set)
1378*5113495bSYour Name {
1379*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1380*5113495bSYour Name
1381*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1382*5113495bSYour Name if (!psoc_nan_obj) {
1383*5113495bSYour Name nan_err("psoc_nan_obj is null");
1384*5113495bSYour Name return;
1385*5113495bSYour Name }
1386*5113495bSYour Name
1387*5113495bSYour Name psoc_nan_obj->nan_caps.nan_vdev_allowed = set;
1388*5113495bSYour Name }
1389*5113495bSYour Name
ucfg_get_nan_feature_config(struct wlan_objmgr_psoc * psoc,uint32_t * nan_feature_config)1390*5113495bSYour Name QDF_STATUS ucfg_get_nan_feature_config(struct wlan_objmgr_psoc *psoc,
1391*5113495bSYour Name uint32_t *nan_feature_config)
1392*5113495bSYour Name {
1393*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1394*5113495bSYour Name
1395*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1396*5113495bSYour Name if (!psoc_nan_obj) {
1397*5113495bSYour Name nan_err("psoc_nan_obj is null");
1398*5113495bSYour Name *nan_feature_config = cfg_default(CFG_NAN_FEATURE_CONFIG);
1399*5113495bSYour Name return QDF_STATUS_E_INVAL;
1400*5113495bSYour Name }
1401*5113495bSYour Name
1402*5113495bSYour Name *nan_feature_config = psoc_nan_obj->cfg_param.nan_feature_config;
1403*5113495bSYour Name return QDF_STATUS_SUCCESS;
1404*5113495bSYour Name }
1405*5113495bSYour Name
ucfg_is_nan_vdev(struct wlan_objmgr_vdev * vdev)1406*5113495bSYour Name bool ucfg_is_nan_vdev(struct wlan_objmgr_vdev *vdev)
1407*5113495bSYour Name {
1408*5113495bSYour Name if (wlan_vdev_mlme_get_opmode(vdev) == QDF_NAN_DISC_MODE ||
1409*5113495bSYour Name (!ucfg_nan_is_vdev_creation_allowed(wlan_vdev_get_psoc(vdev)) &&
1410*5113495bSYour Name wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE))
1411*5113495bSYour Name return true;
1412*5113495bSYour Name
1413*5113495bSYour Name return false;
1414*5113495bSYour Name }
1415*5113495bSYour Name
ucfg_nan_disable_ind_to_userspace(struct wlan_objmgr_psoc * psoc)1416*5113495bSYour Name QDF_STATUS ucfg_nan_disable_ind_to_userspace(struct wlan_objmgr_psoc *psoc)
1417*5113495bSYour Name {
1418*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1419*5113495bSYour Name struct nan_event_params *disable_ind;
1420*5113495bSYour Name struct nan_disable_ind_msg msg = {
1421*5113495bSYour Name .msg_hdr.msg_id = NAN_MSG_ID_DISABLE_INDICATION,
1422*5113495bSYour Name .reason = 0, /* success */ };
1423*5113495bSYour Name
1424*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1425*5113495bSYour Name if (!psoc_nan_obj) {
1426*5113495bSYour Name nan_err("psoc_nan_obj is null");
1427*5113495bSYour Name return QDF_STATUS_E_INVAL;
1428*5113495bSYour Name }
1429*5113495bSYour Name
1430*5113495bSYour Name disable_ind = qdf_mem_malloc(sizeof(struct nan_event_params) +
1431*5113495bSYour Name sizeof(msg));
1432*5113495bSYour Name if (!disable_ind)
1433*5113495bSYour Name return QDF_STATUS_E_NOMEM;
1434*5113495bSYour Name
1435*5113495bSYour Name disable_ind->psoc = psoc,
1436*5113495bSYour Name disable_ind->evt_type = nan_event_id_disable_ind;
1437*5113495bSYour Name disable_ind->buf_len = sizeof(msg);
1438*5113495bSYour Name qdf_mem_copy(disable_ind->buf, &msg, disable_ind->buf_len);
1439*5113495bSYour Name
1440*5113495bSYour Name psoc_nan_obj->cb_obj.os_if_nan_event_handler(disable_ind);
1441*5113495bSYour Name
1442*5113495bSYour Name qdf_mem_free(disable_ind);
1443*5113495bSYour Name return QDF_STATUS_SUCCESS;
1444*5113495bSYour Name }
1445*5113495bSYour Name
ucfg_is_nan_allowed_on_freq(struct wlan_objmgr_pdev * pdev,uint32_t freq)1446*5113495bSYour Name bool ucfg_is_nan_allowed_on_freq(struct wlan_objmgr_pdev *pdev, uint32_t freq)
1447*5113495bSYour Name {
1448*5113495bSYour Name return wlan_is_nan_allowed_on_freq(pdev, freq);
1449*5113495bSYour Name }
1450*5113495bSYour Name
ucfg_is_mlo_sta_nan_ndi_allowed(struct wlan_objmgr_psoc * psoc)1451*5113495bSYour Name bool ucfg_is_mlo_sta_nan_ndi_allowed(struct wlan_objmgr_psoc *psoc)
1452*5113495bSYour Name {
1453*5113495bSYour Name return wlan_is_mlo_sta_nan_ndi_allowed(psoc);
1454*5113495bSYour Name }
1455