aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2013-11-03 03:03:24 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-04 16:19:08 -0500
commiteb456a68c67224efa71e7ef5975cf36c91794695 (patch)
treeaf27bfae17effc9e4f5d63a1d983e1d829cc97ca /drivers/net/ethernet
parent5a0d0a6161aecbbc76e4c1d2b82e4c7cef88bb29 (diff)
net/mlx4_core: Fix quota handling in the QUERY_FUNC_CAP wrapper
In current kernels, the mlx4 driver running on a VM does not differentiate between max resource numbers for the HCA and max quotas -- it simply takes the quota values passed to it as max-resource values. However, the driver actually requires the VFs to be aware of the actual number of resources that the HCA was initialized with, for QPs, CQs, SRQs and MPTs. For QPs, CQs and SRQs, the reason is that in completion handling the driver must know which of the 24 bits are the actual resource number, and which are "padding" bits. For MPTs, also, the driver assumes knowledge of the number of MPTs in the system. The previous commit fixes the quota logic on the VM for the quota values passed to it by QUERY_FUNC_CAPS. For QPs, CQs, SRQs, and MPTs, it takes the max resource numbers from QUERY_HCA (and not QUERY_FUNC_CAPS). The quotas passed in QUERY_FUNC_CAPS are used to report max resource number values in the response to ib_query_device. However, the Hypervisor driver must consider that VMs may be running previous kernels, and compatibility must be preserved. To resolve the incompatibility with previous kernels running on VMs, we deprecated the quota fields in mlx4_QUERY_FUNC_CAP. In the deprecated fields, we pass the max-resource values from INIT_HCA The quota fields are moved to a new location, and the current kernel driver takes the proper values from that location. There is also a new flag in dword 0, bit 28 of the mlx4_QUERY_FUNC_CAP mailbox; if this flag is set, the (VM) driver takes the quota values from the new location. VMs running previous kernels will work properly, except that the max resource numbers reported in ib_query_device for these resources will be too high. The Hypervisor driver will, however, enforce the quotas for these VMs. Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c88
1 files changed, 65 insertions, 23 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index f8c88c3ad9fc..c3e70bc2d875 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -186,18 +186,26 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
186#define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 186#define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1
187#define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4 187#define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4
188#define QUERY_FUNC_CAP_FMR_OFFSET 0x8 188#define QUERY_FUNC_CAP_FMR_OFFSET 0x8
189#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x10 189#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP 0x10
190#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x14 190#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP 0x14
191#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x18 191#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP 0x18
192#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET 0x20 192#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP 0x20
193#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET 0x24 193#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP 0x24
194#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET 0x28 194#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP 0x28
195#define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c 195#define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c
196#define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0x30 196#define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0x30
197 197
198#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x50
199#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x54
200#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x58
201#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET 0x60
202#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET 0x64
203#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET 0x68
204
198#define QUERY_FUNC_CAP_FMR_FLAG 0x80 205#define QUERY_FUNC_CAP_FMR_FLAG 0x80
199#define QUERY_FUNC_CAP_FLAG_RDMA 0x40 206#define QUERY_FUNC_CAP_FLAG_RDMA 0x40
200#define QUERY_FUNC_CAP_FLAG_ETH 0x80 207#define QUERY_FUNC_CAP_FLAG_ETH 0x80
208#define QUERY_FUNC_CAP_FLAG_QUOTAS 0x10
201 209
202/* when opcode modifier = 1 */ 210/* when opcode modifier = 1 */
203#define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 211#define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3
@@ -238,8 +246,9 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
238 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_PROXY); 246 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_PROXY);
239 247
240 } else if (vhcr->op_modifier == 0) { 248 } else if (vhcr->op_modifier == 0) {
241 /* enable rdma and ethernet interfaces */ 249 /* enable rdma and ethernet interfaces, and new quota locations */
242 field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA); 250 field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA |
251 QUERY_FUNC_CAP_FLAG_QUOTAS);
243 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); 252 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET);
244 253
245 field = dev->caps.num_ports; 254 field = dev->caps.num_ports;
@@ -253,12 +262,18 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
253 262
254 size = priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[slave]; 263 size = priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[slave];
255 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); 264 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET);
265 size = dev->caps.num_qps;
266 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP);
256 267
257 size = priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[slave]; 268 size = priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[slave];
258 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); 269 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET);
270 size = dev->caps.num_srqs;
271 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP);
259 272
260 size = priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[slave]; 273 size = priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[slave];
261 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); 274 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET);
275 size = dev->caps.num_cqs;
276 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP);
262 277
263 size = dev->caps.num_eqs; 278 size = dev->caps.num_eqs;
264 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); 279 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET);
@@ -268,12 +283,17 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
268 283
269 size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave]; 284 size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave];
270 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); 285 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);
286 size = dev->caps.num_mpts;
287 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP);
271 288
272 size = priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[slave]; 289 size = priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[slave];
273 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET); 290 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);
291 size = dev->caps.num_mtts;
292 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP);
274 293
275 size = dev->caps.num_mgms + dev->caps.num_amgms; 294 size = dev->caps.num_mgms + dev->caps.num_amgms;
276 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET); 295 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET);
296 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP);
277 297
278 } else 298 } else
279 err = -EINVAL; 299 err = -EINVAL;
@@ -288,7 +308,7 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
288 u32 *outbox; 308 u32 *outbox;
289 u8 field, op_modifier; 309 u8 field, op_modifier;
290 u32 size; 310 u32 size;
291 int err = 0; 311 int err = 0, quotas = 0;
292 312
293 op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */ 313 op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */
294 314
@@ -312,6 +332,7 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
312 goto out; 332 goto out;
313 } 333 }
314 func_cap->flags = field; 334 func_cap->flags = field;
335 quotas = !!(func_cap->flags & QUERY_FUNC_CAP_FLAG_QUOTAS);
315 336
316 MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); 337 MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET);
317 func_cap->num_ports = field; 338 func_cap->num_ports = field;
@@ -319,29 +340,50 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
319 MLX4_GET(size, outbox, QUERY_FUNC_CAP_PF_BHVR_OFFSET); 340 MLX4_GET(size, outbox, QUERY_FUNC_CAP_PF_BHVR_OFFSET);
320 func_cap->pf_context_behaviour = size; 341 func_cap->pf_context_behaviour = size;
321 342
322 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); 343 if (quotas) {
323 func_cap->qp_quota = size & 0xFFFFFF; 344 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET);
345 func_cap->qp_quota = size & 0xFFFFFF;
346
347 MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET);
348 func_cap->srq_quota = size & 0xFFFFFF;
349
350 MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET);
351 func_cap->cq_quota = size & 0xFFFFFF;
352
353 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);
354 func_cap->mpt_quota = size & 0xFFFFFF;
355
356 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);
357 func_cap->mtt_quota = size & 0xFFFFFF;
358
359 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET);
360 func_cap->mcg_quota = size & 0xFFFFFF;
324 361
325 MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); 362 } else {
326 func_cap->srq_quota = size & 0xFFFFFF; 363 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP);
364 func_cap->qp_quota = size & 0xFFFFFF;
327 365
328 MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); 366 MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP);
329 func_cap->cq_quota = size & 0xFFFFFF; 367 func_cap->srq_quota = size & 0xFFFFFF;
330 368
369 MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP);
370 func_cap->cq_quota = size & 0xFFFFFF;
371
372 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP);
373 func_cap->mpt_quota = size & 0xFFFFFF;
374
375 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP);
376 func_cap->mtt_quota = size & 0xFFFFFF;
377
378 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP);
379 func_cap->mcg_quota = size & 0xFFFFFF;
380 }
331 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MAX_EQ_OFFSET); 381 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MAX_EQ_OFFSET);
332 func_cap->max_eq = size & 0xFFFFFF; 382 func_cap->max_eq = size & 0xFFFFFF;
333 383
334 MLX4_GET(size, outbox, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); 384 MLX4_GET(size, outbox, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET);
335 func_cap->reserved_eq = size & 0xFFFFFF; 385 func_cap->reserved_eq = size & 0xFFFFFF;
336 386
337 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);
338 func_cap->mpt_quota = size & 0xFFFFFF;
339
340 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);
341 func_cap->mtt_quota = size & 0xFFFFFF;
342
343 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET);
344 func_cap->mcg_quota = size & 0xFFFFFF;
345 goto out; 387 goto out;
346 } 388 }
347 389