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

Configure Feed

Select the types of activity you want to include in your feed.

net: phy: marvell-88x2222: Support SFP through phy_port interface

The 88x2222 PHY from Marvell only supports serialised modes as its
line-facing interfaces. Convert that driver to the generic phylib SFP
handling.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260108080041.553250-9-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Maxime Chevallier and committed by
Jakub Kicinski
ea317f07 d7c6082f

+38 -56
+38 -56
drivers/net/phy/marvell-88x2222.c
··· 13 13 #include <linux/mdio.h> 14 14 #include <linux/marvell_phy.h> 15 15 #include <linux/of.h> 16 - #include <linux/sfp.h> 16 + #include <linux/phy_port.h> 17 17 #include <linux/netdevice.h> 18 18 19 19 /* Port PCS Configuration */ ··· 473 473 return 0; 474 474 } 475 475 476 - static int mv2222_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) 476 + static int mv2222_configure_serdes(struct phy_port *port, bool enable, 477 + phy_interface_t interface) 477 478 { 478 - struct phy_device *phydev = upstream; 479 - const struct sfp_module_caps *caps; 480 - phy_interface_t sfp_interface; 479 + struct phy_device *phydev = port_phydev(port); 481 480 struct mv2222_data *priv; 482 - struct device *dev; 483 - int ret; 481 + int ret = 0; 484 482 485 483 priv = phydev->priv; 486 - dev = &phydev->mdio.dev; 484 + priv->line_interface = interface; 487 485 488 - caps = sfp_get_module_caps(phydev->sfp_bus); 486 + if (enable) { 487 + linkmode_and(priv->supported, phydev->supported, port->supported); 489 488 490 - phydev->port = caps->port; 491 - sfp_interface = sfp_select_interface(phydev->sfp_bus, caps->link_modes); 489 + ret = mv2222_config_line(phydev); 490 + if (ret < 0) 491 + return ret; 492 492 493 - dev_info(dev, "%s SFP module inserted\n", phy_modes(sfp_interface)); 493 + if (mutex_trylock(&phydev->lock)) { 494 + ret = mv2222_config_aneg(phydev); 495 + mutex_unlock(&phydev->lock); 496 + } 494 497 495 - if (sfp_interface != PHY_INTERFACE_MODE_10GBASER && 496 - sfp_interface != PHY_INTERFACE_MODE_1000BASEX && 497 - sfp_interface != PHY_INTERFACE_MODE_SGMII) { 498 - dev_err(dev, "Incompatible SFP module inserted\n"); 499 - 500 - return -EINVAL; 501 - } 502 - 503 - priv->line_interface = sfp_interface; 504 - linkmode_and(priv->supported, phydev->supported, caps->link_modes); 505 - 506 - ret = mv2222_config_line(phydev); 507 - if (ret < 0) 508 - return ret; 509 - 510 - if (mutex_trylock(&phydev->lock)) { 511 - ret = mv2222_config_aneg(phydev); 512 - mutex_unlock(&phydev->lock); 498 + } else { 499 + linkmode_zero(priv->supported); 513 500 } 514 501 515 502 return ret; 516 503 } 517 504 518 - static void mv2222_sfp_remove(void *upstream) 505 + static void mv2222_port_link_up(struct phy_port *port) 519 506 { 520 - struct phy_device *phydev = upstream; 521 - struct mv2222_data *priv; 522 - 523 - priv = phydev->priv; 524 - 525 - priv->line_interface = PHY_INTERFACE_MODE_NA; 526 - linkmode_zero(priv->supported); 527 - phydev->port = PORT_NONE; 528 - } 529 - 530 - static void mv2222_sfp_link_up(void *upstream) 531 - { 532 - struct phy_device *phydev = upstream; 507 + struct phy_device *phydev = port_phydev(port); 533 508 struct mv2222_data *priv; 534 509 535 510 priv = phydev->priv; 536 511 priv->sfp_link = true; 537 512 } 538 513 539 - static void mv2222_sfp_link_down(void *upstream) 514 + static void mv2222_port_link_down(struct phy_port *port) 540 515 { 541 - struct phy_device *phydev = upstream; 516 + struct phy_device *phydev = port_phydev(port); 542 517 struct mv2222_data *priv; 543 518 544 519 priv = phydev->priv; 545 520 priv->sfp_link = false; 546 521 } 547 522 548 - static const struct sfp_upstream_ops sfp_phy_ops = { 549 - .module_insert = mv2222_sfp_insert, 550 - .module_remove = mv2222_sfp_remove, 551 - .link_up = mv2222_sfp_link_up, 552 - .link_down = mv2222_sfp_link_down, 553 - .attach = phy_sfp_attach, 554 - .detach = phy_sfp_detach, 555 - .connect_phy = phy_sfp_connect_phy, 556 - .disconnect_phy = phy_sfp_disconnect_phy, 523 + static const struct phy_port_ops mv2222_port_ops = { 524 + .link_up = mv2222_port_link_up, 525 + .link_down = mv2222_port_link_down, 526 + .configure_mii = mv2222_configure_serdes, 557 527 }; 528 + 529 + static int mv2222_attach_mii_port(struct phy_device *phydev, struct phy_port *port) 530 + { 531 + port->ops = &mv2222_port_ops; 532 + 533 + __set_bit(PHY_INTERFACE_MODE_10GBASER, port->interfaces); 534 + __set_bit(PHY_INTERFACE_MODE_1000BASEX, port->interfaces); 535 + __set_bit(PHY_INTERFACE_MODE_SGMII, port->interfaces); 536 + 537 + return 0; 538 + } 558 539 559 540 static int mv2222_probe(struct phy_device *phydev) 560 541 { ··· 572 591 priv->line_interface = PHY_INTERFACE_MODE_NA; 573 592 phydev->priv = priv; 574 593 575 - return phy_sfp_probe(phydev, &sfp_phy_ops); 594 + return 0; 576 595 } 577 596 578 597 static struct phy_driver mv2222_drivers[] = { ··· 589 608 .suspend = mv2222_suspend, 590 609 .resume = mv2222_resume, 591 610 .read_status = mv2222_read_status, 611 + .attach_mii_port = mv2222_attach_mii_port, 592 612 }, 593 613 }; 594 614 module_phy_driver(mv2222_drivers);