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. */