aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorSteve Wise <swise@opengridcomputing.com>2009-02-10 19:38:57 -0500
committerRoland Dreier <rolandd@cisco.com>2009-02-10 19:38:57 -0500
commit42fb61f02f9bdc476c7a76d3cce0400d989f44c5 (patch)
tree1b65628292881e77e81f6e1bdc6aed64b38f0646 /drivers/infiniband/hw
parent900f4c16c338f742b80f3aa500e12ceb017e86af (diff)
RDMA/cxgb3: Connection termination fixes
The poll and flush code needs to handle all send opcodes: SEND, SEND_WITH_SE, SEND_WITH_INV, and SEND_WITH_SE_INV. Ignore TERM indications if the connection already gone. Ignore HW receive completions if the RQ is empty. Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c13
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_wr.h6
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c3
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_ev.c5
4 files changed, 20 insertions, 7 deletions
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index 4dcf08b3fd83..c2740e790f73 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -450,7 +450,7 @@ static int cqe_completes_wr(struct t3_cqe *cqe, struct t3_wq *wq)
450 if ((CQE_OPCODE(*cqe) == T3_READ_RESP) && SQ_TYPE(*cqe)) 450 if ((CQE_OPCODE(*cqe) == T3_READ_RESP) && SQ_TYPE(*cqe))
451 return 0; 451 return 0;
452 452
453 if ((CQE_OPCODE(*cqe) == T3_SEND) && RQ_TYPE(*cqe) && 453 if (CQE_SEND_OPCODE(*cqe) && RQ_TYPE(*cqe) &&
454 Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) 454 Q_EMPTY(wq->rq_rptr, wq->rq_wptr))
455 return 0; 455 return 0;
456 456
@@ -1204,11 +1204,12 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
1204 } 1204 }
1205 1205
1206 /* incoming SEND with no receive posted failures */ 1206 /* incoming SEND with no receive posted failures */
1207 if ((CQE_OPCODE(*hw_cqe) == T3_SEND) && RQ_TYPE(*hw_cqe) && 1207 if (CQE_SEND_OPCODE(*hw_cqe) && RQ_TYPE(*hw_cqe) &&
1208 Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) { 1208 Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) {
1209 ret = -1; 1209 ret = -1;
1210 goto skip_cqe; 1210 goto skip_cqe;
1211 } 1211 }
1212 BUG_ON((*cqe_flushed == 0) && !SW_CQE(*hw_cqe));
1212 goto proc_cqe; 1213 goto proc_cqe;
1213 } 1214 }
1214 1215
@@ -1223,6 +1224,13 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
1223 * then we complete this with TPT_ERR_MSN and mark the wq in 1224 * then we complete this with TPT_ERR_MSN and mark the wq in
1224 * error. 1225 * error.
1225 */ 1226 */
1227
1228 if (Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) {
1229 wq->error = 1;
1230 ret = -1;
1231 goto skip_cqe;
1232 }
1233
1226 if (unlikely((CQE_WRID_MSN(*hw_cqe) != (wq->rq_rptr + 1)))) { 1234 if (unlikely((CQE_WRID_MSN(*hw_cqe) != (wq->rq_rptr + 1)))) {
1227 wq->error = 1; 1235 wq->error = 1;
1228 hw_cqe->header |= htonl(V_CQE_STATUS(TPT_ERR_MSN)); 1236 hw_cqe->header |= htonl(V_CQE_STATUS(TPT_ERR_MSN));
@@ -1277,6 +1285,7 @@ proc_cqe:
1277 cxio_hal_pblpool_free(wq->rdev, 1285 cxio_hal_pblpool_free(wq->rdev,
1278 wq->rq[Q_PTR2IDX(wq->rq_rptr, 1286 wq->rq[Q_PTR2IDX(wq->rq_rptr,
1279 wq->rq_size_log2)].pbl_addr, T3_STAG0_PBL_SIZE); 1287 wq->rq_size_log2)].pbl_addr, T3_STAG0_PBL_SIZE);
1288 BUG_ON(Q_EMPTY(wq->rq_rptr, wq->rq_wptr));
1280 wq->rq_rptr++; 1289 wq->rq_rptr++;
1281 } 1290 }
1282 1291
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h
index 04618f7bfbb3..ff9be1a13106 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_wr.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h
@@ -604,6 +604,12 @@ struct t3_cqe {
604#define CQE_STATUS(x) (G_CQE_STATUS(be32_to_cpu((x).header))) 604#define CQE_STATUS(x) (G_CQE_STATUS(be32_to_cpu((x).header)))
605#define CQE_OPCODE(x) (G_CQE_OPCODE(be32_to_cpu((x).header))) 605#define CQE_OPCODE(x) (G_CQE_OPCODE(be32_to_cpu((x).header)))
606 606
607#define CQE_SEND_OPCODE(x)( \
608 (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND) || \
609 (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE) || \
610 (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_INV) || \
611 (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE_INV))
612
607#define CQE_LEN(x) (be32_to_cpu((x).len)) 613#define CQE_LEN(x) (be32_to_cpu((x).len))
608 614
609/* used for RQ completion processing */ 615/* used for RQ completion processing */
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 44e936e48a31..8699947aaf6c 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1678,6 +1678,9 @@ static int terminate(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1678{ 1678{
1679 struct iwch_ep *ep = ctx; 1679 struct iwch_ep *ep = ctx;
1680 1680
1681 if (state_read(&ep->com) != FPDU_MODE)
1682 return CPL_RET_BUF_DONE;
1683
1681 PDBG("%s ep %p\n", __func__, ep); 1684 PDBG("%s ep %p\n", __func__, ep);
1682 skb_pull(skb, sizeof(struct cpl_rdma_terminate)); 1685 skb_pull(skb, sizeof(struct cpl_rdma_terminate));
1683 PDBG("%s saving %d bytes of term msg\n", __func__, skb->len); 1686 PDBG("%s saving %d bytes of term msg\n", __func__, skb->len);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_ev.c b/drivers/infiniband/hw/cxgb3/iwch_ev.c
index 7b67a6771720..743c5d8b8806 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_ev.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_ev.c
@@ -179,11 +179,6 @@ void iwch_ev_dispatch(struct cxio_rdev *rdev_p, struct sk_buff *skb)
179 case TPT_ERR_BOUND: 179 case TPT_ERR_BOUND:
180 case TPT_ERR_INVALIDATE_SHARED_MR: 180 case TPT_ERR_INVALIDATE_SHARED_MR:
181 case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND: 181 case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND:
182 printk(KERN_ERR "%s - CQE Err qpid 0x%x opcode %d status 0x%x "
183 "type %d wrid.hi 0x%x wrid.lo 0x%x \n", __func__,
184 CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),
185 CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),
186 CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));
187 (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context); 182 (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);
188 post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1); 183 post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1);
189 break; 184 break;