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 		QDF_STATUS status;
43 
44 		status = mgmt_rx_reo_deinit_context(ml_grp);
45 		if (QDF_IS_STATUS_ERROR(status)) {
46 			mgmt_rx_reo_err("Reo context deinit failed for grp %u",
47 					ml_grp);
48 			return status;
49 		}
50 	}
51 
52 	return QDF_STATUS_SUCCESS;
53 }
54 
55 QDF_STATUS
56 wlan_mgmt_rx_reo_init(void)
57 {
58 	uint8_t ml_grp;
59 	uint8_t total_mlo_grps = WLAN_MAX_MLO_GROUPS;
60 
61 	if (total_mlo_grps > WLAN_MAX_MLO_GROUPS)
62 		return QDF_STATUS_E_INVAL;
63 
64 	for (ml_grp = 0; ml_grp < total_mlo_grps; ml_grp++) {
65 		QDF_STATUS status;
66 
67 		status = mgmt_rx_reo_init_context(ml_grp);
68 		if (QDF_IS_STATUS_ERROR(status)) {
69 			mgmt_rx_reo_err("Reo context init failed for grp %u",
70 					ml_grp);
71 			return status;
72 		}
73 	}
74 
75 	return QDF_STATUS_SUCCESS;
76 }
77 
78 #ifndef WLAN_MGMT_RX_REO_SIM_SUPPORT
79 QDF_STATUS wlan_mgmt_txrx_process_rx_frame(
80 			struct wlan_objmgr_pdev *pdev,
81 			qdf_nbuf_t buf,
82 			struct mgmt_rx_event_params *mgmt_rx_params)
83 {
84 	return tgt_mgmt_txrx_process_rx_frame(pdev, buf, mgmt_rx_params);
85 }
86 
87 QDF_STATUS
88 wlan_mgmt_rx_reo_get_snapshot_info
89 			(struct wlan_objmgr_pdev *pdev,
90 			 enum mgmt_rx_reo_shared_snapshot_id id,
91 			 struct mgmt_rx_reo_snapshot_info *snapshot_info)
92 {
93 	return tgt_mgmt_rx_reo_get_snapshot_info(pdev, id, snapshot_info);
94 }
95 
96 /**
97  * wlan_get_mlo_link_id_from_pdev() - Helper API to get the MLO HW link id
98  * from the pdev object.
99  * @pdev: Pointer to pdev object
100  *
101  * Return: On success returns the MLO HW link id corresponding to the pdev
102  * object. On failure returns -EINVAL
103  */
104 int8_t
105 wlan_get_mlo_link_id_from_pdev(struct wlan_objmgr_pdev *pdev)
106 {
107 	uint16_t hw_link_id;
108 
109 	hw_link_id = wlan_mlo_get_pdev_hw_link_id(pdev);
110 
111 	if (hw_link_id == INVALID_HW_LINK_ID) {
112 		mgmt_rx_reo_err("Invalid HW link id for the pdev");
113 		return -EINVAL;
114 	}
115 
116 	return hw_link_id;
117 }
118 
119 qdf_export_symbol(wlan_get_mlo_link_id_from_pdev);
120 
121 int8_t
122 wlan_get_mlo_grp_id_from_pdev(struct wlan_objmgr_pdev *pdev)
123 {
124 	uint8_t ml_grp_id;
125 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
126 
127 	if (!psoc) {
128 		mgmt_rx_reo_err("PSOC is NUll");
129 		return -EINVAL;
130 	}
131 
132 	ml_grp_id = wlan_mlo_get_psoc_group_id(psoc);
133 
134 	if (ml_grp_id >= WLAN_MAX_MLO_GROUPS) {
135 		mgmt_rx_reo_debug("Invalid MLO Group ID for the pdev");
136 		return -EINVAL;
137 	}
138 
139 	return ml_grp_id;
140 }
141 
142 qdf_export_symbol(wlan_get_mlo_grp_id_from_pdev);
143 
144 /**
145  * wlan_get_pdev_from_mlo_link_id() - Helper API to get the pdev
146  * object from the MLO HW link id.
147  * @mlo_link_id: MLO HW link id
148  * @ml_grp_id: MLO Group id which it belongs to
149  * @refdbgid: Reference debug id
150  *
151  * Return: On success returns the pdev object from the MLO HW link_id.
152  * On failure returns NULL.
153  */
154 struct wlan_objmgr_pdev *
155 wlan_get_pdev_from_mlo_link_id(uint8_t mlo_link_id, uint8_t ml_grp_id,
156 			       wlan_objmgr_ref_dbgid refdbgid)
157 {
158 	return wlan_mlo_get_pdev_by_hw_link_id(
159 			mlo_link_id, ml_grp_id, refdbgid);
160 }
161 
162 qdf_export_symbol(wlan_get_pdev_from_mlo_link_id);
163 #else
164 QDF_STATUS wlan_mgmt_txrx_process_rx_frame(
165 			struct wlan_objmgr_pdev *pdev,
166 			qdf_nbuf_t buf,
167 			struct mgmt_rx_event_params *mgmt_rx_params)
168 {
169 	QDF_STATUS status;
170 
171 	/* Call the legacy handler to actually process and deliver frames */
172 	status = mgmt_rx_reo_sim_process_rx_frame(pdev, buf, mgmt_rx_params);
173 
174 	/**
175 	 * Free up the mgmt rx params.
176 	 * nbuf shouldn't be freed here as it is taken care by
177 	 * rx_frame_legacy_handler.
178 	 */
179 	free_mgmt_rx_event_params(mgmt_rx_params);
180 
181 	return status;
182 }
183 
184 QDF_STATUS
185 wlan_mgmt_rx_reo_get_snapshot_info
186 			(struct wlan_objmgr_pdev *pdev,
187 			 enum mgmt_rx_reo_shared_snapshot_id id,
188 			 struct mgmt_rx_reo_snapshot_info *snapshot_info)
189 {
190 	QDF_STATUS status;
191 
192 	status = mgmt_rx_reo_sim_get_snapshot_address(pdev, id,
193 						      &snapshot_info->address);
194 	if (QDF_IS_STATUS_ERROR(status)) {
195 		mgmt_rx_reo_err("Failed to get snapshot address for ID = %d",
196 				id);
197 		return status;
198 	}
199 
200 	snapshot_info->version = 1;
201 
202 	return QDF_STATUS_SUCCESS;
203 }
204 
205 /**
206  * wlan_get_mlo_link_id_from_pdev() - Helper API to get the MLO HW link id
207  * from the pdev object.
208  * @pdev: Pointer to pdev object
209  *
210  * Return: On success returns the MLO HW link id corresponding to the pdev
211  * object. On failure returns -1.
212  */
213 int8_t
214 wlan_get_mlo_link_id_from_pdev(struct wlan_objmgr_pdev *pdev)
215 {
216 	return mgmt_rx_reo_sim_get_mlo_link_id_from_pdev(pdev);
217 }
218 
219 qdf_export_symbol(wlan_get_mlo_link_id_from_pdev);
220 
221 /**
222  * wlan_get_pdev_from_mlo_link_id() - Helper API to get the pdev
223  * object from the MLO HW link id.
224  * @mlo_link_id: MLO HW link id
225  * @ml_grp_id: MLO Group id which it belongs to
226  * @refdbgid: Reference debug id
227  *
228  * Return: On success returns the pdev object from the MLO HW link_id.
229  * On failure returns NULL.
230  */
231 struct wlan_objmgr_pdev *
232 wlan_get_pdev_from_mlo_link_id(uint8_t mlo_link_id, uint8_t ml_grp_id,
233 			       wlan_objmgr_ref_dbgid refdbgid)
234 {
235 	return mgmt_rx_reo_sim_get_pdev_from_mlo_link_id(
236 			mlo_link_id, ml_grp_id, refdbgid);
237 }
238 
239 qdf_export_symbol(wlan_get_pdev_from_mlo_link_id);
240 #endif /* WLAN_MGMT_RX_REO_SIM_SUPPORT */
241 
242 QDF_STATUS
243 wlan_mgmt_rx_reo_validate_mlo_link_info(struct wlan_objmgr_psoc *psoc)
244 {
245 	return mgmt_rx_reo_validate_mlo_link_info(psoc);
246 }
247 
248 QDF_STATUS
249 wlan_mgmt_rx_reo_pdev_obj_create_notification(
250 			struct wlan_objmgr_pdev *pdev,
251 			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx)
252 {
253 	return mgmt_rx_reo_pdev_obj_create_notification(pdev,
254 							mgmt_txrx_pdev_ctx);
255 }
256 
257 QDF_STATUS
258 wlan_mgmt_rx_reo_pdev_obj_destroy_notification(
259 			struct wlan_objmgr_pdev *pdev,
260 			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx)
261 {
262 	return mgmt_rx_reo_pdev_obj_destroy_notification(pdev,
263 							 mgmt_txrx_pdev_ctx);
264 }
265 
266 QDF_STATUS
267 wlan_mgmt_rx_reo_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc)
268 {
269 	return mgmt_rx_reo_psoc_obj_create_notification(psoc);
270 }
271 
272 QDF_STATUS
273 wlan_mgmt_rx_reo_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc)
274 {
275 	return mgmt_rx_reo_psoc_obj_destroy_notification(psoc);
276 }
277 
278 QDF_STATUS
279 wlan_mgmt_rx_reo_pdev_attach(struct wlan_objmgr_pdev *pdev)
280 {
281 	return mgmt_rx_reo_pdev_attach(pdev);
282 }
283 
284 qdf_export_symbol(wlan_mgmt_rx_reo_pdev_attach);
285 
286 QDF_STATUS
287 wlan_mgmt_rx_reo_psoc_attach(struct wlan_objmgr_psoc *psoc)
288 {
289 	return mgmt_rx_reo_psoc_attach(psoc);
290 }
291 
292 qdf_export_symbol(wlan_mgmt_rx_reo_psoc_attach);
293 
294 QDF_STATUS
295 wlan_mgmt_rx_reo_pdev_detach(struct wlan_objmgr_pdev *pdev)
296 {
297 	return mgmt_rx_reo_pdev_detach(pdev);
298 }
299 
300 qdf_export_symbol(wlan_mgmt_rx_reo_pdev_detach);
301 
302 QDF_STATUS
303 wlan_mgmt_rx_reo_psoc_detach(struct wlan_objmgr_psoc *psoc)
304 {
305 	return mgmt_rx_reo_psoc_detach(psoc);
306 }
307 
308 qdf_export_symbol(wlan_mgmt_rx_reo_psoc_detach);
309 
310 uint16_t
311 wlan_mgmt_rx_reo_get_pkt_ctr_delta_thresh(struct wlan_objmgr_psoc *psoc)
312 {
313 	return cfg_get(psoc, CFG_MGMT_RX_REO_PKT_CTR_DELTA_THRESH);
314 }
315 
316 #ifdef WLAN_MGMT_RX_REO_DEBUG_SUPPORT
317 uint16_t
318 wlan_mgmt_rx_reo_get_ingress_frame_debug_list_size(struct wlan_objmgr_psoc *psoc)
319 {
320 	if (!psoc) {
321 		mgmt_rx_reo_err("psoc is NULL!");
322 		return 0;
323 	}
324 
325 	return cfg_get(psoc, CFG_MGMT_RX_REO_INGRESS_FRAME_DEBUG_LIST_SIZE);
326 }
327 
328 uint16_t
329 wlan_mgmt_rx_reo_get_egress_frame_debug_list_size(struct wlan_objmgr_psoc *psoc)
330 {
331 	if (!psoc) {
332 		mgmt_rx_reo_err("psoc is NULL!");
333 		return 0;
334 	}
335 
336 	return cfg_get(psoc, CFG_MGMT_RX_REO_EGRESS_FRAME_DEBUG_LIST_SIZE);
337 }
338 
339 uint16_t
340 wlan_mgmt_rx_reo_get_scheduler_debug_list_size(struct wlan_objmgr_psoc *psoc)
341 {
342 	if (!psoc) {
343 		mgmt_rx_reo_err("psoc is NULL!");
344 		return 0;
345 	}
346 
347 	return cfg_get(psoc, CFG_MGMT_RX_REO_SCHEDULER_DEBUG_LIST_SIZE);
348 }
349 #endif /* WLAN_MGMT_RX_REO_DEBUG_SUPPORT */
350 
351 #ifndef WLAN_MGMT_RX_REO_SIM_SUPPORT
352 bool
353 wlan_mgmt_rx_reo_is_feature_enabled_at_psoc(struct wlan_objmgr_psoc *psoc)
354 {
355 	if (!psoc) {
356 		mgmt_rx_reo_err("psoc is NULL!");
357 		return false;
358 	}
359 
360 	if (!cfg_get(psoc, CFG_MGMT_RX_REO_ENABLE))
361 		return false;
362 
363 	return wlan_psoc_nif_feat_cap_get(psoc, WLAN_SOC_F_MGMT_RX_REO_CAPABLE);
364 }
365 
366 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_psoc);
367 
368 bool
369 wlan_mgmt_rx_reo_is_feature_enabled_at_pdev(struct wlan_objmgr_pdev *pdev)
370 {
371 	if (!pdev) {
372 		mgmt_rx_reo_err("pdev is NULL!");
373 		return false;
374 	}
375 
376 	return wlan_mgmt_rx_reo_is_feature_enabled_at_psoc(
377 			wlan_pdev_get_psoc(pdev));
378 }
379 
380 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_pdev);
381 
382 bool
383 wlan_mgmt_rx_reo_is_scheduler_enabled_at_psoc(struct wlan_objmgr_psoc *psoc)
384 {
385 	if (!psoc) {
386 		mgmt_rx_reo_err("psoc is NULL!");
387 		return false;
388 	}
389 
390 	return cfg_get(psoc, CFG_MGMT_RX_REO_SCHEDULER_ENABLE);
391 }
392 
393 qdf_export_symbol(wlan_mgmt_rx_reo_is_scheduler_enabled_at_psoc);
394 
395 bool
396 wlan_mgmt_rx_reo_is_scheduler_enabled_at_pdev(struct wlan_objmgr_pdev *pdev)
397 {
398 	struct wlan_objmgr_psoc *psoc;
399 
400 	if (!pdev) {
401 		mgmt_rx_reo_err("pdev is NULL!");
402 		return false;
403 	}
404 
405 	psoc = wlan_pdev_get_psoc(pdev);
406 	return wlan_mgmt_rx_reo_is_scheduler_enabled_at_psoc(psoc);
407 }
408 
409 qdf_export_symbol(wlan_mgmt_rx_reo_is_scheduler_enabled_at_pdev);
410 #else
411 bool
412 wlan_mgmt_rx_reo_is_feature_enabled_at_psoc(struct wlan_objmgr_psoc *psoc)
413 {
414 	return true;
415 }
416 
417 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_psoc);
418 
419 bool
420 wlan_mgmt_rx_reo_is_feature_enabled_at_pdev(struct wlan_objmgr_pdev *pdev)
421 {
422 	return true;
423 }
424 
425 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_pdev);
426 
427 QDF_STATUS
428 wlan_mgmt_rx_reo_sim_start(uint8_t ml_grp_id)
429 {
430 	return mgmt_rx_reo_sim_start(ml_grp_id);
431 }
432 
433 qdf_export_symbol(wlan_mgmt_rx_reo_sim_start);
434 
435 QDF_STATUS
436 wlan_mgmt_rx_reo_sim_stop(uint8_t ml_grp_id)
437 {
438 	return mgmt_rx_reo_sim_stop(ml_grp_id);
439 }
440 
441 qdf_export_symbol(wlan_mgmt_rx_reo_sim_stop);
442 #endif /* WLAN_MGMT_RX_REO_SIM_SUPPORT */
443 
444 #ifdef WLAN_MLO_MULTI_CHIP
445 bool
446 wlan_mgmt_rx_reo_is_simulation_in_progress(uint8_t ml_grp_id)
447 {
448 	return mgmt_rx_reo_is_simulation_in_progress(ml_grp_id);
449 }
450 
451 #else
452 bool
453 wlan_mgmt_rx_reo_is_simulation_in_progress(uint8_t ml_grp_id)
454 {
455 	return false;
456 }
457 #endif
458 
459 QDF_STATUS
460 wlan_mgmt_rx_reo_print_ingress_frame_stats(uint8_t ml_grp_id)
461 {
462 	return mgmt_rx_reo_print_ingress_frame_stats(ml_grp_id);
463 }
464 
465 QDF_STATUS
466 wlan_mgmt_rx_reo_print_ingress_frame_info(uint8_t ml_grp_id,
467 					  uint16_t num_frames)
468 {
469 	return mgmt_rx_reo_print_ingress_frame_info(ml_grp_id, num_frames);
470 }
471 
472 QDF_STATUS
473 wlan_mgmt_rx_reo_print_egress_frame_stats(uint8_t ml_grp_id)
474 {
475 	return mgmt_rx_reo_print_egress_frame_stats(ml_grp_id);
476 }
477 
478 QDF_STATUS
479 wlan_mgmt_rx_reo_print_egress_frame_info(uint8_t ml_grp_id, uint16_t num_frames)
480 {
481 	return mgmt_rx_reo_print_egress_frame_info(ml_grp_id, num_frames);
482 }
483 
484 QDF_STATUS
485 wlan_mgmt_rx_reo_release_frames(uint8_t mlo_grp_id, uint32_t link_bitmap)
486 {
487 	return mgmt_rx_reo_release_frames(mlo_grp_id, link_bitmap);
488 }
489