iwch_cq.c 5.7 KB

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