static s32 igb_reset_mdicnfg_82580(struct e1000_hw *hw) { s32 ret_val = 0; u32 mdicnfg; u16 nvm_data = 0; if (hw->mac.type != e1000_82580) goto out; if (!igb_sgmii_active_82575(hw)) goto out; ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A + NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1, &nvm_data); if (ret_val) { hw_dbg("NVM Read Error\n"); goto out; } mdicnfg = rd32(E1000_MDICNFG); if (nvm_data & NVM_WORD24_EXT_MDIO) mdicnfg |= E1000_MDICNFG_EXT_MDIO; if (nvm_data & NVM_WORD24_COM_MDIO) mdicnfg |= E1000_MDICNFG_COM_MDIO; wr32(E1000_MDICNFG, mdicnfg); out: return ret_val; }
/** * igb_clear_hw_cntrs_82575 - Clear device specific hardware counters * @hw: pointer to the HW structure * * Clears the hardware counters by reading the counter registers. **/ static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw) { igb_clear_hw_cntrs_base(hw); rd32(E1000_PRC64); rd32(E1000_PRC127); rd32(E1000_PRC255); rd32(E1000_PRC511); rd32(E1000_PRC1023); rd32(E1000_PRC1522); rd32(E1000_PTC64); rd32(E1000_PTC127); rd32(E1000_PTC255); rd32(E1000_PTC511); rd32(E1000_PTC1023); rd32(E1000_PTC1522); rd32(E1000_ALGNERRC); rd32(E1000_RXERRC); rd32(E1000_TNCRS); rd32(E1000_CEXTERR); rd32(E1000_TSCTC); rd32(E1000_TSCTFC); rd32(E1000_MGTPRC); rd32(E1000_MGTPDC); rd32(E1000_MGTPTC); rd32(E1000_IAC); rd32(E1000_ICRXOC); rd32(E1000_ICRXPTC); rd32(E1000_ICRXATC); rd32(E1000_ICTXPTC); rd32(E1000_ICTXATC); rd32(E1000_ICTXQEC); rd32(E1000_ICTXQMTC); rd32(E1000_ICRXDMTC); rd32(E1000_CBTMPC); rd32(E1000_HTDPMC); rd32(E1000_CBRMPC); rd32(E1000_RPTHC); rd32(E1000_HGPTC); rd32(E1000_HTCBDPC); rd32(E1000_HGORCL); rd32(E1000_HGORCH); rd32(E1000_HGOTCL); rd32(E1000_HGOTCH); rd32(E1000_LENERRS); /* This register should not be read in copper configurations */ if (hw->phy.media_type == e1000_media_type_internal_serdes || igb_sgmii_active_82575(hw)) rd32(E1000_SCVPC); }
static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; ctrl = rd32(E1000_CTRL); ctrl |= E1000_CTRL_SLU; ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); wr32(E1000_CTRL, ctrl); ret_val = igb_setup_serdes_link_82575(hw); if (ret_val) goto out; if (igb_sgmii_active_82575(hw) && !hw->phy.reset_disable) { msleep(300); ret_val = hw->phy.ops.reset(hw); if (ret_val) { hw_dbg("Error resetting the PHY.\n"); goto out; } } switch (hw->phy.type) { case e1000_phy_m88: if (hw->phy.id == I347AT4_E_PHY_ID || hw->phy.id == M88E1112_E_PHY_ID) ret_val = igb_copper_link_setup_m88_gen2(hw); else ret_val = igb_copper_link_setup_m88(hw); break; case e1000_phy_igp_3: ret_val = igb_copper_link_setup_igp(hw); break; case e1000_phy_82580: ret_val = igb_copper_link_setup_82580(hw); break; default: ret_val = -E1000_ERR_PHY; break; } if (ret_val) goto out; ret_val = igb_setup_copper_link(hw); out: return ret_val; }
/** * igb_setup_copper_link_82575 - Configure copper link settings * @hw: pointer to the HW structure * * Configures the link for auto-neg or forced speed and duplex. Then we check * for link, once link is established calls to configure collision distance * and flow control are called. **/ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; ctrl = rd32(E1000_CTRL); ctrl |= E1000_CTRL_SLU; ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); wr32(E1000_CTRL, ctrl); ret_val = igb_setup_serdes_link_82575(hw); if (ret_val) goto out; 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); if (ret_val) { hw_dbg("Error resetting the PHY.\n"); goto out; } } switch (hw->phy.type) { case e1000_phy_m88: ret_val = igb_copper_link_setup_m88(hw); break; case e1000_phy_igp_3: ret_val = igb_copper_link_setup_igp(hw); break; case e1000_phy_82580: ret_val = igb_copper_link_setup_82580(hw); break; default: ret_val = -E1000_ERR_PHY; break; } if (ret_val) goto out; ret_val = igb_setup_copper_link(hw); out: return ret_val; }
/** * igb_shutdown_serdes_link_82575 - Remove link during power down * @hw: pointer to the HW structure * * In the case of fiber serdes, shut down optics and PCS on driver unload * when management pass thru is not enabled. **/ void igb_shutdown_serdes_link_82575(struct e1000_hw *hw) { u32 reg; u16 eeprom_data = 0; if (hw->phy.media_type != e1000_media_type_internal_serdes || igb_sgmii_active_82575(hw)) return; if (hw->bus.func == E1000_FUNC_0) 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) hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); /* * If APM is not enabled in the EEPROM and management interface is * not enabled, then power down. */ if (!(eeprom_data & E1000_NVM_APME_82575) && !igb_enable_mng_pass_thru(hw)) { /* Disable PCS to turn off link */ reg = rd32(E1000_PCS_CFG0); reg &= ~E1000_PCS_CFG_PCS_EN; wr32(E1000_PCS_CFG0, reg); /* shutdown the laser */ reg = rd32(E1000_CTRL_EXT); reg |= E1000_CTRL_EXT_SDP3_DATA; wr32(E1000_CTRL_EXT, reg); /* flush the write to verify completion */ wrfl(); msleep(1); } return; }
/** * igb_power_up_serdes_link_82575 - Power up the serdes link after shutdown * @hw: pointer to the HW structure **/ void igb_power_up_serdes_link_82575(struct e1000_hw *hw) { u32 reg; if ((hw->phy.media_type != e1000_media_type_internal_serdes) && !igb_sgmii_active_82575(hw)) return; /* Enable PCS to turn on link */ reg = rd32(E1000_PCS_CFG0); reg |= E1000_PCS_CFG_PCS_EN; wr32(E1000_PCS_CFG0, reg); /* Power up the laser */ reg = rd32(E1000_CTRL_EXT); reg &= ~E1000_CTRL_EXT_SDP3_DATA; wr32(E1000_CTRL_EXT, reg); /* flush the write to verify completion */ wrfl(); msleep(1); }
void igb_power_up_serdes_link_82575(struct e1000_hw *hw) { u32 reg; if ((hw->phy.media_type != e1000_media_type_internal_serdes) && !igb_sgmii_active_82575(hw)) return; reg = rd32(E1000_PCS_CFG0); reg |= E1000_PCS_CFG_PCS_EN; wr32(E1000_PCS_CFG0, reg); reg = rd32(E1000_CTRL_EXT); reg &= ~E1000_CTRL_EXT_SDP3_DATA; wr32(E1000_CTRL_EXT, reg); wrfl(); msleep(1); }
/** * igb_shutdown_serdes_link_82575 - Remove link during power down * @hw: pointer to the HW structure * * In the case of fiber serdes, shut down optics and PCS on driver unload * when management pass thru is not enabled. **/ void igb_shutdown_serdes_link_82575(struct e1000_hw *hw) { u32 reg; if (hw->phy.media_type != e1000_media_type_internal_serdes && igb_sgmii_active_82575(hw)) return; if (!igb_enable_mng_pass_thru(hw)) { /* Disable PCS to turn off link */ reg = rd32(E1000_PCS_CFG0); reg &= ~E1000_PCS_CFG_PCS_EN; wr32(E1000_PCS_CFG0, reg); /* shutdown the laser */ reg = rd32(E1000_CTRL_EXT); reg |= E1000_CTRL_EXT_SDP3_DATA; wr32(E1000_CTRL_EXT, reg); /* flush the write to verify completion */ wrfl(); msleep(1); } }
void igb_shutdown_serdes_link_82575(struct e1000_hw *hw) { u32 reg; if (hw->phy.media_type != e1000_media_type_internal_serdes && igb_sgmii_active_82575(hw)) return; if (!igb_enable_mng_pass_thru(hw)) { reg = rd32(E1000_PCS_CFG0); reg &= ~E1000_PCS_CFG_PCS_EN; wr32(E1000_PCS_CFG0, reg); reg = rd32(E1000_CTRL_EXT); reg |= E1000_CTRL_EXT_SDP3_DATA; wr32(E1000_CTRL_EXT, reg); wrfl(); msleep(1); } }
static s32 igb_get_invariants_82575(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_mac_info *mac = &hw->mac; struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575; u32 eecd; s32 ret_val; u16 size; u32 ctrl_ext = 0; switch (hw->device_id) { case E1000_DEV_ID_82575EB_COPPER: case E1000_DEV_ID_82575EB_FIBER_SERDES: case E1000_DEV_ID_82575GB_QUAD_COPPER: mac->type = e1000_82575; break; case E1000_DEV_ID_82576: case E1000_DEV_ID_82576_NS: case E1000_DEV_ID_82576_NS_SERDES: case E1000_DEV_ID_82576_FIBER: case E1000_DEV_ID_82576_SERDES: case E1000_DEV_ID_82576_QUAD_COPPER: case E1000_DEV_ID_82576_SERDES_QUAD: mac->type = e1000_82576; 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: return -E1000_ERR_MAC_INIT; break; } /* Set media type */ /* * The 82575 uses bits 22:23 for link mode. The mode can be changed * based on the EEPROM. We cannot rely upon device ID. There * is no distinguishable difference between fiber and internal * SerDes mode on the 82575. There can be an external PHY attached * on the SGMII interface. For this, we'll set sgmii_active to true. */ phy->media_type = e1000_media_type_copper; dev_spec->sgmii_active = false; ctrl_ext = rd32(E1000_CTRL_EXT); switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) { case E1000_CTRL_EXT_LINK_MODE_SGMII: dev_spec->sgmii_active = true; ctrl_ext |= E1000_CTRL_I2C_ENA; break; case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES: hw->phy.media_type = e1000_media_type_internal_serdes; ctrl_ext |= E1000_CTRL_I2C_ENA; break; default: ctrl_ext &= ~E1000_CTRL_I2C_ENA; break; } 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 */ mac->mta_reg_count = 128; /* Set rar entry count */ 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; /* 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 */ mac->asf_firmware_present = true; /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = (rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK) ? true : false; /* physical interface link setup */ mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) ? igb_setup_copper_link_82575 : igb_setup_serdes_link_82575; /* NVM initialization */ eecd = rd32(E1000_EECD); nvm->opcode_bits = 8; nvm->delay_usec = 1; switch (nvm->override) { case e1000_nvm_override_spi_large: nvm->page_size = 32; nvm->address_bits = 16; break; case e1000_nvm_override_spi_small: nvm->page_size = 8; nvm->address_bits = 8; break; default: nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; break; } nvm->type = e1000_nvm_eeprom_spi; size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> E1000_EECD_SIZE_EX_SHIFT); /* * Added to a constant, "size" becomes the left-shift value * for setting word_size. */ size += NVM_WORD_SIZE_BASE_SHIFT; /* EEPROM access above 16k is unsupported */ if (size > 14) size = 14; nvm->word_size = 1 << size; /* if 82576 then initialize mailbox parameters */ if (mac->type == e1000_82576) igb_init_mbx_params_pf(hw); /* setup PHY parameters */ if (phy->media_type != e1000_media_type_copper) { phy->type = e1000_phy_none; return 0; } phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; phy->reset_delay_us = 100; /* PHY function pointers */ if (igb_sgmii_active_82575(hw)) { phy->ops.reset = igb_phy_hw_reset_sgmii_82575; phy->ops.read_reg = igb_read_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 { phy->ops.reset = igb_phy_hw_reset; phy->ops.read_reg = igb_read_phy_reg_igp; phy->ops.write_reg = igb_write_phy_reg_igp; } /* set lan id */ hw->bus.func = (rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT; /* Set phy->phy_addr and phy->id. */ ret_val = igb_get_phy_id_82575(hw); if (ret_val) return ret_val; /* Verify phy id and set remaining function pointers */ switch (phy->id) { case M88E1111_I_PHY_ID: phy->type = e1000_phy_m88; phy->ops.get_phy_info = igb_get_phy_info_m88; phy->ops.get_cable_length = igb_get_cable_length_m88; phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; break; case IGP03E1000_E_PHY_ID: phy->type = e1000_phy_igp_3; phy->ops.get_phy_info = igb_get_phy_info_igp; phy->ops.get_cable_length = igb_get_cable_length_igp_2; phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_igp; phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82575; phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state; 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: return -E1000_ERR_PHY; } return 0; }
/** * igb_get_phy_id_82575 - Retrieve PHY addr and id * @hw: pointer to the HW structure * * Retrieves the PHY address and ID for both PHY's which do and do not use * sgmi interface. **/ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = 0; u16 phy_id; u32 ctrl_ext; /* * 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 * and phy->id are set correctly. */ if (!(igb_sgmii_active_82575(hw))) { phy->addr = 1; ret_val = igb_get_phy_id(hw); goto out; } /* Power on sgmii phy if it is disabled */ ctrl_ext = rd32(E1000_CTRL_EXT); wr32(E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); wrfl(); msleep(300); /* * The address field in the I2CCMD register is 3 bits and 0 is invalid. * Therefore, we need to test 1-7 */ for (phy->addr = 1; phy->addr < 8; phy->addr++) { ret_val = igb_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id); if (ret_val == 0) { hw_dbg("Vendor ID 0x%08X read at address %u\n", phy_id, phy->addr); /* * At the time of this writing, The M88 part is * the only supported SGMII PHY product. */ if (phy_id == M88_VENDOR) break; } else { hw_dbg("PHY address %u was unreadable\n", phy->addr); } } /* A valid PHY type couldn't be found. */ if (phy->addr == 8) { phy->addr = 0; ret_val = -E1000_ERR_PHY; goto out; } else { ret_val = igb_get_phy_id(hw); } /* restore previous sfp cage power state */ wr32(E1000_CTRL_EXT, ctrl_ext); out: return ret_val; }
/** * igb_setup_serdes_link_82575 - Setup link for serdes * @hw: pointer to the HW structure * * Configure the physical coding sub-layer (PCS) link. The PCS link is * used on copper connections where the serialized gigabit media independent * interface (sgmii), or serdes fiber is being used. Configures the link * for auto-negotiation or forces speed/duplex. **/ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) { u32 ctrl_ext, ctrl_reg, reg; bool pcs_autoneg; if ((hw->phy.media_type != e1000_media_type_internal_serdes) && !igb_sgmii_active_82575(hw)) return 0; /* * On the 82575, SerDes loopback mode persists until it is * explicitly turned off or a power cycle is performed. A read to * the register does not indicate its status. Therefore, we ensure * loopback mode is disabled during initialization. */ wr32(E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK); /* power on the sfp cage if present */ ctrl_ext = rd32(E1000_CTRL_EXT); ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA; wr32(E1000_CTRL_EXT, ctrl_ext); ctrl_reg = rd32(E1000_CTRL); ctrl_reg |= E1000_CTRL_SLU; if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) { /* set both sw defined pins */ ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1; /* Set switch control to serdes energy detect */ reg = rd32(E1000_CONNSW); reg |= E1000_CONNSW_ENRGSRC; wr32(E1000_CONNSW, reg); } reg = rd32(E1000_PCS_LCTL); /* default pcs_autoneg to the same setting as mac autoneg */ pcs_autoneg = hw->mac.autoneg; 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); 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 | 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); /* * New SerDes mode allows for forcing speed or autonegotiating speed * at 1gb. Autoneg should be default set by most drivers. This is the * mode that will be compatible with older link partners and switches. * However, both are supported by the hardware and some drivers/tools. */ reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP | E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); /* * We force flow control to prevent the CTRL register values from being * overwritten by the autonegotiated flow control values */ reg |= E1000_PCS_LCTL_FORCE_FCTRL; if (pcs_autoneg) { /* Set PCS register for autoneg */ reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */ E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */ hw_dbg("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg); } else { /* Set PCS register for forced link */ reg |= E1000_PCS_LCTL_FSD; /* Force Speed */ hw_dbg("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); } wr32(E1000_PCS_LCTL, reg); if (!igb_sgmii_active_82575(hw)) igb_force_mac_fc(hw); return 0; }
static s32 igb_get_invariants_82575(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_mac_info *mac = &hw->mac; struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575; u32 eecd; s32 ret_val; u16 size; u32 ctrl_ext = 0; switch (hw->device_id) { case E1000_DEV_ID_82575EB_COPPER: case E1000_DEV_ID_82575EB_FIBER_SERDES: case E1000_DEV_ID_82575GB_QUAD_COPPER: mac->type = e1000_82575; break; case E1000_DEV_ID_82576: case E1000_DEV_ID_82576_NS: case E1000_DEV_ID_82576_NS_SERDES: case E1000_DEV_ID_82576_FIBER: case E1000_DEV_ID_82576_SERDES: case E1000_DEV_ID_82576_QUAD_COPPER: case E1000_DEV_ID_82576_QUAD_COPPER_ET2: case E1000_DEV_ID_82576_SERDES_QUAD: mac->type = e1000_82576; break; case E1000_DEV_ID_82580_COPPER: case E1000_DEV_ID_82580_FIBER: case E1000_DEV_ID_82580_QUAD_FIBER: case E1000_DEV_ID_82580_SERDES: case E1000_DEV_ID_82580_SGMII: case E1000_DEV_ID_82580_COPPER_DUAL: case E1000_DEV_ID_DH89XXCC_SGMII: case E1000_DEV_ID_DH89XXCC_SERDES: case E1000_DEV_ID_DH89XXCC_BACKPLANE: case E1000_DEV_ID_DH89XXCC_SFP: mac->type = e1000_82580; break; case E1000_DEV_ID_I350_COPPER: case E1000_DEV_ID_I350_FIBER: case E1000_DEV_ID_I350_SERDES: case E1000_DEV_ID_I350_SGMII: mac->type = e1000_i350; break; default: return -E1000_ERR_MAC_INIT; break; } phy->media_type = e1000_media_type_copper; dev_spec->sgmii_active = false; ctrl_ext = rd32(E1000_CTRL_EXT); switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) { case E1000_CTRL_EXT_LINK_MODE_SGMII: dev_spec->sgmii_active = true; break; case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES: hw->phy.media_type = e1000_media_type_internal_serdes; break; default: break; } mac->mta_reg_count = 128; 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; if (mac->type >= e1000_82580) mac->ops.reset_hw = igb_reset_hw_82580; else mac->ops.reset_hw = igb_reset_hw_82575; mac->asf_firmware_present = true; mac->arc_subsystem_valid = (rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK) ? true : false; if (mac->type == e1000_i350) dev_spec->eee_disable = false; else dev_spec->eee_disable = true; mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) ? igb_setup_copper_link_82575 : igb_setup_serdes_link_82575; eecd = rd32(E1000_EECD); nvm->opcode_bits = 8; nvm->delay_usec = 1; switch (nvm->override) { case e1000_nvm_override_spi_large: nvm->page_size = 32; nvm->address_bits = 16; break; case e1000_nvm_override_spi_small: nvm->page_size = 8; nvm->address_bits = 8; break; default: nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; break; } nvm->type = e1000_nvm_eeprom_spi; size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> E1000_EECD_SIZE_EX_SHIFT); size += NVM_WORD_SIZE_BASE_SHIFT; if ((hw->mac.type == e1000_82576) && (size > 15)) { pr_notice("The NVM size is not valid, defaulting to 32K\n"); size = 15; } nvm->word_size = 1 << size; if (nvm->word_size == (1 << 15)) nvm->page_size = 128; nvm->ops.acquire = igb_acquire_nvm_82575; if (nvm->word_size < (1 << 15)) nvm->ops.read = igb_read_nvm_eerd; else nvm->ops.read = igb_read_nvm_spi; nvm->ops.release = igb_release_nvm_82575; switch (hw->mac.type) { case e1000_82580: nvm->ops.validate = igb_validate_nvm_checksum_82580; nvm->ops.update = igb_update_nvm_checksum_82580; break; case e1000_i350: nvm->ops.validate = igb_validate_nvm_checksum_i350; nvm->ops.update = igb_update_nvm_checksum_i350; break; default: nvm->ops.validate = igb_validate_nvm_checksum; nvm->ops.update = igb_update_nvm_checksum; } nvm->ops.write = igb_write_nvm_spi; switch (mac->type) { case e1000_82576: case e1000_i350: igb_init_mbx_params_pf(hw); break; default: break; } if (phy->media_type != e1000_media_type_copper) { phy->type = e1000_phy_none; return 0; } phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; phy->reset_delay_us = 100; ctrl_ext = rd32(E1000_CTRL_EXT); if (igb_sgmii_active_82575(hw)) { phy->ops.reset = igb_phy_hw_reset_sgmii_82575; ctrl_ext |= E1000_CTRL_I2C_ENA; } else { phy->ops.reset = igb_phy_hw_reset; ctrl_ext &= ~E1000_CTRL_I2C_ENA; } wr32(E1000_CTRL_EXT, ctrl_ext); igb_reset_mdicnfg_82580(hw); if (igb_sgmii_active_82575(hw) && !igb_sgmii_uses_mdio_82575(hw)) { phy->ops.read_reg = igb_read_phy_reg_sgmii_82575; phy->ops.write_reg = igb_write_phy_reg_sgmii_82575; } else if (hw->mac.type >= e1000_82580) { phy->ops.read_reg = igb_read_phy_reg_82580; phy->ops.write_reg = igb_write_phy_reg_82580; } else { phy->ops.read_reg = igb_read_phy_reg_igp; phy->ops.write_reg = igb_write_phy_reg_igp; } hw->bus.func = (rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT; ret_val = igb_get_phy_id_82575(hw); if (ret_val) return ret_val; switch (phy->id) { case I347AT4_E_PHY_ID: case M88E1112_E_PHY_ID: case M88E1111_I_PHY_ID: phy->type = e1000_phy_m88; phy->ops.get_phy_info = igb_get_phy_info_m88; if (phy->id == I347AT4_E_PHY_ID || phy->id == M88E1112_E_PHY_ID) phy->ops.get_cable_length = igb_get_cable_length_m88_gen2; else phy->ops.get_cable_length = igb_get_cable_length_m88; phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; break; case IGP03E1000_E_PHY_ID: phy->type = e1000_phy_igp_3; phy->ops.get_phy_info = igb_get_phy_info_igp; phy->ops.get_cable_length = igb_get_cable_length_igp_2; phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_igp; phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82575; phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state; break; case I82580_I_PHY_ID: case I350_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: return -E1000_ERR_PHY; } return 0; }
static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) { u32 ctrl_ext, ctrl_reg, reg; bool pcs_autoneg; s32 ret_val = E1000_SUCCESS; u16 data; if ((hw->phy.media_type != e1000_media_type_internal_serdes) && !igb_sgmii_active_82575(hw)) return ret_val; wr32(E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK); ctrl_ext = rd32(E1000_CTRL_EXT); ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA; wr32(E1000_CTRL_EXT, ctrl_ext); ctrl_reg = rd32(E1000_CTRL); ctrl_reg |= E1000_CTRL_SLU; if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) { ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1; reg = rd32(E1000_CONNSW); reg |= E1000_CONNSW_ENRGSRC; wr32(E1000_CONNSW, reg); } reg = rd32(E1000_PCS_LCTL); pcs_autoneg = hw->mac.autoneg; switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) { case E1000_CTRL_EXT_LINK_MODE_SGMII: pcs_autoneg = true; reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT); break; case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: pcs_autoneg = false; default: if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) { ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data); if (ret_val) { printk(KERN_DEBUG "NVM Read Error\n\n"); return ret_val; } if (data & E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT) pcs_autoneg = false; } ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD | E1000_CTRL_FD | E1000_CTRL_FRCDPX; reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL; break; } wr32(E1000_CTRL, ctrl_reg); reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP | E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); /* * We force flow control to prevent the CTRL register values from being * overwritten by the autonegotiated flow control values */ reg |= E1000_PCS_LCTL_FORCE_FCTRL; if (pcs_autoneg) { reg |= E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_AN_RESTART; hw_dbg("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg); } else { reg |= E1000_PCS_LCTL_FSD; hw_dbg("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); } wr32(E1000_PCS_LCTL, reg); if (!igb_sgmii_active_82575(hw)) igb_force_mac_fc(hw); return ret_val; }
static s32 igb_get_phy_id_82575(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = 0; u16 phy_id; u32 ctrl_ext; u32 mdic; if (!(igb_sgmii_active_82575(hw))) { phy->addr = 1; ret_val = igb_get_phy_id(hw); goto out; } if (igb_sgmii_uses_mdio_82575(hw)) { switch (hw->mac.type) { case e1000_82575: case e1000_82576: mdic = rd32(E1000_MDIC); mdic &= E1000_MDIC_PHY_MASK; phy->addr = mdic >> E1000_MDIC_PHY_SHIFT; break; case e1000_82580: case e1000_i350: mdic = rd32(E1000_MDICNFG); mdic &= E1000_MDICNFG_PHY_MASK; phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT; break; default: ret_val = -E1000_ERR_PHY; goto out; break; } ret_val = igb_get_phy_id(hw); goto out; } ctrl_ext = rd32(E1000_CTRL_EXT); wr32(E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); wrfl(); msleep(300); for (phy->addr = 1; phy->addr < 8; phy->addr++) { ret_val = igb_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id); if (ret_val == 0) { hw_dbg("Vendor ID 0x%08X read at address %u\n", phy_id, phy->addr); if (phy_id == M88_VENDOR) break; } else { hw_dbg("PHY address %u was unreadable\n", phy->addr); } } if (phy->addr == 8) { phy->addr = 0; ret_val = -E1000_ERR_PHY; goto out; } else { ret_val = igb_get_phy_id(hw); } wr32(E1000_CTRL_EXT, ctrl_ext); out: return ret_val; }