diff options
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 31 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 1 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/qp.c | 9 |
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) | |||
| 996 | static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp) | 996 | static 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 | ||
| 1157 | static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) | 1157 | static 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); |
| 1367 | out: | 1372 | out: |
| 1368 | connect_reply_upcall(ep, err); | 1373 | connect_reply_upcall(ep, err); |
| 1369 | return; | 1374 | return disconnect; |
| 1370 | } | 1375 | } |
| 1371 | 1376 | ||
| 1372 | static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb) | 1377 | static 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 | ||
| 440 | struct c4iw_qp { | 441 | struct 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; |
