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: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
b163b42fd2
|
@ -176,7 +176,7 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)
|
|||
|
||||
/* Verify phy id and set remaining function pointers */
|
||||
switch (phy->id) {
|
||||
case M88E1545_E_PHY_ID:
|
||||
case M88E1543_E_PHY_ID:
|
||||
case I347AT4_E_PHY_ID:
|
||||
case M88E1112_E_PHY_ID:
|
||||
case M88E1111_I_PHY_ID:
|
||||
|
@ -1140,6 +1140,31 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw)
|
|||
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
|
||||
* @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,
|
|||
u16 *duplex)
|
||||
{
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
u32 pcs;
|
||||
u32 pcs, status;
|
||||
|
||||
/* Set up defaults for the return values of this function */
|
||||
mac->serdes_has_link = false;
|
||||
|
@ -1238,22 +1263,33 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
|
|||
mac->serdes_has_link = true;
|
||||
|
||||
/* Detect and store PCS speed */
|
||||
if (pcs & E1000_PCS_LSTS_SPEED_1000) {
|
||||
if (pcs & E1000_PCS_LSTS_SPEED_1000)
|
||||
*speed = SPEED_1000;
|
||||
} else if (pcs & E1000_PCS_LSTS_SPEED_100) {
|
||||
else if (pcs & E1000_PCS_LSTS_SPEED_100)
|
||||
*speed = SPEED_100;
|
||||
} else {
|
||||
else
|
||||
*speed = SPEED_10;
|
||||
}
|
||||
|
||||
/* Detect and store PCS duplex */
|
||||
if (pcs & E1000_PCS_LSTS_DUPLEX_FULL) {
|
||||
if (pcs & E1000_PCS_LSTS_DUPLEX_FULL)
|
||||
*duplex = FULL_DUPLEX;
|
||||
} else {
|
||||
else
|
||||
*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;
|
||||
}
|
||||
|
||||
|
@ -1421,11 +1457,18 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
|
|||
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
|
||||
wr32(E1000_CTRL, ctrl);
|
||||
|
||||
/* Clear Go Link Disconnect bit */
|
||||
if (hw->mac.type >= e1000_82580) {
|
||||
/* Clear Go Link Disconnect bit on supported devices */
|
||||
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 &= ~E1000_82580_PM_GO_LINKD;
|
||||
wr32(E1000_82580_PHY_POWER_MGMT, phpm_reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret_val = igb_setup_serdes_link_82575(hw);
|
||||
|
@ -1448,7 +1491,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
|
|||
switch (hw->phy.id) {
|
||||
case I347AT4_E_PHY_ID:
|
||||
case M88E1112_E_PHY_ID:
|
||||
case M88E1545_E_PHY_ID:
|
||||
case M88E1543_E_PHY_ID:
|
||||
case I210_I_PHY_ID:
|
||||
ret_val = igb_copper_link_setup_m88_gen2(hw);
|
||||
break;
|
||||
|
@ -2477,28 +2520,28 @@ s32 igb_set_eee_i354(struct e1000_hw *hw)
|
|||
u16 phy_data;
|
||||
|
||||
if ((hw->phy.media_type != e1000_media_type_copper) ||
|
||||
(phy->id != M88E1545_E_PHY_ID))
|
||||
(phy->id != M88E1543_E_PHY_ID))
|
||||
goto out;
|
||||
|
||||
if (!hw->dev_spec._82575.eee_disable) {
|
||||
/* 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)
|
||||
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);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
phy_data |= E1000_M88E1545_EEE_CTRL_1_MS;
|
||||
ret_val = phy->ops.write_reg(hw, E1000_M88E1545_EEE_CTRL_1,
|
||||
phy_data |= E1000_M88E1543_EEE_CTRL_1_MS;
|
||||
ret_val = phy->ops.write_reg(hw, E1000_M88E1543_EEE_CTRL_1,
|
||||
phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* 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)
|
||||
goto out;
|
||||
|
||||
|
@ -2549,7 +2592,7 @@ s32 igb_get_eee_status_i354(struct e1000_hw *hw, bool *status)
|
|||
|
||||
/* Check if EEE is supported on this device. */
|
||||
if ((hw->phy.media_type != e1000_media_type_copper) ||
|
||||
(phy->id != M88E1545_E_PHY_ID))
|
||||
(phy->id != M88E1543_E_PHY_ID))
|
||||
goto out;
|
||||
|
||||
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 = {
|
|||
.check_for_link = igb_check_for_link_82575,
|
||||
.rar_set = igb_rar_set,
|
||||
.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
|
||||
.get_thermal_sensor_data = igb_get_thermal_sensor_data_generic,
|
||||
.init_thermal_sensor_thresh = igb_init_thermal_sensor_thresh_generic,
|
||||
|
|
|
@ -787,7 +787,7 @@
|
|||
#define I350_I_PHY_ID 0x015403B0
|
||||
#define M88_VENDOR 0x0141
|
||||
#define I210_I_PHY_ID 0x01410C00
|
||||
#define M88E1545_E_PHY_ID 0x01410EA0
|
||||
#define M88E1543_E_PHY_ID 0x01410EA0
|
||||
|
||||
/* M88E1000 Specific Registers */
|
||||
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
|
||||
|
@ -909,9 +909,9 @@
|
|||
#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_MMDAC_FUNC_DATA 0x4000 /* Data, no post increment */
|
||||
#define E1000_M88E1545_PAGE_ADDR 0x16 /* Page Offset Register */
|
||||
#define E1000_M88E1545_EEE_CTRL_1 0x0
|
||||
#define E1000_M88E1545_EEE_CTRL_1_MS 0x0001 /* EEE Master/Slave */
|
||||
#define E1000_M88E1543_PAGE_ADDR 0x16 /* Page Offset Register */
|
||||
#define E1000_M88E1543_EEE_CTRL_1 0x0
|
||||
#define E1000_M88E1543_EEE_CTRL_1_MS 0x0001 /* EEE Master/Slave */
|
||||
#define E1000_EEE_ADV_DEV_I354 7
|
||||
#define E1000_EEE_ADV_ADDR_I354 60
|
||||
#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,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -731,15 +731,13 @@ s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)
|
|||
s32 ret_val;
|
||||
u16 phy_data;
|
||||
|
||||
if (phy->reset_disable) {
|
||||
ret_val = 0;
|
||||
goto out;
|
||||
}
|
||||
if (phy->reset_disable)
|
||||
return 0;
|
||||
|
||||
/* 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);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
/* Options:
|
||||
* MDI/MDI-X = 0 (default)
|
||||
|
@ -780,23 +778,36 @@ s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)
|
|||
phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
|
||||
|
||||
/* 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_6X;
|
||||
phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE;
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
/* Commit the changes. */
|
||||
ret_val = igb_phy_sw_reset(hw);
|
||||
if (ret_val) {
|
||||
hw_dbg("Error committing the PHY changes\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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->cable_length = phy_data / (is_cm ? 100 : 1);
|
||||
break;
|
||||
case M88E1545_E_PHY_ID:
|
||||
case M88E1543_E_PHY_ID:
|
||||
case I347AT4_E_PHY_ID:
|
||||
/* Remember the original page select and set it to 7 */
|
||||
ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
|
||||
|
|
|
@ -448,6 +448,8 @@ struct igb_adapter {
|
|||
struct i2c_client *i2c_client;
|
||||
u32 rss_indir_tbl_init;
|
||||
u8 rss_indir_tbl[IGB_RETA_SIZE];
|
||||
|
||||
unsigned long link_check_timeout;
|
||||
};
|
||||
|
||||
#define IGB_FLAG_HAS_MSI (1 << 0)
|
||||
|
@ -459,6 +461,7 @@ struct igb_adapter {
|
|||
#define IGB_FLAG_RSS_FIELD_IPV4_UDP (1 << 6)
|
||||
#define IGB_FLAG_RSS_FIELD_IPV6_UDP (1 << 7)
|
||||
#define IGB_FLAG_WOL_SUPPORTED (1 << 8)
|
||||
#define IGB_FLAG_NEED_LINK_UPDATE (1 << 9)
|
||||
|
||||
/* DMA Coalescing defines */
|
||||
#define IGB_MIN_TXPBSIZE 20408
|
||||
|
|
|
@ -172,10 +172,7 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
|||
SUPPORTED_Autoneg |
|
||||
SUPPORTED_Pause);
|
||||
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)) {
|
||||
ecmd->supported |= SUPPORTED_1000baseT_Full;
|
||||
ecmd->advertising |= ADVERTISED_1000baseT_Full;
|
||||
|
@ -209,16 +206,23 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
|||
status = rd32(E1000_STATUS);
|
||||
|
||||
if (status & E1000_STATUS_LU) {
|
||||
if ((hw->mac.type == e1000_i354) &&
|
||||
(status & E1000_STATUS_2P5_SKU) &&
|
||||
!(status & E1000_STATUS_2P5_SKU_OVER))
|
||||
if (hw->mac.type == e1000_i354) {
|
||||
if ((status & E1000_STATUS_2P5_SKU) &&
|
||||
!(status & E1000_STATUS_2P5_SKU_OVER)) {
|
||||
ecmd->supported = SUPPORTED_2500baseX_Full;
|
||||
ecmd->advertising = ADVERTISED_2500baseX_Full;
|
||||
ecmd->speed = SPEED_2500;
|
||||
else if (status & E1000_STATUS_SPEED_1000)
|
||||
} else {
|
||||
ecmd->supported = SUPPORTED_1000baseT_Full;
|
||||
ecmd->advertising = ADVERTISED_1000baseT_Full;
|
||||
}
|
||||
} else if (status & E1000_STATUS_SPEED_1000) {
|
||||
ecmd->speed = SPEED_1000;
|
||||
else if (status & E1000_STATUS_SPEED_100)
|
||||
} else if (status & E1000_STATUS_SPEED_100) {
|
||||
ecmd->speed = SPEED_100;
|
||||
else
|
||||
} else {
|
||||
ecmd->speed = SPEED_10;
|
||||
}
|
||||
if ((status & E1000_STATUS_FD) ||
|
||||
hw->phy.media_type != e1000_media_type_copper)
|
||||
ecmd->duplex = DUPLEX_FULL;
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
#define MAJ 5
|
||||
#define MIN 0
|
||||
#define BUILD 3
|
||||
#define BUILD 5
|
||||
#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
|
||||
__stringify(BUILD) "-k"
|
||||
char igb_driver_name[] = "igb";
|
||||
|
@ -1671,6 +1671,8 @@ void igb_down(struct igb_adapter *adapter)
|
|||
|
||||
igb_irq_disable(adapter);
|
||||
|
||||
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
|
||||
|
||||
for (i = 0; i < adapter->num_q_vectors; i++) {
|
||||
napi_synchronize(&(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)
|
|||
"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)
|
||||
strcpy(part_str, "Unknown");
|
||||
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)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -3923,6 +3943,14 @@ static void igb_watchdog_task(struct work_struct *work)
|
|||
int i;
|
||||
|
||||
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) {
|
||||
/* Cancel scheduled suspend requests. */
|
||||
pm_runtime_resume(netdev->dev.parent);
|
||||
|
@ -4047,9 +4075,14 @@ static void igb_watchdog_task(struct work_struct *work)
|
|||
igb_ptp_rx_hang(adapter);
|
||||
|
||||
/* Reset the timer */
|
||||
if (!test_bit(__IGB_DOWN, &adapter->state))
|
||||
if (!test_bit(__IGB_DOWN, &adapter->state)) {
|
||||
if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE)
|
||||
mod_timer(&adapter->watchdog_timer,
|
||||
round_jiffies(jiffies + HZ));
|
||||
else
|
||||
mod_timer(&adapter->watchdog_timer,
|
||||
round_jiffies(jiffies + 2 * HZ));
|
||||
}
|
||||
}
|
||||
|
||||
enum latency_range {
|
||||
|
|
Загрузка…
Ссылка в новой задаче