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