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