--- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c @@ -36,6 +36,9 @@ #define AT803X_INER 0x0012 #define AT803X_INER_INIT 0xec00 #define AT803X_INSR 0x0013 +#define AT803X_REG_CHIP_CONFIG 0x1f +#define AT803X_BT_BX_REG_SEL 0x8000 +#define AT803X_SGMII_ANEG_EN 0x1000 #define AT803X_PCS_SMART_EEE_CTRL3 0x805D #define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK 0x3 @@ -49,9 +52,10 @@ #define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05 #define AT803X_DEBUG_RGMII_TX_CLK_DLY BIT(8) -#define ATH8030_PHY_ID 0x004dd076 -#define ATH8031_PHY_ID 0x004dd074 -#define ATH8035_PHY_ID 0x004dd072 +#define AT803X_PHY_ID_MASK 0xffffffef +#define ATH8030_PHY_ID 0x004dd076 +#define ATH8031_PHY_ID 0x004dd074 +#define ATH8035_PHY_ID 0x004dd072 MODULE_DESCRIPTION("Atheros 803x PHY driver"); MODULE_AUTHOR("Matus Ujhelyi"); @@ -268,6 +272,27 @@ static int at803x_config_init(struct phy { struct at803x_platform_data *pdata; int ret; + u32 v; + + if (phydev->drv->phy_id == ATH8031_PHY_ID && + phydev->interface == PHY_INTERFACE_MODE_SGMII) + { + v = phy_read(phydev, AT803X_REG_CHIP_CONFIG); + /* select SGMII/fiber page */ + ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG, + v & ~AT803X_BT_BX_REG_SEL); + if (ret) + return ret; + /* enable SGMII autonegotiation */ + ret = phy_write(phydev, MII_BMCR, AT803X_SGMII_ANEG_EN); + if (ret) + return ret; + /* select copper page */ + ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG, + v | AT803X_BT_BX_REG_SEL); + if (ret) + return ret; + } ret = genphy_config_init(phydev); if (ret < 0) @@ -394,7 +419,7 @@ static struct phy_driver at803x_driver[] /* ATHEROS 8035 */ .phy_id = ATH8035_PHY_ID, .name = "Atheros 8035 ethernet", - .phy_id_mask = 0xffffffef, + .phy_id_mask = AT803X_PHY_ID_MASK, .probe = at803x_probe, .config_init = at803x_config_init, .link_change_notify = at803x_link_change_notify, @@ -415,7 +440,7 @@ static struct phy_driver at803x_driver[] /* ATHEROS 8030 */ .phy_id = ATH8030_PHY_ID, .name = "Atheros 8030 ethernet", - .phy_id_mask = 0xffffffef, + .phy_id_mask = AT803X_PHY_ID_MASK, .probe = at803x_probe, .config_init = at803x_config_init, .link_change_notify = at803x_link_change_notify, @@ -435,8 +460,8 @@ static struct phy_driver at803x_driver[] }, { /* ATHEROS 8031 */ .phy_id = ATH8031_PHY_ID, - .name = "Atheros 8031 ethernet", - .phy_id_mask = 0xffffffef, + .name = "Atheros 8031/8033 ethernet", + .phy_id_mask = AT803X_PHY_ID_MASK, .probe = at803x_probe, .config_init = at803x_config_init, .link_change_notify = at803x_link_change_notify, @@ -458,9 +483,9 @@ static struct phy_driver at803x_driver[] module_phy_driver(at803x_driver); static struct mdio_device_id __maybe_unused atheros_tbl[] = { - { ATH8030_PHY_ID, 0xffffffef }, - { ATH8031_PHY_ID, 0xffffffef }, - { ATH8035_PHY_ID, 0xffffffef }, + { ATH8030_PHY_ID, AT803X_PHY_ID_MASK }, + { ATH8031_PHY_ID, AT803X_PHY_ID_MASK }, + { ATH8035_PHY_ID, AT803X_PHY_ID_MASK }, { } };