aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4/main.c
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 /drivers/net/ethernet/mellanox/mlx4/main.c
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>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/main.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c61
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)
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);