Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: dsa: mv88e6060: add phylink_get_caps implementation

Add a phylink_get_caps implementation for Marvell 88e6060 DSA switch.
This is a fast ethernet switch, with internal PHYs for ports 0 through
4. Port 4 also supports MII, REVMII, REVRMII and SNI. Port 5 supports
MII, REVMII, REVRMII and SNI without an internal PHY.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Link: https://lore.kernel.org/r/E1qUkx7-003dMX-9b@rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Russell King (Oracle) and committed by
Jakub Kicinski
479b322e f3cc0030

+45
+45
drivers/net/dsa/mv88e6060.c
··· 247 247 return reg_write(priv, addr, regnum, val); 248 248 } 249 249 250 + static void mv88e6060_phylink_get_caps(struct dsa_switch *ds, int port, 251 + struct phylink_config *config) 252 + { 253 + unsigned long *interfaces = config->supported_interfaces; 254 + struct mv88e6060_priv *priv = ds->priv; 255 + int addr = REG_PORT(port); 256 + int ret; 257 + 258 + ret = reg_read(priv, addr, PORT_STATUS); 259 + if (ret < 0) { 260 + dev_err(ds->dev, 261 + "port %d: unable to read status register: %pe\n", 262 + port, ERR_PTR(ret)); 263 + return; 264 + } 265 + 266 + /* If the port is configured in SNI mode (acts as a 10Mbps PHY), 267 + * it should have phy-mode = "sni", but that doesn't yet exist, so 268 + * forcibly fail validation until the need arises to introduce it. 269 + */ 270 + if (!(ret & PORT_STATUS_PORTMODE)) { 271 + dev_warn(ds->dev, "port %d: SNI mode not supported\n", port); 272 + return; 273 + } 274 + 275 + config->mac_capabilities = MAC_100 | MAC_10 | MAC_SYM_PAUSE; 276 + 277 + if (port >= 4) { 278 + /* Ports 4 and 5 can support MII, REVMII and REVRMII modes */ 279 + __set_bit(PHY_INTERFACE_MODE_MII, interfaces); 280 + __set_bit(PHY_INTERFACE_MODE_REVMII, interfaces); 281 + __set_bit(PHY_INTERFACE_MODE_REVRMII, interfaces); 282 + } 283 + if (port <= 4) { 284 + /* Ports 0 to 3 have internal PHYs, and port 4 can optionally 285 + * use an internal PHY. 286 + */ 287 + /* Internal PHY */ 288 + __set_bit(PHY_INTERFACE_MODE_INTERNAL, interfaces); 289 + /* Default phylib interface mode */ 290 + __set_bit(PHY_INTERFACE_MODE_GMII, interfaces); 291 + } 292 + } 293 + 250 294 static const struct dsa_switch_ops mv88e6060_switch_ops = { 251 295 .get_tag_protocol = mv88e6060_get_tag_protocol, 252 296 .setup = mv88e6060_setup, 253 297 .phy_read = mv88e6060_phy_read, 254 298 .phy_write = mv88e6060_phy_write, 299 + .phylink_get_caps = mv88e6060_phylink_get_caps, 255 300 }; 256 301 257 302 static int mv88e6060_probe(struct mdio_device *mdiodev)