aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c31
-rw-r--r--drivers/infiniband/hw/cxgb4/iw_cxgb4.h1
-rw-r--r--drivers/infiniband/hw/cxgb4/qp.c9
3 files changed, 26 insertions, 15 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 185452abf32c..f9b04bc7e602 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -996,7 +996,7 @@ static void close_complete_upcall(struct c4iw_ep *ep, int status)
996static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp) 996static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)
997{ 997{
998 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); 998 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
999 state_set(&ep->com, ABORTING); 999 __state_set(&ep->com, ABORTING);
1000 set_bit(ABORT_CONN, &ep->com.history); 1000 set_bit(ABORT_CONN, &ep->com.history);
1001 return send_abort(ep, skb, gfp); 1001 return send_abort(ep, skb, gfp);
1002} 1002}
@@ -1154,7 +1154,7 @@ static int update_rx_credits(struct c4iw_ep *ep, u32 credits)
1154 return credits; 1154 return credits;
1155} 1155}
1156 1156
1157static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) 1157static int process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
1158{ 1158{
1159 struct mpa_message *mpa; 1159 struct mpa_message *mpa;
1160 struct mpa_v2_conn_params *mpa_v2_params; 1160 struct mpa_v2_conn_params *mpa_v2_params;
@@ -1164,6 +1164,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
1164 struct c4iw_qp_attributes attrs; 1164 struct c4iw_qp_attributes attrs;
1165 enum c4iw_qp_attr_mask mask; 1165 enum c4iw_qp_attr_mask mask;
1166 int err; 1166 int err;
1167 int disconnect = 0;
1167 1168
1168 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); 1169 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1169 1170
@@ -1173,7 +1174,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
1173 * will abort the connection. 1174 * will abort the connection.
1174 */ 1175 */
1175 if (stop_ep_timer(ep)) 1176 if (stop_ep_timer(ep))
1176 return; 1177 return 0;
1177 1178
1178 /* 1179 /*
1179 * If we get more than the supported amount of private data 1180 * If we get more than the supported amount of private data
@@ -1195,7 +1196,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
1195 * if we don't even have the mpa message, then bail. 1196 * if we don't even have the mpa message, then bail.
1196 */ 1197 */
1197 if (ep->mpa_pkt_len < sizeof(*mpa)) 1198 if (ep->mpa_pkt_len < sizeof(*mpa))
1198 return; 1199 return 0;
1199 mpa = (struct mpa_message *) ep->mpa_pkt; 1200 mpa = (struct mpa_message *) ep->mpa_pkt;
1200 1201
1201 /* Validate MPA header. */ 1202 /* Validate MPA header. */
@@ -1235,7 +1236,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
1235 * We'll continue process when more data arrives. 1236 * We'll continue process when more data arrives.
1236 */ 1237 */
1237 if (ep->mpa_pkt_len < (sizeof(*mpa) + plen)) 1238 if (ep->mpa_pkt_len < (sizeof(*mpa) + plen))
1238 return; 1239 return 0;
1239 1240
1240 if (mpa->flags & MPA_REJECT) { 1241 if (mpa->flags & MPA_REJECT) {
1241 err = -ECONNREFUSED; 1242 err = -ECONNREFUSED;
@@ -1337,9 +1338,11 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
1337 attrs.layer_etype = LAYER_MPA | DDP_LLP; 1338 attrs.layer_etype = LAYER_MPA | DDP_LLP;
1338 attrs.ecode = MPA_NOMATCH_RTR; 1339 attrs.ecode = MPA_NOMATCH_RTR;
1339 attrs.next_state = C4IW_QP_STATE_TERMINATE; 1340 attrs.next_state = C4IW_QP_STATE_TERMINATE;
1341 attrs.send_term = 1;
1340 err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, 1342 err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
1341 C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); 1343 C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
1342 err = -ENOMEM; 1344 err = -ENOMEM;
1345 disconnect = 1;
1343 goto out; 1346 goto out;
1344 } 1347 }
1345 1348
@@ -1355,9 +1358,11 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
1355 attrs.layer_etype = LAYER_MPA | DDP_LLP; 1358 attrs.layer_etype = LAYER_MPA | DDP_LLP;
1356 attrs.ecode = MPA_INSUFF_IRD; 1359 attrs.ecode = MPA_INSUFF_IRD;
1357 attrs.next_state = C4IW_QP_STATE_TERMINATE; 1360 attrs.next_state = C4IW_QP_STATE_TERMINATE;
1361 attrs.send_term = 1;
1358 err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, 1362 err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
1359 C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); 1363 C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
1360 err = -ENOMEM; 1364 err = -ENOMEM;
1365 disconnect = 1;
1361 goto out; 1366 goto out;
1362 } 1367 }
1363 goto out; 1368 goto out;
@@ -1366,7 +1371,7 @@ err:
1366 send_abort(ep, skb, GFP_KERNEL); 1371 send_abort(ep, skb, GFP_KERNEL);
1367out: 1372out:
1368 connect_reply_upcall(ep, err); 1373 connect_reply_upcall(ep, err);
1369 return; 1374 return disconnect;
1370} 1375}
1371 1376
1372static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb) 1377static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
@@ -1524,6 +1529,7 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb)
1524 unsigned int tid = GET_TID(hdr); 1529 unsigned int tid = GET_TID(hdr);
1525 struct tid_info *t = dev->rdev.lldi.tids; 1530 struct tid_info *t = dev->rdev.lldi.tids;
1526 __u8 status = hdr->status; 1531 __u8 status = hdr->status;
1532 int disconnect = 0;
1527 1533
1528 ep = lookup_tid(t, tid); 1534 ep = lookup_tid(t, tid);
1529 if (!ep) 1535 if (!ep)
@@ -1539,7 +1545,7 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb)
1539 switch (ep->com.state) { 1545 switch (ep->com.state) {
1540 case MPA_REQ_SENT: 1546 case MPA_REQ_SENT:
1541 ep->rcv_seq += dlen; 1547 ep->rcv_seq += dlen;
1542 process_mpa_reply(ep, skb); 1548 disconnect = process_mpa_reply(ep, skb);
1543 break; 1549 break;
1544 case MPA_REQ_WAIT: 1550 case MPA_REQ_WAIT:
1545 ep->rcv_seq += dlen; 1551 ep->rcv_seq += dlen;
@@ -1555,13 +1561,16 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb)
1555 ep->com.state, ep->hwtid, status); 1561 ep->com.state, ep->hwtid, status);
1556 attrs.next_state = C4IW_QP_STATE_TERMINATE; 1562 attrs.next_state = C4IW_QP_STATE_TERMINATE;
1557 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, 1563 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
1558 C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); 1564 C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
1565 disconnect = 1;
1559 break; 1566 break;
1560 } 1567 }
1561 default: 1568 default:
1562 break; 1569 break;
1563 } 1570 }
1564 mutex_unlock(&ep->com.mutex); 1571 mutex_unlock(&ep->com.mutex);
1572 if (disconnect)
1573 c4iw_ep_disconnect(ep, 0, GFP_KERNEL);
1565 return 0; 1574 return 0;
1566} 1575}
1567 1576
@@ -3482,9 +3491,9 @@ static void process_timeout(struct c4iw_ep *ep)
3482 __func__, ep, ep->hwtid, ep->com.state); 3491 __func__, ep, ep->hwtid, ep->com.state);
3483 abort = 0; 3492 abort = 0;
3484 } 3493 }
3485 mutex_unlock(&ep->com.mutex);
3486 if (abort) 3494 if (abort)
3487 abort_connection(ep, NULL, GFP_KERNEL); 3495 abort_connection(ep, NULL, GFP_KERNEL);
3496 mutex_unlock(&ep->com.mutex);
3488 c4iw_put_ep(&ep->com); 3497 c4iw_put_ep(&ep->com);
3489} 3498}
3490 3499
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index 7b8c5806a09d..7474b490760a 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -435,6 +435,7 @@ struct c4iw_qp_attributes {
435 u8 ecode; 435 u8 ecode;
436 u16 sq_db_inc; 436 u16 sq_db_inc;
437 u16 rq_db_inc; 437 u16 rq_db_inc;
438 u8 send_term;
438}; 439};
439 440
440struct c4iw_qp { 441struct c4iw_qp {
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index 7b5114cb486f..f18ef34e8184 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -1388,11 +1388,12 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
1388 qhp->attr.layer_etype = attrs->layer_etype; 1388 qhp->attr.layer_etype = attrs->layer_etype;
1389 qhp->attr.ecode = attrs->ecode; 1389 qhp->attr.ecode = attrs->ecode;
1390 ep = qhp->ep; 1390 ep = qhp->ep;
1391 disconnect = 1; 1391 if (!internal) {
1392 c4iw_get_ep(&qhp->ep->com); 1392 c4iw_get_ep(&qhp->ep->com);
1393 if (!internal)
1394 terminate = 1; 1393 terminate = 1;
1395 else { 1394 disconnect = 1;
1395 } else {
1396 terminate = qhp->attr.send_term;
1396 ret = rdma_fini(rhp, qhp, ep); 1397 ret = rdma_fini(rhp, qhp, ep);
1397 if (ret) 1398 if (ret)
1398 goto err; 1399 goto err;