1 /*
2  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  *  DOC: wlan_mgmt_txrx_rx_reo_utils_api.c
20  *  This file contains mgmt rx re-ordering related public function definitions
21  */
22 
23 #include <wlan_mgmt_txrx_rx_reo_utils_api.h>
24 #include <wlan_mgmt_txrx_rx_reo_tgt_api.h>
25 #include "../../core/src/wlan_mgmt_txrx_rx_reo_i.h"
26 #include <cfg_ucfg_api.h>
27 #include <wlan_mgmt_txrx_tgt_api.h>
28 #include<wlan_mgmt_txrx_rx_reo_tgt_api.h>
29 #include <wlan_mlo_mgr_cmn.h>
30 #include <wlan_mlo_mgr_setup.h>
31 
32 QDF_STATUS
33 wlan_mgmt_rx_reo_deinit(void)
34 {
35 	uint8_t ml_grp;
36 	uint8_t total_mlo_grps = WLAN_MAX_MLO_GROUPS;
37 
38 	if (total_mlo_grps > WLAN_MAX_MLO_GROUPS)
39 		return QDF_STATUS_E_INVAL;
40 
41 	for (ml_grp = 0; ml_grp < total_mlo_grps; ml_grp++)
42 		if (mgmt_rx_reo_deinit_context(ml_grp))
43 			return QDF_STATUS_E_INVAL;
44 
45 	return QDF_STATUS_SUCCESS;
46 }
47 
48 QDF_STATUS
49 wlan_mgmt_rx_reo_init(void)
50 {
51 	uint8_t ml_grp;
52 	uint8_t total_mlo_grps = WLAN_MAX_MLO_GROUPS;
53 
54 	if (total_mlo_grps > WLAN_MAX_MLO_GROUPS)
55 		return QDF_STATUS_E_INVAL;
56 
57 	for (ml_grp = 0; ml_grp < total_mlo_grps; ml_grp++)
58 		if (mgmt_rx_reo_init_context(ml_grp))
59 			return QDF_STATUS_E_INVAL;
60 
61 	return QDF_STATUS_SUCCESS;
62 }
63 
64 #ifndef WLAN_MGMT_RX_REO_SIM_SUPPORT
65 QDF_STATUS wlan_mgmt_txrx_process_rx_frame(
66 			struct wlan_objmgr_pdev *pdev,
67 			qdf_nbuf_t buf,
68 			struct mgmt_rx_event_params *mgmt_rx_params)
69 {
70 	return tgt_mgmt_txrx_process_rx_frame(pdev, buf, mgmt_rx_params);
71 }
72 
73 QDF_STATUS
74 wlan_mgmt_rx_reo_get_snapshot_info
75 			(struct wlan_objmgr_pdev *pdev,
76 			 enum mgmt_rx_reo_shared_snapshot_id id,
77 			 struct mgmt_rx_reo_snapshot_info *snapshot_info)
78 {
79 	return tgt_mgmt_rx_reo_get_snapshot_info(pdev, id, snapshot_info);
80 }
81 
82 /**
83  * wlan_get_mlo_link_id_from_pdev() - Helper API to get the MLO HW link id
84  * from the pdev object.
85  * @pdev: Pointer to pdev object
86  *
87  * Return: On success returns the MLO HW link id corresponding to the pdev
88  * object. On failure returns -EINVAL
89  */
90 int8_t
91 wlan_get_mlo_link_id_from_pdev(struct wlan_objmgr_pdev *pdev)
92 {
93 	uint16_t hw_link_id;
94 
95 	hw_link_id = wlan_mlo_get_pdev_hw_link_id(pdev);
96 
97 	if (hw_link_id == INVALID_HW_LINK_ID) {
98 		mgmt_rx_reo_err("Invalid HW link id for the pdev");
99 		return -EINVAL;
100 	}
101 
102 	return hw_link_id;
103 }
104 
105 qdf_export_symbol(wlan_get_mlo_link_id_from_pdev);
106 
107 int8_t
108 wlan_get_mlo_grp_id_from_pdev(struct wlan_objmgr_pdev *pdev)
109 {
110 	uint8_t ml_grp_id;
111 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
112 
113 	if (!psoc) {
114 		mgmt_rx_reo_err("PSOC is NUll");
115 		return -EINVAL;
116 	}
117 
118 	ml_grp_id = wlan_mlo_get_psoc_group_id(psoc);
119 
120 	if (ml_grp_id >= WLAN_MAX_MLO_GROUPS) {
121 		mgmt_rx_reo_debug("Invalid MLO Group ID for the pdev");
122 		return -EINVAL;
123 	}
124 
125 	return ml_grp_id;
126 }
127 
128 qdf_export_symbol(wlan_get_mlo_grp_id_from_pdev);
129 
130 /**
131  * wlan_get_pdev_from_mlo_link_id() - Helper API to get the pdev
132  * object from the MLO HW link id.
133  * @mlo_link_id: MLO HW link id
134  * @ml_grp_id: MLO Group id which it belongs to
135  * @refdbgid: Reference debug id
136  *
137  * Return: On success returns the pdev object from the MLO HW link_id.
138  * On failure returns NULL.
139  */
140 struct wlan_objmgr_pdev *
141 wlan_get_pdev_from_mlo_link_id(uint8_t mlo_link_id, uint8_t ml_grp_id,
142 			       wlan_objmgr_ref_dbgid refdbgid)
143 {
144 	return wlan_mlo_get_pdev_by_hw_link_id(
145 			mlo_link_id, ml_grp_id, refdbgid);
146 }
147 
148 qdf_export_symbol(wlan_get_pdev_from_mlo_link_id);
149 #else
150 QDF_STATUS wlan_mgmt_txrx_process_rx_frame(
151 			struct wlan_objmgr_pdev *pdev,
152 			qdf_nbuf_t buf,
153 			struct mgmt_rx_event_params *mgmt_rx_params)
154 {
155 	QDF_STATUS status;
156 
157 	/* Call the legacy handler to actually process and deliver frames */
158 	status = mgmt_rx_reo_sim_process_rx_frame(pdev, buf, mgmt_rx_params);
159 
160 	/**
161 	 * Free up the mgmt rx params.
162 	 * nbuf shouldn't be freed here as it is taken care by
163 	 * rx_frame_legacy_handler.
164 	 */
165 	free_mgmt_rx_event_params(mgmt_rx_params);
166 
167 	return status;
168 }
169 
170 QDF_STATUS
171 wlan_mgmt_rx_reo_get_snapshot_info
172 			(struct wlan_objmgr_pdev *pdev,
173 			 enum mgmt_rx_reo_shared_snapshot_id id,
174 			 struct mgmt_rx_reo_snapshot_info *snapshot_info)
175 {
176 	QDF_STATUS status;
177 
178 	status = mgmt_rx_reo_sim_get_snapshot_address(pdev, id,
179 						      &snapshot_info->address);
180 	if (QDF_IS_STATUS_ERROR(status)) {
181 		mgmt_rx_reo_err("Failed to get snapshot address for ID = %d",
182 				id);
183 		return status;
184 	}
185 
186 	snapshot_info->version = 1;
187 
188 	return QDF_STATUS_SUCCESS;
189 }
190 
191 /**
192  * wlan_get_mlo_link_id_from_pdev() - Helper API to get the MLO HW link id
193  * from the pdev object.
194  * @pdev: Pointer to pdev object
195  *
196  * Return: On success returns the MLO HW link id corresponding to the pdev
197  * object. On failure returns -1.
198  */
199 int8_t
200 wlan_get_mlo_link_id_from_pdev(struct wlan_objmgr_pdev *pdev)
201 {
202 	return mgmt_rx_reo_sim_get_mlo_link_id_from_pdev(pdev);
203 }
204 
205 qdf_export_symbol(wlan_get_mlo_link_id_from_pdev);
206 
207 /**
208  * wlan_get_pdev_from_mlo_link_id() - Helper API to get the pdev
209  * object from the MLO HW link id.
210  * @mlo_link_id: MLO HW link id
211  * @ml_grp_id: MLO Group id which it belongs to
212  * @refdbgid: Reference debug id
213  *
214  * Return: On success returns the pdev object from the MLO HW link_id.
215  * On failure returns NULL.
216  */
217 struct wlan_objmgr_pdev *
218 wlan_get_pdev_from_mlo_link_id(uint8_t mlo_link_id, uint8_t ml_grp_id,
219 			       wlan_objmgr_ref_dbgid refdbgid)
220 {
221 	return mgmt_rx_reo_sim_get_pdev_from_mlo_link_id(
222 			mlo_link_id, ml_grp_id, refdbgid);
223 }
224 
225 qdf_export_symbol(wlan_get_pdev_from_mlo_link_id);
226 #endif /* WLAN_MGMT_RX_REO_SIM_SUPPORT */
227 
228 QDF_STATUS
229 wlan_mgmt_rx_reo_validate_mlo_link_info(struct wlan_objmgr_psoc *psoc)
230 {
231 	return mgmt_rx_reo_validate_mlo_link_info(psoc);
232 }
233 
234 QDF_STATUS
235 wlan_mgmt_rx_reo_pdev_obj_create_notification(
236 			struct wlan_objmgr_pdev *pdev,
237 			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx)
238 {
239 	return mgmt_rx_reo_pdev_obj_create_notification(pdev,
240 							mgmt_txrx_pdev_ctx);
241 }
242 
243 QDF_STATUS
244 wlan_mgmt_rx_reo_pdev_obj_destroy_notification(
245 			struct wlan_objmgr_pdev *pdev,
246 			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx)
247 {
248 	return mgmt_rx_reo_pdev_obj_destroy_notification(pdev,
249 							 mgmt_txrx_pdev_ctx);
250 }
251 
252 QDF_STATUS
253 wlan_mgmt_rx_reo_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc)
254 {
255 	return mgmt_rx_reo_psoc_obj_create_notification(psoc);
256 }
257 
258 QDF_STATUS
259 wlan_mgmt_rx_reo_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc)
260 {
261 	return mgmt_rx_reo_psoc_obj_destroy_notification(psoc);
262 }
263 
264 QDF_STATUS
265 wlan_mgmt_rx_reo_attach(struct wlan_objmgr_pdev *pdev)
266 {
267 	return mgmt_rx_reo_attach(pdev);
268 }
269 
270 qdf_export_symbol(wlan_mgmt_rx_reo_attach);
271 
272 QDF_STATUS
273 wlan_mgmt_rx_reo_detach(struct wlan_objmgr_pdev *pdev)
274 {
275 	return mgmt_rx_reo_detach(pdev);
276 }
277 
278 qdf_export_symbol(wlan_mgmt_rx_reo_detach);
279 
280 uint16_t
281 wlan_mgmt_rx_reo_get_pkt_ctr_delta_thresh(struct wlan_objmgr_psoc *psoc)
282 {
283 	return cfg_get(psoc, CFG_MGMT_RX_REO_PKT_CTR_DELTA_THRESH);
284 }
285 
286 uint16_t
287 wlan_mgmt_rx_reo_get_ingress_frame_debug_list_size(struct wlan_objmgr_psoc *psoc)
288 {
289 	if (!psoc) {
290 		mgmt_rx_reo_err("psoc is NULL!");
291 		return 0;
292 	}
293 
294 	return cfg_get(psoc, CFG_MGMT_RX_REO_INGRESS_FRAME_DEBUG_LIST_SIZE);
295 }
296 
297 uint16_t
298 wlan_mgmt_rx_reo_get_egress_frame_debug_list_size(struct wlan_objmgr_psoc *psoc)
299 {
300 	if (!psoc) {
301 		mgmt_rx_reo_err("psoc is NULL!");
302 		return 0;
303 	}
304 
305 	return cfg_get(psoc, CFG_MGMT_RX_REO_EGRESS_FRAME_DEBUG_LIST_SIZE);
306 }
307 
308 #ifndef WLAN_MGMT_RX_REO_SIM_SUPPORT
309 bool
310 wlan_mgmt_rx_reo_is_feature_enabled_at_psoc(struct wlan_objmgr_psoc *psoc)
311 {
312 	if (!psoc) {
313 		mgmt_rx_reo_err("psoc is NULL!");
314 		return false;
315 	}
316 
317 	if (!cfg_get(psoc, CFG_MGMT_RX_REO_ENABLE))
318 		return false;
319 
320 	return wlan_psoc_nif_feat_cap_get(psoc, WLAN_SOC_F_MGMT_RX_REO_CAPABLE);
321 }
322 
323 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_psoc);
324 
325 bool
326 wlan_mgmt_rx_reo_is_feature_enabled_at_pdev(struct wlan_objmgr_pdev *pdev)
327 {
328 	if (!pdev) {
329 		mgmt_rx_reo_err("pdev is NULL!");
330 		return false;
331 	}
332 
333 	return wlan_mgmt_rx_reo_is_feature_enabled_at_psoc(
334 			wlan_pdev_get_psoc(pdev));
335 }
336 
337 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_pdev);
338 #else
339 bool
340 wlan_mgmt_rx_reo_is_feature_enabled_at_psoc(struct wlan_objmgr_psoc *psoc)
341 {
342 	return true;
343 }
344 
345 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_psoc);
346 
347 bool
348 wlan_mgmt_rx_reo_is_feature_enabled_at_pdev(struct wlan_objmgr_pdev *pdev)
349 {
350 	return true;
351 }
352 
353 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_pdev);
354 
355 QDF_STATUS
356 wlan_mgmt_rx_reo_sim_start(uint8_t ml_grp_id)
357 {
358 	return mgmt_rx_reo_sim_start(ml_grp_id);
359 }
360 
361 qdf_export_symbol(wlan_mgmt_rx_reo_sim_start);
362 
363 QDF_STATUS
364 wlan_mgmt_rx_reo_sim_stop(uint8_t ml_grp_id)
365 {
366 	return mgmt_rx_reo_sim_stop(ml_grp_id);
367 }
368 
369 qdf_export_symbol(wlan_mgmt_rx_reo_sim_stop);
370 #endif /* WLAN_MGMT_RX_REO_SIM_SUPPORT */
371 
372 #ifdef WLAN_MLO_MULTI_CHIP
373 bool
374 wlan_mgmt_rx_reo_is_simulation_in_progress(uint8_t ml_grp_id)
375 {
376 	return mgmt_rx_reo_is_simulation_in_progress(ml_grp_id);
377 }
378 
379 #else
380 bool
381 wlan_mgmt_rx_reo_is_simulation_in_progress(uint8_t ml_grp_id)
382 {
383 	return false;
384 }
385 #endif
386 
387 QDF_STATUS
388 wlan_mgmt_rx_reo_print_ingress_frame_stats(uint8_t ml_grp_id)
389 {
390 	return mgmt_rx_reo_print_ingress_frame_stats(ml_grp_id);
391 }
392 
393 QDF_STATUS
394 wlan_mgmt_rx_reo_print_ingress_frame_info(uint8_t ml_grp_id,
395 					  uint16_t num_frames)
396 {
397 	return mgmt_rx_reo_print_ingress_frame_info(ml_grp_id, num_frames);
398 }
399 
400 QDF_STATUS
401 wlan_mgmt_rx_reo_print_egress_frame_stats(uint8_t ml_grp_id)
402 {
403 	return mgmt_rx_reo_print_egress_frame_stats(ml_grp_id);
404 }
405 
406 QDF_STATUS
407 wlan_mgmt_rx_reo_print_egress_frame_info(uint8_t ml_grp_id, uint16_t num_frames)
408 {
409 	return mgmt_rx_reo_print_egress_frame_info(ml_grp_id, num_frames);
410 }
411