diff options
Diffstat (limited to 'drivers/net/npe/IxQMgrQAccess.c')
| -rw-r--r-- | drivers/net/npe/IxQMgrQAccess.c | 796 | 
1 files changed, 796 insertions, 0 deletions
| diff --git a/drivers/net/npe/IxQMgrQAccess.c b/drivers/net/npe/IxQMgrQAccess.c new file mode 100644 index 000000000..888573624 --- /dev/null +++ b/drivers/net/npe/IxQMgrQAccess.c @@ -0,0 +1,796 @@ +/** + * @file    IxQMgrQAccess.c + * + * @author Intel Corporation + * @date    30-Oct-2001 + * + * @brief   This file contains functions for putting entries on a queue and + * removing entries from a queue. + * + *  + * @par + * IXP400 SW Release version 2.0 + *  + * -- Copyright Notice -- + *  + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + *  + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + *  + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * @par + * -- End of Copyright Notice -- +*/ + +/* + * Inlines are compiled as function when this is defined. + * N.B. Must be placed before #include of "IxQMgr.h" + */ +#ifndef IXQMGR_H +#    define IXQMGRQACCESS_C +#else +#    error +#endif + +/* + * System defined include files. + */ + +/* + * User defined include files. + */ +#include "IxQMgr.h" +#include "IxQMgrAqmIf_p.h" +#include "IxQMgrQAccess_p.h" +#include "IxQMgrQCfg_p.h" +#include "IxQMgrDefines_p.h" + +/* + * Global variables and extern definitions + */ +extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; + +/* + * Function definitions. + */ +void +ixQMgrQAccessInit (void) +{    +} + +IX_STATUS +ixQMgrQReadWithChecks (IxQMgrQId qId, +                       UINT32 *entry) +{ +    IxQMgrQEntrySizeInWords entrySizeInWords; +    IxQMgrQInlinedReadWriteInfo *infoPtr; + +    if (NULL == entry) +    { +	return IX_QMGR_PARAMETER_ERROR; +    } + +    /* Check QId */ +    if (!ixQMgrQIsConfigured(qId)) +    { +	return IX_QMGR_Q_NOT_CONFIGURED; +    } + +    /* Get the q entry size in words */ +    entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId); + +    ixQMgrAqmIfQPop (qId, entrySizeInWords, entry);	     + +    /* reset the current read count if the counter wrapped around  +    * (unsigned arithmetic) +    */ +    infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; +    if (infoPtr->qReadCount-- > infoPtr->qSizeInEntries) +    { +	infoPtr->qReadCount = 0; +    } + +    /* Check if underflow occurred on the read */ +    if (ixQMgrAqmIfUnderflowCheck (qId)) +    { +	return IX_QMGR_Q_UNDERFLOW; +    } +     +    return IX_SUCCESS; +} + +/* this function reads the remaining of the q entry + * for queues configured with many words. + * (the first word of the entry is already read  + * in the inlined function and the entry pointer already + * incremented + */ +IX_STATUS +ixQMgrQReadMWordsMinus1 (IxQMgrQId qId, +			 UINT32 *entry) +{ +    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; +    UINT32 entrySize = infoPtr->qEntrySizeInWords; +    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; +     +    while (--entrySize) +    { +	/* read the entry and accumulate the result */ +	*(++entry) = IX_OSAL_READ_LONG(++qAccRegAddr); +    } +    /* underflow is available for lower queues only */ +    if (qId < IX_QMGR_MIN_QUEUPP_QID) +    { +	/* get the queue status */ +	UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); +	 +	/* check the underflow status */ +	if (status & infoPtr->qUflowStatBitMask) +	{ +	    /* the queue is empty  +	     *  clear the underflow status bit if it was set  +	     */ +	    IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, +				 status & ~infoPtr->qUflowStatBitMask); +	    return IX_QMGR_Q_UNDERFLOW; +	} +    } +    return IX_SUCCESS; +} + +IX_STATUS +ixQMgrQWriteWithChecks (IxQMgrQId qId, +                        UINT32 *entry) +{ +    IxQMgrQEntrySizeInWords entrySizeInWords; +    IxQMgrQInlinedReadWriteInfo *infoPtr; + +    if (NULL == entry) +    { +	return IX_QMGR_PARAMETER_ERROR; +    } + +    /* Check QId */ +    if (!ixQMgrQIsConfigured(qId)) +    { +	return IX_QMGR_Q_NOT_CONFIGURED; +    } + +    /* Get the q entry size in words */ +    entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId); +     +    ixQMgrAqmIfQPush (qId, entrySizeInWords, entry); + +    /* reset the current read count if the counter wrapped around  +    * (unsigned arithmetic) +    */ +    infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; +    if (infoPtr->qWriteCount++ >= infoPtr->qSizeInEntries) +    { +	infoPtr->qWriteCount = infoPtr->qSizeInEntries; +    } + +    /* Check if overflow occurred on the write*/ +    if (ixQMgrAqmIfOverflowCheck (qId)) +    { +	return IX_QMGR_Q_OVERFLOW; +    } +          +    return IX_SUCCESS; +} + +IX_STATUS +ixQMgrQPeek (IxQMgrQId qId, +	     unsigned int entryIndex, +	     UINT32 *entry) +{ +    unsigned int numEntries; + +#ifndef NDEBUG +    if ((NULL == entry) || (entryIndex >= IX_QMGR_Q_SIZE_INVALID)) +    { +	return IX_QMGR_PARAMETER_ERROR; +    } + +    if (!ixQMgrQIsConfigured(qId)) +    { +	return IX_QMGR_Q_NOT_CONFIGURED; +    } +#endif +     +    if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries)) +    { +	return IX_FAIL; +    } + +    if (entryIndex >= numEntries) /* entryIndex starts at 0 */ +    { +	return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS; +    } + +    return ixQMgrAqmIfQPeek (qId, entryIndex, entry); +} + +IX_STATUS +ixQMgrQPoke (IxQMgrQId qId, +	     unsigned entryIndex, +	     UINT32 *entry) +{ +    unsigned int numEntries; + +#ifndef NDEBUG +    if ((NULL == entry) || (entryIndex > 128)) +    { +	return IX_QMGR_PARAMETER_ERROR; +    } + +    if (!ixQMgrQIsConfigured(qId)) +    { +	return IX_QMGR_Q_NOT_CONFIGURED; +    } +#endif +         +    if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries)) +    { +	return IX_FAIL; +    } + +    if (numEntries < (entryIndex + 1)) /* entryIndex starts at 0 */ +    { +	return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS; +    } + +    return ixQMgrAqmIfQPoke (qId, entryIndex, entry); +} + +IX_STATUS +ixQMgrQStatusGetWithChecks (IxQMgrQId qId, +                            IxQMgrQStatus *qStatus) +{ +    if (NULL == qStatus) +    { +	return IX_QMGR_PARAMETER_ERROR; +    } +    +    if (!ixQMgrQIsConfigured (qId))  +    { +        return IX_QMGR_Q_NOT_CONFIGURED; +    } + +    ixQMgrAqmIfQueStatRead (qId, qStatus); + +    return IX_SUCCESS; +} + +IX_STATUS +ixQMgrQNumEntriesGet (IxQMgrQId qId, +		      unsigned *numEntriesPtr) +{ +    UINT32 qPtrs; +    UINT32 qStatus; +    unsigned numEntries; +    IxQMgrQInlinedReadWriteInfo *infoPtr; + + +#ifndef NDEBUG +    if (NULL == numEntriesPtr) +    { +	return IX_QMGR_PARAMETER_ERROR; +    } + +    /* Check QId */ +    if (!ixQMgrQIsConfigured(qId)) +    { +	return IX_QMGR_Q_NOT_CONFIGURED; +    } +#endif + +    /* get fast access data */ +    infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; + +    /* get snapshot */ +    qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr); + +    /* Mod subtraction of pointers to get number of words in Q. */ +    numEntries = (qPtrs - (qPtrs >> 7)) & 0x7f; +   +    if (numEntries == 0) +    { +	/*  +	 * Could mean either full or empty queue +	 * so look at status +	 */ +	ixQMgrAqmIfQueStatRead (qId, &qStatus); + +	if (qId < IX_QMGR_MIN_QUEUPP_QID) +	{ +	    if (qStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) +	    { +		/* Empty */ +		*numEntriesPtr = 0; +	    } +	    else if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK) +	    { +		/* Full */ +		*numEntriesPtr = infoPtr->qSizeInEntries; +	    } +	    else +	    {	     +		/*  +		 * Queue status and read/write pointers are volatile. +		 * The queue state has changed since we took the +		 * snapshot of the read and write pointers. +		 * Client can retry if they wish +		 */ +		*numEntriesPtr = 0; +		return IX_QMGR_WARNING; +	    } +	} +	else /* It is an upper queue which does not have an empty status bit maintained */ +	{ +	    if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK) +	    { +		/* The queue is Full at the time of snapshot. */ +		*numEntriesPtr = infoPtr->qSizeInEntries; +	    } +	    else +	    { +	       /* The queue is either empty, either moving, +	        * Client can retry if they wish +	        */ +		*numEntriesPtr = 0; +	        return IX_QMGR_WARNING; +	    } +	} +    } +    else +    { +	*numEntriesPtr = (numEntries / infoPtr->qEntrySizeInWords) & (infoPtr->qSizeInEntries - 1); +    } +     +    return IX_SUCCESS; +} + +#if defined(__wince) && defined(NO_INLINE_APIS) + +PUBLIC IX_STATUS +ixQMgrQRead (IxQMgrQId qId, +      UINT32 *entryPtr) +{ +    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; +    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; +    UINT32 entry, entrySize; + +    /* get a new entry */ +    entrySize = infoPtr->qEntrySizeInWords; +    entry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr); + +    if (entrySize != IX_QMGR_Q_ENTRY_SIZE1) +    {  +    *entryPtr = entry; +  /* process the remaining part of the entry */ +   return ixQMgrQReadMWordsMinus1(qId, entryPtr); +    } + +    /* underflow is available for lower queues only */ +    if (qId < IX_QMGR_MIN_QUEUPP_QID) +    { + /* the counter of queue entries is decremented. In happy  +    * day scenario there are many entries in the queue +  * and the counter does not reach zero. +  */ +     if (infoPtr->qReadCount-- == 0) + { +       /* There is maybe no entry in the queue +      * qReadCount is now negative, but will be corrected before +      * the function returns. +         */ +     UINT32 qPtrs; /* queue internal pointers */ + +     /* when a queue is empty, the hw guarantees to return  +       * a null value. If the value is not null, the queue is +      * not empty. +        */ +     if (entry == 0) +     { +       /* get the queue status */ +      UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); +    +        /* check the underflow status */ +        if (status & infoPtr->qUflowStatBitMask) +        { +           /* the queue is empty  +          *  clear the underflow status bit if it was set  +            */ +          IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, +                    status & ~infoPtr->qUflowStatBitMask); +         *entryPtr = 0; +          infoPtr->qReadCount = 0; +            return IX_QMGR_Q_UNDERFLOW; +     } +       } +       /* store the result */ +      *entryPtr = entry; + +      /* No underflow occured : someone is filling the queue +       * or the queue contains null entries. +       * The current counter needs to be +       * updated from the current number of entries in the queue +       */ + +     /* get snapshot of queue pointers */ +        qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr); + +       /* Mod subtraction of pointers to get number of words in Q. */ +      qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;  +   +       if (qPtrs == 0) +     { +       /* no entry in the queue */ +     infoPtr->qReadCount = 0; +        } +       else +        { +       /* convert the number of words inside the queue +      * to a number of entries  +       */ +     infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1); +        } +       return IX_SUCCESS; +  } +    } +    *entryPtr = entry; +    return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixQMgrQBurstRead (IxQMgrQId qId, +          UINT32 numEntries, +          UINT32 *entries) +{ +    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; +    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; +    UINT32 nullCheckEntry; + +    if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1) +    { +    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; + +    /* the code is optimized to take care of data dependencies: +  * Durig a read, there are a few cycles needed to get the  +   * read complete. During these cycles, it is poossible to +    * do some CPU, e.g. increment pointers and decrement  +   * counters. +     */ + + /* fetch a queue entry */ +   nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr); + + /* iterate the specified number of queue entries */  +    while (--numEntries) +    { +       /* check the result of the previous read */ +     if (nullCheckEntry == 0) +        { +       /* if we read a NULL entry, stop. We have underflowed */ +        break; +      } +       else +        { +       /* write the entry */ +       *entries = nullCheckEntry; +      /* fetch next entry */ +      nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr); +      /* increment the write address */ +       entries++; +      } +   } +   /* write the pre-fetched entry */ +   *entries = nullCheckEntry; +    } +    else +    { +    IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords; +  /* read the specified number of queue entries */ +    nullCheckEntry = 0; + while (numEntries--) +    { +       int i; + +      for (i = 0; i < entrySizeInWords; i++) +      { +       *entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i); +       nullCheckEntry |= *entries++; +       } + +       /* if we read a NULL entry, stop. We have underflowed */ +        if (nullCheckEntry == 0) +        { +       break; +      } +       nullCheckEntry = 0; + } +    } + +    /* reset the current read count : next access to the read function  +     * will force a underflow status check  +     */ +    infoPtr->qWriteCount = 0; + +    /* Check if underflow occurred on the read */ +    if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID) +    { +  /* get the queue status */ +  UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); + +   if (status & infoPtr->qUflowStatBitMask) +    { +       /* clear the underflow status bit if it was set */ +      IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, +                status & ~infoPtr->qUflowStatBitMask); +     return IX_QMGR_Q_UNDERFLOW; + } +    } + +    return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixQMgrQWrite (IxQMgrQId qId, +         UINT32 *entry) +{ +    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; +    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; +    UINT32 entrySize; + +    /* write the entry */ +    IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry); +    entrySize = infoPtr->qEntrySizeInWords; + +    if (entrySize != IX_QMGR_Q_ENTRY_SIZE1) +    {    +    /* process the remaining part of the entry */ +   volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; +    while (--entrySize) + { +       ++entry; +        IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry); +    } +   entrySize = infoPtr->qEntrySizeInWords; +    } + +    /* overflow is available for lower queues only */ +    if (qId < IX_QMGR_MIN_QUEUPP_QID) +    {    +  UINT32 qSize = infoPtr->qSizeInEntries; + /* increment the current number of entries in the queue +  * and check for overflow  +   */ + if (infoPtr->qWriteCount++ == qSize) +    { +       /* the queue may have overflow */ +       UINT32 qPtrs; /* queue internal pointers */ +   +       /* get the queue status */ +      UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); + +       /* read the status twice because the status may  +         * not be immediately ready after the write operation +        */ +     if ((status & infoPtr->qOflowStatBitMask) || +        ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr)) +         & infoPtr->qOflowStatBitMask)) +     { +       /* the queue is full, clear the overflow status +      *  bit if it was set  +       */ +     IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, +                    status & ~infoPtr->qOflowStatBitMask); +     infoPtr->qWriteCount = infoPtr->qSizeInEntries; +     return IX_QMGR_Q_OVERFLOW; +      } +       /* No overflow occured : someone is draining the queue +       * and the current counter needs to be +       * updated from the current number of entries in the queue +       */ + +     /* get q pointer snapshot */ +        qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr); + +       /* Mod subtraction of pointers to get number of words in Q. */ +      qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;  + +     if (qPtrs == 0) +     { +       /* the queue may be full at the time of the  +         * snapshot. Next access will check  +         * the overflow status again. +        */ +     infoPtr->qWriteCount = qSize; +       } +       else  +       { +       /* convert the number of words to a number of entries */ +        if (entrySize == IX_QMGR_Q_ENTRY_SIZE1) +     { +           infoPtr->qWriteCount = qPtrs & (qSize - 1); +     } +       else +        { +           infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1); +       } +       } +   } +    } +    return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixQMgrQBurstWrite (IxQMgrQId qId, +          unsigned numEntries, +        UINT32 *entries) +{ +    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; +    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; +    UINT32 status; + +    /* update the current write count */ +    infoPtr->qWriteCount += numEntries; + +    if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1) +    { +    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; +    while (numEntries--) +    { +       IX_OSAL_WRITE_LONG(qAccRegAddr, *entries); +        entries++; +  } +    } +    else +    { + IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords; +  int i; + +  /* write each queue entry */ +    while (numEntries--) +    { +       /* write the queueEntrySize number of words for each entry */ +       for (i = 0; i < entrySizeInWords; i++) +      { +       IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries); +     entries++; +      } +   } +    } + +    /* check if the write count overflows */ +    if (infoPtr->qWriteCount > infoPtr->qSizeInEntries) +    { +  /* reset the current write count */ + infoPtr->qWriteCount = infoPtr->qSizeInEntries; +    } + +    /* Check if overflow occurred on the write operation */ +    if (qId < IX_QMGR_MIN_QUEUPP_QID) +    { +   /* get the queue status */ +  status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); + +  /* read the status twice because the status may  +     * not be ready at the time of the write +     */ + if ((status & infoPtr->qOflowStatBitMask) || +        ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr)) +         & infoPtr->qOflowStatBitMask)) + { +       /* clear the underflow status bit if it was set */ +      IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, +                status & ~infoPtr->qOflowStatBitMask); +     return IX_QMGR_Q_OVERFLOW; +  } +    } + +    return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixQMgrQStatusGet (IxQMgrQId qId, +          IxQMgrQStatus *qStatus) +{ +    /* read the status of a queue in the range 0-31 */ +    if (qId < IX_QMGR_MIN_QUEUPP_QID) +    { +  extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[]; +   extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[]; +    extern UINT32 ixQMgrAqmIfQueLowStatBitsMask; +    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; +    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; +   volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId]; +   volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr; + +  UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId]; +    UINT32 lowStatBitsMask   = ixQMgrAqmIfQueLowStatBitsMask; +   UINT32 underflowBitMask  = infoPtr->qUflowStatBitMask; +  UINT32 overflowBitMask   = infoPtr->qOflowStatBitMask; + +  /* read the status register for this queue */ +   *qStatus = IX_OSAL_READ_LONG(lowStatRegAddr); + /* mask out the status bits relevant only to this queue */ +  *qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask; + +   /* Check if the queue has overflowed */ + if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask) +  { +       /* clear the overflow status bit if it was set */ +       IX_OSAL_WRITE_LONG(qUOStatRegAddr, +                 (IX_OSAL_READ_LONG(qUOStatRegAddr) & +               ~overflowBitMask)); +       *qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK; +   } + +   /* Check if the queue has underflowed */ +        if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask) + { +       /* clear the underflow status bit if it was set */ +      IX_OSAL_WRITE_LONG(qUOStatRegAddr, +                 (IX_OSAL_READ_LONG(qUOStatRegAddr) & +               ~underflowBitMask)); +      *qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK; +   } +    } +    else /* read status of a queue in the range 32-63 */ +    { + extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr; +    extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr; +    extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[]; +  extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[]; + +  volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr; +    volatile UINT32 *qFullStatRegAddr      = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr; +    int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID; +   UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex]; +    UINT32 qFullStatBitMask      = ixQMgrAqmIfQueUppStat1BitMask[maskIndex]; + +    /* Reset the status bits */ + *qStatus = 0; + +   /* Check if the queue is nearly empty */ +    if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask) + { +       *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK; +   } + +   /* Check if the queue is full */ +    if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask) +   { +       *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK; +    } +    } +    return IX_SUCCESS; +} +#endif /* def NO_INLINE_APIS */ |