diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/common.c index 6e0197d2b3..45f645065b 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/common.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/common.c @@ -16,7 +16,7 @@ #include "rtl-otto.h" -struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int port); +struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int link_idx, int port); int rtldsa_port_get_stp_state(struct rtl838x_switch_priv *priv, int port) { @@ -254,7 +254,9 @@ static bool rtldsa_phys_load_deferred(void) static int rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv) { - struct device_node *dn, *phy_node, *pcs_node, *led_node; + struct device_node *dn, *phy_node, *led_node; + struct of_phandle_args pcs_args; + bool has_pcs; u32 pn; /* Check if all busses of Realtek mdio controller are registered */ @@ -292,15 +294,18 @@ static int rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv) if (of_property_read_u32(dn, "reg", &pn)) continue; - pcs_node = of_parse_phandle(dn, "pcs-handle", 0); + has_pcs = !of_parse_phandle_with_args(dn, "pcs-handle", "#pcs-cells", + 0, &pcs_args); phy_node = of_parse_phandle(dn, "phy-handle", 0); - if (pn != priv->r->cpu_port && !phy_node && !pcs_node) { + if (pn != priv->r->cpu_port && !phy_node && !has_pcs) { dev_err(priv->dev, "Port node %d has neither pcs-handle nor phy-handle\n", pn); continue; } - if (pcs_node) { - priv->ports[pn].pcs = rtpcs_create(priv->dev, pcs_node, pn); + if (has_pcs) { + priv->ports[pn].pcs = rtpcs_create(priv->dev, pcs_args.np, + pcs_args.args[0], pn); + of_node_put(pcs_args.np); if (IS_ERR(priv->ports[pn].pcs)) { dev_err(priv->dev, "port %u failed to create PCS instance: %ld\n", pn, PTR_ERR(priv->ports[pn].pcs)); diff --git a/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c b/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c index 6833d1d372..a7bfb6cfc9 100644 --- a/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c +++ b/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c @@ -12,7 +12,6 @@ #include #define RTPCS_SDS_CNT 14 -#define RTPCS_PORT_CNT 57 #define RTPCS_MAX_LINKS_PER_SDS 8 #define RTPCS_SPEED_10 0 @@ -221,6 +220,7 @@ struct rtpcs_serdes { struct regmap_field *mac_mode_force; /* nullable, 931x only */ struct regmap_field *usxgmii_submode; /* nullable, 93xx only */ } swcore_regs; + struct rtpcs_link *link[RTPCS_MAX_LINKS_PER_SDS]; enum rtpcs_sds_mode hw_mode; u8 id; @@ -234,7 +234,6 @@ struct rtpcs_ctrl { struct mii_bus *bus; const struct rtpcs_config *cfg; struct rtpcs_serdes serdes[RTPCS_SDS_CNT]; - struct rtpcs_link *link[RTPCS_PORT_CNT]; struct mutex lock; /* meaning and source may be family-specific */ @@ -4132,8 +4131,8 @@ out: return ret; } -struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int port); -struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int port) +struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int link_idx, int port); +struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int link_idx, int port) { struct platform_device *pdev; struct device_node *pcs_np; @@ -4177,6 +4176,15 @@ struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int if (rtpcs_sds_read(sds, 0, 0) < 0) return ERR_PTR(-EINVAL); + if (link_idx >= RTPCS_MAX_LINKS_PER_SDS) { + put_device(&pdev->dev); + return ERR_PTR(-EINVAL); + } + if (sds->link[link_idx]) { + put_device(&pdev->dev); + return ERR_PTR(-EBUSY); + } + link = devm_kzalloc(ctrl->dev, sizeof(*link), GFP_KERNEL); if (!link) { put_device(&pdev->dev); @@ -4190,10 +4198,10 @@ struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int link->sds = sds; link->pcs.ops = ctrl->cfg->pcs_ops; - ctrl->link[port] = link; - - dev_dbg(ctrl->dev, "phylink_pcs created, port %d, sds %d\n", port, sds_id); + sds->link[link_idx] = link; + dev_dbg(ctrl->dev, "phylink_pcs created, port %d, sds %d, link_idx %d\n", + port, sds_id, link_idx); return &link->pcs; } EXPORT_SYMBOL(rtpcs_create);