aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorStefan Assmann <sassmann@kpanic.de>2012-08-18 00:06:11 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-09-22 04:38:31 -0400
commitf557147c4615f5e03abb673bd566901783565666 (patch)
tree130b73b47e0604209167a2311ebdeb1735b2e687 /drivers/net/ethernet/intel
parentabb17e6c0c7b27693201dc85f75dbb184279fd10 (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.h1
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c104
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
174static int igb_vf_configure(struct igb_adapter *adapter, int vf); 174static int igb_vf_configure(struct igb_adapter *adapter, int vf);
175static int igb_find_enabled_vfs(struct igb_adapter *adapter); 175static bool igb_vfs_are_assigned(struct igb_adapter *adapter);
176static 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,
5037static int igb_vf_configure(struct igb_adapter *adapter, int vf) 5036static 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
5085static int igb_find_enabled_vfs(struct igb_adapter *adapter) 5046static 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) {
5126static 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