From patchwork Thu Sep 7 09:24:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 13376513 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 0E50312B77 for ; Thu, 7 Sep 2023 15:32:53 +0000 (UTC) Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [IPv6:2001:4b98:dc4:8::240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AEC071FD3; Thu, 7 Sep 2023 08:32:38 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [IPv6:2001:4b98:dc4:8::222]) by mslow1.mail.gandi.net (Postfix) with ESMTP id 34722D677E; Thu, 7 Sep 2023 09:24:39 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id B486940006; Thu, 7 Sep 2023 09:24:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1694078657; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NKYGfipofVWW/3g1qYBUmoAQ/1wK2Hf5hr6dKrL514M=; b=ijshBAXsDikrGSk8aI0z3FKVhqzPN3TK04DROLA3/+t4b1AKJrZe0UuyKGZ1uQSs6fXZna lVM95zVnuFR3Hthj9/bdFg7uL3OC95yALhcmjHUI5SgZm0kq9ngmcR2XezdoM9HaJYdCf6 o58wI4ByYcZ4QrXOs8kfX4pek+BDZN3lf/x0nRfdJjajdU8ze1qbT+E0g5ri/YSDczdYIr kv5TQCkfnp4uHuopvMb1M7z3PHoNlGc6uPUw6qLBHRU/ioCj+zTOJrnaXXxSakRCdt7obK p6HWPFaedVdZ3rr/OKZ2apACl8tz6DcbMPlQA9tYHki55WthAAMTecHzCHcIbg== From: Maxime Chevallier To: davem@davemloft.net Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Florian Fainelli , Heiner Kallweit , Russell King , Vladimir Oltean , Oleksij Rempel , =?utf-8?q?Nicol=C3=B2_Veronese?= , thomas.petazzoni@bootlin.com, Christophe Leroy Subject: [RFC PATCH net-next 3/7] net: phy: add helpers to handle sfp phy connect/disconnect Date: Thu, 7 Sep 2023 11:24:01 +0200 Message-ID: <20230907092407.647139-4-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230907092407.647139-1-maxime.chevallier@bootlin.com> References: <20230907092407.647139-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-Sasl: maxime.chevallier@bootlin.com X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC There are a few PHY drivers that can handle SFP modules through their sfp_upstream_ops. Introduce Phylib helpers to keep track of connected SFP PHYs in a netdevice's namespace, by adding the SFP PHY to the upstream PHY's netdev's namespace. By doing so, these SFP PHYs can be enumerated and exposed to users, which will be able to use their capabilities. Signed-off-by: Maxime Chevallier --- drivers/net/phy/at803x.c | 2 ++ drivers/net/phy/marvell-88x2222.c | 2 ++ drivers/net/phy/marvell.c | 2 ++ drivers/net/phy/marvell10g.c | 2 ++ drivers/net/phy/phy_device.c | 40 +++++++++++++++++++++++++++++++ include/linux/phy.h | 2 ++ 6 files changed, 50 insertions(+) diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index 37fb033e1c29..9b1659b03aa5 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c @@ -730,6 +730,8 @@ static const struct sfp_upstream_ops at803x_sfp_ops = { .attach = phy_sfp_attach, .detach = phy_sfp_detach, .module_insert = at803x_sfp_insert, + .connect_phy = phy_sfp_connect_phy, + .disconnect_phy = phy_sfp_disconnect_phy, }; static int at803x_parse_dt(struct phy_device *phydev) diff --git a/drivers/net/phy/marvell-88x2222.c b/drivers/net/phy/marvell-88x2222.c index e3aa30dad2e6..3f77bbc7e04f 100644 --- a/drivers/net/phy/marvell-88x2222.c +++ b/drivers/net/phy/marvell-88x2222.c @@ -555,6 +555,8 @@ static const struct sfp_upstream_ops sfp_phy_ops = { .link_down = mv2222_sfp_link_down, .attach = phy_sfp_attach, .detach = phy_sfp_detach, + .connect_phy = phy_sfp_connect_phy, + .disconnect_phy = phy_sfp_disconnect_phy, }; static int mv2222_probe(struct phy_device *phydev) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index eba652a4c1d8..674e29bce2cc 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -3254,6 +3254,8 @@ static const struct sfp_upstream_ops m88e1510_sfp_ops = { .module_remove = m88e1510_sfp_remove, .attach = phy_sfp_attach, .detach = phy_sfp_detach, + .connect_phy = phy_sfp_connect_phy, + .disconnect_phy = phy_sfp_disconnect_phy, }; static int m88e1510_probe(struct phy_device *phydev) diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c index d4bb90d76881..a88ebc0a6be5 100644 --- a/drivers/net/phy/marvell10g.c +++ b/drivers/net/phy/marvell10g.c @@ -496,6 +496,8 @@ static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) static const struct sfp_upstream_ops mv3310_sfp_ops = { .attach = phy_sfp_attach, .detach = phy_sfp_detach, + .connect_phy = phy_sfp_connect_phy, + .disconnect_phy = phy_sfp_disconnect_phy, .module_insert = mv3310_sfp_insert, }; diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 0c029ae5130a..090c5b14a7b8 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1362,6 +1362,46 @@ phy_standalone_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(phy_standalone); +/** + * phy_sfp_connect_phy - Connect the SFP module's PHY to the upstream PHY + * @upstream: pointer to the upstream phy device + * @phy: pointer to the SFP module's phy device + * + * This helper allows keeping track of PHY devices on the link. It adds the + * SFP module's phy to the phy namespace of the upstream phy + */ +int phy_sfp_connect_phy(void *upstream, struct phy_device *phy) +{ + struct phy_device *phydev = upstream; + struct phy_namespace *phy_ns = phy_get_ns(phydev); + + if (phy_ns) + phy_ns_add_phy(phy_ns, phy); + + return 0; +} +EXPORT_SYMBOL(phy_sfp_connect_phy); + +/** + * phy_sfp_disconnect_phy - Disconnect the SFP module's PHY from the upstream PHY + * @upstream: pointer to the upstream phy device + * @phy: pointer to the SFP module's phy device + * + * This helper allows keeping track of PHY devices on the link. It removes the + * SFP module's phy to the phy namespace of the upstream phy. As the module phy + * will be destroyed, re-inserting the same module will add a new phy with a + * new index. + */ +void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy) +{ + struct phy_device *phydev = upstream; + struct phy_namespace *phy_ns = phy_get_ns(phydev); + + if (phy_ns) + phy_ns_del_phy(phy_ns, phy); +} +EXPORT_SYMBOL(phy_sfp_disconnect_phy); + /** * phy_sfp_attach - attach the SFP bus to the PHY upstream network device * @upstream: pointer to the phy device diff --git a/include/linux/phy.h b/include/linux/phy.h index b12fd33aa84a..02fdf5075f31 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -1720,6 +1720,8 @@ int phy_suspend(struct phy_device *phydev); int phy_resume(struct phy_device *phydev); int __phy_resume(struct phy_device *phydev); int phy_loopback(struct phy_device *phydev, bool enable); +int phy_sfp_connect_phy(void *upstream, struct phy_device *phy); +void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy); void phy_sfp_attach(void *upstream, struct sfp_bus *bus); void phy_sfp_detach(void *upstream, struct sfp_bus *bus); int phy_sfp_probe(struct phy_device *phydev,