| .. | .. |
|---|
| 87 | 87 | [RDMA_NL_IWPM_REMOTE_INFO] = {.dump = iwpm_remote_info_cb}, |
|---|
| 88 | 88 | [RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb}, |
|---|
| 89 | 89 | [RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb}, |
|---|
| 90 | | - [RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb} |
|---|
| 90 | + [RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb}, |
|---|
| 91 | + [RDMA_NL_IWPM_HELLO] = {.dump = iwpm_hello_cb} |
|---|
| 91 | 92 | }; |
|---|
| 92 | 93 | |
|---|
| 93 | 94 | static struct workqueue_struct *iwcm_wq; |
|---|
| .. | .. |
|---|
| 373 | 374 | static void destroy_cm_id(struct iw_cm_id *cm_id) |
|---|
| 374 | 375 | { |
|---|
| 375 | 376 | struct iwcm_id_private *cm_id_priv; |
|---|
| 377 | + struct ib_qp *qp; |
|---|
| 376 | 378 | unsigned long flags; |
|---|
| 377 | 379 | |
|---|
| 378 | 380 | cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); |
|---|
| .. | .. |
|---|
| 390 | 392 | set_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags); |
|---|
| 391 | 393 | |
|---|
| 392 | 394 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
|---|
| 395 | + qp = cm_id_priv->qp; |
|---|
| 396 | + cm_id_priv->qp = NULL; |
|---|
| 397 | + |
|---|
| 393 | 398 | switch (cm_id_priv->state) { |
|---|
| 394 | 399 | case IW_CM_STATE_LISTEN: |
|---|
| 395 | 400 | cm_id_priv->state = IW_CM_STATE_DESTROYING; |
|---|
| 396 | 401 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 397 | 402 | /* destroy the listening endpoint */ |
|---|
| 398 | | - cm_id->device->iwcm->destroy_listen(cm_id); |
|---|
| 403 | + cm_id->device->ops.iw_destroy_listen(cm_id); |
|---|
| 399 | 404 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
|---|
| 400 | 405 | break; |
|---|
| 401 | 406 | case IW_CM_STATE_ESTABLISHED: |
|---|
| 402 | 407 | cm_id_priv->state = IW_CM_STATE_DESTROYING; |
|---|
| 403 | 408 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 404 | 409 | /* Abrupt close of the connection */ |
|---|
| 405 | | - (void)iwcm_modify_qp_err(cm_id_priv->qp); |
|---|
| 410 | + (void)iwcm_modify_qp_err(qp); |
|---|
| 406 | 411 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
|---|
| 407 | 412 | break; |
|---|
| 408 | 413 | case IW_CM_STATE_IDLE: |
|---|
| .. | .. |
|---|
| 418 | 423 | */ |
|---|
| 419 | 424 | cm_id_priv->state = IW_CM_STATE_DESTROYING; |
|---|
| 420 | 425 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 421 | | - cm_id->device->iwcm->reject(cm_id, NULL, 0); |
|---|
| 426 | + cm_id->device->ops.iw_reject(cm_id, NULL, 0); |
|---|
| 422 | 427 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
|---|
| 423 | 428 | break; |
|---|
| 424 | 429 | case IW_CM_STATE_CONN_SENT: |
|---|
| .. | .. |
|---|
| 427 | 432 | BUG(); |
|---|
| 428 | 433 | break; |
|---|
| 429 | 434 | } |
|---|
| 430 | | - if (cm_id_priv->qp) { |
|---|
| 431 | | - cm_id_priv->id.device->iwcm->rem_ref(cm_id_priv->qp); |
|---|
| 432 | | - cm_id_priv->qp = NULL; |
|---|
| 433 | | - } |
|---|
| 434 | 435 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 436 | + if (qp) |
|---|
| 437 | + cm_id_priv->id.device->ops.iw_rem_ref(qp); |
|---|
| 435 | 438 | |
|---|
| 436 | 439 | if (cm_id->mapped) { |
|---|
| 437 | 440 | iwpm_remove_mapinfo(&cm_id->local_addr, &cm_id->m_local_addr); |
|---|
| .. | .. |
|---|
| 504 | 507 | */ |
|---|
| 505 | 508 | static int iw_cm_map(struct iw_cm_id *cm_id, bool active) |
|---|
| 506 | 509 | { |
|---|
| 507 | | - struct iwpm_dev_data pm_reg_msg; |
|---|
| 510 | + const char *devname = dev_name(&cm_id->device->dev); |
|---|
| 511 | + const char *ifname = cm_id->device->iw_ifname; |
|---|
| 512 | + struct iwpm_dev_data pm_reg_msg = {}; |
|---|
| 508 | 513 | struct iwpm_sa_data pm_msg; |
|---|
| 509 | 514 | int status; |
|---|
| 515 | + |
|---|
| 516 | + if (strlen(devname) >= sizeof(pm_reg_msg.dev_name) || |
|---|
| 517 | + strlen(ifname) >= sizeof(pm_reg_msg.if_name)) |
|---|
| 518 | + return -EINVAL; |
|---|
| 510 | 519 | |
|---|
| 511 | 520 | cm_id->m_local_addr = cm_id->local_addr; |
|---|
| 512 | 521 | cm_id->m_remote_addr = cm_id->remote_addr; |
|---|
| 513 | 522 | |
|---|
| 514 | | - memcpy(pm_reg_msg.dev_name, cm_id->device->name, |
|---|
| 515 | | - sizeof(pm_reg_msg.dev_name)); |
|---|
| 516 | | - memcpy(pm_reg_msg.if_name, cm_id->device->iwcm->ifname, |
|---|
| 517 | | - sizeof(pm_reg_msg.if_name)); |
|---|
| 523 | + strcpy(pm_reg_msg.dev_name, devname); |
|---|
| 524 | + strcpy(pm_reg_msg.if_name, ifname); |
|---|
| 518 | 525 | |
|---|
| 519 | 526 | if (iwpm_register_pid(&pm_reg_msg, RDMA_NL_IWCM) || |
|---|
| 520 | 527 | !iwpm_valid_pid()) |
|---|
| .. | .. |
|---|
| 523 | 530 | cm_id->mapped = true; |
|---|
| 524 | 531 | pm_msg.loc_addr = cm_id->local_addr; |
|---|
| 525 | 532 | pm_msg.rem_addr = cm_id->remote_addr; |
|---|
| 533 | + pm_msg.flags = (cm_id->device->iw_driver_flags & IW_F_NO_PORT_MAP) ? |
|---|
| 534 | + IWPM_FLAGS_NO_PORT_MAP : 0; |
|---|
| 526 | 535 | if (active) |
|---|
| 527 | 536 | status = iwpm_add_and_query_mapping(&pm_msg, |
|---|
| 528 | 537 | RDMA_NL_IWCM); |
|---|
| .. | .. |
|---|
| 541 | 550 | |
|---|
| 542 | 551 | return iwpm_create_mapinfo(&cm_id->local_addr, |
|---|
| 543 | 552 | &cm_id->m_local_addr, |
|---|
| 544 | | - RDMA_NL_IWCM); |
|---|
| 553 | + RDMA_NL_IWCM, pm_msg.flags); |
|---|
| 545 | 554 | } |
|---|
| 546 | 555 | |
|---|
| 547 | 556 | /* |
|---|
| .. | .. |
|---|
| 572 | 581 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 573 | 582 | ret = iw_cm_map(cm_id, false); |
|---|
| 574 | 583 | if (!ret) |
|---|
| 575 | | - ret = cm_id->device->iwcm->create_listen(cm_id, backlog); |
|---|
| 584 | + ret = cm_id->device->ops.iw_create_listen(cm_id, |
|---|
| 585 | + backlog); |
|---|
| 576 | 586 | if (ret) |
|---|
| 577 | 587 | cm_id_priv->state = IW_CM_STATE_IDLE; |
|---|
| 578 | 588 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
|---|
| .. | .. |
|---|
| 612 | 622 | cm_id_priv->state = IW_CM_STATE_IDLE; |
|---|
| 613 | 623 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 614 | 624 | |
|---|
| 615 | | - ret = cm_id->device->iwcm->reject(cm_id, private_data, |
|---|
| 625 | + ret = cm_id->device->ops.iw_reject(cm_id, private_data, |
|---|
| 616 | 626 | private_data_len); |
|---|
| 617 | 627 | |
|---|
| 618 | 628 | clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); |
|---|
| .. | .. |
|---|
| 648 | 658 | return -EINVAL; |
|---|
| 649 | 659 | } |
|---|
| 650 | 660 | /* Get the ib_qp given the QPN */ |
|---|
| 651 | | - qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn); |
|---|
| 661 | + qp = cm_id->device->ops.iw_get_qp(cm_id->device, iw_param->qpn); |
|---|
| 652 | 662 | if (!qp) { |
|---|
| 653 | 663 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 654 | 664 | clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); |
|---|
| 655 | 665 | wake_up_all(&cm_id_priv->connect_wait); |
|---|
| 656 | 666 | return -EINVAL; |
|---|
| 657 | 667 | } |
|---|
| 658 | | - cm_id->device->iwcm->add_ref(qp); |
|---|
| 668 | + cm_id->device->ops.iw_add_ref(qp); |
|---|
| 659 | 669 | cm_id_priv->qp = qp; |
|---|
| 660 | 670 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 661 | 671 | |
|---|
| 662 | | - ret = cm_id->device->iwcm->accept(cm_id, iw_param); |
|---|
| 672 | + ret = cm_id->device->ops.iw_accept(cm_id, iw_param); |
|---|
| 663 | 673 | if (ret) { |
|---|
| 664 | 674 | /* An error on accept precludes provider events */ |
|---|
| 665 | 675 | BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_RECV); |
|---|
| 666 | 676 | cm_id_priv->state = IW_CM_STATE_IDLE; |
|---|
| 667 | 677 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
|---|
| 668 | | - if (cm_id_priv->qp) { |
|---|
| 669 | | - cm_id->device->iwcm->rem_ref(qp); |
|---|
| 670 | | - cm_id_priv->qp = NULL; |
|---|
| 671 | | - } |
|---|
| 678 | + qp = cm_id_priv->qp; |
|---|
| 679 | + cm_id_priv->qp = NULL; |
|---|
| 672 | 680 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 681 | + if (qp) |
|---|
| 682 | + cm_id->device->ops.iw_rem_ref(qp); |
|---|
| 673 | 683 | clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); |
|---|
| 674 | 684 | wake_up_all(&cm_id_priv->connect_wait); |
|---|
| 675 | 685 | } |
|---|
| .. | .. |
|---|
| 690 | 700 | struct iwcm_id_private *cm_id_priv; |
|---|
| 691 | 701 | int ret; |
|---|
| 692 | 702 | unsigned long flags; |
|---|
| 693 | | - struct ib_qp *qp; |
|---|
| 703 | + struct ib_qp *qp = NULL; |
|---|
| 694 | 704 | |
|---|
| 695 | 705 | cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); |
|---|
| 696 | 706 | |
|---|
| .. | .. |
|---|
| 707 | 717 | } |
|---|
| 708 | 718 | |
|---|
| 709 | 719 | /* Get the ib_qp given the QPN */ |
|---|
| 710 | | - qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn); |
|---|
| 720 | + qp = cm_id->device->ops.iw_get_qp(cm_id->device, iw_param->qpn); |
|---|
| 711 | 721 | if (!qp) { |
|---|
| 712 | 722 | ret = -EINVAL; |
|---|
| 713 | 723 | goto err; |
|---|
| 714 | 724 | } |
|---|
| 715 | | - cm_id->device->iwcm->add_ref(qp); |
|---|
| 725 | + cm_id->device->ops.iw_add_ref(qp); |
|---|
| 716 | 726 | cm_id_priv->qp = qp; |
|---|
| 717 | 727 | cm_id_priv->state = IW_CM_STATE_CONN_SENT; |
|---|
| 718 | 728 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 719 | 729 | |
|---|
| 720 | 730 | ret = iw_cm_map(cm_id, true); |
|---|
| 721 | 731 | if (!ret) |
|---|
| 722 | | - ret = cm_id->device->iwcm->connect(cm_id, iw_param); |
|---|
| 732 | + ret = cm_id->device->ops.iw_connect(cm_id, iw_param); |
|---|
| 723 | 733 | if (!ret) |
|---|
| 724 | 734 | return 0; /* success */ |
|---|
| 725 | 735 | |
|---|
| 726 | 736 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
|---|
| 727 | | - if (cm_id_priv->qp) { |
|---|
| 728 | | - cm_id->device->iwcm->rem_ref(qp); |
|---|
| 729 | | - cm_id_priv->qp = NULL; |
|---|
| 730 | | - } |
|---|
| 737 | + qp = cm_id_priv->qp; |
|---|
| 738 | + cm_id_priv->qp = NULL; |
|---|
| 731 | 739 | cm_id_priv->state = IW_CM_STATE_IDLE; |
|---|
| 732 | 740 | err: |
|---|
| 733 | 741 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 742 | + if (qp) |
|---|
| 743 | + cm_id->device->ops.iw_rem_ref(qp); |
|---|
| 734 | 744 | clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); |
|---|
| 735 | 745 | wake_up_all(&cm_id_priv->connect_wait); |
|---|
| 736 | 746 | return ret; |
|---|
| .. | .. |
|---|
| 872 | 882 | static int cm_conn_rep_handler(struct iwcm_id_private *cm_id_priv, |
|---|
| 873 | 883 | struct iw_cm_event *iw_event) |
|---|
| 874 | 884 | { |
|---|
| 885 | + struct ib_qp *qp = NULL; |
|---|
| 875 | 886 | unsigned long flags; |
|---|
| 876 | 887 | int ret; |
|---|
| 877 | 888 | |
|---|
| .. | .. |
|---|
| 890 | 901 | cm_id_priv->state = IW_CM_STATE_ESTABLISHED; |
|---|
| 891 | 902 | } else { |
|---|
| 892 | 903 | /* REJECTED or RESET */ |
|---|
| 893 | | - cm_id_priv->id.device->iwcm->rem_ref(cm_id_priv->qp); |
|---|
| 904 | + qp = cm_id_priv->qp; |
|---|
| 894 | 905 | cm_id_priv->qp = NULL; |
|---|
| 895 | 906 | cm_id_priv->state = IW_CM_STATE_IDLE; |
|---|
| 896 | 907 | } |
|---|
| 897 | 908 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 909 | + if (qp) |
|---|
| 910 | + cm_id_priv->id.device->ops.iw_rem_ref(qp); |
|---|
| 898 | 911 | ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event); |
|---|
| 899 | 912 | |
|---|
| 900 | 913 | if (iw_event->private_data_len) |
|---|
| .. | .. |
|---|
| 936 | 949 | static int cm_close_handler(struct iwcm_id_private *cm_id_priv, |
|---|
| 937 | 950 | struct iw_cm_event *iw_event) |
|---|
| 938 | 951 | { |
|---|
| 952 | + struct ib_qp *qp; |
|---|
| 939 | 953 | unsigned long flags; |
|---|
| 940 | | - int ret = 0; |
|---|
| 954 | + int ret = 0, notify_event = 0; |
|---|
| 941 | 955 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
|---|
| 956 | + qp = cm_id_priv->qp; |
|---|
| 957 | + cm_id_priv->qp = NULL; |
|---|
| 942 | 958 | |
|---|
| 943 | | - if (cm_id_priv->qp) { |
|---|
| 944 | | - cm_id_priv->id.device->iwcm->rem_ref(cm_id_priv->qp); |
|---|
| 945 | | - cm_id_priv->qp = NULL; |
|---|
| 946 | | - } |
|---|
| 947 | 959 | switch (cm_id_priv->state) { |
|---|
| 948 | 960 | case IW_CM_STATE_ESTABLISHED: |
|---|
| 949 | 961 | case IW_CM_STATE_CLOSING: |
|---|
| 950 | 962 | cm_id_priv->state = IW_CM_STATE_IDLE; |
|---|
| 951 | | - spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 952 | | - ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event); |
|---|
| 953 | | - spin_lock_irqsave(&cm_id_priv->lock, flags); |
|---|
| 963 | + notify_event = 1; |
|---|
| 954 | 964 | break; |
|---|
| 955 | 965 | case IW_CM_STATE_DESTROYING: |
|---|
| 956 | 966 | break; |
|---|
| .. | .. |
|---|
| 959 | 969 | } |
|---|
| 960 | 970 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
|---|
| 961 | 971 | |
|---|
| 972 | + if (qp) |
|---|
| 973 | + cm_id_priv->id.device->ops.iw_rem_ref(qp); |
|---|
| 974 | + if (notify_event) |
|---|
| 975 | + ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event); |
|---|
| 962 | 976 | return ret; |
|---|
| 963 | 977 | } |
|---|
| 964 | 978 | |
|---|