aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-05-22 22:58:40 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-07-21 19:02:56 -0400
commit9297127b9cdd8d30c829ef5fd28b7cc0323a7bcd (patch)
tree1c5c99f9144f9738436c35c5bdad3a98b70d730a
parent99d744875d01d57d832b8dbfc36d9a1990d503b8 (diff)
ixgbe: Change how we check for pre-existing and assigned VFs
This patch does two things. First it drops the unnecessary work of searching for enabled VFs when we first bring up the adapter and instead just uses pci_num_vf to determine how many VFs are enabled on the adapter. The second thing it does is drop the use of vfdev from the vf_data_storage structure. Instead we just search the entire system for a VF that has us as it's PF, and then if that VF is assigned we indicate that the VFs are assigned. This allows us to still check for assigned VFs even if the vfinfo allocation has failed, or vfinfo has been freed. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Acked-by: Greg Rose <gregory.v.rose@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Tested-by: Sibai Li <sibai.li@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h1
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c8
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c129
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h1
4 files changed, 45 insertions, 94 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 5a286adc65c0..eb5928228670 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -130,7 +130,6 @@ struct vf_data_storage {
130 u16 tx_rate; 130 u16 tx_rate;
131 u16 vlan_count; 131 u16 vlan_count;
132 u8 spoofchk_enabled; 132 u8 spoofchk_enabled;
133 struct pci_dev *vfdev;
134}; 133};
135 134
136struct vf_macvlans { 135struct vf_macvlans {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 24f2b455a23f..9c42679ad83e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7452,13 +7452,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
7452 if (netdev->reg_state == NETREG_REGISTERED) 7452 if (netdev->reg_state == NETREG_REGISTERED)
7453 unregister_netdev(netdev); 7453 unregister_netdev(netdev);
7454 7454
7455 if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { 7455 ixgbe_disable_sriov(adapter);
7456 if (!(ixgbe_check_vf_assignment(adapter)))
7457 ixgbe_disable_sriov(adapter);
7458 else
7459 e_dev_warn("Unloading driver while VFs are assigned "
7460 "- VFs will not be deallocated\n");
7461 }
7462 7456
7463 ixgbe_clear_interrupt_scheme(adapter); 7457 ixgbe_clear_interrupt_scheme(adapter);
7464 7458
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 593fdd54f9ab..47b2ce740ec1 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -44,40 +44,6 @@
44#include "ixgbe_sriov.h" 44#include "ixgbe_sriov.h"
45 45
46#ifdef CONFIG_PCI_IOV 46#ifdef CONFIG_PCI_IOV
47static int ixgbe_find_enabled_vfs(struct ixgbe_adapter *adapter)
48{
49 struct pci_dev *pdev = adapter->pdev;
50 struct pci_dev *pvfdev;
51 u16 vf_devfn = 0;
52 int device_id;
53 int vfs_found = 0;
54
55 switch (adapter->hw.mac.type) {
56 case ixgbe_mac_82599EB:
57 device_id = IXGBE_DEV_ID_82599_VF;
58 break;
59 case ixgbe_mac_X540:
60 device_id = IXGBE_DEV_ID_X540_VF;
61 break;
62 default:
63 device_id = 0;
64 break;
65 }
66
67 vf_devfn = pdev->devfn + 0x80;
68 pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL, device_id, NULL);
69 while (pvfdev) {
70 if (pvfdev->devfn == vf_devfn &&
71 (pvfdev->bus->number >= pdev->bus->number))
72 vfs_found++;
73 vf_devfn += 2;
74 pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL,
75 device_id, pvfdev);
76 }
77
78 return vfs_found;
79}
80
81void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, 47void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
82 const struct ixgbe_info *ii) 48 const struct ixgbe_info *ii)
83{ 49{
@@ -86,7 +52,7 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
86 struct vf_macvlans *mv_list; 52 struct vf_macvlans *mv_list;
87 int pre_existing_vfs = 0; 53 int pre_existing_vfs = 0;
88 54
89 pre_existing_vfs = ixgbe_find_enabled_vfs(adapter); 55 pre_existing_vfs = pci_num_vf(adapter->pdev);
90 if (!pre_existing_vfs && !adapter->num_vfs) 56 if (!pre_existing_vfs && !adapter->num_vfs)
91 return; 57 return;
92 58
@@ -205,14 +171,46 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
205 "SRIOV disabled\n"); 171 "SRIOV disabled\n");
206 ixgbe_disable_sriov(adapter); 172 ixgbe_disable_sriov(adapter);
207} 173}
208#endif /* #ifdef CONFIG_PCI_IOV */
209 174
175static bool ixgbe_vfs_are_assigned(struct ixgbe_adapter *adapter)
176{
177 struct pci_dev *pdev = adapter->pdev;
178 struct pci_dev *vfdev;
179 int dev_id;
180
181 switch (adapter->hw.mac.type) {
182 case ixgbe_mac_82599EB:
183 dev_id = IXGBE_DEV_ID_82599_VF;
184 break;
185 case ixgbe_mac_X540:
186 dev_id = IXGBE_DEV_ID_X540_VF;
187 break;
188 default:
189 return false;
190 }
191
192 /* loop through all the VFs to see if we own any that are assigned */
193 vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL);
194 while (vfdev) {
195 /* if we don't own it we don't care */
196 if (vfdev->is_virtfn && vfdev->physfn == pdev) {
197 /* if it is assigned we cannot release it */
198 if (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
199 return true;
200 }
201
202 vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, vfdev);
203 }
204
205 return false;
206}
207
208#endif /* #ifdef CONFIG_PCI_IOV */
210void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) 209void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
211{ 210{
212 struct ixgbe_hw *hw = &adapter->hw; 211 struct ixgbe_hw *hw = &adapter->hw;
213 u32 gpie; 212 u32 gpie;
214 u32 vmdctl; 213 u32 vmdctl;
215 int i;
216 214
217 /* set num VFs to 0 to prevent access to vfinfo */ 215 /* set num VFs to 0 to prevent access to vfinfo */
218 adapter->num_vfs = 0; 216 adapter->num_vfs = 0;
@@ -230,6 +228,15 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
230 return; 228 return;
231 229
232#ifdef CONFIG_PCI_IOV 230#ifdef CONFIG_PCI_IOV
231 /*
232 * If our VFs are assigned we cannot shut down SR-IOV
233 * without causing issues, so just leave the hardware
234 * available but disabled
235 */
236 if (ixgbe_vfs_are_assigned(adapter)) {
237 e_dev_warn("Unloading driver while VFs are assigned - VFs will not be deallocated\n");
238 return;
239
233 /* disable iov and allow time for transactions to clear */ 240 /* disable iov and allow time for transactions to clear */
234 pci_disable_sriov(adapter->pdev); 241 pci_disable_sriov(adapter->pdev);
235#endif 242#endif
@@ -254,12 +261,6 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
254 /* take a breather then clean up driver data */ 261 /* take a breather then clean up driver data */
255 msleep(100); 262 msleep(100);
256 263
257 /* Release reference to VF devices */
258 for (i = 0; i < adapter->num_vfs; i++) {
259 if (adapter->vfinfo[i].vfdev)
260 pci_dev_put(adapter->vfinfo[i].vfdev);
261 }
262
263 adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED; 264 adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
264} 265}
265 266
@@ -493,28 +494,11 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
493 return 0; 494 return 0;
494} 495}
495 496
496int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter)
497{
498#ifdef CONFIG_PCI_IOV
499 int i;
500 for (i = 0; i < adapter->num_vfs; i++) {
501 if (adapter->vfinfo[i].vfdev->dev_flags &
502 PCI_DEV_FLAGS_ASSIGNED)
503 return true;
504 }
505#endif
506 return false;
507}
508
509int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) 497int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
510{ 498{
511 unsigned char vf_mac_addr[6]; 499 unsigned char vf_mac_addr[6];
512 struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); 500 struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
513 unsigned int vfn = (event_mask & 0x3f); 501 unsigned int vfn = (event_mask & 0x3f);
514 struct pci_dev *pvfdev;
515 unsigned int device_id;
516 u16 thisvf_devfn = (pdev->devfn + 0x80 + (vfn << 1)) |
517 (pdev->devfn & 1);
518 502
519 bool enable = ((event_mask & 0x10000000U) != 0); 503 bool enable = ((event_mask & 0x10000000U) != 0);
520 504
@@ -527,31 +511,6 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
527 * for it later. 511 * for it later.
528 */ 512 */
529 memcpy(adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 6); 513 memcpy(adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 6);
530
531 switch (adapter->hw.mac.type) {
532 case ixgbe_mac_82599EB:
533 device_id = IXGBE_DEV_ID_82599_VF;
534 break;
535 case ixgbe_mac_X540:
536 device_id = IXGBE_DEV_ID_X540_VF;
537 break;
538 default:
539 device_id = 0;
540 break;
541 }
542
543 pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL, device_id, NULL);
544 while (pvfdev) {
545 if (pvfdev->devfn == thisvf_devfn)
546 break;
547 pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL,
548 device_id, pvfdev);
549 }
550 if (pvfdev)
551 adapter->vfinfo[vfn].vfdev = pvfdev;
552 else
553 e_err(drv, "Couldn't find pci dev ptr for VF %4.4x\n",
554 thisvf_devfn);
555 } 514 }
556 515
557 return 0; 516 return 0;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
index 2ab38d5fda92..1be1d30e4e78 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
@@ -42,7 +42,6 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,
42 int vf, struct ifla_vf_info *ivi); 42 int vf, struct ifla_vf_info *ivi);
43void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter); 43void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);
44void ixgbe_disable_sriov(struct ixgbe_adapter *adapter); 44void ixgbe_disable_sriov(struct ixgbe_adapter *adapter);
45int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter);
46#ifdef CONFIG_PCI_IOV 45#ifdef CONFIG_PCI_IOV
47void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, 46void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
48 const struct ixgbe_info *ii); 47 const struct ixgbe_info *ii);