2 ** $Id: //Department/DaVinci/BRANCHES/MT662X_593X_WIFI_DRIVER_V2_3/include/link.h#1 $
6 \brief Definition for simple doubly linked list operations.
8 In this file we define the simple doubly linked list data structure and its
9 operation MACROs and INLINE functions.
12 /*******************************************************************************
13 * Copyright (c) 2007 MediaTek Inc.
15 * All rights reserved. Copying, compilation, modification, distribution
16 * or any other use whatsoever of this material is strictly prohibited
17 * except in accordance with a Software License Agreement with
19 ********************************************************************************
22 /*******************************************************************************
25 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
26 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
27 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
28 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
29 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
30 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
31 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
32 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
33 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
34 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
35 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
36 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
37 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
39 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
40 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
41 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
42 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
43 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
45 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
46 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
47 * OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
48 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
49 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
51 ********************************************************************************
57 * 08 05 2010 yuche.tsai
59 * Modify a MACRO of LINK_FOR_EACH_SAFE for compile error.
63 * Set RLM parameters and enable CNM channel manager
67 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
70 * [WPD00003833][MT6620 and MT5931] Driver migration
71 * [WPD00003833] [MT6620 and MT5931] Driver migration
78 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
79 * add WIFI to BORA source control
80 ** \main\maintrunk.MT5921\8 2008-10-16 15:57:11 GMT mtk01461
81 ** Update driver to fix lint warning
82 ** \main\maintrunk.MT5921\7 2008-08-10 18:47:53 GMT mtk01461
83 ** Update for Driver Review
84 ** \main\maintrunk.MT5921\6 2007-12-11 00:09:00 GMT mtk01461
85 ** Add macro for checking valid list
86 ** \main\maintrunk.MT5921\5 2007-11-13 14:27:01 GMT mtk01461
87 ** Add LINK_IS_INVALID macro
88 ** Revision 1.1.1.1 2007/06/22 08:09:05 MTK01461
96 /*******************************************************************************
97 * C O M P I L E R F L A G S
98 ********************************************************************************
101 /*******************************************************************************
102 * E X T E R N A L R E F E R E N C E S
103 ********************************************************************************
105 #include "gl_typedef.h"
108 /*******************************************************************************
110 ********************************************************************************
112 #define INVALID_LINK_POISON1 ((VOID *) 0x00100101) // May cause page fault & unalignment issue (data abort)
113 #define INVALID_LINK_POISON2 ((VOID *) 0x00100201) // Used to verify that nonbody uses non-initialized link entries.
116 /*******************************************************************************
118 ********************************************************************************
120 /* Simple Doubly Linked List Structures - Entry Part */
121 typedef struct _LINK_ENTRY_T {
122 struct _LINK_ENTRY_T *prNext, *prPrev;
123 } LINK_ENTRY_T, *P_LINK_ENTRY_T;
125 /* Simple Doubly Linked List Structures - List Part */
126 typedef struct _LINK_T {
127 P_LINK_ENTRY_T prNext;
128 P_LINK_ENTRY_T prPrev;
132 /*******************************************************************************
133 * P U B L I C D A T A
134 ********************************************************************************
137 /*******************************************************************************
138 * P R I V A T E D A T A
139 ********************************************************************************
142 /*******************************************************************************
144 ********************************************************************************
146 #if 0 // No one use it, temporarily mark it for [Lint - Info 773]
147 #define LINK_ADDR(rLink) { (P_LINK_ENTRY_T)(&(rLink)), (P_LINK_ENTRY_T)(&(rLink)), 0 }
149 #define LINK_DECLARATION(rLink) \
150 struct _LINK_T rLink = LINK_ADDR(rLink)
153 #define LINK_INITIALIZE(prLink) \
155 ((P_LINK_T)(prLink))->prNext = (P_LINK_ENTRY_T)(prLink); \
156 ((P_LINK_T)(prLink))->prPrev = (P_LINK_ENTRY_T)(prLink); \
157 ((P_LINK_T)(prLink))->u4NumElem = 0; \
160 #define LINK_ENTRY_INITIALIZE(prEntry) \
162 ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)NULL; \
163 ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)NULL; \
166 #define LINK_ENTRY_INVALID(prEntry) \
168 ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)INVALID_LINK_POISON1; \
169 ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)INVALID_LINK_POISON2; \
172 #define LINK_IS_EMPTY(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)(prLink))
174 /* NOTE: We should do memory zero before any LINK been initiated, so we can check
175 * if it is valid before parsing the LINK.
177 #define LINK_IS_INVALID(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)NULL)
179 #define LINK_IS_VALID(prLink) (((P_LINK_T)(prLink))->prNext != (P_LINK_ENTRY_T)NULL)
182 #define LINK_ENTRY(ptr, type, member) ENTRY_OF(ptr, type, member)
184 /* Insert an entry into a link list's head */
185 #define LINK_INSERT_HEAD(prLink, prEntry) \
187 linkAdd(prEntry, prLink); \
188 ((prLink)->u4NumElem)++; \
192 /* Append an entry into a link list's tail */
193 #define LINK_INSERT_TAIL(prLink, prEntry) \
195 linkAddTail(prEntry, prLink); \
196 ((prLink)->u4NumElem)++; \
199 /* Peek head entry, but keep still in link list */
200 #define LINK_PEEK_HEAD(prLink, _type, _member) \
202 LINK_IS_EMPTY(prLink) ? \
203 NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \
206 /* Peek tail entry, but keep still in link list */
207 #define LINK_PEEK_TAIL(prLink, _type, _member) \
209 LINK_IS_EMPTY(prLink) ? \
210 NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \
213 /* Get first entry from a link list */
214 /* NOTE: We assume the link entry located at the beginning of "prEntry Type",
215 * so that we can cast the link entry to other data type without doubts.
216 * And this macro also decrease the total entry count at the same time.
218 #define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \
221 if (LINK_IS_EMPTY(prLink)) { \
222 prEntry = (_P_TYPE)NULL; \
225 prEntry = (_P_TYPE)(((P_LINK_T)(prLink))->prNext); \
226 linkDel((P_LINK_ENTRY_T)prEntry); \
227 ((prLink)->u4NumElem)--; \
231 /* Assume the link entry located at the beginning of prEntry Type.
232 * And also decrease the total entry count.
234 #define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \
238 linkDel((P_LINK_ENTRY_T)prEntry); \
239 ((prLink)->u4NumElem)--; \
242 /* Iterate over a link list */
243 #define LINK_FOR_EACH(prEntry, prLink) \
244 for (prEntry = (prLink)->prNext; \
245 prEntry != (P_LINK_ENTRY_T)(prLink); \
246 prEntry = (P_LINK_ENTRY_T)prEntry->prNext)
248 /* Iterate over a link list backwards */
249 #define LINK_FOR_EACH_PREV(prEntry, prLink) \
250 for (prEntry = (prLink)->prPrev; \
251 prEntry != (P_LINK_ENTRY_T)(prLink); \
252 prEntry = (P_LINK_ENTRY_T)prEntry->prPrev)
254 /* Iterate over a link list safe against removal of link entry */
255 #define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \
256 for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \
257 prEntry != (P_LINK_ENTRY_T)(prLink); \
258 prEntry = prNextEntry, prNextEntry = prEntry->prNext)
260 /* Iterate over a link list of given type */
261 #define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \
262 for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \
263 &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
264 prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember))
266 /* Iterate backwards over a link list of given type */
267 #define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \
268 for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember); \
269 &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
270 prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember))
272 /* Iterate over a link list of given type safe against removal of link entry */
273 #define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \
274 for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember), \
275 prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \
276 &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
278 prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember))
280 /*******************************************************************************
281 * F U N C T I O N D E C L A R A T I O N S
282 ********************************************************************************
285 /*******************************************************************************
287 ********************************************************************************
289 /*----------------------------------------------------------------------------*/
291 * \brief This function is only for internal link list manipulation.
293 * \param[in] prNew Pointer of new link head
294 * \param[in] prPrev Pointer of previous link head
295 * \param[in] prNext Pointer of next link head
299 /*----------------------------------------------------------------------------*/
302 IN P_LINK_ENTRY_T prNew,
303 IN P_LINK_ENTRY_T prPrev,
304 IN P_LINK_ENTRY_T prNext
307 prNext->prPrev = prNew;
308 prNew->prNext = prNext;
309 prNew->prPrev = prPrev;
310 prPrev->prNext = prNew;
313 } /* end of __linkAdd() */
316 /*----------------------------------------------------------------------------*/
318 * \brief This function will add a new entry after the specified link head.
320 * \param[in] prNew New entry to be added
321 * \param[in] prHead Specified link head to add it after
325 /*----------------------------------------------------------------------------*/
328 IN P_LINK_ENTRY_T prNew,
332 __linkAdd(prNew, (P_LINK_ENTRY_T)prLink, prLink->prNext);
335 } /* end of linkAdd() */
338 /*----------------------------------------------------------------------------*/
340 * \brief This function will add a new entry before the specified link head.
342 * \param[in] prNew New entry to be added
343 * \param[in] prHead Specified link head to add it before
347 /*----------------------------------------------------------------------------*/
350 IN P_LINK_ENTRY_T prNew,
354 __linkAdd(prNew, prLink->prPrev, (P_LINK_ENTRY_T)prLink);
357 } /* end of linkAddTail() */
360 /*----------------------------------------------------------------------------*/
362 * \brief This function is only for internal link list manipulation.
364 * \param[in] prPrev Pointer of previous link head
365 * \param[in] prNext Pointer of next link head
369 /*----------------------------------------------------------------------------*/
372 IN P_LINK_ENTRY_T prPrev,
373 IN P_LINK_ENTRY_T prNext
376 prNext->prPrev = prPrev;
377 prPrev->prNext = prNext;
380 } /* end of __linkDel() */
383 /*----------------------------------------------------------------------------*/
385 * \brief This function will delete a specified entry from link list.
386 * NOTE: the entry is in an initial state.
388 * \param prEntry Specified link head(entry)
392 /*----------------------------------------------------------------------------*/
395 IN P_LINK_ENTRY_T prEntry
398 __linkDel(prEntry->prPrev, prEntry->prNext);
400 LINK_ENTRY_INITIALIZE(prEntry);
403 } /* end of linkDel() */
406 /*----------------------------------------------------------------------------*/
408 * \brief This function will delete a specified entry from link list and then add it
409 * after the specified link head.
411 * \param[in] prEntry Specified link head(entry)
412 * \param[in] prOtherHead Another link head to add it after
416 /*----------------------------------------------------------------------------*/
419 IN P_LINK_ENTRY_T prEntry,
423 __linkDel(prEntry->prPrev, prEntry->prNext);
424 linkAdd(prEntry, prLink);
427 } /* end of linkMove() */
430 /*----------------------------------------------------------------------------*/
432 * \brief This function will delete a specified entry from link list and then add it
433 * before the specified link head.
435 * \param[in] prEntry Specified link head(entry)
436 * \param[in] prOtherHead Another link head to add it before
440 /*----------------------------------------------------------------------------*/
443 IN P_LINK_ENTRY_T prEntry,
447 __linkDel(prEntry->prPrev, prEntry->prNext);
448 linkAddTail(prEntry, prLink);
451 } /* end of linkMoveTail() */