Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
As patches for the AR8031/AR8033 copper page selection were merged upstream, we can backport these patches. This also fixes a PHY capabilities detection issue on the Ubiquiti ER-X-SFP. Signed-off-by: David Bauer <mail@david-bauer.net>
- Loading branch information
1 parent
1412424
commit 1516767
Showing
12 changed files
with
361 additions
and
208 deletions.
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
108
...t/linux/generic/backport-5.10/730-net-phy-at803x-select-correct-page-on-config-init.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
From c329e5afb42ff0a88285eb4d8a391a18793e4777 Mon Sep 17 00:00:00 2001 | ||
From: David Bauer <mail@david-bauer.net> | ||
Date: Thu, 15 Apr 2021 03:26:50 +0200 | ||
Subject: [PATCH] net: phy: at803x: select correct page on config init | ||
|
||
The Atheros AR8031 and AR8033 expose different registers for SGMII/Fiber | ||
as well as the copper side of the PHY depending on the BT_BX_REG_SEL bit | ||
in the chip configure register. | ||
|
||
The driver assumes the copper side is selected on probe, but this might | ||
not be the case depending which page was last selected by the | ||
bootloader. Notably, Ubiquiti UniFi bootloaders show this behavior. | ||
|
||
Select the copper page when probing to circumvent this. | ||
|
||
Signed-off-by: David Bauer <mail@david-bauer.net> | ||
Signed-off-by: David S. Miller <davem@davemloft.net> | ||
--- | ||
drivers/net/phy/at803x.c | 50 +++++++++++++++++++++++++++++++++++++++- | ||
1 file changed, 49 insertions(+), 1 deletion(-) | ||
|
||
--- a/drivers/net/phy/at803x.c | ||
+++ b/drivers/net/phy/at803x.c | ||
@@ -139,6 +139,9 @@ | ||
#define ATH8035_PHY_ID 0x004dd072 | ||
#define AT8030_PHY_ID_MASK 0xffffffef | ||
|
||
+#define AT803X_PAGE_FIBER 0 | ||
+#define AT803X_PAGE_COPPER 1 | ||
+ | ||
MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver"); | ||
MODULE_AUTHOR("Matus Ujhelyi"); | ||
MODULE_LICENSE("GPL"); | ||
@@ -190,6 +193,35 @@ static int at803x_debug_reg_mask(struct | ||
return phy_write(phydev, AT803X_DEBUG_DATA, val); | ||
} | ||
|
||
+static int at803x_write_page(struct phy_device *phydev, int page) | ||
+{ | ||
+ int mask; | ||
+ int set; | ||
+ | ||
+ if (page == AT803X_PAGE_COPPER) { | ||
+ set = AT803X_BT_BX_REG_SEL; | ||
+ mask = 0; | ||
+ } else { | ||
+ set = 0; | ||
+ mask = AT803X_BT_BX_REG_SEL; | ||
+ } | ||
+ | ||
+ return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set); | ||
+} | ||
+ | ||
+static int at803x_read_page(struct phy_device *phydev) | ||
+{ | ||
+ int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG); | ||
+ | ||
+ if (ccr < 0) | ||
+ return ccr; | ||
+ | ||
+ if (ccr & AT803X_BT_BX_REG_SEL) | ||
+ return AT803X_PAGE_COPPER; | ||
+ | ||
+ return AT803X_PAGE_FIBER; | ||
+} | ||
+ | ||
static int at803x_enable_rx_delay(struct phy_device *phydev) | ||
{ | ||
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0, | ||
@@ -508,6 +540,7 @@ static int at803x_probe(struct phy_devic | ||
{ | ||
struct device *dev = &phydev->mdio.dev; | ||
struct at803x_priv *priv; | ||
+ int ret; | ||
|
||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
if (!priv) | ||
@@ -515,7 +548,20 @@ static int at803x_probe(struct phy_devic | ||
|
||
phydev->priv = priv; | ||
|
||
- return at803x_parse_dt(phydev); | ||
+ ret = at803x_parse_dt(phydev); | ||
+ if (ret) | ||
+ return ret; | ||
+ | ||
+ /* Some bootloaders leave the fiber page selected. | ||
+ * Switch to the copper page, as otherwise we read | ||
+ * the PHY capabilities from the fiber side. | ||
+ */ | ||
+ if (at803x_match_phy_id(phydev, ATH8031_PHY_ID)) { | ||
+ ret = phy_select_page(phydev, AT803X_PAGE_COPPER); | ||
+ ret = phy_restore_page(phydev, AT803X_PAGE_COPPER, ret); | ||
+ } | ||
+ | ||
+ return ret; | ||
} | ||
|
||
static void at803x_remove(struct phy_device *phydev) | ||
@@ -1097,6 +1143,8 @@ static struct phy_driver at803x_driver[] | ||
.get_wol = at803x_get_wol, | ||
.suspend = at803x_suspend, | ||
.resume = at803x_resume, | ||
+ .read_page = at803x_read_page, | ||
+ .write_page = at803x_write_page, | ||
/* PHY_GBIT_FEATURES */ | ||
.read_status = at803x_read_status, | ||
.aneg_done = at803x_aneg_done, |
73 changes: 73 additions & 0 deletions
73
...inux/generic/backport-5.10/731-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
From 8f7e876273e294b732b42af2e5e6bba91d798954 Mon Sep 17 00:00:00 2001 | ||
From: Michael Walle <michael@walle.cc> | ||
Date: Tue, 20 Apr 2021 12:29:29 +0200 | ||
Subject: [PATCH] net: phy: at803x: fix probe error if copper page is selected | ||
|
||
The commit c329e5afb42f ("net: phy: at803x: select correct page on | ||
config init") selects the copper page during probe. This fails if the | ||
copper page was already selected. In this case, the value of the copper | ||
page (which is 1) is propagated through phy_restore_page() and is | ||
finally returned for at803x_probe(). Fix it, by just using the | ||
at803x_page_write() directly. | ||
|
||
Also in case of an error, the regulator is not disabled and leads to a | ||
WARN_ON() when the probe fails. This couldn't happen before, because | ||
at803x_parse_dt() was the last call in at803x_probe(). It is hard to | ||
see, that the parse_dt() actually enables the regulator. Thus move the | ||
regulator_enable() to the probe function and undo it in case of an | ||
error. | ||
|
||
Fixes: c329e5afb42f ("net: phy: at803x: select correct page on config init") | ||
Signed-off-by: Michael Walle <michael@walle.cc> | ||
Reviewed-by: David Bauer <mail@david-bauer.net> | ||
Signed-off-by: David S. Miller <davem@davemloft.net> | ||
--- | ||
drivers/net/phy/at803x.c | 23 +++++++++++++++++------ | ||
1 file changed, 17 insertions(+), 6 deletions(-) | ||
|
||
--- a/drivers/net/phy/at803x.c | ||
+++ b/drivers/net/phy/at803x.c | ||
@@ -527,10 +527,6 @@ static int at803x_parse_dt(struct phy_de | ||
phydev_err(phydev, "failed to get VDDIO regulator\n"); | ||
return PTR_ERR(priv->vddio); | ||
} | ||
- | ||
- ret = regulator_enable(priv->vddio); | ||
- if (ret < 0) | ||
- return ret; | ||
} | ||
|
||
return 0; | ||
@@ -552,15 +548,30 @@ static int at803x_probe(struct phy_devic | ||
if (ret) | ||
return ret; | ||
|
||
+ if (priv->vddio) { | ||
+ ret = regulator_enable(priv->vddio); | ||
+ if (ret < 0) | ||
+ return ret; | ||
+ } | ||
+ | ||
/* Some bootloaders leave the fiber page selected. | ||
* Switch to the copper page, as otherwise we read | ||
* the PHY capabilities from the fiber side. | ||
*/ | ||
if (at803x_match_phy_id(phydev, ATH8031_PHY_ID)) { | ||
- ret = phy_select_page(phydev, AT803X_PAGE_COPPER); | ||
- ret = phy_restore_page(phydev, AT803X_PAGE_COPPER, ret); | ||
+ phy_lock_mdio_bus(phydev); | ||
+ ret = at803x_write_page(phydev, AT803X_PAGE_COPPER); | ||
+ phy_unlock_mdio_bus(phydev); | ||
+ if (ret) | ||
+ goto err; | ||
} | ||
|
||
+ return 0; | ||
+ | ||
+err: | ||
+ if (priv->vddio) | ||
+ regulator_disable(priv->vddio); | ||
+ | ||
return ret; | ||
} | ||
|
104 changes: 104 additions & 0 deletions
104
...et/linux/generic/backport-5.4/790-net-phy-at803x-select-correct-page-on-config-init.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
From c329e5afb42ff0a88285eb4d8a391a18793e4777 Mon Sep 17 00:00:00 2001 | ||
From: David Bauer <mail@david-bauer.net> | ||
Date: Thu, 15 Apr 2021 03:26:50 +0200 | ||
Subject: [PATCH] net: phy: at803x: select correct page on config init | ||
|
||
The Atheros AR8031 and AR8033 expose different registers for SGMII/Fiber | ||
as well as the copper side of the PHY depending on the BT_BX_REG_SEL bit | ||
in the chip configure register. | ||
|
||
The driver assumes the copper side is selected on probe, but this might | ||
not be the case depending which page was last selected by the | ||
bootloader. Notably, Ubiquiti UniFi bootloaders show this behavior. | ||
|
||
Select the copper page when probing to circumvent this. | ||
|
||
Signed-off-by: David Bauer <mail@david-bauer.net> | ||
Signed-off-by: David S. Miller <davem@davemloft.net> | ||
--- | ||
drivers/net/phy/at803x.c | 50 +++++++++++++++++++++++++++++++++++++++- | ||
1 file changed, 49 insertions(+), 1 deletion(-) | ||
|
||
--- a/drivers/net/phy/at803x.c | ||
+++ b/drivers/net/phy/at803x.c | ||
@@ -67,6 +67,9 @@ | ||
#define ATH8035_PHY_ID 0x004dd072 | ||
#define AT803X_PHY_ID_MASK 0xffffffef | ||
|
||
+#define AT803X_PAGE_FIBER 0 | ||
+#define AT803X_PAGE_COPPER 1 | ||
+ | ||
MODULE_DESCRIPTION("Atheros 803x PHY driver"); | ||
MODULE_AUTHOR("Matus Ujhelyi"); | ||
MODULE_LICENSE("GPL"); | ||
@@ -112,6 +115,35 @@ static int at803x_debug_reg_mask(struct | ||
return phy_write(phydev, AT803X_DEBUG_DATA, val); | ||
} | ||
|
||
+static int at803x_write_page(struct phy_device *phydev, int page) | ||
+{ | ||
+ int mask; | ||
+ int set; | ||
+ | ||
+ if (page == AT803X_PAGE_COPPER) { | ||
+ set = AT803X_BT_BX_REG_SEL; | ||
+ mask = 0; | ||
+ } else { | ||
+ set = 0; | ||
+ mask = AT803X_BT_BX_REG_SEL; | ||
+ } | ||
+ | ||
+ return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set); | ||
+} | ||
+ | ||
+static int at803x_read_page(struct phy_device *phydev) | ||
+{ | ||
+ int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG); | ||
+ | ||
+ if (ccr < 0) | ||
+ return ccr; | ||
+ | ||
+ if (ccr & AT803X_BT_BX_REG_SEL) | ||
+ return AT803X_PAGE_COPPER; | ||
+ | ||
+ return AT803X_PAGE_FIBER; | ||
+} | ||
+ | ||
static int at803x_enable_rx_delay(struct phy_device *phydev) | ||
{ | ||
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0, | ||
@@ -244,6 +276,7 @@ static int at803x_probe(struct phy_devic | ||
{ | ||
struct device *dev = &phydev->mdio.dev; | ||
struct at803x_priv *priv; | ||
+ int ret; | ||
|
||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
if (!priv) | ||
@@ -251,7 +284,16 @@ static int at803x_probe(struct phy_devic | ||
|
||
phydev->priv = priv; | ||
|
||
- return 0; | ||
+ /* Some bootloaders leave the fiber page selected. | ||
+ * Switch to the copper page, as otherwise we read | ||
+ * the PHY capabilities from the fiber side. | ||
+ */ | ||
+ if ((phydev->phy_id & phydev->drv->phy_id_mask) == (ATH8031_PHY_ID & phydev->drv->phy_id_mask)) { | ||
+ ret = phy_select_page(phydev, AT803X_PAGE_COPPER); | ||
+ ret = phy_restore_page(phydev, AT803X_PAGE_COPPER, ret); | ||
+ } | ||
+ | ||
+ return ret; | ||
} | ||
|
||
static int at803x_config_init(struct phy_device *phydev) | ||
@@ -466,6 +508,8 @@ static struct phy_driver at803x_driver[] | ||
.get_wol = at803x_get_wol, | ||
.suspend = at803x_suspend, | ||
.resume = at803x_resume, | ||
+ .read_page = at803x_read_page, | ||
+ .write_page = at803x_write_page, | ||
/* PHY_GBIT_FEATURES */ | ||
.read_status = at803x_read_status, | ||
.aneg_done = at803x_aneg_done, |
41 changes: 41 additions & 0 deletions
41
...linux/generic/backport-5.4/791-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
From 8f7e876273e294b732b42af2e5e6bba91d798954 Mon Sep 17 00:00:00 2001 | ||
From: Michael Walle <michael@walle.cc> | ||
Date: Tue, 20 Apr 2021 12:29:29 +0200 | ||
Subject: [PATCH] net: phy: at803x: fix probe error if copper page is selected | ||
|
||
The commit c329e5afb42f ("net: phy: at803x: select correct page on | ||
config init") selects the copper page during probe. This fails if the | ||
copper page was already selected. In this case, the value of the copper | ||
page (which is 1) is propagated through phy_restore_page() and is | ||
finally returned for at803x_probe(). Fix it, by just using the | ||
at803x_page_write() directly. | ||
|
||
Also in case of an error, the regulator is not disabled and leads to a | ||
WARN_ON() when the probe fails. This couldn't happen before, because | ||
at803x_parse_dt() was the last call in at803x_probe(). It is hard to | ||
see, that the parse_dt() actually enables the regulator. Thus move the | ||
regulator_enable() to the probe function and undo it in case of an | ||
error. | ||
|
||
Fixes: c329e5afb42f ("net: phy: at803x: select correct page on config init") | ||
Signed-off-by: Michael Walle <michael@walle.cc> | ||
Reviewed-by: David Bauer <mail@david-bauer.net> | ||
Signed-off-by: David S. Miller <davem@davemloft.net> | ||
--- | ||
drivers/net/phy/at803x.c | 23 +++++++++++++++++------ | ||
1 file changed, 17 insertions(+), 6 deletions(-) | ||
|
||
--- a/drivers/net/phy/at803x.c | ||
+++ b/drivers/net/phy/at803x.c | ||
@@ -289,8 +289,9 @@ static int at803x_probe(struct phy_devic | ||
* the PHY capabilities from the fiber side. | ||
*/ | ||
if ((phydev->phy_id & phydev->drv->phy_id_mask) == (ATH8031_PHY_ID & phydev->drv->phy_id_mask)) { | ||
- ret = phy_select_page(phydev, AT803X_PAGE_COPPER); | ||
- ret = phy_restore_page(phydev, AT803X_PAGE_COPPER, ret); | ||
+ mutex_lock(&phydev->mdio.bus->mdio_lock); | ||
+ ret = at803x_write_page(phydev, AT803X_PAGE_COPPER); | ||
+ mutex_unlock(&phydev->mdio.bus->mdio_lock); | ||
} | ||
|
||
return ret; |
51 changes: 0 additions & 51 deletions
51
target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
1516767
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with this commit UBNT-ERX-SFP sfp port never link detected
without this commit and with patch in x-wrt@7859aff
the sfp port works great.
@blocktrron ping