1 /*
2  * Copyright (c) 2012-2018, 2020-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 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: Public API implementation of action_oui called by north bound HDD/OSIF.
22  */
23 
24 #include "wlan_action_oui_ucfg_api.h"
25 #include "wlan_action_oui_main.h"
26 #include "target_if_action_oui.h"
27 #include "wlan_action_oui_tgt_api.h"
28 #include <qdf_str.h>
29 
ucfg_action_oui_init(void)30 QDF_STATUS ucfg_action_oui_init(void)
31 {
32 	QDF_STATUS status;
33 
34 	ACTION_OUI_ENTER();
35 
36 	status = wlan_objmgr_register_psoc_create_handler(
37 				WLAN_UMAC_COMP_ACTION_OUI,
38 				action_oui_psoc_create_notification, NULL);
39 	if (!QDF_IS_STATUS_SUCCESS(status)) {
40 		action_oui_err("Failed to register psoc create handler");
41 		goto exit;
42 	}
43 
44 	status = wlan_objmgr_register_psoc_destroy_handler(
45 				WLAN_UMAC_COMP_ACTION_OUI,
46 				action_oui_psoc_destroy_notification, NULL);
47 	if (QDF_IS_STATUS_SUCCESS(status)) {
48 		action_oui_debug("psoc create/delete notifications registered");
49 		goto exit;
50 	}
51 
52 	action_oui_err("Failed to register psoc delete handler");
53 	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_ACTION_OUI,
54 			action_oui_psoc_create_notification, NULL);
55 
56 exit:
57 	ACTION_OUI_EXIT();
58 	return status;
59 }
60 
ucfg_action_oui_deinit(void)61 void ucfg_action_oui_deinit(void)
62 {
63 	QDF_STATUS status;
64 
65 	ACTION_OUI_ENTER();
66 
67 	status = wlan_objmgr_unregister_psoc_create_handler(
68 				WLAN_UMAC_COMP_ACTION_OUI,
69 				action_oui_psoc_create_notification, NULL);
70 	if (!QDF_IS_STATUS_SUCCESS(status))
71 		action_oui_err("Failed to unregister psoc create handler");
72 
73 	status = wlan_objmgr_unregister_psoc_destroy_handler(
74 				WLAN_UMAC_COMP_ACTION_OUI,
75 				action_oui_psoc_destroy_notification,
76 				NULL);
77 	if (!QDF_IS_STATUS_SUCCESS(status))
78 		action_oui_err("Failed to unregister psoc delete handler");
79 
80 	ACTION_OUI_EXIT();
81 }
82 
ucfg_action_oui_psoc_enable(struct wlan_objmgr_psoc * psoc)83 void ucfg_action_oui_psoc_enable(struct wlan_objmgr_psoc *psoc)
84 {
85 	action_oui_psoc_enable(psoc);
86 }
87 
ucfg_action_oui_psoc_disable(struct wlan_objmgr_psoc * psoc)88 void ucfg_action_oui_psoc_disable(struct wlan_objmgr_psoc *psoc)
89 {
90 	action_oui_psoc_disable(psoc);
91 }
92 
ucfg_action_oui_enabled(struct wlan_objmgr_psoc * psoc)93 bool ucfg_action_oui_enabled(struct wlan_objmgr_psoc *psoc)
94 {
95 	struct action_oui_psoc_priv *psoc_priv;
96 
97 	psoc_priv = action_oui_psoc_get_priv(psoc);
98 	if (!psoc_priv) {
99 		action_oui_err("psoc priv is NULL");
100 		return false;
101 	}
102 
103 	return psoc_priv->action_oui_enable;
104 }
105 
106 uint8_t *
ucfg_action_oui_get_config(struct wlan_objmgr_psoc * psoc,enum action_oui_id action_id)107 ucfg_action_oui_get_config(struct wlan_objmgr_psoc *psoc,
108 			   enum action_oui_id action_id)
109 {
110 	struct action_oui_psoc_priv *psoc_priv;
111 
112 	psoc_priv = action_oui_psoc_get_priv(psoc);
113 	if (!psoc_priv) {
114 		action_oui_err("psoc priv is NULL");
115 		return "";
116 	}
117 	if (action_id >= ACTION_OUI_MAXIMUM_ID) {
118 		action_oui_err("Invalid action_oui id: %u", action_id);
119 		return "";
120 	}
121 
122 	return psoc_priv->action_oui_str[action_id];
123 }
124 
125 
126 QDF_STATUS
ucfg_action_oui_parse(struct wlan_objmgr_psoc * psoc,const uint8_t * in_str,enum action_oui_id action_id)127 ucfg_action_oui_parse(struct wlan_objmgr_psoc *psoc,
128 		      const uint8_t *in_str,
129 		      enum action_oui_id action_id)
130 {
131 	return action_oui_parse_string(psoc, in_str, action_id);
132 }
133 
134 QDF_STATUS
ucfg_action_oui_cleanup(struct wlan_objmgr_psoc * psoc,enum action_oui_id action_id)135 ucfg_action_oui_cleanup(struct wlan_objmgr_psoc *psoc,
136 			enum action_oui_id action_id)
137 {
138 	struct action_oui_psoc_priv *psoc_priv;
139 	QDF_STATUS status = QDF_STATUS_E_INVAL;
140 
141 	ACTION_OUI_ENTER();
142 
143 	if (action_id >= ACTION_OUI_MAXIMUM_ID) {
144 		action_oui_err("Invalid action_oui id: %u", action_id);
145 		goto exit;
146 	}
147 
148 	if (!psoc) {
149 		action_oui_err("psoc is NULL");
150 		goto exit;
151 	}
152 
153 	psoc_priv = action_oui_psoc_get_priv(psoc);
154 	if (!psoc_priv) {
155 		action_oui_err("psoc priv is NULL");
156 		goto exit;
157 	}
158 
159 	status = wlan_action_oui_cleanup(psoc_priv, action_id);
160 exit:
161 	ACTION_OUI_EXIT();
162 	return status;
163 }
164 
ucfg_action_oui_send(struct wlan_objmgr_psoc * psoc)165 QDF_STATUS ucfg_action_oui_send(struct wlan_objmgr_psoc *psoc)
166 {
167 	struct action_oui_psoc_priv *psoc_priv;
168 	QDF_STATUS status = QDF_STATUS_E_INVAL;
169 	uint32_t id;
170 
171 	if (!psoc) {
172 		action_oui_err("psoc is NULL");
173 		goto exit;
174 	}
175 
176 	psoc_priv = action_oui_psoc_get_priv(psoc);
177 	if (!psoc_priv) {
178 		action_oui_err("psoc priv is NULL");
179 		goto exit;
180 	}
181 
182 	for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
183 		if (id >= ACTION_OUI_HOST_ONLY)
184 			continue;
185 		status = action_oui_send(psoc_priv, id);
186 		if (!QDF_IS_STATUS_SUCCESS(status))
187 			action_oui_debug("Failed to send: %u", id);
188 	}
189 
190 exit:
191 	return status;
192 }
193 
ucfg_action_oui_send_by_id(struct wlan_objmgr_psoc * psoc,enum action_oui_id id)194 QDF_STATUS ucfg_action_oui_send_by_id(struct wlan_objmgr_psoc *psoc,
195 				      enum action_oui_id id)
196 {
197 	struct action_oui_psoc_priv *psoc_priv;
198 	QDF_STATUS status = QDF_STATUS_E_INVAL;
199 
200 	ACTION_OUI_ENTER();
201 
202 	if (!psoc) {
203 		action_oui_err("psoc is NULL");
204 		goto exit;
205 	}
206 
207 	psoc_priv = action_oui_psoc_get_priv(psoc);
208 	if (!psoc_priv) {
209 		action_oui_err("psoc priv is NULL");
210 		goto exit;
211 	}
212 
213 	if (id >= ACTION_OUI_HOST_ONLY) {
214 		action_oui_err("id %d not for firmware", id);
215 		status = QDF_STATUS_SUCCESS;
216 		goto exit;
217 	}
218 
219 	status = action_oui_send(psoc_priv, id);
220 	if (!QDF_IS_STATUS_SUCCESS(status))
221 		action_oui_debug("Failed to send: %u", id);
222 exit:
223 	ACTION_OUI_EXIT();
224 
225 	return status;
226 }
227 
ucfg_action_oui_search(struct wlan_objmgr_psoc * psoc,struct action_oui_search_attr * attr,enum action_oui_id action_id)228 bool ucfg_action_oui_search(struct wlan_objmgr_psoc *psoc,
229 			    struct action_oui_search_attr *attr,
230 			    enum action_oui_id action_id)
231 {
232 	return wlan_action_oui_search(psoc, attr, action_id);
233 }
234