xref: /wlan-driver/qcacld-3.0/components/nan/core/src/nan_main.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
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