qdf_defer.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /*
  2. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
  3. * Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for
  6. * any purpose with or without fee is hereby granted, provided that the
  7. * above copyright notice and this permission notice appear in all
  8. * copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  13. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  14. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  15. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  16. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. * PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. /**
  20. * DOC: qdf_defer.h
  21. * This file abstracts deferred execution API's.
  22. */
  23. #ifndef __QDF_DEFER_H
  24. #define __QDF_DEFER_H
  25. #include <qdf_types.h>
  26. #include <i_qdf_defer.h>
  27. /*
  28. * TODO This implements work queues (worker threads, kernel threads etc.).
  29. * Note that there is no cancel on a scheduled work. You cannot free a work
  30. * item if its queued. You cannot know if a work item is queued or not unless
  31. * its running, hence you know its not queued.
  32. *
  33. * so if, say, a module is asked to unload itself, how exactly will it make
  34. * sure that the work's not queued, for OS'es that dont provide such a
  35. * mechanism??
  36. */
  37. /*
  38. * Representation of a work queue.
  39. */
  40. typedef __qdf_work_t qdf_work_t;
  41. typedef __qdf_workqueue_t qdf_workqueue_t;
  42. /*
  43. * Representation of a bottom half.
  44. */
  45. typedef __qdf_bh_t qdf_bh_t;
  46. #ifdef ENHANCED_OS_ABSTRACTION
  47. /**
  48. * qdf_create_bh - creates the bottom half deferred handler
  49. * @bh: pointer to bottom
  50. * @func: deferred function to run at bottom half interrupt context.
  51. * @arg: argument for the deferred function
  52. * Return: none
  53. */
  54. void
  55. qdf_create_bh(qdf_bh_t *bh, qdf_defer_fn_t func, void *arg);
  56. /**
  57. * qdf_sched_bh - schedule a bottom half (DPC)
  58. * @bh: pointer to bottom
  59. * Return: none
  60. */
  61. void qdf_sched_bh(qdf_bh_t *bh);
  62. /**
  63. * qdf_destroy_bh - destroy the bh (synchronous)
  64. * @bh: pointer to bottom
  65. * Return: none
  66. */
  67. void qdf_destroy_bh(qdf_bh_t *bh);
  68. /**
  69. * qdf_create_workqueue - create a workqueue, This runs in non-interrupt
  70. * context, so can be preempted by H/W & S/W intr
  71. * @name: string
  72. *
  73. * Return: pointer of type qdf_workqueue_t
  74. */
  75. qdf_workqueue_t *qdf_create_workqueue(char *name);
  76. /**
  77. * qdf_create_singlethread_workqueue() - create a single threaded workqueue
  78. * @name: string
  79. *
  80. * This API creates a dedicated work queue with a single worker thread to avoid
  81. * wasting unnecessary resources when works which needs to be submitted in this
  82. * queue are not very critical and frequent.
  83. *
  84. * Return: pointer of type qdf_workqueue_t
  85. */
  86. qdf_workqueue_t *qdf_create_singlethread_workqueue(char *name);
  87. /**
  88. * qdf_alloc_unbound_workqueue - allocate an unbound workqueue
  89. * @name: string
  90. *
  91. * Return: pointer of type qdf_workqueue_t
  92. */
  93. qdf_workqueue_t *qdf_alloc_unbound_workqueue(char *name);
  94. /**
  95. * qdf_destroy_workqueue - Destroy the workqueue
  96. * @hdl: OS handle
  97. * @wqueue: pointer to workqueue
  98. *
  99. * Return: none
  100. */
  101. void qdf_destroy_workqueue(qdf_handle_t hdl, qdf_workqueue_t *wqueue);
  102. /**
  103. * qdf_cancel_work() - Cancel a work
  104. * @work: pointer to work
  105. *
  106. * Cancel work and wait for its execution to finish.
  107. * This function can be used even if the work re-queues
  108. * itself or migrates to another workqueue. On return
  109. * from this function, work is guaranteed to be not
  110. * pending or executing on any CPU. The caller must
  111. * ensure that the workqueue on which work was last
  112. * queued can't be destroyed before this function returns.
  113. *
  114. * Return: true if work was pending, false otherwise
  115. */
  116. bool qdf_cancel_work(qdf_work_t *work);
  117. /**
  118. * qdf_disable_work - disable the deferred task (synchronous)
  119. * @work: pointer to work
  120. *
  121. * Return: unsigned int
  122. */
  123. uint32_t qdf_disable_work(qdf_work_t *work);
  124. /**
  125. * qdf_flush_work - Flush a deferred task on non-interrupt context
  126. * @work: pointer to work
  127. *
  128. * Wait until work has finished execution. work is guaranteed to be
  129. * idle on return if it hasn't been requeued since flush started.
  130. *
  131. * Return: none
  132. */
  133. void qdf_flush_work(qdf_work_t *work);
  134. /**
  135. * qdf_create_work - create a work/task queue, This runs in non-interrupt
  136. * context, so can be preempted by H/W & S/W intr
  137. * @hdl: OS handle
  138. * @work: pointer to work
  139. * @func: deferred function to run at bottom half non-interrupt context.
  140. * @arg: argument for the deferred function
  141. *
  142. * Return: QDF status
  143. */
  144. QDF_STATUS qdf_create_work(qdf_handle_t hdl, qdf_work_t *work,
  145. qdf_defer_fn_t func, void *arg);
  146. /**
  147. * qdf_sched_work - Schedule a deferred task on non-interrupt context
  148. * @hdl: OS handle
  149. * @work: pointer to work
  150. *
  151. * Return: false if work was already on a queue, true otherwise
  152. */
  153. bool qdf_sched_work(qdf_handle_t hdl, qdf_work_t *work);
  154. /**
  155. * qdf_queue_work - Queue the work/task
  156. * @hdl: OS handle
  157. * @wqueue: pointer to workqueue
  158. * @work: pointer to work
  159. *
  160. * Return: false if work was already on a queue, true otherwise
  161. */
  162. bool
  163. qdf_queue_work(qdf_handle_t hdl, qdf_workqueue_t *wqueue, qdf_work_t *work);
  164. /**
  165. * qdf_flush_workqueue - flush the workqueue
  166. * @hdl: OS handle
  167. * @wqueue: pointer to workqueue
  168. *
  169. * Return: none
  170. */
  171. void qdf_flush_workqueue(qdf_handle_t hdl, qdf_workqueue_t *wqueue);
  172. /**
  173. * qdf_destroy_work - destroy the deferred task (synchronous)
  174. * @hdl: OS handle
  175. * @work: pointer to work
  176. *
  177. * Return: none
  178. */
  179. void qdf_destroy_work(qdf_handle_t hdl, qdf_work_t *work);
  180. /**
  181. * qdf_local_bh_disable - Disables softirq and tasklet processing
  182. * on the local processor
  183. *
  184. * Return: none
  185. */
  186. void qdf_local_bh_disable(void);
  187. /**
  188. * qdf_local_bh_enable - Disables softirq and tasklet processing
  189. * on the local processor
  190. *
  191. * Return: none
  192. */
  193. void qdf_local_bh_enable(void);
  194. #else
  195. /**
  196. * qdf_create_bh - creates the bottom half deferred handler
  197. * @bh: pointer to bottom
  198. * @func: deferred function to run at bottom half interrupt context.
  199. * @arg: argument for the deferred function
  200. * Return: none
  201. */
  202. static inline void
  203. qdf_create_bh(qdf_bh_t *bh, qdf_defer_fn_t func, void *arg)
  204. {
  205. __qdf_init_bh(bh, func, arg);
  206. }
  207. /**
  208. * qdf_sched_bh - schedule a bottom half (DPC)
  209. * @bh: pointer to bottom
  210. * Return: none
  211. */
  212. static inline void qdf_sched_bh(qdf_bh_t *bh)
  213. {
  214. __qdf_sched_bh(bh);
  215. }
  216. /**
  217. * qdf_destroy_bh - destroy the bh (synchronous)
  218. * @bh: pointer to bottom
  219. * Return: none
  220. */
  221. static inline void qdf_destroy_bh(qdf_bh_t *bh)
  222. {
  223. __qdf_disable_bh(bh);
  224. }
  225. /**
  226. * qdf_local_bh_disable - Disables softirq and tasklet processing
  227. * on the local processor
  228. *
  229. * Return: none
  230. */
  231. static inline void qdf_local_bh_disable(void)
  232. {
  233. __qdf_local_bh_disable();
  234. }
  235. /**
  236. * qdf_local_bh_enable - Enables softirq and tasklet processing
  237. * on the local processor
  238. *
  239. * Return: none
  240. */
  241. static inline void qdf_local_bh_enable(void)
  242. {
  243. __qdf_local_bh_enable();
  244. }
  245. /*********************Non-Interrupt Context deferred Execution***************/
  246. /**
  247. * qdf_create_work - create a work/task queue, This runs in non-interrupt
  248. * context, so can be preempted by H/W & S/W intr
  249. * @hdl: OS handle
  250. * @work: pointer to work
  251. * @func: deferred function to run at bottom half non-interrupt context.
  252. * @arg: argument for the deferred function
  253. *
  254. * Return: QDF status
  255. */
  256. static inline QDF_STATUS qdf_create_work(qdf_handle_t hdl, qdf_work_t *work,
  257. qdf_defer_fn_t func, void *arg)
  258. {
  259. return __qdf_init_work(work, func, arg);
  260. }
  261. /**
  262. * qdf_create_workqueue - create a workqueue, This runs in non-interrupt
  263. * context, so can be preempted by H/W & S/W intr
  264. * @name: string
  265. * Return: pointer of type qdf_workqueue_t
  266. */
  267. static inline qdf_workqueue_t *qdf_create_workqueue(char *name)
  268. {
  269. return __qdf_create_workqueue(name);
  270. }
  271. /**
  272. * qdf_create_singlethread_workqueue() - create a single threaded workqueue
  273. * @name: string
  274. *
  275. * This API creates a dedicated work queue with a single worker thread to avoid
  276. * wasting unnecessary resources when works which needs to be submitted in this
  277. * queue are not very critical and frequent.
  278. *
  279. * Return: pointer of type qdf_workqueue_t
  280. */
  281. static inline qdf_workqueue_t *qdf_create_singlethread_workqueue(char *name)
  282. {
  283. return __qdf_create_singlethread_workqueue(name);
  284. }
  285. /**
  286. * qdf_alloc_high_prior_ordered_workqueue - alloc high-prior ordered workqueue
  287. * @name: string
  288. *
  289. * Return: pointer of type qdf_workqueue_t
  290. */
  291. static inline
  292. qdf_workqueue_t *qdf_alloc_high_prior_ordered_workqueue(char *name)
  293. {
  294. return __qdf_alloc_high_prior_ordered_workqueue(name);
  295. }
  296. /**
  297. * qdf_alloc_unbound_workqueue - allocate an unbound workqueue
  298. * @name: string
  299. *
  300. * Return: pointer of type qdf_workqueue_t
  301. */
  302. static inline qdf_workqueue_t *qdf_alloc_unbound_workqueue(char *name)
  303. {
  304. return __qdf_alloc_unbound_workqueue(name);
  305. }
  306. /**
  307. * qdf_queue_work - Queue the work/task
  308. * @hdl: OS handle
  309. * @wqueue: pointer to workqueue
  310. * @work: pointer to work
  311. * Return: false if work was already on a queue, true otherwise
  312. */
  313. static inline bool
  314. qdf_queue_work(qdf_handle_t hdl, qdf_workqueue_t *wqueue, qdf_work_t *work)
  315. {
  316. return __qdf_queue_work(wqueue, work);
  317. }
  318. /**
  319. * qdf_flush_workqueue - flush the workqueue
  320. * @hdl: OS handle
  321. * @wqueue: pointer to workqueue
  322. * Return: none
  323. */
  324. static inline void qdf_flush_workqueue(qdf_handle_t hdl,
  325. qdf_workqueue_t *wqueue)
  326. {
  327. return __qdf_flush_workqueue(wqueue);
  328. }
  329. /**
  330. * qdf_destroy_workqueue - Destroy the workqueue
  331. * @hdl: OS handle
  332. * @wqueue: pointer to workqueue
  333. * Return: none
  334. */
  335. static inline void qdf_destroy_workqueue(qdf_handle_t hdl,
  336. qdf_workqueue_t *wqueue)
  337. {
  338. return __qdf_destroy_workqueue(wqueue);
  339. }
  340. /**
  341. * qdf_sched_work - Schedule a deferred task on non-interrupt context
  342. * @hdl: OS handle
  343. * @work: pointer to work
  344. *
  345. * Return: false if work was already on a queue, true otherwise
  346. */
  347. static inline bool qdf_sched_work(qdf_handle_t hdl, qdf_work_t *work)
  348. {
  349. return __qdf_sched_work(work);
  350. }
  351. /**
  352. * qdf_cancel_work() - Cancel a work
  353. * @work: pointer to work
  354. *
  355. * Cancel work and wait for its execution to finish.
  356. * This function can be used even if the work re-queues
  357. * itself or migrates to another workqueue. On return
  358. * from this function, work is guaranteed to be not
  359. * pending or executing on any CPU. The caller must
  360. * ensure that the workqueue on which work was last
  361. * queued can't be destroyed before this function returns.
  362. *
  363. * Return: true if work was pending, false otherwise
  364. */
  365. static inline bool qdf_cancel_work(qdf_work_t *work)
  366. {
  367. return __qdf_cancel_work(work);
  368. }
  369. /**
  370. * qdf_flush_work - Flush a deferred task on non-interrupt context
  371. * @work: pointer to work
  372. *
  373. * Wait until work has finished execution. work is guaranteed to be
  374. * idle on return if it hasn't been requeued since flush started.
  375. *
  376. * Return: none
  377. */
  378. static inline void qdf_flush_work(qdf_work_t *work)
  379. {
  380. __qdf_flush_work(work);
  381. }
  382. /**
  383. * qdf_disable_work - disable the deferred task (synchronous)
  384. * @work: pointer to work
  385. * Return: unsigned int
  386. */
  387. static inline uint32_t qdf_disable_work(qdf_work_t *work)
  388. {
  389. return __qdf_disable_work(work);
  390. }
  391. /**
  392. * qdf_destroy_work - destroy the deferred task (synchronous)
  393. * @hdl: OS handle
  394. * @work: pointer to work
  395. * Return: none
  396. */
  397. static inline void qdf_destroy_work(qdf_handle_t hdl, qdf_work_t *work)
  398. {
  399. __qdf_disable_work(work);
  400. }
  401. #endif
  402. #endif /*_QDF_DEFER_H*/