source: SVN/rincon/u-boot/cpu/ixp/npe/IxQMgrAqmIf.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 28.3 KB
Line 
1/*
2 * @file:    IxQMgrAqmIf.c
3 *
4 * @author Intel Corporation
5 * @date     30-Oct-2001
6 *
7 * @brief    This component provides a set of functions for
8 * perfoming I/O on the AQM hardware.
9 *
10 * Design Notes:
11 *              These functions are intended to be as fast as possible
12 * and as a result perform NO PARAMETER CHECKING.
13 *
14 *
15 * @par
16 * IXP400 SW Release version 2.0
17 *
18 * -- Copyright Notice --
19 *
20 * @par
21 * Copyright 2001-2005, Intel Corporation.
22 * All rights reserved.
23 *
24 * @par
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
27 * are met:
28 * 1. Redistributions of source code must retain the above copyright
29 *    notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 *    notice, this list of conditions and the following disclaimer in the
32 *    documentation and/or other materials provided with the distribution.
33 * 3. Neither the name of the Intel Corporation nor the names of its contributors
34 *    may be used to endorse or promote products derived from this software
35 *    without specific prior written permission.
36 *
37 * @par
38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
39 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 *
50 * @par
51 * -- End of Copyright Notice --
52*/
53
54/*
55 * Inlines are compiled as function when this is defined.
56 * N.B. Must be placed before #include of "IxQMgrAqmIf_p.h
57 */
58#ifndef IXQMGRAQMIF_P_H
59#    define IXQMGRAQMIF_C
60#else
61#    error
62#endif
63
64/*
65 * User defined include files.
66 */
67#include "IxOsal.h"
68#include "IxQMgr.h"
69#include "IxQMgrAqmIf_p.h"
70#include "IxQMgrLog_p.h"
71
72
73/*
74 * #defines and macros used in this file.
75 */
76
77/* These defines are the bit offsets of the various fields of
78 * the queue configuration register
79 */
80#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET       0x00
81#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET       0x07
82#define IX_QMGR_Q_CONFIG_BADDR_OFFSET       0x0E
83#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET       0x16
84#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET       0x18
85#define IX_QMGR_Q_CONFIG_NE_OFFSET          0x1A
86#define IX_QMGR_Q_CONFIG_NF_OFFSET          0x1D
87
88#define IX_QMGR_BASE_ADDR_16_WORD_ALIGN     0x40
89#define IX_QMGR_BASE_ADDR_16_WORD_SHIFT     0x6
90
91#define IX_QMGR_NE_NF_CLEAR_MASK            0x03FFFFFF
92#define IX_QMGR_NE_MASK                     0x7
93#define IX_QMGR_NF_MASK                     0x7
94#define IX_QMGR_SIZE_MASK                   0x3
95#define IX_QMGR_ENTRY_SIZE_MASK             0x3
96#define IX_QMGR_BADDR_MASK                  0x003FC000
97#define IX_QMGR_RDPTR_MASK                  0x7F
98#define IX_QMGR_WRPTR_MASK                  0x7F
99#define IX_QMGR_RDWRPTR_MASK                0x00003FFF
100
101#define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000
102
103/* Base address of AQM SRAM */
104#define IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET \
105((IX_QMGR_QUECONFIG_BASE_OFFSET) + (IX_QMGR_QUECONFIG_SIZE))
106
107/* Min buffer size used for generating buffer size in QUECONFIG */
108#define IX_QMGR_MIN_BUFFER_SIZE 16
109
110/* Reset values of QMgr hardware registers */
111#define IX_QMGR_QUELOWSTAT_RESET_VALUE    0x33333333
112#define IX_QMGR_QUEUOSTAT_RESET_VALUE     0x00000000
113#define IX_QMGR_QUEUPPSTAT0_RESET_VALUE   0xFFFFFFFF
114#define IX_QMGR_QUEUPPSTAT1_RESET_VALUE   0x00000000
115#define IX_QMGR_INT0SRCSELREG_RESET_VALUE 0x00000000
116#define IX_QMGR_QUEIEREG_RESET_VALUE      0x00000000
117#define IX_QMGR_QINTREG_RESET_VALUE       0xFFFFFFFF
118#define IX_QMGR_QUECONFIG_RESET_VALUE     0x00000000
119
120#define IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS IX_OSAL_IXP400_QMGR_PHYS_BASE
121
122#define IX_QMGR_QUELOWSTAT_BITS_PER_Q (BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)
123
124#define IX_QMGR_QUELOWSTAT_QID_MASK 0x7
125#define IX_QMGR_Q_CONFIG_ADDR_GET(qId)\
126        (((qId) * IX_QMGR_NUM_BYTES_PER_WORD) +\
127                  IX_QMGR_QUECONFIG_BASE_OFFSET)
128
129#define IX_QMGR_ENTRY1_OFFSET 0
130#define IX_QMGR_ENTRY2_OFFSET 1
131#define IX_QMGR_ENTRY4_OFFSET 3
132
133/*
134 * Variable declarations global to this file. Externs are followed by
135 * statics.
136 */
137UINT32 aqmBaseAddress = 0;
138/* Store addresses and bit-masks for certain queue access and status registers.
139 * This is to facilitate inlining of QRead, QWrite and QStatusGet functions
140 * in IxQMgr,h
141 */
142extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
143UINT32 * ixQMgrAqmIfQueAccRegAddr[IX_QMGR_MAX_NUM_QUEUES];
144UINT32 ixQMgrAqmIfQueLowStatRegAddr[IX_QMGR_MIN_QUEUPP_QID];
145UINT32 ixQMgrAqmIfQueLowStatBitsOffset[IX_QMGR_MIN_QUEUPP_QID];
146UINT32 ixQMgrAqmIfQueLowStatBitsMask;
147UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
148UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
149UINT32 ixQMgrAqmIfQueUppStat0BitMask[IX_QMGR_MIN_QUEUPP_QID];
150UINT32 ixQMgrAqmIfQueUppStat1BitMask[IX_QMGR_MIN_QUEUPP_QID];
151
152/*
153 * Fast mutexes, one for each queue, used to protect peek & poke functions
154 */
155IxOsalFastMutex ixQMgrAqmIfPeekPokeFastMutex[IX_QMGR_MAX_NUM_QUEUES];
156
157/*
158 * Function prototypes
159 */
160PRIVATE unsigned
161watermarkToAqmWatermark (IxQMgrWMLevel watermark );
162
163PRIVATE unsigned
164entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize);
165
166PRIVATE unsigned
167bufferSizeToAqmBufferSize (unsigned bufferSizeInWords);
168
169PRIVATE void
170ixQMgrAqmIfRegistersReset (void);
171
172PRIVATE void
173ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
174                            UINT32 configRegWord,
175                            unsigned int qEntrySizeInwords,
176                            unsigned int qSizeInWords,
177                            UINT32 **address);
178/*
179 * Function definitions
180 */
181void
182ixQMgrAqmIfInit (void)
183{
184    UINT32 aqmVirtualAddr;
185    int i;
186
187    /* The value of aqmBaseAddress depends on the logical address
188     * assigned by the MMU.
189     */
190    aqmVirtualAddr =
191        (UINT32) IX_OSAL_MEM_MAP(IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS,
192                                    IX_OSAL_IXP400_QMGR_MAP_SIZE);
193    IX_OSAL_ASSERT (aqmVirtualAddr);
194   
195    ixQMgrAqmIfBaseAddressSet (aqmVirtualAddr);
196
197    ixQMgrAqmIfRegistersReset ();
198
199    for (i = 0; i< IX_QMGR_MAX_NUM_QUEUES; i++)
200    {
201        ixOsalFastMutexInit(&ixQMgrAqmIfPeekPokeFastMutex[i]);
202
203        /********************************************************************
204         * Register addresses and bit masks are calculated and stored here to
205         * facilitate inlining of QRead, QWrite and QStatusGet functions in
206         * IxQMgr.h.
207         * These calculations are normally performed dynamically in inlined
208         * functions in IxQMgrAqmIf_p.h, and their semantics are reused here.
209         */
210
211        /* AQM Queue access reg addresses, per queue */
212        ixQMgrAqmIfQueAccRegAddr[i] = 
213            (UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
214        ixQMgrQInlinedReadWriteInfo[i].qAccRegAddr = 
215            (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
216
217
218        ixQMgrQInlinedReadWriteInfo[i].qConfigRegAddr = 
219            (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(i));
220
221        /* AQM Queue lower-group (0-31), only */
222        if (i < IX_QMGR_MIN_QUEUPP_QID)
223        {
224            /* AQM Q underflow/overflow status register addresses, per queue */
225            ixQMgrQInlinedReadWriteInfo[i].qUOStatRegAddr = 
226                (volatile UINT32 *)(aqmBaseAddress +
227                IX_QMGR_QUEUOSTAT0_OFFSET +
228                ((i / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD) *
229                 IX_QMGR_NUM_BYTES_PER_WORD));
230
231            /* AQM Q underflow status bit masks for status register per queue */
232            ixQMgrQInlinedReadWriteInfo[i].qUflowStatBitMask = 
233                (IX_QMGR_UNDERFLOW_BIT_OFFSET + 1) <<
234                ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
235                 (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
236
237            /* AQM Q overflow status bit masks for status register, per queue */
238            ixQMgrQInlinedReadWriteInfo[i].qOflowStatBitMask = 
239                (IX_QMGR_OVERFLOW_BIT_OFFSET + 1) <<
240                ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
241                 (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
242
243            /* AQM Q lower-group (0-31) status register addresses, per queue */
244            ixQMgrAqmIfQueLowStatRegAddr[i] = aqmBaseAddress +
245                IX_QMGR_QUELOWSTAT0_OFFSET +
246                ((i / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
247                 IX_QMGR_NUM_BYTES_PER_WORD);
248
249            /* AQM Q lower-group (0-31) status register bit offset */
250            ixQMgrAqmIfQueLowStatBitsOffset[i] =
251                (i & (IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD - 1)) * 
252                (BITS_PER_WORD / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD);
253        }
254        else /* AQM Q upper-group (32-63), only */
255        {
256            /* AQM Q upper-group (32-63) Nearly Empty status reg bit masks */
257            ixQMgrAqmIfQueUppStat0BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
258                (1 << (i - IX_QMGR_MIN_QUEUPP_QID));
259
260            /* AQM Q upper-group (32-63) Full status register bit masks */
261            ixQMgrAqmIfQueUppStat1BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
262                (1 << (i - IX_QMGR_MIN_QUEUPP_QID));
263        }
264    }
265
266    /* AQM Q lower-group (0-31) status register bit mask */
267    ixQMgrAqmIfQueLowStatBitsMask = (1 <<
268                                    (BITS_PER_WORD /
269                                     IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)) - 1;
270
271    /* AQM Q upper-group (32-63) Nearly Empty status register address */
272    ixQMgrAqmIfQueUppStat0RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET;
273   
274    /* AQM Q upper-group (32-63) Full status register address */
275    ixQMgrAqmIfQueUppStat1RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET;
276}
277
278/*
279 * Uninitialise the AqmIf module by unmapping memory, etc
280 */
281void
282ixQMgrAqmIfUninit (void)
283{
284    UINT32 virtAddr;
285
286    ixQMgrAqmIfBaseAddressGet (&virtAddr);
287    IX_OSAL_MEM_UNMAP (virtAddr);
288    ixQMgrAqmIfBaseAddressSet (0);
289}
290
291/*
292 * Set the the logical base address of AQM
293 */
294void
295ixQMgrAqmIfBaseAddressSet (UINT32 address)
296{
297    aqmBaseAddress = address;
298}
299
300/*
301 * Get the logical base address of AQM
302 */
303void
304ixQMgrAqmIfBaseAddressGet (UINT32 *address)
305{
306    *address = aqmBaseAddress;
307}
308
309/*
310 * Get the logical base address of AQM SRAM
311 */
312void
313ixQMgrAqmIfSramBaseAddressGet (UINT32 *address)
314{
315    *address = aqmBaseAddress                +
316        IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET;
317}
318
319/*
320 * This function will write the status bits of a queue
321 * specified by qId.
322 */
323void
324ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId, 
325                               UINT32 registerBaseAddrOffset,
326                               unsigned queuesPerRegWord,
327                               UINT32 value)
328{
329    volatile UINT32 *registerAddress;
330    UINT32 registerWord;
331    UINT32 statusBitsMask;
332    UINT32 bitsPerQueue;
333
334    bitsPerQueue = BITS_PER_WORD / queuesPerRegWord;
335
336    /*
337     * Calculate the registerAddress
338     * multiple queues split accross registers
339     */
340    registerAddress = (UINT32*)(aqmBaseAddress +
341                                registerBaseAddrOffset +
342                                ((qId / queuesPerRegWord) *
343                                 IX_QMGR_NUM_BYTES_PER_WORD));   
344
345    /* Read the current data */
346    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
347
348
349    if( (registerBaseAddrOffset == IX_QMGR_INT0SRCSELREG0_OFFSET) &&
350        (qId == IX_QMGR_QUEUE_0) )
351    {
352      statusBitsMask = 0x7 ;   
353
354      /* Queue 0 at INT0SRCSELREG should not corrupt the value bit-3  */
355      value &=  0x7 ;       
356    }
357    else
358    {     
359      /* Calculate the mask for the status bits for this queue. */
360      statusBitsMask = ((1 << bitsPerQueue) - 1);
361      statusBitsMask <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
362
363      /* Mask out bits in value that would overwrite other q data */
364      value <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
365      value &= statusBitsMask;
366    }
367
368    /* Mask out bits to write to */
369    registerWord &= ~statusBitsMask;
370   
371
372    /* Set the write bits */
373    registerWord |= value;
374
375    /*
376     * Write the data
377     */
378    ixQMgrAqmIfWordWrite (registerAddress, registerWord);
379}
380
381/*
382 * This function generates the parameters that can be used to
383 * check if a Qs status matches the specified source select.
384 * It calculates which status word to check (statusWordOffset),
385 * the value to check the status against (checkValue) and the
386 * mask (mask) to mask out all but the bits to check in the status word.
387 */
388void
389ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId,
390                                 IxQMgrSourceId srcSel,
391                                 unsigned int *statusWordOffset,
392                                 UINT32 *checkValue,
393                                 UINT32 *mask)
394{
395    UINT32 shiftVal;
396   
397    if (qId < IX_QMGR_MIN_QUEUPP_QID)
398    {
399        switch (srcSel)
400        {
401            case IX_QMGR_Q_SOURCE_ID_E:
402                *checkValue = IX_QMGR_Q_STATUS_E_BIT_MASK;
403                *mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
404                break;
405            case IX_QMGR_Q_SOURCE_ID_NE:
406                *checkValue = IX_QMGR_Q_STATUS_NE_BIT_MASK;
407                *mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
408                break;
409            case IX_QMGR_Q_SOURCE_ID_NF:
410                *checkValue = IX_QMGR_Q_STATUS_NF_BIT_MASK;
411                *mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
412                break;
413            case IX_QMGR_Q_SOURCE_ID_F:
414                *checkValue = IX_QMGR_Q_STATUS_F_BIT_MASK;
415                *mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
416                break;
417            case IX_QMGR_Q_SOURCE_ID_NOT_E:
418                *checkValue = 0;
419                *mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
420                break;
421            case IX_QMGR_Q_SOURCE_ID_NOT_NE:
422                *checkValue = 0;
423                *mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
424                break;
425            case IX_QMGR_Q_SOURCE_ID_NOT_NF:
426                *checkValue = 0;
427                *mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
428                break;
429            case IX_QMGR_Q_SOURCE_ID_NOT_F:
430                *checkValue = 0;
431                *mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
432                break;
433            default:
434                /* Should never hit */
435                IX_OSAL_ASSERT(0);
436                break;
437        }
438
439        /* One nibble of status per queue so need to shift the
440         * check value and mask out to the correct position.
441         */
442        shiftVal = (qId % IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) * 
443            IX_QMGR_QUELOWSTAT_BITS_PER_Q;
444
445        /* Calculate the which status word to check from the qId,
446         * 8 Qs status per word
447         */
448        *statusWordOffset = qId / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD;
449
450        *checkValue <<= shiftVal;
451        *mask <<= shiftVal;
452    }
453    else
454    {
455        /* One status word */
456        *statusWordOffset = 0;
457        /* Single bits per queue and int source bit hardwired  NE,
458         * Qs start at 32.
459         */
460        *mask = 1 << (qId - IX_QMGR_MIN_QUEUPP_QID);
461        *checkValue = *mask;
462    }
463}
464
465void
466ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId)
467{
468    volatile UINT32 *registerAddress;
469    UINT32 registerWord;
470    UINT32 actualBitOffset;
471   
472    if (qId < IX_QMGR_MIN_QUEUPP_QID)
473    {   
474        registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
475    }
476    else
477    {
478        registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
479    }
480
481    actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);
482
483    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
484    ixQMgrAqmIfWordWrite (registerAddress, (registerWord | actualBitOffset));
485}
486
487void
488ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId)
489{
490    volatile UINT32 *registerAddress;
491    UINT32 registerWord;
492    UINT32 actualBitOffset;
493
494    if (qId < IX_QMGR_MIN_QUEUPP_QID)
495    {   
496        registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
497    }
498    else
499    {
500        registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
501    }
502
503    actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);
504
505    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
506    ixQMgrAqmIfWordWrite (registerAddress, registerWord & (~actualBitOffset));
507}
508
509void
510ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId,
511                       IxQMgrQSizeInWords qSizeInWords,
512                       IxQMgrQEntrySizeInWords entrySizeInWords,
513                       UINT32 freeSRAMAddress)
514{
515    volatile UINT32 *cfgAddress = NULL;
516    UINT32 qCfg = 0;
517    UINT32 baseAddress = 0;
518    unsigned aqmEntrySize = 0;
519    unsigned aqmBufferSize = 0;
520
521    /* Build config register */
522    aqmEntrySize = entrySizeToAqmEntrySize (entrySizeInWords);
523    qCfg |= (aqmEntrySize&IX_QMGR_ENTRY_SIZE_MASK) <<
524        IX_QMGR_Q_CONFIG_ESIZE_OFFSET;
525
526    aqmBufferSize = bufferSizeToAqmBufferSize (qSizeInWords);
527    qCfg |= (aqmBufferSize&IX_QMGR_SIZE_MASK) << IX_QMGR_Q_CONFIG_BSIZE_OFFSET;
528
529    /* baseAddress, calculated relative to aqmBaseAddress and start address  */
530    baseAddress = freeSRAMAddress -
531        (aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
532                   
533    /* Verify base address aligned to a 16 word boundary */
534    if ((baseAddress % IX_QMGR_BASE_ADDR_16_WORD_ALIGN) != 0)
535    {
536        IX_QMGR_LOG_ERROR0("ixQMgrAqmIfQueCfgWrite () address is not on 16 word boundary\n");
537    }
538    /* Now convert it to a 16 word pointer as required by QUECONFIG register */
539    baseAddress >>= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
540   
541   
542    qCfg |= (baseAddress << IX_QMGR_Q_CONFIG_BADDR_OFFSET);
543
544
545    cfgAddress = (UINT32*)(aqmBaseAddress +
546                        IX_QMGR_Q_CONFIG_ADDR_GET(qId));
547
548
549    /* NOTE: High and Low watermarks are set to zero */
550    ixQMgrAqmIfWordWrite (cfgAddress, qCfg);
551}
552
553void
554ixQMgrAqmIfQueCfgRead (IxQMgrQId qId,
555                       unsigned int numEntries,
556                       UINT32 *baseAddress,
557                       unsigned int *ne,
558                       unsigned int *nf,
559                       UINT32 *readPtr,
560                       UINT32 *writePtr)
561{
562    UINT32 qcfg;
563    UINT32 *cfgAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
564    unsigned int qEntrySizeInwords;
565    unsigned int qSizeInWords;
566    UINT32 *readPtr_ = NULL;
567       
568    /* Read the queue configuration register */
569    ixQMgrAqmIfWordRead (cfgAddress, &qcfg);
570   
571    /* Extract the base address */
572    *baseAddress = (UINT32)((qcfg & IX_QMGR_BADDR_MASK) >>
573                            (IX_QMGR_Q_CONFIG_BADDR_OFFSET));
574
575    /* Base address is a 16 word pointer from the start of AQM SRAM.
576     * Convert to absolute word address.
577     */
578    *baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
579    *baseAddress += (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET;
580
581    /*
582     * Extract the watermarks. 0->0 entries, 1->1 entries, 2->2 entries, 3->4 entries......
583     * If ne > 0 ==> neInEntries = 2^(ne - 1)
584     * If ne == 0 ==> neInEntries = 0
585     * The same applies.
586     */
587    *ne = ((qcfg) >> (IX_QMGR_Q_CONFIG_NE_OFFSET)) & IX_QMGR_NE_MASK;
588    *nf = ((qcfg) >> (IX_QMGR_Q_CONFIG_NF_OFFSET)) & IX_QMGR_NF_MASK;
589
590    if (0 != *ne)
591    {
592        *ne = 1 << (*ne - 1);   
593    }
594    if (0 != *nf)
595    {
596        *nf = 1 << (*nf - 1);
597    }
598
599    /* Get the queue entry size in words */
600    qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
601
602    /* Get the queue size in words */
603    qSizeInWords = ixQMgrQSizeInWordsGet (qId);
604
605    ixQMgrAqmIfEntryAddressGet (0/* Entry 0. i.e the readPtr*/,
606                                qcfg,
607                                qEntrySizeInwords,
608                                qSizeInWords,
609                                &readPtr_);
610    *readPtr = (UINT32)readPtr_;
611    *readPtr -= (UINT32)aqmBaseAddress;/* Offset, not absolute address */
612
613    *writePtr = (qcfg >> IX_QMGR_Q_CONFIG_WRPTR_OFFSET) & IX_QMGR_WRPTR_MASK;
614    *writePtr = *baseAddress + (*writePtr * (IX_QMGR_NUM_BYTES_PER_WORD));
615    return;
616}
617
618unsigned
619ixQMgrAqmIfLog2 (unsigned number)
620{
621    unsigned count = 0;
622
623    /*
624     * N.B. this function will return 0
625     * for ixQMgrAqmIfLog2 (0)
626     */
627    while (number/2)
628    {
629        number /=2;
630        count++;       
631    }
632
633    return count;
634}
635
636void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void)
637{
638
639    volatile UINT32 *registerAddress;
640    UINT32 registerWord; 
641
642    /*
643     * Calculate the registerAddress
644     * multiple queues split accross registers
645     */
646    registerAddress = (UINT32*)(aqmBaseAddress +
647                                IX_QMGR_INT0SRCSELREG0_OFFSET);   
648
649    /* Read the current data */
650    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
651
652    /* Set the write bits */
653    registerWord |= (1<<IX_QMGR_INT0SRCSELREG0_BIT3) ;
654
655    /*
656     * Write the data
657     */
658    ixQMgrAqmIfWordWrite (registerAddress, registerWord);
659} 
660
661
662void
663ixQMgrAqmIfIntSrcSelWrite (IxQMgrQId qId,
664                          IxQMgrSourceId sourceId)
665{
666    ixQMgrAqmIfQRegisterBitsWrite (qId,
667                                   IX_QMGR_INT0SRCSELREG0_OFFSET,
668                                   IX_QMGR_INTSRC_NUM_QUE_PER_WORD,
669                                   sourceId);
670}
671
672
673
674void
675ixQMgrAqmIfWatermarkSet (IxQMgrQId qId,
676                        unsigned ne,
677                        unsigned nf)
678{
679    volatile UINT32 *address = 0;
680    UINT32 value = 0;
681    unsigned aqmNeWatermark = 0;
682    unsigned aqmNfWatermark = 0;
683
684    address = (UINT32*)(aqmBaseAddress +
685                     IX_QMGR_Q_CONFIG_ADDR_GET(qId));
686
687    aqmNeWatermark = watermarkToAqmWatermark (ne);
688    aqmNfWatermark = watermarkToAqmWatermark (nf);
689
690    /* Read the current watermarks */
691    ixQMgrAqmIfWordRead (address, &value);
692
693    /* Clear out the old watermarks */
694    value &=  IX_QMGR_NE_NF_CLEAR_MASK;
695   
696    /* Generate the value to write */
697    value |= (aqmNeWatermark << IX_QMGR_Q_CONFIG_NE_OFFSET) |
698        (aqmNfWatermark << IX_QMGR_Q_CONFIG_NF_OFFSET); 
699
700    ixQMgrAqmIfWordWrite (address, value);
701
702}
703
704PRIVATE void
705ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
706                            UINT32 configRegWord,
707                            unsigned int qEntrySizeInwords,
708                            unsigned int qSizeInWords,
709                            UINT32 **address)
710{
711    UINT32 readPtr;
712    UINT32 baseAddress;
713    UINT32 *topOfAqmSram;
714
715    topOfAqmSram = ((UINT32 *)aqmBaseAddress + IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS);
716
717    /* Extract the base address */
718    baseAddress = (UINT32)((configRegWord & IX_QMGR_BADDR_MASK) >>
719                           (IX_QMGR_Q_CONFIG_BADDR_OFFSET));
720
721    /* Base address is a 16 word pointer from the start of AQM SRAM.
722     * Convert to absolute word address.
723     */
724    baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
725    baseAddress += ((UINT32)aqmBaseAddress + (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET);
726
727    /* Extract the read pointer. Read pointer is a word pointer */
728    readPtr = (UINT32)((configRegWord >>
729                        IX_QMGR_Q_CONFIG_RDPTR_OFFSET)&IX_QMGR_RDPTR_MASK);
730
731    /* Read/Write pointers(word pointers)  are offsets from the queue buffer space base address.
732     * Calculate the absolute read pointer address. NOTE: Queues are circular buffers.
733     */
734    readPtr  = (readPtr + (entryIndex * qEntrySizeInwords)) & (qSizeInWords - 1); /* Mask by queue size */
735    *address = (UINT32 *)(baseAddress + (readPtr * (IX_QMGR_NUM_BYTES_PER_WORD)));
736
737    switch (qEntrySizeInwords)
738    {
739        case IX_QMGR_Q_ENTRY_SIZE1:
740            IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY1_OFFSET) < topOfAqmSram);     
741            break;
742        case IX_QMGR_Q_ENTRY_SIZE2:
743            IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY2_OFFSET) < topOfAqmSram);
744            break;
745        case IX_QMGR_Q_ENTRY_SIZE4:
746            IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY4_OFFSET) < topOfAqmSram);
747            break;
748        default:
749            IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfEntryAddressGet");
750            break;
751    }
752   
753}
754
755IX_STATUS
756ixQMgrAqmIfQPeek (IxQMgrQId qId,
757                  unsigned int entryIndex,
758                  unsigned int *entry)
759{
760    UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
761    UINT32 *entryAddress = NULL;
762    UINT32 configRegWordOnEntry;
763    UINT32 configRegWordOnExit;
764    unsigned int qEntrySizeInwords;
765    unsigned int qSizeInWords;
766
767    /* Get the queue entry size in words */
768    qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
769
770    /* Get the queue size in words */
771    qSizeInWords = ixQMgrQSizeInWordsGet (qId);
772
773    /* Read the config register */
774    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);
775
776    /* Get the entry address */
777    ixQMgrAqmIfEntryAddressGet (entryIndex,
778                                configRegWordOnEntry,
779                                qEntrySizeInwords,
780                                qSizeInWords,
781                                &entryAddress);
782
783    /* Get the lock or return busy */
784    if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
785    {
786        return IX_FAIL;
787    }
788
789    while(qEntrySizeInwords--)
790    {
791        ixQMgrAqmIfWordRead (entryAddress++, entry++);
792    }
793
794    /* Release the lock */
795    ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);
796
797    /* Read the config register */
798    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);
799
800    /* Check that the read and write pointers have not changed */
801    if (configRegWordOnEntry != configRegWordOnExit)
802    {
803        return IX_FAIL;
804    }
805
806    return IX_SUCCESS;
807}
808
809IX_STATUS
810ixQMgrAqmIfQPoke (IxQMgrQId qId,
811                  unsigned entryIndex,
812                  unsigned int *entry)
813{
814    UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
815    UINT32 *entryAddress = NULL;
816    UINT32 configRegWordOnEntry;
817    UINT32 configRegWordOnExit;
818    unsigned int qEntrySizeInwords;
819    unsigned int qSizeInWords;
820   
821    /* Get the queue entry size in words */
822    qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
823
824    /* Get the queue size in words */
825    qSizeInWords = ixQMgrQSizeInWordsGet (qId);
826
827    /* Read the config register */
828    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);
829
830    /* Get the entry address */
831    ixQMgrAqmIfEntryAddressGet (entryIndex,
832                                configRegWordOnEntry,
833                                qEntrySizeInwords,
834                                qSizeInWords,
835                                &entryAddress);
836
837    /* Get the lock or return busy */
838    if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
839    {
840        return IX_FAIL;
841    }
842
843    /* Else read the entry directly from SRAM. This will not move the read pointer */
844    while(qEntrySizeInwords--)
845    {
846        ixQMgrAqmIfWordWrite (entryAddress++, *entry++);
847    }
848
849    /* Release the lock */
850    ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);
851
852    /* Read the config register */
853    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);
854
855    /* Check that the read and write pointers have not changed */
856    if (configRegWordOnEntry != configRegWordOnExit)
857    {
858        return IX_FAIL;
859    }
860
861    return IX_SUCCESS;
862}
863
864PRIVATE unsigned
865watermarkToAqmWatermark (IxQMgrWMLevel watermark )
866{
867    unsigned aqmWatermark = 0;
868
869    /*
870     * Watermarks 0("000"),1("001"),2("010"),4("011"),
871     * 8("100"),16("101"),32("110"),64("111")
872     */
873    aqmWatermark = ixQMgrAqmIfLog2 (watermark * 2);
874   
875    return aqmWatermark;
876}
877
878PRIVATE unsigned
879entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize)
880{
881    /* entrySize  1("00"),2("01"),4("10") */
882    return (ixQMgrAqmIfLog2 (entrySize));
883}
884
885PRIVATE unsigned
886bufferSizeToAqmBufferSize (unsigned bufferSizeInWords)
887{
888    /* bufferSize 16("00"),32("01),64("10"),128("11") */
889    return (ixQMgrAqmIfLog2 (bufferSizeInWords / IX_QMGR_MIN_BUFFER_SIZE));
890}
891
892/*
893 * Reset AQM registers to default values.
894 */
895PRIVATE void
896ixQMgrAqmIfRegistersReset (void)
897{
898    volatile UINT32 *qConfigWordAddress = NULL;
899    unsigned int i;
900
901    /*
902     * Need to initialize AQM hardware registers to an initial
903     * value as init may have been called as a result of a soft
904     * reset. i.e. soft reset does not reset hardware registers.
905     */
906
907    /* Reset queues 0..31 status registers 0..3 */
908    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT0_OFFSET), 
909                         IX_QMGR_QUELOWSTAT_RESET_VALUE);
910    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT1_OFFSET), 
911                         IX_QMGR_QUELOWSTAT_RESET_VALUE);
912    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT2_OFFSET), 
913                         IX_QMGR_QUELOWSTAT_RESET_VALUE);
914    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT3_OFFSET), 
915                         IX_QMGR_QUELOWSTAT_RESET_VALUE);
916
917    /* Reset underflow/overflow status registers 0..1 */
918    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT0_OFFSET), 
919                         IX_QMGR_QUEUOSTAT_RESET_VALUE);
920    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT1_OFFSET), 
921                         IX_QMGR_QUEUOSTAT_RESET_VALUE);
922   
923    /* Reset queues 32..63 nearly empty status registers */
924    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET),
925                         IX_QMGR_QUEUPPSTAT0_RESET_VALUE);
926
927    /* Reset queues 32..63 full status registers */
928    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET),
929                         IX_QMGR_QUEUPPSTAT1_RESET_VALUE);
930
931    /* Reset int0 status flag source select registers 0..3 */
932    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG0_OFFSET),
933                         IX_QMGR_INT0SRCSELREG_RESET_VALUE);
934    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG1_OFFSET),
935                         IX_QMGR_INT0SRCSELREG_RESET_VALUE);
936    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG2_OFFSET),
937                         IX_QMGR_INT0SRCSELREG_RESET_VALUE);
938    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG3_OFFSET),
939                         IX_QMGR_INT0SRCSELREG_RESET_VALUE);
940         
941    /* Reset queue interrupt enable register 0..1 */
942    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET),
943                         IX_QMGR_QUEIEREG_RESET_VALUE);
944    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET),
945                         IX_QMGR_QUEIEREG_RESET_VALUE);
946
947    /* Reset queue interrupt register 0..1 */
948    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG0_OFFSET),
949                         IX_QMGR_QINTREG_RESET_VALUE);
950    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG1_OFFSET),
951                         IX_QMGR_QINTREG_RESET_VALUE);
952
953    /* Reset queue configuration words 0..63 */
954    qConfigWordAddress = (UINT32 *)(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
955    for (i = 0; i < (IX_QMGR_QUECONFIG_SIZE / sizeof(UINT32)); i++)
956    {
957        ixQMgrAqmIfWordWrite(qConfigWordAddress,
958                             IX_QMGR_QUECONFIG_RESET_VALUE);
959        /* Next word */
960        qConfigWordAddress++;
961    }
962}
963
Note: See TracBrowser for help on using the repository browser.