xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_rx_reo_i.h (revision 99fa424053c36915d7f5d091d5a0ffff0b801be5)
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_i.h
20  *  This file contains mgmt rx re-ordering related APIs
21  */
22 
23 #ifndef _WLAN_MGMT_TXRX_RX_REO_I_H
24 #define _WLAN_MGMT_TXRX_RX_REO_I_H
25 
26 #ifdef WLAN_MGMT_RX_REO_SUPPORT
27 #include <qdf_list.h>
28 #include <qdf_timer.h>
29 #include <qdf_lock.h>
30 #include <qdf_nbuf.h>
31 #include <qdf_threads.h>
32 #include <qdf_defer.h>
33 #include <wlan_mgmt_txrx_rx_reo_utils_api.h>
34 #include <wlan_mgmt_txrx_rx_reo_public_structs.h>
35 #include <wlan_objmgr_pdev_obj.h>
36 #include <wlan_objmgr_psoc_obj.h>
37 #include <wlan_mlo_mgr_public_structs.h>
38 
39 #define MGMT_RX_REO_INGRESS_LIST_MAX_SIZE                  (512)
40 #define MGMT_RX_REO_INGRESS_LIST_TIMEOUT_US                (250 * USEC_PER_MSEC)
41 #define MGMT_RX_REO_INGRESS_LIST_AGEOUT_TIMER_PERIOD_MS    (50)
42 
43 #define MGMT_RX_REO_EGRESS_LIST_MAX_SIZE                   (256)
44 
45 #define INGRESS_TO_EGRESS_MOVEMENT_TEMP_LIST_MAX_SIZE \
46 				(MGMT_RX_REO_INGRESS_LIST_MAX_SIZE)
47 
48 #define MGMT_RX_REO_EGRESS_INACTIVITY_TIMEOUT    (10 * 60 * MSEC_PER_SEC)
49 
50 #define STATUS_WAIT_FOR_FRAME_ON_OTHER_LINKS         (BIT(0))
51 #define STATUS_AGED_OUT                              (BIT(1))
52 #define STATUS_OLDER_THAN_LATEST_AGED_OUT_FRAME      (BIT(2))
53 #define STATUS_INGRESS_LIST_OVERFLOW                 (BIT(3))
54 #define STATUS_OLDER_THAN_READY_TO_DELIVER_FRAMES    (BIT(4))
55 #define STATUS_EGRESS_LIST_OVERFLOW                  (BIT(5))
56 
57 #define MGMT_RX_REO_INVALID_LINK   (-1)
58 
59 /* Reason to release an entry from the reorder list */
60 #define RELEASE_REASON_ZERO_WAIT_COUNT                          (BIT(0))
61 #define RELEASE_REASON_AGED_OUT                                 (BIT(1))
62 #define RELEASE_REASON_OLDER_THAN_AGED_OUT_FRAME                (BIT(2))
63 #define RELEASE_REASON_INGRESS_LIST_OVERFLOW                    (BIT(3))
64 #define RELEASE_REASON_OLDER_THAN_READY_TO_DELIVER_FRAMES       (BIT(4))
65 #define RELEASE_REASON_EGRESS_LIST_OVERFLOW                     (BIT(5))
66 #define RELEASE_REASON_MAX  \
67 		(RELEASE_REASON_EGRESS_LIST_OVERFLOW << 1)
68 
69 #define LIST_ENTRY_IS_WAITING_FOR_FRAME_ON_OTHER_LINK(entry)   \
70 	((entry)->status & STATUS_WAIT_FOR_FRAME_ON_OTHER_LINKS)
71 #define LIST_ENTRY_IS_AGED_OUT(entry)   \
72 	((entry)->status & STATUS_AGED_OUT)
73 #define LIST_ENTRY_IS_OLDER_THAN_LATEST_AGED_OUT_FRAME(entry)  \
74 	((entry)->status & STATUS_OLDER_THAN_LATEST_AGED_OUT_FRAME)
75 #define LIST_ENTRY_IS_REMOVED_DUE_TO_INGRESS_LIST_OVERFLOW(entry)  \
76 	((entry)->status & STATUS_INGRESS_LIST_OVERFLOW)
77 #define LIST_ENTRY_IS_OLDER_THAN_READY_TO_DELIVER_FRAMES(entry)  \
78 	((entry)->status & STATUS_OLDER_THAN_READY_TO_DELIVER_FRAMES)
79 #define LIST_ENTRY_IS_REMOVED_DUE_TO_EGRESS_LIST_OVERFLOW(entry)  \
80 	((entry)->status & STATUS_EGRESS_LIST_OVERFLOW)
81 
82 #ifdef WLAN_MGMT_RX_REO_DEBUG_SUPPORT
83 #define MGMT_RX_REO_EGRESS_FRAME_DEBUG_INFO_BOARDER_MAX_SIZE   (848)
84 #define MGMT_RX_REO_EGRESS_FRAME_DELIVERY_REASON_STATS_BOARDER_A_MAX_SIZE  (66)
85 #define MGMT_RX_REO_EGRESS_FRAME_DELIVERY_REASON_STATS_BOARDER_B_MAX_SIZE  (73)
86 #define MGMT_RX_REO_EGRESS_FRAME_DEBUG_INFO_FLAG_MAX_SIZE   (3)
87 #define MGMT_RX_REO_EGRESS_FRAME_DEBUG_INFO_WAIT_COUNT_MAX_SIZE   (69)
88 #define MGMT_RX_REO_EGRESS_FRAME_DEBUG_INFO_PER_LINK_SNAPSHOTS_MAX_SIZE   (94)
89 #define MGMT_RX_REO_EGRESS_FRAME_DEBUG_INFO_SNAPSHOT_MAX_SIZE     (22)
90 #define MGMT_RX_REO_EGRESS_FRAME_DEBUG_INFO_PRINT_MAX_FRAMES     (0)
91 
92 #define MGMT_RX_REO_INGRESS_FRAME_DEBUG_INFO_BOARDER_MAX_SIZE   (807)
93 #define MGMT_RX_REO_INGRESS_FRAME_DEBUG_INFO_FLAG_MAX_SIZE   (13)
94 #define MGMT_RX_REO_INGRESS_FRAME_DEBUG_INFO_WAIT_COUNT_MAX_SIZE   (69)
95 #define MGMT_RX_REO_INGRESS_FRAME_DEBUG_INFO_PER_LINK_SNAPSHOTS_MAX_SIZE   (94)
96 #define MGMT_RX_REO_INGRESS_FRAME_DEBUG_INFO_SNAPSHOT_MAX_SIZE     (22)
97 #define MGMT_RX_REO_INGRESS_FRAME_DEBUG_INFO_PRINT_MAX_FRAMES     (0)
98 #endif /* WLAN_MGMT_RX_REO_DEBUG_SUPPORT*/
99 
100 /*
101  * struct mgmt_rx_reo_pdev_info - Pdev information required by the Management
102  * Rx REO module
103  * @host_snapshot: Latest snapshot seen at the Host.
104  * It considers both MGMT Rx and MGMT FW consumed.
105  * @last_valid_shared_snapshot: Array of last valid snapshots(for snapshots
106  * shared between host and target)
107  * @host_target_shared_snapshot_info: Array of meta information related to
108  * snapshots(for snapshots shared between host and target)
109  * @filter: MGMT Rx REO filter
110  * @init_complete: Flag to indicate initialization completion of the
111  * mgmt_rx_reo_pdev_info object
112  */
113 struct mgmt_rx_reo_pdev_info {
114 	struct mgmt_rx_reo_snapshot_params host_snapshot;
115 	struct mgmt_rx_reo_snapshot_params last_valid_shared_snapshot
116 				[MGMT_RX_REO_SHARED_SNAPSHOT_MAX];
117 	struct mgmt_rx_reo_snapshot_info host_target_shared_snapshot_info
118 				[MGMT_RX_REO_SHARED_SNAPSHOT_MAX];
119 	struct mgmt_rx_reo_filter filter;
120 	struct mgmt_rx_reo_shared_snapshot raw_snapshots[MAX_MLO_LINKS]
121 			[MGMT_RX_REO_SHARED_SNAPSHOT_MAX]
122 			[MGMT_RX_REO_SNAPSHOT_READ_RETRY_LIMIT]
123 			[MGMT_RX_REO_SNAPSHOT_B2B_READ_SWAR_RETRY_LIMIT];
124 	bool init_complete;
125 };
126 
127 /**
128  * mgmt_rx_reo_pdev_attach() - Initializes the per pdev data structures related
129  * to management rx-reorder module
130  * @pdev: pointer to pdev object
131  *
132  * Return: QDF_STATUS
133  */
134 QDF_STATUS mgmt_rx_reo_pdev_attach(struct wlan_objmgr_pdev *pdev);
135 
136 /**
137  * mgmt_rx_reo_psoc_attach() - Initializes the per psoc data structures related
138  * to management rx-reorder module
139  * @psoc: pointer to psoc object
140  *
141  * Return: QDF_STATUS
142  */
143 QDF_STATUS mgmt_rx_reo_psoc_attach(struct wlan_objmgr_psoc *psoc);
144 
145 /**
146  * mgmt_rx_reo_pdev_detach() - Clears the per pdev data structures related to
147  * management rx-reorder module
148  * @pdev: pointer to pdev object
149  *
150  * Return: QDF_STATUS
151  */
152 QDF_STATUS mgmt_rx_reo_pdev_detach(struct wlan_objmgr_pdev *pdev);
153 
154 /**
155  * mgmt_rx_reo_psoc_detach() - Clears the per psoc data structures related to
156  * management rx-reorder module
157  * @psoc: pointer to psoc object
158  *
159  * Return: QDF_STATUS
160  */
161 QDF_STATUS mgmt_rx_reo_psoc_detach(struct wlan_objmgr_psoc *psoc);
162 
163 /**
164  * mgmt_rx_reo_pdev_obj_create_notification() - pdev create handler for
165  * management rx-reorder module
166  * @pdev: pointer to pdev object
167  * @mgmt_txrx_pdev_ctx: pdev private object of mgmt txrx module
168  *
169  * This function gets called from object manager when pdev is being created and
170  * creates management rx-reorder pdev context
171  *
172  * Return: QDF_STATUS
173  */
174 QDF_STATUS
175 mgmt_rx_reo_pdev_obj_create_notification(
176 	struct wlan_objmgr_pdev *pdev,
177 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx);
178 
179 /**
180  * mgmt_rx_reo_pdev_obj_destroy_notification() - pdev destroy handler for
181  * management rx-reorder feature
182  * @pdev: pointer to pdev object
183  * @mgmt_txrx_pdev_ctx: pdev private object of mgmt txrx module
184  *
185  * This function gets called from object manager when pdev is being destroyed
186  * and destroys management rx-reorder pdev context
187  *
188  * Return: QDF_STATUS
189  */
190 QDF_STATUS
191 mgmt_rx_reo_pdev_obj_destroy_notification(
192 	struct wlan_objmgr_pdev *pdev,
193 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx);
194 
195 /**
196  * mgmt_rx_reo_psoc_obj_create_notification() - psoc create handler for
197  * management rx-reorder module
198  * @psoc: pointer to psoc object
199  *
200  * This function gets called from object manager when psoc is being created.
201  *
202  * Return: QDF_STATUS
203  */
204 QDF_STATUS
205 mgmt_rx_reo_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc);
206 
207 /**
208  * mgmt_rx_reo_psoc_obj_destroy_notification() - psoc destroy handler for
209  * management rx-reorder feature
210  * @psoc: pointer to psoc object
211  *
212  * This function gets called from object manager when psoc is being destroyed.
213  *
214  * Return: QDF_STATUS
215  */
216 QDF_STATUS
217 mgmt_rx_reo_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc);
218 
219 /**
220  * enum mgmt_rx_reo_frame_descriptor_type - Enumeration for management frame
221  * descriptor type.
222  * @MGMT_RX_REO_FRAME_DESC_HOST_CONSUMED_FRAME: Management frame to be consumed
223  * by host.
224  * @MGMT_RX_REO_FRAME_DESC_FW_CONSUMED_FRAME: Management frame consumed by FW
225  * @MGMT_RX_REO_FRAME_DESC_ERROR_FRAME: Management frame which got dropped
226  * at host due to any error
227  * @MGMT_RX_REO_FRAME_DESC_TYPE_MAX: Maximum number of frame types
228  */
229 enum mgmt_rx_reo_frame_descriptor_type {
230 	MGMT_RX_REO_FRAME_DESC_HOST_CONSUMED_FRAME = 0,
231 	MGMT_RX_REO_FRAME_DESC_FW_CONSUMED_FRAME,
232 	MGMT_RX_REO_FRAME_DESC_ERROR_FRAME,
233 	MGMT_RX_REO_FRAME_DESC_TYPE_MAX,
234 };
235 
236 /**
237  * enum mgmt_rx_reo_list_type - Enumeration for management rx reorder list type
238  * @MGMT_RX_REO_LIST_TYPE_INGRESS: Ingress list type
239  * @MGMT_RX_REO_LIST_TYPE_EGRESS: Egress list type
240  * @MGMT_RX_REO_LIST_TYPE_MAX: Maximum number of list types
241  * @MGMT_RX_REO_LIST_TYPE_INVALID: Invalid list type
242  */
243 enum mgmt_rx_reo_list_type {
244 	MGMT_RX_REO_LIST_TYPE_INGRESS = 0,
245 	MGMT_RX_REO_LIST_TYPE_EGRESS,
246 	MGMT_RX_REO_LIST_TYPE_MAX,
247 	MGMT_RX_REO_LIST_TYPE_INVALID,
248 };
249 
250 /**
251  * enum mgmt_rx_reo_ingress_drop_reason - Enumeration for management rx reorder
252  * reason code for dropping an incoming management frame
253  * @MGMT_RX_REO_INGRESS_DROP_REASON_INVALID: Invalid ingress drop reason code
254  * @MGMT_RX_REO_INVALID_REO_PARAMS: Invalid reo parameters
255  * @MGMT_RX_REO_OUT_OF_ORDER_PKT_CTR: Packet counter of the current frame is
256  * less than the packet counter of the last frame in the same link
257  * @MGMT_RX_REO_DUPLICATE_PKT_CTR: Packet counter of the current frame is same
258  * as the packet counter of the last frame
259  * @MGMT_RX_REO_ZERO_DURATION: Zero duration for a management frame which is
260  * supposed to be consumed by host
261  * @MGMT_RX_REO_SNAPSHOT_SANITY_FAILURE: Snapshot sanity failure in any of the
262  * links
263  * @MGMT_RX_REO_INGRESS_DROP_REASON_MAX: Maximum value of ingress drop reason
264  * code
265  */
266 enum mgmt_rx_reo_ingress_drop_reason {
267 	MGMT_RX_REO_INGRESS_DROP_REASON_INVALID = 0,
268 	MGMT_RX_REO_INVALID_REO_PARAMS,
269 	MGMT_RX_REO_OUT_OF_ORDER_PKT_CTR,
270 	MGMT_RX_REO_DUPLICATE_PKT_CTR,
271 	MGMT_RX_REO_ZERO_DURATION,
272 	MGMT_RX_REO_SNAPSHOT_SANITY_FAILURE,
273 	MGMT_RX_REO_INGRESS_DROP_REASON_MAX,
274 };
275 
276 /**
277  * enum mgmt_rx_reo_execution_context - Execution contexts related to management
278  * Rx reorder
279  * @MGMT_RX_REO_CONTEXT_MGMT_RX: Incoming mgmt Rx context
280  * @MGMT_RX_REO_CONTEXT_INGRESS_LIST_TIMEOUT: Ingress list time out context
281  * @MGMT_RX_REO_CONTEXT_SCHEDULER_CB: Schgeduler call back context
282  * @MGMT_RX_REO_CONTEXT_MAX: Maximum number of execution contexts
283  * @MGMT_RX_REO_CONTEXT_INVALID: Invalid execution context
284  */
285 enum mgmt_rx_reo_execution_context {
286 	MGMT_RX_REO_CONTEXT_MGMT_RX,
287 	MGMT_RX_REO_CONTEXT_INGRESS_LIST_TIMEOUT,
288 	MGMT_RX_REO_CONTEXT_SCHEDULER_CB,
289 	MGMT_RX_REO_CONTEXT_MAX,
290 	MGMT_RX_REO_CONTEXT_INVALID,
291 };
292 
293 /**
294  * struct mgmt_rx_reo_context_info - This structure holds the information
295  * about the current execution context
296  * @context: Current execution context
297  * @in_reo_params: Reo parameters of the current management frame
298  * @context_id: Context identifier
299  */
300 struct mgmt_rx_reo_context_info {
301 	enum mgmt_rx_reo_execution_context context;
302 	struct mgmt_rx_reo_params in_reo_params;
303 	int32_t context_id;
304 };
305 
306 /**
307  * struct mgmt_rx_reo_frame_info - This structure holds the information
308  * about a management frame.
309  * @valid: Indicates whether the structure content is valid
310  * @reo_params: Management Rx reorder parameters
311  */
312 struct mgmt_rx_reo_frame_info {
313 	bool valid;
314 	struct mgmt_rx_reo_params reo_params;
315 };
316 
317 /**
318  * struct mgmt_rx_reo_list - Linked list used to reorder/deliver the management
319  * frames received. Each list entry would correspond to a management frame. List
320  * entries would be sorted in the same order in which they are received by
321  * MAC HW.
322  * @list: Linked list
323  * @list_lock: Spin lock to protect the list
324  * @max_list_size: Maximum size of the reorder list
325  * @overflow_count: Number of times list overflow occurred
326  * @last_overflow_ts: Host time stamp of last overflow
327  * @last_inserted_frame: Information about the last frame inserted to the list
328  * @last_released_frame: Information about the last frame released from the list
329  */
330 struct mgmt_rx_reo_list {
331 	qdf_list_t list;
332 	qdf_spinlock_t list_lock;
333 	uint32_t max_list_size;
334 	uint64_t overflow_count;
335 	uint64_t last_overflow_ts;
336 	struct mgmt_rx_reo_frame_info last_inserted_frame;
337 	struct mgmt_rx_reo_frame_info last_released_frame;
338 };
339 
340 /**
341  * struct mgmt_rx_reo_ingress_list - Linked list used to reorder the management
342  * frames received
343  * @reo_list: Linked list used for reordering
344  * @list_entry_timeout_us: Time out value(microsecond) for the list entries
345  * @ageout_timer: Periodic timer to age-out the list entries
346  */
347 struct mgmt_rx_reo_ingress_list {
348 	struct mgmt_rx_reo_list reo_list;
349 	uint32_t list_entry_timeout_us;
350 	qdf_timer_t ageout_timer;
351 };
352 
353 /**
354  * struct mgmt_rx_reo_egress_list - Linked list used to store the frames which
355  * are reordered and pending delivery
356  * @reo_list: Linked list used for storing the frames which are reordered and
357  * pending delivery
358  * @egress_inactivity_timer: Management Rx inactivity timer
359  */
360 struct mgmt_rx_reo_egress_list {
361 	struct mgmt_rx_reo_list reo_list;
362 	qdf_timer_t egress_inactivity_timer;
363 };
364 
365 /*
366  * struct mgmt_rx_reo_wait_count - Wait count for a mgmt frame
367  * @per_link_count: Array of wait counts for all MLO links. Each array entry
368  * holds the number of frames this mgmt frame should wait for on that
369  * particular link.
370  * @total_count: Sum of entries in @per_link_count
371  */
372 struct mgmt_rx_reo_wait_count {
373 	unsigned int per_link_count[MAX_MLO_LINKS];
374 	unsigned long long int total_count;
375 };
376 
377 /**
378  * struct mgmt_rx_reo_list_entry - Entry in the Management reorder list
379  * @node: List node
380  * @nbuf: nbuf corresponding to this frame
381  * @rx_params: Management rx event parameters
382  * @wait_count: Wait counts for the frame
383  * @initial_wait_count: Wait count when the frame is queued
384  * @ingress_timestamp: Host time stamp when this frame has arrived reorder
385  * module
386  * @ingress_list_insertion_ts: Host time stamp when this entry is inserted to
387  * the ingress list.
388  * @ingress_list_removal_ts: Host time stamp when this entry is removed from
389  * the ingress list
390  * @egress_list_insertion_ts: Host time stamp when this entry is inserted to
391  * the egress list.
392  * @egress_list_removal_ts: Host time stamp when this entry is removed from
393  * the egress list
394  * @first_scheduled_ts: Host time stamp when this entry is first scheduled
395  * by scheduler
396  * @last_scheduled_ts: Host time stamp when this entry is last scheduled
397  * by scheduler
398  * @egress_timestamp: Host time stamp when this frame has exited reorder
399  * module
400  * @egress_list_size: Egress list size just before removing this frame
401  * @status: Status for this entry
402  * @pdev: Pointer to pdev object corresponding to this frame
403  * @release_reason: Release reason
404  * @is_delivered: Indicates whether the frame is delivered successfully
405  * @is_dropped: Indciates whether the frame is dropped in reo layer
406  * @is_premature_delivery: Indicates whether the frame is delivered
407  * prematurely
408  * @is_parallel_rx: Indicates that this frame is received in parallel to the
409  * last frame which is delivered to the upper layer.
410  * @shared_snapshots: snapshots shared b/w host and target
411  * @host_snapshot: host snapshot
412  * @scheduled_count: Number of times scheduler is invoked for this frame
413  * @ctx_info: Execution context info
414  */
415 struct mgmt_rx_reo_list_entry {
416 	qdf_list_node_t node;
417 	qdf_nbuf_t nbuf;
418 	struct mgmt_rx_event_params *rx_params;
419 	struct mgmt_rx_reo_wait_count wait_count;
420 	struct mgmt_rx_reo_wait_count initial_wait_count;
421 	uint64_t ingress_timestamp;
422 	uint64_t ingress_list_insertion_ts;
423 	uint64_t ingress_list_removal_ts;
424 	uint64_t egress_list_insertion_ts;
425 	uint64_t egress_list_removal_ts;
426 	uint64_t first_scheduled_ts;
427 	uint64_t last_scheduled_ts;
428 	uint64_t egress_timestamp;
429 	uint64_t egress_list_size;
430 	uint32_t status;
431 	struct wlan_objmgr_pdev *pdev;
432 	uint8_t release_reason;
433 	bool is_delivered;
434 	bool is_dropped;
435 	bool is_premature_delivery;
436 	bool is_parallel_rx;
437 	struct mgmt_rx_reo_snapshot_params shared_snapshots
438 			[MAX_MLO_LINKS][MGMT_RX_REO_SHARED_SNAPSHOT_MAX];
439 	struct mgmt_rx_reo_snapshot_params host_snapshot[MAX_MLO_LINKS];
440 	qdf_atomic_t scheduled_count;
441 	struct mgmt_rx_reo_context_info ctx_info;
442 };
443 
444 #ifdef WLAN_MGMT_RX_REO_SIM_SUPPORT
445 
446 #define MGMT_RX_REO_SIM_INTER_FRAME_DELAY_MIN             (300 * USEC_PER_MSEC)
447 #define MGMT_RX_REO_SIM_INTER_FRAME_DELAY_MIN_MAX_DELTA   (200 * USEC_PER_MSEC)
448 
449 #define MGMT_RX_REO_SIM_DELAY_MAC_HW_TO_FW_MIN            (1000 * USEC_PER_MSEC)
450 #define MGMT_RX_REO_SIM_DELAY_MAC_HW_TO_FW_MIN_MAX_DELTA  (500 * USEC_PER_MSEC)
451 
452 #define MGMT_RX_REO_SIM_DELAY_FW_TO_HOST_MIN              (1000 * USEC_PER_MSEC)
453 #define MGMT_RX_REO_SIM_DELAY_FW_TO_HOST_MIN_MAX_DELTA    (500 * USEC_PER_MSEC)
454 
455 #define MGMT_RX_REO_SIM_PERCENTAGE_FW_CONSUMED_FRAMES  (10)
456 #define MGMT_RX_REO_SIM_PERCENTAGE_ERROR_FRAMES        (10)
457 
458 #define MGMT_RX_REO_SIM_PENDING_FRAME_LIST_MAX_SIZE    (1000)
459 #define MGMT_RX_REO_SIM_STALE_FRAME_LIST_MAX_SIZE      \
460 				(MGMT_RX_REO_SIM_PENDING_FRAME_LIST_MAX_SIZE)
461 #define MGMT_RX_REO_SIM_STALE_FRAME_TEMP_LIST_MAX_SIZE (100)
462 
463 /**
464  * struct mgmt_rx_frame_params - Parameters associated with a management frame.
465  * This structure is used by the simulation framework.
466  * @link_id: MLO HW link id
467  * @mgmt_pkt_ctr: Management packet counter
468  * @global_timestamp: Global time stamp in micro seconds
469  */
470 struct mgmt_rx_frame_params {
471 	uint8_t link_id;
472 	uint16_t mgmt_pkt_ctr;
473 	uint32_t global_timestamp;
474 };
475 
476 /**
477  * struct mgmt_rx_reo_master_frame_list - List which contains all the
478  * management frames received and not yet consumed by FW/Host. Order of frames
479  * in the list is same as the order in which they are received in the air.
480  * This is used by the simulation framework to confirm that the outcome of
481  * reordering is correct.
482  * @pending_list: List which contains all the frames received after the
483  * last frame delivered to upper layer. These frames will eventually reach host.
484  * @stale_list: List which contains all the stale management frames which
485  * are not yet consumed by FW/Host. Stale management frames are the frames which
486  * are older than last delivered frame to upper layer.
487  * @lock: Spin lock to protect pending frame list and stale frame list.
488  */
489 struct mgmt_rx_reo_master_frame_list {
490 	qdf_list_t pending_list;
491 	qdf_list_t stale_list;
492 	qdf_spinlock_t lock;
493 };
494 
495 /**
496  * struct mgmt_rx_reo_pending_frame_list_entry - Structure used to represent an
497  * entry in the pending frame list.
498  * @params: parameters related to the management frame
499  * @node: linked list node
500  */
501 struct mgmt_rx_reo_pending_frame_list_entry {
502 	struct mgmt_rx_frame_params params;
503 	qdf_list_node_t node;
504 };
505 
506 /**
507  * struct mgmt_rx_reo_stale_frame_list_entry - Structure used to represent an
508  * entry in the stale frame list.
509  * @params: parameters related to the management frame
510  * @node: linked list node
511  */
512 struct mgmt_rx_reo_stale_frame_list_entry {
513 	struct mgmt_rx_frame_params params;
514 	qdf_list_node_t node;
515 };
516 
517 /**
518  * struct mgmt_rx_frame_mac_hw - Structure used to represent the management
519  * frame at MAC HW level
520  * @params: parameters related to the management frame
521  * @frame_handler_fw: Work structure to queue the frame to the FW
522  * @sim_context: pointer management rx-reorder simulation context
523  */
524 struct mgmt_rx_frame_mac_hw {
525 	struct mgmt_rx_frame_params params;
526 	qdf_work_t frame_handler_fw;
527 	struct mgmt_rx_reo_sim_context *sim_context;
528 };
529 
530 /**
531  * struct mgmt_rx_frame_fw - Structure used to represent the management
532  * frame at FW level
533  * @params: parameters related to the management frame
534  * @is_consumed_by_fw: indicates whether the frame is consumed by FW
535  * @frame_handler_host: Work structure to queue the frame to the host
536  * @sim_context: pointer management rx-reorder simulation context
537  */
538 struct mgmt_rx_frame_fw {
539 	struct mgmt_rx_frame_params params;
540 	bool is_consumed_by_fw;
541 	qdf_work_t frame_handler_host;
542 	struct mgmt_rx_reo_sim_context *sim_context;
543 };
544 
545 /**
546  * struct mgmt_rx_reo_sim_mac_hw - Structure used to represent the MAC HW
547  * @mgmt_pkt_ctr: Stores the last management packet counter for all the links
548  */
549 struct mgmt_rx_reo_sim_mac_hw {
550 	uint16_t mgmt_pkt_ctr[MAX_MLO_LINKS];
551 };
552 
553 /**
554  * struct mgmt_rx_reo_sim_link_id_to_pdev_map - Map from link id to pdev
555  * object. This is used for simulation purpose only.
556  * @map: link id to pdev map. Link id is the array index.
557  * @lock: lock used to protect this structure
558  * @num_mlo_links: Total number of MLO HW links. In case of simulation all the
559  * pdevs are assumed to have MLO capability and number of MLO links is same as
560  * the number of pdevs in the system.
561  * @valid_link_list: List of valid link id values
562  */
563 struct mgmt_rx_reo_sim_link_id_to_pdev_map {
564 	struct wlan_objmgr_pdev *map[MAX_MLO_LINKS];
565 	qdf_spinlock_t lock;
566 	uint8_t num_mlo_links;
567 	int8_t valid_link_list[MAX_MLO_LINKS];
568 };
569 
570 /**
571  * struct mgmt_rx_reo_mac_hw_simulator - Structure which stores the members
572  * required for the MAC HW simulation
573  * @mac_hw_info: MAC HW info
574  * @mac_hw_thread: kthread which simulates MAC HW
575  */
576 struct mgmt_rx_reo_mac_hw_simulator {
577 	struct mgmt_rx_reo_sim_mac_hw mac_hw_info;
578 	qdf_thread_t *mac_hw_thread;
579 };
580 
581 /**
582  * struct mgmt_rx_reo_sim_context - Management rx-reorder simulation context
583  * @host_mgmt_frame_handler: Per link work queue to simulate the host layer
584  * @fw_mgmt_frame_handler: Per link work queue to simulate the FW layer
585  * @master_frame_list: List used to store information about all the management
586  * frames
587  * @mac_hw_sim:  MAC HW simulation object
588  * @snapshot: snapshots required for reo algorithm
589  * @link_id_to_pdev_map: link_id to pdev object map
590  * @mlo_grp_id: MLO group id which it belongs to
591  */
592 struct mgmt_rx_reo_sim_context {
593 	struct workqueue_struct *host_mgmt_frame_handler[MAX_MLO_LINKS];
594 	struct workqueue_struct *fw_mgmt_frame_handler[MAX_MLO_LINKS];
595 	struct mgmt_rx_reo_master_frame_list master_frame_list;
596 	struct mgmt_rx_reo_mac_hw_simulator mac_hw_sim;
597 	struct mgmt_rx_reo_shared_snapshot snapshot[MAX_MLO_LINKS]
598 					    [MGMT_RX_REO_SHARED_SNAPSHOT_MAX];
599 	struct mgmt_rx_reo_sim_link_id_to_pdev_map link_id_to_pdev_map;
600 	uint8_t mlo_grp_id;
601 };
602 #endif /* WLAN_MGMT_RX_REO_SIM_SUPPORT */
603 
604 #ifdef WLAN_MGMT_RX_REO_DEBUG_SUPPORT
605 /**
606  * struct reo_ingress_debug_frame_info - Debug information about a frame
607  * entering reorder algorithm
608  * @link_id: link id
609  * @mgmt_pkt_ctr: management packet counter
610  * @global_timestamp: MLO global time stamp
611  * @start_timestamp: start time stamp of the frame
612  * @end_timestamp: end time stamp of the frame
613  * @duration_us: duration of the frame in us
614  * @desc_type: Type of the frame descriptor
615  * @frame_type: frame type
616  * @frame_subtype: frame sub type
617  * @ingress_timestamp: Host time stamp when the frames enters the reorder
618  * algorithm
619  * @ingress_duration: Duration in us for processing the incoming frame.
620  * ingress_duration = Time stamp at which reorder list update is done -
621  * Time stamp at which frame has entered the reorder module
622  * @wait_count: Wait count calculated for the current frame
623  * @is_queued: Indicates whether this frame is queued to reorder list
624  * @is_stale: Indicates whether this frame is stale.
625  * @is_parallel_rx: Indicates that this frame is received in parallel to the
626  * last frame which is delivered to the upper layer.
627  * @zero_wait_count_rx: Indicates whether this frame's wait count was
628  * zero when received by host
629  * @immediate_delivery: Indicates whether this frame can be delivered
630  * immediately to the upper layers
631  * @queued_list: Type of list in which the current frame is queued
632  * @is_error: Indicates whether any error occurred during processing this frame
633  * @last_delivered_frame: Stores the information about the last frame delivered
634  * to the upper layer
635  * @ingress_list_size_rx: Size of the ingress list when this frame is
636  * received (before updating the ingress list based on this frame).
637  * @ingress_list_insertion_pos: Position in the ingress list where this
638  * frame is going to get inserted (Applicable for only host consumed frames)
639  * @egress_list_size_rx: Size of the egress list when this frame is
640  * added to the egress list
641  * @egress_list_insertion_pos: Position in the egress list where this
642  * frame is going to get inserted
643  * @shared_snapshots: snapshots shared b/w host and target
644  * @host_snapshot: host snapshot
645  * @cpu_id: CPU index
646  * @reo_required: Indicates whether reorder is required for the current frame.
647  * If reorder is not required, current frame will just be used for updating the
648  * wait count of frames already part of the reorder list.
649  * @context_id: Context identifier
650  * @drop_reason: Reason for dropping the frame
651  * @drop: Indicates whether the frame has to be dropped
652  */
653 struct reo_ingress_debug_frame_info {
654 	uint8_t link_id;
655 	uint16_t mgmt_pkt_ctr;
656 	uint32_t global_timestamp;
657 	uint32_t start_timestamp;
658 	uint32_t end_timestamp;
659 	uint32_t duration_us;
660 	enum mgmt_rx_reo_frame_descriptor_type desc_type;
661 	uint8_t frame_type;
662 	uint8_t frame_subtype;
663 	uint64_t ingress_timestamp;
664 	uint64_t ingress_duration;
665 	struct mgmt_rx_reo_wait_count wait_count;
666 	bool is_queued;
667 	bool is_stale;
668 	bool is_parallel_rx;
669 	bool zero_wait_count_rx;
670 	bool immediate_delivery;
671 	enum mgmt_rx_reo_list_type queued_list;
672 	bool is_error;
673 	struct mgmt_rx_reo_frame_info last_delivered_frame;
674 	int16_t ingress_list_size_rx;
675 	int16_t ingress_list_insertion_pos;
676 	int16_t egress_list_size_rx;
677 	int16_t egress_list_insertion_pos;
678 	struct mgmt_rx_reo_snapshot_params shared_snapshots
679 			[MAX_MLO_LINKS][MGMT_RX_REO_SHARED_SNAPSHOT_MAX];
680 	struct mgmt_rx_reo_snapshot_params host_snapshot[MAX_MLO_LINKS];
681 	int cpu_id;
682 	bool reo_required;
683 	int32_t context_id;
684 	enum mgmt_rx_reo_ingress_drop_reason drop_reason;
685 	bool drop;
686 };
687 
688 /**
689  * struct reo_egress_debug_frame_info - Debug information about a frame
690  * leaving the reorder module
691  * @is_delivered: Indicates whether the frame is delivered to upper layers
692  * @is_dropped: Indciates whether the frame is dropped in reo layer
693  * @is_premature_delivery: Indicates whether the frame is delivered
694  * prematurely
695  * @link_id: link id
696  * @mgmt_pkt_ctr: management packet counter
697  * @global_timestamp: MLO global time stamp
698  * @ingress_timestamp: Host time stamp when the frame enters the reorder module
699  * @ingress_list_insertion_ts: Host time stamp when this entry is inserted to
700  * the ingress list.
701  * @ingress_list_removal_ts: Host time stamp when this entry is removed from
702  * the ingress list
703  * @egress_list_insertion_ts: Host time stamp when this entry is inserted to
704  * the egress list.
705  * @egress_list_removal_ts: Host time stamp when this entry is removed from
706  * the egress list
707  * @egress_timestamp: Host time stamp just before delivery of the frame to upper
708  * layer
709  * @egress_duration: Duration in us taken by the upper layer to process
710  * the frame.
711  * @egress_list_size: Egress list size just before removing this frame
712  * @first_scheduled_ts: Host time stamp when this entry is first scheduled for
713  * delivery
714  * @last_scheduled_ts: Host time stamp when this entry is last scheduled for
715  * delivery
716  * @scheduled_count: Number of times this entry is scheduled
717  * @initial_wait_count: Wait count when the frame is queued
718  * @final_wait_count: Wait count when frame is released to upper layer
719  * @release_reason: Reason for delivering the frame to upper layers
720  * @shared_snapshots: snapshots shared b/w host and target
721  * @host_snapshot: host snapshot
722  * @cpu_id: CPU index
723  * @ctx_info: Execution context info
724  */
725 struct reo_egress_debug_frame_info {
726 	bool is_delivered;
727 	bool is_dropped;
728 	bool is_premature_delivery;
729 	uint8_t link_id;
730 	uint16_t mgmt_pkt_ctr;
731 	uint32_t global_timestamp;
732 	uint64_t ingress_timestamp;
733 	uint64_t ingress_list_insertion_ts;
734 	uint64_t ingress_list_removal_ts;
735 	uint64_t egress_list_insertion_ts;
736 	uint64_t egress_list_removal_ts;
737 	uint64_t egress_timestamp;
738 	uint64_t egress_duration;
739 	uint64_t egress_list_size;
740 	uint64_t first_scheduled_ts;
741 	uint64_t last_scheduled_ts;
742 	int32_t scheduled_count;
743 	struct mgmt_rx_reo_wait_count initial_wait_count;
744 	struct mgmt_rx_reo_wait_count final_wait_count;
745 	uint8_t release_reason;
746 	struct mgmt_rx_reo_snapshot_params shared_snapshots
747 			[MAX_MLO_LINKS][MGMT_RX_REO_SHARED_SNAPSHOT_MAX];
748 	struct mgmt_rx_reo_snapshot_params host_snapshot[MAX_MLO_LINKS];
749 	int cpu_id;
750 	struct mgmt_rx_reo_context_info ctx_info;
751 };
752 
753 /**
754  * struct reo_ingress_frame_stats - Structure to store statistics related to
755  * incoming frames
756  * @ingress_count: Number of frames entering reo module
757  * @reo_count: Number of frames for which reorder is required
758  * @queued_count: Number of frames queued to reorder list
759  * @zero_wait_count_rx_count: Number of frames for which wait count is
760  * zero when received at host
761  * @immediate_delivery_count: Number of frames which can be delivered
762  * immediately to the upper layers without reordering. A frame can be
763  * immediately delivered if it has wait count of zero on reception at host
764  * and the global time stamp is less than or equal to the global time
765  * stamp of all the frames in the reorder list. Such frames would get
766  * inserted to the head of the reorder list and gets delivered immediately
767  * to the upper layers.
768  * @stale_count: Number of stale frames. Any frame older than the
769  * last frame delivered to upper layer is a stale frame.
770  * @error_count: Number of frames dropped due to error occurred
771  * within the reorder module
772  * @parallel_rx_count: Number of frames which are categorised as parallel rx
773  * @missing_count: Number of frames missing. This is calculated based on the
774  * packet counter holes.
775  * @drop_count: Number of frames dropped by host.
776  */
777 struct reo_ingress_frame_stats {
778 	uint64_t ingress_count
779 		[MAX_MLO_LINKS][MGMT_RX_REO_FRAME_DESC_TYPE_MAX];
780 	uint64_t reo_count
781 		[MAX_MLO_LINKS][MGMT_RX_REO_FRAME_DESC_TYPE_MAX];
782 	uint64_t queued_count[MAX_MLO_LINKS][MGMT_RX_REO_LIST_TYPE_MAX];
783 	uint64_t zero_wait_count_rx_count
784 		[MAX_MLO_LINKS][MGMT_RX_REO_LIST_TYPE_MAX];
785 	uint64_t immediate_delivery_count
786 		[MAX_MLO_LINKS][MGMT_RX_REO_LIST_TYPE_MAX];
787 	uint64_t stale_count[MAX_MLO_LINKS]
788 			    [MGMT_RX_REO_FRAME_DESC_TYPE_MAX];
789 	uint64_t error_count[MAX_MLO_LINKS]
790 			    [MGMT_RX_REO_FRAME_DESC_TYPE_MAX];
791 	uint64_t parallel_rx_count[MAX_MLO_LINKS]
792 			    [MGMT_RX_REO_FRAME_DESC_TYPE_MAX];
793 	uint64_t missing_count[MAX_MLO_LINKS];
794 	uint64_t drop_count[MAX_MLO_LINKS][MGMT_RX_REO_INGRESS_DROP_REASON_MAX];
795 };
796 
797 /**
798  * struct reo_egress_frame_stats - Structure to store statistics related to
799  * outgoing frames
800  * @delivery_attempts_count: Number of attempts to deliver management
801  * frames to upper layers
802  * @delivery_success_count: Number of successful management frame
803  * deliveries to upper layer
804  * @drop_count: Number of management frames dropped within reo layer
805  * @premature_delivery_count:  Number of frames delivered
806  * prematurely. Premature delivery is the delivery of a management frame
807  * to the upper layers even before its wait count is reaching zero.
808  * @delivery_reason_count: Number frames delivered successfully for
809  * each link and release reason.
810  * @delivery_context_count: Number frames delivered successfully for
811  * each link and execution context.
812  */
813 struct reo_egress_frame_stats {
814 	uint64_t delivery_attempts_count[MAX_MLO_LINKS];
815 	uint64_t delivery_success_count[MAX_MLO_LINKS];
816 	uint64_t drop_count[MAX_MLO_LINKS];
817 	uint64_t premature_delivery_count[MAX_MLO_LINKS];
818 	uint64_t delivery_reason_count[MAX_MLO_LINKS][RELEASE_REASON_MAX];
819 	uint64_t delivery_context_count[MAX_MLO_LINKS][MGMT_RX_REO_CONTEXT_MAX];
820 };
821 
822 /**
823  * struct reo_ingress_debug_info - Circular array to store the
824  * debug information about the frames entering the reorder algorithm.
825  * @frame_list: Circular array to store the debug info about frames
826  * @frame_list_size: Size of circular array @frame_list
827  * @next_index: The index at which information about next frame will be logged
828  * @wrap_aroud: Flag to indicate whether wrap around occurred when logging
829  * debug information to @frame_list
830  * @stats: Stats related to incoming frames
831  * @boarder: boarder string
832  */
833 struct reo_ingress_debug_info {
834 	struct reo_ingress_debug_frame_info *frame_list;
835 	uint16_t frame_list_size;
836 	int next_index;
837 	bool wrap_aroud;
838 	struct reo_ingress_frame_stats stats;
839 	char boarder[MGMT_RX_REO_INGRESS_FRAME_DEBUG_INFO_BOARDER_MAX_SIZE + 1];
840 };
841 
842 /**
843  * struct reo_egress_debug_info - Circular array to store the
844  * debug information about the frames leaving the reorder module.
845  * @frame_list: Circular array to store the debug info
846  * @frame_list_size: Size of circular array @frame_list
847  * @next_index: The index at which information about next frame will be logged
848  * @wrap_aroud: Flag to indicate whether wrap around occurred when logging
849  * debug information to @frame_list
850  * @stats: Stats related to outgoing frames
851  * @boarder: boarder string
852  */
853 struct reo_egress_debug_info {
854 	struct reo_egress_debug_frame_info *frame_list;
855 	uint16_t frame_list_size;
856 	int next_index;
857 	bool wrap_aroud;
858 	struct reo_egress_frame_stats stats;
859 	char boarder[MGMT_RX_REO_EGRESS_FRAME_DEBUG_INFO_BOARDER_MAX_SIZE + 1];
860 };
861 
862 /**
863  * struct reo_scheduler_debug_frame_info - Debug information about a frame
864  * gettign scheduled by management Rx reo scheduler
865  * @link_id: link id
866  * @mgmt_pkt_ctr: management packet counter
867  * @global_timestamp: MLO global time stamp
868  * @ingress_timestamp: Host time stamp when the frame enters the reorder module
869  * @ingress_list_insertion_ts: Host time stamp when this entry is inserted to
870  * the ingress list.
871  * @ingress_list_removal_ts: Host time stamp when this entry is removed from
872  * the ingress list
873  * @egress_list_insertion_ts: Host time stamp when this entry is inserted to
874  * the egress list.
875  * @scheduled_ts: Host time stamp when this entry is scheduled for delivery
876  * @first_scheduled_ts: Host time stamp when this entry is first scheduled for
877  * delivery
878  * @last_scheduled_ts: Host time stamp when this entry is last scheduled for
879  * delivery
880  * @scheduled_count: Number of times this entry is scheduled
881  * @initial_wait_count: Wait count when the frame is queued
882  * @final_wait_count: Wait count when frame is released to upper layer
883  * @shared_snapshots: snapshots shared b/w host and target
884  * @host_snapshot: host snapshot
885  * @cpu_id: CPU index
886  * @ctx_info: Execution context info
887  */
888 struct reo_scheduler_debug_frame_info {
889 	uint8_t link_id;
890 	uint16_t mgmt_pkt_ctr;
891 	uint32_t global_timestamp;
892 	uint64_t ingress_timestamp;
893 	uint64_t ingress_list_insertion_ts;
894 	uint64_t ingress_list_removal_ts;
895 	uint64_t egress_list_insertion_ts;
896 	uint64_t scheduled_ts;
897 	uint64_t first_scheduled_ts;
898 	uint64_t last_scheduled_ts;
899 	int32_t scheduled_count;
900 	struct mgmt_rx_reo_wait_count initial_wait_count;
901 	struct mgmt_rx_reo_wait_count final_wait_count;
902 	struct mgmt_rx_reo_snapshot_params shared_snapshots
903 			[MAX_MLO_LINKS][MGMT_RX_REO_SHARED_SNAPSHOT_MAX];
904 	struct mgmt_rx_reo_snapshot_params host_snapshot[MAX_MLO_LINKS];
905 	int cpu_id;
906 	struct mgmt_rx_reo_context_info ctx_info;
907 };
908 
909 /**
910  * struct reo_scheduler_stats - Structure to store statistics related to
911  * frames scheduled by reo scheduler
912  * @scheduled_count: Scheduled count
913  * @rescheduled_count: Rescheduled count
914  * @scheduler_cb_count: Scheduler callback count
915  */
916 struct reo_scheduler_stats {
917 	uint64_t scheduled_count[MAX_MLO_LINKS][MGMT_RX_REO_CONTEXT_MAX];
918 	uint64_t rescheduled_count[MAX_MLO_LINKS][MGMT_RX_REO_CONTEXT_MAX];
919 	uint64_t scheduler_cb_count[MAX_MLO_LINKS];
920 };
921 
922 /**
923  * struct reo_scheduler_debug_info - Circular array to store the
924  * debug information about the frames scheduled by reo scheduler
925  * @frame_list: Circular array to store the debug info
926  * @frame_list_size: Size of circular array @frame_list
927  * @next_index: The index at which information about next frame will be logged
928  * @wrap_aroud: Flag to indicate whether wrap around occurred when logging
929  * debug information to @frame_list
930  * @stats: Stats related to scheduler
931  */
932 struct reo_scheduler_debug_info {
933 	struct reo_scheduler_debug_frame_info *frame_list;
934 	uint16_t frame_list_size;
935 	int next_index;
936 	bool wrap_aroud;
937 	struct reo_scheduler_stats stats;
938 };
939 #endif /* WLAN_MGMT_RX_REO_DEBUG_SUPPORT */
940 
941 /**
942  * struct mgmt_rx_reo_context - This structure holds the info required for
943  * management rx-reordering. Reordering is done across all the psocs.
944  * So there should be only one instance of this structure defined.
945  * @ingress_list: Ingress list object
946  * @egress_list: Egress list object
947  * @reo_algo_entry_lock: Spin lock to protect reo algorithm entry critical
948  * section execution
949  * @frame_release_lock: Spin lock to serialize the frame delivery to the
950  * upper layers. This could prevent race conditions like the one given in
951  * the following example.
952  * Lets take an example of 2 links (Link A & B) and each has received
953  * a management frame A1(deauth) and B1(auth) such that MLO global time
954  * stamp of A1 < MLO global time stamp of B1. Host is concurrently
955  * executing "mgmt_rx_reo_list_release_entries" for A1 and B1 in
956  * 2 different CPUs. It is possible that frame B1 gets processed by
957  * upper layers before frame A1 and this could result in unwanted
958  * disconnection. Hence it is required to serialize the delivery
959  * of management frames to upper layers in the strict order of MLO
960  * global time stamp.
961  * @sim_context: Management rx-reorder simulation context
962  * @ingress_debug_info_init_count: Initialization count of
963  * object @ingress_frame_debug_info
964  * @ingress_frame_debug_info: Debug object to log incoming frames
965  * @egress_frame_debug_info: Debug object to log outgoing frames
966  * @egress_debug_info_init_count: Initialization count of
967  * object @egress_frame_debug_info
968  * @scheduler_debug_info_init_count: Initialization count of
969  * object @scheduler_debug_info
970  * @scheduler_debug_info: Debug object to log scheduler debug info
971  * @simulation_in_progress: Flag to indicate whether simulation is
972  * in progress
973  * @mlo_grp_id: MLO Group ID which it belongs to
974  * @context_id: Context identifier
975  */
976 struct mgmt_rx_reo_context {
977 	struct mgmt_rx_reo_ingress_list ingress_list;
978 	struct mgmt_rx_reo_egress_list egress_list;
979 	qdf_spinlock_t reo_algo_entry_lock;
980 	qdf_spinlock_t frame_release_lock;
981 #ifdef WLAN_MGMT_RX_REO_SIM_SUPPORT
982 	struct mgmt_rx_reo_sim_context sim_context;
983 #endif /* WLAN_MGMT_RX_REO_SIM_SUPPORT */
984 #ifdef WLAN_MGMT_RX_REO_DEBUG_SUPPORT
985 	qdf_atomic_t ingress_debug_info_init_count;
986 	struct  reo_ingress_debug_info ingress_frame_debug_info;
987 	qdf_atomic_t egress_debug_info_init_count;
988 	struct  reo_egress_debug_info egress_frame_debug_info;
989 	qdf_atomic_t scheduler_debug_info_init_count;
990 	struct  reo_scheduler_debug_info scheduler_debug_info;
991 #endif /* WLAN_MGMT_RX_REO_DEBUG_SUPPORT */
992 	bool simulation_in_progress;
993 	uint8_t mlo_grp_id;
994 	qdf_atomic_t context_id;
995 };
996 
997 /**
998  * struct mgmt_rx_reo_frame_descriptor - Frame Descriptor used to describe
999  * a management frame in mgmt rx reo module.
1000  * @type: Frame descriptor type
1001  * @frame_type: frame type
1002  * @frame_subtype: frame subtype
1003  * @nbuf: nbuf corresponding to this frame
1004  * @rx_params: Management rx event parameters
1005  * @wait_count: Wait counts for the frame
1006  * @ingress_timestamp: Host time stamp when the frames enters the reorder
1007  * algorithm
1008  * @is_stale: Indicates whether this frame is stale. Any frame older than the
1009  * last frame delivered to upper layer is a stale frame. Stale frames should not
1010  * be delivered to the upper layers. These frames can be discarded after
1011  * updating the host snapshot and wait counts of entries currently residing in
1012  * the reorder list.
1013  * @zero_wait_count_rx: Indicates whether this frame's wait count was
1014  * zero when received by host
1015  * @immediate_delivery: Indicates whether this frame can be delivered
1016  * immediately to the upper layers
1017  * @ingress_list_size_rx: Size of the ingress list when this frame is
1018  * received (before updating the ingress list based on this frame).
1019  * @ingress_list_insertion_pos: Position in the ingress list where this
1020  * frame is going to get inserted (Applicable for only host consumed frames)
1021  * @egress_list_size_rx: Size of the egress list when this frame is
1022  * added to the egress list
1023  * @egress_list_insertion_pos: Position in the egress list where this
1024  * frame is going to get inserted
1025  * @shared_snapshots: snapshots shared b/w host and target
1026  * @host_snapshot: host snapshot
1027  * @is_parallel_rx: Indicates that this frame is received in parallel to the
1028  * last frame which is delivered to the upper layer.
1029  * @queued_list: Type of list in which the current frame is queued
1030  * @pkt_ctr_delta: Packet counter delta of the current and last frame
1031  * @reo_required: Indicates whether reorder is required for the current frame.
1032  * If reorder is not required, current frame will just be used for updating the
1033  * wait count of frames already part of the reorder list.
1034  * @last_delivered_frame: Stores the information about the last frame delivered
1035  * to the upper layer
1036  * @reo_params_copy: Copy of @rx_params->reo_params structure
1037  * @drop_reason: Reason for dropping the frame
1038  * @drop: Indicates whether the frame has to be dropped
1039  */
1040 struct mgmt_rx_reo_frame_descriptor {
1041 	enum mgmt_rx_reo_frame_descriptor_type type;
1042 	uint8_t frame_type;
1043 	uint8_t frame_subtype;
1044 	qdf_nbuf_t nbuf;
1045 	struct mgmt_rx_event_params *rx_params;
1046 	struct mgmt_rx_reo_wait_count wait_count;
1047 	uint64_t ingress_timestamp;
1048 	bool is_stale;
1049 	bool zero_wait_count_rx;
1050 	bool immediate_delivery;
1051 	int16_t ingress_list_size_rx;
1052 	int16_t ingress_list_insertion_pos;
1053 	int16_t egress_list_size_rx;
1054 	int16_t egress_list_insertion_pos;
1055 	struct mgmt_rx_reo_snapshot_params shared_snapshots
1056 			[MAX_MLO_LINKS][MGMT_RX_REO_SHARED_SNAPSHOT_MAX];
1057 	struct mgmt_rx_reo_snapshot_params host_snapshot[MAX_MLO_LINKS];
1058 	bool is_parallel_rx;
1059 	enum mgmt_rx_reo_list_type queued_list;
1060 	int pkt_ctr_delta;
1061 	bool reo_required;
1062 	struct mgmt_rx_reo_frame_info last_delivered_frame;
1063 	struct mgmt_rx_reo_params reo_params_copy;
1064 	enum mgmt_rx_reo_ingress_drop_reason drop_reason;
1065 	bool drop;
1066 };
1067 
1068 /**
1069  * mgmt_rx_reo_list_overflowed() - Helper API to check whether mgmt rx reorder
1070  * list overflowed
1071  * @reo_list: Pointer to management rx reorder list
1072  *
1073  * Return: true or false
1074  */
1075 static inline bool
1076 mgmt_rx_reo_list_overflowed(struct mgmt_rx_reo_list *reo_list)
1077 {
1078 	if (!reo_list) {
1079 		mgmt_rx_reo_err("reo list is null");
1080 		return false;
1081 	}
1082 
1083 	return (qdf_list_size(&reo_list->list) > reo_list->max_list_size);
1084 }
1085 
1086 /**
1087  * mgmt_rx_reo_get_context_from_ingress_list() - Helper API to get pointer to
1088  * management rx reorder context from pointer to management rx reo ingress list
1089  * @ingress_list: Pointer to management rx reo ingress list
1090  *
1091  * Return: Pointer to management rx reorder context
1092  */
1093 static inline struct mgmt_rx_reo_context *
1094 mgmt_rx_reo_get_context_from_ingress_list
1095 		(const struct mgmt_rx_reo_ingress_list *ingress_list) {
1096 	if (!ingress_list) {
1097 		mgmt_rx_reo_err("ingress list is null");
1098 		return NULL;
1099 	}
1100 
1101 	return qdf_container_of(ingress_list, struct mgmt_rx_reo_context,
1102 				ingress_list);
1103 }
1104 
1105 /**
1106  * mgmt_rx_reo_get_context_from_egress_list() - Helper API to get pointer to
1107  * management rx reorder context from pointer to management rx reo egress list
1108  * @egress_list: Pointer to management rx reo egress list
1109  *
1110  * Return: Pointer to management rx reorder context
1111  */
1112 static inline struct mgmt_rx_reo_context *
1113 mgmt_rx_reo_get_context_from_egress_list
1114 			(const struct mgmt_rx_reo_egress_list *egress_list) {
1115 	if (!egress_list) {
1116 		mgmt_rx_reo_err("Egress list is null");
1117 		return NULL;
1118 	}
1119 
1120 	return qdf_container_of(egress_list, struct mgmt_rx_reo_context,
1121 				egress_list);
1122 }
1123 
1124 /**
1125  * mgmt_rx_reo_get_global_ts() - Helper API to get global time stamp
1126  * corresponding to the mgmt rx event
1127  * @rx_params: Management rx event params
1128  *
1129  * Return: global time stamp corresponding to the mgmt rx event
1130  */
1131 static inline uint32_t
1132 mgmt_rx_reo_get_global_ts(struct mgmt_rx_event_params *rx_params)
1133 {
1134 	if (!rx_params) {
1135 		mgmt_rx_reo_err("rx params is null");
1136 		return 0;
1137 	}
1138 
1139 	if (!rx_params->reo_params) {
1140 		mgmt_rx_reo_err("reo params is null");
1141 		return 0;
1142 	}
1143 
1144 	return rx_params->reo_params->global_timestamp;
1145 }
1146 
1147 /**
1148  * mgmt_rx_reo_get_start_ts() - Helper API to get start time stamp of the frame
1149  * @rx_params: Management rx event params
1150  *
1151  * Return: start time stamp of the frame
1152  */
1153 static inline uint32_t
1154 mgmt_rx_reo_get_start_ts(struct mgmt_rx_event_params *rx_params)
1155 {
1156 	if (!rx_params) {
1157 		mgmt_rx_reo_err("rx params is null");
1158 		return 0;
1159 	}
1160 
1161 	if (!rx_params->reo_params) {
1162 		mgmt_rx_reo_err("reo params is null");
1163 		return 0;
1164 	}
1165 
1166 	return rx_params->reo_params->start_timestamp;
1167 }
1168 
1169 /**
1170  * mgmt_rx_reo_get_end_ts() - Helper API to get end time stamp of the frame
1171  * @rx_params: Management rx event params
1172  *
1173  * Return: end time stamp of the frame
1174  */
1175 static inline uint32_t
1176 mgmt_rx_reo_get_end_ts(struct mgmt_rx_event_params *rx_params)
1177 {
1178 	if (!rx_params) {
1179 		mgmt_rx_reo_err("rx params is null");
1180 		return 0;
1181 	}
1182 
1183 	if (!rx_params->reo_params) {
1184 		mgmt_rx_reo_err("reo params is null");
1185 		return 0;
1186 	}
1187 
1188 	return rx_params->reo_params->end_timestamp;
1189 }
1190 
1191 /**
1192  * mgmt_rx_reo_get_duration_us() - Helper API to get the duration of the frame
1193  * in us
1194  * @rx_params: Management rx event params
1195  *
1196  * Return: Duration of the frame in us
1197  */
1198 static inline uint32_t
1199 mgmt_rx_reo_get_duration_us(struct mgmt_rx_event_params *rx_params)
1200 {
1201 	if (!rx_params) {
1202 		mgmt_rx_reo_err("rx params is null");
1203 		return 0;
1204 	}
1205 
1206 	if (!rx_params->reo_params) {
1207 		mgmt_rx_reo_err("reo params is null");
1208 		return 0;
1209 	}
1210 
1211 	return rx_params->reo_params->duration_us;
1212 }
1213 
1214 /**
1215  * mgmt_rx_reo_get_pkt_counter() - Helper API to get packet counter
1216  * corresponding to the mgmt rx event
1217  * @rx_params: Management rx event params
1218  *
1219  * Return: Management packet counter corresponding to the mgmt rx event
1220  */
1221 static inline uint16_t
1222 mgmt_rx_reo_get_pkt_counter(struct mgmt_rx_event_params *rx_params)
1223 {
1224 	if (!rx_params) {
1225 		mgmt_rx_reo_err("rx params is null");
1226 		return 0;
1227 	}
1228 
1229 	if (!rx_params->reo_params) {
1230 		mgmt_rx_reo_err("reo params is null");
1231 		return 0;
1232 	}
1233 
1234 	return rx_params->reo_params->mgmt_pkt_ctr;
1235 }
1236 
1237 /**
1238  * mgmt_rx_reo_get_link_id() - Helper API to get link id corresponding to the
1239  * mgmt rx event
1240  * @rx_params: Management rx event params
1241  *
1242  * Return: link id corresponding to the mgmt rx event
1243  */
1244 static inline uint8_t
1245 mgmt_rx_reo_get_link_id(struct mgmt_rx_event_params *rx_params)
1246 {
1247 	if (!rx_params) {
1248 		mgmt_rx_reo_err("rx params is null");
1249 		return 0;
1250 	}
1251 
1252 	if (!rx_params->reo_params) {
1253 		mgmt_rx_reo_err("reo params is null");
1254 		return 0;
1255 	}
1256 
1257 	return rx_params->reo_params->link_id;
1258 }
1259 
1260 /**
1261  * mgmt_rx_reo_get_mlo_grp_id() - Helper API to get MLO Group id
1262  * corresponding to the mgmt rx event
1263  * @rx_params: Management rx event params
1264  *
1265  * Return: MLO group id corresponding to the mgmt rx event
1266  */
1267 static inline uint8_t
1268 mgmt_rx_reo_get_mlo_grp_id(struct mgmt_rx_event_params *rx_params)
1269 {
1270 	if (!rx_params) {
1271 		mgmt_rx_reo_err("rx params is null");
1272 		return 0;
1273 	}
1274 
1275 	if (!rx_params->reo_params) {
1276 		mgmt_rx_reo_err("reo params is null");
1277 		return 0;
1278 	}
1279 
1280 	return rx_params->reo_params->mlo_grp_id;
1281 }
1282 
1283 /**
1284  * mgmt_rx_reo_get_pdev_id() - Helper API to get pdev id corresponding to the
1285  * mgmt rx event
1286  * @rx_params: Management rx event params
1287  *
1288  * Return: pdev id corresponding to the mgmt rx event
1289  */
1290 static inline uint8_t
1291 mgmt_rx_reo_get_pdev_id(struct mgmt_rx_event_params *rx_params)
1292 {
1293 	if (!rx_params) {
1294 		mgmt_rx_reo_err("rx params is null");
1295 		return 0;
1296 	}
1297 
1298 	if (!rx_params->reo_params) {
1299 		mgmt_rx_reo_err("reo params is null");
1300 		return 0;
1301 	}
1302 
1303 	return rx_params->reo_params->pdev_id;
1304 }
1305 
1306 /**
1307  * mgmt_rx_reo_init_context() - Initialize the management rx-reorder context
1308  * @ml_grp_id: MLO Group ID to be initialized
1309  *
1310  * API to initialize each global management rx-reorder context object per group
1311  *
1312  * Return: QDF_STATUS
1313  */
1314 QDF_STATUS
1315 mgmt_rx_reo_init_context(uint8_t ml_grp_id);
1316 
1317 /**
1318  * mgmt_rx_reo_deinit_context() - De initialize the management rx-reorder
1319  * context
1320  * @ml_grp_id: MLO Group ID to be deinitialized
1321  *
1322  * API to de initialize each global management rx-reorder context object per
1323  * group
1324  *
1325  * Return: QDF_STATUS
1326  */
1327 QDF_STATUS
1328 mgmt_rx_reo_deinit_context(uint8_t ml_grp_id);
1329 
1330 /**
1331  * mgmt_rx_reo_is_simulation_in_progress() - API to check whether
1332  * simulation is in progress
1333  * @ml_grp_id: MLO group id of mgmt rx reo
1334  *
1335  * Return: true if simulation is in progress, else false
1336  */
1337 bool
1338 mgmt_rx_reo_is_simulation_in_progress(uint8_t ml_grp_id);
1339 
1340 /**
1341  * mgmt_rx_reo_print_ingress_frame_stats() - Helper API to print
1342  * stats related to incoming management frames
1343  * @ml_grp_id: MLO group id of mgmt rx reo
1344  *
1345  * This API prints stats related to management frames entering management
1346  * Rx reorder module.
1347  *
1348  * Return: QDF_STATUS
1349  */
1350 QDF_STATUS
1351 mgmt_rx_reo_print_ingress_frame_stats(uint8_t ml_grp_id);
1352 
1353 /**
1354  * mgmt_rx_reo_print_ingress_frame_info() - Print the debug information
1355  * about the latest frames entered the reorder module
1356  * @ml_grp_id: MLO group id of mgmt rx reo
1357  * @num_frames: Number of frames for which the debug information is to be
1358  * printed. If @num_frames is 0, then debug information about all the frames
1359  * in the ring buffer will be  printed.
1360  *
1361  * Return: QDF_STATUS of operation
1362  */
1363 QDF_STATUS
1364 mgmt_rx_reo_print_ingress_frame_info(uint8_t ml_grp_id, uint16_t num_frames);
1365 
1366 /**
1367  * mgmt_rx_reo_print_egress_frame_stats() - Helper API to print
1368  * stats related to outgoing management frames
1369  * @ml_grp_id: MLO group id of mgmt rx reo
1370  *
1371  * This API prints stats related to management frames exiting management
1372  * Rx reorder module.
1373  *
1374  * Return: QDF_STATUS
1375  */
1376 QDF_STATUS
1377 mgmt_rx_reo_print_egress_frame_stats(uint8_t ml_grp_id);
1378 
1379 /**
1380  * mgmt_rx_reo_print_egress_frame_info() - Print the debug information
1381  * about the latest frames leaving the reorder module
1382  * @ml_grp_id: MLO group id of mgmt rx reo
1383  * @num_frames: Number of frames for which the debug information is to be
1384  * printed. If @num_frames is 0, then debug information about all the frames
1385  * in the ring buffer will be  printed.
1386  *
1387  * Return: QDF_STATUS of operation
1388  */
1389 QDF_STATUS
1390 mgmt_rx_reo_print_egress_frame_info(uint8_t ml_grp_id, uint16_t num_frames);
1391 
1392 #ifdef WLAN_MGMT_RX_REO_SIM_SUPPORT
1393 /**
1394  * mgmt_rx_reo_sim_start() - Helper API to start management Rx reorder
1395  * simulation
1396  * @ml_grp_id: MLO group id of mgmt rx reo
1397  *
1398  * This API starts the simulation framework which mimics the management frame
1399  * generation by target. MAC HW is modelled as a kthread. FW and host layers
1400  * are modelled as an ordered work queues.
1401  *
1402  * Return: QDF_STATUS
1403  */
1404 QDF_STATUS
1405 mgmt_rx_reo_sim_start(uint8_t ml_grp_id);
1406 
1407 /**
1408  * mgmt_rx_reo_sim_stop() - Helper API to stop management Rx reorder
1409  * simulation
1410  * @ml_grp_id: MLO group id of mgmt rx reo
1411  *
1412  * This API stops the simulation framework which mimics the management frame
1413  * generation by target. MAC HW is modelled as a kthread. FW and host layers
1414  * are modelled as an ordered work queues.
1415  *
1416  * Return: QDF_STATUS
1417  */
1418 QDF_STATUS
1419 mgmt_rx_reo_sim_stop(uint8_t ml_grp_id);
1420 
1421 /**
1422  * mgmt_rx_reo_sim_process_rx_frame() - API to process the management frame
1423  * in case of simulation
1424  * @pdev: pointer to pdev object
1425  * @buf: pointer to management frame buffer
1426  * @mgmt_rx_params: pointer to management frame parameters
1427  *
1428  * This API validates whether the reo algorithm has reordered frames correctly.
1429  *
1430  * Return: QDF_STATUS
1431  */
1432 QDF_STATUS
1433 mgmt_rx_reo_sim_process_rx_frame(struct wlan_objmgr_pdev *pdev,
1434 				 qdf_nbuf_t buf,
1435 				 struct mgmt_rx_event_params *mgmt_rx_params);
1436 
1437 /**
1438  * mgmt_rx_reo_sim_get_snapshot_address() - Get snapshot address
1439  * @pdev: pointer to pdev
1440  * @id: snapshot identifier
1441  * @address: pointer to snapshot address
1442  *
1443  * Helper API to get address of snapshot @id for pdev @pdev. For simulation
1444  * purpose snapshots are allocated in the simulation context object.
1445  *
1446  * Return: QDF_STATUS
1447  */
1448 QDF_STATUS
1449 mgmt_rx_reo_sim_get_snapshot_address(
1450 			struct wlan_objmgr_pdev *pdev,
1451 			enum mgmt_rx_reo_shared_snapshot_id id,
1452 			struct mgmt_rx_reo_shared_snapshot **address);
1453 
1454 /**
1455  * mgmt_rx_reo_sim_pdev_object_create_notification() - pdev create handler for
1456  * management rx-reorder simulation framework
1457  * @pdev: pointer to pdev object
1458  *
1459  * This function gets called from object manager when pdev is being created and
1460  * builds the link id to pdev map in simulation context object.
1461  *
1462  * Return: QDF_STATUS
1463  */
1464 QDF_STATUS
1465 mgmt_rx_reo_sim_pdev_object_create_notification(struct wlan_objmgr_pdev *pdev);
1466 
1467 /**
1468  * mgmt_rx_reo_sim_pdev_object_destroy_notification() - pdev destroy handler for
1469  * management rx-reorder simulation framework
1470  * @pdev: pointer to pdev object
1471  *
1472  * This function gets called from object manager when pdev is being destroyed
1473  * and destroys the link id to pdev map in simulation context.
1474  *
1475  * Return: QDF_STATUS
1476  */
1477 QDF_STATUS
1478 mgmt_rx_reo_sim_pdev_object_destroy_notification(struct wlan_objmgr_pdev *pdev);
1479 
1480 /**
1481  * mgmt_rx_reo_sim_get_mlo_link_id_from_pdev() - Helper API to get the MLO HW
1482  * link id from the pdev object.
1483  * @pdev: Pointer to pdev object
1484  *
1485  * This API is applicable for simulation only. A static map from MLO HW link id
1486  * to the pdev object is created at the init time. This API uses the map to
1487  * find the MLO HW link id for a given pdev.
1488  *
1489  * Return: On success returns the MLO HW link id corresponding to the pdev
1490  * object. On failure returns -1.
1491  */
1492 int8_t
1493 mgmt_rx_reo_sim_get_mlo_link_id_from_pdev(struct wlan_objmgr_pdev *pdev);
1494 
1495 /**
1496  * mgmt_rx_reo_sim_get_pdev_from_mlo_link_id() - Helper API to get the pdev
1497  * object from the MLO HW link id.
1498  * @mlo_link_id: MLO HW link id
1499  * @refdbgid: Reference debug id
1500  *
1501  * This API is applicable for simulation only. A static map from MLO HW link id
1502  * to the pdev object is created at the init time. This API uses the map to
1503  * find the pdev object from the MLO HW link id.
1504  *
1505  * Return: On success returns the pdev object corresponding to the MLO HW
1506  * link id. On failure returns NULL.
1507  */
1508 struct wlan_objmgr_pdev *
1509 mgmt_rx_reo_sim_get_pdev_from_mlo_link_id(uint8_t mlo_link_id,
1510 					  wlan_objmgr_ref_dbgid refdbgid);
1511 #endif /* WLAN_MGMT_RX_REO_SIM_SUPPORT */
1512 
1513 /**
1514  * is_mgmt_rx_reo_required() - Whether MGMT REO required for this frame/event
1515  * @pdev: pdev for which this frame/event is intended
1516  * @desc: Descriptor corresponding to this frame/event
1517  *
1518  * Return: true if REO is required; else false
1519  */
1520 static inline bool is_mgmt_rx_reo_required(
1521 			struct wlan_objmgr_pdev *pdev,
1522 			struct mgmt_rx_reo_frame_descriptor *desc)
1523 {
1524 	/**
1525 	 * NOTE: Implementing a simple policy based on the number of MLO vdevs
1526 	 * in the given pdev.
1527 	 */
1528 	return  wlan_pdev_get_mlo_vdev_count(pdev);
1529 }
1530 
1531 /**
1532  * wlan_mgmt_rx_reo_algo_entry() - Entry point to the MGMT Rx REO algorithm for
1533  * a given MGMT frame/event.
1534  * @pdev: pdev for which this frame/event is intended
1535  * @desc: Descriptor corresponding to this frame/event
1536  * @is_queued: Whether this frame/event is queued in the REO list
1537  *
1538  * Return: QDF_STATUS of operation
1539  */
1540 QDF_STATUS
1541 wlan_mgmt_rx_reo_algo_entry(struct wlan_objmgr_pdev *pdev,
1542 			    struct mgmt_rx_reo_frame_descriptor *desc,
1543 			    bool *is_queued);
1544 
1545 /**
1546  * mgmt_rx_reo_validate_mlo_link_info() - Validate the MLO HW link info
1547  * obtained from the global shared memory arena
1548  * @psoc: Pointer to psoc object
1549  *
1550  * Validate the following MLO HW link related information extracted from
1551  * management Rx reorder related TLVs in global shared memory arena.
1552  *         1. Number of active MLO HW links
1553  *         2. Valid MLO HW link bitmap
1554  *
1555  * Return: QDF_STATUS of operation
1556  */
1557 QDF_STATUS
1558 mgmt_rx_reo_validate_mlo_link_info(struct wlan_objmgr_psoc *psoc);
1559 
1560 /**
1561  * mgmt_rx_reo_release_frames() - Release management frames which are ready
1562  * for delivery
1563  * @mlo_grp_id: MLO group ID
1564  * @link_bitmap: Link bitmap
1565  *
1566  * Return: QDF_STATUS
1567  */
1568 QDF_STATUS
1569 mgmt_rx_reo_release_frames(uint8_t mlo_grp_id, uint32_t link_bitmap);
1570 #endif /* WLAN_MGMT_RX_REO_SUPPORT */
1571 #endif /* _WLAN_MGMT_TXRX_RX_REO_I_H */
1572