From: David Bauer Date: Fri, 4 Jun 2021 13:12:14 +0000 (+0200) Subject: generic: backport at803x fixes X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=15167671b0d7cf0c95568dd6f9620db082df5d96;p=openwrt%2Fstaging%2Fjow.git generic: backport at803x fixes 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 --- diff --git a/target/linux/generic/backport-5.10/730-net-phy-at803x-select-correct-page-on-config-init.patch b/target/linux/generic/backport-5.10/730-net-phy-at803x-select-correct-page-on-config-init.patch new file mode 100644 index 0000000000..00be403299 --- /dev/null +++ b/target/linux/generic/backport-5.10/730-net-phy-at803x-select-correct-page-on-config-init.patch @@ -0,0 +1,108 @@ +From c329e5afb42ff0a88285eb4d8a391a18793e4777 Mon Sep 17 00:00:00 2001 +From: David Bauer +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 +Signed-off-by: David S. Miller +--- + 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, diff --git a/target/linux/generic/backport-5.10/731-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch b/target/linux/generic/backport-5.10/731-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch new file mode 100644 index 0000000000..d6ec7450e8 --- /dev/null +++ b/target/linux/generic/backport-5.10/731-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch @@ -0,0 +1,73 @@ +From 8f7e876273e294b732b42af2e5e6bba91d798954 Mon Sep 17 00:00:00 2001 +From: Michael Walle +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 +Reviewed-by: David Bauer +Signed-off-by: David S. Miller +--- + 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; + } + diff --git a/target/linux/generic/backport-5.4/790-net-phy-at803x-select-correct-page-on-config-init.patch b/target/linux/generic/backport-5.4/790-net-phy-at803x-select-correct-page-on-config-init.patch new file mode 100644 index 0000000000..c6811736f8 --- /dev/null +++ b/target/linux/generic/backport-5.4/790-net-phy-at803x-select-correct-page-on-config-init.patch @@ -0,0 +1,104 @@ +From c329e5afb42ff0a88285eb4d8a391a18793e4777 Mon Sep 17 00:00:00 2001 +From: David Bauer +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 +Signed-off-by: David S. Miller +--- + 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, diff --git a/target/linux/generic/backport-5.4/791-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch b/target/linux/generic/backport-5.4/791-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch new file mode 100644 index 0000000000..ac9583a89e --- /dev/null +++ b/target/linux/generic/backport-5.4/791-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch @@ -0,0 +1,41 @@ +From 8f7e876273e294b732b42af2e5e6bba91d798954 Mon Sep 17 00:00:00 2001 +From: Michael Walle +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 +Reviewed-by: David Bauer +Signed-off-by: David S. Miller +--- + 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; diff --git a/target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch deleted file mode 100644 index b063b10251..0000000000 --- a/target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: Roman Yeryomin -Subject: kernel: add at803x fix for sgmii mode - -Some (possibly broken) bootloaders incorreclty initialize at8033 -phy. This patch enables sgmii autonegotiation mode. - -[john@phrozen.org: felix added this to his upstream queue] - -Signed-off-by: Roman Yeryomin ---- - drivers/net/phy/at803x.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -76,6 +76,7 @@ - #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A - #define AT803X_REG_CHIP_CONFIG 0x1f - #define AT803X_BT_BX_REG_SEL 0x8000 -+#define AT803X_SGMII_ANEG_EN 0x1000 - - #define AT803X_DEBUG_ADDR 0x1D - #define AT803X_DEBUG_DATA 0x1E -@@ -562,6 +563,27 @@ static int at8031_pll_config(struct phy_ - static int at803x_config_init(struct phy_device *phydev) - { - 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; -+ } - - /* The RX and TX delay default is: - * after HW reset: RX delay enabled and TX delay disabled diff --git a/target/linux/generic/pending-5.10/736-net-phy-at803x-add-at8031-features.patch b/target/linux/generic/pending-5.10/736-net-phy-at803x-add-at8031-features.patch deleted file mode 100644 index 77d3946aae..0000000000 --- a/target/linux/generic/pending-5.10/736-net-phy-at803x-add-at8031-features.patch +++ /dev/null @@ -1,36 +0,0 @@ -Add back explicit PHY feature flags for the AR8031 and -AR8033 PHY instead of reading them from the PHY. - -The Botloader for Ubiquiti UniFi AC boards (and possibly more) -leave fiber page selected, thus we will end up reading the PHY -capabilities of the SGMII side (which does not offer 10 Mbit/s). - -We already have a hack in place, which switches back to the copper -page, however this happens after capabilities are read. - -The original conversation about 735-net-phy-at803x-fix-at8033-sgmii-mode -back in 2015 explicitly mention the UniFi AC Lite. The issue however is -not missing autonegotiation on the Fiber side, but the fact the PHY -is never switched to the copper side. So half of this patch is superfluous. - -A fix is currently being upstreamed. Once this is mainlined and available to us, -these patches can be dropped: - -735-net-phy-at803x-fix-at8033-sgmii-mode.patch -736-net-phy-at803x-add-at8031-features.patch - -This was tested on a UniFi AC Lite. - -See https://patchwork.kernel.org/project/netdevbpf/list/?series=467341 - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1119,7 +1119,7 @@ static struct phy_driver at803x_driver[] - .get_wol = at803x_get_wol, - .suspend = at803x_suspend, - .resume = at803x_resume, -- /* PHY_GBIT_FEATURES */ -+ .features = PHY_GBIT_FEATURES, - .read_status = at803x_read_status, - .aneg_done = at803x_aneg_done, - .ack_interrupt = &at803x_ack_interrupt, diff --git a/target/linux/generic/pending-5.4/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/pending-5.4/735-net-phy-at803x-fix-at8033-sgmii-mode.patch deleted file mode 100644 index 795743057a..0000000000 --- a/target/linux/generic/pending-5.4/735-net-phy-at803x-fix-at8033-sgmii-mode.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: Roman Yeryomin -Subject: kernel: add at803x fix for sgmii mode - -Some (possibly broken) bootloaders incorreclty initialize at8033 -phy. This patch enables sgmii autonegotiation mode. - -[john@phrozen.org: felix added this to his upstream queue] - -Signed-off-by: Roman Yeryomin ---- - drivers/net/phy/at803x.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -46,6 +46,7 @@ - #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A - #define AT803X_REG_CHIP_CONFIG 0x1f - #define AT803X_BT_BX_REG_SEL 0x8000 -+#define AT803X_SGMII_ANEG_EN 0x1000 - - #define AT803X_DEBUG_ADDR 0x1D - #define AT803X_DEBUG_DATA 0x1E -@@ -259,6 +260,27 @@ static int at803x_probe(struct phy_devic - static int at803x_config_init(struct phy_device *phydev) - { - 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; -+ } - - /* The RX and TX delay default is: - * after HW reset: RX delay enabled and TX delay disabled diff --git a/target/linux/generic/pending-5.4/736-net-phy-at803x-add-at8031-features.patch b/target/linux/generic/pending-5.4/736-net-phy-at803x-add-at8031-features.patch deleted file mode 100644 index aa70f82823..0000000000 --- a/target/linux/generic/pending-5.4/736-net-phy-at803x-add-at8031-features.patch +++ /dev/null @@ -1,36 +0,0 @@ -Add back explicit PHY feature flags for the AR8031 and -AR8033 PHY instead of reading them from the PHY. - -The Botloader for Ubiquiti UniFi AC boards (and possibly more) -leave fiber page selected, thus we will end up reading the PHY -capabilities of the SGMII side (which does not offer 10 Mbit/s). - -We already have a hack in place, which switches back to the copper -page, however this happens after capabilities are read. - -The original conversation about 735-net-phy-at803x-fix-at8033-sgmii-mode -back in 2015 explicitly mention the UniFi AC Lite. The issue however is -not missing autonegotiation on the Fiber side, but the fact the PHY -is never switched to the copper side. So half of this patch is superfluous. - -A fix is currently being upstreamed. Once this is mainlined and available to us, -these patches can be dropped: - -735-net-phy-at803x-fix-at8033-sgmii-mode.patch -736-net-phy-at803x-add-at8031-features.patch - -This was tested on a UniFi AC Lite. - -See https://patchwork.kernel.org/project/netdevbpf/list/?series=467341 - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -490,7 +490,7 @@ static struct phy_driver at803x_driver[] - .get_wol = at803x_get_wol, - .suspend = at803x_suspend, - .resume = at803x_resume, -- /* PHY_GBIT_FEATURES */ -+ .features = PHY_GBIT_FEATURES, - .read_status = at803x_read_status, - .aneg_done = at803x_aneg_done, - .ack_interrupt = &at803x_ack_interrupt, diff --git a/target/linux/layerscape/patches-5.4/701-net-0327-at803x-Address-packet-drops-at-low-traffic-rate-due-.patch b/target/linux/layerscape/patches-5.4/701-net-0327-at803x-Address-packet-drops-at-low-traffic-rate-due-.patch index 303d122459..f8dda3a22d 100644 --- a/target/linux/layerscape/patches-5.4/701-net-0327-at803x-Address-packet-drops-at-low-traffic-rate-due-.patch +++ b/target/linux/layerscape/patches-5.4/701-net-0327-at803x-Address-packet-drops-at-low-traffic-rate-due-.patch @@ -41,7 +41,7 @@ Signed-off-by: Vladimir Oltean depends on BCM63XX || COMPILE_TEST --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c -@@ -63,6 +63,8 @@ +@@ -62,6 +62,8 @@ #define AT803X_DEBUG_REG_5 0x05 #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) @@ -50,8 +50,8 @@ Signed-off-by: Vladimir Oltean #define ATH8030_PHY_ID 0x004dd076 #define ATH8031_PHY_ID 0x004dd074 #define ATH8032_PHY_ID 0x004dd023 -@@ -257,6 +259,19 @@ static int at803x_probe(struct phy_devic - return 0; +@@ -299,10 +301,30 @@ static int at803x_probe(struct phy_devic + return ret; } +static void at803x_enable_smart_eee(struct phy_device *phydev, int on) @@ -70,9 +70,6 @@ Signed-off-by: Vladimir Oltean static int at803x_config_init(struct phy_device *phydev) { int ret; -@@ -282,6 +297,13 @@ static int at803x_config_init(struct phy - return ret; - } + +#ifdef CONFIG_AT803X_PHY_SMART_EEE diff --git a/target/linux/layerscape/patches-5.4/701-net-0330-net-phy-at803x-add-vddio-1v8-and-eee-disable-support.patch b/target/linux/layerscape/patches-5.4/701-net-0330-net-phy-at803x-add-vddio-1v8-and-eee-disable-support.patch index 32339191e4..7ae1ba3333 100644 --- a/target/linux/layerscape/patches-5.4/701-net-0330-net-phy-at803x-add-vddio-1v8-and-eee-disable-support.patch +++ b/target/linux/layerscape/patches-5.4/701-net-0330-net-phy-at803x-add-vddio-1v8-and-eee-disable-support.patch @@ -28,10 +28,10 @@ Signed-off-by: Yangbo Lu #define AT803X_REG_CHIP_CONFIG 0x1f #define AT803X_BT_BX_REG_SEL 0x8000 +#define AT803X_SMARTEEE_DISABLED_VAL 0x1000 - #define AT803X_SGMII_ANEG_EN 0x1000 #define AT803X_DEBUG_ADDR 0x1D -@@ -65,6 +70,9 @@ + #define AT803X_DEBUG_DATA 0x1E +@@ -64,6 +69,9 @@ #define AT803X_LPI_EN BIT(8) @@ -41,9 +41,9 @@ Signed-off-by: Yangbo Lu #define ATH8030_PHY_ID 0x004dd076 #define ATH8031_PHY_ID 0x004dd074 #define ATH8032_PHY_ID 0x004dd023 -@@ -72,12 +80,16 @@ - #define AT803X_PHY_ID_MASK 0xffffffef - #define AT8032_PHY_ID_MASK 0xffffffff +@@ -74,12 +82,16 @@ + #define AT803X_PAGE_FIBER 0 + #define AT803X_PAGE_COPPER 1 +#define AT803X_EEE_FEATURE_DISABLE (1 << 1) +#define AT803X_VDDIO_1P8V (1 << 2) @@ -58,7 +58,7 @@ Signed-off-by: Yangbo Lu }; struct at803x_context { -@@ -141,6 +153,39 @@ static int at803x_disable_tx_delay(struc +@@ -172,6 +184,39 @@ static int at803x_disable_tx_delay(struc AT803X_DEBUG_TX_CLK_DLY_EN, 0); } @@ -98,7 +98,7 @@ Signed-off-by: Yangbo Lu /* save relevant PHY registers to private copy */ static void at803x_context_save(struct phy_device *phydev, struct at803x_context *context) -@@ -254,6 +299,12 @@ static int at803x_probe(struct phy_devic +@@ -286,6 +331,12 @@ static int at803x_probe(struct phy_devic if (!priv) return -ENOMEM; @@ -110,16 +110,16 @@ Signed-off-by: Yangbo Lu + phydev->priv = priv; - return 0; -@@ -275,6 +326,7 @@ static void at803x_enable_smart_eee(stru + /* Some bootloaders leave the fiber page selected. +@@ -316,6 +367,7 @@ static void at803x_enable_smart_eee(stru + static int at803x_config_init(struct phy_device *phydev) { - int ret; + struct at803x_priv *priv = phydev->priv; - u32 v; + int ret; + - if (phydev->drv->phy_id == ATH8031_PHY_ID && -@@ -323,6 +375,18 @@ static int at803x_config_init(struct phy +@@ -344,6 +396,18 @@ static int at803x_config_init(struct phy else ret = at803x_disable_tx_delay(phydev); diff --git a/target/linux/ramips/patches-5.10/710-at803x.patch b/target/linux/ramips/patches-5.10/710-at803x.patch index dab62b7607..d15dd92965 100644 --- a/target/linux/ramips/patches-5.10/710-at803x.patch +++ b/target/linux/ramips/patches-5.10/710-at803x.patch @@ -23,7 +23,7 @@ Signed-off-by: René van Dorst #define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10 #define AT803X_SFC_ASSERT_CRS BIT(11) -@@ -83,9 +85,18 @@ +@@ -82,9 +84,18 @@ #define AT803X_MODE_CFG_MASK 0x0F #define AT803X_MODE_CFG_SGMII 0x01 @@ -42,7 +42,7 @@ Signed-off-by: René van Dorst #define AT803X_DEBUG_REG_0 0x00 #define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) -@@ -505,10 +516,72 @@ static int at803x_parse_dt(struct phy_de +@@ -532,12 +543,75 @@ static int at803x_parse_dt(struct phy_de return 0; } @@ -100,22 +100,25 @@ Signed-off-by: René van Dorst + .detach = phy_sfp_detach, + .module_insert = at803x_sfp_insert, +}; ++ + static int at803x_probe(struct phy_device *phydev) { struct device *dev = &phydev->mdio.dev; struct at803x_priv *priv; -+ int ret; + int ret; + + + if (at803x_mode(phydev) == AT803X_MODE_FIBER) { + ret = phy_sfp_probe(phydev, &at803x_sfp_ops); + if (ret < 0) + return ret; + } - ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) -@@ -709,6 +782,10 @@ static int at803x_read_status(struct phy + return -ENOMEM; +@@ -744,6 +818,10 @@ static int at803x_read_status(struct phy { int ss, err, old_link = phydev->link; @@ -126,7 +129,7 @@ Signed-off-by: René van Dorst /* Update the link, but return if there was an error */ err = genphy_update_link(phydev); if (err) -@@ -809,6 +886,12 @@ static int at803x_config_aneg(struct phy +@@ -844,6 +922,12 @@ static int at803x_config_aneg(struct phy { int ret; @@ -139,7 +142,7 @@ Signed-off-by: René van Dorst ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); if (ret < 0) return ret; -@@ -1110,6 +1193,7 @@ static struct phy_driver at803x_driver[] +@@ -1145,6 +1229,7 @@ static struct phy_driver at803x_driver[] /* Qualcomm Atheros AR8031/AR8033 */ PHY_ID_MATCH_EXACT(ATH8031_PHY_ID), .name = "Qualcomm Atheros AR8031/AR8033", diff --git a/target/linux/ramips/patches-5.4/991-at803x.patch b/target/linux/ramips/patches-5.4/991-at803x.patch index 95411211b2..29e79e65d7 100644 --- a/target/linux/ramips/patches-5.4/991-at803x.patch +++ b/target/linux/ramips/patches-5.4/991-at803x.patch @@ -23,7 +23,7 @@ Signed-off-by: René van Dorst #define AT803X_SPECIFIC_STATUS 0x11 #define AT803X_SS_SPEED_MASK (3 << 14) -@@ -53,9 +55,18 @@ +@@ -52,9 +54,18 @@ #define AT803X_MODE_CFG_MASK 0x0F #define AT803X_MODE_CFG_SGMII 0x01 @@ -42,7 +42,7 @@ Signed-off-by: René van Dorst #define AT803X_DEBUG_REG_0 0x00 #define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) -@@ -243,10 +254,72 @@ static int at803x_resume(struct phy_devi +@@ -274,12 +285,73 @@ static int at803x_resume(struct phy_devi return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0); } @@ -105,17 +105,18 @@ Signed-off-by: René van Dorst { struct device *dev = &phydev->mdio.dev; struct at803x_priv *priv; -+ int ret; -+ + int ret; + + if (at803x_mode(phydev) == AT803X_MODE_FIBER) { + ret = phy_sfp_probe(phydev, &at803x_sfp_ops); + if (ret < 0) + return ret; + } - ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) -@@ -394,6 +467,10 @@ static int at803x_read_status(struct phy + return -ENOMEM; +@@ -415,6 +487,10 @@ static int at803x_read_status(struct phy { int ss, err, old_link = phydev->link; @@ -126,7 +127,7 @@ Signed-off-by: René van Dorst /* Update the link, but return if there was an error */ err = genphy_update_link(phydev); if (err) -@@ -448,6 +525,19 @@ static int at803x_read_status(struct phy +@@ -469,6 +545,19 @@ static int at803x_read_status(struct phy return 0; } @@ -146,7 +147,7 @@ Signed-off-by: René van Dorst static struct phy_driver at803x_driver[] = { { /* ATHEROS 8035 */ -@@ -461,6 +551,7 @@ static struct phy_driver at803x_driver[] +@@ -482,6 +571,7 @@ static struct phy_driver at803x_driver[] .suspend = at803x_suspend, .resume = at803x_resume, /* PHY_GBIT_FEATURES */