From 86deef6158befc7c47deb9ea1f7d521faf764ec5 Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Thu, 22 Aug 2024 01:55:36 -0400 Subject: [PATCH] realtek: 6.6: change to current dsa structures The DSA framework has changed a bit since 6.1, lets adapt to match. Currently there is no one-patch-fits-all solution to directly fix all errors up to 6.6. So cover the final differences with this second patch. Most notable upstream changes are: - a88dd7538461 ("net: dsa: remove legacy_pre_march2020 detection") - 53d04b981110 ("net: dsa: remove phylink_validate() method") Signed-off-by: Markus Stockhausen [Minor checkpatch.pl cleanups] Signed-off-by: Sander Vanheule --- .../drivers/net/dsa/rtl83xx/common.c | 21 +++- .../files-6.6/drivers/net/dsa/rtl83xx/dsa.c | 108 ++++++++++++------ .../drivers/net/dsa/rtl83xx/rtl838x.h | 7 ++ 3 files changed, 102 insertions(+), 34 deletions(-) diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/common.c index 7ce5f0146e..b17d9ae5d5 100644 --- a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/common.c +++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/common.c @@ -25,6 +25,9 @@ extern const struct rtl838x_reg rtl931x_reg; extern const struct dsa_switch_ops rtl83xx_switch_ops; 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) @@ -1461,7 +1464,7 @@ static int rtl83xx_fib_event(struct notifier_block *this, unsigned long event, v static int __init rtl83xx_sw_probe(struct platform_device *pdev) { - int err = 0; + int i, err = 0; struct rtl838x_switch_priv *priv; struct device *dev = &pdev->dev; u64 bpdu_mask; @@ -1559,6 +1562,22 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev) } pr_debug("Chip version %c\n", priv->version); + for (i = 0; i <= priv->cpu_port; i++) { + switch (soc_info.family) { + case RTL8380_FAMILY_ID: + case RTL8390_FAMILY_ID: + priv->pcs[i].pcs.ops = &rtl83xx_pcs_ops; + break; + case RTL9300_FAMILY_ID: + case RTL9310_FAMILY_ID: + priv->pcs[i].pcs.ops = &rtl93xx_pcs_ops; + break; + } + priv->pcs[i].pcs.neg_mode = true; + priv->pcs[i].priv = priv; + priv->pcs[i].port = i; + } + err = rtl83xx_mdio_probe(priv); if (err) { /* Probing fails the 1st time because of missing ethernet driver diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c index 24c3643929..0f14947fda 100644 --- a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c +++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c @@ -312,11 +312,13 @@ static int rtl93xx_get_sds(struct phy_device *phydev) return sds_num; } -static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port, - unsigned long *supported, - struct phylink_link_state *state) +static int rtl83xx_pcs_validate(struct phylink_pcs *pcs, + unsigned long *supported, + const struct phylink_link_state *state) { - struct rtl838x_switch_priv *priv = ds->priv; + struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs); + struct rtl838x_switch_priv *priv = rtpcs->priv; + int port = rtpcs->port; __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; pr_debug("In %s port %d, state is %d", __func__, port, state->interface); @@ -331,10 +333,10 @@ static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port, state->interface != PHY_INTERFACE_MODE_INTERNAL && state->interface != PHY_INTERFACE_MODE_SGMII) { bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); - dev_err(ds->dev, + dev_err(priv->ds->dev, "Unsupported interface: %d for port %d\n", state->interface, port); - return; + return -EINVAL; } /* Allow all the expected bits */ @@ -367,15 +369,17 @@ static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port, bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + + return 0; } -static void rtl93xx_phylink_validate(struct dsa_switch *ds, int port, - unsigned long *supported, - struct phylink_link_state *state) +static int rtl93xx_pcs_validate(struct phylink_pcs *pcs, + unsigned long *supported, + const struct phylink_link_state *state) { - struct rtl838x_switch_priv *priv = ds->priv; + struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs); + struct rtl838x_switch_priv *priv = rtpcs->priv; + int port = rtpcs->port; __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; pr_debug("In %s port %d, state is %d (%s)", __func__, port, state->interface, @@ -396,10 +400,10 @@ static void rtl93xx_phylink_validate(struct dsa_switch *ds, int port, state->interface != PHY_INTERFACE_MODE_INTERNAL && state->interface != PHY_INTERFACE_MODE_SGMII) { bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); - dev_err(ds->dev, + dev_err(priv->ds->dev, "Unsupported interface: %d for port %d\n", state->interface, port); - return; + return -EINVAL; } /* Allow all the expected bits */ @@ -449,20 +453,24 @@ static void rtl93xx_phylink_validate(struct dsa_switch *ds, int port, bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); pr_debug("%s leaving supported: %*pb", __func__, __ETHTOOL_LINK_MODE_MASK_NBITS, supported); + + return 0; } -static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port, - struct phylink_link_state *state) +static void rtl83xx_pcs_get_state(struct phylink_pcs *pcs, + struct phylink_link_state *state) { - struct rtl838x_switch_priv *priv = ds->priv; + struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs); + struct rtl838x_switch_priv *priv = rtpcs->priv; + int port = rtpcs->port; u64 speed; u64 link; - if (port < 0 || port > priv->cpu_port) - return -EINVAL; + if (port < 0 || port > priv->cpu_port) { + state->link = false; + return; + } state->link = 0; link = priv->r->get_port_reg_le(priv->r->mac_link_sts); @@ -499,20 +507,22 @@ static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port, state->pause |= MLO_PAUSE_RX; if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port)) state->pause |= MLO_PAUSE_TX; - - return 1; } -static int rtl93xx_phylink_mac_link_state(struct dsa_switch *ds, int port, - struct phylink_link_state *state) +static void rtl93xx_pcs_get_state(struct phylink_pcs *pcs, + struct phylink_link_state *state) { - struct rtl838x_switch_priv *priv = ds->priv; + struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs); + struct rtl838x_switch_priv *priv = rtpcs->priv; + int port = rtpcs->port; u64 speed; u64 link; u64 media; - if (port < 0 || port > priv->cpu_port) - return -EINVAL; + if (port < 0 || port > priv->cpu_port) { + state->link = false; + return; + } /* On the RTL9300 for at least the RTL8226B PHY, the MAC-side link * state needs to be read twice in order to read a correct result. @@ -581,8 +591,28 @@ static int rtl93xx_phylink_mac_link_state(struct dsa_switch *ds, int port, state->pause |= MLO_PAUSE_RX; if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port)) state->pause |= MLO_PAUSE_TX; +} + +static int rtl83xx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, + phy_interface_t interface, + const unsigned long *advertising, + bool permit_pause_to_mac) +{ + return 0; +} + +static void rtl83xx_pcs_an_restart(struct phylink_pcs *pcs) +{ +/* No restart functionality existed before we migrated to pcs */ +} + +static struct phylink_pcs *rtl83xx_phylink_mac_select_pcs(struct dsa_switch *ds, + int port, + phy_interface_t interface) +{ + struct rtl838x_switch_priv *priv = ds->priv; - return 1; + return &priv->pcs[port].pcs; } static void rtl83xx_config_interface(int port, phy_interface_t interface) @@ -2126,6 +2156,13 @@ int dsa_phy_write(struct dsa_switch *ds, int phy_addr, int phy_reg, u16 val) return write_phy(phy_addr, 0, phy_reg, val); } +const struct phylink_pcs_ops rtl83xx_pcs_ops = { + .pcs_an_restart = rtl83xx_pcs_an_restart, + .pcs_validate = rtl83xx_pcs_validate, + .pcs_get_state = rtl83xx_pcs_get_state, + .pcs_config = rtl83xx_pcs_config, +}; + const struct dsa_switch_ops rtl83xx_switch_ops = { .get_tag_protocol = rtl83xx_get_tag_protocol, .setup = rtl83xx_setup, @@ -2133,11 +2170,10 @@ const struct dsa_switch_ops rtl83xx_switch_ops = { .phy_read = dsa_phy_read, .phy_write = dsa_phy_write, - .phylink_validate = rtl83xx_phylink_validate, - .phylink_mac_link_state = rtl83xx_phylink_mac_link_state, .phylink_mac_config = rtl83xx_phylink_mac_config, .phylink_mac_link_down = rtl83xx_phylink_mac_link_down, .phylink_mac_link_up = rtl83xx_phylink_mac_link_up, + .phylink_mac_select_pcs = rtl83xx_phylink_mac_select_pcs, .get_strings = rtl83xx_get_strings, .get_ethtool_stats = rtl83xx_get_ethtool_stats, @@ -2177,6 +2213,13 @@ const struct dsa_switch_ops rtl83xx_switch_ops = { .port_bridge_flags = rtl83xx_port_bridge_flags, }; +const struct phylink_pcs_ops rtl93xx_pcs_ops = { + .pcs_an_restart = rtl83xx_pcs_an_restart, + .pcs_validate = rtl93xx_pcs_validate, + .pcs_get_state = rtl93xx_pcs_get_state, + .pcs_config = rtl83xx_pcs_config, +}; + const struct dsa_switch_ops rtl930x_switch_ops = { .get_tag_protocol = rtl83xx_get_tag_protocol, .setup = rtl93xx_setup, @@ -2184,11 +2227,10 @@ const struct dsa_switch_ops rtl930x_switch_ops = { .phy_read = dsa_phy_read, .phy_write = dsa_phy_write, - .phylink_validate = rtl93xx_phylink_validate, - .phylink_mac_link_state = rtl93xx_phylink_mac_link_state, .phylink_mac_config = rtl93xx_phylink_mac_config, .phylink_mac_link_down = rtl93xx_phylink_mac_link_down, .phylink_mac_link_up = rtl93xx_phylink_mac_link_up, + .phylink_mac_select_pcs = rtl83xx_phylink_mac_select_pcs, .get_strings = rtl83xx_get_strings, .get_ethtool_stats = rtl83xx_get_ethtool_stats, diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h index 261af32bb4..176fd07fe4 100644 --- a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h +++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h @@ -639,6 +639,12 @@ struct rtl838x_port { const struct dsa_port *dp; }; +struct rtl838x_pcs { + struct phylink_pcs pcs; + struct rtl838x_switch_priv *priv; + int port; +}; + struct rtl838x_vlan_info { u64 untagged_ports; u64 tagged_ports; @@ -1058,6 +1064,7 @@ struct rtl838x_switch_priv { u16 family_id; char version; struct rtl838x_port ports[57]; + struct rtl838x_pcs pcs[57]; struct mutex reg_mutex; /* Mutex for individual register manipulations */ struct mutex pie_mutex; /* Mutex for Packet Inspection Engine */ int link_state_irq; -- 2.30.2