Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/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>
  • Loading branch information
David S. Miller committed Sep 4, 2013
2 parents 48f8e0a + 66f40b8 commit b163b42
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 60 deletions.
81 changes: 62 additions & 19 deletions drivers/net/ethernet/intel/igb/e1000_82575.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -1238,20 +1263,31 @@ 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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/ethernet/intel/igb/e1000_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down
11 changes: 0 additions & 11 deletions drivers/net/ethernet/intel/igb/e1000_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
31 changes: 21 additions & 10 deletions drivers/net/ethernet/intel/igb/e1000_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/intel/igb/igb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
26 changes: 15 additions & 11 deletions drivers/net/ethernet/intel/igb/igb_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))
ecmd->speed = SPEED_2500;
else if (status & E1000_STATUS_SPEED_1000)
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 {
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;
Expand Down
Loading

0 comments on commit b163b42

Please sign in to comment.