xref: /wlan-dirver/qcacld-3.0/core/cds/inc/cds_sched.h (revision eff16d956b6c25bc860fac91ea57d737c47dd7a7)
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