From 070d8eb4d57038f3986027cd6d4610bd27ec2d59 Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Mon, 11 Aug 2025 04:34:00 -0400 Subject: [PATCH] realtek: mdio: rtl931x: move functions over to bus This commit repeats the mdio function relocation from the other targets. In short that means: - phy read/write functions are moved away from the phy driver - SerDes read/write functions are moved away from the dsa driver - All gets consolidated into the mdio driver (inside the ethernet driver) This is mostly a copy/paste to keep the changes small. The SerDes phy mapping and the simplification of the central bus functions will come later. Signed-off-by: Markus Stockhausen Link: https://github.com/openwrt/openwrt/pull/19743 Signed-off-by: Robert Marko --- .../include/asm/mach-rtl838x/mach-rtl83xx.h | 4 - .../drivers/net/dsa/rtl83xx/common.c | 2 - .../drivers/net/dsa/rtl83xx/rtl838x.c | 2 - .../drivers/net/dsa/rtl83xx/rtl839x.c | 1 - .../drivers/net/dsa/rtl83xx/rtl83xx.h | 5 - .../drivers/net/dsa/rtl83xx/rtl930x.c | 1 - .../drivers/net/dsa/rtl83xx/rtl931x.c | 144 ---------- .../drivers/net/ethernet/rtl838x_eth.c | 249 +++++++++++++++++- .../drivers/net/ethernet/rtl838x_eth.h | 3 + .../files-6.12/drivers/net/phy/rtl83xx-phy.c | 118 +++------ .../files-6.12/drivers/net/phy/rtl83xx-phy.h | 4 - 11 files changed, 277 insertions(+), 256 deletions(-) diff --git a/target/linux/realtek/files-6.12/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h b/target/linux/realtek/files-6.12/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h index 808cbd245c6..72abbadc1e1 100644 --- a/target/linux/realtek/files-6.12/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h +++ b/target/linux/realtek/files-6.12/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h @@ -414,8 +414,4 @@ struct rtl83xx_soc_info { int cpu_port; }; -/* rtl83xx-related functions used across subsystems */ -int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val); -int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val); - #endif /* _MACH_RTL838X_H_ */ diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/common.c index 9ccf1e1840b..eef52e4ac20 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/common.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/common.c @@ -29,8 +29,6 @@ extern const struct dsa_switch_ops rtl930x_switch_ops; extern const struct phylink_pcs_ops rtl83xx_pcs_ops; extern const struct phylink_pcs_ops rtl93xx_pcs_ops; -DEFINE_MUTEX(smi_lock); - int rtl83xx_port_get_stp_state(struct rtl838x_switch_priv *priv, int port) { u32 msti = 0; diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c index e0c8d73fa4f..2fed65adabc 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c @@ -23,8 +23,6 @@ #define RTL838X_VLAN_PORT_TAG_STS_CTRL_OTAG_STS_MASK GENMASK(3,2) #define RTL838X_VLAN_PORT_TAG_STS_CTRL_ITAG_STS_MASK GENMASK(1,0) -extern struct mutex smi_lock; - /* see_dal_maple_acl_log2PhyTmplteField and src/app/diag_v2/src/diag_acl.c */ /* Definition of the RTL838X-specific template field IDs as used in the PIE */ enum template_field_id { diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c index 87ba9e0fbc1..0d433c0b56b 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c @@ -20,7 +20,6 @@ #define RTL839X_VLAN_PORT_TAG_STS_CTRL_IGR_P_OTAG_KEEP_MASK GENMASK(1,1) #define RTL839X_VLAN_PORT_TAG_STS_CTRL_IGR_P_ITAG_KEEP_MASK GENMASK(0,0) -extern struct mutex smi_lock; extern struct rtl83xx_soc_info soc_info; /* Definition of the RTL839X-specific template field IDs as used in the PIE */ diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h index 7dff91e3b75..ef5230d92ed 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h @@ -192,11 +192,6 @@ void rtl931x_print_matrix(void); int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_lag_upper_info *info); int rtl83xx_lag_del(struct dsa_switch *ds, int group, int port); -/* phy functions that will need to be moved to the future mdio driver */ - -int rtl931x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val); -int rtl931x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val); - /* * TODO: The following functions are currently not in use. So compiler will complain if * they are static and not made available externally. To preserve them for future use diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c index d7f611f943b..f6a5affb437 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c @@ -33,7 +33,6 @@ /* get shift for given led in any set */ #define RTL930X_LED_SET_LEDX_SHIFT(x) (16 * (x % 2)) -extern struct mutex smi_lock; extern struct rtl83xx_soc_info soc_info; /* Definition of the RTL930X-specific template field IDs as used in the PIE */ diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c index 36103b43dd6..226b7ce5d3d 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c @@ -25,7 +25,6 @@ #define RTL931X_VLAN_PORT_TAG_ITPID_IDX_MASK GENMASK(2,1) #define RTL931X_VLAN_PORT_TAG_ITPID_KEEP_MASK GENMASK(0,0) -extern struct mutex smi_lock; extern struct rtl83xx_soc_info soc_info; /* Definition of the RTL931X-specific template field IDs as used in the PIE */ @@ -317,149 +316,6 @@ irqreturn_t rtl931x_switch_irq(int irq, void *dev_id) return IRQ_HANDLED; } -int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val) -{ - u32 v; - int err = 0; - - val &= 0xffff; - if (port > 63 || page > 4095 || reg > 31) - return -ENOTSUPP; - - mutex_lock(&smi_lock); - pr_debug("%s: writing to phy %d %d %d %d\n", __func__, port, page, reg, val); - /* Clear both port registers */ - sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2); - sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2 + 4); - sw_w32_mask(0, BIT(port % 32), RTL931X_SMI_INDRT_ACCESS_CTRL_2 + (port / 32) * 4); - - sw_w32_mask(0xffff, val, RTL931X_SMI_INDRT_ACCESS_CTRL_3); - - v = reg << 6 | page << 11 ; - sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); - - sw_w32(0x1ff, RTL931X_SMI_INDRT_ACCESS_CTRL_1); - - v |= BIT(4) | 1; /* Write operation and execute */ - sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); - - do { - } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x1); - - if (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x2) - err = -EIO; - - mutex_unlock(&smi_lock); - - return err; -} - -int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val) -{ - u32 v; - - if (port > 63 || page > 4095 || reg > 31) - return -ENOTSUPP; - - mutex_lock(&smi_lock); - - sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL); - - v = reg << 6 | page << 11 | 1; - sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); - - do { - } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x1); - - v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0); - *val = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3); - *val = (*val & 0xffff0000) >> 16; - - pr_debug("%s: port %d, page: %d, reg: %x, val: %x, v: %08x\n", - __func__, port, page, reg, *val, v); - - mutex_unlock(&smi_lock); - - return 0; -} - -/* Read an mmd register of the PHY */ -int rtl931x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val) -{ - int err = 0; - u32 v; - /* Select PHY register type - * If select 1G/10G MMD register type, registers EXT_PAGE, MAIN_PAGE and REG settings are don’t care. - * 0x0 Normal register (Clause 22) - * 0x1: 1G MMD register (MMD via Clause 22 registers 13 and 14) - * 0x2: 10G MMD register (MMD via Clause 45) - */ - int type = 2; - - mutex_lock(&smi_lock); - - /* Set PHY to access via port-number */ - sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL); - - /* Set MMD device number and register to write to */ - sw_w32(devnum << 16 | regnum, RTL931X_SMI_INDRT_ACCESS_MMD_CTRL); - - v = type << 2 | BIT(0); /* MMD-access-type | EXEC */ - sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); - - do { - v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0); - } while (v & BIT(0)); - - /* Check for error condition */ - if (v & BIT(1)) - err = -EIO; - - *val = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3) >> 16; - - pr_debug("%s: port %d, dev: %x, regnum: %x, val: %x (err %d)\n", __func__, - port, devnum, regnum, *val, err); - - mutex_unlock(&smi_lock); - - return err; -} - -/* Write to an mmd register of the PHY */ -int rtl931x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val) -{ - int err = 0; - u32 v; - int type = 2; - u64 pm; - - mutex_lock(&smi_lock); - - /* Set PHY to access via port-mask */ - pm = (u64)1 << port; - sw_w32((u32)pm, RTL931X_SMI_INDRT_ACCESS_CTRL_2); - sw_w32((u32)(pm >> 32), RTL931X_SMI_INDRT_ACCESS_CTRL_2 + 4); - - /* Set data to write */ - sw_w32_mask(0xffff, val, RTL931X_SMI_INDRT_ACCESS_CTRL_3); - - /* Set MMD device number and register to write to */ - sw_w32(devnum << 16 | regnum, RTL931X_SMI_INDRT_ACCESS_MMD_CTRL); - - v = BIT(4) | type << 2 | BIT(0); /* WRITE | MMD-access-type | EXEC */ - sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); - - do { - v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0); - } while (v & BIT(0)); - - pr_debug("%s: port %d, dev: %x, regnum: %x, val: %x (err %d)\n", __func__, - port, devnum, regnum, val, err); - mutex_unlock(&smi_lock); - - return err; -} - void rtl931x_print_matrix(void) { struct table_reg *r = rtl_table_get(RTL9310_TBL_2, 1); diff --git a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c index cc3166340bf..ddfdabacb64 100644 --- a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c +++ b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c @@ -69,10 +69,13 @@ extern int rtl931x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v); #define RTMDIO_ABS BIT(2) #define RTMDIO_PKG BIT(3) -#define RTMDIO_838X_BASE (0xe780) -#define RTMDIO_839X_BASE (0xa000) -#define RTMDIO_930X_SDS_INDACS_CMD (0x03B0) -#define RTMDIO_930X_SDS_INDACS_DATA (0x03B4) +/* MDIO SerDes registers */ +#define RTMDIO_838X_BASE (0xe780) +#define RTMDIO_839X_BASE (0xa000) +#define RTMDIO_930X_SDS_INDACS_CMD (0x03B0) +#define RTMDIO_930X_SDS_INDACS_DATA (0x03B4) +#define RTMDIO_931X_SERDES_INDRT_ACCESS_CTRL (0x5638) +#define RTMDIO_931X_SERDES_INDRT_DATA_CTRL (0x563C) struct p_hdr { uint8_t *buf; @@ -2394,6 +2397,228 @@ static int rtmdio_930x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val) return err; } +/* + * The RTL931x family has 14 "frontend" SerDes that are cascaded. All operations (e.g. reset) work + * on this frontend view while their registers are distributed over a total of least 26 background + * SerDes. Two types of SerDes exist: + * + * An "even" SerDes with numbers 0, 1, 2, 4, 6, 8, 10, 12 works on one background SerDes. + * + * The "odd" SerDes with numbers 3, 5, 7, 9, 11 & 13 SerDes consist of a total of 3 background + * SerDes (one analog and two XSGMII) each with its own page/register set. So it gives this + * mapping: + + * Frontend SerDes | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + * -----------------+------------------------------------------ + * Backend SerDes 1 | 0 1 2 3 6 7 10 11 14 15 18 19 22 23 + * Backend SerDes 2 | 0 1 2 4 6 8 10 12 14 16 18 20 22 24 + * Backend SerDes 3 | 0 1 2 5 6 9 10 13 14 17 18 21 22 25 + * + * Align this for readability by simulating a total of 576 pages and mix them as follows. + * + * frontend page "even" frontend SerDes "odd" frontend SerDes + * page 0x000-0x03f (analog): page 0x000-0x03f back SDS page 0x000-0x03f back SDS + * page 0x100-0x13f (XSGMII1): page 0x000-0x03f back SDS page 0x000-0x03f back SDS+1 + * page 0x200-0x23f (XSGMII2): page 0x000-0x03f back SDS page 0x000-0x03f back SDS+2 + */ + +int rtmdio_931x_read_sds_phy(int sds, int page, int regnum) +{ + u32 cmd = sds << 2 | page << 7 | regnum << 13 | 1; + int i, ret = -EIO; + + pr_debug("%s: phy_addr(SDS-ID) %d, phy_reg: %d\n", __func__, sds, regnum); + + mutex_lock(&rtmdio_lock_sds); + sw_w32(cmd, RTMDIO_931X_SERDES_INDRT_ACCESS_CTRL); + + for (i = 0; i < 100; i++) { + if (!(sw_r32(RTMDIO_931X_SERDES_INDRT_ACCESS_CTRL) & 0x1)) + break; + mdelay(1); + } + + if (i < 100) + ret = sw_r32(RTMDIO_931X_SERDES_INDRT_DATA_CTRL) & 0xffff; + + mutex_unlock(&rtmdio_lock_sds); + + pr_debug("%s: returning %08x\n", __func__, ret); + + return ret; +} + +int rtmdio_931x_write_sds_phy(int sds, int page, int regnum, u16 val) +{ + u32 cmd = sds << 2 | page << 7 | regnum << 13;; + int i, ret = -EIO; + + mutex_lock(&rtmdio_lock_sds); + sw_w32(cmd, RTMDIO_931X_SERDES_INDRT_ACCESS_CTRL); + sw_w32(val, RTMDIO_931X_SERDES_INDRT_DATA_CTRL); + + cmd = sw_r32(RTMDIO_931X_SERDES_INDRT_ACCESS_CTRL) | 0x3; + sw_w32(cmd, RTMDIO_931X_SERDES_INDRT_ACCESS_CTRL); + + for (i = 0; i < 100; i++) { + if (!(sw_r32(RTMDIO_931X_SERDES_INDRT_ACCESS_CTRL) & 0x1)) + break; + mdelay(1); + } + + mutex_unlock(&rtmdio_lock_sds); + + if (i < 100) + ret = 0; + + return ret; +} + +/* RTL931x specific MDIO functions */ + +static int rtmdio_931x_write_phy(u32 port, u32 page, u32 reg, u32 val) +{ + u32 v; + int err = 0; + + val &= 0xffff; + if (port > 63 || page > 4095 || reg > 31) + return -ENOTSUPP; + + mutex_lock(&rtmdio_lock); + pr_debug("%s: writing to phy %d %d %d %d\n", __func__, port, page, reg, val); + /* Clear both port registers */ + sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2); + sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2 + 4); + sw_w32_mask(0, BIT(port % 32), RTL931X_SMI_INDRT_ACCESS_CTRL_2 + (port / 32) * 4); + + sw_w32_mask(0xffff, val, RTL931X_SMI_INDRT_ACCESS_CTRL_3); + + v = reg << 6 | page << 11 ; + sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); + + sw_w32(0x1ff, RTL931X_SMI_INDRT_ACCESS_CTRL_1); + + v |= BIT(4) | 1; /* Write operation and execute */ + sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); + + do { + } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x1); + + if (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x2) + err = -EIO; + + mutex_unlock(&rtmdio_lock); + + return err; +} + +static int rtmdio_931x_read_phy(u32 port, u32 page, u32 reg, u32 *val) +{ + u32 v; + + if (port > 63 || page > 4095 || reg > 31) + return -ENOTSUPP; + + mutex_lock(&rtmdio_lock); + + sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL); + + v = reg << 6 | page << 11 | 1; + sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); + + do { + } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x1); + + v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0); + *val = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3); + *val = (*val & 0xffff0000) >> 16; + + pr_debug("%s: port %d, page: %d, reg: %x, val: %x, v: %08x\n", + __func__, port, page, reg, *val, v); + + mutex_unlock(&rtmdio_lock); + + return 0; +} + +/* Read an mmd register of the PHY */ +static int rtmdio_931x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val) +{ + int err = 0; + u32 v; + /* Select PHY register type + * If select 1G/10G MMD register type, registers EXT_PAGE, MAIN_PAGE and REG settings are don’t care. + * 0x0 Normal register (Clause 22) + * 0x1: 1G MMD register (MMD via Clause 22 registers 13 and 14) + * 0x2: 10G MMD register (MMD via Clause 45) + */ + int type = 2; + + mutex_lock(&rtmdio_lock); + + /* Set PHY to access via port-number */ + sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL); + + /* Set MMD device number and register to write to */ + sw_w32(devnum << 16 | regnum, RTL931X_SMI_INDRT_ACCESS_MMD_CTRL); + + v = type << 2 | BIT(0); /* MMD-access-type | EXEC */ + sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); + + do { + v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0); + } while (v & BIT(0)); + + /* Check for error condition */ + if (v & BIT(1)) + err = -EIO; + + *val = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3) >> 16; + + pr_debug("%s: port %d, dev: %x, regnum: %x, val: %x (err %d)\n", __func__, + port, devnum, regnum, *val, err); + + mutex_unlock(&rtmdio_lock); + + return err; +} + +/* Write to an mmd register of the PHY */ +static int rtmdio_931x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val) +{ + int err = 0; + u32 v; + int type = 2; + u64 pm; + + mutex_lock(&rtmdio_lock); + + /* Set PHY to access via port-mask */ + pm = (u64)1 << port; + sw_w32((u32)pm, RTL931X_SMI_INDRT_ACCESS_CTRL_2); + sw_w32((u32)(pm >> 32), RTL931X_SMI_INDRT_ACCESS_CTRL_2 + 4); + + /* Set data to write */ + sw_w32_mask(0xffff, val, RTL931X_SMI_INDRT_ACCESS_CTRL_3); + + /* Set MMD device number and register to write to */ + sw_w32(devnum << 16 | regnum, RTL931X_SMI_INDRT_ACCESS_MMD_CTRL); + + v = BIT(4) | type << 2 | BIT(0); /* WRITE | MMD-access-type | EXEC */ + sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); + + do { + v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0); + } while (v & BIT(0)); + + pr_debug("%s: port %d, dev: %x, regnum: %x, val: %x (err %d)\n", __func__, + port, devnum, regnum, val, err); + mutex_unlock(&rtmdio_lock); + + return err; +} + /* These are the core functions of our new Realtek SoC MDIO bus. */ static int rtmdio_read_c45(struct mii_bus *bus, int addr, int devnum, int regnum) @@ -2506,8 +2731,8 @@ static int rtmdio_93xx_read(struct mii_bus *bus, int addr, int regnum) priv->raw[addr] = (priv->page[addr] == priv->rawpage); if (priv->phy_is_internal[addr]) { - return rtl931x_read_sds_phy(priv->sds_id[addr], - priv->page[addr], regnum); + return rtmdio_931x_read_sds_phy(priv->sds_id[addr], + priv->page[addr], regnum); } err = (*priv->read_phy)(addr, priv->page[addr], regnum, &val); @@ -2594,8 +2819,8 @@ static int rtmdio_93xx_write(struct mii_bus *bus, int addr, int regnum, u16 val) if (!priv->raw[addr] && (regnum != RTMDIO_PAGE_SELECT || page == priv->rawpage)) { priv->raw[addr] = (page == priv->rawpage); if (priv->phy_is_internal[addr]) { - return rtl931x_write_sds_phy(priv->sds_id[addr], - page, regnum, val); + return rtmdio_931x_write_sds_phy(priv->sds_id[addr], + page, regnum, val); } err = (*priv->write_phy)(addr, page, regnum, val); @@ -2922,10 +3147,10 @@ static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv) priv->mii_bus->read = rtmdio_93xx_read; priv->mii_bus->write = rtmdio_93xx_write; priv->mii_bus->reset = rtmdio_931x_reset; - bus_priv->read_mmd_phy = rtl931x_read_mmd_phy; - bus_priv->write_mmd_phy = rtl931x_write_mmd_phy; - bus_priv->read_phy = rtl931x_read_phy; - bus_priv->write_phy = rtl931x_write_phy; + bus_priv->read_mmd_phy = rtmdio_931x_read_mmd_phy; + bus_priv->write_mmd_phy = rtmdio_931x_write_mmd_phy; + bus_priv->read_phy = rtmdio_931x_read_phy; + bus_priv->write_phy = rtmdio_931x_write_phy; bus_priv->cpu_port = RTL931X_CPU_PORT; bus_priv->rawpage = 0x1fff; break; diff --git a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h index edeea8f6e2b..a24cb891d20 100644 --- a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h +++ b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h @@ -466,4 +466,7 @@ int rtmdio_838x_write_phy(u32 port, u32 page, u32 reg, u32 val); int rtmdio_930x_read_sds_phy(int sds, int page, int regnum); int rtmdio_930x_write_sds_phy(int sds, int page, int regnum, u16 val); +int rtmdio_931x_read_sds_phy(int sds, int page, int regnum); +int rtmdio_931x_write_sds_phy(int sds, int page, int regnum, u16 val); + #endif /* _RTL838X_ETH_H */ diff --git a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c index 98066bf233e..9b51a97abf9 100644 --- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c +++ b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c @@ -19,7 +19,7 @@ #include "rtl83xx-phy.h" extern struct rtl83xx_soc_info soc_info; -extern struct mutex smi_lock; + extern int phy_package_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val); extern int phy_package_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val); extern int phy_package_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum); @@ -28,6 +28,9 @@ extern int phy_package_read_paged(struct phy_device *phydev, int page, u32 regnu extern int rtmdio_930x_read_sds_phy(int sds, int page, int regnum); extern int rtmdio_930x_write_sds_phy(int sds, int page, int regnum, u16 val); +extern int rtmdio_931x_read_sds_phy(int sds, int page, int regnum); +extern int rtmdio_931x_write_sds_phy(int sds, int page, int regnum, u16 val); + #define PHY_PAGE_2 2 #define PHY_PAGE_4 4 @@ -295,53 +298,6 @@ static u32 rtl9300_sds_mode_get(int sds_num) return v & RTL930X_SDS_MASK; } -int rtl931x_read_sds_phy(int phy_addr, int page, int phy_reg) -{ - int i; - u32 cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 1; - - pr_debug("%s: phy_addr(SDS-ID) %d, phy_reg: %d\n", __func__, phy_addr, phy_reg); - sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL); - - for (i = 0; i < 100; i++) { - if (!(sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) & 0x1)) - break; - mdelay(1); - } - - if (i >= 100) - return -EIO; - - pr_debug("%s: returning %04x\n", __func__, sw_r32(RTL931X_SERDES_INDRT_DATA_CTRL) & 0xffff); - - return sw_r32(RTL931X_SERDES_INDRT_DATA_CTRL) & 0xffff; -} - -int rtl931x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v) -{ - int i; - u32 cmd; - - cmd = phy_addr << 2 | page << 7 | phy_reg << 13; - sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL); - - sw_w32(v, RTL931X_SERDES_INDRT_DATA_CTRL); - - cmd = sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) | 0x3; - sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL); - - for (i = 0; i < 100; i++) { - if (!(sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) & 0x1)) - break; - mdelay(1); - } - - if (i >= 100) - return -EIO; - - return 0; -} - /* Read the link and speed status of the 2 internal SGMII/1000Base-X * ports of the RTL838x SoCs */ @@ -2949,18 +2905,18 @@ static void rtl9310_sds_field_w(int sds, u32 page, u32 reg, int end_bit, int sta if (l < 32) { u32 mask = BIT(l) - 1; - data = rtl931x_read_sds_phy(sds, page, reg); + data = rtmdio_931x_read_sds_phy(sds, page, reg); data &= ~(mask << start_bit); data |= (v & mask) << start_bit; } - rtl931x_write_sds_phy(sds, page, reg, data); + rtmdio_931x_write_sds_phy(sds, page, reg, data); } static u32 rtl9310_sds_field_r(int sds, u32 page, u32 reg, int end_bit, int start_bit) { int l = end_bit - start_bit + 1; - u32 v = rtl931x_read_sds_phy(sds, page, reg); + u32 v = rtmdio_931x_read_sds_phy(sds, page, reg); if (l >= 32) return v; @@ -3187,9 +3143,9 @@ static void rtl931x_cmu_type_set(u32 asds, phy_interface_t mode, int chiptype) __func__, cmu_type, cmu_page, frc_cmu_spd, lane, asds); if (cmu_type == 1) { - pr_info("%s A CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7)); + pr_info("%s A CMU page 0x28 0x7 %08x\n", __func__, rtmdio_931x_read_sds_phy(asds, 0x28, 0x7)); rtl9310_sds_field_w(asds, cmu_page, 0x7, 15, 15, 0); - pr_info("%s B CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7)); + pr_info("%s B CMU page 0x28 0x7 %08x\n", __func__, rtmdio_931x_read_sds_phy(asds, 0x28, 0x7)); if (chiptype) { rtl9310_sds_field_w(asds, cmu_page, 0xd, 14, 14, 0); } @@ -3201,7 +3157,7 @@ static void rtl931x_cmu_type_set(u32 asds, phy_interface_t mode, int chiptype) rtl9310_sds_field_w(evenSds, 0x20, 0x12, 15, 13, frc_cmu_spd); } - pr_info("%s CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7)); + pr_info("%s CMU page 0x28 0x7 %08x\n", __func__, rtmdio_931x_read_sds_phy(asds, 0x28, 0x7)); return; } @@ -3212,15 +3168,15 @@ static void rtl931x_sds_rx_rst(u32 sds) if (sds < 2) return; - rtl931x_write_sds_phy(asds, 0x2e, 0x12, 0x2740); - rtl931x_write_sds_phy(asds, 0x2f, 0x0, 0x0); - rtl931x_write_sds_phy(asds, 0x2f, 0x2, 0x2010); - rtl931x_write_sds_phy(asds, 0x20, 0x0, 0xc10); + rtmdio_931x_write_sds_phy(asds, 0x2e, 0x12, 0x2740); + rtmdio_931x_write_sds_phy(asds, 0x2f, 0x0, 0x0); + rtmdio_931x_write_sds_phy(asds, 0x2f, 0x2, 0x2010); + rtmdio_931x_write_sds_phy(asds, 0x20, 0x0, 0xc10); - rtl931x_write_sds_phy(asds, 0x2e, 0x12, 0x27c0); - rtl931x_write_sds_phy(asds, 0x2f, 0x0, 0xc000); - rtl931x_write_sds_phy(asds, 0x2f, 0x2, 0x6010); - rtl931x_write_sds_phy(asds, 0x20, 0x0, 0xc30); + rtmdio_931x_write_sds_phy(asds, 0x2e, 0x12, 0x27c0); + rtmdio_931x_write_sds_phy(asds, 0x2f, 0x0, 0xc000); + rtmdio_931x_write_sds_phy(asds, 0x2f, 0x2, 0x6010); + rtmdio_931x_write_sds_phy(asds, 0x20, 0x0, 0xc30); mdelay(50); } @@ -3314,17 +3270,17 @@ void rtl931x_sds_init(u32 sds, phy_interface_t mode) val = rtl9310_sds_field_r(asds, 0x1F, 0x9, 11, 6); pr_info("%s: fibermode %08X stored mode 0x%x analog SDS %d", __func__, - rtl931x_read_sds_phy(asds, 0x1f, 0x9), val, asds); + rtmdio_931x_read_sds_phy(asds, 0x1f, 0x9), val, asds); pr_info("%s: SGMII mode %08X in 0x24 0x9 analog SDS %d", __func__, - rtl931x_read_sds_phy(asds, 0x24, 0x9), asds); + rtmdio_931x_read_sds_phy(asds, 0x24, 0x9), asds); pr_info("%s: CMU mode %08X stored even SDS %d", __func__, - rtl931x_read_sds_phy(asds & ~1, 0x20, 0x12), asds & ~1); + rtmdio_931x_read_sds_phy(asds & ~1, 0x20, 0x12), asds & ~1); pr_info("%s: serdes_mode_ctrl %08X", __func__, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2)); - pr_info("%s CMU page 0x24 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x24, 0x7)); - pr_info("%s CMU page 0x26 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x26, 0x7)); - pr_info("%s CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7)); - pr_info("%s XSG page 0x0 0xe %08x\n", __func__, rtl931x_read_sds_phy(dSds, 0x0, 0xe)); - pr_info("%s XSG2 page 0x0 0xe %08x\n", __func__, rtl931x_read_sds_phy(dSds + 1, 0x0, 0xe)); + pr_info("%s CMU page 0x24 0x7 %08x\n", __func__, rtmdio_931x_read_sds_phy(asds, 0x24, 0x7)); + pr_info("%s CMU page 0x26 0x7 %08x\n", __func__, rtmdio_931x_read_sds_phy(asds, 0x26, 0x7)); + pr_info("%s CMU page 0x28 0x7 %08x\n", __func__, rtmdio_931x_read_sds_phy(asds, 0x28, 0x7)); + pr_info("%s XSG page 0x0 0xe %08x\n", __func__, rtmdio_931x_read_sds_phy(dSds, 0x0, 0xe)); + pr_info("%s XSG2 page 0x0 0xe %08x\n", __func__, rtmdio_931x_read_sds_phy(dSds + 1, 0x0, 0xe)); model_info = sw_r32(RTL93XX_MODEL_NAME_INFO); if ((model_info >> 4) & 0x1) { @@ -3340,7 +3296,7 @@ void rtl931x_sds_init(u32 sds, phy_interface_t mode) dSds = (sds - 1) * 2; pr_info("%s: 2.5gbit %08X dsds %d", __func__, - rtl931x_read_sds_phy(dSds, 0x1, 0x14), dSds); + rtmdio_931x_read_sds_phy(dSds, 0x1, 0x14), dSds); pr_info("%s: RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR 0x%08X\n", __func__, sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR)); ori = sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR); @@ -3377,13 +3333,13 @@ void rtl931x_sds_init(u32 sds, phy_interface_t mode) rtl9310_sds_field_w(asds, 0x6, 0x2, 12, 12, 1); for (int i = 0; i < sizeof(sds_config_10p3125g_type1) / sizeof(sds_config); ++i) { - rtl931x_write_sds_phy(asds, sds_config_10p3125g_type1[i].page - 0x4, sds_config_10p3125g_type1[i].reg, sds_config_10p3125g_type1[i].data); + rtmdio_931x_write_sds_phy(asds, sds_config_10p3125g_type1[i].page - 0x4, sds_config_10p3125g_type1[i].reg, sds_config_10p3125g_type1[i].data); } evenSds = asds - (asds % 2); for (int i = 0; i < sizeof(sds_config_10p3125g_cmu_type1) / sizeof(sds_config); ++i) { - rtl931x_write_sds_phy(evenSds, + rtmdio_931x_write_sds_phy(evenSds, sds_config_10p3125g_cmu_type1[i].page - 0x4, sds_config_10p3125g_cmu_type1[i].reg, sds_config_10p3125g_cmu_type1[i].data); } @@ -3400,13 +3356,13 @@ void rtl931x_sds_init(u32 sds, phy_interface_t mode) rtl9310_sds_field_w(asds, 0x2f, 0x1, 11, 0, 0x00); rtl9310_sds_field_w(asds, 0x2e, 0xf, 12, 6, 0x7F); - rtl931x_write_sds_phy(asds, 0x2f, 0x12, 0xaaa); + rtmdio_931x_write_sds_phy(asds, 0x2f, 0x12, 0xaaa); rtl931x_sds_rx_rst(sds); - rtl931x_write_sds_phy(asds, 0x7, 0x10, op_code); - rtl931x_write_sds_phy(asds, 0x6, 0x1d, 0x0480); - rtl931x_write_sds_phy(asds, 0x6, 0xe, 0x0400); + rtmdio_931x_write_sds_phy(asds, 0x7, 0x10, op_code); + rtmdio_931x_write_sds_phy(asds, 0x6, 0x1d, 0x0480); + rtmdio_931x_write_sds_phy(asds, 0x6, 0xe, 0x0400); } break; @@ -3458,16 +3414,16 @@ void rtl931x_sds_init(u32 sds, phy_interface_t mode) if (sds >= 2 && sds <= 13) { if (chiptype) - rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx_type1[sds - 2]); + rtmdio_931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx_type1[sds - 2]); else { val = 0xa0000; sw_w32(val, RTL93XX_CHIP_INFO); val = sw_r32(RTL93XX_CHIP_INFO); if (val & BIT(28)) /* consider 9311 etc. RTL9313_CHIP_ID == HWP_CHIP_ID(unit)) */ { - rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx2[sds - 2]); + rtmdio_931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx2[sds - 2]); } else { - rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx[sds - 2]); + rtmdio_931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx[sds - 2]); } val = 0; sw_w32(val, RTL93XX_CHIP_INFO); @@ -3523,7 +3479,7 @@ int rtl931x_sds_cmu_band_get(int sds, phy_interface_t mode) sds -= (sds % 2); asds = rtl931x_get_analog_sds(sds); page += 1; - rtl931x_write_sds_phy(asds, 0x1f, 0x02, 73); + rtmdio_931x_write_sds_phy(asds, 0x1f, 0x02, 73); rtl9310_sds_field_w(asds, page, 0x5, 15, 15, 1); band = rtl9310_sds_field_r(asds, 0x1f, 0x15, 8, 3); diff --git a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h index f57eb508675..652e27a5c59 100644 --- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h +++ b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h @@ -60,16 +60,12 @@ struct __attribute__ ((__packed__)) fw_header { #define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C) /* Registers of the internal SerDes of the 9310 */ -#define RTL931X_SERDES_INDRT_ACCESS_CTRL (0x5638) -#define RTL931X_SERDES_INDRT_DATA_CTRL (0x563C) #define RTL931X_SERDES_MODE_CTRL (0x13cc) #define RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR (0x13F4) #define RTL931X_MAC_SERDES_MODE_CTRL(sds) (0x136C + (((sds) << 2))) int rtl9300_serdes_setup(int port, int sds_num, phy_interface_t phy_mode); -int rtl931x_read_sds_phy(int phy_addr, int page, int phy_reg); -int rtl931x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v); int rtl931x_sds_cmu_band_get(int sds, phy_interface_t mode); void rtl931x_sds_init(u32 sds, phy_interface_t mode); -- 2.47.2