aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2012-08-03 04:40:57 -0400
committerRoland Dreier <roland@purestorage.com>2012-09-30 23:33:43 -0400
commit47605df953985c2b792ac9f3ddf70d270b89adb8 (patch)
treeb95cef28771ea4982a5bca6130dab4ace79d622c
parentafa8fd1db9f295a0c4130bc6d87bf8b05bdd0523 (diff)
mlx4: Modify proxy/tunnel QP mechanism so that guests do no calculations
Previously, the structure of a guest's proxy QPs followed the structure of the PPF special qps (qp0 port 1, qp0 port 2, qp1 port 1, qp1 port 2, ...). The guest then did offset calculations on the sqp_base qp number that the PPF passed to it in QUERY_FUNC_CAP(). This is now changed so that the guest does no offset calculations regarding proxy or tunnel QPs to use. This change frees the PPF from needing to adhere to a specific order in allocating proxy and tunnel QPs. Now QUERY_FUNC_CAP provides each port individually with its proxy qp0, proxy qp1, tunnel qp0, and tunnel qp1 QP numbers, and these are used directly where required (with no offset calculations). To accomplish this change, several fields were added to the phys_caps structure for use by the PPF and by non-SR-IOV mode: base_sqpn -- in non-sriov mode, this was formerly sqp_start. base_proxy_sqpn -- the first physical proxy qp number -- used by PPF base_tunnel_sqpn -- the first physical tunnel qp number -- used by PPF. The current code in the PPF still adheres to the previous layout of sqps, proxy-sqps and tunnel-sqps. However, the PPF can change this layout without affecting VF or (paravirtualized) PF code. Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c12
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c104
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c173
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.h14
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c61
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/qp.c71
-rw-r--r--include/linux/mlx4/device.h16
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
1075static int is_proxy_qp0(struct mlx4_ib_dev *dev, int qpn, int slave) 1075static 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
124static int is_sqp(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) 124static 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 */
134static int is_qp0(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) 149static 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
148static void *get_wqe(struct mlx4_ib_qp *qp, int offset) 172static 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
958static 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
938struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, 975struct 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
2021static void build_tunnel_header(struct ib_send_wr *wr, void *wqe, unsigned *mlx_seg_len) 2055static 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
264int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap) 274int 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
144struct mlx4_adapter { 145struct mlx4_adapter {
@@ -195,7 +196,8 @@ struct mlx4_set_ib_param {
195}; 196};
196 197
197int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap); 198int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap);
198int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap); 199int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
200 struct mlx4_func_cap *func_cap);
199int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, 201int 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)
410int mlx4_get_parav_qkey(struct mlx4_dev *dev, u32 qpn, u32 *qkey) 410int 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
603err_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 */
71static int is_qp0(struct mlx4_dev *dev, struct mlx4_qp *qp, int *real_qp0, int *proxy_qp0) 71static 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); 523err_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
502void mlx4_cleanup_qp_table(struct mlx4_dev *dev) 533void 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
333struct mlx4_caps { 336struct 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
723static inline int mlx4_is_qp_reserved(struct mlx4_dev *dev, u32 qpn) 727static 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
729static inline int mlx4_is_guest_proxy(struct mlx4_dev *dev, int slave, u32 qpn) 733static 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;