aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorGreg Rose <gregory.v.rose@intel.com>2011-10-13 22:57:14 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-10-17 08:08:13 -0400
commit0224d663063d542b3d829706f3fcbd0f640f19b3 (patch)
treeffdcb4a4f95e499424ad01d9436b993720bfeb48 /drivers/net/ethernet/intel
parent4d2d55ac94f52ea8787270ec29579ced83f5f96b (diff)
igb: Check if subordinate VFs are assigned to virtual machines
Kvm and the Xen pci-back driver will set a flag in the virtual function pci device dev_flags when the VF is assigned to a guest VM. Before destroying subordinate VFs check to see if the flag is set and if so skip the call to pci_disable_sriov() to avoid system crashes. Copy the maintainer for the Xen pci-back driver. Also CC'ing maintainers of all drivers found to call pci_disable_sriov(). V2 - Fix uninitialized variable warning Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Christian Benvenuti <benve@cisco.com> Cc: Sathya Perla <sathya.perla@emulex.com> Cc: Dimitris Michailidis <dm@chelsio.com> Cc: Jon Mason <jdmason@kudzu.us> Cc: James Smart <james.smart@emulex.com> Signed-off-by: Greg Rose <gregory.v.rose@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.h3
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c177
2 files changed, 150 insertions, 30 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 4c500a76972e..559443015cc5 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -72,6 +72,8 @@ struct igb_adapter;
72#define IGB_MAX_VF_MC_ENTRIES 30 72#define IGB_MAX_VF_MC_ENTRIES 30
73#define IGB_MAX_VF_FUNCTIONS 8 73#define IGB_MAX_VF_FUNCTIONS 8
74#define IGB_MAX_VFTA_ENTRIES 128 74#define IGB_MAX_VFTA_ENTRIES 128
75#define IGB_82576_VF_DEV_ID 0x10CA
76#define IGB_I350_VF_DEV_ID 0x1520
75 77
76struct vf_data_storage { 78struct vf_data_storage {
77 unsigned char vf_mac_addresses[ETH_ALEN]; 79 unsigned char vf_mac_addresses[ETH_ALEN];
@@ -83,6 +85,7 @@ struct vf_data_storage {
83 u16 pf_vlan; /* When set, guest VLAN config not allowed. */ 85 u16 pf_vlan; /* When set, guest VLAN config not allowed. */
84 u16 pf_qos; 86 u16 pf_qos;
85 u16 tx_rate; 87 u16 tx_rate;
88 struct pci_dev *vfdev;
86}; 89};
87 90
88#define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */ 91#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 c10cc716fdec..837adbbce772 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -162,6 +162,9 @@ static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate);
162static int igb_ndo_get_vf_config(struct net_device *netdev, int vf, 162static int igb_ndo_get_vf_config(struct net_device *netdev, int vf,
163 struct ifla_vf_info *ivi); 163 struct ifla_vf_info *ivi);
164static void igb_check_vf_rate_limit(struct igb_adapter *); 164static void igb_check_vf_rate_limit(struct igb_adapter *);
165static int igb_vf_configure(struct igb_adapter *adapter, int vf);
166static int igb_find_enabled_vfs(struct igb_adapter *adapter);
167static int igb_check_vf_assignment(struct igb_adapter *adapter);
165 168
166#ifdef CONFIG_PM 169#ifdef CONFIG_PM
167static int igb_suspend(struct pci_dev *, pm_message_t); 170static int igb_suspend(struct pci_dev *, pm_message_t);
@@ -2232,8 +2235,12 @@ static void __devexit igb_remove(struct pci_dev *pdev)
2232 /* reclaim resources allocated to VFs */ 2235 /* reclaim resources allocated to VFs */
2233 if (adapter->vf_data) { 2236 if (adapter->vf_data) {
2234 /* disable iov and allow time for transactions to clear */ 2237 /* disable iov and allow time for transactions to clear */
2235 pci_disable_sriov(pdev); 2238 if (!igb_check_vf_assignment(adapter)) {
2236 msleep(500); 2239 pci_disable_sriov(pdev);
2240 msleep(500);
2241 } else {
2242 dev_info(&pdev->dev, "VF(s) assigned to guests!\n");
2243 }
2237 2244
2238 kfree(adapter->vf_data); 2245 kfree(adapter->vf_data);
2239 adapter->vf_data = NULL; 2246 adapter->vf_data = NULL;
@@ -2270,42 +2277,49 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter)
2270{ 2277{
2271#ifdef CONFIG_PCI_IOV 2278#ifdef CONFIG_PCI_IOV
2272 struct pci_dev *pdev = adapter->pdev; 2279 struct pci_dev *pdev = adapter->pdev;
2280 int old_vfs = igb_find_enabled_vfs(adapter);
2281 int i;
2273 2282
2274 if (adapter->vfs_allocated_count) { 2283 if (old_vfs) {
2275 adapter->vf_data = kcalloc(adapter->vfs_allocated_count, 2284 dev_info(&pdev->dev, "%d pre-allocated VFs found - override "
2276 sizeof(struct vf_data_storage), 2285 "max_vfs setting of %d\n", old_vfs, max_vfs);
2277 GFP_KERNEL); 2286 adapter->vfs_allocated_count = old_vfs;
2278 /* if allocation failed then we do not support SR-IOV */
2279 if (!adapter->vf_data) {
2280 adapter->vfs_allocated_count = 0;
2281 dev_err(&pdev->dev, "Unable to allocate memory for VF "
2282 "Data Storage\n");
2283 }
2284 } 2287 }
2285 2288
2286 if (pci_enable_sriov(pdev, adapter->vfs_allocated_count)) { 2289 if (!adapter->vfs_allocated_count)
2287 kfree(adapter->vf_data); 2290 return;
2288 adapter->vf_data = NULL; 2291
2289#endif /* CONFIG_PCI_IOV */ 2292 adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
2293 sizeof(struct vf_data_storage), GFP_KERNEL);
2294 /* if allocation failed then we do not support SR-IOV */
2295 if (!adapter->vf_data) {
2290 adapter->vfs_allocated_count = 0; 2296 adapter->vfs_allocated_count = 0;
2291#ifdef CONFIG_PCI_IOV 2297 dev_err(&pdev->dev, "Unable to allocate memory for VF "
2292 } else { 2298 "Data Storage\n");
2293 unsigned char mac_addr[ETH_ALEN]; 2299 goto out;
2294 int i;
2295 dev_info(&pdev->dev, "%d vfs allocated\n",
2296 adapter->vfs_allocated_count);
2297 for (i = 0; i < adapter->vfs_allocated_count; i++) {
2298 random_ether_addr(mac_addr);
2299 igb_set_vf_mac(adapter, i, mac_addr);
2300 }
2301 /* DMA Coalescing is not supported in IOV mode. */
2302 if (adapter->flags & IGB_FLAG_DMAC)
2303 adapter->flags &= ~IGB_FLAG_DMAC;
2304 } 2300 }
2301
2302 if (!old_vfs) {
2303 if (pci_enable_sriov(pdev, adapter->vfs_allocated_count))
2304 goto err_out;
2305 }
2306 dev_info(&pdev->dev, "%d VFs allocated\n",
2307 adapter->vfs_allocated_count);
2308 for (i = 0; i < adapter->vfs_allocated_count; i++)
2309 igb_vf_configure(adapter, i);
2310
2311 /* DMA Coalescing is not supported in IOV mode. */
2312 adapter->flags &= ~IGB_FLAG_DMAC;
2313 goto out;
2314err_out:
2315 kfree(adapter->vf_data);
2316 adapter->vf_data = NULL;
2317 adapter->vfs_allocated_count = 0;
2318out:
2319 return;
2305#endif /* CONFIG_PCI_IOV */ 2320#endif /* CONFIG_PCI_IOV */
2306} 2321}
2307 2322
2308
2309/** 2323/**
2310 * igb_init_hw_timer - Initialize hardware timer used with IEEE 1588 timestamp 2324 * igb_init_hw_timer - Initialize hardware timer used with IEEE 1588 timestamp
2311 * @adapter: board private structure to initialize 2325 * @adapter: board private structure to initialize
@@ -4917,6 +4931,109 @@ static int igb_notify_dca(struct notifier_block *nb, unsigned long event,
4917} 4931}
4918#endif /* CONFIG_IGB_DCA */ 4932#endif /* CONFIG_IGB_DCA */
4919 4933
4934#ifdef CONFIG_PCI_IOV
4935static int igb_vf_configure(struct igb_adapter *adapter, int vf)
4936{
4937 unsigned char mac_addr[ETH_ALEN];
4938 struct pci_dev *pdev = adapter->pdev;
4939 struct e1000_hw *hw = &adapter->hw;
4940 struct pci_dev *pvfdev;
4941 unsigned int device_id;
4942 u16 thisvf_devfn;
4943
4944 random_ether_addr(mac_addr);
4945 igb_set_vf_mac(adapter, vf, mac_addr);
4946
4947 switch (adapter->hw.mac.type) {
4948 case e1000_82576:
4949 device_id = IGB_82576_VF_DEV_ID;
4950 /* VF Stride for 82576 is 2 */
4951 thisvf_devfn = (pdev->devfn + 0x80 + (vf << 1)) |
4952 (pdev->devfn & 1);
4953 break;
4954 case e1000_i350:
4955 device_id = IGB_I350_VF_DEV_ID;
4956 /* VF Stride for I350 is 4 */
4957 thisvf_devfn = (pdev->devfn + 0x80 + (vf << 2)) |
4958 (pdev->devfn & 3);
4959 break;
4960 default:
4961 device_id = 0;
4962 thisvf_devfn = 0;
4963 break;
4964 }
4965
4966 pvfdev = pci_get_device(hw->vendor_id, device_id, NULL);
4967 while (pvfdev) {
4968 if (pvfdev->devfn == thisvf_devfn)
4969 break;
4970 pvfdev = pci_get_device(hw->vendor_id,
4971 device_id, pvfdev);
4972 }
4973
4974 if (pvfdev)
4975 adapter->vf_data[vf].vfdev = pvfdev;
4976 else
4977 dev_err(&pdev->dev,
4978 "Couldn't find pci dev ptr for VF %4.4x\n",
4979 thisvf_devfn);
4980 return pvfdev != NULL;
4981}
4982
4983static int igb_find_enabled_vfs(struct igb_adapter *adapter)
4984{
4985 struct e1000_hw *hw = &adapter->hw;
4986 struct pci_dev *pdev = adapter->pdev;
4987 struct pci_dev *pvfdev;
4988 u16 vf_devfn = 0;
4989 u16 vf_stride;
4990 unsigned int device_id;
4991 int vfs_found = 0;
4992
4993 switch (adapter->hw.mac.type) {
4994 case e1000_82576:
4995 device_id = IGB_82576_VF_DEV_ID;
4996 /* VF Stride for 82576 is 2 */
4997 vf_stride = 2;
4998 break;
4999 case e1000_i350:
5000 device_id = IGB_I350_VF_DEV_ID;
5001 /* VF Stride for I350 is 4 */
5002 vf_stride = 4;
5003 break;
5004 default:
5005 device_id = 0;
5006 vf_stride = 0;
5007 break;
5008 }
5009
5010 vf_devfn = pdev->devfn + 0x80;
5011 pvfdev = pci_get_device(hw->vendor_id, device_id, NULL);
5012 while (pvfdev) {
5013 if (pvfdev->devfn == vf_devfn)
5014 vfs_found++;
5015 vf_devfn += vf_stride;
5016 pvfdev = pci_get_device(hw->vendor_id,
5017 device_id, pvfdev);
5018 }
5019
5020 return vfs_found;
5021}
5022
5023static int igb_check_vf_assignment(struct igb_adapter *adapter)
5024{
5025 int i;
5026 for (i = 0; i < adapter->vfs_allocated_count; i++) {
5027 if (adapter->vf_data[i].vfdev) {
5028 if (adapter->vf_data[i].vfdev->dev_flags &
5029 PCI_DEV_FLAGS_ASSIGNED)
5030 return true;
5031 }
5032 }
5033 return false;
5034}
5035
5036#endif
4920static void igb_ping_all_vfs(struct igb_adapter *adapter) 5037static void igb_ping_all_vfs(struct igb_adapter *adapter)
4921{ 5038{
4922 struct e1000_hw *hw = &adapter->hw; 5039 struct e1000_hw *hw = &adapter->hw;