IxQMgrAqmIf.c 27 KB

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