Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp6831026rdb; Fri, 15 Dec 2023 09:21:43 -0800 (PST) X-Google-Smtp-Source: AGHT+IGfDD8hH3oG1Dw96tBoxUIXp03L7oz1C3XA3MxqoQrzuQGJe+ij361hNNby89uYfyWAJwd1 X-Received: by 2002:a05:6a00:1acc:b0:6ce:55b1:caf2 with SMTP id f12-20020a056a001acc00b006ce55b1caf2mr8140558pfv.3.1702660902690; Fri, 15 Dec 2023 09:21:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702660902; cv=none; d=google.com; s=arc-20160816; b=JSc3QC4u91XPqlNg9rXxWla83Mqp0vCZMxr0E0hyt7PsGQcUtHCGurIMEEg90DO4GP d0F+CEcnAO+Y3/YxboNw20MGdRC+KVrnDeJ8RlY5WhtcjbbPd+FZj17ziTV3fSEKvNNS 1ho6AkSnFDfd9YkU4jhVFMqxyksg0KmjDpQU/ZpjPwOI7lEqOPIGTEare6gCvPXDtuWk G5lv2rvbufz4LfqO+dRhWjb82D2sqbNpquv3WtUM+IvDC8bLP6xu49ba0QcOS5q0Wgzw H7YcA1pb2dyl484g5o0LWpULvKqSXbGEWjMBcMD2s+GXFIPXcZvt+TZsbEbXXv3lT/6g jGLw== ARC-Message-Signature: i=1; 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:message-id:date:subject:cc:to :from:dkim-signature; bh=xekBtYrzEfeddVkt5T9IKlymKf8ZyjRogSe1ZvmnuGg=; fh=01/i7K9ues3Vkkz8uyECvnCPITXmGs/30yOh5FbyFgY=; b=kdEsqsXSXQWZgAmsrhx474Zt0Nr34BUYFUu3ObkvrMvKRqwGv7cZBZLM1GS737ytee tN5avtlO8LHTBsN1o6X1Tw+hIR5Eh9npgj+hwPuP6W8PCBi/lnF0HBZruROYMAfn1iSP jgo6RC+QXDBVE35E9ckMQ34vWEZtVX7HNRl/leRci+F9+O/d+yq6V6Z23Gw39MbQDX3v JFCbgNF8BHiV7IbTDdI4Kxf/lnNXDvBQ3ik+VKrGTE6mlL/knCDR4EfFVGpvaRHRPs4Z 5jDp82hAp8t8RbN9X8DNXKvr1/0et2vzdoyZUeadtEHJXys2bPiorpnxEEIa5+2yMKSi 28Fg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=GsxhrFTr; spf=pass (google.com: domain of linux-kernel+bounces-1392-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-1392-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id h18-20020a056a00231200b006cdfbccebc5si13226738pfh.316.2023.12.15.09.21.42 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Dec 2023 09:21:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-1392-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=GsxhrFTr; spf=pass (google.com: domain of linux-kernel+bounces-1392-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-1392-linux.lists.archive=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 4D572286CE3 for ; Fri, 15 Dec 2023 17:21:13 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 59AE046540; Fri, 15 Dec 2023 17:12:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="GsxhrFTr" X-Original-To: linux-kernel@vger.kernel.org Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) (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 9DF05446DA; Fri, 15 Dec 2023 17:12:42 +0000 (UTC) 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 DF2B9C0002; Fri, 15 Dec 2023 17:12:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1702660360; 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; bh=xekBtYrzEfeddVkt5T9IKlymKf8ZyjRogSe1ZvmnuGg=; b=GsxhrFTr6YBTjpyd1T4DAoYvUrXV4W5tPMgSU8RxDu9GUqiZnVL2PQSK1M5kVSXZfO2kAK 6CqorskmU7E95I+JWTl+tb6m70n3LL5/CSKQgu+JEsg7z0gDTib4NJRhysJnXB+i6DOXk0 qz+hBN6q0Buv2G4MwnoaIJQvZhREFQYu5SrIlwp1sykoI2uDyjCLLb1YwQBLnUgetv1u6y rTe2bOxpjQiciTorImkMZCZjxUA5MLj7wEJbbUjIigZyKqk4urj5d+YL7uHFS6jVobZVD9 Tx0UN5DjQfPEp3DvqZIFVfvpq5vCG4dHle7gABWOPZWwDPJ3OBguZi/C62laAQ== 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=20Maincent?= , Jesse Brandeburg , Jonathan Corbet , =?UTF-8?q?Marek=20Beh=C3=BAn?= , Piergiorgio Beruto , Oleksij Rempel , =?UTF-8?q?Nicol=C3=B2=20Veronese?= Subject: [PATCH net-next v4 00/13] Introduce PHY listing and link_topology tracking Date: Fri, 15 Dec 2023 18:12:22 +0100 Message-ID: <20231215171237.1152563-1-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-GND-Sasl: maxime.chevallier@bootlin.com Hello everyone, Here's a V4 of the multi-PHY support series. This is mostly bugfixes to allow building without phylib, but I also removed the RFC flag. The blurb bellow is a full description of the series, however I realised that I failed to mentionned why this is called "phy_link_topology". The end-goal of this struct is not only to track the phy_devices but also the different front-facing ports across the topology. I'm picking a pretty generic name to convey the fact that this should be strictly related to PHYs. As a remainder, this ongoing work aims ultimately at supporting complex link topologies that involve multiplexing multiple PHYs/SFPs on a single netdevice. As a first step, it's required that we are able to enumerate the PHYs on a given ethernet interface. By just doing so, we also improve already-existing use-cases, namely the copper SFP modules support when a media-converter is used (as we have 2 PHYs on the link, but only one is referenced by net_device.phydev, which is used on a variety of netlink commands). The series is architectured as follows : - The first patch adds the notion of phy_link_topology, which tracks all PHYs attached to a netdevice. - Patches 2, 3 and 4 adds some plumbing into SFP and phylib to be able to connect the dots when building the topology tree, to know which PHY is connected to which SFP bus, trying not to be too invasive on phylib. - Patch 5 allows passing a PHY_INDEX to ethnl commands. I'm uncertain about this, as there are at least 4 netlink commands ( 5 with the one introduced in patch 7 ) that targets PHYs directly or indirectly, which to me makes it worth-it to have a generic way to pass a PHY index to commands, however the approach taken may be too generic. - Patch 6 is the netlink spec update + ethtool-user.c|h autogenerated code update (the autogenerated code triggers checkpatch warning though) - Patch 7 introduces a new netlink command set to list PHYs on a netdevice. It implements a custom DUMP and GET operation to allow filtered dumps, that lists all PHYs on a given netdevice. I couldn't use most of ethnl's plumbing though. - Patch 8 is the netlink spec update + ethtool-user.c|h update for that new command - Patch 8,9,10 and 11 updates the PLCA, strset, cable-test and pse netlink commands to use the user-provided PHY instead of net_device.phydev. - Finally patch 12 adds some documentation for this whole work. Examples ======== Here's a short overview of the kind of operations you can have regarding the PHY topology. These tests were performed on a MacchiatoBin, which has 3 interfaces : eth0 and eth1 have the following layout: MAC - PHY - SFP eth2 has this more classic topology : MAC - PHY - RJ45 finally eth3 has the following topology : MAC - SFP When performing a dump with all interfaces down, we don't get any result, as no PHY has been attached to their respective net_device : # ./cli.py --spec specs/ethtool.yaml --schema genetlink-legacy.yaml --dump phy-get None The following output is with eth0, eth2 and eth3 up, but no SFP module inserted in none of the interfaces : # ./cli.py --spec specs/ethtool.yaml --schema genetlink-legacy.yaml --dump phy-get [{'downstream-sfp-name': 'sfp-eth0', 'drvname': 'mv88x3310', 'header': {'dev-index': 2, 'dev-name': 'eth0'}, 'id': 0, 'index': 1, 'name': 'f212a600.mdio-mii:00', 'upstream-type': 'mac'}, {'drvname': 'Marvell 88E1510', 'header': {'dev-index': 4, 'dev-name': 'eth2'}, 'id': 21040593, 'index': 1, 'name': 'f212a200.mdio-mii:00', 'upstream-type': 'mac'}] And now is a dump operation with a copper SFP in the eth0 port : # ./cli.py --spec specs/ethtool.yaml --schema genetlink-legacy.yaml --dump phy-get [{'downstream-sfp-name': 'sfp-eth0', 'drvname': 'mv88x3310', 'header': {'dev-index': 2, 'dev-name': 'eth0'}, 'id': 0, 'index': 1, 'name': 'f212a600.mdio-mii:00', 'upstream-type': 'mac'}, {'drvname': 'Marvell 88E1111', 'header': {'dev-index': 2, 'dev-name': 'eth0'}, 'id': 21040322, 'index': 2, 'name': 'i2c:sfp-eth0:16', 'upstream': {'index': 1, 'sfp-name': 'sfp-eth0'}, 'upstream-type': 'phy'}, {'drvname': 'Marvell 88E1510', 'header': {'dev-index': 4, 'dev-name': 'eth2'}, 'id': 21040593, 'index': 1, 'name': 'f212a200.mdio-mii:00', 'upstream-type': 'mac'}] -- Note that this shouldn't actually work as the 88x3310 PHY doesn't allow a 1G SFP to be connected to its SFP interface, and I don't have a 10G copper SFP, so for the sake of the demo I applied the following modification, which of courses gives a non-functionnal link, but the PHY attach still works, which is what I want to demonstrate : @@ -488,7 +488,7 @@ static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) if (iface != PHY_INTERFACE_MODE_10GBASER) { dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n"); - return -EINVAL; + //return -EINVAL; } return 0; } Finally an example of the filtered DUMP operation that Jakub suggested in V1 : # ./cli.py --spec specs/ethtool.yaml --schema genetlink-legacy.yaml \ # --dump phy-get --json '{"header" : {"dev-name" : "eth0"}}' [{'downstream-sfp-name': 'sfp-eth0', 'drvname': 'mv88x3310', 'header': {'dev-index': 2, 'dev-name': 'eth0'}, 'id': 0, 'index': 1, 'name': 'f212a600.mdio-mii:00', 'upstream-type': 'mac'}, {'drvname': 'Marvell 88E1111', 'header': {'dev-index': 2, 'dev-name': 'eth0'}, 'id': 21040322, 'index': 2, 'name': 'i2c:sfp-eth0:16', 'upstream': {'index': 1, 'sfp-name': 'sfp-eth0'}, 'upstream-type': 'phy'}] And a classic GET operation allows querying a single PHY's info : # ./cli.py --spec specs/ethtool.yaml --schema genetlink-legacy.yaml \ # --do phy-get --json '{"header" : {"dev-name" : "eth0", "phy-index" : 2}}' {'drvname': 'Marvell 88E1111', 'header': {'dev-index': 2, 'dev-name': 'eth0'}, 'id': 21040322, 'index': 2, 'name': 'i2c:sfp-eth0:16', 'upstream': {'index': 1, 'sfp-name': 'sfp-eth0'}, 'upstream-type': 'phy'} Changes in V4: - Dropped the RFC flag - Made the net_device integration independent to having phylib enabled - Removed the autogenerated ethtool-user code for the YNL specs Changes in V3: - Added RTNL assertions where needed - Fixed issues in the DUMP code for PHY_GET, which crashed when running it twice in a row - Added the documentation, and moved in-source docs around - renamed link_topology to phy_link_topology Changes in V2: - Added the DUMP operation - Added much more information in the reported data, to be able to reconstruct precisely the topology tree - renamed phy_list to link_topology Maxime Chevallier (13): net: phy: Introduce ethernet link topology representation net: sfp: pass the phy_device when disconnecting an sfp module's PHY net: phy: add helpers to handle sfp phy connect/disconnect net: sfp: Add helper to return the SFP bus name net: ethtool: Allow passing a phy index for some commands netlink: specs: add phy-index as a header parameter net: ethtool: Introduce a command to list PHYs on an interface netlink: specs: add ethnl PHY_GET command set net: ethtool: plca: Target the command to the requested PHY net: ethtool: pse-pd: Target the command to the requested PHY net: ethtool: cable-test: Target the command to the requested PHY net: ethtool: strset: Allow querying phy stats by index Documentation: networking: document phy_link_topology Documentation/netlink/specs/ethtool.yaml | 68 ++++ Documentation/networking/ethtool-netlink.rst | 51 +++ Documentation/networking/index.rst | 1 + .../networking/phy-link-topology.rst | 121 +++++++ MAINTAINERS | 2 + drivers/net/phy/Makefile | 2 +- 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 | 55 ++++ drivers/net/phy/phy_link_topology.c | 79 +++++ drivers/net/phy/phylink.c | 3 +- drivers/net/phy/sfp-bus.c | 15 +- include/linux/netdevice.h | 4 +- include/linux/phy.h | 6 + include/linux/phy_link_topology.h | 64 ++++ include/linux/phy_link_topology_core.h | 19 ++ include/linux/sfp.h | 8 +- include/uapi/linux/ethtool.h | 16 + include/uapi/linux/ethtool_netlink.h | 30 ++ net/core/dev.c | 3 + net/ethtool/Makefile | 2 +- net/ethtool/cabletest.c | 12 +- net/ethtool/netlink.c | 33 ++ net/ethtool/netlink.h | 12 +- net/ethtool/phy.c | 306 ++++++++++++++++++ net/ethtool/plca.c | 13 +- net/ethtool/pse-pd.c | 14 +- net/ethtool/strset.c | 15 +- 30 files changed, 922 insertions(+), 40 deletions(-) create mode 100644 Documentation/networking/phy-link-topology.rst create mode 100644 drivers/net/phy/phy_link_topology.c create mode 100644 include/linux/phy_link_topology.h create mode 100644 include/linux/phy_link_topology_core.h create mode 100644 net/ethtool/phy.c -- 2.43.0