Commit d2fe99e8 authored by Kumar Sanghvi's avatar Kumar Sanghvi Committed by Roland Dreier

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: default avatarKumar Sanghvi <kumaras@chelsio.com>
Reviewed-by: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 56da00fc
This diff is collapsed.
...@@ -323,6 +323,7 @@ struct c4iw_mpa_attributes { ...@@ -323,6 +323,7 @@ struct c4iw_mpa_attributes {
u8 recv_marker_enabled; u8 recv_marker_enabled;
u8 xmit_marker_enabled; u8 xmit_marker_enabled;
u8 crc_enabled; u8 crc_enabled;
u8 enhanced_rdma_conn;
u8 version; u8 version;
u8 p2p_type; u8 p2p_type;
}; };
...@@ -349,6 +350,8 @@ struct c4iw_qp_attributes { ...@@ -349,6 +350,8 @@ struct c4iw_qp_attributes {
u8 is_terminate_local; u8 is_terminate_local;
struct c4iw_mpa_attributes mpa_attr; struct c4iw_mpa_attributes mpa_attr;
struct c4iw_ep *llp_stream_handle; struct c4iw_ep *llp_stream_handle;
u8 layer_etype;
u8 ecode;
}; };
struct c4iw_qp { struct c4iw_qp {
...@@ -501,11 +504,18 @@ enum c4iw_mmid_state { ...@@ -501,11 +504,18 @@ enum c4iw_mmid_state {
#define MPA_KEY_REP "MPA ID Rep Frame" #define MPA_KEY_REP "MPA ID Rep Frame"
#define MPA_MAX_PRIVATE_DATA 256 #define MPA_MAX_PRIVATE_DATA 256
#define MPA_ENHANCED_RDMA_CONN 0x10
#define MPA_REJECT 0x20 #define MPA_REJECT 0x20
#define MPA_CRC 0x40 #define MPA_CRC 0x40
#define MPA_MARKERS 0x80 #define MPA_MARKERS 0x80
#define MPA_FLAGS_MASK 0xE0 #define MPA_FLAGS_MASK 0xE0
#define MPA_V2_PEER2PEER_MODEL 0x8000
#define MPA_V2_ZERO_LEN_FPDU_RTR 0x4000
#define MPA_V2_RDMA_WRITE_RTR 0x8000
#define MPA_V2_RDMA_READ_RTR 0x4000
#define MPA_V2_IRD_ORD_MASK 0x3FFF
#define c4iw_put_ep(ep) { \ #define c4iw_put_ep(ep) { \
PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \
ep, atomic_read(&((ep)->kref.refcount))); \ ep, atomic_read(&((ep)->kref.refcount))); \
...@@ -528,6 +538,11 @@ struct mpa_message { ...@@ -528,6 +538,11 @@ struct mpa_message {
u8 private_data[0]; u8 private_data[0];
}; };
struct mpa_v2_conn_params {
__be16 ird;
__be16 ord;
};
struct terminate_message { struct terminate_message {
u8 layer_etype; u8 layer_etype;
u8 ecode; u8 ecode;
...@@ -580,7 +595,10 @@ enum c4iw_ddp_ecodes { ...@@ -580,7 +595,10 @@ enum c4iw_ddp_ecodes {
enum c4iw_mpa_ecodes { enum c4iw_mpa_ecodes {
MPA_CRC_ERR = 0x02, MPA_CRC_ERR = 0x02,
MPA_MARKER_ERR = 0x03 MPA_MARKER_ERR = 0x03,
MPA_LOCAL_CATA = 0x05,
MPA_INSUFF_IRD = 0x06,
MPA_NOMATCH_RTR = 0x07,
}; };
enum c4iw_ep_state { enum c4iw_ep_state {
...@@ -651,6 +669,8 @@ struct c4iw_ep { ...@@ -651,6 +669,8 @@ struct c4iw_ep {
u16 txq_idx; u16 txq_idx;
u16 ctrlq_idx; u16 ctrlq_idx;
u8 tos; u8 tos;
u8 retry_with_mpa_v1;
u8 tried_with_mpa_v1;
}; };
static inline struct c4iw_ep *to_ep(struct iw_cm_id *cm_id) static inline struct c4iw_ep *to_ep(struct iw_cm_id *cm_id)
......
...@@ -917,7 +917,11 @@ static void post_terminate(struct c4iw_qp *qhp, struct t4_cqe *err_cqe, ...@@ -917,7 +917,11 @@ static void post_terminate(struct c4iw_qp *qhp, struct t4_cqe *err_cqe,
wqe->u.terminate.type = FW_RI_TYPE_TERMINATE; wqe->u.terminate.type = FW_RI_TYPE_TERMINATE;
wqe->u.terminate.immdlen = cpu_to_be32(sizeof *term); wqe->u.terminate.immdlen = cpu_to_be32(sizeof *term);
term = (struct terminate_message *)wqe->u.terminate.termmsg; term = (struct terminate_message *)wqe->u.terminate.termmsg;
build_term_codes(err_cqe, &term->layer_etype, &term->ecode); if (qhp->attr.layer_etype == (LAYER_MPA|DDP_LLP)) {
term->layer_etype = qhp->attr.layer_etype;
term->ecode = qhp->attr.ecode;
} else
build_term_codes(err_cqe, &term->layer_etype, &term->ecode);
c4iw_ofld_send(&qhp->rhp->rdev, skb); c4iw_ofld_send(&qhp->rhp->rdev, skb);
} }
...@@ -1012,6 +1016,7 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, ...@@ -1012,6 +1016,7 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
static void build_rtr_msg(u8 p2p_type, struct fw_ri_init *init) static void build_rtr_msg(u8 p2p_type, struct fw_ri_init *init)
{ {
PDBG("%s p2p_type = %d\n", __func__, p2p_type);
memset(&init->u, 0, sizeof init->u); memset(&init->u, 0, sizeof init->u);
switch (p2p_type) { switch (p2p_type) {
case FW_RI_INIT_P2PTYPE_RDMA_WRITE: case FW_RI_INIT_P2PTYPE_RDMA_WRITE:
...@@ -1212,6 +1217,8 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, ...@@ -1212,6 +1217,8 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
break; break;
case C4IW_QP_STATE_TERMINATE: case C4IW_QP_STATE_TERMINATE:
set_state(qhp, C4IW_QP_STATE_TERMINATE); set_state(qhp, C4IW_QP_STATE_TERMINATE);
qhp->attr.layer_etype = attrs->layer_etype;
qhp->attr.ecode = attrs->ecode;
if (qhp->ibqp.uobject) if (qhp->ibqp.uobject)
t4_set_wq_in_error(&qhp->wq); t4_set_wq_in_error(&qhp->wq);
ep = qhp->ep; ep = qhp->ep;
...@@ -1334,7 +1341,10 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp) ...@@ -1334,7 +1341,10 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
rhp = qhp->rhp; rhp = qhp->rhp;
attrs.next_state = C4IW_QP_STATE_ERROR; attrs.next_state = C4IW_QP_STATE_ERROR;
c4iw_modify_qp(rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); if (qhp->attr.state == C4IW_QP_STATE_TERMINATE)
c4iw_modify_qp(rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
else
c4iw_modify_qp(rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 0);
wait_event(qhp->wait, !qhp->ep); wait_event(qhp->wait, !qhp->ep);
remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid); remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment