kernel: add at803x fix for sgmii mode
Some (possibly broken) bootloaders incorreclty initialize at8033 phy. This patch enables sgmii autonegotiation mode. Signed-off-by: Roman Yeryomin <roman@advem.lv> SVN-Revision: 48109
This commit is contained in:
parent
54b4265873
commit
e14d2aee0a
4 changed files with 384 additions and 0 deletions
|
@ -0,0 +1,96 @@
|
|||
--- 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,
|
||||
@@ -413,7 +438,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,
|
||||
@@ -431,8 +456,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,
|
||||
@@ -454,9 +479,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 },
|
||||
{ }
|
||||
};
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
--- 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,
|
||||
@@ -413,7 +438,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,
|
||||
@@ -431,8 +456,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,
|
||||
@@ -454,9 +479,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 },
|
||||
{ }
|
||||
};
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
--- 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,
|
||||
@@ -413,7 +438,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,
|
||||
@@ -431,8 +456,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,
|
||||
@@ -454,9 +479,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 },
|
||||
{ }
|
||||
};
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
--- 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,
|
||||
@@ -413,7 +438,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,
|
||||
@@ -431,8 +456,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,
|
||||
@@ -454,9 +479,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 },
|
||||
{ }
|
||||
};
|
||||
|
Loading…
Reference in a new issue