IxQMgrQCfg.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  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. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the above copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. Neither the name of the Intel Corporation nor the names of its contributors
  32. * may be used to endorse or promote products derived from this software
  33. * without specific prior written permission.
  34. *
  35. * @par
  36. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
  37. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  38. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  39. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  40. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  41. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  42. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  44. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  45. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. *
  48. * @par
  49. * -- End of Copyright Notice --
  50. */
  51. /*
  52. * System defined include files.
  53. */
  54. /*
  55. * User defined include files.
  56. */
  57. #include "IxOsal.h"
  58. #include "IxQMgr.h"
  59. #include "IxQMgrAqmIf_p.h"
  60. #include "IxQMgrQCfg_p.h"
  61. #include "IxQMgrDefines_p.h"
  62. /*
  63. * #defines and macros used in this file.
  64. */
  65. #define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
  66. /* Total size of SRAM */
  67. #define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
  68. /*
  69. * Check that qId is a valid queue identifier. This is provided to
  70. * make the code easier to read.
  71. */
  72. #define IX_QMGR_QID_IS_VALID(qId) \
  73. (((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID)))
  74. /*
  75. * Typedefs whose scope is limited to this file.
  76. */
  77. /*
  78. * This struct describes an AQM queue.
  79. * N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue
  80. * as these are requested by Access in the data path. sizeInEntries is
  81. * not required by the data path so it can be calculated dynamically.
  82. *
  83. */
  84. typedef struct
  85. {
  86. char qName[IX_QMGR_MAX_QNAME_LEN+1]; /* Textual description of a queue*/
  87. IxQMgrQSizeInWords qSizeInWords; /* The number of words in the queue */
  88. IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/
  89. BOOL isConfigured; /* This flag is TRUE if the queue has
  90. * been configured
  91. */
  92. } IxQMgrCfgQ;
  93. /*
  94. * Variable declarations global to this file. Externs are followed by
  95. * statics.
  96. */
  97. extern UINT32 * ixQMgrAqmIfQueAccRegAddr[];
  98. /* Store data required to inline read and write access
  99. */
  100. IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES];
  101. static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES];
  102. /* This pointer holds the starting address of AQM SRAM not used by
  103. * the AQM queues.
  104. */
  105. static UINT32 freeSramAddress=0;
  106. /* 4 words of zeroed memory for inline access */
  107. static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 };
  108. static BOOL cfgInitialized = FALSE;
  109. static IxOsalMutex ixQMgrQCfgMutex;
  110. /*
  111. * Statistics
  112. */
  113. static IxQMgrQCfgStats stats;
  114. /*
  115. * Function declarations
  116. */
  117. PRIVATE BOOL
  118. watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level);
  119. PRIVATE BOOL
  120. qSizeInWordsIsOk (IxQMgrQSizeInWords qSize);
  121. PRIVATE BOOL
  122. qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize);
  123. /*
  124. * Function definitions.
  125. */
  126. void
  127. ixQMgrQCfgInit (void)
  128. {
  129. int loopIndex;
  130. for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
  131. {
  132. /* info for code inlining */
  133. ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder;
  134. /* info for code inlining */
  135. ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0;
  136. ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0;
  137. ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder;
  138. ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder;
  139. ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0;
  140. ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0;
  141. ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0;
  142. ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0;
  143. ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder;
  144. }
  145. /* Initialise the AqmIf component */
  146. ixQMgrAqmIfInit ();
  147. /* Reset all queues to have queue name = NULL, entry size = 0 and
  148. * isConfigured = false
  149. */
  150. for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
  151. {
  152. strcpy (cfgQueueInfo[loopIndex].qName, "");
  153. cfgQueueInfo[loopIndex].qSizeInWords = 0;
  154. cfgQueueInfo[loopIndex].qEntrySizeInWords = 0;
  155. cfgQueueInfo[loopIndex].isConfigured = FALSE;
  156. /* Statistics */
  157. stats.qStats[loopIndex].isConfigured = FALSE;
  158. stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName;
  159. }
  160. /* Statistics */
  161. stats.wmSetCnt = 0;
  162. ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress);
  163. ixOsalMutexInit(&ixQMgrQCfgMutex);
  164. cfgInitialized = TRUE;
  165. }
  166. void
  167. ixQMgrQCfgUninit (void)
  168. {
  169. cfgInitialized = FALSE;
  170. /* Uninitialise the AqmIf component */
  171. ixQMgrAqmIfUninit ();
  172. }
  173. IX_STATUS
  174. ixQMgrQConfig (char *qName,
  175. IxQMgrQId qId,
  176. IxQMgrQSizeInWords qSizeInWords,
  177. IxQMgrQEntrySizeInWords qEntrySizeInWords)
  178. {
  179. UINT32 aqmLocalBaseAddress;
  180. if (!cfgInitialized)
  181. {
  182. return IX_FAIL;
  183. }
  184. if (!IX_QMGR_QID_IS_VALID(qId))
  185. {
  186. return IX_QMGR_INVALID_Q_ID;
  187. }
  188. else if (NULL == qName)
  189. {
  190. return IX_QMGR_PARAMETER_ERROR;
  191. }
  192. else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN)
  193. {
  194. return IX_QMGR_PARAMETER_ERROR;
  195. }
  196. else if (!qSizeInWordsIsOk (qSizeInWords))
  197. {
  198. return IX_QMGR_INVALID_QSIZE;
  199. }
  200. else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords))
  201. {
  202. return IX_QMGR_INVALID_Q_ENTRY_SIZE;
  203. }
  204. else if (cfgQueueInfo[qId].isConfigured)
  205. {
  206. return IX_QMGR_Q_ALREADY_CONFIGURED;
  207. }
  208. ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER);
  209. /* Write the config register */
  210. ixQMgrAqmIfQueCfgWrite (qId,
  211. qSizeInWords,
  212. qEntrySizeInWords,
  213. freeSramAddress);
  214. strcpy (cfgQueueInfo[qId].qName, qName);
  215. cfgQueueInfo[qId].qSizeInWords = qSizeInWords;
  216. cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
  217. /* store pre-computed information in the same cache line
  218. * to facilitate inlining of QRead and QWrite functions
  219. * in IxQMgr.h
  220. */
  221. ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0;
  222. ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0;
  223. ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
  224. ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries =
  225. (UINT32)qSizeInWords / (UINT32)qEntrySizeInWords;
  226. /* Calculate the new freeSramAddress from the size of the queue
  227. * currently being configured.
  228. */
  229. freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD);
  230. /* Get the virtual SRAM address */
  231. ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
  232. IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <=
  233. IX_QMGR_QUE_BUFFER_SPACE_SIZE);
  234. /* The queue is now configured */
  235. cfgQueueInfo[qId].isConfigured = TRUE;
  236. ixOsalMutexUnlock(&ixQMgrQCfgMutex);
  237. #ifndef NDEBUG
  238. /* Update statistics */
  239. stats.qStats[qId].isConfigured = TRUE;
  240. stats.qStats[qId].qName = cfgQueueInfo[qId].qName;
  241. #endif
  242. return IX_SUCCESS;
  243. }
  244. IxQMgrQSizeInWords
  245. ixQMgrQSizeInWordsGet (IxQMgrQId qId)
  246. {
  247. /* No parameter checking as this is used on the data path */
  248. return (cfgQueueInfo[qId].qSizeInWords);
  249. }
  250. IX_STATUS
  251. ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
  252. unsigned *qSizeInEntries)
  253. {
  254. if (!ixQMgrQIsConfigured(qId))
  255. {
  256. return IX_QMGR_Q_NOT_CONFIGURED;
  257. }
  258. if(NULL == qSizeInEntries)
  259. {
  260. return IX_QMGR_PARAMETER_ERROR;
  261. }
  262. *qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) /
  263. (UINT32)cfgQueueInfo[qId].qEntrySizeInWords;
  264. return IX_SUCCESS;
  265. }
  266. IxQMgrQEntrySizeInWords
  267. ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId)
  268. {
  269. /* No parameter checking as this is used on the data path */
  270. return (cfgQueueInfo[qId].qEntrySizeInWords);
  271. }
  272. IX_STATUS
  273. ixQMgrWatermarkSet (IxQMgrQId qId,
  274. IxQMgrWMLevel ne,
  275. IxQMgrWMLevel nf)
  276. {
  277. IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
  278. IxQMgrQStatus qStatusOnExit; /* to this function */
  279. if (!ixQMgrQIsConfigured(qId))
  280. {
  281. return IX_QMGR_Q_NOT_CONFIGURED;
  282. }
  283. if (!watermarkLevelIsOk (qId, ne))
  284. {
  285. return IX_QMGR_INVALID_Q_WM;
  286. }
  287. if (!watermarkLevelIsOk (qId, nf))
  288. {
  289. return IX_QMGR_INVALID_Q_WM;
  290. }
  291. /* Get the current queue status */
  292. ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
  293. #ifndef NDEBUG
  294. /* Update statistics */
  295. stats.wmSetCnt++;
  296. #endif
  297. ixQMgrAqmIfWatermarkSet (qId,
  298. ne,
  299. nf);
  300. /* Get the current queue status */
  301. ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
  302. /* If the status has changed return a warning */
  303. if (qStatusOnEntry != qStatusOnExit)
  304. {
  305. return IX_QMGR_WARNING;
  306. }
  307. return IX_SUCCESS;
  308. }
  309. IX_STATUS
  310. ixQMgrAvailableSramAddressGet (UINT32 *address,
  311. unsigned *sizeOfFreeRam)
  312. {
  313. UINT32 aqmLocalBaseAddress;
  314. if ((NULL == address)||(NULL == sizeOfFreeRam))
  315. {
  316. return IX_QMGR_PARAMETER_ERROR;
  317. }
  318. if (!cfgInitialized)
  319. {
  320. return IX_FAIL;
  321. }
  322. *address = freeSramAddress;
  323. /* Get the virtual SRAM address */
  324. ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
  325. /*
  326. * Calculate the size in bytes of free sram
  327. * i.e. current free SRAM virtual pointer from
  328. * (base + total size)
  329. */
  330. *sizeOfFreeRam =
  331. (aqmLocalBaseAddress +
  332. IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) -
  333. freeSramAddress;
  334. if (0 == *sizeOfFreeRam)
  335. {
  336. return IX_QMGR_NO_AVAILABLE_SRAM;
  337. }
  338. return IX_SUCCESS;
  339. }
  340. BOOL
  341. ixQMgrQIsConfigured (IxQMgrQId qId)
  342. {
  343. if (!IX_QMGR_QID_IS_VALID(qId))
  344. {
  345. return FALSE;
  346. }
  347. return cfgQueueInfo[qId].isConfigured;
  348. }
  349. IxQMgrQCfgStats*
  350. ixQMgrQCfgStatsGet (void)
  351. {
  352. return &stats;
  353. }
  354. IxQMgrQCfgStats*
  355. ixQMgrQCfgQStatsGet (IxQMgrQId qId)
  356. {
  357. unsigned int ne;
  358. unsigned int nf;
  359. UINT32 baseAddress;
  360. UINT32 readPtr;
  361. UINT32 writePtr;
  362. stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords;
  363. stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords;
  364. if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
  365. {
  366. if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
  367. {
  368. IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId);
  369. }
  370. }
  371. ixQMgrAqmIfQueCfgRead (qId,
  372. stats.qStats[qId].numEntries,
  373. &baseAddress,
  374. &ne,
  375. &nf,
  376. &readPtr,
  377. &writePtr);
  378. stats.qStats[qId].baseAddress = baseAddress;
  379. stats.qStats[qId].ne = ne;
  380. stats.qStats[qId].nf = nf;
  381. stats.qStats[qId].readPtr = readPtr;
  382. stats.qStats[qId].writePtr = writePtr;
  383. return &stats;
  384. }
  385. /*
  386. * Static function definitions
  387. */
  388. PRIVATE BOOL
  389. watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level)
  390. {
  391. unsigned qSizeInEntries;
  392. switch (level)
  393. {
  394. case IX_QMGR_Q_WM_LEVEL0:
  395. case IX_QMGR_Q_WM_LEVEL1:
  396. case IX_QMGR_Q_WM_LEVEL2:
  397. case IX_QMGR_Q_WM_LEVEL4:
  398. case IX_QMGR_Q_WM_LEVEL8:
  399. case IX_QMGR_Q_WM_LEVEL16:
  400. case IX_QMGR_Q_WM_LEVEL32:
  401. case IX_QMGR_Q_WM_LEVEL64:
  402. break;
  403. default:
  404. return FALSE;
  405. }
  406. /* Check watermark is not bigger than the qSizeInEntries */
  407. ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries);
  408. if ((unsigned)level > qSizeInEntries)
  409. {
  410. return FALSE;
  411. }
  412. return TRUE;
  413. }
  414. PRIVATE BOOL
  415. qSizeInWordsIsOk (IxQMgrQSizeInWords qSize)
  416. {
  417. BOOL status;
  418. switch (qSize)
  419. {
  420. case IX_QMGR_Q_SIZE16:
  421. case IX_QMGR_Q_SIZE32:
  422. case IX_QMGR_Q_SIZE64:
  423. case IX_QMGR_Q_SIZE128:
  424. status = TRUE;
  425. break;
  426. default:
  427. status = FALSE;
  428. break;
  429. }
  430. return status;
  431. }
  432. PRIVATE BOOL
  433. qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize)
  434. {
  435. BOOL status;
  436. switch (entrySize)
  437. {
  438. case IX_QMGR_Q_ENTRY_SIZE1:
  439. case IX_QMGR_Q_ENTRY_SIZE2:
  440. case IX_QMGR_Q_ENTRY_SIZE4:
  441. status = TRUE;
  442. break;
  443. default:
  444. status = FALSE;
  445. break;
  446. }
  447. return status;
  448. }