diff options
author | Jack Morgenstein <jackm@dev.mellanox.co.il> | 2012-08-03 04:40:57 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-09-30 23:33:43 -0400 |
commit | 47605df953985c2b792ac9f3ddf70d270b89adb8 (patch) | |
tree | b95cef28771ea4982a5bca6130dab4ace79d622c /drivers/net/ethernet/mellanox/mlx4/main.c | |
parent | afa8fd1db9f295a0c4130bc6d87bf8b05bdd0523 (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>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/main.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 61 |
1 files changed, 48 insertions, 13 deletions
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); |