aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorTatyana Nikolova <Tatyana.E.Nikolova@intel.com>2014-03-11 15:17:25 -0400
committerRoland Dreier <roland@purestorage.com>2014-03-17 13:03:17 -0400
commit4ac79a70033cbb9b7fa2bb2f3770308359af8c12 (patch)
treebfa2f9023e5e270bd3143ad6067d8e1c40cb5ab7 /drivers/infiniband/hw
parentcfbf8d4857c26a8a307fb7cd258074c9dcd8c691 (diff)
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>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c119
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.h3
2 files changed, 93 insertions, 29 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 9c9f2f57e960..e852a3a42b9e 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -128,6 +128,7 @@ static void build_mpa_v1(struct nes_cm_node *, void *, u8);
128static void build_rdma0_msg(struct nes_cm_node *, struct nes_qp **); 128static void build_rdma0_msg(struct nes_cm_node *, struct nes_qp **);
129 129
130static void print_core(struct nes_cm_core *core); 130static void print_core(struct nes_cm_core *core);
131static void record_ird_ord(struct nes_cm_node *, u16, u16);
131 132
132/* External CM API Interface */ 133/* External CM API Interface */
133/* instance of function pointers for client API */ 134/* 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,
317 } 318 }
318 } 319 }
319 320
320
321 if (priv_data_len + mpa_hdr_len != len) { 321 if (priv_data_len + mpa_hdr_len != len) {
322 nes_debug(NES_DBG_CM, "The received ietf buffer was not right" 322 nes_debug(NES_DBG_CM, "The received ietf buffer was not right"
323 " complete (%x + %x != %x)\n", 323 " complete (%x + %x != %x)\n",
@@ -356,25 +356,57 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type,
356 /* send reset */ 356 /* send reset */
357 return -EINVAL; 357 return -EINVAL;
358 } 358 }
359 if (ird_size == IETF_NO_IRD_ORD || ord_size == IETF_NO_IRD_ORD)
360 cm_node->mpav2_ird_ord = IETF_NO_IRD_ORD;
359 361
360 if (cm_node->state != NES_CM_STATE_MPAREQ_SENT) { 362 if (cm_node->mpav2_ird_ord != IETF_NO_IRD_ORD) {
361 /* responder */ 363 /* responder */
362 if (cm_node->ord_size > ird_size) 364 if (cm_node->state != NES_CM_STATE_MPAREQ_SENT) {
363 cm_node->ord_size = ird_size; 365 /* we are still negotiating */
364 } else { 366 if (ord_size > NES_MAX_IRD) {
365 /* initiator */ 367 cm_node->ird_size = NES_MAX_IRD;
366 if (cm_node->ord_size > ird_size) 368 } else {
367 cm_node->ord_size = ird_size; 369 cm_node->ird_size = ord_size;
368 370 if (ord_size == 0 &&
369 if (cm_node->ird_size < ord_size) { 371 (rtr_ctrl_ord & IETF_RDMA0_READ)) {
370 /* no resources available */ 372 cm_node->ird_size = 1;
371 /* send terminate message */ 373 nes_debug(NES_DBG_CM,
372 return -EINVAL; 374 "%s: Remote peer doesn't support RDMA0_READ (ord=%u)\n",
375 __func__, ord_size);
376 }
377 }
378 if (ird_size > NES_MAX_ORD)
379 cm_node->ord_size = NES_MAX_ORD;
380 else
381 cm_node->ord_size = ird_size;
382 } else { /* initiator */
383 if (ord_size > NES_MAX_IRD) {
384 nes_debug(NES_DBG_CM,
385 "%s: Unable to support the requested (ord =%u)\n",
386 __func__, ord_size);
387 return -EINVAL;
388 }
389 cm_node->ird_size = ord_size;
390
391 if (ird_size > NES_MAX_ORD) {
392 cm_node->ord_size = NES_MAX_ORD;
393 } else {
394 if (ird_size == 0 &&
395 (rtr_ctrl_ord & IETF_RDMA0_READ)) {
396 nes_debug(NES_DBG_CM,
397 "%s: Remote peer doesn't support RDMA0_READ (ird=%u)\n",
398 __func__, ird_size);
399 return -EINVAL;
400 } else {
401 cm_node->ord_size = ird_size;
402 }
403 }
373 } 404 }
374 } 405 }
375 406
376 if (rtr_ctrl_ord & IETF_RDMA0_READ) { 407 if (rtr_ctrl_ord & IETF_RDMA0_READ) {
377 cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO; 408 cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO;
409
378 } else if (rtr_ctrl_ord & IETF_RDMA0_WRITE) { 410 } else if (rtr_ctrl_ord & IETF_RDMA0_WRITE) {
379 cm_node->send_rdma0_op = SEND_RDMA_WRITE_ZERO; 411 cm_node->send_rdma0_op = SEND_RDMA_WRITE_ZERO;
380 } else { /* Not supported RDMA0 operation */ 412 } else { /* Not supported RDMA0 operation */
@@ -514,6 +546,19 @@ static void print_core(struct nes_cm_core *core)
514 nes_debug(NES_DBG_CM, "-------------- end core ---------------\n"); 546 nes_debug(NES_DBG_CM, "-------------- end core ---------------\n");
515} 547}
516 548
549static void record_ird_ord(struct nes_cm_node *cm_node,
550 u16 conn_ird, u16 conn_ord)
551{
552 if (conn_ird > NES_MAX_IRD)
553 conn_ird = NES_MAX_IRD;
554
555 if (conn_ord > NES_MAX_ORD)
556 conn_ord = NES_MAX_ORD;
557
558 cm_node->ird_size = conn_ird;
559 cm_node->ord_size = conn_ord;
560}
561
517/** 562/**
518 * cm_build_mpa_frame - build a MPA V1 frame or MPA V2 frame 563 * cm_build_mpa_frame - build a MPA V1 frame or MPA V2 frame
519 */ 564 */
@@ -557,11 +602,13 @@ static void build_mpa_v2(struct nes_cm_node *cm_node,
557 mpa_frame->priv_data_len += htons(IETF_RTR_MSG_SIZE); 602 mpa_frame->priv_data_len += htons(IETF_RTR_MSG_SIZE);
558 603
559 /* initialize RTR msg */ 604 /* initialize RTR msg */
560 ctrl_ird = (cm_node->ird_size > IETF_NO_IRD_ORD) ? 605 if (cm_node->mpav2_ird_ord == IETF_NO_IRD_ORD) {
561 IETF_NO_IRD_ORD : cm_node->ird_size; 606 ctrl_ird = IETF_NO_IRD_ORD;
562 ctrl_ord = (cm_node->ord_size > IETF_NO_IRD_ORD) ? 607 ctrl_ord = IETF_NO_IRD_ORD;
563 IETF_NO_IRD_ORD : cm_node->ord_size; 608 } else {
564 609 ctrl_ird = cm_node->ird_size & IETF_NO_IRD_ORD;
610 ctrl_ord = cm_node->ord_size & IETF_NO_IRD_ORD;
611 }
565 ctrl_ird |= IETF_PEER_TO_PEER; 612 ctrl_ird |= IETF_PEER_TO_PEER;
566 ctrl_ird |= IETF_FLPDU_ZERO_LEN; 613 ctrl_ird |= IETF_FLPDU_ZERO_LEN;
567 614
@@ -1409,8 +1456,9 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1409 1456
1410 cm_node->mpa_frame_rev = mpa_version; 1457 cm_node->mpa_frame_rev = mpa_version;
1411 cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO; 1458 cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO;
1412 cm_node->ird_size = IETF_NO_IRD_ORD; 1459 cm_node->mpav2_ird_ord = 0;
1413 cm_node->ord_size = IETF_NO_IRD_ORD; 1460 cm_node->ird_size = 0;
1461 cm_node->ord_size = 0;
1414 1462
1415 nes_debug(NES_DBG_CM, "Make node addresses : loc = %pI4:%x, rem = %pI4:%x\n", 1463 nes_debug(NES_DBG_CM, "Make node addresses : loc = %pI4:%x, rem = %pI4:%x\n",
1416 &cm_node->loc_addr, cm_node->loc_port, 1464 &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)
3027 rem_ref_cm_node(cm_node->cm_core, cm_node); 3075 rem_ref_cm_node(cm_node->cm_core, cm_node);
3028 return -ECONNRESET; 3076 return -ECONNRESET;
3029 } 3077 }
3030
3031 /* associate the node with the QP */ 3078 /* associate the node with the QP */
3032 nesqp->cm_node = (void *)cm_node; 3079 nesqp->cm_node = (void *)cm_node;
3033 cm_node->nesqp = nesqp; 3080 cm_node->nesqp = nesqp;
3034 3081
3082
3035 nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n", 3083 nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n",
3036 nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener); 3084 nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener);
3037 atomic_inc(&cm_accepts); 3085 atomic_inc(&cm_accepts);
@@ -3054,6 +3102,11 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3054 if (cm_node->mpa_frame_rev == IETF_MPA_V1) 3102 if (cm_node->mpa_frame_rev == IETF_MPA_V1)
3055 mpa_frame_offset = 4; 3103 mpa_frame_offset = 4;
3056 3104
3105 if (cm_node->mpa_frame_rev == IETF_MPA_V1 ||
3106 cm_node->mpav2_ird_ord == IETF_NO_IRD_ORD) {
3107 record_ird_ord(cm_node, (u16)conn_param->ird, (u16)conn_param->ord);
3108 }
3109
3057 memcpy(mpa_v2_frame->priv_data, conn_param->private_data, 3110 memcpy(mpa_v2_frame->priv_data, conn_param->private_data,
3058 conn_param->private_data_len); 3111 conn_param->private_data_len);
3059 3112
@@ -3117,7 +3170,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3117 } 3170 }
3118 nesqp->skip_lsmm = 1; 3171 nesqp->skip_lsmm = 1;
3119 3172
3120
3121 /* Cache the cm_id in the qp */ 3173 /* Cache the cm_id in the qp */
3122 nesqp->cm_id = cm_id; 3174 nesqp->cm_id = cm_id;
3123 cm_node->cm_id = cm_id; 3175 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)
3154 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32( 3206 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(
3155 ((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT)); 3207 ((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT));
3156 nesqp->nesqp_context->ird_ord_sizes |= 3208 nesqp->nesqp_context->ird_ord_sizes |=
3157 cpu_to_le32((u32)conn_param->ord); 3209 cpu_to_le32((u32)cm_node->ord_size);
3158 3210
3159 memset(&nes_quad, 0, sizeof(nes_quad)); 3211 memset(&nes_quad, 0, sizeof(nes_quad));
3160 nes_quad.DstIpAdrIndex = 3212 nes_quad.DstIpAdrIndex =
@@ -3194,6 +3246,9 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3194 cm_event.remote_addr = cm_id->remote_addr; 3246 cm_event.remote_addr = cm_id->remote_addr;
3195 cm_event.private_data = NULL; 3247 cm_event.private_data = NULL;
3196 cm_event.private_data_len = 0; 3248 cm_event.private_data_len = 0;
3249 cm_event.ird = cm_node->ird_size;
3250 cm_event.ord = cm_node->ord_size;
3251
3197 ret = cm_id->event_handler(cm_id, &cm_event); 3252 ret = cm_id->event_handler(cm_id, &cm_event);
3198 attr.qp_state = IB_QPS_RTS; 3253 attr.qp_state = IB_QPS_RTS;
3199 nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); 3254 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)
3290 3345
3291 /* cache the cm_id in the qp */ 3346 /* cache the cm_id in the qp */
3292 nesqp->cm_id = cm_id; 3347 nesqp->cm_id = cm_id;
3293
3294 cm_id->provider_data = nesqp; 3348 cm_id->provider_data = nesqp;
3295
3296 nesqp->private_data_len = conn_param->private_data_len; 3349 nesqp->private_data_len = conn_param->private_data_len;
3297 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord);
3298 /* space for rdma0 read msg */
3299 if (conn_param->ord == 0)
3300 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(1);
3301 3350
3302 nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord); 3351 nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord);
3303 nes_debug(NES_DBG_CM, "mpa private data len =%u\n", 3352 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)
3334 return -ENOMEM; 3383 return -ENOMEM;
3335 } 3384 }
3336 3385
3386 record_ird_ord(cm_node, (u16)conn_param->ird, (u16)conn_param->ord);
3387 if (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO &&
3388 cm_node->ord_size == 0)
3389 cm_node->ord_size = 1;
3390
3337 cm_node->apbvt_set = apbvt_set; 3391 cm_node->apbvt_set = apbvt_set;
3338 nesqp->cm_node = cm_node; 3392 nesqp->cm_node = cm_node;
3339 cm_node->nesqp = nesqp; 3393 cm_node->nesqp = nesqp;
@@ -3530,6 +3584,8 @@ static void cm_event_connected(struct nes_cm_event *event)
3530 nesqp->nesqp_context->ird_ord_sizes |= 3584 nesqp->nesqp_context->ird_ord_sizes |=
3531 cpu_to_le32((u32)1 << 3585 cpu_to_le32((u32)1 <<
3532 NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT); 3586 NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT);
3587 nesqp->nesqp_context->ird_ord_sizes |=
3588 cpu_to_le32((u32)cm_node->ord_size);
3533 3589
3534 /* Adjust tail for not having a LSMM */ 3590 /* Adjust tail for not having a LSMM */
3535 /*nesqp->hwqp.sq_tail = 1;*/ 3591 /*nesqp->hwqp.sq_tail = 1;*/
@@ -3742,8 +3798,13 @@ static void cm_event_mpa_req(struct nes_cm_event *event)
3742 cm_event_raddr->sin_addr.s_addr = htonl(event->cm_info.rem_addr); 3798 cm_event_raddr->sin_addr.s_addr = htonl(event->cm_info.rem_addr);
3743 cm_event.private_data = cm_node->mpa_frame_buf; 3799 cm_event.private_data = cm_node->mpa_frame_buf;
3744 cm_event.private_data_len = (u8)cm_node->mpa_frame_size; 3800 cm_event.private_data_len = (u8)cm_node->mpa_frame_size;
3801 if (cm_node->mpa_frame_rev == IETF_MPA_V1) {
3802 cm_event.ird = NES_MAX_IRD;
3803 cm_event.ord = NES_MAX_ORD;
3804 } else {
3745 cm_event.ird = cm_node->ird_size; 3805 cm_event.ird = cm_node->ird_size;
3746 cm_event.ord = cm_node->ord_size; 3806 cm_event.ord = cm_node->ord_size;
3807 }
3747 3808
3748 ret = cm_id->event_handler(cm_id, &cm_event); 3809 ret = cm_id->event_handler(cm_id, &cm_event);
3749 if (ret) 3810 if (ret)
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index 4646e6666087..522c99cd07c4 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -58,6 +58,8 @@
58#define IETF_RDMA0_WRITE 0x8000 58#define IETF_RDMA0_WRITE 0x8000
59#define IETF_RDMA0_READ 0x4000 59#define IETF_RDMA0_READ 0x4000
60#define IETF_NO_IRD_ORD 0x3FFF 60#define IETF_NO_IRD_ORD 0x3FFF
61#define NES_MAX_IRD 0x40
62#define NES_MAX_ORD 0x7F
61 63
62enum ietf_mpa_flags { 64enum ietf_mpa_flags {
63 IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ 65 IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */
@@ -333,6 +335,7 @@ struct nes_cm_node {
333 enum mpa_frame_version mpa_frame_rev; 335 enum mpa_frame_version mpa_frame_rev;
334 u16 ird_size; 336 u16 ird_size;
335 u16 ord_size; 337 u16 ord_size;
338 u16 mpav2_ird_ord;
336 339
337 u16 mpa_frame_size; 340 u16 mpa_frame_size;
338 struct iw_cm_id *cm_id; 341 struct iw_cm_id *cm_id;