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