diff options
| -rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 12 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 104 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 173 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.h | 14 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 61 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/qp.c | 71 | ||||
| -rw-r--r-- | include/linux/mlx4/device.h | 16 |
7 files changed, 290 insertions, 161 deletions
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 603a114b3dfe..658a622791fb 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
| @@ -505,7 +505,7 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | |||
| 505 | } else | 505 | } else |
| 506 | tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0]; | 506 | tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0]; |
| 507 | 507 | ||
| 508 | dqpn = dev->dev->caps.sqp_start + 8 * slave + port + (dest_qpt * 2) - 1; | 508 | dqpn = dev->dev->phys_caps.base_proxy_sqpn + 8 * slave + port + (dest_qpt * 2) - 1; |
| 509 | 509 | ||
| 510 | /* get tunnel tx data buf for slave */ | 510 | /* get tunnel tx data buf for slave */ |
| 511 | src_qp = tun_qp->qp; | 511 | src_qp = tun_qp->qp; |
| @@ -1074,9 +1074,9 @@ static int mlx4_ib_multiplex_sa_handler(struct ib_device *ibdev, int port, | |||
| 1074 | 1074 | ||
| 1075 | static int is_proxy_qp0(struct mlx4_ib_dev *dev, int qpn, int slave) | 1075 | static int is_proxy_qp0(struct mlx4_ib_dev *dev, int qpn, int slave) |
| 1076 | { | 1076 | { |
| 1077 | int slave_start = dev->dev->caps.sqp_start + 8 * slave; | 1077 | int proxy_start = dev->dev->phys_caps.base_proxy_sqpn + 8 * slave; |
| 1078 | 1078 | ||
| 1079 | return (qpn >= slave_start && qpn <= slave_start + 1); | 1079 | return (qpn >= proxy_start && qpn <= proxy_start + 1); |
| 1080 | } | 1080 | } |
| 1081 | 1081 | ||
| 1082 | 1082 | ||
| @@ -1191,14 +1191,14 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc | |||
| 1191 | int slave; | 1191 | int slave; |
| 1192 | 1192 | ||
| 1193 | /* Get slave that sent this packet */ | 1193 | /* Get slave that sent this packet */ |
| 1194 | if (wc->src_qp < dev->dev->caps.sqp_start || | 1194 | if (wc->src_qp < dev->dev->phys_caps.base_proxy_sqpn || |
| 1195 | wc->src_qp >= dev->dev->caps.base_tunnel_sqpn || | 1195 | wc->src_qp >= dev->dev->phys_caps.base_proxy_sqpn + 8 * MLX4_MFUNC_MAX || |
| 1196 | (wc->src_qp & 0x1) != ctx->port - 1 || | 1196 | (wc->src_qp & 0x1) != ctx->port - 1 || |
| 1197 | wc->src_qp & 0x4) { | 1197 | wc->src_qp & 0x4) { |
| 1198 | mlx4_ib_warn(ctx->ib_dev, "can't multiplex bad sqp:%d\n", wc->src_qp); | 1198 | mlx4_ib_warn(ctx->ib_dev, "can't multiplex bad sqp:%d\n", wc->src_qp); |
| 1199 | return; | 1199 | return; |
| 1200 | } | 1200 | } |
| 1201 | slave = ((wc->src_qp & ~0x7) - dev->dev->caps.sqp_start) / 8; | 1201 | slave = ((wc->src_qp & ~0x7) - dev->dev->phys_caps.base_proxy_sqpn) / 8; |
| 1202 | if (slave != ctx->slave) { | 1202 | if (slave != ctx->slave) { |
| 1203 | mlx4_ib_warn(ctx->ib_dev, "can't multiplex bad sqp:%d: " | 1203 | mlx4_ib_warn(ctx->ib_dev, "can't multiplex bad sqp:%d: " |
| 1204 | "belongs to another slave\n", wc->src_qp); | 1204 | "belongs to another slave\n", wc->src_qp); |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index a8622510de42..96fe103f5973 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -116,33 +116,57 @@ static int is_tunnel_qp(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) | |||
| 116 | if (!mlx4_is_master(dev->dev)) | 116 | if (!mlx4_is_master(dev->dev)) |
| 117 | return 0; | 117 | return 0; |
| 118 | 118 | ||
| 119 | return qp->mqp.qpn >= dev->dev->caps.base_sqpn && | 119 | return qp->mqp.qpn >= dev->dev->phys_caps.base_tunnel_sqpn && |
| 120 | qp->mqp.qpn < dev->dev->caps.base_sqpn + | 120 | qp->mqp.qpn < dev->dev->phys_caps.base_tunnel_sqpn + |
| 121 | 8 + 16 * MLX4_MFUNC_MAX; | 121 | 8 * MLX4_MFUNC_MAX; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | static int is_sqp(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) | 124 | static int is_sqp(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) |
| 125 | { | 125 | { |
| 126 | return ((mlx4_is_master(dev->dev) && | 126 | int proxy_sqp = 0; |
| 127 | qp->mqp.qpn >= dev->dev->caps.base_sqpn && | 127 | int real_sqp = 0; |
| 128 | qp->mqp.qpn <= dev->dev->caps.base_sqpn + 3) || | 128 | int i; |
| 129 | (qp->mqp.qpn >= dev->dev->caps.sqp_start && | 129 | /* PPF or Native -- real SQP */ |
| 130 | qp->mqp.qpn <= dev->dev->caps.sqp_start + 3)); | 130 | real_sqp = ((mlx4_is_master(dev->dev) || !mlx4_is_mfunc(dev->dev)) && |
| 131 | qp->mqp.qpn >= dev->dev->phys_caps.base_sqpn && | ||
| 132 | qp->mqp.qpn <= dev->dev->phys_caps.base_sqpn + 3); | ||
| 133 | if (real_sqp) | ||
| 134 | return 1; | ||
| 135 | /* VF or PF -- proxy SQP */ | ||
| 136 | if (mlx4_is_mfunc(dev->dev)) { | ||
| 137 | for (i = 0; i < dev->dev->caps.num_ports; i++) { | ||
| 138 | if (qp->mqp.qpn == dev->dev->caps.qp0_proxy[i] || | ||
| 139 | qp->mqp.qpn == dev->dev->caps.qp1_proxy[i]) { | ||
| 140 | proxy_sqp = 1; | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | } | ||
| 144 | } | ||
| 145 | return proxy_sqp; | ||
| 131 | } | 146 | } |
| 132 | 147 | ||
| 133 | /* used for INIT/CLOSE port logic */ | 148 | /* used for INIT/CLOSE port logic */ |
| 134 | static int is_qp0(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) | 149 | static int is_qp0(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) |
| 135 | { | 150 | { |
| 136 | int qp0; | 151 | int proxy_qp0 = 0; |
| 137 | 152 | int real_qp0 = 0; | |
| 138 | /* qp0 is either the proxy qp0, or the real qp0 */ | 153 | int i; |
| 139 | qp0 = (qp->mqp.qpn >= dev->dev->caps.sqp_start && | 154 | /* PPF or Native -- real QP0 */ |
| 140 | qp->mqp.qpn <= dev->dev->caps.sqp_start + 1) || | 155 | real_qp0 = ((mlx4_is_master(dev->dev) || !mlx4_is_mfunc(dev->dev)) && |
| 141 | (mlx4_is_master(dev->dev) && | 156 | qp->mqp.qpn >= dev->dev->phys_caps.base_sqpn && |
| 142 | qp->mqp.qpn >= dev->dev->caps.base_sqpn && | 157 | qp->mqp.qpn <= dev->dev->phys_caps.base_sqpn + 1); |
| 143 | qp->mqp.qpn <= dev->dev->caps.base_sqpn + 1); | 158 | if (real_qp0) |
| 144 | 159 | return 1; | |
| 145 | return qp0; | 160 | /* VF or PF -- proxy QP0 */ |
| 161 | if (mlx4_is_mfunc(dev->dev)) { | ||
| 162 | for (i = 0; i < dev->dev->caps.num_ports; i++) { | ||
| 163 | if (qp->mqp.qpn == dev->dev->caps.qp0_proxy[i]) { | ||
| 164 | proxy_qp0 = 1; | ||
| 165 | break; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | } | ||
| 169 | return proxy_qp0; | ||
| 146 | } | 170 | } |
| 147 | 171 | ||
| 148 | static void *get_wqe(struct mlx4_ib_qp *qp, int offset) | 172 | static void *get_wqe(struct mlx4_ib_qp *qp, int offset) |
| @@ -607,8 +631,10 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
| 607 | qp_type = MLX4_IB_QPT_TUN_SMI_OWNER; | 631 | qp_type = MLX4_IB_QPT_TUN_SMI_OWNER; |
| 608 | else | 632 | else |
| 609 | qp_type = MLX4_IB_QPT_TUN_SMI; | 633 | qp_type = MLX4_IB_QPT_TUN_SMI; |
| 610 | qpn = dev->dev->caps.base_tunnel_sqpn + 8 * tnl_init->slave + | 634 | /* we are definitely in the PPF here, since we are creating |
| 611 | tnl_init->proxy_qp_type * 2 + tnl_init->port - 1; | 635 | * tunnel QPs. base_tunnel_sqpn is therefore valid. */ |
| 636 | qpn = dev->dev->phys_caps.base_tunnel_sqpn + 8 * tnl_init->slave | ||
| 637 | + tnl_init->proxy_qp_type * 2 + tnl_init->port - 1; | ||
| 612 | sqpn = qpn; | 638 | sqpn = qpn; |
| 613 | } | 639 | } |
| 614 | 640 | ||
| @@ -630,12 +656,6 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
| 630 | 656 | ||
| 631 | qp->mlx4_ib_qp_type = qp_type; | 657 | qp->mlx4_ib_qp_type = qp_type; |
| 632 | 658 | ||
| 633 | if (mlx4_is_mfunc(dev->dev) && | ||
| 634 | (qp_type == MLX4_IB_QPT_SMI || qp_type == MLX4_IB_QPT_GSI)) { | ||
| 635 | qpn -= 8; | ||
| 636 | sqpn -= 8; | ||
| 637 | } | ||
| 638 | |||
| 639 | mutex_init(&qp->mutex); | 659 | mutex_init(&qp->mutex); |
| 640 | spin_lock_init(&qp->sq.lock); | 660 | spin_lock_init(&qp->sq.lock); |
| 641 | spin_lock_init(&qp->rq.lock); | 661 | spin_lock_init(&qp->rq.lock); |
| @@ -935,6 +955,23 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, | |||
| 935 | del_gid_entries(qp); | 955 | del_gid_entries(qp); |
| 936 | } | 956 | } |
| 937 | 957 | ||
| 958 | static u32 get_sqp_num(struct mlx4_ib_dev *dev, struct ib_qp_init_attr *attr) | ||
| 959 | { | ||
| 960 | /* Native or PPF */ | ||
| 961 | if (!mlx4_is_mfunc(dev->dev) || | ||
| 962 | (mlx4_is_master(dev->dev) && | ||
| 963 | attr->create_flags & MLX4_IB_SRIOV_SQP)) { | ||
| 964 | return dev->dev->phys_caps.base_sqpn + | ||
| 965 | (attr->qp_type == IB_QPT_SMI ? 0 : 2) + | ||
| 966 | attr->port_num - 1; | ||
| 967 | } | ||
| 968 | /* PF or VF -- creating proxies */ | ||
| 969 | if (attr->qp_type == IB_QPT_SMI) | ||
| 970 | return dev->dev->caps.qp0_proxy[attr->port_num - 1]; | ||
| 971 | else | ||
| 972 | return dev->dev->caps.qp1_proxy[attr->port_num - 1]; | ||
| 973 | } | ||
| 974 | |||
| 938 | struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | 975 | struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, |
| 939 | struct ib_qp_init_attr *init_attr, | 976 | struct ib_qp_init_attr *init_attr, |
| 940 | struct ib_udata *udata) | 977 | struct ib_udata *udata) |
| @@ -998,9 +1035,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | |||
| 998 | return ERR_PTR(-EINVAL); | 1035 | return ERR_PTR(-EINVAL); |
| 999 | 1036 | ||
| 1000 | err = create_qp_common(to_mdev(pd->device), pd, init_attr, udata, | 1037 | err = create_qp_common(to_mdev(pd->device), pd, init_attr, udata, |
| 1001 | to_mdev(pd->device)->dev->caps.sqp_start + | 1038 | get_sqp_num(to_mdev(pd->device), init_attr), |
| 1002 | (init_attr->qp_type == IB_QPT_SMI ? 0 : 2) + | ||
| 1003 | init_attr->port_num - 1, | ||
| 1004 | &qp); | 1039 | &qp); |
| 1005 | if (err) | 1040 | if (err) |
| 1006 | return ERR_PTR(err); | 1041 | return ERR_PTR(err); |
| @@ -1643,8 +1678,7 @@ static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp, | |||
| 1643 | sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->wr.ud.remote_qpn); | 1678 | sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->wr.ud.remote_qpn); |
| 1644 | else | 1679 | else |
| 1645 | sqp->ud_header.bth.destination_qpn = | 1680 | sqp->ud_header.bth.destination_qpn = |
| 1646 | cpu_to_be32(mdev->dev->caps.base_tunnel_sqpn + | 1681 | cpu_to_be32(mdev->dev->caps.qp0_tunnel[sqp->qp.port - 1]); |
| 1647 | sqp->qp.port - 1); | ||
| 1648 | 1682 | ||
| 1649 | sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1)); | 1683 | sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1)); |
| 1650 | if (mlx4_get_parav_qkey(mdev->dev, sqp->qp.mqp.qpn, &qkey)) | 1684 | if (mlx4_get_parav_qkey(mdev->dev, sqp->qp.mqp.qpn, &qkey)) |
| @@ -2012,10 +2046,10 @@ static void set_tunnel_datagram_seg(struct mlx4_ib_dev *dev, | |||
| 2012 | cpu_to_be32(0xf0000000); | 2046 | cpu_to_be32(0xf0000000); |
| 2013 | 2047 | ||
| 2014 | memcpy(dseg->av, &sqp_av, sizeof (struct mlx4_av)); | 2048 | memcpy(dseg->av, &sqp_av, sizeof (struct mlx4_av)); |
| 2015 | dseg->dqpn = cpu_to_be32(dev->dev->caps.base_tunnel_sqpn + | 2049 | /* This function used only for sending on QP1 proxies */ |
| 2016 | qpt * 2 + port - 1); | 2050 | dseg->dqpn = cpu_to_be32(dev->dev->caps.qp1_tunnel[port - 1]); |
| 2017 | /* use well-known qkey from the QPC */ | 2051 | /* Use QKEY from the QP context, which is set by master */ |
| 2018 | dseg->qkey = cpu_to_be32(0x80000000); | 2052 | dseg->qkey = cpu_to_be32(IB_QP_SET_QKEY); |
| 2019 | } | 2053 | } |
| 2020 | 2054 | ||
| 2021 | static void build_tunnel_header(struct ib_send_wr *wr, void *wqe, unsigned *mlx_seg_len) | 2055 | static void build_tunnel_header(struct ib_send_wr *wr, void *wqe, unsigned *mlx_seg_len) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 1d74e8541146..e2ed36e2fb29 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
| @@ -184,8 +184,6 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
| 184 | #define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET 0x28 | 184 | #define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET 0x28 |
| 185 | #define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c | 185 | #define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c |
| 186 | #define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0X30 | 186 | #define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0X30 |
| 187 | #define QUERY_FUNC_CAP_BASE_TUNNEL_QPN_OFFSET 0x44 | ||
| 188 | #define QUERY_FUNC_CAP_BASE_PROXY_QPN_OFFSET 0x48 | ||
| 189 | 187 | ||
| 190 | #define QUERY_FUNC_CAP_FMR_FLAG 0x80 | 188 | #define QUERY_FUNC_CAP_FMR_FLAG 0x80 |
| 191 | #define QUERY_FUNC_CAP_FLAG_RDMA 0x40 | 189 | #define QUERY_FUNC_CAP_FLAG_RDMA 0x40 |
| @@ -196,21 +194,39 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
| 196 | #define QUERY_FUNC_CAP_RDMA_PROPS_OFFSET 0x8 | 194 | #define QUERY_FUNC_CAP_RDMA_PROPS_OFFSET 0x8 |
| 197 | #define QUERY_FUNC_CAP_ETH_PROPS_OFFSET 0xc | 195 | #define QUERY_FUNC_CAP_ETH_PROPS_OFFSET 0xc |
| 198 | 196 | ||
| 197 | #define QUERY_FUNC_CAP_QP0_TUNNEL 0x10 | ||
| 198 | #define QUERY_FUNC_CAP_QP0_PROXY 0x14 | ||
| 199 | #define QUERY_FUNC_CAP_QP1_TUNNEL 0x18 | ||
| 200 | #define QUERY_FUNC_CAP_QP1_PROXY 0x1c | ||
| 201 | |||
| 199 | #define QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC 0x40 | 202 | #define QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC 0x40 |
| 200 | #define QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN 0x80 | 203 | #define QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN 0x80 |
| 201 | 204 | ||
| 202 | #define QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID 0x80 | 205 | #define QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID 0x80 |
| 203 | 206 | ||
| 204 | if (vhcr->op_modifier == 1) { | 207 | if (vhcr->op_modifier == 1) { |
| 205 | field = vhcr->in_modifier; | ||
| 206 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); | ||
| 207 | |||
| 208 | field = 0; | 208 | field = 0; |
| 209 | /* ensure force vlan and force mac bits are not set */ | 209 | /* ensure force vlan and force mac bits are not set */ |
| 210 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); | 210 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); |
| 211 | /* ensure that phy_wqe_gid bit is not set */ | 211 | /* ensure that phy_wqe_gid bit is not set */ |
| 212 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET); | 212 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET); |
| 213 | 213 | ||
| 214 | field = vhcr->in_modifier; /* phys-port = logical-port */ | ||
| 215 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); | ||
| 216 | |||
| 217 | /* size is now the QP number */ | ||
| 218 | size = dev->phys_caps.base_tunnel_sqpn + 8 * slave + field - 1; | ||
| 219 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_TUNNEL); | ||
| 220 | |||
| 221 | size += 2; | ||
| 222 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_TUNNEL); | ||
| 223 | |||
| 224 | size = dev->phys_caps.base_proxy_sqpn + 8 * slave + field - 1; | ||
| 225 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_PROXY); | ||
| 226 | |||
| 227 | size += 2; | ||
| 228 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_PROXY); | ||
| 229 | |||
| 214 | } else if (vhcr->op_modifier == 0) { | 230 | } else if (vhcr->op_modifier == 0) { |
| 215 | /* enable rdma and ethernet interfaces */ | 231 | /* enable rdma and ethernet interfaces */ |
| 216 | field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA); | 232 | field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA); |
| @@ -249,117 +265,124 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
| 249 | size = dev->caps.num_mgms + dev->caps.num_amgms; | 265 | size = dev->caps.num_mgms + dev->caps.num_amgms; |
| 250 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET); | 266 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET); |
| 251 | 267 | ||
| 252 | size = dev->caps.base_tunnel_sqpn + 8 * slave; | ||
| 253 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_BASE_TUNNEL_QPN_OFFSET); | ||
| 254 | |||
| 255 | size = dev->caps.sqp_start + 8 * slave; | ||
| 256 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_BASE_PROXY_QPN_OFFSET); | ||
| 257 | |||
| 258 | } else | 268 | } else |
| 259 | err = -EINVAL; | 269 | err = -EINVAL; |
| 260 | 270 | ||
| 261 | return err; | 271 | return err; |
| 262 | } | 272 | } |
| 263 | 273 | ||
| 264 | int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap) | 274 | int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port, |
| 275 | struct mlx4_func_cap *func_cap) | ||
| 265 | { | 276 | { |
| 266 | struct mlx4_cmd_mailbox *mailbox; | 277 | struct mlx4_cmd_mailbox *mailbox; |
| 267 | u32 *outbox; | 278 | u32 *outbox; |
| 268 | u8 field; | 279 | u8 field, op_modifier; |
| 269 | u32 size; | 280 | u32 size; |
| 270 | int i; | ||
| 271 | int err = 0; | 281 | int err = 0; |
| 272 | 282 | ||
| 283 | op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */ | ||
| 273 | 284 | ||
| 274 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 285 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
| 275 | if (IS_ERR(mailbox)) | 286 | if (IS_ERR(mailbox)) |
| 276 | return PTR_ERR(mailbox); | 287 | return PTR_ERR(mailbox); |
| 277 | 288 | ||
| 278 | err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_FUNC_CAP, | 289 | err = mlx4_cmd_box(dev, 0, mailbox->dma, gen_or_port, op_modifier, |
| 290 | MLX4_CMD_QUERY_FUNC_CAP, | ||
| 279 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); | 291 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); |
| 280 | if (err) | 292 | if (err) |
| 281 | goto out; | 293 | goto out; |
| 282 | 294 | ||
| 283 | outbox = mailbox->buf; | 295 | outbox = mailbox->buf; |
| 284 | 296 | ||
| 285 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS_OFFSET); | 297 | if (!op_modifier) { |
| 286 | if (!(field & (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA))) { | 298 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS_OFFSET); |
| 287 | mlx4_err(dev, "The host supports neither eth nor rdma interfaces\n"); | 299 | if (!(field & (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA))) { |
| 288 | err = -EPROTONOSUPPORT; | 300 | mlx4_err(dev, "The host supports neither eth nor rdma interfaces\n"); |
| 289 | goto out; | 301 | err = -EPROTONOSUPPORT; |
| 290 | } | 302 | goto out; |
| 291 | func_cap->flags = field; | 303 | } |
| 292 | 304 | func_cap->flags = field; | |
| 293 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); | ||
| 294 | func_cap->num_ports = field; | ||
| 295 | 305 | ||
| 296 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_PF_BHVR_OFFSET); | 306 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); |
| 297 | func_cap->pf_context_behaviour = size; | 307 | func_cap->num_ports = field; |
| 298 | 308 | ||
| 299 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); | 309 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_PF_BHVR_OFFSET); |
| 300 | func_cap->qp_quota = size & 0xFFFFFF; | 310 | func_cap->pf_context_behaviour = size; |
| 301 | 311 | ||
| 302 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); | 312 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); |
| 303 | func_cap->srq_quota = size & 0xFFFFFF; | 313 | func_cap->qp_quota = size & 0xFFFFFF; |
| 304 | 314 | ||
| 305 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); | 315 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); |
| 306 | func_cap->cq_quota = size & 0xFFFFFF; | 316 | func_cap->srq_quota = size & 0xFFFFFF; |
| 307 | 317 | ||
| 308 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_MAX_EQ_OFFSET); | 318 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); |
| 309 | func_cap->max_eq = size & 0xFFFFFF; | 319 | func_cap->cq_quota = size & 0xFFFFFF; |
| 310 | 320 | ||
| 311 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); | 321 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_MAX_EQ_OFFSET); |
| 312 | func_cap->reserved_eq = size & 0xFFFFFF; | 322 | func_cap->max_eq = size & 0xFFFFFF; |
| 313 | 323 | ||
| 314 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); | 324 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); |
| 315 | func_cap->mpt_quota = size & 0xFFFFFF; | 325 | func_cap->reserved_eq = size & 0xFFFFFF; |
| 316 | 326 | ||
| 317 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET); | 327 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); |
| 318 | func_cap->mtt_quota = size & 0xFFFFFF; | 328 | func_cap->mpt_quota = size & 0xFFFFFF; |
| 319 | 329 | ||
| 320 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET); | 330 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET); |
| 321 | func_cap->mcg_quota = size & 0xFFFFFF; | 331 | func_cap->mtt_quota = size & 0xFFFFFF; |
| 322 | 332 | ||
| 323 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_BASE_TUNNEL_QPN_OFFSET); | 333 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET); |
| 324 | func_cap->base_tunnel_qpn = size & 0xFFFFFF; | 334 | func_cap->mcg_quota = size & 0xFFFFFF; |
| 335 | goto out; | ||
| 336 | } | ||
| 325 | 337 | ||
| 326 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_BASE_PROXY_QPN_OFFSET); | 338 | /* logical port query */ |
| 327 | func_cap->base_proxy_qpn = size & 0xFFFFFF; | 339 | if (gen_or_port > dev->caps.num_ports) { |
| 340 | err = -EINVAL; | ||
| 341 | goto out; | ||
| 342 | } | ||
| 328 | 343 | ||
| 329 | for (i = 1; i <= func_cap->num_ports; ++i) { | 344 | if (dev->caps.port_type[gen_or_port] == MLX4_PORT_TYPE_ETH) { |
| 330 | err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 1, | 345 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); |
| 331 | MLX4_CMD_QUERY_FUNC_CAP, | 346 | if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN) { |
| 332 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); | 347 | mlx4_err(dev, "VLAN is enforced on this port\n"); |
| 333 | if (err) | 348 | err = -EPROTONOSUPPORT; |
| 334 | goto out; | 349 | goto out; |
| 350 | } | ||
| 335 | 351 | ||
| 336 | if (dev->caps.port_type[i] == MLX4_PORT_TYPE_ETH) { | 352 | if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC) { |
| 337 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); | 353 | mlx4_err(dev, "Force mac is enabled on this port\n"); |
| 338 | if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN) { | 354 | err = -EPROTONOSUPPORT; |
| 339 | mlx4_err(dev, "VLAN is enforced on this port\n"); | 355 | goto out; |
| 340 | err = -EPROTONOSUPPORT; | 356 | } |
| 341 | goto out; | 357 | } else if (dev->caps.port_type[gen_or_port] == MLX4_PORT_TYPE_IB) { |
| 342 | } | 358 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET); |
| 343 | 359 | if (field & QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID) { | |
| 344 | if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC) { | 360 | mlx4_err(dev, "phy_wqe_gid is " |
| 345 | mlx4_err(dev, "Force mac is enabled on this port\n"); | 361 | "enforced on this ib port\n"); |
| 346 | err = -EPROTONOSUPPORT; | 362 | err = -EPROTONOSUPPORT; |
| 347 | goto out; | 363 | goto out; |
| 348 | } | ||
| 349 | } else if (dev->caps.port_type[i] == MLX4_PORT_TYPE_IB) { | ||
| 350 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET); | ||
| 351 | if (field & QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID) { | ||
| 352 | mlx4_err(dev, "phy_wqe_gid is " | ||
| 353 | "enforced on this ib port\n"); | ||
| 354 | err = -EPROTONOSUPPORT; | ||
| 355 | goto out; | ||
| 356 | } | ||
| 357 | } | 364 | } |
| 365 | } | ||
| 358 | 366 | ||
| 359 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); | 367 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); |
| 360 | func_cap->physical_port[i] = field; | 368 | func_cap->physical_port = field; |
| 369 | if (func_cap->physical_port != gen_or_port) { | ||
| 370 | err = -ENOSYS; | ||
| 371 | goto out; | ||
| 361 | } | 372 | } |
| 362 | 373 | ||
| 374 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP0_TUNNEL); | ||
| 375 | func_cap->qp0_tunnel_qpn = size & 0xFFFFFF; | ||
| 376 | |||
| 377 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP0_PROXY); | ||
| 378 | func_cap->qp0_proxy_qpn = size & 0xFFFFFF; | ||
| 379 | |||
| 380 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP1_TUNNEL); | ||
| 381 | func_cap->qp1_tunnel_qpn = size & 0xFFFFFF; | ||
| 382 | |||
| 383 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP1_PROXY); | ||
| 384 | func_cap->qp1_proxy_qpn = size & 0xFFFFFF; | ||
| 385 | |||
| 363 | /* All other resources are allocated by the master, but we still report | 386 | /* All other resources are allocated by the master, but we still report |
| 364 | * 'num' and 'reserved' capabilities as follows: | 387 | * 'num' and 'reserved' capabilities as follows: |
| 365 | * - num remains the maximum resource index | 388 | * - num remains the maximum resource index |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index ced1de57c818..85abe9c11a22 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h | |||
| @@ -134,11 +134,12 @@ struct mlx4_func_cap { | |||
| 134 | int max_eq; | 134 | int max_eq; |
| 135 | int reserved_eq; | 135 | int reserved_eq; |
| 136 | int mcg_quota; | 136 | int mcg_quota; |
| 137 | u32 base_qpn; | 137 | u32 qp0_tunnel_qpn; |
| 138 | u32 base_tunnel_qpn; | 138 | u32 qp0_proxy_qpn; |
| 139 | u32 base_proxy_qpn; | 139 | u32 qp1_tunnel_qpn; |
| 140 | u8 physical_port[MLX4_MAX_PORTS + 1]; | 140 | u32 qp1_proxy_qpn; |
| 141 | u8 port_flags[MLX4_MAX_PORTS + 1]; | 141 | u8 physical_port; |
| 142 | u8 port_flags; | ||
| 142 | }; | 143 | }; |
| 143 | 144 | ||
| 144 | struct mlx4_adapter { | 145 | struct mlx4_adapter { |
| @@ -195,7 +196,8 @@ struct mlx4_set_ib_param { | |||
| 195 | }; | 196 | }; |
| 196 | 197 | ||
| 197 | int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap); | 198 | int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap); |
| 198 | int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap); | 199 | int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port, |
| 200 | struct mlx4_func_cap *func_cap); | ||
| 199 | int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | 201 | int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, |
| 200 | struct mlx4_vhcr *vhcr, | 202 | struct mlx4_vhcr *vhcr, |
| 201 | struct mlx4_cmd_mailbox *inbox, | 203 | struct mlx4_cmd_mailbox *inbox, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 76f69fdd01d5..1e2ab9d00f1c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
| @@ -410,15 +410,16 @@ static int mlx4_how_many_lives_vf(struct mlx4_dev *dev) | |||
| 410 | int mlx4_get_parav_qkey(struct mlx4_dev *dev, u32 qpn, u32 *qkey) | 410 | int mlx4_get_parav_qkey(struct mlx4_dev *dev, u32 qpn, u32 *qkey) |
| 411 | { | 411 | { |
| 412 | u32 qk = MLX4_RESERVED_QKEY_BASE; | 412 | u32 qk = MLX4_RESERVED_QKEY_BASE; |
| 413 | if (qpn >= dev->caps.base_tunnel_sqpn + 8 * MLX4_MFUNC_MAX || | 413 | |
| 414 | qpn < dev->caps.sqp_start) | 414 | if (qpn >= dev->phys_caps.base_tunnel_sqpn + 8 * MLX4_MFUNC_MAX || |
| 415 | qpn < dev->phys_caps.base_proxy_sqpn) | ||
| 415 | return -EINVAL; | 416 | return -EINVAL; |
| 416 | 417 | ||
| 417 | if (qpn >= dev->caps.base_tunnel_sqpn) | 418 | if (qpn >= dev->phys_caps.base_tunnel_sqpn) |
| 418 | /* tunnel qp */ | 419 | /* tunnel qp */ |
| 419 | qk += qpn - dev->caps.base_tunnel_sqpn; | 420 | qk += qpn - dev->phys_caps.base_tunnel_sqpn; |
| 420 | else | 421 | else |
| 421 | qk += qpn - dev->caps.sqp_start; | 422 | qk += qpn - dev->phys_caps.base_proxy_sqpn; |
| 422 | *qkey = qk; | 423 | *qkey = qk; |
| 423 | return 0; | 424 | return 0; |
| 424 | } | 425 | } |
| @@ -527,9 +528,10 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) | |||
| 527 | } | 528 | } |
| 528 | 529 | ||
| 529 | memset(&func_cap, 0, sizeof(func_cap)); | 530 | memset(&func_cap, 0, sizeof(func_cap)); |
| 530 | err = mlx4_QUERY_FUNC_CAP(dev, &func_cap); | 531 | err = mlx4_QUERY_FUNC_CAP(dev, 0, &func_cap); |
| 531 | if (err) { | 532 | if (err) { |
| 532 | mlx4_err(dev, "QUERY_FUNC_CAP command failed, aborting.\n"); | 533 | mlx4_err(dev, "QUERY_FUNC_CAP general command failed, aborting (%d).\n", |
| 534 | err); | ||
| 533 | return err; | 535 | return err; |
| 534 | } | 536 | } |
| 535 | 537 | ||
| @@ -557,12 +559,33 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) | |||
| 557 | return -ENODEV; | 559 | return -ENODEV; |
| 558 | } | 560 | } |
| 559 | 561 | ||
| 562 | dev->caps.qp0_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); | ||
| 563 | dev->caps.qp0_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); | ||
| 564 | dev->caps.qp1_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); | ||
| 565 | dev->caps.qp1_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); | ||
| 566 | |||
| 567 | if (!dev->caps.qp0_tunnel || !dev->caps.qp0_proxy || | ||
| 568 | !dev->caps.qp1_tunnel || !dev->caps.qp1_proxy) { | ||
| 569 | err = -ENOMEM; | ||
| 570 | goto err_mem; | ||
| 571 | } | ||
| 572 | |||
| 560 | for (i = 1; i <= dev->caps.num_ports; ++i) { | 573 | for (i = 1; i <= dev->caps.num_ports; ++i) { |
| 574 | err = mlx4_QUERY_FUNC_CAP(dev, (u32) i, &func_cap); | ||
| 575 | if (err) { | ||
| 576 | mlx4_err(dev, "QUERY_FUNC_CAP port command failed for" | ||
| 577 | " port %d, aborting (%d).\n", i, err); | ||
| 578 | goto err_mem; | ||
| 579 | } | ||
| 580 | dev->caps.qp0_tunnel[i - 1] = func_cap.qp0_tunnel_qpn; | ||
| 581 | dev->caps.qp0_proxy[i - 1] = func_cap.qp0_proxy_qpn; | ||
| 582 | dev->caps.qp1_tunnel[i - 1] = func_cap.qp1_tunnel_qpn; | ||
| 583 | dev->caps.qp1_proxy[i - 1] = func_cap.qp1_proxy_qpn; | ||
| 561 | dev->caps.port_mask[i] = dev->caps.port_type[i]; | 584 | dev->caps.port_mask[i] = dev->caps.port_type[i]; |
| 562 | if (mlx4_get_slave_pkey_gid_tbl_len(dev, i, | 585 | if (mlx4_get_slave_pkey_gid_tbl_len(dev, i, |
| 563 | &dev->caps.gid_table_len[i], | 586 | &dev->caps.gid_table_len[i], |
| 564 | &dev->caps.pkey_table_len[i])) | 587 | &dev->caps.pkey_table_len[i])) |
| 565 | return -ENODEV; | 588 | goto err_mem; |
| 566 | } | 589 | } |
| 567 | 590 | ||
| 568 | if (dev->caps.uar_page_size * (dev->caps.num_uars - | 591 | if (dev->caps.uar_page_size * (dev->caps.num_uars - |
| @@ -572,14 +595,20 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) | |||
| 572 | "PCI resource 2 size of 0x%llx, aborting.\n", | 595 | "PCI resource 2 size of 0x%llx, aborting.\n", |
| 573 | dev->caps.uar_page_size * dev->caps.num_uars, | 596 | dev->caps.uar_page_size * dev->caps.num_uars, |
| 574 | (unsigned long long) pci_resource_len(dev->pdev, 2)); | 597 | (unsigned long long) pci_resource_len(dev->pdev, 2)); |
| 575 | return -ENODEV; | 598 | goto err_mem; |
| 576 | } | 599 | } |
| 577 | 600 | ||
| 578 | /* Calculate our sqp_start */ | ||
| 579 | dev->caps.sqp_start = func_cap.base_proxy_qpn; | ||
| 580 | dev->caps.base_tunnel_sqpn = func_cap.base_tunnel_qpn; | ||
| 581 | |||
| 582 | return 0; | 601 | return 0; |
| 602 | |||
| 603 | err_mem: | ||
| 604 | kfree(dev->caps.qp0_tunnel); | ||
| 605 | kfree(dev->caps.qp0_proxy); | ||
| 606 | kfree(dev->caps.qp1_tunnel); | ||
| 607 | kfree(dev->caps.qp1_proxy); | ||
| 608 | dev->caps.qp0_tunnel = dev->caps.qp0_proxy = | ||
| 609 | dev->caps.qp1_tunnel = dev->caps.qp1_proxy = NULL; | ||
| 610 | |||
| 611 | return err; | ||
| 583 | } | 612 | } |
| 584 | 613 | ||
| 585 | /* | 614 | /* |
| @@ -2261,6 +2290,12 @@ static void mlx4_remove_one(struct pci_dev *pdev) | |||
| 2261 | 2290 | ||
| 2262 | if (!mlx4_is_slave(dev)) | 2291 | if (!mlx4_is_slave(dev)) |
| 2263 | mlx4_free_ownership(dev); | 2292 | mlx4_free_ownership(dev); |
| 2293 | |||
| 2294 | kfree(dev->caps.qp0_tunnel); | ||
| 2295 | kfree(dev->caps.qp0_proxy); | ||
| 2296 | kfree(dev->caps.qp1_tunnel); | ||
| 2297 | kfree(dev->caps.qp1_proxy); | ||
| 2298 | |||
| 2264 | kfree(priv); | 2299 | kfree(priv); |
| 2265 | pci_release_regions(pdev); | 2300 | pci_release_regions(pdev); |
| 2266 | pci_disable_device(pdev); | 2301 | pci_disable_device(pdev); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c index 436ef6c69add..81e2abe07bbb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c | |||
| @@ -68,15 +68,15 @@ void mlx4_qp_event(struct mlx4_dev *dev, u32 qpn, int event_type) | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | /* used for INIT/CLOSE port logic */ | 70 | /* used for INIT/CLOSE port logic */ |
| 71 | static int is_qp0(struct mlx4_dev *dev, struct mlx4_qp *qp, int *real_qp0, int *proxy_qp0) | 71 | static int is_master_qp0(struct mlx4_dev *dev, struct mlx4_qp *qp, int *real_qp0, int *proxy_qp0) |
| 72 | { | 72 | { |
| 73 | /* this procedure is called after we already know we are on the master */ | ||
| 73 | /* qp0 is either the proxy qp0, or the real qp0 */ | 74 | /* qp0 is either the proxy qp0, or the real qp0 */ |
| 74 | *proxy_qp0 = qp->qpn >= dev->caps.sqp_start && | 75 | u32 pf_proxy_offset = dev->phys_caps.base_proxy_sqpn + 8 * mlx4_master_func_num(dev); |
| 75 | qp->qpn <= dev->caps.sqp_start + 1; | 76 | *proxy_qp0 = qp->qpn >= pf_proxy_offset && qp->qpn <= pf_proxy_offset + 1; |
| 76 | 77 | ||
| 77 | *real_qp0 = mlx4_is_master(dev) && | 78 | *real_qp0 = qp->qpn >= dev->phys_caps.base_sqpn && |
| 78 | qp->qpn >= dev->caps.base_sqpn && | 79 | qp->qpn <= dev->phys_caps.base_sqpn + 1; |
| 79 | qp->qpn <= dev->caps.base_sqpn + 1; | ||
| 80 | 80 | ||
| 81 | return *real_qp0 || *proxy_qp0; | 81 | return *real_qp0 || *proxy_qp0; |
| 82 | } | 82 | } |
| @@ -143,7 +143,7 @@ static int __mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt, | |||
| 143 | MLX4_CMD_2RST_QP, MLX4_CMD_TIME_CLASS_A, native); | 143 | MLX4_CMD_2RST_QP, MLX4_CMD_TIME_CLASS_A, native); |
| 144 | if (mlx4_is_master(dev) && cur_state != MLX4_QP_STATE_ERR && | 144 | if (mlx4_is_master(dev) && cur_state != MLX4_QP_STATE_ERR && |
| 145 | cur_state != MLX4_QP_STATE_RST && | 145 | cur_state != MLX4_QP_STATE_RST && |
| 146 | is_qp0(dev, qp, &real_qp0, &proxy_qp0)) { | 146 | is_master_qp0(dev, qp, &real_qp0, &proxy_qp0)) { |
| 147 | port = (qp->qpn & 1) + 1; | 147 | port = (qp->qpn & 1) + 1; |
| 148 | if (proxy_qp0) | 148 | if (proxy_qp0) |
| 149 | priv->mfunc.master.qp0_state[port].proxy_qp0_active = 0; | 149 | priv->mfunc.master.qp0_state[port].proxy_qp0_active = 0; |
| @@ -175,7 +175,7 @@ static int __mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt, | |||
| 175 | new_state == MLX4_QP_STATE_RST ? 2 : 0, | 175 | new_state == MLX4_QP_STATE_RST ? 2 : 0, |
| 176 | op[cur_state][new_state], MLX4_CMD_TIME_CLASS_C, native); | 176 | op[cur_state][new_state], MLX4_CMD_TIME_CLASS_C, native); |
| 177 | 177 | ||
| 178 | if (mlx4_is_master(dev) && is_qp0(dev, qp, &real_qp0, &proxy_qp0)) { | 178 | if (mlx4_is_master(dev) && is_master_qp0(dev, qp, &real_qp0, &proxy_qp0)) { |
| 179 | port = (qp->qpn & 1) + 1; | 179 | port = (qp->qpn & 1) + 1; |
| 180 | if (cur_state != MLX4_QP_STATE_ERR && | 180 | if (cur_state != MLX4_QP_STATE_ERR && |
| 181 | cur_state != MLX4_QP_STATE_RST && | 181 | cur_state != MLX4_QP_STATE_RST && |
| @@ -422,6 +422,7 @@ int mlx4_init_qp_table(struct mlx4_dev *dev) | |||
| 422 | struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table; | 422 | struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table; |
| 423 | int err; | 423 | int err; |
| 424 | int reserved_from_top = 0; | 424 | int reserved_from_top = 0; |
| 425 | int k; | ||
| 425 | 426 | ||
| 426 | spin_lock_init(&qp_table->lock); | 427 | spin_lock_init(&qp_table->lock); |
| 427 | INIT_RADIX_TREE(&dev->qp_table_tree, GFP_ATOMIC); | 428 | INIT_RADIX_TREE(&dev->qp_table_tree, GFP_ATOMIC); |
| @@ -436,7 +437,7 @@ int mlx4_init_qp_table(struct mlx4_dev *dev) | |||
| 436 | * We also reserve the MSB of the 24-bit QP number to indicate | 437 | * We also reserve the MSB of the 24-bit QP number to indicate |
| 437 | * that a QP is an XRC QP. | 438 | * that a QP is an XRC QP. |
| 438 | */ | 439 | */ |
| 439 | dev->caps.base_sqpn = | 440 | dev->phys_caps.base_sqpn = |
| 440 | ALIGN(dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW], 8); | 441 | ALIGN(dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW], 8); |
| 441 | 442 | ||
| 442 | { | 443 | { |
| @@ -479,24 +480,54 @@ int mlx4_init_qp_table(struct mlx4_dev *dev) | |||
| 479 | */ | 480 | */ |
| 480 | 481 | ||
| 481 | err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps, | 482 | err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps, |
| 482 | (1 << 23) - 1, dev->caps.base_sqpn + 8 + | 483 | (1 << 23) - 1, dev->phys_caps.base_sqpn + 8 + |
| 483 | 16 * MLX4_MFUNC_MAX * !!mlx4_is_master(dev), | 484 | 16 * MLX4_MFUNC_MAX * !!mlx4_is_master(dev), |
| 484 | reserved_from_top); | 485 | reserved_from_top); |
| 486 | if (err) | ||
| 487 | return err; | ||
| 485 | 488 | ||
| 486 | /* In mfunc, sqp_start is the base of the proxy SQPs, since the PF also | ||
| 487 | * uses paravirtualized SQPs. | ||
| 488 | * In native mode, sqp_start is the base of the real SQPs. */ | ||
| 489 | if (mlx4_is_mfunc(dev)) { | 489 | if (mlx4_is_mfunc(dev)) { |
| 490 | dev->caps.sqp_start = dev->caps.base_sqpn + | 490 | /* for PPF use */ |
| 491 | 8 * (mlx4_master_func_num(dev) + 1); | 491 | dev->phys_caps.base_proxy_sqpn = dev->phys_caps.base_sqpn + 8; |
| 492 | dev->caps.base_tunnel_sqpn = dev->caps.sqp_start + 8 * MLX4_MFUNC_MAX; | 492 | dev->phys_caps.base_tunnel_sqpn = dev->phys_caps.base_sqpn + 8 + 8 * MLX4_MFUNC_MAX; |
| 493 | } else | 493 | |
| 494 | dev->caps.sqp_start = dev->caps.base_sqpn; | 494 | /* In mfunc, calculate proxy and tunnel qp offsets for the PF here, |
| 495 | * since the PF does not call mlx4_slave_caps */ | ||
| 496 | dev->caps.qp0_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); | ||
| 497 | dev->caps.qp0_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); | ||
| 498 | dev->caps.qp1_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); | ||
| 499 | dev->caps.qp1_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); | ||
| 500 | |||
| 501 | if (!dev->caps.qp0_tunnel || !dev->caps.qp0_proxy || | ||
| 502 | !dev->caps.qp1_tunnel || !dev->caps.qp1_proxy) { | ||
| 503 | err = -ENOMEM; | ||
| 504 | goto err_mem; | ||
| 505 | } | ||
| 495 | 506 | ||
| 507 | for (k = 0; k < dev->caps.num_ports; k++) { | ||
| 508 | dev->caps.qp0_proxy[k] = dev->phys_caps.base_proxy_sqpn + | ||
| 509 | 8 * mlx4_master_func_num(dev) + k; | ||
| 510 | dev->caps.qp0_tunnel[k] = dev->caps.qp0_proxy[k] + 8 * MLX4_MFUNC_MAX; | ||
| 511 | dev->caps.qp1_proxy[k] = dev->phys_caps.base_proxy_sqpn + | ||
| 512 | 8 * mlx4_master_func_num(dev) + MLX4_MAX_PORTS + k; | ||
| 513 | dev->caps.qp1_tunnel[k] = dev->caps.qp1_proxy[k] + 8 * MLX4_MFUNC_MAX; | ||
| 514 | } | ||
| 515 | } | ||
| 516 | |||
| 517 | |||
| 518 | err = mlx4_CONF_SPECIAL_QP(dev, dev->phys_caps.base_sqpn); | ||
| 496 | if (err) | 519 | if (err) |
| 497 | return err; | 520 | goto err_mem; |
| 521 | return 0; | ||
| 498 | 522 | ||
| 499 | return mlx4_CONF_SPECIAL_QP(dev, dev->caps.base_sqpn); | 523 | err_mem: |
| 524 | kfree(dev->caps.qp0_tunnel); | ||
| 525 | kfree(dev->caps.qp0_proxy); | ||
| 526 | kfree(dev->caps.qp1_tunnel); | ||
| 527 | kfree(dev->caps.qp1_proxy); | ||
| 528 | dev->caps.qp0_tunnel = dev->caps.qp0_proxy = | ||
| 529 | dev->caps.qp1_tunnel = dev->caps.qp1_proxy = NULL; | ||
| 530 | return err; | ||
| 500 | } | 531 | } |
| 501 | 532 | ||
| 502 | void mlx4_cleanup_qp_table(struct mlx4_dev *dev) | 533 | void mlx4_cleanup_qp_table(struct mlx4_dev *dev) |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index c0f8f74a0a5e..6d1acb04cd17 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
| @@ -328,6 +328,9 @@ struct mlx4_phys_caps { | |||
| 328 | u32 gid_phys_table_len[MLX4_MAX_PORTS + 1]; | 328 | u32 gid_phys_table_len[MLX4_MAX_PORTS + 1]; |
| 329 | u32 pkey_phys_table_len[MLX4_MAX_PORTS + 1]; | 329 | u32 pkey_phys_table_len[MLX4_MAX_PORTS + 1]; |
| 330 | u32 num_phys_eqs; | 330 | u32 num_phys_eqs; |
| 331 | u32 base_sqpn; | ||
| 332 | u32 base_proxy_sqpn; | ||
| 333 | u32 base_tunnel_sqpn; | ||
| 331 | }; | 334 | }; |
| 332 | 335 | ||
| 333 | struct mlx4_caps { | 336 | struct mlx4_caps { |
| @@ -358,9 +361,10 @@ struct mlx4_caps { | |||
| 358 | int max_rq_desc_sz; | 361 | int max_rq_desc_sz; |
| 359 | int max_qp_init_rdma; | 362 | int max_qp_init_rdma; |
| 360 | int max_qp_dest_rdma; | 363 | int max_qp_dest_rdma; |
| 361 | int sqp_start; | 364 | u32 *qp0_proxy; |
| 362 | u32 base_sqpn; | 365 | u32 *qp1_proxy; |
| 363 | u32 base_tunnel_sqpn; | 366 | u32 *qp0_tunnel; |
| 367 | u32 *qp1_tunnel; | ||
| 364 | int num_srqs; | 368 | int num_srqs; |
| 365 | int max_srq_wqes; | 369 | int max_srq_wqes; |
| 366 | int max_srq_sge; | 370 | int max_srq_sge; |
| @@ -722,15 +726,15 @@ static inline int mlx4_is_master(struct mlx4_dev *dev) | |||
| 722 | 726 | ||
| 723 | static inline int mlx4_is_qp_reserved(struct mlx4_dev *dev, u32 qpn) | 727 | static inline int mlx4_is_qp_reserved(struct mlx4_dev *dev, u32 qpn) |
| 724 | { | 728 | { |
| 725 | return (qpn < dev->caps.base_sqpn + 8 + | 729 | return (qpn < dev->phys_caps.base_sqpn + 8 + |
| 726 | 16 * MLX4_MFUNC_MAX * !!mlx4_is_master(dev)); | 730 | 16 * MLX4_MFUNC_MAX * !!mlx4_is_master(dev)); |
| 727 | } | 731 | } |
| 728 | 732 | ||
| 729 | static inline int mlx4_is_guest_proxy(struct mlx4_dev *dev, int slave, u32 qpn) | 733 | static inline int mlx4_is_guest_proxy(struct mlx4_dev *dev, int slave, u32 qpn) |
| 730 | { | 734 | { |
| 731 | int base = dev->caps.sqp_start + slave * 8; | 735 | int guest_proxy_base = dev->phys_caps.base_proxy_sqpn + slave * 8; |
| 732 | 736 | ||
| 733 | if (qpn >= base && qpn < base + 8) | 737 | if (qpn >= guest_proxy_base && qpn < guest_proxy_base + 8) |
| 734 | return 1; | 738 | return 1; |
| 735 | 739 | ||
| 736 | return 0; | 740 | return 0; |
