uboot/cpu/ixp/npe/IxQMgrQAccess.c
<<
>>
Prefs
   1/**
   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 */
 797