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