diff options
Diffstat (limited to 'drivers/net/ethernet/emulex/benet/be_main.c')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 129 |
1 files changed, 82 insertions, 47 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 75e6653128fc..a32dc4fbb73c 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3098,6 +3098,13 @@ static int be_clear(struct be_adapter *adapter) if (sriov_enabled(adapter)) be_vf_clear(adapter); + /* Re-configure FW to distribute resources evenly across max-supported + * number of VFs, only when VFs are not already enabled. + */ + if (be_physfn(adapter) && !pci_vfs_assigned(adapter->pdev)) + be_cmd_set_sriov_config(adapter, adapter->pool_res, + pci_sriov_get_totalvfs(adapter->pdev)); + #ifdef CONFIG_BE2NET_VXLAN be_disable_vxlan_offloads(adapter); #endif @@ -3170,19 +3177,6 @@ static int be_vf_setup(struct be_adapter *adapter) u32 privileges; old_vfs = pci_num_vf(adapter->pdev); - if (old_vfs) { - dev_info(dev, "%d VFs are already enabled\n", old_vfs); - if (old_vfs != num_vfs) - dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs); - adapter->num_vfs = old_vfs; - } else { - if (num_vfs > be_max_vfs(adapter)) - dev_info(dev, "Device supports %d VFs and not %d\n", - be_max_vfs(adapter), num_vfs); - adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter)); - if (!adapter->num_vfs) - return 0; - } status = be_vf_setup_init(adapter); if (status) @@ -3194,17 +3188,15 @@ static int be_vf_setup(struct be_adapter *adapter) if (status) goto err; } - } else { - status = be_vfs_if_create(adapter); - if (status) - goto err; - } - if (old_vfs) { status = be_vfs_mac_query(adapter); if (status) goto err; } else { + status = be_vfs_if_create(adapter); + if (status) + goto err; + status = be_vf_eth_addr_config(adapter); if (status) goto err; @@ -3270,19 +3262,7 @@ static u8 be_convert_mc_type(u32 function_mode) static void BEx_get_resources(struct be_adapter *adapter, struct be_resources *res) { - struct pci_dev *pdev = adapter->pdev; - bool use_sriov = false; - int max_vfs = 0; - - if (be_physfn(adapter) && BE3_chip(adapter)) { - be_cmd_get_profile_config(adapter, res, 0); - /* Some old versions of BE3 FW don't report max_vfs value */ - if (res->max_vfs == 0) { - max_vfs = pci_sriov_get_totalvfs(pdev); - res->max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0; - } - use_sriov = res->max_vfs && sriov_want(adapter); - } + bool use_sriov = adapter->num_vfs ? 1 : 0; if (be_physfn(adapter)) res->max_uc_mac = BE_UC_PMAC_COUNT; @@ -3349,6 +3329,54 @@ static void be_setup_init(struct be_adapter *adapter) adapter->cmd_privileges = MIN_PRIVILEGES; } +static int be_get_sriov_config(struct be_adapter *adapter) +{ + struct device *dev = &adapter->pdev->dev; + struct be_resources res = {0}; + int status, max_vfs, old_vfs; + + status = be_cmd_get_profile_config(adapter, &res, 0); + if (status) + return status; + + adapter->pool_res = res; + + /* Some old versions of BE3 FW don't report max_vfs value */ + if (BE3_chip(adapter) && !res.max_vfs) { + max_vfs = pci_sriov_get_totalvfs(adapter->pdev); + res.max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0; + } + + adapter->pool_res.max_vfs = res.max_vfs; + pci_sriov_set_totalvfs(adapter->pdev, be_max_vfs(adapter)); + + if (!be_max_vfs(adapter)) { + if (num_vfs) + dev_warn(dev, "device doesn't support SRIOV\n"); + adapter->num_vfs = 0; + return 0; + } + + /* validate num_vfs module param */ + old_vfs = pci_num_vf(adapter->pdev); + if (old_vfs) { + dev_info(dev, "%d VFs are already enabled\n", old_vfs); + if (old_vfs != num_vfs) + dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs); + adapter->num_vfs = old_vfs; + } else { + if (num_vfs > be_max_vfs(adapter)) { + dev_info(dev, "Resources unavailable to init %d VFs\n", + num_vfs); + dev_info(dev, "Limiting to %d VFs\n", + be_max_vfs(adapter)); + } + adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter)); + } + + return 0; +} + static int be_get_resources(struct be_adapter *adapter) { struct device *dev = &adapter->pdev->dev; @@ -3374,14 +3402,6 @@ static int be_get_resources(struct be_adapter *adapter) res.max_evt_qs /= 2; adapter->res = res; - if (be_physfn(adapter)) { - status = be_cmd_get_profile_config(adapter, &res, 0); - if (status) - return status; - adapter->res.max_vfs = res.max_vfs; - adapter->res.vf_if_cap_flags = res.vf_if_cap_flags; - } - dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n", be_max_txqs(adapter), be_max_rxqs(adapter), be_max_rss(adapter), be_max_eqs(adapter), @@ -3394,7 +3414,6 @@ static int be_get_resources(struct be_adapter *adapter) return 0; } -/* Routine to query per function resource limits */ static int be_get_config(struct be_adapter *adapter) { u16 profile_id; @@ -3412,6 +3431,26 @@ static int be_get_config(struct be_adapter *adapter) if (!status) dev_info(&adapter->pdev->dev, "Using profile 0x%x\n", profile_id); + + status = be_get_sriov_config(adapter); + if (status) + return status; + + /* When the HW is in SRIOV capable configuration, the PF-pool + * resources are equally distributed across the max-number of + * VFs. The user may request only a subset of the max-vfs to be + * enabled. Based on num_vfs, redistribute the resources across + * num_vfs so that each VF will have access to more number of + * resources. This facility is not available in BE3 FW. + * Also, this is done by FW in Lancer chip. + */ + if (!pci_num_vf(adapter->pdev)) { + status = be_cmd_set_sriov_config(adapter, + adapter->pool_res, + adapter->num_vfs); + if (status) + return status; + } } status = be_get_resources(adapter); @@ -3597,12 +3636,8 @@ static int be_setup(struct be_adapter *adapter) be_cmd_set_logical_link_config(adapter, IFLA_VF_LINK_STATE_AUTO, 0); - if (sriov_want(adapter)) { - if (be_max_vfs(adapter)) - be_vf_setup(adapter); - else - dev_warn(dev, "device doesn't support SRIOV\n"); - } + if (adapter->num_vfs) + be_vf_setup(adapter); status = be_cmd_get_phy_info(adapter); if (!status && be_pause_supported(adapter)) |