IxQMgrQCfg.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. /**
  2. * @file QMgrQCfg.c
  3. *
  4. * @author Intel Corporation
  5. * @date 30-Oct-2001
  6. *
  7. * @brief This modules provides an interface for setting up the static
  8. * configuration of AQM queues.This file contains the following
  9. * functions:
  10. *
  11. *
  12. *
  13. * @par
  14. * IXP400 SW Release version 2.0
  15. *
  16. * -- Copyright Notice --
  17. *
  18. * @par
  19. * Copyright 2001-2005, Intel Corporation.
  20. * All rights reserved.
  21. *
  22. * @par
  23. * SPDX-License-Identifier: BSD-3-Clause
  24. * @par
  25. * -- End of Copyright Notice --
  26. */
  27. /*
  28. * System defined include files.
  29. */
  30. /*
  31. * User defined include files.
  32. */
  33. #include "IxOsal.h"
  34. #include "IxQMgr.h"
  35. #include "IxQMgrAqmIf_p.h"
  36. #include "IxQMgrQCfg_p.h"
  37. #include "IxQMgrDefines_p.h"
  38. /*
  39. * #defines and macros used in this file.
  40. */
  41. #define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
  42. /* Total size of SRAM */
  43. #define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
  44. /*
  45. * Check that qId is a valid queue identifier. This is provided to
  46. * make the code easier to read.
  47. */
  48. #define IX_QMGR_QID_IS_VALID(qId) \
  49. (((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID)))
  50. /*
  51. * Typedefs whose scope is limited to this file.
  52. */
  53. /*
  54. * This struct describes an AQM queue.
  55. * N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue
  56. * as these are requested by Access in the data path. sizeInEntries is
  57. * not required by the data path so it can be calculated dynamically.
  58. *
  59. */
  60. typedef struct
  61. {
  62. char qName[IX_QMGR_MAX_QNAME_LEN+1]; /* Textual description of a queue*/
  63. IxQMgrQSizeInWords qSizeInWords; /* The number of words in the queue */
  64. IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/
  65. BOOL isConfigured; /* This flag is true if the queue has
  66. * been configured
  67. */
  68. } IxQMgrCfgQ;
  69. /*
  70. * Variable declarations global to this file. Externs are followed by
  71. * statics.
  72. */
  73. extern UINT32 * ixQMgrAqmIfQueAccRegAddr[];
  74. /* Store data required to inline read and write access
  75. */
  76. IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES];
  77. static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES];
  78. /* This pointer holds the starting address of AQM SRAM not used by
  79. * the AQM queues.
  80. */
  81. static UINT32 freeSramAddress=0;
  82. /* 4 words of zeroed memory for inline access */
  83. static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 };
  84. static BOOL cfgInitialized = false;
  85. static IxOsalMutex ixQMgrQCfgMutex;
  86. /*
  87. * Statistics
  88. */
  89. static IxQMgrQCfgStats stats;
  90. /*
  91. * Function declarations
  92. */
  93. PRIVATE BOOL
  94. watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level);
  95. PRIVATE BOOL
  96. qSizeInWordsIsOk (IxQMgrQSizeInWords qSize);
  97. PRIVATE BOOL
  98. qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize);
  99. /*
  100. * Function definitions.
  101. */
  102. void
  103. ixQMgrQCfgInit (void)
  104. {
  105. int loopIndex;
  106. for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
  107. {
  108. /* info for code inlining */
  109. ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder;
  110. /* info for code inlining */
  111. ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0;
  112. ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0;
  113. ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder;
  114. ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder;
  115. ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0;
  116. ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0;
  117. ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0;
  118. ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0;
  119. ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder;
  120. }
  121. /* Initialise the AqmIf component */
  122. ixQMgrAqmIfInit ();
  123. /* Reset all queues to have queue name = NULL, entry size = 0 and
  124. * isConfigured = false
  125. */
  126. for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
  127. {
  128. strcpy (cfgQueueInfo[loopIndex].qName, "");
  129. cfgQueueInfo[loopIndex].qSizeInWords = 0;
  130. cfgQueueInfo[loopIndex].qEntrySizeInWords = 0;
  131. cfgQueueInfo[loopIndex].isConfigured = false;
  132. /* Statistics */
  133. stats.qStats[loopIndex].isConfigured = false;
  134. stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName;
  135. }
  136. /* Statistics */
  137. stats.wmSetCnt = 0;
  138. ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress);
  139. ixOsalMutexInit(&ixQMgrQCfgMutex);
  140. cfgInitialized = true;
  141. }
  142. void
  143. ixQMgrQCfgUninit (void)
  144. {
  145. cfgInitialized = false;
  146. /* Uninitialise the AqmIf component */
  147. ixQMgrAqmIfUninit ();
  148. }
  149. IX_STATUS
  150. ixQMgrQConfig (char *qName,
  151. IxQMgrQId qId,
  152. IxQMgrQSizeInWords qSizeInWords,
  153. IxQMgrQEntrySizeInWords qEntrySizeInWords)
  154. {
  155. UINT32 aqmLocalBaseAddress;
  156. if (!cfgInitialized)
  157. {
  158. return IX_FAIL;
  159. }
  160. if (!IX_QMGR_QID_IS_VALID(qId))
  161. {
  162. return IX_QMGR_INVALID_Q_ID;
  163. }
  164. else if (NULL == qName)
  165. {
  166. return IX_QMGR_PARAMETER_ERROR;
  167. }
  168. else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN)
  169. {
  170. return IX_QMGR_PARAMETER_ERROR;
  171. }
  172. else if (!qSizeInWordsIsOk (qSizeInWords))
  173. {
  174. return IX_QMGR_INVALID_QSIZE;
  175. }
  176. else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords))
  177. {
  178. return IX_QMGR_INVALID_Q_ENTRY_SIZE;
  179. }
  180. else if (cfgQueueInfo[qId].isConfigured)
  181. {
  182. return IX_QMGR_Q_ALREADY_CONFIGURED;
  183. }
  184. ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER);
  185. /* Write the config register */
  186. ixQMgrAqmIfQueCfgWrite (qId,
  187. qSizeInWords,
  188. qEntrySizeInWords,
  189. freeSramAddress);
  190. strcpy (cfgQueueInfo[qId].qName, qName);
  191. cfgQueueInfo[qId].qSizeInWords = qSizeInWords;
  192. cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
  193. /* store pre-computed information in the same cache line
  194. * to facilitate inlining of QRead and QWrite functions
  195. * in IxQMgr.h
  196. */
  197. ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0;
  198. ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0;
  199. ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
  200. ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries =
  201. (UINT32)qSizeInWords / (UINT32)qEntrySizeInWords;
  202. /* Calculate the new freeSramAddress from the size of the queue
  203. * currently being configured.
  204. */
  205. freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD);
  206. /* Get the virtual SRAM address */
  207. ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
  208. IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <=
  209. IX_QMGR_QUE_BUFFER_SPACE_SIZE);
  210. /* The queue is now configured */
  211. cfgQueueInfo[qId].isConfigured = true;
  212. ixOsalMutexUnlock(&ixQMgrQCfgMutex);
  213. #ifndef NDEBUG
  214. /* Update statistics */
  215. stats.qStats[qId].isConfigured = true;
  216. stats.qStats[qId].qName = cfgQueueInfo[qId].qName;
  217. #endif
  218. return IX_SUCCESS;
  219. }
  220. IxQMgrQSizeInWords
  221. ixQMgrQSizeInWordsGet (IxQMgrQId qId)
  222. {
  223. /* No parameter checking as this is used on the data path */
  224. return (cfgQueueInfo[qId].qSizeInWords);
  225. }
  226. IX_STATUS
  227. ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
  228. unsigned *qSizeInEntries)
  229. {
  230. if (!ixQMgrQIsConfigured(qId))
  231. {
  232. return IX_QMGR_Q_NOT_CONFIGURED;
  233. }
  234. if(NULL == qSizeInEntries)
  235. {
  236. return IX_QMGR_PARAMETER_ERROR;
  237. }
  238. *qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) /
  239. (UINT32)cfgQueueInfo[qId].qEntrySizeInWords;
  240. return IX_SUCCESS;
  241. }
  242. IxQMgrQEntrySizeInWords
  243. ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId)
  244. {
  245. /* No parameter checking as this is used on the data path */
  246. return (cfgQueueInfo[qId].qEntrySizeInWords);
  247. }
  248. IX_STATUS
  249. ixQMgrWatermarkSet (IxQMgrQId qId,
  250. IxQMgrWMLevel ne,
  251. IxQMgrWMLevel nf)
  252. {
  253. IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
  254. IxQMgrQStatus qStatusOnExit; /* to this function */
  255. if (!ixQMgrQIsConfigured(qId))
  256. {
  257. return IX_QMGR_Q_NOT_CONFIGURED;
  258. }
  259. if (!watermarkLevelIsOk (qId, ne))
  260. {
  261. return IX_QMGR_INVALID_Q_WM;
  262. }
  263. if (!watermarkLevelIsOk (qId, nf))
  264. {
  265. return IX_QMGR_INVALID_Q_WM;
  266. }
  267. /* Get the current queue status */
  268. ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
  269. #ifndef NDEBUG
  270. /* Update statistics */
  271. stats.wmSetCnt++;
  272. #endif
  273. ixQMgrAqmIfWatermarkSet (qId,
  274. ne,
  275. nf);
  276. /* Get the current queue status */
  277. ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
  278. /* If the status has changed return a warning */
  279. if (qStatusOnEntry != qStatusOnExit)
  280. {
  281. return IX_QMGR_WARNING;
  282. }
  283. return IX_SUCCESS;
  284. }
  285. IX_STATUS
  286. ixQMgrAvailableSramAddressGet (UINT32 *address,
  287. unsigned *sizeOfFreeRam)
  288. {
  289. UINT32 aqmLocalBaseAddress;
  290. if ((NULL == address)||(NULL == sizeOfFreeRam))
  291. {
  292. return IX_QMGR_PARAMETER_ERROR;
  293. }
  294. if (!cfgInitialized)
  295. {
  296. return IX_FAIL;
  297. }
  298. *address = freeSramAddress;
  299. /* Get the virtual SRAM address */
  300. ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
  301. /*
  302. * Calculate the size in bytes of free sram
  303. * i.e. current free SRAM virtual pointer from
  304. * (base + total size)
  305. */
  306. *sizeOfFreeRam =
  307. (aqmLocalBaseAddress +
  308. IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) -
  309. freeSramAddress;
  310. if (0 == *sizeOfFreeRam)
  311. {
  312. return IX_QMGR_NO_AVAILABLE_SRAM;
  313. }
  314. return IX_SUCCESS;
  315. }
  316. BOOL
  317. ixQMgrQIsConfigured (IxQMgrQId qId)
  318. {
  319. if (!IX_QMGR_QID_IS_VALID(qId))
  320. {
  321. return false;
  322. }
  323. return cfgQueueInfo[qId].isConfigured;
  324. }
  325. IxQMgrQCfgStats*
  326. ixQMgrQCfgStatsGet (void)
  327. {
  328. return &stats;
  329. }
  330. IxQMgrQCfgStats*
  331. ixQMgrQCfgQStatsGet (IxQMgrQId qId)
  332. {
  333. unsigned int ne;
  334. unsigned int nf;
  335. UINT32 baseAddress;
  336. UINT32 readPtr;
  337. UINT32 writePtr;
  338. stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords;
  339. stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords;
  340. if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
  341. {
  342. if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
  343. {
  344. IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId);
  345. }
  346. }
  347. ixQMgrAqmIfQueCfgRead (qId,
  348. stats.qStats[qId].numEntries,
  349. &baseAddress,
  350. &ne,
  351. &nf,
  352. &readPtr,
  353. &writePtr);
  354. stats.qStats[qId].baseAddress = baseAddress;
  355. stats.qStats[qId].ne = ne;
  356. stats.qStats[qId].nf = nf;
  357. stats.qStats[qId].readPtr = readPtr;
  358. stats.qStats[qId].writePtr = writePtr;
  359. return &stats;
  360. }
  361. /*
  362. * Static function definitions
  363. */
  364. PRIVATE BOOL
  365. watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level)
  366. {
  367. unsigned qSizeInEntries;
  368. switch (level)
  369. {
  370. case IX_QMGR_Q_WM_LEVEL0:
  371. case IX_QMGR_Q_WM_LEVEL1:
  372. case IX_QMGR_Q_WM_LEVEL2:
  373. case IX_QMGR_Q_WM_LEVEL4:
  374. case IX_QMGR_Q_WM_LEVEL8:
  375. case IX_QMGR_Q_WM_LEVEL16:
  376. case IX_QMGR_Q_WM_LEVEL32:
  377. case IX_QMGR_Q_WM_LEVEL64:
  378. break;
  379. default:
  380. return false;
  381. }
  382. /* Check watermark is not bigger than the qSizeInEntries */
  383. ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries);
  384. if ((unsigned)level > qSizeInEntries)
  385. {
  386. return false;
  387. }
  388. return true;
  389. }
  390. PRIVATE BOOL
  391. qSizeInWordsIsOk (IxQMgrQSizeInWords qSize)
  392. {
  393. BOOL status;
  394. switch (qSize)
  395. {
  396. case IX_QMGR_Q_SIZE16:
  397. case IX_QMGR_Q_SIZE32:
  398. case IX_QMGR_Q_SIZE64:
  399. case IX_QMGR_Q_SIZE128:
  400. status = true;
  401. break;
  402. default:
  403. status = false;
  404. break;
  405. }
  406. return status;
  407. }
  408. PRIVATE BOOL
  409. qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize)
  410. {
  411. BOOL status;
  412. switch (entrySize)
  413. {
  414. case IX_QMGR_Q_ENTRY_SIZE1:
  415. case IX_QMGR_Q_ENTRY_SIZE2:
  416. case IX_QMGR_Q_ENTRY_SIZE4:
  417. status = true;
  418. break;
  419. default:
  420. status = false;
  421. break;
  422. }
  423. return status;
  424. }