aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb/igb_main.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-02-19 23:40:30 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-20 03:22:54 -0500
commit376801172ade1ab80efdd42dba859282400885ed (patch)
tree0e9edfc72125712318f2e9107658f434ff41dd45 /drivers/net/igb/igb_main.c
parent4ae196dfd61d06b061c069edcdd7c73121e60a21 (diff)
igb: this patch addes the sr-iov enablement option via num_vfs parameter
This code adds a module parameter called num_vfs which defines if the driver should attempt to use sr-iov and if so how many VFs should be enabled. 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>
Diffstat (limited to 'drivers/net/igb/igb_main.c')
-rw-r--r--drivers/net/igb/igb_main.c125
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 */
152static void igb_netpoll(struct net_device *); 151static void igb_netpoll(struct net_device *);
153#endif 152#endif
154 153
154#ifdef CONFIG_PCI_IOV
155static ssize_t igb_set_num_vfs(struct device *, struct device_attribute *,
156 const char *, size_t);
157static ssize_t igb_show_num_vfs(struct device *, struct device_attribute *,
158 char *);
159DEVICE_ATTR(num_vfs, S_IRUGO | S_IWUSR, igb_show_num_vfs, igb_set_num_vfs);
160#endif
155static pci_ers_result_t igb_io_error_detected(struct pci_dev *, 161static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
156 pci_channel_state_t); 162 pci_channel_state_t);
157static pci_ers_result_t igb_io_slot_reset(struct pci_dev *); 163static 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
5400static 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
5408static 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 */