xref: /wlan-dirver/qca-wifi-host-cmn/qdf/inc/qdf_defer.h (revision 1397a33f48ea6455be40871470b286e535820eb8)
1 /*
2  * Copyright (c) 2014-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 /**
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_delayed_work_t qdf_delayed_work_t;
46 typedef __qdf_workqueue_t     qdf_workqueue_t;
47 
48 /*
49  * Representation of a bottom half.
50  */
51 typedef __qdf_bh_t       qdf_bh_t;
52 
53 /**
54  * qdf_create_bh - creates the bottom half deferred handler
55  * @bh: pointer to bottom
56  * @func: deferred function to run at bottom half interrupt context.
57  * @arg: argument for the deferred function
58  * Return: none
59  */
60 static inline void
61 qdf_create_bh(qdf_bh_t  *bh, qdf_defer_fn_t  func, void  *arg)
62 {
63 	__qdf_init_bh(bh, func, arg);
64 }
65 
66 /**
67  * qdf_sched - schedule a bottom half (DPC)
68  * @bh: pointer to bottom
69  * Return: none
70  */
71 static inline void qdf_sched_bh(qdf_bh_t *bh)
72 {
73 	__qdf_sched_bh(bh);
74 }
75 
76 /**
77  * qdf_destroy_bh - destroy the bh (synchronous)
78  * @bh: pointer to bottom
79  * Return: none
80  */
81 static inline void qdf_destroy_bh(qdf_bh_t *bh)
82 {
83 	__qdf_disable_bh(bh);
84 }
85 
86 /*********************Non-Interrupt Context deferred Execution***************/
87 
88 /**
89  * qdf_create_work - create a work/task queue, This runs in non-interrupt
90  * context, so can be preempted by H/W & S/W intr
91  * @hdl: OS handle
92  * @work: pointer to work
93  * @func: deferred function to run at bottom half non-interrupt context.
94  * @arg: argument for the deferred function
95  *
96  * Return: QDF status
97  */
98 static inline QDF_STATUS qdf_create_work(qdf_handle_t hdl, qdf_work_t  *work,
99 				   qdf_defer_fn_t  func, void  *arg)
100 {
101 	return __qdf_init_work(work, func, arg);
102 }
103 
104 /**
105  * qdf_create_delayed_work - create a delayed work/task, This runs in
106  * non-interrupt context, so can be preempted by H/W & S/W intr
107  * @work: pointer to work
108  * @func: deferred function to run at bottom half non-interrupt context.
109  * @arg: argument for the deferred function
110  * Return: none
111  */
112 static inline void qdf_create_delayed_work(qdf_delayed_work_t *work,
113 					   qdf_defer_fn_t func,
114 					   void *arg)
115 {
116 	__qdf_init_delayed_work(work, func, arg);
117 }
118 
119 /**
120  * qdf_create_workqueue - create a workqueue, This runs in non-interrupt
121  * context, so can be preempted by H/W & S/W intr
122  * @name: string
123  * Return: pointer of type qdf_workqueue_t
124  */
125 static inline qdf_workqueue_t *qdf_create_workqueue(char *name)
126 {
127 	return  __qdf_create_workqueue(name);
128 }
129 
130 /**
131  * qdf_create_singlethread_workqueue() - create a single threaded workqueue
132  * @name: string
133  *
134  * This API creates a dedicated work queue with a single worker thread to avoid
135  * wasting unnecessary resources when works which needs to be submitted in this
136  * queue are not very critical and frequent.
137  *
138  * Return: pointer of type qdf_workqueue_t
139  */
140 static inline qdf_workqueue_t *qdf_create_singlethread_workqueue(char *name)
141 {
142 	return  __qdf_create_singlethread_workqueue(name);
143 }
144 
145 /**
146  * qdf_alloc_unbound_workqueue - allocate an unbound workqueue
147  * @name: string
148  *
149  * Return: pointer of type qdf_workqueue_t
150  */
151 static inline qdf_workqueue_t *qdf_alloc_unbound_workqueue(char *name)
152 {
153 	return  __qdf_alloc_unbound_workqueue(name);
154 }
155 
156 /**
157  * qdf_queue_work - Queue the work/task
158  * @hdl: OS handle
159  * @wqueue: pointer to workqueue
160  * @work: pointer to work
161  * Return: none
162  */
163 static inline void
164 qdf_queue_work(qdf_handle_t hdl, qdf_workqueue_t *wqueue, qdf_work_t *work)
165 {
166 	return  __qdf_queue_work(wqueue, work);
167 }
168 
169 /**
170  * qdf_queue_delayed_work - Queue the delayed work/task
171  * @wqueue: pointer to workqueue
172  * @work: pointer to work
173  * @delay: delay interval in milliseconds
174  * Return: none
175  */
176 static inline void qdf_queue_delayed_work(qdf_workqueue_t *wqueue,
177 					  qdf_delayed_work_t *work,
178 					  uint32_t delay)
179 {
180 	return  __qdf_queue_delayed_work(wqueue, work, delay);
181 }
182 
183 /**
184  * qdf_flush_workqueue - flush the workqueue
185  * @hdl: OS handle
186  * @wqueue: pointer to workqueue
187  * Return: none
188  */
189 static inline void qdf_flush_workqueue(qdf_handle_t hdl,
190 				       qdf_workqueue_t *wqueue)
191 {
192 	return  __qdf_flush_workqueue(wqueue);
193 }
194 
195 /**
196  * qdf_destroy_workqueue - Destroy the workqueue
197  * @hdl: OS handle
198  * @wqueue: pointer to workqueue
199  * Return: none
200  */
201 static inline void qdf_destroy_workqueue(qdf_handle_t hdl,
202 					 qdf_workqueue_t *wqueue)
203 {
204 	return  __qdf_destroy_workqueue(wqueue);
205 }
206 
207 /**
208  * qdf_sched_work - Schedule a deferred task on non-interrupt context
209  * @hdl: OS handle
210  * @work: pointer to work
211  * Retrun: none
212  */
213 static inline void qdf_sched_work(qdf_handle_t hdl, qdf_work_t *work)
214 {
215 	__qdf_sched_work(work);
216 }
217 
218 /**
219  * qdf_sched_delayed_work() - Schedule a delayed task
220  * @work: pointer to delayed work
221  * @delay: delay interval in milliseconds
222  * Return: none
223  */
224 static inline void
225 qdf_sched_delayed_work(qdf_delayed_work_t *work, uint32_t delay)
226 {
227 	__qdf_sched_delayed_work(work, delay);
228 }
229 
230 /**
231  * qdf_cancel_work() - Cancel a work
232  * @work: pointer to work
233  *
234  * Cancel work and wait for its execution to finish.
235  * This function can be used even if the work re-queues
236  * itself or migrates to another workqueue. On return
237  * from this function, work is guaranteed to be not
238  * pending or executing on any CPU. The caller must
239  * ensure that the workqueue on which work was last
240  * queued can't be destroyed before this function returns.
241  *
242  * Return: true if work was pending, false otherwise
243  */
244 static inline bool qdf_cancel_work(qdf_work_t *work)
245 {
246 	return __qdf_cancel_work(work);
247 }
248 
249 /**
250  * qdf_cancel_delayed_work() - Cancel a delayed work
251  * @work: pointer to delayed work
252  *
253  * This is qdf_cancel_work for delayed works.
254  *
255  * Return: true if work was pending, false otherwise
256  */
257 static inline bool qdf_cancel_delayed_work(qdf_delayed_work_t *work)
258 {
259 	return __qdf_cancel_delayed_work(work);
260 }
261 
262 /**
263  * qdf_flush_work - Flush a deferred task on non-interrupt context
264  * @work: pointer to work
265  *
266  * Wait until work has finished execution. work is guaranteed to be
267  * idle on return if it hasn't been requeued since flush started.
268  *
269  * Return: none
270  */
271 static inline void qdf_flush_work(qdf_work_t *work)
272 {
273 	__qdf_flush_work(work);
274 }
275 
276 /**
277  * qdf_flush_delayed_work() - Flush a delayed work
278  * @work: pointer to delayed work
279  *
280  * This is qdf_flush_work for delayed works.
281  *
282  * Return: none
283  */
284 static inline void qdf_flush_delayed_work(qdf_delayed_work_t *work)
285 {
286 	__qdf_flush_delayed_work(work);
287 }
288 
289 /**
290  * qdf_disable_work - disable the deferred task (synchronous)
291  * @work: pointer to work
292  * Return: unsigned int
293  */
294 static inline uint32_t qdf_disable_work(qdf_work_t *work)
295 {
296 	return __qdf_disable_work(work);
297 }
298 
299 /**
300  * qdf_destroy_work - destroy the deferred task (synchronous)
301  * @hdl: OS handle
302  * @work: pointer to work
303  * Return: none
304  */
305 static inline void qdf_destroy_work(qdf_handle_t hdl, qdf_work_t *work)
306 {
307 	__qdf_disable_work(work);
308 }
309 
310 #endif /*_QDF_DEFER_H*/
311