xref: /wlan-dirver/qca-wifi-host-cmn/qdf/inc/qdf_defer.h (revision a86b23ee68a2491aede2e03991f3fb37046f4e41)
1 /*
2  * Copyright (c) 2014-2020 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 /**
20  * DOC: qdf_defer.h
21  * This file abstracts deferred execution API's.
22  */
23 
24 #ifndef __QDF_DEFER_H
25 #define __QDF_DEFER_H
26 
27 #include <qdf_types.h>
28 #include <i_qdf_defer.h>
29 
30 /**
31  * TODO This implements work queues (worker threads, kernel threads etc.).
32  * Note that there is no cancel on a scheduled work. You cannot free a work
33  * item if its queued. You cannot know if a work item is queued or not unless
34  * its running, hence you know its not queued.
35  *
36  * so if, say, a module is asked to unload itself, how exactly will it make
37  * sure that the work's not queued, for OS'es that dont provide such a
38  * mechanism??
39  */
40 
41 /*
42  * Representation of a work queue.
43  */
44 typedef __qdf_work_t     qdf_work_t;
45 typedef __qdf_workqueue_t     qdf_workqueue_t;
46 
47 /*
48  * Representation of a bottom half.
49  */
50 typedef __qdf_bh_t       qdf_bh_t;
51 
52 /**
53  * qdf_create_bh - creates the bottom half deferred handler
54  * @bh: pointer to bottom
55  * @func: deferred function to run at bottom half interrupt context.
56  * @arg: argument for the deferred function
57  * Return: none
58  */
59 static inline void
60 qdf_create_bh(qdf_bh_t  *bh, qdf_defer_fn_t  func, void  *arg)
61 {
62 	__qdf_init_bh(bh, func, arg);
63 }
64 
65 /**
66  * qdf_sched - schedule a bottom half (DPC)
67  * @bh: pointer to bottom
68  * Return: none
69  */
70 static inline void qdf_sched_bh(qdf_bh_t *bh)
71 {
72 	__qdf_sched_bh(bh);
73 }
74 
75 /**
76  * qdf_destroy_bh - destroy the bh (synchronous)
77  * @bh: pointer to bottom
78  * Return: none
79  */
80 static inline void qdf_destroy_bh(qdf_bh_t *bh)
81 {
82 	__qdf_disable_bh(bh);
83 }
84 
85 /*********************Non-Interrupt Context deferred Execution***************/
86 
87 /**
88  * qdf_create_work - create a work/task queue, This runs in non-interrupt
89  * context, so can be preempted by H/W & S/W intr
90  * @hdl: OS handle
91  * @work: pointer to work
92  * @func: deferred function to run at bottom half non-interrupt context.
93  * @arg: argument for the deferred function
94  *
95  * Return: QDF status
96  */
97 static inline QDF_STATUS qdf_create_work(qdf_handle_t hdl, qdf_work_t  *work,
98 				   qdf_defer_fn_t  func, void  *arg)
99 {
100 	return __qdf_init_work(work, func, arg);
101 }
102 
103 /**
104  * qdf_create_workqueue - create a workqueue, This runs in non-interrupt
105  * context, so can be preempted by H/W & S/W intr
106  * @name: string
107  * Return: pointer of type qdf_workqueue_t
108  */
109 static inline qdf_workqueue_t *qdf_create_workqueue(char *name)
110 {
111 	return  __qdf_create_workqueue(name);
112 }
113 
114 /**
115  * qdf_create_singlethread_workqueue() - create a single threaded workqueue
116  * @name: string
117  *
118  * This API creates a dedicated work queue with a single worker thread to avoid
119  * wasting unnecessary resources when works which needs to be submitted in this
120  * queue are not very critical and frequent.
121  *
122  * Return: pointer of type qdf_workqueue_t
123  */
124 static inline qdf_workqueue_t *qdf_create_singlethread_workqueue(char *name)
125 {
126 	return  __qdf_create_singlethread_workqueue(name);
127 }
128 
129 /**
130  * qdf_alloc_high_prior_ordered_workqueue - alloc high-prior ordered workqueue
131  * @name: string
132  *
133  * Return: pointer of type qdf_workqueue_t
134  */
135 static inline
136 qdf_workqueue_t *qdf_alloc_high_prior_ordered_workqueue(char *name)
137 {
138 	return __qdf_alloc_high_prior_ordered_workqueue(name);
139 }
140 
141 /**
142  * qdf_alloc_unbound_workqueue - allocate an unbound workqueue
143  * @name: string
144  *
145  * Return: pointer of type qdf_workqueue_t
146  */
147 static inline qdf_workqueue_t *qdf_alloc_unbound_workqueue(char *name)
148 {
149 	return  __qdf_alloc_unbound_workqueue(name);
150 }
151 
152 /**
153  * qdf_queue_work - Queue the work/task
154  * @hdl: OS handle
155  * @wqueue: pointer to workqueue
156  * @work: pointer to work
157  * Return: none
158  */
159 static inline void
160 qdf_queue_work(qdf_handle_t hdl, qdf_workqueue_t *wqueue, qdf_work_t *work)
161 {
162 	return  __qdf_queue_work(wqueue, work);
163 }
164 
165 /**
166  * qdf_flush_workqueue - flush the workqueue
167  * @hdl: OS handle
168  * @wqueue: pointer to workqueue
169  * Return: none
170  */
171 static inline void qdf_flush_workqueue(qdf_handle_t hdl,
172 				       qdf_workqueue_t *wqueue)
173 {
174 	return  __qdf_flush_workqueue(wqueue);
175 }
176 
177 /**
178  * qdf_destroy_workqueue - Destroy the workqueue
179  * @hdl: OS handle
180  * @wqueue: pointer to workqueue
181  * Return: none
182  */
183 static inline void qdf_destroy_workqueue(qdf_handle_t hdl,
184 					 qdf_workqueue_t *wqueue)
185 {
186 	return  __qdf_destroy_workqueue(wqueue);
187 }
188 
189 /**
190  * qdf_sched_work - Schedule a deferred task on non-interrupt context
191  * @hdl: OS handle
192  * @work: pointer to work
193  * Retrun: none
194  */
195 static inline void qdf_sched_work(qdf_handle_t hdl, qdf_work_t *work)
196 {
197 	__qdf_sched_work(work);
198 }
199 
200 /**
201  * qdf_cancel_work() - Cancel a work
202  * @work: pointer to work
203  *
204  * Cancel work and wait for its execution to finish.
205  * This function can be used even if the work re-queues
206  * itself or migrates to another workqueue. On return
207  * from this function, work is guaranteed to be not
208  * pending or executing on any CPU. The caller must
209  * ensure that the workqueue on which work was last
210  * queued can't be destroyed before this function returns.
211  *
212  * Return: true if work was pending, false otherwise
213  */
214 static inline bool qdf_cancel_work(qdf_work_t *work)
215 {
216 	return __qdf_cancel_work(work);
217 }
218 
219 /**
220  * qdf_flush_work - Flush a deferred task on non-interrupt context
221  * @work: pointer to work
222  *
223  * Wait until work has finished execution. work is guaranteed to be
224  * idle on return if it hasn't been requeued since flush started.
225  *
226  * Return: none
227  */
228 static inline void qdf_flush_work(qdf_work_t *work)
229 {
230 	__qdf_flush_work(work);
231 }
232 
233 /**
234  * qdf_disable_work - disable the deferred task (synchronous)
235  * @work: pointer to work
236  * Return: unsigned int
237  */
238 static inline uint32_t qdf_disable_work(qdf_work_t *work)
239 {
240 	return __qdf_disable_work(work);
241 }
242 
243 /**
244  * qdf_destroy_work - destroy the deferred task (synchronous)
245  * @hdl: OS handle
246  * @work: pointer to work
247  * Return: none
248  */
249 static inline void qdf_destroy_work(qdf_handle_t hdl, qdf_work_t *work)
250 {
251 	__qdf_disable_work(work);
252 }
253 
254 #endif /*_QDF_DEFER_H*/
255