From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 084FB476057; Wed, 9 Sep 2026 09:39:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788946782; cv=none; b=gnaSSn9zrNtyktcMhe9+dkX1zX8xpX2iJa9+f3loQG/5L9u/Ag/hfZLnODVCErwXhYjQrwAdzHrsHI/CG4emqA1hU09R0YysS0d6ALXJVEHe7QAh6weawixkkWFkZlakEQnigm0bmjuUfqfqkzOmFUMUZpzmBBcFLfxRpanXjIQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788946782; c=relaxed/simple; bh=JYTVmzHKPHTghgLtcTWuxyerqAB1ckFX8CrcJJrC/8I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=O27QCiUPuSm+oPc0yCpPkHH0YnZUdpCaZ83pdrAdpKqrouxwotT/SseqPftln6mKQ/4uPCteM4nGp3v7polnT7835NvN7RLYxYj5T7PZu5lSvpJLTARNzzhJ9wozBdcXc4TQcgWH8EE36t32iSTcNLowb11Iqkv4xzmzCaoS440= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=YSGXiQWe; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="YSGXiQWe" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 9E3FA4E415B0; Wed, 9 Sep 2026 09:39:34 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 71C1360448; Wed, 9 Sep 2026 09:39:34 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 4C83E11C7AF2B; Wed, 9 Sep 2026 11:39:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1788946773; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=z1Flu6RdCuDLQ2adgpFyHnOUdjqin9zfWO/PZ35io10=; b=YSGXiQWeBU/jWQ9KtCAA7KnxsUJnKxXOTRDkiHLRgdS457mqS6Bux87+Ak4qVaUjBNjrkD BpTxAZ9srYYVaZcGhs4ZjrEgyWVfK+LvwSkU44W7gEvQSjeG/d8/A+ELt/V6I2s+1I1GA6 THRmcD3aMXAxlU88HK0uoCoMt6SodxwKY0Fn4h70PotHSf45Ii0Ck7A6SqMNLwvhHxZSGU c8NDLKbm6p9V4N3KvV4cTFkLKBmYzkD/tOiAKDkUuHVbXkWU4TlPewVKhHwz/9pyeG75tz slaucwj3u1d3UF7YBFnZ5cKNNr4zuz7LOQddIeXD3vxWJg3UJLrsO+xUXeO6OQ== From: Maxime Chevallier To: davem@davemloft.net, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , Heiner Kallweit Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Christophe Leroy , Herve Codina , Florian Fainelli , Vladimir Oltean , =?UTF-8?q?K=C3=B6ry=20Maincent?= , =?UTF-8?q?Marek=20Beh=C3=BAn?= , Oleksij Rempel , =?UTF-8?q?Nicol=C3=B2=20Veronese?= , Simon Horman , mwojtas@chromium.org, Romain Gantois , Daniel Golle , Dimitri Fedrau , Frank Wunderlich , Pietro Ameruoso Subject: [PATCH net-next v17 03/10] net: phylink: Register a phy_port for MAC-driven SFP cages Date: Wed, 9 Sep 2026 11:39:04 +0200 Message-ID: <20260909093912.1290810-4-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260909093912.1290810-1-maxime.chevallier@bootlin.com> References: <20260909093912.1290810-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Last-TLS-Session-Version: TLSv1.3 phy_port tracks the interfaces that a netdevice feeds into. SFP cages are such ports, but so far we are only tracking the ones that are driven by PHYs acting as media-converters. Let's populate a phy_port for MAC driven SFP cages, handled by phylink. This phy_port represents the SFP cage itself, and not the module that may be plugged into it. It's therefore not an MDI interface, so only the 'interfaces' field is relevant here. The phy_port is only populated for 'NETDEV' phylink instances, as otherwise we don't have any topology to attach the port to. Reviewed-by: Andrew Lunn Signed-off-by: Maxime Chevallier --- drivers/net/phy/phylink.c | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index b9fc8599df74..7c6c4243c711 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include @@ -93,6 +95,7 @@ struct phylink { DECLARE_PHY_INTERFACE_MASK(sfp_interfaces); __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support); u8 sfp_port; + struct phy_port *sfp_cage_port; struct eee_config eee_cfg; @@ -1765,6 +1768,46 @@ static void phylink_fixed_poll(struct timer_list *t) static const struct sfp_upstream_ops sfp_phylink_ops; +static int phylink_create_sfp_cage_port(struct phylink *pl) +{ + struct phy_port *port; + int ret = 0; + + if (!pl->netdev || !pl->sfp_bus) + return 0; + + port = phy_port_alloc(); + if (!port) + return -ENOMEM; + + port->is_sfp = true; + port->is_mii = true; + port->active = true; + + phy_interface_and(port->interfaces, pl->config->supported_interfaces, + phylink_sfp_interfaces); + phy_port_update_supported(port); + + ret = phy_link_topo_add_port(pl->netdev, port); + if (ret) + phy_port_destroy(port); + else + pl->sfp_cage_port = port; + + return ret; +} + +static void phylink_destroy_sfp_cage_port(struct phylink *pl) +{ + if (pl->netdev && pl->sfp_cage_port) + phy_link_topo_del_port(pl->netdev, pl->sfp_cage_port); + + if (pl->sfp_cage_port) + phy_port_destroy(pl->sfp_cage_port); + + pl->sfp_cage_port = NULL; +} + static int phylink_register_sfp(struct phylink *pl, const struct fwnode_handle *fwnode) { @@ -1782,9 +1825,18 @@ static int phylink_register_sfp(struct phylink *pl, pl->sfp_bus = bus; + ret = phylink_create_sfp_cage_port(pl); + if (ret) { + sfp_bus_put(bus); + return ret; + } + ret = sfp_bus_add_upstream(bus, pl, &sfp_phylink_ops); sfp_bus_put(bus); + if (ret) + phylink_destroy_sfp_cage_port(pl); + return ret; } @@ -2067,6 +2119,7 @@ EXPORT_SYMBOL_GPL(phylink_create); void phylink_destroy(struct phylink *pl) { sfp_bus_del_upstream(pl->sfp_bus); + phylink_destroy_sfp_cage_port(pl); if (pl->link_gpio) gpiod_put(pl->link_gpio); -- 2.55.0