RDMA/cxgb4: Handle CPL_RDMA_TERMINATE messages
authorSteve Wise <swise@opengridcomputing.com>
Fri, 10 Sep 2010 16:15:09 +0000 (11:15 -0500)
committerRoland Dreier <rolandd@cisco.com>
Tue, 28 Sep 2010 17:46:32 +0000 (10:46 -0700)
T4 FW sends up CPL_RDMA_TERMINATE to indicate a peer TERM.  This
triggers the QP moving to TERMINATE state.

Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/cxgb4/ev.c
drivers/infiniband/hw/cxgb4/qp.c

index 2c60266..2f0a26c 100644 (file)
@@ -1725,23 +1725,24 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
 
 static int terminate(struct c4iw_dev *dev, struct sk_buff *skb)
 {
-       struct c4iw_ep *ep;
-       struct cpl_rdma_terminate *term = cplhdr(skb);
+       struct cpl_rdma_terminate *rpl = cplhdr(skb);
        struct tid_info *t = dev->rdev.lldi.tids;
-       unsigned int tid = GET_TID(term);
+       unsigned int tid = GET_TID(rpl);
+       struct c4iw_ep *ep;
+       struct c4iw_qp_attributes attrs;
 
        ep = lookup_tid(t, tid);
+       BUG_ON(!ep);
 
-       if (state_read(&ep->com) != FPDU_MODE)
-               return 0;
+       if (ep->com.qp) {
+               printk(KERN_WARNING MOD "TERM received tid %u qpid %u\n", tid,
+                      ep->com.qp->wq.sq.qid);
+               attrs.next_state = C4IW_QP_STATE_TERMINATE;
+               c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
+                              C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
+       } else
+               printk(KERN_WARNING MOD "TERM received tid %u no qp\n", tid);
 
-       PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
-       skb_pull(skb, sizeof *term);
-       PDBG("%s saving %d bytes of term msg\n", __func__, skb->len);
-       skb_copy_from_linear_data(skb, ep->com.qp->attr.terminate_buffer,
-                                 skb->len);
-       ep->com.qp->attr.terminate_msg_len = skb->len;
-       ep->com.qp->attr.is_terminate_local = 0;
        return 0;
 }
 
index 491e76a..c13041a 100644 (file)
@@ -60,7 +60,7 @@ static void post_qp_event(struct c4iw_dev *dev, struct c4iw_cq *chp,
        if (qhp->attr.state == C4IW_QP_STATE_RTS) {
                attrs.next_state = C4IW_QP_STATE_TERMINATE;
                c4iw_modify_qp(qhp->rhp, qhp, C4IW_QP_ATTR_NEXT_STATE,
-                              &attrs, 1);
+                              &attrs, 0);
        }
 
        event.event = ib_event;
index bdbf54d..1199d1b 100644 (file)
@@ -1238,7 +1238,8 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
                                t4_set_wq_in_error(&qhp->wq);
                        ep = qhp->ep;
                        c4iw_get_ep(&ep->com);
-                       terminate = 1;
+                       if (!internal)
+                               terminate = 1;
                        disconnect = 1;
                        break;
                case C4IW_QP_STATE_ERROR: