aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKumar Sanghvi <kumaras@chelsio.com>2011-09-25 10:47:44 -0400
committerRoland Dreier <roland@purestorage.com>2011-10-06 12:39:24 -0400
commitd2fe99e86bb2ccbb87df20b0136d5983b6a4cc09 (patch)
tree2978723397dc5f036f30a1dcf316854310001b62
parent56da00fc92e6f227874bba36f127ffc8847ee1f8 (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.c469
-rw-r--r--drivers/infiniband/hw/cxgb4/iw_cxgb4.h22
-rw-r--r--drivers/infiniband/hw/cxgb4/qp.c14
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 "
103static int mpa_rev = 1; 103static int mpa_rev = 1;
104module_param(mpa_rev, int, 0644); 104module_param(mpa_rev, int, 0644);
105MODULE_PARM_DESC(mpa_rev, "MPA Revision, 0 supports amso1100, " 105MODULE_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
108static int markers_enabled; 109static int markers_enabled;
109module_param(markers_enabled, int, 0644); 110module_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
500static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb) 501static 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));