OpenWrt – Rev 1

Subversion Repositories:
Rev:
--- 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");
@@ -267,6 +271,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)
@@ -393,7 +418,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,
@@ -412,7 +437,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,
@@ -430,8 +455,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,
@@ -465,9 +490,9 @@ module_init(atheros_init);
 module_exit(atheros_exit);
 
 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 },
        { }
 };