From patchwork Wed Feb 28 11:47:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 207817 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp3301931dyb; Wed, 28 Feb 2024 04:10:49 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUTvPaHwvBwXJEQ0XpT/NpWOUFsdUmUW6zpvoKvEUVP4ySbDIPGeCElpDMlqPyJKU6ZbQ1tYubnx+iBwAd+58pk//TIFw== X-Google-Smtp-Source: AGHT+IHd0IGijOpflImROJSpoCnI1gOupvMUqv+6ciBSH8SDC3xeb2zvTp42U4ViT/utg4wtzcX+ X-Received: by 2002:a62:f24d:0:b0:6e5:5857:6691 with SMTP id y13-20020a62f24d000000b006e558576691mr2637623pfl.17.1709122249112; Wed, 28 Feb 2024 04:10:49 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709122249; cv=pass; d=google.com; s=arc-20160816; b=ZU1yaZxI0iZg2JZOSmfZfGyOYNhh3TKVYKYhWnQa4Ud6+IdK7zIV17nyD2AG5PyIhJ hDiTbud5n7VTE5uuapPPnWuT/iam+LbkWpa0kKuZBtz/Kca/wV4lFdmQ2zY81sNvGaZ8 xIFaYviwa3myWsLT9USLYy+DMofO1eVLpgotUPQ1V8LFTxEvfocoj+uaBstBsX3X+IHl AY1bV1wWTni+ZZtin32RPDeDvpULl5+uD82Hx+0fhjZeBYncNq0uHygaGOldsgh5DqGZ iUjI9pdnVkL00uN26Fiqh7IKVpHKlE7cTY/TQ43fMxUZv3yMJy6olryxqvP7UoO9nPOq DZZw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=WGnNVUxK8+4nuwNfaVCRc3innySKx+Yfr/4TeTdTE3E=; fh=1vUu/d1GTjraph6G+ET+Z0z13QVrf6oL/IrrK9zaTF8=; b=NPlrASGZQAlNoT+S0AXNMR8i83zAR6dHXBR9Ji0pOPI5SwHk2CKF94EUlgtpgLSgj6 UAk/zAfFhnehBJk/vskww3TioK9jPTR1IUQNmUsJsfWkAiD14md1y64jrR0lfQOBp5Jc DD4YgIQUFNwJmUNyH67a2QmNPr3ugnAcUUfodQQFWDAlWkQWuMfexLLQx7h8arNqP753 B1hbVt3Fq0witf3+2+YxmSd8g9Hw4pb55uG88fevR4tnYfTYKCKllP2oZr7pDji+NWxi IqW0XhbxESrO/ngMGb32QUgVZcWuIiVG/pr1J/MKMJwE65rdlCxcL610CPUNXaYSfRFR as9g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=VFPMNCrv; arc=pass (i=1 spf=pass spfdomain=bootlin.com dkim=pass dkdomain=bootlin.com dmarc=pass fromdomain=bootlin.com); spf=pass (google.com: domain of linux-kernel+bounces-84947-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-84947-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id 7-20020a630a07000000b005dc82a6711fsi7224701pgk.102.2024.02.28.04.10.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 04:10:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-84947-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=VFPMNCrv; arc=pass (i=1 spf=pass spfdomain=bootlin.com dkim=pass dkdomain=bootlin.com dmarc=pass fromdomain=bootlin.com); spf=pass (google.com: domain of linux-kernel+bounces-84947-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-84947-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id D6C542955B3 for ; Wed, 28 Feb 2024 11:51:10 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 502291474C3; Wed, 28 Feb 2024 11:47:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="VFPMNCrv" Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (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 6D4597353F; Wed, 28 Feb 2024 11:47:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709120867; cv=none; b=QlL7WkzX/RsiIKLL+CNMluywSXHGvD4aqCehgRj6d4CuZtLd7vWXgzQtQbe3TH62M5vQvqsF0e45rn/jISIvKPkM89K1TAug/7jjGhNwRmQ7D9h558/rRW/5XsSP3fre1fqEbErRlTLrt6q8Avj+EW5/KkMr4mC/C+xn/LuBvL4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709120867; c=relaxed/simple; bh=IYMziL0EvScVpg14JRyOfpUiLrK1HAFwJ6mNbJqmX04=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tI6XlB6BdOi+IDCfCm9h3yRpYC3AMU+Vd9/5ZqGxT5M5xX0vGZBVzxOAbGsHP/WDw0t0aWHUE5ySlV6DB1K97sHO6uJQ9205TVbSEN2VGYlhNkCdRCu5t51XnlQ49to8c+vEAxrWHU2JkoLKACY5Qfzbh//HD/kI+4FSpjOec2w= 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=VFPMNCrv; arc=none smtp.client-ip=217.70.183.197 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 Received: by mail.gandi.net (Postfix) with ESMTPSA id ECB201C000F; Wed, 28 Feb 2024 11:47:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1709120858; 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=WGnNVUxK8+4nuwNfaVCRc3innySKx+Yfr/4TeTdTE3E=; b=VFPMNCrvMFQSeCWAhHmCDV35Qm8HbB/vXW3Zgop410rjRlIxv+bcZGB8qdua6Vd+4KmYIp xtSvhFzG+LXGIBPmMcchoDJcaXBd5NT2x5dGTnPj/AAl0cEwuhxJXwJLkuNhrxw3slHYtl crE8HyO0vkeZYNadKDhOhojga+5cxJCsnyhXSbeGr51G+0H+pUfq5pdLODNlcy9u3MWnFi XS8cAs9amwnmrAyY6OEbF8+/wYpvynJO1M30EjBu3lf2gL4zo9RqSEpU6NM5g37oLMT6fy E/2y7wuxAzke7oz7Pe5vkrCO9NE9bWO+oCu4CZvuDE4734rKq8NcwSrhYbpXpA== From: Maxime Chevallier To: davem@davemloft.net Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , linux-arm-kernel@lists.infradead.org, Christophe Leroy , Herve Codina , Florian Fainelli , Heiner Kallweit , Vladimir Oltean , =?utf-8?q?K=C3=B6ry_Maincent?= , Jesse Brandeburg , Jonathan Corbet , =?utf-8?q?Marek_Beh=C3=BAn?= , Piergiorgio Beruto , Oleksij Rempel , =?utf-8?q?Nicol=C3=B2_Veronese?= , Simon Horman , mwojtas@chromium.org Subject: [PATCH net-next v9 03/13] net: phy: add helpers to handle sfp phy connect/disconnect Date: Wed, 28 Feb 2024 12:47:17 +0100 Message-ID: <20240228114728.51861-4-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240228114728.51861-1-maxime.chevallier@bootlin.com> References: <20240228114728.51861-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-Sasl: maxime.chevallier@bootlin.com X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792144571543796000 X-GMAIL-MSGID: 1792144571543796000 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 --- V9: No changes V8: Took the at803x into account V7: No changes V6: Moved phy_get_link_topology() definition to this patch V5: No Changes V4: Rebased the at803x part with the newer version on net-next V3: Renaming V2: Renaming 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 | 48 +++++++++++++++++++++++++++++++ drivers/net/phy/qcom/at803x.c | 2 ++ drivers/net/phy/qcom/qca807x.c | 2 ++ include/linux/phy.h | 2 ++ 7 files changed, 60 insertions(+) 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 1faa22f58366..c26d20bdac51 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 ad43e280930c..6642eb642d4b 100644 --- a/drivers/net/phy/marvell10g.c +++ b/drivers/net/phy/marvell10g.c @@ -503,6 +503,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 8478199f2d89..d47a2aa6ce87 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -277,6 +277,14 @@ static void phy_mdio_device_remove(struct mdio_device *mdiodev) static struct phy_driver genphy_driver; +static struct phy_link_topology *phy_get_link_topology(struct phy_device *phydev) +{ + if (phydev->attached_dev) + return phydev->attached_dev->link_topo; + + return NULL; +} + static LIST_HEAD(phy_fixup_list); static DEFINE_MUTEX(phy_fixup_lock); @@ -1370,6 +1378,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_link_topology *topo = phy_get_link_topology(phydev); + + if (topo) + return phy_link_topo_add_phy(topo, phy, PHY_UPSTREAM_PHY, phydev); + + 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_link_topology *topo = phy_get_link_topology(phydev); + + if (topo) + phy_link_topo_del_phy(topo, 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/drivers/net/phy/qcom/at803x.c b/drivers/net/phy/qcom/at803x.c index 4717c59d51d0..235d242076cb 100644 --- a/drivers/net/phy/qcom/at803x.c +++ b/drivers/net/phy/qcom/at803x.c @@ -769,6 +769,8 @@ static const struct sfp_upstream_ops at8031_sfp_ops = { .attach = phy_sfp_attach, .detach = phy_sfp_detach, .module_insert = at8031_sfp_insert, + .connect_phy = phy_sfp_connect_phy, + .disconnect_phy = phy_sfp_disconnect_phy, }; static int at8031_parse_dt(struct phy_device *phydev) diff --git a/drivers/net/phy/qcom/qca807x.c b/drivers/net/phy/qcom/qca807x.c index 780c28e2e4aa..0ff16122c3d9 100644 --- a/drivers/net/phy/qcom/qca807x.c +++ b/drivers/net/phy/qcom/qca807x.c @@ -699,6 +699,8 @@ static const struct sfp_upstream_ops qca807x_sfp_ops = { .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, }; static int qca807x_probe(struct phy_device *phydev) diff --git a/include/linux/phy.h b/include/linux/phy.h index 236b95472865..eb505097bc9f 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -1752,6 +1752,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,