realtek: 6.6: change to current dsa structures
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Thu, 22 Aug 2024 05:55:36 +0000 (01:55 -0400)
committerSander Vanheule <sander@svanheule.net>
Sat, 14 Sep 2024 18:08:24 +0000 (20:08 +0200)
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 <markus.stockhausen@gmx.de>
[Minor checkpatch.pl cleanups]
Signed-off-by: Sander Vanheule <sander@svanheule.net>
target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/common.c
target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c
target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h

index 7ce5f0146e71a1bbc32817e154d037596aa79196..b17d9ae5d5674942a2a50bcc18d2c399604c2c27 100644 (file)
@@ -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
index 24c36439296e0597cbb810b3d9ab1e08d7deb2d7..0f14947fda6301cd30f2c6b65d7188fc71d3beaa 100644 (file)
@@ -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,
index 261af32bb46ee7cf669d0b04e04926a6c3127b4b..176fd07fe4328d1e0e73a76a3cbcb2b2397baf1f 100644 (file)
@@ -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;