--- a/drivers/net/phy/mxl-gpy.c +++ b/drivers/net/phy/mxl-gpy.c @@ -126,6 +126,12 @@ static int gpy_config_init(struct phy_de if (ret < 0) return ret; + /* Disable SGMII auto-negotiation */ + ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, + VSPEC1_SGMII_CTRL_ANEN, 0); + if (ret < 0) + return ret; + return gpy_led_write(phydev); } @@ -151,65 +157,6 @@ static int gpy_probe(struct phy_device * return 0; } -static bool gpy_sgmii_need_reaneg(struct phy_device *phydev) -{ - int fw_ver, fw_type, fw_minor; - size_t i; - - fw_ver = phy_read(phydev, PHY_FWV); - if (fw_ver < 0) - return true; - - fw_type = FIELD_GET(PHY_FWV_TYPE_MASK, fw_ver); - fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, fw_ver); - - for (i = 0; i < ARRAY_SIZE(ver_need_sgmii_reaneg); i++) { - if (fw_type != ver_need_sgmii_reaneg[i].type) - continue; - if (fw_minor < ver_need_sgmii_reaneg[i].minor) - return true; - break; - } - - return false; -} - -static bool gpy_2500basex_chk(struct phy_device *phydev) -{ - int ret; - - ret = phy_read(phydev, PHY_MIISTAT); - if (ret < 0) { - phydev_err(phydev, "Error: MDIO register access failed: %d\n", - ret); - return false; - } - - if (!(ret & PHY_MIISTAT_LS) || - FIELD_GET(PHY_MIISTAT_SPD_MASK, ret) != PHY_MIISTAT_SPD_2500) - return false; - - phydev->speed = SPEED_2500; - phydev->interface = PHY_INTERFACE_MODE_2500BASEX; - phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, - VSPEC1_SGMII_CTRL_ANEN, 0); - return true; -} - -static bool gpy_sgmii_aneg_en(struct phy_device *phydev) -{ - int ret; - - ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL); - if (ret < 0) { - phydev_err(phydev, "Error: MMD register access failed: %d\n", - ret); - return true; - } - - return (ret & VSPEC1_SGMII_CTRL_ANEN) ? true : false; -} - static int gpy_config_aneg(struct phy_device *phydev) { bool changed = false; @@ -248,53 +195,11 @@ static int gpy_config_aneg(struct phy_de phydev->interface == PHY_INTERFACE_MODE_INTERNAL) return 0; - /* No need to trigger re-ANEG if link speed is 2.5G or SGMII ANEG is - * disabled. - */ - if (!gpy_sgmii_need_reaneg(phydev) || gpy_2500basex_chk(phydev) || - !gpy_sgmii_aneg_en(phydev)) - return 0; - - /* There is a design constraint in GPY2xx device where SGMII AN is - * only triggered when there is change of speed. If, PHY link - * partner`s speed is still same even after PHY TPI is down and up - * again, SGMII AN is not triggered and hence no new in-band message - * from GPY to MAC side SGMII. - * This could cause an issue during power up, when PHY is up prior to - * MAC. At this condition, once MAC side SGMII is up, MAC side SGMII - * wouldn`t receive new in-band message from GPY with correct link - * status, speed and duplex info. - * - * 1) If PHY is already up and TPI link status is still down (such as - * hard reboot), TPI link status is polled for 4 seconds before - * retriggerring SGMII AN. - * 2) If PHY is already up and TPI link status is also up (such as soft - * reboot), polling of TPI link status is not needed and SGMII AN is - * immediately retriggered. - * 3) Other conditions such as PHY is down, speed change etc, skip - * retriggering SGMII AN. Note: in case of speed change, GPY FW will - * initiate SGMII AN. - */ - - if (phydev->state != PHY_UP) - return 0; - - ret = phy_read_poll_timeout(phydev, MII_BMSR, ret, ret & BMSR_LSTATUS, - 20000, 4000000, false); - if (ret == -ETIMEDOUT) - return 0; - else if (ret < 0) - return ret; - - /* Trigger SGMII AN. */ - return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, - VSPEC1_SGMII_CTRL_ANRS, VSPEC1_SGMII_CTRL_ANRS); + return 0; } static void gpy_update_interface(struct phy_device *phydev) { - int ret; - /* Interface mode is fixed for USXGMII and integrated PHY */ if (phydev->interface == PHY_INTERFACE_MODE_USXGMII || phydev->interface == PHY_INTERFACE_MODE_INTERNAL) @@ -306,29 +211,11 @@ static void gpy_update_interface(struct switch (phydev->speed) { case SPEED_2500: phydev->interface = PHY_INTERFACE_MODE_2500BASEX; - ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, - VSPEC1_SGMII_CTRL_ANEN, 0); - if (ret < 0) - phydev_err(phydev, - "Error: Disable of SGMII ANEG failed: %d\n", - ret); break; case SPEED_1000: case SPEED_100: case SPEED_10: phydev->interface = PHY_INTERFACE_MODE_SGMII; - if (gpy_sgmii_aneg_en(phydev)) - break; - /* Enable and restart SGMII ANEG for 10/100/1000Mbps link speed - * if ANEG is disabled (in 2500-BaseX mode). - */ - ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, - VSPEC1_SGMII_ANEN_ANRS, - VSPEC1_SGMII_ANEN_ANRS); - if (ret < 0) - phydev_err(phydev, - "Error: Enable of SGMII ANEG failed: %d\n", - ret); break; } }