1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name * Copyright (c) 2021-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
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 core nan function definitions
22*5113495bSYour Name */
23*5113495bSYour Name
24*5113495bSYour Name #include "wlan_utility.h"
25*5113495bSYour Name #include "nan_ucfg_api.h"
26*5113495bSYour Name #include "wlan_nan_api.h"
27*5113495bSYour Name #include "target_if_nan.h"
28*5113495bSYour Name #include "scheduler_api.h"
29*5113495bSYour Name #include "wlan_policy_mgr_api.h"
30*5113495bSYour Name #include "wlan_osif_request_manager.h"
31*5113495bSYour Name #include "wlan_serialization_api.h"
32*5113495bSYour Name #include "wlan_objmgr_cmn.h"
33*5113495bSYour Name #include "wlan_tdls_ucfg_api.h"
34*5113495bSYour Name #include "wlan_objmgr_global_obj.h"
35*5113495bSYour Name #include "wlan_objmgr_psoc_obj.h"
36*5113495bSYour Name #include "wlan_objmgr_pdev_obj.h"
37*5113495bSYour Name #include "wlan_objmgr_vdev_obj.h"
38*5113495bSYour Name #include "qdf_platform.h"
39*5113495bSYour Name #include "wlan_osif_request_manager.h"
40*5113495bSYour Name #include "wlan_p2p_api.h"
41*5113495bSYour Name #include "wlan_mlme_vdev_mgr_interface.h"
42*5113495bSYour Name
nan_set_discovery_state(struct wlan_objmgr_psoc * psoc,enum nan_disc_state new_state)43*5113495bSYour Name QDF_STATUS nan_set_discovery_state(struct wlan_objmgr_psoc *psoc,
44*5113495bSYour Name enum nan_disc_state new_state)
45*5113495bSYour Name {
46*5113495bSYour Name enum nan_disc_state cur_state;
47*5113495bSYour Name struct nan_psoc_priv_obj *psoc_priv = nan_get_psoc_priv_obj(psoc);
48*5113495bSYour Name bool nan_state_change_allowed = false;
49*5113495bSYour Name QDF_STATUS status = QDF_STATUS_E_INVAL;
50*5113495bSYour Name
51*5113495bSYour Name if (!psoc_priv) {
52*5113495bSYour Name nan_err("nan psoc priv object is NULL");
53*5113495bSYour Name return QDF_STATUS_E_INVAL;
54*5113495bSYour Name }
55*5113495bSYour Name
56*5113495bSYour Name qdf_spin_lock_bh(&psoc_priv->lock);
57*5113495bSYour Name cur_state = psoc_priv->disc_state;
58*5113495bSYour Name if (cur_state == new_state) {
59*5113495bSYour Name qdf_spin_unlock_bh(&psoc_priv->lock);
60*5113495bSYour Name nan_err("curr_state: %u and new state: %u are same",
61*5113495bSYour Name cur_state, new_state);
62*5113495bSYour Name return status;
63*5113495bSYour Name }
64*5113495bSYour Name
65*5113495bSYour Name switch (new_state) {
66*5113495bSYour Name case NAN_DISC_DISABLED:
67*5113495bSYour Name nan_state_change_allowed = true;
68*5113495bSYour Name break;
69*5113495bSYour Name case NAN_DISC_ENABLE_IN_PROGRESS:
70*5113495bSYour Name if (cur_state == NAN_DISC_DISABLED)
71*5113495bSYour Name nan_state_change_allowed = true;
72*5113495bSYour Name break;
73*5113495bSYour Name case NAN_DISC_ENABLED:
74*5113495bSYour Name if (cur_state == NAN_DISC_ENABLE_IN_PROGRESS)
75*5113495bSYour Name nan_state_change_allowed = true;
76*5113495bSYour Name break;
77*5113495bSYour Name case NAN_DISC_DISABLE_IN_PROGRESS:
78*5113495bSYour Name if (cur_state == NAN_DISC_ENABLE_IN_PROGRESS ||
79*5113495bSYour Name cur_state == NAN_DISC_ENABLED)
80*5113495bSYour Name nan_state_change_allowed = true;
81*5113495bSYour Name break;
82*5113495bSYour Name default:
83*5113495bSYour Name break;
84*5113495bSYour Name }
85*5113495bSYour Name
86*5113495bSYour Name if (nan_state_change_allowed) {
87*5113495bSYour Name psoc_priv->disc_state = new_state;
88*5113495bSYour Name status = QDF_STATUS_SUCCESS;
89*5113495bSYour Name }
90*5113495bSYour Name
91*5113495bSYour Name qdf_spin_unlock_bh(&psoc_priv->lock);
92*5113495bSYour Name
93*5113495bSYour Name nan_debug("NAN State transitioned from %d -> %d", cur_state,
94*5113495bSYour Name psoc_priv->disc_state);
95*5113495bSYour Name
96*5113495bSYour Name return status;
97*5113495bSYour Name }
98*5113495bSYour Name
nan_get_discovery_state(struct wlan_objmgr_psoc * psoc)99*5113495bSYour Name enum nan_disc_state nan_get_discovery_state(struct wlan_objmgr_psoc *psoc)
100*5113495bSYour Name {
101*5113495bSYour Name struct nan_psoc_priv_obj *psoc_priv = nan_get_psoc_priv_obj(psoc);
102*5113495bSYour Name
103*5113495bSYour Name if (!psoc_priv) {
104*5113495bSYour Name nan_err("nan psoc priv object is NULL");
105*5113495bSYour Name return NAN_DISC_DISABLED;
106*5113495bSYour Name }
107*5113495bSYour Name
108*5113495bSYour Name return psoc_priv->disc_state;
109*5113495bSYour Name }
110*5113495bSYour Name
nan_release_cmd(void * in_req,uint32_t cmdtype)111*5113495bSYour Name void nan_release_cmd(void *in_req, uint32_t cmdtype)
112*5113495bSYour Name {
113*5113495bSYour Name struct wlan_objmgr_vdev *vdev = NULL;
114*5113495bSYour Name
115*5113495bSYour Name if (!in_req)
116*5113495bSYour Name return;
117*5113495bSYour Name
118*5113495bSYour Name switch (cmdtype) {
119*5113495bSYour Name case WLAN_SER_CMD_NDP_INIT_REQ: {
120*5113495bSYour Name struct nan_datapath_initiator_req *req = in_req;
121*5113495bSYour Name
122*5113495bSYour Name vdev = req->vdev;
123*5113495bSYour Name break;
124*5113495bSYour Name }
125*5113495bSYour Name case WLAN_SER_CMD_NDP_RESP_REQ: {
126*5113495bSYour Name struct nan_datapath_responder_req *req = in_req;
127*5113495bSYour Name
128*5113495bSYour Name vdev = req->vdev;
129*5113495bSYour Name break;
130*5113495bSYour Name }
131*5113495bSYour Name case WLAN_SER_CMD_NDP_DATA_END_INIT_REQ: {
132*5113495bSYour Name struct nan_datapath_end_req *req = in_req;
133*5113495bSYour Name
134*5113495bSYour Name vdev = req->vdev;
135*5113495bSYour Name break;
136*5113495bSYour Name }
137*5113495bSYour Name case WLAN_SER_CMD_NDP_END_ALL_REQ: {
138*5113495bSYour Name struct nan_datapath_end_all_ndps *req = in_req;
139*5113495bSYour Name
140*5113495bSYour Name vdev = req->vdev;
141*5113495bSYour Name break;
142*5113495bSYour Name }
143*5113495bSYour Name default:
144*5113495bSYour Name nan_err("invalid req type: %d", cmdtype);
145*5113495bSYour Name break;
146*5113495bSYour Name }
147*5113495bSYour Name
148*5113495bSYour Name if (vdev)
149*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
150*5113495bSYour Name else
151*5113495bSYour Name nan_err("vdev is null");
152*5113495bSYour Name
153*5113495bSYour Name qdf_mem_free(in_req);
154*5113495bSYour Name }
155*5113495bSYour Name
nan_req_incomplete(void * req,uint32_t cmdtype)156*5113495bSYour Name static void nan_req_incomplete(void *req, uint32_t cmdtype)
157*5113495bSYour Name {
158*5113495bSYour Name /* send msg to userspace if needed that cmd got incomplete */
159*5113495bSYour Name }
160*5113495bSYour Name
nan_req_activated(void * in_req,uint32_t cmdtype)161*5113495bSYour Name static void nan_req_activated(void *in_req, uint32_t cmdtype)
162*5113495bSYour Name {
163*5113495bSYour Name uint32_t req_type;
164*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
165*5113495bSYour Name struct wlan_objmgr_vdev *vdev;
166*5113495bSYour Name struct wlan_nan_tx_ops *tx_ops;
167*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
168*5113495bSYour Name
169*5113495bSYour Name switch (cmdtype) {
170*5113495bSYour Name case WLAN_SER_CMD_NDP_INIT_REQ: {
171*5113495bSYour Name struct nan_datapath_initiator_req *req = in_req;
172*5113495bSYour Name
173*5113495bSYour Name vdev = req->vdev;
174*5113495bSYour Name req_type = NDP_INITIATOR_REQ;
175*5113495bSYour Name break;
176*5113495bSYour Name }
177*5113495bSYour Name case WLAN_SER_CMD_NDP_RESP_REQ: {
178*5113495bSYour Name struct nan_datapath_responder_req *req = in_req;
179*5113495bSYour Name
180*5113495bSYour Name vdev = req->vdev;
181*5113495bSYour Name req_type = NDP_RESPONDER_REQ;
182*5113495bSYour Name break;
183*5113495bSYour Name }
184*5113495bSYour Name case WLAN_SER_CMD_NDP_DATA_END_INIT_REQ: {
185*5113495bSYour Name struct nan_datapath_end_req *req = in_req;
186*5113495bSYour Name
187*5113495bSYour Name vdev = req->vdev;
188*5113495bSYour Name req_type = NDP_END_REQ;
189*5113495bSYour Name break;
190*5113495bSYour Name }
191*5113495bSYour Name case WLAN_SER_CMD_NDP_END_ALL_REQ: {
192*5113495bSYour Name struct nan_datapath_end_all_ndps *req = in_req;
193*5113495bSYour Name
194*5113495bSYour Name vdev = req->vdev;
195*5113495bSYour Name req_type = NDP_END_ALL;
196*5113495bSYour Name break;
197*5113495bSYour Name }
198*5113495bSYour Name default:
199*5113495bSYour Name nan_alert("in correct cmdtype: %d", cmdtype);
200*5113495bSYour Name return;
201*5113495bSYour Name }
202*5113495bSYour Name
203*5113495bSYour Name if (!vdev) {
204*5113495bSYour Name nan_alert("vdev is null");
205*5113495bSYour Name return;
206*5113495bSYour Name }
207*5113495bSYour Name
208*5113495bSYour Name psoc = wlan_vdev_get_psoc(vdev);
209*5113495bSYour Name if (!psoc) {
210*5113495bSYour Name nan_alert("psoc is null");
211*5113495bSYour Name return;
212*5113495bSYour Name }
213*5113495bSYour Name
214*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
215*5113495bSYour Name if (!psoc_nan_obj) {
216*5113495bSYour Name nan_err("psoc_nan_obj is null");
217*5113495bSYour Name return;
218*5113495bSYour Name }
219*5113495bSYour Name
220*5113495bSYour Name tx_ops = &psoc_nan_obj->tx_ops;
221*5113495bSYour Name if (!tx_ops) {
222*5113495bSYour Name nan_alert("tx_ops is null");
223*5113495bSYour Name return;
224*5113495bSYour Name }
225*5113495bSYour Name
226*5113495bSYour Name /* send ndp_intiator_req/responder_req/end_req to FW */
227*5113495bSYour Name tx_ops->nan_datapath_req_tx(in_req, req_type);
228*5113495bSYour Name }
229*5113495bSYour Name
nan_serialized_cb(struct wlan_serialization_command * ser_cmd,enum wlan_serialization_cb_reason reason)230*5113495bSYour Name static QDF_STATUS nan_serialized_cb(struct wlan_serialization_command *ser_cmd,
231*5113495bSYour Name enum wlan_serialization_cb_reason reason)
232*5113495bSYour Name {
233*5113495bSYour Name void *req;
234*5113495bSYour Name
235*5113495bSYour Name if (!ser_cmd || !ser_cmd->umac_cmd) {
236*5113495bSYour Name nan_alert("cmd or umac_cmd is null");
237*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
238*5113495bSYour Name }
239*5113495bSYour Name req = ser_cmd->umac_cmd;
240*5113495bSYour Name
241*5113495bSYour Name switch (reason) {
242*5113495bSYour Name case WLAN_SER_CB_ACTIVATE_CMD:
243*5113495bSYour Name nan_req_activated(req, ser_cmd->cmd_type);
244*5113495bSYour Name break;
245*5113495bSYour Name case WLAN_SER_CB_CANCEL_CMD:
246*5113495bSYour Name case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
247*5113495bSYour Name nan_req_incomplete(req, ser_cmd->cmd_type);
248*5113495bSYour Name break;
249*5113495bSYour Name case WLAN_SER_CB_RELEASE_MEM_CMD:
250*5113495bSYour Name nan_release_cmd(req, ser_cmd->cmd_type);
251*5113495bSYour Name break;
252*5113495bSYour Name default:
253*5113495bSYour Name /* Do nothing but logging */
254*5113495bSYour Name nan_alert("invalid serialized cb reason: %d", reason);
255*5113495bSYour Name break;
256*5113495bSYour Name }
257*5113495bSYour Name
258*5113495bSYour Name return QDF_STATUS_SUCCESS;
259*5113495bSYour Name }
260*5113495bSYour Name
nan_scheduled_msg_handler(struct scheduler_msg * msg)261*5113495bSYour Name QDF_STATUS nan_scheduled_msg_handler(struct scheduler_msg *msg)
262*5113495bSYour Name {
263*5113495bSYour Name enum wlan_serialization_status status = 0;
264*5113495bSYour Name struct wlan_serialization_command cmd = {0};
265*5113495bSYour Name
266*5113495bSYour Name if (!msg || !msg->bodyptr) {
267*5113495bSYour Name nan_alert("msg or bodyptr is null");
268*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
269*5113495bSYour Name }
270*5113495bSYour Name switch (msg->type) {
271*5113495bSYour Name case NDP_INITIATOR_REQ: {
272*5113495bSYour Name struct nan_datapath_initiator_req *req = msg->bodyptr;
273*5113495bSYour Name
274*5113495bSYour Name cmd.cmd_type = WLAN_SER_CMD_NDP_INIT_REQ;
275*5113495bSYour Name cmd.vdev = req->vdev;
276*5113495bSYour Name break;
277*5113495bSYour Name }
278*5113495bSYour Name case NDP_RESPONDER_REQ: {
279*5113495bSYour Name struct nan_datapath_responder_req *req = msg->bodyptr;
280*5113495bSYour Name
281*5113495bSYour Name cmd.cmd_type = WLAN_SER_CMD_NDP_RESP_REQ;
282*5113495bSYour Name cmd.vdev = req->vdev;
283*5113495bSYour Name break;
284*5113495bSYour Name }
285*5113495bSYour Name case NDP_END_REQ: {
286*5113495bSYour Name struct nan_datapath_end_req *req = msg->bodyptr;
287*5113495bSYour Name
288*5113495bSYour Name cmd.cmd_type = WLAN_SER_CMD_NDP_DATA_END_INIT_REQ;
289*5113495bSYour Name cmd.vdev = req->vdev;
290*5113495bSYour Name break;
291*5113495bSYour Name }
292*5113495bSYour Name case NDP_END_ALL: {
293*5113495bSYour Name struct nan_datapath_end_all_ndps *req = msg->bodyptr;
294*5113495bSYour Name
295*5113495bSYour Name cmd.cmd_type = WLAN_SER_CMD_NDP_END_ALL_REQ;
296*5113495bSYour Name cmd.vdev = req->vdev;
297*5113495bSYour Name break;
298*5113495bSYour Name }
299*5113495bSYour Name default:
300*5113495bSYour Name nan_err("wrong request type: %d", msg->type);
301*5113495bSYour Name return QDF_STATUS_E_INVAL;
302*5113495bSYour Name }
303*5113495bSYour Name
304*5113495bSYour Name /* TBD - support more than one req of same type or avoid */
305*5113495bSYour Name cmd.cmd_id = 0;
306*5113495bSYour Name cmd.cmd_cb = nan_serialized_cb;
307*5113495bSYour Name cmd.umac_cmd = msg->bodyptr;
308*5113495bSYour Name cmd.source = WLAN_UMAC_COMP_NAN;
309*5113495bSYour Name cmd.is_high_priority = false;
310*5113495bSYour Name cmd.cmd_timeout_duration = NAN_SER_CMD_TIMEOUT;
311*5113495bSYour Name nan_debug("cmd_type: %d", cmd.cmd_type);
312*5113495bSYour Name cmd.is_blocking = true;
313*5113495bSYour Name
314*5113495bSYour Name status = wlan_serialization_request(&cmd);
315*5113495bSYour Name /* following is TBD */
316*5113495bSYour Name if (status != WLAN_SER_CMD_ACTIVE && status != WLAN_SER_CMD_PENDING) {
317*5113495bSYour Name nan_err("unable to serialize command");
318*5113495bSYour Name wlan_objmgr_vdev_release_ref(cmd.vdev, WLAN_NAN_ID);
319*5113495bSYour Name qdf_mem_free(msg->bodyptr);
320*5113495bSYour Name msg->bodyptr = NULL;
321*5113495bSYour Name return QDF_STATUS_E_INVAL;
322*5113495bSYour Name }
323*5113495bSYour Name return QDF_STATUS_SUCCESS;
324*5113495bSYour Name }
325*5113495bSYour Name
326*5113495bSYour Name static QDF_STATUS
nan_increment_ndp_sessions(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_ndi_mac,struct nan_datapath_channel_info * ndp_chan_info)327*5113495bSYour Name nan_increment_ndp_sessions(struct wlan_objmgr_psoc *psoc,
328*5113495bSYour Name struct qdf_mac_addr *peer_ndi_mac,
329*5113495bSYour Name struct nan_datapath_channel_info *ndp_chan_info)
330*5113495bSYour Name {
331*5113495bSYour Name struct wlan_objmgr_peer *peer;
332*5113495bSYour Name struct nan_peer_priv_obj *peer_nan_obj;
333*5113495bSYour Name
334*5113495bSYour Name peer = wlan_objmgr_get_peer_by_mac(psoc,
335*5113495bSYour Name peer_ndi_mac->bytes,
336*5113495bSYour Name WLAN_NAN_ID);
337*5113495bSYour Name
338*5113495bSYour Name if (!peer) {
339*5113495bSYour Name nan_err("peer object is null");
340*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
341*5113495bSYour Name }
342*5113495bSYour Name
343*5113495bSYour Name peer_nan_obj = nan_get_peer_priv_obj(peer);
344*5113495bSYour Name if (!peer_nan_obj) {
345*5113495bSYour Name nan_err("peer_nan_obj is null");
346*5113495bSYour Name wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
347*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
348*5113495bSYour Name }
349*5113495bSYour Name qdf_spin_lock_bh(&peer_nan_obj->lock);
350*5113495bSYour Name
351*5113495bSYour Name /*
352*5113495bSYour Name * Store the first channel info in NDP Confirm as the home channel info
353*5113495bSYour Name * and store it in the peer private object.
354*5113495bSYour Name */
355*5113495bSYour Name if (!peer_nan_obj->active_ndp_sessions)
356*5113495bSYour Name qdf_mem_copy(&peer_nan_obj->home_chan_info, ndp_chan_info,
357*5113495bSYour Name sizeof(struct nan_datapath_channel_info));
358*5113495bSYour Name
359*5113495bSYour Name peer_nan_obj->active_ndp_sessions++;
360*5113495bSYour Name nan_debug("Number of active session = %d for peer:"QDF_MAC_ADDR_FMT,
361*5113495bSYour Name peer_nan_obj->active_ndp_sessions,
362*5113495bSYour Name QDF_MAC_ADDR_REF(peer_ndi_mac->bytes));
363*5113495bSYour Name qdf_spin_unlock_bh(&peer_nan_obj->lock);
364*5113495bSYour Name wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
365*5113495bSYour Name
366*5113495bSYour Name return QDF_STATUS_SUCCESS;
367*5113495bSYour Name }
368*5113495bSYour Name
nan_decrement_ndp_sessions(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_ndi_mac)369*5113495bSYour Name static QDF_STATUS nan_decrement_ndp_sessions(struct wlan_objmgr_psoc *psoc,
370*5113495bSYour Name struct qdf_mac_addr *peer_ndi_mac)
371*5113495bSYour Name {
372*5113495bSYour Name struct wlan_objmgr_peer *peer;
373*5113495bSYour Name struct nan_peer_priv_obj *peer_nan_obj;
374*5113495bSYour Name
375*5113495bSYour Name peer = wlan_objmgr_get_peer_by_mac(psoc,
376*5113495bSYour Name peer_ndi_mac->bytes,
377*5113495bSYour Name WLAN_NAN_ID);
378*5113495bSYour Name
379*5113495bSYour Name if (!peer) {
380*5113495bSYour Name nan_err("peer object is null");
381*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
382*5113495bSYour Name }
383*5113495bSYour Name
384*5113495bSYour Name peer_nan_obj = nan_get_peer_priv_obj(peer);
385*5113495bSYour Name if (!peer_nan_obj) {
386*5113495bSYour Name nan_err("peer_nan_obj is null");
387*5113495bSYour Name wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
388*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
389*5113495bSYour Name }
390*5113495bSYour Name
391*5113495bSYour Name qdf_spin_lock_bh(&peer_nan_obj->lock);
392*5113495bSYour Name if (!peer_nan_obj->active_ndp_sessions) {
393*5113495bSYour Name qdf_spin_unlock_bh(&peer_nan_obj->lock);
394*5113495bSYour Name nan_err("Active NDP sessions already zero!");
395*5113495bSYour Name wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
396*5113495bSYour Name return QDF_STATUS_E_FAILURE;
397*5113495bSYour Name }
398*5113495bSYour Name peer_nan_obj->active_ndp_sessions--;
399*5113495bSYour Name nan_debug("Number of active session = %d for peer:"QDF_MAC_ADDR_FMT,
400*5113495bSYour Name peer_nan_obj->active_ndp_sessions,
401*5113495bSYour Name QDF_MAC_ADDR_REF(peer_ndi_mac->bytes));
402*5113495bSYour Name qdf_spin_unlock_bh(&peer_nan_obj->lock);
403*5113495bSYour Name wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
404*5113495bSYour Name
405*5113495bSYour Name return QDF_STATUS_SUCCESS;
406*5113495bSYour Name }
407*5113495bSYour Name
408*5113495bSYour Name static QDF_STATUS
ndi_remove_and_update_primary_connection(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)409*5113495bSYour Name ndi_remove_and_update_primary_connection(struct wlan_objmgr_psoc *psoc,
410*5113495bSYour Name struct wlan_objmgr_vdev *vdev)
411*5113495bSYour Name {
412*5113495bSYour Name struct nan_vdev_priv_obj *vdev_nan_obj;
413*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
414*5113495bSYour Name struct nan_peer_priv_obj *peer_nan_obj = NULL;
415*5113495bSYour Name struct wlan_objmgr_peer *peer, *peer_next;
416*5113495bSYour Name qdf_list_t *peer_list;
417*5113495bSYour Name void (*nan_conc_callback)(void);
418*5113495bSYour Name
419*5113495bSYour Name
420*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
421*5113495bSYour Name if (!psoc_nan_obj) {
422*5113495bSYour Name nan_err("Invalid psoc nan private obj");
423*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
424*5113495bSYour Name }
425*5113495bSYour Name
426*5113495bSYour Name vdev_nan_obj = nan_get_vdev_priv_obj(vdev);
427*5113495bSYour Name if (!vdev_nan_obj) {
428*5113495bSYour Name nan_err("Invalid vdev nan private obj");
429*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
430*5113495bSYour Name }
431*5113495bSYour Name
432*5113495bSYour Name peer_list = &vdev->vdev_objmgr.wlan_peer_list;
433*5113495bSYour Name if (!peer_list) {
434*5113495bSYour Name nan_err("Peer list for vdev obj is NULL");
435*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
436*5113495bSYour Name }
437*5113495bSYour Name
438*5113495bSYour Name peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list,
439*5113495bSYour Name WLAN_NAN_ID);
440*5113495bSYour Name
441*5113495bSYour Name while (peer) {
442*5113495bSYour Name peer_nan_obj = nan_get_peer_priv_obj(peer);
443*5113495bSYour Name if (!peer_nan_obj)
444*5113495bSYour Name nan_err("NAN peer object for Peer " QDF_MAC_ADDR_FMT " is NULL",
445*5113495bSYour Name QDF_MAC_ADDR_REF(wlan_peer_get_macaddr(peer)));
446*5113495bSYour Name else if (peer_nan_obj->active_ndp_sessions)
447*5113495bSYour Name break;
448*5113495bSYour Name
449*5113495bSYour Name peer_next = wlan_peer_get_next_active_peer_of_vdev(vdev,
450*5113495bSYour Name peer_list,
451*5113495bSYour Name peer,
452*5113495bSYour Name WLAN_NAN_ID);
453*5113495bSYour Name wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
454*5113495bSYour Name peer = peer_next;
455*5113495bSYour Name }
456*5113495bSYour Name
457*5113495bSYour Name if (!peer && NDI_CONCURRENCY_SUPPORTED(psoc)) {
458*5113495bSYour Name policy_mgr_decr_session_set_pcl(psoc, QDF_NDI_MODE,
459*5113495bSYour Name wlan_vdev_get_id(vdev));
460*5113495bSYour Name vdev_nan_obj->ndp_init_done = false;
461*5113495bSYour Name
462*5113495bSYour Name nan_conc_callback = psoc_nan_obj->cb_obj.nan_concurrency_update;
463*5113495bSYour Name if (nan_conc_callback)
464*5113495bSYour Name nan_conc_callback();
465*5113495bSYour Name
466*5113495bSYour Name return QDF_STATUS_SUCCESS;
467*5113495bSYour Name }
468*5113495bSYour Name
469*5113495bSYour Name if (peer_nan_obj && NDI_CONCURRENCY_SUPPORTED(psoc)) {
470*5113495bSYour Name psoc_nan_obj->cb_obj.update_ndi_conn(wlan_vdev_get_id(vdev),
471*5113495bSYour Name &peer_nan_obj->home_chan_info);
472*5113495bSYour Name policy_mgr_update_connection_info(psoc, wlan_vdev_get_id(vdev));
473*5113495bSYour Name qdf_mem_copy(vdev_nan_obj->primary_peer_mac.bytes,
474*5113495bSYour Name wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE);
475*5113495bSYour Name policy_mgr_check_n_start_opportunistic_timer(psoc);
476*5113495bSYour Name }
477*5113495bSYour Name
478*5113495bSYour Name if (peer)
479*5113495bSYour Name wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
480*5113495bSYour Name
481*5113495bSYour Name return QDF_STATUS_SUCCESS;
482*5113495bSYour Name }
483*5113495bSYour Name
484*5113495bSYour Name static QDF_STATUS
ndi_update_ndp_session(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * peer_ndi_mac,struct nan_datapath_channel_info * ndp_chan_info)485*5113495bSYour Name ndi_update_ndp_session(struct wlan_objmgr_vdev *vdev,
486*5113495bSYour Name struct qdf_mac_addr *peer_ndi_mac,
487*5113495bSYour Name struct nan_datapath_channel_info *ndp_chan_info)
488*5113495bSYour Name {
489*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
490*5113495bSYour Name struct wlan_objmgr_peer *peer;
491*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
492*5113495bSYour Name struct nan_vdev_priv_obj *vdev_nan_obj;
493*5113495bSYour Name struct nan_peer_priv_obj *peer_nan_obj;
494*5113495bSYour Name
495*5113495bSYour Name psoc = wlan_vdev_get_psoc(vdev);
496*5113495bSYour Name
497*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
498*5113495bSYour Name if (!psoc_nan_obj) {
499*5113495bSYour Name nan_err("psoc_nan_obj is null");
500*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
501*5113495bSYour Name }
502*5113495bSYour Name
503*5113495bSYour Name vdev_nan_obj = nan_get_vdev_priv_obj(vdev);
504*5113495bSYour Name if (!vdev_nan_obj) {
505*5113495bSYour Name nan_err("NAN vdev private object is NULL");
506*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
507*5113495bSYour Name }
508*5113495bSYour Name
509*5113495bSYour Name peer = wlan_objmgr_get_peer_by_mac(psoc,
510*5113495bSYour Name peer_ndi_mac->bytes,
511*5113495bSYour Name WLAN_NAN_ID);
512*5113495bSYour Name
513*5113495bSYour Name if (!peer) {
514*5113495bSYour Name nan_err("peer object is null");
515*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
516*5113495bSYour Name }
517*5113495bSYour Name
518*5113495bSYour Name peer_nan_obj = nan_get_peer_priv_obj(peer);
519*5113495bSYour Name if (!peer_nan_obj) {
520*5113495bSYour Name nan_err("peer_nan_obj is null");
521*5113495bSYour Name wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
522*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
523*5113495bSYour Name }
524*5113495bSYour Name
525*5113495bSYour Name qdf_spin_lock_bh(&peer_nan_obj->lock);
526*5113495bSYour Name qdf_mem_copy(&peer_nan_obj->home_chan_info, ndp_chan_info,
527*5113495bSYour Name sizeof(*ndp_chan_info));
528*5113495bSYour Name psoc_nan_obj->cb_obj.update_ndi_conn(wlan_vdev_get_id(vdev),
529*5113495bSYour Name &peer_nan_obj->home_chan_info);
530*5113495bSYour Name qdf_spin_unlock_bh(&peer_nan_obj->lock);
531*5113495bSYour Name wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
532*5113495bSYour Name
533*5113495bSYour Name if (qdf_is_macaddr_equal(&vdev_nan_obj->primary_peer_mac,
534*5113495bSYour Name peer_ndi_mac)) {
535*5113495bSYour Name /* TODO: Update policy mgr with connection info */
536*5113495bSYour Name }
537*5113495bSYour Name return QDF_STATUS_SUCCESS;
538*5113495bSYour Name }
539*5113495bSYour Name
540*5113495bSYour Name static QDF_STATUS
ndi_update_policy_mgr_conn_table(struct nan_datapath_confirm_event * confirm,struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)541*5113495bSYour Name ndi_update_policy_mgr_conn_table(struct nan_datapath_confirm_event *confirm,
542*5113495bSYour Name struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
543*5113495bSYour Name {
544*5113495bSYour Name QDF_STATUS status = QDF_STATUS_SUCCESS;
545*5113495bSYour Name
546*5113495bSYour Name if (policy_mgr_is_hw_dbs_capable(psoc)) {
547*5113495bSYour Name status = policy_mgr_update_and_wait_for_connection_update(psoc,
548*5113495bSYour Name vdev_id, confirm->ch[0].freq,
549*5113495bSYour Name POLICY_MGR_UPDATE_REASON_NDP_UPDATE);
550*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
551*5113495bSYour Name nan_err("Failed to set or wait for HW mode change");
552*5113495bSYour Name return status;
553*5113495bSYour Name }
554*5113495bSYour Name }
555*5113495bSYour Name
556*5113495bSYour Name policy_mgr_incr_active_session(psoc, QDF_NDI_MODE, vdev_id);
557*5113495bSYour Name
558*5113495bSYour Name return status;
559*5113495bSYour Name }
560*5113495bSYour Name
nan_handle_confirm(struct nan_datapath_confirm_event * confirm)561*5113495bSYour Name static QDF_STATUS nan_handle_confirm(struct nan_datapath_confirm_event *confirm)
562*5113495bSYour Name {
563*5113495bSYour Name uint8_t vdev_id;
564*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
565*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
566*5113495bSYour Name struct nan_vdev_priv_obj *vdev_nan_obj;
567*5113495bSYour Name struct wlan_objmgr_peer *peer;
568*5113495bSYour Name void (*nan_conc_callback)(void);
569*5113495bSYour Name
570*5113495bSYour Name vdev_id = wlan_vdev_get_id(confirm->vdev);
571*5113495bSYour Name psoc = wlan_vdev_get_psoc(confirm->vdev);
572*5113495bSYour Name if (!psoc) {
573*5113495bSYour Name nan_err("psoc is null");
574*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
575*5113495bSYour Name }
576*5113495bSYour Name
577*5113495bSYour Name peer = wlan_objmgr_get_peer_by_mac(psoc,
578*5113495bSYour Name confirm->peer_ndi_mac_addr.bytes,
579*5113495bSYour Name WLAN_NAN_ID);
580*5113495bSYour Name if (!peer && confirm->rsp_code == NAN_DATAPATH_RESPONSE_ACCEPT) {
581*5113495bSYour Name nan_debug("Drop NDP confirm as peer isn't available");
582*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
583*5113495bSYour Name }
584*5113495bSYour Name
585*5113495bSYour Name if (peer)
586*5113495bSYour Name wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
587*5113495bSYour Name
588*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
589*5113495bSYour Name if (!psoc_nan_obj) {
590*5113495bSYour Name nan_err("psoc_nan_obj is null");
591*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
592*5113495bSYour Name }
593*5113495bSYour Name
594*5113495bSYour Name vdev_nan_obj = nan_get_vdev_priv_obj(confirm->vdev);
595*5113495bSYour Name if (!vdev_nan_obj) {
596*5113495bSYour Name nan_err("vdev_nan_obj is null");
597*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
598*5113495bSYour Name }
599*5113495bSYour Name
600*5113495bSYour Name if (confirm->rsp_code != NAN_DATAPATH_RESPONSE_ACCEPT &&
601*5113495bSYour Name confirm->num_active_ndps_on_peer == 0) {
602*5113495bSYour Name /*
603*5113495bSYour Name * This peer was created at ndp_indication but
604*5113495bSYour Name * confirm failed, so it needs to be deleted
605*5113495bSYour Name */
606*5113495bSYour Name nan_err("NDP confirm with reject and no active ndp sessions. deleting peer: "QDF_MAC_ADDR_FMT" on vdev_id: %d",
607*5113495bSYour Name QDF_MAC_ADDR_REF(confirm->peer_ndi_mac_addr.bytes),
608*5113495bSYour Name vdev_id);
609*5113495bSYour Name psoc_nan_obj->cb_obj.delete_peers_by_addr(vdev_id,
610*5113495bSYour Name confirm->peer_ndi_mac_addr);
611*5113495bSYour Name }
612*5113495bSYour Name
613*5113495bSYour Name /* Increment NDP sessions for the Peer */
614*5113495bSYour Name if (confirm->rsp_code == NAN_DATAPATH_RESPONSE_ACCEPT)
615*5113495bSYour Name nan_increment_ndp_sessions(psoc, &confirm->peer_ndi_mac_addr,
616*5113495bSYour Name &confirm->ch[0]);
617*5113495bSYour Name
618*5113495bSYour Name psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, confirm->vdev,
619*5113495bSYour Name NDP_CONFIRM, confirm);
620*5113495bSYour Name
621*5113495bSYour Name if (confirm->rsp_code == NAN_DATAPATH_RESPONSE_ACCEPT &&
622*5113495bSYour Name !vdev_nan_obj->ndp_init_done) {
623*5113495bSYour Name /*
624*5113495bSYour Name * If this is the NDI's first NDP, store the NDP instance in
625*5113495bSYour Name * vdev object as its primary connection. If this instance ends
626*5113495bSYour Name * the second NDP should take its place.
627*5113495bSYour Name */
628*5113495bSYour Name qdf_mem_copy(vdev_nan_obj->primary_peer_mac.bytes,
629*5113495bSYour Name &confirm->peer_ndi_mac_addr, QDF_MAC_ADDR_SIZE);
630*5113495bSYour Name
631*5113495bSYour Name psoc_nan_obj->cb_obj.update_ndi_conn(vdev_id, &confirm->ch[0]);
632*5113495bSYour Name
633*5113495bSYour Name if (NAN_CONCURRENCY_SUPPORTED(psoc)) {
634*5113495bSYour Name ndi_update_policy_mgr_conn_table(confirm, psoc,
635*5113495bSYour Name vdev_id);
636*5113495bSYour Name vdev_nan_obj->ndp_init_done = true;
637*5113495bSYour Name
638*5113495bSYour Name nan_conc_callback = psoc_nan_obj->cb_obj.nan_concurrency_update;
639*5113495bSYour Name if (nan_conc_callback)
640*5113495bSYour Name nan_conc_callback();
641*5113495bSYour Name }
642*5113495bSYour Name }
643*5113495bSYour Name
644*5113495bSYour Name return QDF_STATUS_SUCCESS;
645*5113495bSYour Name }
646*5113495bSYour Name
nan_handle_initiator_rsp(struct nan_datapath_initiator_rsp * rsp,struct wlan_objmgr_vdev ** vdev)647*5113495bSYour Name static QDF_STATUS nan_handle_initiator_rsp(
648*5113495bSYour Name struct nan_datapath_initiator_rsp *rsp,
649*5113495bSYour Name struct wlan_objmgr_vdev **vdev)
650*5113495bSYour Name {
651*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
652*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
653*5113495bSYour Name
654*5113495bSYour Name *vdev = rsp->vdev;
655*5113495bSYour Name psoc = wlan_vdev_get_psoc(rsp->vdev);
656*5113495bSYour Name if (!psoc) {
657*5113495bSYour Name nan_err("psoc is null");
658*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
659*5113495bSYour Name }
660*5113495bSYour Name
661*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
662*5113495bSYour Name if (!psoc_nan_obj) {
663*5113495bSYour Name nan_err("psoc_nan_obj is null");
664*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
665*5113495bSYour Name }
666*5113495bSYour Name
667*5113495bSYour Name psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, rsp->vdev,
668*5113495bSYour Name NDP_INITIATOR_RSP, rsp);
669*5113495bSYour Name
670*5113495bSYour Name return QDF_STATUS_SUCCESS;
671*5113495bSYour Name }
672*5113495bSYour Name
nan_handle_ndp_ind(struct nan_datapath_indication_event * ndp_ind)673*5113495bSYour Name static QDF_STATUS nan_handle_ndp_ind(
674*5113495bSYour Name struct nan_datapath_indication_event *ndp_ind)
675*5113495bSYour Name {
676*5113495bSYour Name uint8_t vdev_id;
677*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
678*5113495bSYour Name QDF_STATUS status = QDF_STATUS_SUCCESS;
679*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
680*5113495bSYour Name
681*5113495bSYour Name vdev_id = wlan_vdev_get_id(ndp_ind->vdev);
682*5113495bSYour Name psoc = wlan_vdev_get_psoc(ndp_ind->vdev);
683*5113495bSYour Name if (!psoc) {
684*5113495bSYour Name nan_err("psoc is null");
685*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
686*5113495bSYour Name }
687*5113495bSYour Name
688*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
689*5113495bSYour Name if (!psoc_nan_obj) {
690*5113495bSYour Name nan_err("psoc_nan_obj is null");
691*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
692*5113495bSYour Name }
693*5113495bSYour Name
694*5113495bSYour Name nan_debug("role: %d, vdev: %d, csid: %d, peer_mac_addr "
695*5113495bSYour Name QDF_MAC_ADDR_FMT,
696*5113495bSYour Name ndp_ind->role, vdev_id, ndp_ind->ncs_sk_type,
697*5113495bSYour Name QDF_MAC_ADDR_REF(ndp_ind->peer_mac_addr.bytes));
698*5113495bSYour Name
699*5113495bSYour Name if ((ndp_ind->role == NAN_DATAPATH_ROLE_INITIATOR) ||
700*5113495bSYour Name ((NAN_DATAPATH_ROLE_RESPONDER == ndp_ind->role) &&
701*5113495bSYour Name (NAN_DATAPATH_ACCEPT_POLICY_ALL == ndp_ind->policy))) {
702*5113495bSYour Name status = psoc_nan_obj->cb_obj.add_ndi_peer(vdev_id,
703*5113495bSYour Name ndp_ind->peer_mac_addr);
704*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
705*5113495bSYour Name nan_err("Couldn't add ndi peer, ndp_role: %d",
706*5113495bSYour Name ndp_ind->role);
707*5113495bSYour Name return status;
708*5113495bSYour Name }
709*5113495bSYour Name }
710*5113495bSYour Name psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc,
711*5113495bSYour Name ndp_ind->vdev,
712*5113495bSYour Name NDP_INDICATION,
713*5113495bSYour Name ndp_ind);
714*5113495bSYour Name
715*5113495bSYour Name return status;
716*5113495bSYour Name }
717*5113495bSYour Name
nan_handle_responder_rsp(struct nan_datapath_responder_rsp * rsp,struct wlan_objmgr_vdev ** vdev)718*5113495bSYour Name static QDF_STATUS nan_handle_responder_rsp(
719*5113495bSYour Name struct nan_datapath_responder_rsp *rsp,
720*5113495bSYour Name struct wlan_objmgr_vdev **vdev)
721*5113495bSYour Name {
722*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
723*5113495bSYour Name QDF_STATUS status = QDF_STATUS_SUCCESS;
724*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
725*5113495bSYour Name
726*5113495bSYour Name *vdev = rsp->vdev;
727*5113495bSYour Name psoc = wlan_vdev_get_psoc(rsp->vdev);
728*5113495bSYour Name if (!psoc) {
729*5113495bSYour Name nan_err("psoc is null");
730*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
731*5113495bSYour Name }
732*5113495bSYour Name
733*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
734*5113495bSYour Name if (!psoc_nan_obj) {
735*5113495bSYour Name nan_err("psoc_nan_obj is null");
736*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
737*5113495bSYour Name }
738*5113495bSYour Name
739*5113495bSYour Name if (QDF_IS_STATUS_SUCCESS(rsp->status) && rsp->create_peer) {
740*5113495bSYour Name status = psoc_nan_obj->cb_obj.add_ndi_peer(
741*5113495bSYour Name wlan_vdev_get_id(rsp->vdev),
742*5113495bSYour Name rsp->peer_mac_addr);
743*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
744*5113495bSYour Name nan_err("Couldn't add ndi peer");
745*5113495bSYour Name rsp->status = QDF_STATUS_E_FAILURE;
746*5113495bSYour Name }
747*5113495bSYour Name }
748*5113495bSYour Name psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, rsp->vdev,
749*5113495bSYour Name NDP_RESPONDER_RSP, rsp);
750*5113495bSYour Name
751*5113495bSYour Name return QDF_STATUS_SUCCESS;
752*5113495bSYour Name }
753*5113495bSYour Name
nan_handle_ndp_end_rsp(struct nan_datapath_end_rsp_event * rsp,struct wlan_objmgr_vdev ** vdev)754*5113495bSYour Name static QDF_STATUS nan_handle_ndp_end_rsp(
755*5113495bSYour Name struct nan_datapath_end_rsp_event *rsp,
756*5113495bSYour Name struct wlan_objmgr_vdev **vdev)
757*5113495bSYour Name {
758*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
759*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
760*5113495bSYour Name struct osif_request *request;
761*5113495bSYour Name
762*5113495bSYour Name *vdev = rsp->vdev;
763*5113495bSYour Name psoc = wlan_vdev_get_psoc(rsp->vdev);
764*5113495bSYour Name if (!psoc) {
765*5113495bSYour Name nan_err("psoc is NULL");
766*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
767*5113495bSYour Name }
768*5113495bSYour Name
769*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
770*5113495bSYour Name if (!psoc_nan_obj) {
771*5113495bSYour Name nan_err("psoc_nan_obj is NULL");
772*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
773*5113495bSYour Name }
774*5113495bSYour Name
775*5113495bSYour Name /* Unblock the wait here if NDP_END request is a failure */
776*5113495bSYour Name if (rsp->status != 0) {
777*5113495bSYour Name request = osif_request_get(psoc_nan_obj->ndp_request_ctx);
778*5113495bSYour Name if (request) {
779*5113495bSYour Name osif_request_complete(request);
780*5113495bSYour Name osif_request_put(request);
781*5113495bSYour Name }
782*5113495bSYour Name }
783*5113495bSYour Name psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, rsp->vdev,
784*5113495bSYour Name NDP_END_RSP, rsp);
785*5113495bSYour Name
786*5113495bSYour Name return QDF_STATUS_SUCCESS;
787*5113495bSYour Name }
788*5113495bSYour Name
nan_handle_end_ind(struct nan_datapath_end_indication_event * ind)789*5113495bSYour Name static QDF_STATUS nan_handle_end_ind(
790*5113495bSYour Name struct nan_datapath_end_indication_event *ind)
791*5113495bSYour Name {
792*5113495bSYour Name uint32_t i;
793*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
794*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
795*5113495bSYour Name struct wlan_objmgr_vdev *vdev_itr;
796*5113495bSYour Name struct nan_vdev_priv_obj *vdev_nan_obj;
797*5113495bSYour Name struct osif_request *request;
798*5113495bSYour Name
799*5113495bSYour Name psoc = wlan_vdev_get_psoc(ind->vdev);
800*5113495bSYour Name if (!psoc) {
801*5113495bSYour Name nan_err("psoc is NULL");
802*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
803*5113495bSYour Name }
804*5113495bSYour Name
805*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
806*5113495bSYour Name if (!psoc_nan_obj) {
807*5113495bSYour Name nan_err("psoc_nan_obj is NULL");
808*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
809*5113495bSYour Name }
810*5113495bSYour Name
811*5113495bSYour Name /* Decrement NDP sessions for all Peers in the event */
812*5113495bSYour Name for (i = 0; i < ind->num_ndp_ids; i++)
813*5113495bSYour Name nan_decrement_ndp_sessions(psoc,
814*5113495bSYour Name &ind->ndp_map[i].peer_ndi_mac_addr);
815*5113495bSYour Name
816*5113495bSYour Name for (i = 0; i < ind->num_ndp_ids; i++) {
817*5113495bSYour Name vdev_itr = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
818*5113495bSYour Name ind->ndp_map[i].vdev_id,
819*5113495bSYour Name WLAN_NAN_ID);
820*5113495bSYour Name if (!vdev_itr) {
821*5113495bSYour Name nan_err("NAN vdev object is NULL");
822*5113495bSYour Name continue;
823*5113495bSYour Name }
824*5113495bSYour Name
825*5113495bSYour Name vdev_nan_obj = nan_get_vdev_priv_obj(vdev_itr);
826*5113495bSYour Name if (!vdev_nan_obj) {
827*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev_itr, WLAN_NAN_ID);
828*5113495bSYour Name nan_err("NAN vdev private object is NULL");
829*5113495bSYour Name continue;
830*5113495bSYour Name }
831*5113495bSYour Name
832*5113495bSYour Name if (qdf_is_macaddr_equal(&vdev_nan_obj->primary_peer_mac,
833*5113495bSYour Name &ind->ndp_map[i].peer_ndi_mac_addr))
834*5113495bSYour Name ndi_remove_and_update_primary_connection(psoc,
835*5113495bSYour Name vdev_itr);
836*5113495bSYour Name
837*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev_itr, WLAN_NAN_ID);
838*5113495bSYour Name }
839*5113495bSYour Name
840*5113495bSYour Name psoc_nan_obj->cb_obj.ndp_delete_peers(ind->ndp_map, ind->num_ndp_ids);
841*5113495bSYour Name psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, ind->vdev,
842*5113495bSYour Name NDP_END_IND, ind);
843*5113495bSYour Name
844*5113495bSYour Name /* Unblock the NDP_END wait */
845*5113495bSYour Name request = osif_request_get(psoc_nan_obj->ndp_request_ctx);
846*5113495bSYour Name if (request) {
847*5113495bSYour Name osif_request_complete(request);
848*5113495bSYour Name osif_request_put(request);
849*5113495bSYour Name }
850*5113495bSYour Name
851*5113495bSYour Name return QDF_STATUS_SUCCESS;
852*5113495bSYour Name }
853*5113495bSYour Name
nan_handle_enable_rsp(struct nan_event_params * nan_event)854*5113495bSYour Name static QDF_STATUS nan_handle_enable_rsp(struct nan_event_params *nan_event)
855*5113495bSYour Name {
856*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
857*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
858*5113495bSYour Name QDF_STATUS status;
859*5113495bSYour Name void (*call_back)(void *cookie);
860*5113495bSYour Name uint8_t vdev_id;
861*5113495bSYour Name void (*nan_conc_callback)(void);
862*5113495bSYour Name
863*5113495bSYour Name psoc = nan_event->psoc;
864*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
865*5113495bSYour Name if (!psoc_nan_obj) {
866*5113495bSYour Name nan_err("psoc_nan_obj is NULL");
867*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
868*5113495bSYour Name }
869*5113495bSYour Name
870*5113495bSYour Name if (nan_event->is_nan_enable_success) {
871*5113495bSYour Name status = nan_set_discovery_state(psoc, NAN_DISC_ENABLED);
872*5113495bSYour Name
873*5113495bSYour Name if (QDF_IS_STATUS_SUCCESS(status)) {
874*5113495bSYour Name psoc_nan_obj->nan_disc_mac_id = nan_event->mac_id;
875*5113495bSYour Name vdev_id = nan_event->vdev_id;
876*5113495bSYour Name if (!ucfg_nan_is_vdev_creation_allowed(psoc)) {
877*5113495bSYour Name vdev_id = NAN_PSEUDO_VDEV_ID;
878*5113495bSYour Name } else if (vdev_id >= WLAN_MAX_VDEVS) {
879*5113495bSYour Name nan_err("Invalid NAN vdev_id: %u", vdev_id);
880*5113495bSYour Name goto fail;
881*5113495bSYour Name }
882*5113495bSYour Name nan_debug("NAN vdev_id: %u", vdev_id);
883*5113495bSYour Name policy_mgr_incr_active_session(psoc, QDF_NAN_DISC_MODE,
884*5113495bSYour Name vdev_id);
885*5113495bSYour Name policy_mgr_process_force_scc_for_nan(psoc);
886*5113495bSYour Name
887*5113495bSYour Name } else {
888*5113495bSYour Name /*
889*5113495bSYour Name * State set to DISABLED OR DISABLE_IN_PROGRESS, try to
890*5113495bSYour Name * restore the single MAC mode.
891*5113495bSYour Name */
892*5113495bSYour Name psoc_nan_obj->nan_social_ch_2g_freq = 0;
893*5113495bSYour Name psoc_nan_obj->nan_social_ch_5g_freq = 0;
894*5113495bSYour Name policy_mgr_check_n_start_opportunistic_timer(psoc);
895*5113495bSYour Name }
896*5113495bSYour Name goto done;
897*5113495bSYour Name } else {
898*5113495bSYour Name nan_info("NAN enable has failed");
899*5113495bSYour Name /* NAN Enable has failed, restore changes */
900*5113495bSYour Name goto fail;
901*5113495bSYour Name }
902*5113495bSYour Name
903*5113495bSYour Name fail:
904*5113495bSYour Name psoc_nan_obj->nan_social_ch_2g_freq = 0;
905*5113495bSYour Name psoc_nan_obj->nan_social_ch_5g_freq = 0;
906*5113495bSYour Name nan_set_discovery_state(psoc, NAN_DISC_DISABLED);
907*5113495bSYour Name if (ucfg_is_nan_dbs_supported(psoc))
908*5113495bSYour Name policy_mgr_check_n_start_opportunistic_timer(psoc);
909*5113495bSYour Name
910*5113495bSYour Name /*
911*5113495bSYour Name * If FW respond with NAN enable failure, then TDLS should be enable
912*5113495bSYour Name * again if there is TDLS connection exist earlier.
913*5113495bSYour Name * decrement the active TDLS session.
914*5113495bSYour Name */
915*5113495bSYour Name ucfg_tdls_notify_connect_failure(psoc);
916*5113495bSYour Name
917*5113495bSYour Name done:
918*5113495bSYour Name nan_cstats_log_nan_enable_resp_evt(nan_event);
919*5113495bSYour Name
920*5113495bSYour Name nan_conc_callback = psoc_nan_obj->cb_obj.nan_concurrency_update;
921*5113495bSYour Name if (nan_conc_callback)
922*5113495bSYour Name nan_conc_callback();
923*5113495bSYour Name call_back = psoc_nan_obj->cb_obj.ucfg_nan_request_process_cb;
924*5113495bSYour Name if (call_back)
925*5113495bSYour Name call_back(psoc_nan_obj->nan_disc_request_ctx);
926*5113495bSYour Name
927*5113495bSYour Name return QDF_STATUS_SUCCESS;
928*5113495bSYour Name }
929*5113495bSYour Name
nan_disable_cleanup(struct wlan_objmgr_psoc * psoc)930*5113495bSYour Name QDF_STATUS nan_disable_cleanup(struct wlan_objmgr_psoc *psoc)
931*5113495bSYour Name {
932*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
933*5113495bSYour Name QDF_STATUS status;
934*5113495bSYour Name uint8_t vdev_id;
935*5113495bSYour Name void (*nan_conc_callback)(void);
936*5113495bSYour Name
937*5113495bSYour Name if (!psoc) {
938*5113495bSYour Name nan_err("psoc is NULL");
939*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
940*5113495bSYour Name }
941*5113495bSYour Name
942*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
943*5113495bSYour Name if (!psoc_nan_obj) {
944*5113495bSYour Name nan_err("psoc_nan_obj is NULL");
945*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
946*5113495bSYour Name }
947*5113495bSYour Name
948*5113495bSYour Name status = nan_set_discovery_state(psoc, NAN_DISC_DISABLED);
949*5113495bSYour Name if (QDF_IS_STATUS_SUCCESS(status)) {
950*5113495bSYour Name void (*call_back)(void *cookie);
951*5113495bSYour Name
952*5113495bSYour Name call_back = psoc_nan_obj->cb_obj.ucfg_nan_request_process_cb;
953*5113495bSYour Name vdev_id = policy_mgr_mode_specific_vdev_id(psoc,
954*5113495bSYour Name PM_NAN_DISC_MODE);
955*5113495bSYour Name nan_debug("NAN vdev_id: %u", vdev_id);
956*5113495bSYour Name policy_mgr_decr_session_set_pcl(psoc, QDF_NAN_DISC_MODE,
957*5113495bSYour Name vdev_id);
958*5113495bSYour Name if (psoc_nan_obj->is_explicit_disable && call_back)
959*5113495bSYour Name call_back(psoc_nan_obj->nan_disc_request_ctx);
960*5113495bSYour Name
961*5113495bSYour Name nan_handle_emlsr_concurrency(psoc, false);
962*5113495bSYour Name policy_mgr_nan_sap_post_disable_conc_check(psoc);
963*5113495bSYour Name nan_cstats_log_nan_disable_resp_evt(vdev_id, psoc);
964*5113495bSYour Name } else {
965*5113495bSYour Name /* Should not happen, NAN state can always be disabled */
966*5113495bSYour Name nan_err("Cannot set NAN state to disabled!");
967*5113495bSYour Name return QDF_STATUS_E_FAILURE;
968*5113495bSYour Name }
969*5113495bSYour Name nan_conc_callback = psoc_nan_obj->cb_obj.nan_concurrency_update;
970*5113495bSYour Name if (nan_conc_callback)
971*5113495bSYour Name nan_conc_callback();
972*5113495bSYour Name
973*5113495bSYour Name return status;
974*5113495bSYour Name }
975*5113495bSYour Name
nan_handle_disable_ind(struct nan_event_params * nan_event)976*5113495bSYour Name static QDF_STATUS nan_handle_disable_ind(struct nan_event_params *nan_event)
977*5113495bSYour Name {
978*5113495bSYour Name return nan_disable_cleanup(nan_event->psoc);
979*5113495bSYour Name }
980*5113495bSYour Name
nan_handle_schedule_update(struct nan_datapath_sch_update_event * ind)981*5113495bSYour Name static QDF_STATUS nan_handle_schedule_update(
982*5113495bSYour Name struct nan_datapath_sch_update_event *ind)
983*5113495bSYour Name {
984*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
985*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
986*5113495bSYour Name
987*5113495bSYour Name psoc = wlan_vdev_get_psoc(ind->vdev);
988*5113495bSYour Name if (!psoc) {
989*5113495bSYour Name nan_err("psoc is NULL");
990*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
991*5113495bSYour Name }
992*5113495bSYour Name
993*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
994*5113495bSYour Name if (!psoc_nan_obj) {
995*5113495bSYour Name nan_err("psoc_nan_obj is NULL");
996*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
997*5113495bSYour Name }
998*5113495bSYour Name
999*5113495bSYour Name ndi_update_ndp_session(ind->vdev, &ind->peer_addr, &ind->ch[0]);
1000*5113495bSYour Name psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, ind->vdev,
1001*5113495bSYour Name NDP_SCHEDULE_UPDATE, ind);
1002*5113495bSYour Name
1003*5113495bSYour Name return QDF_STATUS_SUCCESS;
1004*5113495bSYour Name }
1005*5113495bSYour Name
1006*5113495bSYour Name /**
1007*5113495bSYour Name * nan_handle_host_update() - extract the vdev from host event
1008*5113495bSYour Name * @evt: Event data received from firmware
1009*5113495bSYour Name * @vdev: pointer to vdev
1010*5113495bSYour Name *
1011*5113495bSYour Name * Return: none
1012*5113495bSYour Name */
nan_handle_host_update(struct nan_datapath_host_event * evt,struct wlan_objmgr_vdev ** vdev)1013*5113495bSYour Name static void nan_handle_host_update(struct nan_datapath_host_event *evt,
1014*5113495bSYour Name struct wlan_objmgr_vdev **vdev)
1015*5113495bSYour Name {
1016*5113495bSYour Name *vdev = evt->vdev;
1017*5113495bSYour Name }
1018*5113495bSYour Name
nan_discovery_event_handler(struct scheduler_msg * msg)1019*5113495bSYour Name QDF_STATUS nan_discovery_event_handler(struct scheduler_msg *msg)
1020*5113495bSYour Name {
1021*5113495bSYour Name struct nan_event_params *nan_event;
1022*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1023*5113495bSYour Name
1024*5113495bSYour Name if (!msg || !msg->bodyptr) {
1025*5113495bSYour Name nan_err("msg body is null");
1026*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1027*5113495bSYour Name }
1028*5113495bSYour Name
1029*5113495bSYour Name nan_event = msg->bodyptr;
1030*5113495bSYour Name if (!nan_event->psoc) {
1031*5113495bSYour Name nan_err("psoc is NULL");
1032*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1033*5113495bSYour Name }
1034*5113495bSYour Name
1035*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(nan_event->psoc);
1036*5113495bSYour Name if (!psoc_nan_obj) {
1037*5113495bSYour Name nan_err("psoc_nan_obj is null");
1038*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1039*5113495bSYour Name }
1040*5113495bSYour Name
1041*5113495bSYour Name switch (msg->type) {
1042*5113495bSYour Name case nan_event_id_enable_rsp:
1043*5113495bSYour Name nan_handle_enable_rsp(nan_event);
1044*5113495bSYour Name break;
1045*5113495bSYour Name case nan_event_id_disable_ind:
1046*5113495bSYour Name nan_handle_disable_ind(nan_event);
1047*5113495bSYour Name break;
1048*5113495bSYour Name case nan_event_id_generic_rsp:
1049*5113495bSYour Name case nan_event_id_error_rsp:
1050*5113495bSYour Name break;
1051*5113495bSYour Name default:
1052*5113495bSYour Name nan_err("Unknown event ID type - %d", msg->type);
1053*5113495bSYour Name break;
1054*5113495bSYour Name }
1055*5113495bSYour Name
1056*5113495bSYour Name psoc_nan_obj->cb_obj.os_if_nan_event_handler(nan_event);
1057*5113495bSYour Name
1058*5113495bSYour Name return QDF_STATUS_SUCCESS;
1059*5113495bSYour Name }
1060*5113495bSYour Name
nan_datapath_event_handler(struct scheduler_msg * pe_msg)1061*5113495bSYour Name QDF_STATUS nan_datapath_event_handler(struct scheduler_msg *pe_msg)
1062*5113495bSYour Name {
1063*5113495bSYour Name QDF_STATUS status = QDF_STATUS_SUCCESS;
1064*5113495bSYour Name struct wlan_serialization_queued_cmd_info cmd;
1065*5113495bSYour Name
1066*5113495bSYour Name cmd.requestor = WLAN_UMAC_COMP_NAN;
1067*5113495bSYour Name cmd.cmd_id = 0;
1068*5113495bSYour Name cmd.req_type = WLAN_SER_CANCEL_NON_SCAN_CMD;
1069*5113495bSYour Name cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE;
1070*5113495bSYour Name
1071*5113495bSYour Name if (!pe_msg->bodyptr) {
1072*5113495bSYour Name nan_err("msg body is null");
1073*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1074*5113495bSYour Name }
1075*5113495bSYour Name
1076*5113495bSYour Name switch (pe_msg->type) {
1077*5113495bSYour Name case NDP_CONFIRM: {
1078*5113495bSYour Name nan_handle_confirm(pe_msg->bodyptr);
1079*5113495bSYour Name break;
1080*5113495bSYour Name }
1081*5113495bSYour Name case NDP_INITIATOR_RSP: {
1082*5113495bSYour Name nan_handle_initiator_rsp(pe_msg->bodyptr, &cmd.vdev);
1083*5113495bSYour Name cmd.cmd_type = WLAN_SER_CMD_NDP_INIT_REQ;
1084*5113495bSYour Name wlan_serialization_remove_cmd(&cmd);
1085*5113495bSYour Name break;
1086*5113495bSYour Name }
1087*5113495bSYour Name case NDP_INDICATION: {
1088*5113495bSYour Name nan_handle_ndp_ind(pe_msg->bodyptr);
1089*5113495bSYour Name break;
1090*5113495bSYour Name }
1091*5113495bSYour Name case NDP_RESPONDER_RSP:
1092*5113495bSYour Name nan_handle_responder_rsp(pe_msg->bodyptr, &cmd.vdev);
1093*5113495bSYour Name cmd.cmd_type = WLAN_SER_CMD_NDP_RESP_REQ;
1094*5113495bSYour Name wlan_serialization_remove_cmd(&cmd);
1095*5113495bSYour Name break;
1096*5113495bSYour Name case NDP_END_RSP:
1097*5113495bSYour Name nan_handle_ndp_end_rsp(pe_msg->bodyptr, &cmd.vdev);
1098*5113495bSYour Name cmd.cmd_type = WLAN_SER_CMD_NDP_DATA_END_INIT_REQ;
1099*5113495bSYour Name wlan_serialization_remove_cmd(&cmd);
1100*5113495bSYour Name break;
1101*5113495bSYour Name case NDP_END_IND:
1102*5113495bSYour Name nan_handle_end_ind(pe_msg->bodyptr);
1103*5113495bSYour Name break;
1104*5113495bSYour Name case NDP_SCHEDULE_UPDATE:
1105*5113495bSYour Name nan_handle_schedule_update(pe_msg->bodyptr);
1106*5113495bSYour Name break;
1107*5113495bSYour Name case NDP_HOST_UPDATE:
1108*5113495bSYour Name nan_handle_host_update(pe_msg->bodyptr, &cmd.vdev);
1109*5113495bSYour Name cmd.cmd_type = WLAN_SER_CMD_NDP_END_ALL_REQ;
1110*5113495bSYour Name wlan_serialization_remove_cmd(&cmd);
1111*5113495bSYour Name break;
1112*5113495bSYour Name default:
1113*5113495bSYour Name nan_alert("Unhandled NDP event: %d", pe_msg->type);
1114*5113495bSYour Name status = QDF_STATUS_E_NOSUPPORT;
1115*5113495bSYour Name break;
1116*5113495bSYour Name }
1117*5113495bSYour Name return status;
1118*5113495bSYour Name }
1119*5113495bSYour Name
nan_is_enable_allowed(struct wlan_objmgr_psoc * psoc,uint32_t nan_ch_freq,uint8_t vdev_id)1120*5113495bSYour Name bool nan_is_enable_allowed(struct wlan_objmgr_psoc *psoc, uint32_t nan_ch_freq,
1121*5113495bSYour Name uint8_t vdev_id)
1122*5113495bSYour Name {
1123*5113495bSYour Name if (!psoc) {
1124*5113495bSYour Name nan_err("psoc object object is NULL");
1125*5113495bSYour Name return false;
1126*5113495bSYour Name }
1127*5113495bSYour Name
1128*5113495bSYour Name return (NAN_DISC_DISABLED == nan_get_discovery_state(psoc) &&
1129*5113495bSYour Name policy_mgr_allow_concurrency(psoc, PM_NAN_DISC_MODE,
1130*5113495bSYour Name nan_ch_freq, HW_MODE_20_MHZ,
1131*5113495bSYour Name 0, vdev_id));
1132*5113495bSYour Name }
1133*5113495bSYour Name
nan_is_disc_active(struct wlan_objmgr_psoc * psoc)1134*5113495bSYour Name bool nan_is_disc_active(struct wlan_objmgr_psoc *psoc)
1135*5113495bSYour Name {
1136*5113495bSYour Name if (!psoc) {
1137*5113495bSYour Name nan_err("psoc object object is NULL");
1138*5113495bSYour Name return false;
1139*5113495bSYour Name }
1140*5113495bSYour Name
1141*5113495bSYour Name return (NAN_DISC_ENABLED == nan_get_discovery_state(psoc) ||
1142*5113495bSYour Name NAN_DISC_ENABLE_IN_PROGRESS == nan_get_discovery_state(psoc));
1143*5113495bSYour Name }
1144*5113495bSYour Name
nan_set_hw_mode(struct wlan_objmgr_psoc * psoc,uint32_t nan_ch_freq)1145*5113495bSYour Name static QDF_STATUS nan_set_hw_mode(struct wlan_objmgr_psoc *psoc,
1146*5113495bSYour Name uint32_t nan_ch_freq)
1147*5113495bSYour Name {
1148*5113495bSYour Name QDF_STATUS status = QDF_STATUS_E_INVAL;
1149*5113495bSYour Name struct wlan_objmgr_pdev *pdev = NULL;
1150*5113495bSYour Name struct wlan_objmgr_vdev *vdev = NULL;
1151*5113495bSYour Name uint8_t vdev_id;
1152*5113495bSYour Name
1153*5113495bSYour Name policy_mgr_stop_opportunistic_timer(psoc);
1154*5113495bSYour Name
1155*5113495bSYour Name if (policy_mgr_is_hw_mode_change_in_progress(psoc)) {
1156*5113495bSYour Name status = policy_mgr_wait_for_connection_update(psoc);
1157*5113495bSYour Name if (!QDF_IS_STATUS_SUCCESS(status)) {
1158*5113495bSYour Name nan_err("Failed to wait for connection update");
1159*5113495bSYour Name goto pre_enable_failure;
1160*5113495bSYour Name }
1161*5113495bSYour Name }
1162*5113495bSYour Name
1163*5113495bSYour Name pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_NAN_ID);
1164*5113495bSYour Name if (!pdev) {
1165*5113495bSYour Name nan_err("null pdev");
1166*5113495bSYour Name status = QDF_STATUS_E_INVAL;
1167*5113495bSYour Name goto pre_enable_failure;
1168*5113495bSYour Name }
1169*5113495bSYour Name
1170*5113495bSYour Name /* Piggyback on any available vdev for policy manager update */
1171*5113495bSYour Name vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_NAN_ID);
1172*5113495bSYour Name if (!vdev) {
1173*5113495bSYour Name nan_err("No vdev is up yet, unable to proceed!");
1174*5113495bSYour Name status = QDF_STATUS_E_INVAL;
1175*5113495bSYour Name goto pre_enable_failure;
1176*5113495bSYour Name }
1177*5113495bSYour Name vdev_id = wlan_vdev_get_id(vdev);
1178*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
1179*5113495bSYour Name
1180*5113495bSYour Name status = policy_mgr_update_and_wait_for_connection_update(psoc, vdev_id,
1181*5113495bSYour Name nan_ch_freq,
1182*5113495bSYour Name POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY);
1183*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
1184*5113495bSYour Name nan_err("Failed to set or wait for HW mode change");
1185*5113495bSYour Name goto pre_enable_failure;
1186*5113495bSYour Name }
1187*5113495bSYour Name
1188*5113495bSYour Name if (wlan_util_is_vdev_in_cac_wait(pdev, WLAN_NAN_ID)) {
1189*5113495bSYour Name nan_err_rl("cac is in progress");
1190*5113495bSYour Name status = QDF_STATUS_E_FAILURE;
1191*5113495bSYour Name goto pre_enable_failure;
1192*5113495bSYour Name }
1193*5113495bSYour Name
1194*5113495bSYour Name pre_enable_failure:
1195*5113495bSYour Name if (pdev)
1196*5113495bSYour Name wlan_objmgr_pdev_release_ref(pdev, WLAN_NAN_ID);
1197*5113495bSYour Name
1198*5113495bSYour Name return status;
1199*5113495bSYour Name }
1200*5113495bSYour Name
nan_handle_emlsr_concurrency(struct wlan_objmgr_psoc * psoc,bool nan_enable)1201*5113495bSYour Name void nan_handle_emlsr_concurrency(struct wlan_objmgr_psoc *psoc,
1202*5113495bSYour Name bool nan_enable)
1203*5113495bSYour Name {
1204*5113495bSYour Name if (nan_enable) {
1205*5113495bSYour Name /*
1206*5113495bSYour Name * Check if any set link is already progress,
1207*5113495bSYour Name * wait for it to complete
1208*5113495bSYour Name */
1209*5113495bSYour Name policy_mgr_wait_for_set_link_update(psoc);
1210*5113495bSYour Name
1211*5113495bSYour Name wlan_handle_emlsr_sta_concurrency(psoc, true, false);
1212*5113495bSYour Name
1213*5113495bSYour Name /* Wait till rsp is received if NAN enable causes a set link */
1214*5113495bSYour Name policy_mgr_wait_for_set_link_update(psoc);
1215*5113495bSYour Name } else {
1216*5113495bSYour Name wlan_handle_emlsr_sta_concurrency(psoc, false, true);
1217*5113495bSYour Name }
1218*5113495bSYour Name }
1219*5113495bSYour Name
nan_is_sta_sta_concurrency_present(struct wlan_objmgr_psoc * psoc)1220*5113495bSYour Name bool nan_is_sta_sta_concurrency_present(struct wlan_objmgr_psoc *psoc)
1221*5113495bSYour Name {
1222*5113495bSYour Name uint32_t sta_cnt;
1223*5113495bSYour Name
1224*5113495bSYour Name sta_cnt = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1225*5113495bSYour Name NULL);
1226*5113495bSYour Name /* Allow if STA is not in connected state */
1227*5113495bSYour Name if (!sta_cnt)
1228*5113495bSYour Name return false;
1229*5113495bSYour Name
1230*5113495bSYour Name /*
1231*5113495bSYour Name * sta > 2 : (STA + STA + STA) or (ML STA + STA) or (ML STA + ML STA),
1232*5113495bSYour Name * STA concurrency will be present.
1233*5113495bSYour Name *
1234*5113495bSYour Name * ML STA: Although both links would be treated as separate STAs
1235*5113495bSYour Name * (sta cnt = 2) from policy mgr perspective, but it is not considered
1236*5113495bSYour Name * as STA concurrency
1237*5113495bSYour Name */
1238*5113495bSYour Name if (sta_cnt > 2 ||
1239*5113495bSYour Name (sta_cnt == 2 && policy_mgr_is_non_ml_sta_present(psoc)))
1240*5113495bSYour Name return true;
1241*5113495bSYour Name
1242*5113495bSYour Name return false;
1243*5113495bSYour Name }
1244*5113495bSYour Name
nan_discovery_pre_enable(struct wlan_objmgr_pdev * pdev,uint32_t nan_ch_freq)1245*5113495bSYour Name QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_pdev *pdev,
1246*5113495bSYour Name uint32_t nan_ch_freq)
1247*5113495bSYour Name {
1248*5113495bSYour Name QDF_STATUS status = QDF_STATUS_E_INVAL;
1249*5113495bSYour Name struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
1250*5113495bSYour Name
1251*5113495bSYour Name if (!psoc) {
1252*5113495bSYour Name nan_err("psoc is null");
1253*5113495bSYour Name return QDF_STATUS_E_INVAL;
1254*5113495bSYour Name }
1255*5113495bSYour Name
1256*5113495bSYour Name status = nan_set_discovery_state(psoc, NAN_DISC_ENABLE_IN_PROGRESS);
1257*5113495bSYour Name
1258*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
1259*5113495bSYour Name nan_err("Unable to set NAN Disc State to ENABLE_IN_PROGRESS");
1260*5113495bSYour Name goto pre_enable_failure;
1261*5113495bSYour Name }
1262*5113495bSYour Name
1263*5113495bSYour Name if ((policy_mgr_get_sap_mode_count(psoc, NULL)) &&
1264*5113495bSYour Name !policy_mgr_nan_sap_pre_enable_conc_check(psoc, PM_NAN_DISC_MODE,
1265*5113495bSYour Name nan_ch_freq)) {
1266*5113495bSYour Name nan_debug("NAN not enabled due to concurrency constraints");
1267*5113495bSYour Name status = QDF_STATUS_E_INVAL;
1268*5113495bSYour Name goto pre_enable_failure;
1269*5113495bSYour Name }
1270*5113495bSYour Name
1271*5113495bSYour Name /*
1272*5113495bSYour Name * Reject STA+STA in below case
1273*5113495bSYour Name * Non-ML STA: STA+STA+NAN concurrency is not supported
1274*5113495bSYour Name */
1275*5113495bSYour Name if (nan_is_sta_sta_concurrency_present(psoc)) {
1276*5113495bSYour Name nan_err("STA+STA+NAN concurrency is not allowed");
1277*5113495bSYour Name status = QDF_STATUS_E_FAILURE;
1278*5113495bSYour Name goto pre_enable_failure;
1279*5113495bSYour Name }
1280*5113495bSYour Name
1281*5113495bSYour Name wlan_p2p_abort_scan(pdev);
1282*5113495bSYour Name
1283*5113495bSYour Name if (policy_mgr_is_hw_dbs_capable(psoc)) {
1284*5113495bSYour Name status = nan_set_hw_mode(psoc, nan_ch_freq);
1285*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
1286*5113495bSYour Name goto pre_enable_failure;
1287*5113495bSYour Name }
1288*5113495bSYour Name
1289*5113495bSYour Name nan_handle_emlsr_concurrency(psoc, true);
1290*5113495bSYour Name
1291*5113495bSYour Name /* Try to teardown TDLS links, but do not wait */
1292*5113495bSYour Name status = ucfg_tdls_teardown_links(psoc);
1293*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
1294*5113495bSYour Name nan_err("Failed to teardown TDLS links");
1295*5113495bSYour Name
1296*5113495bSYour Name pre_enable_failure:
1297*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
1298*5113495bSYour Name nan_set_discovery_state(psoc, NAN_DISC_DISABLED);
1299*5113495bSYour Name
1300*5113495bSYour Name return status;
1301*5113495bSYour Name }
1302*5113495bSYour Name
nan_discovery_disable_req(struct nan_disable_req * req)1303*5113495bSYour Name static QDF_STATUS nan_discovery_disable_req(struct nan_disable_req *req)
1304*5113495bSYour Name {
1305*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1306*5113495bSYour Name struct wlan_nan_tx_ops *tx_ops;
1307*5113495bSYour Name
1308*5113495bSYour Name /*
1309*5113495bSYour Name * State was already set to Disabled by failed Enable
1310*5113495bSYour Name * request OR by the Disable Indication event, drop the
1311*5113495bSYour Name * Disable request.
1312*5113495bSYour Name */
1313*5113495bSYour Name if (NAN_DISC_DISABLED == nan_get_discovery_state(req->psoc))
1314*5113495bSYour Name return QDF_STATUS_SUCCESS;
1315*5113495bSYour Name
1316*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(req->psoc);
1317*5113495bSYour Name if (!psoc_nan_obj) {
1318*5113495bSYour Name nan_err("psoc_nan_obj is null");
1319*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1320*5113495bSYour Name }
1321*5113495bSYour Name
1322*5113495bSYour Name tx_ops = &psoc_nan_obj->tx_ops;
1323*5113495bSYour Name if (!tx_ops->nan_discovery_req_tx) {
1324*5113495bSYour Name nan_err("NAN Discovery tx op is NULL");
1325*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1326*5113495bSYour Name }
1327*5113495bSYour Name
1328*5113495bSYour Name return tx_ops->nan_discovery_req_tx(req, NAN_DISABLE_REQ);
1329*5113495bSYour Name }
1330*5113495bSYour Name
nan_discovery_enable_req(struct nan_enable_req * req)1331*5113495bSYour Name static QDF_STATUS nan_discovery_enable_req(struct nan_enable_req *req)
1332*5113495bSYour Name {
1333*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1334*5113495bSYour Name struct wlan_nan_tx_ops *tx_ops;
1335*5113495bSYour Name
1336*5113495bSYour Name /*
1337*5113495bSYour Name * State was already set to Disable in progress by a disable request,
1338*5113495bSYour Name * drop the Enable request, start opportunistic timer and move back to
1339*5113495bSYour Name * the Disabled state.
1340*5113495bSYour Name */
1341*5113495bSYour Name if (NAN_DISC_DISABLE_IN_PROGRESS ==
1342*5113495bSYour Name nan_get_discovery_state(req->psoc)) {
1343*5113495bSYour Name policy_mgr_check_n_start_opportunistic_timer(req->psoc);
1344*5113495bSYour Name return nan_set_discovery_state(req->psoc, NAN_DISC_DISABLED);
1345*5113495bSYour Name }
1346*5113495bSYour Name
1347*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(req->psoc);
1348*5113495bSYour Name if (!psoc_nan_obj) {
1349*5113495bSYour Name nan_err("psoc_nan_obj is null");
1350*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1351*5113495bSYour Name }
1352*5113495bSYour Name
1353*5113495bSYour Name psoc_nan_obj->nan_social_ch_2g_freq = req->social_chan_2g_freq;
1354*5113495bSYour Name psoc_nan_obj->nan_social_ch_5g_freq = req->social_chan_5g_freq;
1355*5113495bSYour Name
1356*5113495bSYour Name tx_ops = &psoc_nan_obj->tx_ops;
1357*5113495bSYour Name if (!tx_ops->nan_discovery_req_tx) {
1358*5113495bSYour Name nan_err("NAN Discovery tx op is NULL");
1359*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1360*5113495bSYour Name }
1361*5113495bSYour Name
1362*5113495bSYour Name return tx_ops->nan_discovery_req_tx(req, NAN_ENABLE_REQ);
1363*5113495bSYour Name }
1364*5113495bSYour Name
nan_discovery_generic_req(struct nan_generic_req * req)1365*5113495bSYour Name static QDF_STATUS nan_discovery_generic_req(struct nan_generic_req *req)
1366*5113495bSYour Name {
1367*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1368*5113495bSYour Name struct wlan_nan_tx_ops *tx_ops;
1369*5113495bSYour Name
1370*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(req->psoc);
1371*5113495bSYour Name if (!psoc_nan_obj) {
1372*5113495bSYour Name nan_err("psoc_nan_obj is null");
1373*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1374*5113495bSYour Name }
1375*5113495bSYour Name
1376*5113495bSYour Name tx_ops = &psoc_nan_obj->tx_ops;
1377*5113495bSYour Name if (!tx_ops->nan_discovery_req_tx) {
1378*5113495bSYour Name nan_err("NAN Discovery tx op is NULL");
1379*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1380*5113495bSYour Name }
1381*5113495bSYour Name
1382*5113495bSYour Name return tx_ops->nan_discovery_req_tx(req, NAN_GENERIC_REQ);
1383*5113495bSYour Name }
1384*5113495bSYour Name
nan_discovery_flush_callback(struct scheduler_msg * msg)1385*5113495bSYour Name QDF_STATUS nan_discovery_flush_callback(struct scheduler_msg *msg)
1386*5113495bSYour Name {
1387*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
1388*5113495bSYour Name
1389*5113495bSYour Name if (!msg || !msg->bodyptr) {
1390*5113495bSYour Name nan_err("Null pointer for NAN Discovery message");
1391*5113495bSYour Name return QDF_STATUS_E_INVAL;
1392*5113495bSYour Name }
1393*5113495bSYour Name
1394*5113495bSYour Name switch (msg->type) {
1395*5113495bSYour Name case NAN_ENABLE_REQ:
1396*5113495bSYour Name psoc = ((struct nan_enable_req *)msg->bodyptr)->psoc;
1397*5113495bSYour Name break;
1398*5113495bSYour Name case NAN_DISABLE_REQ:
1399*5113495bSYour Name psoc = ((struct nan_disable_req *)msg->bodyptr)->psoc;
1400*5113495bSYour Name break;
1401*5113495bSYour Name case NAN_GENERIC_REQ:
1402*5113495bSYour Name psoc = ((struct nan_generic_req *)msg->bodyptr)->psoc;
1403*5113495bSYour Name break;
1404*5113495bSYour Name default:
1405*5113495bSYour Name nan_err("Unsupported request type: %d", msg->type);
1406*5113495bSYour Name qdf_mem_free(msg->bodyptr);
1407*5113495bSYour Name return QDF_STATUS_E_INVAL;
1408*5113495bSYour Name }
1409*5113495bSYour Name
1410*5113495bSYour Name wlan_objmgr_psoc_release_ref(psoc, WLAN_NAN_ID);
1411*5113495bSYour Name qdf_mem_free(msg->bodyptr);
1412*5113495bSYour Name
1413*5113495bSYour Name return QDF_STATUS_SUCCESS;
1414*5113495bSYour Name }
1415*5113495bSYour Name
nan_discovery_scheduled_handler(struct scheduler_msg * msg)1416*5113495bSYour Name QDF_STATUS nan_discovery_scheduled_handler(struct scheduler_msg *msg)
1417*5113495bSYour Name {
1418*5113495bSYour Name QDF_STATUS status = QDF_STATUS_SUCCESS;
1419*5113495bSYour Name
1420*5113495bSYour Name if (!msg || !msg->bodyptr) {
1421*5113495bSYour Name nan_alert("msg or bodyptr is null");
1422*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1423*5113495bSYour Name }
1424*5113495bSYour Name
1425*5113495bSYour Name switch (msg->type) {
1426*5113495bSYour Name case NAN_ENABLE_REQ:
1427*5113495bSYour Name status = nan_discovery_enable_req(msg->bodyptr);
1428*5113495bSYour Name break;
1429*5113495bSYour Name case NAN_DISABLE_REQ:
1430*5113495bSYour Name status = nan_discovery_disable_req(msg->bodyptr);
1431*5113495bSYour Name break;
1432*5113495bSYour Name case NAN_GENERIC_REQ:
1433*5113495bSYour Name status = nan_discovery_generic_req(msg->bodyptr);
1434*5113495bSYour Name break;
1435*5113495bSYour Name default:
1436*5113495bSYour Name nan_err("Unsupported request type: %d", msg->type);
1437*5113495bSYour Name qdf_mem_free(msg->bodyptr);
1438*5113495bSYour Name return QDF_STATUS_E_FAILURE;
1439*5113495bSYour Name }
1440*5113495bSYour Name
1441*5113495bSYour Name nan_discovery_flush_callback(msg);
1442*5113495bSYour Name return status;
1443*5113495bSYour Name }
1444*5113495bSYour Name
1445*5113495bSYour Name QDF_STATUS
wlan_nan_get_connection_info(struct wlan_objmgr_psoc * psoc,struct policy_mgr_vdev_entry_info * conn_info)1446*5113495bSYour Name wlan_nan_get_connection_info(struct wlan_objmgr_psoc *psoc,
1447*5113495bSYour Name struct policy_mgr_vdev_entry_info *conn_info)
1448*5113495bSYour Name {
1449*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1450*5113495bSYour Name
1451*5113495bSYour Name if (!psoc) {
1452*5113495bSYour Name nan_err("psoc obj is NULL");
1453*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1454*5113495bSYour Name }
1455*5113495bSYour Name
1456*5113495bSYour Name if (nan_get_discovery_state(psoc) != NAN_DISC_ENABLED) {
1457*5113495bSYour Name nan_err("NAN State needs to be Enabled");
1458*5113495bSYour Name return QDF_STATUS_E_INVAL;
1459*5113495bSYour Name }
1460*5113495bSYour Name
1461*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1462*5113495bSYour Name if (!psoc_nan_obj) {
1463*5113495bSYour Name nan_err("psoc_nan_obj is null");
1464*5113495bSYour Name return QDF_STATUS_E_NULL_VALUE;
1465*5113495bSYour Name }
1466*5113495bSYour Name
1467*5113495bSYour Name /* For policy_mgr use NAN mandatory Social ch 6 */
1468*5113495bSYour Name conn_info->mhz = psoc_nan_obj->nan_social_ch_2g_freq;
1469*5113495bSYour Name conn_info->mac_id = psoc_nan_obj->nan_disc_mac_id;
1470*5113495bSYour Name conn_info->chan_width = CH_WIDTH_20MHZ;
1471*5113495bSYour Name conn_info->type = WMI_VDEV_TYPE_NAN;
1472*5113495bSYour Name
1473*5113495bSYour Name return QDF_STATUS_SUCCESS;
1474*5113495bSYour Name }
1475*5113495bSYour Name
wlan_nan_get_disc_5g_ch_freq(struct wlan_objmgr_psoc * psoc)1476*5113495bSYour Name uint32_t wlan_nan_get_disc_5g_ch_freq(struct wlan_objmgr_psoc *psoc)
1477*5113495bSYour Name {
1478*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1479*5113495bSYour Name
1480*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1481*5113495bSYour Name if (!psoc_nan_obj) {
1482*5113495bSYour Name nan_err("psoc_nan_obj is null");
1483*5113495bSYour Name return 0;
1484*5113495bSYour Name }
1485*5113495bSYour Name
1486*5113495bSYour Name if (nan_get_discovery_state(psoc) != NAN_DISC_ENABLED)
1487*5113495bSYour Name return 0;
1488*5113495bSYour Name
1489*5113495bSYour Name return psoc_nan_obj->nan_social_ch_5g_freq;
1490*5113495bSYour Name }
1491*5113495bSYour Name
wlan_nan_get_sap_conc_support(struct wlan_objmgr_psoc * psoc)1492*5113495bSYour Name bool wlan_nan_get_sap_conc_support(struct wlan_objmgr_psoc *psoc)
1493*5113495bSYour Name {
1494*5113495bSYour Name struct nan_psoc_priv_obj *psoc_nan_obj;
1495*5113495bSYour Name
1496*5113495bSYour Name psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1497*5113495bSYour Name if (!psoc_nan_obj) {
1498*5113495bSYour Name nan_err("psoc_nan_obj is null");
1499*5113495bSYour Name return 0;
1500*5113495bSYour Name }
1501*5113495bSYour Name
1502*5113495bSYour Name return (psoc_nan_obj->nan_caps.nan_sap_supported &&
1503*5113495bSYour Name ucfg_is_nan_conc_control_supported(psoc));
1504*5113495bSYour Name }
1505*5113495bSYour Name
wlan_nan_is_beamforming_supported(struct wlan_objmgr_psoc * psoc)1506*5113495bSYour Name bool wlan_nan_is_beamforming_supported(struct wlan_objmgr_psoc *psoc)
1507*5113495bSYour Name {
1508*5113495bSYour Name return ucfg_nan_is_beamforming_supported(psoc);
1509*5113495bSYour Name }
1510*5113495bSYour Name
1511*5113495bSYour Name /*
1512*5113495bSYour Name * The NAN Cluster ID is a MAC address that takes a value from
1513*5113495bSYour Name * 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF and is carried in the A3 field of
1514*5113495bSYour Name * some of the NAN frames. The NAN Cluster ID is randomly chosen by the device
1515*5113495bSYour Name * that initiates the NAN Cluster.
1516*5113495bSYour Name */
1517*5113495bSYour Name #define NAN_CLUSTER_MATCH "\x50\x6F\x9A\x01"
1518*5113495bSYour Name #define NAN_CLUSTER_MATCH_SIZE 4
1519*5113495bSYour Name
1520*5113495bSYour Name /**
1521*5113495bSYour Name * wlan_nan_is_bssid_in_cluster() - to check whether BSSID is a part of NAN
1522*5113495bSYour Name * cluster
1523*5113495bSYour Name * @bssid: BSSID present in mgmt frame
1524*5113495bSYour Name *
1525*5113495bSYour Name * Return: true if BSSID is part of NAN cluster
1526*5113495bSYour Name */
1527*5113495bSYour Name static
wlan_nan_is_bssid_in_cluster(tSirMacAddr bssid)1528*5113495bSYour Name bool wlan_nan_is_bssid_in_cluster(tSirMacAddr bssid)
1529*5113495bSYour Name {
1530*5113495bSYour Name if (qdf_mem_cmp(bssid, NAN_CLUSTER_MATCH, NAN_CLUSTER_MATCH_SIZE) == 0)
1531*5113495bSYour Name return true;
1532*5113495bSYour Name
1533*5113495bSYour Name return false;
1534*5113495bSYour Name }
1535*5113495bSYour Name
1536*5113495bSYour Name /**
1537*5113495bSYour Name * wlan_nan_extract_vdev_id_from_vdev_list() -retrieve vdev from vdev list in
1538*5113495bSYour Name * pdev and check for nan vdev_id
1539*5113495bSYour Name * @pdev: PDEV object
1540*5113495bSYour Name * @dbg_id: Object Manager ref debug id
1541*5113495bSYour Name *
1542*5113495bSYour Name * API to get NAN vdev_id for only NAN BSSID.
1543*5113495bSYour Name *
1544*5113495bSYour Name * Return: NAN vdev_id
1545*5113495bSYour Name */
1546*5113495bSYour Name static
wlan_nan_extract_vdev_id_from_vdev_list(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid dbg_id)1547*5113495bSYour Name uint8_t wlan_nan_extract_vdev_id_from_vdev_list(struct wlan_objmgr_pdev *pdev,
1548*5113495bSYour Name wlan_objmgr_ref_dbgid dbg_id)
1549*5113495bSYour Name {
1550*5113495bSYour Name struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
1551*5113495bSYour Name qdf_list_t *vdev_list = NULL;
1552*5113495bSYour Name struct wlan_objmgr_vdev *vdev;
1553*5113495bSYour Name qdf_list_node_t *node = NULL;
1554*5113495bSYour Name qdf_list_node_t *prev_node = NULL;
1555*5113495bSYour Name uint8_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
1556*5113495bSYour Name
1557*5113495bSYour Name wlan_pdev_obj_lock(pdev);
1558*5113495bSYour Name
1559*5113495bSYour Name vdev_list = &objmgr->wlan_vdev_list;
1560*5113495bSYour Name if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS)
1561*5113495bSYour Name goto end;
1562*5113495bSYour Name
1563*5113495bSYour Name do {
1564*5113495bSYour Name vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
1565*5113495bSYour Name vdev_node);
1566*5113495bSYour Name if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
1567*5113495bSYour Name QDF_STATUS_SUCCESS) {
1568*5113495bSYour Name if (wlan_vdev_mlme_get_opmode(vdev) ==
1569*5113495bSYour Name QDF_NAN_DISC_MODE) {
1570*5113495bSYour Name vdev_id = wlan_vdev_get_id(vdev);
1571*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev, dbg_id);
1572*5113495bSYour Name goto end;
1573*5113495bSYour Name }
1574*5113495bSYour Name
1575*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev, dbg_id);
1576*5113495bSYour Name }
1577*5113495bSYour Name
1578*5113495bSYour Name prev_node = node;
1579*5113495bSYour Name } while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1580*5113495bSYour Name QDF_STATUS_SUCCESS);
1581*5113495bSYour Name end:
1582*5113495bSYour Name wlan_pdev_obj_unlock(pdev);
1583*5113495bSYour Name
1584*5113495bSYour Name return vdev_id;
1585*5113495bSYour Name }
1586*5113495bSYour Name
nan_get_vdev_id_from_bssid(struct wlan_objmgr_pdev * pdev,tSirMacAddr bssid,wlan_objmgr_ref_dbgid dbg_id)1587*5113495bSYour Name uint8_t nan_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
1588*5113495bSYour Name tSirMacAddr bssid,
1589*5113495bSYour Name wlan_objmgr_ref_dbgid dbg_id)
1590*5113495bSYour Name {
1591*5113495bSYour Name uint8_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
1592*5113495bSYour Name
1593*5113495bSYour Name if (wlan_nan_is_bssid_in_cluster(bssid))
1594*5113495bSYour Name vdev_id = wlan_nan_extract_vdev_id_from_vdev_list(pdev, dbg_id);
1595*5113495bSYour Name
1596*5113495bSYour Name return vdev_id;
1597*5113495bSYour Name }
1598