diff options
author | David S. Miller <davem@davemloft.net> | 2013-04-25 00:55:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-25 00:55:27 -0400 |
commit | 92dea7c06656f709a3957aacef20574ce3dbe6fc (patch) | |
tree | 2664042bc9f9bdaad0df284ba8dbc354631cef26 | |
parent | d3734b0496f5a310a85bb53310c047b8e42bc440 (diff) | |
parent | 67b1b9033607fa237fb69519ddb4cb4979a651fc (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next
Jeff Kirsher says:
====================
This series contains updates to ixgbe, igb and pci.
The ixgbe changes contains a fix to a possible divide by zero by bailing
out of the ixgbe_update_itr() function if the last interrupt timeslice is
zero. In addition, support is added for the new OCP x520 adapter as well
as LX support for 82599 devices. Jacob provides a patch to change
variable wol_supported to wol_enabled to better reflect what the code
is actually doing (i.e. checking if WoL is enabled).
Alex adds SRIOV helper function to pci that will determine if a PF
has any VFs that are currently assigned to a guest.
The remaining 8 patches are against igb and contain the following changes:
* implement SERDES loopback configuration for i210 devices by unsetting
sigdetect bit, so as to fix Ethtool loopback test failure
* add support for the SMBI semaphore for I210/I211 devices
* implement the new generic pci_vfs_assigned helper function (Alex's PCI
helper function)
* display warning when link speed is downgraded due to Smartspeed
* ensure that VLAN hardware filtering remains enabled when the device is
in promiscuous mode and VT mode simultaneously
* cleanup dead code in igb
* bump the driver version
v2: updated the PCI patch to add SRIOV helper function to remove extern
from the declaration of pci_vfs_assigned in pci.h and return 0 if
SR-IOV is disabled which is inline with other PCI SR-IOV functions
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_82575.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_hw.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_i210.c | 65 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ethtool.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 117 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 21 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 6 | ||||
-rw-r--r-- | drivers/pci/iov.c | 41 | ||||
-rw-r--r-- | include/linux/pci.h | 5 |
12 files changed, 212 insertions, 94 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index c9bba39d50bd..ff6a17cb1362 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c | |||
@@ -389,6 +389,9 @@ static s32 igb_init_mac_params_82575(struct e1000_hw *hw) | |||
389 | dev_spec->eee_disable = false; | 389 | dev_spec->eee_disable = false; |
390 | else | 390 | else |
391 | dev_spec->eee_disable = true; | 391 | dev_spec->eee_disable = true; |
392 | /* Allow a single clear of the SW semaphore on I210 and newer */ | ||
393 | if (mac->type >= e1000_i210) | ||
394 | dev_spec->clear_semaphore_once = true; | ||
392 | /* physical interface link setup */ | 395 | /* physical interface link setup */ |
393 | mac->ops.setup_physical_interface = | 396 | mac->ops.setup_physical_interface = |
394 | (hw->phy.media_type == e1000_media_type_copper) | 397 | (hw->phy.media_type == e1000_media_type_copper) |
@@ -440,8 +443,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
440 | mac->type = e1000_i350; | 443 | mac->type = e1000_i350; |
441 | break; | 444 | break; |
442 | case E1000_DEV_ID_I210_COPPER: | 445 | case E1000_DEV_ID_I210_COPPER: |
443 | case E1000_DEV_ID_I210_COPPER_OEM1: | ||
444 | case E1000_DEV_ID_I210_COPPER_IT: | ||
445 | case E1000_DEV_ID_I210_FIBER: | 446 | case E1000_DEV_ID_I210_FIBER: |
446 | case E1000_DEV_ID_I210_SERDES: | 447 | case E1000_DEV_ID_I210_SERDES: |
447 | case E1000_DEV_ID_I210_SGMII: | 448 | case E1000_DEV_ID_I210_SGMII: |
@@ -2049,10 +2050,6 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) | |||
2049 | hw_dbg("Auto Read Done did not complete\n"); | 2050 | hw_dbg("Auto Read Done did not complete\n"); |
2050 | } | 2051 | } |
2051 | 2052 | ||
2052 | /* If EEPROM is not present, run manual init scripts */ | ||
2053 | if ((rd32(E1000_EECD) & E1000_EECD_PRES) == 0) | ||
2054 | igb_reset_init_script_82575(hw); | ||
2055 | |||
2056 | /* clear global device reset status bit */ | 2053 | /* clear global device reset status bit */ |
2057 | wr32(E1000_STATUS, E1000_STAT_DEV_RST_SET); | 2054 | wr32(E1000_STATUS, E1000_STAT_DEV_RST_SET); |
2058 | 2055 | ||
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h index 1138ccaf95ff..488abb24a54f 100644 --- a/drivers/net/ethernet/intel/igb/e1000_hw.h +++ b/drivers/net/ethernet/intel/igb/e1000_hw.h | |||
@@ -64,8 +64,6 @@ struct e1000_hw; | |||
64 | #define E1000_DEV_ID_I350_SERDES 0x1523 | 64 | #define E1000_DEV_ID_I350_SERDES 0x1523 |
65 | #define E1000_DEV_ID_I350_SGMII 0x1524 | 65 | #define E1000_DEV_ID_I350_SGMII 0x1524 |
66 | #define E1000_DEV_ID_I210_COPPER 0x1533 | 66 | #define E1000_DEV_ID_I210_COPPER 0x1533 |
67 | #define E1000_DEV_ID_I210_COPPER_OEM1 0x1534 | ||
68 | #define E1000_DEV_ID_I210_COPPER_IT 0x1535 | ||
69 | #define E1000_DEV_ID_I210_FIBER 0x1536 | 67 | #define E1000_DEV_ID_I210_FIBER 0x1536 |
70 | #define E1000_DEV_ID_I210_SERDES 0x1537 | 68 | #define E1000_DEV_ID_I210_SERDES 0x1537 |
71 | #define E1000_DEV_ID_I210_SGMII 0x1538 | 69 | #define E1000_DEV_ID_I210_SGMII 0x1538 |
@@ -529,6 +527,7 @@ struct e1000_dev_spec_82575 { | |||
529 | bool sgmii_active; | 527 | bool sgmii_active; |
530 | bool global_device_reset; | 528 | bool global_device_reset; |
531 | bool eee_disable; | 529 | bool eee_disable; |
530 | bool clear_semaphore_once; | ||
532 | }; | 531 | }; |
533 | 532 | ||
534 | struct e1000_hw { | 533 | struct e1000_hw { |
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c index 9764cd3610e5..ddb3cf51b9b9 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.c +++ b/drivers/net/ethernet/intel/igb/e1000_i210.c | |||
@@ -44,10 +44,42 @@ | |||
44 | static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) | 44 | static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) |
45 | { | 45 | { |
46 | u32 swsm; | 46 | u32 swsm; |
47 | s32 ret_val = E1000_SUCCESS; | ||
48 | s32 timeout = hw->nvm.word_size + 1; | 47 | s32 timeout = hw->nvm.word_size + 1; |
49 | s32 i = 0; | 48 | s32 i = 0; |
50 | 49 | ||
50 | /* Get the SW semaphore */ | ||
51 | while (i < timeout) { | ||
52 | swsm = rd32(E1000_SWSM); | ||
53 | if (!(swsm & E1000_SWSM_SMBI)) | ||
54 | break; | ||
55 | |||
56 | udelay(50); | ||
57 | i++; | ||
58 | } | ||
59 | |||
60 | if (i == timeout) { | ||
61 | /* In rare circumstances, the SW semaphore may already be held | ||
62 | * unintentionally. Clear the semaphore once before giving up. | ||
63 | */ | ||
64 | if (hw->dev_spec._82575.clear_semaphore_once) { | ||
65 | hw->dev_spec._82575.clear_semaphore_once = false; | ||
66 | igb_put_hw_semaphore(hw); | ||
67 | for (i = 0; i < timeout; i++) { | ||
68 | swsm = rd32(E1000_SWSM); | ||
69 | if (!(swsm & E1000_SWSM_SMBI)) | ||
70 | break; | ||
71 | |||
72 | udelay(50); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | /* If we do not have the semaphore here, we have to give up. */ | ||
77 | if (i == timeout) { | ||
78 | hw_dbg("Driver can't access device - SMBI bit is set.\n"); | ||
79 | return -E1000_ERR_NVM; | ||
80 | } | ||
81 | } | ||
82 | |||
51 | /* Get the FW semaphore. */ | 83 | /* Get the FW semaphore. */ |
52 | for (i = 0; i < timeout; i++) { | 84 | for (i = 0; i < timeout; i++) { |
53 | swsm = rd32(E1000_SWSM); | 85 | swsm = rd32(E1000_SWSM); |
@@ -64,12 +96,10 @@ static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) | |||
64 | /* Release semaphores */ | 96 | /* Release semaphores */ |
65 | igb_put_hw_semaphore(hw); | 97 | igb_put_hw_semaphore(hw); |
66 | hw_dbg("Driver can't access the NVM\n"); | 98 | hw_dbg("Driver can't access the NVM\n"); |
67 | ret_val = -E1000_ERR_NVM; | 99 | return -E1000_ERR_NVM; |
68 | goto out; | ||
69 | } | 100 | } |
70 | 101 | ||
71 | out: | 102 | return E1000_SUCCESS; |
72 | return ret_val; | ||
73 | } | 103 | } |
74 | 104 | ||
75 | /** | 105 | /** |
@@ -99,23 +129,6 @@ void igb_release_nvm_i210(struct e1000_hw *hw) | |||
99 | } | 129 | } |
100 | 130 | ||
101 | /** | 131 | /** |
102 | * igb_put_hw_semaphore_i210 - Release hardware semaphore | ||
103 | * @hw: pointer to the HW structure | ||
104 | * | ||
105 | * Release hardware semaphore used to access the PHY or NVM | ||
106 | **/ | ||
107 | static void igb_put_hw_semaphore_i210(struct e1000_hw *hw) | ||
108 | { | ||
109 | u32 swsm; | ||
110 | |||
111 | swsm = rd32(E1000_SWSM); | ||
112 | |||
113 | swsm &= ~E1000_SWSM_SWESMBI; | ||
114 | |||
115 | wr32(E1000_SWSM, swsm); | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore | 132 | * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore |
120 | * @hw: pointer to the HW structure | 133 | * @hw: pointer to the HW structure |
121 | * @mask: specifies which semaphore to acquire | 134 | * @mask: specifies which semaphore to acquire |
@@ -138,11 +151,11 @@ s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) | |||
138 | } | 151 | } |
139 | 152 | ||
140 | swfw_sync = rd32(E1000_SW_FW_SYNC); | 153 | swfw_sync = rd32(E1000_SW_FW_SYNC); |
141 | if (!(swfw_sync & fwmask)) | 154 | if (!(swfw_sync & (fwmask | swmask))) |
142 | break; | 155 | break; |
143 | 156 | ||
144 | /* Firmware currently using resource (fwmask) */ | 157 | /* Firmware currently using resource (fwmask) */ |
145 | igb_put_hw_semaphore_i210(hw); | 158 | igb_put_hw_semaphore(hw); |
146 | mdelay(5); | 159 | mdelay(5); |
147 | i++; | 160 | i++; |
148 | } | 161 | } |
@@ -156,7 +169,7 @@ s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) | |||
156 | swfw_sync |= swmask; | 169 | swfw_sync |= swmask; |
157 | wr32(E1000_SW_FW_SYNC, swfw_sync); | 170 | wr32(E1000_SW_FW_SYNC, swfw_sync); |
158 | 171 | ||
159 | igb_put_hw_semaphore_i210(hw); | 172 | igb_put_hw_semaphore(hw); |
160 | out: | 173 | out: |
161 | return ret_val; | 174 | return ret_val; |
162 | } | 175 | } |
@@ -180,7 +193,7 @@ void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) | |||
180 | swfw_sync &= ~mask; | 193 | swfw_sync &= ~mask; |
181 | wr32(E1000_SW_FW_SYNC, swfw_sync); | 194 | wr32(E1000_SW_FW_SYNC, swfw_sync); |
182 | 195 | ||
183 | igb_put_hw_semaphore_i210(hw); | 196 | igb_put_hw_semaphore(hw); |
184 | } | 197 | } |
185 | 198 | ||
186 | /** | 199 | /** |
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 48b594701efa..7876240fa74e 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c | |||
@@ -1678,17 +1678,12 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter) | |||
1678 | wr32(E1000_CONNSW, reg); | 1678 | wr32(E1000_CONNSW, reg); |
1679 | 1679 | ||
1680 | /* Unset sigdetect for SERDES loopback on | 1680 | /* Unset sigdetect for SERDES loopback on |
1681 | * 82580 and i350 devices. | 1681 | * 82580 and newer devices. |
1682 | */ | 1682 | */ |
1683 | switch (hw->mac.type) { | 1683 | if (hw->mac.type >= e1000_82580) { |
1684 | case e1000_82580: | ||
1685 | case e1000_i350: | ||
1686 | reg = rd32(E1000_PCS_CFG0); | 1684 | reg = rd32(E1000_PCS_CFG0); |
1687 | reg |= E1000_PCS_CFG_IGN_SD; | 1685 | reg |= E1000_PCS_CFG_IGN_SD; |
1688 | wr32(E1000_PCS_CFG0, reg); | 1686 | wr32(E1000_PCS_CFG0, reg); |
1689 | break; | ||
1690 | default: | ||
1691 | break; | ||
1692 | } | 1687 | } |
1693 | 1688 | ||
1694 | /* Set PCS register for forced speed */ | 1689 | /* Set PCS register for forced speed */ |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index dcaa35481dd7..64cbe0dfe043 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -60,9 +60,9 @@ | |||
60 | #include <linux/i2c.h> | 60 | #include <linux/i2c.h> |
61 | #include "igb.h" | 61 | #include "igb.h" |
62 | 62 | ||
63 | #define MAJ 4 | 63 | #define MAJ 5 |
64 | #define MIN 1 | 64 | #define MIN 0 |
65 | #define BUILD 2 | 65 | #define BUILD 3 |
66 | #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ | 66 | #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ |
67 | __stringify(BUILD) "-k" | 67 | __stringify(BUILD) "-k" |
68 | char igb_driver_name[] = "igb"; | 68 | char igb_driver_name[] = "igb"; |
@@ -180,7 +180,6 @@ static void igb_check_vf_rate_limit(struct igb_adapter *); | |||
180 | 180 | ||
181 | #ifdef CONFIG_PCI_IOV | 181 | #ifdef CONFIG_PCI_IOV |
182 | static int igb_vf_configure(struct igb_adapter *adapter, int vf); | 182 | static int igb_vf_configure(struct igb_adapter *adapter, int vf); |
183 | static bool igb_vfs_are_assigned(struct igb_adapter *adapter); | ||
184 | #endif | 183 | #endif |
185 | 184 | ||
186 | #ifdef CONFIG_PM | 185 | #ifdef CONFIG_PM |
@@ -2402,7 +2401,7 @@ static int igb_disable_sriov(struct pci_dev *pdev) | |||
2402 | /* reclaim resources allocated to VFs */ | 2401 | /* reclaim resources allocated to VFs */ |
2403 | if (adapter->vf_data) { | 2402 | if (adapter->vf_data) { |
2404 | /* disable iov and allow time for transactions to clear */ | 2403 | /* disable iov and allow time for transactions to clear */ |
2405 | if (igb_vfs_are_assigned(adapter)) { | 2404 | if (pci_vfs_assigned(pdev)) { |
2406 | dev_warn(&pdev->dev, | 2405 | dev_warn(&pdev->dev, |
2407 | "Cannot deallocate SR-IOV virtual functions while they are assigned - VFs will not be deallocated\n"); | 2406 | "Cannot deallocate SR-IOV virtual functions while they are assigned - VFs will not be deallocated\n"); |
2408 | return -EPERM; | 2407 | return -EPERM; |
@@ -3737,6 +3736,10 @@ static void igb_set_rx_mode(struct net_device *netdev) | |||
3737 | rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_VFE); | 3736 | rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_VFE); |
3738 | 3737 | ||
3739 | if (netdev->flags & IFF_PROMISC) { | 3738 | if (netdev->flags & IFF_PROMISC) { |
3739 | u32 mrqc = rd32(E1000_MRQC); | ||
3740 | /* retain VLAN HW filtering if in VT mode */ | ||
3741 | if (mrqc & E1000_MRQC_ENABLE_VMDQ) | ||
3742 | rctl |= E1000_RCTL_VFE; | ||
3740 | rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); | 3743 | rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); |
3741 | vmolr |= (E1000_VMOLR_ROPE | E1000_VMOLR_MPME); | 3744 | vmolr |= (E1000_VMOLR_ROPE | E1000_VMOLR_MPME); |
3742 | } else { | 3745 | } else { |
@@ -3902,6 +3905,7 @@ static void igb_watchdog_task(struct work_struct *work) | |||
3902 | struct igb_adapter, | 3905 | struct igb_adapter, |
3903 | watchdog_task); | 3906 | watchdog_task); |
3904 | struct e1000_hw *hw = &adapter->hw; | 3907 | struct e1000_hw *hw = &adapter->hw; |
3908 | struct e1000_phy_info *phy = &hw->phy; | ||
3905 | struct net_device *netdev = adapter->netdev; | 3909 | struct net_device *netdev = adapter->netdev; |
3906 | u32 link; | 3910 | u32 link; |
3907 | int i; | 3911 | int i; |
@@ -3930,6 +3934,11 @@ static void igb_watchdog_task(struct work_struct *work) | |||
3930 | (ctrl & E1000_CTRL_RFCE) ? "RX" : | 3934 | (ctrl & E1000_CTRL_RFCE) ? "RX" : |
3931 | (ctrl & E1000_CTRL_TFCE) ? "TX" : "None"); | 3935 | (ctrl & E1000_CTRL_TFCE) ? "TX" : "None"); |
3932 | 3936 | ||
3937 | /* check if SmartSpeed worked */ | ||
3938 | igb_check_downshift(hw); | ||
3939 | if (phy->speed_downgraded) | ||
3940 | netdev_warn(netdev, "Link Speed was downgraded by SmartSpeed\n"); | ||
3941 | |||
3933 | /* check for thermal sensor event */ | 3942 | /* check for thermal sensor event */ |
3934 | if (igb_thermal_sensor_event(hw, | 3943 | if (igb_thermal_sensor_event(hw, |
3935 | E1000_THSTAT_LINK_THROTTLE)) { | 3944 | E1000_THSTAT_LINK_THROTTLE)) { |
@@ -5242,39 +5251,6 @@ static int igb_vf_configure(struct igb_adapter *adapter, int vf) | |||
5242 | return 0; | 5251 | return 0; |
5243 | } | 5252 | } |
5244 | 5253 | ||
5245 | static bool igb_vfs_are_assigned(struct igb_adapter *adapter) | ||
5246 | { | ||
5247 | struct pci_dev *pdev = adapter->pdev; | ||
5248 | struct pci_dev *vfdev; | ||
5249 | int dev_id; | ||
5250 | |||
5251 | switch (adapter->hw.mac.type) { | ||
5252 | case e1000_82576: | ||
5253 | dev_id = IGB_82576_VF_DEV_ID; | ||
5254 | break; | ||
5255 | case e1000_i350: | ||
5256 | dev_id = IGB_I350_VF_DEV_ID; | ||
5257 | break; | ||
5258 | default: | ||
5259 | return false; | ||
5260 | } | ||
5261 | |||
5262 | /* loop through all the VFs to see if we own any that are assigned */ | ||
5263 | vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL); | ||
5264 | while (vfdev) { | ||
5265 | /* if we don't own it we don't care */ | ||
5266 | if (vfdev->is_virtfn && vfdev->physfn == pdev) { | ||
5267 | /* if it is assigned we cannot release it */ | ||
5268 | if (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED) | ||
5269 | return true; | ||
5270 | } | ||
5271 | |||
5272 | vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, vfdev); | ||
5273 | } | ||
5274 | |||
5275 | return false; | ||
5276 | } | ||
5277 | |||
5278 | #endif | 5254 | #endif |
5279 | static void igb_ping_all_vfs(struct igb_adapter *adapter) | 5255 | static void igb_ping_all_vfs(struct igb_adapter *adapter) |
5280 | { | 5256 | { |
@@ -5548,12 +5524,75 @@ out: | |||
5548 | return err; | 5524 | return err; |
5549 | } | 5525 | } |
5550 | 5526 | ||
5527 | static int igb_find_vlvf_entry(struct igb_adapter *adapter, int vid) | ||
5528 | { | ||
5529 | struct e1000_hw *hw = &adapter->hw; | ||
5530 | int i; | ||
5531 | u32 reg; | ||
5532 | |||
5533 | /* Find the vlan filter for this id */ | ||
5534 | for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) { | ||
5535 | reg = rd32(E1000_VLVF(i)); | ||
5536 | if ((reg & E1000_VLVF_VLANID_ENABLE) && | ||
5537 | vid == (reg & E1000_VLVF_VLANID_MASK)) | ||
5538 | break; | ||
5539 | } | ||
5540 | |||
5541 | if (i >= E1000_VLVF_ARRAY_SIZE) | ||
5542 | i = -1; | ||
5543 | |||
5544 | return i; | ||
5545 | } | ||
5546 | |||
5551 | static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf) | 5547 | static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf) |
5552 | { | 5548 | { |
5549 | struct e1000_hw *hw = &adapter->hw; | ||
5553 | int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT; | 5550 | int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT; |
5554 | int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK); | 5551 | int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK); |
5552 | int err = 0; | ||
5553 | |||
5554 | /* If in promiscuous mode we need to make sure the PF also has | ||
5555 | * the VLAN filter set. | ||
5556 | */ | ||
5557 | if (add && (adapter->netdev->flags & IFF_PROMISC)) | ||
5558 | err = igb_vlvf_set(adapter, vid, add, | ||
5559 | adapter->vfs_allocated_count); | ||
5560 | if (err) | ||
5561 | goto out; | ||
5555 | 5562 | ||
5556 | return igb_vlvf_set(adapter, vid, add, vf); | 5563 | err = igb_vlvf_set(adapter, vid, add, vf); |
5564 | |||
5565 | if (err) | ||
5566 | goto out; | ||
5567 | |||
5568 | /* Go through all the checks to see if the VLAN filter should | ||
5569 | * be wiped completely. | ||
5570 | */ | ||
5571 | if (!add && (adapter->netdev->flags & IFF_PROMISC)) { | ||
5572 | u32 vlvf, bits; | ||
5573 | |||
5574 | int regndx = igb_find_vlvf_entry(adapter, vid); | ||
5575 | if (regndx < 0) | ||
5576 | goto out; | ||
5577 | /* See if any other pools are set for this VLAN filter | ||
5578 | * entry other than the PF. | ||
5579 | */ | ||
5580 | vlvf = bits = rd32(E1000_VLVF(regndx)); | ||
5581 | bits &= 1 << (E1000_VLVF_POOLSEL_SHIFT + | ||
5582 | adapter->vfs_allocated_count); | ||
5583 | /* If the filter was removed then ensure PF pool bit | ||
5584 | * is cleared if the PF only added itself to the pool | ||
5585 | * because the PF is in promiscuous mode. | ||
5586 | */ | ||
5587 | if ((vlvf & VLAN_VID_MASK) == vid && | ||
5588 | !test_bit(vid, adapter->active_vlans) && | ||
5589 | !bits) | ||
5590 | igb_vlvf_set(adapter, vid, add, | ||
5591 | adapter->vfs_allocated_count); | ||
5592 | } | ||
5593 | |||
5594 | out: | ||
5595 | return err; | ||
5557 | } | 5596 | } |
5558 | 5597 | ||
5559 | static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf) | 5598 | static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf) |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index 7946da94b228..3f792428ca53 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c | |||
@@ -266,6 +266,8 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, | |||
266 | /* Determine 1G link capabilities off of SFP+ type */ | 266 | /* Determine 1G link capabilities off of SFP+ type */ |
267 | if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || | 267 | if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || |
268 | hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || | 268 | hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || |
269 | hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || | ||
270 | hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || | ||
269 | hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || | 271 | hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || |
270 | hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) { | 272 | hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) { |
271 | *speed = IXGBE_LINK_SPEED_1GB_FULL; | 273 | *speed = IXGBE_LINK_SPEED_1GB_FULL; |
@@ -1055,7 +1057,7 @@ mac_reset_top: | |||
1055 | * LMS state either. | 1057 | * LMS state either. |
1056 | */ | 1058 | */ |
1057 | if ((hw->phy.multispeed_fiber && hw->mng_fw_enabled) || | 1059 | if ((hw->phy.multispeed_fiber && hw->mng_fw_enabled) || |
1058 | hw->wol_supported) | 1060 | hw->wol_enabled) |
1059 | hw->mac.orig_autoc = | 1061 | hw->mac.orig_autoc = |
1060 | (hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) | | 1062 | (hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) | |
1061 | curr_lms; | 1063 | curr_lms; |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index c3f1afd86906..bbe00bcc7582 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | |||
@@ -231,6 +231,10 @@ static int ixgbe_get_settings(struct net_device *netdev, | |||
231 | case ixgbe_sfp_type_lr: | 231 | case ixgbe_sfp_type_lr: |
232 | case ixgbe_sfp_type_srlr_core0: | 232 | case ixgbe_sfp_type_srlr_core0: |
233 | case ixgbe_sfp_type_srlr_core1: | 233 | case ixgbe_sfp_type_srlr_core1: |
234 | case ixgbe_sfp_type_1g_sx_core0: | ||
235 | case ixgbe_sfp_type_1g_sx_core1: | ||
236 | case ixgbe_sfp_type_1g_lx_core0: | ||
237 | case ixgbe_sfp_type_1g_lx_core1: | ||
234 | ecmd->supported |= SUPPORTED_FIBRE; | 238 | ecmd->supported |= SUPPORTED_FIBRE; |
235 | ecmd->advertising |= ADVERTISED_FIBRE; | 239 | ecmd->advertising |= ADVERTISED_FIBRE; |
236 | ecmd->port = PORT_FIBRE; | 240 | ecmd->port = PORT_FIBRE; |
@@ -246,12 +250,6 @@ static int ixgbe_get_settings(struct net_device *netdev, | |||
246 | ecmd->advertising |= ADVERTISED_TP; | 250 | ecmd->advertising |= ADVERTISED_TP; |
247 | ecmd->port = PORT_TP; | 251 | ecmd->port = PORT_TP; |
248 | break; | 252 | break; |
249 | case ixgbe_sfp_type_1g_sx_core0: | ||
250 | case ixgbe_sfp_type_1g_sx_core1: | ||
251 | ecmd->supported |= SUPPORTED_FIBRE; | ||
252 | ecmd->advertising |= ADVERTISED_FIBRE; | ||
253 | ecmd->port = PORT_FIBRE; | ||
254 | break; | ||
255 | case ixgbe_sfp_type_unknown: | 253 | case ixgbe_sfp_type_unknown: |
256 | default: | 254 | default: |
257 | ecmd->supported |= SUPPORTED_FIBRE; | 255 | ecmd->supported |= SUPPORTED_FIBRE; |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 6225f880a3f4..88f67375e85e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -2095,6 +2095,9 @@ static void ixgbe_update_itr(struct ixgbe_q_vector *q_vector, | |||
2095 | */ | 2095 | */ |
2096 | /* what was last interrupt timeslice? */ | 2096 | /* what was last interrupt timeslice? */ |
2097 | timepassed_us = q_vector->itr >> 2; | 2097 | timepassed_us = q_vector->itr >> 2; |
2098 | if (timepassed_us == 0) | ||
2099 | return; | ||
2100 | |||
2098 | bytes_perint = bytes / timepassed_us; /* bytes/usec */ | 2101 | bytes_perint = bytes / timepassed_us; /* bytes/usec */ |
2099 | 2102 | ||
2100 | switch (itr_setting) { | 2103 | switch (itr_setting) { |
@@ -7205,6 +7208,7 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, | |||
7205 | /* only support first port */ | 7208 | /* only support first port */ |
7206 | if (hw->bus.func != 0) | 7209 | if (hw->bus.func != 0) |
7207 | break; | 7210 | break; |
7211 | case IXGBE_SUBDEV_ID_82599_SP_560FLR: | ||
7208 | case IXGBE_SUBDEV_ID_82599_SFP: | 7212 | case IXGBE_SUBDEV_ID_82599_SFP: |
7209 | case IXGBE_SUBDEV_ID_82599_RNDC: | 7213 | case IXGBE_SUBDEV_ID_82599_RNDC: |
7210 | case IXGBE_SUBDEV_ID_82599_ECNA_DP: | 7214 | case IXGBE_SUBDEV_ID_82599_ECNA_DP: |
@@ -7213,6 +7217,14 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, | |||
7213 | break; | 7217 | break; |
7214 | } | 7218 | } |
7215 | break; | 7219 | break; |
7220 | case IXGBE_DEV_ID_82599EN_SFP: | ||
7221 | /* Only this subdevice supports WOL */ | ||
7222 | switch (subdevice_id) { | ||
7223 | case IXGBE_SUBDEV_ID_82599EN_SFP_OCP1: | ||
7224 | is_wol_supported = 1; | ||
7225 | break; | ||
7226 | } | ||
7227 | break; | ||
7216 | case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: | 7228 | case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: |
7217 | /* All except this subdevice support WOL */ | 7229 | /* All except this subdevice support WOL */ |
7218 | if (subdevice_id != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) | 7230 | if (subdevice_id != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) |
@@ -7529,9 +7541,9 @@ skip_sriov: | |||
7529 | /* WOL not supported for all devices */ | 7541 | /* WOL not supported for all devices */ |
7530 | adapter->wol = 0; | 7542 | adapter->wol = 0; |
7531 | hw->eeprom.ops.read(hw, 0x2c, &adapter->eeprom_cap); | 7543 | hw->eeprom.ops.read(hw, 0x2c, &adapter->eeprom_cap); |
7532 | hw->wol_supported = ixgbe_wol_supported(adapter, pdev->device, | 7544 | hw->wol_enabled = ixgbe_wol_supported(adapter, pdev->device, |
7533 | pdev->subsystem_device); | 7545 | pdev->subsystem_device); |
7534 | if (hw->wol_supported) | 7546 | if (hw->wol_enabled) |
7535 | adapter->wol = IXGBE_WUFC_MAG; | 7547 | adapter->wol = IXGBE_WUFC_MAG; |
7536 | 7548 | ||
7537 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | 7549 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c index 060d2ad2ac96..e5691ccbce9d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | |||
@@ -956,6 +956,13 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) | |||
956 | else | 956 | else |
957 | hw->phy.sfp_type = | 957 | hw->phy.sfp_type = |
958 | ixgbe_sfp_type_1g_sx_core1; | 958 | ixgbe_sfp_type_1g_sx_core1; |
959 | } else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) { | ||
960 | if (hw->bus.lan_id == 0) | ||
961 | hw->phy.sfp_type = | ||
962 | ixgbe_sfp_type_1g_lx_core0; | ||
963 | else | ||
964 | hw->phy.sfp_type = | ||
965 | ixgbe_sfp_type_1g_lx_core1; | ||
959 | } else { | 966 | } else { |
960 | hw->phy.sfp_type = ixgbe_sfp_type_unknown; | 967 | hw->phy.sfp_type = ixgbe_sfp_type_unknown; |
961 | } | 968 | } |
@@ -1043,6 +1050,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) | |||
1043 | if (comp_codes_10g == 0 && | 1050 | if (comp_codes_10g == 0 && |
1044 | !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || | 1051 | !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || |
1045 | hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || | 1052 | hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || |
1053 | hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || | ||
1054 | hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || | ||
1046 | hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || | 1055 | hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || |
1047 | hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { | 1056 | hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { |
1048 | hw->phy.type = ixgbe_phy_sfp_unsupported; | 1057 | hw->phy.type = ixgbe_phy_sfp_unsupported; |
@@ -1058,10 +1067,12 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) | |||
1058 | 1067 | ||
1059 | hw->mac.ops.get_device_caps(hw, &enforce_sfp); | 1068 | hw->mac.ops.get_device_caps(hw, &enforce_sfp); |
1060 | if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) && | 1069 | if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) && |
1061 | !((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) || | 1070 | !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || |
1062 | (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1) || | 1071 | hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || |
1063 | (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0) || | 1072 | hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || |
1064 | (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1))) { | 1073 | hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || |
1074 | hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || | ||
1075 | hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { | ||
1065 | /* Make sure we're a supported PHY type */ | 1076 | /* Make sure we're a supported PHY type */ |
1066 | if (hw->phy.type == ixgbe_phy_sfp_intel) { | 1077 | if (hw->phy.type == ixgbe_phy_sfp_intel) { |
1067 | status = 0; | 1078 | status = 0; |
@@ -1125,10 +1136,12 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, | |||
1125 | * SR modules | 1136 | * SR modules |
1126 | */ | 1137 | */ |
1127 | if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 || | 1138 | if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 || |
1139 | sfp_type == ixgbe_sfp_type_1g_lx_core0 || | ||
1128 | sfp_type == ixgbe_sfp_type_1g_cu_core0 || | 1140 | sfp_type == ixgbe_sfp_type_1g_cu_core0 || |
1129 | sfp_type == ixgbe_sfp_type_1g_sx_core0) | 1141 | sfp_type == ixgbe_sfp_type_1g_sx_core0) |
1130 | sfp_type = ixgbe_sfp_type_srlr_core0; | 1142 | sfp_type = ixgbe_sfp_type_srlr_core0; |
1131 | else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 || | 1143 | else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 || |
1144 | sfp_type == ixgbe_sfp_type_1g_lx_core1 || | ||
1132 | sfp_type == ixgbe_sfp_type_1g_cu_core1 || | 1145 | sfp_type == ixgbe_sfp_type_1g_cu_core1 || |
1133 | sfp_type == ixgbe_sfp_type_1g_sx_core1) | 1146 | sfp_type == ixgbe_sfp_type_1g_sx_core1) |
1134 | sfp_type = ixgbe_sfp_type_srlr_core1; | 1147 | sfp_type = ixgbe_sfp_type_srlr_core1; |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 402f1a2ada3e..6d7066531139 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | |||
@@ -56,11 +56,13 @@ | |||
56 | #define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 | 56 | #define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 |
57 | #define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72 | 57 | #define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72 |
58 | #define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0 | 58 | #define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0 |
59 | #define IXGBE_SUBDEV_ID_82599_SP_560FLR 0x211B | ||
59 | #define IXGBE_SUBDEV_ID_82599_ECNA_DP 0x0470 | 60 | #define IXGBE_SUBDEV_ID_82599_ECNA_DP 0x0470 |
60 | #define IXGBE_SUBDEV_ID_82599_LOM_SFP 0x8976 | 61 | #define IXGBE_SUBDEV_ID_82599_LOM_SFP 0x8976 |
61 | #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 | 62 | #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 |
62 | #define IXGBE_DEV_ID_82599_SFP_SF2 0x154D | 63 | #define IXGBE_DEV_ID_82599_SFP_SF2 0x154D |
63 | #define IXGBE_DEV_ID_82599EN_SFP 0x1557 | 64 | #define IXGBE_DEV_ID_82599EN_SFP 0x1557 |
65 | #define IXGBE_SUBDEV_ID_82599EN_SFP_OCP1 0x0001 | ||
64 | #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC | 66 | #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC |
65 | #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 | 67 | #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 |
66 | #define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C | 68 | #define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C |
@@ -2610,6 +2612,8 @@ enum ixgbe_sfp_type { | |||
2610 | ixgbe_sfp_type_1g_cu_core1 = 10, | 2612 | ixgbe_sfp_type_1g_cu_core1 = 10, |
2611 | ixgbe_sfp_type_1g_sx_core0 = 11, | 2613 | ixgbe_sfp_type_1g_sx_core0 = 11, |
2612 | ixgbe_sfp_type_1g_sx_core1 = 12, | 2614 | ixgbe_sfp_type_1g_sx_core1 = 12, |
2615 | ixgbe_sfp_type_1g_lx_core0 = 13, | ||
2616 | ixgbe_sfp_type_1g_lx_core1 = 14, | ||
2613 | ixgbe_sfp_type_not_present = 0xFFFE, | 2617 | ixgbe_sfp_type_not_present = 0xFFFE, |
2614 | ixgbe_sfp_type_unknown = 0xFFFF | 2618 | ixgbe_sfp_type_unknown = 0xFFFF |
2615 | }; | 2619 | }; |
@@ -2999,7 +3003,7 @@ struct ixgbe_hw { | |||
2999 | bool force_full_reset; | 3003 | bool force_full_reset; |
3000 | bool allow_unsupported_sfp; | 3004 | bool allow_unsupported_sfp; |
3001 | bool mng_fw_enabled; | 3005 | bool mng_fw_enabled; |
3002 | bool wol_supported; | 3006 | bool wol_enabled; |
3003 | }; | 3007 | }; |
3004 | 3008 | ||
3005 | struct ixgbe_info { | 3009 | struct ixgbe_info { |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index ee599f274f05..c93071d428f5 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -729,6 +729,47 @@ int pci_num_vf(struct pci_dev *dev) | |||
729 | EXPORT_SYMBOL_GPL(pci_num_vf); | 729 | EXPORT_SYMBOL_GPL(pci_num_vf); |
730 | 730 | ||
731 | /** | 731 | /** |
732 | * pci_vfs_assigned - returns number of VFs are assigned to a guest | ||
733 | * @dev: the PCI device | ||
734 | * | ||
735 | * Returns number of VFs belonging to this device that are assigned to a guest. | ||
736 | * If device is not a physical function returns -ENODEV. | ||
737 | */ | ||
738 | int pci_vfs_assigned(struct pci_dev *dev) | ||
739 | { | ||
740 | struct pci_dev *vfdev; | ||
741 | unsigned int vfs_assigned = 0; | ||
742 | unsigned short dev_id; | ||
743 | |||
744 | /* only search if we are a PF */ | ||
745 | if (!dev->is_physfn) | ||
746 | return 0; | ||
747 | |||
748 | /* | ||
749 | * determine the device ID for the VFs, the vendor ID will be the | ||
750 | * same as the PF so there is no need to check for that one | ||
751 | */ | ||
752 | pci_read_config_word(dev, dev->sriov->pos + PCI_SRIOV_VF_DID, &dev_id); | ||
753 | |||
754 | /* loop through all the VFs to see if we own any that are assigned */ | ||
755 | vfdev = pci_get_device(dev->vendor, dev_id, NULL); | ||
756 | while (vfdev) { | ||
757 | /* | ||
758 | * It is considered assigned if it is a virtual function with | ||
759 | * our dev as the physical function and the assigned bit is set | ||
760 | */ | ||
761 | if (vfdev->is_virtfn && (vfdev->physfn == dev) && | ||
762 | (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)) | ||
763 | vfs_assigned++; | ||
764 | |||
765 | vfdev = pci_get_device(dev->vendor, dev_id, vfdev); | ||
766 | } | ||
767 | |||
768 | return vfs_assigned; | ||
769 | } | ||
770 | EXPORT_SYMBOL_GPL(pci_vfs_assigned); | ||
771 | |||
772 | /** | ||
732 | * pci_sriov_set_totalvfs -- reduce the TotalVFs available | 773 | * pci_sriov_set_totalvfs -- reduce the TotalVFs available |
733 | * @dev: the PCI PF device | 774 | * @dev: the PCI PF device |
734 | * @numvfs: number that should be used for TotalVFs supported | 775 | * @numvfs: number that should be used for TotalVFs supported |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 710067f3618c..43e45ac36458 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1644,6 +1644,7 @@ extern int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); | |||
1644 | extern void pci_disable_sriov(struct pci_dev *dev); | 1644 | extern void pci_disable_sriov(struct pci_dev *dev); |
1645 | extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); | 1645 | extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); |
1646 | extern int pci_num_vf(struct pci_dev *dev); | 1646 | extern int pci_num_vf(struct pci_dev *dev); |
1647 | int pci_vfs_assigned(struct pci_dev *dev); | ||
1647 | extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); | 1648 | extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); |
1648 | extern int pci_sriov_get_totalvfs(struct pci_dev *dev); | 1649 | extern int pci_sriov_get_totalvfs(struct pci_dev *dev); |
1649 | #else | 1650 | #else |
@@ -1662,6 +1663,10 @@ static inline int pci_num_vf(struct pci_dev *dev) | |||
1662 | { | 1663 | { |
1663 | return 0; | 1664 | return 0; |
1664 | } | 1665 | } |
1666 | static inline int pci_vfs_assigned(struct pci_dev *dev) | ||
1667 | { | ||
1668 | return 0; | ||
1669 | } | ||
1665 | static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) | 1670 | static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) |
1666 | { | 1671 | { |
1667 | return 0; | 1672 | return 0; |