iwch_cq.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
  3. * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  4. *
  5. * This software is available to you under a choice of one of two
  6. * licenses. You may choose to be licensed under the terms of the GNU
  7. * General Public License (GPL) Version 2, available from the file
  8. * COPYING in the main directory of this source tree, or the
  9. * OpenIB.org BSD license below:
  10. *
  11. * Redistribution and use in source and binary forms, with or
  12. * without modification, are permitted provided that the following
  13. * conditions are met:
  14. *
  15. * - Redistributions of source code must retain the above
  16. * copyright notice, this list of conditions and the following
  17. * disclaimer.
  18. *
  19. * - Redistributions in binary form must reproduce the above
  20. * copyright notice, this list of conditions and the following
  21. * disclaimer in the documentation and/or other materials
  22. * provided with the distribution.
  23. *
  24. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  28. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  29. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  30. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  31. * SOFTWARE.
  32. */
  33. #include "iwch_provider.h"
  34. #include "iwch.h"
  35. /*
  36. * Get one cq entry from cxio and map it to openib.
  37. *
  38. * Returns:
  39. * 0 EMPTY;
  40. * 1 cqe returned
  41. * -EAGAIN caller must try again
  42. * any other -errno fatal error
  43. */
  44. static int iwch_poll_cq_one(struct iwch_dev *rhp, struct iwch_cq *chp,
  45. struct ib_wc *wc)
  46. {
  47. struct iwch_qp *qhp = NULL;
  48. struct t3_cqe cqe, *rd_cqe;
  49. struct t3_wq *wq;
  50. u32 credit = 0;
  51. u8 cqe_flushed;
  52. u64 cookie;
  53. int ret = 1;
  54. rd_cqe = cxio_next_cqe(&chp->cq);
  55. if (!rd_cqe)
  56. return 0;
  57. qhp = get_qhp(rhp, CQE_QPID(*rd_cqe));
  58. if (!qhp)
  59. wq = NULL;
  60. else {
  61. spin_lock(&qhp->lock);
  62. wq = &(qhp->wq);
  63. }
  64. ret = cxio_poll_cq(wq, &(chp->cq), &cqe, &cqe_flushed, &cookie,
  65. &credit);
  66. if (t3a_device(chp->rhp) && credit) {
  67. PDBG("%s updating %d cq credits on id %d\n", __FUNCTION__,
  68. credit, chp->cq.cqid);
  69. cxio_hal_cq_op(&rhp->rdev, &chp->cq, CQ_CREDIT_UPDATE, credit);
  70. }
  71. if (ret) {
  72. ret = -EAGAIN;
  73. goto out;
  74. }
  75. ret = 1;
  76. wc->wr_id = cookie;
  77. wc->qp = &qhp->ibqp;
  78. wc->vendor_err = CQE_STATUS(cqe);
  79. PDBG("%s qpid 0x%x type %d opcode %d status 0x%x wrid hi 0x%x "
  80. "lo 0x%x cookie 0x%llx\n", __FUNCTION__,
  81. CQE_QPID(cqe), CQE_TYPE(cqe),
  82. CQE_OPCODE(cqe), CQE_STATUS(cqe), CQE_WRID_HI(cqe),
  83. CQE_WRID_LOW(cqe), (unsigned long long) cookie);
  84. if (CQE_TYPE(cqe) == 0) {
  85. if (!CQE_STATUS(cqe))
  86. wc->byte_len = CQE_LEN(cqe);
  87. else
  88. wc->byte_len = 0;
  89. wc->opcode = IB_WC_RECV;
  90. } else {
  91. switch (CQE_OPCODE(cqe)) {
  92. case T3_RDMA_WRITE:
  93. wc->opcode = IB_WC_RDMA_WRITE;
  94. break;
  95. case T3_READ_REQ:
  96. wc->opcode = IB_WC_RDMA_READ;
  97. wc->byte_len = CQE_LEN(cqe);
  98. break;
  99. case T3_SEND:
  100. case T3_SEND_WITH_SE:
  101. wc->opcode = IB_WC_SEND;
  102. break;
  103. case T3_BIND_MW:
  104. wc->opcode = IB_WC_BIND_MW;
  105. break;
  106. /* these aren't supported yet */
  107. case T3_SEND_WITH_INV:
  108. case T3_SEND_WITH_SE_INV:
  109. case T3_LOCAL_INV:
  110. case T3_FAST_REGISTER:
  111. default:
  112. printk(KERN_ERR MOD "Unexpected opcode %d "
  113. "in the CQE received for QPID=0x%0x\n",
  114. CQE_OPCODE(cqe), CQE_QPID(cqe));
  115. ret = -EINVAL;
  116. goto out;
  117. }
  118. }
  119. if (cqe_flushed)
  120. wc->status = IB_WC_WR_FLUSH_ERR;
  121. else {
  122. switch (CQE_STATUS(cqe)) {
  123. case TPT_ERR_SUCCESS:
  124. wc->status = IB_WC_SUCCESS;
  125. break;
  126. case TPT_ERR_STAG:
  127. wc->status = IB_WC_LOC_ACCESS_ERR;
  128. break;
  129. case TPT_ERR_PDID:
  130. wc->status = IB_WC_LOC_PROT_ERR;
  131. break;
  132. case TPT_ERR_QPID:
  133. case TPT_ERR_ACCESS:
  134. wc->status = IB_WC_LOC_ACCESS_ERR;
  135. break;
  136. case TPT_ERR_WRAP:
  137. wc->status = IB_WC_GENERAL_ERR;
  138. break;
  139. case TPT_ERR_BOUND:
  140. wc->status = IB_WC_LOC_LEN_ERR;
  141. break;
  142. case TPT_ERR_INVALIDATE_SHARED_MR:
  143. case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND:
  144. wc->status = IB_WC_MW_BIND_ERR;
  145. break;
  146. case TPT_ERR_CRC:
  147. case TPT_ERR_MARKER:
  148. case TPT_ERR_PDU_LEN_ERR:
  149. case TPT_ERR_OUT_OF_RQE:
  150. case TPT_ERR_DDP_VERSION:
  151. case TPT_ERR_RDMA_VERSION:
  152. case TPT_ERR_DDP_QUEUE_NUM:
  153. case TPT_ERR_MSN:
  154. case TPT_ERR_TBIT:
  155. case TPT_ERR_MO:
  156. case TPT_ERR_MSN_RANGE:
  157. case TPT_ERR_IRD_OVERFLOW:
  158. case TPT_ERR_OPCODE:
  159. wc->status = IB_WC_FATAL_ERR;
  160. break;
  161. case TPT_ERR_SWFLUSH:
  162. wc->status = IB_WC_WR_FLUSH_ERR;
  163. break;
  164. default:
  165. printk(KERN_ERR MOD "Unexpected cqe_status 0x%x for "
  166. "QPID=0x%0x\n", CQE_STATUS(cqe), CQE_QPID(cqe));
  167. ret = -EINVAL;
  168. }
  169. }
  170. out:
  171. if (wq)
  172. spin_unlock(&qhp->lock);
  173. return ret;
  174. }
  175. int iwch_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
  176. {
  177. struct iwch_dev *rhp;
  178. struct iwch_cq *chp;
  179. unsigned long flags;
  180. int npolled;
  181. int err = 0;
  182. chp = to_iwch_cq(ibcq);
  183. rhp = chp->rhp;
  184. spin_lock_irqsave(&chp->lock, flags);
  185. for (npolled = 0; npolled < num_entries; ++npolled) {
  186. #ifdef DEBUG
  187. int i=0;
  188. #endif
  189. /*
  190. * Because T3 can post CQEs that are _not_ associated
  191. * with a WR, we might have to poll again after removing
  192. * one of these.
  193. */
  194. do {
  195. err = iwch_poll_cq_one(rhp, chp, wc + npolled);
  196. #ifdef DEBUG
  197. BUG_ON(++i > 1000);
  198. #endif
  199. } while (err == -EAGAIN);
  200. if (err <= 0)
  201. break;
  202. }
  203. spin_unlock_irqrestore(&chp->lock, flags);
  204. if (err < 0)
  205. return err;
  206. else {
  207. return npolled;
  208. }
  209. }