aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx4
diff options
context:
space:
mode:
authorDoug Ledford <dledford@redhat.com>2016-12-14 14:44:25 -0500
committerDoug Ledford <dledford@redhat.com>2016-12-14 14:44:25 -0500
commit86ef0beaa0bdbec70d4261977b8b4a100fe54bfe (patch)
treed2c1b52a7a6e493bada10dbdbcd2f8511baccc66 /drivers/infiniband/hw/mlx4
parent253f8b22e0ad643edafd75e831e5c765732877f5 (diff)
parent7ceb740c540dde362b3055ad92c6a38009eb7a83 (diff)
Merge branch 'mlx' into merge-test
Diffstat (limited to 'drivers/infiniband/hw/mlx4')
-rw-r--r--drivers/infiniband/hw/mlx4/ah.c10
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c49
-rw-r--r--drivers/infiniband/hw/mlx4/main.c30
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h3
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c13
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
127struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) 129struct 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
485static 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
483int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, 502int 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);
742void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq); 742void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
743void mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq); 743void mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
744 744
745struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr); 745struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
746 struct ib_udata *udata);
746int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr); 747int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr);
747int mlx4_ib_destroy_ah(struct ib_ah *ah); 748int 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
935err: 935err:
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,