diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 137 | 
1 files changed, 58 insertions, 79 deletions
| diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 03bc1e8af575..274c781b5547 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -109,6 +109,7 @@ static void igb_free_all_rx_resources(struct igb_adapter *);  static void igb_setup_mrqc(struct igb_adapter *);  static int igb_probe(struct pci_dev *, const struct pci_device_id *);  static void igb_remove(struct pci_dev *pdev); +static void igb_init_queue_configuration(struct igb_adapter *adapter);  static int igb_sw_init(struct igb_adapter *);  int igb_open(struct net_device *);  int igb_close(struct net_device *); @@ -175,9 +176,7 @@ static void igb_nfc_filter_restore(struct igb_adapter *adapter);  #ifdef CONFIG_PCI_IOV  static int igb_vf_configure(struct igb_adapter *adapter, int vf); -static int igb_pci_enable_sriov(struct pci_dev *dev, int num_vfs); -static int igb_disable_sriov(struct pci_dev *dev); -static int igb_pci_disable_sriov(struct pci_dev *dev); +static int igb_disable_sriov(struct pci_dev *dev, bool reinit);  #endif  static int igb_suspend(struct device *); @@ -3665,7 +3664,7 @@ err_sw_init:  	kfree(adapter->shadow_vfta);  	igb_clear_interrupt_scheme(adapter);  #ifdef CONFIG_PCI_IOV -	igb_disable_sriov(pdev); +	igb_disable_sriov(pdev, false);  #endif  	pci_iounmap(pdev, adapter->io_addr);  err_ioremap: @@ -3679,7 +3678,38 @@ err_dma:  }  #ifdef CONFIG_PCI_IOV -static int igb_disable_sriov(struct pci_dev *pdev) +static int igb_sriov_reinit(struct pci_dev *dev) +{ +	struct net_device *netdev = pci_get_drvdata(dev); +	struct igb_adapter *adapter = netdev_priv(netdev); +	struct pci_dev *pdev = adapter->pdev; + +	rtnl_lock(); + +	if (netif_running(netdev)) +		igb_close(netdev); +	else +		igb_reset(adapter); + +	igb_clear_interrupt_scheme(adapter); + +	igb_init_queue_configuration(adapter); + +	if (igb_init_interrupt_scheme(adapter, true)) { +		rtnl_unlock(); +		dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); +		return -ENOMEM; +	} + +	if (netif_running(netdev)) +		igb_open(netdev); + +	rtnl_unlock(); + +	return 0; +} + +static int igb_disable_sriov(struct pci_dev *pdev, bool reinit)  {  	struct net_device *netdev = pci_get_drvdata(pdev);  	struct igb_adapter *adapter = netdev_priv(netdev); @@ -3713,10 +3743,10 @@ static int igb_disable_sriov(struct pci_dev *pdev)  		adapter->flags |= IGB_FLAG_DMAC;  	} -	return 0; +	return reinit ? igb_sriov_reinit(pdev) : 0;  } -static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs) +static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs, bool reinit)  {  	struct net_device *netdev = pci_get_drvdata(pdev);  	struct igb_adapter *adapter = netdev_priv(netdev); @@ -3781,12 +3811,6 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)  			"Unable to allocate memory for VF MAC filter list\n");  	} -	/* only call pci_enable_sriov() if no VFs are allocated already */ -	if (!old_vfs) { -		err = pci_enable_sriov(pdev, adapter->vfs_allocated_count); -		if (err) -			goto err_out; -	}  	dev_info(&pdev->dev, "%d VFs allocated\n",  		 adapter->vfs_allocated_count);  	for (i = 0; i < adapter->vfs_allocated_count; i++) @@ -3794,6 +3818,17 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)  	/* DMA Coalescing is not supported in IOV mode. */  	adapter->flags &= ~IGB_FLAG_DMAC; + +	if (reinit) { +		err = igb_sriov_reinit(pdev); +		if (err) +			goto err_out; +	} + +	/* only call pci_enable_sriov() if no VFs are allocated already */ +	if (!old_vfs) +		err = pci_enable_sriov(pdev, adapter->vfs_allocated_count); +  	goto out;  err_out: @@ -3863,9 +3898,7 @@ static void igb_remove(struct pci_dev *pdev)  	igb_release_hw_control(adapter);  #ifdef CONFIG_PCI_IOV -	rtnl_lock(); -	igb_disable_sriov(pdev); -	rtnl_unlock(); +	igb_disable_sriov(pdev, false);  #endif  	unregister_netdev(netdev); @@ -3911,7 +3944,7 @@ static void igb_probe_vfs(struct igb_adapter *adapter)  	igb_reset_interrupt_capability(adapter);  	pci_sriov_set_totalvfs(pdev, 7); -	igb_enable_sriov(pdev, max_vfs); +	igb_enable_sriov(pdev, max_vfs, false);  #endif /* CONFIG_PCI_IOV */  } @@ -9520,71 +9553,17 @@ static void igb_shutdown(struct pci_dev *pdev)  	}  } -#ifdef CONFIG_PCI_IOV -static int igb_sriov_reinit(struct pci_dev *dev) -{ -	struct net_device *netdev = pci_get_drvdata(dev); -	struct igb_adapter *adapter = netdev_priv(netdev); -	struct pci_dev *pdev = adapter->pdev; - -	rtnl_lock(); - -	if (netif_running(netdev)) -		igb_close(netdev); -	else -		igb_reset(adapter); - -	igb_clear_interrupt_scheme(adapter); - -	igb_init_queue_configuration(adapter); - -	if (igb_init_interrupt_scheme(adapter, true)) { -		rtnl_unlock(); -		dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); -		return -ENOMEM; -	} - -	if (netif_running(netdev)) -		igb_open(netdev); - -	rtnl_unlock(); - -	return 0; -} - -static int igb_pci_disable_sriov(struct pci_dev *dev) -{ -	int err = igb_disable_sriov(dev); - -	if (!err) -		err = igb_sriov_reinit(dev); - -	return err; -} - -static int igb_pci_enable_sriov(struct pci_dev *dev, int num_vfs) -{ -	int err = igb_enable_sriov(dev, num_vfs); - -	if (err) -		goto out; - -	err = igb_sriov_reinit(dev); -	if (!err) -		return num_vfs; - -out: -	return err; -} - -#endif  static int igb_pci_sriov_configure(struct pci_dev *dev, int num_vfs)  {  #ifdef CONFIG_PCI_IOV -	if (num_vfs == 0) -		return igb_pci_disable_sriov(dev); -	else -		return igb_pci_enable_sriov(dev, num_vfs); +	int err; + +	if (num_vfs == 0) { +		return igb_disable_sriov(dev, true); +	} else { +		err = igb_enable_sriov(dev, num_vfs, true); +		return err ? err : num_vfs; +	}  #endif  	return 0;  } |