xref: /wlan-dirver/qca-wifi-host-cmn/qdf/inc/qdf_defer.h (revision cd39549564686e1d60a410c477b7c6e9e19791fd)
1 /*
2  * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
3  *
4  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5  *
6  *
7  * Permission to use, copy, modify, and/or distribute this software for
8  * any purpose with or without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19  * PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * This file was originally distributed by Qualcomm Atheros, Inc.
24  * under proprietary terms before Copyright ownership was assigned
25  * to the Linux Foundation.
26  */
27 
28 /**
29  * DOC: qdf_defer.h
30  * This file abstracts deferred execution API's.
31  */
32 
33 #ifndef __QDF_DEFER_H
34 #define __QDF_DEFER_H
35 
36 #include <qdf_types.h>
37 #include <i_qdf_defer.h>
38 
39 /**
40  * TODO This implements work queues (worker threads, kernel threads etc.).
41  * Note that there is no cancel on a scheduled work. You cannot free a work
42  * item if its queued. You cannot know if a work item is queued or not unless
43  * its running, hence you know its not queued.
44  *
45  * so if, say, a module is asked to unload itself, how exactly will it make
46  * sure that the work's not queued, for OS'es that dont provide such a
47  * mechanism??
48  */
49 
50 /*
51  * Representation of a work queue.
52  */
53 typedef __qdf_work_t     qdf_work_t;
54 typedef __qdf_delayed_work_t qdf_delayed_work_t;
55 typedef __qdf_workqueue_t     qdf_workqueue_t;
56 
57 /*
58  * Representation of a bottom half.
59  */
60 typedef __qdf_bh_t       qdf_bh_t;
61 
62 /**
63  * qdf_create_bh - creates the bottom half deferred handler
64  * @hdl: os handle
65  * @bh: pointer to bottom
66  * @func: deferred function to run at bottom half interrupt context.
67  * @arg: argument for the deferred function
68  * Return: none
69  */
70 static inline void qdf_create_bh(qdf_handle_t  hdl, qdf_bh_t  *bh,
71 				 qdf_defer_fn_t  func, void  *arg)
72 {
73 	__qdf_init_bh(hdl, bh, func, arg);
74 }
75 
76 /**
77  * qdf_sched - schedule a bottom half (DPC)
78  * @hdl: OS handle
79  * @bh: pointer to bottom
80  * Return: none
81  */
82 static inline void qdf_sched_bh(qdf_handle_t hdl, qdf_bh_t *bh)
83 {
84 	__qdf_sched_bh(hdl, bh);
85 }
86 
87 /**
88  * qdf_destroy_bh - destroy the bh (synchronous)
89  * @hdl: OS handle
90  * @bh: pointer to bottom
91  * Return: none
92  */
93 static inline void qdf_destroy_bh(qdf_handle_t hdl, qdf_bh_t *bh)
94 {
95 	__qdf_disable_bh(hdl, bh);
96 }
97 
98 /*********************Non-Interrupt Context deferred Execution***************/
99 
100 /**
101  * qdf_create_work - create a work/task queue, This runs in non-interrupt
102  * context, so can be preempted by H/W & S/W intr
103  * @hdl: OS handle
104  * @work: pointer to work
105  * @func: deferred function to run at bottom half non-interrupt context.
106  * @arg: argument for the deferred function
107  * Return: none
108  */
109 static inline void qdf_create_work(qdf_handle_t hdl, qdf_work_t  *work,
110 				   qdf_defer_fn_t  func, void  *arg)
111 {
112 	__qdf_init_work(hdl, work, func, arg);
113 }
114 
115 /**
116  * qdf_create_delayed_work - create a delayed work/task, This runs in
117  * non-interrupt context, so can be preempted by H/W & S/W intr
118  * @hdl: OS handle
119  * @work: pointer to work
120  * @func: deferred function to run at bottom half non-interrupt context.
121  * @arg: argument for the deferred function
122  * Return: none
123  */
124 static inline void qdf_create_delayed_work(qdf_handle_t hdl,
125 					   qdf_delayed_work_t  *work,
126 					   qdf_defer_fn_t  func, void  *arg)
127 {
128 	__qdf_init_delayed_work(hdl, work, func, arg);
129 }
130 
131 /**
132  * qdf_create_workqueue - create a workqueue, This runs in non-interrupt
133  * context, so can be preempted by H/W & S/W intr
134  * @name: string
135  * Return: pointer of type qdf_workqueue_t
136  */
137 static inline qdf_workqueue_t *qdf_create_workqueue(char *name)
138 {
139 	return  __qdf_create_workqueue(name);
140 }
141 
142 /**
143  * qdf_queue_work - Queue the work/task
144  * @hdl: OS handle
145  * @wqueue: pointer to workqueue
146  * @work: pointer to work
147  * Return: none
148  */
149 static inline void
150 qdf_queue_work(qdf_handle_t hdl, qdf_workqueue_t *wqueue, qdf_work_t *work)
151 {
152 	return  __qdf_queue_work(hdl, wqueue, work);
153 }
154 
155 /**
156  * qdf_queue_delayed_work - Queue the delayed work/task
157  * @hdl: OS handle
158  * @wqueue: pointer to workqueue
159  * @work: pointer to work
160  * @delay: delay interval
161  * Return: none
162  */
163 static inline void qdf_queue_delayed_work(qdf_handle_t hdl,
164 					  qdf_workqueue_t *wqueue,
165 					  qdf_delayed_work_t *work,
166 					  uint32_t delay)
167 {
168 	return  __qdf_queue_delayed_work(hdl, wqueue, work, delay);
169 }
170 
171 /**
172  * qdf_flush_workqueue - flush the workqueue
173  * @hdl: OS handle
174  * @wqueue: pointer to workqueue
175  * Return: none
176  */
177 static inline void qdf_flush_workqueue(qdf_handle_t hdl,
178 				       qdf_workqueue_t *wqueue)
179 {
180 	return  __qdf_flush_workqueue(hdl, wqueue);
181 }
182 
183 /**
184  * qdf_destroy_workqueue - Destroy the workqueue
185  * @hdl: OS handle
186  * @wqueue: pointer to workqueue
187  * Return: none
188  */
189 static inline void qdf_destroy_workqueue(qdf_handle_t hdl,
190 					 qdf_workqueue_t *wqueue)
191 {
192 	return  __qdf_destroy_workqueue(hdl, wqueue);
193 }
194 
195 /**
196  * qdf_sched_work - Schedule a deferred task on non-interrupt context
197  * @hdl: OS handle
198  * @work: pointer to work
199  * Retrun: none
200  */
201 static inline void qdf_sched_work(qdf_handle_t hdl, qdf_work_t *work)
202 {
203 	__qdf_sched_work(hdl, work);
204 }
205 
206 /**
207  * qdf_sched_delayed_work() - Schedule a delayed task
208  * @hdl: OS handle
209  * @work: pointer to delayed work
210  * @delay: delay interval
211  * Return: none
212  */
213 static inline void qdf_sched_delayed_work(qdf_handle_t hdl,
214 					  qdf_delayed_work_t *work,
215 					  uint32_t delay)
216 {
217 	__qdf_sched_delayed_work(hdl, work, delay);
218 }
219 
220 /**
221  * qdf_cancel_work() - Cancel a work
222  * @hdl: OS handle
223  * @work: pointer to work
224  *
225  * Cancel work and wait for its execution to finish.
226  * This function can be used even if the work re-queues
227  * itself or migrates to another workqueue. On return
228  * from this function, work is guaranteed to be not
229  * pending or executing on any CPU. The caller must
230  * ensure that the workqueue on which work was last
231  * queued can't be destroyed before this function returns.
232  *
233  * Return: true if work was pending, false otherwise
234  */
235 static inline bool qdf_cancel_work(qdf_handle_t hdl,
236 				   qdf_work_t *work)
237 {
238 	return __qdf_cancel_work(hdl, work);
239 }
240 
241 /**
242  * qdf_cancel_delayed_work() - Cancel a delayed work
243  * @hdl: OS handle
244  * @work: pointer to delayed work
245  *
246  * This is qdf_cancel_work for delayed works.
247  *
248  * Return: true if work was pending, false otherwise
249  */
250 static inline bool qdf_cancel_delayed_work(qdf_handle_t hdl,
251 					   qdf_delayed_work_t *work)
252 {
253 	return __qdf_cancel_delayed_work(hdl, work);
254 }
255 
256 /**
257  * qdf_flush_work - Flush a deferred task on non-interrupt context
258  * @hdl: OS handle
259  * @work: pointer to work
260  *
261  * Wait until work has finished execution. work is guaranteed to be
262  * idle on return if it hasn't been requeued since flush started.
263  *
264  * Return: none
265  */
266 static inline void qdf_flush_work(qdf_handle_t hdl, qdf_work_t *work)
267 {
268 	__qdf_flush_work(hdl, work);
269 }
270 
271 /**
272  * qdf_flush_delayed_work() - Flush a delayed work
273  * @hdl: OS handle
274  * @work: pointer to delayed work
275  *
276  * This is qdf_flush_work for delayed works.
277  *
278  * Return: none
279  */
280 static inline void qdf_flush_delayed_work(qdf_handle_t hdl,
281 					  qdf_delayed_work_t *work)
282 {
283 	__qdf_flush_delayed_work(hdl, work);
284 }
285 
286 /**
287  * qdf_disable_work - disable the deferred task (synchronous)
288  * @hdl: OS handle
289  * @work: pointer to work
290  * Return: unsigned int
291  */
292 static inline uint32_t qdf_disable_work(qdf_handle_t hdl, qdf_work_t *work)
293 {
294 	return __qdf_disable_work(hdl, work);
295 }
296 
297 /**
298  * qdf_destroy_work - destroy the deferred task (synchronous)
299  * @hdl: OS handle
300  * @work: pointer to work
301  * Return: none
302  */
303 static inline void qdf_destroy_work(qdf_handle_t hdl, qdf_work_t *work)
304 {
305 	__qdf_disable_work(hdl, work);
306 }
307 
308 #endif /*_QDF_DEFER_H*/
309