Print this page
4431 igb support for I354
4616 igb has uninitialized kstats
*** 142,151 ****
--- 142,152 ----
reg = E1000_READ_REG(hw, E1000_MDIC);
ext_mdio = !!(reg & E1000_MDIC_DEST);
break;
case e1000_82580:
case e1000_i350:
+ case e1000_i354:
case e1000_i210:
case e1000_i211:
reg = E1000_READ_REG(hw, E1000_MDICNFG);
ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO);
break;
*** 205,214 ****
--- 206,216 ----
phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
} else {
switch (hw->mac.type) {
case e1000_82580:
case e1000_i350:
+ case e1000_i354:
phy->ops.read_reg = e1000_read_phy_reg_82580;
phy->ops.write_reg = e1000_write_phy_reg_82580;
break;
case e1000_i210:
case e1000_i211:
*** 224,247 ****
/* Set phy->phy_addr and phy->id. */
ret_val = e1000_get_phy_id_82575(hw);
/* Verify phy id and set remaining function pointers */
switch (phy->id) {
case I347AT4_E_PHY_ID:
case M88E1112_E_PHY_ID:
case M88E1340M_E_PHY_ID:
case M88E1111_I_PHY_ID:
phy->type = e1000_phy_m88;
phy->ops.check_polarity = e1000_check_polarity_m88;
phy->ops.get_info = e1000_get_phy_info_m88;
! if (phy->id == I347AT4_E_PHY_ID ||
! phy->id == M88E1112_E_PHY_ID ||
! phy->id == M88E1340M_E_PHY_ID)
phy->ops.get_cable_length =
e1000_get_cable_length_m88_gen2;
! else
phy->ops.get_cable_length = e1000_get_cable_length_m88;
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
break;
case IGP03E1000_E_PHY_ID:
case IGP04E1000_E_PHY_ID:
phy->type = e1000_phy_igp_3;
--- 226,255 ----
/* Set phy->phy_addr and phy->id. */
ret_val = e1000_get_phy_id_82575(hw);
/* Verify phy id and set remaining function pointers */
switch (phy->id) {
+ case M88E1543_E_PHY_ID:
+ case M88E1512_E_PHY_ID:
case I347AT4_E_PHY_ID:
case M88E1112_E_PHY_ID:
case M88E1340M_E_PHY_ID:
case M88E1111_I_PHY_ID:
phy->type = e1000_phy_m88;
phy->ops.check_polarity = e1000_check_polarity_m88;
phy->ops.get_info = e1000_get_phy_info_m88;
! switch (phy->id) {
! case I347AT4_E_PHY_ID:
! case M88E1112_E_PHY_ID:
! case M88E1340M_E_PHY_ID:
! case M88E1543_E_PHY_ID:
! case M88E1512_E_PHY_ID:
phy->ops.get_cable_length =
e1000_get_cable_length_m88_gen2;
! default:
phy->ops.get_cable_length = e1000_get_cable_length_m88;
+ }
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
break;
case IGP03E1000_E_PHY_ID:
case IGP04E1000_E_PHY_ID:
phy->type = e1000_phy_igp_3;
*** 353,362 ****
--- 361,371 ----
case e1000_82580:
nvm->ops.validate = e1000_validate_nvm_checksum_82580;
nvm->ops.update = e1000_update_nvm_checksum_82580;
break;
case e1000_i350:
+ case e1000_i354:
nvm->ops.validate = e1000_validate_nvm_checksum_i350;
nvm->ops.update = e1000_update_nvm_checksum_i350;
break;
default:
break;
*** 386,399 ****
mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
if (mac->type == e1000_82576)
mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
if (mac->type == e1000_82580)
mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
! if (mac->type == e1000_i350)
mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
! /* Enable EEE default settings for EEE supported devices */
if (mac->type >= e1000_i350)
dev_spec->eee_disable = TRUE;
/* Allow a single clear of the SW semaphore on I210 and newer */
if (mac->type >= e1000_i210)
--- 395,408 ----
mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
if (mac->type == e1000_82576)
mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
if (mac->type == e1000_82580)
mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
! if (mac->type == e1000_i350 || mac->type == e1000_i354)
mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
! /* Disable EEE default settings for EEE supported devices */
if (mac->type >= e1000_i350)
dev_spec->eee_disable = TRUE;
/* Allow a single clear of the SW semaphore on I210 and newer */
if (mac->type >= e1000_i210)
*** 434,444 ****
mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
/* configure collision distance */
mac->ops.config_collision_dist = e1000_config_collision_dist_82575;
/* multicast address update */
mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
! if (mac->type == e1000_i350) {
/* writing VFTA */
mac->ops.write_vfta = e1000_write_vfta_i350;
/* clearing VFTA */
mac->ops.clear_vfta = e1000_clear_vfta_i350;
} else {
--- 443,453 ----
mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
/* configure collision distance */
mac->ops.config_collision_dist = e1000_config_collision_dist_82575;
/* multicast address update */
mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
! if (mac->type == e1000_i350 || mac->type == e1000_i354) {
/* writing VFTA */
mac->ops.write_vfta = e1000_write_vfta_i350;
/* clearing VFTA */
mac->ops.clear_vfta = e1000_clear_vfta_i350;
} else {
*** 620,629 ****
--- 629,642 ----
u32 ctrl_ext;
u32 mdic;
DEBUGFUNC("e1000_get_phy_id_82575");
+ /* some i354 devices need an extra read for phy id */
+ if (hw->mac.type == e1000_i354)
+ e1000_get_phy_id(hw);
+
/*
* For SGMII PHYs, we try the list of possible addresses until
* we find one that works. For non-SGMII PHYs
* (e.g. integrated copper PHYs), an address of 1 should
* work. The result of this function should mean phy->phy_addr
*** 643,652 ****
--- 656,666 ----
mdic &= E1000_MDIC_PHY_MASK;
phy->addr = mdic >> E1000_MDIC_PHY_SHIFT;
break;
case e1000_82580:
case e1000_i350:
+ case e1000_i354:
case e1000_i210:
case e1000_i211:
mdic = E1000_READ_REG(hw, E1000_MDICNFG);
mdic &= E1000_MDICNFG_PHY_MASK;
phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT;
*** 1213,1222 ****
--- 1227,1237 ----
static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
u16 *speed, u16 *duplex)
{
struct e1000_mac_info *mac = &hw->mac;
u32 pcs;
+ u32 status;
DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
/*
* Read the PCS Status register for link state. For non-copper mode,
*** 1243,1252 ****
--- 1258,1279 ----
if (pcs & E1000_PCS_LSTS_DUPLEX_FULL)
*duplex = FULL_DUPLEX;
else
*duplex = HALF_DUPLEX;
+ /* Check if it is an I354 2.5Gb backplane connection. */
+ if (mac->type == e1000_i354) {
+ status = E1000_READ_REG(hw, E1000_STATUS);
+ if ((status & E1000_STATUS_2P5_SKU) &&
+ !(status & E1000_STATUS_2P5_SKU_OVER)) {
+ *speed = SPEED_2500;
+ *duplex = FULL_DUPLEX;
+ DEBUGOUT("2500 Mbs, ");
+ DEBUGOUT("Full Duplex\n");
+ }
+ }
+
} else {
mac->serdes_has_link = FALSE;
*speed = 0;
*duplex = 0;
}
*** 1428,1442 ****
ctrl = E1000_READ_REG(hw, E1000_CTRL);
ctrl |= E1000_CTRL_SLU;
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
! /* Clear Go Link Disconnect bit */
! if (hw->mac.type >= e1000_82580) {
phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
phpm_reg &= ~E1000_82580_PM_GO_LINKD;
E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg);
}
ret_val = e1000_setup_serdes_link_82575(hw);
if (ret_val)
goto out;
--- 1455,1476 ----
ctrl = E1000_READ_REG(hw, E1000_CTRL);
ctrl |= E1000_CTRL_SLU;
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
! /* 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 = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
phpm_reg &= ~E1000_82580_PM_GO_LINKD;
E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg);
+ break;
+ default:
+ break;
}
ret_val = e1000_setup_serdes_link_82575(hw);
if (ret_val)
goto out;
*** 2130,2175 ****
*
* enables/disables L2 switch anti-spoofing functionality.
**/
void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
{
! u32 dtxswc;
switch (hw->mac.type) {
case e1000_82576:
! dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
! if (enable) {
! dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
! E1000_DTXSWC_VLAN_SPOOF_MASK);
! /* The PF can spoof - it has to in order to
! * support emulation mode NICs */
! dtxswc ^= (1 << pf | 1 << (pf +
! E1000_DTXSWC_VLAN_SPOOF_SHIFT));
! } else {
! dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
! E1000_DTXSWC_VLAN_SPOOF_MASK);
! }
! E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
break;
case e1000_i350:
! dtxswc = E1000_READ_REG(hw, E1000_TXSWC);
if (enable) {
! dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
E1000_DTXSWC_VLAN_SPOOF_MASK);
/* The PF can spoof - it has to in order to
* support emulation mode NICs
*/
! dtxswc ^= (1 << pf | 1 << (pf +
! E1000_DTXSWC_VLAN_SPOOF_SHIFT));
} else {
! dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
E1000_DTXSWC_VLAN_SPOOF_MASK);
}
! E1000_WRITE_REG(hw, E1000_TXSWC, dtxswc);
! default:
! break;
! }
}
/**
* e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback
* @hw: pointer to the hardware struct
--- 2164,2199 ----
*
* enables/disables L2 switch anti-spoofing functionality.
**/
void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
{
! u32 reg_val, reg_offset;
switch (hw->mac.type) {
case e1000_82576:
! reg_offset = E1000_DTXSWC;
break;
case e1000_i350:
! case e1000_i354:
! reg_offset = E1000_TXSWC;
! break;
! default:
! return;
! }
! reg_val = E1000_READ_REG(hw, reg_offset);
if (enable) {
! reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK |
E1000_DTXSWC_VLAN_SPOOF_MASK);
/* The PF can spoof - it has to in order to
* support emulation mode NICs
*/
! reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
} else {
! reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
E1000_DTXSWC_VLAN_SPOOF_MASK);
}
! E1000_WRITE_REG(hw, reg_offset, reg_val);
}
/**
* e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback
* @hw: pointer to the hardware struct
*** 2189,2198 ****
--- 2213,2223 ----
else
dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
break;
case e1000_i350:
+ case e1000_i354:
dtxswc = E1000_READ_REG(hw, E1000_TXSWC);
if (enable)
dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
else
dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
*** 2686,2695 ****
--- 2711,2828 ----
E1000_READ_REG(hw, E1000_EEER);
out:
return ret_val;
}
+
+ /**
+ * e1000_set_eee_i354 - Enable/disable EEE support
+ * @hw: pointer to the HW structure
+ *
+ * Enable/disable EEE legacy mode based on setting in dev_spec structure.
+ *
+ **/
+ s32 e1000_set_eee_i354(struct e1000_hw *hw)
+ {
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val = E1000_SUCCESS;
+ u16 phy_data;
+
+ DEBUGFUNC("e1000_set_eee_i354");
+
+ if ((hw->phy.media_type != e1000_media_type_copper) ||
+ ((phy->id != M88E1543_E_PHY_ID) &&
+ (phy->id != M88E1512_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_M88E1543_PAGE_ADDR, 18);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.read_reg(hw, E1000_M88E1543_EEE_CTRL_1,
+ &phy_data);
+ if (ret_val)
+ goto out;
+
+ 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_M88E1543_PAGE_ADDR, 0);
+ if (ret_val)
+ goto out;
+
+ /* Turn on EEE advertisement. */
+ ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
+ E1000_EEE_ADV_DEV_I354,
+ &phy_data);
+ if (ret_val)
+ goto out;
+
+ phy_data |= E1000_EEE_ADV_100_SUPPORTED |
+ E1000_EEE_ADV_1000_SUPPORTED;
+ ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
+ E1000_EEE_ADV_DEV_I354,
+ phy_data);
+ } else {
+ /* Turn off EEE advertisement. */
+ ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
+ E1000_EEE_ADV_DEV_I354,
+ &phy_data);
+ if (ret_val)
+ goto out;
+
+ phy_data &= ~(E1000_EEE_ADV_100_SUPPORTED |
+ E1000_EEE_ADV_1000_SUPPORTED);
+ ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
+ E1000_EEE_ADV_DEV_I354,
+ phy_data);
+ }
+
+ out:
+ return ret_val;
+ }
+
+ /**
+ * e1000_get_eee_status_i354 - Get EEE status
+ * @hw: pointer to the HW structure
+ * @status: EEE status
+ *
+ * Get EEE status by guessing based on whether Tx or Rx LPI indications have
+ * been received.
+ **/
+ s32 e1000_get_eee_status_i354(struct e1000_hw *hw, bool *status)
+ {
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val = E1000_SUCCESS;
+ u16 phy_data;
+
+ DEBUGFUNC("e1000_get_eee_status_i354");
+
+ /* Check if EEE is supported on this device. */
+ if ((hw->phy.media_type != e1000_media_type_copper) ||
+ ((phy->id != M88E1543_E_PHY_ID) &&
+ (phy->id != M88E1512_E_PHY_ID)))
+ goto out;
+
+ ret_val = e1000_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354,
+ E1000_PCS_STATUS_DEV_I354,
+ &phy_data);
+ if (ret_val)
+ goto out;
+
+ *status = phy_data & (E1000_PCS_STATUS_TX_LPI_RCVD |
+ E1000_PCS_STATUS_RX_LPI_RCVD) ? TRUE : FALSE;
+
+ out:
+ return ret_val;
+ }
/* Due to a hw errata, if the host tries to configure the VFTA register
* while performing queries from the BMC or DMA, then the VFTA in some
* cases won't be written.
*/