Commit b163b42f authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

====================
This series contains updates to igb only.

Todd provides a fix for igb to not look for a PBA in the iNVM on
devices that are flashless.

Akeem provides igb patches to add a new PHY id for i354, as well as
a couple of patches to implement the new PHY id.  He also provides
several patches to correctly report the appropriate media type as
well as correctly report advertised/supported link for i354 devices.
Lastly Akeem implements a 1 second delay mechanism for i210 devices
to avoid erroneous link issue with the link partner.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 48f8e0af 66f40b8a
...@@ -176,7 +176,7 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw) ...@@ -176,7 +176,7 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)
/* Verify phy id and set remaining function pointers */ /* Verify phy id and set remaining function pointers */
switch (phy->id) { switch (phy->id) {
case M88E1545_E_PHY_ID: case M88E1543_E_PHY_ID:
case I347AT4_E_PHY_ID: case I347AT4_E_PHY_ID:
case M88E1112_E_PHY_ID: case M88E1112_E_PHY_ID:
case M88E1111_I_PHY_ID: case M88E1111_I_PHY_ID:
...@@ -1140,6 +1140,31 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw) ...@@ -1140,6 +1140,31 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
/**
* igb_get_link_up_info_82575 - Get link speed/duplex info
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
*
* This is a wrapper function, if using the serial gigabit media independent
* interface, use PCS to retrieve the link speed and duplex information.
* Otherwise, use the generic function to get the link speed and duplex info.
**/
static s32 igb_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
u16 *duplex)
{
s32 ret_val;
if (hw->phy.media_type != e1000_media_type_copper)
ret_val = igb_get_pcs_speed_and_duplex_82575(hw, speed,
duplex);
else
ret_val = igb_get_speed_and_duplex_copper(hw, speed,
duplex);
return ret_val;
}
/** /**
* igb_check_for_link_82575 - Check for link * igb_check_for_link_82575 - Check for link
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
...@@ -1217,7 +1242,7 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed, ...@@ -1217,7 +1242,7 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
u16 *duplex) u16 *duplex)
{ {
struct e1000_mac_info *mac = &hw->mac; struct e1000_mac_info *mac = &hw->mac;
u32 pcs; u32 pcs, status;
/* Set up defaults for the return values of this function */ /* Set up defaults for the return values of this function */
mac->serdes_has_link = false; mac->serdes_has_link = false;
...@@ -1238,20 +1263,31 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed, ...@@ -1238,20 +1263,31 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
mac->serdes_has_link = true; mac->serdes_has_link = true;
/* Detect and store PCS speed */ /* Detect and store PCS speed */
if (pcs & E1000_PCS_LSTS_SPEED_1000) { if (pcs & E1000_PCS_LSTS_SPEED_1000)
*speed = SPEED_1000; *speed = SPEED_1000;
} else if (pcs & E1000_PCS_LSTS_SPEED_100) { else if (pcs & E1000_PCS_LSTS_SPEED_100)
*speed = SPEED_100; *speed = SPEED_100;
} else { else
*speed = SPEED_10; *speed = SPEED_10;
}
/* Detect and store PCS duplex */ /* Detect and store PCS duplex */
if (pcs & E1000_PCS_LSTS_DUPLEX_FULL) { if (pcs & E1000_PCS_LSTS_DUPLEX_FULL)
*duplex = FULL_DUPLEX; *duplex = FULL_DUPLEX;
} else { else
*duplex = HALF_DUPLEX; *duplex = HALF_DUPLEX;
/* Check if it is an I354 2.5Gb backplane connection. */
if (mac->type == e1000_i354) {
status = rd32(E1000_STATUS);
if ((status & E1000_STATUS_2P5_SKU) &&
!(status & E1000_STATUS_2P5_SKU_OVER)) {
*speed = SPEED_2500;
*duplex = FULL_DUPLEX;
hw_dbg("2500 Mbs, ");
hw_dbg("Full Duplex\n");
}
} }
} }
return 0; return 0;
...@@ -1421,11 +1457,18 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) ...@@ -1421,11 +1457,18 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
wr32(E1000_CTRL, ctrl); wr32(E1000_CTRL, ctrl);
/* Clear Go Link Disconnect bit */ /* Clear Go Link Disconnect bit on supported devices */
if (hw->mac.type >= e1000_82580) { switch (hw->mac.type) {
case e1000_82580:
case e1000_i350:
case e1000_i210:
case e1000_i211:
phpm_reg = rd32(E1000_82580_PHY_POWER_MGMT); phpm_reg = rd32(E1000_82580_PHY_POWER_MGMT);
phpm_reg &= ~E1000_82580_PM_GO_LINKD; phpm_reg &= ~E1000_82580_PM_GO_LINKD;
wr32(E1000_82580_PHY_POWER_MGMT, phpm_reg); wr32(E1000_82580_PHY_POWER_MGMT, phpm_reg);
break;
default:
break;
} }
ret_val = igb_setup_serdes_link_82575(hw); ret_val = igb_setup_serdes_link_82575(hw);
...@@ -1448,7 +1491,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) ...@@ -1448,7 +1491,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
switch (hw->phy.id) { switch (hw->phy.id) {
case I347AT4_E_PHY_ID: case I347AT4_E_PHY_ID:
case M88E1112_E_PHY_ID: case M88E1112_E_PHY_ID:
case M88E1545_E_PHY_ID: case M88E1543_E_PHY_ID:
case I210_I_PHY_ID: case I210_I_PHY_ID:
ret_val = igb_copper_link_setup_m88_gen2(hw); ret_val = igb_copper_link_setup_m88_gen2(hw);
break; break;
...@@ -2477,28 +2520,28 @@ s32 igb_set_eee_i354(struct e1000_hw *hw) ...@@ -2477,28 +2520,28 @@ s32 igb_set_eee_i354(struct e1000_hw *hw)
u16 phy_data; u16 phy_data;
if ((hw->phy.media_type != e1000_media_type_copper) || if ((hw->phy.media_type != e1000_media_type_copper) ||
(phy->id != M88E1545_E_PHY_ID)) (phy->id != M88E1543_E_PHY_ID))
goto out; goto out;
if (!hw->dev_spec._82575.eee_disable) { if (!hw->dev_spec._82575.eee_disable) {
/* Switch to PHY page 18. */ /* Switch to PHY page 18. */
ret_val = phy->ops.write_reg(hw, E1000_M88E1545_PAGE_ADDR, 18); ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 18);
if (ret_val) if (ret_val)
goto out; goto out;
ret_val = phy->ops.read_reg(hw, E1000_M88E1545_EEE_CTRL_1, ret_val = phy->ops.read_reg(hw, E1000_M88E1543_EEE_CTRL_1,
&phy_data); &phy_data);
if (ret_val) if (ret_val)
goto out; goto out;
phy_data |= E1000_M88E1545_EEE_CTRL_1_MS; phy_data |= E1000_M88E1543_EEE_CTRL_1_MS;
ret_val = phy->ops.write_reg(hw, E1000_M88E1545_EEE_CTRL_1, ret_val = phy->ops.write_reg(hw, E1000_M88E1543_EEE_CTRL_1,
phy_data); phy_data);
if (ret_val) if (ret_val)
goto out; goto out;
/* Return the PHY to page 0. */ /* Return the PHY to page 0. */
ret_val = phy->ops.write_reg(hw, E1000_M88E1545_PAGE_ADDR, 0); ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
if (ret_val) if (ret_val)
goto out; goto out;
...@@ -2549,7 +2592,7 @@ s32 igb_get_eee_status_i354(struct e1000_hw *hw, bool *status) ...@@ -2549,7 +2592,7 @@ s32 igb_get_eee_status_i354(struct e1000_hw *hw, bool *status)
/* Check if EEE is supported on this device. */ /* Check if EEE is supported on this device. */
if ((hw->phy.media_type != e1000_media_type_copper) || if ((hw->phy.media_type != e1000_media_type_copper) ||
(phy->id != M88E1545_E_PHY_ID)) (phy->id != M88E1543_E_PHY_ID))
goto out; goto out;
ret_val = igb_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354, ret_val = igb_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354,
...@@ -2705,7 +2748,7 @@ static struct e1000_mac_operations e1000_mac_ops_82575 = { ...@@ -2705,7 +2748,7 @@ static struct e1000_mac_operations e1000_mac_ops_82575 = {
.check_for_link = igb_check_for_link_82575, .check_for_link = igb_check_for_link_82575,
.rar_set = igb_rar_set, .rar_set = igb_rar_set,
.read_mac_addr = igb_read_mac_addr_82575, .read_mac_addr = igb_read_mac_addr_82575,
.get_speed_and_duplex = igb_get_speed_and_duplex_copper, .get_speed_and_duplex = igb_get_link_up_info_82575,
#ifdef CONFIG_IGB_HWMON #ifdef CONFIG_IGB_HWMON
.get_thermal_sensor_data = igb_get_thermal_sensor_data_generic, .get_thermal_sensor_data = igb_get_thermal_sensor_data_generic,
.init_thermal_sensor_thresh = igb_init_thermal_sensor_thresh_generic, .init_thermal_sensor_thresh = igb_init_thermal_sensor_thresh_generic,
......
...@@ -787,7 +787,7 @@ ...@@ -787,7 +787,7 @@
#define I350_I_PHY_ID 0x015403B0 #define I350_I_PHY_ID 0x015403B0
#define M88_VENDOR 0x0141 #define M88_VENDOR 0x0141
#define I210_I_PHY_ID 0x01410C00 #define I210_I_PHY_ID 0x01410C00
#define M88E1545_E_PHY_ID 0x01410EA0 #define M88E1543_E_PHY_ID 0x01410EA0
/* M88E1000 Specific Registers */ /* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
...@@ -909,9 +909,9 @@ ...@@ -909,9 +909,9 @@
#define E1000_EEE_LP_ADV_DEV_I210 7 /* EEE LP Adv Device */ #define E1000_EEE_LP_ADV_DEV_I210 7 /* EEE LP Adv Device */
#define E1000_EEE_LP_ADV_ADDR_I210 61 /* EEE LP Adv Register */ #define E1000_EEE_LP_ADV_ADDR_I210 61 /* EEE LP Adv Register */
#define E1000_MMDAC_FUNC_DATA 0x4000 /* Data, no post increment */ #define E1000_MMDAC_FUNC_DATA 0x4000 /* Data, no post increment */
#define E1000_M88E1545_PAGE_ADDR 0x16 /* Page Offset Register */ #define E1000_M88E1543_PAGE_ADDR 0x16 /* Page Offset Register */
#define E1000_M88E1545_EEE_CTRL_1 0x0 #define E1000_M88E1543_EEE_CTRL_1 0x0
#define E1000_M88E1545_EEE_CTRL_1_MS 0x0001 /* EEE Master/Slave */ #define E1000_M88E1543_EEE_CTRL_1_MS 0x0001 /* EEE Master/Slave */
#define E1000_EEE_ADV_DEV_I354 7 #define E1000_EEE_ADV_DEV_I354 7
#define E1000_EEE_ADV_ADDR_I354 60 #define E1000_EEE_ADV_ADDR_I354 60
#define E1000_EEE_ADV_100_SUPPORTED (1 << 1) /* 100BaseTx EEE Supported */ #define E1000_EEE_ADV_100_SUPPORTED (1 << 1) /* 100BaseTx EEE Supported */
......
...@@ -1171,17 +1171,6 @@ s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, ...@@ -1171,17 +1171,6 @@ s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
hw_dbg("Half Duplex\n"); hw_dbg("Half Duplex\n");
} }
/* Check if it is an I354 2.5Gb backplane connection. */
if (hw->mac.type == e1000_i354) {
if ((status & E1000_STATUS_2P5_SKU) &&
!(status & E1000_STATUS_2P5_SKU_OVER)) {
*speed = SPEED_2500;
*duplex = FULL_DUPLEX;
hw_dbg("2500 Mbs, ");
hw_dbg("Full Duplex\n");
}
}
return 0; return 0;
} }
......
...@@ -731,15 +731,13 @@ s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw) ...@@ -731,15 +731,13 @@ s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)
s32 ret_val; s32 ret_val;
u16 phy_data; u16 phy_data;
if (phy->reset_disable) { if (phy->reset_disable)
ret_val = 0; return 0;
goto out;
}
/* Enable CRS on Tx. This must be set for half-duplex operation. */ /* Enable CRS on Tx. This must be set for half-duplex operation. */
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val) if (ret_val)
goto out; return ret_val;
/* Options: /* Options:
* MDI/MDI-X = 0 (default) * MDI/MDI-X = 0 (default)
...@@ -780,23 +778,36 @@ s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw) ...@@ -780,23 +778,36 @@ s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)
phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
/* Enable downshift and setting it to X6 */ /* Enable downshift and setting it to X6 */
if (phy->id == M88E1543_E_PHY_ID) {
phy_data &= ~I347AT4_PSCR_DOWNSHIFT_ENABLE;
ret_val =
phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val)
return ret_val;
ret_val = igb_phy_sw_reset(hw);
if (ret_val) {
hw_dbg("Error committing the PHY changes\n");
return ret_val;
}
}
phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK; phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK;
phy_data |= I347AT4_PSCR_DOWNSHIFT_6X; phy_data |= I347AT4_PSCR_DOWNSHIFT_6X;
phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE; phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE;
ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val) if (ret_val)
goto out; return ret_val;
/* Commit the changes. */ /* Commit the changes. */
ret_val = igb_phy_sw_reset(hw); ret_val = igb_phy_sw_reset(hw);
if (ret_val) { if (ret_val) {
hw_dbg("Error committing the PHY changes\n"); hw_dbg("Error committing the PHY changes\n");
goto out; return ret_val;
} }
out: return 0;
return ret_val;
} }
/** /**
...@@ -1806,7 +1817,7 @@ s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw) ...@@ -1806,7 +1817,7 @@ s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw)
phy->max_cable_length = phy_data / (is_cm ? 100 : 1); phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
phy->cable_length = phy_data / (is_cm ? 100 : 1); phy->cable_length = phy_data / (is_cm ? 100 : 1);
break; break;
case M88E1545_E_PHY_ID: case M88E1543_E_PHY_ID:
case I347AT4_E_PHY_ID: case I347AT4_E_PHY_ID:
/* Remember the original page select and set it to 7 */ /* Remember the original page select and set it to 7 */
ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
......
...@@ -448,6 +448,8 @@ struct igb_adapter { ...@@ -448,6 +448,8 @@ struct igb_adapter {
struct i2c_client *i2c_client; struct i2c_client *i2c_client;
u32 rss_indir_tbl_init; u32 rss_indir_tbl_init;
u8 rss_indir_tbl[IGB_RETA_SIZE]; u8 rss_indir_tbl[IGB_RETA_SIZE];
unsigned long link_check_timeout;
}; };
#define IGB_FLAG_HAS_MSI (1 << 0) #define IGB_FLAG_HAS_MSI (1 << 0)
...@@ -459,6 +461,7 @@ struct igb_adapter { ...@@ -459,6 +461,7 @@ struct igb_adapter {
#define IGB_FLAG_RSS_FIELD_IPV4_UDP (1 << 6) #define IGB_FLAG_RSS_FIELD_IPV4_UDP (1 << 6)
#define IGB_FLAG_RSS_FIELD_IPV6_UDP (1 << 7) #define IGB_FLAG_RSS_FIELD_IPV6_UDP (1 << 7)
#define IGB_FLAG_WOL_SUPPORTED (1 << 8) #define IGB_FLAG_WOL_SUPPORTED (1 << 8)
#define IGB_FLAG_NEED_LINK_UPDATE (1 << 9)
/* DMA Coalescing defines */ /* DMA Coalescing defines */
#define IGB_MIN_TXPBSIZE 20408 #define IGB_MIN_TXPBSIZE 20408
......
...@@ -172,10 +172,7 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -172,10 +172,7 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
SUPPORTED_Autoneg | SUPPORTED_Autoneg |
SUPPORTED_Pause); SUPPORTED_Pause);
ecmd->advertising = ADVERTISED_FIBRE; ecmd->advertising = ADVERTISED_FIBRE;
if (hw->mac.type == e1000_i354) {
ecmd->supported |= SUPPORTED_2500baseX_Full;
ecmd->advertising |= ADVERTISED_2500baseX_Full;
}
if ((eth_flags->e1000_base_lx) || (eth_flags->e1000_base_sx)) { if ((eth_flags->e1000_base_lx) || (eth_flags->e1000_base_sx)) {
ecmd->supported |= SUPPORTED_1000baseT_Full; ecmd->supported |= SUPPORTED_1000baseT_Full;
ecmd->advertising |= ADVERTISED_1000baseT_Full; ecmd->advertising |= ADVERTISED_1000baseT_Full;
...@@ -209,16 +206,23 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -209,16 +206,23 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
status = rd32(E1000_STATUS); status = rd32(E1000_STATUS);
if (status & E1000_STATUS_LU) { if (status & E1000_STATUS_LU) {
if ((hw->mac.type == e1000_i354) && if (hw->mac.type == e1000_i354) {
(status & E1000_STATUS_2P5_SKU) && if ((status & E1000_STATUS_2P5_SKU) &&
!(status & E1000_STATUS_2P5_SKU_OVER)) !(status & E1000_STATUS_2P5_SKU_OVER)) {
ecmd->speed = SPEED_2500; ecmd->supported = SUPPORTED_2500baseX_Full;
else if (status & E1000_STATUS_SPEED_1000) ecmd->advertising = ADVERTISED_2500baseX_Full;
ecmd->speed = SPEED_2500;
} else {
ecmd->supported = SUPPORTED_1000baseT_Full;
ecmd->advertising = ADVERTISED_1000baseT_Full;
}
} else if (status & E1000_STATUS_SPEED_1000) {
ecmd->speed = SPEED_1000; ecmd->speed = SPEED_1000;
else if (status & E1000_STATUS_SPEED_100) } else if (status & E1000_STATUS_SPEED_100) {
ecmd->speed = SPEED_100; ecmd->speed = SPEED_100;
else } else {
ecmd->speed = SPEED_10; ecmd->speed = SPEED_10;
}
if ((status & E1000_STATUS_FD) || if ((status & E1000_STATUS_FD) ||
hw->phy.media_type != e1000_media_type_copper) hw->phy.media_type != e1000_media_type_copper)
ecmd->duplex = DUPLEX_FULL; ecmd->duplex = DUPLEX_FULL;
......
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
#define MAJ 5 #define MAJ 5
#define MIN 0 #define MIN 0
#define BUILD 3 #define BUILD 5
#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";
...@@ -1671,6 +1671,8 @@ void igb_down(struct igb_adapter *adapter) ...@@ -1671,6 +1671,8 @@ void igb_down(struct igb_adapter *adapter)
igb_irq_disable(adapter); igb_irq_disable(adapter);
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
for (i = 0; i < adapter->num_q_vectors; i++) { for (i = 0; i < adapter->num_q_vectors; i++) {
napi_synchronize(&(adapter->q_vector[i]->napi)); napi_synchronize(&(adapter->q_vector[i]->napi));
napi_disable(&(adapter->q_vector[i]->napi)); napi_disable(&(adapter->q_vector[i]->napi));
...@@ -2367,7 +2369,14 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2367,7 +2369,14 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
"Width x1" : "unknown"), netdev->dev_addr); "Width x1" : "unknown"), netdev->dev_addr);
} }
ret_val = igb_read_part_string(hw, part_str, E1000_PBANUM_LENGTH); if ((hw->mac.type >= e1000_i210 ||
igb_get_flash_presence_i210(hw))) {
ret_val = igb_read_part_string(hw, part_str,
E1000_PBANUM_LENGTH);
} else {
ret_val = -E1000_ERR_INVM_VALUE_NOT_FOUND;
}
if (ret_val) if (ret_val)
strcpy(part_str, "Unknown"); strcpy(part_str, "Unknown");
dev_info(&pdev->dev, "%s: PBA No: %s\n", netdev->name, part_str); dev_info(&pdev->dev, "%s: PBA No: %s\n", netdev->name, part_str);
...@@ -3879,6 +3888,17 @@ bool igb_has_link(struct igb_adapter *adapter) ...@@ -3879,6 +3888,17 @@ bool igb_has_link(struct igb_adapter *adapter)
break; break;
} }
if (((hw->mac.type == e1000_i210) ||
(hw->mac.type == e1000_i211)) &&
(hw->phy.id == I210_I_PHY_ID)) {
if (!netif_carrier_ok(adapter->netdev)) {
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
} else if (!(adapter->flags & IGB_FLAG_NEED_LINK_UPDATE)) {
adapter->flags |= IGB_FLAG_NEED_LINK_UPDATE;
adapter->link_check_timeout = jiffies;
}
}
return link_active; return link_active;
} }
...@@ -3923,6 +3943,14 @@ static void igb_watchdog_task(struct work_struct *work) ...@@ -3923,6 +3943,14 @@ static void igb_watchdog_task(struct work_struct *work)
int i; int i;
link = igb_has_link(adapter); link = igb_has_link(adapter);
if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) {
if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
else
link = false;
}
if (link) { if (link) {
/* Cancel scheduled suspend requests. */ /* Cancel scheduled suspend requests. */
pm_runtime_resume(netdev->dev.parent); pm_runtime_resume(netdev->dev.parent);
...@@ -4047,9 +4075,14 @@ static void igb_watchdog_task(struct work_struct *work) ...@@ -4047,9 +4075,14 @@ static void igb_watchdog_task(struct work_struct *work)
igb_ptp_rx_hang(adapter); igb_ptp_rx_hang(adapter);
/* Reset the timer */ /* Reset the timer */
if (!test_bit(__IGB_DOWN, &adapter->state)) if (!test_bit(__IGB_DOWN, &adapter->state)) {
mod_timer(&adapter->watchdog_timer, if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE)
round_jiffies(jiffies + 2 * HZ)); mod_timer(&adapter->watchdog_timer,
round_jiffies(jiffies + HZ));
else
mod_timer(&adapter->watchdog_timer,
round_jiffies(jiffies + 2 * HZ));
}
} }
enum latency_range { enum latency_range {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment