diff options
| author | Kumar Sanghvi <kumaras@chelsio.com> | 2011-09-25 10:47:44 -0400 |
|---|---|---|
| committer | Roland Dreier <roland@purestorage.com> | 2011-10-06 12:39:24 -0400 |
| commit | d2fe99e86bb2ccbb87df20b0136d5983b6a4cc09 (patch) | |
| tree | 2978723397dc5f036f30a1dcf316854310001b62 | |
| parent | 56da00fc92e6f227874bba36f127ffc8847ee1f8 (diff) | |
RDMA/cxgb4: Add support for MPAv2 Enhanced RDMA Negotiation
This patch adds support for Enhanced RDMA Connection Establishment
(draft-ietf-storm-mpa-peer-connect-06), aka MPAv2. Details of draft
can be obtained from:
<http://www.ietf.org/id/draft-ietf-storm-mpa-peer-connect-06.txt>
The patch updates the following functions for initiator perspective:
- send_mpa_request
- process_mpa_reply
- post_terminate for TERM error codes
- destroy_qp for TERM related change
- adds layer/etype/ecode to c4iw_qp_attrs for sending with TERM
- peer_abort for retrying connection attempt with MPA_v1 message
- added c4iw_reconnect function
The patch updates the following functions for responder perspective:
- process_mpa_request
- send_mpa_reply
- c4iw_accept_cr
- passes ird/ord to upper layers
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 469 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 22 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/qp.c | 14 |
3 files changed, 466 insertions, 39 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 77f769d9227d..b36cdac9c558 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
| @@ -103,7 +103,8 @@ MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " | |||
| 103 | static int mpa_rev = 1; | 103 | static int mpa_rev = 1; |
| 104 | module_param(mpa_rev, int, 0644); | 104 | module_param(mpa_rev, int, 0644); |
| 105 | MODULE_PARM_DESC(mpa_rev, "MPA Revision, 0 supports amso1100, " | 105 | MODULE_PARM_DESC(mpa_rev, "MPA Revision, 0 supports amso1100, " |
| 106 | "1 is spec compliant. (default=1)"); | 106 | "1 is RFC0544 spec compliant, 2 is IETF MPA Peer Connect Draft" |
| 107 | " compliant (default=1)"); | ||
| 107 | 108 | ||
| 108 | static int markers_enabled; | 109 | static int markers_enabled; |
| 109 | module_param(markers_enabled, int, 0644); | 110 | module_param(markers_enabled, int, 0644); |
| @@ -497,17 +498,21 @@ static int send_connect(struct c4iw_ep *ep) | |||
| 497 | return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); | 498 | return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); |
| 498 | } | 499 | } |
| 499 | 500 | ||
| 500 | static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb) | 501 | static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb, |
| 502 | u8 mpa_rev_to_use) | ||
| 501 | { | 503 | { |
| 502 | int mpalen, wrlen; | 504 | int mpalen, wrlen; |
| 503 | struct fw_ofld_tx_data_wr *req; | 505 | struct fw_ofld_tx_data_wr *req; |
| 504 | struct mpa_message *mpa; | 506 | struct mpa_message *mpa; |
| 507 | struct mpa_v2_conn_params mpa_v2_params; | ||
| 505 | 508 | ||
| 506 | PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen); | 509 | PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen); |
| 507 | 510 | ||
| 508 | BUG_ON(skb_cloned(skb)); | 511 | BUG_ON(skb_cloned(skb)); |
| 509 | 512 | ||
| 510 | mpalen = sizeof(*mpa) + ep->plen; | 513 | mpalen = sizeof(*mpa) + ep->plen; |
| 514 | if (mpa_rev_to_use == 2) | ||
| 515 | mpalen += sizeof(struct mpa_v2_conn_params); | ||
| 511 | wrlen = roundup(mpalen + sizeof *req, 16); | 516 | wrlen = roundup(mpalen + sizeof *req, 16); |
| 512 | skb = get_skb(skb, wrlen, GFP_KERNEL); | 517 | skb = get_skb(skb, wrlen, GFP_KERNEL); |
| 513 | if (!skb) { | 518 | if (!skb) { |
| @@ -533,12 +538,39 @@ static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb) | |||
| 533 | mpa = (struct mpa_message *)(req + 1); | 538 | mpa = (struct mpa_message *)(req + 1); |
| 534 | memcpy(mpa->key, MPA_KEY_REQ, sizeof(mpa->key)); | 539 | memcpy(mpa->key, MPA_KEY_REQ, sizeof(mpa->key)); |
| 535 | mpa->flags = (crc_enabled ? MPA_CRC : 0) | | 540 | mpa->flags = (crc_enabled ? MPA_CRC : 0) | |
| 536 | (markers_enabled ? MPA_MARKERS : 0); | 541 | (markers_enabled ? MPA_MARKERS : 0) | |
| 542 | (mpa_rev_to_use == 2 ? MPA_ENHANCED_RDMA_CONN : 0); | ||
| 537 | mpa->private_data_size = htons(ep->plen); | 543 | mpa->private_data_size = htons(ep->plen); |
| 538 | mpa->revision = mpa_rev; | 544 | mpa->revision = mpa_rev_to_use; |
| 545 | if (mpa_rev_to_use == 1) | ||
| 546 | ep->tried_with_mpa_v1 = 1; | ||
| 547 | |||
| 548 | if (mpa_rev_to_use == 2) { | ||
| 549 | mpa->private_data_size += | ||
| 550 | htons(sizeof(struct mpa_v2_conn_params)); | ||
| 551 | mpa_v2_params.ird = htons((u16)ep->ird); | ||
| 552 | mpa_v2_params.ord = htons((u16)ep->ord); | ||
| 553 | |||
| 554 | if (peer2peer) { | ||
| 555 | mpa_v2_params.ird |= htons(MPA_V2_PEER2PEER_MODEL); | ||
| 556 | if (p2p_type == FW_RI_INIT_P2PTYPE_RDMA_WRITE) | ||
| 557 | mpa_v2_params.ord |= | ||
| 558 | htons(MPA_V2_RDMA_WRITE_RTR); | ||
| 559 | else if (p2p_type == FW_RI_INIT_P2PTYPE_READ_REQ) | ||
| 560 | mpa_v2_params.ord |= | ||
| 561 | htons(MPA_V2_RDMA_READ_RTR); | ||
| 562 | } | ||
| 563 | memcpy(mpa->private_data, &mpa_v2_params, | ||
| 564 | sizeof(struct mpa_v2_conn_params)); | ||
| 539 | 565 | ||
| 540 | if (ep->plen) | 566 | if (ep->plen) |
| 541 | memcpy(mpa->private_data, ep->mpa_pkt + sizeof(*mpa), ep->plen); | 567 | memcpy(mpa->private_data + |
| 568 | sizeof(struct mpa_v2_conn_params), | ||
| 569 | ep->mpa_pkt + sizeof(*mpa), ep->plen); | ||
| 570 | } else | ||
| 571 | if (ep->plen) | ||
| 572 | memcpy(mpa->private_data, | ||
| 573 | ep->mpa_pkt + sizeof(*mpa), ep->plen); | ||
| 542 | 574 | ||
| 543 | /* | 575 | /* |
| 544 | * Reference the mpa skb. This ensures the data area | 576 | * Reference the mpa skb. This ensures the data area |
| @@ -562,10 +594,13 @@ static int send_mpa_reject(struct c4iw_ep *ep, const void *pdata, u8 plen) | |||
| 562 | struct fw_ofld_tx_data_wr *req; | 594 | struct fw_ofld_tx_data_wr *req; |
| 563 | struct mpa_message *mpa; | 595 | struct mpa_message *mpa; |
| 564 | struct sk_buff *skb; | 596 | struct sk_buff *skb; |
| 597 | struct mpa_v2_conn_params mpa_v2_params; | ||
| 565 | 598 | ||
| 566 | PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen); | 599 | PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen); |
| 567 | 600 | ||
| 568 | mpalen = sizeof(*mpa) + plen; | 601 | mpalen = sizeof(*mpa) + plen; |
| 602 | if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) | ||
| 603 | mpalen += sizeof(struct mpa_v2_conn_params); | ||
| 569 | wrlen = roundup(mpalen + sizeof *req, 16); | 604 | wrlen = roundup(mpalen + sizeof *req, 16); |
| 570 | 605 | ||
| 571 | skb = get_skb(NULL, wrlen, GFP_KERNEL); | 606 | skb = get_skb(NULL, wrlen, GFP_KERNEL); |
| @@ -595,8 +630,29 @@ static int send_mpa_reject(struct c4iw_ep *ep, const void *pdata, u8 plen) | |||
| 595 | mpa->flags = MPA_REJECT; | 630 | mpa->flags = MPA_REJECT; |
| 596 | mpa->revision = mpa_rev; | 631 | mpa->revision = mpa_rev; |
| 597 | mpa->private_data_size = htons(plen); | 632 | mpa->private_data_size = htons(plen); |
| 598 | if (plen) | 633 | |
| 599 | memcpy(mpa->private_data, pdata, plen); | 634 | if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) { |
| 635 | mpa->flags |= MPA_ENHANCED_RDMA_CONN; | ||
| 636 | mpa->private_data_size += | ||
| 637 | htons(sizeof(struct mpa_v2_conn_params)); | ||
| 638 | mpa_v2_params.ird = htons(((u16)ep->ird) | | ||
| 639 | (peer2peer ? MPA_V2_PEER2PEER_MODEL : | ||
| 640 | 0)); | ||
| 641 | mpa_v2_params.ord = htons(((u16)ep->ord) | (peer2peer ? | ||
| 642 | (p2p_type == | ||
| 643 | FW_RI_INIT_P2PTYPE_RDMA_WRITE ? | ||
| 644 | MPA_V2_RDMA_WRITE_RTR : p2p_type == | ||
| 645 | FW_RI_INIT_P2PTYPE_READ_REQ ? | ||
| 646 | MPA_V2_RDMA_READ_RTR : 0) : 0)); | ||
| 647 | memcpy(mpa->private_data, &mpa_v2_params, | ||
| 648 | sizeof(struct mpa_v2_conn_params)); | ||
| 649 | |||
| 650 | if (ep->plen) | ||
| 651 | memcpy(mpa->private_data + | ||
| 652 | sizeof(struct mpa_v2_conn_params), pdata, plen); | ||
| 653 | } else | ||
| 654 | if (plen) | ||
| 655 | memcpy(mpa->private_data, pdata, plen); | ||
| 600 | 656 | ||
| 601 | /* | 657 | /* |
| 602 | * Reference the mpa skb again. This ensures the data area | 658 | * Reference the mpa skb again. This ensures the data area |
| @@ -617,10 +673,13 @@ static int send_mpa_reply(struct c4iw_ep *ep, const void *pdata, u8 plen) | |||
| 617 | struct fw_ofld_tx_data_wr *req; | 673 | struct fw_ofld_tx_data_wr *req; |
| 618 | struct mpa_message *mpa; | 674 | struct mpa_message *mpa; |
| 619 | struct sk_buff *skb; | 675 | struct sk_buff *skb; |
| 676 | struct mpa_v2_conn_params mpa_v2_params; | ||
| 620 | 677 | ||
| 621 | PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen); | 678 | PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen); |
| 622 | 679 | ||
| 623 | mpalen = sizeof(*mpa) + plen; | 680 | mpalen = sizeof(*mpa) + plen; |
| 681 | if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) | ||
| 682 | mpalen += sizeof(struct mpa_v2_conn_params); | ||
| 624 | wrlen = roundup(mpalen + sizeof *req, 16); | 683 | wrlen = roundup(mpalen + sizeof *req, 16); |
| 625 | 684 | ||
| 626 | skb = get_skb(NULL, wrlen, GFP_KERNEL); | 685 | skb = get_skb(NULL, wrlen, GFP_KERNEL); |
| @@ -649,10 +708,36 @@ static int send_mpa_reply(struct c4iw_ep *ep, const void *pdata, u8 plen) | |||
| 649 | memcpy(mpa->key, MPA_KEY_REP, sizeof(mpa->key)); | 708 | memcpy(mpa->key, MPA_KEY_REP, sizeof(mpa->key)); |
| 650 | mpa->flags = (ep->mpa_attr.crc_enabled ? MPA_CRC : 0) | | 709 | mpa->flags = (ep->mpa_attr.crc_enabled ? MPA_CRC : 0) | |
| 651 | (markers_enabled ? MPA_MARKERS : 0); | 710 | (markers_enabled ? MPA_MARKERS : 0); |
| 652 | mpa->revision = mpa_rev; | 711 | mpa->revision = ep->mpa_attr.version; |
| 653 | mpa->private_data_size = htons(plen); | 712 | mpa->private_data_size = htons(plen); |
| 654 | if (plen) | 713 | |
| 655 | memcpy(mpa->private_data, pdata, plen); | 714 | if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) { |
| 715 | mpa->flags |= MPA_ENHANCED_RDMA_CONN; | ||
| 716 | mpa->private_data_size += | ||
| 717 | htons(sizeof(struct mpa_v2_conn_params)); | ||
