igb: add support for 82580 MAC
This patch adds support for the 82580 MAC. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2909c3f79d
commit
bb2ac47bcf
@ -46,7 +46,10 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *);
|
|||||||
static s32 igb_init_hw_82575(struct e1000_hw *);
|
static s32 igb_init_hw_82575(struct e1000_hw *);
|
||||||
static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *);
|
static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *);
|
||||||
static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *);
|
static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *);
|
||||||
|
static s32 igb_read_phy_reg_82580(struct e1000_hw *, u32, u16 *);
|
||||||
|
static s32 igb_write_phy_reg_82580(struct e1000_hw *, u32, u16);
|
||||||
static s32 igb_reset_hw_82575(struct e1000_hw *);
|
static s32 igb_reset_hw_82575(struct e1000_hw *);
|
||||||
|
static s32 igb_reset_hw_82580(struct e1000_hw *);
|
||||||
static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
|
static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
|
||||||
static s32 igb_setup_copper_link_82575(struct e1000_hw *);
|
static s32 igb_setup_copper_link_82575(struct e1000_hw *);
|
||||||
static s32 igb_setup_serdes_link_82575(struct e1000_hw *);
|
static s32 igb_setup_serdes_link_82575(struct e1000_hw *);
|
||||||
@ -62,6 +65,12 @@ static s32 igb_reset_init_script_82575(struct e1000_hw *);
|
|||||||
static s32 igb_read_mac_addr_82575(struct e1000_hw *);
|
static s32 igb_read_mac_addr_82575(struct e1000_hw *);
|
||||||
static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw);
|
static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw);
|
||||||
|
|
||||||
|
static const u16 e1000_82580_rxpbs_table[] =
|
||||||
|
{ 36, 72, 144, 1, 2, 4, 8, 16,
|
||||||
|
35, 70, 140 };
|
||||||
|
#define E1000_82580_RXPBS_TABLE_SIZE \
|
||||||
|
(sizeof(e1000_82580_rxpbs_table)/sizeof(u16))
|
||||||
|
|
||||||
static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
||||||
{
|
{
|
||||||
struct e1000_phy_info *phy = &hw->phy;
|
struct e1000_phy_info *phy = &hw->phy;
|
||||||
@ -88,6 +97,13 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
|||||||
case E1000_DEV_ID_82576_SERDES_QUAD:
|
case E1000_DEV_ID_82576_SERDES_QUAD:
|
||||||
mac->type = e1000_82576;
|
mac->type = e1000_82576;
|
||||||
break;
|
break;
|
||||||
|
case E1000_DEV_ID_82580_COPPER:
|
||||||
|
case E1000_DEV_ID_82580_FIBER:
|
||||||
|
case E1000_DEV_ID_82580_SERDES:
|
||||||
|
case E1000_DEV_ID_82580_SGMII:
|
||||||
|
case E1000_DEV_ID_82580_COPPER_DUAL:
|
||||||
|
mac->type = e1000_82580;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -E1000_ERR_MAC_INIT;
|
return -E1000_ERR_MAC_INIT;
|
||||||
break;
|
break;
|
||||||
@ -110,6 +126,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
|||||||
dev_spec->sgmii_active = true;
|
dev_spec->sgmii_active = true;
|
||||||
ctrl_ext |= E1000_CTRL_I2C_ENA;
|
ctrl_ext |= E1000_CTRL_I2C_ENA;
|
||||||
break;
|
break;
|
||||||
|
case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
|
||||||
case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
|
case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
|
||||||
hw->phy.media_type = e1000_media_type_internal_serdes;
|
hw->phy.media_type = e1000_media_type_internal_serdes;
|
||||||
ctrl_ext |= E1000_CTRL_I2C_ENA;
|
ctrl_ext |= E1000_CTRL_I2C_ENA;
|
||||||
@ -121,12 +138,26 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
|||||||
|
|
||||||
wr32(E1000_CTRL_EXT, ctrl_ext);
|
wr32(E1000_CTRL_EXT, ctrl_ext);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if using i2c make certain the MDICNFG register is cleared to prevent
|
||||||
|
* communications from being misrouted to the mdic registers
|
||||||
|
*/
|
||||||
|
if ((ctrl_ext & E1000_CTRL_I2C_ENA) && (hw->mac.type == e1000_82580))
|
||||||
|
wr32(E1000_MDICNFG, 0);
|
||||||
|
|
||||||
/* Set mta register count */
|
/* Set mta register count */
|
||||||
mac->mta_reg_count = 128;
|
mac->mta_reg_count = 128;
|
||||||
/* Set rar entry count */
|
/* Set rar entry count */
|
||||||
mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
|
mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
|
||||||
if (mac->type == e1000_82576)
|
if (mac->type == e1000_82576)
|
||||||
mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
|
mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
|
||||||
|
if (mac->type == e1000_82580)
|
||||||
|
mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
|
||||||
|
/* reset */
|
||||||
|
if (mac->type == e1000_82580)
|
||||||
|
mac->ops.reset_hw = igb_reset_hw_82580;
|
||||||
|
else
|
||||||
|
mac->ops.reset_hw = igb_reset_hw_82575;
|
||||||
/* Set if part includes ASF firmware */
|
/* Set if part includes ASF firmware */
|
||||||
mac->asf_firmware_present = true;
|
mac->asf_firmware_present = true;
|
||||||
/* Set if manageability features are enabled. */
|
/* Set if manageability features are enabled. */
|
||||||
@ -194,6 +225,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
|||||||
phy->ops.reset = igb_phy_hw_reset_sgmii_82575;
|
phy->ops.reset = igb_phy_hw_reset_sgmii_82575;
|
||||||
phy->ops.read_reg = igb_read_phy_reg_sgmii_82575;
|
phy->ops.read_reg = igb_read_phy_reg_sgmii_82575;
|
||||||
phy->ops.write_reg = igb_write_phy_reg_sgmii_82575;
|
phy->ops.write_reg = igb_write_phy_reg_sgmii_82575;
|
||||||
|
} else if (hw->mac.type == e1000_82580) {
|
||||||
|
phy->ops.reset = igb_phy_hw_reset;
|
||||||
|
phy->ops.read_reg = igb_read_phy_reg_82580;
|
||||||
|
phy->ops.write_reg = igb_write_phy_reg_82580;
|
||||||
} else {
|
} else {
|
||||||
phy->ops.reset = igb_phy_hw_reset;
|
phy->ops.reset = igb_phy_hw_reset;
|
||||||
phy->ops.read_reg = igb_read_phy_reg_igp;
|
phy->ops.read_reg = igb_read_phy_reg_igp;
|
||||||
@ -225,6 +260,12 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
|||||||
phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82575;
|
phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82575;
|
||||||
phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state;
|
phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state;
|
||||||
break;
|
break;
|
||||||
|
case I82580_I_PHY_ID:
|
||||||
|
phy->type = e1000_phy_82580;
|
||||||
|
phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_82580;
|
||||||
|
phy->ops.get_cable_length = igb_get_cable_length_82580;
|
||||||
|
phy->ops.get_phy_info = igb_get_phy_info_82580;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -E1000_ERR_PHY;
|
return -E1000_ERR_PHY;
|
||||||
}
|
}
|
||||||
@ -635,6 +676,10 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw)
|
|||||||
|
|
||||||
if (hw->bus.func == 1)
|
if (hw->bus.func == 1)
|
||||||
mask = E1000_NVM_CFG_DONE_PORT_1;
|
mask = E1000_NVM_CFG_DONE_PORT_1;
|
||||||
|
else if (hw->bus.func == E1000_FUNC_2)
|
||||||
|
mask = E1000_NVM_CFG_DONE_PORT_2;
|
||||||
|
else if (hw->bus.func == E1000_FUNC_3)
|
||||||
|
mask = E1000_NVM_CFG_DONE_PORT_3;
|
||||||
|
|
||||||
while (timeout) {
|
while (timeout) {
|
||||||
if (rd32(E1000_EEMNGCTL) & mask)
|
if (rd32(E1000_EEMNGCTL) & mask)
|
||||||
@ -754,6 +799,10 @@ void igb_shutdown_serdes_link_82575(struct e1000_hw *hw)
|
|||||||
|
|
||||||
if (hw->bus.func == E1000_FUNC_0)
|
if (hw->bus.func == E1000_FUNC_0)
|
||||||
hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
|
hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
|
||||||
|
else if (hw->mac.type == e1000_82580)
|
||||||
|
hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
|
||||||
|
NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
|
||||||
|
&eeprom_data);
|
||||||
else if (hw->bus.func == E1000_FUNC_1)
|
else if (hw->bus.func == E1000_FUNC_1)
|
||||||
hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
|
hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
|
||||||
|
|
||||||
@ -918,6 +967,9 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (igb_sgmii_active_82575(hw) && !hw->phy.reset_disable) {
|
if (igb_sgmii_active_82575(hw) && !hw->phy.reset_disable) {
|
||||||
|
/* allow time for SFP cage time to power up phy */
|
||||||
|
msleep(300);
|
||||||
|
|
||||||
ret_val = hw->phy.ops.reset(hw);
|
ret_val = hw->phy.ops.reset(hw);
|
||||||
if (ret_val) {
|
if (ret_val) {
|
||||||
hw_dbg("Error resetting the PHY.\n");
|
hw_dbg("Error resetting the PHY.\n");
|
||||||
@ -931,6 +983,9 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
|
|||||||
case e1000_phy_igp_3:
|
case e1000_phy_igp_3:
|
||||||
ret_val = igb_copper_link_setup_igp(hw);
|
ret_val = igb_copper_link_setup_igp(hw);
|
||||||
break;
|
break;
|
||||||
|
case e1000_phy_82580:
|
||||||
|
ret_val = igb_copper_link_setup_82580(hw);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ret_val = -E1000_ERR_PHY;
|
ret_val = -E1000_ERR_PHY;
|
||||||
break;
|
break;
|
||||||
@ -955,7 +1010,8 @@ out:
|
|||||||
**/
|
**/
|
||||||
static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
|
static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
|
||||||
{
|
{
|
||||||
u32 ctrl_reg, reg;
|
u32 ctrl_ext, ctrl_reg, reg;
|
||||||
|
bool pcs_autoneg;
|
||||||
|
|
||||||
if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
|
if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
|
||||||
!igb_sgmii_active_82575(hw))
|
!igb_sgmii_active_82575(hw))
|
||||||
@ -970,9 +1026,9 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
|
|||||||
wr32(E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
|
wr32(E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
|
||||||
|
|
||||||
/* power on the sfp cage if present */
|
/* power on the sfp cage if present */
|
||||||
reg = rd32(E1000_CTRL_EXT);
|
ctrl_ext = rd32(E1000_CTRL_EXT);
|
||||||
reg &= ~E1000_CTRL_EXT_SDP3_DATA;
|
ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
|
||||||
wr32(E1000_CTRL_EXT, reg);
|
wr32(E1000_CTRL_EXT, ctrl_ext);
|
||||||
|
|
||||||
ctrl_reg = rd32(E1000_CTRL);
|
ctrl_reg = rd32(E1000_CTRL);
|
||||||
ctrl_reg |= E1000_CTRL_SLU;
|
ctrl_reg |= E1000_CTRL_SLU;
|
||||||
@ -989,15 +1045,31 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
|
|||||||
|
|
||||||
reg = rd32(E1000_PCS_LCTL);
|
reg = rd32(E1000_PCS_LCTL);
|
||||||
|
|
||||||
if (igb_sgmii_active_82575(hw)) {
|
/* default pcs_autoneg to the same setting as mac autoneg */
|
||||||
/* allow time for SFP cage to power up phy */
|
pcs_autoneg = hw->mac.autoneg;
|
||||||
msleep(300);
|
|
||||||
|
|
||||||
/* AN time out should be disabled for SGMII mode */
|
switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
|
||||||
|
case E1000_CTRL_EXT_LINK_MODE_SGMII:
|
||||||
|
/* sgmii mode lets the phy handle forcing speed/duplex */
|
||||||
|
pcs_autoneg = true;
|
||||||
|
/* autoneg time out should be disabled for SGMII mode */
|
||||||
reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
|
reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
|
||||||
} else {
|
break;
|
||||||
|
case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
|
||||||
|
/* disable PCS autoneg and support parallel detect only */
|
||||||
|
pcs_autoneg = false;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* non-SGMII modes only supports a speed of 1000/Full for the
|
||||||
|
* link so it is best to just force the MAC and let the pcs
|
||||||
|
* link either autoneg or be forced to 1000/Full
|
||||||
|
*/
|
||||||
ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
|
ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
|
||||||
E1000_CTRL_FD | E1000_CTRL_FRCDPX;
|
E1000_CTRL_FD | E1000_CTRL_FRCDPX;
|
||||||
|
|
||||||
|
/* set speed of 1000/Full if speed/duplex is forced */
|
||||||
|
reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
wr32(E1000_CTRL, ctrl_reg);
|
wr32(E1000_CTRL, ctrl_reg);
|
||||||
@ -1008,7 +1080,6 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
|
|||||||
* mode that will be compatible with older link partners and switches.
|
* mode that will be compatible with older link partners and switches.
|
||||||
* However, both are supported by the hardware and some drivers/tools.
|
* However, both are supported by the hardware and some drivers/tools.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
|
reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
|
||||||
E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
|
E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
|
||||||
|
|
||||||
@ -1018,34 +1089,18 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
|
|||||||
*/
|
*/
|
||||||
reg |= E1000_PCS_LCTL_FORCE_FCTRL;
|
reg |= E1000_PCS_LCTL_FORCE_FCTRL;
|
||||||
|
|
||||||
/*
|
if (pcs_autoneg) {
|
||||||
* we always set sgmii to autoneg since it is the phy that will be
|
|
||||||
* forcing the link and the serdes is just a go-between
|
|
||||||
*/
|
|
||||||
if (hw->mac.autoneg || igb_sgmii_active_82575(hw)) {
|
|
||||||
/* Set PCS register for autoneg */
|
/* Set PCS register for autoneg */
|
||||||
reg |= E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */
|
reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
|
||||||
E1000_PCS_LCTL_FDV_FULL | /* SerDes Full dplx */
|
|
||||||
E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
|
|
||||||
E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
|
E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
|
||||||
hw_dbg("Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
|
hw_dbg("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg);
|
||||||
} else {
|
} else {
|
||||||
/* Check for duplex first */
|
/* Set PCS register for forced link */
|
||||||
if (hw->mac.forced_speed_duplex & E1000_ALL_FULL_DUPLEX)
|
reg |= E1000_PCS_LCTL_FSD | /* Force Speed */
|
||||||
reg |= E1000_PCS_LCTL_FDV_FULL;
|
E1000_PCS_LCTL_FORCE_LINK | /* Force Link */
|
||||||
|
E1000_PCS_LCTL_FLV_LINK_UP; /* Force link value up */
|
||||||
|
|
||||||
/* No need to check for 1000/full since the spec states that
|
hw_dbg("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg);
|
||||||
* it requires autoneg to be enabled */
|
|
||||||
/* Now set speed */
|
|
||||||
if (hw->mac.forced_speed_duplex & E1000_ALL_100_SPEED)
|
|
||||||
reg |= E1000_PCS_LCTL_FSV_100;
|
|
||||||
|
|
||||||
/* Force speed and force link */
|
|
||||||
reg |= E1000_PCS_LCTL_FSD |
|
|
||||||
E1000_PCS_LCTL_FORCE_LINK |
|
|
||||||
E1000_PCS_LCTL_FLV_LINK_UP;
|
|
||||||
|
|
||||||
hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wr32(E1000_PCS_LCTL, reg);
|
wr32(E1000_PCS_LCTL, reg);
|
||||||
@ -1354,8 +1409,183 @@ void igb_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
|
|||||||
wr32(E1000_VT_CTL, vt_ctl);
|
wr32(E1000_VT_CTL, vt_ctl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igb_read_phy_reg_82580 - Read 82580 MDI control register
|
||||||
|
* @hw: pointer to the HW structure
|
||||||
|
* @offset: register offset to be read
|
||||||
|
* @data: pointer to the read data
|
||||||
|
*
|
||||||
|
* Reads the MDI control register in the PHY at offset and stores the
|
||||||
|
* information read to data.
|
||||||
|
**/
|
||||||
|
static s32 igb_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||||
|
{
|
||||||
|
u32 mdicnfg = 0;
|
||||||
|
s32 ret_val;
|
||||||
|
|
||||||
|
|
||||||
|
ret_val = hw->phy.ops.acquire(hw);
|
||||||
|
if (ret_val)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We config the phy address in MDICNFG register now. Same bits
|
||||||
|
* as before. The values in MDIC can be written but will be
|
||||||
|
* ignored. This allows us to call the old function after
|
||||||
|
* configuring the PHY address in the new register
|
||||||
|
*/
|
||||||
|
mdicnfg = (hw->phy.addr << E1000_MDIC_PHY_SHIFT);
|
||||||
|
wr32(E1000_MDICNFG, mdicnfg);
|
||||||
|
|
||||||
|
ret_val = igb_read_phy_reg_mdic(hw, offset, data);
|
||||||
|
|
||||||
|
hw->phy.ops.release(hw);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igb_write_phy_reg_82580 - Write 82580 MDI control register
|
||||||
|
* @hw: pointer to the HW structure
|
||||||
|
* @offset: register offset to write to
|
||||||
|
* @data: data to write to register at offset
|
||||||
|
*
|
||||||
|
* Writes data to MDI control register in the PHY at offset.
|
||||||
|
**/
|
||||||
|
static s32 igb_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data)
|
||||||
|
{
|
||||||
|
u32 mdicnfg = 0;
|
||||||
|
s32 ret_val;
|
||||||
|
|
||||||
|
|
||||||
|
ret_val = hw->phy.ops.acquire(hw);
|
||||||
|
if (ret_val)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We config the phy address in MDICNFG register now. Same bits
|
||||||
|
* as before. The values in MDIC can be written but will be
|
||||||
|
* ignored. This allows us to call the old function after
|
||||||
|
* configuring the PHY address in the new register
|
||||||
|
*/
|
||||||
|
mdicnfg = (hw->phy.addr << E1000_MDIC_PHY_SHIFT);
|
||||||
|
wr32(E1000_MDICNFG, mdicnfg);
|
||||||
|
|
||||||
|
ret_val = igb_write_phy_reg_mdic(hw, offset, data);
|
||||||
|
|
||||||
|
hw->phy.ops.release(hw);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igb_reset_hw_82580 - Reset hardware
|
||||||
|
* @hw: pointer to the HW structure
|
||||||
|
*
|
||||||
|
* This resets function or entire device (all ports, etc.)
|
||||||
|
* to a known state.
|
||||||
|
**/
|
||||||
|
static s32 igb_reset_hw_82580(struct e1000_hw *hw)
|
||||||
|
{
|
||||||
|
s32 ret_val = 0;
|
||||||
|
/* BH SW mailbox bit in SW_FW_SYNC */
|
||||||
|
u16 swmbsw_mask = E1000_SW_SYNCH_MB;
|
||||||
|
u32 ctrl, icr;
|
||||||
|
bool global_device_reset = hw->dev_spec._82575.global_device_reset;
|
||||||
|
|
||||||
|
|
||||||
|
hw->dev_spec._82575.global_device_reset = false;
|
||||||
|
|
||||||
|
/* Get current control state. */
|
||||||
|
ctrl = rd32(E1000_CTRL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevent the PCI-E bus from sticking if there is no TLP connection
|
||||||
|
* on the last TLP read/write transaction when MAC is reset.
|
||||||
|
*/
|
||||||
|
ret_val = igb_disable_pcie_master(hw);
|
||||||
|
if (ret_val)
|
||||||
|
hw_dbg("PCI-E Master disable polling has failed.\n");
|
||||||
|
|
||||||
|
hw_dbg("Masking off all interrupts\n");
|
||||||
|
wr32(E1000_IMC, 0xffffffff);
|
||||||
|
wr32(E1000_RCTL, 0);
|
||||||
|
wr32(E1000_TCTL, E1000_TCTL_PSP);
|
||||||
|
wrfl();
|
||||||
|
|
||||||
|
msleep(10);
|
||||||
|
|
||||||
|
/* Determine whether or not a global dev reset is requested */
|
||||||
|
if (global_device_reset &&
|
||||||
|
igb_acquire_swfw_sync_82575(hw, swmbsw_mask))
|
||||||
|
global_device_reset = false;
|
||||||
|
|
||||||
|
if (global_device_reset &&
|
||||||
|
!(rd32(E1000_STATUS) & E1000_STAT_DEV_RST_SET))
|
||||||
|
ctrl |= E1000_CTRL_DEV_RST;
|
||||||
|
else
|
||||||
|
ctrl |= E1000_CTRL_RST;
|
||||||
|
|
||||||
|
wr32(E1000_CTRL, ctrl);
|
||||||
|
|
||||||
|
/* Add delay to insure DEV_RST has time to complete */
|
||||||
|
if (global_device_reset)
|
||||||
|
msleep(5);
|
||||||
|
|
||||||
|
ret_val = igb_get_auto_rd_done(hw);
|
||||||
|
if (ret_val) {
|
||||||
|
/*
|
||||||
|
* When auto config read does not complete, do not
|
||||||
|
* return with an error. This can happen in situations
|
||||||
|
* where there is no eeprom and prevents getting link.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Clear any pending interrupt events. */
|
||||||
|
wr32(E1000_IMC, 0xffffffff);
|
||||||
|
icr = rd32(E1000_ICR);
|
||||||
|
|
||||||
|
/* Install any alternate MAC address into RAR0 */
|
||||||
|
ret_val = igb_check_alt_mac_addr(hw);
|
||||||
|
|
||||||
|
/* Release semaphore */
|
||||||
|
if (global_device_reset)
|
||||||
|
igb_release_swfw_sync_82575(hw, swmbsw_mask);
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igb_rxpbs_adjust_82580 - adjust RXPBS value to reflect actual RX PBA size
|
||||||
|
* @data: data received by reading RXPBS register
|
||||||
|
*
|
||||||
|
* The 82580 uses a table based approach for packet buffer allocation sizes.
|
||||||
|
* This function converts the retrieved value into the correct table value
|
||||||
|
* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
|
||||||
|
* 0x0 36 72 144 1 2 4 8 16
|
||||||
|
* 0x8 35 70 140 rsv rsv rsv rsv rsv
|
||||||
|
*/
|
||||||
|
u16 igb_rxpbs_adjust_82580(u32 data)
|
||||||
|
{
|
||||||
|
u16 ret_val = 0;
|
||||||
|
|
||||||
|
if (data < E1000_82580_RXPBS_TABLE_SIZE)
|
||||||
|
ret_val = e1000_82580_rxpbs_table[data];
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
static struct e1000_mac_operations e1000_mac_ops_82575 = {
|
static struct e1000_mac_operations e1000_mac_ops_82575 = {
|
||||||
.reset_hw = igb_reset_hw_82575,
|
|
||||||
.init_hw = igb_init_hw_82575,
|
.init_hw = igb_init_hw_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,
|
||||||
|
@ -38,6 +38,11 @@ extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
|
|||||||
|
|
||||||
#define E1000_RAR_ENTRIES_82575 16
|
#define E1000_RAR_ENTRIES_82575 16
|
||||||
#define E1000_RAR_ENTRIES_82576 24
|
#define E1000_RAR_ENTRIES_82576 24
|
||||||
|
#define E1000_RAR_ENTRIES_82580 24
|
||||||
|
|
||||||
|
#define E1000_SW_SYNCH_MB 0x00000100
|
||||||
|
#define E1000_STAT_DEV_RST_SET 0x00100000
|
||||||
|
#define E1000_CTRL_DEV_RST 0x20000000
|
||||||
|
|
||||||
/* SRRCTL bit definitions */
|
/* SRRCTL bit definitions */
|
||||||
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
|
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
|
||||||
@ -232,5 +237,6 @@ struct e1000_adv_tx_context_desc {
|
|||||||
#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
|
#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
|
||||||
void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
|
void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
|
||||||
void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
|
void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
|
||||||
|
u16 igb_rxpbs_adjust_82580(u32 data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#define E1000_CTRL_EXT_PFRSTD 0x00004000
|
#define E1000_CTRL_EXT_PFRSTD 0x00004000
|
||||||
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
|
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
|
||||||
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
|
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
|
||||||
|
#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000
|
||||||
#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
|
#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
|
||||||
#define E1000_CTRL_EXT_EIAME 0x01000000
|
#define E1000_CTRL_EXT_EIAME 0x01000000
|
||||||
#define E1000_CTRL_EXT_IRCA 0x00000001
|
#define E1000_CTRL_EXT_IRCA 0x00000001
|
||||||
@ -557,8 +558,12 @@
|
|||||||
#define NVM_ALT_MAC_ADDR_PTR 0x0037
|
#define NVM_ALT_MAC_ADDR_PTR 0x0037
|
||||||
#define NVM_CHECKSUM_REG 0x003F
|
#define NVM_CHECKSUM_REG 0x003F
|
||||||
|
|
||||||
#define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */
|
#define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */
|
||||||
#define E1000_NVM_CFG_DONE_PORT_1 0x80000 /* ...for second port */
|
#define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */
|
||||||
|
#define E1000_NVM_CFG_DONE_PORT_2 0x100000 /* ...for third port */
|
||||||
|
#define E1000_NVM_CFG_DONE_PORT_3 0x200000 /* ...for fourth port */
|
||||||
|
|
||||||
|
#define NVM_82580_LAN_FUNC_OFFSET(a) (a ? (0x40 + (0x40 * a)) : 0)
|
||||||
|
|
||||||
/* Mask bits for fields in Word 0x0f of the NVM */
|
/* Mask bits for fields in Word 0x0f of the NVM */
|
||||||
#define NVM_WORD0F_PAUSE_MASK 0x3000
|
#define NVM_WORD0F_PAUSE_MASK 0x3000
|
||||||
@ -625,6 +630,7 @@
|
|||||||
*/
|
*/
|
||||||
#define M88E1111_I_PHY_ID 0x01410CC0
|
#define M88E1111_I_PHY_ID 0x01410CC0
|
||||||
#define IGP03E1000_E_PHY_ID 0x02A80390
|
#define IGP03E1000_E_PHY_ID 0x02A80390
|
||||||
|
#define I82580_I_PHY_ID 0x015403A0
|
||||||
#define M88_VENDOR 0x0141
|
#define M88_VENDOR 0x0141
|
||||||
|
|
||||||
/* M88E1000 Specific Registers */
|
/* M88E1000 Specific Registers */
|
||||||
|
@ -47,19 +47,30 @@ struct e1000_hw;
|
|||||||
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
|
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
|
||||||
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
|
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
|
||||||
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
|
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
|
||||||
|
#define E1000_DEV_ID_82580_COPPER 0x150E
|
||||||
|
#define E1000_DEV_ID_82580_FIBER 0x150F
|
||||||
|
#define E1000_DEV_ID_82580_SERDES 0x1510
|
||||||
|
#define E1000_DEV_ID_82580_SGMII 0x1511
|
||||||
|
#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516
|
||||||
|
|
||||||
#define E1000_REVISION_2 2
|
#define E1000_REVISION_2 2
|
||||||
#define E1000_REVISION_4 4
|
#define E1000_REVISION_4 4
|
||||||
|
|
||||||
#define E1000_FUNC_0 0
|
#define E1000_FUNC_0 0
|
||||||
#define E1000_FUNC_1 1
|
#define E1000_FUNC_1 1
|
||||||
|
#define E1000_FUNC_2 2
|
||||||
|
#define E1000_FUNC_3 3
|
||||||
|
|
||||||
|
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0
|
||||||
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3
|
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3
|
||||||
|
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN2 6
|
||||||
|
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN3 9
|
||||||
|
|
||||||
enum e1000_mac_type {
|
enum e1000_mac_type {
|
||||||
e1000_undefined = 0,
|
e1000_undefined = 0,
|
||||||
e1000_82575,
|
e1000_82575,
|
||||||
e1000_82576,
|
e1000_82576,
|
||||||
|
e1000_82580,
|
||||||
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
|
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -290,6 +301,7 @@ struct e1000_mac_operations {
|
|||||||
|
|
||||||
struct e1000_phy_operations {
|
struct e1000_phy_operations {
|
||||||
s32 (*acquire)(struct e1000_hw *);
|
s32 (*acquire)(struct e1000_hw *);
|
||||||
|
s32 (*check_polarity)(struct e1000_hw *);
|
||||||
s32 (*check_reset_block)(struct e1000_hw *);
|
s32 (*check_reset_block)(struct e1000_hw *);
|
||||||
s32 (*force_speed_duplex)(struct e1000_hw *);
|
s32 (*force_speed_duplex)(struct e1000_hw *);
|
||||||
s32 (*get_cfg_done)(struct e1000_hw *hw);
|
s32 (*get_cfg_done)(struct e1000_hw *hw);
|
||||||
@ -466,6 +478,7 @@ struct e1000_mbx_info {
|
|||||||
|
|
||||||
struct e1000_dev_spec_82575 {
|
struct e1000_dev_spec_82575 {
|
||||||
bool sgmii_active;
|
bool sgmii_active;
|
||||||
|
bool global_device_reset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct e1000_hw {
|
struct e1000_hw {
|
||||||
|
@ -136,7 +136,7 @@ out:
|
|||||||
* Reads the MDI control regsiter in the PHY at offset and stores the
|
* Reads the MDI control regsiter in the PHY at offset and stores the
|
||||||
* information read to data.
|
* information read to data.
|
||||||
**/
|
**/
|
||||||
static s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
|
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||||
{
|
{
|
||||||
struct e1000_phy_info *phy = &hw->phy;
|
struct e1000_phy_info *phy = &hw->phy;
|
||||||
u32 i, mdic = 0;
|
u32 i, mdic = 0;
|
||||||
@ -194,7 +194,7 @@ out:
|
|||||||
*
|
*
|
||||||
* Writes data to MDI control register in the PHY at offset.
|
* Writes data to MDI control register in the PHY at offset.
|
||||||
**/
|
**/
|
||||||
static s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
|
s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
|
||||||
{
|
{
|
||||||
struct e1000_phy_info *phy = &hw->phy;
|
struct e1000_phy_info *phy = &hw->phy;
|
||||||
u32 i, mdic = 0;
|
u32 i, mdic = 0;
|
||||||
@ -1947,7 +1947,7 @@ s32 igb_phy_init_script_igp3(struct e1000_hw *hw)
|
|||||||
*
|
*
|
||||||
* Polarity is determined based on the PHY specific status register.
|
* Polarity is determined based on the PHY specific status register.
|
||||||
**/
|
**/
|
||||||
s32 igb_check_polarity_82580(struct e1000_hw *hw)
|
static s32 igb_check_polarity_82580(struct e1000_hw *hw)
|
||||||
{
|
{
|
||||||
struct e1000_phy_info *phy = &hw->phy;
|
struct e1000_phy_info *phy = &hw->phy;
|
||||||
s32 ret_val;
|
s32 ret_val;
|
||||||
|
@ -61,10 +61,11 @@ s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
|
|||||||
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
|
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
|
||||||
u32 usec_interval, bool *success);
|
u32 usec_interval, bool *success);
|
||||||
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
|
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
|
||||||
|
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||||
|
s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
|
||||||
s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
|
s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||||
s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
|
s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
|
||||||
s32 igb_copper_link_setup_82580(struct e1000_hw *hw);
|
s32 igb_copper_link_setup_82580(struct e1000_hw *hw);
|
||||||
s32 igb_check_polarity_82580(struct e1000_hw *hw);
|
|
||||||
s32 igb_get_phy_info_82580(struct e1000_hw *hw);
|
s32 igb_get_phy_info_82580(struct e1000_hw *hw);
|
||||||
s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw);
|
s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw);
|
||||||
s32 igb_get_cable_length_82580(struct e1000_hw *hw);
|
s32 igb_get_cable_length_82580(struct e1000_hw *hw);
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
|
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
|
||||||
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
|
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
|
||||||
#define E1000_MDIC 0x00020 /* MDI Control - RW */
|
#define E1000_MDIC 0x00020 /* MDI Control - RW */
|
||||||
|
#define E1000_MDICNFG 0x00E04 /* MDI Config - RW */
|
||||||
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
|
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
|
||||||
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
|
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
|
||||||
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
|
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
|
||||||
|
Loading…
Reference in New Issue
Block a user