From: David Bauer Date: Sat, 11 Apr 2020 20:43:15 +0000 (+0200) Subject: generic: use AT803X patches sent upstream X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=0fcf9d971147e17ad955d6b8143bc87d63c06b87;p=openwrt%2Fstaging%2Fblocktrron.git generic: use AT803X patches sent upstream --- diff --git a/target/linux/generic/backport-5.4/700-net-phy-at803x-use-phydev-phy-mode-in-aneg_done.patch b/target/linux/generic/backport-5.4/700-net-phy-at803x-use-phydev-phy-mode-in-aneg_done.patch new file mode 100644 index 0000000000..f5a11161df --- /dev/null +++ b/target/linux/generic/backport-5.4/700-net-phy-at803x-use-phydev-phy-mode-in-aneg_done.patch @@ -0,0 +1,32 @@ +From cd4fb0bb4a49aad79adedcee6a2bd8185935cc3f Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Fri, 10 Apr 2020 17:57:37 +0200 +Subject: [PATCH 1/4] net: phy: at803x: use phydev phy-mode in aneg_done + +at803x_aneg_done currently reads the chip configuration register to +determine the operation mode of the AR8031/AR8033 PHY. + +This read has to be performed every time the link-state changes. It's +also inconsistent, as some places already use the phy-mode defined for +the phydev. + +Use the phy-mode of the phydev to remove this read and be more +consistent throughout the driver. + +Signed-off-by: David Bauer +--- + drivers/net/phy/at803x.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/phy/at803x.c ++++ b/drivers/net/phy/at803x.c +@@ -348,8 +348,7 @@ static int at803x_aneg_done(struct phy_d + * in SGMII mode, if copper side autoneg is successful, + * also check SGMII side autoneg result + */ +- ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); +- if ((ccr & AT803X_MODE_CFG_MASK) != AT803X_MODE_CFG_SGMII) ++ if (phydev->interface != PHY_INTERFACE_MODE_SGMII) + return aneg_done; + + /* switch to SGMII/fiber page */ diff --git a/target/linux/generic/backport-5.4/701-net-phy-at803x-use-paged-reads.patch b/target/linux/generic/backport-5.4/701-net-phy-at803x-use-paged-reads.patch new file mode 100644 index 0000000000..81736352ae --- /dev/null +++ b/target/linux/generic/backport-5.4/701-net-phy-at803x-use-paged-reads.patch @@ -0,0 +1,98 @@ +From 0c486c4fc5102f73fed4a203018616871a7855b2 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Tue, 17 Mar 2020 21:21:14 +0100 +Subject: [PATCH 2/4] net: phy: at803x: use paged reads + +Refactor the page-switching in at803x_aneg_done to use +paged reads as suggested by Andrew Lunn. + +This way, potential race conditions are avoided, as the +MDIO lock was previously not taken. + +Signed-off-by: David Bauer +--- + drivers/net/phy/at803x.c | 40 ++++++++++++++++++++++++++++++++++------ + 1 file changed, 34 insertions(+), 6 deletions(-) + +--- a/drivers/net/phy/at803x.c ++++ b/drivers/net/phy/at803x.c +@@ -62,6 +62,9 @@ + #define AT803X_DEBUG_REG_5 0x05 + #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) + ++#define AT803X_PAGE_FIBER 0 ++#define AT803X_PAGE_COPPER 1 ++ + #define ATH8030_PHY_ID 0x004dd076 + #define ATH8031_PHY_ID 0x004dd074 + #define ATH8035_PHY_ID 0x004dd072 +@@ -112,6 +115,32 @@ 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; ++ else ++ mask = AT803X_BT_BX_REG_SEL; ++ ++ return __phy_modify_changed(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, +@@ -338,7 +367,7 @@ static void at803x_link_change_notify(st + + static int at803x_aneg_done(struct phy_device *phydev) + { +- int ccr; ++ int pssr; + + int aneg_done = genphy_aneg_done(phydev); + if (aneg_done != BMSR_ANEGCOMPLETE) +@@ -351,16 +380,13 @@ static int at803x_aneg_done(struct phy_d + if (phydev->interface != PHY_INTERFACE_MODE_SGMII) + return aneg_done; + +- /* switch to SGMII/fiber page */ +- phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL); ++ pssr = phy_read_paged(phydev, AT803X_PAGE_FIBER, AT803X_PSSR); + + /* check if the SGMII link is OK. */ +- if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) { ++ if (!(pssr & AT803X_PSSR_MR_AN_COMPLETE)) { + phydev_warn(phydev, "803x_aneg_done: SGMII link is not ok\n"); + aneg_done = 0; + } +- /* switch back to copper page */ +- phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL); + + return aneg_done; + } +@@ -465,6 +491,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/702-net-phy-at803x-select-correct-page-on-config-init.patch b/target/linux/generic/backport-5.4/702-net-phy-at803x-select-correct-page-on-config-init.patch new file mode 100644 index 0000000000..23bfd5a9f6 --- /dev/null +++ b/target/linux/generic/backport-5.4/702-net-phy-at803x-select-correct-page-on-config-init.patch @@ -0,0 +1,37 @@ +From 0a8c84ba82f9e55cf9c97394a0a83a9318b64a66 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Sun, 5 Apr 2020 02:29:36 +0200 +Subject: [PATCH 3/4] 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. + +Select the copper page when initializing the configuration to circumvent +this. + +Signed-off-by: David Bauer +--- + drivers/net/phy/at803x.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/phy/at803x.c ++++ b/drivers/net/phy/at803x.c +@@ -287,6 +287,13 @@ static int at803x_config_init(struct phy + { + int ret; + ++ if (phydev->drv->phy_id == ATH8031_PHY_ID) { ++ ret = phy_select_page(phydev, AT803X_PAGE_COPPER); ++ if (ret < 0) ++ return ret; ++ mutex_unlock(&phydev->mdio.bus->mdio_lock); ++ } ++ + /* The RX and TX delay default is: + * after HW reset: RX delay enabled and TX delay disabled + * after SW reset: RX delay enabled, while TX delay retains the diff --git a/target/linux/generic/backport-5.4/703-net-phy-at803x-enable-SGMII-aneg-on-config-init.patch b/target/linux/generic/backport-5.4/703-net-phy-at803x-enable-SGMII-aneg-on-config-init.patch new file mode 100644 index 0000000000..644e8a9a68 --- /dev/null +++ b/target/linux/generic/backport-5.4/703-net-phy-at803x-enable-SGMII-aneg-on-config-init.patch @@ -0,0 +1,34 @@ +From 84ad131ed1a668cf656cb5f6921db4012b2edef3 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Fri, 10 Apr 2020 17:54:58 +0200 +Subject: [PATCH 4/4] net: phy: at803x: enable SGMII aneg on config init + +Some bootloaders disable the fiber-side autonegotiation on the AR8033, +expecting it to be enabled by the kernel. +This however is currently not the case with at803x, leaving the SGMII +side unusable. + +Activate the fiber-side autonegotiation to make the SGMII link work. + +Signed-off-by: David Bauer +--- + drivers/net/phy/at803x.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/net/phy/at803x.c ++++ b/drivers/net/phy/at803x.c +@@ -288,6 +288,14 @@ static int at803x_config_init(struct phy + int ret; + + if (phydev->drv->phy_id == ATH8031_PHY_ID) { ++ if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { ++ ret = phy_modify_paged_changed(phydev, ++ AT803X_PAGE_FIBER, ++ MII_BMCR, 0, ++ BMCR_ANENABLE); ++ if (ret < 0) ++ return ret; ++ } + ret = phy_select_page(phydev, AT803X_PAGE_COPPER); + if (ret < 0) + return ret; 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