Skip to content

Commit fa44f2f

Browse files
Greg RoseJeff Kirsher
Greg Rose
authored and
Jeff Kirsher
committed
igb: Enable SR-IOV configuration via PCI sysfs interface
Implement callback in the driver for the new PCI bus driver interface that allows the user to enable/disable SR-IOV virtual functions in a device via the sysfs interface. Signed-off-by: Greg Rose <[email protected]> Tested-by: Aaron Brown <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent b67e191 commit fa44f2f

File tree

1 file changed

+219
-101
lines changed

1 file changed

+219
-101
lines changed

drivers/net/ethernet/intel/igb/igb_main.c

Lines changed: 219 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ static const struct dev_pm_ops igb_pm_ops = {
193193
};
194194
#endif
195195
static void igb_shutdown(struct pci_dev *);
196+
static int igb_pci_sriov_configure(struct pci_dev *dev, int num_vfs);
196197
#ifdef CONFIG_IGB_DCA
197198
static int igb_notify_dca(struct notifier_block *, unsigned long, void *);
198199
static struct notifier_block dca_notifier = {
@@ -234,6 +235,7 @@ static struct pci_driver igb_driver = {
234235
.driver.pm = &igb_pm_ops,
235236
#endif
236237
.shutdown = igb_shutdown,
238+
.sriov_configure = igb_pci_sriov_configure,
237239
.err_handler = &igb_err_handler
238240
};
239241

@@ -2195,6 +2197,99 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
21952197
return err;
21962198
}
21972199

2200+
#ifdef CONFIG_PCI_IOV
2201+
static int igb_disable_sriov(struct pci_dev *pdev)
2202+
{
2203+
struct net_device *netdev = pci_get_drvdata(pdev);
2204+
struct igb_adapter *adapter = netdev_priv(netdev);
2205+
struct e1000_hw *hw = &adapter->hw;
2206+
2207+
/* reclaim resources allocated to VFs */
2208+
if (adapter->vf_data) {
2209+
/* disable iov and allow time for transactions to clear */
2210+
if (igb_vfs_are_assigned(adapter)) {
2211+
dev_warn(&pdev->dev,
2212+
"Cannot deallocate SR-IOV virtual functions while they are assigned - VFs will not be deallocated\n");
2213+
return -EPERM;
2214+
} else {
2215+
pci_disable_sriov(pdev);
2216+
msleep(500);
2217+
}
2218+
2219+
kfree(adapter->vf_data);
2220+
adapter->vf_data = NULL;
2221+
adapter->vfs_allocated_count = 0;
2222+
wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
2223+
wrfl();
2224+
msleep(100);
2225+
dev_info(&pdev->dev, "IOV Disabled\n");
2226+
2227+
/* Re-enable DMA Coalescing flag since IOV is turned off */
2228+
adapter->flags |= IGB_FLAG_DMAC;
2229+
}
2230+
2231+
return 0;
2232+
}
2233+
2234+
static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)
2235+
{
2236+
struct net_device *netdev = pci_get_drvdata(pdev);
2237+
struct igb_adapter *adapter = netdev_priv(netdev);
2238+
int old_vfs = pci_num_vf(pdev);
2239+
int err = 0;
2240+
int i;
2241+
2242+
if (!num_vfs)
2243+
goto out;
2244+
else if (old_vfs && old_vfs == num_vfs)
2245+
goto out;
2246+
else if (old_vfs && old_vfs != num_vfs)
2247+
err = igb_disable_sriov(pdev);
2248+
2249+
if (err)
2250+
goto out;
2251+
2252+
if (num_vfs > 7) {
2253+
err = -EPERM;
2254+
goto out;
2255+
}
2256+
2257+
adapter->vfs_allocated_count = num_vfs;
2258+
2259+
adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
2260+
sizeof(struct vf_data_storage), GFP_KERNEL);
2261+
2262+
/* if allocation failed then we do not support SR-IOV */
2263+
if (!adapter->vf_data) {
2264+
adapter->vfs_allocated_count = 0;
2265+
dev_err(&pdev->dev,
2266+
"Unable to allocate memory for VF Data Storage\n");
2267+
err = -ENOMEM;
2268+
goto out;
2269+
}
2270+
2271+
err = pci_enable_sriov(pdev, adapter->vfs_allocated_count);
2272+
if (err)
2273+
goto err_out;
2274+
2275+
dev_info(&pdev->dev, "%d VFs allocated\n",
2276+
adapter->vfs_allocated_count);
2277+
for (i = 0; i < adapter->vfs_allocated_count; i++)
2278+
igb_vf_configure(adapter, i);
2279+
2280+
/* DMA Coalescing is not supported in IOV mode. */
2281+
adapter->flags &= ~IGB_FLAG_DMAC;
2282+
goto out;
2283+
2284+
err_out:
2285+
kfree(adapter->vf_data);
2286+
adapter->vf_data = NULL;
2287+
adapter->vfs_allocated_count = 0;
2288+
out:
2289+
return err;
2290+
}
2291+
2292+
#endif
21982293
/**
21992294
* igb_remove - Device Removal Routine
22002295
* @pdev: PCI device information struct
@@ -2242,23 +2337,7 @@ static void igb_remove(struct pci_dev *pdev)
22422337
igb_clear_interrupt_scheme(adapter);
22432338

22442339
#ifdef CONFIG_PCI_IOV
2245-
/* reclaim resources allocated to VFs */
2246-
if (adapter->vf_data) {
2247-
/* disable iov and allow time for transactions to clear */
2248-
if (igb_vfs_are_assigned(adapter)) {
2249-
dev_info(&pdev->dev, "Unloading driver while VFs are assigned - VFs will not be deallocated\n");
2250-
} else {
2251-
pci_disable_sriov(pdev);
2252-
msleep(500);
2253-
}
2254-
2255-
kfree(adapter->vf_data);
2256-
adapter->vf_data = NULL;
2257-
wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
2258-
wrfl();
2259-
msleep(100);
2260-
dev_info(&pdev->dev, "IOV Disabled\n");
2261-
}
2340+
igb_disable_sriov(pdev);
22622341
#endif
22632342

22642343
iounmap(hw->hw_addr);
@@ -2289,103 +2368,22 @@ static void igb_probe_vfs(struct igb_adapter *adapter)
22892368
#ifdef CONFIG_PCI_IOV
22902369
struct pci_dev *pdev = adapter->pdev;
22912370
struct e1000_hw *hw = &adapter->hw;
2292-
int old_vfs = pci_num_vf(adapter->pdev);
2293-
int i;
22942371

22952372
/* Virtualization features not supported on i210 family. */
22962373
if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211))
22972374
return;
22982375

2299-
if (old_vfs) {
2300-
dev_info(&pdev->dev, "%d pre-allocated VFs found - override "
2301-
"max_vfs setting of %d\n", old_vfs, max_vfs);
2302-
adapter->vfs_allocated_count = old_vfs;
2303-
}
2304-
2305-
if (!adapter->vfs_allocated_count)
2306-
return;
2307-
2308-
adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
2309-
sizeof(struct vf_data_storage), GFP_KERNEL);
2310-
2311-
/* if allocation failed then we do not support SR-IOV */
2312-
if (!adapter->vf_data) {
2313-
adapter->vfs_allocated_count = 0;
2314-
dev_err(&pdev->dev, "Unable to allocate memory for VF "
2315-
"Data Storage\n");
2316-
goto out;
2317-
}
2376+
igb_enable_sriov(pdev, max_vfs);
2377+
pci_sriov_set_totalvfs(pdev, 7);
23182378

2319-
if (!old_vfs) {
2320-
if (pci_enable_sriov(pdev, adapter->vfs_allocated_count))
2321-
goto err_out;
2322-
}
2323-
dev_info(&pdev->dev, "%d VFs allocated\n",
2324-
adapter->vfs_allocated_count);
2325-
for (i = 0; i < adapter->vfs_allocated_count; i++)
2326-
igb_vf_configure(adapter, i);
2327-
2328-
/* DMA Coalescing is not supported in IOV mode. */
2329-
adapter->flags &= ~IGB_FLAG_DMAC;
2330-
goto out;
2331-
err_out:
2332-
kfree(adapter->vf_data);
2333-
adapter->vf_data = NULL;
2334-
adapter->vfs_allocated_count = 0;
2335-
out:
2336-
return;
23372379
#endif /* CONFIG_PCI_IOV */
23382380
}
23392381

2340-
/**
2341-
* igb_sw_init - Initialize general software structures (struct igb_adapter)
2342-
* @adapter: board private structure to initialize
2343-
*
2344-
* igb_sw_init initializes the Adapter private data structure.
2345-
* Fields are initialized based on PCI device information and
2346-
* OS network device settings (MTU size).
2347-
**/
2348-
static int igb_sw_init(struct igb_adapter *adapter)
2382+
static void igb_init_queue_configuration(struct igb_adapter *adapter)
23492383
{
23502384
struct e1000_hw *hw = &adapter->hw;
2351-
struct net_device *netdev = adapter->netdev;
2352-
struct pci_dev *pdev = adapter->pdev;
23532385
u32 max_rss_queues;
23542386

2355-
pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);
2356-
2357-
/* set default ring sizes */
2358-
adapter->tx_ring_count = IGB_DEFAULT_TXD;
2359-
adapter->rx_ring_count = IGB_DEFAULT_RXD;
2360-
2361-
/* set default ITR values */
2362-
adapter->rx_itr_setting = IGB_DEFAULT_ITR;
2363-
adapter->tx_itr_setting = IGB_DEFAULT_ITR;
2364-
2365-
/* set default work limits */
2366-
adapter->tx_work_limit = IGB_DEFAULT_TX_WORK;
2367-
2368-
adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN +
2369-
VLAN_HLEN;
2370-
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
2371-
2372-
spin_lock_init(&adapter->stats64_lock);
2373-
#ifdef CONFIG_PCI_IOV
2374-
switch (hw->mac.type) {
2375-
case e1000_82576:
2376-
case e1000_i350:
2377-
if (max_vfs > 7) {
2378-
dev_warn(&pdev->dev,
2379-
"Maximum of 7 VFs per PF, using max\n");
2380-
adapter->vfs_allocated_count = 7;
2381-
} else
2382-
adapter->vfs_allocated_count = max_vfs;
2383-
break;
2384-
default:
2385-
break;
2386-
}
2387-
#endif /* CONFIG_PCI_IOV */
2388-
23892387
/* Determine the maximum number of RSS queues supported. */
23902388
switch (hw->mac.type) {
23912389
case e1000_i211:
@@ -2444,6 +2442,60 @@ static int igb_sw_init(struct igb_adapter *adapter)
24442442
adapter->flags |= IGB_FLAG_QUEUE_PAIRS;
24452443
break;
24462444
}
2445+
}
2446+
2447+
/**
2448+
* igb_sw_init - Initialize general software structures (struct igb_adapter)
2449+
* @adapter: board private structure to initialize
2450+
*
2451+
* igb_sw_init initializes the Adapter private data structure.
2452+
* Fields are initialized based on PCI device information and
2453+
* OS network device settings (MTU size).
2454+
**/
2455+
static int igb_sw_init(struct igb_adapter *adapter)
2456+
{
2457+
struct e1000_hw *hw = &adapter->hw;
2458+
struct net_device *netdev = adapter->netdev;
2459+
struct pci_dev *pdev = adapter->pdev;
2460+
2461+
pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);
2462+
2463+
/* set default ring sizes */
2464+
adapter->tx_ring_count = IGB_DEFAULT_TXD;
2465+
adapter->rx_ring_count = IGB_DEFAULT_RXD;
2466+
2467+
/* set default ITR values */
2468+
adapter->rx_itr_setting = IGB_DEFAULT_ITR;
2469+
adapter->tx_itr_setting = IGB_DEFAULT_ITR;
2470+
2471+
/* set default work limits */
2472+
adapter->tx_work_limit = IGB_DEFAULT_TX_WORK;
2473+
2474+
adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN +
2475+
VLAN_HLEN;
2476+
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
2477+
2478+
spin_lock_init(&adapter->stats64_lock);
2479+
#ifdef CONFIG_PCI_IOV
2480+
switch (hw->mac.type) {
2481+
case e1000_82576:
2482+
case e1000_i350:
2483+
if (max_vfs > 7) {
2484+
dev_warn(&pdev->dev,
2485+
"Maximum of 7 VFs per PF, using max\n");
2486+
adapter->vfs_allocated_count = 7;
2487+
} else
2488+
adapter->vfs_allocated_count = max_vfs;
2489+
if (adapter->vfs_allocated_count)
2490+
dev_warn(&pdev->dev,
2491+
"Enabling SR-IOV VFs using the module parameter is deprecated - please use the pci sysfs interface.\n");
2492+
break;
2493+
default:
2494+
break;
2495+
}
2496+
#endif /* CONFIG_PCI_IOV */
2497+
2498+
igb_init_queue_configuration(adapter);
24472499

24482500
/* Setup and initialize a copy of the hw vlan table array */
24492501
adapter->shadow_vfta = kzalloc(sizeof(u32) *
@@ -6902,6 +6954,72 @@ static void igb_shutdown(struct pci_dev *pdev)
69026954
}
69036955
}
69046956

6957+
#ifdef CONFIG_PCI_IOV
6958+
static int igb_sriov_reinit(struct pci_dev *dev)
6959+
{
6960+
struct net_device *netdev = pci_get_drvdata(dev);
6961+
struct igb_adapter *adapter = netdev_priv(netdev);
6962+
struct pci_dev *pdev = adapter->pdev;
6963+
6964+
rtnl_lock();
6965+
6966+
if (netif_running(netdev))
6967+
igb_close(netdev);
6968+
6969+
igb_clear_interrupt_scheme(adapter);
6970+
6971+
igb_init_queue_configuration(adapter);
6972+
6973+
if (igb_init_interrupt_scheme(adapter, true)) {
6974+
dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
6975+
return -ENOMEM;
6976+
}
6977+
6978+
if (netif_running(netdev))
6979+
igb_open(netdev);
6980+
6981+
rtnl_unlock();
6982+
6983+
return 0;
6984+
}
6985+
6986+
static int igb_pci_disable_sriov(struct pci_dev *dev)
6987+
{
6988+
int err = igb_disable_sriov(dev);
6989+
6990+
if (!err)
6991+
err = igb_sriov_reinit(dev);
6992+
6993+
return err;
6994+
}
6995+
6996+
static int igb_pci_enable_sriov(struct pci_dev *dev, int num_vfs)
6997+
{
6998+
int err = igb_enable_sriov(dev, num_vfs);
6999+
7000+
if (err)
7001+
goto out;
7002+
7003+
err = igb_sriov_reinit(dev);
7004+
if (!err)
7005+
return num_vfs;
7006+
7007+
out:
7008+
return err;
7009+
}
7010+
7011+
#endif
7012+
static int igb_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
7013+
{
7014+
#ifdef CONFIG_PCI_IOV
7015+
if (num_vfs == 0)
7016+
return igb_pci_disable_sriov(dev);
7017+
else
7018+
return igb_pci_enable_sriov(dev, num_vfs);
7019+
#endif
7020+
return 0;
7021+
}
7022+
69057023
#ifdef CONFIG_NET_POLL_CONTROLLER
69067024
/*
69077025
* Polling 'interrupt' - used by things like netconsole to send skbs

0 commit comments

Comments
 (0)