diff options
author | Stefan Assmann <sassmann@kpanic.de> | 2012-08-18 00:06:11 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-09-22 04:38:31 -0400 |
commit | f557147c4615f5e03abb673bd566901783565666 (patch) | |
tree | 130b73b47e0604209167a2311ebdeb1735b2e687 /drivers/net/ethernet/intel | |
parent | abb17e6c0c7b27693201dc85f75dbb184279fd10 (diff) |
igb: Change how we check for pre-existing and assigned VFs
Adapt the pre-existing and assigned VFs code to the ixgbe way introduced
in commit 9297127b9cdd8d30c829ef5fd28b7cc0323a7bcd.
Instead of searching the enabled VFs we use pci_num_vf to determine enabled VFs.
By comparing to which PF an assigned VF is owned it's possible to decide
whether to leave it enabled or not.
Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Robert Garrett <robertx.e.garrett@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 104 |
2 files changed, 22 insertions, 83 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 43c8e2914263..6f17f698fafe 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h | |||
@@ -101,7 +101,6 @@ struct vf_data_storage { | |||
101 | u16 pf_vlan; /* When set, guest VLAN config not allowed. */ | 101 | u16 pf_vlan; /* When set, guest VLAN config not allowed. */ |
102 | u16 pf_qos; | 102 | u16 pf_qos; |
103 | u16 tx_rate; | 103 | u16 tx_rate; |
104 | struct pci_dev *vfdev; | ||
105 | }; | 104 | }; |
106 | 105 | ||
107 | #define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */ | 106 | #define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */ |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 246646b61a1a..073009671e7a 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -172,8 +172,7 @@ static void igb_check_vf_rate_limit(struct igb_adapter *); | |||
172 | 172 | ||
173 | #ifdef CONFIG_PCI_IOV | 173 | #ifdef CONFIG_PCI_IOV |
174 | static int igb_vf_configure(struct igb_adapter *adapter, int vf); | 174 | static int igb_vf_configure(struct igb_adapter *adapter, int vf); |
175 | static int igb_find_enabled_vfs(struct igb_adapter *adapter); | 175 | static bool igb_vfs_are_assigned(struct igb_adapter *adapter); |
176 | static int igb_check_vf_assignment(struct igb_adapter *adapter); | ||
177 | #endif | 176 | #endif |
178 | 177 | ||
179 | #ifdef CONFIG_PM | 178 | #ifdef CONFIG_PM |
@@ -2300,11 +2299,11 @@ static void __devexit igb_remove(struct pci_dev *pdev) | |||
2300 | /* reclaim resources allocated to VFs */ | 2299 | /* reclaim resources allocated to VFs */ |
2301 | if (adapter->vf_data) { | 2300 | if (adapter->vf_data) { |
2302 | /* disable iov and allow time for transactions to clear */ | 2301 | /* disable iov and allow time for transactions to clear */ |
2303 | if (!igb_check_vf_assignment(adapter)) { | 2302 | if (igb_vfs_are_assigned(adapter)) { |
2303 | dev_info(&pdev->dev, "Unloading driver while VFs are assigned - VFs will not be deallocated\n"); | ||
2304 | } else { | ||
2304 | pci_disable_sriov(pdev); | 2305 | pci_disable_sriov(pdev); |
2305 | msleep(500); | 2306 | msleep(500); |
2306 | } else { | ||
2307 | dev_info(&pdev->dev, "VF(s) assigned to guests!\n"); | ||
2308 | } | 2307 | } |
2309 | 2308 | ||
2310 | kfree(adapter->vf_data); | 2309 | kfree(adapter->vf_data); |
@@ -2344,7 +2343,7 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter) | |||
2344 | #ifdef CONFIG_PCI_IOV | 2343 | #ifdef CONFIG_PCI_IOV |
2345 | struct pci_dev *pdev = adapter->pdev; | 2344 | struct pci_dev *pdev = adapter->pdev; |
2346 | struct e1000_hw *hw = &adapter->hw; | 2345 | struct e1000_hw *hw = &adapter->hw; |
2347 | int old_vfs = igb_find_enabled_vfs(adapter); | 2346 | int old_vfs = pci_num_vf(adapter->pdev); |
2348 | int i; | 2347 | int i; |
2349 | 2348 | ||
2350 | /* Virtualization features not supported on i210 family. */ | 2349 | /* Virtualization features not supported on i210 family. */ |
@@ -5037,102 +5036,43 @@ static int igb_notify_dca(struct notifier_block *nb, unsigned long event, | |||
5037 | static int igb_vf_configure(struct igb_adapter *adapter, int vf) | 5036 | static int igb_vf_configure(struct igb_adapter *adapter, int vf) |
5038 | { | 5037 | { |
5039 | unsigned char mac_addr[ETH_ALEN]; | 5038 | unsigned char mac_addr[ETH_ALEN]; |
5040 | struct pci_dev *pdev = adapter->pdev; | ||
5041 | struct e1000_hw *hw = &adapter->hw; | ||
5042 | struct pci_dev *pvfdev; | ||
5043 | unsigned int device_id; | ||
5044 | u16 thisvf_devfn; | ||
5045 | 5039 | ||
5046 | eth_random_addr(mac_addr); | 5040 | eth_random_addr(mac_addr); |
5047 | igb_set_vf_mac(adapter, vf, mac_addr); | 5041 | igb_set_vf_mac(adapter, vf, mac_addr); |
5048 | 5042 | ||
5049 | switch (adapter->hw.mac.type) { | 5043 | return 0; |
5050 | case e1000_82576: | ||
5051 | device_id = IGB_82576_VF_DEV_ID; | ||
5052 | /* VF Stride for 82576 is 2 */ | ||
5053 | thisvf_devfn = (pdev->devfn + 0x80 + (vf << 1)) | | ||
5054 | (pdev->devfn & 1); | ||
5055 | break; | ||
5056 | case e1000_i350: | ||
5057 | device_id = IGB_I350_VF_DEV_ID; | ||
5058 | /* VF Stride for I350 is 4 */ | ||
5059 | thisvf_devfn = (pdev->devfn + 0x80 + (vf << 2)) | | ||
5060 | (pdev->devfn & 3); | ||
5061 | break; | ||
5062 | default: | ||
5063 | device_id = 0; | ||
5064 | thisvf_devfn = 0; | ||
5065 | break; | ||
5066 | } | ||
5067 | |||
5068 | pvfdev = pci_get_device(hw->vendor_id, device_id, NULL); | ||
5069 | while (pvfdev) { | ||
5070 | if (pvfdev->devfn == thisvf_devfn) | ||
5071 | break; | ||
5072 | pvfdev = pci_get_device(hw->vendor_id, | ||
5073 | device_id, pvfdev); | ||
5074 | } | ||
5075 | |||
5076 | if (pvfdev) | ||
5077 | adapter->vf_data[vf].vfdev = pvfdev; | ||
5078 | else | ||
5079 | dev_err(&pdev->dev, | ||
5080 | "Couldn't find pci dev ptr for VF %4.4x\n", | ||
5081 | thisvf_devfn); | ||
5082 | return pvfdev != NULL; | ||
5083 | } | 5044 | } |
5084 | 5045 | ||
5085 | static int igb_find_enabled_vfs(struct igb_adapter *adapter) | 5046 | static bool igb_vfs_are_assigned(struct igb_adapter *adapter) |
5086 | { | 5047 | { |
5087 | struct e1000_hw *hw = &adapter->hw; | ||
5088 | struct pci_dev *pdev = adapter->pdev; | 5048 | struct pci_dev *pdev = adapter->pdev; |
5089 | struct pci_dev *pvfdev; | 5049 | struct pci_dev *vfdev; |
5090 | u16 vf_devfn = 0; | 5050 | int dev_id; |
5091 | u16 vf_stride; | ||
5092 | unsigned int device_id; | ||
5093 | int vfs_found = 0; | ||
5094 | 5051 | ||
5095 | switch (adapter->hw.mac.type) { | 5052 | switch (adapter->hw.mac.type) { |
5096 | case e1000_82576: | 5053 | case e1000_82576: |
5097 | device_id = IGB_82576_VF_DEV_ID; | 5054 | dev_id = IGB_82576_VF_DEV_ID; |
5098 | /* VF Stride for 82576 is 2 */ | ||
5099 | vf_stride = 2; | ||
5100 | break; | 5055 | break; |
5101 | case e1000_i350: | 5056 | case e1000_i350: |
5102 | device_id = IGB_I350_VF_DEV_ID; | 5057 | dev_id = IGB_I350_VF_DEV_ID; |
5103 | /* VF Stride for I350 is 4 */ | ||
5104 | vf_stride = 4; | ||
5105 | break; | 5058 | break; |
5106 | default: | 5059 | default: |
5107 | device_id = 0; | 5060 | return false; |
5108 | vf_stride = 0; | ||
5109 | break; | ||
5110 | } | ||
5111 | |||
5112 | vf_devfn = pdev->devfn + 0x80; | ||
5113 | pvfdev = pci_get_device(hw->vendor_id, device_id, NULL); | ||
5114 | while (pvfdev) { | ||
5115 | if (pvfdev->devfn == vf_devfn && | ||
5116 | (pvfdev->bus->number >= pdev->bus->number)) | ||
5117 | vfs_found++; | ||
5118 | vf_devfn += vf_stride; | ||
5119 | pvfdev = pci_get_device(hw->vendor_id, | ||
5120 | device_id, pvfdev); | ||
5121 | } | 5061 | } |
5122 | 5062 | ||
5123 | return vfs_found; | 5063 | /* loop through all the VFs to see if we own any that are assigned */ |
5124 | } | 5064 | vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL); |
5125 | 5065 | while (vfdev) { | |
5126 | static int igb_check_vf_assignment(struct igb_adapter *adapter) | 5066 | /* if we don't own it we don't care */ |
5127 | { | 5067 | if (vfdev->is_virtfn && vfdev->physfn == pdev) { |
5128 | int i; | 5068 | /* if it is assigned we cannot release it */ |
5129 | for (i = 0; i < adapter->vfs_allocated_count; i++) { | 5069 | if (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED) |
5130 | if (adapter->vf_data[i].vfdev) { | ||
5131 | if (adapter->vf_data[i].vfdev->dev_flags & | ||
5132 | PCI_DEV_FLAGS_ASSIGNED) | ||
5133 | return true; | 5070 | return true; |
5134 | } | 5071 | } |
5072 | |||
5073 | vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, vfdev); | ||
5135 | } | 5074 | } |
5075 | |||
5136 | return false; | 5076 | return false; |
5137 | } | 5077 | } |
5138 | 5078 | ||