diff --git a/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c b/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c index c826966d38..5107e73dae 100644 --- a/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c +++ b/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c @@ -58,17 +58,6 @@ #define RTMDIO_931X_SMI_PORT_POLLING_SEL (0x0C9C) #define RTMDIO_931X_SMI_PORT_ADDR (0x0C74) -/* 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) - #define sw_r32(reg) readl(RTMDIO_SW_BASE + reg) #define sw_w32(val, reg) writel(val, RTMDIO_SW_BASE + reg) #define sw_w32_mask(clear, set, reg) sw_w32((sw_r32(reg) & ~(clear)) | (set), reg) @@ -140,7 +129,6 @@ */ DEFINE_MUTEX(rtmdio_lock); -DEFINE_MUTEX(rtmdio_lock_sds); struct rtmdio_bus_priv { const struct rtmdio_config *cfg; @@ -148,9 +136,7 @@ struct rtmdio_bus_priv { bool raw[RTMDIO_MAX_PORT]; int smi_bus[RTMDIO_MAX_PORT]; u8 smi_addr[RTMDIO_MAX_PORT]; - int sds_id[RTMDIO_MAX_PORT]; bool smi_bus_isc45[RTMDIO_MAX_SMI_BUS]; - bool phy_is_internal[RTMDIO_MAX_PORT]; phy_interface_t interfaces[RTMDIO_MAX_PORT]; }; @@ -159,56 +145,11 @@ struct rtmdio_config { int raw_page; int (*read_mmd_phy)(u32 port, u32 addr, u32 reg, u32 *val); int (*read_phy)(u32 port, u32 page, u32 reg, u32 *val); - int (*read_sds_phy)(int sds, int page, int regnum); int (*reset)(struct mii_bus *bus); int (*write_mmd_phy)(u32 port, u32 addr, u32 reg, u32 val); int (*write_phy)(u32 port, u32 page, u32 reg, u32 val); - int (*write_sds_phy)(int sds, int page, int regnum, u16 val); }; -/* SerDes reader/writer functions for the ports without external phy. */ - -/* - * The RTL838x has 6 SerDes. The 16 bit registers start at 0xbb00e780 and are mapped directly into - * 32 bit memory addresses. High 16 bits are always empty. A "lower" memory block serves pages 0/3 - * a "higher" memory block pages 1/2. - */ - -static int rtmdio_838x_reg_offset(int sds, int page, int regnum) -{ - if (sds < 0 || sds > 5) - return -EINVAL; - - if (page == 0 || page == 3) - return (sds << 9) + (page << 7) + (regnum << 2); - else if (page == 1 || page == 2) - return 0xb80 + (sds << 8) + (page << 7) + (regnum << 2); - - return -EINVAL; -} - -static int rtmdio_838x_read_sds_phy(int sds, int page, int regnum) -{ - int offset = rtmdio_838x_reg_offset(sds, page, regnum); - - if (offset < 0) - return offset; - - return sw_r32(RTMDIO_838X_BASE + offset) & GENMASK(15, 0); -} - -static int rtmdio_838x_write_sds_phy(int sds, int page, int regnum, u16 val) -{ - int offset = rtmdio_838x_reg_offset(sds, page, regnum); - - if (offset < 0) - return offset; - - sw_w32(val, RTMDIO_838X_BASE + offset); - - return 0; -} - /* RTL838x specific MDIO functions */ static int rtmdio_838x_smi_wait_op(int timeout) @@ -334,107 +275,6 @@ static int rtmdio_838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val) return err; } -/* - * The RTL839x has 14 SerDes starting at 0xbb00a000. 0-7, 10, 11 are 5GBit, 8, 9, 12, 13 are - * 10 GBit. Two adjacent SerDes are tightly coupled and share a 1024 bytes register area. Per 32 - * bit address two registers are stored. The first register is stored in the lower 2 bytes ("on - * the right" due to big endian) and the second register in the upper 2 bytes. The following - * register areas are known: - * - * - XSG0 (4 pages @ offset 0x000): for even SerDes - * - XSG1 (4 pages @ offset 0x100): for odd SerDes - * - TGRX (4 pages @ offset 0x200): for even 10G SerDes - * - ANA_RG (2 pages @ offset 0x300): for even 5G SerDes - * - ANA_RG (2 pages @ offset 0x380): for odd 5G SerDes - * - ANA_TG (2 pages @ offset 0x300): for even 10G SerDes - * - ANA_TG (2 pages @ offset 0x380): for odd 10G SerDes - * - * The most consistent mapping that aligns to the RTL93xx devices is: - * - * even 5G SerDes odd 5G SerDes even 10G SerDes odd 10G SerDes - * Page 0: XSG0/0 XSG1/0 XSG0/0 XSG1/0 - * Page 1: XSG0/1 XSG1/1 XSG0/1 XSG1/1 - * Page 2: XSG0/2 XSG1/2 XSG0/2 XSG1/2 - * Page 3: XSG0/3 XSG1/3 XSG0/3 XSG1/3 - * Page 4: TGRX/0 - * Page 5: TGRX/1 - * Page 6: TGRX/2 - * Page 7: TGRX/3 - * Page 8: ANA_RG ANA_RG - * Page 9: ANA_RG_EXT ANA_RG_EXT - * Page 10: ANA_TG ANA_TG - * Page 11: ANA_TG_EXT ANA_TG_EXT - */ - -static int rtmdio_839x_reg_offset(int sds, int page, int regnum) -{ - int offset = ((sds & 0xfe) << 9) + ((regnum & 0xfe) << 1) + (page << 6); - int sds5g = (GENMASK(11, 10) | GENMASK(7, 0)) & BIT(sds); - - if (sds < 0 || sds > 13 || page < 0 || page > 11 || regnum < 0 || regnum > 31) - return -EIO; - - if (page < 4) - return offset + ((sds & 1) << 8); - else if ((page & 4) && (sds == 8 || sds == 12)) - return offset + 0x100; - else if (page >= 8 && page <= 9 && sds5g) - return offset + 0x100 + ((sds & 1) << 7); - else if (page >= 10 && !sds5g) - return offset + 0x80 + ((sds & 1) << 7); - - return -EINVAL; /* hole */ -} - -static int rtmdio_839x_read_sds_phy(int sds, int page, int regnum) -{ - int bitpos = ((regnum << 4) & 0x10); - int offset; - u32 val; - - offset = rtmdio_839x_reg_offset(sds, page, regnum); - if (offset == -EINVAL) - return 0; - - if (offset < 0) - return offset; - - /* phy id is empty so simulate one */ - if (page == 2 && regnum == 2) - return 0x1c; - if (page == 2 && regnum == 3) - return 0x8393; - - val = sw_r32(RTMDIO_839X_BASE + offset); - val = (val >> bitpos) & 0xffff; - - return val; -} - -static int rtmdio_839x_write_sds_phy(int sds, int page, int regnum, u16 val) -{ - u32 neighbor; - int offset; - u32 set; - - offset = rtmdio_839x_reg_offset(sds, page, regnum); - if (offset == -EINVAL) - return 0; - - if (offset < 0) - return 0; - - neighbor = rtmdio_839x_read_sds_phy(sds, page, regnum ^ 1); - if (regnum & 1) - set = (val << 16) + neighbor; - else - set = (neighbor << 16) + val; - - sw_w32(set, RTMDIO_839X_BASE + offset); - - return 0; -} - /* RTL839x specific MDIO functions */ static int rtmdio_839x_smi_wait_op(int timeout) @@ -583,70 +423,6 @@ errout: return err; } -/* - * The RTL930x family has 12 SerDes of three types. They are accessed through two IO registers at - * 0xbb0003b0 which simulate commands to an internal MDIO bus: - * - * - SerDes 0-1 exist on the RTL9301 and 9302B and are QSGMII capable - * - SerDes 2-9 are USXGMII capabable with either quad or single configuration - * - SerDes 10-11 are 10GBase-R capable - */ - -static int rtmdio_930x_read_sds_phy(int sds, int page, int regnum) -{ - int i, ret = -EIO; - u32 cmd; - - if (sds < 0 || sds > 11 || page < 0 || page > 63 || regnum < 0 || regnum > 31) - return -EIO; - - mutex_lock(&rtmdio_lock_sds); - - cmd = sds << 2 | page << 7 | regnum << 13 | 1; - sw_w32(cmd, RTMDIO_930X_SDS_INDACS_CMD); - - for (i = 0; i < 100; i++) { - if (!(sw_r32(RTMDIO_930X_SDS_INDACS_CMD) & 0x1)) - break; - mdelay(1); - } - - if (i < 100) - ret = sw_r32(RTMDIO_930X_SDS_INDACS_DATA) & 0xffff; - - mutex_unlock(&rtmdio_lock_sds); - - return ret; -} - -static int rtmdio_930x_write_sds_phy(int sds, int page, int regnum, u16 val) -{ - int i, ret = -EIO; - u32 cmd; - - if (sds < 0 || sds > 11 || page < 0 || page > 63 || regnum < 0 || regnum > 31) - return -EIO; - - mutex_lock(&rtmdio_lock_sds); - - cmd = sds << 2 | page << 7 | regnum << 13 | 0x3; - sw_w32(val, RTMDIO_930X_SDS_INDACS_DATA); - sw_w32(cmd, RTMDIO_930X_SDS_INDACS_CMD); - - for (i = 0; i < 100; i++) { - if (!(sw_r32(RTMDIO_930X_SDS_INDACS_CMD) & 0x1)) - break; - mdelay(1); - } - - mutex_unlock(&rtmdio_lock_sds); - - if (i < 100) - ret = 0; - - return ret; -} - /* RTL930x specific MDIO functions */ static int rtmdio_930x_write_phy(u32 port, u32 page, u32 reg, u32 val) @@ -768,146 +544,6 @@ 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 with 64 pages and 32 registers. Three types of SerDes exist: - * - * - Serdes 0,1 are "simple" and work on one background serdes. - * - "Even" SerDes with numbers 2, 4, 6, 8, 10, 12 work on two background SerDes. One analog and - * one digital. - * - "Odd" SerDes with numbers 3, 5, 7, 9, 11, 13 work on a total of 3 background SerDes (one analog - * and two digital) - * - * This maps to: - * - * 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 3 5 7 9 11 13 15 17 19 21 23 25 - * - * Note: In Realtek proprietary XSGMII mode (10G pumped SGMII) the frontend SerDes works on the - * two digital SerDes while in all other modes it works on the analog and the first digital SerDes. - * Overlapping (e.g. backend SerDes 7 can be analog or digital 2) is avoided by the existing - * hardware designs. - * - * 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 (digi 1): page 0x000-0x03f back SDS page 0x000-0x03f back SDS+1 - * page 0x200-0x23f (digi 2): page 0x000-0x03f back SDS+1 page 0x000-0x03f back SDS+2 - */ - -static int rtsds_931x_get_backing_sds(int sds, int page) -{ - int map[] = {0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23}; - int back = map[sds]; - - if (page & 0xc0) - return -EINVAL; /* hole */ - - if (sds >= 2) { - if (sds & 1) - back += (page >> 8); /* distribute "odd" to 3 background SerDes */ - else - back += (page >> 9); /* distribute "even" to 2 background SerDes */ - } - - return back; -} - -static int rtsds_931x_read(int sds, int page, int regnum) -{ - int backsds, i, cmd, ret = -EIO; - int backpage = page & 0x3f; - - if (sds < 0 || sds > 13 || page < 0 || page > 575 || regnum < 0 || regnum > 31) - return -EIO; - - backsds = rtsds_931x_get_backing_sds(sds, page); - if (backsds == -EINVAL) - return 0; - - mutex_lock(&rtmdio_lock_sds); - - cmd = backsds << 2 | backpage << 7 | regnum << 13 | 0x1; - 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)) { - ret = sw_r32(RTMDIO_931X_SERDES_INDRT_DATA_CTRL) & 0xffff; - break; - } - mdelay(1); - } - - mutex_unlock(&rtmdio_lock_sds); - - return ret; -} - -static int rtsds_931x_write(int sds, int page, int regnum, u16 val) -{ - int backsds, i, cmd, ret = -EIO; - int backpage = page & 0x3f; - - if (sds < 0 || sds > 13 || page < 0 || page > 575 || regnum < 0 || regnum > 31) - return -EIO; - - backsds = rtsds_931x_get_backing_sds(sds, page); - if (backsds == -EINVAL) - return 0; - - mutex_lock(&rtmdio_lock_sds); - - cmd = backsds << 2 | backpage << 7 | regnum << 13 | 0x3; - sw_w32(val, RTMDIO_931X_SERDES_INDRT_DATA_CTRL); - 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)) { - ret = 0; - break; - } - mdelay(1); - } - - mutex_unlock(&rtmdio_lock_sds); - - return ret; -} - -__always_unused -static int rtsds_931x_write_field(int sds, int page, int reg, int end_bit, int start_bit, u16 val) -{ - int l = end_bit - start_bit + 1; - u32 data = val; - - if (l < 32) { - u32 mask = BIT(l) - 1; - - data = rtsds_931x_read(sds, page, reg); - data &= ~(mask << start_bit); - data |= (val & mask) << start_bit; - } - - return rtsds_931x_write(sds, page, reg, data); -} - -__always_unused -static int rtsds_931x_read_field(int sds, int page, int reg, int end_bit, int start_bit) -{ - int l = end_bit - start_bit + 1; - u32 v = rtsds_931x_read(sds, page, reg); - - if (l >= 32) - return v; - - return (v >> start_bit) & (BIT(l) - 1); -} - /* RTL931x specific MDIO functions */ static int rtmdio_931x_write_phy(u32 port, u32 page, u32 reg, u32 val) @@ -1069,58 +705,6 @@ static int rtmdio_read_c45(struct mii_bus *bus, int addr, int devnum, int regnum return err ? err : val; } -static int rtmdio_map_sds_register(int page, int regnum, int *sds_page, int *sds_regnum) -{ - /* - * For the SerDes PHY simulate a register mapping like common RealTek PHYs do. Always - * keep the common registers 0x00-0x0f in place and map the SerDes registers into the - * upper vendor specific registers 0x10-0x17 according to the page select register - * (0x1f). That gives a register mapping as follows: - * - * +-----------------------+-----------------------+---------------+-----------------+ - * | reg 0x00-0x0f | reg 0x10-0x17 | reg 0x18-0x1e | reg 0x1f | - * +-----------------------+-----------------------+---------------+-----------------+ - * | SerDes fiber page (2) | real SerDes registers | zero | SerDes page | - * | registers 0x00-0x0f | in packages of 8 | | select register | - * +-----------------------+-----------------------+---------------+-----------------+ - */ - - if (regnum < 16) { - *sds_page = 2; - *sds_regnum = regnum; - } else if (regnum < 24) { - *sds_page = page / 4; - *sds_regnum = 8 * (page % 4) + (regnum - 16); - } else - return 0; - - return 1; -} - -static int rtmdio_read_sds_phy(struct rtmdio_bus_priv *priv, int sds, int page, int regnum) -{ - int ret, sds_page, sds_regnum; - - ret = rtmdio_map_sds_register(page, regnum, &sds_page, &sds_regnum); - if (ret) - ret = priv->cfg->read_sds_phy(sds, sds_page, sds_regnum); - pr_debug("rd_SDS(sds=%d, pag=%d, reg=%d) = %d\n", sds, page, regnum, ret); - - return ret; -} - -static int rtmdio_write_sds_phy(struct rtmdio_bus_priv *priv, int sds, int page, int regnum, u16 val) -{ - int ret, sds_page, sds_regnum; - - ret = rtmdio_map_sds_register(page, regnum, &sds_page, &sds_regnum); - if (ret) - ret = priv->cfg->write_sds_phy(sds, sds_page, sds_regnum, val); - pr_debug("wr_SDS(sds=%d, pag=%d, reg=%d, val=%d) err = %d\n", sds, page, regnum, val, ret); - - return ret; -} - static int rtmdio_read(struct mii_bus *bus, int addr, int regnum) { struct rtmdio_bus_priv *priv = bus->priv; @@ -1133,9 +717,6 @@ static int rtmdio_read(struct mii_bus *bus, int addr, int regnum) return priv->page[addr]; priv->raw[addr] = (priv->page[addr] == priv->cfg->raw_page); - if ((priv->phy_is_internal[addr]) && (priv->sds_id[addr] >= 0)) - return rtmdio_read_sds_phy(priv, priv->sds_id[addr], - priv->page[addr], regnum); err = (*priv->cfg->read_phy)(addr, priv->page[addr], regnum, &val); pr_debug("rd_PHY(adr=%d, pag=%d, reg=%d) = %d, err = %d\n", @@ -1172,9 +753,6 @@ static int rtmdio_write(struct mii_bus *bus, int addr, int regnum, u16 val) if (!priv->raw[addr] && (regnum != RTMDIO_PAGE_SELECT || page == priv->cfg->raw_page)) { priv->raw[addr] = (page == priv->cfg->raw_page); - if (priv->phy_is_internal[addr] && priv->sds_id[addr] >= 0) - return rtmdio_write_sds_phy(priv, priv->sds_id[addr], - priv->page[addr], regnum, val); err = (*priv->cfg->write_phy)(addr, page, regnum, val); pr_debug("wr_PHY(adr=%d, pag=%d, reg=%d, val=%d) err = %d\n", @@ -1381,7 +959,7 @@ static int rtmdio_reset(struct mii_bus *bus) static int rtmdio_probe(struct platform_device *pdev) { - struct device_node *dn, *mii_np, *pcs_node; + struct device_node *dn, *mii_np; struct device *dev = &pdev->dev; struct rtmdio_bus_priv *priv; struct mii_bus *bus; @@ -1442,8 +1020,6 @@ static int rtmdio_probe(struct platform_device *pdev) return -ENODEV; } - priv->phy_is_internal[pn] = of_property_read_bool(dn, "phy-is-integrated"); - if (of_device_is_compatible(dn, "ethernet-phy-ieee802.3-c45")) priv->smi_bus_isc45[priv->smi_bus[pn]] = true; } @@ -1463,21 +1039,6 @@ static int rtmdio_probe(struct platform_device *pdev) if (of_get_phy_mode(dn, &priv->interfaces[pn])) priv->interfaces[pn] = PHY_INTERFACE_MODE_NA; dev_dbg(dev, "phy mode of port %d is %s\n", pn, phy_modes(priv->interfaces[pn])); - - /* - * TODO: The MDIO driver does not need any info about the SerDes. As long as - * the PCS driver cannot completely control the SerDes, look up the information - * via the pcs-handle of the switch port node. - */ - - priv->sds_id[pn] = -1; - pcs_node = of_parse_phandle(dn, "pcs-handle", 0); - if (pcs_node) - of_property_read_u32(pcs_node, "reg", &priv->sds_id[pn]); - if (priv->phy_is_internal[pn] && priv->sds_id[pn] >= 0) - priv->smi_bus[pn] = -1; - if (priv->sds_id[pn] >= 0) - dev_dbg(dev, "PHY %d has SDS %d\n", pn, priv->sds_id[pn]); } snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev)); @@ -1490,11 +1051,9 @@ static const struct rtmdio_config rtmdio_838x_cfg = { .raw_page = 4095, .read_mmd_phy = rtmdio_838x_read_mmd_phy, .read_phy = rtmdio_838x_read_phy, - .read_sds_phy = rtmdio_838x_read_sds_phy, .reset = rtmdio_838x_reset, .write_mmd_phy = rtmdio_838x_write_mmd_phy, .write_phy = rtmdio_838x_write_phy, - .write_sds_phy = rtmdio_838x_write_sds_phy, }; static const struct rtmdio_config rtmdio_839x_cfg = { @@ -1502,11 +1061,9 @@ static const struct rtmdio_config rtmdio_839x_cfg = { .raw_page = 8191, .read_mmd_phy = rtmdio_839x_read_mmd_phy, .read_phy = rtmdio_839x_read_phy, - .read_sds_phy = rtmdio_839x_read_sds_phy, .reset = rtmdio_839x_reset, .write_mmd_phy = rtmdio_839x_write_mmd_phy, .write_phy = rtmdio_839x_write_phy, - .write_sds_phy = rtmdio_839x_write_sds_phy, }; static const struct rtmdio_config rtmdio_930x_cfg = { @@ -1514,11 +1071,9 @@ static const struct rtmdio_config rtmdio_930x_cfg = { .raw_page = 4095, .read_mmd_phy = rtmdio_930x_read_mmd_phy, .read_phy = rtmdio_930x_read_phy, - .read_sds_phy = rtmdio_930x_read_sds_phy, .reset = rtmdio_930x_reset, .write_mmd_phy = rtmdio_930x_write_mmd_phy, .write_phy = rtmdio_930x_write_phy, - .write_sds_phy = rtmdio_930x_write_sds_phy, }; static const struct rtmdio_config rtmdio_931x_cfg = { @@ -1526,11 +1081,9 @@ static const struct rtmdio_config rtmdio_931x_cfg = { .raw_page = 8191, .read_mmd_phy = rtmdio_931x_read_mmd_phy, .read_phy = rtmdio_931x_read_phy, - .read_sds_phy = rtsds_931x_read, .reset = rtmdio_931x_reset, .write_mmd_phy = rtmdio_931x_write_mmd_phy, .write_phy = rtmdio_931x_write_phy, - .write_sds_phy = rtsds_931x_write, }; static const struct of_device_id rtmdio_ids[] = {