diff options
| author | Alexander Duyck <alexander.h.duyck@intel.com> | 2009-04-07 10:37:52 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-04-08 19:03:15 -0400 |
| commit | 2a3abf6d17b6026a59e5cf7452d70ec1ad6a69fa (patch) | |
| tree | 6cd19064d7da11d3f51da36e9336b2e696e98839 | |
| parent | d4e0fe01a38a073568aee541a0247fe734095979 (diff) | |
igb: remove sysfs entry that was used to set the number of vfs
This patch removes the sysfs entry num_vfs which was added to support
enabling pci virtual functions for 82576.
To prevent VFs from loading automatically a module parameter "max_vfs" was
added so that the number of VFs per PF can be limited. This is especially
useful when 4 or more 82576 ports are on the system because otherwise to
load all VFs would result in 8 interface per physical port.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/igb/igb_main.c | 159 |
1 files changed, 54 insertions, 105 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 6b0697c565b9..db7274e62228 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
| @@ -152,14 +152,13 @@ static struct notifier_block dca_notifier = { | |||
| 152 | /* for netdump / net console */ | 152 | /* for netdump / net console */ |
| 153 | static void igb_netpoll(struct net_device *); | 153 | static void igb_netpoll(struct net_device *); |
| 154 | #endif | 154 | #endif |
| 155 | |||
| 156 | #ifdef CONFIG_PCI_IOV | 155 | #ifdef CONFIG_PCI_IOV |
| 157 | static ssize_t igb_set_num_vfs(struct device *, struct device_attribute *, | 156 | static unsigned int max_vfs = 0; |
| 158 | const char *, size_t); | 157 | module_param(max_vfs, uint, 0); |
| 159 | static ssize_t igb_show_num_vfs(struct device *, struct device_attribute *, | 158 | MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate " |
| 160 | char *); | 159 | "per physical function"); |
| 161 | DEVICE_ATTR(num_vfs, S_IRUGO | S_IWUSR, igb_show_num_vfs, igb_set_num_vfs); | 160 | #endif /* CONFIG_PCI_IOV */ |
| 162 | #endif | 161 | |
| 163 | static pci_ers_result_t igb_io_error_detected(struct pci_dev *, | 162 | static pci_ers_result_t igb_io_error_detected(struct pci_dev *, |
| 164 | pci_channel_state_t); | 163 | pci_channel_state_t); |
| 165 | static pci_ers_result_t igb_io_slot_reset(struct pci_dev *); | 164 | static pci_ers_result_t igb_io_slot_reset(struct pci_dev *); |
| @@ -671,6 +670,21 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter) | |||
| 671 | 670 | ||
| 672 | /* If we can't do MSI-X, try MSI */ | 671 | /* If we can't do MSI-X, try MSI */ |
| 673 | msi_only: | 672 | msi_only: |
| 673 | #ifdef CONFIG_PCI_IOV | ||
| 674 | /* disable SR-IOV for non MSI-X configurations */ | ||
| 675 | if (adapter->vf_data) { | ||
| 676 | struct e1000_hw *hw = &adapter->hw; | ||
| 677 | /* disable iov and allow time for transactions to clear */ | ||
| 678 | pci_disable_sriov(adapter->pdev); | ||
| 679 | msleep(500); | ||
| 680 | |||
| 681 | kfree(adapter->vf_data); | ||
| 682 | adapter->vf_data = NULL; | ||
| 683 | wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); | ||
| 684 | msleep(100); | ||
| 685 | dev_info(&adapter->pdev->dev, "IOV Disabled\n"); | ||
| 686 | } | ||
| 687 | #endif | ||
| 674 | adapter->num_rx_queues = 1; | 688 | adapter->num_rx_queues = 1; |
| 675 | adapter->num_tx_queues = 1; | 689 | adapter->num_tx_queues = 1; |
| 676 | if (!pci_enable_msi(adapter->pdev)) | 690 | if (!pci_enable_msi(adapter->pdev)) |
| @@ -1238,6 +1252,39 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
| 1238 | if (err) | 1252 | if (err) |
| 1239 | goto err_sw_init; | 1253 | goto err_sw_init; |
| 1240 | 1254 | ||
| 1255 | #ifdef CONFIG_PCI_IOV | ||
| 1256 | /* since iov functionality isn't critical to base device function we | ||
| 1257 | * can accept failure. If it fails we don't allow iov to be enabled */ | ||
| 1258 | if (hw->mac.type == e1000_82576) { | ||
| 1259 | /* 82576 supports a maximum of 7 VFs in addition to the PF */ | ||
| 1260 | unsigned int num_vfs = (max_vfs > 7) ? 7 : max_vfs; | ||
| 1261 | int i; | ||
| 1262 | unsigned char mac_addr[ETH_ALEN]; | ||
| 1263 | |||
| 1264 | if (num_vfs) | ||
| 1265 | adapter->vf_data = kcalloc(num_vfs, | ||
| 1266 | sizeof(struct vf_data_storage), | ||
| 1267 | GFP_KERNEL); | ||
| 1268 | if (!adapter->vf_data) { | ||
| 1269 | dev_err(&pdev->dev, "Could not allocate VF private " | ||
| 1270 | "data - IOV enable failed\n"); | ||
| 1271 | } else { | ||
| 1272 | err = pci_enable_sriov(pdev, num_vfs); | ||
| 1273 | if (!err) { | ||
| 1274 | adapter->vfs_allocated_count = num_vfs; | ||
| 1275 | dev_info(&pdev->dev, "%d vfs allocated\n", num_vfs); | ||
| 1276 | for (i = 0; i < adapter->vfs_allocated_count; i++) { | ||
| 1277 | random_ether_addr(mac_addr); | ||
| 1278 | igb_set_vf_mac(adapter, i, mac_addr); | ||
| 1279 | } | ||
| 1280 | } else { | ||
| 1281 | kfree(adapter->vf_data); | ||
| 1282 | adapter->vf_data = NULL; | ||
| 1283 | } | ||
| 1284 | } | ||
| 1285 | } | ||
| 1286 | |||
| 1287 | #endif | ||
| 1241 | /* setup the private structure */ | 1288 | /* setup the private structure */ |
| 1242 | err = igb_sw_init(adapter); | 1289 | err = igb_sw_init(adapter); |
| 1243 | if (err) | 1290 | if (err) |
| @@ -1397,19 +1444,6 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
| 1397 | if (err) | 1444 | if (err) |
| 1398 | goto err_register; | 1445 | goto err_register; |
| 1399 | 1446 | ||
| 1400 | #ifdef CONFIG_PCI_IOV | ||
| 1401 | /* since iov functionality isn't critical to base device function we | ||
| 1402 | * can accept failure. If it fails we don't allow iov to be enabled */ | ||
| 1403 | if (hw->mac.type == e1000_82576) { | ||
| 1404 | err = pci_enable_sriov(pdev, 0); | ||
| 1405 | if (!err) | ||
| 1406 | err = device_create_file(&netdev->dev, | ||
| 1407 | &dev_attr_num_vfs); | ||
| 1408 | if (err) | ||
| 1409 | dev_err(&pdev->dev, "Failed to initialize IOV\n"); | ||
| 1410 | } | ||
| 1411 | |||
| 1412 | #endif | ||
| 1413 | #ifdef CONFIG_IGB_DCA | 1447 | #ifdef CONFIG_IGB_DCA |
| 1414 | if (dca_add_requester(&pdev->dev) == 0) { | 1448 | if (dca_add_requester(&pdev->dev) == 0) { |
| 1415 | adapter->flags |= IGB_FLAG_DCA_ENABLED; | 1449 | adapter->flags |= IGB_FLAG_DCA_ENABLED; |
| @@ -5422,89 +5456,4 @@ static void igb_vmm_control(struct igb_adapter *adapter) | |||
| 5422 | igb_vmdq_set_replication_pf(hw, true); | 5456 | igb_vmdq_set_replication_pf(hw, true); |
| 5423 | } | 5457 | } |
| 5424 | 5458 | ||
| 5425 | #ifdef CONFIG_PCI_IOV | ||
| 5426 | static ssize_t igb_show_num_vfs(struct device *dev, | ||
| 5427 | struct device_attribute *attr, char *buf) | ||
| 5428 | { | ||
| 5429 | struct igb_adapter *adapter = netdev_priv(to_net_dev(dev)); | ||
| 5430 | |||
| 5431 | return sprintf(buf, "%d\n", adapter->vfs_allocated_count); | ||
| 5432 | } | ||
| 5433 | |||
| 5434 | static ssize_t igb_set_num_vfs(struct device *dev, | ||
| 5435 | struct device_attribute *attr, | ||
| 5436 | const char *buf, size_t count) | ||
| 5437 | { | ||
| 5438 | struct net_device *netdev = to_net_dev(dev); | ||
| 5439 | struct igb_adapter *adapter = netdev_priv(netdev); | ||
| 5440 | struct e1000_hw *hw = &adapter->hw; | ||
| 5441 | struct pci_dev *pdev = adapter->pdev; | ||
| 5442 | unsigned int num_vfs, i; | ||
| 5443 | unsigned char mac_addr[ETH_ALEN]; | ||
| 5444 | int err; | ||
| 5445 | |||
| 5446 | sscanf(buf, "%u", &num_vfs); | ||
| 5447 | |||
| 5448 | if (num_vfs > 7) | ||
| 5449 | num_vfs = 7; | ||
| 5450 | |||
| 5451 | /* value unchanged do nothing */ | ||
| 5452 | if (num_vfs == adapter->vfs_allocated_count) | ||
| 5453 | return count; | ||
| 5454 | |||
| 5455 | if (netdev->flags & IFF_UP) | ||
| 5456 | igb_close(netdev); | ||
| 5457 | |||
| 5458 | igb_reset_interrupt_capability(adapter); | ||
| 5459 | igb_free_queues(adapter); | ||
| 5460 | adapter->tx_ring = NULL; | ||
| 5461 | adapter->rx_ring = NULL; | ||
| 5462 | adapter->vfs_allocated_count = 0; | ||
| 5463 | |||
| 5464 | /* reclaim resources allocated to VFs since we are changing count */ | ||
| 5465 | if (adapter->vf_data) { | ||
| 5466 | /* disable iov and allow time for transactions to clear */ | ||
| 5467 | pci_disable_sriov(pdev); | ||
| 5468 | msleep(500); | ||
| 5469 | |||
| 5470 | kfree(adapter->vf_data); | ||
| 5471 | adapter->vf_data = NULL; | ||
| 5472 | wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); | ||
| 5473 | msleep(100); | ||
| 5474 | dev_info(&pdev->dev, "IOV Disabled\n"); | ||
| 5475 | } | ||
| 5476 | |||
| 5477 | if (num_vfs) { | ||
| 5478 | adapter->vf_data = kcalloc(num_vfs, | ||
| 5479 | sizeof(struct vf_data_storage), | ||
| 5480 | GFP_KERNEL); | ||
| 5481 | if (!adapter->vf_data) { | ||
| 5482 | dev_err(&pdev->dev, "Could not allocate VF private " | ||
| 5483 | "data - IOV enable failed\n"); | ||
| 5484 | } else { | ||
| 5485 | err = pci_enable_sriov(pdev, num_vfs); | ||
| 5486 | if (!err) { | ||
| 5487 | adapter->vfs_allocated_count = num_vfs; | ||
| 5488 | dev_info(&pdev->dev, "%d vfs allocated\n", num_vfs); | ||
| 5489 | for (i = 0; i < adapter->vfs_allocated_count; i++) { | ||
| 5490 | random_ether_addr(mac_addr); | ||
