Add 2.5G auto negotiation advertisement.

Signed-off-by: Sasha Neftin <sasha.nef...@intel.com>
Signed-off-by: Guinan Sun <guinanx....@intel.com>
---
 drivers/net/e1000/base/e1000_defines.h |  2 ++
 drivers/net/e1000/base/e1000_phy.c     | 33 ++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/net/e1000/base/e1000_defines.h 
b/drivers/net/e1000/base/e1000_defines.h
index 3ef1e4d32..dbc515aef 100644
--- a/drivers/net/e1000/base/e1000_defines.h
+++ b/drivers/net/e1000/base/e1000_defines.h
@@ -331,6 +331,8 @@
 #define ADVERTISE_100_FULL             0x0008
 #define ADVERTISE_1000_HALF            0x0010 /* Not used, just FYI */
 #define ADVERTISE_1000_FULL            0x0020
+#define ADVERTISE_2500_HALF            0x0040 /* NOT used, just FYI */
+#define ADVERTISE_2500_FULL            0x0080
 
 /* 1000/H is not supported, nor spec-compliant. */
 #define E1000_ALL_SPEED_DUPLEX ( \
diff --git a/drivers/net/e1000/base/e1000_phy.c 
b/drivers/net/e1000/base/e1000_phy.c
index f6ee570ac..4e829eaa8 100644
--- a/drivers/net/e1000/base/e1000_phy.c
+++ b/drivers/net/e1000/base/e1000_phy.c
@@ -1450,6 +1450,7 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
        s32 ret_val;
        u16 mii_autoneg_adv_reg;
        u16 mii_1000t_ctrl_reg = 0;
+       u16 aneg_multigbt_an_ctrl = 0;
 
        DEBUGFUNC("e1000_phy_setup_autoneg");
 
@@ -1468,6 +1469,18 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
                        return ret_val;
        }
 
+       if ((phy->autoneg_mask & ADVERTISE_2500_FULL) &&
+           hw->phy.id == I225_I_PHY_ID) {
+       /* Read the MULTI GBT AN Control Register - reg 7.32 */
+               ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
+                                           MMD_DEVADDR_SHIFT) |
+                                           ANEG_MULTIGBT_AN_CTRL,
+                                           &aneg_multigbt_an_ctrl);
+
+               if (ret_val)
+                       return ret_val;
+       }
+
        /* Need to parse both autoneg_advertised and fc and set up
         * the appropriate PHY registers.  First we will parse for
         * autoneg_advertised software override.  Since we can advertise
@@ -1521,6 +1534,18 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
                mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
        }
 
+       /* We do not allow the Phy to advertise 2500 Mb Half Duplex */
+       if (phy->autoneg_advertised & ADVERTISE_2500_HALF)
+               DEBUGOUT("Advertise 2500mb Half duplex request denied!\n");
+
+       /* Do we want to advertise 2500 Mb Full Duplex? */
+       if (phy->autoneg_advertised & ADVERTISE_2500_FULL) {
+               DEBUGOUT("Advertise 2500mb Full duplex\n");
+               aneg_multigbt_an_ctrl |= CR_2500T_FD_CAPS;
+       } else {
+               aneg_multigbt_an_ctrl &= ~CR_2500T_FD_CAPS;
+       }
+
        /* Check for a software override of the flow control settings, and
         * setup the PHY advertisement registers accordingly.  If
         * auto-negotiation is enabled, then software will have to set the
@@ -1585,6 +1610,14 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
                ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL,
                                             mii_1000t_ctrl_reg);
 
+       if ((phy->autoneg_mask & ADVERTISE_2500_FULL) &&
+           hw->phy.id == I225_I_PHY_ID)
+               ret_val = phy->ops.write_reg(hw,
+                                            (STANDARD_AN_REG_MASK <<
+                                            MMD_DEVADDR_SHIFT) |
+                                            ANEG_MULTIGBT_AN_CTRL,
+                                            aneg_multigbt_an_ctrl);
+
        return ret_val;
 }
 
-- 
2.17.1

Reply via email to