net: dsa: vsc73xx: add phylink capabilities
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Mon, 9 Oct 2023 10:39:45 +0000 (11:39 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 11 Oct 2023 09:06:05 +0000 (10:06 +0100)
Add phylink capabilities for vsc73xx. Although this switch driver does
populates the .adjust_link method, dsa_slave_phy_setup() will still be
used to create phylink instances for the LAN ports, although phylink
won't be used for shared links.

There are two different classes of switch - 5+1 and 8 port. The 5+1
port switches uses port indicies 0-4 for the user interfaces and 6 for
the CPU port. The 8 port is confusing - some comments in the driver
imply that port index 7 is used, but the driver actually still uses 6,
so that is what we go with. Also, there appear to be no DTs in the
kernel tree that are using the 8 port variety.

It also looks like port 5 is always skipped.

The switch supports 10M, 100M and 1G speeds. It is not clear whether
all these speeds are supported on the CPU interface. It also looks like
symmetric pause is supported, whether asymmetric pause is as well is
unclear. However, it looks like the pause configuration is entirely
static, and doesn't depend on negotiation results.

So, let's do the best effort we can based on the information found in
the driver when creating vsc73xx_phylink_get_caps().

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/vitesse-vsc73xx-core.c

index 4f09e7438f3b933d6f5feaa9970810968c7abdcb..35a846d7e13f47ecfd8e18027df42d5e0fdbd4fe 100644 (file)
@@ -1037,6 +1037,31 @@ static int vsc73xx_get_max_mtu(struct dsa_switch *ds, int port)
        return 9600 - ETH_HLEN - ETH_FCS_LEN;
 }
 
+static void vsc73xx_phylink_get_caps(struct dsa_switch *dsa, int port,
+                                    struct phylink_config *config)
+{
+       unsigned long *interfaces = config->supported_interfaces;
+
+       if (port == 5)
+               return;
+
+       if (port == CPU_PORT) {
+               __set_bit(PHY_INTERFACE_MODE_MII, interfaces);
+               __set_bit(PHY_INTERFACE_MODE_REVMII, interfaces);
+               __set_bit(PHY_INTERFACE_MODE_GMII, interfaces);
+               __set_bit(PHY_INTERFACE_MODE_RGMII, interfaces);
+       }
+
+       if (port <= 4) {
+               /* Internal PHYs */
+               __set_bit(PHY_INTERFACE_MODE_INTERNAL, interfaces);
+               /* phylib default */
+               __set_bit(PHY_INTERFACE_MODE_GMII, interfaces);
+       }
+
+       config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000;
+}
+
 static const struct dsa_switch_ops vsc73xx_ds_ops = {
        .get_tag_protocol = vsc73xx_get_tag_protocol,
        .setup = vsc73xx_setup,
@@ -1050,6 +1075,7 @@ static const struct dsa_switch_ops vsc73xx_ds_ops = {
        .port_disable = vsc73xx_port_disable,
        .port_change_mtu = vsc73xx_change_mtu,
        .port_max_mtu = vsc73xx_get_max_mtu,
+       .phylink_get_caps = vsc73xx_phylink_get_caps,
 };
 
 static int vsc73xx_gpio_get(struct gpio_chip *chip, unsigned int offset)