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