blob: 2c3e302696c1cf266571f5dd3be047985db0290b [file] [log] [blame]
Wolfgang Denk4646d2a2006-05-30 15:56:48 +02001/**
2 * @file IxQMgrQAccess.c
3 *
4 * @author Intel Corporation
5 * @date 30-Oct-2001
6 *
7 * @brief This file contains functions for putting entries on a queue and
8 * removing entries from a queue.
9 *
10 *
11 * @par
12 * IXP400 SW Release version 2.0
13 *
14 * -- Copyright Notice --
15 *
16 * @par
17 * Copyright 2001-2005, Intel Corporation.
18 * All rights reserved.
19 *
20 * @par
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. Neither the name of the Intel Corporation nor the names of its contributors
30 * may be used to endorse or promote products derived from this software
31 * without specific prior written permission.
32 *
33 * @par
34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
35 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 *
46 * @par
47 * -- End of Copyright Notice --
48*/
49
50/*
51 * Inlines are compiled as function when this is defined.
52 * N.B. Must be placed before #include of "IxQMgr.h"
53 */
54#ifndef IXQMGR_H
55# define IXQMGRQACCESS_C
56#else
57# error
58#endif
59
60/*
61 * System defined include files.
62 */
63
64/*
65 * User defined include files.
66 */
67#include "IxQMgr.h"
68#include "IxQMgrAqmIf_p.h"
69#include "IxQMgrQAccess_p.h"
70#include "IxQMgrQCfg_p.h"
71#include "IxQMgrDefines_p.h"
72
73/*
74 * Global variables and extern definitions
75 */
76extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
77
78/*
79 * Function definitions.
80 */
81void
82ixQMgrQAccessInit (void)
83{
84}
85
86IX_STATUS
87ixQMgrQReadWithChecks (IxQMgrQId qId,
88 UINT32 *entry)
89{
90 IxQMgrQEntrySizeInWords entrySizeInWords;
91 IxQMgrQInlinedReadWriteInfo *infoPtr;
92
93 if (NULL == entry)
94 {
95 return IX_QMGR_PARAMETER_ERROR;
96 }
97
98 /* Check QId */
99 if (!ixQMgrQIsConfigured(qId))
100 {
101 return IX_QMGR_Q_NOT_CONFIGURED;
102 }
103
104 /* Get the q entry size in words */
105 entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
106
107 ixQMgrAqmIfQPop (qId, entrySizeInWords, entry);
108
109 /* reset the current read count if the counter wrapped around
110 * (unsigned arithmetic)
111 */
112 infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
113 if (infoPtr->qReadCount-- > infoPtr->qSizeInEntries)
114 {
115 infoPtr->qReadCount = 0;
116 }
117
118 /* Check if underflow occurred on the read */
119 if (ixQMgrAqmIfUnderflowCheck (qId))
120 {
121 return IX_QMGR_Q_UNDERFLOW;
122 }
123
124 return IX_SUCCESS;
125}
126
127/* this function reads the remaining of the q entry
128 * for queues configured with many words.
129 * (the first word of the entry is already read
130 * in the inlined function and the entry pointer already
131 * incremented
132 */
133IX_STATUS
134ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
135 UINT32 *entry)
136{
137 IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
138 UINT32 entrySize = infoPtr->qEntrySizeInWords;
139 volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
140
141 while (--entrySize)
142 {
143 /* read the entry and accumulate the result */
144 *(++entry) = IX_OSAL_READ_LONG(++qAccRegAddr);
145 }
146 /* underflow is available for lower queues only */
147 if (qId < IX_QMGR_MIN_QUEUPP_QID)
148 {
149 /* get the queue status */
150 UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
151
152 /* check the underflow status */
153 if (status & infoPtr->qUflowStatBitMask)
154 {
155 /* the queue is empty
156 * clear the underflow status bit if it was set
157 */
158 IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
159 status & ~infoPtr->qUflowStatBitMask);
160 return IX_QMGR_Q_UNDERFLOW;
161 }
162 }
163 return IX_SUCCESS;
164}
165
166IX_STATUS
167ixQMgrQWriteWithChecks (IxQMgrQId qId,
168 UINT32 *entry)
169{
170 IxQMgrQEntrySizeInWords entrySizeInWords;
171 IxQMgrQInlinedReadWriteInfo *infoPtr;
172
173 if (NULL == entry)
174 {
175 return IX_QMGR_PARAMETER_ERROR;
176 }
177
178 /* Check QId */
179 if (!ixQMgrQIsConfigured(qId))
180 {
181 return IX_QMGR_Q_NOT_CONFIGURED;
182 }
183
184 /* Get the q entry size in words */
185 entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
186
187 ixQMgrAqmIfQPush (qId, entrySizeInWords, entry);
188
189 /* reset the current read count if the counter wrapped around
190 * (unsigned arithmetic)
191 */
192 infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
193 if (infoPtr->qWriteCount++ >= infoPtr->qSizeInEntries)
194 {
195 infoPtr->qWriteCount = infoPtr->qSizeInEntries;
196 }
197
198 /* Check if overflow occurred on the write*/
199 if (ixQMgrAqmIfOverflowCheck (qId))
200 {
201 return IX_QMGR_Q_OVERFLOW;
202 }
203
204 return IX_SUCCESS;
205}
206
207IX_STATUS
208ixQMgrQPeek (IxQMgrQId qId,
209 unsigned int entryIndex,
210 UINT32 *entry)
211{
212 unsigned int numEntries;
213
214#ifndef NDEBUG
215 if ((NULL == entry) || (entryIndex >= IX_QMGR_Q_SIZE_INVALID))
216 {
217 return IX_QMGR_PARAMETER_ERROR;
218 }
219
220 if (!ixQMgrQIsConfigured(qId))
221 {
222 return IX_QMGR_Q_NOT_CONFIGURED;
223 }
224#endif
225
226 if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
227 {
228 return IX_FAIL;
229 }
230
231 if (entryIndex >= numEntries) /* entryIndex starts at 0 */
232 {
233 return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
234 }
235
236 return ixQMgrAqmIfQPeek (qId, entryIndex, entry);
237}
238
239IX_STATUS
240ixQMgrQPoke (IxQMgrQId qId,
241 unsigned entryIndex,
242 UINT32 *entry)
243{
244 unsigned int numEntries;
245
246#ifndef NDEBUG
247 if ((NULL == entry) || (entryIndex > 128))
248 {
249 return IX_QMGR_PARAMETER_ERROR;
250 }
251
252 if (!ixQMgrQIsConfigured(qId))
253 {
254 return IX_QMGR_Q_NOT_CONFIGURED;
255 }
256#endif
257
258 if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
259 {
260 return IX_FAIL;
261 }
262
263 if (numEntries < (entryIndex + 1)) /* entryIndex starts at 0 */
264 {
265 return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
266 }
267
268 return ixQMgrAqmIfQPoke (qId, entryIndex, entry);
269}
270
271IX_STATUS
272ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
273 IxQMgrQStatus *qStatus)
274{
275 if (NULL == qStatus)
276 {
277 return IX_QMGR_PARAMETER_ERROR;
278 }
279
280 if (!ixQMgrQIsConfigured (qId))
281 {
282 return IX_QMGR_Q_NOT_CONFIGURED;
283 }
284
285 ixQMgrAqmIfQueStatRead (qId, qStatus);
286
287 return IX_SUCCESS;
288}
289
290IX_STATUS
291ixQMgrQNumEntriesGet (IxQMgrQId qId,
292 unsigned *numEntriesPtr)
293{
294 UINT32 qPtrs;
295 UINT32 qStatus;
296 unsigned numEntries;
297 IxQMgrQInlinedReadWriteInfo *infoPtr;
298
299
300#ifndef NDEBUG
301 if (NULL == numEntriesPtr)
302 {
303 return IX_QMGR_PARAMETER_ERROR;
304 }
305
306 /* Check QId */
307 if (!ixQMgrQIsConfigured(qId))
308 {
309 return IX_QMGR_Q_NOT_CONFIGURED;
310 }
311#endif
312
313 /* get fast access data */
314 infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
315
316 /* get snapshot */
317 qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
318
319 /* Mod subtraction of pointers to get number of words in Q. */
320 numEntries = (qPtrs - (qPtrs >> 7)) & 0x7f;
321
322 if (numEntries == 0)
323 {
324 /*
325 * Could mean either full or empty queue
326 * so look at status
327 */
328 ixQMgrAqmIfQueStatRead (qId, &qStatus);
329
330 if (qId < IX_QMGR_MIN_QUEUPP_QID)
331 {
332 if (qStatus & IX_QMGR_Q_STATUS_E_BIT_MASK)
333 {
334 /* Empty */
335 *numEntriesPtr = 0;
336 }
337 else if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
338 {
339 /* Full */
340 *numEntriesPtr = infoPtr->qSizeInEntries;
341 }
342 else
343 {
344 /*
345 * Queue status and read/write pointers are volatile.
346 * The queue state has changed since we took the
347 * snapshot of the read and write pointers.
348 * Client can retry if they wish
349 */
350 *numEntriesPtr = 0;
351 return IX_QMGR_WARNING;
352 }
353 }
354 else /* It is an upper queue which does not have an empty status bit maintained */
355 {
356 if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
357 {
358 /* The queue is Full at the time of snapshot. */
359 *numEntriesPtr = infoPtr->qSizeInEntries;
360 }
361 else
362 {
363 /* The queue is either empty, either moving,
364 * Client can retry if they wish
365 */
366 *numEntriesPtr = 0;
367 return IX_QMGR_WARNING;
368 }
369 }
370 }
371 else
372 {
373 *numEntriesPtr = (numEntries / infoPtr->qEntrySizeInWords) & (infoPtr->qSizeInEntries - 1);
374 }
375
376 return IX_SUCCESS;
377}
378
379#if defined(__wince) && defined(NO_INLINE_APIS)
380
381PUBLIC IX_STATUS
382ixQMgrQRead (IxQMgrQId qId,
383 UINT32 *entryPtr)
384{
385 extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
386 IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
387 UINT32 entry, entrySize;
388
389 /* get a new entry */
390 entrySize = infoPtr->qEntrySizeInWords;
391 entry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
392
393 if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
394 {
395 *entryPtr = entry;
396 /* process the remaining part of the entry */
397 return ixQMgrQReadMWordsMinus1(qId, entryPtr);
398 }
399
400 /* underflow is available for lower queues only */
401 if (qId < IX_QMGR_MIN_QUEUPP_QID)
402 {
403 /* the counter of queue entries is decremented. In happy
404 * day scenario there are many entries in the queue
405 * and the counter does not reach zero.
406 */
407 if (infoPtr->qReadCount-- == 0)
408 {
409 /* There is maybe no entry in the queue
410 * qReadCount is now negative, but will be corrected before
411 * the function returns.
412 */
413 UINT32 qPtrs; /* queue internal pointers */
414
415 /* when a queue is empty, the hw guarantees to return
416 * a null value. If the value is not null, the queue is
417 * not empty.
418 */
419 if (entry == 0)
420 {
421 /* get the queue status */
422 UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
423
424 /* check the underflow status */
425 if (status & infoPtr->qUflowStatBitMask)
426 {
427 /* the queue is empty
428 * clear the underflow status bit if it was set
429 */
430 IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
431 status & ~infoPtr->qUflowStatBitMask);
432 *entryPtr = 0;
433 infoPtr->qReadCount = 0;
434 return IX_QMGR_Q_UNDERFLOW;
435 }
436 }
437 /* store the result */
438 *entryPtr = entry;
439
440 /* No underflow occured : someone is filling the queue
441 * or the queue contains null entries.
442 * The current counter needs to be
443 * updated from the current number of entries in the queue
444 */
445
446 /* get snapshot of queue pointers */
447 qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
448
449 /* Mod subtraction of pointers to get number of words in Q. */
450 qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
451
452 if (qPtrs == 0)
453 {
454 /* no entry in the queue */
455 infoPtr->qReadCount = 0;
456 }
457 else
458 {
459 /* convert the number of words inside the queue
460 * to a number of entries
461 */
462 infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1);
463 }
464 return IX_SUCCESS;
465 }
466 }
467 *entryPtr = entry;
468 return IX_SUCCESS;
469}
470
471PUBLIC IX_STATUS
472ixQMgrQBurstRead (IxQMgrQId qId,
473 UINT32 numEntries,
474 UINT32 *entries)
475{
476 extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
477 IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
478 UINT32 nullCheckEntry;
479
480 if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
481 {
482 volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
483
484 /* the code is optimized to take care of data dependencies:
485 * Durig a read, there are a few cycles needed to get the
486 * read complete. During these cycles, it is poossible to
487 * do some CPU, e.g. increment pointers and decrement
488 * counters.
489 */
490
491 /* fetch a queue entry */
492 nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
493
494 /* iterate the specified number of queue entries */
495 while (--numEntries)
496 {
497 /* check the result of the previous read */
498 if (nullCheckEntry == 0)
499 {
500 /* if we read a NULL entry, stop. We have underflowed */
501 break;
502 }
503 else
504 {
505 /* write the entry */
506 *entries = nullCheckEntry;
507 /* fetch next entry */
508 nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr);
509 /* increment the write address */
510 entries++;
511 }
512 }
513 /* write the pre-fetched entry */
514 *entries = nullCheckEntry;
515 }
516 else
517 {
518 IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
519 /* read the specified number of queue entries */
520 nullCheckEntry = 0;
521 while (numEntries--)
522 {
523 int i;
524
525 for (i = 0; i < entrySizeInWords; i++)
526 {
527 *entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i);
528 nullCheckEntry |= *entries++;
529 }
530
531 /* if we read a NULL entry, stop. We have underflowed */
532 if (nullCheckEntry == 0)
533 {
534 break;
535 }
536 nullCheckEntry = 0;
537 }
538 }
539
540 /* reset the current read count : next access to the read function
541 * will force a underflow status check
542 */
543 infoPtr->qWriteCount = 0;
544
545 /* Check if underflow occurred on the read */
546 if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID)
547 {
548 /* get the queue status */
549 UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
550
551 if (status & infoPtr->qUflowStatBitMask)
552 {
553 /* clear the underflow status bit if it was set */
554 IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
555 status & ~infoPtr->qUflowStatBitMask);
556 return IX_QMGR_Q_UNDERFLOW;
557 }
558 }
559
560 return IX_SUCCESS;
561}
562
563PUBLIC IX_STATUS
564ixQMgrQWrite (IxQMgrQId qId,
565 UINT32 *entry)
566{
567 extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
568 IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
569 UINT32 entrySize;
570
571 /* write the entry */
572 IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry);
573 entrySize = infoPtr->qEntrySizeInWords;
574
575 if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
576 {
577 /* process the remaining part of the entry */
578 volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
579 while (--entrySize)
580 {
581 ++entry;
582 IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry);
583 }
584 entrySize = infoPtr->qEntrySizeInWords;
585 }
586
587 /* overflow is available for lower queues only */
588 if (qId < IX_QMGR_MIN_QUEUPP_QID)
589 {
590 UINT32 qSize = infoPtr->qSizeInEntries;
591 /* increment the current number of entries in the queue
592 * and check for overflow
593 */
594 if (infoPtr->qWriteCount++ == qSize)
595 {
596 /* the queue may have overflow */
597 UINT32 qPtrs; /* queue internal pointers */
598
599 /* get the queue status */
600 UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
601
602 /* read the status twice because the status may
603 * not be immediately ready after the write operation
604 */
605 if ((status & infoPtr->qOflowStatBitMask) ||
606 ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
607 & infoPtr->qOflowStatBitMask))
608 {
609 /* the queue is full, clear the overflow status
610 * bit if it was set
611 */
612 IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
613 status & ~infoPtr->qOflowStatBitMask);
614 infoPtr->qWriteCount = infoPtr->qSizeInEntries;
615 return IX_QMGR_Q_OVERFLOW;
616 }
617 /* No overflow occured : someone is draining the queue
618 * and the current counter needs to be
619 * updated from the current number of entries in the queue
620 */
621
622 /* get q pointer snapshot */
623 qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
624
625 /* Mod subtraction of pointers to get number of words in Q. */
626 qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
627
628 if (qPtrs == 0)
629 {
630 /* the queue may be full at the time of the
631 * snapshot. Next access will check
632 * the overflow status again.
633 */
634 infoPtr->qWriteCount = qSize;
635 }
636 else
637 {
638 /* convert the number of words to a number of entries */
639 if (entrySize == IX_QMGR_Q_ENTRY_SIZE1)
640 {
641 infoPtr->qWriteCount = qPtrs & (qSize - 1);
642 }
643 else
644 {
645 infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1);
646 }
647 }
648 }
649 }
650 return IX_SUCCESS;
651}
652
653PUBLIC IX_STATUS
654ixQMgrQBurstWrite (IxQMgrQId qId,
655 unsigned numEntries,
656 UINT32 *entries)
657{
658 extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
659 IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
660 UINT32 status;
661
662 /* update the current write count */
663 infoPtr->qWriteCount += numEntries;
664
665 if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
666 {
667 volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
668 while (numEntries--)
669 {
670 IX_OSAL_WRITE_LONG(qAccRegAddr, *entries);
671 entries++;
672 }
673 }
674 else
675 {
676 IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
677 int i;
678
679 /* write each queue entry */
680 while (numEntries--)
681 {
682 /* write the queueEntrySize number of words for each entry */
683 for (i = 0; i < entrySizeInWords; i++)
684 {
685 IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries);
686 entries++;
687 }
688 }
689 }
690
691 /* check if the write count overflows */
692 if (infoPtr->qWriteCount > infoPtr->qSizeInEntries)
693 {
694 /* reset the current write count */
695 infoPtr->qWriteCount = infoPtr->qSizeInEntries;
696 }
697
698 /* Check if overflow occurred on the write operation */
699 if (qId < IX_QMGR_MIN_QUEUPP_QID)
700 {
701 /* get the queue status */
702 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
703
704 /* read the status twice because the status may
705 * not be ready at the time of the write
706 */
707 if ((status & infoPtr->qOflowStatBitMask) ||
708 ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
709 & infoPtr->qOflowStatBitMask))
710 {
711 /* clear the underflow status bit if it was set */
712 IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
713 status & ~infoPtr->qOflowStatBitMask);
714 return IX_QMGR_Q_OVERFLOW;
715 }
716 }
717
718 return IX_SUCCESS;
719}
720
721PUBLIC IX_STATUS
722ixQMgrQStatusGet (IxQMgrQId qId,
723 IxQMgrQStatus *qStatus)
724{
725 /* read the status of a queue in the range 0-31 */
726 if (qId < IX_QMGR_MIN_QUEUPP_QID)
727 {
728 extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[];
729 extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[];
730 extern UINT32 ixQMgrAqmIfQueLowStatBitsMask;
731 extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
732 IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
733 volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId];
734 volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr;
735
736 UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId];
737 UINT32 lowStatBitsMask = ixQMgrAqmIfQueLowStatBitsMask;
738 UINT32 underflowBitMask = infoPtr->qUflowStatBitMask;
739 UINT32 overflowBitMask = infoPtr->qOflowStatBitMask;
740
741 /* read the status register for this queue */
742 *qStatus = IX_OSAL_READ_LONG(lowStatRegAddr);
743 /* mask out the status bits relevant only to this queue */
744 *qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask;
745
746 /* Check if the queue has overflowed */
747 if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask)
748 {
749 /* clear the overflow status bit if it was set */
750 IX_OSAL_WRITE_LONG(qUOStatRegAddr,
751 (IX_OSAL_READ_LONG(qUOStatRegAddr) &
752 ~overflowBitMask));
753 *qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK;
754 }
755
756 /* Check if the queue has underflowed */
757 if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask)
758 {
759 /* clear the underflow status bit if it was set */
760 IX_OSAL_WRITE_LONG(qUOStatRegAddr,
761 (IX_OSAL_READ_LONG(qUOStatRegAddr) &
762 ~underflowBitMask));
763 *qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK;
764 }
765 }
766 else /* read status of a queue in the range 32-63 */
767 {
768 extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
769 extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
770 extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[];
771 extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[];
772
773 volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr;
774 volatile UINT32 *qFullStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr;
775 int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID;
776 UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex];
777 UINT32 qFullStatBitMask = ixQMgrAqmIfQueUppStat1BitMask[maskIndex];
778
779 /* Reset the status bits */
780 *qStatus = 0;
781
782 /* Check if the queue is nearly empty */
783 if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask)
784 {
785 *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
786 }
787
788 /* Check if the queue is full */
789 if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask)
790 {
791 *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK;
792 }
793 }
794 return IX_SUCCESS;
795}
796#endif /* def NO_INLINE_APIS */