diff options
| -rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 119 | ||||
| -rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.h | 3 |
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); | |||
| 128 | static void build_rdma0_msg(struct nes_cm_node *, struct nes_qp **); | 128 | static void build_rdma0_msg(struct nes_cm_node *, struct nes_qp **); |
| 129 | 129 | ||
| 130 | static void print_core(struct nes_cm_core *core); | 130 | static void print_core(struct nes_cm_core *core); |
| 131 | static 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 | ||
| 549 | static 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 | ||
| 62 | enum ietf_mpa_flags { | 64 | enum 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; |
