netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/6] net: Introduce Ethernet Inband Extensions
@ 2022-05-19 13:56 Maxime Chevallier
  2022-05-19 13:56 ` [PATCH net-next 1/6] net: phy: Introduce QUSGMII PHY mode Maxime Chevallier
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Maxime Chevallier @ 2022-05-19 13:56 UTC (permalink / raw)
  To: davem, Rob Herring
  Cc: Maxime Chevallier, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
	Russell King, linux-arm-kernel, Richard Cochran, Horatiu.Vultur,
	Allan.Nielsen, UNGLinuxDriver

Hello everyone,

This series introduces support for Ethernet in-band extensions, a
mechanism proposed by Cisco as part of the USXGMII spec.

The idea is to leverage the 7 bytes preamble to convey meaningful data,
in what's called an "extension".

This series adds the QUSGMII mode, which is a quad variant of the
USXGMII standard, and adds its support in the lan966x driver. In
QUSGMII, extensions can be used.

The only extension support thus far is the PCH mode, a way to convey
part of a timestamp into the ethernet preamble. That's a pretty
straightfoward extension, documented in the Cisco spec. Other extensions
can exist, each being identified by a 2 bits code in the preamble,
parsed by the hardware.

We therefore need an API to synchronise which mode is supported by a
given PHY, then a way to enable it in the PHY, from the MAC's control.

This is done through a new phy_driver callback, .inband_ext_config(),
that the MAC driver will call to ask a PHY driver to enable a given
extension.

The PCH mode that is added in this series is used to offload a bit
the MDIO bus when doing PHY-side timestamping, by conveying the nanoseconds
part of the timestamp into the preamble. The MAC driver then extracts
the timestamp (using lan966x's IFH mechanism), puts the nanosecond part
in the SKB. The RX deferred timestamping then asks the PHY for the rest
of the timestamp.

Other modes exists, such as Microchip's MCH mode, but this series only
include PCH since it's simple enough and keeps the code reviewable.

Thanks,

Maxime

Maxime Chevallier (6):
  net: phy: Introduce QUSGMII PHY mode
  dt-bindings: net: ethernet-controller: add QUSGMII mode
  net: lan966x: Add QUSGMII support for lan966x
  net: phy: Add support for inband extensions
  net: lan966x: Allow using PCH extension for PTP
  net: phy: micrel: Add QUSGMII support and PCH extension

 .../bindings/net/ethernet-controller.yaml     |   1 +
 Documentation/networking/phy.rst              |   9 ++
 .../ethernet/microchip/lan966x/lan966x_main.c |  14 +--
 .../ethernet/microchip/lan966x/lan966x_main.h |   6 ++
 .../microchip/lan966x/lan966x_phylink.c       |   9 +-
 .../ethernet/microchip/lan966x/lan966x_port.c |  33 ++++--
 .../ethernet/microchip/lan966x/lan966x_ptp.c  |  93 +++++++++++++++-
 .../ethernet/microchip/lan966x/lan966x_regs.h |  72 +++++++++++++
 drivers/net/phy/micrel.c                      | 102 ++++++++++++++++--
 drivers/net/phy/phy.c                         |  68 ++++++++++++
 drivers/net/phy/phylink.c                     |   3 +
 include/linux/phy.h                           |  28 ++++-
 12 files changed, 413 insertions(+), 25 deletions(-)

-- 
2.36.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH net-next 1/6] net: phy: Introduce QUSGMII PHY mode
  2022-05-19 13:56 [PATCH net-next 0/6] net: Introduce Ethernet Inband Extensions Maxime Chevallier
@ 2022-05-19 13:56 ` Maxime Chevallier
  2022-05-19 13:56 ` [PATCH net-next 2/6] dt-bindings: net: ethernet-controller: add QUSGMII mode Maxime Chevallier
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Maxime Chevallier @ 2022-05-19 13:56 UTC (permalink / raw)
  To: davem, Rob Herring
  Cc: Maxime Chevallier, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
	Russell King, linux-arm-kernel, Richard Cochran, Horatiu.Vultur,
	Allan.Nielsen, UNGLinuxDriver

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 <maxime.chevallier@bootlin.com>
---
 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";
 	}
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 2/6] dt-bindings: net: ethernet-controller: add QUSGMII mode
  2022-05-19 13:56 [PATCH net-next 0/6] net: Introduce Ethernet Inband Extensions Maxime Chevallier
  2022-05-19 13:56 ` [PATCH net-next 1/6] net: phy: Introduce QUSGMII PHY mode Maxime Chevallier
@ 2022-05-19 13:56 ` Maxime Chevallier
  2022-06-01 21:10   ` Rob Herring
  2022-05-19 13:56 ` [PATCH net-next 3/6] net: lan966x: Add QUSGMII support for lan966x Maxime Chevallier
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Maxime Chevallier @ 2022-05-19 13:56 UTC (permalink / raw)
  To: davem, Rob Herring
  Cc: Maxime Chevallier, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
	Russell King, linux-arm-kernel, Richard Cochran, Horatiu.Vultur,
	Allan.Nielsen, UNGLinuxDriver

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 <maxime.chevallier@bootlin.com>
---
 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
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 3/6] net: lan966x: Add QUSGMII support for lan966x
  2022-05-19 13:56 [PATCH net-next 0/6] net: Introduce Ethernet Inband Extensions Maxime Chevallier
  2022-05-19 13:56 ` [PATCH net-next 1/6] net: phy: Introduce QUSGMII PHY mode Maxime Chevallier
  2022-05-19 13:56 ` [PATCH net-next 2/6] dt-bindings: net: ethernet-controller: add QUSGMII mode Maxime Chevallier
@ 2022-05-19 13:56 ` Maxime Chevallier
  2022-05-19 14:26   ` Russell King (Oracle)
  2022-05-19 13:56 ` [PATCH net-next 4/6] net: phy: Add support for inband extensions Maxime Chevallier
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Maxime Chevallier @ 2022-05-19 13:56 UTC (permalink / raw)
  To: davem, Rob Herring
  Cc: Maxime Chevallier, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
	Russell King, linux-arm-kernel, Richard Cochran, Horatiu.Vultur,
	Allan.Nielsen, UNGLinuxDriver

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 <maxime.chevallier@bootlin.com>
---
 .../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)
 
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 4/6] net: phy: Add support for inband extensions
  2022-05-19 13:56 [PATCH net-next 0/6] net: Introduce Ethernet Inband Extensions Maxime Chevallier
                   ` (2 preceding siblings ...)
  2022-05-19 13:56 ` [PATCH net-next 3/6] net: lan966x: Add QUSGMII support for lan966x Maxime Chevallier
@ 2022-05-19 13:56 ` Maxime Chevallier
  2022-05-19 14:10   ` Andrew Lunn
  2022-05-19 14:28   ` Andrew Lunn
  2022-05-19 13:56 ` [PATCH net-next 5/6] net: lan966x: Allow using PCH extension for PTP Maxime Chevallier
  2022-05-19 13:56 ` [PATCH net-next 6/6] net: phy: micrel: Add QUSGMII support and PCH extension Maxime Chevallier
  5 siblings, 2 replies; 12+ messages in thread
From: Maxime Chevallier @ 2022-05-19 13:56 UTC (permalink / raw)
  To: davem, Rob Herring
  Cc: Maxime Chevallier, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
	Russell King, linux-arm-kernel, Richard Cochran, Horatiu.Vultur,
	Allan.Nielsen, UNGLinuxDriver

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 <maxime.chevallier@bootlin.com>
---
 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)
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 5/6] net: lan966x: Allow using PCH extension for PTP
  2022-05-19 13:56 [PATCH net-next 0/6] net: Introduce Ethernet Inband Extensions Maxime Chevallier
                   ` (3 preceding siblings ...)
  2022-05-19 13:56 ` [PATCH net-next 4/6] net: phy: Add support for inband extensions Maxime Chevallier
@ 2022-05-19 13:56 ` Maxime Chevallier
  2022-05-19 13:56 ` [PATCH net-next 6/6] net: phy: micrel: Add QUSGMII support and PCH extension Maxime Chevallier
  5 siblings, 0 replies; 12+ messages in thread
From: Maxime Chevallier @ 2022-05-19 13:56 UTC (permalink / raw)
  To: davem, Rob Herring
  Cc: Maxime Chevallier, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
	Russell King, linux-arm-kernel, Richard Cochran, Horatiu.Vultur,
	Allan.Nielsen, UNGLinuxDriver

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 <maxime.chevallier@bootlin.com>
---
 .../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_ */
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 6/6] net: phy: micrel: Add QUSGMII support and PCH extension
  2022-05-19 13:56 [PATCH net-next 0/6] net: Introduce Ethernet Inband Extensions Maxime Chevallier
                   ` (4 preceding siblings ...)
  2022-05-19 13:56 ` [PATCH net-next 5/6] net: lan966x: Allow using PCH extension for PTP Maxime Chevallier
@ 2022-05-19 13:56 ` Maxime Chevallier
  5 siblings, 0 replies; 12+ messages in thread
From: Maxime Chevallier @ 2022-05-19 13:56 UTC (permalink / raw)
  To: davem, Rob Herring
  Cc: Maxime Chevallier, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
	Russell King, linux-arm-kernel, Richard Cochran, Horatiu.Vultur,
	Allan.Nielsen, UNGLinuxDriver

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 <maxime.chevallier@bootlin.com>
---
 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,
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 4/6] net: phy: Add support for inband extensions
  2022-05-19 13:56 ` [PATCH net-next 4/6] net: phy: Add support for inband extensions Maxime Chevallier
@ 2022-05-19 14:10   ` Andrew Lunn
  2022-05-19 14:28   ` Andrew Lunn
  1 sibling, 0 replies; 12+ messages in thread
From: Andrew Lunn @ 2022-05-19 14:10 UTC (permalink / raw)
  To: Maxime Chevallier
  Cc: davem, Rob Herring, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Florian Fainelli, Heiner Kallweit,
	Russell King, linux-arm-kernel, Richard Cochran, Horatiu.Vultur,
	Allan.Nielsen, UNGLinuxDriver

> +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);

You appear to be missing locking in this patchset.

> +int phy_inband_ext_enable(struct phy_device *phydev, u32 ext)
> +{
> +	return phy_set_inband_ext(phydev, ext, ext);

There should be an -EOPNOTSUPP here is requested to enable an
extension which is not available.

> +}
> +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);

And the same here.

> +}
> +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)

the documentation is important here, since it makes it clear if these
are values directly taken from the specification, or if these are
linux specific, and the driver needs to map from linux to whatever the
spec calls them.

     Andrew

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 3/6] net: lan966x: Add QUSGMII support for lan966x
  2022-05-19 13:56 ` [PATCH net-next 3/6] net: lan966x: Add QUSGMII support for lan966x Maxime Chevallier
@ 2022-05-19 14:26   ` Russell King (Oracle)
  2022-07-27 13:48     ` Maxime Chevallier
  0 siblings, 1 reply; 12+ messages in thread
From: Russell King (Oracle) @ 2022-05-19 14:26 UTC (permalink / raw)
  To: Maxime Chevallier
  Cc: davem, Rob Herring, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
	linux-arm-kernel, Richard Cochran, Horatiu.Vultur, Allan.Nielsen,
	UNGLinuxDriver

Hi,

On Thu, May 19, 2022 at 03:56:44PM +0200, Maxime Chevallier wrote:
> 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);
> +}

Maybe linux/phy.h should provide a helper, something like:

	phy_interface_serdes_lanes()

that returns how many serdes lanes the interface mode uses?

> 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);

I don't think that the ethernet MAC driver should be changing the
interface mode before passing it down to the generic PHY layer -
phy_set_mode_ext() is defined to take the phy interface mode, and any
aliasing of modes should really be up to the generic PHY driver not
the ethernet MAC driver.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 4/6] net: phy: Add support for inband extensions
  2022-05-19 13:56 ` [PATCH net-next 4/6] net: phy: Add support for inband extensions Maxime Chevallier
  2022-05-19 14:10   ` Andrew Lunn
@ 2022-05-19 14:28   ` Andrew Lunn
  1 sibling, 0 replies; 12+ messages in thread
From: Andrew Lunn @ 2022-05-19 14:28 UTC (permalink / raw)
  To: Maxime Chevallier
  Cc: davem, Rob Herring, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Florian Fainelli, Heiner Kallweit,
	Russell King, linux-arm-kernel, Richard Cochran, Horatiu.Vultur,
	Allan.Nielsen, UNGLinuxDriver

> +static int phy_set_inband_ext(struct phy_device *phydev, u32 mask, u32 ext)
> +{

> +/*
> + * TODO : Doc
> + */
> +enum {
> +	__PHY_INBAND_EXT_PCH = 0,
> +};

I'm not so happy with this API passing masks and values, when you are
actually dealing with a feature which is a boolean, exists, does not
exist.

> +int phy_inband_ext_enable(struct phy_device *phydev, u32 ext);
> +int phy_inband_ext_disable(struct phy_device *phydev, u32 ext);

I would prefer enum phy_inband_ext ext;

phy_inband_ext_set_available(struct phy_device *phydev, enum phy_inband_ext ext);

and add

phy_inband_ext_set_unavailable(struct phy_device *phydev, enum phy_inband_ext ext);

Internally you can then turn these into operations on a u32.

	   Andrew

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 2/6] dt-bindings: net: ethernet-controller: add QUSGMII mode
  2022-05-19 13:56 ` [PATCH net-next 2/6] dt-bindings: net: ethernet-controller: add QUSGMII mode Maxime Chevallier
@ 2022-06-01 21:10   ` Rob Herring
  0 siblings, 0 replies; 12+ messages in thread
From: Rob Herring @ 2022-06-01 21:10 UTC (permalink / raw)
  To: Maxime Chevallier
  Cc: Allan.Nielsen, thomas.petazzoni, Russell King, linux-arm-kernel,
	Andrew Lunn, devicetree, netdev, Florian Fainelli,
	Heiner Kallweit, Rob Herring, Horatiu.Vultur, Richard Cochran,
	linux-kernel, davem, UNGLinuxDriver

On Thu, 19 May 2022 15:56:43 +0200, Maxime Chevallier wrote:
> 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 <maxime.chevallier@bootlin.com>
> ---
>  Documentation/devicetree/bindings/net/ethernet-controller.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 3/6] net: lan966x: Add QUSGMII support for lan966x
  2022-05-19 14:26   ` Russell King (Oracle)
@ 2022-07-27 13:48     ` Maxime Chevallier
  0 siblings, 0 replies; 12+ messages in thread
From: Maxime Chevallier @ 2022-07-27 13:48 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: davem, Rob Herring, netdev, linux-kernel, devicetree,
	thomas.petazzoni, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
	linux-arm-kernel, Richard Cochran, Horatiu.Vultur, Allan.Nielsen,
	UNGLinuxDriver

Hello Russell,

On Thu, 19 May 2022 15:26:23 +0100
"Russell King (Oracle)" <linux@armlinux.org.uk> wrote:

> Hi,
> 
> On Thu, May 19, 2022 at 03:56:44PM +0200, Maxime Chevallier wrote:
> > 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);
> > +}  
>
> Maybe linux/phy.h should provide a helper, something like:
> 
> 	phy_interface_serdes_lanes()
> 
> that returns how many serdes lanes the interface mode uses?

Sorry about the delayed answer, I was resuming the work on this, and
realised that although a helper would be indeed great, especially for
generic PHY drivers, it won't help much in this case since
QSGMII/QUSGMII both use 1 serdes lane, as SGMII and such. If I'm not
mistaken, QSGMII is SGMII clocked at 5Gbps with a specific preamble
allowing to identify the src/dst port.

We could however imagine a helper identifying the number of links, or
lanes (or another terminology) that is carried by a given mode. I know
that besides QSGMII for 4 ports, there exists PSGMII for 5 ports, and
OSGMII for 8 ports, so this would definitely prove useful in the
future.

Sorry if this ends-up being a misunderstanding on the terminology,
we're probably already talking about the same thing, but I think that
"serdes lane" would better describe the number of physical differential
pairs that creates the link (like, 1 for SGMII, 2 for RXAUI, 4 for XAUI
and so on).

maybe something like

	phy_interface_lines() or
	phy_interface_num_ports() or simply
	phy_interface_lanes()

> > 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);  
> 
> I don't think that the ethernet MAC driver should be changing the
> interface mode before passing it down to the generic PHY layer -
> phy_set_mode_ext() is defined to take the phy interface mode, and any
> aliasing of modes should really be up to the generic PHY driver not
> the ethernet MAC driver.

Indeed, I'll split the series so that we first add support for the new
mode, and then send separate series for the generic PHY driver on one
side, and inband extensions on the other one.

Thanks,

Maxime

> Thanks.
> 


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-07-27 13:48 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-19 13:56 [PATCH net-next 0/6] net: Introduce Ethernet Inband Extensions Maxime Chevallier
2022-05-19 13:56 ` [PATCH net-next 1/6] net: phy: Introduce QUSGMII PHY mode Maxime Chevallier
2022-05-19 13:56 ` [PATCH net-next 2/6] dt-bindings: net: ethernet-controller: add QUSGMII mode Maxime Chevallier
2022-06-01 21:10   ` Rob Herring
2022-05-19 13:56 ` [PATCH net-next 3/6] net: lan966x: Add QUSGMII support for lan966x Maxime Chevallier
2022-05-19 14:26   ` Russell King (Oracle)
2022-07-27 13:48     ` Maxime Chevallier
2022-05-19 13:56 ` [PATCH net-next 4/6] net: phy: Add support for inband extensions Maxime Chevallier
2022-05-19 14:10   ` Andrew Lunn
2022-05-19 14:28   ` Andrew Lunn
2022-05-19 13:56 ` [PATCH net-next 5/6] net: lan966x: Allow using PCH extension for PTP Maxime Chevallier
2022-05-19 13:56 ` [PATCH net-next 6/6] net: phy: micrel: Add QUSGMII support and PCH extension Maxime Chevallier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).