1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #ifndef __CDS_SCHED_H 21 #define __CDS_SCHED_H 22 23 /**========================================================================= 24 25 \file cds_sched.h 26 27 \brief Connectivity driver services scheduler 28 29 ========================================================================*/ 30 31 /*-------------------------------------------------------------------------- 32 Include Files 33 ------------------------------------------------------------------------*/ 34 #include <qdf_event.h> 35 #include <i_qdf_types.h> 36 #include <linux/wait.h> 37 #if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) 38 #include <linux/wakelock.h> 39 #endif 40 #include <qdf_types.h> 41 #include "qdf_lock.h" 42 #include "qdf_mc_timer.h" 43 #include "cds_config.h" 44 #include "qdf_cpuhp.h" 45 46 #define MC_SUSPEND_EVENT 0x002 47 #define RX_POST_EVENT 0x001 48 #define RX_SUSPEND_EVENT 0x002 49 #define RX_VDEV_DEL_EVENT 0x004 50 #define RX_SHUTDOWN_EVENT 0x010 51 52 #define RX_REFILL_POST_EVENT 0x001 53 #define RX_REFILL_SUSPEND_EVENT 0x002 54 #define RX_REFILL_SHUTDOWN_EVENT 0x004 55 56 #ifdef QCA_CONFIG_SMP 57 /* 58 ** Maximum number of cds messages to be allocated for 59 ** OL Rx thread. 60 */ 61 #define CDS_MAX_OL_RX_PKT 4000 62 63 #define CDS_ACTIVE_STAID_CLEANUP_DELAY 10 64 #define CDS_ACTIVE_STAID_CLEANUP_TIMEOUT 200 65 #endif 66 67 typedef void (*cds_ol_rx_thread_cb)(void *context, 68 qdf_nbuf_t rxpkt, 69 uint16_t staid); 70 71 /* 72 ** CDS message wrapper for data rx from TXRX 73 */ 74 struct cds_ol_rx_pkt { 75 struct list_head list; 76 void *context; 77 78 /* Rx skb */ 79 qdf_nbuf_t Rxpkt; 80 81 /* Station id to which this packet is destined */ 82 uint16_t staId; 83 84 /* Call back to further send this packet to txrx layer */ 85 cds_ol_rx_thread_cb callback; 86 87 }; 88 89 /* 90 ** CDS Scheduler context 91 ** The scheduler context contains the following: 92 ** ** the messages queues 93 ** ** the handle to the thread 94 ** ** pointer to the events that gracefully shutdown the MC and Tx threads 95 ** 96 */ 97 typedef struct _cds_sched_context { 98 #ifdef QCA_CONFIG_SMP 99 spinlock_t ol_rx_thread_lock; 100 101 /* OL Rx thread handle */ 102 struct task_struct *ol_rx_thread; 103 104 /* Handle of Event for Rx thread to signal startup */ 105 struct completion ol_rx_start_event; 106 107 /* Completion object to suspend OL rx thread */ 108 struct completion ol_suspend_rx_event; 109 110 /* Completion object to resume OL rx thread */ 111 struct completion ol_resume_rx_event; 112 113 /* Completion object for OL Rxthread shutdown */ 114 struct completion ol_rx_shutdown; 115 116 /* Waitq for OL Rx thread */ 117 wait_queue_head_t ol_rx_wait_queue; 118 119 unsigned long ol_rx_event_flag; 120 121 /* Rx buffer queue */ 122 struct list_head ol_rx_thread_queue; 123 124 /* Spinlock to synchronize between tasklet and thread */ 125 spinlock_t ol_rx_queue_lock; 126 127 /* Lock to synchronize free buffer queue access */ 128 spinlock_t cds_ol_rx_pkt_freeq_lock; 129 130 /* Free message queue for OL Rx processing */ 131 struct list_head cds_ol_rx_pkt_freeq; 132 133 /* The CPU hotplug event registration handle, used to unregister */ 134 struct qdf_cpuhp_handler *cpuhp_event_handle; 135 136 /* affinity lock */ 137 struct mutex affinity_lock; 138 139 /* Saved rx thread CPU affinity */ 140 struct cpumask rx_thread_cpu_mask; 141 142 /* CPU affinity bitmask */ 143 uint8_t conf_rx_thread_cpu_mask; 144 145 /* high throughput required */ 146 bool high_throughput_required; 147 148 /* affinity required during uplink traffic*/ 149 bool rx_affinity_required; 150 uint8_t conf_rx_thread_ul_affinity; 151 152 /* sta id packets under processing in thread context*/ 153 uint16_t active_staid; 154 #endif 155 } cds_sched_context, *p_cds_sched_context; 156 157 /** 158 * struct cds_log_complete - Log completion internal structure 159 * @is_fatal: Type is fatal or not 160 * @indicator: Source of bug report 161 * @reason_code: Reason code for bug report 162 * @is_report_in_progress: If bug report is in progress 163 * @recovery_needed: if recovery is needed after report completion 164 * 165 * This structure internally stores the log related params 166 */ 167 struct cds_log_complete { 168 uint32_t is_fatal; 169 uint32_t indicator; 170 uint32_t reason_code; 171 bool is_report_in_progress; 172 bool recovery_needed; 173 }; 174 175 struct cds_context { 176 /* Scheduler Context */ 177 cds_sched_context qdf_sched; 178 179 /* HDD Module Context */ 180 void *hdd_context; 181 182 /* MAC Module Context */ 183 void *mac_context; 184 185 uint32_t driver_state; 186 187 /* WMA Context */ 188 void *wma_context; 189 190 void *hif_context; 191 192 void *htc_ctx; 193 194 void *g_ol_context; 195 /* 196 * qdf_ctx will be used by qdf 197 * while allocating dma memory 198 * to access dev information. 199 */ 200 qdf_device_t qdf_ctx; 201 202 void *dp_soc; 203 204 void *dp_mem_pre_alloc_ctx; 205 206 /* Configuration handle used to get system configuration */ 207 struct cdp_cfg *cfg_ctx; 208 209 /* radio index per driver */ 210 int radio_index; 211 212 bool is_wakelock_log_enabled; 213 uint32_t wakelock_log_level; 214 uint32_t connectivity_log_level; 215 uint32_t packet_stats_log_level; 216 uint32_t driver_debug_log_level; 217 uint32_t fw_debug_log_level; 218 struct cds_log_complete log_complete; 219 qdf_spinlock_t bug_report_lock; 220 221 bool enable_fatal_event; 222 struct cds_config_info *cds_cfg; 223 224 struct ol_tx_sched_wrr_ac_specs_t ac_specs[QCA_WLAN_AC_ALL]; 225 qdf_work_t cds_recovery_work; 226 qdf_workqueue_t *cds_recovery_wq; 227 enum qdf_hang_reason recovery_reason; 228 }; 229 230 /*--------------------------------------------------------------------------- 231 Function declarations and documentation 232 ---------------------------------------------------------------------------*/ 233 #ifdef QCA_CONFIG_SMP 234 int cds_sched_handle_cpu_hot_plug(void); 235 int cds_sched_handle_throughput_req(bool high_tput_required); 236 237 /** 238 * cds_sched_handle_rx_thread_affinity_req - rx thread affinity req handler 239 * @high_tput_required: high throughput is required or not 240 * 241 * rx thread affinity handler will find online cores and 242 * will assign proper core based on perf requirement 243 * 244 * Return: None 245 */ 246 void cds_sched_handle_rx_thread_affinity_req(bool high_throughput); 247 248 /** 249 * cds_set_rx_thread_ul_cpu_mask() - Rx_thread affinity for UL from INI 250 * @cpu_affinity_mask: CPU affinity bitmap 251 * 252 * Return:None 253 */ 254 void cds_set_rx_thread_ul_cpu_mask(uint8_t cpu_affinity_mask); 255 256 /** 257 * cds_set_rx_thread_cpu_mask() - Rx_thread affinity from INI 258 * @cpu_affinity_mask: CPU affinity bitmap 259 * 260 * Return:None 261 */ 262 void cds_set_rx_thread_cpu_mask(uint8_t cpu_affinity_mask); 263 264 /*--------------------------------------------------------------------------- 265 \brief cds_drop_rxpkt_by_staid() - API to drop pending Rx packets for a sta 266 The \a cds_drop_rxpkt_by_staid() drops queued packets for a station, to drop 267 all the pending packets the caller has to send WLAN_MAX_STA_COUNT as staId. 268 \param pSchedContext - pointer to the global CDS Sched Context 269 \param staId - Station Id 270 271 \return Nothing 272 \sa cds_drop_rxpkt_by_staid() 273 -------------------------------------------------------------------------*/ 274 void cds_drop_rxpkt_by_staid(p_cds_sched_context pSchedContext, uint16_t staId); 275 276 /*--------------------------------------------------------------------------- 277 \brief cds_indicate_rxpkt() - API to Indicate rx data packet 278 The \a cds_indicate_rxpkt() enqueues the rx packet onto ol_rx_thread_queue 279 and notifies cds_ol_rx_thread(). 280 \param Arg - pointer to the global CDS Sched Context 281 \param pkt - Vos data message buffer 282 283 \return Nothing 284 \sa cds_indicate_rxpkt() 285 -------------------------------------------------------------------------*/ 286 void cds_indicate_rxpkt(p_cds_sched_context pSchedContext, 287 struct cds_ol_rx_pkt *pkt); 288 289 /** 290 * cds_close_rx_thread() - close the Rx thread 291 * 292 * This api closes the Rx thread: 293 * 294 * Return: qdf status 295 */ 296 QDF_STATUS cds_close_rx_thread(void); 297 298 /*--------------------------------------------------------------------------- 299 \brief cds_alloc_ol_rx_pkt() - API to return next available cds message 300 The \a cds_alloc_ol_rx_pkt() returns next available cds message buffer 301 used for Rx Data processing. 302 \param pSchedContext - pointer to the global CDS Sched Context 303 304 \return pointer to cds message buffer 305 \sa cds_alloc_ol_rx_pkt() 306 -------------------------------------------------------------------------*/ 307 struct cds_ol_rx_pkt *cds_alloc_ol_rx_pkt(p_cds_sched_context pSchedContext); 308 309 /*--------------------------------------------------------------------------- 310 \brief cds_free_ol_rx_pkt() - API to release cds message to the freeq 311 The \a cds_free_ol_rx_pkt() returns the cds message used for Rx data 312 to the free queue. 313 \param pSchedContext - pointer to the global CDS Sched Context 314 \param pkt - Vos message buffer to be returned to free queue. 315 316 \return Nothing 317 \sa cds_free_ol_rx_pkt() 318 -------------------------------------------------------------------------*/ 319 void cds_free_ol_rx_pkt(p_cds_sched_context pSchedContext, 320 struct cds_ol_rx_pkt *pkt); 321 /*--------------------------------------------------------------------------- 322 \brief cds_free_ol_rx_pkt_freeq() - Free cdss buffer free queue 323 The \a cds_free_ol_rx_pkt_freeq() does mem free of the buffers 324 available in free cds buffer queue which is used for Data rx processing 325 from Tlshim. 326 \param pSchedContext - pointer to the global CDS Sched Context 327 328 \return Nothing 329 \sa cds_free_ol_rx_pkt_freeq() 330 -------------------------------------------------------------------------*/ 331 void cds_free_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext); 332 #else 333 /** 334 * cds_sched_handle_rx_thread_affinity_req - rx thread affinity req handler 335 * @high_tput_required: high throughput is required or not 336 * 337 * rx thread affinity handler will find online cores and 338 * will assign proper core based on perf requirement 339 * 340 * Return: None 341 */ 342 static inline void cds_sched_handle_rx_thread_affinity_req( 343 bool high_throughput) {} 344 345 /** 346 * cds_set_rx_thread_ul_cpu_mask() - Rx_thread affinity for UL from INI 347 * @cpu_affinity_mask: CPU affinity bitmap 348 * 349 * Return:None 350 */ 351 static inline void cds_set_rx_thread_ul_cpu_mask(uint8_t cpu_affinity_mask) {} 352 353 /** 354 * cds_set_rx_thread_cpu_mask() - Rx_thread affinity from INI 355 * @cpu_affinity_mask: CPU affinity bitmap 356 * 357 * Return:None 358 */ 359 static inline void cds_set_rx_thread_cpu_mask(uint8_t cpu_affinity_mask) {} 360 361 /** 362 * cds_drop_rxpkt_by_staid() - api to drop pending rx packets for a sta 363 * @pSchedContext: Pointer to the global CDS Sched Context 364 * @staId: Station Id 365 * 366 * This api drops queued packets for a station, to drop all the pending 367 * packets the caller has to send WLAN_MAX_STA_COUNT as staId. 368 * 369 * Return: none 370 */ 371 static inline 372 void cds_drop_rxpkt_by_staid(p_cds_sched_context pSchedContext, uint16_t staId) 373 { 374 } 375 376 /** 377 * cds_indicate_rxpkt() - API to Indicate rx data packet 378 * @pSchedContext: pointer to CDS Sched Context 379 * @pkt: CDS OL RX pkt pointer containing to RX data message buffer 380 * 381 * Return: none 382 */ 383 static inline 384 void cds_indicate_rxpkt(p_cds_sched_context pSchedContext, 385 struct cds_ol_rx_pkt *pkt) 386 { 387 } 388 389 /** 390 * cds_close_rx_thread() - close the Rx thread 391 * 392 * This api closes the Rx thread: 393 * 394 * Return: qdf status 395 */ 396 static inline 397 QDF_STATUS cds_close_rx_thread(void) 398 { 399 return QDF_STATUS_SUCCESS; 400 } 401 402 /** 403 * cds_alloc_ol_rx_pkt() - API to return next available cds message 404 * @pSchedContext: pointer to CDS Sched Context 405 * 406 * Return: none 407 */ 408 static inline 409 struct cds_ol_rx_pkt *cds_alloc_ol_rx_pkt(p_cds_sched_context pSchedContext) 410 { 411 return NULL; 412 } 413 414 /** 415 * cds_free_ol_rx_pkt() - API to release cds message to the freeq 416 * @pSchedContext: pointer to CDS Sched Context 417 * @pkt: CDS message buffer to be returned to free queue 418 * 419 * Return: none 420 */ 421 static inline 422 void cds_free_ol_rx_pkt(p_cds_sched_context pSchedContext, 423 struct cds_ol_rx_pkt *pkt) 424 { 425 } 426 427 /** 428 * cds_free_ol_rx_pkt_freeq() - Free cds buffer free queue 429 * @pSchedContext: pointer to CDS Sched Context 430 * @pkt: CDS message buffer to be returned to free queue 431 * 432 * Return: none 433 */ 434 static inline 435 void cds_free_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext) 436 { 437 } 438 439 static inline int cds_sched_handle_throughput_req( 440 bool high_tput_required) 441 { 442 return 0; 443 } 444 445 #endif 446 447 /*--------------------------------------------------------------------------- 448 449 \brief cds_sched_open() - initialize the CDS Scheduler 450 451 The \a cds_sched_open() function initializes the CDS Scheduler 452 Upon successful initialization: 453 454 - All the message queues are initialized 455 456 - The Main Controller thread is created and ready to receive and 457 dispatch messages. 458 459 - The Tx thread is created and ready to receive and dispatch messages 460 461 \param p_cds_context - pointer to the global QDF Context 462 463 \param p_cds_sched_context - pointer to a previously allocated buffer big 464 enough to hold a scheduler context. 465 466 \return QDF_STATUS_SUCCESS - Scheduler was successfully initialized and 467 is ready to be used. 468 469 QDF_STATUS_E_RESOURCES - System resources (other than memory) 470 are unavailable to initialize the scheduler 471 472 QDF_STATUS_E_NOMEM - insufficient memory exists to initialize 473 the scheduler 474 475 QDF_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open 476 function 477 478 QDF_STATUS_E_FAILURE - Failure to initialize the scheduler/ 479 480 \sa cds_sched_open() 481 482 -------------------------------------------------------------------------*/ 483 QDF_STATUS cds_sched_open(void *p_cds_context, 484 p_cds_sched_context pSchedCxt, uint32_t SchedCtxSize); 485 486 /*--------------------------------------------------------------------------- 487 488 \brief cds_sched_close() - Close the CDS Scheduler 489 490 The \a cds_sched_closes() function closes the CDS Scheduler 491 Upon successful closing: 492 493 - All the message queues are flushed 494 495 - The Main Controller thread is closed 496 497 - The Tx thread is closed 498 499 \return QDF_STATUS_SUCCESS - Scheduler was successfully initialized and 500 is ready to be used. 501 502 QDF_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open 503 function 504 505 QDF_STATUS_E_FAILURE - Failure to initialize the scheduler/ 506 507 \sa cds_sched_close() 508 509 ---------------------------------------------------------------------------*/ 510 QDF_STATUS cds_sched_close(void); 511 512 p_cds_sched_context get_cds_sched_ctxt(void); 513 514 void qdf_timer_module_init(void); 515 void qdf_timer_module_deinit(void); 516 void cds_ssr_protect_init(void); 517 int cds_get_gfp_flags(void); 518 519 /** 520 * cds_shutdown_notifier_register() - Register for shutdown notification 521 * @cb : Call back to be called 522 * @priv : Private pointer to be passed back to call back 523 * 524 * During driver remove or shutdown (recovery), external threads might be stuck 525 * waiting on some event from firmware at lower layers. Remove or shutdown can't 526 * proceed till the thread completes to avoid any race condition. Call backs can 527 * be registered here to get early notification of remove or shutdown so that 528 * waiting thread can be unblocked and hence remove or shutdown can proceed 529 * further as waiting there may not make sense when FW may already have been 530 * down. 531 * 532 * Return: CDS status 533 */ 534 QDF_STATUS cds_shutdown_notifier_register(void (*cb)(void *priv), void *priv); 535 536 /** 537 * cds_shutdown_notifier_purge() - Purge all the notifiers 538 * 539 * Shutdown notifiers are added to provide the early notification of remove or 540 * shutdown being initiated. Adding this API to purge all the registered call 541 * backs as they are not useful any more while all the lower layers are being 542 * shutdown. 543 * 544 * Return: None 545 */ 546 void cds_shutdown_notifier_purge(void); 547 548 /** 549 * cds_shutdown_notifier_call() - Call shutdown notifier call back 550 * 551 * Call registered shutdown notifier call back to indicate about remove or 552 * shutdown. 553 */ 554 void cds_shutdown_notifier_call(void); 555 556 /** 557 * cds_resume_rx_thread() - resume rx thread by completing its resume event 558 * 559 * Resume RX thread by completing RX thread resume event 560 * 561 * Return: None 562 */ 563 void cds_resume_rx_thread(void); 564 565 #endif /* #ifndef __CDS_SCHED_H */ 566