IxQMgrQAccess.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. /**
  2. * @file IxQMgrQAccess.c
  3. *
  4. * @author Intel Corporation
  5. * @date 30-Oct-2001
  6. *
  7. * @brief This file contains functions for putting entries on a queue and
  8. * removing entries from a queue.
  9. *
  10. *
  11. * @par
  12. * IXP400 SW Release version 2.0
  13. *
  14. * -- Copyright Notice --
  15. *
  16. * @par
  17. * Copyright 2001-2005, Intel Corporation.
  18. * All rights reserved.
  19. *
  20. * @par
  21. * Redistribution and use in source and binary forms, with or without
  22. * modification, are permitted provided that the following conditions
  23. * are met:
  24. * 1. Redistributions of source code must retain the above copyright
  25. * notice, this list of conditions and the following disclaimer.
  26. * 2. Redistributions in binary form must reproduce the above copyright
  27. * notice, this list of conditions and the following disclaimer in the
  28. * documentation and/or other materials provided with the distribution.
  29. * 3. Neither the name of the Intel Corporation nor the names of its contributors
  30. * may be used to endorse or promote products derived from this software
  31. * without specific prior written permission.
  32. *
  33. * @par
  34. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
  35. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  36. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  37. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  38. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  39. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  40. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  41. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  42. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  43. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  44. * SUCH DAMAGE.
  45. *
  46. * @par
  47. * -- End of Copyright Notice --
  48. */
  49. /*
  50. * Inlines are compiled as function when this is defined.
  51. * N.B. Must be placed before #include of "IxQMgr.h"
  52. */
  53. #ifndef IXQMGR_H
  54. # define IXQMGRQACCESS_C
  55. #else
  56. # error
  57. #endif
  58. /*
  59. * System defined include files.
  60. */
  61. /*
  62. * User defined include files.
  63. */
  64. #include "IxQMgr.h"
  65. #include "IxQMgrAqmIf_p.h"
  66. #include "IxQMgrQAccess_p.h"
  67. #include "IxQMgrQCfg_p.h"
  68. #include "IxQMgrDefines_p.h"
  69. /*
  70. * Global variables and extern definitions
  71. */
  72. extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
  73. /*
  74. * Function definitions.
  75. */
  76. void
  77. ixQMgrQAccessInit (void)
  78. {
  79. }
  80. IX_STATUS
  81. ixQMgrQReadWithChecks (IxQMgrQId qId,
  82. UINT32 *entry)
  83. {
  84. IxQMgrQEntrySizeInWords entrySizeInWords;
  85. IxQMgrQInlinedReadWriteInfo *infoPtr;
  86. if (NULL == entry)
  87. {
  88. return IX_QMGR_PARAMETER_ERROR;
  89. }
  90. /* Check QId */
  91. if (!ixQMgrQIsConfigured(qId))
  92. {
  93. return IX_QMGR_Q_NOT_CONFIGURED;
  94. }
  95. /* Get the q entry size in words */
  96. entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
  97. ixQMgrAqmIfQPop (qId, entrySizeInWords, entry);
  98. /* reset the current read count if the counter wrapped around
  99. * (unsigned arithmetic)
  100. */
  101. infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
  102. if (infoPtr->qReadCount-- > infoPtr->qSizeInEntries)
  103. {
  104. infoPtr->qReadCount = 0;
  105. }
  106. /* Check if underflow occurred on the read */
  107. if (ixQMgrAqmIfUnderflowCheck (qId))
  108. {
  109. return IX_QMGR_Q_UNDERFLOW;
  110. }
  111. return IX_SUCCESS;
  112. }
  113. /* this function reads the remaining of the q entry
  114. * for queues configured with many words.
  115. * (the first word of the entry is already read
  116. * in the inlined function and the entry pointer already
  117. * incremented
  118. */
  119. IX_STATUS
  120. ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
  121. UINT32 *entry)
  122. {
  123. IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
  124. UINT32 entrySize = infoPtr->qEntrySizeInWords;
  125. volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
  126. while (--entrySize)
  127. {
  128. /* read the entry and accumulate the result */
  129. *(++entry) = IX_OSAL_READ_LONG(++qAccRegAddr);
  130. }
  131. /* underflow is available for lower queues only */
  132. if (qId < IX_QMGR_MIN_QUEUPP_QID)
  133. {
  134. /* get the queue status */
  135. UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
  136. /* check the underflow status */
  137. if (status & infoPtr->qUflowStatBitMask)
  138. {
  139. /* the queue is empty
  140. * clear the underflow status bit if it was set
  141. */
  142. IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
  143. status & ~infoPtr->qUflowStatBitMask);
  144. return IX_QMGR_Q_UNDERFLOW;
  145. }
  146. }
  147. return IX_SUCCESS;
  148. }
  149. IX_STATUS
  150. ixQMgrQWriteWithChecks (IxQMgrQId qId,
  151. UINT32 *entry)
  152. {
  153. IxQMgrQEntrySizeInWords entrySizeInWords;
  154. IxQMgrQInlinedReadWriteInfo *infoPtr;
  155. if (NULL == entry)
  156. {
  157. return IX_QMGR_PARAMETER_ERROR;
  158. }
  159. /* Check QId */
  160. if (!ixQMgrQIsConfigured(qId))
  161. {
  162. return IX_QMGR_Q_NOT_CONFIGURED;
  163. }
  164. /* Get the q entry size in words */
  165. entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
  166. ixQMgrAqmIfQPush (qId, entrySizeInWords, entry);
  167. /* reset the current read count if the counter wrapped around
  168. * (unsigned arithmetic)
  169. */
  170. infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
  171. if (infoPtr->qWriteCount++ >= infoPtr->qSizeInEntries)
  172. {
  173. infoPtr->qWriteCount = infoPtr->qSizeInEntries;
  174. }
  175. /* Check if overflow occurred on the write*/
  176. if (ixQMgrAqmIfOverflowCheck (qId))
  177. {
  178. return IX_QMGR_Q_OVERFLOW;
  179. }
  180. return IX_SUCCESS;
  181. }
  182. IX_STATUS
  183. ixQMgrQPeek (IxQMgrQId qId,
  184. unsigned int entryIndex,
  185. UINT32 *entry)
  186. {
  187. unsigned int numEntries;
  188. #ifndef NDEBUG
  189. if ((NULL == entry) || (entryIndex >= IX_QMGR_Q_SIZE_INVALID))
  190. {
  191. return IX_QMGR_PARAMETER_ERROR;
  192. }
  193. if (!ixQMgrQIsConfigured(qId))
  194. {
  195. return IX_QMGR_Q_NOT_CONFIGURED;
  196. }
  197. #endif
  198. if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
  199. {
  200. return IX_FAIL;
  201. }
  202. if (entryIndex >= numEntries) /* entryIndex starts at 0 */
  203. {
  204. return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
  205. }
  206. return ixQMgrAqmIfQPeek (qId, entryIndex, entry);
  207. }
  208. IX_STATUS
  209. ixQMgrQPoke (IxQMgrQId qId,
  210. unsigned entryIndex,
  211. UINT32 *entry)
  212. {
  213. unsigned int numEntries;
  214. #ifndef NDEBUG
  215. if ((NULL == entry) || (entryIndex > 128))
  216. {
  217. return IX_QMGR_PARAMETER_ERROR;
  218. }
  219. if (!ixQMgrQIsConfigured(qId))
  220. {
  221. return IX_QMGR_Q_NOT_CONFIGURED;
  222. }
  223. #endif
  224. if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
  225. {
  226. return IX_FAIL;
  227. }
  228. if (numEntries < (entryIndex + 1)) /* entryIndex starts at 0 */
  229. {
  230. return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
  231. }
  232. return ixQMgrAqmIfQPoke (qId, entryIndex, entry);
  233. }
  234. IX_STATUS
  235. ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
  236. IxQMgrQStatus *qStatus)
  237. {
  238. if (NULL == qStatus)
  239. {
  240. return IX_QMGR_PARAMETER_ERROR;
  241. }
  242. if (!ixQMgrQIsConfigured (qId))
  243. {
  244. return IX_QMGR_Q_NOT_CONFIGURED;
  245. }
  246. ixQMgrAqmIfQueStatRead (qId, qStatus);
  247. return IX_SUCCESS;
  248. }
  249. IX_STATUS
  250. ixQMgrQNumEntriesGet (IxQMgrQId qId,
  251. unsigned *numEntriesPtr)
  252. {
  253. UINT32 qPtrs;
  254. UINT32 qStatus;
  255. unsigned numEntries;
  256. IxQMgrQInlinedReadWriteInfo *infoPtr;
  257. #ifndef NDEBUG
  258. if (NULL == numEntriesPtr)
  259. {
  260. return IX_QMGR_PARAMETER_ERROR;
  261. }
  262. /* Check QId */
  263. if (!ixQMgrQIsConfigured(qId))
  264. {
  265. return IX_QMGR_Q_NOT_CONFIGURED;
  266. }
  267. #endif
  268. /* get fast access data */
  269. infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
  270. /* get snapshot */
  271. qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
  272. /* Mod subtraction of pointers to get number of words in Q. */
  273. numEntries = (qPtrs - (qPtrs >> 7)) & 0x7f;
  274. if (numEntries == 0)
  275. {
  276. /*
  277. * Could mean either full or empty queue
  278. * so look at status
  279. */
  280. ixQMgrAqmIfQueStatRead (qId, &qStatus);
  281. if (qId < IX_QMGR_MIN_QUEUPP_QID)
  282. {
  283. if (qStatus & IX_QMGR_Q_STATUS_E_BIT_MASK)
  284. {
  285. /* Empty */
  286. *numEntriesPtr = 0;
  287. }
  288. else if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
  289. {
  290. /* Full */
  291. *numEntriesPtr = infoPtr->qSizeInEntries;
  292. }
  293. else
  294. {
  295. /*
  296. * Queue status and read/write pointers are volatile.
  297. * The queue state has changed since we took the
  298. * snapshot of the read and write pointers.
  299. * Client can retry if they wish
  300. */
  301. *numEntriesPtr = 0;
  302. return IX_QMGR_WARNING;
  303. }
  304. }
  305. else /* It is an upper queue which does not have an empty status bit maintained */
  306. {
  307. if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
  308. {
  309. /* The queue is Full at the time of snapshot. */
  310. *numEntriesPtr = infoPtr->qSizeInEntries;
  311. }
  312. else
  313. {
  314. /* The queue is either empty, either moving,
  315. * Client can retry if they wish
  316. */
  317. *numEntriesPtr = 0;
  318. return IX_QMGR_WARNING;
  319. }
  320. }
  321. }
  322. else
  323. {
  324. *numEntriesPtr = (numEntries / infoPtr->qEntrySizeInWords) & (infoPtr->qSizeInEntries - 1);
  325. }
  326. return IX_SUCCESS;
  327. }
  328. #if defined(__wince) && defined(NO_INLINE_APIS)
  329. PUBLIC IX_STATUS
  330. ixQMgrQRead (IxQMgrQId qId,
  331. UINT32 *entryPtr)
  332. {
  333. extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
  334. IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
  335. UINT32 entry, entrySize;
  336. /* get a new entry */
  337. entrySize = infoPtr->qEntrySizeInWords;
  338. entry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
  339. if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
  340. {
  341. *entryPtr = entry;
  342. /* process the remaining part of the entry */
  343. return ixQMgrQReadMWordsMinus1(qId, entryPtr);
  344. }
  345. /* underflow is available for lower queues only */
  346. if (qId < IX_QMGR_MIN_QUEUPP_QID)
  347. {
  348. /* the counter of queue entries is decremented. In happy
  349. * day scenario there are many entries in the queue
  350. * and the counter does not reach zero.
  351. */
  352. if (infoPtr->qReadCount-- == 0)
  353. {
  354. /* There is maybe no entry in the queue
  355. * qReadCount is now negative, but will be corrected before
  356. * the function returns.
  357. */
  358. UINT32 qPtrs; /* queue internal pointers */
  359. /* when a queue is empty, the hw guarantees to return
  360. * a null value. If the value is not null, the queue is
  361. * not empty.
  362. */
  363. if (entry == 0)
  364. {
  365. /* get the queue status */
  366. UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
  367. /* check the underflow status */
  368. if (status & infoPtr->qUflowStatBitMask)
  369. {
  370. /* the queue is empty
  371. * clear the underflow status bit if it was set
  372. */
  373. IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
  374. status & ~infoPtr->qUflowStatBitMask);
  375. *entryPtr = 0;
  376. infoPtr->qReadCount = 0;
  377. return IX_QMGR_Q_UNDERFLOW;
  378. }
  379. }
  380. /* store the result */
  381. *entryPtr = entry;
  382. /* No underflow occured : someone is filling the queue
  383. * or the queue contains null entries.
  384. * The current counter needs to be
  385. * updated from the current number of entries in the queue
  386. */
  387. /* get snapshot of queue pointers */
  388. qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
  389. /* Mod subtraction of pointers to get number of words in Q. */
  390. qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
  391. if (qPtrs == 0)
  392. {
  393. /* no entry in the queue */
  394. infoPtr->qReadCount = 0;
  395. }
  396. else
  397. {
  398. /* convert the number of words inside the queue
  399. * to a number of entries
  400. */
  401. infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1);
  402. }
  403. return IX_SUCCESS;
  404. }
  405. }
  406. *entryPtr = entry;
  407. return IX_SUCCESS;
  408. }
  409. PUBLIC IX_STATUS
  410. ixQMgrQBurstRead (IxQMgrQId qId,
  411. UINT32 numEntries,
  412. UINT32 *entries)
  413. {
  414. extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
  415. IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
  416. UINT32 nullCheckEntry;
  417. if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
  418. {
  419. volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
  420. /* the code is optimized to take care of data dependencies:
  421. * Durig a read, there are a few cycles needed to get the
  422. * read complete. During these cycles, it is poossible to
  423. * do some CPU, e.g. increment pointers and decrement
  424. * counters.
  425. */
  426. /* fetch a queue entry */
  427. nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
  428. /* iterate the specified number of queue entries */
  429. while (--numEntries)
  430. {
  431. /* check the result of the previous read */
  432. if (nullCheckEntry == 0)
  433. {
  434. /* if we read a NULL entry, stop. We have underflowed */
  435. break;
  436. }
  437. else
  438. {
  439. /* write the entry */
  440. *entries = nullCheckEntry;
  441. /* fetch next entry */
  442. nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr);
  443. /* increment the write address */
  444. entries++;
  445. }
  446. }
  447. /* write the pre-fetched entry */
  448. *entries = nullCheckEntry;
  449. }
  450. else
  451. {
  452. IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
  453. /* read the specified number of queue entries */
  454. nullCheckEntry = 0;
  455. while (numEntries--)
  456. {
  457. int i;
  458. for (i = 0; i < entrySizeInWords; i++)
  459. {
  460. *entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i);
  461. nullCheckEntry |= *entries++;
  462. }
  463. /* if we read a NULL entry, stop. We have underflowed */
  464. if (nullCheckEntry == 0)
  465. {
  466. break;
  467. }
  468. nullCheckEntry = 0;
  469. }
  470. }
  471. /* reset the current read count : next access to the read function
  472. * will force a underflow status check
  473. */
  474. infoPtr->qWriteCount = 0;
  475. /* Check if underflow occurred on the read */
  476. if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID)
  477. {
  478. /* get the queue status */
  479. UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
  480. if (status & infoPtr->qUflowStatBitMask)
  481. {
  482. /* clear the underflow status bit if it was set */
  483. IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
  484. status & ~infoPtr->qUflowStatBitMask);
  485. return IX_QMGR_Q_UNDERFLOW;
  486. }
  487. }
  488. return IX_SUCCESS;
  489. }
  490. PUBLIC IX_STATUS
  491. ixQMgrQWrite (IxQMgrQId qId,
  492. UINT32 *entry)
  493. {
  494. extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
  495. IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
  496. UINT32 entrySize;
  497. /* write the entry */
  498. IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry);
  499. entrySize = infoPtr->qEntrySizeInWords;
  500. if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
  501. {
  502. /* process the remaining part of the entry */
  503. volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
  504. while (--entrySize)
  505. {
  506. ++entry;
  507. IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry);
  508. }
  509. entrySize = infoPtr->qEntrySizeInWords;
  510. }
  511. /* overflow is available for lower queues only */
  512. if (qId < IX_QMGR_MIN_QUEUPP_QID)
  513. {
  514. UINT32 qSize = infoPtr->qSizeInEntries;
  515. /* increment the current number of entries in the queue
  516. * and check for overflow
  517. */
  518. if (infoPtr->qWriteCount++ == qSize)
  519. {
  520. /* the queue may have overflow */
  521. UINT32 qPtrs; /* queue internal pointers */
  522. /* get the queue status */
  523. UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
  524. /* read the status twice because the status may
  525. * not be immediately ready after the write operation
  526. */
  527. if ((status & infoPtr->qOflowStatBitMask) ||
  528. ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
  529. & infoPtr->qOflowStatBitMask))
  530. {
  531. /* the queue is full, clear the overflow status
  532. * bit if it was set
  533. */
  534. IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
  535. status & ~infoPtr->qOflowStatBitMask);
  536. infoPtr->qWriteCount = infoPtr->qSizeInEntries;
  537. return IX_QMGR_Q_OVERFLOW;
  538. }
  539. /* No overflow occured : someone is draining the queue
  540. * and the current counter needs to be
  541. * updated from the current number of entries in the queue
  542. */
  543. /* get q pointer snapshot */
  544. qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
  545. /* Mod subtraction of pointers to get number of words in Q. */
  546. qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
  547. if (qPtrs == 0)
  548. {
  549. /* the queue may be full at the time of the
  550. * snapshot. Next access will check
  551. * the overflow status again.
  552. */
  553. infoPtr->qWriteCount = qSize;
  554. }
  555. else
  556. {
  557. /* convert the number of words to a number of entries */
  558. if (entrySize == IX_QMGR_Q_ENTRY_SIZE1)
  559. {
  560. infoPtr->qWriteCount = qPtrs & (qSize - 1);
  561. }
  562. else
  563. {
  564. infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1);
  565. }
  566. }
  567. }
  568. }
  569. return IX_SUCCESS;
  570. }
  571. PUBLIC IX_STATUS
  572. ixQMgrQBurstWrite (IxQMgrQId qId,
  573. unsigned numEntries,
  574. UINT32 *entries)
  575. {
  576. extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
  577. IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
  578. UINT32 status;
  579. /* update the current write count */
  580. infoPtr->qWriteCount += numEntries;
  581. if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
  582. {
  583. volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
  584. while (numEntries--)
  585. {
  586. IX_OSAL_WRITE_LONG(qAccRegAddr, *entries);
  587. entries++;
  588. }
  589. }
  590. else
  591. {
  592. IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
  593. int i;
  594. /* write each queue entry */
  595. while (numEntries--)
  596. {
  597. /* write the queueEntrySize number of words for each entry */
  598. for (i = 0; i < entrySizeInWords; i++)
  599. {
  600. IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries);
  601. entries++;
  602. }
  603. }
  604. }
  605. /* check if the write count overflows */
  606. if (infoPtr->qWriteCount > infoPtr->qSizeInEntries)
  607. {
  608. /* reset the current write count */
  609. infoPtr->qWriteCount = infoPtr->qSizeInEntries;
  610. }
  611. /* Check if overflow occurred on the write operation */
  612. if (qId < IX_QMGR_MIN_QUEUPP_QID)
  613. {
  614. /* get the queue status */
  615. status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
  616. /* read the status twice because the status may
  617. * not be ready at the time of the write
  618. */
  619. if ((status & infoPtr->qOflowStatBitMask) ||
  620. ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
  621. & infoPtr->qOflowStatBitMask))
  622. {
  623. /* clear the underflow status bit if it was set */
  624. IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
  625. status & ~infoPtr->qOflowStatBitMask);
  626. return IX_QMGR_Q_OVERFLOW;
  627. }
  628. }
  629. return IX_SUCCESS;
  630. }
  631. PUBLIC IX_STATUS
  632. ixQMgrQStatusGet (IxQMgrQId qId,
  633. IxQMgrQStatus *qStatus)
  634. {
  635. /* read the status of a queue in the range 0-31 */
  636. if (qId < IX_QMGR_MIN_QUEUPP_QID)
  637. {
  638. extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[];
  639. extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[];
  640. extern UINT32 ixQMgrAqmIfQueLowStatBitsMask;
  641. extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
  642. IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
  643. volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId];
  644. volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr;
  645. UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId];
  646. UINT32 lowStatBitsMask = ixQMgrAqmIfQueLowStatBitsMask;
  647. UINT32 underflowBitMask = infoPtr->qUflowStatBitMask;
  648. UINT32 overflowBitMask = infoPtr->qOflowStatBitMask;
  649. /* read the status register for this queue */
  650. *qStatus = IX_OSAL_READ_LONG(lowStatRegAddr);
  651. /* mask out the status bits relevant only to this queue */
  652. *qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask;
  653. /* Check if the queue has overflowed */
  654. if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask)
  655. {
  656. /* clear the overflow status bit if it was set */
  657. IX_OSAL_WRITE_LONG(qUOStatRegAddr,
  658. (IX_OSAL_READ_LONG(qUOStatRegAddr) &
  659. ~overflowBitMask));
  660. *qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK;
  661. }
  662. /* Check if the queue has underflowed */
  663. if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask)
  664. {
  665. /* clear the underflow status bit if it was set */
  666. IX_OSAL_WRITE_LONG(qUOStatRegAddr,
  667. (IX_OSAL_READ_LONG(qUOStatRegAddr) &
  668. ~underflowBitMask));
  669. *qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK;
  670. }
  671. }
  672. else /* read status of a queue in the range 32-63 */
  673. {
  674. extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
  675. extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
  676. extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[];
  677. extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[];
  678. volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr;
  679. volatile UINT32 *qFullStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr;
  680. int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID;
  681. UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex];
  682. UINT32 qFullStatBitMask = ixQMgrAqmIfQueUppStat1BitMask[maskIndex];
  683. /* Reset the status bits */
  684. *qStatus = 0;
  685. /* Check if the queue is nearly empty */
  686. if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask)
  687. {
  688. *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
  689. }
  690. /* Check if the queue is full */
  691. if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask)
  692. {
  693. *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK;
  694. }
  695. }
  696. return IX_SUCCESS;
  697. }
  698. #endif /* def NO_INLINE_APIS */