1 /*
2  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022, 2024 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 public API's exposed.
22  */
23 
24 #include "wlan_p2p_api.h"
25 #include <wlan_objmgr_psoc_obj.h>
26 #include "wlan_p2p_public_struct.h"
27 #include "../../core/src/wlan_p2p_main.h"
28 #include "../../core/src/wlan_p2p_roc.h"
29 #include <cds_utils.h>
30 #include "wlan_scan_api.h"
31 #include "../../core/src/wlan_p2p_off_chan_tx.h"
32 
wlan_p2p_check_oui_and_force_1x1(uint8_t * assoc_ie,uint32_t assoc_ie_len)33 bool wlan_p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t assoc_ie_len)
34 {
35 	if (!assoc_ie || !assoc_ie_len)
36 		return false;
37 
38 	return p2p_check_oui_and_force_1x1(assoc_ie, assoc_ie_len);
39 }
40 
wlan_p2p_cleanup_roc_by_vdev(struct wlan_objmgr_vdev * vdev,bool sync)41 QDF_STATUS wlan_p2p_cleanup_roc_by_vdev(struct wlan_objmgr_vdev *vdev,
42 					bool sync)
43 {
44 	struct p2p_soc_priv_obj *p2p_soc_obj;
45 	struct wlan_objmgr_psoc *psoc;
46 
47 	p2p_debug("vdev:%pK", vdev);
48 
49 	if (!vdev) {
50 		p2p_debug("null vdev");
51 		return QDF_STATUS_E_INVAL;
52 	}
53 
54 	psoc = wlan_vdev_get_psoc(vdev);
55 	if (!psoc) {
56 		p2p_err("null psoc");
57 		return QDF_STATUS_E_INVAL;
58 	}
59 
60 	p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
61 			WLAN_UMAC_COMP_P2P);
62 	if (!p2p_soc_obj) {
63 		p2p_err("p2p soc context is NULL");
64 		return QDF_STATUS_E_FAILURE;
65 	}
66 
67 	return p2p_cleanup_roc(p2p_soc_obj, vdev, sync);
68 }
69 
wlan_p2p_status_connect(struct wlan_objmgr_vdev * vdev)70 QDF_STATUS wlan_p2p_status_connect(struct wlan_objmgr_vdev *vdev)
71 {
72 	if (!vdev) {
73 		p2p_err("vdev is NULL");
74 		return QDF_STATUS_E_INVAL;
75 	}
76 
77 	return p2p_status_connect(vdev);
78 }
79 
80 bool
wlan_p2p_is_action_frame_of_p2p_type(uint8_t * data_buf,uint32_t length)81 wlan_p2p_is_action_frame_of_p2p_type(uint8_t *data_buf,
82 				     uint32_t length)
83 {
84 	return p2p_is_action_frame_of_p2p_type(data_buf, length);
85 }
86 
87 #ifdef WLAN_FEATURE_P2P_P2P_STA
88 QDF_STATUS
wlan_p2p_check_and_force_scc_go_plus_go(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)89 wlan_p2p_check_and_force_scc_go_plus_go(struct wlan_objmgr_psoc *psoc,
90 					struct wlan_objmgr_vdev *vdev)
91 {
92 	if (!vdev) {
93 		p2p_err("vdev is NULL");
94 		return QDF_STATUS_E_INVAL;
95 	}
96 
97 	return p2p_check_and_force_scc_go_plus_go(psoc, vdev);
98 }
99 #endif
100 
wlan_p2p_abort_vdev_scan(struct wlan_objmgr_pdev * pdev,void * object,void * arg)101 static void wlan_p2p_abort_vdev_scan(struct wlan_objmgr_pdev *pdev,
102 				     void *object, void *arg)
103 {
104 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
105 	struct scan_cancel_request *req;
106 	struct p2p_soc_priv_obj *p2p_soc_obj;
107 	QDF_STATUS status;
108 
109 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_DEVICE_MODE)
110 		return;
111 
112 	p2p_soc_obj =
113 		wlan_objmgr_psoc_get_comp_private_obj(wlan_vdev_get_psoc(vdev),
114 						      WLAN_UMAC_COMP_P2P);
115 	if (!p2p_soc_obj) {
116 		p2p_err("P2P soc object is NULL");
117 		return;
118 	}
119 
120 	req = qdf_mem_malloc(sizeof(*req));
121 	if (!req)
122 		return;
123 
124 	req->vdev = vdev;
125 	req->cancel_req.requester = p2p_soc_obj->scan_req_id;
126 	req->cancel_req.scan_id = INVALID_SCAN_ID;
127 	req->cancel_req.vdev_id = wlan_vdev_get_id(vdev);
128 	req->cancel_req.req_type = WLAN_SCAN_CANCEL_VDEV_ALL;
129 
130 	qdf_mtrace(QDF_MODULE_ID_P2P, QDF_MODULE_ID_SCAN,
131 		   req->cancel_req.req_type,
132 		   req->cancel_req.vdev_id,
133 		   req->cancel_req.scan_id);
134 	status = wlan_scan_cancel(req);
135 
136 	p2p_debug("abort scan, scan req id:%d, scan id:%d, status:%d",
137 		  req->cancel_req.requester,
138 		  req->cancel_req.scan_id, status);
139 }
140 
wlan_p2p_abort_scan(struct wlan_objmgr_pdev * pdev)141 QDF_STATUS wlan_p2p_abort_scan(struct wlan_objmgr_pdev *pdev)
142 {
143 	return wlan_objmgr_pdev_iterate_obj_list(pdev,
144 						 WLAN_VDEV_OP,
145 						 wlan_p2p_abort_vdev_scan,
146 						 NULL, 0, WLAN_P2P_ID);
147 }
148