|
@@ -70,6 +70,35 @@ static const u16 e1000_82580_rxpbs_table[] =
|
|
|
#define E1000_82580_RXPBS_TABLE_SIZE \
|
|
|
(sizeof(e1000_82580_rxpbs_table)/sizeof(u16))
|
|
|
|
|
|
+/**
|
|
|
+ * igb_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO
|
|
|
+ * @hw: pointer to the HW structure
|
|
|
+ *
|
|
|
+ * Called to determine if the I2C pins are being used for I2C or as an
|
|
|
+ * external MDIO interface since the two options are mutually exclusive.
|
|
|
+ **/
|
|
|
+static bool igb_sgmii_uses_mdio_82575(struct e1000_hw *hw)
|
|
|
+{
|
|
|
+ u32 reg = 0;
|
|
|
+ bool ext_mdio = false;
|
|
|
+
|
|
|
+ switch (hw->mac.type) {
|
|
|
+ case e1000_82575:
|
|
|
+ case e1000_82576:
|
|
|
+ reg = rd32(E1000_MDIC);
|
|
|
+ ext_mdio = !!(reg & E1000_MDIC_DEST);
|
|
|
+ break;
|
|
|
+ case e1000_82580:
|
|
|
+ case e1000_i350:
|
|
|
+ reg = rd32(E1000_MDICNFG);
|
|
|
+ ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return ext_mdio;
|
|
|
+}
|
|
|
+
|
|
|
static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
|
|
{
|
|
|
struct e1000_phy_info *phy = &hw->phy;
|
|
@@ -144,13 +173,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
|
|
|
|
|
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 */
|
|
@@ -229,18 +251,20 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
|
|
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;
|
|
|
+ if (igb_sgmii_active_82575(hw))
|
|
|
+ phy->ops.reset = igb_phy_hw_reset_sgmii_82575;
|
|
|
+ else
|
|
|
+ phy->ops.reset = igb_phy_hw_reset;
|
|
|
+
|
|
|
+ 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.reset = igb_phy_hw_reset;
|
|
|
- phy->ops.read_reg = igb_read_phy_reg_82580;
|
|
|
- phy->ops.write_reg = igb_write_phy_reg_82580;
|
|
|
+ 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;
|
|
|
+ phy->ops.read_reg = igb_read_phy_reg_igp;
|
|
|
+ phy->ops.write_reg = igb_write_phy_reg_igp;
|
|
|
}
|
|
|
|
|
|
/* set lan id */
|
|
@@ -400,6 +424,7 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
|
|
|
s32 ret_val = 0;
|
|
|
u16 phy_id;
|
|
|
u32 ctrl_ext;
|
|
|
+ u32 mdic;
|
|
|
|
|
|
/*
|
|
|
* For SGMII PHYs, we try the list of possible addresses until
|
|
@@ -414,6 +439,29 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *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;
|
|
|
+ }
|
|
|
+
|
|
|
/* 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);
|