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_attach(struct wlan_objmgr_pdev *pdev)
280 {
281 	return mgmt_rx_reo_attach(pdev);
282 }
283 
284 qdf_export_symbol(wlan_mgmt_rx_reo_attach);
285 
286 QDF_STATUS
287 wlan_mgmt_rx_reo_detach(struct wlan_objmgr_pdev *pdev)
288 {
289 	return mgmt_rx_reo_detach(pdev);
290 }
291 
292 qdf_export_symbol(wlan_mgmt_rx_reo_detach);
293 
294 uint16_t
295 wlan_mgmt_rx_reo_get_pkt_ctr_delta_thresh(struct wlan_objmgr_psoc *psoc)
296 {
297 	return cfg_get(psoc, CFG_MGMT_RX_REO_PKT_CTR_DELTA_THRESH);
298 }
299 
300 uint16_t
301 wlan_mgmt_rx_reo_get_ingress_frame_debug_list_size(struct wlan_objmgr_psoc *psoc)
302 {
303 	if (!psoc) {
304 		mgmt_rx_reo_err("psoc is NULL!");
305 		return 0;
306 	}
307 
308 	return cfg_get(psoc, CFG_MGMT_RX_REO_INGRESS_FRAME_DEBUG_LIST_SIZE);
309 }
310 
311 uint16_t
312 wlan_mgmt_rx_reo_get_egress_frame_debug_list_size(struct wlan_objmgr_psoc *psoc)
313 {
314 	if (!psoc) {
315 		mgmt_rx_reo_err("psoc is NULL!");
316 		return 0;
317 	}
318 
319 	return cfg_get(psoc, CFG_MGMT_RX_REO_EGRESS_FRAME_DEBUG_LIST_SIZE);
320 }
321 
322 #ifndef WLAN_MGMT_RX_REO_SIM_SUPPORT
323 bool
324 wlan_mgmt_rx_reo_is_feature_enabled_at_psoc(struct wlan_objmgr_psoc *psoc)
325 {
326 	if (!psoc) {
327 		mgmt_rx_reo_err("psoc is NULL!");
328 		return false;
329 	}
330 
331 	if (!cfg_get(psoc, CFG_MGMT_RX_REO_ENABLE))
332 		return false;
333 
334 	return wlan_psoc_nif_feat_cap_get(psoc, WLAN_SOC_F_MGMT_RX_REO_CAPABLE);
335 }
336 
337 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_psoc);
338 
339 bool
340 wlan_mgmt_rx_reo_is_feature_enabled_at_pdev(struct wlan_objmgr_pdev *pdev)
341 {
342 	if (!pdev) {
343 		mgmt_rx_reo_err("pdev is NULL!");
344 		return false;
345 	}
346 
347 	return wlan_mgmt_rx_reo_is_feature_enabled_at_psoc(
348 			wlan_pdev_get_psoc(pdev));
349 }
350 
351 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_pdev);
352 #else
353 bool
354 wlan_mgmt_rx_reo_is_feature_enabled_at_psoc(struct wlan_objmgr_psoc *psoc)
355 {
356 	return true;
357 }
358 
359 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_psoc);
360 
361 bool
362 wlan_mgmt_rx_reo_is_feature_enabled_at_pdev(struct wlan_objmgr_pdev *pdev)
363 {
364 	return true;
365 }
366 
367 qdf_export_symbol(wlan_mgmt_rx_reo_is_feature_enabled_at_pdev);
368 
369 QDF_STATUS
370 wlan_mgmt_rx_reo_sim_start(uint8_t ml_grp_id)
371 {
372 	return mgmt_rx_reo_sim_start(ml_grp_id);
373 }
374 
375 qdf_export_symbol(wlan_mgmt_rx_reo_sim_start);
376 
377 QDF_STATUS
378 wlan_mgmt_rx_reo_sim_stop(uint8_t ml_grp_id)
379 {
380 	return mgmt_rx_reo_sim_stop(ml_grp_id);
381 }
382 
383 qdf_export_symbol(wlan_mgmt_rx_reo_sim_stop);
384 #endif /* WLAN_MGMT_RX_REO_SIM_SUPPORT */
385 
386 #ifdef WLAN_MLO_MULTI_CHIP
387 bool
388 wlan_mgmt_rx_reo_is_simulation_in_progress(uint8_t ml_grp_id)
389 {
390 	return mgmt_rx_reo_is_simulation_in_progress(ml_grp_id);
391 }
392 
393 #else
394 bool
395 wlan_mgmt_rx_reo_is_simulation_in_progress(uint8_t ml_grp_id)
396 {
397 	return false;
398 }
399 #endif
400 
401 QDF_STATUS
402 wlan_mgmt_rx_reo_print_ingress_frame_stats(uint8_t ml_grp_id)
403 {
404 	return mgmt_rx_reo_print_ingress_frame_stats(ml_grp_id);
405 }
406 
407 QDF_STATUS
408 wlan_mgmt_rx_reo_print_ingress_frame_info(uint8_t ml_grp_id,
409 					  uint16_t num_frames)
410 {
411 	return mgmt_rx_reo_print_ingress_frame_info(ml_grp_id, num_frames);
412 }
413 
414 QDF_STATUS
415 wlan_mgmt_rx_reo_print_egress_frame_stats(uint8_t ml_grp_id)
416 {
417 	return mgmt_rx_reo_print_egress_frame_stats(ml_grp_id);
418 }
419 
420 QDF_STATUS
421 wlan_mgmt_rx_reo_print_egress_frame_info(uint8_t ml_grp_id, uint16_t num_frames)
422 {
423 	return mgmt_rx_reo_print_egress_frame_info(ml_grp_id, num_frames);
424 }
425