IxQMgrQAccess.c 20 KB

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