2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-22 04:03:58 +08:00

RDMA/nes: Fixes for IRD/ORD negotiation with MPA v2

Fixes to enable the negotiation of the supported IRD/ORD sizes with
the peer when exchanging MPA v2 messages in connection establishment.

Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
Tatyana Nikolova 2014-03-11 14:17:25 -05:00 committed by Roland Dreier
parent cfbf8d4857
commit 4ac79a7003
2 changed files with 92 additions and 28 deletions

View File

@ -128,6 +128,7 @@ static void build_mpa_v1(struct nes_cm_node *, void *, u8);
static void build_rdma0_msg(struct nes_cm_node *, struct nes_qp **); static void build_rdma0_msg(struct nes_cm_node *, struct nes_qp **);
static void print_core(struct nes_cm_core *core); static void print_core(struct nes_cm_core *core);
static void record_ird_ord(struct nes_cm_node *, u16, u16);
/* External CM API Interface */ /* External CM API Interface */
/* instance of function pointers for client API */ /* instance of function pointers for client API */
@ -317,7 +318,6 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type,
} }
} }
if (priv_data_len + mpa_hdr_len != len) { if (priv_data_len + mpa_hdr_len != len) {
nes_debug(NES_DBG_CM, "The received ietf buffer was not right" nes_debug(NES_DBG_CM, "The received ietf buffer was not right"
" complete (%x + %x != %x)\n", " complete (%x + %x != %x)\n",
@ -356,25 +356,57 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type,
/* send reset */ /* send reset */
return -EINVAL; return -EINVAL;
} }
if (ird_size == IETF_NO_IRD_ORD || ord_size == IETF_NO_IRD_ORD)
cm_node->mpav2_ird_ord = IETF_NO_IRD_ORD;
if (cm_node->state != NES_CM_STATE_MPAREQ_SENT) { if (cm_node->mpav2_ird_ord != IETF_NO_IRD_ORD) {
/* responder */ /* responder */
if (cm_node->ord_size > ird_size) if (cm_node->state != NES_CM_STATE_MPAREQ_SENT) {
cm_node->ord_size = ird_size; /* we are still negotiating */
} else { if (ord_size > NES_MAX_IRD) {
/* initiator */ cm_node->ird_size = NES_MAX_IRD;
if (cm_node->ord_size > ird_size) } else {
cm_node->ord_size = ird_size; cm_node->ird_size = ord_size;
if (ord_size == 0 &&
(rtr_ctrl_ord & IETF_RDMA0_READ)) {
cm_node->ird_size = 1;
nes_debug(NES_DBG_CM,
"%s: Remote peer doesn't support RDMA0_READ (ord=%u)\n",
__func__, ord_size);
}
}
if (ird_size > NES_MAX_ORD)
cm_node->ord_size = NES_MAX_ORD;
else
cm_node->ord_size = ird_size;
} else { /* initiator */
if (ord_size > NES_MAX_IRD) {
nes_debug(NES_DBG_CM,
"%s: Unable to support the requested (ord =%u)\n",
__func__, ord_size);
return -EINVAL;
}
cm_node->ird_size = ord_size;
if (cm_node->ird_size < ord_size) { if (ird_size > NES_MAX_ORD) {
/* no resources available */ cm_node->ord_size = NES_MAX_ORD;
/* send terminate message */ } else {
return -EINVAL; if (ird_size == 0 &&
(rtr_ctrl_ord & IETF_RDMA0_READ)) {
nes_debug(NES_DBG_CM,
"%s: Remote peer doesn't support RDMA0_READ (ird=%u)\n",
__func__, ird_size);
return -EINVAL;
} else {
cm_node->ord_size = ird_size;
}
}
} }
} }
if (rtr_ctrl_ord & IETF_RDMA0_READ) { if (rtr_ctrl_ord & IETF_RDMA0_READ) {
cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO; cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO;
} else if (rtr_ctrl_ord & IETF_RDMA0_WRITE) { } else if (rtr_ctrl_ord & IETF_RDMA0_WRITE) {
cm_node->send_rdma0_op = SEND_RDMA_WRITE_ZERO; cm_node->send_rdma0_op = SEND_RDMA_WRITE_ZERO;
} else { /* Not supported RDMA0 operation */ } else { /* Not supported RDMA0 operation */
@ -514,6 +546,19 @@ static void print_core(struct nes_cm_core *core)
nes_debug(NES_DBG_CM, "-------------- end core ---------------\n"); nes_debug(NES_DBG_CM, "-------------- end core ---------------\n");
} }
static void record_ird_ord(struct nes_cm_node *cm_node,
u16 conn_ird, u16 conn_ord)
{
if (conn_ird > NES_MAX_IRD)
conn_ird = NES_MAX_IRD;
if (conn_ord > NES_MAX_ORD)
conn_ord = NES_MAX_ORD;
cm_node->ird_size = conn_ird;
cm_node->ord_size = conn_ord;
}
/** /**
* cm_build_mpa_frame - build a MPA V1 frame or MPA V2 frame * cm_build_mpa_frame - build a MPA V1 frame or MPA V2 frame
*/ */
@ -557,11 +602,13 @@ static void build_mpa_v2(struct nes_cm_node *cm_node,
mpa_frame->priv_data_len += htons(IETF_RTR_MSG_SIZE); mpa_frame->priv_data_len += htons(IETF_RTR_MSG_SIZE);
/* initialize RTR msg */ /* initialize RTR msg */
ctrl_ird = (cm_node->ird_size > IETF_NO_IRD_ORD) ? if (cm_node->mpav2_ird_ord == IETF_NO_IRD_ORD) {
IETF_NO_IRD_ORD : cm_node->ird_size; ctrl_ird = IETF_NO_IRD_ORD;
ctrl_ord = (cm_node->ord_size > IETF_NO_IRD_ORD) ? ctrl_ord = IETF_NO_IRD_ORD;
IETF_NO_IRD_ORD : cm_node->ord_size; } else {
ctrl_ird = cm_node->ird_size & IETF_NO_IRD_ORD;
ctrl_ord = cm_node->ord_size & IETF_NO_IRD_ORD;
}
ctrl_ird |= IETF_PEER_TO_PEER; ctrl_ird |= IETF_PEER_TO_PEER;
ctrl_ird |= IETF_FLPDU_ZERO_LEN; ctrl_ird |= IETF_FLPDU_ZERO_LEN;
@ -1409,8 +1456,9 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
cm_node->mpa_frame_rev = mpa_version; cm_node->mpa_frame_rev = mpa_version;
cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO; cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO;
cm_node->ird_size = IETF_NO_IRD_ORD; cm_node->mpav2_ird_ord = 0;
cm_node->ord_size = IETF_NO_IRD_ORD; cm_node->ird_size = 0;
cm_node->ord_size = 0;
nes_debug(NES_DBG_CM, "Make node addresses : loc = %pI4:%x, rem = %pI4:%x\n", nes_debug(NES_DBG_CM, "Make node addresses : loc = %pI4:%x, rem = %pI4:%x\n",
&cm_node->loc_addr, cm_node->loc_port, &cm_node->loc_addr, cm_node->loc_port,
@ -3027,11 +3075,11 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
rem_ref_cm_node(cm_node->cm_core, cm_node); rem_ref_cm_node(cm_node->cm_core, cm_node);
return -ECONNRESET; return -ECONNRESET;
} }
/* associate the node with the QP */ /* associate the node with the QP */
nesqp->cm_node = (void *)cm_node; nesqp->cm_node = (void *)cm_node;
cm_node->nesqp = nesqp; cm_node->nesqp = nesqp;
nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n", nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n",
nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener); nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener);
atomic_inc(&cm_accepts); atomic_inc(&cm_accepts);
@ -3054,6 +3102,11 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
if (cm_node->mpa_frame_rev == IETF_MPA_V1) if (cm_node->mpa_frame_rev == IETF_MPA_V1)
mpa_frame_offset = 4; mpa_frame_offset = 4;
if (cm_node->mpa_frame_rev == IETF_MPA_V1 ||
cm_node->mpav2_ird_ord == IETF_NO_IRD_ORD) {
record_ird_ord(cm_node, (u16)conn_param->ird, (u16)conn_param->ord);
}
memcpy(mpa_v2_frame->priv_data, conn_param->private_data, memcpy(mpa_v2_frame->priv_data, conn_param->private_data,
conn_param->private_data_len); conn_param->private_data_len);
@ -3117,7 +3170,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
} }
nesqp->skip_lsmm = 1; nesqp->skip_lsmm = 1;
/* Cache the cm_id in the qp */ /* Cache the cm_id in the qp */
nesqp->cm_id = cm_id; nesqp->cm_id = cm_id;
cm_node->cm_id = cm_id; cm_node->cm_id = cm_id;
@ -3154,7 +3206,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32( nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(
((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT)); ((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT));
nesqp->nesqp_context->ird_ord_sizes |= nesqp->nesqp_context->ird_ord_sizes |=
cpu_to_le32((u32)conn_param->ord); cpu_to_le32((u32)cm_node->ord_size);
memset(&nes_quad, 0, sizeof(nes_quad)); memset(&nes_quad, 0, sizeof(nes_quad));
nes_quad.DstIpAdrIndex = nes_quad.DstIpAdrIndex =
@ -3194,6 +3246,9 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
cm_event.remote_addr = cm_id->remote_addr; cm_event.remote_addr = cm_id->remote_addr;
cm_event.private_data = NULL; cm_event.private_data = NULL;
cm_event.private_data_len = 0; cm_event.private_data_len = 0;
cm_event.ird = cm_node->ird_size;
cm_event.ord = cm_node->ord_size;
ret = cm_id->event_handler(cm_id, &cm_event); ret = cm_id->event_handler(cm_id, &cm_event);
attr.qp_state = IB_QPS_RTS; attr.qp_state = IB_QPS_RTS;
nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL);
@ -3290,14 +3345,8 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
/* cache the cm_id in the qp */ /* cache the cm_id in the qp */
nesqp->cm_id = cm_id; nesqp->cm_id = cm_id;
cm_id->provider_data = nesqp; cm_id->provider_data = nesqp;
nesqp->private_data_len = conn_param->private_data_len; nesqp->private_data_len = conn_param->private_data_len;
nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord);
/* space for rdma0 read msg */
if (conn_param->ord == 0)
nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(1);
nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord); nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord);
nes_debug(NES_DBG_CM, "mpa private data len =%u\n", nes_debug(NES_DBG_CM, "mpa private data len =%u\n",
@ -3334,6 +3383,11 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
return -ENOMEM; return -ENOMEM;
} }
record_ird_ord(cm_node, (u16)conn_param->ird, (u16)conn_param->ord);
if (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO &&
cm_node->ord_size == 0)
cm_node->ord_size = 1;
cm_node->apbvt_set = apbvt_set; cm_node->apbvt_set = apbvt_set;
nesqp->cm_node = cm_node; nesqp->cm_node = cm_node;
cm_node->nesqp = nesqp; cm_node->nesqp = nesqp;
@ -3530,6 +3584,8 @@ static void cm_event_connected(struct nes_cm_event *event)
nesqp->nesqp_context->ird_ord_sizes |= nesqp->nesqp_context->ird_ord_sizes |=
cpu_to_le32((u32)1 << cpu_to_le32((u32)1 <<
NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT); NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT);
nesqp->nesqp_context->ird_ord_sizes |=
cpu_to_le32((u32)cm_node->ord_size);
/* Adjust tail for not having a LSMM */ /* Adjust tail for not having a LSMM */
/*nesqp->hwqp.sq_tail = 1;*/ /*nesqp->hwqp.sq_tail = 1;*/
@ -3742,8 +3798,13 @@ static void cm_event_mpa_req(struct nes_cm_event *event)
cm_event_raddr->sin_addr.s_addr = htonl(event->cm_info.rem_addr); cm_event_raddr->sin_addr.s_addr = htonl(event->cm_info.rem_addr);
cm_event.private_data = cm_node->mpa_frame_buf; cm_event.private_data = cm_node->mpa_frame_buf;
cm_event.private_data_len = (u8)cm_node->mpa_frame_size; cm_event.private_data_len = (u8)cm_node->mpa_frame_size;
if (cm_node->mpa_frame_rev == IETF_MPA_V1) {
cm_event.ird = NES_MAX_IRD;
cm_event.ord = NES_MAX_ORD;
} else {
cm_event.ird = cm_node->ird_size; cm_event.ird = cm_node->ird_size;
cm_event.ord = cm_node->ord_size; cm_event.ord = cm_node->ord_size;
}
ret = cm_id->event_handler(cm_id, &cm_event); ret = cm_id->event_handler(cm_id, &cm_event);
if (ret) if (ret)

View File

@ -58,6 +58,8 @@
#define IETF_RDMA0_WRITE 0x8000 #define IETF_RDMA0_WRITE 0x8000
#define IETF_RDMA0_READ 0x4000 #define IETF_RDMA0_READ 0x4000
#define IETF_NO_IRD_ORD 0x3FFF #define IETF_NO_IRD_ORD 0x3FFF
#define NES_MAX_IRD 0x40
#define NES_MAX_ORD 0x7F
enum ietf_mpa_flags { enum ietf_mpa_flags {
IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */
@ -333,6 +335,7 @@ struct nes_cm_node {
enum mpa_frame_version mpa_frame_rev; enum mpa_frame_version mpa_frame_rev;
u16 ird_size; u16 ird_size;
u16 ord_size; u16 ord_size;
u16 mpav2_ird_ord;
u16 mpa_frame_size; u16 mpa_frame_size;
struct iw_cm_id *cm_id; struct iw_cm_id *cm_id;