4 * @author Intel Corporation
7 * @brief This component provides a set of functions for
8 * perfoming I/O on the AQM hardware.
11 * These functions are intended to be as fast as possible
12 * and as a result perform NO PARAMETER CHECKING.
16 * IXP400 SW Release version 2.0
18 * -- Copyright Notice --
21 * Copyright 2001-2005, Intel Corporation.
22 * All rights reserved.
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
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.
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
51 * -- End of Copyright Notice --
55 * Inlines are compiled as function when this is defined.
56 * N.B. Must be placed before #include of "IxQMgrAqmIf_p.h
58 #ifndef IXQMGRAQMIF_P_H
59 # define IXQMGRAQMIF_C
65 * User defined include files.
69 #include "IxQMgrAqmIf_p.h"
70 #include "IxQMgrLog_p.h"
74 * #defines and macros used in this file.
77 /* These defines are the bit offsets of the various fields of
78 * the queue configuration register
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
88 #define IX_QMGR_BASE_ADDR_16_WORD_ALIGN 0x40
89 #define IX_QMGR_BASE_ADDR_16_WORD_SHIFT 0x6
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
101 #define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000
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))
107 /* Min buffer size used for generating buffer size in QUECONFIG */
108 #define IX_QMGR_MIN_BUFFER_SIZE 16
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
120 #define IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS IX_OSAL_IXP400_QMGR_PHYS_BASE
122 #define IX_QMGR_QUELOWSTAT_BITS_PER_Q (BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)
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)
129 #define IX_QMGR_ENTRY1_OFFSET 0
130 #define IX_QMGR_ENTRY2_OFFSET 1
131 #define IX_QMGR_ENTRY4_OFFSET 3
134 * Variable declarations global to this file. Externs are followed by
137 UINT32 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
142 extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo
[];
143 UINT32
* ixQMgrAqmIfQueAccRegAddr
[IX_QMGR_MAX_NUM_QUEUES
];
144 UINT32 ixQMgrAqmIfQueLowStatRegAddr
[IX_QMGR_MIN_QUEUPP_QID
];
145 UINT32 ixQMgrAqmIfQueLowStatBitsOffset
[IX_QMGR_MIN_QUEUPP_QID
];
146 UINT32 ixQMgrAqmIfQueLowStatBitsMask
;
147 UINT32 ixQMgrAqmIfQueUppStat0RegAddr
;
148 UINT32 ixQMgrAqmIfQueUppStat1RegAddr
;
149 UINT32 ixQMgrAqmIfQueUppStat0BitMask
[IX_QMGR_MIN_QUEUPP_QID
];
150 UINT32 ixQMgrAqmIfQueUppStat1BitMask
[IX_QMGR_MIN_QUEUPP_QID
];
153 * Fast mutexes, one for each queue, used to protect peek & poke functions
155 IxOsalFastMutex ixQMgrAqmIfPeekPokeFastMutex
[IX_QMGR_MAX_NUM_QUEUES
];
158 * Function prototypes
161 watermarkToAqmWatermark (IxQMgrWMLevel watermark
);
164 entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize
);
167 bufferSizeToAqmBufferSize (unsigned bufferSizeInWords
);
170 ixQMgrAqmIfRegistersReset (void);
173 ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex
,
174 UINT32 configRegWord
,
175 unsigned int qEntrySizeInwords
,
176 unsigned int qSizeInWords
,
179 * Function definitions
182 ixQMgrAqmIfInit (void)
184 UINT32 aqmVirtualAddr
;
187 /* The value of aqmBaseAddress depends on the logical address
188 * assigned by the MMU.
191 (UINT32
) IX_OSAL_MEM_MAP(IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS
,
192 IX_OSAL_IXP400_QMGR_MAP_SIZE
);
193 IX_OSAL_ASSERT (aqmVirtualAddr
);
195 ixQMgrAqmIfBaseAddressSet (aqmVirtualAddr
);
197 ixQMgrAqmIfRegistersReset ();
199 for (i
= 0; i
< IX_QMGR_MAX_NUM_QUEUES
; i
++)
201 ixOsalFastMutexInit(&ixQMgrAqmIfPeekPokeFastMutex
[i
]);
203 /********************************************************************
204 * Register addresses and bit masks are calculated and stored here to
205 * facilitate inlining of QRead, QWrite and QStatusGet functions in
207 * These calculations are normally performed dynamically in inlined
208 * functions in IxQMgrAqmIf_p.h, and their semantics are reused here.
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
));
218 ixQMgrQInlinedReadWriteInfo
[i
].qConfigRegAddr
=
219 (volatile UINT32
*)(aqmBaseAddress
+ IX_QMGR_Q_CONFIG_ADDR_GET(i
));
221 /* AQM Queue lower-group (0-31), only */
222 if (i
< IX_QMGR_MIN_QUEUPP_QID
)
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
));
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
));
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
));
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
);
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
);
254 else /* AQM Q upper-group (32-63), only */
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
));
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
));
266 /* AQM Q lower-group (0-31) status register bit mask */
267 ixQMgrAqmIfQueLowStatBitsMask
= (1 <<
269 IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD
)) - 1;
271 /* AQM Q upper-group (32-63) Nearly Empty status register address */
272 ixQMgrAqmIfQueUppStat0RegAddr
= aqmBaseAddress
+ IX_QMGR_QUEUPPSTAT0_OFFSET
;
274 /* AQM Q upper-group (32-63) Full status register address */
275 ixQMgrAqmIfQueUppStat1RegAddr
= aqmBaseAddress
+ IX_QMGR_QUEUPPSTAT1_OFFSET
;
279 * Uninitialise the AqmIf module by unmapping memory, etc
282 ixQMgrAqmIfUninit (void)
286 ixQMgrAqmIfBaseAddressGet (&virtAddr
);
287 IX_OSAL_MEM_UNMAP (virtAddr
);
288 ixQMgrAqmIfBaseAddressSet (0);
292 * Set the the logical base address of AQM
295 ixQMgrAqmIfBaseAddressSet (UINT32 address
)
297 aqmBaseAddress
= address
;
301 * Get the logical base address of AQM
304 ixQMgrAqmIfBaseAddressGet (UINT32
*address
)
306 *address
= aqmBaseAddress
;
310 * Get the logical base address of AQM SRAM
313 ixQMgrAqmIfSramBaseAddressGet (UINT32
*address
)
315 *address
= aqmBaseAddress
+
316 IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET
;
320 * This function will write the status bits of a queue
324 ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId
,
325 UINT32 registerBaseAddrOffset
,
326 unsigned queuesPerRegWord
,
329 volatile UINT32
*registerAddress
;
331 UINT32 statusBitsMask
;
334 bitsPerQueue
= BITS_PER_WORD
/ queuesPerRegWord
;
337 * Calculate the registerAddress
338 * multiple queues split accross registers
340 registerAddress
= (UINT32
*)(aqmBaseAddress
+
341 registerBaseAddrOffset
+
342 ((qId
/ queuesPerRegWord
) *
343 IX_QMGR_NUM_BYTES_PER_WORD
));
345 /* Read the current data */
346 ixQMgrAqmIfWordRead (registerAddress
, ®isterWord
);
349 if( (registerBaseAddrOffset
== IX_QMGR_INT0SRCSELREG0_OFFSET
) &&
350 (qId
== IX_QMGR_QUEUE_0
) )
352 statusBitsMask
= 0x7 ;
354 /* Queue 0 at INT0SRCSELREG should not corrupt the value bit-3 */
359 /* Calculate the mask for the status bits for this queue. */
360 statusBitsMask
= ((1 << bitsPerQueue
) - 1);
361 statusBitsMask
<<= ((qId
& (queuesPerRegWord
- 1)) * bitsPerQueue
);
363 /* Mask out bits in value that would overwrite other q data */
364 value
<<= ((qId
& (queuesPerRegWord
- 1)) * bitsPerQueue
);
365 value
&= statusBitsMask
;
368 /* Mask out bits to write to */
369 registerWord
&= ~statusBitsMask
;
372 /* Set the write bits */
373 registerWord
|= value
;
378 ixQMgrAqmIfWordWrite (registerAddress
, registerWord
);
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.
389 ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId
,
390 IxQMgrSourceId srcSel
,
391 unsigned int *statusWordOffset
,
397 if (qId
< IX_QMGR_MIN_QUEUPP_QID
)
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
;
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
;
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
;
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
;
417 case IX_QMGR_Q_SOURCE_ID_NOT_E
:
419 *mask
= IX_QMGR_Q_STATUS_E_BIT_MASK
;
421 case IX_QMGR_Q_SOURCE_ID_NOT_NE
:
423 *mask
= IX_QMGR_Q_STATUS_NE_BIT_MASK
;
425 case IX_QMGR_Q_SOURCE_ID_NOT_NF
:
427 *mask
= IX_QMGR_Q_STATUS_NF_BIT_MASK
;
429 case IX_QMGR_Q_SOURCE_ID_NOT_F
:
431 *mask
= IX_QMGR_Q_STATUS_F_BIT_MASK
;
434 /* Should never hit */
439 /* One nibble of status per queue so need to shift the
440 * check value and mask out to the correct position.
442 shiftVal
= (qId
% IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD
) *
443 IX_QMGR_QUELOWSTAT_BITS_PER_Q
;
445 /* Calculate the which status word to check from the qId,
446 * 8 Qs status per word
448 *statusWordOffset
= qId
/ IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD
;
450 *checkValue
<<= shiftVal
;
455 /* One status word */
456 *statusWordOffset
= 0;
457 /* Single bits per queue and int source bit hardwired NE,
460 *mask
= 1 << (qId
- IX_QMGR_MIN_QUEUPP_QID
);
466 ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId
)
468 volatile UINT32
*registerAddress
;
470 UINT32 actualBitOffset
;
472 if (qId
< IX_QMGR_MIN_QUEUPP_QID
)
474 registerAddress
= (UINT32
*)(aqmBaseAddress
+ IX_QMGR_QUEIEREG0_OFFSET
);
478 registerAddress
= (UINT32
*)(aqmBaseAddress
+ IX_QMGR_QUEIEREG1_OFFSET
);
481 actualBitOffset
= 1 << (qId
% IX_QMGR_MIN_QUEUPP_QID
);
483 ixQMgrAqmIfWordRead (registerAddress
, ®isterWord
);
484 ixQMgrAqmIfWordWrite (registerAddress
, (registerWord
| actualBitOffset
));
488 ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId
)
490 volatile UINT32
*registerAddress
;
492 UINT32 actualBitOffset
;
494 if (qId
< IX_QMGR_MIN_QUEUPP_QID
)
496 registerAddress
= (UINT32
*)(aqmBaseAddress
+ IX_QMGR_QUEIEREG0_OFFSET
);
500 registerAddress
= (UINT32
*)(aqmBaseAddress
+ IX_QMGR_QUEIEREG1_OFFSET
);
503 actualBitOffset
= 1 << (qId
% IX_QMGR_MIN_QUEUPP_QID
);
505 ixQMgrAqmIfWordRead (registerAddress
, ®isterWord
);
506 ixQMgrAqmIfWordWrite (registerAddress
, registerWord
& (~actualBitOffset
));
510 ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId
,
511 IxQMgrQSizeInWords qSizeInWords
,
512 IxQMgrQEntrySizeInWords entrySizeInWords
,
513 UINT32 freeSRAMAddress
)
515 volatile UINT32
*cfgAddress
= NULL
;
517 UINT32 baseAddress
= 0;
518 unsigned aqmEntrySize
= 0;
519 unsigned aqmBufferSize
= 0;
521 /* Build config register */
522 aqmEntrySize
= entrySizeToAqmEntrySize (entrySizeInWords
);
523 qCfg
|= (aqmEntrySize
&IX_QMGR_ENTRY_SIZE_MASK
) <<
524 IX_QMGR_Q_CONFIG_ESIZE_OFFSET
;
526 aqmBufferSize
= bufferSizeToAqmBufferSize (qSizeInWords
);
527 qCfg
|= (aqmBufferSize
&IX_QMGR_SIZE_MASK
) << IX_QMGR_Q_CONFIG_BSIZE_OFFSET
;
529 /* baseAddress, calculated relative to aqmBaseAddress and start address */
530 baseAddress
= freeSRAMAddress
-
531 (aqmBaseAddress
+ IX_QMGR_QUECONFIG_BASE_OFFSET
);
533 /* Verify base address aligned to a 16 word boundary */
534 if ((baseAddress
% IX_QMGR_BASE_ADDR_16_WORD_ALIGN
) != 0)
536 IX_QMGR_LOG_ERROR0("ixQMgrAqmIfQueCfgWrite () address is not on 16 word boundary\n");
538 /* Now convert it to a 16 word pointer as required by QUECONFIG register */
539 baseAddress
>>= IX_QMGR_BASE_ADDR_16_WORD_SHIFT
;
542 qCfg
|= (baseAddress
<< IX_QMGR_Q_CONFIG_BADDR_OFFSET
);
545 cfgAddress
= (UINT32
*)(aqmBaseAddress
+
546 IX_QMGR_Q_CONFIG_ADDR_GET(qId
));
549 /* NOTE: High and Low watermarks are set to zero */
550 ixQMgrAqmIfWordWrite (cfgAddress
, qCfg
);
554 ixQMgrAqmIfQueCfgRead (IxQMgrQId qId
,
555 unsigned int numEntries
,
563 UINT32
*cfgAddress
= (UINT32
*)(aqmBaseAddress
+ IX_QMGR_Q_CONFIG_ADDR_GET(qId
));
564 unsigned int qEntrySizeInwords
;
565 unsigned int qSizeInWords
;
566 UINT32
*readPtr_
= NULL
;
568 /* Read the queue configuration register */
569 ixQMgrAqmIfWordRead (cfgAddress
, &qcfg
);
571 /* Extract the base address */
572 *baseAddress
= (UINT32
)((qcfg
& IX_QMGR_BADDR_MASK
) >>
573 (IX_QMGR_Q_CONFIG_BADDR_OFFSET
));
575 /* Base address is a 16 word pointer from the start of AQM SRAM.
576 * Convert to absolute word address.
578 *baseAddress
<<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT
;
579 *baseAddress
+= (UINT32
)IX_QMGR_QUECONFIG_BASE_OFFSET
;
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
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
;
592 *ne
= 1 << (*ne
- 1);
596 *nf
= 1 << (*nf
- 1);
599 /* Get the queue entry size in words */
600 qEntrySizeInwords
= ixQMgrQEntrySizeInWordsGet (qId
);
602 /* Get the queue size in words */
603 qSizeInWords
= ixQMgrQSizeInWordsGet (qId
);
605 ixQMgrAqmIfEntryAddressGet (0/* Entry 0. i.e the readPtr*/,
610 *readPtr
= (UINT32
)readPtr_
;
611 *readPtr
-= (UINT32
)aqmBaseAddress
;/* Offset, not absolute address */
613 *writePtr
= (qcfg
>> IX_QMGR_Q_CONFIG_WRPTR_OFFSET
) & IX_QMGR_WRPTR_MASK
;
614 *writePtr
= *baseAddress
+ (*writePtr
* (IX_QMGR_NUM_BYTES_PER_WORD
));
619 ixQMgrAqmIfLog2 (unsigned number
)
624 * N.B. this function will return 0
625 * for ixQMgrAqmIfLog2 (0)
636 void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void)
639 volatile UINT32
*registerAddress
;
643 * Calculate the registerAddress
644 * multiple queues split accross registers
646 registerAddress
= (UINT32
*)(aqmBaseAddress
+
647 IX_QMGR_INT0SRCSELREG0_OFFSET
);
649 /* Read the current data */
650 ixQMgrAqmIfWordRead (registerAddress
, ®isterWord
);
652 /* Set the write bits */
653 registerWord
|= (1<<IX_QMGR_INT0SRCSELREG0_BIT3
) ;
658 ixQMgrAqmIfWordWrite (registerAddress
, registerWord
);
663 ixQMgrAqmIfIntSrcSelWrite (IxQMgrQId qId
,
664 IxQMgrSourceId sourceId
)
666 ixQMgrAqmIfQRegisterBitsWrite (qId
,
667 IX_QMGR_INT0SRCSELREG0_OFFSET
,
668 IX_QMGR_INTSRC_NUM_QUE_PER_WORD
,
675 ixQMgrAqmIfWatermarkSet (IxQMgrQId qId
,
679 volatile UINT32
*address
= 0;
681 unsigned aqmNeWatermark
= 0;
682 unsigned aqmNfWatermark
= 0;
684 address
= (UINT32
*)(aqmBaseAddress
+
685 IX_QMGR_Q_CONFIG_ADDR_GET(qId
));
687 aqmNeWatermark
= watermarkToAqmWatermark (ne
);
688 aqmNfWatermark
= watermarkToAqmWatermark (nf
);
690 /* Read the current watermarks */
691 ixQMgrAqmIfWordRead (address
, &value
);
693 /* Clear out the old watermarks */
694 value
&= IX_QMGR_NE_NF_CLEAR_MASK
;
696 /* Generate the value to write */
697 value
|= (aqmNeWatermark
<< IX_QMGR_Q_CONFIG_NE_OFFSET
) |
698 (aqmNfWatermark
<< IX_QMGR_Q_CONFIG_NF_OFFSET
);
700 ixQMgrAqmIfWordWrite (address
, value
);
705 ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex
,
706 UINT32 configRegWord
,
707 unsigned int qEntrySizeInwords
,
708 unsigned int qSizeInWords
,
713 UINT32
*topOfAqmSram
;
715 topOfAqmSram
= ((UINT32
*)aqmBaseAddress
+ IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS
);
717 /* Extract the base address */
718 baseAddress
= (UINT32
)((configRegWord
& IX_QMGR_BADDR_MASK
) >>
719 (IX_QMGR_Q_CONFIG_BADDR_OFFSET
));
721 /* Base address is a 16 word pointer from the start of AQM SRAM.
722 * Convert to absolute word address.
724 baseAddress
<<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT
;
725 baseAddress
+= ((UINT32
)aqmBaseAddress
+ (UINT32
)IX_QMGR_QUECONFIG_BASE_OFFSET
);
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
);
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.
734 readPtr
= (readPtr
+ (entryIndex
* qEntrySizeInwords
)) & (qSizeInWords
- 1); /* Mask by queue size */
735 *address
= (UINT32
*)(baseAddress
+ (readPtr
* (IX_QMGR_NUM_BYTES_PER_WORD
)));
737 switch (qEntrySizeInwords
)
739 case IX_QMGR_Q_ENTRY_SIZE1
:
740 IX_OSAL_ASSERT((*address
+ IX_QMGR_ENTRY1_OFFSET
) < topOfAqmSram
);
742 case IX_QMGR_Q_ENTRY_SIZE2
:
743 IX_OSAL_ASSERT((*address
+ IX_QMGR_ENTRY2_OFFSET
) < topOfAqmSram
);
745 case IX_QMGR_Q_ENTRY_SIZE4
:
746 IX_OSAL_ASSERT((*address
+ IX_QMGR_ENTRY4_OFFSET
) < topOfAqmSram
);
749 IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfEntryAddressGet");
756 ixQMgrAqmIfQPeek (IxQMgrQId qId
,
757 unsigned int entryIndex
,
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
;
767 /* Get the queue entry size in words */
768 qEntrySizeInwords
= ixQMgrQEntrySizeInWordsGet (qId
);
770 /* Get the queue size in words */
771 qSizeInWords
= ixQMgrQSizeInWordsGet (qId
);
773 /* Read the config register */
774 ixQMgrAqmIfWordRead (cfgRegAddress
, &configRegWordOnEntry
);
776 /* Get the entry address */
777 ixQMgrAqmIfEntryAddressGet (entryIndex
,
778 configRegWordOnEntry
,
783 /* Get the lock or return busy */
784 if (IX_SUCCESS
!= ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex
[qId
]))
789 while(qEntrySizeInwords
--)
791 ixQMgrAqmIfWordRead (entryAddress
++, entry
++);
794 /* Release the lock */
795 ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex
[qId
]);
797 /* Read the config register */
798 ixQMgrAqmIfWordRead (cfgRegAddress
, &configRegWordOnExit
);
800 /* Check that the read and write pointers have not changed */
801 if (configRegWordOnEntry
!= configRegWordOnExit
)
810 ixQMgrAqmIfQPoke (IxQMgrQId qId
,
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
;
821 /* Get the queue entry size in words */
822 qEntrySizeInwords
= ixQMgrQEntrySizeInWordsGet (qId
);
824 /* Get the queue size in words */
825 qSizeInWords
= ixQMgrQSizeInWordsGet (qId
);
827 /* Read the config register */
828 ixQMgrAqmIfWordRead (cfgRegAddress
, &configRegWordOnEntry
);
830 /* Get the entry address */
831 ixQMgrAqmIfEntryAddressGet (entryIndex
,
832 configRegWordOnEntry
,
837 /* Get the lock or return busy */
838 if (IX_SUCCESS
!= ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex
[qId
]))
843 /* Else read the entry directly from SRAM. This will not move the read pointer */
844 while(qEntrySizeInwords
--)
846 ixQMgrAqmIfWordWrite (entryAddress
++, *entry
++);
849 /* Release the lock */
850 ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex
[qId
]);
852 /* Read the config register */
853 ixQMgrAqmIfWordRead (cfgRegAddress
, &configRegWordOnExit
);
855 /* Check that the read and write pointers have not changed */
856 if (configRegWordOnEntry
!= configRegWordOnExit
)
865 watermarkToAqmWatermark (IxQMgrWMLevel watermark
)
867 unsigned aqmWatermark
= 0;
870 * Watermarks 0("000"),1("001"),2("010"),4("011"),
871 * 8("100"),16("101"),32("110"),64("111")
873 aqmWatermark
= ixQMgrAqmIfLog2 (watermark
* 2);
879 entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize
)
881 /* entrySize 1("00"),2("01"),4("10") */
882 return (ixQMgrAqmIfLog2 (entrySize
));
886 bufferSizeToAqmBufferSize (unsigned bufferSizeInWords
)
888 /* bufferSize 16("00"),32("01),64("10"),128("11") */
889 return (ixQMgrAqmIfLog2 (bufferSizeInWords
/ IX_QMGR_MIN_BUFFER_SIZE
));
893 * Reset AQM registers to default values.
896 ixQMgrAqmIfRegistersReset (void)
898 volatile UINT32
*qConfigWordAddress
= NULL
;
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.
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
);
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
);
923 /* Reset queues 32..63 nearly empty status registers */
924 ixQMgrAqmIfWordWrite((UINT32
*)(aqmBaseAddress
+ IX_QMGR_QUEUPPSTAT0_OFFSET
),
925 IX_QMGR_QUEUPPSTAT0_RESET_VALUE
);
927 /* Reset queues 32..63 full status registers */
928 ixQMgrAqmIfWordWrite((UINT32
*)(aqmBaseAddress
+ IX_QMGR_QUEUPPSTAT1_OFFSET
),
929 IX_QMGR_QUEUPPSTAT1_RESET_VALUE
);
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
);
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
);
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
);
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
++)
957 ixQMgrAqmIfWordWrite(qConfigWordAddress
,
958 IX_QMGR_QUECONFIG_RESET_VALUE
);
960 qConfigWordAddress
++;