1 /*
2  * Copyright (c) 2011-2012, 2014-2016, 2018-2019, 2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 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 /**
21  * \file csr_link_list.h
22  *
23  * Exports and types for the Common link list interfaces.
24  */
25 
26 #ifndef CSR_LINK_LIST_H__
27 #define CSR_LINK_LIST_H__
28 
29 #include "qdf_lock.h"
30 #include "qdf_mc_timer.h"
31 #include "cds_api.h"
32 #include "sir_types.h"
33 #include "qdf_util.h"
34 
35 #define LL_ACCESS_LOCK          true
36 #define LL_ACCESS_NOLOCK        false
37 
38 typedef struct tagListElem {
39 	struct tagListElem *last;
40 	struct tagListElem *next;
41 } tListElem;
42 
43 typedef enum {
44 	LIST_FLAG_CLOSE = 0,
45 	LIST_FLAG_OPEN = 0xa1b2c4d7,
46 } tListFlag;
47 
48 /* This is a circular double link list */
49 typedef struct tagDblLinkList {
50 	tListElem ListHead;
51 	qdf_mutex_t Lock;
52 	uint32_t Count;
53 	tListFlag Flag;
54 } tDblLinkList;
55 
56 /*
57  * To get the address of an object of (type) base on the (address)
58  * of one of its (field)
59  */
60 #define GET_BASE_ADDR(address, type, field) \
61 	(qdf_container_of(address, type, field))
62 /* To get the offset of (field) inside structure (type) */
63 #define GET_FIELD_OFFSET(type, field)  (qdf_offsetof(type, field))
64 #define GET_ROUND_UP(_Field, _Boundary) \
65 	(((_Field) + ((_Boundary) - 1))  & ~((_Boundary) - 1))
66 #define csrIsListEmpty(pHead) ((pHead)->next == (pHead))
67 
68 uint32_t csr_ll_count(tDblLinkList *pList);
69 QDF_STATUS csr_ll_open(tDblLinkList *pList);
70 void csr_ll_close(tDblLinkList *pList);
71 void csr_ll_lock(tDblLinkList *pList);
72 void csr_ll_unlock(tDblLinkList *pList);
73 bool csr_ll_is_list_empty(tDblLinkList *pList, bool fInterlocked);
74 void csr_ll_insert_head(tDblLinkList *pList, tListElem *pEntry,
75 		bool fInterlocked);
76 void csr_ll_insert_tail(tDblLinkList *pList, tListElem *pEntry,
77 		bool fInterlocked);
78 /* This function put pNewEntry before pEntry. Caller should have found pEntry */
79 void csr_ll_insert_entry(tDblLinkList *pList, tListElem *pEntry,
80 		tListElem *pNewEntry, bool fInterlocked);
81 tListElem *csr_ll_peek_head(tDblLinkList *pList, bool fInterlocked);
82 tListElem *csr_ll_peek_tail(tDblLinkList *pList, bool fInterlocked);
83 tListElem *csr_ll_remove_head(tDblLinkList *pList, bool fInterlocked);
84 tListElem *csr_ll_remove_tail(tDblLinkList *pList, bool fInterlocked);
85 bool csr_ll_remove_entry(tDblLinkList *pList, tListElem *pEntryToRemove,
86 		bool fInterlocked);
87 void csr_ll_purge(tDblLinkList *pList, bool fInterlocked);
88 /* csr_ll_next return NULL if reaching the end or list is empty */
89 tListElem *csr_ll_next(tDblLinkList *pList, tListElem *pEntry,
90 		bool fInterlocked);
91 tListElem *csr_ll_previous(tDblLinkList *pList, tListElem *pEntry,
92 		bool fInterlocked);
93 bool csr_ll_find_entry(tDblLinkList *pList, tListElem *pEntryToFind);
94 #endif
95