RDMA/cxgb4: Handle CPL_RDMA_TERMINATE messages
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>
This commit is contained in:
committed by
Roland Dreier
parent
6ff0e343b3
commit
0e42c1f430
@@ -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)
|
static int terminate(struct c4iw_dev *dev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct c4iw_ep *ep;
|
struct cpl_rdma_terminate *rpl = cplhdr(skb);
|
||||||
struct cpl_rdma_terminate *term = cplhdr(skb);
|
|
||||||
struct tid_info *t = dev->rdev.lldi.tids;
|
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);
|
ep = lookup_tid(t, tid);
|
||||||
|
BUG_ON(!ep);
|
||||||
|
|
||||||
if (state_read(&ep->com) != FPDU_MODE)
|
if (ep->com.qp) {
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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) {
|
if (qhp->attr.state == C4IW_QP_STATE_RTS) {
|
||||||
attrs.next_state = C4IW_QP_STATE_TERMINATE;
|
attrs.next_state = C4IW_QP_STATE_TERMINATE;
|
||||||
c4iw_modify_qp(qhp->rhp, qhp, C4IW_QP_ATTR_NEXT_STATE,
|
c4iw_modify_qp(qhp->rhp, qhp, C4IW_QP_ATTR_NEXT_STATE,
|
||||||
&attrs, 1);
|
&attrs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
event.event = ib_event;
|
event.event = ib_event;
|
||||||
|
@@ -1238,7 +1238,8 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
|
|||||||
t4_set_wq_in_error(&qhp->wq);
|
t4_set_wq_in_error(&qhp->wq);
|
||||||
ep = qhp->ep;
|
ep = qhp->ep;
|
||||||
c4iw_get_ep(&ep->com);
|
c4iw_get_ep(&ep->com);
|
||||||
terminate = 1;
|
if (!internal)
|
||||||
|
terminate = 1;
|
||||||
disconnect = 1;
|
disconnect = 1;
|
||||||
break;
|
break;
|
||||||
case C4IW_QP_STATE_ERROR:
|
case C4IW_QP_STATE_ERROR:
|
||||||
|
Reference in New Issue
Block a user