__wlan_dsc.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*
  2. * Copyright (c) 2018-2019, 2021 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. * DOC: Driver State Management (DSC) APIs for *internal* use
  20. */
  21. #ifndef ____WLAN_DSC_H
  22. #define ____WLAN_DSC_H
  23. #include "qdf_event.h"
  24. #include "qdf_list.h"
  25. #include "qdf_threads.h"
  26. #include "qdf_timer.h"
  27. #include "qdf_trace.h"
  28. #include "qdf_types.h"
  29. #include "wlan_dsc.h"
  30. #define dsc_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, params)
  31. #define dsc_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_QDF, params)
  32. #ifdef WLAN_DSC_DEBUG
  33. #define dsc_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_QDF, params)
  34. #else
  35. #define dsc_debug(params...) /* no-op */
  36. #endif
  37. #define dsc_nofl_err(params...) \
  38. QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_QDF, params)
  39. #define dsc_nofl_info(params...) \
  40. QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_QDF, params)
  41. #define dsc_nofl_debug(params...) \
  42. QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_QDF, params)
  43. #define dsc_enter_exit dsc_debug
  44. #define dsc_enter() dsc_enter_exit("enter")
  45. #define dsc_enter_str(str) dsc_enter_exit("enter(\"%s\")", str)
  46. #define dsc_exit() dsc_enter_exit("exit")
  47. #define dsc_exit_status(status) dsc_enter_exit("exit(status:%u)", status)
  48. static inline bool __dsc_assert(const bool cond, const char *cond_str,
  49. const char *func, const uint32_t line)
  50. {
  51. if (cond)
  52. return true;
  53. QDF_DEBUG_PANIC_FL(func, line, "Failed assertion '%s'!", cond_str);
  54. return false;
  55. }
  56. #define dsc_assert(cond) __dsc_assert(cond, #cond, __func__, __LINE__)
  57. #define dsc_assert_success(status) dsc_assert(QDF_IS_STATUS_SUCCESS(status))
  58. #ifdef WLAN_DSC_DEBUG
  59. #define DSC_OP_TIMEOUT_MS (1 * 60 * 1000) /* 1 minute */
  60. #define DSC_TRANS_TIMEOUT_MS (1 * 60 * 1000) /* 1 minute */
  61. #define DSC_TRANS_WAIT_TIMEOUT_MS (2 * 60 * 1000) /* 2 minutes */
  62. /**
  63. * struct dsc_op - list node for operation tracking information
  64. * @node: list node
  65. * @timeout_timer: a timer used to detect operation timeouts
  66. * @thread: the thread which started the operation
  67. * @func: name of the function the operation was started from
  68. */
  69. struct dsc_op {
  70. qdf_list_node_t node;
  71. qdf_timer_t timeout_timer;
  72. qdf_thread_t *thread;
  73. const char *func;
  74. };
  75. #endif /* WLAN_DSC_DEBUG */
  76. /**
  77. * struct dsc_ops - operations in flight tracking container
  78. * @list: list for tracking debug information
  79. * @count: count of current operations in flight
  80. * @event: event used to wait in *_wait_for_ops() APIs
  81. */
  82. struct dsc_ops {
  83. #ifdef WLAN_DSC_DEBUG
  84. qdf_list_t list;
  85. #endif
  86. uint32_t count;
  87. qdf_event_t event;
  88. };
  89. /**
  90. * struct dsc_tran - representation of a pending transition
  91. * @abort: used to indicate if the transition stopped waiting due to an abort
  92. * @desc: unique description of the transition
  93. * @node: list node
  94. * @event: event used to wait in *_start_trans_wait() APIs
  95. * @timeout_timer: a timer used to detect transition wait timeouts
  96. * @thread: the thread which started the transition wait
  97. */
  98. struct dsc_tran {
  99. bool abort;
  100. const char *desc;
  101. qdf_list_node_t node;
  102. qdf_event_t event;
  103. #ifdef WLAN_DSC_DEBUG
  104. qdf_timer_t timeout_timer;
  105. qdf_thread_t *thread;
  106. #endif
  107. };
  108. /**
  109. * struct dsc_trans - transition information container
  110. * @active_desc: unique description of the current transition in progress
  111. * @queue: queue of pending transitions
  112. * @timeout_timer: a timer used to detect transition timeouts
  113. * @thread: the thread which started the transition
  114. */
  115. struct dsc_trans {
  116. const char *active_desc;
  117. qdf_list_t queue;
  118. #ifdef WLAN_DSC_DEBUG
  119. qdf_timer_t timeout_timer;
  120. qdf_thread_t *thread;
  121. #endif
  122. };
  123. /**
  124. * struct dsc_driver - concrete dsc driver context
  125. * @lock: lock under which all dsc APIs execute
  126. * @psocs: list of children psoc contexts
  127. * @trans: transition tracking container for this node
  128. * @ops: operations in flight tracking container for this node
  129. */
  130. struct dsc_driver {
  131. struct qdf_spinlock lock;
  132. qdf_list_t psocs;
  133. struct dsc_trans trans;
  134. struct dsc_ops ops;
  135. };
  136. /**
  137. * struct dsc_psoc - concrete dsc psoc context
  138. * @node: list node for membership in @driver->psocs
  139. * @driver: parent driver context
  140. * @vdevs: list of children vdevs contexts
  141. * @trans: transition tracking container for this node
  142. * @ops: operations in flight tracking container for this node
  143. */
  144. struct dsc_psoc {
  145. qdf_list_node_t node;
  146. struct dsc_driver *driver;
  147. qdf_list_t vdevs;
  148. struct dsc_trans trans;
  149. struct dsc_ops ops;
  150. };
  151. /**
  152. * struct dsc_vdev - concrete dsc vdev context
  153. * @node: list node for membership in @psoc->vdevs
  154. * @psoc: parent psoc context
  155. * @trans: transition tracking container for this node
  156. * @ops: operations in flight tracking container for this node
  157. * @nb_cmd_during_ssr: north bound command id
  158. */
  159. struct dsc_vdev {
  160. qdf_list_node_t node;
  161. struct dsc_psoc *psoc;
  162. struct dsc_trans trans;
  163. struct dsc_ops ops;
  164. uint8_t nb_cmd_during_ssr;
  165. };
  166. #define dsc_for_each_driver_psoc(driver_ptr, psoc_cursor) \
  167. qdf_list_for_each(&(driver_ptr)->psocs, psoc_cursor, node)
  168. #define dsc_for_each_psoc_vdev(psoc_ptr, vdev_cursor) \
  169. qdf_list_for_each(&(psoc_ptr)->vdevs, vdev_cursor, node)
  170. /**
  171. * __dsc_lock() - grab the dsc driver lock
  172. * @driver: the driver to lock
  173. *
  174. * Return: None
  175. */
  176. void __dsc_lock(struct dsc_driver *driver);
  177. /**
  178. * __dsc_unlock() - release the dsc driver lock
  179. * @driver: the driver to unlock
  180. *
  181. * Return: None
  182. */
  183. void __dsc_unlock(struct dsc_driver *driver);
  184. /**
  185. * __dsc_ops_init() - initialize @ops
  186. * @ops: the ops container to initialize
  187. *
  188. * Return: None
  189. */
  190. void __dsc_ops_init(struct dsc_ops *ops);
  191. /**
  192. * __dsc_ops_deinit() - de-initialize @ops
  193. * @ops: the ops container to de-initialize
  194. *
  195. * Return: None
  196. */
  197. void __dsc_ops_deinit(struct dsc_ops *ops);
  198. /**
  199. * __dsc_ops_insert() - insert @func into the trakcing information in @ops
  200. * @ops: the ops container to insert into
  201. * @func: the debug information to insert
  202. *
  203. * Return: QDF_STATUS
  204. */
  205. QDF_STATUS __dsc_ops_insert(struct dsc_ops *ops, const char *func);
  206. /**
  207. * __dsc_ops_remove() - remove @func from the tracking information in @ops
  208. * @ops: the ops container to remove from
  209. * @func: the debug information to remove
  210. *
  211. * Return: None
  212. */
  213. bool __dsc_ops_remove(struct dsc_ops *ops, const char *func);
  214. /**
  215. * __dsc_trans_init() - initialize @trans
  216. * @trans: the trans container to initialize
  217. *
  218. * Return: None
  219. */
  220. void __dsc_trans_init(struct dsc_trans *trans);
  221. /**
  222. * __dsc_trans_deinit() - de-initialize @trans
  223. * @trans: the trans container to de-initialize
  224. *
  225. * Return: None
  226. */
  227. void __dsc_trans_deinit(struct dsc_trans *trans);
  228. /**
  229. * __dsc_trans_start() - set the active transition on @trans
  230. * @trans: the transition container used to track the new active transition
  231. * @desc: unique description of the transition being started
  232. *
  233. * Return: QDF_STATUS
  234. */
  235. QDF_STATUS __dsc_trans_start(struct dsc_trans *trans, const char *desc);
  236. /**
  237. * __dsc_trans_stop() - unset the active transition on @trans
  238. * @trans: the transition container currently tracking the active transition
  239. *
  240. * Return: None
  241. */
  242. void __dsc_trans_stop(struct dsc_trans *trans);
  243. /**
  244. * __dsc_trans_queue() - queue @tran at the back of @trans
  245. * @trans: the transitions container to enqueue to
  246. * @tran: the transition to enqueue
  247. * @desc: unique description of the transition being queued
  248. *
  249. * Return: QDF_STATUS
  250. */
  251. QDF_STATUS __dsc_trans_queue(struct dsc_trans *trans, struct dsc_tran *tran,
  252. const char *desc);
  253. /**
  254. * __dsc_tran_wait() - block until @tran completes
  255. * @tran: the transition to wait on
  256. *
  257. * Return: QDF_STATUS
  258. */
  259. QDF_STATUS __dsc_tran_wait(struct dsc_tran *tran);
  260. /**
  261. * __dsc_trans_abort() - abort the next queued transition from @trans
  262. * @trans: the transitions container to abort from
  263. *
  264. * Return: true if a transition was aborted, false if @trans is empty
  265. */
  266. bool __dsc_trans_abort(struct dsc_trans *trans);
  267. /**
  268. * __dsc_trans_trigger() - trigger the next queued trans in @trans
  269. * @trans: the transitions container to trigger from
  270. *
  271. * Return: true if a transition was triggered
  272. */
  273. bool __dsc_trans_trigger(struct dsc_trans *trans);
  274. /**
  275. * __dsc_trans_active() - check if a transition is active in @trans
  276. * @trans: the transitions container to check
  277. *
  278. * Return: true if @trans has an active transition
  279. */
  280. bool __dsc_trans_active(struct dsc_trans *trans);
  281. /**
  282. * __dsc_trans_queued() - check if a transition is queued in @trans
  283. * @trans: the transitions container to check
  284. *
  285. * Return: true if @trans has a queued transition
  286. */
  287. bool __dsc_trans_queued(struct dsc_trans *trans);
  288. /**
  289. * __dsc_trans_active_or_queued() - check if a transition is active or queued
  290. * in @trans
  291. * @trans: the transitions container to check
  292. *
  293. * Return: true if @trans has an active or queued transition
  294. */
  295. bool __dsc_trans_active_or_queued(struct dsc_trans *trans);
  296. /**
  297. * __dsc_driver_trans_trigger_checked() - trigger any next pending driver
  298. * transition, only after passing the "can trans" check
  299. *
  300. * Return: true if the trigger was "handled." This indicates down-tree nodes
  301. * should _not_ attempt to trigger a new transition.
  302. */
  303. bool __dsc_driver_trans_trigger_checked(struct dsc_driver *driver);
  304. /**
  305. * __dsc_psoc_trans_trigger_checked() - trigger any next pending psoc
  306. * transition, only after passing the "can trans" check
  307. *
  308. * Return: true if the trigger was "handled." This indicates down-tree nodes
  309. * should _not_ attempt to trigger a new transition.
  310. */
  311. bool __dsc_psoc_trans_trigger_checked(struct dsc_psoc *psoc);
  312. #endif /* ____WLAN_DSC_H */