[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250213101606.1154014-12-maxime.chevallier@bootlin.com>
Date: Thu, 13 Feb 2025 11:15:59 +0100
From: Maxime Chevallier <maxime.chevallier@...tlin.com>
To: davem@...emloft.net
Cc: Maxime Chevallier <maxime.chevallier@...tlin.com>,
netdev@...r.kernel.org,
linux-kernel@...r.kernel.org,
linux-arm-msm@...r.kernel.org,
thomas.petazzoni@...tlin.com,
Andrew Lunn <andrew@...n.ch>,
Jakub Kicinski <kuba@...nel.org>,
Eric Dumazet <edumazet@...gle.com>,
Paolo Abeni <pabeni@...hat.com>,
Russell King <linux@...linux.org.uk>,
linux-arm-kernel@...ts.infradead.org,
Christophe Leroy <christophe.leroy@...roup.eu>,
Herve Codina <herve.codina@...tlin.com>,
Florian Fainelli <f.fainelli@...il.com>,
Heiner Kallweit <hkallweit1@...il.com>,
Vladimir Oltean <vladimir.oltean@....com>,
Köry Maincent <kory.maincent@...tlin.com>,
Marek Behún <kabel@...nel.org>,
Oleksij Rempel <o.rempel@...gutronix.de>,
Nicolò Veronese <nicveronese@...il.com>,
Simon Horman <horms@...nel.org>,
mwojtas@...omium.org,
Antoine Tenart <atenart@...nel.org>,
devicetree@...r.kernel.org,
Conor Dooley <conor+dt@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>,
Rob Herring <robh@...nel.org>,
Romain Gantois <romain.gantois@...tlin.com>,
Daniel Golle <daniel@...rotopia.org>,
Dimitri Fedrau <dimitri.fedrau@...bherr.com>,
Sean Anderson <seanga2@...il.com>
Subject: [PATCH net-next v4 11/15] net: phy: qca807x: Support SFP through phy_port interface
QCA8072/8075 may be used as combo-port PHYs, with Serdes (100/1000BaseX)
and Copper interfaces. The PHY has the ability to read the configuration
it's in. If the configuration indicates the PHY is in combo mode, allow
registering up to 2 ports.
Register a dedicated set of port ops to handle the serdes port, and rely
on generic phylib SFP support for the SFP handling.
Signed-off-by: Maxime Chevallier <maxime.chevallier@...tlin.com>
---
V4: New patch
drivers/net/phy/qcom/qca807x.c | 75 +++++++++++++++-------------------
1 file changed, 32 insertions(+), 43 deletions(-)
diff --git a/drivers/net/phy/qcom/qca807x.c b/drivers/net/phy/qcom/qca807x.c
index 3279de857b47..d6e5004c2e14 100644
--- a/drivers/net/phy/qcom/qca807x.c
+++ b/drivers/net/phy/qcom/qca807x.c
@@ -13,7 +13,7 @@
#include <linux/phy.h>
#include <linux/bitfield.h>
#include <linux/gpio/driver.h>
-#include <linux/sfp.h>
+#include <linux/phy_port.h>
#include "qcom.h"
@@ -641,67 +641,55 @@ static int qca807x_phy_package_config_init_once(struct phy_device *phydev)
return ret;
}
-static int qca807x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
+static int qca807x_configure_serdes(struct phy_port *port, bool enable,
+ phy_interface_t interface)
{
- struct phy_device *phydev = upstream;
- __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
- phy_interface_t iface;
+ struct phy_device *phydev = port_phydev(port);
int ret;
- DECLARE_PHY_INTERFACE_MASK(interfaces);
- sfp_parse_support(phydev->sfp_bus, id, support, interfaces);
- iface = sfp_select_interface(phydev->sfp_bus, support);
+ if (!phydev)
+ return -ENODEV;
- dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface));
-
- switch (iface) {
- case PHY_INTERFACE_MODE_1000BASEX:
- case PHY_INTERFACE_MODE_100BASEX:
+ if (enable) {
/* Set PHY mode to PSGMII combo (1/4 copper + combo ports) mode */
ret = phy_modify(phydev,
QCA807X_CHIP_CONFIGURATION,
QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK,
QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER);
+ if (ret)
+ return ret;
/* Enable fiber mode autodection (1000Base-X or 100Base-FX) */
ret = phy_set_bits_mmd(phydev,
MDIO_MMD_AN,
QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION,
QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN);
- /* Select fiber page */
- ret = phy_clear_bits(phydev,
- QCA807X_CHIP_CONFIGURATION,
- QCA807X_BT_BX_REG_SEL);
-
- phydev->port = PORT_FIBRE;
- break;
- default:
- dev_err(&phydev->mdio.dev, "Incompatible SFP module inserted\n");
- return -EINVAL;
+ if (ret)
+ return ret;
}
- return ret;
+ phydev->port = enable ? PORT_FIBRE : PORT_TP;
+
+ return phy_modify(phydev, QCA807X_CHIP_CONFIGURATION,
+ QCA807X_BT_BX_REG_SEL,
+ enable ? 0 : QCA807X_BT_BX_REG_SEL);
}
-static void qca807x_sfp_remove(void *upstream)
+static const struct phy_port_ops qca807x_serdes_port_ops = {
+ .configure_mii = qca807x_configure_serdes,
+};
+
+static int qca807x_attach_port(struct phy_device *phydev, struct phy_port *port)
{
- struct phy_device *phydev = upstream;
+ if (!port->is_serdes)
+ return 0;
- /* Select copper page */
- phy_set_bits(phydev,
- QCA807X_CHIP_CONFIGURATION,
- QCA807X_BT_BX_REG_SEL);
+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, port->interfaces);
+ __set_bit(PHY_INTERFACE_MODE_100BASEX, port->interfaces);
- phydev->port = PORT_TP;
-}
+ port->ops = &qca807x_serdes_port_ops;
-static const struct sfp_upstream_ops qca807x_sfp_ops = {
- .attach = phy_sfp_attach,
- .detach = phy_sfp_detach,
- .module_insert = qca807x_sfp_insert,
- .module_remove = qca807x_sfp_remove,
- .connect_phy = phy_sfp_connect_phy,
- .disconnect_phy = phy_sfp_disconnect_phy,
-};
+ return 0;
+}
static int qca807x_probe(struct phy_device *phydev)
{
@@ -745,9 +733,8 @@ static int qca807x_probe(struct phy_device *phydev)
/* Attach SFP bus on combo port*/
if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) {
- ret = phy_sfp_probe(phydev, &qca807x_sfp_ops);
- if (ret)
- return ret;
+ phydev->max_n_ports = 2;
+
linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);
linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->advertising);
}
@@ -801,6 +788,7 @@ static struct phy_driver qca807x_drivers[] = {
.suspend = genphy_suspend,
.cable_test_start = qca807x_cable_test_start,
.cable_test_get_status = qca808x_cable_test_get_status,
+ .attach_port = qca807x_attach_port,
},
{
PHY_ID_MATCH_EXACT(PHY_ID_QCA8075),
@@ -824,6 +812,7 @@ static struct phy_driver qca807x_drivers[] = {
.led_hw_is_supported = qca807x_led_hw_is_supported,
.led_hw_control_set = qca807x_led_hw_control_set,
.led_hw_control_get = qca807x_led_hw_control_get,
+ .attach_port = qca807x_attach_port,
},
};
module_phy_driver(qca807x_drivers);
--
2.48.1
Powered by blists - more mailing lists