[openwrt/openwrt] kernel: qca-ssdk: fix C45 MDIO support on kernel 6.6
LEDE Commits
lede-commits at lists.infradead.org
Tue Mar 26 10:10:54 PDT 2024
robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/1d33ee019f62021dfd4911ce8b5a7537a545ede8
commit 1d33ee019f62021dfd4911ce8b5a7537a545ede8
Author: Robert Marko <robimarko at gmail.com>
AuthorDate: Tue Mar 26 12:36:27 2024 +0100
kernel: qca-ssdk: fix C45 MDIO support on kernel 6.6
Kernel 6.3 has introduced separate C45 read/write operations, and thus
split them out of the C22 operations completely so the old way of marking
C45 reads and writes via the register value does not work anymore.
This is causing SSDK to fail and find C45 only PHY-s such as Aquantia ones:
[ 22.187877] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 8, phy_id = 0x0 phytype doesn't match
[ 22.209924] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 0, phy_id = 0x0 phytype doesn't match
This in turn causes USXGMII MAC autoneg bit to not get set and then UNIPHY
autoneg will time out, causing the 10G ports not to work:
[ 37.292784] uniphy autoneg time out!
So, lets detect C45 reads and writes by the magic BIT(30) in the register
argument and if so call separate C45 mdiobus read/write functions.
Signed-off-by: Robert Marko <robimarko at gmail.com>
---
package/kernel/qca-ssdk/Makefile | 2 +-
...dio-adapt-to-C22-and-C45-read-write-split.patch | 98 ++++++++++++++++++++++
2 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile
index 6a7bab7a9a..cd81aeb61c 100644
--- a/package/kernel/qca-ssdk/Makefile
+++ b/package/kernel/qca-ssdk/Makefile
@@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=qca-ssdk
-PKG_RELEASE:=5
+PKG_RELEASE:=6
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git
PKG_SOURCE_PROTO:=git
diff --git a/package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch b/package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch
new file mode 100644
index 0000000000..7ddca554ec
--- /dev/null
+++ b/package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch
@@ -0,0 +1,98 @@
+From bdae481e89cbe551068a99028bb57119b59f5ff4 Mon Sep 17 00:00:00 2001
+From: Robert Marko <robimarko at gmail.com>
+Date: Tue, 26 Mar 2024 12:19:49 +0100
+Subject: [PATCH] mdio: adapt to C22 and C45 read/write split
+
+Kernel 6.3 has introduced separate C45 read/write operations, and thus
+split them out of the C22 operations completely so the old way of marking
+C45 reads and writes via the register value does not work anymore.
+
+This is causing SSDK to fail and find C45 only PHY-s such as Aquantia ones:
+[ 22.187877] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 8, phy_id = 0x0 phytype doesn't match
+[ 22.209924] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 0, phy_id = 0x0 phytype doesn't match
+
+This in turn causes USXGMII MAC autoneg bit to not get set and then UNIPHY
+autoneg will time out, causing the 10G ports not to work:
+[ 37.292784] uniphy autoneg time out!
+
+So, lets detect C45 reads and writes by the magic BIT(30) in the register
+argument and if so call separate C45 mdiobus read/write functions.
+
+Signed-off-by: Robert Marko <robimarko at gmail.com>
+---
+ include/init/ssdk_plat.h | 7 +++++++
+ src/init/ssdk_plat.c | 30 ++++++++++++++++++++++++++++++
+ 2 files changed, 37 insertions(+)
+
+--- a/include/init/ssdk_plat.h
++++ b/include/init/ssdk_plat.h
+@@ -505,3 +505,10 @@ void ssdk_plat_exit(a_uint32_t dev_id);
+
+ #endif
+ /*qca808x_end*/
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0))
++#define MII_ADDR_C45 (1<<30)
++#define MII_DEVADDR_C45_SHIFT 16
++#define MII_DEVADDR_C45_MASK GENMASK(20, 16)
++#define MII_REGADDR_C45_MASK GENMASK(15, 0)
++#endif
+--- a/src/init/ssdk_plat.c
++++ b/src/init/ssdk_plat.c
+@@ -356,6 +356,18 @@ phy_addr_validation_check(a_uint32_t phy
+ return A_TRUE;
+ }
+
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0))
++static inline u16 mdiobus_c45_regad(u32 regnum)
++{
++ return FIELD_GET(MII_REGADDR_C45_MASK, regnum);
++}
++
++static inline u16 mdiobus_c45_devad(u32 regnum)
++{
++ return FIELD_GET(MII_DEVADDR_C45_MASK, regnum);
++}
++#endif
++
+ sw_error_t
+ qca_ar8327_phy_read(a_uint32_t dev_id, a_uint32_t phy_addr,
+ a_uint32_t reg, a_uint16_t* data)
+@@ -371,9 +383,18 @@ qca_ar8327_phy_read(a_uint32_t dev_id, a
+ if (!bus)
+ return SW_NOT_SUPPORTED;
+ phy_addr = TO_PHY_ADDR(phy_addr);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0))
++ mutex_lock(&bus->mdio_lock);
++ if (reg & MII_ADDR_C45)
++ *data = __mdiobus_c45_read(bus, phy_addr, mdiobus_c45_devad(reg), mdiobus_c45_regad(reg));
++ else
++ *data = __mdiobus_read(bus, phy_addr, reg);
++ mutex_unlock(&bus->mdio_lock);
++#else
+ mutex_lock(&bus->mdio_lock);
+ *data = __mdiobus_read(bus, phy_addr, reg);
+ mutex_unlock(&bus->mdio_lock);
++#endif
+
+ return 0;
+ }
+@@ -393,9 +414,18 @@ qca_ar8327_phy_write(a_uint32_t dev_id,
+ if (!bus)
+ return SW_NOT_SUPPORTED;
+ phy_addr = TO_PHY_ADDR(phy_addr);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0))
++ mutex_lock(&bus->mdio_lock);
++ if (reg & MII_ADDR_C45)
++ __mdiobus_c45_write(bus, phy_addr, mdiobus_c45_devad(reg), mdiobus_c45_regad(reg), data);
++ else
++ __mdiobus_write(bus, phy_addr, reg, data);
++ mutex_unlock(&bus->mdio_lock);
++#else
+ mutex_lock(&bus->mdio_lock);
+ __mdiobus_write(bus, phy_addr, reg, data);
+ mutex_unlock(&bus->mdio_lock);
++#endif
+
+ return 0;
+ }
More information about the lede-commits
mailing list