Added support for the Hynix HY27US08121A 64MB Flash chip.
[u-boot-openmoko/mini2440.git] / drivers / net / bcm570x_queue.h
blob336b3caa4a96657bf4719b7e314cc4028fb3d02f
2 /******************************************************************************/
3 /* */
4 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
5 /* Corporation. */
6 /* All rights reserved. */
7 /* */
8 /* This program is free software; you can redistribute it and/or modify */
9 /* it under the terms of the GNU General Public License as published by */
10 /* the Free Software Foundation, located in the file LICENSE. */
11 /* */
12 /* Queue functions. */
13 /* void QQ_InitQueue(PQQ_CONTAINER pQueue) */
14 /* char QQ_Full(PQQ_CONTAINER pQueue) */
15 /* char QQ_Empty(PQQ_CONTAINER pQueue) */
16 /* unsigned int QQ_GetSize(PQQ_CONTAINER pQueue) */
17 /* unsigned int QQ_GetEntryCnt(PQQ_CONTAINER pQueue) */
18 /* char QQ_PushHead(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
19 /* char QQ_PushTail(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
20 /* PQQ_ENTRY QQ_PopHead(PQQ_CONTAINER pQueue) */
21 /* PQQ_ENTRY QQ_PopTail(PQQ_CONTAINER pQueue) */
22 /* PQQ_ENTRY QQ_GetHead(PQQ_CONTAINER pQueue, unsigned int Idx) */
23 /* PQQ_ENTRY QQ_GetTail(PQQ_CONTAINER pQueue, unsigned int Idx) */
24 /* */
25 /* */
26 /* History: */
27 /* 02/25/00 Hav Khauv Initial version. */
28 /******************************************************************************/
30 #ifndef BCM_QUEUE_H
31 #define BCM_QUEUE_H
32 #ifndef EMBEDDED
33 #define EMBEDDED 1
34 #endif
36 /******************************************************************************/
37 /* Queue definitions. */
38 /******************************************************************************/
40 /* Entry for queueing. */
41 typedef void *PQQ_ENTRY;
43 /* Linux Atomic Ops support */
44 typedef struct { int counter; } atomic_t;
48 * This combination of `inline' and `extern' has almost the effect of a
49 * macro. The way to use it is to put a function definition in a header
50 * file with these keywords, and put another copy of the definition
51 * (lacking `inline' and `extern') in a library file. The definition in
52 * the header file will cause most calls to the function to be inlined.
53 * If any uses of the function remain, they will refer to the single copy
54 * in the library.
56 extern __inline void
57 atomic_set(atomic_t* entry, int val)
59 entry->counter = val;
61 extern __inline int
62 atomic_read(atomic_t* entry)
64 return entry->counter;
66 extern __inline void
67 atomic_inc(atomic_t* entry)
69 if(entry)
70 entry->counter++;
73 extern __inline void
74 atomic_dec(atomic_t* entry)
76 if(entry)
77 entry->counter--;
80 extern __inline void
81 atomic_sub(int a, atomic_t* entry)
83 if(entry)
84 entry->counter -= a;
86 extern __inline void
87 atomic_add(int a, atomic_t* entry)
89 if(entry)
90 entry->counter += a;
94 /* Queue header -- base type. */
95 typedef struct {
96 unsigned int Head;
97 unsigned int Tail;
98 unsigned int Size;
99 atomic_t EntryCnt;
100 PQQ_ENTRY Array[1];
101 } QQ_CONTAINER, *PQQ_CONTAINER;
104 /* Declare queue type macro. */
105 #define DECLARE_QUEUE_TYPE(_QUEUE_TYPE, _QUEUE_SIZE) \
107 typedef struct { \
108 QQ_CONTAINER Container; \
109 PQQ_ENTRY EntryBuffer[_QUEUE_SIZE]; \
110 } _QUEUE_TYPE, *P##_QUEUE_TYPE
113 /******************************************************************************/
114 /* Compilation switches. */
115 /******************************************************************************/
117 #if DBG
118 #undef QQ_NO_OVERFLOW_CHECK
119 #undef QQ_NO_UNDERFLOW_CHECK
120 #endif /* DBG */
122 #ifdef QQ_USE_MACROS
123 /* notdone */
124 #else
126 #ifdef QQ_NO_INLINE
127 #define __inline
128 #endif /* QQ_NO_INLINE */
130 /******************************************************************************/
131 /* Description: */
132 /* */
133 /* Return: */
134 /******************************************************************************/
135 extern __inline void
136 QQ_InitQueue(
137 PQQ_CONTAINER pQueue,
138 unsigned int QueueSize) {
139 pQueue->Head = 0;
140 pQueue->Tail = 0;
141 pQueue->Size = QueueSize+1;
142 atomic_set(&pQueue->EntryCnt, 0);
143 } /* QQ_InitQueue */
146 /******************************************************************************/
147 /* Description: */
148 /* */
149 /* Return: */
150 /******************************************************************************/
151 extern __inline char
152 QQ_Full(
153 PQQ_CONTAINER pQueue) {
154 unsigned int NewHead;
156 NewHead = (pQueue->Head + 1) % pQueue->Size;
158 return(NewHead == pQueue->Tail);
159 } /* QQ_Full */
162 /******************************************************************************/
163 /* Description: */
164 /* */
165 /* Return: */
166 /******************************************************************************/
167 extern __inline char
168 QQ_Empty(
169 PQQ_CONTAINER pQueue) {
170 return(pQueue->Head == pQueue->Tail);
171 } /* QQ_Empty */
174 /******************************************************************************/
175 /* Description: */
176 /* */
177 /* Return: */
178 /******************************************************************************/
179 extern __inline unsigned int
180 QQ_GetSize(
181 PQQ_CONTAINER pQueue) {
182 return pQueue->Size;
183 } /* QQ_GetSize */
186 /******************************************************************************/
187 /* Description: */
188 /* */
189 /* Return: */
190 /******************************************************************************/
191 extern __inline unsigned int
192 QQ_GetEntryCnt(
193 PQQ_CONTAINER pQueue) {
194 return atomic_read(&pQueue->EntryCnt);
195 } /* QQ_GetEntryCnt */
198 /******************************************************************************/
199 /* Description: */
200 /* */
201 /* Return: */
202 /* TRUE entry was added successfully. */
203 /* FALSE queue is full. */
204 /******************************************************************************/
205 extern __inline char
206 QQ_PushHead(
207 PQQ_CONTAINER pQueue,
208 PQQ_ENTRY pEntry) {
209 unsigned int Head;
211 Head = (pQueue->Head + 1) % pQueue->Size;
213 #if !defined(QQ_NO_OVERFLOW_CHECK)
214 if(Head == pQueue->Tail) {
215 return 0;
216 } /* if */
217 #endif /* QQ_NO_OVERFLOW_CHECK */
219 pQueue->Array[pQueue->Head] = pEntry;
220 wmb();
221 pQueue->Head = Head;
222 atomic_inc(&pQueue->EntryCnt);
224 return -1;
225 } /* QQ_PushHead */
228 /******************************************************************************/
229 /* Description: */
230 /* */
231 /* Return: */
232 /* TRUE entry was added successfully. */
233 /* FALSE queue is full. */
234 /******************************************************************************/
235 extern __inline char
236 QQ_PushTail(
237 PQQ_CONTAINER pQueue,
238 PQQ_ENTRY pEntry) {
239 unsigned int Tail;
241 Tail = pQueue->Tail;
242 if(Tail == 0) {
243 Tail = pQueue->Size;
244 } /* if */
245 Tail--;
247 #if !defined(QQ_NO_OVERFLOW_CHECK)
248 if(Tail == pQueue->Head) {
249 return 0;
250 } /* if */
251 #endif /* QQ_NO_OVERFLOW_CHECK */
253 pQueue->Array[Tail] = pEntry;
254 wmb();
255 pQueue->Tail = Tail;
256 atomic_inc(&pQueue->EntryCnt);
258 return -1;
259 } /* QQ_PushTail */
262 /******************************************************************************/
263 /* Description: */
264 /* */
265 /* Return: */
266 /******************************************************************************/
267 extern __inline PQQ_ENTRY
268 QQ_PopHead(
269 PQQ_CONTAINER pQueue) {
270 unsigned int Head;
271 PQQ_ENTRY Entry;
273 Head = pQueue->Head;
275 #if !defined(QQ_NO_UNDERFLOW_CHECK)
276 if(Head == pQueue->Tail) {
277 return (PQQ_ENTRY) 0;
278 } /* if */
279 #endif /* QQ_NO_UNDERFLOW_CHECK */
281 if(Head == 0) {
282 Head = pQueue->Size;
283 } /* if */
284 Head--;
286 Entry = pQueue->Array[Head];
287 #ifdef EMBEDDED
288 membar();
289 #else
290 mb();
291 #endif
292 pQueue->Head = Head;
293 atomic_dec(&pQueue->EntryCnt);
295 return Entry;
296 } /* QQ_PopHead */
299 /******************************************************************************/
300 /* Description: */
301 /* */
302 /* Return: */
303 /******************************************************************************/
304 extern __inline PQQ_ENTRY
305 QQ_PopTail(
306 PQQ_CONTAINER pQueue) {
307 unsigned int Tail;
308 PQQ_ENTRY Entry;
310 Tail = pQueue->Tail;
312 #if !defined(QQ_NO_UNDERFLOW_CHECK)
313 if(Tail == pQueue->Head) {
314 return (PQQ_ENTRY) 0;
315 } /* if */
316 #endif /* QQ_NO_UNDERFLOW_CHECK */
318 Entry = pQueue->Array[Tail];
319 #ifdef EMBEDDED
320 membar();
321 #else
322 mb();
323 #endif
324 pQueue->Tail = (Tail + 1) % pQueue->Size;
325 atomic_dec(&pQueue->EntryCnt);
327 return Entry;
328 } /* QQ_PopTail */
331 /******************************************************************************/
332 /* Description: */
333 /* */
334 /* Return: */
335 /******************************************************************************/
336 extern __inline PQQ_ENTRY
337 QQ_GetHead(
338 PQQ_CONTAINER pQueue,
339 unsigned int Idx)
341 if(Idx >= atomic_read(&pQueue->EntryCnt))
343 return (PQQ_ENTRY) 0;
346 if(pQueue->Head > Idx)
348 Idx = pQueue->Head - Idx;
350 else
352 Idx = pQueue->Size - (Idx - pQueue->Head);
354 Idx--;
356 return pQueue->Array[Idx];
360 /******************************************************************************/
361 /* Description: */
362 /* */
363 /* Return: */
364 /******************************************************************************/
365 extern __inline PQQ_ENTRY
366 QQ_GetTail(
367 PQQ_CONTAINER pQueue,
368 unsigned int Idx)
370 if(Idx >= atomic_read(&pQueue->EntryCnt))
372 return (PQQ_ENTRY) 0;
375 Idx += pQueue->Tail;
376 if(Idx >= pQueue->Size)
378 Idx = Idx - pQueue->Size;
381 return pQueue->Array[Idx];
384 #endif /* QQ_USE_MACROS */
387 #endif /* QUEUE_H */