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>
This commit is contained in:
commit
92dea7c066
12 changed files with 212 additions and 94 deletions
|
@ -389,6 +389,9 @@ static s32 igb_init_mac_params_82575(struct e1000_hw *hw)
|
||||||
dev_spec->eee_disable = false;
|
dev_spec->eee_disable = false;
|
||||||
else
|
else
|
||||||
dev_spec->eee_disable = true;
|
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 */
|
/* physical interface link setup */
|
||||||
mac->ops.setup_physical_interface =
|
mac->ops.setup_physical_interface =
|
||||||
(hw->phy.media_type == e1000_media_type_copper)
|
(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;
|
mac->type = e1000_i350;
|
||||||
break;
|
break;
|
||||||
case E1000_DEV_ID_I210_COPPER:
|
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_FIBER:
|
||||||
case E1000_DEV_ID_I210_SERDES:
|
case E1000_DEV_ID_I210_SERDES:
|
||||||
case E1000_DEV_ID_I210_SGMII:
|
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");
|
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 */
|
/* clear global device reset status bit */
|
||||||
wr32(E1000_STATUS, E1000_STAT_DEV_RST_SET);
|
wr32(E1000_STATUS, E1000_STAT_DEV_RST_SET);
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,6 @@ struct e1000_hw;
|
||||||
#define E1000_DEV_ID_I350_SERDES 0x1523
|
#define E1000_DEV_ID_I350_SERDES 0x1523
|
||||||
#define E1000_DEV_ID_I350_SGMII 0x1524
|
#define E1000_DEV_ID_I350_SGMII 0x1524
|
||||||
#define E1000_DEV_ID_I210_COPPER 0x1533
|
#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_FIBER 0x1536
|
||||||
#define E1000_DEV_ID_I210_SERDES 0x1537
|
#define E1000_DEV_ID_I210_SERDES 0x1537
|
||||||
#define E1000_DEV_ID_I210_SGMII 0x1538
|
#define E1000_DEV_ID_I210_SGMII 0x1538
|
||||||
|
@ -529,6 +527,7 @@ struct e1000_dev_spec_82575 {
|
||||||
bool sgmii_active;
|
bool sgmii_active;
|
||||||
bool global_device_reset;
|
bool global_device_reset;
|
||||||
bool eee_disable;
|
bool eee_disable;
|
||||||
|
bool clear_semaphore_once;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct e1000_hw {
|
struct e1000_hw {
|
||||||
|
|
|
@ -44,10 +44,42 @@
|
||||||
static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
|
static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
|
||||||
{
|
{
|
||||||
u32 swsm;
|
u32 swsm;
|
||||||
s32 ret_val = E1000_SUCCESS;
|
|
||||||
s32 timeout = hw->nvm.word_size + 1;
|
s32 timeout = hw->nvm.word_size + 1;
|
||||||
s32 i = 0;
|
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. */
|
/* Get the FW semaphore. */
|
||||||
for (i = 0; i < timeout; i++) {
|
for (i = 0; i < timeout; i++) {
|
||||||
swsm = rd32(E1000_SWSM);
|
swsm = rd32(E1000_SWSM);
|
||||||
|
@ -64,12 +96,10 @@ static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
|
||||||
/* Release semaphores */
|
/* Release semaphores */
|
||||||
igb_put_hw_semaphore(hw);
|
igb_put_hw_semaphore(hw);
|
||||||
hw_dbg("Driver can't access the NVM\n");
|
hw_dbg("Driver can't access the NVM\n");
|
||||||
ret_val = -E1000_ERR_NVM;
|
return -E1000_ERR_NVM;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
return E1000_SUCCESS;
|
||||||
return ret_val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,23 +128,6 @@ void igb_release_nvm_i210(struct e1000_hw *hw)
|
||||||
igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
|
igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
|
||||||
* @hw: pointer to the HW structure
|
* @hw: pointer to the HW structure
|
||||||
|
@ -138,11 +151,11 @@ s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
swfw_sync = rd32(E1000_SW_FW_SYNC);
|
swfw_sync = rd32(E1000_SW_FW_SYNC);
|
||||||
if (!(swfw_sync & fwmask))
|
if (!(swfw_sync & (fwmask | swmask)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Firmware currently using resource (fwmask) */
|
/* Firmware currently using resource (fwmask) */
|
||||||
igb_put_hw_semaphore_i210(hw);
|
igb_put_hw_semaphore(hw);
|
||||||
mdelay(5);
|
mdelay(5);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +169,7 @@ s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
|
||||||
swfw_sync |= swmask;
|
swfw_sync |= swmask;
|
||||||
wr32(E1000_SW_FW_SYNC, swfw_sync);
|
wr32(E1000_SW_FW_SYNC, swfw_sync);
|
||||||
|
|
||||||
igb_put_hw_semaphore_i210(hw);
|
igb_put_hw_semaphore(hw);
|
||||||
out:
|
out:
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +193,7 @@ void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
|
||||||
swfw_sync &= ~mask;
|
swfw_sync &= ~mask;
|
||||||
wr32(E1000_SW_FW_SYNC, swfw_sync);
|
wr32(E1000_SW_FW_SYNC, swfw_sync);
|
||||||
|
|
||||||
igb_put_hw_semaphore_i210(hw);
|
igb_put_hw_semaphore(hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1678,17 +1678,12 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter)
|
||||||
wr32(E1000_CONNSW, reg);
|
wr32(E1000_CONNSW, reg);
|
||||||
|
|
||||||
/* Unset sigdetect for SERDES loopback on
|
/* Unset sigdetect for SERDES loopback on
|
||||||
* 82580 and i350 devices.
|
* 82580 and newer devices.
|
||||||
*/
|
*/
|
||||||
switch (hw->mac.type) {
|
if (hw->mac.type >= e1000_82580) {
|
||||||
case e1000_82580:
|
|
||||||
case e1000_i350:
|
|
||||||
reg = rd32(E1000_PCS_CFG0);
|
reg = rd32(E1000_PCS_CFG0);
|
||||||
reg |= E1000_PCS_CFG_IGN_SD;
|
reg |= E1000_PCS_CFG_IGN_SD;
|
||||||
wr32(E1000_PCS_CFG0, reg);
|
wr32(E1000_PCS_CFG0, reg);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set PCS register for forced speed */
|
/* Set PCS register for forced speed */
|
||||||
|
|
|
@ -60,9 +60,9 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include "igb.h"
|
#include "igb.h"
|
||||||
|
|
||||||
#define MAJ 4
|
#define MAJ 5
|
||||||
#define MIN 1
|
#define MIN 0
|
||||||
#define BUILD 2
|
#define BUILD 3
|
||||||
#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
|
#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
|
||||||
__stringify(BUILD) "-k"
|
__stringify(BUILD) "-k"
|
||||||
char igb_driver_name[] = "igb";
|
char igb_driver_name[] = "igb";
|
||||||
|
@ -180,7 +180,6 @@ static void igb_check_vf_rate_limit(struct igb_adapter *);
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_IOV
|
#ifdef CONFIG_PCI_IOV
|
||||||
static int igb_vf_configure(struct igb_adapter *adapter, int vf);
|
static int igb_vf_configure(struct igb_adapter *adapter, int vf);
|
||||||
static bool igb_vfs_are_assigned(struct igb_adapter *adapter);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
@ -2402,7 +2401,7 @@ static int igb_disable_sriov(struct pci_dev *pdev)
|
||||||
/* reclaim resources allocated to VFs */
|
/* reclaim resources allocated to VFs */
|
||||||
if (adapter->vf_data) {
|
if (adapter->vf_data) {
|
||||||
/* disable iov and allow time for transactions to clear */
|
/* disable iov and allow time for transactions to clear */
|
||||||
if (igb_vfs_are_assigned(adapter)) {
|
if (pci_vfs_assigned(pdev)) {
|
||||||
dev_warn(&pdev->dev,
|
dev_warn(&pdev->dev,
|
||||||
"Cannot deallocate SR-IOV virtual functions while they are assigned - VFs will not be deallocated\n");
|
"Cannot deallocate SR-IOV virtual functions while they are assigned - VFs will not be deallocated\n");
|
||||||
return -EPERM;
|
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);
|
rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_VFE);
|
||||||
|
|
||||||
if (netdev->flags & IFF_PROMISC) {
|
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);
|
rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
|
||||||
vmolr |= (E1000_VMOLR_ROPE | E1000_VMOLR_MPME);
|
vmolr |= (E1000_VMOLR_ROPE | E1000_VMOLR_MPME);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3902,6 +3905,7 @@ static void igb_watchdog_task(struct work_struct *work)
|
||||||
struct igb_adapter,
|
struct igb_adapter,
|
||||||
watchdog_task);
|
watchdog_task);
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
|
struct e1000_phy_info *phy = &hw->phy;
|
||||||
struct net_device *netdev = adapter->netdev;
|
struct net_device *netdev = adapter->netdev;
|
||||||
u32 link;
|
u32 link;
|
||||||
int i;
|
int i;
|
||||||
|
@ -3930,6 +3934,11 @@ static void igb_watchdog_task(struct work_struct *work)
|
||||||
(ctrl & E1000_CTRL_RFCE) ? "RX" :
|
(ctrl & E1000_CTRL_RFCE) ? "RX" :
|
||||||
(ctrl & E1000_CTRL_TFCE) ? "TX" : "None");
|
(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 */
|
/* check for thermal sensor event */
|
||||||
if (igb_thermal_sensor_event(hw,
|
if (igb_thermal_sensor_event(hw,
|
||||||
E1000_THSTAT_LINK_THROTTLE)) {
|
E1000_THSTAT_LINK_THROTTLE)) {
|
||||||
|
@ -5242,39 +5251,6 @@ static int igb_vf_configure(struct igb_adapter *adapter, int vf)
|
||||||
return 0;
|
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
|
#endif
|
||||||
static void igb_ping_all_vfs(struct igb_adapter *adapter)
|
static void igb_ping_all_vfs(struct igb_adapter *adapter)
|
||||||
{
|
{
|
||||||
|
@ -5548,12 +5524,75 @@ out:
|
||||||
return err;
|
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)
|
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 add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
|
||||||
int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK);
|
int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK);
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
return igb_vlvf_set(adapter, vid, add, vf);
|
/* 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;
|
||||||
|
|
||||||
|
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)
|
static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf)
|
||||||
|
|
|
@ -266,6 +266,8 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
|
||||||
/* Determine 1G link capabilities off of SFP+ type */
|
/* Determine 1G link capabilities off of SFP+ type */
|
||||||
if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
|
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_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_core0 ||
|
||||||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
|
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
|
||||||
*speed = IXGBE_LINK_SPEED_1GB_FULL;
|
*speed = IXGBE_LINK_SPEED_1GB_FULL;
|
||||||
|
@ -1055,7 +1057,7 @@ mac_reset_top:
|
||||||
* LMS state either.
|
* LMS state either.
|
||||||
*/
|
*/
|
||||||
if ((hw->phy.multispeed_fiber && hw->mng_fw_enabled) ||
|
if ((hw->phy.multispeed_fiber && hw->mng_fw_enabled) ||
|
||||||
hw->wol_supported)
|
hw->wol_enabled)
|
||||||
hw->mac.orig_autoc =
|
hw->mac.orig_autoc =
|
||||||
(hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) |
|
(hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) |
|
||||||
curr_lms;
|
curr_lms;
|
||||||
|
|
|
@ -231,6 +231,10 @@ static int ixgbe_get_settings(struct net_device *netdev,
|
||||||
case ixgbe_sfp_type_lr:
|
case ixgbe_sfp_type_lr:
|
||||||
case ixgbe_sfp_type_srlr_core0:
|
case ixgbe_sfp_type_srlr_core0:
|
||||||
case ixgbe_sfp_type_srlr_core1:
|
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->supported |= SUPPORTED_FIBRE;
|
||||||
ecmd->advertising |= ADVERTISED_FIBRE;
|
ecmd->advertising |= ADVERTISED_FIBRE;
|
||||||
ecmd->port = PORT_FIBRE;
|
ecmd->port = PORT_FIBRE;
|
||||||
|
@ -246,12 +250,6 @@ static int ixgbe_get_settings(struct net_device *netdev,
|
||||||
ecmd->advertising |= ADVERTISED_TP;
|
ecmd->advertising |= ADVERTISED_TP;
|
||||||
ecmd->port = PORT_TP;
|
ecmd->port = PORT_TP;
|
||||||
break;
|
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:
|
case ixgbe_sfp_type_unknown:
|
||||||
default:
|
default:
|
||||||
ecmd->supported |= SUPPORTED_FIBRE;
|
ecmd->supported |= SUPPORTED_FIBRE;
|
||||||
|
|
|
@ -2095,6 +2095,9 @@ static void ixgbe_update_itr(struct ixgbe_q_vector *q_vector,
|
||||||
*/
|
*/
|
||||||
/* what was last interrupt timeslice? */
|
/* what was last interrupt timeslice? */
|
||||||
timepassed_us = q_vector->itr >> 2;
|
timepassed_us = q_vector->itr >> 2;
|
||||||
|
if (timepassed_us == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
bytes_perint = bytes / timepassed_us; /* bytes/usec */
|
bytes_perint = bytes / timepassed_us; /* bytes/usec */
|
||||||
|
|
||||||
switch (itr_setting) {
|
switch (itr_setting) {
|
||||||
|
@ -7205,6 +7208,7 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
|
||||||
/* only support first port */
|
/* only support first port */
|
||||||
if (hw->bus.func != 0)
|
if (hw->bus.func != 0)
|
||||||
break;
|
break;
|
||||||
|
case IXGBE_SUBDEV_ID_82599_SP_560FLR:
|
||||||
case IXGBE_SUBDEV_ID_82599_SFP:
|
case IXGBE_SUBDEV_ID_82599_SFP:
|
||||||
case IXGBE_SUBDEV_ID_82599_RNDC:
|
case IXGBE_SUBDEV_ID_82599_RNDC:
|
||||||
case IXGBE_SUBDEV_ID_82599_ECNA_DP:
|
case IXGBE_SUBDEV_ID_82599_ECNA_DP:
|
||||||
|
@ -7213,6 +7217,14 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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:
|
case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
|
||||||
/* All except this subdevice support WOL */
|
/* All except this subdevice support WOL */
|
||||||
if (subdevice_id != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ)
|
if (subdevice_id != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ)
|
||||||
|
@ -7529,9 +7541,9 @@ skip_sriov:
|
||||||
/* WOL not supported for all devices */
|
/* WOL not supported for all devices */
|
||||||
adapter->wol = 0;
|
adapter->wol = 0;
|
||||||
hw->eeprom.ops.read(hw, 0x2c, &adapter->eeprom_cap);
|
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);
|
pdev->subsystem_device);
|
||||||
if (hw->wol_supported)
|
if (hw->wol_enabled)
|
||||||
adapter->wol = IXGBE_WUFC_MAG;
|
adapter->wol = IXGBE_WUFC_MAG;
|
||||||
|
|
||||||
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
|
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
|
||||||
|
|
|
@ -956,6 +956,13 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
|
||||||
else
|
else
|
||||||
hw->phy.sfp_type =
|
hw->phy.sfp_type =
|
||||||
ixgbe_sfp_type_1g_sx_core1;
|
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 {
|
} else {
|
||||||
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
|
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 &&
|
if (comp_codes_10g == 0 &&
|
||||||
!(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
|
!(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_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_core0 ||
|
||||||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
|
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
|
||||||
hw->phy.type = ixgbe_phy_sfp_unsupported;
|
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);
|
hw->mac.ops.get_device_caps(hw, &enforce_sfp);
|
||||||
if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_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_core0 ||
|
||||||
(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1) ||
|
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_lx_core0 ||
|
||||||
(hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1))) {
|
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 */
|
/* Make sure we're a supported PHY type */
|
||||||
if (hw->phy.type == ixgbe_phy_sfp_intel) {
|
if (hw->phy.type == ixgbe_phy_sfp_intel) {
|
||||||
status = 0;
|
status = 0;
|
||||||
|
@ -1125,10 +1136,12 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
|
||||||
* SR modules
|
* SR modules
|
||||||
*/
|
*/
|
||||||
if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 ||
|
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_cu_core0 ||
|
||||||
sfp_type == ixgbe_sfp_type_1g_sx_core0)
|
sfp_type == ixgbe_sfp_type_1g_sx_core0)
|
||||||
sfp_type = ixgbe_sfp_type_srlr_core0;
|
sfp_type = ixgbe_sfp_type_srlr_core0;
|
||||||
else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 ||
|
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_cu_core1 ||
|
||||||
sfp_type == ixgbe_sfp_type_1g_sx_core1)
|
sfp_type == ixgbe_sfp_type_1g_sx_core1)
|
||||||
sfp_type = ixgbe_sfp_type_srlr_core1;
|
sfp_type = ixgbe_sfp_type_srlr_core1;
|
||||||
|
|
|
@ -56,11 +56,13 @@
|
||||||
#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9
|
#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9
|
||||||
#define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72
|
#define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72
|
||||||
#define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0
|
#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_ECNA_DP 0x0470
|
||||||
#define IXGBE_SUBDEV_ID_82599_LOM_SFP 0x8976
|
#define IXGBE_SUBDEV_ID_82599_LOM_SFP 0x8976
|
||||||
#define IXGBE_DEV_ID_82599_SFP_EM 0x1507
|
#define IXGBE_DEV_ID_82599_SFP_EM 0x1507
|
||||||
#define IXGBE_DEV_ID_82599_SFP_SF2 0x154D
|
#define IXGBE_DEV_ID_82599_SFP_SF2 0x154D
|
||||||
#define IXGBE_DEV_ID_82599EN_SFP 0x1557
|
#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_XAUI_LOM 0x10FC
|
||||||
#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
|
#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
|
||||||
#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C
|
#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_cu_core1 = 10,
|
||||||
ixgbe_sfp_type_1g_sx_core0 = 11,
|
ixgbe_sfp_type_1g_sx_core0 = 11,
|
||||||
ixgbe_sfp_type_1g_sx_core1 = 12,
|
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_not_present = 0xFFFE,
|
||||||
ixgbe_sfp_type_unknown = 0xFFFF
|
ixgbe_sfp_type_unknown = 0xFFFF
|
||||||
};
|
};
|
||||||
|
@ -2999,7 +3003,7 @@ struct ixgbe_hw {
|
||||||
bool force_full_reset;
|
bool force_full_reset;
|
||||||
bool allow_unsupported_sfp;
|
bool allow_unsupported_sfp;
|
||||||
bool mng_fw_enabled;
|
bool mng_fw_enabled;
|
||||||
bool wol_supported;
|
bool wol_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ixgbe_info {
|
struct ixgbe_info {
|
||||||
|
|
|
@ -728,6 +728,47 @@ int pci_num_vf(struct pci_dev *dev)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pci_num_vf);
|
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
|
* pci_sriov_set_totalvfs -- reduce the TotalVFs available
|
||||||
* @dev: the PCI PF device
|
* @dev: the PCI PF device
|
||||||
|
|
|
@ -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 void pci_disable_sriov(struct pci_dev *dev);
|
||||||
extern irqreturn_t pci_sriov_migration(struct pci_dev *dev);
|
extern irqreturn_t pci_sriov_migration(struct pci_dev *dev);
|
||||||
extern int pci_num_vf(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_set_totalvfs(struct pci_dev *dev, u16 numvfs);
|
||||||
extern int pci_sriov_get_totalvfs(struct pci_dev *dev);
|
extern int pci_sriov_get_totalvfs(struct pci_dev *dev);
|
||||||
#else
|
#else
|
||||||
|
@ -1662,6 +1663,10 @@ static inline int pci_num_vf(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
return 0;
|
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)
|
static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue