117f15d634e6601360435097a6be6389d5e0a6f3
[openwrt.git] / target / linux / generic / patches-3.18 / 735-net-phy-at803x-fix-at8033-sgmii-mode.patch
1 --- a/drivers/net/phy/at803x.c
2 +++ b/drivers/net/phy/at803x.c
3 @@ -36,6 +36,9 @@
4  #define AT803X_INER                            0x0012
5  #define AT803X_INER_INIT                       0xec00
6  #define AT803X_INSR                            0x0013
7 +#define AT803X_REG_CHIP_CONFIG                 0x1f
8 +#define AT803X_BT_BX_REG_SEL                   0x8000
9 +#define AT803X_SGMII_ANEG_EN                   0x1000
10  
11  #define AT803X_PCS_SMART_EEE_CTRL3                     0x805D
12  #define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK   0x3
13 @@ -49,9 +52,10 @@
14  #define AT803X_DEBUG_SYSTEM_MODE_CTRL          0x05
15  #define AT803X_DEBUG_RGMII_TX_CLK_DLY          BIT(8)
16  
17 -#define ATH8030_PHY_ID 0x004dd076
18 -#define ATH8031_PHY_ID 0x004dd074
19 -#define ATH8035_PHY_ID 0x004dd072
20 +#define AT803X_PHY_ID_MASK                     0xffffffef
21 +#define ATH8030_PHY_ID                         0x004dd076
22 +#define ATH8031_PHY_ID                         0x004dd074
23 +#define ATH8035_PHY_ID                         0x004dd072
24  
25  MODULE_DESCRIPTION("Atheros 803x PHY driver");
26  MODULE_AUTHOR("Matus Ujhelyi");
27 @@ -268,6 +272,27 @@ static int at803x_config_init(struct phy
28  {
29         struct at803x_platform_data *pdata;
30         int ret;
31 +       u32 v;
32 +
33 +       if (phydev->drv->phy_id == ATH8031_PHY_ID &&
34 +               phydev->interface == PHY_INTERFACE_MODE_SGMII)
35 +       {
36 +               v = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
37 +               /* select SGMII/fiber page */
38 +               ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG,
39 +                                               v & ~AT803X_BT_BX_REG_SEL);
40 +               if (ret)
41 +                       return ret;
42 +               /* enable SGMII autonegotiation */
43 +               ret = phy_write(phydev, MII_BMCR, AT803X_SGMII_ANEG_EN);
44 +               if (ret)
45 +                       return ret;
46 +               /* select copper page */
47 +               ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG,
48 +                                               v | AT803X_BT_BX_REG_SEL);
49 +               if (ret)
50 +                       return ret;
51 +       }
52  
53         ret = genphy_config_init(phydev);
54         if (ret < 0)
55 @@ -394,7 +419,7 @@ static struct phy_driver at803x_driver[]
56         /* ATHEROS 8035 */
57         .phy_id                 = ATH8035_PHY_ID,
58         .name                   = "Atheros 8035 ethernet",
59 -       .phy_id_mask            = 0xffffffef,
60 +       .phy_id_mask            = AT803X_PHY_ID_MASK,
61         .probe                  = at803x_probe,
62         .config_init            = at803x_config_init,
63         .link_change_notify     = at803x_link_change_notify,
64 @@ -413,7 +438,7 @@ static struct phy_driver at803x_driver[]
65         /* ATHEROS 8030 */
66         .phy_id                 = ATH8030_PHY_ID,
67         .name                   = "Atheros 8030 ethernet",
68 -       .phy_id_mask            = 0xffffffef,
69 +       .phy_id_mask            = AT803X_PHY_ID_MASK,
70         .probe                  = at803x_probe,
71         .config_init            = at803x_config_init,
72         .link_change_notify     = at803x_link_change_notify,
73 @@ -431,8 +456,8 @@ static struct phy_driver at803x_driver[]
74  }, {
75         /* ATHEROS 8031 */
76         .phy_id                 = ATH8031_PHY_ID,
77 -       .name                   = "Atheros 8031 ethernet",
78 -       .phy_id_mask            = 0xffffffef,
79 +       .name                   = "Atheros 8031/8033 ethernet",
80 +       .phy_id_mask            = AT803X_PHY_ID_MASK,
81         .probe                  = at803x_probe,
82         .config_init            = at803x_config_init,
83         .link_change_notify     = at803x_link_change_notify,
84 @@ -454,9 +479,9 @@ static struct phy_driver at803x_driver[]
85  module_phy_driver(at803x_driver);
86  
87  static struct mdio_device_id __maybe_unused atheros_tbl[] = {
88 -       { ATH8030_PHY_ID, 0xffffffef },
89 -       { ATH8031_PHY_ID, 0xffffffef },
90 -       { ATH8035_PHY_ID, 0xffffffef },
91 +       { ATH8030_PHY_ID, AT803X_PHY_ID_MASK },
92 +       { ATH8031_PHY_ID, AT803X_PHY_ID_MASK },
93 +       { ATH8035_PHY_ID, AT803X_PHY_ID_MASK },
94         { }
95  };
96