diff options
author | Doug Ledford <dledford@redhat.com> | 2016-12-14 14:44:25 -0500 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-12-14 14:44:25 -0500 |
commit | 86ef0beaa0bdbec70d4261977b8b4a100fe54bfe (patch) | |
tree | d2c1b52a7a6e493bada10dbdbcd2f8511baccc66 /drivers/infiniband/hw/mlx4 | |
parent | 253f8b22e0ad643edafd75e831e5c765732877f5 (diff) | |
parent | 7ceb740c540dde362b3055ad92c6a38009eb7a83 (diff) |
Merge branch 'mlx' into merge-test
Diffstat (limited to 'drivers/infiniband/hw/mlx4')
-rw-r--r-- | drivers/infiniband/hw/mlx4/ah.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 49 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 30 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mlx4_ib.h | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 13 |
5 files changed, 78 insertions, 27 deletions
diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c index 5fc623362731..20c6d17ac8b8 100644 --- a/drivers/infiniband/hw/mlx4/ah.c +++ b/drivers/infiniband/hw/mlx4/ah.c | |||
@@ -111,7 +111,9 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr | |||
111 | !(1 << ah->av.eth.stat_rate & dev->caps.stat_rate_support)) | 111 | !(1 << ah->av.eth.stat_rate & dev->caps.stat_rate_support)) |
112 | --ah->av.eth.stat_rate; | 112 | --ah->av.eth.stat_rate; |
113 | } | 113 | } |
114 | 114 | ah->av.eth.sl_tclass_flowlabel |= | |
115 | cpu_to_be32((ah_attr->grh.traffic_class << 20) | | ||
116 | ah_attr->grh.flow_label); | ||
115 | /* | 117 | /* |
116 | * HW requires multicast LID so we just choose one. | 118 | * HW requires multicast LID so we just choose one. |
117 | */ | 119 | */ |
@@ -119,12 +121,14 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr | |||
119 | ah->av.ib.dlid = cpu_to_be16(0xc000); | 121 | ah->av.ib.dlid = cpu_to_be16(0xc000); |
120 | 122 | ||
121 | memcpy(ah->av.eth.dgid, ah_attr->grh.dgid.raw, 16); | 123 | memcpy(ah->av.eth.dgid, ah_attr->grh.dgid.raw, 16); |
122 | ah->av.eth.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 29); | 124 | ah->av.eth.sl_tclass_flowlabel |= cpu_to_be32(ah_attr->sl << 29); |
123 | 125 | ||
124 | return &ah->ibah; | 126 | return &ah->ibah; |
125 | } | 127 | } |
126 | 128 | ||
127 | struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) | 129 | struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr, |
130 | struct ib_udata *udata) | ||
131 | |||
128 | { | 132 | { |
129 | struct mlx4_ib_ah *ah; | 133 | struct mlx4_ib_ah *ah; |
130 | struct ib_ah *ret; | 134 | struct ib_ah *ret; |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index b0cd66336fcb..db564ccc0f92 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <linux/mlx4/cmd.h> | 39 | #include <linux/mlx4/cmd.h> |
40 | #include <linux/gfp.h> | 40 | #include <linux/gfp.h> |
41 | #include <rdma/ib_pma.h> | 41 | #include <rdma/ib_pma.h> |
42 | #include <linux/ip.h> | ||
43 | #include <net/ipv6.h> | ||
42 | 44 | ||
43 | #include <linux/mlx4/driver.h> | 45 | #include <linux/mlx4/driver.h> |
44 | #include "mlx4_ib.h" | 46 | #include "mlx4_ib.h" |
@@ -480,6 +482,23 @@ static int find_slave_port_pkey_ix(struct mlx4_ib_dev *dev, int slave, | |||
480 | return -EINVAL; | 482 | return -EINVAL; |
481 | } | 483 | } |
482 | 484 | ||
485 | static int get_gids_from_l3_hdr(struct ib_grh *grh, union ib_gid *sgid, | ||
486 | union ib_gid *dgid) | ||
487 | { | ||
488 | int version = ib_get_rdma_header_version((const union rdma_network_hdr *)grh); | ||
489 | enum rdma_network_type net_type; | ||
490 | |||
491 | if (version == 4) | ||
492 | net_type = RDMA_NETWORK_IPV4; | ||
493 | else if (version == 6) | ||
494 | net_type = RDMA_NETWORK_IPV6; | ||
495 | else | ||
496 | return -EINVAL; | ||
497 | |||
498 | return ib_get_gids_from_rdma_hdr((union rdma_network_hdr *)grh, net_type, | ||
499 | sgid, dgid); | ||
500 | } | ||
501 | |||
483 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | 502 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, |
484 | enum ib_qp_type dest_qpt, struct ib_wc *wc, | 503 | enum ib_qp_type dest_qpt, struct ib_wc *wc, |
485 | struct ib_grh *grh, struct ib_mad *mad) | 504 | struct ib_grh *grh, struct ib_mad *mad) |
@@ -538,7 +557,10 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | |||
538 | memset(&attr, 0, sizeof attr); | 557 | memset(&attr, 0, sizeof attr); |
539 | attr.port_num = port; | 558 | attr.port_num = port; |
540 | if (is_eth) { | 559 | if (is_eth) { |
541 | memcpy(&attr.grh.dgid.raw[0], &grh->dgid.raw[0], 16); | 560 | union ib_gid sgid; |
561 | |||
562 | if (get_gids_from_l3_hdr(grh, &sgid, &attr.grh.dgid)) | ||
563 | return -EINVAL; | ||
542 | attr.ah_flags = IB_AH_GRH; | 564 | attr.ah_flags = IB_AH_GRH; |
543 | } | 565 | } |
544 | ah = ib_create_ah(tun_ctx->pd, &attr); | 566 | ah = ib_create_ah(tun_ctx->pd, &attr); |
@@ -651,6 +673,11 @@ static int mlx4_ib_demux_mad(struct ib_device *ibdev, u8 port, | |||
651 | is_eth = 1; | 673 | is_eth = 1; |
652 | 674 | ||
653 | if (is_eth) { | 675 | if (is_eth) { |
676 | union ib_gid dgid; | ||
677 | union ib_gid sgid; | ||
678 | |||
679 | if (get_gids_from_l3_hdr(grh, &sgid, &dgid)) | ||
680 | return -EINVAL; | ||
654 | if (!(wc->wc_flags & IB_WC_GRH)) { | 681 | if (!(wc->wc_flags & IB_WC_GRH)) { |
655 | mlx4_ib_warn(ibdev, "RoCE grh not present.\n"); | 682 | mlx4_ib_warn(ibdev, "RoCE grh not present.\n"); |
656 | return -EINVAL; | 683 | return -EINVAL; |
@@ -659,10 +686,10 @@ static int mlx4_ib_demux_mad(struct ib_device *ibdev, u8 port, | |||
659 | mlx4_ib_warn(ibdev, "RoCE mgmt class is not CM\n"); | 686 | mlx4_ib_warn(ibdev, "RoCE mgmt class is not CM\n"); |
660 | return -EINVAL; | 687 | return -EINVAL; |
661 | } | 688 | } |
662 | err = mlx4_get_slave_from_roce_gid(dev->dev, port, grh->dgid.raw, &slave); | 689 | err = mlx4_get_slave_from_roce_gid(dev->dev, port, dgid.raw, &slave); |
663 | if (err && mlx4_is_mf_bonded(dev->dev)) { | 690 | if (err && mlx4_is_mf_bonded(dev->dev)) { |
664 | other_port = (port == 1) ? 2 : 1; | 691 | other_port = (port == 1) ? 2 : 1; |
665 | err = mlx4_get_slave_from_roce_gid(dev->dev, other_port, grh->dgid.raw, &slave); | 692 | err = mlx4_get_slave_from_roce_gid(dev->dev, other_port, dgid.raw, &slave); |
666 | if (!err) { | 693 | if (!err) { |
667 | port = other_port; | 694 | port = other_port; |
668 | pr_debug("resolved slave %d from gid %pI6 wire port %d other %d\n", | 695 | pr_debug("resolved slave %d from gid %pI6 wire port %d other %d\n", |
@@ -702,10 +729,18 @@ static int mlx4_ib_demux_mad(struct ib_device *ibdev, u8 port, | |||
702 | 729 | ||
703 | /* If a grh is present, we demux according to it */ | 730 | /* If a grh is present, we demux according to it */ |
704 | if (wc->wc_flags & IB_WC_GRH) { | 731 | if (wc->wc_flags & IB_WC_GRH) { |
705 | slave = mlx4_ib_find_real_gid(ibdev, port, grh->dgid.global.interface_id); | 732 | if (grh->dgid.global.interface_id == |
706 | if (slave < 0) { | 733 | cpu_to_be64(IB_SA_WELL_KNOWN_GUID) && |
707 | mlx4_ib_warn(ibdev, "failed matching grh\n"); | 734 | grh->dgid.global.subnet_prefix == cpu_to_be64( |
708 | return -ENOENT; | 735 | atomic64_read(&dev->sriov.demux[port - 1].subnet_prefix))) { |
736 | slave = 0; | ||
737 | } else { | ||
738 | slave = mlx4_ib_find_real_gid(ibdev, port, | ||
739 | grh->dgid.global.interface_id); | ||
740 | if (slave < 0) { | ||
741 | mlx4_ib_warn(ibdev, "failed matching grh\n"); | ||
742 | return -ENOENT; | ||
743 | } | ||
709 | } | 744 | } |
710 | } | 745 | } |
711 | /* Class-specific handling */ | 746 | /* Class-specific handling */ |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 1b54786d13d0..6c61cf9a16a6 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -547,6 +547,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, | |||
547 | props->max_map_per_fmr = dev->dev->caps.max_fmr_maps; | 547 | props->max_map_per_fmr = dev->dev->caps.max_fmr_maps; |
548 | props->hca_core_clock = dev->dev->caps.hca_core_clock * 1000UL; | 548 | props->hca_core_clock = dev->dev->caps.hca_core_clock * 1000UL; |
549 | props->timestamp_mask = 0xFFFFFFFFFFFFULL; | 549 | props->timestamp_mask = 0xFFFFFFFFFFFFULL; |
550 | props->max_ah = INT_MAX; | ||
550 | 551 | ||
551 | if (!mlx4_is_slave(dev->dev)) | 552 | if (!mlx4_is_slave(dev->dev)) |
552 | err = mlx4_get_internal_clock_params(dev->dev, &clock_params); | 553 | err = mlx4_get_internal_clock_params(dev->dev, &clock_params); |
@@ -697,9 +698,11 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port, | |||
697 | if (err) | 698 | if (err) |
698 | goto out; | 699 | goto out; |
699 | 700 | ||
700 | props->active_width = (((u8 *)mailbox->buf)[5] == 0x40) ? | 701 | props->active_width = (((u8 *)mailbox->buf)[5] == 0x40) || |
701 | IB_WIDTH_4X : IB_WIDTH_1X; | 702 | (((u8 *)mailbox->buf)[5] == 0x20 /*56Gb*/) ? |
702 | props->active_speed = IB_SPEED_QDR; | 703 | IB_WIDTH_4X : IB_WIDTH_1X; |
704 | props->active_speed = (((u8 *)mailbox->buf)[5] == 0x20 /*56Gb*/) ? | ||
705 | IB_SPEED_FDR : IB_SPEED_QDR; | ||
703 | props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_IP_BASED_GIDS; | 706 | props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_IP_BASED_GIDS; |
704 | props->gid_tbl_len = mdev->dev->caps.gid_table_len[port]; | 707 | props->gid_tbl_len = mdev->dev->caps.gid_table_len[port]; |
705 | props->max_msg_sz = mdev->dev->caps.max_msg_sz; | 708 | props->max_msg_sz = mdev->dev->caps.max_msg_sz; |
@@ -2817,14 +2820,19 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2817 | if (!ibdev->ib_uc_qpns_bitmap) | 2820 | if (!ibdev->ib_uc_qpns_bitmap) |
2818 | goto err_steer_qp_release; | 2821 | goto err_steer_qp_release; |
2819 | 2822 | ||
2820 | bitmap_zero(ibdev->ib_uc_qpns_bitmap, ibdev->steer_qpn_count); | 2823 | if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_DMFS_IPOIB) { |
2821 | 2824 | bitmap_zero(ibdev->ib_uc_qpns_bitmap, | |
2822 | err = mlx4_FLOW_STEERING_IB_UC_QP_RANGE( | 2825 | ibdev->steer_qpn_count); |
2823 | dev, ibdev->steer_qpn_base, | 2826 | err = mlx4_FLOW_STEERING_IB_UC_QP_RANGE( |
2824 | ibdev->steer_qpn_base + | 2827 | dev, ibdev->steer_qpn_base, |
2825 | ibdev->steer_qpn_count - 1); | 2828 | ibdev->steer_qpn_base + |
2826 | if (err) | 2829 | ibdev->steer_qpn_count - 1); |
2827 | goto err_steer_free_bitmap; | 2830 | if (err) |
2831 | goto err_steer_free_bitmap; | ||
2832 | } else { | ||
2833 | bitmap_fill(ibdev->ib_uc_qpns_bitmap, | ||
2834 | ibdev->steer_qpn_count); | ||
2835 | } | ||
2828 | } | 2836 | } |
2829 | 2837 | ||
2830 | for (j = 1; j <= ibdev->dev->caps.num_ports; j++) | 2838 | for (j = 1; j <= ibdev->dev->caps.num_ports; j++) |
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index 35141f451e5c..7f3d976d81ed 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h | |||
@@ -742,7 +742,8 @@ int mlx4_ib_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags); | |||
742 | void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq); | 742 | void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq); |
743 | void mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq); | 743 | void mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq); |
744 | 744 | ||
745 | struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr); | 745 | struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr, |
746 | struct ib_udata *udata); | ||
746 | int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr); | 747 | int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr); |
747 | int mlx4_ib_destroy_ah(struct ib_ah *ah); | 748 | int mlx4_ib_destroy_ah(struct ib_ah *ah); |
748 | 749 | ||
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 570bc866b1d6..c068add8838b 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -644,7 +644,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
644 | int qpn; | 644 | int qpn; |
645 | int err; | 645 | int err; |
646 | struct ib_qp_cap backup_cap; | 646 | struct ib_qp_cap backup_cap; |
647 | struct mlx4_ib_sqp *sqp; | 647 | struct mlx4_ib_sqp *sqp = NULL; |
648 | struct mlx4_ib_qp *qp; | 648 | struct mlx4_ib_qp *qp; |
649 | enum mlx4_ib_qp_type qp_type = (enum mlx4_ib_qp_type) init_attr->qp_type; | 649 | enum mlx4_ib_qp_type qp_type = (enum mlx4_ib_qp_type) init_attr->qp_type; |
650 | struct mlx4_ib_cq *mcq; | 650 | struct mlx4_ib_cq *mcq; |
@@ -933,7 +933,9 @@ err_db: | |||
933 | mlx4_db_free(dev->dev, &qp->db); | 933 | mlx4_db_free(dev->dev, &qp->db); |
934 | 934 | ||
935 | err: | 935 | err: |
936 | if (!*caller_qp) | 936 | if (sqp) |
937 | kfree(sqp); | ||
938 | else if (!*caller_qp) | ||
937 | kfree(qp); | 939 | kfree(qp); |
938 | return err; | 940 | return err; |
939 | } | 941 | } |
@@ -1280,7 +1282,8 @@ static int _mlx4_ib_destroy_qp(struct ib_qp *qp) | |||
1280 | if (is_qp0(dev, mqp)) | 1282 | if (is_qp0(dev, mqp)) |
1281 | mlx4_CLOSE_PORT(dev->dev, mqp->port); | 1283 | mlx4_CLOSE_PORT(dev->dev, mqp->port); |
1282 | 1284 | ||
1283 | if (dev->qp1_proxy[mqp->port - 1] == mqp) { | 1285 | if (mqp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI && |
1286 | dev->qp1_proxy[mqp->port - 1] == mqp) { | ||
1284 | mutex_lock(&dev->qp1_proxy_lock[mqp->port - 1]); | 1287 | mutex_lock(&dev->qp1_proxy_lock[mqp->port - 1]); |
1285 | dev->qp1_proxy[mqp->port - 1] = NULL; | 1288 | dev->qp1_proxy[mqp->port - 1] = NULL; |
1286 | mutex_unlock(&dev->qp1_proxy_lock[mqp->port - 1]); | 1289 | mutex_unlock(&dev->qp1_proxy_lock[mqp->port - 1]); |
@@ -1764,14 +1767,14 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
1764 | u8 port_num = mlx4_is_bonded(to_mdev(ibqp->device)->dev) ? 1 : | 1767 | u8 port_num = mlx4_is_bonded(to_mdev(ibqp->device)->dev) ? 1 : |
1765 | attr_mask & IB_QP_PORT ? attr->port_num : qp->port; | 1768 | attr_mask & IB_QP_PORT ? attr->port_num : qp->port; |
1766 | union ib_gid gid; | 1769 | union ib_gid gid; |
1767 | struct ib_gid_attr gid_attr; | 1770 | struct ib_gid_attr gid_attr = {.gid_type = IB_GID_TYPE_IB}; |
1768 | u16 vlan = 0xffff; | 1771 | u16 vlan = 0xffff; |
1769 | u8 smac[ETH_ALEN]; | 1772 | u8 smac[ETH_ALEN]; |
1770 | int status = 0; | 1773 | int status = 0; |
1771 | int is_eth = rdma_cap_eth_ah(&dev->ib_dev, port_num) && | 1774 | int is_eth = rdma_cap_eth_ah(&dev->ib_dev, port_num) && |
1772 | attr->ah_attr.ah_flags & IB_AH_GRH; | 1775 | attr->ah_attr.ah_flags & IB_AH_GRH; |
1773 | 1776 | ||
1774 | if (is_eth) { | 1777 | if (is_eth && attr->ah_attr.ah_flags & IB_AH_GRH) { |
1775 | int index = attr->ah_attr.grh.sgid_index; | 1778 | int index = attr->ah_attr.grh.sgid_index; |
1776 | 1779 | ||
1777 | status = ib_get_cached_gid(ibqp->device, port_num, | 1780 | status = ib_get_cached_gid(ibqp->device, port_num, |