xref: /wlan-driver/qcacld-3.0/components/dsc/src/__wlan_dsc.h (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2018-2019, 2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /**
21*5113495bSYour Name  * DOC: Driver State Management (DSC) APIs for *internal* use
22*5113495bSYour Name  */
23*5113495bSYour Name 
24*5113495bSYour Name #ifndef ____WLAN_DSC_H
25*5113495bSYour Name #define ____WLAN_DSC_H
26*5113495bSYour Name 
27*5113495bSYour Name #include "qdf_event.h"
28*5113495bSYour Name #include "qdf_list.h"
29*5113495bSYour Name #include "qdf_threads.h"
30*5113495bSYour Name #include "qdf_timer.h"
31*5113495bSYour Name #include "qdf_trace.h"
32*5113495bSYour Name #include "qdf_types.h"
33*5113495bSYour Name #include "wlan_dsc.h"
34*5113495bSYour Name 
35*5113495bSYour Name #define dsc_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, params)
36*5113495bSYour Name #define dsc_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_QDF, params)
37*5113495bSYour Name #ifdef WLAN_DSC_DEBUG
38*5113495bSYour Name #define dsc_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_QDF, params)
39*5113495bSYour Name #else
40*5113495bSYour Name #define dsc_debug(params...) /* no-op */
41*5113495bSYour Name #endif
42*5113495bSYour Name 
43*5113495bSYour Name #define dsc_nofl_err(params...) \
44*5113495bSYour Name 	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_QDF, params)
45*5113495bSYour Name #define dsc_nofl_info(params...) \
46*5113495bSYour Name 	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_QDF, params)
47*5113495bSYour Name #define dsc_nofl_debug(params...) \
48*5113495bSYour Name 	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_QDF, params)
49*5113495bSYour Name 
50*5113495bSYour Name #define dsc_enter_exit dsc_debug
51*5113495bSYour Name #define dsc_enter() dsc_enter_exit("enter")
52*5113495bSYour Name #define dsc_enter_str(str) dsc_enter_exit("enter(\"%s\")", str)
53*5113495bSYour Name #define dsc_exit() dsc_enter_exit("exit")
54*5113495bSYour Name #define dsc_exit_status(status) dsc_enter_exit("exit(status:%u)", status)
55*5113495bSYour Name 
__dsc_assert(const bool cond,const char * cond_str,const char * func,const uint32_t line)56*5113495bSYour Name static inline bool __dsc_assert(const bool cond, const char *cond_str,
57*5113495bSYour Name 				const char *func, const uint32_t line)
58*5113495bSYour Name {
59*5113495bSYour Name 	if (cond)
60*5113495bSYour Name 		return true;
61*5113495bSYour Name 
62*5113495bSYour Name 	QDF_DEBUG_PANIC_FL(func, line, "Failed assertion '%s'!", cond_str);
63*5113495bSYour Name 
64*5113495bSYour Name 	return false;
65*5113495bSYour Name }
66*5113495bSYour Name 
67*5113495bSYour Name #define dsc_assert(cond) __dsc_assert(cond, #cond, __func__, __LINE__)
68*5113495bSYour Name #define dsc_assert_success(status) dsc_assert(QDF_IS_STATUS_SUCCESS(status))
69*5113495bSYour Name 
70*5113495bSYour Name #ifdef WLAN_DSC_DEBUG
71*5113495bSYour Name #define DSC_OP_TIMEOUT_MS		(1 * 60 * 1000) /* 1 minute */
72*5113495bSYour Name #define DSC_TRANS_TIMEOUT_MS		(1 * 60 * 1000) /* 1 minute */
73*5113495bSYour Name #define DSC_TRANS_WAIT_TIMEOUT_MS	(2 * 60 * 1000) /* 2 minutes */
74*5113495bSYour Name 
75*5113495bSYour Name /**
76*5113495bSYour Name  * struct dsc_op - list node for operation tracking information
77*5113495bSYour Name  * @node: list node
78*5113495bSYour Name  * @timeout_timer: a timer used to detect operation timeouts
79*5113495bSYour Name  * @thread: the thread which started the operation
80*5113495bSYour Name  * @func: name of the function the operation was started from
81*5113495bSYour Name  */
82*5113495bSYour Name struct dsc_op {
83*5113495bSYour Name 	qdf_list_node_t node;
84*5113495bSYour Name 	qdf_timer_t timeout_timer;
85*5113495bSYour Name 	qdf_thread_t *thread;
86*5113495bSYour Name 	const char *func;
87*5113495bSYour Name };
88*5113495bSYour Name #endif /* WLAN_DSC_DEBUG */
89*5113495bSYour Name 
90*5113495bSYour Name /**
91*5113495bSYour Name  * struct dsc_ops - operations in flight tracking container
92*5113495bSYour Name  * @list: list for tracking debug information
93*5113495bSYour Name  * @count: count of current operations in flight
94*5113495bSYour Name  * @event: event used to wait in *_wait_for_ops() APIs
95*5113495bSYour Name  */
96*5113495bSYour Name struct dsc_ops {
97*5113495bSYour Name #ifdef WLAN_DSC_DEBUG
98*5113495bSYour Name 	qdf_list_t list;
99*5113495bSYour Name #endif
100*5113495bSYour Name 	uint32_t count;
101*5113495bSYour Name 	qdf_event_t event;
102*5113495bSYour Name };
103*5113495bSYour Name 
104*5113495bSYour Name /**
105*5113495bSYour Name  * struct dsc_tran - representation of a pending transition
106*5113495bSYour Name  * @abort: used to indicate if the transition stopped waiting due to an abort
107*5113495bSYour Name  * @desc: unique description of the transition
108*5113495bSYour Name  * @node: list node
109*5113495bSYour Name  * @event: event used to wait in *_start_trans_wait() APIs
110*5113495bSYour Name  * @timeout_timer: a timer used to detect transition wait timeouts
111*5113495bSYour Name  * @thread: the thread which started the transition wait
112*5113495bSYour Name  */
113*5113495bSYour Name struct dsc_tran {
114*5113495bSYour Name 	bool abort;
115*5113495bSYour Name 	const char *desc;
116*5113495bSYour Name 	qdf_list_node_t node;
117*5113495bSYour Name 	qdf_event_t event;
118*5113495bSYour Name #ifdef WLAN_DSC_DEBUG
119*5113495bSYour Name 	qdf_timer_t timeout_timer;
120*5113495bSYour Name 	qdf_thread_t *thread;
121*5113495bSYour Name #endif
122*5113495bSYour Name };
123*5113495bSYour Name 
124*5113495bSYour Name /**
125*5113495bSYour Name  * struct dsc_trans - transition information container
126*5113495bSYour Name  * @active_desc: unique description of the current transition in progress
127*5113495bSYour Name  * @queue: queue of pending transitions
128*5113495bSYour Name  * @timeout_timer: a timer used to detect transition timeouts
129*5113495bSYour Name  * @thread: the thread which started the transition
130*5113495bSYour Name  */
131*5113495bSYour Name struct dsc_trans {
132*5113495bSYour Name 	const char *active_desc;
133*5113495bSYour Name 	qdf_list_t queue;
134*5113495bSYour Name #ifdef WLAN_DSC_DEBUG
135*5113495bSYour Name 	qdf_timer_t timeout_timer;
136*5113495bSYour Name 	qdf_thread_t *thread;
137*5113495bSYour Name #endif
138*5113495bSYour Name };
139*5113495bSYour Name 
140*5113495bSYour Name /**
141*5113495bSYour Name  * struct dsc_driver - concrete dsc driver context
142*5113495bSYour Name  * @lock: lock under which all dsc APIs execute
143*5113495bSYour Name  * @psocs: list of children psoc contexts
144*5113495bSYour Name  * @trans: transition tracking container for this node
145*5113495bSYour Name  * @ops: operations in flight tracking container for this node
146*5113495bSYour Name  */
147*5113495bSYour Name struct dsc_driver {
148*5113495bSYour Name 	struct qdf_spinlock lock;
149*5113495bSYour Name 	qdf_list_t psocs;
150*5113495bSYour Name 	struct dsc_trans trans;
151*5113495bSYour Name 	struct dsc_ops ops;
152*5113495bSYour Name };
153*5113495bSYour Name 
154*5113495bSYour Name /**
155*5113495bSYour Name  * struct dsc_psoc - concrete dsc psoc context
156*5113495bSYour Name  * @node: list node for membership in @driver->psocs
157*5113495bSYour Name  * @driver: parent driver context
158*5113495bSYour Name  * @vdevs: list of children vdevs contexts
159*5113495bSYour Name  * @trans: transition tracking container for this node
160*5113495bSYour Name  * @ops: operations in flight tracking container for this node
161*5113495bSYour Name  */
162*5113495bSYour Name struct dsc_psoc {
163*5113495bSYour Name 	qdf_list_node_t node;
164*5113495bSYour Name 	struct dsc_driver *driver;
165*5113495bSYour Name 	qdf_list_t vdevs;
166*5113495bSYour Name 	struct dsc_trans trans;
167*5113495bSYour Name 	struct dsc_ops ops;
168*5113495bSYour Name };
169*5113495bSYour Name 
170*5113495bSYour Name /**
171*5113495bSYour Name  * struct dsc_vdev - concrete dsc vdev context
172*5113495bSYour Name  * @node: list node for membership in @psoc->vdevs
173*5113495bSYour Name  * @psoc: parent psoc context
174*5113495bSYour Name  * @trans: transition tracking container for this node
175*5113495bSYour Name  * @ops: operations in flight tracking container for this node
176*5113495bSYour Name  * @nb_cmd_during_ssr: north bound command id
177*5113495bSYour Name  */
178*5113495bSYour Name struct dsc_vdev {
179*5113495bSYour Name 	qdf_list_node_t node;
180*5113495bSYour Name 	struct dsc_psoc *psoc;
181*5113495bSYour Name 	struct dsc_trans trans;
182*5113495bSYour Name 	struct dsc_ops ops;
183*5113495bSYour Name 	uint8_t nb_cmd_during_ssr;
184*5113495bSYour Name };
185*5113495bSYour Name 
186*5113495bSYour Name #define dsc_for_each_driver_psoc(driver_ptr, psoc_cursor) \
187*5113495bSYour Name 	qdf_list_for_each(&(driver_ptr)->psocs, psoc_cursor, node)
188*5113495bSYour Name 
189*5113495bSYour Name #define dsc_for_each_psoc_vdev(psoc_ptr, vdev_cursor) \
190*5113495bSYour Name 	qdf_list_for_each(&(psoc_ptr)->vdevs, vdev_cursor, node)
191*5113495bSYour Name 
192*5113495bSYour Name /**
193*5113495bSYour Name  * __dsc_lock() - grab the dsc driver lock
194*5113495bSYour Name  * @driver: the driver to lock
195*5113495bSYour Name  *
196*5113495bSYour Name  * Return: None
197*5113495bSYour Name  */
198*5113495bSYour Name void __dsc_lock(struct dsc_driver *driver);
199*5113495bSYour Name 
200*5113495bSYour Name /**
201*5113495bSYour Name  * __dsc_unlock() - release the dsc driver lock
202*5113495bSYour Name  * @driver: the driver to unlock
203*5113495bSYour Name  *
204*5113495bSYour Name  * Return: None
205*5113495bSYour Name  */
206*5113495bSYour Name void __dsc_unlock(struct dsc_driver *driver);
207*5113495bSYour Name 
208*5113495bSYour Name /**
209*5113495bSYour Name  * __dsc_ops_init() - initialize @ops
210*5113495bSYour Name  * @ops: the ops container to initialize
211*5113495bSYour Name  *
212*5113495bSYour Name  * Return: None
213*5113495bSYour Name  */
214*5113495bSYour Name void __dsc_ops_init(struct dsc_ops *ops);
215*5113495bSYour Name 
216*5113495bSYour Name /**
217*5113495bSYour Name  * __dsc_ops_deinit() - de-initialize @ops
218*5113495bSYour Name  * @ops: the ops container to de-initialize
219*5113495bSYour Name  *
220*5113495bSYour Name  * Return: None
221*5113495bSYour Name  */
222*5113495bSYour Name void __dsc_ops_deinit(struct dsc_ops *ops);
223*5113495bSYour Name 
224*5113495bSYour Name /**
225*5113495bSYour Name  * __dsc_ops_insert() - insert @func into the trakcing information in @ops
226*5113495bSYour Name  * @ops: the ops container to insert into
227*5113495bSYour Name  * @func: the debug information to insert
228*5113495bSYour Name  *
229*5113495bSYour Name  * Return: QDF_STATUS
230*5113495bSYour Name  */
231*5113495bSYour Name QDF_STATUS __dsc_ops_insert(struct dsc_ops *ops, const char *func);
232*5113495bSYour Name 
233*5113495bSYour Name /**
234*5113495bSYour Name  * __dsc_ops_remove() - remove @func from the tracking information in @ops
235*5113495bSYour Name  * @ops: the ops container to remove from
236*5113495bSYour Name  * @func: the debug information to remove
237*5113495bSYour Name  *
238*5113495bSYour Name  * Return: None
239*5113495bSYour Name  */
240*5113495bSYour Name bool __dsc_ops_remove(struct dsc_ops *ops, const char *func);
241*5113495bSYour Name 
242*5113495bSYour Name /**
243*5113495bSYour Name  * __dsc_trans_init() - initialize @trans
244*5113495bSYour Name  * @trans: the trans container to initialize
245*5113495bSYour Name  *
246*5113495bSYour Name  * Return: None
247*5113495bSYour Name  */
248*5113495bSYour Name void __dsc_trans_init(struct dsc_trans *trans);
249*5113495bSYour Name 
250*5113495bSYour Name /**
251*5113495bSYour Name  * __dsc_trans_deinit() - de-initialize @trans
252*5113495bSYour Name  * @trans: the trans container to de-initialize
253*5113495bSYour Name  *
254*5113495bSYour Name  * Return: None
255*5113495bSYour Name  */
256*5113495bSYour Name void __dsc_trans_deinit(struct dsc_trans *trans);
257*5113495bSYour Name 
258*5113495bSYour Name /**
259*5113495bSYour Name  * __dsc_trans_start() - set the active transition on @trans
260*5113495bSYour Name  * @trans: the transition container used to track the new active transition
261*5113495bSYour Name  * @desc: unique description of the transition being started
262*5113495bSYour Name  *
263*5113495bSYour Name  * Return: QDF_STATUS
264*5113495bSYour Name  */
265*5113495bSYour Name QDF_STATUS __dsc_trans_start(struct dsc_trans *trans, const char *desc);
266*5113495bSYour Name 
267*5113495bSYour Name /**
268*5113495bSYour Name  * __dsc_trans_stop() - unset the active transition on @trans
269*5113495bSYour Name  * @trans: the transition container currently tracking the active transition
270*5113495bSYour Name  *
271*5113495bSYour Name  * Return: None
272*5113495bSYour Name  */
273*5113495bSYour Name void __dsc_trans_stop(struct dsc_trans *trans);
274*5113495bSYour Name 
275*5113495bSYour Name /**
276*5113495bSYour Name  * __dsc_trans_queue() - queue @tran at the back of @trans
277*5113495bSYour Name  * @trans: the transitions container to enqueue to
278*5113495bSYour Name  * @tran: the transition to enqueue
279*5113495bSYour Name  * @desc: unique description of the transition being queued
280*5113495bSYour Name  *
281*5113495bSYour Name  * Return: QDF_STATUS
282*5113495bSYour Name  */
283*5113495bSYour Name QDF_STATUS __dsc_trans_queue(struct dsc_trans *trans, struct dsc_tran *tran,
284*5113495bSYour Name 			     const char *desc);
285*5113495bSYour Name 
286*5113495bSYour Name /**
287*5113495bSYour Name  * __dsc_tran_wait() - block until @tran completes
288*5113495bSYour Name  * @tran: the transition to wait on
289*5113495bSYour Name  *
290*5113495bSYour Name  * Return: QDF_STATUS
291*5113495bSYour Name  */
292*5113495bSYour Name QDF_STATUS __dsc_tran_wait(struct dsc_tran *tran);
293*5113495bSYour Name 
294*5113495bSYour Name /**
295*5113495bSYour Name  * __dsc_trans_abort() - abort the next queued transition from @trans
296*5113495bSYour Name  * @trans: the transitions container to abort from
297*5113495bSYour Name  *
298*5113495bSYour Name  * Return: true if a transition was aborted, false if @trans is empty
299*5113495bSYour Name  */
300*5113495bSYour Name bool __dsc_trans_abort(struct dsc_trans *trans);
301*5113495bSYour Name 
302*5113495bSYour Name /**
303*5113495bSYour Name  * __dsc_trans_trigger() - trigger the next queued trans in @trans
304*5113495bSYour Name  * @trans: the transitions container to trigger from
305*5113495bSYour Name  *
306*5113495bSYour Name  * Return: true if a transition was triggered
307*5113495bSYour Name  */
308*5113495bSYour Name bool __dsc_trans_trigger(struct dsc_trans *trans);
309*5113495bSYour Name 
310*5113495bSYour Name /**
311*5113495bSYour Name  * __dsc_trans_active() - check if a transition is active in @trans
312*5113495bSYour Name  * @trans: the transitions container to check
313*5113495bSYour Name  *
314*5113495bSYour Name  * Return: true if @trans has an active transition
315*5113495bSYour Name  */
316*5113495bSYour Name bool __dsc_trans_active(struct dsc_trans *trans);
317*5113495bSYour Name 
318*5113495bSYour Name /**
319*5113495bSYour Name  * __dsc_trans_queued() - check if a transition is queued in @trans
320*5113495bSYour Name  * @trans: the transitions container to check
321*5113495bSYour Name  *
322*5113495bSYour Name  * Return: true if @trans has a queued transition
323*5113495bSYour Name  */
324*5113495bSYour Name bool __dsc_trans_queued(struct dsc_trans *trans);
325*5113495bSYour Name 
326*5113495bSYour Name /**
327*5113495bSYour Name  * __dsc_trans_active_or_queued() - check if a transition is active or queued
328*5113495bSYour Name  *	in @trans
329*5113495bSYour Name  * @trans: the transitions container to check
330*5113495bSYour Name  *
331*5113495bSYour Name  * Return: true if @trans has an active or queued transition
332*5113495bSYour Name  */
333*5113495bSYour Name bool __dsc_trans_active_or_queued(struct dsc_trans *trans);
334*5113495bSYour Name 
335*5113495bSYour Name /**
336*5113495bSYour Name  * __dsc_driver_trans_trigger_checked() - trigger any next pending driver
337*5113495bSYour Name  *	transition, only after passing the "can trans" check
338*5113495bSYour Name  * @driver: driver context
339*5113495bSYour Name  *
340*5113495bSYour Name  * Return: true if the trigger was "handled." This indicates down-tree nodes
341*5113495bSYour Name  * should _not_ attempt to trigger a new transition.
342*5113495bSYour Name  */
343*5113495bSYour Name bool __dsc_driver_trans_trigger_checked(struct dsc_driver *driver);
344*5113495bSYour Name 
345*5113495bSYour Name /**
346*5113495bSYour Name  * __dsc_psoc_trans_trigger_checked() - trigger any next pending psoc
347*5113495bSYour Name  *	transition, only after passing the "can trans" check
348*5113495bSYour Name  * @psoc: psoc context
349*5113495bSYour Name  *
350*5113495bSYour Name  * Return: true if the trigger was "handled." This indicates down-tree nodes
351*5113495bSYour Name  * should _not_ attempt to trigger a new transition.
352*5113495bSYour Name  */
353*5113495bSYour Name bool __dsc_psoc_trans_trigger_checked(struct dsc_psoc *psoc);
354*5113495bSYour Name 
355*5113495bSYour Name #endif /* ____WLAN_DSC_H */
356