From nobody Thu Sep 18 12:50:19 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5532C4708E for ; Tue, 6 Dec 2022 12:52:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234350AbiLFMwl (ORCPT ); Tue, 6 Dec 2022 07:52:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56450 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234390AbiLFMwf (ORCPT ); Tue, 6 Dec 2022 07:52:35 -0500 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B6E9E1839C; Tue, 6 Dec 2022 04:52:24 -0800 (PST) Received: by mail-ed1-x52c.google.com with SMTP id m19so20084347edj.8; Tue, 06 Dec 2022 04:52:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc:subject:date:message-id:reply-to; bh=74BFqwUTcgpc/7zsTZVAsiQmX/jMtMmjSZEV7hyDC7M=; b=DTgB7WMVy1PTMRcvpYCqzjztI4ZyizUfgp3jdquAxGQnMCC8UiH1iEMBTlFyNb93Hl ZXJzjJV0y4PXKmCfWT/XlOK1lDi4skQ9psq65XLy6d6dolwxqlZNGUWK2ItfIUDkbS7i YE97Gj7d1jsiAAadTiX29KhybQxVNYURKsZFvypT3VZHlL7P/OZtm9LfM8TcwKc5xtmI 2ou5uFhiBPx8WYcjTLZyQ5zSiaxWbVJwIvLsfOXDR62NdNJTQiggYVFXf6YmCQQPe9Xb CiwnpZN+AXvXRFonV9sJZSVH9yzHz6sKlXbkm4e6V6kESSDJKfj1zITFZDH9fxS9RemP ObSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=74BFqwUTcgpc/7zsTZVAsiQmX/jMtMmjSZEV7hyDC7M=; b=QULeiZTpr41lD+u51PGk6yP9uGJTlKqkq625HmUg/LKerZIGtV+J9gV/kbXJYiPi4J 8yqJ+RYIKGQIX4Tyd5qDe9auXvB+YEpOK1Y9jgY7OLuydDgq4ok+s52S2Ap6EX7RkbwP 8YeuQylFxDVH/dRaes8NEekjCsWST0oHu6vn5LkliC59BVvidTh82K3sbIE8737/EqmJ K75Ybde+jWYk7ZYbvvY1brHOEpBgAp3aROBHUXqfKrqviQHNO0WQIWS4pfrLDNZ7gfjQ HS3kFNjvDTZHhIbQfgII26gbnIju4Hf/RTXdklkjlXygBPdT8DqA7UB/yqHFW3R2Ra01 cZiw== X-Gm-Message-State: ANoB5pm6sDGs5FJek7aEn0KdmxgNbjJTEil3BRHwWHMtrpL1MldAW0mJ ScKKILZzAEikpLUDkcGorns= X-Google-Smtp-Source: AA0mqf4cNKmGVTeRAT/vACEY88Ya7lYQfi3wqhpRSpjsMKUL1h/+ujgbgajdLID9CyIcdvYBYIMkOQ== X-Received: by 2002:aa7:cc8d:0:b0:461:15f0:a574 with SMTP id p13-20020aa7cc8d000000b0046115f0a574mr21537041edt.187.1670331142866; Tue, 06 Dec 2022 04:52:22 -0800 (PST) Received: from gvm01 (net-2-45-26-236.cust.vodafonedsl.it. [2.45.26.236]) by smtp.gmail.com with ESMTPSA id tj13-20020a170907c24d00b00780b1979adesm7365886ejc.218.2022.12.06.04.52.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 04:52:22 -0800 (PST) Date: Tue, 6 Dec 2022 13:52:32 +0100 From: Piergiorgio Beruto To: Andrew Lunn , Heiner Kallweit , Russell King , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Oleksij Rempel Subject: [PATCH v4 net-next 1/5] net/ethtool: add netlink interface for the PLCA RS Message-ID: <6ac7b9b950c732b8d7d9005b716e23cea1d6463f.1670329232.git.piergiorgio.beruto@gmail.com> References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Disposition: inline Content-Transfer-Encoding: quoted-printable In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add support for configuring the PLCA Reconciliation Sublayer on multi-drop PHYs that support IEEE802.3cg-2019 Clause 148 (e.g., 10BASE-T1S). This patch adds the appropriate netlink interface to ethtool. Signed-off-by: Piergiorgio Beruto --- Documentation/networking/ethtool-netlink.rst | 133 +++++++++ MAINTAINERS | 6 + include/linux/ethtool.h | 11 + include/linux/phy.h | 64 ++++ include/uapi/linux/ethtool_netlink.h | 25 ++ net/ethtool/Makefile | 2 +- net/ethtool/netlink.c | 30 ++ net/ethtool/netlink.h | 6 + net/ethtool/plca.c | 290 +++++++++++++++++++ 9 files changed, 566 insertions(+), 1 deletion(-) create mode 100644 net/ethtool/plca.c diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/n= etworking/ethtool-netlink.rst index bede24ef44fd..044c20a52e24 100644 --- a/Documentation/networking/ethtool-netlink.rst +++ b/Documentation/networking/ethtool-netlink.rst @@ -1687,6 +1687,136 @@ to control PoDL PSE Admin functions. This option is= implementing ``IEEE 802.3-2018`` 30.15.1.2.1 acPoDLPSEAdminControl. See ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` for supported values. =20 +PLCA_GET_CFG +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Gets PLCA RS attributes. + +Request contents: + + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + ``ETHTOOL_A_PLCA_HEADER`` nested request header + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Kernel response contents: + + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + ``ETHTOOL_A_PLCA_HEADER`` nested reply header + ``ETHTOOL_A_PLCA_VERSION`` u16 Supported PLCA management + interface standard/versi= on + ``ETHTOOL_A_PLCA_ENABLED`` u8 PLCA Admin State + ``ETHTOOL_A_PLCA_NODE_ID`` u8 PLCA unique local node ID + ``ETHTOOL_A_PLCA_NODE_CNT`` u8 Number of PLCA nodes on = the + netkork, including the + coordinator + ``ETHTOOL_A_PLCA_TO_TMR`` u8 Transmit Opportunity Tim= er + value in bit-times (BT) + ``ETHTOOL_A_PLCA_BURST_CNT`` u8 Number of additional pac= kets + the node is allowed to s= end + within a single TO + ``ETHTOOL_A_PLCA_BURST_TMR`` u8 Time to wait for the MAC= to + transmit a new frame bef= ore + terminating the burst + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + +When set, the optional ``ETHTOOL_A_PLCA_VERSION`` attribute indicates which +standard and version the PLCA management interface complies to. When not s= et, +the interface is vendor-specific and (possibly) supplied by the driver. +The OPEN Alliance SIG specifies a standard register map for 10BASE-T1S PHYs +embedding the PLCA Reconcialiation Sublayer. See "10BASE-T1S PLCA Manageme= nt +Registers" at https://www.opensig.org/about/specifications/. When this sta= ndard +is supported, ETHTOOL_A_PLCA_VERSION is reported as 0Axx where 'xx' denote= s the +map version (see Table A.1.0 =E2=80=94 IDVER bits assignment). + +When set, the optional ``ETHTOOL_A_PLCA_ENABLED`` attribute indicates the +administrative state of the PLCA RS. When not set, the node operates in "p= lain" +CSMA/CD mode. This option is corresponding to ``IEEE 802.3cg-2019`` 30.16.= 1.1.1 +aPLCAAdminState / 30.16.1.2.1 acPLCAAdminControl. + +When set, the optional ``ETHTOOL_A_PLCA_NODE_ID`` attribute indicates the +configured local node ID of the PHY. This ID determines which transmit +opportunity (TO) is reserved for the node to transmit into. This option is +corresponding to ``IEEE 802.3cg-2019`` 30.16.1.1.4 aPLCALocalNodeID. + +When set, the optional ``ETHTOOL_A_PLCA_NODE_CNT`` attribute indicates the +configured maximum number of PLCA nodes on the mixing-segment. This number +determines the total number of transmit opportunities generated during a +PLCA cycle. This attribute is relevant only for the PLCA coordinator, whic= h is +the node with aPLCALocalNodeID set to 0. Follower nodes ignore this settin= g. +This option is corresponding to ``IEEE 802.3cg-2019`` 30.16.1.1.3 +aPLCANodeCount. + +When set, the optional ``ETHTOOL_A_PLCA_TO_TMR`` attribute indicates the +configured value of the transmit opportunity timer in bit-times. This value +must be set equal across all nodes sharing the medium for PLCA to work +correctly. This option is corresponding to ``IEEE 802.3cg-2019`` 30.16.1.1= .5 +aPLCATransmitOpportunityTimer. + +When set, the optional ``ETHTOOL_A_PLCA_BURST_CNT`` attribute indicates the +configured number of extra packets that the node is allowed to send during= a +single transmit opportunity. By default, this attribute is 0, meaning that +the node can only send a sigle frame per TO. When greater than 0, the PLCA= RS +keeps the TO after any transmission, waiting for the MAC to send a new fra= me +for up to aPLCABurstTimer BTs. This can only happen a number of times per = PLCA +cycle up to the value of this parameter. After that, the burst is over and= the +normal counting of TOs resumes. This option is corresponding to +``IEEE 802.3cg-2019`` 30.16.1.1.6 aPLCAMaxBurstCount. + +When set, the optional ``ETHTOOL_A_PLCA_BURST_TMR`` attribute indicates how +many bit-times the PLCA RS waits for the MAC to initiate a new transmission +when aPLCAMaxBurstCount is greater than 0. If the MAC fails to send a new +frame within this time, the burst ends and the counting of TOs resumes. +Otherwise, the new frame is sent as part of the current burst. This option +is corresponding to ``IEEE 802.3cg-2019`` 30.16.1.1.7 aPLCABurstTimer. + +PLCA_SET_CFG +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Sets PLCA RS parameters. + +Request contents: + + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + ``ETHTOOL_A_PLCA_HEADER`` nested request header + ``ETHTOOL_A_PLCA_ENABLED`` u8 PLCA Admin State + ``ETHTOOL_A_PLCA_NODE_ID`` u8 PLCA unique local node ID + ``ETHTOOL_A_PLCA_NODE_CNT`` u8 Number of PLCA nodes on = the + netkork, including the + coordinator + ``ETHTOOL_A_PLCA_TO_TMR`` u8 Transmit Opportunity Tim= er + value in bit-times (BT) + ``ETHTOOL_A_PLCA_BURST_CNT`` u8 Number of additional pac= kets + the node is allowed to s= end + within a single TO + ``ETHTOOL_A_PLCA_BURST_TMR`` u8 Time to wait for the MAC= to + transmit a new frame bef= ore + terminating the burst + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + +For a description of each attribute, see ``PLCA_GET_CFG``. + +PLCA_GET_STATUS +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Gets PLCA RS status information. + +Request contents: + + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + ``ETHTOOL_A_PLCA_HEADER`` nested request header + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Kernel response contents: + + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + ``ETHTOOL_A_PLCA_HEADER`` nested reply header + ``ETHTOOL_A_PLCA_STATUS`` u8 PLCA RS operational stat= us + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + +When set, the ``ETHTOOL_A_PLCA_STATUS`` attribute indicates whether the no= de is +detecting the presence of the BEACON on the network. This flag is +corresponding to ``IEEE 802.3cg-2019`` 30.16.1.1.2 aPLCAStatus. + Request translation =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -1788,4 +1918,7 @@ are netlink only. n/a ``ETHTOOL_MSG_PHC_VCLOCKS_GET`` n/a ``ETHTOOL_MSG_MODULE_GET`` n/a ``ETHTOOL_MSG_MODULE_SET`` + n/a ``ETHTOOL_MSG_PLCA_GET_CFG`` + n/a ``ETHTOOL_MSG_PLCA_SET_CFG`` + n/a ``ETHTOOL_MSG_PLCA_GET_STATUS`` =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D diff --git a/MAINTAINERS b/MAINTAINERS index 955c1be1efb2..7952243e4b43 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16396,6 +16396,12 @@ S: Maintained F: Documentation/devicetree/bindings/iio/chemical/plantower,pms7003.yaml F: drivers/iio/chemical/pms7003.c =20 +PLCA RECONCILIATION SUBLAYER (IEEE802.3 Clause 148) +M: Piergiorgio Beruto +L: netdev@vger.kernel.org +S: Maintained +F: net/ethtool/plca.c + PLDMFW LIBRARY M: Jacob Keller S: Maintained diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 9e0a76fc7de9..4bfe95ec1f0a 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -802,12 +802,16 @@ int ethtool_virtdev_set_link_ksettings(struct net_dev= ice *dev, =20 struct phy_device; struct phy_tdr_config; +struct phy_plca_cfg; +struct phy_plca_status; =20 /** * struct ethtool_phy_ops - Optional PHY device options * @get_sset_count: Get number of strings that @get_strings will write. * @get_strings: Return a set of strings that describe the requested objec= ts * @get_stats: Return extended statistics about the PHY device. + * @get_plca_cfg: Return PLCA configuration. + * @set_plca_cfg: Set PLCA configuration. * @start_cable_test: Start a cable test * @start_cable_test_tdr: Start a Time Domain Reflectometry cable test * @@ -819,6 +823,13 @@ struct ethtool_phy_ops { int (*get_strings)(struct phy_device *dev, u8 *data); int (*get_stats)(struct phy_device *dev, struct ethtool_stats *stats, u64 *data); + int (*get_plca_cfg)(struct phy_device *dev, + struct phy_plca_cfg *plca_cfg); + int (*set_plca_cfg)(struct phy_device *dev, + struct netlink_ext_ack *extack, + const struct phy_plca_cfg *plca_cfg); + int (*get_plca_status)(struct phy_device *dev, + struct phy_plca_status *plca_st); int (*start_cable_test)(struct phy_device *phydev, struct netlink_ext_ack *extack); int (*start_cable_test_tdr)(struct phy_device *phydev, diff --git a/include/linux/phy.h b/include/linux/phy.h index 71eeb4e3b1fd..f3ecc9a86e67 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -765,6 +765,63 @@ struct phy_tdr_config { }; #define PHY_PAIR_ALL -1 =20 +/** + * struct phy_plca_cfg - Configuration of the PLCA (Physical Layer Collisi= on + * Avoidance) Reconciliation Sublayer. + * + * @version: read-only PLCA register map version. 0 =3D not available. Ign= ored + * when setting the configuration. Format is the same as reported by the= PLCA + * IDVER register (31.CA00). -1 =3D not available. + * @enabled: PLCA configured mode (enabled/disabled). -1 =3D not available= / don't + * set. 0 =3D disabled, anything else =3D enabled. + * @node_id: the PLCA local node identifier. -1 =3D not available / don't = set. + * Allowed values [0 .. 254]. 255 =3D node disabled. + * @node_cnt: the PLCA node count (maximum number of nodes having a TO). O= nly + * meaningful for the coordinator (node_id =3D 0). -1 =3D not available = / don't + * set. Allowed values [0 .. 255]. + * @to_tmr: The value of the PLCA to_timer in bit-times, which determines = the + * PLCA transmit opportunity window opening. See IEEE802.3 Clause 148 for + * more details. The to_timer shall be set equal over all nodes. + * -1 =3D not available / don't set. Allowed values [0 .. 255]. + * @burst_cnt: controls how many additional frames a node is allowed to se= nd in + * single transmit opportunity (TO). The default value of 0 means that t= he + * node is allowed exactly one frame per TO. A value of 1 allows two fra= mes + * per TO, and so on. -1 =3D not available / don't set. + * Allowed values [0 .. 255]. + * @burst_tmr: controls how many bit times to wait for the MAC to send a n= ew + * frame before interrupting the burst. This value should be set to a va= lue + * greater than the MAC inter-packet gap (which is typically 96 bits). + * -1 =3D not available / don't set. Allowed values [0 .. 255]. + * + * A structure containing configuration parameters for setting/getting the= PLCA + * RS configuration. The driver does not need to implement all the paramet= ers, + * but should report what is actually used. + */ +struct phy_plca_cfg { + s32 version; + s16 enabled; + s16 node_id; + s16 node_cnt; + s16 to_tmr; + s16 burst_cnt; + s16 burst_tmr; +}; + +/** + * struct phy_plca_status - Status of the PLCA (Physical Layer Collision + * Avoidance) Reconciliation Sublayer. + * + * @pst: The PLCA status as reported by the PST bit in the PLCA STATUS + * register(31.CA03), indicating BEACON activity. + * + * A structure containing status information of the PLCA RS configuration. + * The driver does not need to implement all the parameters, but should re= port + * what is actually used. + */ +struct phy_plca_status { + bool pst; +}; + /** * struct phy_driver - Driver structure for a particular PHY type * @@ -1775,6 +1832,13 @@ int phy_ethtool_get_strings(struct phy_device *phyde= v, u8 *data); int phy_ethtool_get_sset_count(struct phy_device *phydev); int phy_ethtool_get_stats(struct phy_device *phydev, struct ethtool_stats *stats, u64 *data); +int phy_ethtool_get_plca_cfg(struct phy_device *phydev, + struct phy_plca_cfg *plca_cfg); +int phy_ethtool_set_plca_cfg(struct phy_device *phydev, + struct netlink_ext_ack *extack, + const struct phy_plca_cfg *plca_cfg); +int phy_ethtool_get_plca_status(struct phy_device *phydev, + struct phy_plca_status *plca_st); =20 static inline int phy_package_read(struct phy_device *phydev, u32 regnum) { diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/etht= ool_netlink.h index aaf7c6963d61..81e3d7b42d0f 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -51,6 +51,9 @@ enum { ETHTOOL_MSG_MODULE_SET, ETHTOOL_MSG_PSE_GET, ETHTOOL_MSG_PSE_SET, + ETHTOOL_MSG_PLCA_GET_CFG, + ETHTOOL_MSG_PLCA_SET_CFG, + ETHTOOL_MSG_PLCA_GET_STATUS, =20 /* add new constants above here */ __ETHTOOL_MSG_USER_CNT, @@ -97,6 +100,9 @@ enum { ETHTOOL_MSG_MODULE_GET_REPLY, ETHTOOL_MSG_MODULE_NTF, ETHTOOL_MSG_PSE_GET_REPLY, + ETHTOOL_MSG_PLCA_GET_CFG_REPLY, + ETHTOOL_MSG_PLCA_GET_STATUS_REPLY, + ETHTOOL_MSG_PLCA_NTF, =20 /* add new constants above here */ __ETHTOOL_MSG_KERNEL_CNT, @@ -880,6 +886,25 @@ enum { ETHTOOL_A_PSE_MAX =3D (__ETHTOOL_A_PSE_CNT - 1) }; =20 +/* PLCA */ + +enum { + ETHTOOL_A_PLCA_UNSPEC, + ETHTOOL_A_PLCA_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PLCA_VERSION, /* u16 */ + ETHTOOL_A_PLCA_ENABLED, /* u8 */ + ETHTOOL_A_PLCA_STATUS, /* u8 */ + ETHTOOL_A_PLCA_NODE_CNT, /* u8 */ + ETHTOOL_A_PLCA_NODE_ID, /* u8 */ + ETHTOOL_A_PLCA_TO_TMR, /* u8 */ + ETHTOOL_A_PLCA_BURST_CNT, /* u8 */ + ETHTOOL_A_PLCA_BURST_TMR, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_PLCA_CNT, + ETHTOOL_A_PLCA_MAX =3D (__ETHTOOL_A_PLCA_CNT - 1) +}; + /* generic netlink info */ #define ETHTOOL_GENL_NAME "ethtool" #define ETHTOOL_GENL_VERSION 1 diff --git a/net/ethtool/Makefile b/net/ethtool/Makefile index 72ab0944262a..b18930e2ce9a 100644 --- a/net/ethtool/Makefile +++ b/net/ethtool/Makefile @@ -8,4 +8,4 @@ ethtool_nl-y :=3D netlink.o bitset.o strset.o linkinfo.o li= nkmodes.o \ linkstate.o debug.o wol.o features.o privflags.o rings.o \ channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \ tunnels.o fec.o eeprom.o stats.o phc_vclocks.o module.o \ - pse-pd.o + pse-pd.o plca.o diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c index 1a4c11356c96..eb044f48cb24 100644 --- a/net/ethtool/netlink.c +++ b/net/ethtool/netlink.c @@ -287,6 +287,8 @@ ethnl_default_requests[__ETHTOOL_MSG_USER_CNT] =3D { [ETHTOOL_MSG_PHC_VCLOCKS_GET] =3D ðnl_phc_vclocks_request_ops, [ETHTOOL_MSG_MODULE_GET] =3D ðnl_module_request_ops, [ETHTOOL_MSG_PSE_GET] =3D ðnl_pse_request_ops, + [ETHTOOL_MSG_PLCA_GET_CFG] =3D ðnl_plca_cfg_request_ops, + [ETHTOOL_MSG_PLCA_GET_STATUS] =3D ðnl_plca_status_request_ops, }; =20 static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *= cb) @@ -602,6 +604,7 @@ ethnl_default_notify_ops[ETHTOOL_MSG_KERNEL_MAX + 1] = =3D { [ETHTOOL_MSG_EEE_NTF] =3D ðnl_eee_request_ops, [ETHTOOL_MSG_FEC_NTF] =3D ðnl_fec_request_ops, [ETHTOOL_MSG_MODULE_NTF] =3D ðnl_module_request_ops, + [ETHTOOL_MSG_PLCA_NTF] =3D ðnl_plca_cfg_request_ops, }; =20 /* default notification handler */ @@ -695,6 +698,7 @@ static const ethnl_notify_handler_t ethnl_notify_handle= rs[] =3D { [ETHTOOL_MSG_EEE_NTF] =3D ethnl_default_notify, [ETHTOOL_MSG_FEC_NTF] =3D ethnl_default_notify, [ETHTOOL_MSG_MODULE_NTF] =3D ethnl_default_notify, + [ETHTOOL_MSG_PLCA_NTF] =3D ethnl_default_notify, }; =20 void ethtool_notify(struct net_device *dev, unsigned int cmd, const void *= data) @@ -1040,6 +1044,32 @@ static const struct genl_ops ethtool_genl_ops[] =3D { .policy =3D ethnl_pse_set_policy, .maxattr =3D ARRAY_SIZE(ethnl_pse_set_policy) - 1, }, + { + .cmd =3D ETHTOOL_MSG_PLCA_GET_CFG, + .doit =3D ethnl_default_doit, + .start =3D ethnl_default_start, + .dumpit =3D ethnl_default_dumpit, + .done =3D ethnl_default_done, + .policy =3D ethnl_plca_get_cfg_policy, + .maxattr =3D ARRAY_SIZE(ethnl_plca_get_cfg_policy) - 1, + }, + { + .cmd =3D ETHTOOL_MSG_PLCA_SET_CFG, + .flags =3D GENL_UNS_ADMIN_PERM, + .doit =3D ethnl_set_plca_cfg, + .policy =3D ethnl_plca_set_cfg_policy, + .maxattr =3D ARRAY_SIZE(ethnl_plca_set_cfg_policy) - 1, + }, + { + .cmd =3D ETHTOOL_MSG_PLCA_GET_STATUS, + .doit =3D ethnl_default_doit, + .start =3D ethnl_default_start, + .dumpit =3D ethnl_default_dumpit, + .done =3D ethnl_default_done, + .policy =3D ethnl_plca_get_status_policy, + .maxattr =3D ARRAY_SIZE(ethnl_plca_get_status_policy) - 1, + }, + }; =20 static const struct genl_multicast_group ethtool_nl_mcgrps[] =3D { diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h index 1bfd374f9718..c0ed1a6d0833 100644 --- a/net/ethtool/netlink.h +++ b/net/ethtool/netlink.h @@ -346,6 +346,8 @@ extern const struct ethnl_request_ops ethnl_stats_reque= st_ops; extern const struct ethnl_request_ops ethnl_phc_vclocks_request_ops; extern const struct ethnl_request_ops ethnl_module_request_ops; extern const struct ethnl_request_ops ethnl_pse_request_ops; +extern const struct ethnl_request_ops ethnl_plca_cfg_request_ops; +extern const struct ethnl_request_ops ethnl_plca_status_request_ops; =20 extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS = + 1]; extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_= FLAGS + 1]; @@ -386,6 +388,9 @@ extern const struct nla_policy ethnl_module_get_policy[= ETHTOOL_A_MODULE_HEADER + extern const struct nla_policy ethnl_module_set_policy[ETHTOOL_A_MODULE_PO= WER_MODE_POLICY + 1]; extern const struct nla_policy ethnl_pse_get_policy[ETHTOOL_A_PSE_HEADER += 1]; extern const struct nla_policy ethnl_pse_set_policy[ETHTOOL_A_PSE_MAX + 1]; +extern const struct nla_policy ethnl_plca_get_cfg_policy[ETHTOOL_A_PLCA_HE= ADER + 1]; +extern const struct nla_policy ethnl_plca_set_cfg_policy[ETHTOOL_A_PLCA_MA= X + 1]; +extern const struct nla_policy ethnl_plca_get_status_policy[ETHTOOL_A_PLCA= _HEADER + 1]; =20 int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info); int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info); @@ -406,6 +411,7 @@ int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struc= t netlink_callback *cb); int ethnl_set_fec(struct sk_buff *skb, struct genl_info *info); int ethnl_set_module(struct sk_buff *skb, struct genl_info *info); int ethnl_set_pse(struct sk_buff *skb, struct genl_info *info); +int ethnl_set_plca_cfg(struct sk_buff *skb, struct genl_info *info); =20 extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN]; extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_G= STRING_LEN]; diff --git a/net/ethtool/plca.c b/net/ethtool/plca.c new file mode 100644 index 000000000000..0282acab1c4d --- /dev/null +++ b/net/ethtool/plca.c @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include + +#include "netlink.h" +#include "common.h" + +struct plca_req_info { + struct ethnl_req_info base; +}; + +struct plca_reply_data { + struct ethnl_reply_data base; + struct phy_plca_cfg plca_cfg; + struct phy_plca_status plca_st; +}; + +#define PLCA_REPDATA(__reply_base) \ + container_of(__reply_base, struct plca_reply_data, base) + +// PLCA get configuration message ----------------------------------------= --- // + +const struct nla_policy ethnl_plca_get_cfg_policy[] =3D { + [ETHTOOL_A_PLCA_HEADER] =3D + NLA_POLICY_NESTED(ethnl_header_policy), +}; + +static int plca_get_cfg_prepare_data(const struct ethnl_req_info *req_base, + struct ethnl_reply_data *reply_base, + struct genl_info *info) +{ + struct plca_reply_data *data =3D PLCA_REPDATA(reply_base); + struct net_device *dev =3D reply_base->dev; + const struct ethtool_phy_ops *ops; + int ret; + + // check that the PHY device is available and connected + if (!dev->phydev) { + ret =3D -EOPNOTSUPP; + goto out; + } + + // note: rtnl_lock is held already by ethnl_default_doit + ops =3D ethtool_phy_ops; + if (!ops || !ops->get_plca_cfg) { + ret =3D -EOPNOTSUPP; + goto out; + } + + ret =3D ethnl_ops_begin(dev); + if (ret < 0) + goto out; + + ret =3D ops->get_plca_cfg(dev->phydev, &data->plca_cfg); + if (ret < 0) + goto out; + + ethnl_ops_complete(dev); + +out: + return ret; +} + +static int plca_get_cfg_reply_size(const struct ethnl_req_info *req_base, + const struct ethnl_reply_data *reply_base) +{ + return nla_total_size(sizeof(u16)) + /* _VERSION */ + nla_total_size(sizeof(u8)) + /* _ENABLED */ + nla_total_size(sizeof(u8)) + /* _STATUS */ + nla_total_size(sizeof(u8)) + /* _NODE_CNT */ + nla_total_size(sizeof(u8)) + /* _NODE_ID */ + nla_total_size(sizeof(u8)) + /* _TO_TIMER */ + nla_total_size(sizeof(u8)) + /* _BURST_COUNT */ + nla_total_size(sizeof(u8)); /* _BURST_TIMER */ +} + +static int plca_get_cfg_fill_reply(struct sk_buff *skb, + const struct ethnl_req_info *req_base, + const struct ethnl_reply_data *reply_base) +{ + const struct plca_reply_data *data =3D PLCA_REPDATA(reply_base); + const struct phy_plca_cfg *plca =3D &data->plca_cfg; + + if ((plca->version >=3D 0 && + nla_put_u16(skb, ETHTOOL_A_PLCA_VERSION, (u16)plca->version)) || + (plca->enabled >=3D 0 && + nla_put_u8(skb, ETHTOOL_A_PLCA_ENABLED, !!plca->enabled)) || + (plca->node_id >=3D 0 && + nla_put_u8(skb, ETHTOOL_A_PLCA_NODE_ID, (u8)plca->node_id)) || + (plca->node_cnt >=3D 0 && + nla_put_u8(skb, ETHTOOL_A_PLCA_NODE_CNT, (u8)plca->node_cnt)) || + (plca->to_tmr >=3D 0 && + nla_put_u8(skb, ETHTOOL_A_PLCA_TO_TMR, (u8)plca->to_tmr)) || + (plca->burst_cnt >=3D 0 && + nla_put_u8(skb, ETHTOOL_A_PLCA_BURST_CNT, (u8)plca->burst_cnt)) || + (plca->burst_tmr >=3D 0 && + nla_put_u8(skb, ETHTOOL_A_PLCA_BURST_TMR, (u8)plca->burst_tmr))) + return -EMSGSIZE; + + return 0; +}; + +const struct ethnl_request_ops ethnl_plca_cfg_request_ops =3D { + .request_cmd =3D ETHTOOL_MSG_PLCA_GET_CFG, + .reply_cmd =3D ETHTOOL_MSG_PLCA_GET_CFG_REPLY, + .hdr_attr =3D ETHTOOL_A_PLCA_HEADER, + .req_info_size =3D sizeof(struct plca_req_info), + .reply_data_size =3D sizeof(struct plca_reply_data), + + .prepare_data =3D plca_get_cfg_prepare_data, + .reply_size =3D plca_get_cfg_reply_size, + .fill_reply =3D plca_get_cfg_fill_reply, +}; + +// PLCA set configuration message ----------------------------------------= --- // + +const struct nla_policy ethnl_plca_set_cfg_policy[] =3D { + [ETHTOOL_A_PLCA_HEADER] =3D + NLA_POLICY_NESTED(ethnl_header_policy), + [ETHTOOL_A_PLCA_ENABLED] =3D { .type =3D NLA_U8 }, + [ETHTOOL_A_PLCA_NODE_ID] =3D { .type =3D NLA_U8 }, + [ETHTOOL_A_PLCA_NODE_CNT] =3D { .type =3D NLA_U8 }, + [ETHTOOL_A_PLCA_TO_TMR] =3D { .type =3D NLA_U8 }, + [ETHTOOL_A_PLCA_BURST_CNT] =3D { .type =3D NLA_U8 }, + [ETHTOOL_A_PLCA_BURST_TMR] =3D { .type =3D NLA_U8 }, +}; + +int ethnl_set_plca_cfg(struct sk_buff *skb, struct genl_info *info) +{ + struct ethnl_req_info req_info =3D {}; + struct nlattr **tb =3D info->attrs; + const struct ethtool_phy_ops *ops; + struct phy_plca_cfg plca_cfg; + struct net_device *dev; + + bool mod =3D false; + int ret; + + ret =3D ethnl_parse_header_dev_get(&req_info, + tb[ETHTOOL_A_PLCA_HEADER], + genl_info_net(info), info->extack, + true); + if (ret < 0) + return ret; + + dev =3D req_info.dev; + + // check that the PHY device is available and connected + rtnl_lock(); + + if (!dev->phydev) { + ret =3D -EOPNOTSUPP; + goto out_rtnl; + } + + ops =3D ethtool_phy_ops; + if (!ops || !ops->set_plca_cfg) { + ret =3D -EOPNOTSUPP; + goto out_rtnl; + } + + ret =3D ethnl_ops_begin(dev); + if (ret < 0) + goto out_rtnl; + + memset(&plca_cfg, 0xFF, sizeof(plca_cfg)); + + if (tb[ETHTOOL_A_PLCA_ENABLED]) { + plca_cfg.enabled =3D !!nla_get_u8(tb[ETHTOOL_A_PLCA_ENABLED]); + mod =3D true; + } + + if (tb[ETHTOOL_A_PLCA_NODE_ID]) { + plca_cfg.node_id =3D nla_get_u8(tb[ETHTOOL_A_PLCA_NODE_ID]); + mod =3D true; + } + + if (tb[ETHTOOL_A_PLCA_NODE_CNT]) { + plca_cfg.node_cnt =3D nla_get_u8(tb[ETHTOOL_A_PLCA_NODE_CNT]); + mod =3D true; + } + + if (tb[ETHTOOL_A_PLCA_TO_TMR]) { + plca_cfg.to_tmr =3D nla_get_u8(tb[ETHTOOL_A_PLCA_TO_TMR]); + mod =3D true; + } + + if (tb[ETHTOOL_A_PLCA_BURST_CNT]) { + plca_cfg.burst_cnt =3D nla_get_u8(tb[ETHTOOL_A_PLCA_BURST_CNT]); + mod =3D true; + } + + if (tb[ETHTOOL_A_PLCA_BURST_TMR]) { + plca_cfg.burst_tmr =3D nla_get_u8(tb[ETHTOOL_A_PLCA_BURST_TMR]); + mod =3D true; + } + + ret =3D 0; + if (!mod) + goto out_ops; + + ret =3D ops->set_plca_cfg(dev->phydev, info->extack, &plca_cfg); + + if (ret < 0) + goto out_ops; + + ethtool_notify(dev, ETHTOOL_MSG_PLCA_NTF, NULL); + +out_ops: + ethnl_ops_complete(dev); +out_rtnl: + rtnl_unlock(); + ethnl_parse_header_dev_put(&req_info); + + return ret; +} + +// PLCA get status message -----------------------------------------------= --- // + +const struct nla_policy ethnl_plca_get_status_policy[] =3D { + [ETHTOOL_A_PLCA_HEADER] =3D + NLA_POLICY_NESTED(ethnl_header_policy), +}; + +static int plca_get_status_prepare_data(const struct ethnl_req_info *req_b= ase, + struct ethnl_reply_data *reply_base, + struct genl_info *info) +{ + struct plca_reply_data *data =3D PLCA_REPDATA(reply_base); + struct net_device *dev =3D reply_base->dev; + const struct ethtool_phy_ops *ops; + int ret; + + // check that the PHY device is available and connected + if (!dev->phydev) { + ret =3D -EOPNOTSUPP; + goto out; + } + + // note: rtnl_lock is held already by ethnl_default_doit + ops =3D ethtool_phy_ops; + if (!ops || !ops->get_plca_status) { + ret =3D -EOPNOTSUPP; + goto out; + } + + ret =3D ethnl_ops_begin(dev); + if (ret < 0) + goto out; + + ret =3D ops->get_plca_status(dev->phydev, &data->plca_st); + if (ret < 0) + goto out; + + ethnl_ops_complete(dev); +out: + return ret; +} + +static int plca_get_status_reply_size(const struct ethnl_req_info *req_bas= e, + const struct ethnl_reply_data *reply_base) +{ + return nla_total_size(sizeof(u8)); /* _STATUS */ +} + +static int plca_get_status_fill_reply(struct sk_buff *skb, + const struct ethnl_req_info *req_base, + const struct ethnl_reply_data *reply_base) +{ + const struct plca_reply_data *data =3D PLCA_REPDATA(reply_base); + const u8 status =3D data->plca_st.pst; + + if (nla_put_u8(skb, ETHTOOL_A_PLCA_STATUS, !!status)) + return -EMSGSIZE; + + return 0; +}; + +const struct ethnl_request_ops ethnl_plca_status_request_ops =3D { + .request_cmd =3D ETHTOOL_MSG_PLCA_GET_STATUS, + .reply_cmd =3D ETHTOOL_MSG_PLCA_GET_STATUS_REPLY, + .hdr_attr =3D ETHTOOL_A_PLCA_HEADER, + .req_info_size =3D sizeof(struct plca_req_info), + .reply_data_size =3D sizeof(struct plca_reply_data), + + .prepare_data =3D plca_get_status_prepare_data, + .reply_size =3D plca_get_status_reply_size, + .fill_reply =3D plca_get_status_fill_reply, +}; --=20 2.35.1 From nobody Thu Sep 18 12:50:19 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 529DBC4708E for ; Tue, 6 Dec 2022 12:53:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234377AbiLFMxR (ORCPT ); Tue, 6 Dec 2022 07:53:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57194 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234387AbiLFMxC (ORCPT ); Tue, 6 Dec 2022 07:53:02 -0500 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D33872BD8; Tue, 6 Dec 2022 04:52:48 -0800 (PST) Received: by mail-ed1-x52d.google.com with SMTP id e13so20087506edj.7; Tue, 06 Dec 2022 04:52:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=FXBmcabeWV8OKzX28uoLmsQs7tuaar1G2adsb2jdhL4=; b=fgAhRp0Zxgbh1QGUw5CSaxFoSJuAGkigAjZ+JI4KvUbGXZwe6i+MHIkxEBfGYG+Nvc 068rPdcUb/JkwZnSFqv7Tc82aYVr51PJ4B/ba0LdRU5K1Q4LTS/jKpy03WoEksA4rEt7 ZBOTKVP8aZlqfzPvKwsL3uTzBa9mF1wdyoBAV6emerCyt/EzJajgroDjLb6WN21Zio1h LAwUDo13VRPP+eNAWL3wFpMyTiMEhk4+Yt8UCIDkrYhPnCdpv74r6sQJCF2HNXx6lF3q wollQGeuCGZ/iLlCNCe4aWHl7t36E22K70C5Saa5dBw0uKikXZrNnE4VpFrylXxnAD69 KiTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=FXBmcabeWV8OKzX28uoLmsQs7tuaar1G2adsb2jdhL4=; b=xgyx2b9oQhK8UcKFzMNn1AGEDtU6kaxurytZdIrlT3fzWfKk1mmIpbWlDZiPswgBcM YyXFI5eq3ZvHr8rZ4HsQ5epc6/OeRGS/oGEou68pAl+oTKqZnD57UdEZwb8CDDxf/WvF J6OM31igg7CADV76tzKUwnq+bo1anYhWe0yHrdQovG4xiTFq14wsQAM+Fp2fKDrKhNca emgIZI5krYxopeurTxGmkJhuojR+vE3UPYoe+aodZ72sgbKlybm1+pBlOjoNkskADGg8 25CfZ1JtNn07YrylZ7qZG0MsM1A7dVYAivILDv9dWZPbSag+dpIL9mjY9jdU21ZF+2Dc hsaQ== X-Gm-Message-State: ANoB5plV8JCC9YzupDFsEj9QQk54tdmL+LUHaGkuisuQRy4S/YopHh6w MnYxQ29FxvSRQp5R1FnT9H4= X-Google-Smtp-Source: AA0mqf5vaBwKLbovgK15vPIP5tdEG9ap1tSabo8a0VOIJbigylAS037G03wfO1iEHYhORj1Nb7Mvrw== X-Received: by 2002:a05:6402:e04:b0:469:e6ef:9164 with SMTP id h4-20020a0564020e0400b00469e6ef9164mr29387573edh.185.1670331167169; Tue, 06 Dec 2022 04:52:47 -0800 (PST) Received: from gvm01 (net-2-45-26-236.cust.vodafonedsl.it. [2.45.26.236]) by smtp.gmail.com with ESMTPSA id a2-20020a170906684200b007bf71053d97sm7412434ejs.40.2022.12.06.04.52.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 04:52:46 -0800 (PST) Date: Tue, 6 Dec 2022 13:52:57 +0100 From: Piergiorgio Beruto To: Andrew Lunn , Heiner Kallweit , Russell King , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Oleksij Rempel Subject: [PATCH v4 net-next 2/5] drivers/net/phy: add the link modes for the 10BASE-T1S Ethernet PHY Message-ID: <9dd727e8bfb3c1e9f0e7c13f101d7c6d040b9651.1670329232.git.piergiorgio.beruto@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch adds the link modes for the IEEE 802.3cg Clause 147 10BASE-T1S Ethernet PHY. According to the specifications, the 10BASE-T1S supports Point-To-Point Full-Duplex, Point-To-Point Half-Duplex and/or Point-To-Multipoint (AKA Multi-Drop) Half-Duplex operations. Signed-off-by: Piergiorgio Beruto --- drivers/net/phy/phy-core.c | 5 ++++- drivers/net/phy/phylink.c | 6 +++++- include/linux/phy.h | 11 +++++++++++ include/uapi/linux/ethtool.h | 3 +++ net/ethtool/common.c | 8 ++++++++ 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c index 5d08c627a516..a64186dc53f8 100644 --- a/drivers/net/phy/phy-core.c +++ b/drivers/net/phy/phy-core.c @@ -13,7 +13,7 @@ */ const char *phy_speed_to_str(int speed) { - BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS !=3D 99, + BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS !=3D 102, "Enum ethtool_link_mode_bit_indices and phylib are out of sync. " "If a speed or mode has been added please update phy_speed_to_str " "and the PHY settings array.\n"); @@ -260,6 +260,9 @@ static const struct phy_setting settings[] =3D { PHY_SETTING( 10, FULL, 10baseT_Full ), PHY_SETTING( 10, HALF, 10baseT_Half ), PHY_SETTING( 10, FULL, 10baseT1L_Full ), + PHY_SETTING( 10, FULL, 10baseT1S_Full ), + PHY_SETTING( 10, HALF, 10baseT1S_Half ), + PHY_SETTING( 10, HALF, 10baseT1S_P2MP_Half ), }; #undef PHY_SETTING =20 diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 09cc65c0da93..319790221d7f 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -241,12 +241,16 @@ void phylink_caps_to_linkmodes(unsigned long *linkmod= es, unsigned long caps) if (caps & MAC_ASYM_PAUSE) __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes); =20 - if (caps & MAC_10HD) + if (caps & MAC_10HD) { __set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, linkmodes); + __set_bit(ETHTOOL_LINK_MODE_10baseT1S_Half_BIT, linkmodes); + __set_bit(ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT, linkmodes); + } =20 if (caps & MAC_10FD) { __set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, linkmodes); __set_bit(ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, linkmodes); + __set_bit(ETHTOOL_LINK_MODE_10baseT1S_Full_BIT, linkmodes); } =20 if (caps & MAC_100HD) { diff --git a/include/linux/phy.h b/include/linux/phy.h index f3ecc9a86e67..49d0488bf480 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -1036,6 +1036,17 @@ struct phy_driver { int (*get_sqi)(struct phy_device *dev); /** @get_sqi_max: Get the maximum signal quality indication */ int (*get_sqi_max)(struct phy_device *dev); + + /* PLCA RS interface */ + /** @get_plca_cfg: Return the current PLCA configuration */ + int (*get_plca_cfg)(struct phy_device *dev, + struct phy_plca_cfg *plca_cfg); + /** @set_plca_cfg: Set the PLCA configuration */ + int (*set_plca_cfg)(struct phy_device *dev, + const struct phy_plca_cfg *plca_cfg); + /** @get_plca_status: Return the current PLCA status info */ + int (*get_plca_status)(struct phy_device *dev, + struct phy_plca_status *plca_st); }; #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ struct phy_driver, mdiodrv) diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index 58e587ba0450..5f414deacf23 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -1741,6 +1741,9 @@ enum ethtool_link_mode_bit_indices { ETHTOOL_LINK_MODE_800000baseDR8_2_Full_BIT =3D 96, ETHTOOL_LINK_MODE_800000baseSR8_Full_BIT =3D 97, ETHTOOL_LINK_MODE_800000baseVR8_Full_BIT =3D 98, + ETHTOOL_LINK_MODE_10baseT1S_Full_BIT =3D 99, + ETHTOOL_LINK_MODE_10baseT1S_Half_BIT =3D 100, + ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT =3D 101, =20 /* must be last entry */ __ETHTOOL_LINK_MODE_MASK_NBITS diff --git a/net/ethtool/common.c b/net/ethtool/common.c index 21cfe8557205..c586db0c5e68 100644 --- a/net/ethtool/common.c +++ b/net/ethtool/common.c @@ -208,6 +208,9 @@ const char link_mode_names[][ETH_GSTRING_LEN] =3D { __DEFINE_LINK_MODE_NAME(800000, DR8_2, Full), __DEFINE_LINK_MODE_NAME(800000, SR8, Full), __DEFINE_LINK_MODE_NAME(800000, VR8, Full), + __DEFINE_LINK_MODE_NAME(10, T1S, Full), + __DEFINE_LINK_MODE_NAME(10, T1S, Half), + __DEFINE_LINK_MODE_NAME(10, T1S_P2MP, Half), }; static_assert(ARRAY_SIZE(link_mode_names) =3D=3D __ETHTOOL_LINK_MODE_MASK_= NBITS); =20 @@ -244,6 +247,8 @@ static_assert(ARRAY_SIZE(link_mode_names) =3D=3D __ETHT= OOL_LINK_MODE_MASK_NBITS); #define __LINK_MODE_LANES_X 1 #define __LINK_MODE_LANES_FX 1 #define __LINK_MODE_LANES_T1L 1 +#define __LINK_MODE_LANES_T1S 1 +#define __LINK_MODE_LANES_T1S_P2MP 1 #define __LINK_MODE_LANES_VR8 8 #define __LINK_MODE_LANES_DR8_2 8 =20 @@ -366,6 +371,9 @@ const struct link_mode_info link_mode_params[] =3D { __DEFINE_LINK_MODE_PARAMS(800000, DR8_2, Full), __DEFINE_LINK_MODE_PARAMS(800000, SR8, Full), __DEFINE_LINK_MODE_PARAMS(800000, VR8, Full), + __DEFINE_LINK_MODE_PARAMS(10, T1S, Full), + __DEFINE_LINK_MODE_PARAMS(10, T1S, Half), + __DEFINE_LINK_MODE_PARAMS(10, T1S_P2MP, Half), }; static_assert(ARRAY_SIZE(link_mode_params) =3D=3D __ETHTOOL_LINK_MODE_MASK= _NBITS); =20 --=20 2.35.1 From nobody Thu Sep 18 12:50:19 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9D3CC4708E for ; Tue, 6 Dec 2022 12:53:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234567AbiLFMxd (ORCPT ); Tue, 6 Dec 2022 07:53:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234553AbiLFMxW (ORCPT ); Tue, 6 Dec 2022 07:53:22 -0500 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D0E19FCF; Tue, 6 Dec 2022 04:53:05 -0800 (PST) Received: by mail-ed1-x52c.google.com with SMTP id m19so20086754edj.8; Tue, 06 Dec 2022 04:53:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=Hp7aegHQL/VcwqFRTSdu/GwDmHSFMjOcY3IIQ3kMIu8=; b=ZCuvHmkHDemAl+juwzPIhP0wBrPlylUL/PHX4cO6bZqdeBuciC6Y22Qsvx7SYdV8TW uLUu+gCwGalnoAQg+58epv36kP/KqG+8kcwR9Y/ErIr2JHao3P0P2b48lDJSN4SNTiTi IFBPy6ecERyXQa35YllkQbRaJrIbMqnwwaUv1BYVT8V2bG0/OkJySGqjjEFKZl2dW4tS GyhQZMnyFso0L/E1GDEv++yhlLkZps1SczolutaLfdnri5YIxaLHpHxNx4ea34PqWDvC P+hyjpb2DDONvkPIoCmJq2GxuxvEdV+Ec/uYhwVkq8khoItwdnWMjGUKDfU3fA4AxqO3 L05Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Hp7aegHQL/VcwqFRTSdu/GwDmHSFMjOcY3IIQ3kMIu8=; b=OCLBFWdz7HAcRcvvVqnz/A1WAu6r3NaVvgThBHH9p5Xzph7SLLcwOqI2GKezpO2bT7 GRE9jXo6a5GTgYces4QkOn/eCb3kSt4gfBkb3LRxS1QWagO83Enlw9D3rZAjzKb9nW82 X+kTiVJT8X2WA8pdL/0GylZrZTr+sGCc/bB5VaALmgZl4DrVY0gY1Z3KwJbvO8cfj8y5 aKNp7J2r3DCwo3JUPlt6fAi6iu0u0WE40ehFNlVkmze3iS9nE6t0+DhB0L66/9KFl4lC 4/fX6ZbIMse1SjoG2mDOMdwB+Qq9VeS0nvKdzjDQRL6O/nZVTGknA0+zZOUBIc8VE89G DxGg== X-Gm-Message-State: ANoB5pmLhR3spnCJnP69rMiVJTiumRt5Rh2fA7tbY4ksSLJOmhyjBWQ9 u6cUHd2I3KhQePeO7bXLRJ8= X-Google-Smtp-Source: AA0mqf530HdUgqA6cbWz2YPbT4L2uoBR6Om5H6NAJPAMTAgdJbsi+hQKPajdxLSVdjzvki1ZTyfnCg== X-Received: by 2002:a05:6402:2912:b0:46a:c132:8a25 with SMTP id ee18-20020a056402291200b0046ac1328a25mr45280969edb.205.1670331184298; Tue, 06 Dec 2022 04:53:04 -0800 (PST) Received: from gvm01 (net-2-45-26-236.cust.vodafonedsl.it. [2.45.26.236]) by smtp.gmail.com with ESMTPSA id h5-20020aa7c945000000b0044dbecdcd29sm941444edt.12.2022.12.06.04.53.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 04:53:03 -0800 (PST) Date: Tue, 6 Dec 2022 13:53:14 +0100 From: Piergiorgio Beruto To: Andrew Lunn , Heiner Kallweit , Russell King , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Oleksij Rempel Subject: [PATCH v4 net-next 3/5] drivers/net/phy: add connection between ethtool and phylib for PLCA Message-ID: <2f192989f373ff118f102ebca160aed220517031.1670329232.git.piergiorgio.beruto@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch adds the required connection between netlink ethtool and phylib to resolve PLCA get/set config and get status messages. Signed-off-by: Piergiorgio Beruto --- drivers/net/phy/phy.c | 175 +++++++++++++++++++++++++++++++++++ drivers/net/phy/phy_device.c | 3 + 2 files changed, 178 insertions(+) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index e5b6cb1a77f9..3fc251f5de26 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -543,6 +543,181 @@ int phy_ethtool_get_stats(struct phy_device *phydev, } EXPORT_SYMBOL(phy_ethtool_get_stats); =20 +/** + * phy_ethtool_get_plca_cfg - Get PLCA RS configuration + * + * @phydev: the phy_device struct + * @plca_cfg: where to store the retrieved configuration + */ +int phy_ethtool_get_plca_cfg(struct phy_device *phydev, + struct phy_plca_cfg *plca_cfg) +{ + int ret; + + if (!phydev->drv) { + ret =3D -EIO; + goto out; + } + + if (!phydev->drv->get_plca_cfg) { + ret =3D -EOPNOTSUPP; + goto out; + } + + memset(plca_cfg, 0xFF, sizeof(*plca_cfg)); + + mutex_lock(&phydev->lock); + ret =3D phydev->drv->get_plca_cfg(phydev, plca_cfg); + + if (ret) + goto out_drv; + +out_drv: + mutex_unlock(&phydev->lock); +out: + return ret; +} + +/** + * phy_ethtool_set_plca_cfg - Set PLCA RS configuration + * + * @phydev: the phy_device struct + * @extack: extack for reporting useful error messages + * @plca_cfg: new PLCA configuration to apply + */ +int phy_ethtool_set_plca_cfg(struct phy_device *phydev, + struct netlink_ext_ack *extack, + const struct phy_plca_cfg *plca_cfg) +{ + int ret; + struct phy_plca_cfg *curr_plca_cfg =3D 0; + + if (!phydev->drv) { + ret =3D -EIO; + goto out; + } + + if (!phydev->drv->set_plca_cfg || + !phydev->drv->get_plca_cfg) { + ret =3D -EOPNOTSUPP; + goto out; + } + + curr_plca_cfg =3D kmalloc(sizeof(*curr_plca_cfg), GFP_KERNEL); + memset(curr_plca_cfg, 0xFF, sizeof(*curr_plca_cfg)); + + mutex_lock(&phydev->lock); + + ret =3D phydev->drv->get_plca_cfg(phydev, curr_plca_cfg); + if (ret) + goto out_drv; + + if (curr_plca_cfg->enabled < 0 && plca_cfg->enabled >=3D 0) { + NL_SET_ERR_MSG(extack, + "PHY does not support changing the PLCA 'enable' attribute"); + ret =3D -EINVAL; + goto out_drv; + } + + if (curr_plca_cfg->node_id < 0 && plca_cfg->node_id >=3D 0) { + NL_SET_ERR_MSG(extack, + "PHY does not support changing the PLCA 'local node ID' attribut= e"); + ret =3D -EINVAL; + goto out_drv; + } + + if (curr_plca_cfg->node_cnt < 0 && plca_cfg->node_cnt >=3D 0) { + NL_SET_ERR_MSG(extack, + "PHY does not support changing the PLCA 'node count' attribute"); + ret =3D -EINVAL; + goto out_drv; + } + + if (curr_plca_cfg->to_tmr < 0 && plca_cfg->to_tmr >=3D 0) { + NL_SET_ERR_MSG(extack, + "PHY does not support changing the PLCA 'TO timer' attribute"); + ret =3D -EINVAL; + goto out_drv; + } + + if (curr_plca_cfg->burst_cnt < 0 && plca_cfg->burst_cnt >=3D 0) { + NL_SET_ERR_MSG(extack, + "PHY does not support changing the PLCA 'burst count' attribute"= ); + ret =3D -EINVAL; + goto out_drv; + } + + if (curr_plca_cfg->burst_tmr < 0 && plca_cfg->burst_tmr >=3D 0) { + NL_SET_ERR_MSG(extack, + "PHY does not support changing the PLCA 'burst timer' attribute"= ); + ret =3D -EINVAL; + goto out_drv; + } + + // if enabling PLCA, perform additional sanity checks + if (plca_cfg->enabled > 0) { + if (!linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT, + phydev->advertising)) { + ret =3D -EOPNOTSUPP; + NL_SET_ERR_MSG(extack, + "Point to Multi-Point mode is not enabled"); + } + + // allow setting node_id concurrently with enabled + if (plca_cfg->node_id >=3D 0) + curr_plca_cfg->node_id =3D plca_cfg->node_id; + + if (curr_plca_cfg->node_id >=3D 255) { + NL_SET_ERR_MSG(extack, "PLCA node ID is not set"); + ret =3D -EINVAL; + goto out_drv; + } + } + + ret =3D phydev->drv->set_plca_cfg(phydev, plca_cfg); + if (ret) + goto out_drv; + +out_drv: + kfree(curr_plca_cfg); + mutex_unlock(&phydev->lock); +out: + return ret; +} + +/** + * phy_ethtool_get_plca_status - Get PLCA RS status information + * + * @phydev: the phy_device struct + * @plca_st: where to store the retrieved status information + */ +int phy_ethtool_get_plca_status(struct phy_device *phydev, + struct phy_plca_status *plca_st) +{ + int ret; + + if (!phydev->drv) { + ret =3D -EIO; + goto out; + } + + if (!phydev->drv->get_plca_status) { + ret =3D -EOPNOTSUPP; + goto out; + } + + mutex_lock(&phydev->lock); + ret =3D phydev->drv->get_plca_status(phydev, plca_st); + + if (ret) + goto out_drv; + +out_drv: + mutex_unlock(&phydev->lock); +out: + return ret; +} + /** * phy_start_cable_test - Start a cable test * diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 716870a4499c..f248010c403d 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -3262,6 +3262,9 @@ static const struct ethtool_phy_ops phy_ethtool_phy_o= ps =3D { .get_sset_count =3D phy_ethtool_get_sset_count, .get_strings =3D phy_ethtool_get_strings, .get_stats =3D phy_ethtool_get_stats, + .get_plca_cfg =3D phy_ethtool_get_plca_cfg, + .set_plca_cfg =3D phy_ethtool_set_plca_cfg, + .get_plca_status =3D phy_ethtool_get_plca_status, .start_cable_test =3D phy_start_cable_test, .start_cable_test_tdr =3D phy_start_cable_test_tdr, }; --=20 2.35.1 From nobody Thu Sep 18 12:50:19 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3AD97C352A1 for ; Tue, 6 Dec 2022 12:53:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234583AbiLFMxu (ORCPT ); Tue, 6 Dec 2022 07:53:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233419AbiLFMx3 (ORCPT ); Tue, 6 Dec 2022 07:53:29 -0500 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4FB439FC5; Tue, 6 Dec 2022 04:53:24 -0800 (PST) Received: by mail-ej1-x631.google.com with SMTP id b2so5918748eja.7; Tue, 06 Dec 2022 04:53:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=P/FdT2vT8R1YX3cb+9g3eSSTweRxOkiVzd83P/jGkbQ=; b=CI0SCwWBeMn35xXFc8wT4XaebyrtRl5SX8F5g7GUpfim7rAvGYU39chB5sHYipiazw enLFLdzIDTPd3E+62dFUOt2KjFgbt6Nf6S4s2LKya1NzyYwNTGJ0JSzyVhS6mArWR1IF qcvGnyzfB7/4hy+wtF7l2V7vPFCGuICFoQEqioRR4l+ltcB/AS2L0FzLuLYRJoUTk4mJ pPRcJLvxfZLHth/orAPxKAYCDnmPojjrKwSi3+rtycHeRVbC7DCcgeO0euSe0rDCKTzQ nYrPXAXj4jcVjyAZ9H8bdiyHse4bKepD6ehs+SHB4Bm8ZBAPxjjaLgQLh7FwkhUNPDNa ydSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=P/FdT2vT8R1YX3cb+9g3eSSTweRxOkiVzd83P/jGkbQ=; b=1tK30446oIUSuHlqtkDlrmyb2y0D1xKsU0Qdz0hmJ7+W6lBAZAxpA9nuzdmDIRtW+j sLz76TIMpKJ1/5HxZEgVMogIN0elvQBSedidXvNj4JY7KNcAChSoEWJCYTVivhUts8n6 OMkJ434D/rNbSdh0eamqd8D64pbsnGUVzsti8A2dDDZUCo5485FRNnS8hrH8525dFQ+B /wF7wWQPQVpf92OGSa5MUfAYCSQiQYFIspJF7N5T9884x20dR6E5KU96cSQSEHpcXmhS zPuaYIL1ui0jeQc+PcIWP1vVN4B7jZQN9rBNrVQKT2vsY7Ghd3KJn/5qHQLh66+HKDIe X0eA== X-Gm-Message-State: ANoB5pnmT+tHjNIVFbHgFkHOZHUUn79gENYAw3micoQvjoSsjNuTrt2p +coAUhQ3tpTLc5FygYb56Iw= X-Google-Smtp-Source: AA0mqf6Ujp0bfWRahqjgtaPPccLZserAzSEzGiAydQG3bTBuW+NWO7NJAlyj/ph92E3KZ0okDLJW4Q== X-Received: by 2002:a17:907:50a2:b0:7c0:98e6:1216 with SMTP id fv34-20020a17090750a200b007c098e61216mr23786759ejc.575.1670331202765; Tue, 06 Dec 2022 04:53:22 -0800 (PST) Received: from gvm01 (net-2-45-26-236.cust.vodafonedsl.it. [2.45.26.236]) by smtp.gmail.com with ESMTPSA id iy17-20020a170907819100b007c03fa39c33sm7274875ejc.71.2022.12.06.04.53.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 04:53:22 -0800 (PST) Date: Tue, 6 Dec 2022 13:53:32 +0100 From: Piergiorgio Beruto To: Andrew Lunn , Heiner Kallweit , Russell King , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Oleksij Rempel Subject: [PATCH v4 net-next 4/5] drivers/net/phy: add helpers to get/set PLCA configuration Message-ID: <4c6bb420c2169edb31abd5c4d5fe04090ed329e4.1670329232.git.piergiorgio.beruto@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch adds support in phylib to read/write PLCA configuration for Ethernet PHYs that support the OPEN Alliance "10BASE-T1S PLCA Management Registers" specifications. These can be found at https://www.opensig.org/about/specifications/ Signed-off-by: Piergiorgio Beruto --- MAINTAINERS | 1 + drivers/net/phy/mdio-open-alliance.h | 44 +++++++ drivers/net/phy/phy-c45.c | 180 +++++++++++++++++++++++++++ include/linux/phy.h | 6 + 4 files changed, 231 insertions(+) create mode 100644 drivers/net/phy/mdio-open-alliance.h diff --git a/MAINTAINERS b/MAINTAINERS index 7952243e4b43..ed626cbdf5af 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16400,6 +16400,7 @@ PLCA RECONCILIATION SUBLAYER (IEEE802.3 Clause 148) M: Piergiorgio Beruto L: netdev@vger.kernel.org S: Maintained +F: drivers/net/phy/mdio-open-alliance.h F: net/ethtool/plca.c =20 PLDMFW LIBRARY diff --git a/drivers/net/phy/mdio-open-alliance.h b/drivers/net/phy/mdio-op= en-alliance.h new file mode 100644 index 000000000000..565f4162611d --- /dev/null +++ b/drivers/net/phy/mdio-open-alliance.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mdio-open-alliance.h - definition of OPEN Alliance SIG standard registe= rs + */ + +#ifndef __MDIO_OPEN_ALLIANCE__ +#define __MDIO_OPEN_ALLIANCE__ + +#include + +/* MDIO Manageable Devices (MMDs). */ +#define MDIO_MMD_OATC14 MDIO_MMD_VEND2 + +/* Open Alliance TC14 (10BASE-T1S) registers */ +#define MDIO_OATC14_PLCA_IDVER 0xca00 /* PLCA ID and version */ +#define MDIO_OATC14_PLCA_CTRL0 0xca01 /* PLCA Control register 0 */ +#define MDIO_OATC14_PLCA_CTRL1 0xca02 /* PLCA Control register 1 */ +#define MDIO_OATC14_PLCA_STATUS 0xca03 /* PLCA Status register */ +#define MDIO_OATC14_PLCA_TOTMR 0xca04 /* PLCA TO Timer register */ +#define MDIO_OATC14_PLCA_BURST 0xca05 /* PLCA BURST mode register */ + +/* Open Alliance TC14 PLCA IDVER register */ +#define MDIO_OATC14_PLCA_IDM 0xff00 /* PLCA MAP ID */ +#define MDIO_OATC14_PLCA_VER 0x00ff /* PLCA MAP version */ + +/* Open Alliance TC14 PLCA CTRL0 register */ +#define MDIO_OATC14_PLCA_EN 0x8000 /* PLCA enable */ +#define MDIO_OATC14_PLCA_RST 0x4000 /* PLCA reset */ + +/* Open Alliance TC14 PLCA CTRL1 register */ +#define MDIO_OATC14_PLCA_NCNT 0xff00 /* PLCA node count */ +#define MDIO_OATC14_PLCA_ID 0x00ff /* PLCA local node ID */ + +/* Open Alliance TC14 PLCA STATUS register */ +#define MDIO_OATC14_PLCA_PST 0x8000 /* PLCA status indication */ + +/* Open Alliance TC14 PLCA TOTMR register */ +#define MDIO_OATC14_PLCA_TOT 0x00ff + +/* Open Alliance TC14 PLCA BURST register */ +#define MDIO_OATC14_PLCA_MAXBC 0xff00 +#define MDIO_OATC14_PLCA_BTMR 0x00ff + +#endif /* __MDIO_OPEN_ALLIANCE__ */ diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c index a87a4b3ffce4..dace5d3b29ad 100644 --- a/drivers/net/phy/phy-c45.c +++ b/drivers/net/phy/phy-c45.c @@ -8,6 +8,8 @@ #include #include =20 +#include "mdio-open-alliance.h" + /** * genphy_c45_baset1_able - checks if the PMA has BASE-T1 extended abiliti= es * @phydev: target phy_device struct @@ -931,6 +933,184 @@ int genphy_c45_fast_retrain(struct phy_device *phydev= , bool enable) } EXPORT_SYMBOL_GPL(genphy_c45_fast_retrain); =20 +/** + * genphy_c45_plca_get_cfg - get PLCA configuration from standard registers + * @phydev: target phy_device struct + * @plca_cfg: output structure to store the PLCA configuration + * + * Description: if the PHY complies to the Open Alliance TC14 10BASE-T1S P= LCA + * Management Registers specifications, this function can be used to ret= rieve + * the current PLCA configuration from the standard registers in MMD 31. + */ +int genphy_c45_plca_get_cfg(struct phy_device *phydev, + struct phy_plca_cfg *plca_cfg) +{ + int ret; + + ret =3D phy_read_mmd(phydev, MDIO_MMD_OATC14, MDIO_OATC14_PLCA_IDVER); + if (ret < 0) + return ret; + + plca_cfg->version =3D ret; + + ret =3D phy_read_mmd(phydev, MDIO_MMD_OATC14, MDIO_OATC14_PLCA_CTRL0); + if (ret < 0) + return ret; + + plca_cfg->enabled =3D !!(ret & MDIO_OATC14_PLCA_EN); + + ret =3D phy_read_mmd(phydev, MDIO_MMD_OATC14, MDIO_OATC14_PLCA_CTRL1); + if (ret < 0) + return ret; + + plca_cfg->node_cnt =3D (ret & MDIO_OATC14_PLCA_NCNT) >> 8; + plca_cfg->node_id =3D (ret & MDIO_OATC14_PLCA_ID); + + ret =3D phy_read_mmd(phydev, MDIO_MMD_OATC14, MDIO_OATC14_PLCA_TOTMR); + if (ret < 0) + return ret; + + plca_cfg->to_tmr =3D ret & MDIO_OATC14_PLCA_TOT; + + ret =3D phy_read_mmd(phydev, MDIO_MMD_OATC14, MDIO_OATC14_PLCA_BURST); + if (ret < 0) + return ret; + + plca_cfg->burst_cnt =3D (ret & MDIO_OATC14_PLCA_MAXBC) >> 8; + plca_cfg->burst_tmr =3D (ret & MDIO_OATC14_PLCA_BTMR); + + return 0; +} +EXPORT_SYMBOL_GPL(genphy_c45_plca_get_cfg); + +/** + * genphy_c45_plca_set_cfg - set PLCA configuration using standard registe= rs + * @phydev: target phy_device struct + * @plca_cfg: structure containing the PLCA configuration. Fields set to -= 1 are + * not to be changed. + * + * Description: if the PHY complies to the Open Alliance TC14 10BASE-T1S P= LCA + * Management Registers specifications, this function can be used to mod= ify + * the PLCA configuration using the standard registers in MMD 31. + */ +int genphy_c45_plca_set_cfg(struct phy_device *phydev, + const struct phy_plca_cfg *plca_cfg) +{ + int ret; + u16 val; + + // PLCA IDVER is read-only + if (plca_cfg->version >=3D 0) + return -EINVAL; + + // first of all, disable PLCA if required + if (plca_cfg->enabled =3D=3D 0) { + ret =3D phy_clear_bits_mmd(phydev, MDIO_MMD_OATC14, + MDIO_OATC14_PLCA_CTRL0, + MDIO_OATC14_PLCA_EN); + + if (ret < 0) + return ret; + } + + if (plca_cfg->node_cnt >=3D 0 || plca_cfg->node_id >=3D 0) { + if (plca_cfg->node_cnt < 0 || plca_cfg->node_id < 0) { + ret =3D phy_read_mmd(phydev, MDIO_MMD_OATC14, + MDIO_OATC14_PLCA_CTRL1); + + if (ret < 0) + return ret; + + val =3D ret; + } + + if (plca_cfg->node_cnt >=3D 0) + val =3D (val & ~MDIO_OATC14_PLCA_NCNT) | + (plca_cfg->node_cnt << 8); + + if (plca_cfg->node_id >=3D 0) + val =3D (val & ~MDIO_OATC14_PLCA_ID) | + (plca_cfg->node_id); + + ret =3D phy_write_mmd(phydev, MDIO_MMD_OATC14, + MDIO_OATC14_PLCA_CTRL1, val); + + if (ret < 0) + return ret; + } + + if (plca_cfg->to_tmr >=3D 0) { + ret =3D phy_write_mmd(phydev, MDIO_MMD_OATC14, + MDIO_OATC14_PLCA_TOTMR, + plca_cfg->to_tmr); + + if (ret < 0) + return ret; + } + + if (plca_cfg->burst_cnt >=3D 0 || plca_cfg->burst_tmr >=3D 0) { + if (plca_cfg->burst_cnt < 0 || plca_cfg->burst_tmr < 0) { + ret =3D phy_read_mmd(phydev, MDIO_MMD_OATC14, + MDIO_OATC14_PLCA_BURST); + + if (ret < 0) + return ret; + + val =3D ret; + } + + if (plca_cfg->burst_cnt >=3D 0) + val =3D (val & ~MDIO_OATC14_PLCA_MAXBC) | + (plca_cfg->burst_cnt << 8); + + if (plca_cfg->burst_tmr >=3D 0) + val =3D (val & ~MDIO_OATC14_PLCA_BTMR) | + (plca_cfg->burst_tmr); + + ret =3D phy_write_mmd(phydev, MDIO_MMD_OATC14, + MDIO_OATC14_PLCA_BURST, val); + + if (ret < 0) + return ret; + } + + // if we need to enable PLCA, do it at the end + if (plca_cfg->enabled > 0) { + ret =3D phy_set_bits_mmd(phydev, MDIO_MMD_OATC14, + MDIO_OATC14_PLCA_CTRL0, + MDIO_OATC14_PLCA_EN); + + if (ret < 0) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(genphy_c45_plca_set_cfg); + +/** + * genphy_c45_plca_get_status - get PLCA status from standard registers + * @phydev: target phy_device struct + * @plca_st: output structure to store the PLCA status + * + * Description: if the PHY complies to the Open Alliance TC14 10BASE-T1S P= LCA + * Management Registers specifications, this function can be used to ret= rieve + * the current PLCA status information from the standard registers in MM= D 31. + */ +int genphy_c45_plca_get_status(struct phy_device *phydev, + struct phy_plca_status *plca_st) +{ + int ret; + + ret =3D phy_read_mmd(phydev, MDIO_MMD_OATC14, MDIO_OATC14_PLCA_STATUS); + if (ret < 0) + return ret; + + plca_st->pst =3D !!(ret & MDIO_OATC14_PLCA_PST); + return 0; +} +EXPORT_SYMBOL_GPL(genphy_c45_plca_get_status); + struct phy_driver genphy_c45_driver =3D { .phy_id =3D 0xffffffff, .phy_id_mask =3D 0xffffffff, diff --git a/include/linux/phy.h b/include/linux/phy.h index 49d0488bf480..4548c8e8f6a9 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -1745,6 +1745,12 @@ int genphy_c45_loopback(struct phy_device *phydev, b= ool enable); int genphy_c45_pma_resume(struct phy_device *phydev); int genphy_c45_pma_suspend(struct phy_device *phydev); int genphy_c45_fast_retrain(struct phy_device *phydev, bool enable); +int genphy_c45_plca_get_cfg(struct phy_device *phydev, + struct phy_plca_cfg *plca_cfg); +int genphy_c45_plca_set_cfg(struct phy_device *phydev, + const struct phy_plca_cfg *plca_cfg); +int genphy_c45_plca_get_status(struct phy_device *phydev, + struct phy_plca_status *plca_st); =20 /* Generic C45 PHY driver */ extern struct phy_driver genphy_c45_driver; --=20 2.35.1 From nobody Thu Sep 18 12:50:19 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F103EC352A1 for ; Tue, 6 Dec 2022 12:54:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234704AbiLFMyU (ORCPT ); Tue, 6 Dec 2022 07:54:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234565AbiLFMyA (ORCPT ); Tue, 6 Dec 2022 07:54:00 -0500 Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [IPv6:2a00:1450:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C58B562CC; Tue, 6 Dec 2022 04:53:55 -0800 (PST) Received: by mail-ej1-x636.google.com with SMTP id bj12so5865310ejb.13; Tue, 06 Dec 2022 04:53:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=vtmK9mWiq87BtwWKXZvJqVPU4p1Dd/y6RGKbmSiy148=; b=HtxvEH5dKBCXLe4DbnWPWFk+DyJq5ujOjCHJosyNoP7VgEJtDsyKezoqupW6IQBpq3 zvMBT7t71JQD8/5wbU725kdxpUmV/ugobB/ZHhrTodWhqiT/8MmV0khzm8/x27lEB1fm LI0bhU9llE1cXyYD1ZB8UgBKzKnS1eEjqGkYT67A8iPKRIq+KXxQ3JR/ZIef37SMt0+A /XOxkQM7Vakqui3a66qQfuOR4caXTnC6Uepod3UmL72QXBTmPTHWKNkVZY1CeCZ/m/9M ev+uKl+uWBLady3+HteAs7LBRq8FQVioAbPcwUAr2YLMmSPTSapKKX7kX9LfgxDNIh8n aFaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=vtmK9mWiq87BtwWKXZvJqVPU4p1Dd/y6RGKbmSiy148=; b=OrYnmaNkX97hVrT8BQxjYrH/m//QL6Qtr1RW47dGikfXITz16Vpfq9vHAMFChfQbBk Eo7ZZpeigg3uGJsGwSPaKNFnOJRYISUodBvd0+WDuonV6BOOduf1bKk1nEe5hoZrK7Sm HCJm4ETU+nnv40yihrr55Iac7PKU6kEO9eFxAXFDH+5vt0vAOKvkA7D8+4wCWsRgfNyh qYSGiTQ5aXqjO30Cpr+koUWNAUNBly2utkJGrZiIPoa+e6AASgERPTVNj2ujauI4JpIz V1C0T5yZ+wU3q1m2ADj0H1Yea3ndd0ObXv8Qy34o0EJyJSZl2K75+f92woiMeH0liFcd 38cQ== X-Gm-Message-State: ANoB5pmLVeDGT/X1Z6Vy0S6fHhHbx3CO/JNI74/yJ0HdWpZzslvQweCU jinqtMnWfzgDgI9VyyGmii4= X-Google-Smtp-Source: AA0mqf7T5qbqjZjJ0XEPJN0VQd0dBwxxUDpb7vsrCpHVdMK6djrHmF5mpQ/q8gQU8j+14ftSTL/6yg== X-Received: by 2002:a17:906:2cd3:b0:7bf:b675:ffdd with SMTP id r19-20020a1709062cd300b007bfb675ffddmr33108707ejr.610.1670331234207; Tue, 06 Dec 2022 04:53:54 -0800 (PST) Received: from gvm01 (net-2-45-26-236.cust.vodafonedsl.it. [2.45.26.236]) by smtp.gmail.com with ESMTPSA id g1-20020a17090604c100b0073dc5bb7c32sm7331993eja.64.2022.12.06.04.53.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 04:53:53 -0800 (PST) Date: Tue, 6 Dec 2022 13:54:04 +0100 From: Piergiorgio Beruto To: Andrew Lunn , Heiner Kallweit , Russell King , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Oleksij Rempel Subject: [PATCH v4 net-next 5/5] drivers/net/phy: add driver for the onsemi NCN26000 10BASE-T1S PHY Message-ID: <1816cb14213fc2050b1a7e97a68be7186340d994.1670329232.git.piergiorgio.beruto@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch adds support for the onsemi NCN26000 10BASE-T1S industrial Ethernet PHY. The driver supports Point-to-Multipoint operation without auto-negotiation and with link control handling. The PHY also features PLCA for improving performance in P2MP mode. Signed-off-by: Piergiorgio Beruto --- MAINTAINERS | 7 ++ drivers/net/phy/Kconfig | 7 ++ drivers/net/phy/Makefile | 1 + drivers/net/phy/ncn26000.c | 193 +++++++++++++++++++++++++++++++++++++ 4 files changed, 208 insertions(+) create mode 100644 drivers/net/phy/ncn26000.c diff --git a/MAINTAINERS b/MAINTAINERS index ed626cbdf5af..09f0bfa3ae64 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15357,6 +15357,13 @@ L: linux-mips@vger.kernel.org S: Maintained F: arch/mips/boot/dts/ralink/omega2p.dts =20 +ONSEMI ETHERNET PHY DRIVERS +M: Piergiorgio Beruto +L: netdev@vger.kernel.org +S: Supported +W: http://www.onsemi.com +F: drivers/net/phy/ncn* + OP-TEE DRIVER M: Jens Wiklander L: op-tee@lists.trustedfirmware.org diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index af00cf44cd97..7c466830c611 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -267,6 +267,13 @@ config NATIONAL_PHY help Currently supports the DP83865 PHY. =20 +config NCN26000_PHY + tristate "onsemi 10BASE-T1S Ethernet PHY" + help + Adds support for the onsemi 10BASE-T1S Ethernet PHY. + Currently supports the NCN26000 10BASE-T1S Industrial PHY + with MII interface. + config NXP_C45_TJA11XX_PHY tristate "NXP C45 TJA11XX PHYs" depends on PTP_1588_CLOCK_OPTIONAL diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index f7138d3c896b..b5138066ba04 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_MICROCHIP_T1_PHY) +=3D microchip_t1.o obj-$(CONFIG_MICROSEMI_PHY) +=3D mscc/ obj-$(CONFIG_MOTORCOMM_PHY) +=3D motorcomm.o obj-$(CONFIG_NATIONAL_PHY) +=3D national.o +obj-$(CONFIG_NCN26000_PHY) +=3D ncn26000.o obj-$(CONFIG_NXP_C45_TJA11XX_PHY) +=3D nxp-c45-tja11xx.o obj-$(CONFIG_NXP_TJA11XX_PHY) +=3D nxp-tja11xx.o obj-$(CONFIG_QSEMI_PHY) +=3D qsemi.o diff --git a/drivers/net/phy/ncn26000.c b/drivers/net/phy/ncn26000.c new file mode 100644 index 000000000000..9e02c5c55244 --- /dev/null +++ b/drivers/net/phy/ncn26000.c @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Driver for the onsemi 10BASE-T1S NCN26000 PHYs family. + * + * Copyright 2022 onsemi + */ +#include +#include +#include +#include +#include +#include +#include + +#include "mdio-open-alliance.h" + +#define PHY_ID_NCN26000 0x180FF5A1 + +#define NCN26000_REG_IRQ_CTL 16 +#define NCN26000_REG_IRQ_STATUS 17 + +// the NCN26000 maps link_ctrl to BMCR_ANENABLE +#define NCN26000_BCMR_LINK_CTRL_BIT BMCR_ANENABLE + +// the NCN26000 maps link_status to BMSR_ANEGCOMPLETE +#define NCN26000_BMSR_LINK_STATUS_BIT BMSR_ANEGCOMPLETE + +#define NCN26000_IRQ_LINKST_BIT BIT(0) +#define NCN26000_IRQ_PLCAST_BIT BIT(1) +#define NCN26000_IRQ_LJABBER_BIT BIT(2) +#define NCN26000_IRQ_RJABBER_BIT BIT(3) +#define NCN26000_IRQ_PLCAREC_BIT BIT(4) +#define NCN26000_IRQ_PHYSCOL_BIT BIT(5) + +#define TO_TMR_DEFAULT 32 + +struct ncn26000_priv { + u16 enabled_irqs; +}; + +// module parameter: if set, the link status is derived from the PLCA stat= us +// default: false +static bool link_status_plca; +module_param(link_status_plca, bool, 0644); + +// driver callbacks + +static int ncn26000_config_init(struct phy_device *phydev) +{ + /* HW bug workaround: the default value of the PLCA TO_TIMER should be + * 32, where the current version of NCN26000 reports 24. This will be + * fixed in future PHY versions. For the time being, we force the + * correct default here. + */ + return phy_write_mmd(phydev, MDIO_MMD_OATC14, MDIO_OATC14_PLCA_TOTMR, + TO_TMR_DEFAULT); +} + +static int ncn26000_config_aneg(struct phy_device *phydev) +{ + // Note: the NCN26000 supports only P2MP link mode. Therefore, AN is not + // supported. However, this function is invoked by phylib to enable the + // PHY, regardless of the AN support. + phydev->mdix_ctrl =3D ETH_TP_MDI_AUTO; + phydev->mdix =3D ETH_TP_MDI; + + // bring up the link + return phy_write(phydev, MII_BMCR, NCN26000_BCMR_LINK_CTRL_BIT); +} + +static int ncn26000_get_features(struct phy_device *phydev) +{ + linkmode_zero(phydev->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, phydev->supported); + + linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT, + phydev->supported); + + linkmode_copy(phydev->advertising, phydev->supported); + return 0; +} + +static int ncn26000_read_status(struct phy_device *phydev) +{ + // The NCN26000 reports NCN26000_LINK_STATUS_BIT if the link status of + // the PHY is up. It further reports the logical AND of the link status + // and the PLCA status in the BMSR_LSTATUS bit. Thus, report the link + // status by testing the appropriate BMSR bit according to the module's + // parameter configuration. + const int lstatus_flag =3D link_status_plca ? + BMSR_LSTATUS : NCN26000_BMSR_LINK_STATUS_BIT; + + int ret; + + ret =3D phy_read(phydev, MII_BMSR); + if (unlikely(ret < 0)) + return ret; + + // update link status + phydev->link =3D (ret & lstatus_flag) ? 1 : 0; + + // handle more IRQs here + + return 0; +} + +static irqreturn_t ncn26000_handle_interrupt(struct phy_device *phydev) +{ + const struct ncn26000_priv *const priv =3D phydev->priv; + int ret; + + // clear the latched bits in MII_BMSR + phy_read(phydev, MII_BMSR); + + // read and aknowledge the IRQ status register + ret =3D phy_read(phydev, NCN26000_REG_IRQ_STATUS); + + if (unlikely(ret < 0) || (ret & priv->enabled_irqs) =3D=3D 0) + return IRQ_NONE; + + phy_trigger_machine(phydev); + return IRQ_HANDLED; +} + +static int ncn26000_config_intr(struct phy_device *phydev) +{ + int ret; + struct ncn26000_priv *priv =3D phydev->priv; + + if (phydev->interrupts =3D=3D PHY_INTERRUPT_ENABLED) { + // acknowledge IRQs + ret =3D phy_read(phydev, NCN26000_REG_IRQ_STATUS); + if (ret < 0) + return ret; + + // get link status notifications + priv->enabled_irqs =3D NCN26000_IRQ_LINKST_BIT; + } else { + // disable all IRQs + priv->enabled_irqs =3D 0; + } + + ret =3D phy_write(phydev, NCN26000_REG_IRQ_CTL, priv->enabled_irqs); + if (ret !=3D 0) + return ret; + + return 0; +} + +static int ncn26000_probe(struct phy_device *phydev) +{ + struct device *dev =3D &phydev->mdio.dev; + struct ncn26000_priv *priv; + + priv =3D devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + phydev->priv =3D priv; + + return 0; +} + +static struct phy_driver ncn26000_driver[] =3D { + { + PHY_ID_MATCH_MODEL(PHY_ID_NCN26000), + .name =3D "NCN26000", + .probe =3D ncn26000_probe, + .get_features =3D ncn26000_get_features, + .config_init =3D ncn26000_config_init, + .config_intr =3D ncn26000_config_intr, + .config_aneg =3D ncn26000_config_aneg, + .read_status =3D ncn26000_read_status, + .handle_interrupt =3D ncn26000_handle_interrupt, + .get_plca_cfg =3D genphy_c45_plca_get_cfg, + .set_plca_cfg =3D genphy_c45_plca_set_cfg, + .get_plca_status =3D genphy_c45_plca_get_status, + .soft_reset =3D genphy_soft_reset, + }, +}; + +module_phy_driver(ncn26000_driver); + +static struct mdio_device_id __maybe_unused ncn26000_tbl[] =3D { + { PHY_ID_MATCH_MODEL(PHY_ID_NCN26000) }, + { } +}; + +MODULE_DEVICE_TABLE(mdio, ncn26000_tbl); + +MODULE_AUTHOR("Piergiorgio Beruto"); +MODULE_DESCRIPTION("onsemi 10BASE-T1S PHY driver"); +MODULE_LICENSE("Dual BSD/GPL"); --=20 2.35.1