1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: This file contains p2p north bound interface definitions
22  */
23 
24 #include <wmi_unified_api.h>
25 #include <wlan_objmgr_psoc_obj.h>
26 #include <wlan_objmgr_vdev_obj.h>
27 #include <scheduler_api.h>
28 #include "wlan_p2p_public_struct.h"
29 #include "wlan_p2p_ucfg_api.h"
30 #include "wlan_p2p_api.h"
31 #include "../../core/src/wlan_p2p_main.h"
32 #include "../../core/src/wlan_p2p_roc.h"
33 #include "../../core/src/wlan_p2p_off_chan_tx.h"
34 #include "target_if.h"
35 
36 static inline struct wlan_lmac_if_p2p_tx_ops *
ucfg_p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc * psoc)37 ucfg_p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc *psoc)
38 {
39 	return &(psoc->soc_cb.tx_ops->p2p);
40 }
41 
42 /**
43  * is_p2p_ps_allowed() - If P2P power save is allowed or not
44  * @vdev: vdev object
45  * @id: umac component id
46  *
47  * This function returns TRUE if P2P power-save is allowed
48  * else returns FALSE.
49  *
50  * Return: bool
51  */
is_p2p_ps_allowed(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id)52 static bool is_p2p_ps_allowed(struct wlan_objmgr_vdev *vdev,
53 				enum wlan_umac_comp_id id)
54 {
55 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
56 	uint8_t is_p2pgo = 0;
57 
58 	if (!vdev) {
59 		p2p_err("vdev:%pK", vdev);
60 		return true;
61 	}
62 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
63 						WLAN_UMAC_COMP_P2P);
64 
65 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
66 		is_p2pgo = 1;
67 
68 	if (!p2p_vdev_obj || !is_p2pgo) {
69 		p2p_err("p2p_vdev_obj:%pK is_p2pgo:%u",
70 			p2p_vdev_obj, is_p2pgo);
71 		return false;
72 	}
73 	if (p2p_vdev_obj->non_p2p_peer_count &&
74 	    p2p_vdev_obj->noa_status == false) {
75 		p2p_debug("non_p2p_peer_count: %u, noa_status: %d",
76 			p2p_vdev_obj->non_p2p_peer_count,
77 			p2p_vdev_obj->noa_status);
78 		return false;
79 	}
80 
81 	return true;
82 }
83 
ucfg_p2p_init(void)84 QDF_STATUS ucfg_p2p_init(void)
85 {
86 	return p2p_component_init();
87 }
88 
ucfg_p2p_deinit(void)89 QDF_STATUS ucfg_p2p_deinit(void)
90 {
91 	return p2p_component_deinit();
92 }
93 
ucfg_p2p_psoc_open(struct wlan_objmgr_psoc * soc)94 QDF_STATUS ucfg_p2p_psoc_open(struct wlan_objmgr_psoc *soc)
95 {
96 	return p2p_psoc_object_open(soc);
97 }
98 
ucfg_p2p_psoc_close(struct wlan_objmgr_psoc * soc)99 QDF_STATUS ucfg_p2p_psoc_close(struct wlan_objmgr_psoc *soc)
100 {
101 	return p2p_psoc_object_close(soc);
102 }
103 
ucfg_p2p_psoc_start(struct wlan_objmgr_psoc * soc,struct p2p_start_param * req)104 QDF_STATUS ucfg_p2p_psoc_start(struct wlan_objmgr_psoc *soc,
105 	struct p2p_start_param *req)
106 {
107 	return p2p_psoc_start(soc, req);
108 }
109 
ucfg_p2p_psoc_stop(struct wlan_objmgr_psoc * soc)110 QDF_STATUS ucfg_p2p_psoc_stop(struct wlan_objmgr_psoc *soc)
111 {
112 	return p2p_psoc_stop(soc);
113 }
114 
ucfg_p2p_roc_req(struct wlan_objmgr_psoc * soc,struct p2p_roc_req * roc_req,uint64_t * cookie)115 QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc,
116 	struct p2p_roc_req *roc_req, uint64_t *cookie)
117 {
118 	struct scheduler_msg msg = {0};
119 	struct p2p_soc_priv_obj *p2p_soc_obj;
120 	struct p2p_roc_context *roc_ctx;
121 	QDF_STATUS status;
122 	int32_t id;
123 
124 	p2p_debug("soc:%pK, vdev_id:%d, chanfreq:%d, phy_mode:%d, duration:%d",
125 		  soc, roc_req->vdev_id, roc_req->chan_freq,
126 		  roc_req->phy_mode, roc_req->duration);
127 
128 	if (!soc) {
129 		p2p_err("psoc context passed is NULL");
130 		return QDF_STATUS_E_INVAL;
131 	}
132 
133 	p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
134 			WLAN_UMAC_COMP_P2P);
135 	if (!p2p_soc_obj) {
136 		p2p_err("P2P soc object is NULL");
137 		return QDF_STATUS_E_FAILURE;
138 	}
139 
140 	roc_ctx = qdf_mem_malloc(sizeof(*roc_ctx));
141 	if (!roc_ctx)
142 		return QDF_STATUS_E_NOMEM;
143 
144 	status = qdf_idr_alloc(&p2p_soc_obj->p2p_idr, roc_ctx, &id);
145 	if (QDF_IS_STATUS_ERROR(status)) {
146 		qdf_mem_free(roc_ctx);
147 		p2p_err("failed to alloc idr, status %d", status);
148 		return status;
149 	}
150 
151 	*cookie = (uint64_t)id;
152 	roc_ctx->p2p_soc_obj = p2p_soc_obj;
153 	roc_ctx->vdev_id = roc_req->vdev_id;
154 	roc_ctx->chan_freq = roc_req->chan_freq;
155 	roc_ctx->phy_mode = roc_req->phy_mode;
156 	roc_ctx->duration = roc_req->duration;
157 	roc_ctx->roc_state = ROC_STATE_IDLE;
158 	roc_ctx->roc_type = USER_REQUESTED;
159 	roc_ctx->id = id;
160 	msg.type = P2P_ROC_REQ;
161 	msg.bodyptr = roc_ctx;
162 	msg.callback = p2p_process_cmd;
163 	status = scheduler_post_message(QDF_MODULE_ID_HDD,
164 					QDF_MODULE_ID_P2P,
165 					QDF_MODULE_ID_OS_IF,
166 					&msg);
167 	if (QDF_IS_STATUS_ERROR(status)) {
168 		qdf_mem_free(roc_ctx);
169 		qdf_idr_remove(&p2p_soc_obj->p2p_idr, id);
170 		p2p_err("post msg fail:%d", status);
171 	}
172 	p2p_debug("cookie = 0x%llx", *cookie);
173 
174 	return status;
175 }
176 
ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc * soc,uint64_t cookie)177 QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc,
178 	uint64_t cookie)
179 {
180 	struct scheduler_msg msg = {0};
181 	struct p2p_soc_priv_obj *p2p_soc_obj;
182 	struct cancel_roc_context *cancel_roc;
183 	void *roc_ctx = NULL;
184 	QDF_STATUS status;
185 
186 	p2p_debug("soc:%pK, cookie:0x%llx", soc, cookie);
187 
188 	if (!soc) {
189 		p2p_err("psoc context passed is NULL");
190 		return QDF_STATUS_E_INVAL;
191 	}
192 
193 	p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
194 			WLAN_UMAC_COMP_P2P);
195 	if (!p2p_soc_obj) {
196 		p2p_err("p2p soc context is NULL");
197 		return QDF_STATUS_E_FAILURE;
198 	}
199 
200 	status = qdf_idr_find(&p2p_soc_obj->p2p_idr,
201 			      cookie, &roc_ctx);
202 	if (QDF_IS_STATUS_ERROR(status)) {
203 		p2p_debug("invalid id for cookie 0x%llx", cookie);
204 		return QDF_STATUS_E_INVAL;
205 	}
206 
207 	cancel_roc = qdf_mem_malloc(sizeof(*cancel_roc));
208 	if (!cancel_roc)
209 		return QDF_STATUS_E_NOMEM;
210 
211 
212 	cancel_roc->p2p_soc_obj = p2p_soc_obj;
213 	cancel_roc->cookie = (uintptr_t)roc_ctx;
214 	msg.type = P2P_CANCEL_ROC_REQ;
215 	msg.bodyptr = cancel_roc;
216 	msg.callback = p2p_process_cmd;
217 	status = scheduler_post_message(QDF_MODULE_ID_HDD,
218 					QDF_MODULE_ID_P2P,
219 					QDF_MODULE_ID_OS_IF,
220 					&msg);
221 
222 	if (QDF_IS_STATUS_ERROR(status)) {
223 		qdf_mem_free(cancel_roc);
224 		p2p_err("post msg fail:%d", status);
225 	}
226 
227 	return status;
228 }
229 
ucfg_p2p_cleanup_roc_by_vdev(struct wlan_objmgr_vdev * vdev)230 QDF_STATUS ucfg_p2p_cleanup_roc_by_vdev(struct wlan_objmgr_vdev *vdev)
231 {
232 	return wlan_p2p_cleanup_roc_by_vdev(vdev, true);
233 }
234 
ucfg_p2p_cleanup_roc_by_psoc(struct wlan_objmgr_psoc * psoc)235 QDF_STATUS ucfg_p2p_cleanup_roc_by_psoc(struct wlan_objmgr_psoc *psoc)
236 {
237 	struct p2p_soc_priv_obj *obj;
238 
239 	if (!psoc) {
240 		p2p_err("null psoc");
241 		return QDF_STATUS_E_INVAL;
242 	}
243 
244 	obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_P2P);
245 	if (!obj) {
246 		p2p_err("null p2p soc obj");
247 		return QDF_STATUS_E_FAILURE;
248 	}
249 
250 	return p2p_cleanup_roc(obj, NULL, true);
251 }
252 
ucfg_p2p_cleanup_tx_by_vdev(struct wlan_objmgr_vdev * vdev)253 QDF_STATUS ucfg_p2p_cleanup_tx_by_vdev(struct wlan_objmgr_vdev *vdev)
254 {
255 	struct p2p_soc_priv_obj *obj;
256 	struct wlan_objmgr_psoc *psoc;
257 
258 	if (!vdev) {
259 		p2p_debug("null vdev");
260 		return QDF_STATUS_E_INVAL;
261 	}
262 
263 	psoc = wlan_vdev_get_psoc(vdev);
264 	if (!psoc) {
265 		p2p_err("null psoc");
266 		return QDF_STATUS_E_INVAL;
267 	}
268 
269 	obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_P2P);
270 	if (!obj) {
271 		p2p_err("null p2p soc obj");
272 		return QDF_STATUS_E_FAILURE;
273 	}
274 	p2p_del_all_rand_mac_vdev(vdev);
275 
276 	return p2p_cleanup_tx_sync(obj, vdev);
277 }
278 
ucfg_p2p_cleanup_tx_by_psoc(struct wlan_objmgr_psoc * psoc)279 QDF_STATUS ucfg_p2p_cleanup_tx_by_psoc(struct wlan_objmgr_psoc *psoc)
280 {
281 	struct p2p_soc_priv_obj *obj;
282 
283 	if (!psoc) {
284 		p2p_err("null psoc");
285 		return QDF_STATUS_E_INVAL;
286 	}
287 
288 	obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_P2P);
289 	if (!obj) {
290 		p2p_err("null p2p soc obj");
291 		return QDF_STATUS_E_FAILURE;
292 	}
293 	p2p_del_all_rand_mac_soc(psoc);
294 
295 	return p2p_cleanup_tx_sync(obj, NULL);
296 }
297 
ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc * soc,struct p2p_mgmt_tx * mgmt_frm,uint64_t * cookie,struct wlan_objmgr_pdev * pdev)298 QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc,
299 			    struct p2p_mgmt_tx *mgmt_frm, uint64_t *cookie,
300 			    struct wlan_objmgr_pdev *pdev)
301 {
302 	struct scheduler_msg msg = {0};
303 	struct p2p_soc_priv_obj *p2p_soc_obj;
304 	struct  tx_action_context *tx_action;
305 	QDF_STATUS status;
306 	int32_t id;
307 
308 	if (!soc) {
309 		p2p_err("psoc context passed is NULL");
310 		return QDF_STATUS_E_INVAL;
311 	}
312 
313 	p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
314 			WLAN_UMAC_COMP_P2P);
315 	if (!p2p_soc_obj) {
316 		p2p_err("P2P soc context is NULL");
317 		return QDF_STATUS_E_FAILURE;
318 	}
319 
320 	tx_action = qdf_mem_malloc(sizeof(*tx_action));
321 	if (!tx_action)
322 		return QDF_STATUS_E_NOMEM;
323 
324 	/* return cookie just for ota ack frames */
325 	if (mgmt_frm->dont_wait_for_ack)
326 		id = 0;
327 	else {
328 		status = qdf_idr_alloc(&p2p_soc_obj->p2p_idr,
329 				       tx_action, &id);
330 		if (QDF_IS_STATUS_ERROR(status)) {
331 			qdf_mem_free(tx_action);
332 			p2p_err("failed to alloc idr, status :%d", status);
333 			return status;
334 		}
335 	}
336 
337 	*cookie = (uint64_t)id;
338 	tx_action->p2p_soc_obj = p2p_soc_obj;
339 	tx_action->vdev_id = mgmt_frm->vdev_id;
340 	tx_action->chan_freq = mgmt_frm->chan_freq;
341 	tx_action->duration = mgmt_frm->wait;
342 	tx_action->buf_len = mgmt_frm->len;
343 	tx_action->no_cck = mgmt_frm->no_cck;
344 	tx_action->no_ack = mgmt_frm->dont_wait_for_ack;
345 	tx_action->off_chan = mgmt_frm->off_chan;
346 	tx_action->buf = qdf_mem_malloc(tx_action->buf_len);
347 	if (!(tx_action->buf)) {
348 		qdf_mem_free(tx_action);
349 		return QDF_STATUS_E_NOMEM;
350 	}
351 	qdf_mem_copy(tx_action->buf, mgmt_frm->buf, tx_action->buf_len);
352 	tx_action->nbuf = NULL;
353 	tx_action->id = id;
354 
355 	p2p_rand_mac_tx(pdev, tx_action);
356 
357 	p2p_debug("soc:%pK, vdev_id:%d, freq:%d, wait:%d, buf_len:%d, cck:%d, no ack:%d, off chan:%d cookie = 0x%llx",
358 		  soc, mgmt_frm->vdev_id, mgmt_frm->chan_freq,
359 		  mgmt_frm->wait, mgmt_frm->len, mgmt_frm->no_cck,
360 		  mgmt_frm->dont_wait_for_ack, mgmt_frm->off_chan, *cookie);
361 
362 	msg.type = P2P_MGMT_TX;
363 	msg.bodyptr = tx_action;
364 	msg.callback = p2p_process_cmd;
365 	msg.flush_callback = p2p_msg_flush_callback;
366 	status = scheduler_post_message(QDF_MODULE_ID_HDD,
367 					QDF_MODULE_ID_P2P,
368 					QDF_MODULE_ID_OS_IF,
369 					&msg);
370 	if (QDF_IS_STATUS_ERROR(status)) {
371 		if (id)
372 			qdf_idr_remove(&p2p_soc_obj->p2p_idr, id);
373 		qdf_mem_free(tx_action->buf);
374 		qdf_mem_free(tx_action);
375 		p2p_err("post msg fail:%d", status);
376 	}
377 
378 	return status;
379 }
380 
ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc * soc,struct wlan_objmgr_vdev * vdev,uint64_t cookie)381 QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc,
382 	struct wlan_objmgr_vdev *vdev, uint64_t cookie)
383 {
384 	struct scheduler_msg msg = {0};
385 	struct p2p_soc_priv_obj *p2p_soc_obj;
386 	struct cancel_roc_context *cancel_tx;
387 	void *tx_ctx;
388 	QDF_STATUS status;
389 
390 	p2p_debug("soc:%pK, cookie:0x%llx", soc, cookie);
391 
392 	if (!soc) {
393 		p2p_err("psoc context passed is NULL");
394 		return QDF_STATUS_E_INVAL;
395 	}
396 
397 	p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
398 			WLAN_UMAC_COMP_P2P);
399 	if (!p2p_soc_obj) {
400 		p2p_err("p2p soc context is NULL");
401 		return QDF_STATUS_E_FAILURE;
402 	}
403 
404 	status = qdf_idr_find(&p2p_soc_obj->p2p_idr,
405 			      (int32_t)cookie, &tx_ctx);
406 	if (QDF_IS_STATUS_ERROR(status)) {
407 		p2p_debug("invalid id for cookie 0x%llx", cookie);
408 		return QDF_STATUS_E_INVAL;
409 	}
410 	p2p_del_random_mac(soc, wlan_vdev_get_id(vdev), cookie);
411 
412 	cancel_tx = qdf_mem_malloc(sizeof(*cancel_tx));
413 	if (!cancel_tx)
414 		return QDF_STATUS_E_NOMEM;
415 
416 	cancel_tx->p2p_soc_obj = p2p_soc_obj;
417 	cancel_tx->cookie = (uintptr_t)tx_ctx;
418 	msg.type = P2P_MGMT_TX_CANCEL;
419 	msg.bodyptr = cancel_tx;
420 	msg.callback = p2p_process_cmd;
421 	status = scheduler_post_message(QDF_MODULE_ID_HDD,
422 					QDF_MODULE_ID_P2P,
423 					QDF_MODULE_ID_OS_IF,
424 					&msg);
425 	if (QDF_IS_STATUS_ERROR(status)) {
426 		qdf_mem_free(cancel_tx);
427 		p2p_err("post msg fail: %d", status);
428 	}
429 
430 	return status;
431 }
432 
ucfg_p2p_check_random_mac(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,uint8_t * random_mac_addr)433 bool ucfg_p2p_check_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id,
434 			       uint8_t *random_mac_addr)
435 {
436 	return p2p_check_random_mac(soc, vdev_id, random_mac_addr);
437 }
438 
ucfg_p2p_set_ps(struct wlan_objmgr_psoc * soc,struct p2p_ps_config * ps_config)439 QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc,
440 	struct p2p_ps_config *ps_config)
441 {
442 	struct wlan_lmac_if_p2p_tx_ops *p2p_ops;
443 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
444 	uint16_t obj_id;
445 	struct wlan_objmgr_vdev *vdev;
446 	struct p2p_ps_config go_ps_config;
447 
448 	p2p_debug("soc:%pK, vdev_id:%d, opp_ps:%d, ct_window:%d, count:%d, interval:%d, duration:%d, start:%d, single noa duration:%d, ps_selection:%d",
449 		  soc, ps_config->vdev_id, ps_config->opp_ps,
450 		  ps_config->ct_window, ps_config->count,
451 		  ps_config->interval, ps_config->duration,
452 		  ps_config->start, ps_config->single_noa_duration,
453 		  ps_config->ps_selection);
454 
455 	if (!soc) {
456 		p2p_err("psoc context passed is NULL");
457 		return QDF_STATUS_E_INVAL;
458 	}
459 
460 	for (obj_id = 0; obj_id < WLAN_UMAC_PSOC_MAX_VDEVS; obj_id++) {
461 
462 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, obj_id,
463 							WLAN_P2P_ID);
464 		if (vdev) {
465 			if (is_p2p_ps_allowed(vdev, WLAN_UMAC_COMP_P2P)) {
466 				wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
467 				break;
468 			}
469 			wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
470 			p2p_debug("skip p2p set ps vdev %d, NoA is disabled as legacy STA is connected to GO.",
471 				  obj_id);
472 		}
473 	}
474 	if (obj_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
475 		p2p_debug("No GO found!");
476 		return QDF_STATUS_E_INVAL;
477 	}
478 	go_ps_config = *ps_config;
479 	go_ps_config.vdev_id = obj_id;
480 
481 	p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc);
482 	if (p2p_ops->set_ps) {
483 		status = p2p_ops->set_ps(soc, &go_ps_config);
484 		p2p_debug("p2p set ps vdev %d, status:%d", obj_id, status);
485 	}
486 
487 	return status;
488 }
489 
490 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
ucfg_p2p_lo_start(struct wlan_objmgr_psoc * soc,struct p2p_lo_start * p2p_lo_start)491 QDF_STATUS ucfg_p2p_lo_start(struct wlan_objmgr_psoc *soc,
492 	struct p2p_lo_start *p2p_lo_start)
493 {
494 	struct wlan_lmac_if_p2p_tx_ops *p2p_ops;
495 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
496 
497 	p2p_debug("soc:%pK, vdev_id:%d, ctl_flags:%d, freq:%d, period:%d, interval:%d, count:%d, dev_types_len:%d, probe_resp_len:%d, device_types:%pK, probe_resp_tmplt:%pK",
498 		soc, p2p_lo_start->vdev_id, p2p_lo_start->ctl_flags,
499 		p2p_lo_start->freq, p2p_lo_start->period,
500 		p2p_lo_start->interval, p2p_lo_start->count,
501 		p2p_lo_start->dev_types_len, p2p_lo_start->probe_resp_len,
502 		p2p_lo_start->device_types, p2p_lo_start->probe_resp_tmplt);
503 
504 	if (!soc) {
505 		p2p_err("psoc context passed is NULL");
506 		return QDF_STATUS_E_INVAL;
507 	}
508 
509 	p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc);
510 	if (p2p_ops->lo_start) {
511 		status = p2p_ops->lo_start(soc, p2p_lo_start);
512 		p2p_debug("p2p lo start, status:%d", status);
513 	}
514 
515 	return status;
516 }
517 
ucfg_p2p_lo_stop(struct wlan_objmgr_psoc * soc,uint32_t vdev_id)518 QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc,
519 	uint32_t vdev_id)
520 {
521 	struct wlan_lmac_if_p2p_tx_ops *p2p_ops;
522 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
523 
524 	p2p_debug("soc:%pK, vdev_id:%d", soc, vdev_id);
525 
526 	if (!soc) {
527 		p2p_err("psoc context passed is NULL");
528 		return QDF_STATUS_E_INVAL;
529 	}
530 
531 	p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc);
532 	if (p2p_ops->lo_stop) {
533 		status = p2p_ops->lo_stop(soc, vdev_id);
534 		p2p_debug("p2p lo stop, status:%d", status);
535 	}
536 
537 	return status;
538 }
539 #endif
540 
ucfg_p2p_set_noa(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,bool disable_noa)541 QDF_STATUS  ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc,
542 	uint32_t vdev_id, bool disable_noa)
543 {
544 	struct wlan_lmac_if_p2p_tx_ops *p2p_ops;
545 	QDF_STATUS status = QDF_STATUS_E_INVAL;
546 
547 	p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc);
548 	if (p2p_ops->set_noa) {
549 		status = p2p_ops->set_noa(soc, vdev_id, disable_noa);
550 		p2p_debug("p2p set noa, status:%d", status);
551 	}
552 
553 	return status;
554 }
555 
ucfg_p2p_register_callbacks(struct wlan_objmgr_psoc * soc,struct p2p_protocol_callbacks * cb_obj)556 QDF_STATUS ucfg_p2p_register_callbacks(struct wlan_objmgr_psoc *soc,
557 	    struct p2p_protocol_callbacks *cb_obj)
558 {
559 	struct p2p_soc_priv_obj *p2p_soc_obj;
560 
561 	if (!soc || !cb_obj) {
562 		p2p_err("psoc: %pK or cb_obj: %pK context passed is NULL",
563 			soc, cb_obj);
564 		return QDF_STATUS_E_INVAL;
565 	}
566 
567 	p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
568 		      WLAN_UMAC_COMP_P2P);
569 	if (!p2p_soc_obj) {
570 		p2p_err("p2p soc private object is NULL");
571 		return QDF_STATUS_E_FAILURE;
572 	}
573 	p2p_soc_obj->p2p_cb = *cb_obj;
574 
575 	return QDF_STATUS_SUCCESS;
576 }
577 
578 #ifdef WLAN_FEATURE_MCC_QUOTA
579 QDF_STATUS
ucfg_p2p_register_mcc_quota_event_os_if_cb(struct wlan_objmgr_psoc * psoc,mcc_quota_event_callback cb)580 ucfg_p2p_register_mcc_quota_event_os_if_cb(struct wlan_objmgr_psoc *psoc,
581 					   mcc_quota_event_callback cb)
582 {
583 	struct p2p_soc_priv_obj *p2p_soc_obj;
584 
585 	if (!psoc) {
586 		p2p_err("invalid psoc");
587 		return QDF_STATUS_E_INVAL;
588 	}
589 
590 	p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
591 							    WLAN_UMAC_COMP_P2P);
592 	if (!p2p_soc_obj) {
593 		p2p_err("p2p soc private object is NULL");
594 		return QDF_STATUS_E_FAILURE;
595 	}
596 	p2p_soc_obj->mcc_quota_ev_os_if_cb = cb;
597 
598 	return QDF_STATUS_SUCCESS;
599 }
600 #endif
601 
ucfg_p2p_status_scan(struct wlan_objmgr_vdev * vdev)602 QDF_STATUS ucfg_p2p_status_scan(struct wlan_objmgr_vdev *vdev)
603 {
604 	if (!vdev) {
605 		p2p_err("vdev is NULL");
606 		return QDF_STATUS_E_INVAL;
607 	}
608 
609 	return p2p_status_scan(vdev);
610 }
611 
ucfg_p2p_status_connect(struct wlan_objmgr_vdev * vdev)612 QDF_STATUS ucfg_p2p_status_connect(struct wlan_objmgr_vdev *vdev)
613 {
614 	return wlan_p2p_status_connect(vdev);
615 }
616 
ucfg_p2p_status_disconnect(struct wlan_objmgr_vdev * vdev)617 QDF_STATUS ucfg_p2p_status_disconnect(struct wlan_objmgr_vdev *vdev)
618 {
619 	if (!vdev) {
620 		p2p_err("vdev is NULL");
621 		return QDF_STATUS_E_INVAL;
622 	}
623 
624 	return p2p_status_disconnect(vdev);
625 }
626 
ucfg_p2p_status_start_bss(struct wlan_objmgr_vdev * vdev)627 QDF_STATUS ucfg_p2p_status_start_bss(struct wlan_objmgr_vdev *vdev)
628 {
629 	if (!vdev) {
630 		p2p_err("vdev is NULL");
631 		return QDF_STATUS_E_INVAL;
632 	}
633 
634 	return p2p_status_start_bss(vdev);
635 }
636 
ucfg_p2p_status_stop_bss(struct wlan_objmgr_vdev * vdev)637 QDF_STATUS ucfg_p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev)
638 {
639 	if (!vdev) {
640 		p2p_err("vdev is NULL");
641 		return QDF_STATUS_E_INVAL;
642 	}
643 
644 	return p2p_status_stop_bss(vdev);
645 }
646 
ucfg_p2p_get_indoor_ch_support(struct wlan_objmgr_psoc * psoc)647 bool ucfg_p2p_get_indoor_ch_support(struct wlan_objmgr_psoc *psoc)
648 {
649 	struct p2p_soc_priv_obj *p2p_soc_obj;
650 
651 	if (!psoc) {
652 		p2p_err("invalid psoc");
653 		return false;
654 	}
655 
656 	p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
657 							    WLAN_UMAC_COMP_P2P);
658 	if (!p2p_soc_obj) {
659 		p2p_err("p2p soc private object is NULL");
660 		return false;
661 	}
662 
663 	return p2p_soc_obj->param.indoor_channel_support;
664 }
665 
666 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
667 bool
ucfg_is_p2p_device_dynamic_set_mac_addr_supported(struct wlan_objmgr_psoc * psoc)668 ucfg_is_p2p_device_dynamic_set_mac_addr_supported(struct wlan_objmgr_psoc *psoc)
669 {
670 	struct wmi_unified *wmi_handle;
671 
672 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
673 	if (!wmi_handle) {
674 		p2p_err("wmi handle is NULL");
675 		return false;
676 	}
677 
678 	return wmi_service_enabled(wmi_handle,
679 				   wmi_service_p2p_device_update_mac_addr_support);
680 }
681 #endif
682 
683