From 29b088ef21e96354801c9819acb0b604755f33e9 Mon Sep 17 00:00:00 2001 From: Ken Date: Mon, 28 Apr 2025 13:55:49 +0800 Subject: [PATCH] qca-wifi-7: fix WF189 WAN port link issues Fixes: WIFI-14546 Signed-off-by: Ken --- .../ipq53xx/dts/ipq5332-cig-wf189.dts | 1 + .../files-6.1/drivers/net/phy/rtk/rtk_phy.c | 13 +- ...-rtl-phy-driver-for-c45-mdio-read-wr.patch | 262 ++++++++++++++++++ 3 files changed, 266 insertions(+), 10 deletions(-) mode change 100755 => 100644 feeds/qca-wifi-7/ipq53xx/files-6.1/drivers/net/phy/rtk/rtk_phy.c create mode 100644 feeds/qca-wifi-7/qca-ssdk-qca/patches/0006-qca-ssdk-Fix-10G-rtl-phy-driver-for-c45-mdio-read-wr.patch diff --git a/feeds/qca-wifi-7/ipq53xx/dts/ipq5332-cig-wf189.dts b/feeds/qca-wifi-7/ipq53xx/dts/ipq5332-cig-wf189.dts index 54558a392..fc3a6526b 100644 --- a/feeds/qca-wifi-7/ipq53xx/dts/ipq5332-cig-wf189.dts +++ b/feeds/qca-wifi-7/ipq53xx/dts/ipq5332-cig-wf189.dts @@ -47,6 +47,7 @@ phy0: ethernet-phy@0 { reg = <8>; + compatible ="ethernet-phy-ieee802.3-c45"; }; phy1: ethernet-phy@1 { diff --git a/feeds/qca-wifi-7/ipq53xx/files-6.1/drivers/net/phy/rtk/rtk_phy.c b/feeds/qca-wifi-7/ipq53xx/files-6.1/drivers/net/phy/rtk/rtk_phy.c old mode 100755 new mode 100644 index 94a8825e2..bd4de0df2 --- a/feeds/qca-wifi-7/ipq53xx/files-6.1/drivers/net/phy/rtk/rtk_phy.c +++ b/feeds/qca-wifi-7/ipq53xx/files-6.1/drivers/net/phy/rtk/rtk_phy.c @@ -48,6 +48,9 @@ static int rtl826xb_get_features(struct phy_device *phydev) linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, phydev->supported); + linkmode_clear_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, + phydev->supported); + return 0; } @@ -80,7 +83,6 @@ static int rtkphy_config_init(struct phy_device *phydev) case REALTEK_PHY_ID_RTL8261N: case REALTEK_PHY_ID_RTL8264B: phydev_info(phydev, "%s:%u [RTL8261N/RTL826XB] phy_id: 0x%X PHYAD:%d\n", __FUNCTION__, __LINE__, phydev->drv->phy_id, phydev->mdio.addr); - phy_modify_mmd_changed(phydev, 7, 0x20, BIT(12), 0); #if 1 /* toggle reset */ phy_modify_mmd_changed(phydev, 30, 0x145, BIT(0) , 1); @@ -213,7 +215,6 @@ static int rtkphy_c45_aneg_done(struct phy_device *phydev) static int rtkphy_c45_read_status(struct phy_device *phydev) { int ret = 0, status = 0; - uint16_t local; phydev->speed = SPEED_UNKNOWN; phydev->duplex = DUPLEX_UNKNOWN; phydev->pause = 0; @@ -232,9 +233,6 @@ static int rtkphy_c45_read_status(struct phy_device *phydev) if (ret) return ret; - phy_write_mmd(phydev, 7, 0x20, 0x181); - local = phy_read_mmd(phydev, 7, 0x20); - status = phy_read_mmd(phydev, 31, 0xA414); if (status < 0) return status; @@ -242,11 +240,6 @@ static int rtkphy_c45_read_status(struct phy_device *phydev) phydev->lp_advertising, status & BIT(11)); phy_resolve_aneg_linkmode(phydev); - if((phydev->speed == 10000) && (local == 0x181)) - { - phydev->speed = 5000; - phydev->duplex = DUPLEX_FULL; - } } else { diff --git a/feeds/qca-wifi-7/qca-ssdk-qca/patches/0006-qca-ssdk-Fix-10G-rtl-phy-driver-for-c45-mdio-read-wr.patch b/feeds/qca-wifi-7/qca-ssdk-qca/patches/0006-qca-ssdk-Fix-10G-rtl-phy-driver-for-c45-mdio-read-wr.patch new file mode 100644 index 000000000..845377ed8 --- /dev/null +++ b/feeds/qca-wifi-7/qca-ssdk-qca/patches/0006-qca-ssdk-Fix-10G-rtl-phy-driver-for-c45-mdio-read-wr.patch @@ -0,0 +1,262 @@ +From 9181fe30babf33002126dd4367fb314077827609 Mon Sep 17 00:00:00 2001 +From: huangyunxiang +Date: Mon, 28 Apr 2025 09:51:00 +0800 +Subject: [PATCH] qca-ssdk Fix 10G rtl phy driver for c45 mdio read/write and + set fix ablity set + +--- + include/hsl/hsl.h | 4 +- + include/init/ssdk_plat.h | 7 ++ + src/hsl/phy/rtl826xb_phy.c | 73 +++++++++++-------- + src/init/ssdk_init.c | 2 + + src/init/ssdk_plat.c | 54 ++++++++++++++ + 5 files changed, 106 insertions(+), 34 deletions(-) + +diff --git a/include/hsl/hsl.h b/include/hsl/hsl.h +index e6b49d6b55..6e82450991 100644 +--- a/include/hsl/hsl.h ++++ b/include/hsl/hsl.h +@@ -193,7 +193,7 @@ do { \ + rv = SW_NOT_INITIALIZED; \ + } \ + } while (0); +- ++#endif + #define HSL_PHY_GET(rv, dev, phy_addr, reg, value) \ + do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ +@@ -213,7 +213,7 @@ do { \ + rv = SW_NOT_INITIALIZED; \ + } \ + } while (0); +-#endif ++//#endif + /*qca808x_start*/ + #if (defined(API_LOCK) \ + && (defined(HSL_STANDALONG) || (defined(KERNEL_MODULE) && defined(USER_MODE)))) +diff --git a/include/init/ssdk_plat.h b/include/init/ssdk_plat.h +index 92596477af..9fe5bb824a 100644 +--- a/include/init/ssdk_plat.h ++++ b/include/init/ssdk_plat.h +@@ -471,6 +471,13 @@ a_uint32_t qca_mii_read(a_uint32_t dev_id, a_uint32_t reg); + void qca_mii_write(a_uint32_t dev_id, a_uint32_t reg, a_uint32_t val); + int qca_mii_update(a_uint32_t dev_id, a_uint32_t reg, a_uint32_t mask, a_uint32_t val); + ++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); ++sw_error_t ++qca_ar8327_phy_write(a_uint32_t dev_id, a_uint32_t phy_addr, ++ a_uint32_t reg, a_uint16_t data); ++ + a_uint32_t __qca_mii_read(a_uint32_t dev_id, a_uint32_t reg); + void __qca_mii_write(a_uint32_t dev_id, a_uint32_t reg, a_uint32_t val); + int __qca_mii_update(a_uint32_t dev_id, a_uint32_t reg, a_uint32_t mask, a_uint32_t val); +diff --git a/src/hsl/phy/rtl826xb_phy.c b/src/hsl/phy/rtl826xb_phy.c +index a336348aa9..4eaa1ea4f1 100644 +--- a/src/hsl/phy/rtl826xb_phy.c ++++ b/src/hsl/phy/rtl826xb_phy.c +@@ -48,46 +48,66 @@ void rtl826xb_phy_lock_init(void) + + static a_uint16_t rtl826x_phy_mmd_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_mmd, a_uint16_t reg_id) + { ++ a_uint16_t phy_data; ++ sw_error_t rv; + a_uint32_t reg_id_c45 = RTL826XB_REG_ADDRESS(reg_mmd, reg_id); +- +- return __hsl_phy_mii_reg_read(dev_id, phy_id, reg_id_c45); ++ HSL_PHY_GET(rv, dev_id, phy_id, reg_id_c45, &phy_data); ++ return phy_data; + } + + + static sw_error_t rtl826x_phy_mmd_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_mmd, a_uint16_t reg_id, a_uint16_t reg_val) + { ++ sw_error_t rv; + a_uint32_t reg_id_c45 = RTL826XB_REG_ADDRESS(reg_mmd, reg_id); +- +- return __hsl_phy_mii_reg_write(dev_id, phy_id, reg_id_c45, reg_val); ++ HSL_PHY_SET(rv, dev_id, phy_id, reg_id_c45, reg_val); ++ return rv; + } + + + static a_uint16_t rtl826x_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg) + { +- return __hsl_phy_mii_reg_read(dev_id, phy_id, reg); ++ a_uint16_t phy_data; ++ sw_error_t rv; ++ HSL_PHY_GET(rv, dev_id, phy_id, reg, &phy_data); ++ return phy_data; + } + + + static sw_error_t rtl826x_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg, a_uint16_t reg_val) + { +- return __hsl_phy_mii_reg_write(dev_id, phy_id, reg, reg_val); ++ sw_error_t rv; ++ ++ HSL_PHY_SET(rv, dev_id, phy_id, reg, reg_val); ++ ++ return rv; + } + + + static a_int16_t hal_miim_mmd_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t mmdAddr, a_uint16_t mmdReg) + { ++ a_uint16_t phy_data; ++ sw_error_t rv; ++ + a_uint32_t reg_id_c45 = RTL826XB_REG_ADDRESS(mmdAddr, mmdReg); + +- return __hsl_phy_mii_reg_read(dev_id, phy_id, reg_id_c45); ++ HSL_PHY_GET(rv, dev_id, phy_id, reg_id_c45, &phy_data); ++ ++ return phy_data; + } + + + + static a_int32_t hal_miim_mmd_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t mmdAddr, a_uint16_t mmdReg, a_uint16_t phy_data) + { ++ sw_error_t rv; ++ + a_uint32_t reg_id_c45 = RTL826XB_REG_ADDRESS(mmdAddr, mmdReg); + +- return __hsl_phy_mii_reg_write(dev_id, phy_id, reg_id_c45, phy_data); ++ HSL_PHY_SET(rv, dev_id, phy_id, reg_id_c45, phy_data); ++ ++ ++ return rv; + } + + +@@ -1281,34 +1301,23 @@ phy_826xb_autoNegoAbility_set(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t a + hsl_phy_phydev_autoneg_update(dev_id, phy_id, A_TRUE, autoneg); + + phyData = phy_common_general_reg_mmd_get(dev_id, phy_id, PHY_MMD_AN, 16); ++ phyData &= (~(0x0020 | 0x0040 | FAL_PHY_ADV_100TX_HD | FAL_PHY_ADV_100TX_FD | FAL_PHY_ADV_PAUSE | FAL_PHY_ADV_ASY_PAUSE)); ++ phyData |= (autoneg & FAL_PHY_ADV_100TX_HD) ? (FAL_PHY_ADV_100TX_HD) : (0); ++ phyData |= ((autoneg & FAL_PHY_ADV_100TX_FD)) ? (FAL_PHY_ADV_100TX_FD) : (0); ++// phyData |= (autoneg & FAL_PHY_ADV_PAUSE) ? (FAL_PHY_ADV_PAUSE) : (0); ++// phyData |= (autoneg & FAL_PHY_ADV_ASY_PAUSE) ? (FAL_PHY_ADV_ASY_PAUSE) : (0); + +- phyData &= (~(0x0020 | 0x0040 | 0x0080 | 0x0100 | 0x0400 | 0x0800)); +- phyData |= ((autoneg & 1 << 1)) ? (0x0040) : (0); +- phyData |= ((autoneg & 1 << 2)) ? (0x0080) : (0); +- phyData |= ((autoneg & 1 << 3)) ? (0x0100) : (0); +- phyData |= ((autoneg & 1 << 4)) ? (0x0400) : (0); +- phyData |= ((autoneg & 1 << 5)) ? (0x0800) : (0); +-// phyData |= ((autoneg & 1 << 9)) ? (0x0400) : (0); +-// phyData |= ((autoneg & 1 << 10)) ? (0x0800) : (0); +- +- phy_common_general_reg_mmd_set(dev_id, phy_id, PHY_MMD_AN, 16, phyData); +- ++ phy_common_general_reg_mmd_set(dev_id, phy_id, PHY_MMD_AN, 16, phyData); + phyData = phy_common_general_reg_mmd_get(dev_id, phy_id, PHY_MMD_AN, 32); ++ phyData &= (~(FAL_PHY_ADV_2500T_FD | FAL_PHY_ADV_5000T_FD | FAL_PHY_ADV_10000T_FD)); ++ phyData |= (autoneg & FAL_PHY_ADV_2500T_FD) ? (FAL_PHY_ADV_2500T_FD) : (0); ++ phyData |= (autoneg & FAL_PHY_ADV_5000T_FD) ? (FAL_PHY_ADV_5000T_FD) : (0); ++// phyData |= (autoneg & FAL_PHY_ADV_10000T_FD) ? (FAL_PHY_ADV_10000T_FD) : (0); + +- phyData &= (~(0x4000 | 0x2000 | 0x1000)); +- phyData |= (autoneg & 1 << 12) ? (0x0080) : (0); +- phyData |= (autoneg & 1 << 13) ? (0x0100) : (0); +- phyData |= (autoneg & 1 << 14) ? (0x1000) : (0); +- +- phy_common_general_reg_mmd_set(dev_id, phy_id, PHY_MMD_AN, 32, phyData); +- +- ++ phy_common_general_reg_mmd_set(dev_id, phy_id, PHY_MMD_AN, 32, phyData); + phyData = phy_common_general_reg_mmd_get(dev_id, phy_id, PHY_MMD_VEND2, 0xA412); +- +- +- phyData &= (~(0x0100 | 0x0200)); +- phyData |= (autoneg & 1 << 9) ? (0x0200) : (0); +-// phyData |= (autoneg & 1 << 5) ? (0x0200) : (0); ++ phyData &= (~(0x0100 | FAL_PHY_ADV_1000T_FD)); ++ phyData |= (autoneg & FAL_PHY_ADV_1000T_FD) ? (FAL_PHY_ADV_1000T_FD) : (0); + + phy_common_general_reg_mmd_set(dev_id, phy_id, PHY_MMD_VEND2, 0xA412, phyData); + +diff --git a/src/init/ssdk_init.c b/src/init/ssdk_init.c +index 59f5fc43c0..fb6288db73 100644 +--- a/src/init/ssdk_init.c ++++ b/src/init/ssdk_init.c +@@ -2210,6 +2210,8 @@ static void ssdk_cfg_default_init(ssdk_init_cfg *cfg) + memset(cfg, 0, sizeof(ssdk_init_cfg)); + cfg->cpu_mode = HSL_CPU_1; + cfg->nl_prot = 30; ++ cfg->reg_func.mdio_set = qca_ar8327_phy_write; ++ cfg->reg_func.mdio_get = qca_ar8327_phy_read; + /*qca808x_end*/ + + cfg->reg_func.header_reg_set = qca_switch_reg_write; +diff --git a/src/init/ssdk_plat.c b/src/init/ssdk_plat.c +index 87bd0dbaf1..24285c8de7 100644 +--- a/src/init/ssdk_plat.c ++++ b/src/init/ssdk_plat.c +@@ -458,6 +458,60 @@ int __qca_mii_update(a_uint32_t dev_id, a_uint32_t reg, a_uint32_t mask, a_uint3 + return 0; + } + ++a_bool_t ++phy_addr_validation_check(a_uint32_t phy_addr) ++{ ++ ++ if ((phy_addr > SSDK_PHY_BCAST_ID) || (phy_addr < SSDK_PHY_MIN_ID)) ++ return A_FALSE; ++ else ++ return A_TRUE; ++} ++ ++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) ++{ ++ struct mii_bus *bus = NULL; ++ ++ if (A_TRUE != phy_addr_validation_check (phy_addr)) ++ { ++ return SW_BAD_PARAM; ++ } ++ ++ bus = ssdk_phy_miibus_get(dev_id, phy_addr); ++ if (!bus) ++ return SW_NOT_SUPPORTED; ++ ++ mutex_lock(&bus->mdio_lock); ++ *data = __mdiobus_read(bus, phy_addr, reg); ++ mutex_unlock(&bus->mdio_lock); ++ ++ return 0; ++} ++ ++sw_error_t ++qca_ar8327_phy_write(a_uint32_t dev_id, a_uint32_t phy_addr, ++ a_uint32_t reg, a_uint16_t data) ++{ ++ struct mii_bus *bus = NULL; ++ ++ if (A_TRUE != phy_addr_validation_check (phy_addr)) ++ { ++ return SW_BAD_PARAM; ++ } ++ ++ bus = ssdk_phy_miibus_get(dev_id, phy_addr); ++ if (!bus) ++ return SW_NOT_SUPPORTED; ++ ++ mutex_lock(&bus->mdio_lock); ++ __mdiobus_write(bus, phy_addr, reg, data); ++ mutex_unlock(&bus->mdio_lock); ++ ++ return 0; ++} ++ + a_uint32_t qca_mii_read(a_uint32_t dev_id, a_uint32_t reg) + { + a_uint32_t val = 0xffffffff; +-- +2.34.1 +