xref: /wlan-dirver/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_api.c (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <qdf_status.h>
20 #include <target_if_direct_buf_rx_api.h>
21 #include <wlan_objmgr_cmn.h>
22 #include <wlan_objmgr_global_obj.h>
23 #include <wlan_objmgr_psoc_obj.h>
24 #include <wlan_objmgr_cmn.h>
25 #include "target_if_direct_buf_rx_main.h"
26 #include <qdf_module.h>
27 #include <wlan_lmac_if_def.h>
28 
29 #if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG)
30 /* Base debugfs entry for DBR module */
31 qdf_dentry_t dbr_debugfs_entry;
32 
33 static inline void
34 target_if_direct_buf_rx_debugfs_init(void)
35 {
36 	dbr_debugfs_entry = qdf_debugfs_create_dir("dbr_ring_debug", NULL);
37 
38 	if (!dbr_debugfs_entry)
39 		direct_buf_rx_err("error while creating direct_buf rx debugfs dir");
40 }
41 
42 static inline void
43 target_if_direct_buf_rx_debugfs_deinit(void)
44 {
45 	if (dbr_debugfs_entry) {
46 		qdf_debugfs_remove_dir_recursive(dbr_debugfs_entry);
47 		dbr_debugfs_entry = NULL;
48 	}
49 }
50 #else
51 static inline void
52 target_if_direct_buf_rx_debugfs_init(void)
53 {
54 }
55 
56 static inline void
57 target_if_direct_buf_rx_debugfs_deinit(void)
58 {
59 }
60 #endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */
61 
62 QDF_STATUS direct_buf_rx_init(void)
63 {
64 	QDF_STATUS status;
65 
66 	status = wlan_objmgr_register_psoc_create_handler(
67 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
68 			target_if_direct_buf_rx_psoc_create_handler,
69 			NULL);
70 
71 	if (QDF_IS_STATUS_ERROR(status)) {
72 		direct_buf_rx_err("Failed to register psoc create handler");
73 		return status;
74 	}
75 
76 	status = wlan_objmgr_register_psoc_destroy_handler(
77 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
78 			target_if_direct_buf_rx_psoc_destroy_handler,
79 			NULL);
80 
81 	if (QDF_IS_STATUS_ERROR(status)) {
82 		direct_buf_rx_err("Failed to register psoc destroy handler");
83 		goto dbr_unreg_psoc_create;
84 	}
85 
86 	status = wlan_objmgr_register_pdev_create_handler(
87 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
88 			target_if_direct_buf_rx_pdev_create_handler,
89 			NULL);
90 
91 	if (QDF_IS_STATUS_ERROR(status)) {
92 		direct_buf_rx_err("Failed to register pdev create handler");
93 		goto dbr_unreg_psoc_destroy;
94 	}
95 
96 	status = wlan_objmgr_register_pdev_destroy_handler(
97 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
98 			target_if_direct_buf_rx_pdev_destroy_handler,
99 			NULL);
100 
101 	if (QDF_IS_STATUS_ERROR(status)) {
102 		direct_buf_rx_err("Failed to register pdev destroy handler");
103 		goto dbr_unreg_pdev_create;
104 	}
105 
106 	target_if_direct_buf_rx_debugfs_init();
107 
108 	direct_buf_rx_info("Direct Buffer RX pdev,psoc create and destroy handlers registered");
109 
110 	return QDF_STATUS_SUCCESS;
111 
112 dbr_unreg_pdev_create:
113 	status = wlan_objmgr_unregister_pdev_create_handler(
114 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
115 			target_if_direct_buf_rx_pdev_create_handler,
116 			NULL);
117 
118 dbr_unreg_psoc_destroy:
119 	status = wlan_objmgr_unregister_psoc_destroy_handler(
120 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
121 			target_if_direct_buf_rx_psoc_destroy_handler,
122 			NULL);
123 
124 dbr_unreg_psoc_create:
125 	status = wlan_objmgr_unregister_psoc_create_handler(
126 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
127 			target_if_direct_buf_rx_psoc_create_handler,
128 			NULL);
129 
130 	return QDF_STATUS_E_FAILURE;
131 }
132 qdf_export_symbol(direct_buf_rx_init);
133 
134 QDF_STATUS direct_buf_rx_deinit(void)
135 {
136 	QDF_STATUS status;
137 
138 	target_if_direct_buf_rx_debugfs_deinit();
139 
140 	status = wlan_objmgr_unregister_pdev_destroy_handler(
141 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
142 			target_if_direct_buf_rx_pdev_destroy_handler,
143 			NULL);
144 
145 	if (QDF_IS_STATUS_ERROR(status))
146 		direct_buf_rx_err("Failed to unregister pdev destroy handler");
147 
148 	status = wlan_objmgr_unregister_pdev_create_handler(
149 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
150 			target_if_direct_buf_rx_pdev_create_handler,
151 			NULL);
152 
153 	if (QDF_IS_STATUS_ERROR(status))
154 		direct_buf_rx_err("Failed to unregister pdev create handler");
155 
156 	status = wlan_objmgr_unregister_psoc_destroy_handler(
157 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
158 			target_if_direct_buf_rx_psoc_destroy_handler,
159 			NULL);
160 
161 	if (QDF_IS_STATUS_ERROR(status))
162 		direct_buf_rx_err("Failed to unregister psoc destroy handler");
163 
164 	status = wlan_objmgr_unregister_psoc_create_handler(
165 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
166 			target_if_direct_buf_rx_psoc_create_handler,
167 			NULL);
168 
169 	if (QDF_IS_STATUS_ERROR(status))
170 		direct_buf_rx_err("Failed to unregister psoc create handler");
171 
172 	direct_buf_rx_debug("Direct Buffer RX pdev,psoc create and destroy handlers unregistered");
173 
174 	return status;
175 }
176 qdf_export_symbol(direct_buf_rx_deinit);
177 
178 QDF_STATUS direct_buf_rx_target_attach(struct wlan_objmgr_psoc *psoc,
179 				void *hal_soc, qdf_device_t osdev)
180 {
181 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
182 
183 	if (!hal_soc || !osdev) {
184 		direct_buf_rx_err("hal soc or osdev is null");
185 		return QDF_STATUS_E_INVAL;
186 	}
187 
188 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
189 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
190 
191 	direct_buf_rx_debug("Dbr psoc obj %pK", dbr_psoc_obj);
192 
193 	if (!dbr_psoc_obj) {
194 		direct_buf_rx_err("dir buf rx psoc obj is null");
195 		return QDF_STATUS_E_FAILURE;
196 	}
197 
198 	dbr_psoc_obj->hal_soc = hal_soc;
199 	dbr_psoc_obj->osdev = osdev;
200 
201 	return QDF_STATUS_SUCCESS;
202 }
203 
204 #ifdef DIRECT_BUF_RX_DEBUG
205 static inline void
206 target_if_direct_buf_rx_debug_register_tx_ops(
207 	struct wlan_lmac_if_tx_ops *tx_ops)
208 {
209 	tx_ops->dbr_tx_ops.direct_buf_rx_start_ring_debug =
210 				target_if_dbr_start_ring_debug;
211 	tx_ops->dbr_tx_ops.direct_buf_rx_stop_ring_debug =
212 				target_if_dbr_stop_ring_debug;
213 	tx_ops->dbr_tx_ops.direct_buf_rx_start_buffer_poisoning =
214 				target_if_dbr_start_buffer_poisoning;
215 	tx_ops->dbr_tx_ops.direct_buf_rx_stop_buffer_poisoning =
216 				target_if_dbr_stop_buffer_poisoning;
217 }
218 #else
219 static inline void
220 target_if_direct_buf_rx_debug_register_tx_ops(
221 	struct wlan_lmac_if_tx_ops *tx_ops)
222 {
223 }
224 #endif /* DIRECT_BUF_RX_DEBUG */
225 
226 void target_if_direct_buf_rx_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
227 {
228 	tx_ops->dbr_tx_ops.direct_buf_rx_module_register =
229 				target_if_direct_buf_rx_module_register;
230 	tx_ops->dbr_tx_ops.direct_buf_rx_module_unregister =
231 				target_if_direct_buf_rx_module_unregister;
232 	tx_ops->dbr_tx_ops.direct_buf_rx_register_events =
233 				target_if_direct_buf_rx_register_events;
234 	tx_ops->dbr_tx_ops.direct_buf_rx_unregister_events =
235 				target_if_direct_buf_rx_unregister_events;
236 	tx_ops->dbr_tx_ops.direct_buf_rx_print_ring_stat =
237 				target_if_direct_buf_rx_print_ring_stat;
238 	tx_ops->dbr_tx_ops.direct_buf_rx_get_ring_params =
239 				target_if_direct_buf_rx_get_ring_params;
240 	target_if_direct_buf_rx_debug_register_tx_ops(tx_ops);
241 }
242 qdf_export_symbol(target_if_direct_buf_rx_register_tx_ops);
243 
244 QDF_STATUS target_if_dbr_update_pdev_for_hw_mode_change(
245 		struct wlan_objmgr_pdev *pdev, int phy_idx)
246 {
247 	struct wlan_objmgr_psoc *psoc;
248 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
249 
250 	psoc = wlan_pdev_get_psoc(pdev);
251 	if (!psoc) {
252 		direct_buf_rx_err("psoc is null");
253 		return QDF_STATUS_E_NULL_VALUE;
254 	}
255 
256 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
257 			psoc, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
258 	if (!dbr_psoc_obj) {
259 		direct_buf_rx_err("dir buf rx psoc object is null");
260 		return QDF_STATUS_E_NULL_VALUE;
261 	}
262 
263 	/* Update DBR object in pdev */
264 	pdev->pdev_comp_priv_obj[WLAN_TARGET_IF_COMP_DIRECT_BUF_RX] =
265 		(void *)dbr_psoc_obj->dbr_pdev_obj[phy_idx];
266 
267 	return QDF_STATUS_SUCCESS;
268 }
269