generic: use AT803X patches sent upstream
authorDavid Bauer <mail@david-bauer.net>
Sat, 11 Apr 2020 20:43:15 +0000 (22:43 +0200)
committerDavid Bauer <mail@david-bauer.net>
Sat, 16 May 2020 22:14:04 +0000 (00:14 +0200)
target/linux/generic/backport-5.4/700-net-phy-at803x-use-phydev-phy-mode-in-aneg_done.patch [new file with mode: 0644]
target/linux/generic/backport-5.4/701-net-phy-at803x-use-paged-reads.patch [new file with mode: 0644]
target/linux/generic/backport-5.4/702-net-phy-at803x-select-correct-page-on-config-init.patch [new file with mode: 0644]
target/linux/generic/backport-5.4/703-net-phy-at803x-enable-SGMII-aneg-on-config-init.patch [new file with mode: 0644]
target/linux/generic/pending-5.4/735-net-phy-at803x-fix-at8033-sgmii-mode.patch [deleted file]

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 (file)
index 0000000..f5a1116
--- /dev/null
@@ -0,0 +1,32 @@
+From cd4fb0bb4a49aad79adedcee6a2bd8185935cc3f Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+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 <mail@david-bauer.net>
+---
+ 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 (file)
index 0000000..8173635
--- /dev/null
@@ -0,0 +1,98 @@
+From 0c486c4fc5102f73fed4a203018616871a7855b2 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+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 <mail@david-bauer.net>
+---
+ 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 (file)
index 0000000..23bfd5a
--- /dev/null
@@ -0,0 +1,37 @@
+From 0a8c84ba82f9e55cf9c97394a0a83a9318b64a66 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+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 <mail@david-bauer.net>
+---
+ 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 (file)
index 0000000..644e8a9
--- /dev/null
@@ -0,0 +1,34 @@
+From 84ad131ed1a668cf656cb5f6921db4012b2edef3 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+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 <mail@david-bauer.net>
+---
+ 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 (file)
index 7957430..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From: Roman Yeryomin <roman@advem.lv>
-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 <roman@advem.lv>
----
- 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