IxQMgrAqmIf.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  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. * Inlines are compiled as function when this is defined.
  55. * N.B. Must be placed before #include of "IxQMgrAqmIf_p.h
  56. */
  57. #ifndef IXQMGRAQMIF_P_H
  58. # define IXQMGRAQMIF_C
  59. #else
  60. # error
  61. #endif
  62. /*
  63. * User defined include files.
  64. */
  65. #include "IxOsal.h"
  66. #include "IxQMgr.h"
  67. #include "IxQMgrAqmIf_p.h"
  68. #include "IxQMgrLog_p.h"
  69. /*
  70. * #defines and macros used in this file.
  71. */
  72. /* These defines are the bit offsets of the various fields of
  73. * the queue configuration register
  74. */
  75. #define IX_QMGR_Q_CONFIG_WRPTR_OFFSET 0x00
  76. #define IX_QMGR_Q_CONFIG_RDPTR_OFFSET 0x07
  77. #define IX_QMGR_Q_CONFIG_BADDR_OFFSET 0x0E
  78. #define IX_QMGR_Q_CONFIG_ESIZE_OFFSET 0x16
  79. #define IX_QMGR_Q_CONFIG_BSIZE_OFFSET 0x18
  80. #define IX_QMGR_Q_CONFIG_NE_OFFSET 0x1A
  81. #define IX_QMGR_Q_CONFIG_NF_OFFSET 0x1D
  82. #define IX_QMGR_BASE_ADDR_16_WORD_ALIGN 0x40
  83. #define IX_QMGR_BASE_ADDR_16_WORD_SHIFT 0x6
  84. #define IX_QMGR_NE_NF_CLEAR_MASK 0x03FFFFFF
  85. #define IX_QMGR_NE_MASK 0x7
  86. #define IX_QMGR_NF_MASK 0x7
  87. #define IX_QMGR_SIZE_MASK 0x3
  88. #define IX_QMGR_ENTRY_SIZE_MASK 0x3
  89. #define IX_QMGR_BADDR_MASK 0x003FC000
  90. #define IX_QMGR_RDPTR_MASK 0x7F
  91. #define IX_QMGR_WRPTR_MASK 0x7F
  92. #define IX_QMGR_RDWRPTR_MASK 0x00003FFF
  93. #define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000
  94. /* Base address of AQM SRAM */
  95. #define IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET \
  96. ((IX_QMGR_QUECONFIG_BASE_OFFSET) + (IX_QMGR_QUECONFIG_SIZE))
  97. /* Min buffer size used for generating buffer size in QUECONFIG */
  98. #define IX_QMGR_MIN_BUFFER_SIZE 16
  99. /* Reset values of QMgr hardware registers */
  100. #define IX_QMGR_QUELOWSTAT_RESET_VALUE 0x33333333
  101. #define IX_QMGR_QUEUOSTAT_RESET_VALUE 0x00000000
  102. #define IX_QMGR_QUEUPPSTAT0_RESET_VALUE 0xFFFFFFFF
  103. #define IX_QMGR_QUEUPPSTAT1_RESET_VALUE 0x00000000
  104. #define IX_QMGR_INT0SRCSELREG_RESET_VALUE 0x00000000
  105. #define IX_QMGR_QUEIEREG_RESET_VALUE 0x00000000
  106. #define IX_QMGR_QINTREG_RESET_VALUE 0xFFFFFFFF
  107. #define IX_QMGR_QUECONFIG_RESET_VALUE 0x00000000
  108. #define IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS IX_OSAL_IXP400_QMGR_PHYS_BASE
  109. #define IX_QMGR_QUELOWSTAT_BITS_PER_Q (BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)
  110. #define IX_QMGR_QUELOWSTAT_QID_MASK 0x7
  111. #define IX_QMGR_Q_CONFIG_ADDR_GET(qId)\
  112. (((qId) * IX_QMGR_NUM_BYTES_PER_WORD) +\
  113. IX_QMGR_QUECONFIG_BASE_OFFSET)
  114. #define IX_QMGR_ENTRY1_OFFSET 0
  115. #define IX_QMGR_ENTRY2_OFFSET 1
  116. #define IX_QMGR_ENTRY4_OFFSET 3
  117. /*
  118. * Variable declarations global to this file. Externs are followed by
  119. * statics.
  120. */
  121. UINT32 aqmBaseAddress = 0;
  122. /* Store addresses and bit-masks for certain queue access and status registers.
  123. * This is to facilitate inlining of QRead, QWrite and QStatusGet functions
  124. * in IxQMgr,h
  125. */
  126. extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
  127. UINT32 * ixQMgrAqmIfQueAccRegAddr[IX_QMGR_MAX_NUM_QUEUES];
  128. UINT32 ixQMgrAqmIfQueLowStatRegAddr[IX_QMGR_MIN_QUEUPP_QID];
  129. UINT32 ixQMgrAqmIfQueLowStatBitsOffset[IX_QMGR_MIN_QUEUPP_QID];
  130. UINT32 ixQMgrAqmIfQueLowStatBitsMask;
  131. UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
  132. UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
  133. UINT32 ixQMgrAqmIfQueUppStat0BitMask[IX_QMGR_MIN_QUEUPP_QID];
  134. UINT32 ixQMgrAqmIfQueUppStat1BitMask[IX_QMGR_MIN_QUEUPP_QID];
  135. /*
  136. * Fast mutexes, one for each queue, used to protect peek & poke functions
  137. */
  138. IxOsalFastMutex ixQMgrAqmIfPeekPokeFastMutex[IX_QMGR_MAX_NUM_QUEUES];
  139. /*
  140. * Function prototypes
  141. */
  142. PRIVATE unsigned
  143. watermarkToAqmWatermark (IxQMgrWMLevel watermark );
  144. PRIVATE unsigned
  145. entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize);
  146. PRIVATE unsigned
  147. bufferSizeToAqmBufferSize (unsigned bufferSizeInWords);
  148. PRIVATE void
  149. ixQMgrAqmIfRegistersReset (void);
  150. PRIVATE void
  151. ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
  152. UINT32 configRegWord,
  153. unsigned int qEntrySizeInwords,
  154. unsigned int qSizeInWords,
  155. UINT32 **address);
  156. /*
  157. * Function definitions
  158. */
  159. void
  160. ixQMgrAqmIfInit (void)
  161. {
  162. UINT32 aqmVirtualAddr;
  163. int i;
  164. /* The value of aqmBaseAddress depends on the logical address
  165. * assigned by the MMU.
  166. */
  167. aqmVirtualAddr =
  168. (UINT32) IX_OSAL_MEM_MAP(IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS,
  169. IX_OSAL_IXP400_QMGR_MAP_SIZE);
  170. IX_OSAL_ASSERT (aqmVirtualAddr);
  171. ixQMgrAqmIfBaseAddressSet (aqmVirtualAddr);
  172. ixQMgrAqmIfRegistersReset ();
  173. for (i = 0; i< IX_QMGR_MAX_NUM_QUEUES; i++)
  174. {
  175. ixOsalFastMutexInit(&ixQMgrAqmIfPeekPokeFastMutex[i]);
  176. /********************************************************************
  177. * Register addresses and bit masks are calculated and stored here to
  178. * facilitate inlining of QRead, QWrite and QStatusGet functions in
  179. * IxQMgr.h.
  180. * These calculations are normally performed dynamically in inlined
  181. * functions in IxQMgrAqmIf_p.h, and their semantics are reused here.
  182. */
  183. /* AQM Queue access reg addresses, per queue */
  184. ixQMgrAqmIfQueAccRegAddr[i] =
  185. (UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
  186. ixQMgrQInlinedReadWriteInfo[i].qAccRegAddr =
  187. (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
  188. ixQMgrQInlinedReadWriteInfo[i].qConfigRegAddr =
  189. (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(i));
  190. /* AQM Queue lower-group (0-31), only */
  191. if (i < IX_QMGR_MIN_QUEUPP_QID)
  192. {
  193. /* AQM Q underflow/overflow status register addresses, per queue */
  194. ixQMgrQInlinedReadWriteInfo[i].qUOStatRegAddr =
  195. (volatile UINT32 *)(aqmBaseAddress +
  196. IX_QMGR_QUEUOSTAT0_OFFSET +
  197. ((i / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD) *
  198. IX_QMGR_NUM_BYTES_PER_WORD));
  199. /* AQM Q underflow status bit masks for status register per queue */
  200. ixQMgrQInlinedReadWriteInfo[i].qUflowStatBitMask =
  201. (IX_QMGR_UNDERFLOW_BIT_OFFSET + 1) <<
  202. ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
  203. (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
  204. /* AQM Q overflow status bit masks for status register, per queue */
  205. ixQMgrQInlinedReadWriteInfo[i].qOflowStatBitMask =
  206. (IX_QMGR_OVERFLOW_BIT_OFFSET + 1) <<
  207. ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
  208. (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
  209. /* AQM Q lower-group (0-31) status register addresses, per queue */
  210. ixQMgrAqmIfQueLowStatRegAddr[i] = aqmBaseAddress +
  211. IX_QMGR_QUELOWSTAT0_OFFSET +
  212. ((i / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
  213. IX_QMGR_NUM_BYTES_PER_WORD);
  214. /* AQM Q lower-group (0-31) status register bit offset */
  215. ixQMgrAqmIfQueLowStatBitsOffset[i] =
  216. (i & (IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD - 1)) *
  217. (BITS_PER_WORD / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD);
  218. }
  219. else /* AQM Q upper-group (32-63), only */
  220. {
  221. /* AQM Q upper-group (32-63) Nearly Empty status reg bit masks */
  222. ixQMgrAqmIfQueUppStat0BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
  223. (1 << (i - IX_QMGR_MIN_QUEUPP_QID));
  224. /* AQM Q upper-group (32-63) Full status register bit masks */
  225. ixQMgrAqmIfQueUppStat1BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
  226. (1 << (i - IX_QMGR_MIN_QUEUPP_QID));
  227. }
  228. }
  229. /* AQM Q lower-group (0-31) status register bit mask */
  230. ixQMgrAqmIfQueLowStatBitsMask = (1 <<
  231. (BITS_PER_WORD /
  232. IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)) - 1;
  233. /* AQM Q upper-group (32-63) Nearly Empty status register address */
  234. ixQMgrAqmIfQueUppStat0RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET;
  235. /* AQM Q upper-group (32-63) Full status register address */
  236. ixQMgrAqmIfQueUppStat1RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET;
  237. }
  238. /*
  239. * Uninitialise the AqmIf module by unmapping memory, etc
  240. */
  241. void
  242. ixQMgrAqmIfUninit (void)
  243. {
  244. UINT32 virtAddr;
  245. ixQMgrAqmIfBaseAddressGet (&virtAddr);
  246. IX_OSAL_MEM_UNMAP (virtAddr);
  247. ixQMgrAqmIfBaseAddressSet (0);
  248. }
  249. /*
  250. * Set the the logical base address of AQM
  251. */
  252. void
  253. ixQMgrAqmIfBaseAddressSet (UINT32 address)
  254. {
  255. aqmBaseAddress = address;
  256. }
  257. /*
  258. * Get the logical base address of AQM
  259. */
  260. void
  261. ixQMgrAqmIfBaseAddressGet (UINT32 *address)
  262. {
  263. *address = aqmBaseAddress;
  264. }
  265. /*
  266. * Get the logical base address of AQM SRAM
  267. */
  268. void
  269. ixQMgrAqmIfSramBaseAddressGet (UINT32 *address)
  270. {
  271. *address = aqmBaseAddress +
  272. IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET;
  273. }
  274. /*
  275. * This function will write the status bits of a queue
  276. * specified by qId.
  277. */
  278. void
  279. ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId,
  280. UINT32 registerBaseAddrOffset,
  281. unsigned queuesPerRegWord,
  282. UINT32 value)
  283. {
  284. volatile UINT32 *registerAddress;
  285. UINT32 registerWord;
  286. UINT32 statusBitsMask;
  287. UINT32 bitsPerQueue;
  288. bitsPerQueue = BITS_PER_WORD / queuesPerRegWord;
  289. /*
  290. * Calculate the registerAddress
  291. * multiple queues split accross registers
  292. */
  293. registerAddress = (UINT32*)(aqmBaseAddress +
  294. registerBaseAddrOffset +
  295. ((qId / queuesPerRegWord) *
  296. IX_QMGR_NUM_BYTES_PER_WORD));
  297. /* Read the current data */
  298. ixQMgrAqmIfWordRead (registerAddress, &registerWord);
  299. if( (registerBaseAddrOffset == IX_QMGR_INT0SRCSELREG0_OFFSET) &&
  300. (qId == IX_QMGR_QUEUE_0) )
  301. {
  302. statusBitsMask = 0x7 ;
  303. /* Queue 0 at INT0SRCSELREG should not corrupt the value bit-3 */
  304. value &= 0x7 ;
  305. }
  306. else
  307. {
  308. /* Calculate the mask for the status bits for this queue. */
  309. statusBitsMask = ((1 << bitsPerQueue) - 1);
  310. statusBitsMask <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
  311. /* Mask out bits in value that would overwrite other q data */
  312. value <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
  313. value &= statusBitsMask;
  314. }
  315. /* Mask out bits to write to */
  316. registerWord &= ~statusBitsMask;
  317. /* Set the write bits */
  318. registerWord |= value;
  319. /*
  320. * Write the data
  321. */
  322. ixQMgrAqmIfWordWrite (registerAddress, registerWord);
  323. }
  324. /*
  325. * This function generates the parameters that can be used to
  326. * check if a Qs status matches the specified source select.
  327. * It calculates which status word to check (statusWordOffset),
  328. * the value to check the status against (checkValue) and the
  329. * mask (mask) to mask out all but the bits to check in the status word.
  330. */
  331. void
  332. ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId,
  333. IxQMgrSourceId srcSel,
  334. unsigned int *statusWordOffset,
  335. UINT32 *checkValue,
  336. UINT32 *mask)
  337. {
  338. UINT32 shiftVal;
  339. if (qId < IX_QMGR_MIN_QUEUPP_QID)
  340. {
  341. switch (srcSel)
  342. {
  343. case IX_QMGR_Q_SOURCE_ID_E:
  344. *checkValue = IX_QMGR_Q_STATUS_E_BIT_MASK;
  345. *mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
  346. break;
  347. case IX_QMGR_Q_SOURCE_ID_NE:
  348. *checkValue = IX_QMGR_Q_STATUS_NE_BIT_MASK;
  349. *mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
  350. break;
  351. case IX_QMGR_Q_SOURCE_ID_NF:
  352. *checkValue = IX_QMGR_Q_STATUS_NF_BIT_MASK;
  353. *mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
  354. break;
  355. case IX_QMGR_Q_SOURCE_ID_F:
  356. *checkValue = IX_QMGR_Q_STATUS_F_BIT_MASK;
  357. *mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
  358. break;
  359. case IX_QMGR_Q_SOURCE_ID_NOT_E:
  360. *checkValue = 0;
  361. *mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
  362. break;
  363. case IX_QMGR_Q_SOURCE_ID_NOT_NE:
  364. *checkValue = 0;
  365. *mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
  366. break;
  367. case IX_QMGR_Q_SOURCE_ID_NOT_NF:
  368. *checkValue = 0;
  369. *mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
  370. break;
  371. case IX_QMGR_Q_SOURCE_ID_NOT_F:
  372. *checkValue = 0;
  373. *mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
  374. break;
  375. default:
  376. /* Should never hit */
  377. IX_OSAL_ASSERT(0);
  378. break;
  379. }
  380. /* One nibble of status per queue so need to shift the
  381. * check value and mask out to the correct position.
  382. */
  383. shiftVal = (qId % IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
  384. IX_QMGR_QUELOWSTAT_BITS_PER_Q;
  385. /* Calculate the which status word to check from the qId,
  386. * 8 Qs status per word
  387. */
  388. *statusWordOffset = qId / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD;
  389. *checkValue <<= shiftVal;
  390. *mask <<= shiftVal;
  391. }
  392. else
  393. {
  394. /* One status word */
  395. *statusWordOffset = 0;
  396. /* Single bits per queue and int source bit hardwired NE,
  397. * Qs start at 32.
  398. */
  399. *mask = 1 << (qId - IX_QMGR_MIN_QUEUPP_QID);
  400. *checkValue = *mask;
  401. }
  402. }
  403. void
  404. ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId)
  405. {
  406. volatile UINT32 *registerAddress;
  407. UINT32 registerWord;
  408. UINT32 actualBitOffset;
  409. if (qId < IX_QMGR_MIN_QUEUPP_QID)
  410. {
  411. registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
  412. }
  413. else
  414. {
  415. registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
  416. }
  417. actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);
  418. ixQMgrAqmIfWordRead (registerAddress, &registerWord);
  419. ixQMgrAqmIfWordWrite (registerAddress, (registerWord | actualBitOffset));
  420. }
  421. void
  422. ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId)
  423. {
  424. volatile UINT32 *registerAddress;
  425. UINT32 registerWord;
  426. UINT32 actualBitOffset;
  427. if (qId < IX_QMGR_MIN_QUEUPP_QID)
  428. {
  429. registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
  430. }
  431. else
  432. {
  433. registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
  434. }
  435. actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);
  436. ixQMgrAqmIfWordRead (registerAddress, &registerWord);
  437. ixQMgrAqmIfWordWrite (registerAddress, registerWord & (~actualBitOffset));
  438. }
  439. void
  440. ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId,
  441. IxQMgrQSizeInWords qSizeInWords,
  442. IxQMgrQEntrySizeInWords entrySizeInWords,
  443. UINT32 freeSRAMAddress)
  444. {
  445. volatile UINT32 *cfgAddress = NULL;
  446. UINT32 qCfg = 0;
  447. UINT32 baseAddress = 0;
  448. unsigned aqmEntrySize = 0;
  449. unsigned aqmBufferSize = 0;
  450. /* Build config register */
  451. aqmEntrySize = entrySizeToAqmEntrySize (entrySizeInWords);
  452. qCfg |= (aqmEntrySize&IX_QMGR_ENTRY_SIZE_MASK) <<
  453. IX_QMGR_Q_CONFIG_ESIZE_OFFSET;
  454. aqmBufferSize = bufferSizeToAqmBufferSize (qSizeInWords);
  455. qCfg |= (aqmBufferSize&IX_QMGR_SIZE_MASK) << IX_QMGR_Q_CONFIG_BSIZE_OFFSET;
  456. /* baseAddress, calculated relative to aqmBaseAddress and start address */
  457. baseAddress = freeSRAMAddress -
  458. (aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
  459. /* Verify base address aligned to a 16 word boundary */
  460. if ((baseAddress % IX_QMGR_BASE_ADDR_16_WORD_ALIGN) != 0)
  461. {
  462. IX_QMGR_LOG_ERROR0("ixQMgrAqmIfQueCfgWrite () address is not on 16 word boundary\n");
  463. }
  464. /* Now convert it to a 16 word pointer as required by QUECONFIG register */
  465. baseAddress >>= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
  466. qCfg |= (baseAddress << IX_QMGR_Q_CONFIG_BADDR_OFFSET);
  467. cfgAddress = (UINT32*)(aqmBaseAddress +
  468. IX_QMGR_Q_CONFIG_ADDR_GET(qId));
  469. /* NOTE: High and Low watermarks are set to zero */
  470. ixQMgrAqmIfWordWrite (cfgAddress, qCfg);
  471. }
  472. void
  473. ixQMgrAqmIfQueCfgRead (IxQMgrQId qId,
  474. unsigned int numEntries,
  475. UINT32 *baseAddress,
  476. unsigned int *ne,
  477. unsigned int *nf,
  478. UINT32 *readPtr,
  479. UINT32 *writePtr)
  480. {
  481. UINT32 qcfg;
  482. UINT32 *cfgAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
  483. unsigned int qEntrySizeInwords;
  484. unsigned int qSizeInWords;
  485. UINT32 *readPtr_ = NULL;
  486. /* Read the queue configuration register */
  487. ixQMgrAqmIfWordRead (cfgAddress, &qcfg);
  488. /* Extract the base address */
  489. *baseAddress = (UINT32)((qcfg & IX_QMGR_BADDR_MASK) >>
  490. (IX_QMGR_Q_CONFIG_BADDR_OFFSET));
  491. /* Base address is a 16 word pointer from the start of AQM SRAM.
  492. * Convert to absolute word address.
  493. */
  494. *baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
  495. *baseAddress += (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET;
  496. /*
  497. * Extract the watermarks. 0->0 entries, 1->1 entries, 2->2 entries, 3->4 entries......
  498. * If ne > 0 ==> neInEntries = 2^(ne - 1)
  499. * If ne == 0 ==> neInEntries = 0
  500. * The same applies.
  501. */
  502. *ne = ((qcfg) >> (IX_QMGR_Q_CONFIG_NE_OFFSET)) & IX_QMGR_NE_MASK;
  503. *nf = ((qcfg) >> (IX_QMGR_Q_CONFIG_NF_OFFSET)) & IX_QMGR_NF_MASK;
  504. if (0 != *ne)
  505. {
  506. *ne = 1 << (*ne - 1);
  507. }
  508. if (0 != *nf)
  509. {
  510. *nf = 1 << (*nf - 1);
  511. }
  512. /* Get the queue entry size in words */
  513. qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
  514. /* Get the queue size in words */
  515. qSizeInWords = ixQMgrQSizeInWordsGet (qId);
  516. ixQMgrAqmIfEntryAddressGet (0/* Entry 0. i.e the readPtr*/,
  517. qcfg,
  518. qEntrySizeInwords,
  519. qSizeInWords,
  520. &readPtr_);
  521. *readPtr = (UINT32)readPtr_;
  522. *readPtr -= (UINT32)aqmBaseAddress;/* Offset, not absolute address */
  523. *writePtr = (qcfg >> IX_QMGR_Q_CONFIG_WRPTR_OFFSET) & IX_QMGR_WRPTR_MASK;
  524. *writePtr = *baseAddress + (*writePtr * (IX_QMGR_NUM_BYTES_PER_WORD));
  525. return;
  526. }
  527. unsigned
  528. ixQMgrAqmIfLog2 (unsigned number)
  529. {
  530. unsigned count = 0;
  531. /*
  532. * N.B. this function will return 0
  533. * for ixQMgrAqmIfLog2 (0)
  534. */
  535. while (number/2)
  536. {
  537. number /=2;
  538. count++;
  539. }
  540. return count;
  541. }
  542. void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void)
  543. {
  544. volatile UINT32 *registerAddress;
  545. UINT32 registerWord;
  546. /*
  547. * Calculate the registerAddress
  548. * multiple queues split accross registers
  549. */
  550. registerAddress = (UINT32*)(aqmBaseAddress +
  551. IX_QMGR_INT0SRCSELREG0_OFFSET);
  552. /* Read the current data */
  553. ixQMgrAqmIfWordRead (registerAddress, &registerWord);
  554. /* Set the write bits */
  555. registerWord |= (1<<IX_QMGR_INT0SRCSELREG0_BIT3) ;
  556. /*
  557. * Write the data
  558. */
  559. ixQMgrAqmIfWordWrite (registerAddress, registerWord);
  560. }
  561. void
  562. ixQMgrAqmIfIntSrcSelWrite (IxQMgrQId qId,
  563. IxQMgrSourceId sourceId)
  564. {
  565. ixQMgrAqmIfQRegisterBitsWrite (qId,
  566. IX_QMGR_INT0SRCSELREG0_OFFSET,
  567. IX_QMGR_INTSRC_NUM_QUE_PER_WORD,
  568. sourceId);
  569. }
  570. void
  571. ixQMgrAqmIfWatermarkSet (IxQMgrQId qId,
  572. unsigned ne,
  573. unsigned nf)
  574. {
  575. volatile UINT32 *address = 0;
  576. UINT32 value = 0;
  577. unsigned aqmNeWatermark = 0;
  578. unsigned aqmNfWatermark = 0;
  579. address = (UINT32*)(aqmBaseAddress +
  580. IX_QMGR_Q_CONFIG_ADDR_GET(qId));
  581. aqmNeWatermark = watermarkToAqmWatermark (ne);
  582. aqmNfWatermark = watermarkToAqmWatermark (nf);
  583. /* Read the current watermarks */
  584. ixQMgrAqmIfWordRead (address, &value);
  585. /* Clear out the old watermarks */
  586. value &= IX_QMGR_NE_NF_CLEAR_MASK;
  587. /* Generate the value to write */
  588. value |= (aqmNeWatermark << IX_QMGR_Q_CONFIG_NE_OFFSET) |
  589. (aqmNfWatermark << IX_QMGR_Q_CONFIG_NF_OFFSET);
  590. ixQMgrAqmIfWordWrite (address, value);
  591. }
  592. PRIVATE void
  593. ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
  594. UINT32 configRegWord,
  595. unsigned int qEntrySizeInwords,
  596. unsigned int qSizeInWords,
  597. UINT32 **address)
  598. {
  599. UINT32 readPtr;
  600. UINT32 baseAddress;
  601. UINT32 *topOfAqmSram;
  602. topOfAqmSram = ((UINT32 *)aqmBaseAddress + IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS);
  603. /* Extract the base address */
  604. baseAddress = (UINT32)((configRegWord & IX_QMGR_BADDR_MASK) >>
  605. (IX_QMGR_Q_CONFIG_BADDR_OFFSET));
  606. /* Base address is a 16 word pointer from the start of AQM SRAM.
  607. * Convert to absolute word address.
  608. */
  609. baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
  610. baseAddress += ((UINT32)aqmBaseAddress + (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET);
  611. /* Extract the read pointer. Read pointer is a word pointer */
  612. readPtr = (UINT32)((configRegWord >>
  613. IX_QMGR_Q_CONFIG_RDPTR_OFFSET)&IX_QMGR_RDPTR_MASK);
  614. /* Read/Write pointers(word pointers) are offsets from the queue buffer space base address.
  615. * Calculate the absolute read pointer address. NOTE: Queues are circular buffers.
  616. */
  617. readPtr = (readPtr + (entryIndex * qEntrySizeInwords)) & (qSizeInWords - 1); /* Mask by queue size */
  618. *address = (UINT32 *)(baseAddress + (readPtr * (IX_QMGR_NUM_BYTES_PER_WORD)));
  619. switch (qEntrySizeInwords)
  620. {
  621. case IX_QMGR_Q_ENTRY_SIZE1:
  622. IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY1_OFFSET) < topOfAqmSram);
  623. break;
  624. case IX_QMGR_Q_ENTRY_SIZE2:
  625. IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY2_OFFSET) < topOfAqmSram);
  626. break;
  627. case IX_QMGR_Q_ENTRY_SIZE4:
  628. IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY4_OFFSET) < topOfAqmSram);
  629. break;
  630. default:
  631. IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfEntryAddressGet");
  632. break;
  633. }
  634. }
  635. IX_STATUS
  636. ixQMgrAqmIfQPeek (IxQMgrQId qId,
  637. unsigned int entryIndex,
  638. unsigned int *entry)
  639. {
  640. UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
  641. UINT32 *entryAddress = NULL;
  642. UINT32 configRegWordOnEntry;
  643. UINT32 configRegWordOnExit;
  644. unsigned int qEntrySizeInwords;
  645. unsigned int qSizeInWords;
  646. /* Get the queue entry size in words */
  647. qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
  648. /* Get the queue size in words */
  649. qSizeInWords = ixQMgrQSizeInWordsGet (qId);
  650. /* Read the config register */
  651. ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);
  652. /* Get the entry address */
  653. ixQMgrAqmIfEntryAddressGet (entryIndex,
  654. configRegWordOnEntry,
  655. qEntrySizeInwords,
  656. qSizeInWords,
  657. &entryAddress);
  658. /* Get the lock or return busy */
  659. if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
  660. {
  661. return IX_FAIL;
  662. }
  663. while(qEntrySizeInwords--)
  664. {
  665. ixQMgrAqmIfWordRead (entryAddress++, entry++);
  666. }
  667. /* Release the lock */
  668. ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);
  669. /* Read the config register */
  670. ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);
  671. /* Check that the read and write pointers have not changed */
  672. if (configRegWordOnEntry != configRegWordOnExit)
  673. {
  674. return IX_FAIL;
  675. }
  676. return IX_SUCCESS;
  677. }
  678. IX_STATUS
  679. ixQMgrAqmIfQPoke (IxQMgrQId qId,
  680. unsigned entryIndex,
  681. unsigned int *entry)
  682. {
  683. UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
  684. UINT32 *entryAddress = NULL;
  685. UINT32 configRegWordOnEntry;
  686. UINT32 configRegWordOnExit;
  687. unsigned int qEntrySizeInwords;
  688. unsigned int qSizeInWords;
  689. /* Get the queue entry size in words */
  690. qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
  691. /* Get the queue size in words */
  692. qSizeInWords = ixQMgrQSizeInWordsGet (qId);
  693. /* Read the config register */
  694. ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);
  695. /* Get the entry address */
  696. ixQMgrAqmIfEntryAddressGet (entryIndex,
  697. configRegWordOnEntry,
  698. qEntrySizeInwords,
  699. qSizeInWords,
  700. &entryAddress);
  701. /* Get the lock or return busy */
  702. if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
  703. {
  704. return IX_FAIL;
  705. }
  706. /* Else read the entry directly from SRAM. This will not move the read pointer */
  707. while(qEntrySizeInwords--)
  708. {
  709. ixQMgrAqmIfWordWrite (entryAddress++, *entry++);
  710. }
  711. /* Release the lock */
  712. ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);
  713. /* Read the config register */
  714. ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);
  715. /* Check that the read and write pointers have not changed */
  716. if (configRegWordOnEntry != configRegWordOnExit)
  717. {
  718. return IX_FAIL;
  719. }
  720. return IX_SUCCESS;
  721. }
  722. PRIVATE unsigned
  723. watermarkToAqmWatermark (IxQMgrWMLevel watermark )
  724. {
  725. unsigned aqmWatermark = 0;
  726. /*
  727. * Watermarks 0("000"),1("001"),2("010"),4("011"),
  728. * 8("100"),16("101"),32("110"),64("111")
  729. */
  730. aqmWatermark = ixQMgrAqmIfLog2 (watermark * 2);
  731. return aqmWatermark;
  732. }
  733. PRIVATE unsigned
  734. entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize)
  735. {
  736. /* entrySize 1("00"),2("01"),4("10") */
  737. return (ixQMgrAqmIfLog2 (entrySize));
  738. }
  739. PRIVATE unsigned
  740. bufferSizeToAqmBufferSize (unsigned bufferSizeInWords)
  741. {
  742. /* bufferSize 16("00"),32("01),64("10"),128("11") */
  743. return (ixQMgrAqmIfLog2 (bufferSizeInWords / IX_QMGR_MIN_BUFFER_SIZE));
  744. }
  745. /*
  746. * Reset AQM registers to default values.
  747. */
  748. PRIVATE void
  749. ixQMgrAqmIfRegistersReset (void)
  750. {
  751. volatile UINT32 *qConfigWordAddress = NULL;
  752. unsigned int i;
  753. /*
  754. * Need to initialize AQM hardware registers to an initial
  755. * value as init may have been called as a result of a soft
  756. * reset. i.e. soft reset does not reset hardware registers.
  757. */
  758. /* Reset queues 0..31 status registers 0..3 */
  759. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT0_OFFSET),
  760. IX_QMGR_QUELOWSTAT_RESET_VALUE);
  761. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT1_OFFSET),
  762. IX_QMGR_QUELOWSTAT_RESET_VALUE);
  763. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT2_OFFSET),
  764. IX_QMGR_QUELOWSTAT_RESET_VALUE);
  765. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT3_OFFSET),
  766. IX_QMGR_QUELOWSTAT_RESET_VALUE);
  767. /* Reset underflow/overflow status registers 0..1 */
  768. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT0_OFFSET),
  769. IX_QMGR_QUEUOSTAT_RESET_VALUE);
  770. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT1_OFFSET),
  771. IX_QMGR_QUEUOSTAT_RESET_VALUE);
  772. /* Reset queues 32..63 nearly empty status registers */
  773. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET),
  774. IX_QMGR_QUEUPPSTAT0_RESET_VALUE);
  775. /* Reset queues 32..63 full status registers */
  776. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET),
  777. IX_QMGR_QUEUPPSTAT1_RESET_VALUE);
  778. /* Reset int0 status flag source select registers 0..3 */
  779. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG0_OFFSET),
  780. IX_QMGR_INT0SRCSELREG_RESET_VALUE);
  781. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG1_OFFSET),
  782. IX_QMGR_INT0SRCSELREG_RESET_VALUE);
  783. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG2_OFFSET),
  784. IX_QMGR_INT0SRCSELREG_RESET_VALUE);
  785. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG3_OFFSET),
  786. IX_QMGR_INT0SRCSELREG_RESET_VALUE);
  787. /* Reset queue interrupt enable register 0..1 */
  788. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET),
  789. IX_QMGR_QUEIEREG_RESET_VALUE);
  790. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET),
  791. IX_QMGR_QUEIEREG_RESET_VALUE);
  792. /* Reset queue interrupt register 0..1 */
  793. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG0_OFFSET),
  794. IX_QMGR_QINTREG_RESET_VALUE);
  795. ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG1_OFFSET),
  796. IX_QMGR_QINTREG_RESET_VALUE);
  797. /* Reset queue configuration words 0..63 */
  798. qConfigWordAddress = (UINT32 *)(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
  799. for (i = 0; i < (IX_QMGR_QUECONFIG_SIZE / sizeof(UINT32)); i++)
  800. {
  801. ixQMgrAqmIfWordWrite(qConfigWordAddress,
  802. IX_QMGR_QUECONFIG_RESET_VALUE);
  803. /* Next word */
  804. qConfigWordAddress++;
  805. }
  806. }