diff options
Diffstat (limited to 'drivers/net/igb')
-rw-r--r-- | drivers/net/igb/igb_main.c | 125 |
1 files changed, 120 insertions, 5 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index b9e7980e3f47..6cae258df96d 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -146,12 +146,18 @@ static struct notifier_block dca_notifier = { | |||
146 | .priority = 0 | 146 | .priority = 0 |
147 | }; | 147 | }; |
148 | #endif | 148 | #endif |
149 | |||
150 | #ifdef CONFIG_NET_POLL_CONTROLLER | 149 | #ifdef CONFIG_NET_POLL_CONTROLLER |
151 | /* for netdump / net console */ | 150 | /* for netdump / net console */ |
152 | static void igb_netpoll(struct net_device *); | 151 | static void igb_netpoll(struct net_device *); |
153 | #endif | 152 | #endif |
154 | 153 | ||
154 | #ifdef CONFIG_PCI_IOV | ||
155 | static ssize_t igb_set_num_vfs(struct device *, struct device_attribute *, | ||
156 | const char *, size_t); | ||
157 | static ssize_t igb_show_num_vfs(struct device *, struct device_attribute *, | ||
158 | char *); | ||
159 | DEVICE_ATTR(num_vfs, S_IRUGO | S_IWUSR, igb_show_num_vfs, igb_set_num_vfs); | ||
160 | #endif | ||
155 | static pci_ers_result_t igb_io_error_detected(struct pci_dev *, | 161 | static pci_ers_result_t igb_io_error_detected(struct pci_dev *, |
156 | pci_channel_state_t); | 162 | pci_channel_state_t); |
157 | static pci_ers_result_t igb_io_slot_reset(struct pci_dev *); | 163 | static pci_ers_result_t igb_io_slot_reset(struct pci_dev *); |
@@ -588,9 +594,6 @@ static int igb_request_msix(struct igb_adapter *adapter) | |||
588 | goto out; | 594 | goto out; |
589 | ring->itr_register = E1000_EITR(0) + (vector << 2); | 595 | ring->itr_register = E1000_EITR(0) + (vector << 2); |
590 | ring->itr_val = adapter->itr; | 596 | ring->itr_val = adapter->itr; |
591 | /* overwrite the poll routine for MSIX, we've already done | ||
592 | * netif_napi_add */ | ||
593 | ring->napi.poll = &igb_clean_rx_ring_msix; | ||
594 | vector++; | 597 | vector++; |
595 | } | 598 | } |
596 | 599 | ||
@@ -1392,6 +1395,19 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
1392 | if (err) | 1395 | if (err) |
1393 | goto err_register; | 1396 | goto err_register; |
1394 | 1397 | ||
1398 | #ifdef CONFIG_PCI_IOV | ||
1399 | /* since iov functionality isn't critical to base device function we | ||
1400 | * can accept failure. If it fails we don't allow iov to be enabled */ | ||
1401 | if (hw->mac.type == e1000_82576) { | ||
1402 | err = pci_enable_sriov(pdev, 0); | ||
1403 | if (!err) | ||
1404 | err = device_create_file(&netdev->dev, | ||
1405 | &dev_attr_num_vfs); | ||
1406 | if (err) | ||
1407 | dev_err(&pdev->dev, "Failed to initialize IOV\n"); | ||
1408 | } | ||
1409 | |||
1410 | #endif | ||
1395 | #ifdef CONFIG_IGB_DCA | 1411 | #ifdef CONFIG_IGB_DCA |
1396 | if (dca_add_requester(&pdev->dev) == 0) { | 1412 | if (dca_add_requester(&pdev->dev) == 0) { |
1397 | adapter->flags |= IGB_FLAG_DCA_ENABLED; | 1413 | adapter->flags |= IGB_FLAG_DCA_ENABLED; |
@@ -1547,6 +1563,20 @@ static void __devexit igb_remove(struct pci_dev *pdev) | |||
1547 | 1563 | ||
1548 | igb_free_queues(adapter); | 1564 | igb_free_queues(adapter); |
1549 | 1565 | ||
1566 | #ifdef CONFIG_PCI_IOV | ||
1567 | /* reclaim resources allocated to VFs */ | ||
1568 | if (adapter->vf_data) { | ||
1569 | /* disable iov and allow time for transactions to clear */ | ||
1570 | pci_disable_sriov(pdev); | ||
1571 | msleep(500); | ||
1572 | |||
1573 | kfree(adapter->vf_data); | ||
1574 | adapter->vf_data = NULL; | ||
1575 | wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); | ||
1576 | msleep(100); | ||
1577 | dev_info(&pdev->dev, "IOV Disabled\n"); | ||
1578 | } | ||
1579 | #endif | ||
1550 | iounmap(hw->hw_addr); | 1580 | iounmap(hw->hw_addr); |
1551 | if (hw->flash_address) | 1581 | if (hw->flash_address) |
1552 | iounmap(hw->flash_address); | 1582 | iounmap(hw->flash_address); |
@@ -5341,7 +5371,7 @@ static int igb_set_vf_mac(struct igb_adapter *adapter, | |||
5341 | 5371 | ||
5342 | igb_rar_set(hw, mac_addr, rar_entry); | 5372 | igb_rar_set(hw, mac_addr, rar_entry); |
5343 | 5373 | ||
5344 | memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, 6); | 5374 | memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN); |
5345 | 5375 | ||
5346 | igb_set_rah_pool(hw, vf, rar_entry); | 5376 | igb_set_rah_pool(hw, vf, rar_entry); |
5347 | 5377 | ||
@@ -5366,4 +5396,89 @@ static void igb_vmm_control(struct igb_adapter *adapter) | |||
5366 | igb_vmdq_set_replication_pf(hw, true); | 5396 | igb_vmdq_set_replication_pf(hw, true); |
5367 | } | 5397 | } |
5368 | 5398 | ||
5399 | #ifdef CONFIG_PCI_IOV | ||
5400 | static ssize_t igb_show_num_vfs(struct device *dev, | ||
5401 | struct device_attribute *attr, char *buf) | ||
5402 | { | ||
5403 | struct igb_adapter *adapter = netdev_priv(to_net_dev(dev)); | ||
5404 | |||
5405 | return sprintf(buf, "%d\n", adapter->vfs_allocated_count); | ||
5406 | } | ||
5407 | |||
5408 | static ssize_t igb_set_num_vfs(struct device *dev, | ||
5409 | struct device_attribute *attr, | ||
5410 | const char *buf, size_t count) | ||
5411 | { | ||
5412 | struct net_device *netdev = to_net_dev(dev); | ||
5413 | struct igb_adapter *adapter = netdev_priv(netdev); | ||
5414 | struct e1000_hw *hw = &adapter->hw; | ||
5415 | struct pci_dev *pdev = adapter->pdev; | ||
5416 | unsigned int num_vfs, i; | ||
5417 | unsigned char mac_addr[ETH_ALEN]; | ||
5418 | int err; | ||
5419 | |||
5420 | sscanf(buf, "%u", &num_vfs); | ||
5421 | |||
5422 | if (num_vfs > 7) | ||
5423 | num_vfs = 7; | ||
5424 | |||
5425 | /* value unchanged do nothing */ | ||
5426 | if (num_vfs == adapter->vfs_allocated_count) | ||
5427 | return count; | ||
5428 | |||
5429 | if (netdev->flags & IFF_UP) | ||
5430 | igb_close(netdev); | ||
5431 | |||
5432 | igb_reset_interrupt_capability(adapter); | ||
5433 | igb_free_queues(adapter); | ||
5434 | adapter->tx_ring = NULL; | ||
5435 | adapter->rx_ring = NULL; | ||
5436 | adapter->vfs_allocated_count = 0; | ||
5437 | |||
5438 | /* reclaim resources allocated to VFs since we are changing count */ | ||
5439 | if (adapter->vf_data) { | ||
5440 | /* disable iov and allow time for transactions to clear */ | ||
5441 | pci_disable_sriov(pdev); | ||
5442 | msleep(500); | ||
5443 | |||
5444 | kfree(adapter->vf_data); | ||
5445 | adapter->vf_data = NULL; | ||
5446 | wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); | ||
5447 | msleep(100); | ||
5448 | dev_info(&pdev->dev, "IOV Disabled\n"); | ||
5449 | } | ||
5450 | |||
5451 | if (num_vfs) { | ||
5452 | adapter->vf_data = kcalloc(num_vfs, | ||
5453 | sizeof(struct vf_data_storage), | ||
5454 | GFP_KERNEL); | ||
5455 | if (!adapter->vf_data) { | ||
5456 | dev_err(&pdev->dev, "Could not allocate VF private " | ||
5457 | "data - IOV enable failed\n"); | ||
5458 | } else { | ||
5459 | err = pci_enable_sriov(pdev, num_vfs); | ||
5460 | if (!err) { | ||
5461 | adapter->vfs_allocated_count = num_vfs; | ||
5462 | dev_info(&pdev->dev, "%d vfs allocated\n", num_vfs); | ||
5463 | for (i = 0; i < adapter->vfs_allocated_count; i++) { | ||
5464 | random_ether_addr(mac_addr); | ||
5465 | igb_set_vf_mac(adapter, i, mac_addr); | ||
5466 | } | ||
5467 | } else { | ||
5468 | kfree(adapter->vf_data); | ||
5469 | adapter->vf_data = NULL; | ||
5470 | } | ||
5471 | } | ||
5472 | } | ||
5473 | |||
5474 | igb_set_interrupt_capability(adapter); | ||
5475 | igb_alloc_queues(adapter); | ||
5476 | igb_reset(adapter); | ||
5477 | |||
5478 | if (netdev->flags & IFF_UP) | ||
5479 | igb_open(netdev); | ||
5480 | |||
5481 | return count; | ||
5482 | } | ||
5483 | #endif /* CONFIG_PCI_IOV */ | ||
5369 | /* igb_main.c */ | 5484 | /* igb_main.c */ |