diff options
author | David S. Miller <davem@davemloft.net> | 2013-04-25 08:55:27 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-25 08:55:27 +0400 |
commit | 92dea7c06656f709a3957aacef20574ce3dbe6fc (patch) | |
tree | 2664042bc9f9bdaad0df284ba8dbc354631cef26 | |
parent | d3734b0496f5a310a85bb53310c047b8e42bc440 (diff) | |
parent | 67b1b9033607fa237fb69519ddb4cb4979a651fc (diff) | |
download | linux-92dea7c06656f709a3957aacef20574ce3dbe6fc.tar.xz |
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) dev_spec->eee_disable = false; else dev_spec->eee_disable = true; + /* Allow a single clear of the SW semaphore on I210 and newer */ + if (mac->type >= e1000_i210) + dev_spec->clear_semaphore_once = true; /* physical interface link setup */ mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) @@ -440,8 +443,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) mac->type = e1000_i350; break; case E1000_DEV_ID_I210_COPPER: - case E1000_DEV_ID_I210_COPPER_OEM1: - case E1000_DEV_ID_I210_COPPER_IT: case E1000_DEV_ID_I210_FIBER: case E1000_DEV_ID_I210_SERDES: case E1000_DEV_ID_I210_SGMII: @@ -2049,10 +2050,6 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) hw_dbg("Auto Read Done did not complete\n"); } - /* If EEPROM is not present, run manual init scripts */ - if ((rd32(E1000_EECD) & E1000_EECD_PRES) == 0) - igb_reset_init_script_82575(hw); - /* clear global device reset status bit */ wr32(E1000_STATUS, E1000_STAT_DEV_RST_SET); 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; #define E1000_DEV_ID_I350_SERDES 0x1523 #define E1000_DEV_ID_I350_SGMII 0x1524 #define E1000_DEV_ID_I210_COPPER 0x1533 -#define E1000_DEV_ID_I210_COPPER_OEM1 0x1534 -#define E1000_DEV_ID_I210_COPPER_IT 0x1535 #define E1000_DEV_ID_I210_FIBER 0x1536 #define E1000_DEV_ID_I210_SERDES 0x1537 #define E1000_DEV_ID_I210_SGMII 0x1538 @@ -529,6 +527,7 @@ struct e1000_dev_spec_82575 { bool sgmii_active; bool global_device_reset; bool eee_disable; + bool clear_semaphore_once; }; 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 @@ static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) { u32 swsm; - s32 ret_val = E1000_SUCCESS; s32 timeout = hw->nvm.word_size + 1; s32 i = 0; + /* Get the SW semaphore */ + while (i < timeout) { + swsm = rd32(E1000_SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + udelay(50); + i++; + } + + if (i == timeout) { + /* In rare circumstances, the SW semaphore may already be held + * unintentionally. Clear the semaphore once before giving up. + */ + if (hw->dev_spec._82575.clear_semaphore_once) { + hw->dev_spec._82575.clear_semaphore_once = false; + igb_put_hw_semaphore(hw); + for (i = 0; i < timeout; i++) { + swsm = rd32(E1000_SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + udelay(50); + } + } + + /* If we do not have the semaphore here, we have to give up. */ + if (i == timeout) { + hw_dbg("Driver can't access device - SMBI bit is set.\n"); + return -E1000_ERR_NVM; + } + } + /* Get the FW semaphore. */ for (i = 0; i < timeout; i++) { swsm = rd32(E1000_SWSM); @@ -64,12 +96,10 @@ static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) /* Release semaphores */ igb_put_hw_semaphore(hw); hw_dbg("Driver can't access the NVM\n"); - ret_val = -E1000_ERR_NVM; - goto out; + return -E1000_ERR_NVM; } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -99,23 +129,6 @@ void igb_release_nvm_i210(struct e1000_hw *hw) } /** - * igb_put_hw_semaphore_i210 - Release hardware semaphore - * @hw: pointer to the HW structure - * - * Release hardware semaphore used to access the PHY or NVM - **/ -static void igb_put_hw_semaphore_i210(struct e1000_hw *hw) -{ - u32 swsm; - - swsm = rd32(E1000_SWSM); - - swsm &= ~E1000_SWSM_SWESMBI; - - wr32(E1000_SWSM, swsm); -} - -/** * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore * @hw: pointer to the HW structure * @mask: specifies which semaphore to acquire @@ -138,11 +151,11 @@ s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) } swfw_sync = rd32(E1000_SW_FW_SYNC); - if (!(swfw_sync & fwmask)) + if (!(swfw_sync & (fwmask | swmask))) break; /* Firmware currently using resource (fwmask) */ - igb_put_hw_semaphore_i210(hw); + igb_put_hw_semaphore(hw); mdelay(5); i++; } @@ -156,7 +169,7 @@ s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) swfw_sync |= swmask; wr32(E1000_SW_FW_SYNC, swfw_sync); - igb_put_hw_semaphore_i210(hw); + igb_put_hw_semaphore(hw); out: return ret_val; } @@ -180,7 +193,7 @@ void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) swfw_sync &= ~mask; wr32(E1000_SW_FW_SYNC, swfw_sync); - igb_put_hw_semaphore_i210(hw); + igb_put_hw_semaphore(hw); } /** 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) wr32(E1000_CONNSW, reg); /* Unset sigdetect for SERDES loopback on - * 82580 and i350 devices. + * 82580 and newer devices. */ - switch (hw->mac.type) { - case e1000_82580: - case e1000_i350: + if (hw->mac.type >= e1000_82580) { reg = rd32(E1000_PCS_CFG0); reg |= E1000_PCS_CFG_IGN_SD; wr32(E1000_PCS_CFG0, reg); - break; - default: - break; } /* 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 @@ #include <linux/i2c.h> #include "igb.h" -#define MAJ 4 -#define MIN 1 -#define BUILD 2 +#define MAJ 5 +#define MIN 0 +#define BUILD 3 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ __stringify(BUILD) "-k" char igb_driver_name[] = "igb"; @@ -180,7 +180,6 @@ static void igb_check_vf_rate_limit(struct igb_adapter *); #ifdef CONFIG_PCI_IOV static int igb_vf_configure(struct igb_adapter *adapter, int vf); -static bool igb_vfs_are_assigned(struct igb_adapter *adapter); #endif #ifdef CONFIG_PM @@ -2402,7 +2401,7 @@ static int igb_disable_sriov(struct pci_dev *pdev) /* reclaim resources allocated to VFs */ if (adapter->vf_data) { /* disable iov and allow time for transactions to clear */ - if (igb_vfs_are_assigned(adapter)) { + if (pci_vfs_assigned(pdev)) { dev_warn(&pdev->dev, "Cannot deallocate SR-IOV virtual functions while they are assigned - VFs will not be deallocated\n"); return -EPERM; @@ -3737,6 +3736,10 @@ static void igb_set_rx_mode(struct net_device *netdev) rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_VFE); if (netdev->flags & IFF_PROMISC) { + u32 mrqc = rd32(E1000_MRQC); + /* retain VLAN HW filtering if in VT mode */ + if (mrqc & E1000_MRQC_ENABLE_VMDQ) + rctl |= E1000_RCTL_VFE; rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); vmolr |= (E1000_VMOLR_ROPE | E1000_VMOLR_MPME); } else { @@ -3902,6 +3905,7 @@ static void igb_watchdog_task(struct work_struct *work) struct igb_adapter, watchdog_task); struct e1000_hw *hw = &adapter->hw; + struct e1000_phy_info *phy = &hw->phy; struct net_device *netdev = adapter->netdev; u32 link; int i; @@ -3930,6 +3934,11 @@ static void igb_watchdog_task(struct work_struct *work) (ctrl & E1000_CTRL_RFCE) ? "RX" : (ctrl & E1000_CTRL_TFCE) ? "TX" : "None"); + /* check if SmartSpeed worked */ + igb_check_downshift(hw); + if (phy->speed_downgraded) + netdev_warn(netdev, "Link Speed was downgraded by SmartSpeed\n"); + /* check for thermal sensor event */ if (igb_thermal_sensor_event(hw, E1000_THSTAT_LINK_THROTTLE)) { @@ -5242,39 +5251,6 @@ static int igb_vf_configure(struct igb_adapter *adapter, int vf) return 0; } -static bool igb_vfs_are_assigned(struct igb_adapter *adapter) -{ - struct pci_dev *pdev = adapter->pdev; - struct pci_dev *vfdev; - int dev_id; - - switch (adapter->hw.mac.type) { - case e1000_82576: - dev_id = IGB_82576_VF_DEV_ID; - break; - case e1000_i350: - dev_id = IGB_I350_VF_DEV_ID; - break; - default: - return false; - } - - /* loop through all the VFs to see if we own any that are assigned */ - vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL); - while (vfdev) { - /* if we don't own it we don't care */ - if (vfdev->is_virtfn && vfdev->physfn == pdev) { - /* if it is assigned we cannot release it */ - if (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED) - return true; - } - - vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, vfdev); - } - - return false; -} - #endif static void igb_ping_all_vfs(struct igb_adapter *adapter) { @@ -5548,12 +5524,75 @@ out: return err; } +static int igb_find_vlvf_entry(struct igb_adapter *adapter, int vid) +{ + struct e1000_hw *hw = &adapter->hw; + int i; + u32 reg; + + /* Find the vlan filter for this id */ + for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) { + reg = rd32(E1000_VLVF(i)); + if ((reg & E1000_VLVF_VLANID_ENABLE) && + vid == (reg & E1000_VLVF_VLANID_MASK)) + break; + } + + if (i >= E1000_VLVF_ARRAY_SIZE) + i = -1; + + return i; +} + static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf) { + struct e1000_hw *hw = &adapter->hw; int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT; int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK); + int err = 0; + + /* If in promiscuous mode we need to make sure the PF also has + * the VLAN filter set. + */ + if (add && (adapter->netdev->flags & IFF_PROMISC)) + err = igb_vlvf_set(adapter, vid, add, + adapter->vfs_allocated_count); + if (err) + goto out; - return igb_vlvf_set(adapter, vid, add, vf); + err = igb_vlvf_set(adapter, vid, add, vf); + + if (err) + goto out; + + /* Go through all the checks to see if the VLAN filter should + * be wiped completely. + */ + if (!add && (adapter->netdev->flags & IFF_PROMISC)) { + u32 vlvf, bits; + + int regndx = igb_find_vlvf_entry(adapter, vid); + if (regndx < 0) + goto out; + /* See if any other pools are set for this VLAN filter + * entry other than the PF. + */ + vlvf = bits = rd32(E1000_VLVF(regndx)); + bits &= 1 << (E1000_VLVF_POOLSEL_SHIFT + + adapter->vfs_allocated_count); + /* If the filter was removed then ensure PF pool bit + * is cleared if the PF only added itself to the pool + * because the PF is in promiscuous mode. + */ + if ((vlvf & VLAN_VID_MASK) == vid && + !test_bit(vid, adapter->active_vlans) && + !bits) + igb_vlvf_set(adapter, vid, add, + adapter->vfs_allocated_count); + } + +out: + return err; } 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, /* Determine 1G link capabilities off of SFP+ type */ if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) { *speed = IXGBE_LINK_SPEED_1GB_FULL; @@ -1055,7 +1057,7 @@ mac_reset_top: * LMS state either. */ if ((hw->phy.multispeed_fiber && hw->mng_fw_enabled) || - hw->wol_supported) + hw->wol_enabled) hw->mac.orig_autoc = (hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) | 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, case ixgbe_sfp_type_lr: case ixgbe_sfp_type_srlr_core0: case ixgbe_sfp_type_srlr_core1: + case ixgbe_sfp_type_1g_sx_core0: + case ixgbe_sfp_type_1g_sx_core1: + case ixgbe_sfp_type_1g_lx_core0: + case ixgbe_sfp_type_1g_lx_core1: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; @@ -246,12 +250,6 @@ static int ixgbe_get_settings(struct net_device *netdev, ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; break; - case ixgbe_sfp_type_1g_sx_core0: - case ixgbe_sfp_type_1g_sx_core1: - ecmd->supported |= SUPPORTED_FIBRE; - ecmd->advertising |= ADVERTISED_FIBRE; - ecmd->port = PORT_FIBRE; - break; case ixgbe_sfp_type_unknown: default: 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, */ /* what was last interrupt timeslice? */ timepassed_us = q_vector->itr >> 2; + if (timepassed_us == 0) + return; + bytes_perint = bytes / timepassed_us; /* bytes/usec */ switch (itr_setting) { @@ -7205,6 +7208,7 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, /* only support first port */ if (hw->bus.func != 0) break; + case IXGBE_SUBDEV_ID_82599_SP_560FLR: case IXGBE_SUBDEV_ID_82599_SFP: case IXGBE_SUBDEV_ID_82599_RNDC: case IXGBE_SUBDEV_ID_82599_ECNA_DP: @@ -7213,6 +7217,14 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, break; } break; + case IXGBE_DEV_ID_82599EN_SFP: + /* Only this subdevice supports WOL */ + switch (subdevice_id) { + case IXGBE_SUBDEV_ID_82599EN_SFP_OCP1: + is_wol_supported = 1; + break; + } + break; case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: /* All except this subdevice support WOL */ if (subdevice_id != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) @@ -7529,9 +7541,9 @@ skip_sriov: /* WOL not supported for all devices */ adapter->wol = 0; hw->eeprom.ops.read(hw, 0x2c, &adapter->eeprom_cap); - hw->wol_supported = ixgbe_wol_supported(adapter, pdev->device, + hw->wol_enabled = ixgbe_wol_supported(adapter, pdev->device, pdev->subsystem_device); - if (hw->wol_supported) + if (hw->wol_enabled) adapter->wol = IXGBE_WUFC_MAG; 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) else hw->phy.sfp_type = ixgbe_sfp_type_1g_sx_core1; + } else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_1g_lx_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_1g_lx_core1; } else { hw->phy.sfp_type = ixgbe_sfp_type_unknown; } @@ -1043,6 +1050,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) if (comp_codes_10g == 0 && !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { hw->phy.type = ixgbe_phy_sfp_unsupported; @@ -1058,10 +1067,12 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) hw->mac.ops.get_device_caps(hw, &enforce_sfp); if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) && - !((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) || - (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1) || - (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0) || - (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1))) { + !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { /* Make sure we're a supported PHY type */ if (hw->phy.type == ixgbe_phy_sfp_intel) { status = 0; @@ -1125,10 +1136,12 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, * SR modules */ if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 || + sfp_type == ixgbe_sfp_type_1g_lx_core0 || sfp_type == ixgbe_sfp_type_1g_cu_core0 || sfp_type == ixgbe_sfp_type_1g_sx_core0) sfp_type = ixgbe_sfp_type_srlr_core0; else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 || + sfp_type == ixgbe_sfp_type_1g_lx_core1 || sfp_type == ixgbe_sfp_type_1g_cu_core1 || sfp_type == ixgbe_sfp_type_1g_sx_core1) 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 @@ #define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 #define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72 #define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0 +#define IXGBE_SUBDEV_ID_82599_SP_560FLR 0x211B #define IXGBE_SUBDEV_ID_82599_ECNA_DP 0x0470 #define IXGBE_SUBDEV_ID_82599_LOM_SFP 0x8976 #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 #define IXGBE_DEV_ID_82599_SFP_SF2 0x154D #define IXGBE_DEV_ID_82599EN_SFP 0x1557 +#define IXGBE_SUBDEV_ID_82599EN_SFP_OCP1 0x0001 #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 #define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C @@ -2610,6 +2612,8 @@ enum ixgbe_sfp_type { ixgbe_sfp_type_1g_cu_core1 = 10, ixgbe_sfp_type_1g_sx_core0 = 11, ixgbe_sfp_type_1g_sx_core1 = 12, + ixgbe_sfp_type_1g_lx_core0 = 13, + ixgbe_sfp_type_1g_lx_core1 = 14, ixgbe_sfp_type_not_present = 0xFFFE, ixgbe_sfp_type_unknown = 0xFFFF }; @@ -2999,7 +3003,7 @@ struct ixgbe_hw { bool force_full_reset; bool allow_unsupported_sfp; bool mng_fw_enabled; - bool wol_supported; + bool wol_enabled; }; 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) EXPORT_SYMBOL_GPL(pci_num_vf); /** + * pci_vfs_assigned - returns number of VFs are assigned to a guest + * @dev: the PCI device + * + * Returns number of VFs belonging to this device that are assigned to a guest. + * If device is not a physical function returns -ENODEV. + */ +int pci_vfs_assigned(struct pci_dev *dev) +{ + struct pci_dev *vfdev; + unsigned int vfs_assigned = 0; + unsigned short dev_id; + + /* only search if we are a PF */ + if (!dev->is_physfn) + return 0; + + /* + * determine the device ID for the VFs, the vendor ID will be the + * same as the PF so there is no need to check for that one + */ + pci_read_config_word(dev, dev->sriov->pos + PCI_SRIOV_VF_DID, &dev_id); + + /* loop through all the VFs to see if we own any that are assigned */ + vfdev = pci_get_device(dev->vendor, dev_id, NULL); + while (vfdev) { + /* + * It is considered assigned if it is a virtual function with + * our dev as the physical function and the assigned bit is set + */ + if (vfdev->is_virtfn && (vfdev->physfn == dev) && + (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)) + vfs_assigned++; + + vfdev = pci_get_device(dev->vendor, dev_id, vfdev); + } + + return vfs_assigned; +} +EXPORT_SYMBOL_GPL(pci_vfs_assigned); + +/** * pci_sriov_set_totalvfs -- reduce the TotalVFs available * @dev: the PCI PF device * @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); extern void pci_disable_sriov(struct pci_dev *dev); extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); extern int pci_num_vf(struct pci_dev *dev); +int pci_vfs_assigned(struct pci_dev *dev); extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); extern int pci_sriov_get_totalvfs(struct pci_dev *dev); #else @@ -1662,6 +1663,10 @@ static inline int pci_num_vf(struct pci_dev *dev) { return 0; } +static inline int pci_vfs_assigned(struct pci_dev *dev) +{ + return 0; +} static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) { return 0; |