diff options
Diffstat (limited to 'drivers/net/igb/igb_main.c')
-rw-r--r-- | drivers/net/igb/igb_main.c | 166 |
1 files changed, 61 insertions, 105 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 6b0697c565b9..08c801490c72 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,46 @@ 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, | ||
1270 | "Could not allocate VF private data - " | ||
1271 | "IOV enable failed\n"); | ||
1272 | } else { | ||
1273 | err = pci_enable_sriov(pdev, num_vfs); | ||
1274 | if (!err) { | ||
1275 | adapter->vfs_allocated_count = num_vfs; | ||
1276 | dev_info(&pdev->dev, | ||
1277 | "%d vfs allocated\n", | ||
1278 | num_vfs); | ||
1279 | for (i = 0; | ||
1280 | i < adapter->vfs_allocated_count; | ||
1281 | i++) { | ||
1282 | random_ether_addr(mac_addr); | ||
1283 | igb_set_vf_mac(adapter, i, | ||
1284 | mac_addr); | ||
1285 | } | ||
1286 | } else { | ||
1287 | kfree(adapter->vf_data); | ||
1288 | adapter->vf_data = NULL; | ||
1289 | } | ||
1290 | } | ||
1291 | } | ||
1292 | } | ||
1293 | |||
1294 | #endif | ||
1241 | /* setup the private structure */ | 1295 | /* setup the private structure */ |
1242 | err = igb_sw_init(adapter); | 1296 | err = igb_sw_init(adapter); |
1243 | if (err) | 1297 | if (err) |
@@ -1397,19 +1451,6 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
1397 | if (err) | 1451 | if (err) |
1398 | goto err_register; | 1452 | goto err_register; |
1399 | 1453 | ||
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 | 1454 | #ifdef CONFIG_IGB_DCA |
1414 | if (dca_add_requester(&pdev->dev) == 0) { | 1455 | if (dca_add_requester(&pdev->dev) == 0) { |
1415 | adapter->flags |= IGB_FLAG_DCA_ENABLED; | 1456 | adapter->flags |= IGB_FLAG_DCA_ENABLED; |
@@ -5422,89 +5463,4 @@ static void igb_vmm_control(struct igb_adapter *adapter) | |||
5422 | igb_vmdq_set_replication_pf(hw, true); | 5463 | igb_vmdq_set_replication_pf(hw, true); |
5423 | } | 5464 | } |
5424 | 5465 | ||
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); | ||
5491 | igb_set_vf_mac(adapter, i, mac_addr); | ||
5492 | } | ||
5493 | } else { | ||
5494 | kfree(adapter->vf_data); | ||
5495 | adapter->vf_data = NULL; | ||
5496 | } | ||
5497 | } | ||
5498 | } | ||
5499 | |||
5500 | igb_set_interrupt_capability(adapter); | ||
5501 | igb_alloc_queues(adapter); | ||
5502 | igb_reset(adapter); | ||
5503 | |||
5504 | if (netdev->flags & IFF_UP) | ||
5505 | igb_open(netdev); | ||
5506 | |||
5507 | return count; | ||
5508 | } | ||
5509 | #endif /* CONFIG_PCI_IOV */ | ||
5510 | /* igb_main.c */ | 5466 | /* igb_main.c */ |