xref: /wlan-driver/qca-wifi-host-cmn/qdf/inc/qdf_list.h (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2014-2018, 2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2023 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: qdf_list.h
22*5113495bSYour Name  *  QCA driver framework (QDF) list APIs
23*5113495bSYour Name  *  Definitions for QDF Linked Lists API
24*5113495bSYour Name  *
25*5113495bSYour Name  *  Lists are implemented as a doubly linked list. An item in a list can
26*5113495bSYour Name  *  be of any type as long as the datatype contains a field of type
27*5113495bSYour Name  *  qdf_link_t.
28*5113495bSYour Name  *
29*5113495bSYour Name  *  In general, a list is a doubly linked list of items with a pointer
30*5113495bSYour Name  *  to the front of the list and a pointer to the end of the list.  The
31*5113495bSYour Name  *  list items contain a forward and back link.
32*5113495bSYour Name  *
33*5113495bSYour Name  *  QDF linked list APIs are NOT thread safe so make sure to use appropriate
34*5113495bSYour Name  *  locking mechanisms to assure operations on the list are thread safe.
35*5113495bSYour Name  */
36*5113495bSYour Name 
37*5113495bSYour Name #if !defined(__QDF_LIST_H)
38*5113495bSYour Name #define __QDF_LIST_H
39*5113495bSYour Name 
40*5113495bSYour Name /* Include Files */
41*5113495bSYour Name #include <qdf_types.h>
42*5113495bSYour Name #include <qdf_status.h>
43*5113495bSYour Name #include <i_qdf_list.h>
44*5113495bSYour Name #include <qdf_trace.h>
45*5113495bSYour Name 
46*5113495bSYour Name typedef __qdf_list_node_t qdf_list_node_t;
47*5113495bSYour Name typedef __qdf_list_t qdf_list_t;
48*5113495bSYour Name 
49*5113495bSYour Name /* Function declarations */
50*5113495bSYour Name 
51*5113495bSYour Name /**
52*5113495bSYour Name  * qdf_list_insert_before() - insert new node before the node
53*5113495bSYour Name  * @list: Pointer to list
54*5113495bSYour Name  * @new_node: Pointer to input node
55*5113495bSYour Name  * @node: node before which new node should be added.
56*5113495bSYour Name  *
57*5113495bSYour Name  * Return: QDF status
58*5113495bSYour Name  */
59*5113495bSYour Name QDF_STATUS qdf_list_insert_before(qdf_list_t *list,
60*5113495bSYour Name 	qdf_list_node_t *new_node, qdf_list_node_t *node);
61*5113495bSYour Name /**
62*5113495bSYour Name  * qdf_list_insert_after() - insert new node after the node
63*5113495bSYour Name  * @list: Pointer to list
64*5113495bSYour Name  * @new_node: Pointer to input node
65*5113495bSYour Name  * @node: node after which new node should be added.
66*5113495bSYour Name  *
67*5113495bSYour Name  * Return: QDF status
68*5113495bSYour Name  */
69*5113495bSYour Name QDF_STATUS qdf_list_insert_after(qdf_list_t *list,
70*5113495bSYour Name 	qdf_list_node_t *new_node, qdf_list_node_t *node);
71*5113495bSYour Name QDF_STATUS qdf_list_insert_front(qdf_list_t *list, qdf_list_node_t *node);
72*5113495bSYour Name 
73*5113495bSYour Name QDF_STATUS qdf_list_insert_back_size(qdf_list_t *list, qdf_list_node_t *node,
74*5113495bSYour Name 				     uint32_t *size);
75*5113495bSYour Name 
76*5113495bSYour Name QDF_STATUS qdf_list_remove_front(qdf_list_t *list, qdf_list_node_t **node1);
77*5113495bSYour Name 
78*5113495bSYour Name QDF_STATUS qdf_list_peek_next(qdf_list_t *list,	qdf_list_node_t *node,
79*5113495bSYour Name 			      qdf_list_node_t **node1);
80*5113495bSYour Name 
81*5113495bSYour Name /**
82*5113495bSYour Name  * qdf_list_create() - Create qdf list and initialize list head
83*5113495bSYour Name  * @list: object of list
84*5113495bSYour Name  * @max_size: max size of the list
85*5113495bSYour Name  *
86*5113495bSYour Name  * Return: none
87*5113495bSYour Name  */
qdf_list_create(__qdf_list_t * list,uint32_t max_size)88*5113495bSYour Name static inline void qdf_list_create(__qdf_list_t *list, uint32_t max_size)
89*5113495bSYour Name {
90*5113495bSYour Name 	__qdf_list_create(list, max_size);
91*5113495bSYour Name }
92*5113495bSYour Name 
93*5113495bSYour Name #define QDF_LIST_ANCHOR(list) __QDF_LIST_ANCHOR(list)
94*5113495bSYour Name 
95*5113495bSYour Name #define QDF_LIST_NODE_INIT(prev, next) __QDF_LIST_NODE_INIT(prev, next)
96*5113495bSYour Name #define QDF_LIST_NODE_INIT_SINGLE(node) __QDF_LIST_NODE_INIT_SINGLE(node)
97*5113495bSYour Name 
98*5113495bSYour Name #define QDF_LIST_INIT(tail, head) __QDF_LIST_INIT(tail, head)
99*5113495bSYour Name #define QDF_LIST_INIT_SINGLE(node) __QDF_LIST_INIT_SINGLE(node)
100*5113495bSYour Name #define QDF_LIST_INIT_EMPTY(list) __QDF_LIST_INIT_EMPTY(list)
101*5113495bSYour Name 
102*5113495bSYour Name #define qdf_list_for_each(list_ptr, cursor, node_field) \
103*5113495bSYour Name 	__qdf_list_for_each(list_ptr, cursor, node_field)
104*5113495bSYour Name 
105*5113495bSYour Name #define qdf_list_for_each_del(list_ptr, cursor, next, node_field) \
106*5113495bSYour Name 	__qdf_list_for_each_del(list_ptr, cursor, next, node_field)
107*5113495bSYour Name 
108*5113495bSYour Name #define qdf_list_for_each_from(list_ptr, cursor, node_field) \
109*5113495bSYour Name 	__qdf_list_for_each_from(list_ptr, cursor, node_field)
110*5113495bSYour Name 
111*5113495bSYour Name #define qdf_list_for_each_continue(list_ptr, cursor, node_field) \
112*5113495bSYour Name 	__qdf_list_for_each_continue(list_ptr, cursor, node_field)
113*5113495bSYour Name 
114*5113495bSYour Name #define qdf_list_first_entry_or_null(list_ptr, type, node_field) \
115*5113495bSYour Name 	__qdf_list_first_entry_or_null(list_ptr, type, node_field)
116*5113495bSYour Name 
117*5113495bSYour Name #define qdf_list_last_entry(list_ptr, type, node_field) \
118*5113495bSYour Name 	__qdf_list_last_entry(list_ptr, type, node_field)
119*5113495bSYour Name 
120*5113495bSYour Name /**
121*5113495bSYour Name  * qdf_init_list_head() - initialize list head
122*5113495bSYour Name  * @list_head: pointer to list head
123*5113495bSYour Name  *
124*5113495bSYour Name  * Return: none
125*5113495bSYour Name  */
qdf_init_list_head(__qdf_list_node_t * list_head)126*5113495bSYour Name static inline void qdf_init_list_head(__qdf_list_node_t *list_head)
127*5113495bSYour Name {
128*5113495bSYour Name 	__qdf_init_list_head(list_head);
129*5113495bSYour Name }
130*5113495bSYour Name 
131*5113495bSYour Name /**
132*5113495bSYour Name  * qdf_list_destroy() - Destroy the list
133*5113495bSYour Name  * @list: object of list
134*5113495bSYour Name  * Return: none
135*5113495bSYour Name  */
qdf_list_destroy(qdf_list_t * list)136*5113495bSYour Name static inline void qdf_list_destroy(qdf_list_t *list)
137*5113495bSYour Name {
138*5113495bSYour Name 	if (list->count != 0) {
139*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
140*5113495bSYour Name 			  "%s: list length not equal to zero", __func__);
141*5113495bSYour Name 		QDF_ASSERT(0);
142*5113495bSYour Name 	}
143*5113495bSYour Name }
144*5113495bSYour Name 
145*5113495bSYour Name /**
146*5113495bSYour Name  * qdf_list_size() - gives the size of the list
147*5113495bSYour Name  * @list: object of list
148*5113495bSYour Name  *
149*5113495bSYour Name  * Return: uint32_t size of the list
150*5113495bSYour Name  */
qdf_list_size(qdf_list_t * list)151*5113495bSYour Name static inline uint32_t qdf_list_size(qdf_list_t *list)
152*5113495bSYour Name {
153*5113495bSYour Name 	return __qdf_list_size(list);
154*5113495bSYour Name }
155*5113495bSYour Name 
156*5113495bSYour Name /**
157*5113495bSYour Name  * qdf_list_max_size() - gives the max size of the list
158*5113495bSYour Name  * @list: object of list
159*5113495bSYour Name  * Return: max size of the list
160*5113495bSYour Name  */
qdf_list_max_size(qdf_list_t * list)161*5113495bSYour Name static inline uint32_t qdf_list_max_size(qdf_list_t *list)
162*5113495bSYour Name {
163*5113495bSYour Name 	return __qdf_list_max_size(list);
164*5113495bSYour Name }
165*5113495bSYour Name 
166*5113495bSYour Name QDF_STATUS qdf_list_insert_back(qdf_list_t *list, qdf_list_node_t *node);
167*5113495bSYour Name 
168*5113495bSYour Name QDF_STATUS qdf_list_remove_back(qdf_list_t *list, qdf_list_node_t **node1);
169*5113495bSYour Name 
170*5113495bSYour Name QDF_STATUS qdf_list_peek_front(qdf_list_t *list, qdf_list_node_t **node1);
171*5113495bSYour Name 
172*5113495bSYour Name QDF_STATUS qdf_list_remove_node(qdf_list_t *list,
173*5113495bSYour Name 				qdf_list_node_t *node_to_remove);
174*5113495bSYour Name 
175*5113495bSYour Name bool qdf_list_empty(qdf_list_t *list);
176*5113495bSYour Name 
177*5113495bSYour Name /**
178*5113495bSYour Name  * qdf_list_has_node() - check if a node is in a list
179*5113495bSYour Name  * @list: pointer to the list being searched
180*5113495bSYour Name  * @node: pointer to the node to search for
181*5113495bSYour Name  *
182*5113495bSYour Name  * This API has a time complexity of O(n).
183*5113495bSYour Name  *
184*5113495bSYour Name  * Return: true if the node is in the list
185*5113495bSYour Name  */
186*5113495bSYour Name bool qdf_list_has_node(qdf_list_t *list, qdf_list_node_t *node);
187*5113495bSYour Name 
188*5113495bSYour Name /**
189*5113495bSYour Name  * qdf_list_node_in_any_list() - ensure @node is a member of a list
190*5113495bSYour Name  * @node: list node to check
191*5113495bSYour Name  *
192*5113495bSYour Name  * This API has a time complexity of O(1). See also qdf_list_has_node().
193*5113495bSYour Name  *
194*5113495bSYour Name  * Return: true, if @node appears to be in a list
195*5113495bSYour Name  */
196*5113495bSYour Name bool qdf_list_node_in_any_list(const qdf_list_node_t *node);
197*5113495bSYour Name 
198*5113495bSYour Name /**
199*5113495bSYour Name  * qdf_list_join - Join two lists and reinitialize the emptied list
200*5113495bSYour Name  * @list1: Pointer to list 1
201*5113495bSYour Name  * @list2: Pointer to list 2
202*5113495bSYour Name  *
203*5113495bSYour Name  * This API joins list1 and list2 and writes the resultant list (list1 + list2)
204*5113495bSYour Name  * to list1. list2 is re initialized to an empty list.
205*5113495bSYour Name  *
206*5113495bSYour Name  * Return: QDF_STATUS of operation
207*5113495bSYour Name  */
208*5113495bSYour Name QDF_STATUS qdf_list_join(qdf_list_t *list1, qdf_list_t *list2);
209*5113495bSYour Name 
210*5113495bSYour Name /**
211*5113495bSYour Name  * qdf_list_split - Split a list into two chunks
212*5113495bSYour Name  * @new: Pointer to the list to store one of the chunks after splitting.
213*5113495bSYour Name  * This list will be overwritten by the API and hence it should be
214*5113495bSYour Name  * an empty list to avoid data loss.
215*5113495bSYour Name  * @list: Pointer to the list to be split
216*5113495bSYour Name  * @node: Pointer to a node within the @list. If @node is not present in
217*5113495bSYour Name  * the @list, behaviour is undefined.
218*5113495bSYour Name  *
219*5113495bSYour Name  * This API splits @list after @node. The initial portion of the @list
220*5113495bSYour Name  * up to and including @node will be moved to @new. The remaining portion will
221*5113495bSYour Name  * be assigned to @list.
222*5113495bSYour Name  */
223*5113495bSYour Name QDF_STATUS qdf_list_split(qdf_list_t *new, qdf_list_t *list,
224*5113495bSYour Name 			  qdf_list_node_t *node);
225*5113495bSYour Name #endif /* __QDF_LIST_H */
226