xref: /wlan-dirver/qca-wifi-host-cmn/qdf/inc/qdf_defer.h (revision 4865edfd190c086bbe2c69aae12a8226f877b91e)
1 /*
2  * Copyright (c) 2014-2017 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_queue_work - Queue the work/task
147  * @hdl: OS handle
148  * @wqueue: pointer to workqueue
149  * @work: pointer to work
150  * Return: none
151  */
152 static inline void
153 qdf_queue_work(qdf_handle_t hdl, qdf_workqueue_t *wqueue, qdf_work_t *work)
154 {
155 	return  __qdf_queue_work(wqueue, work);
156 }
157 
158 /**
159  * qdf_queue_delayed_work - Queue the delayed work/task
160  * @wqueue: pointer to workqueue
161  * @work: pointer to work
162  * @delay: delay interval in milliseconds
163  * Return: none
164  */
165 static inline void qdf_queue_delayed_work(qdf_workqueue_t *wqueue,
166 					  qdf_delayed_work_t *work,
167 					  uint32_t delay)
168 {
169 	return  __qdf_queue_delayed_work(wqueue, work, delay);
170 }
171 
172 /**
173  * qdf_flush_workqueue - flush the workqueue
174  * @hdl: OS handle
175  * @wqueue: pointer to workqueue
176  * Return: none
177  */
178 static inline void qdf_flush_workqueue(qdf_handle_t hdl,
179 				       qdf_workqueue_t *wqueue)
180 {
181 	return  __qdf_flush_workqueue(wqueue);
182 }
183 
184 /**
185  * qdf_destroy_workqueue - Destroy the workqueue
186  * @hdl: OS handle
187  * @wqueue: pointer to workqueue
188  * Return: none
189  */
190 static inline void qdf_destroy_workqueue(qdf_handle_t hdl,
191 					 qdf_workqueue_t *wqueue)
192 {
193 	return  __qdf_destroy_workqueue(wqueue);
194 }
195 
196 /**
197  * qdf_sched_work - Schedule a deferred task on non-interrupt context
198  * @hdl: OS handle
199  * @work: pointer to work
200  * Retrun: none
201  */
202 static inline void qdf_sched_work(qdf_handle_t hdl, qdf_work_t *work)
203 {
204 	__qdf_sched_work(work);
205 }
206 
207 /**
208  * qdf_sched_delayed_work() - Schedule a delayed task
209  * @work: pointer to delayed work
210  * @delay: delay interval in milliseconds
211  * Return: none
212  */
213 static inline void
214 qdf_sched_delayed_work(qdf_delayed_work_t *work, uint32_t delay)
215 {
216 	__qdf_sched_delayed_work(work, delay);
217 }
218 
219 /**
220  * qdf_cancel_work() - Cancel a work
221  * @work: pointer to work
222  *
223  * Cancel work and wait for its execution to finish.
224  * This function can be used even if the work re-queues
225  * itself or migrates to another workqueue. On return
226  * from this function, work is guaranteed to be not
227  * pending or executing on any CPU. The caller must
228  * ensure that the workqueue on which work was last
229  * queued can't be destroyed before this function returns.
230  *
231  * Return: true if work was pending, false otherwise
232  */
233 static inline bool qdf_cancel_work(qdf_work_t *work)
234 {
235 	return __qdf_cancel_work(work);
236 }
237 
238 /**
239  * qdf_cancel_delayed_work() - Cancel a delayed work
240  * @work: pointer to delayed work
241  *
242  * This is qdf_cancel_work for delayed works.
243  *
244  * Return: true if work was pending, false otherwise
245  */
246 static inline bool qdf_cancel_delayed_work(qdf_delayed_work_t *work)
247 {
248 	return __qdf_cancel_delayed_work(work);
249 }
250 
251 /**
252  * qdf_flush_work - Flush a deferred task on non-interrupt context
253  * @work: pointer to work
254  *
255  * Wait until work has finished execution. work is guaranteed to be
256  * idle on return if it hasn't been requeued since flush started.
257  *
258  * Return: none
259  */
260 static inline void qdf_flush_work(qdf_work_t *work)
261 {
262 	__qdf_flush_work(work);
263 }
264 
265 /**
266  * qdf_flush_delayed_work() - Flush a delayed work
267  * @work: pointer to delayed work
268  *
269  * This is qdf_flush_work for delayed works.
270  *
271  * Return: none
272  */
273 static inline void qdf_flush_delayed_work(qdf_delayed_work_t *work)
274 {
275 	__qdf_flush_delayed_work(work);
276 }
277 
278 /**
279  * qdf_disable_work - disable the deferred task (synchronous)
280  * @work: pointer to work
281  * Return: unsigned int
282  */
283 static inline uint32_t qdf_disable_work(qdf_work_t *work)
284 {
285 	return __qdf_disable_work(work);
286 }
287 
288 /**
289  * qdf_destroy_work - destroy the deferred task (synchronous)
290  * @hdl: OS handle
291  * @work: pointer to work
292  * Return: none
293  */
294 static inline void qdf_destroy_work(qdf_handle_t hdl, qdf_work_t *work)
295 {
296 	__qdf_disable_work(work);
297 }
298 
299 #endif /*_QDF_DEFER_H*/
300