xref: /wlan-dirver/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_api.c (revision 8cfe6b10058a04cafb17eed051f2ddf11bee8931)
1 /*
2  * Copyright (c) 2017-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 #include <qdf_status.h>
21 #include <target_if_direct_buf_rx_api.h>
22 #include <wlan_objmgr_cmn.h>
23 #include <wlan_objmgr_global_obj.h>
24 #include <wlan_objmgr_psoc_obj.h>
25 #include <wlan_objmgr_cmn.h>
26 #include "target_if_direct_buf_rx_main.h"
27 #include <qdf_module.h>
28 #include <wlan_lmac_if_def.h>
29 
30 #if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG)
31 /* Base debugfs entry for DBR module */
32 qdf_dentry_t dbr_debugfs_entry;
33 
34 static inline void
35 target_if_direct_buf_rx_debugfs_init(void)
36 {
37 	dbr_debugfs_entry = qdf_debugfs_create_dir("dbr_ring_debug", NULL);
38 
39 	if (!dbr_debugfs_entry)
40 		direct_buf_rx_err("error while creating direct_buf rx debugfs dir");
41 }
42 
43 static inline void
44 target_if_direct_buf_rx_debugfs_deinit(void)
45 {
46 	if (dbr_debugfs_entry) {
47 		qdf_debugfs_remove_dir_recursive(dbr_debugfs_entry);
48 		dbr_debugfs_entry = NULL;
49 	}
50 }
51 #else
52 static inline void
53 target_if_direct_buf_rx_debugfs_init(void)
54 {
55 }
56 
57 static inline void
58 target_if_direct_buf_rx_debugfs_deinit(void)
59 {
60 }
61 #endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */
62 
63 QDF_STATUS direct_buf_rx_init(void)
64 {
65 	QDF_STATUS status;
66 
67 	status = wlan_objmgr_register_psoc_create_handler(
68 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
69 			target_if_direct_buf_rx_psoc_create_handler,
70 			NULL);
71 
72 	if (QDF_IS_STATUS_ERROR(status)) {
73 		direct_buf_rx_err("Failed to register psoc create handler");
74 		return status;
75 	}
76 
77 	status = wlan_objmgr_register_psoc_destroy_handler(
78 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
79 			target_if_direct_buf_rx_psoc_destroy_handler,
80 			NULL);
81 
82 	if (QDF_IS_STATUS_ERROR(status)) {
83 		direct_buf_rx_err("Failed to register psoc destroy handler");
84 		goto dbr_unreg_psoc_create;
85 	}
86 
87 	status = wlan_objmgr_register_pdev_create_handler(
88 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
89 			target_if_direct_buf_rx_pdev_create_handler,
90 			NULL);
91 
92 	if (QDF_IS_STATUS_ERROR(status)) {
93 		direct_buf_rx_err("Failed to register pdev create handler");
94 		goto dbr_unreg_psoc_destroy;
95 	}
96 
97 	status = wlan_objmgr_register_pdev_destroy_handler(
98 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
99 			target_if_direct_buf_rx_pdev_destroy_handler,
100 			NULL);
101 
102 	if (QDF_IS_STATUS_ERROR(status)) {
103 		direct_buf_rx_err("Failed to register pdev destroy handler");
104 		goto dbr_unreg_pdev_create;
105 	}
106 
107 	target_if_direct_buf_rx_debugfs_init();
108 
109 	direct_buf_rx_info("Direct Buffer RX pdev,psoc create and destroy handlers registered");
110 
111 	return QDF_STATUS_SUCCESS;
112 
113 dbr_unreg_pdev_create:
114 	status = wlan_objmgr_unregister_pdev_create_handler(
115 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
116 			target_if_direct_buf_rx_pdev_create_handler,
117 			NULL);
118 
119 dbr_unreg_psoc_destroy:
120 	status = wlan_objmgr_unregister_psoc_destroy_handler(
121 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
122 			target_if_direct_buf_rx_psoc_destroy_handler,
123 			NULL);
124 
125 dbr_unreg_psoc_create:
126 	status = wlan_objmgr_unregister_psoc_create_handler(
127 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
128 			target_if_direct_buf_rx_psoc_create_handler,
129 			NULL);
130 
131 	return QDF_STATUS_E_FAILURE;
132 }
133 qdf_export_symbol(direct_buf_rx_init);
134 
135 QDF_STATUS direct_buf_rx_deinit(void)
136 {
137 	QDF_STATUS status;
138 
139 	target_if_direct_buf_rx_debugfs_deinit();
140 
141 	status = wlan_objmgr_unregister_pdev_destroy_handler(
142 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
143 			target_if_direct_buf_rx_pdev_destroy_handler,
144 			NULL);
145 
146 	if (QDF_IS_STATUS_ERROR(status))
147 		direct_buf_rx_err("Failed to unregister pdev destroy handler");
148 
149 	status = wlan_objmgr_unregister_pdev_create_handler(
150 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
151 			target_if_direct_buf_rx_pdev_create_handler,
152 			NULL);
153 
154 	if (QDF_IS_STATUS_ERROR(status))
155 		direct_buf_rx_err("Failed to unregister pdev create handler");
156 
157 	status = wlan_objmgr_unregister_psoc_destroy_handler(
158 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
159 			target_if_direct_buf_rx_psoc_destroy_handler,
160 			NULL);
161 
162 	if (QDF_IS_STATUS_ERROR(status))
163 		direct_buf_rx_err("Failed to unregister psoc destroy handler");
164 
165 	status = wlan_objmgr_unregister_psoc_create_handler(
166 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
167 			target_if_direct_buf_rx_psoc_create_handler,
168 			NULL);
169 
170 	if (QDF_IS_STATUS_ERROR(status))
171 		direct_buf_rx_err("Failed to unregister psoc create handler");
172 
173 	direct_buf_rx_debug("Direct Buffer RX pdev,psoc create and destroy handlers unregistered");
174 
175 	return status;
176 }
177 qdf_export_symbol(direct_buf_rx_deinit);
178 
179 QDF_STATUS direct_buf_rx_target_attach(struct wlan_objmgr_psoc *psoc,
180 				void *hal_soc, qdf_device_t osdev)
181 {
182 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
183 
184 	if (!hal_soc || !osdev) {
185 		direct_buf_rx_err("hal soc or osdev is null");
186 		return QDF_STATUS_E_INVAL;
187 	}
188 
189 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
190 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
191 
192 	direct_buf_rx_debug("Dbr psoc obj %pK", dbr_psoc_obj);
193 
194 	if (!dbr_psoc_obj) {
195 		direct_buf_rx_err("dir buf rx psoc obj is null");
196 		return QDF_STATUS_E_FAILURE;
197 	}
198 
199 	dbr_psoc_obj->hal_soc = hal_soc;
200 	dbr_psoc_obj->osdev = osdev;
201 
202 	return QDF_STATUS_SUCCESS;
203 }
204 
205 #ifdef DIRECT_BUF_RX_DEBUG
206 static inline void
207 target_if_direct_buf_rx_debug_register_tx_ops(
208 	struct wlan_lmac_if_tx_ops *tx_ops)
209 {
210 	tx_ops->dbr_tx_ops.direct_buf_rx_start_ring_debug =
211 				target_if_dbr_start_ring_debug;
212 	tx_ops->dbr_tx_ops.direct_buf_rx_stop_ring_debug =
213 				target_if_dbr_stop_ring_debug;
214 	tx_ops->dbr_tx_ops.direct_buf_rx_start_buffer_poisoning =
215 				target_if_dbr_start_buffer_poisoning;
216 	tx_ops->dbr_tx_ops.direct_buf_rx_stop_buffer_poisoning =
217 				target_if_dbr_stop_buffer_poisoning;
218 }
219 #else
220 static inline void
221 target_if_direct_buf_rx_debug_register_tx_ops(
222 	struct wlan_lmac_if_tx_ops *tx_ops)
223 {
224 }
225 #endif /* DIRECT_BUF_RX_DEBUG */
226 
227 void target_if_direct_buf_rx_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
228 {
229 	tx_ops->dbr_tx_ops.direct_buf_rx_module_register =
230 				target_if_direct_buf_rx_module_register;
231 	tx_ops->dbr_tx_ops.direct_buf_rx_module_unregister =
232 				target_if_direct_buf_rx_module_unregister;
233 	tx_ops->dbr_tx_ops.direct_buf_rx_register_events =
234 				target_if_direct_buf_rx_register_events;
235 	tx_ops->dbr_tx_ops.direct_buf_rx_unregister_events =
236 				target_if_direct_buf_rx_unregister_events;
237 	tx_ops->dbr_tx_ops.direct_buf_rx_print_ring_stat =
238 				target_if_direct_buf_rx_print_ring_stat;
239 	tx_ops->dbr_tx_ops.direct_buf_rx_get_ring_params =
240 				target_if_direct_buf_rx_get_ring_params;
241 	target_if_direct_buf_rx_debug_register_tx_ops(tx_ops);
242 }
243 qdf_export_symbol(target_if_direct_buf_rx_register_tx_ops);
244 
245 QDF_STATUS target_if_dbr_update_pdev_for_hw_mode_change(
246 		struct wlan_objmgr_pdev *pdev, int phy_idx)
247 {
248 	struct wlan_objmgr_psoc *psoc;
249 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
250 
251 	psoc = wlan_pdev_get_psoc(pdev);
252 	if (!psoc) {
253 		direct_buf_rx_err("psoc is null");
254 		return QDF_STATUS_E_NULL_VALUE;
255 	}
256 
257 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
258 			psoc, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
259 	if (!dbr_psoc_obj) {
260 		direct_buf_rx_err("dir buf rx psoc object is null");
261 		return QDF_STATUS_E_NULL_VALUE;
262 	}
263 
264 	/* Update DBR object in pdev */
265 	pdev->pdev_comp_priv_obj[WLAN_TARGET_IF_COMP_DIRECT_BUF_RX] =
266 		(void *)dbr_psoc_obj->dbr_pdev_obj[phy_idx];
267 
268 	return QDF_STATUS_SUCCESS;
269 }
270 
271 QDF_STATUS target_if_dbr_set_event_handler_ctx(
272 		struct wlan_objmgr_psoc *psoc,
273 		enum wmi_rx_exec_ctx event_handler_ctx)
274 {
275 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
276 
277 	if (!psoc) {
278 		direct_buf_rx_err("psoc is null");
279 		return QDF_STATUS_E_NULL_VALUE;
280 	}
281 
282 	if (event_handler_ctx != WMI_RX_UMAC_CTX &&
283 	    event_handler_ctx != WMI_RX_WORK_CTX) {
284 		qdf_err("DBR handler context: Invalid context");
285 		return QDF_STATUS_E_INVAL;
286 	}
287 
288 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
289 			psoc, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
290 	if (!dbr_psoc_obj) {
291 		direct_buf_rx_err("dir buf rx psoc object is null");
292 		return QDF_STATUS_E_NULL_VALUE;
293 	}
294 
295 	dbr_psoc_obj->handler_ctx = event_handler_ctx;
296 
297 	direct_buf_rx_info("DBR handler context: %d",
298 			   dbr_psoc_obj->handler_ctx);
299 
300 	return QDF_STATUS_SUCCESS;
301 }
302