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
mgmt_rx_reo_list_overflowed(struct mgmt_rx_reo_list * reo_list)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 *
mgmt_rx_reo_get_context_from_ingress_list(const struct mgmt_rx_reo_ingress_list * ingress_list)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 *
mgmt_rx_reo_get_context_from_egress_list(const struct mgmt_rx_reo_egress_list * egress_list)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
mgmt_rx_reo_get_global_ts(struct mgmt_rx_event_params * rx_params)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
mgmt_rx_reo_get_start_ts(struct mgmt_rx_event_params * rx_params)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
mgmt_rx_reo_get_end_ts(struct mgmt_rx_event_params * rx_params)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
mgmt_rx_reo_get_duration_us(struct mgmt_rx_event_params * rx_params)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
mgmt_rx_reo_get_pkt_counter(struct mgmt_rx_event_params * rx_params)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
mgmt_rx_reo_get_link_id(struct mgmt_rx_event_params * rx_params)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
mgmt_rx_reo_get_mlo_grp_id(struct mgmt_rx_event_params * rx_params)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
mgmt_rx_reo_get_pdev_id(struct mgmt_rx_event_params * rx_params)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 */
is_mgmt_rx_reo_required(struct wlan_objmgr_pdev * pdev,struct mgmt_rx_reo_frame_descriptor * desc)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