#define PHY_SGMII_IF_MODE_1000X 0x0000 #define PHY_SGMII_DEV_ABILITY_FD 0x0020 #define PHY_SGMII_DEV_ABILITY_PS1_PAUSE 0x0080 #define PHY_SGMII_DEV_ABILITY_PS2_ASM_DIR 0x0100 #define PHY_SGMII_DEV_ABILITY_1000X (PHY_SGMII_DEV_ABILITY_FD | PHY_SGMII_DEV_ABILITY_PS1_PAUSE | PHY_SGMII_DEV_ABILITY_PS2_ASM_DIR) static void vsc9959_pcs_init_1000basex(struct phy_device *pcs, unsigned int link_an_mode, const struct phylink_link_state *state) { u16 if_mode = PHY_SGMII_IF_MODE_1000X; u16 val; phy_write(pcs, PHY_SGMII_IF_MODE_1000X, if_mode); phy_write(pcs, MII_ADVERTISE, PHY_SGMII_DEV_ABILITY_1000X); /* Adjust link timer for SGMII - For Serdes 1000BaseX auto-negotiation the timer should be 10 ms. The link_timer register is configured in units of the clock. - When running as 1G SGMII, Serdes clock is 125 MHz, so unit = 1 / (125*10^6 Hz) = 8 ns. 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0 - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so unit = 1 / (312.5*10^6 Hz) = 3.2 ns. 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08. Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, we always set up here a value of 2.5 SGMII. */ /* In the upstream driver I see a different value: 0x1312d0;*/ mdiobus_write(bus, addr, ENETC_PCS_LINK_TIMER2, 0x0007); mdiobus_write(bus, addr, ENETC_PCS_LINK_TIMER1, 0xa120); val = BMCR_SPEED1000 | BMCR_FULLDPLX; if (link_an_mode == MLO_AN_INBAND) val |= BMCR_ANENABLE | BMCR_ANRESTART; phy_write(pcs, MII_BMCR, val); }