From patchwork Thu May 19 13:56:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 12855090 X-Patchwork-Delegate: kuba@kernel.org 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 C38B3C433EF for ; Thu, 19 May 2022 13:57:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239273AbiESN5N (ORCPT ); Thu, 19 May 2022 09:57:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56594 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238834AbiESN5I (ORCPT ); Thu, 19 May 2022 09:57:08 -0400 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::221]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F1C5E65; Thu, 19 May 2022 06:57:00 -0700 (PDT) Received: (Authenticated sender: maxime.chevallier@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id C27B9240018; Thu, 19 May 2022 13:56:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1652968616; 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=+OOpYFAzojc6pPu7a3Cjy9JL3eWpwDvEMOqBp/XLQgg=; b=dtLrrAdyCTFWwrLJm+qeQJGHpa3bmwxvW+UgOFJ2YIIByrWEe4gUjtmZGjssJ89W9srh8R kZUUlf/rHIlPTNDYwmaIVUZU1WPsbHJKInceDUATxGClPhC6AZXeJcAej8dgHMEoW0dq0E lYbranHyebS2g9nlHnKF1ZapApg5OPpr1GWEzmXkkxa2ZFeR2fqPG0GDXmowXSFxd5lFX/ 9e+Cg0cVQKmps3VHV4/wykA4TXYwrxEHWkfwDBp3Ybo7yQf2RO+YN26CKmh0edA2YauRGK dissJ8wdsdBTMbsA9chamCqVZRRQVvWCNiKLkCb7FvfgSTYn5wUCMwwP0sgdkA== From: Maxime Chevallier To: davem@davemloft.net, Rob Herring Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Russell King , linux-arm-kernel@lists.infradead.org, Richard Cochran , Horatiu.Vultur@microchip.com, Allan.Nielsen@microchip.com, UNGLinuxDriver@microchip.com Subject: [PATCH net-next 1/6] net: phy: Introduce QUSGMII PHY mode Date: Thu, 19 May 2022 15:56:42 +0200 Message-Id: <20220519135647.465653-2-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220519135647.465653-1-maxime.chevallier@bootlin.com> References: <20220519135647.465653-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The QUSGMII mode is a derivative of Cisco's USXGMII standard. This standard is pretty similar to SGMII, but allows for faster speeds, and has the build-in bits for Quad and Octa variants (like QSGMII). The main difference with SGMII/QSGMII is that USXGMII/QUSGMII re-uses the preamble to carry various information, named 'Extensions'. As of today, the USXGMII standard only mentions the "PCH" extension, which is used to convey timestamps, allowing in-band signaling of PTP timestamps without having to modify the frame itself. This commit adds support for that mode. When no extension is in use, it behaves exactly like QSGMII, although it's not compatible with QSGMII. Signed-off-by: Maxime Chevallier --- Documentation/networking/phy.rst | 9 +++++++++ drivers/net/phy/phylink.c | 3 +++ include/linux/phy.h | 3 +++ 3 files changed, 15 insertions(+) diff --git a/Documentation/networking/phy.rst b/Documentation/networking/phy.rst index d43da709bf40..72c3c9fbce6f 100644 --- a/Documentation/networking/phy.rst +++ b/Documentation/networking/phy.rst @@ -308,6 +308,15 @@ Some of the interface modes are described below: rate of 125Mpbs using a 4B/5B encoding scheme, resulting in an underlying data rate of 100Mpbs. +``PHY_INTERFACE_MODE_QUSGMII`` + This defines the Cisco the Quad USGMII mode, which is the Quad variant of + the USGMII (Universal SGMII) link. It's very similar to QSGMII, but uses + a Packet Control Header (PCH) instead of the 7 bytes preamble to carry not + only the port id, but also so-called "extensions". The only documented + extension so-far in the specification is the inclusion of timestamps, for + PTP-enabled PHYs. This mode isn't compatible with QSGMII, but offers the + same capabilities in terms of link speed and negociation. + Pause frames / flow control =========================== diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 06943889d747..228eed5bc85a 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -320,6 +320,7 @@ void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface, case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_QUSGMII: case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_GMII: caps |= MAC_1000HD | MAC_1000FD; @@ -631,6 +632,7 @@ static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode) switch (pl->link_config.interface) { case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_QUSGMII: phylink_set(pl->supported, 10baseT_Half); phylink_set(pl->supported, 10baseT_Full); phylink_set(pl->supported, 100baseT_Half); @@ -2944,6 +2946,7 @@ void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state, case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_QUSGMII: phylink_decode_sgmii_word(state, lpa); break; diff --git a/include/linux/phy.h b/include/linux/phy.h index 36ca2b5c2253..4a2731c78590 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -152,6 +152,7 @@ typedef enum { PHY_INTERFACE_MODE_USXGMII, /* 10GBASE-KR - with Clause 73 AN */ PHY_INTERFACE_MODE_10GKR, + PHY_INTERFACE_MODE_QUSGMII, PHY_INTERFACE_MODE_MAX, } phy_interface_t; @@ -267,6 +268,8 @@ static inline const char *phy_modes(phy_interface_t interface) return "10gbase-kr"; case PHY_INTERFACE_MODE_100BASEX: return "100base-x"; + case PHY_INTERFACE_MODE_QUSGMII: + return "qusgmii"; default: return "unknown"; } From patchwork Thu May 19 13:56:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 12855089 X-Patchwork-Delegate: kuba@kernel.org 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 3C468C4167B for ; Thu, 19 May 2022 13:57:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239189AbiESN5M (ORCPT ); Thu, 19 May 2022 09:57:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237828AbiESN5I (ORCPT ); Thu, 19 May 2022 09:57:08 -0400 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::221]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 923162AD2; Thu, 19 May 2022 06:57:03 -0700 (PDT) Received: (Authenticated sender: maxime.chevallier@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 613DE24001A; Thu, 19 May 2022 13:56:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1652968618; 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=QPggy8DjxLmgMYSoeke7qJ+fzc4rcw2qLCr35/LZ95U=; b=eXmcVNZEpkG/9pDpy7nmw3FauLQz7qRAEaKixvmmNUMQBykSenPtBG3UJEfzr7Sl1qdNh0 4lYq4Cdu3XveCT1sIq7Mh6Yn8ZRWBYNjsRFMls4Ql3qNcfIRZNCWS+yaL8Ztu6WUrMpqM+ r0HfK1/WU2rPdlnyJCNAoyMku+cB6fxpE3rOZLwBXRPyuB3oQNXo3uYFrrhqdI0IQPBxrb Z5yiCFORBBwkfnlnuUgK47/n+4dxXh6aYogksPiDd8c9Sa3+Apaj34jIIAvLOjLrSgVDKB zvHuJoHFNjTlmn2hBc5U555aLmc6pNa0Z2LOEvdey9wfkN/xQwaymwerCy0aPg== From: Maxime Chevallier To: davem@davemloft.net, Rob Herring Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Russell King , linux-arm-kernel@lists.infradead.org, Richard Cochran , Horatiu.Vultur@microchip.com, Allan.Nielsen@microchip.com, UNGLinuxDriver@microchip.com Subject: [PATCH net-next 2/6] dt-bindings: net: ethernet-controller: add QUSGMII mode Date: Thu, 19 May 2022 15:56:43 +0200 Message-Id: <20220519135647.465653-3-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220519135647.465653-1-maxime.chevallier@bootlin.com> References: <20220519135647.465653-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add a new QUSGMII mode, standing for "Quad Universal Serial Gigabit Media Independent Interface", a derivative of USGMII which, similarly to QSGMII, allows to multiplex 4 1Gbps links to a Quad-PHY. The main difference with QSGMII is that QUSGMII can include an extension instead of the standard 7bytes ethernet preamble, allowing to convey arbitrary data such as Timestamps. Signed-off-by: Maxime Chevallier Acked-by: Rob Herring --- Documentation/devicetree/bindings/net/ethernet-controller.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/net/ethernet-controller.yaml b/Documentation/devicetree/bindings/net/ethernet-controller.yaml index 4f15463611f8..dccde2033697 100644 --- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml +++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml @@ -67,6 +67,7 @@ properties: - gmii - sgmii - qsgmii + - qusgmii - tbi - rev-mii - rmii From patchwork Thu May 19 13:56:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 12855102 X-Patchwork-Delegate: kuba@kernel.org 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 F3353C433EF for ; Thu, 19 May 2022 13:57:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239352AbiESN5R (ORCPT ); Thu, 19 May 2022 09:57:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56700 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239074AbiESN5J (ORCPT ); Thu, 19 May 2022 09:57:09 -0400 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::221]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3C18663C6; Thu, 19 May 2022 06:57:07 -0700 (PDT) Received: (Authenticated sender: maxime.chevallier@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id DBB7F240023; Thu, 19 May 2022 13:56:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1652968620; 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=T5HVJtctx3gpJWBcmBUXPdRuM6h7gI5qAkK5+JtRuxU=; b=CO8RJtvVmUy1s2EUnqCO2BnRsTGkzHRCrVybvOn9SvVRNN3joBdEKkd0GpKyPojdevGxnU W0It2jG4mTiYJt1bgwAfeYOIJ/6Nh8RPjSZP0zZKeQiQ8TJDLmzvLl8xpZimqRhn/Dakc0 DWgQXH+yzH1AnCkQcR8klCAZZ8+NdFaCR5NtzJ0nrXuB+rUZNa06IExZmM7cR3Bn2jb7UO 7PBL0DRnyOcVl5Lqt+eaz2z7aQamt9SVdxSyDvcRtXdA4LEpe+siLIKLQKQumf9JTk2Ec1 BxdA/9qK2M1m3HcxwQM9/1iRwrZKsCSytYaVfYyXM1LzioEJgsP+ELPjB7/KyA== From: Maxime Chevallier To: davem@davemloft.net, Rob Herring Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Russell King , linux-arm-kernel@lists.infradead.org, Richard Cochran , Horatiu.Vultur@microchip.com, Allan.Nielsen@microchip.com, UNGLinuxDriver@microchip.com Subject: [PATCH net-next 3/6] net: lan966x: Add QUSGMII support for lan966x Date: Thu, 19 May 2022 15:56:44 +0200 Message-Id: <20220519135647.465653-4-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220519135647.465653-1-maxime.chevallier@bootlin.com> References: <20220519135647.465653-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The Lan996x controller supports the QUSGMII mode, which is very similar to QSGMII in the way it's configured and the autonegociation capababilities it provides. This commit adds support for that mode, treating it most of the time like QSGMII, making sure that we do configure the PCS how we should. Signed-off-by: Maxime Chevallier --- .../ethernet/microchip/lan966x/lan966x_main.c | 2 ++ .../ethernet/microchip/lan966x/lan966x_main.h | 6 +++++ .../microchip/lan966x/lan966x_phylink.c | 9 +++++++- .../ethernet/microchip/lan966x/lan966x_port.c | 22 ++++++++++++++----- .../ethernet/microchip/lan966x/lan966x_regs.h | 6 +++++ 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c index ca1cef79b83f..b8c2ef905e46 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -728,6 +728,8 @@ static int lan966x_probe_port(struct lan966x *lan966x, u32 p, port->phylink_config.supported_interfaces); __set_bit(PHY_INTERFACE_MODE_QSGMII, port->phylink_config.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_QUSGMII, + port->phylink_config.supported_interfaces); __set_bit(PHY_INTERFACE_MODE_1000BASEX, port->phylink_config.supported_interfaces); __set_bit(PHY_INTERFACE_MODE_2500BASEX, diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h index e6642083ab9e..304c784f48f6 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h @@ -452,4 +452,10 @@ static inline void lan_rmw(u32 val, u32 mask, struct lan966x *lan966x, gcnt, gwidth, raddr, rinst, rcnt, rwidth)); } +static inline bool lan966x_is_qsgmii(phy_interface_t mode) +{ + return (mode == PHY_INTERFACE_MODE_QSGMII) || + (mode == PHY_INTERFACE_MODE_QUSGMII); +} + #endif /* __LAN966X_MAIN_H__ */ diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c b/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c index 38a7e95d69b4..96708352f53e 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c @@ -28,11 +28,18 @@ static int lan966x_phylink_mac_prepare(struct phylink_config *config, phy_interface_t iface) { struct lan966x_port *port = netdev_priv(to_net_dev(config->dev)); + phy_interface_t serdes_mode = iface; int err; if (port->serdes) { + /* As far as the SerDes is concerned, QUSGMII is the same as + * QSGMII. + */ + if (lan966x_is_qsgmii(iface)) + serdes_mode = PHY_INTERFACE_MODE_QSGMII; + err = phy_set_mode_ext(port->serdes, PHY_MODE_ETHERNET, - iface); + serdes_mode); if (err) { netdev_err(to_net_dev(config->dev), "Could not set mode of SerDes\n"); diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c index f141644e4372..ef65a44b2d34 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c @@ -168,7 +168,7 @@ static void lan966x_port_link_up(struct lan966x_port *port) /* Also the GIGA_MODE_ENA(1) needs to be set regardless of the * port speed for QSGMII ports. */ - if (config->portmode == PHY_INTERFACE_MODE_QSGMII) + if (lan966x_is_qsgmii(config->portmode)) mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1); lan_wr(config->duplex | mode, @@ -331,10 +331,14 @@ int lan966x_port_pcs_set(struct lan966x_port *port, struct lan966x *lan966x = port->lan966x; bool inband_aneg = false; bool outband; + bool full_preamble = false; + + if (config->portmode == PHY_INTERFACE_MODE_QUSGMII) + full_preamble = true; if (config->inband) { if (config->portmode == PHY_INTERFACE_MODE_SGMII || - config->portmode == PHY_INTERFACE_MODE_QSGMII) + lan966x_is_qsgmii(config->portmode)) inband_aneg = true; /* Cisco-SGMII in-band-aneg */ else if (config->portmode == PHY_INTERFACE_MODE_1000BASEX && config->autoneg) @@ -345,9 +349,15 @@ int lan966x_port_pcs_set(struct lan966x_port *port, outband = true; } - /* Disable or enable inband */ - lan_rmw(DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA_SET(outband), - DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA, + /* Disable or enable inband. + * For QUSGMII, we rely on the preamble to transmit data such as + * timestamps, therefore force full preamble transmission, and prevent + * premable shortening + */ + lan_rmw(DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA_SET(outband) | + DEV_PCS1G_MODE_CFG_SAVE_PREAMBLE_ENA_SET(full_preamble), + DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA | + DEV_PCS1G_MODE_CFG_SAVE_PREAMBLE_ENA, lan966x, DEV_PCS1G_MODE_CFG(port->chip_port)); /* Enable PCS */ @@ -396,7 +406,7 @@ void lan966x_port_init(struct lan966x_port *port) if (lan966x->fdma) lan966x_fdma_netdev_init(lan966x, port->dev); - if (config->portmode != PHY_INTERFACE_MODE_QSGMII) + if (!lan966x_is_qsgmii(config->portmode)) return; lan_rmw(DEV_CLOCK_CFG_PCS_RX_RST_SET(0) | diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h index 2f59285bef29..d4839e4b8ed5 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h @@ -504,6 +504,12 @@ enum lan966x_target { #define DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA_GET(x)\ FIELD_GET(DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA, x) +#define DEV_PCS1G_MODE_CFG_SAVE_PREAMBLE_ENA BIT(1) +#define DEV_PCS1G_MODE_CFG_SAVE_PREAMBLE_ENA_SET(x)\ + FIELD_PREP(DEV_PCS1G_MODE_CFG_SAVE_PREAMBLE_ENA, x) +#define DEV_PCS1G_MODE_CFG_SAVE_PREAMBLE_ENA_GET(x)\ + FIELD_GET(DEV_PCS1G_MODE_CFG_SAVE_PREAMBLE_ENA, x) + /* DEV:PCS1G_CFG_STATUS:PCS1G_SD_CFG */ #define DEV_PCS1G_SD_CFG(t) __REG(TARGET_DEV, t, 8, 72, 0, 1, 68, 8, 0, 1, 4) From patchwork Thu May 19 13:56:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 12855091 X-Patchwork-Delegate: kuba@kernel.org 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 646B1C433EF for ; Thu, 19 May 2022 13:57:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239325AbiESN5O (ORCPT ); Thu, 19 May 2022 09:57:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56612 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238804AbiESN5I (ORCPT ); Thu, 19 May 2022 09:57:08 -0400 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::221]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 932512BE7; Thu, 19 May 2022 06:57:04 -0700 (PDT) Received: (Authenticated sender: maxime.chevallier@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id AB19924000A; Thu, 19 May 2022 13:57:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1652968623; 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=pWGVazQWGDDZgzON711pAZLPzapDACfEJlg6W1kTnfg=; b=BhkmYgd0BYKmyoJAXqAKqMjHEUFihdXTXN70fxztHSnrObK3NtNQFzMboMqwt+XpzQQBq8 Yckb+AaL2hE1pmmtEbLR6rLBxyeepVgkzziIS882Uojd76piQeLymSa7cHjUN3tFnQqX0A /HiQNag2wBM6NiYjZFQdF4ixegzRmBH+6+CkP1eh5m73aUKH14Fldg3uY3qgC8C7HSl3Zy 7wfbsiUhnuFoVNDgwX9BUFpRq6lxwsuk3Xj7UuEefU8Fxxi8GiIk7GXCHkAaaT3zBG67iM OmCXXf7ZSi2i5fa5SWdwzpMMobse/smQ6HYAlkS6nDQCtYamQECNfPh5KOY35A== From: Maxime Chevallier To: davem@davemloft.net, Rob Herring Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Russell King , linux-arm-kernel@lists.infradead.org, Richard Cochran , Horatiu.Vultur@microchip.com, Allan.Nielsen@microchip.com, UNGLinuxDriver@microchip.com Subject: [PATCH net-next 4/6] net: phy: Add support for inband extensions Date: Thu, 19 May 2022 15:56:45 +0200 Message-Id: <20220519135647.465653-5-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220519135647.465653-1-maxime.chevallier@bootlin.com> References: <20220519135647.465653-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The USXGMII Standard by Cisco introduces the notion of extensions used in the preamble. The standard proposes a "PCH" extension, which allows passing timestamps in the preamble. However, other alternatives are possible, like Microchip's "MCH" mode, that allows passing indication to a PHY telling whether or not the PHY should timestamp an outgoing packet, therefore removing the need for the PHY to have an internal classifier. This commit allows reporting the various extensions a PHY supports, without tying them to the actual PHY mode. This is done 1) because there are multiple variants of the USXGMII mode, like QUSGMII and OUSGMII, and 2) because other non-cisco standards might one day propose a similar mechanism. Signed-off-by: Maxime Chevallier --- drivers/net/phy/phy.c | 68 +++++++++++++++++++++++++++++++++++++++++++ include/linux/phy.h | 25 +++++++++++++++- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index beb2b66da132..bbd3d7620609 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1475,3 +1475,71 @@ int phy_ethtool_nway_reset(struct net_device *ndev) return phy_restart_aneg(phydev); } EXPORT_SYMBOL(phy_ethtool_nway_reset); + +/** + * PHY modes in the USXGMII family can have extensions, with data transmitted + * in the frame preamble. + * For now, only QUSGMII is supported, but other variants like USGMII and + * OUSGMII can be added in the future. + */ +static inline bool phy_interface_has_inband_ext(phy_interface_t interface) +{ + return interface == PHY_INTERFACE_MODE_QUSGMII; +} + +bool phy_inband_ext_available(struct phy_device *phydev, u32 ext) +{ + return !!(phydev->inband_ext.available & ext); +} +EXPORT_SYMBOL(phy_inband_ext_available); + +bool phy_inband_ext_enabled(struct phy_device *phydev, u32 ext) +{ + return !!(phydev->inband_ext.enabled & ext); +} +EXPORT_SYMBOL(phy_inband_ext_enabled); + +static int phy_set_inband_ext(struct phy_device *phydev, u32 mask, u32 ext) +{ + int ret; + + if (!phy_interface_has_inband_ext(phydev->interface)) + return -EOPNOTSUPP; + + if (!phydev->drv->inband_ext_config) + return -EOPNOTSUPP; + + ret = phydev->drv->inband_ext_config(phydev, mask, ext); + if (ret) + return ret; + + phydev->inband_ext.enabled &= ~mask; + phydev->inband_ext.enabled |= (mask & ext); + + return 0; +} + +int phy_inband_ext_enable(struct phy_device *phydev, u32 ext) +{ + return phy_set_inband_ext(phydev, ext, ext); +} +EXPORT_SYMBOL(phy_inband_ext_enable); + +int phy_inband_ext_disable(struct phy_device *phydev, u32 ext) +{ + return phy_set_inband_ext(phydev, ext, 0); +} +EXPORT_SYMBOL(phy_inband_ext_disable); + +int phy_inband_ext_set_available(struct phy_device *phydev, u32 mask, u32 ext) +{ + if (!(mask & phydev->drv->inband_ext)) + return -EOPNOTSUPP; + + phydev->inband_ext.available &= ~mask; + phydev->inband_ext.available |= (mask & ext); + + return 0; +} +EXPORT_SYMBOL(phy_inband_ext_set_available); + diff --git a/include/linux/phy.h b/include/linux/phy.h index 4a2731c78590..6b08f49bce5b 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -190,6 +190,21 @@ static inline void phy_interface_set_rgmii(unsigned long *intf) __set_bit(PHY_INTERFACE_MODE_RGMII_TXID, intf); } +/* + * TODO : Doc + */ +enum { + __PHY_INBAND_EXT_PCH = 0, +}; + +#define PHY_INBAND_EXT_PCH BIT(__PHY_INBAND_EXT_PCH) + +int phy_inband_ext_enable(struct phy_device *phydev, u32 ext); +int phy_inband_ext_disable(struct phy_device *phydev, u32 ext); +int phy_inband_ext_set_available(struct phy_device *phydev, u32 mask, u32 ext); +bool phy_inband_ext_available(struct phy_device *phydev, u32 ext); +bool phy_inband_ext_enabled(struct phy_device *phydev, u32 ext); + /* * phy_supported_speeds - return all speeds currently supported by a PHY device */ @@ -275,7 +290,6 @@ static inline const char *phy_modes(phy_interface_t interface) } } - #define PHY_INIT_TIMEOUT 100000 #define PHY_FORCE_TIMEOUT 10 @@ -635,6 +649,11 @@ struct phy_device { phy_interface_t interface; + struct { + u32 available; + u32 enabled; + } inband_ext; + /* * forced speed & duplex (no autoneg) * partner speed & duplex & pause (autoneg) @@ -766,6 +785,7 @@ struct phy_driver { u32 phy_id_mask; const unsigned long * const features; u32 flags; + u32 inband_ext; const void *driver_data; /** @@ -935,6 +955,9 @@ 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); + + int (*inband_ext_config)(struct phy_device *dev, u32 features, + u32 mask); }; #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ struct phy_driver, mdiodrv) From patchwork Thu May 19 13:56:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 12855092 X-Patchwork-Delegate: kuba@kernel.org 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 7D8BCC433F5 for ; Thu, 19 May 2022 13:57:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232267AbiESN5P (ORCPT ); Thu, 19 May 2022 09:57:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56612 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239063AbiESN5J (ORCPT ); Thu, 19 May 2022 09:57:09 -0400 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::221]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF0CA5F85; Thu, 19 May 2022 06:57:06 -0700 (PDT) Received: (Authenticated sender: maxime.chevallier@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 950EF24001C; Thu, 19 May 2022 13:57:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1652968625; 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=NpJ7Y06rlWK7NL20S9LW+d8iM18Q5646oiRCct7xMqs=; b=k+Zosj4bOSeQs9ipDgkyb56cMN8WWYNa19kqrZCCXZNm+sPTw5+0ByMrqu8uK4XlC4oOx/ I1g5DbmuImllriMWb2oq8i1g7O0lDnj1BZJ4fIbhFdlJADgA4aanPAOT/oWyZ1IO7immjS Ew9zguV/iN1necrZiMOhAbaLEGrbwBEL++6D7/f6mf6BwG7lnQDKYw6H0bxQzaAgrGOCVx MHzVmOvfrrHdQiCDzBXn9o8tQxq/3s8Z0MGoLasRbNxESYbWZ25Ome3mWxMClQ0x1aeE6H BZlt0I4Ixn3VdCw0r20BFMLSacJUakI8/z47zVvdHX+u8WTwp6d5duR4mM+0Sg== From: Maxime Chevallier To: davem@davemloft.net, Rob Herring Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Russell King , linux-arm-kernel@lists.infradead.org, Richard Cochran , Horatiu.Vultur@microchip.com, Allan.Nielsen@microchip.com, UNGLinuxDriver@microchip.com Subject: [PATCH net-next 5/6] net: lan966x: Allow using PCH extension for PTP Date: Thu, 19 May 2022 15:56:46 +0200 Message-Id: <20220519135647.465653-6-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220519135647.465653-1-maxime.chevallier@bootlin.com> References: <20220519135647.465653-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This commit adds the logic to use the PCH mode for timestamp passing in ingress traffic for PTP. The tricky part is that we need to configure both the PHY and the MAC, since the MAC will extract the timetsamp reported by the PHY from the preamble and set it into the SKB. Note that with the PCH mode, we only get the RX timestamp that way, the TX timestamps are still reported OOB by the PHY. Note that only the nanoseconds part is extracted from the PCH extension, since there's not enough room in the 4 bytes extension to pass a full 80bits timestamp. The seconds part of the timestamp still needs to get retrieved from the PHY using an out-of-band mechanism. Signed-off-by: Maxime Chevallier --- .../ethernet/microchip/lan966x/lan966x_main.c | 12 +-- .../ethernet/microchip/lan966x/lan966x_port.c | 11 +++ .../ethernet/microchip/lan966x/lan966x_ptp.c | 93 ++++++++++++++++++- .../ethernet/microchip/lan966x/lan966x_regs.h | 66 +++++++++++++ 4 files changed, 171 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c index b8c2ef905e46..d5d65cc9fc76 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -400,13 +400,11 @@ static int lan966x_port_ioctl(struct net_device *dev, struct ifreq *ifr, { struct lan966x_port *port = netdev_priv(dev); - if (!phy_has_hwtstamp(dev->phydev) && port->lan966x->ptp) { - switch (cmd) { - case SIOCSHWTSTAMP: - return lan966x_ptp_hwtstamp_set(port, ifr); - case SIOCGHWTSTAMP: - return lan966x_ptp_hwtstamp_get(port, ifr); - } + switch (cmd) { + case SIOCSHWTSTAMP: + return lan966x_ptp_hwtstamp_set(port, ifr); + case SIOCGHWTSTAMP: + return lan966x_ptp_hwtstamp_get(port, ifr); } if (!dev->phydev) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c index ef65a44b2d34..3a0aaf566698 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c @@ -360,6 +360,17 @@ int lan966x_port_pcs_set(struct lan966x_port *port, DEV_PCS1G_MODE_CFG_SAVE_PREAMBLE_ENA, lan966x, DEV_PCS1G_MODE_CFG(port->chip_port)); + if (full_preamble) + lan_rmw(DEV_ENABLE_CONFIG_MM_TX_ENA_SET(1) | + DEV_ENABLE_CONFIG_MM_RX_ENA_SET(1), + DEV_ENABLE_CONFIG_MM_TX_ENA | + DEV_ENABLE_CONFIG_MM_RX_ENA, + lan966x, DEV_ENABLE_CONFIG(port->chip_port)); + + lan_rmw(SYS_PTP_MODE_CFG_PTP_MODE_VAL_SET(1), + SYS_PTP_MODE_CFG_PTP_MODE_VAL, + lan966x, SYS_PTP_MODE_CFG(port->chip_port, 0)); + /* Enable PCS */ lan_wr(DEV_PCS1G_CFG_PCS_ENA_SET(1), lan966x, DEV_PCS1G_CFG(port->chip_port)); diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c index ae782778d6dd..f9dc0861f038 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c @@ -35,11 +35,28 @@ static u64 lan966x_ptp_get_nominal_value(void) return res; } -int lan966x_ptp_hwtstamp_set(struct lan966x_port *port, struct ifreq *ifr) +/* Enable or disable PCH timestamp transmission. This uses the USGMII PCH + * extensions to transmit the timestamps in the frame preamble. + */ +static void lan966x_ptp_pch_configure(struct lan966x_port *port, bool enable) +{ + lan_rmw(SYS_PCH_CFG_PCH_SUB_PORT_ID_SET(port->chip_port % 4) | + SYS_PCH_CFG_PCH_TX_MODE_SET(enable) | + SYS_PCH_CFG_PCH_RX_MODE_SET(enable), + SYS_PCH_CFG_PCH_SUB_PORT_ID | + SYS_PCH_CFG_PCH_TX_MODE | + SYS_PCH_CFG_PCH_RX_MODE, + port->lan966x, SYS_PCH_CFG(port->chip_port)); +} + +static int lan966x_ptp_mac_hwtstamp_set(struct lan966x_port *port, + struct ifreq *ifr, + bool inband) { struct lan966x *lan966x = port->lan966x; struct hwtstamp_config cfg; struct lan966x_phc *phc; + bool timestamp_in_pch = false; /* For now don't allow to run ptp on ports that are part of a bridge, * because in case of transparent clock the HW will still forward the @@ -88,16 +105,48 @@ int lan966x_ptp_hwtstamp_set(struct lan966x_port *port, struct ifreq *ifr) return -ERANGE; } + if (inband && + port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP && + port->config.portmode == PHY_INTERFACE_MODE_QUSGMII) + timestamp_in_pch = true; + /* Commit back the result & save it */ mutex_lock(&lan966x->ptp_lock); phc = &lan966x->phc[LAN966X_PHC_PORT]; memcpy(&phc->hwtstamp_config, &cfg, sizeof(cfg)); + lan966x_ptp_pch_configure(port, timestamp_in_pch); mutex_unlock(&lan966x->ptp_lock); return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; + } -int lan966x_ptp_hwtstamp_get(struct lan966x_port *port, struct ifreq *ifr) +int lan966x_ptp_hwtstamp_set(struct lan966x_port *port, struct ifreq *ifr) +{ + struct phy_device *phydev = port->dev->phydev; + int ret; + + if (!phy_has_hwtstamp(phydev) && port->lan966x->ptp) + return lan966x_ptp_mac_hwtstamp_set(port, ifr, false); + + ret = phy_mii_ioctl(phydev, ifr, SIOCSHWTSTAMP); + if (ret) + return ret; + + if (phy_inband_ext_available(phydev, PHY_INBAND_EXT_PCH)) { + ret = phy_inband_ext_enable(phydev, PHY_INBAND_EXT_PCH); + if (ret) + return ret; + + ret = lan966x_ptp_mac_hwtstamp_set(port, ifr, true); + if (ret) + return phy_inband_ext_disable(phydev, PHY_INBAND_EXT_PCH); + } + + return ret; +} + +static int lan966x_ptp_mac_hwtstamp_get(struct lan966x_port *port, struct ifreq *ifr) { struct lan966x *lan966x = port->lan966x; struct lan966x_phc *phc; @@ -107,6 +156,14 @@ int lan966x_ptp_hwtstamp_get(struct lan966x_port *port, struct ifreq *ifr) sizeof(phc->hwtstamp_config)) ? -EFAULT : 0; } +int lan966x_ptp_hwtstamp_get(struct lan966x_port *port, struct ifreq *ifr) +{ + if (!phy_has_hwtstamp(port->dev->phydev) && port->lan966x->ptp) + return lan966x_ptp_mac_hwtstamp_get(port, ifr); + + return phy_mii_ioctl(port->dev->phydev, ifr, SIOCGHWTSTAMP); +} + static int lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb) { struct ptp_header *header; @@ -182,8 +239,16 @@ int lan966x_ptp_txtstamp_request(struct lan966x_port *port, LAN966X_SKB_CB(skb)->jiffies = jiffies; lan966x->ptp_skbs++; - port->ts_id++; - if (port->ts_id == LAN966X_MAX_PTP_ID) + + /* If PHC is enabled, the subns part of the ID is not passed in the PCH + * header. So shift it by 2 to skip the subns part + */ + if (phy_inband_ext_enabled(port->dev->phydev, PHY_INBAND_EXT_PCH)) + port->ts_id = (((port->ts_id >> 2) + 1) << 2); + else + port->ts_id++; + + if (port->ts_id >= LAN966X_MAX_PTP_ID) port->ts_id = 0; spin_unlock_irqrestore(&lan966x->ptp_ts_id_lock, flags); @@ -285,6 +350,26 @@ irqreturn_t lan966x_ptp_irq_handler(int irq, void *args) /* Read RX timestamping to get the ID */ id = lan_rd(lan966x, PTP_TWOSTEP_STAMP); + /* If PCH is enabled, there is a "feature" that also the MAC + * will generate an interrupt for transmitted frames. This + * interrupt should be ignored, so clear the allocated resources + * and try to get the next timestamp. Maybe should clean the + * resources on the TX side? + */ + if (phy_inband_ext_enabled(port->dev->phydev, PHY_INBAND_EXT_PCH)) { + spin_lock(&lan966x->ptp_ts_id_lock); + lan966x->ptp_skbs--; + spin_unlock(&lan966x->ptp_ts_id_lock); + + dev_kfree_skb_any(skb_match); + + lan_rmw(PTP_TWOSTEP_CTRL_NXT_SET(1), + PTP_TWOSTEP_CTRL_NXT, + lan966x, PTP_TWOSTEP_CTRL); + + continue; + } + spin_lock_irqsave(&port->tx_skbs.lock, flags); skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) { if (LAN966X_SKB_CB(skb)->ts_id != id) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h index d4839e4b8ed5..e0d4364ee204 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h @@ -585,6 +585,27 @@ enum lan966x_target { #define DEV_PCS1G_STICKY_LINK_DOWN_STICKY_GET(x)\ FIELD_GET(DEV_PCS1G_STICKY_LINK_DOWN_STICKY, x) +/* DEV:MM_CONFIG:ENABLE_CONFIG */ +#define DEV_ENABLE_CONFIG(t) __REG(TARGET_DEV, t, 8, 156, 0, 1, 8, 0, 0, 1, 4) + +#define DEV_ENABLE_CONFIG_KEEP_S_AFTER_D BIT(8) +#define DEV_ENABLE_CONFIG_KEEP_S_AFTER_D_SET(x)\ + FIELD_PREP(DEV_ENABLE_CONFIG_KEEP_S_AFTER_D, x) +#define DEV_ENABLE_CONFIG_KEEP_S_AFTER_D_GET(x)\ + FIELD_GET(DEV_ENABLE_CONFIG_KEEP_S_AFTER_D, x) + +#define DEV_ENABLE_CONFIG_MM_TX_ENA BIT(4) +#define DEV_ENABLE_CONFIG_MM_TX_ENA_SET(x)\ + FIELD_PREP(DEV_ENABLE_CONFIG_MM_TX_ENA, x) +#define DEV_ENABLE_CONFIG_MM_TX_ENA_GET(x)\ + FIELD_GET(DEV_ENABLE_CONFIG_MM_TX_ENA, x) + +#define DEV_ENABLE_CONFIG_MM_RX_ENA BIT(0) +#define DEV_ENABLE_CONFIG_MM_RX_ENA_SET(x)\ + FIELD_PREP(DEV_ENABLE_CONFIG_MM_RX_ENA, x) +#define DEV_ENABLE_CONFIG_MM_RX_ENA_GET(x)\ + FIELD_GET(DEV_ENABLE_CONFIG_MM_RX_ENA, x) + /* FDMA:FDMA:FDMA_CH_ACTIVATE */ #define FDMA_CH_ACTIVATE __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 0, 0, 1, 4) @@ -792,6 +813,15 @@ enum lan966x_target { #define PTP_TWOSTEP_STAMP_STAMP_NSEC_GET(x)\ FIELD_GET(PTP_TWOSTEP_STAMP_STAMP_NSEC, x) +/* SYS:PTPPORT:PTP_MODE_CFG */ +#define SYS_PTP_MODE_CFG(g, r) __REG(TARGET_SYS, 0, 1, 4452, g, 10, 28, 20, r, 2, 4) + +#define SYS_PTP_MODE_CFG_PTP_MODE_VAL GENMASK(1, 0) +#define SYS_PTP_MODE_CFG_PTP_MODE_VAL_SET(x)\ + FIELD_PREP(SYS_PTP_MODE_CFG_PTP_MODE_VAL, x) +#define SYS_PTP_MODE_CFG_PTP_MODE_VAL_GET(x)\ + FIELD_GET(SYS_PTP_MODE_CFG_PTP_MODE_VAL, x) + /* DEVCPU_QS:XTR:XTR_GRP_CFG */ #define QS_XTR_GRP_CFG(r) __REG(TARGET_QS, 0, 1, 0, 0, 1, 36, 0, r, 2, 4) @@ -972,6 +1002,21 @@ enum lan966x_target { #define REW_PORT_CFG_NO_REWRITE_GET(x)\ FIELD_GET(REW_PORT_CFG_NO_REWRITE, x) +/* REW:PORT:PTP_MISC_CFG */ +#define REW_PTP_MISC_CFG(g) __REG(TARGET_REW, 0, 1, 0, g, 10, 128, 80, 0, 1, 4) + +#define REW_PTP_MISC_CFG_PTP_RSRV_MOVEBACK BIT(2) +#define REW_PTP_MISC_CFG_PTP_RSRV_MOVEBACK_SET(x)\ + FIELD_PREP(REW_PTP_MISC_CFG_PTP_RSRV_MOVEBACK, x) +#define REW_PTP_MISC_CFG_PTP_RSRV_MOVEBACK_GET(x)\ + FIELD_GET(REW_PTP_MISC_CFG_PTP_RSRV_MOVEBACK, x) + +#define REW_PTP_MISC_CFG_PTP_SIGNATURE_SEL GENMASK(1, 0) +#define REW_PTP_MISC_CFG_PTP_SIGNATURE_SEL_SET(x)\ + FIELD_PREP(REW_PTP_MISC_CFG_PTP_SIGNATURE_SEL, x) +#define REW_PTP_MISC_CFG_PTP_SIGNATURE_SEL_GET(x)\ + FIELD_GET(REW_PTP_MISC_CFG_PTP_SIGNATURE_SEL, x) + /* SYS:SYSTEM:RESET_CFG */ #define SYS_RESET_CFG __REG(TARGET_SYS, 0, 1, 4128, 0, 1, 168, 0, 0, 1, 4) @@ -1101,4 +1146,25 @@ enum lan966x_target { #define SYS_RAM_INIT_RAM_INIT_GET(x)\ FIELD_GET(SYS_RAM_INIT_RAM_INIT, x) +/* SYS:PTPPORT:PCH_CFG */ +#define SYS_PCH_CFG(g) __REG(TARGET_SYS, 0, 1, 4452, g, 10, 28, 0, 0, 1, 4) + +#define SYS_PCH_CFG_PCH_SUB_PORT_ID GENMASK(10, 7) +#define SYS_PCH_CFG_PCH_SUB_PORT_ID_SET(x)\ + FIELD_PREP(SYS_PCH_CFG_PCH_SUB_PORT_ID, x) +#define SYS_PCH_CFG_PCH_SUB_PORT_ID_GET(x)\ + FIELD_GET(SYS_PCH_CFG_PCH_SUB_PORT_ID, x) + +#define SYS_PCH_CFG_PCH_TX_MODE GENMASK(6, 5) +#define SYS_PCH_CFG_PCH_TX_MODE_SET(x)\ + FIELD_PREP(SYS_PCH_CFG_PCH_TX_MODE, x) +#define SYS_PCH_CFG_PCH_TX_MODE_GET(x)\ + FIELD_GET(SYS_MAC_FC_CFG_PAUSE_VAL_CFG, x) + +#define SYS_PCH_CFG_PCH_RX_MODE GENMASK(4, 2) +#define SYS_PCH_CFG_PCH_RX_MODE_SET(x)\ + FIELD_PREP(SYS_PCH_CFG_PCH_RX_MODE, x) +#define SYS_PCH_CFG_PCH_RX_MODE_GET(x)\ + FIELD_GET(SYS_PCH_CFG_PCH_RX_MODE, x) + #endif /* _LAN966X_REGS_H_ */ From patchwork Thu May 19 13:56:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 12855103 X-Patchwork-Delegate: kuba@kernel.org 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 7A7F9C433EF for ; Thu, 19 May 2022 13:57:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239376AbiESN5W (ORCPT ); Thu, 19 May 2022 09:57:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239175AbiESN5K (ORCPT ); Thu, 19 May 2022 09:57:10 -0400 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::221]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E9FB2BF4; Thu, 19 May 2022 06:57:07 -0700 (PDT) Received: (Authenticated sender: maxime.chevallier@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 71767240013; Thu, 19 May 2022 13:57:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1652968626; 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=e/Kd10AwKv2w3Q0mttVB1gl1+W1auqMdjySJEYCTO9o=; b=dyizHEMJHFYCCIPWTfmsbIgm6s+HL+xuND5A7ZvZtWqLtwVgFsgIqHuZ7oUxJajIKw85UR Z/wW1Nnr3b1fkgwjp17UPMJ5PGp/Z7HBX3IOlO1Tdc4kEYRxs92oeNCCbcQSRMsXXIq30R msUR/n19m080Ye0bygpUyYekyT+dUr2FwqfafTSplu4eLsWAE5edca+1yJZhApddYXq32a SJklsaSONInJjLdyC/t0UfZLHxQXAJqr1ck6S1c1tSNKutM9vvOwWY3VB5o8ZmWtBjsJ+Z lp3leL015Tj753cA9CFjQ+mkZhasBqRZOoQM8qTjFfUDbsKBKQpheAdBl93HAA== From: Maxime Chevallier To: davem@davemloft.net, Rob Herring Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Russell King , linux-arm-kernel@lists.infradead.org, Richard Cochran , Horatiu.Vultur@microchip.com, Allan.Nielsen@microchip.com, UNGLinuxDriver@microchip.com Subject: [PATCH net-next 6/6] net: phy: micrel: Add QUSGMII support and PCH extension Date: Thu, 19 May 2022 15:56:47 +0200 Message-Id: <20220519135647.465653-7-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220519135647.465653-1-maxime.chevallier@bootlin.com> References: <20220519135647.465653-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This commit adds support for the PCH extension in the Lan8814 PHY, allowing the PHY to report RX timestamps to the MAC in the ethernet preamble. When using the PCH extension, the PHY will only report the nanoseconds part of the timestamp in-band, and the seconds part out-of-band. The main goal in the end is to lower the pressure on the MDIO bus, which may get pushed to its limit on 48 ports switches doing PTP at a high rate. Signed-off-by: Maxime Chevallier --- drivers/net/phy/micrel.c | 102 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 6 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index f537e61cb61d..904b46701782 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -116,6 +116,10 @@ #define LTC_HARD_RESET 0x023F #define LTC_HARD_RESET_ BIT(0) +#define TSU_GENERAL_CONFIG 0x2C0 +#define TSU_GENERAL_CONFIG_TSU_ENABLE_ BIT(0) +#define TSU_GENERAL_CONFIG_TSU_ENABLE_PCH_ BIT(1) + #define TSU_HARD_RESET 0x02C1 #define TSU_HARD_RESET_ BIT(0) @@ -139,6 +143,7 @@ #define PTP_OPERATING_MODE 0x0241 #define PTP_OPERATING_MODE_STANDALONE_ BIT(0) +#define PTP_OPERATING_MODE_PCH_ BIT(1) #define PTP_TX_MOD 0x028F #define PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_ BIT(12) @@ -227,6 +232,15 @@ #define PS_TO_REG 200 #define FIFO_SIZE 8 +struct lan8814_skb_cb { + u8 rew_op; + u16 ts_id; + unsigned long jiffies; +}; + +#define LAN8814_SKB_CB(skb) \ + ((struct lan8814_skb_cb *)((skb)->cb)) + struct kszphy_hw_stat { const char *string; u8 reg; @@ -1809,6 +1823,16 @@ static void lan8814_ptp_rx_ts_get(struct phy_device *phydev, *seq_id = lanphy_read_page_reg(phydev, 5, PTP_RX_MSG_HEADER2); } +static void lan8814_ptp_rx_ts_get_partial(struct phy_device *phydev, + u32 *seconds, u16 *seq_id) +{ + *seconds = lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_SEC_HI); + *seconds = (*seconds << 16) | + lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_SEC_LO); + + *seq_id = lanphy_read_page_reg(phydev, 5, PTP_RX_MSG_HEADER2); +} + static void lan8814_ptp_tx_ts_get(struct phy_device *phydev, u32 *seconds, u32 *nano_seconds, u16 *seq_id) { @@ -1955,6 +1979,13 @@ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) lan8814_flush_fifo(ptp_priv->phydev, false); lan8814_flush_fifo(ptp_priv->phydev, true); + if (phydev->interface == PHY_INTERFACE_MODE_QUSGMII && + ptp_priv->hwts_tx_type == HWTSTAMP_TX_ON) + phy_inband_ext_set_available(phydev, PHY_INBAND_EXT_PCH, + PHY_INBAND_EXT_PCH); + else + phy_inband_ext_set_available(phydev, PHY_INBAND_EXT_PCH, 0); + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; } @@ -2283,11 +2314,17 @@ static int lan8814_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm) return 0; } -static void lan8814_get_sig_tx(struct sk_buff *skb, u16 *sig) +static void lan8814_get_sig_tx(struct phy_device *phydev, + struct sk_buff *skb, u16 *sig) { struct ptp_header *ptp_header; u32 type; + if (phy_inband_ext_enabled(phydev, PHY_INBAND_EXT_PCH)) { + *sig = LAN8814_SKB_CB(skb)->ts_id >> 2; + return; + } + type = ptp_classify_raw(skb); ptp_header = ptp_parse_header(skb, type); @@ -2309,7 +2346,7 @@ static void lan8814_dequeue_tx_skb(struct kszphy_ptp_priv *ptp_priv) spin_lock_irqsave(&ptp_priv->tx_queue.lock, flags); skb_queue_walk_safe(&ptp_priv->tx_queue, skb, skb_tmp) { - lan8814_get_sig_tx(skb, &skb_sig); + lan8814_get_sig_tx(phydev, skb, &skb_sig); if (memcmp(&skb_sig, &seq_id, sizeof(seq_id))) continue; @@ -2367,8 +2404,20 @@ static bool lan8814_match_skb(struct kszphy_ptp_priv *ptp_priv, if (ret) { shhwtstamps = skb_hwtstamps(skb); - memset(shhwtstamps, 0, sizeof(*shhwtstamps)); - shhwtstamps->hwtstamp = ktime_set(rx_ts->seconds, rx_ts->nsec); + + if (phy_inband_ext_enabled(ptp_priv->phydev, PHY_INBAND_EXT_PCH)) { + /* When using the PCH extension, we get the seconds part + * from MDIO accesses, but the seconds part gets + * set by the MAC driver according to the PCH data in the + * preamble + */ + struct timespec64 ts = ktime_to_timespec64(shhwtstamps->hwtstamp); + + shhwtstamps->hwtstamp = ktime_set(rx_ts->seconds, ts.tv_nsec); + } else { + memset(shhwtstamps, 0, sizeof(*shhwtstamps)); + shhwtstamps->hwtstamp = ktime_set(rx_ts->seconds, rx_ts->nsec); + } netif_rx(skb); } @@ -2387,8 +2436,17 @@ static void lan8814_get_rx_ts(struct kszphy_ptp_priv *ptp_priv) if (!rx_ts) return; - lan8814_ptp_rx_ts_get(phydev, &rx_ts->seconds, &rx_ts->nsec, - &rx_ts->seq_id); + /* When using PCH mode, the nanoseconds part of the timestamp is + * transmitted inband through the ethernet preamble. We only need + * to retrieve the seconds part along with the seq_id, the MAC + * driver will fill-in the nanoseconds part itself + */ + if (phy_inband_ext_enabled(ptp_priv->phydev, PHY_INBAND_EXT_PCH)) + lan8814_ptp_rx_ts_get_partial(phydev, &rx_ts->seconds, + &rx_ts->seq_id); + else + lan8814_ptp_rx_ts_get(phydev, &rx_ts->seconds, + &rx_ts->nsec, &rx_ts->seq_id); /* If we failed to match the skb add it to the queue for when * the frame will come @@ -2682,6 +2740,36 @@ static int lan8814_set_tunable(struct phy_device *phydev, } } +static int lan8814_inband_ext_config(struct phy_device *phydev, u32 mask, u32 ext) +{ + u32 tsu_cfg; + + if (!(mask & PHY_INBAND_EXT_PCH)) + return -EOPNOTSUPP; + + tsu_cfg = ~TSU_GENERAL_CONFIG_TSU_ENABLE_; + + lanphy_write_page_reg(phydev, 5, TSU_GENERAL_CONFIG, tsu_cfg); + + if (ext & PHY_INBAND_EXT_PCH) { + lanphy_write_page_reg(phydev, 4, PTP_OPERATING_MODE, + PTP_OPERATING_MODE_PCH_); + + tsu_cfg |= TSU_GENERAL_CONFIG_TSU_ENABLE_PCH_; + } else { + lanphy_write_page_reg(phydev, 4, PTP_OPERATING_MODE, + PTP_OPERATING_MODE_STANDALONE_); + + tsu_cfg &= ~TSU_GENERAL_CONFIG_TSU_ENABLE_PCH_; + } + + tsu_cfg |= TSU_GENERAL_CONFIG_TSU_ENABLE_; + + lanphy_write_page_reg(phydev, 5, TSU_GENERAL_CONFIG, tsu_cfg); + + return 0; +} + static int lan8814_config_init(struct phy_device *phydev) { int val; @@ -2914,6 +3002,7 @@ static struct phy_driver ksphy_driver[] = { .phy_id = PHY_ID_LAN8814, .phy_id_mask = MICREL_PHY_ID_MASK, .name = "Microchip INDY Gigabit Quad PHY", + .inband_ext = PHY_INBAND_EXT_PCH, .config_init = lan8814_config_init, .probe = lan8814_probe, .soft_reset = genphy_soft_reset, @@ -2927,6 +3016,7 @@ static struct phy_driver ksphy_driver[] = { .resume = kszphy_resume, .config_intr = lan8814_config_intr, .handle_interrupt = lan8814_handle_interrupt, + .inband_ext_config = lan8814_inband_ext_config, }, { .phy_id = PHY_ID_LAN8804, .phy_id_mask = MICREL_PHY_ID_MASK,