deefb031a2e5f3d76a3ce1f4798b96d25c30400f
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / mt6628 / wlan / include / link.h
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/link.h#1 $
3 */
4
5 /*! \file   link.h
6     \brief  Definition for simple doubly linked list operations.
7
8     In this file we define the simple doubly linked list data structure and its
9     operation MACROs and INLINE functions.
10 */
11
12
13
14 /*
15 ** $Log: link.h $
16  *
17  * 08 05 2010 yuche.tsai
18  * NULL
19  * Modify a MACRO of LINK_FOR_EACH_SAFE for compile error.
20  *
21  * 07 19 2010 cm.chang
22  * 
23  * Set RLM parameters and enable CNM channel manager
24  *
25  * 07 08 2010 cp.wu
26  *
27  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
28  *
29  * 06 07 2010 cp.wu
30  * [WPD00003833][MT6620 and MT5931] Driver migration
31  * [WPD00003833] [MT6620 and MT5931] Driver migration
32  * .
33  *
34  *
35  *
36  *
37  * May 4 2009 mtk01084
38  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
39  * add WIFI to BORA source control
40 **  \main\maintrunk.MT5921\8 2008-10-16 15:57:11 GMT mtk01461
41 **  Update driver to fix lint warning
42 **  \main\maintrunk.MT5921\7 2008-08-10 18:47:53 GMT mtk01461
43 **  Update for Driver Review
44 **  \main\maintrunk.MT5921\6 2007-12-11 00:09:00 GMT mtk01461
45 **  Add macro for checking valid list
46 **  \main\maintrunk.MT5921\5 2007-11-13 14:27:01 GMT mtk01461
47 **  Add LINK_IS_INVALID macro
48 ** Revision 1.1.1.1  2007/06/22 08:09:05  MTK01461
49 ** no message
50 **
51 */
52
53 #ifndef _LINK_H
54 #define _LINK_H
55
56 /*******************************************************************************
57 *                         C O M P I L E R   F L A G S
58 ********************************************************************************
59 */
60
61 /*******************************************************************************
62 *                    E X T E R N A L   R E F E R E N C E S
63 ********************************************************************************
64 */
65 #include "gl_typedef.h"
66
67
68 /*******************************************************************************
69 *                              C O N S T A N T S
70 ********************************************************************************
71 */
72 #define INVALID_LINK_POISON1    ((VOID *) 0x00100101) // May cause page fault & unalignment issue (data abort)
73 #define INVALID_LINK_POISON2    ((VOID *) 0x00100201) // Used to verify that nonbody uses non-initialized link entries.
74
75
76 /*******************************************************************************
77 *                             D A T A   T Y P E S
78 ********************************************************************************
79 */
80 /* Simple Doubly Linked List Structures - Entry Part */
81 typedef struct _LINK_ENTRY_T {
82     struct _LINK_ENTRY_T *prNext, *prPrev;
83 } LINK_ENTRY_T, *P_LINK_ENTRY_T;
84
85 /* Simple Doubly Linked List Structures - List Part */
86 typedef struct _LINK_T {
87     P_LINK_ENTRY_T  prNext;
88     P_LINK_ENTRY_T  prPrev;
89     UINT_32 u4NumElem;
90 } LINK_T, *P_LINK_T;
91
92 /*******************************************************************************
93 *                            P U B L I C   D A T A
94 ********************************************************************************
95 */
96
97 /*******************************************************************************
98 *                           P R I V A T E   D A T A
99 ********************************************************************************
100 */
101
102 /*******************************************************************************
103 *                                 M A C R O S
104 ********************************************************************************
105 */
106 #if 0 // No one use it, temporarily mark it for [Lint - Info 773]
107 #define LINK_ADDR(rLink)        { (P_LINK_ENTRY_T)(&(rLink)), (P_LINK_ENTRY_T)(&(rLink)), 0 }
108
109 #define LINK_DECLARATION(rLink) \
110     struct _LINK_T rLink = LINK_ADDR(rLink)
111 #endif
112
113 #define LINK_INITIALIZE(prLink) \
114     do { \
115         ((P_LINK_T)(prLink))->prNext = (P_LINK_ENTRY_T)(prLink); \
116         ((P_LINK_T)(prLink))->prPrev = (P_LINK_ENTRY_T)(prLink); \
117         ((P_LINK_T)(prLink))->u4NumElem = 0; \
118     } while (0)
119
120 #define LINK_ENTRY_INITIALIZE(prEntry) \
121     do { \
122         ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)NULL; \
123         ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)NULL; \
124     } while (0)
125
126 #define LINK_ENTRY_INVALID(prEntry) \
127     do { \
128         ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)INVALID_LINK_POISON1; \
129         ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)INVALID_LINK_POISON2; \
130     } while (0)
131
132 #define LINK_IS_EMPTY(prLink)           (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)(prLink))
133
134 /* NOTE: We should do memory zero before any LINK been initiated, so we can check
135  * if it is valid before parsing the LINK.
136  */
137 #define LINK_IS_INVALID(prLink)         (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)NULL)
138
139 #define LINK_IS_VALID(prLink)           (((P_LINK_T)(prLink))->prNext != (P_LINK_ENTRY_T)NULL)
140
141
142 #define LINK_ENTRY(ptr, type, member)   ENTRY_OF(ptr, type, member)
143
144 /* Insert an entry into a link list's head */
145 #define LINK_INSERT_HEAD(prLink, prEntry) \
146         { \
147             linkAdd(prEntry, prLink); \
148             ((prLink)->u4NumElem)++; \
149         }
150
151
152 /* Append an entry into a link list's tail */
153 #define LINK_INSERT_TAIL(prLink, prEntry) \
154         { \
155             linkAddTail(prEntry, prLink); \
156             ((prLink)->u4NumElem)++; \
157         }
158
159 /* Peek head entry, but keep still in link list */
160 #define LINK_PEEK_HEAD(prLink, _type, _member) \
161         ( \
162             LINK_IS_EMPTY(prLink) ? \
163             NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \
164         )
165
166 /* Peek tail entry, but keep still in link list */
167 #define LINK_PEEK_TAIL(prLink, _type, _member) \
168         ( \
169             LINK_IS_EMPTY(prLink) ? \
170             NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \
171         )
172
173 /* Get first entry from a link list */
174 /* NOTE: We assume the link entry located at the beginning of "prEntry Type",
175  * so that we can cast the link entry to other data type without doubts.
176  * And this macro also decrease the total entry count at the same time.
177  */
178 #define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \
179         { \
180             ASSERT(prLink); \
181             if (LINK_IS_EMPTY(prLink)) { \
182                 prEntry = (_P_TYPE)NULL; \
183             } \
184             else { \
185                 prEntry = (_P_TYPE)(((P_LINK_T)(prLink))->prNext); \
186                 linkDel((P_LINK_ENTRY_T)prEntry); \
187                 ((prLink)->u4NumElem)--; \
188             } \
189         }
190
191 /* Assume the link entry located at the beginning of prEntry Type.
192  * And also decrease the total entry count.
193  */
194 #define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \
195         { \
196             ASSERT(prLink); \
197             ASSERT(prEntry); \
198             linkDel((P_LINK_ENTRY_T)prEntry); \
199             ((prLink)->u4NumElem)--; \
200         }
201
202 /* Iterate over a link list */
203 #define LINK_FOR_EACH(prEntry, prLink) \
204     for (prEntry = (prLink)->prNext; \
205          prEntry != (P_LINK_ENTRY_T)(prLink); \
206          prEntry = (P_LINK_ENTRY_T)prEntry->prNext)
207
208 /* Iterate over a link list backwards */
209 #define LINK_FOR_EACH_PREV(prEntry, prLink) \
210     for (prEntry = (prLink)->prPrev; \
211          prEntry != (P_LINK_ENTRY_T)(prLink); \
212          prEntry = (P_LINK_ENTRY_T)prEntry->prPrev)
213
214 /* Iterate over a link list safe against removal of link entry */
215 #define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \
216     for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \
217          prEntry != (P_LINK_ENTRY_T)(prLink); \
218          prEntry = prNextEntry, prNextEntry = prEntry->prNext)
219
220 /* Iterate over a link list of given type */
221 #define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \
222     for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \
223          &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
224          prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember))
225
226 /* Iterate backwards over a link list of given type */
227 #define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \
228     for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember);  \
229          &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
230          prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember))
231
232 /* Iterate over a link list of given type safe against removal of link entry */
233 #define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \
234     for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember),  \
235          prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \
236          &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
237          prObj = prNextObj, \
238          prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember))
239
240 /*******************************************************************************
241 *                  F U N C T I O N   D E C L A R A T I O N S
242 ********************************************************************************
243 */
244
245 /*******************************************************************************
246 *                              F U N C T I O N S
247 ********************************************************************************
248 */
249 /*----------------------------------------------------------------------------*/
250 /*!
251 * \brief This function is only for internal link list manipulation.
252 *
253 * \param[in] prNew  Pointer of new link head
254 * \param[in] prPrev Pointer of previous link head
255 * \param[in] prNext Pointer of next link head
256 *
257 * \return (none)
258 */
259 /*----------------------------------------------------------------------------*/
260 __KAL_INLINE__ VOID
261 __linkAdd (
262     IN P_LINK_ENTRY_T prNew,
263     IN P_LINK_ENTRY_T prPrev,
264     IN P_LINK_ENTRY_T prNext
265     )
266 {
267     prNext->prPrev = prNew;
268     prNew->prNext = prNext;
269     prNew->prPrev = prPrev;
270     prPrev->prNext = prNew;
271
272     return;
273 } /* end of __linkAdd() */
274
275
276 /*----------------------------------------------------------------------------*/
277 /*!
278 * \brief This function will add a new entry after the specified link head.
279 *
280 * \param[in] prNew  New entry to be added
281 * \param[in] prHead Specified link head to add it after
282 *
283 * \return (none)
284 */
285 /*----------------------------------------------------------------------------*/
286 __KAL_INLINE__ VOID
287 linkAdd (
288     IN P_LINK_ENTRY_T prNew,
289     IN P_LINK_T prLink
290     )
291 {
292     __linkAdd(prNew, (P_LINK_ENTRY_T)prLink, prLink->prNext);
293
294     return;
295 } /* end of linkAdd() */
296
297
298 /*----------------------------------------------------------------------------*/
299 /*!
300 * \brief This function will add a new entry before the specified link head.
301 *
302 * \param[in] prNew  New entry to be added
303 * \param[in] prHead Specified link head to add it before
304 *
305 * \return (none)
306 */
307 /*----------------------------------------------------------------------------*/
308 __KAL_INLINE__ VOID
309 linkAddTail (
310     IN P_LINK_ENTRY_T prNew,
311     IN P_LINK_T prLink
312     )
313 {
314     __linkAdd(prNew, prLink->prPrev, (P_LINK_ENTRY_T)prLink);
315
316     return;
317 } /* end of linkAddTail() */
318
319
320 /*----------------------------------------------------------------------------*/
321 /*!
322 * \brief This function is only for internal link list manipulation.
323 *
324 * \param[in] prPrev Pointer of previous link head
325 * \param[in] prNext Pointer of next link head
326 *
327 * \return (none)
328 */
329 /*----------------------------------------------------------------------------*/
330 __KAL_INLINE__ VOID
331 __linkDel (
332     IN P_LINK_ENTRY_T prPrev,
333     IN P_LINK_ENTRY_T prNext
334     )
335 {
336     prNext->prPrev = prPrev;
337     prPrev->prNext = prNext;
338
339     return;
340 } /* end of __linkDel() */
341
342
343 /*----------------------------------------------------------------------------*/
344 /*!
345 * \brief This function will delete a specified entry from link list.
346 *        NOTE: the entry is in an initial state.
347 *
348 * \param prEntry    Specified link head(entry)
349 *
350 * \return (none)
351 */
352 /*----------------------------------------------------------------------------*/
353 __KAL_INLINE__ VOID
354 linkDel (
355     IN P_LINK_ENTRY_T prEntry
356     )
357 {
358     __linkDel(prEntry->prPrev, prEntry->prNext);
359
360     LINK_ENTRY_INITIALIZE(prEntry);
361
362     return;
363 } /* end of linkDel() */
364
365
366 /*----------------------------------------------------------------------------*/
367 /*!
368 * \brief This function will delete a specified entry from link list and then add it
369 *        after the specified link head.
370 *
371 * \param[in] prEntry        Specified link head(entry)
372 * \param[in] prOtherHead    Another link head to add it after
373 *
374 * \return (none)
375 */
376 /*----------------------------------------------------------------------------*/
377 __KAL_INLINE__ VOID
378 linkMove (
379     IN P_LINK_ENTRY_T prEntry,
380     IN P_LINK_T prLink
381     )
382 {
383     __linkDel(prEntry->prPrev, prEntry->prNext);
384     linkAdd(prEntry, prLink);
385
386     return;
387 } /* end of linkMove() */
388
389
390 /*----------------------------------------------------------------------------*/
391 /*!
392 * \brief This function will delete a specified entry from link list and then add it
393 *        before the specified link head.
394 *
395 * \param[in] prEntry        Specified link head(entry)
396 * \param[in] prOtherHead    Another link head to add it before
397 *
398 * \return (none)
399 */
400 /*----------------------------------------------------------------------------*/
401 __KAL_INLINE__ VOID
402 linkMoveTail (
403     IN P_LINK_ENTRY_T prEntry,
404     IN P_LINK_T prLink
405     )
406 {
407     __linkDel(prEntry->prPrev, prEntry->prNext);
408     linkAddTail(prEntry, prLink);
409
410     return;
411 } /* end of linkMoveTail() */
412
413 #endif /* _LINK_H */
414