diff mbox

[OpenWrt-Devel,2/2] kernel: add at803x fix for sgmii mode

Message ID 1450571439-1028-1-git-send-email-roman@advem.lv
State Accepted
Headers show

Commit Message

Roman Yeryomin Dec. 20, 2015, 12:30 a.m. UTC
Some (possibly broken) bootloaders incorreclty initialize at8033
phy. This patch enables sgmii autonegotiation mode.

Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
 .../735-net-phy-at803x-fix-at8033-sgmii-mode.patch | 96 ++++++++++++++++++++++
 .../735-net-phy-at803x-fix-at8033-sgmii-mode.patch | 96 ++++++++++++++++++++++
 .../735-net-phy-at803x-fix-at8033-sgmii-mode.patch | 96 ++++++++++++++++++++++
 .../735-net-phy-at803x-fix-at8033-sgmii-mode.patch | 96 ++++++++++++++++++++++
 4 files changed, 384 insertions(+)
 create mode 100644 target/linux/generic/patches-3.18/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
 create mode 100644 target/linux/generic/patches-4.1/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
 create mode 100644 target/linux/generic/patches-4.3/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
 create mode 100644 target/linux/generic/patches-4.4/735-net-phy-at803x-fix-at8033-sgmii-mode.patch

Comments

Christian Lamparter Dec. 20, 2015, 1:13 p.m. UTC | #1
Hello,

On Sunday, December 20, 2015 02:30:39 AM Roman Yeryomin wrote:
> Some (possibly broken) bootloaders incorreclty initialize at8033
> phy. This patch enables sgmii autonegotiation mode.
> 
> Signed-off-by: Roman Yeryomin <roman@advem.lv>
> ---
Can you tell us a bit about the "possibly broken" bootloaders you talk
about? Like what devices (based "possibly" on QCA956x) have those and
from where you are getting this information?

I'm asking because we (Chris and I) encountered similar issues with the
Cisco Merakin MR18. It has a AR8035-A (confirmed by opening up the device)
but calls it a AR8033. The PHY apparently connected via RGMII 
(uses QCA955X_ETH_CFG_RGMII_EN [0]) but the device needs to write some
calibration values to SGMII and SERDES registers in order to work [1].
We are quite keen to know what's going on since this seems counter-intuitive.

Regards,
Christian

[0] <https://dev.openwrt.org/browser/trunk/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c?rev=47878#L256>
[1] <https://dev.openwrt.org/browser/trunk/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c?rev=47878#L182>
Roman Yeryomin Dec. 20, 2015, 6:20 p.m. UTC | #2
On 20 December 2015 at 15:13, Christian Lamparter
<chunkeey@googlemail.com> wrote:
> Hello,
>
> On Sunday, December 20, 2015 02:30:39 AM Roman Yeryomin wrote:
>> Some (possibly broken) bootloaders incorreclty initialize at8033
>> phy. This patch enables sgmii autonegotiation mode.
>>
>> Signed-off-by: Roman Yeryomin <roman@advem.lv>
>> ---
> Can you tell us a bit about the "possibly broken" bootloaders you talk
> about? Like what devices (based "possibly" on QCA956x) have those and
> from where you are getting this information?

The device is uapac.
But I'm taking about phy setup itself...

> I'm asking because we (Chris and I) encountered similar issues with the
> Cisco Merakin MR18. It has a AR8035-A (confirmed by opening up the device)
> but calls it a AR8033. The PHY apparently connected via RGMII
> (uses QCA955X_ETH_CFG_RGMII_EN [0]) but the device needs to write some
> calibration values to SGMII and SERDES registers in order to work [1].
> We are quite keen to know what's going on since this seems counter-intuitive.

..and you are talking about SoC's gmac setup, which is completely
different thing.
Also, FYI, AR8035 doesn't have sgmii, it has rgmii only.

Regards,
Roman
Christian Lamparter Dec. 20, 2015, 8:20 p.m. UTC | #3
Hello,

On Sunday, December 20, 2015 08:20:12 PM Roman Yeryomin wrote:
> On 20 December 2015 at 15:13, Christian Lamparter
> <chunkeey@googlemail.com> wrote:
> > On Sunday, December 20, 2015 02:30:39 AM Roman Yeryomin wrote:
> >> Some (possibly broken) bootloaders incorreclty initialize at8033
> >> phy. This patch enables sgmii autonegotiation mode.
> >>
> >> Signed-off-by: Roman Yeryomin <roman@advem.lv>
> >> ---
> > Can you tell us a bit about the "possibly broken" bootloaders you talk
> > about? Like what devices (based "possibly" on QCA956x) have those and
> > from where you are getting this information?
> 
> The device is uapac.
Unifi AP AC? So, GPL - Sources are hard to come by... Sad.

> But I'm taking about phy setup itself...
> 
> > I'm asking because we (Chris and I) encountered similar issues with the
> > Cisco Merakin MR18. It has a AR8035-A (confirmed by opening up the device)
> > but calls it a AR8033. The PHY apparently connected via RGMII
> > (uses QCA955X_ETH_CFG_RGMII_EN [0]) but the device needs to write some
> > calibration values to SGMII and SERDES registers in order to work [1].
> > We are quite keen to know what's going on since this seems counter-intuitive.
> 
> ..and you are talking about SoC's gmac setup, which is completely
> different thing.
>
> Also, FYI, AR8035 doesn't have sgmii, it has rgmii only.
Exactly, this is the issue here. The AR803x datasheet lists it as RGMII
only. But the Cisco's source tells me the opposite. I hoped to find a QCA
device which uses SGMII properly to check if they do the same "calibrations"
code or if the stuff is specific to the MR18. But because this device comes
from Ubiquiti, then this is probably not going to happen.

Regards,
Christian
diff mbox

Patch

diff --git a/target/linux/generic/patches-3.18/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/patches-3.18/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
new file mode 100644
index 0000000..117f15d
--- /dev/null
+++ b/target/linux/generic/patches-3.18/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
@@ -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 },
+ 	{ }
+ };
+ 
diff --git a/target/linux/generic/patches-4.1/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/patches-4.1/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
new file mode 100644
index 0000000..117f15d
--- /dev/null
+++ b/target/linux/generic/patches-4.1/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
@@ -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 },
+ 	{ }
+ };
+ 
diff --git a/target/linux/generic/patches-4.3/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/patches-4.3/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
new file mode 100644
index 0000000..117f15d
--- /dev/null
+++ b/target/linux/generic/patches-4.3/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
@@ -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 },
+ 	{ }
+ };
+ 
diff --git a/target/linux/generic/patches-4.4/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/patches-4.4/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
new file mode 100644
index 0000000..117f15d
--- /dev/null
+++ b/target/linux/generic/patches-4.4/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
@@ -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 },
+ 	{ }
+ };
+