linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/9] net: ethernet backplane support on DPAA1
@ 2020-06-22 13:35 Florinel Iordache
  2020-06-22 13:35 ` [PATCH net-next v3 1/7] doc: net: add backplane documentation Florinel Iordache
                   ` (6 more replies)
  0 siblings, 7 replies; 24+ messages in thread
From: Florinel Iordache @ 2020-06-22 13:35 UTC (permalink / raw)
  To: davem, netdev, andrew, f.fainelli, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, leoyang.li, madalin.bucur, ioana.ciornei, linux-kernel,
	Florinel Iordache

Add support for Ethernet Backplane KR driver only on DPAA1 devices.
Ethernet Backplane KR generic driver is using link training
(ieee802.3ap/ba standards), equalization algorithms (bee, fixed) and
enable qoriq family of devices.
This driver is dependent on uboot Backplane KR support:
patchwork.ozlabs.org/project/uboot/list/?series=164627&state=*

v3 changes:
* The entire DPAA2 support was removed as well as phylink changes.
This patchset contains only DPAA1 support for KR.
* DPAA2 support will be added after we find a suitable solution
for PCS representation.
* All the changes made in v2 that addressed all the feedback not
related to PCS representation, are kept in v3 as well.

Florinel Iordache (7):
  doc: net: add backplane documentation
  dt-bindings: net: add backplane dt bindings
  net: fman: add kr support for dpaa1 mac
  net: phy: add backplane kr driver support
  net: phy: enable qoriq backplane support
  net: phy: add bee algorithm for kr training
  arm64: dts: add serdes and mdio description

 .../bindings/net/ethernet-controller.yaml          |    7 +-
 .../devicetree/bindings/net/ethernet-phy.yaml      |   50 +
 .../devicetree/bindings/net/serdes-lane.yaml       |   49 +
 Documentation/devicetree/bindings/net/serdes.yaml  |   42 +
 Documentation/networking/backplane.rst             |  159 ++
 Documentation/networking/phy.rst                   |    9 +-
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi     |   33 +-
 .../boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi    |    5 +-
 .../boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi    |    5 +-
 drivers/net/ethernet/freescale/fman/mac.c          |   10 +-
 drivers/net/phy/Kconfig                            |    2 +
 drivers/net/phy/Makefile                           |    1 +
 drivers/net/phy/backplane/Kconfig                  |   40 +
 drivers/net/phy/backplane/Makefile                 |   12 +
 drivers/net/phy/backplane/backplane.c              | 1557 ++++++++++++++++++++
 drivers/net/phy/backplane/backplane.h              |  293 ++++
 drivers/net/phy/backplane/eq_bee.c                 | 1076 ++++++++++++++
 drivers/net/phy/backplane/eq_fixed.c               |   83 ++
 drivers/net/phy/backplane/equalization.h           |  275 ++++
 drivers/net/phy/backplane/link_training.c          | 1529 +++++++++++++++++++
 drivers/net/phy/backplane/link_training.h          |   32 +
 drivers/net/phy/backplane/qoriq_backplane.c        |  473 ++++++
 drivers/net/phy/backplane/qoriq_backplane.h        |   42 +
 drivers/net/phy/backplane/qoriq_serdes_10g.c       |  486 ++++++
 24 files changed, 6258 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/serdes-lane.yaml
 create mode 100644 Documentation/devicetree/bindings/net/serdes.yaml
 create mode 100644 Documentation/networking/backplane.rst
 create mode 100644 drivers/net/phy/backplane/Kconfig
 create mode 100644 drivers/net/phy/backplane/Makefile
 create mode 100644 drivers/net/phy/backplane/backplane.c
 create mode 100644 drivers/net/phy/backplane/backplane.h
 create mode 100644 drivers/net/phy/backplane/eq_bee.c
 create mode 100644 drivers/net/phy/backplane/eq_fixed.c
 create mode 100644 drivers/net/phy/backplane/equalization.h
 create mode 100644 drivers/net/phy/backplane/link_training.c
 create mode 100644 drivers/net/phy/backplane/link_training.h
 create mode 100644 drivers/net/phy/backplane/qoriq_backplane.c
 create mode 100644 drivers/net/phy/backplane/qoriq_backplane.h
 create mode 100644 drivers/net/phy/backplane/qoriq_serdes_10g.c

-- 
1.9.1


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

* [PATCH net-next v3 1/7] doc: net: add backplane documentation
  2020-06-22 13:35 [PATCH net-next v2 0/9] net: ethernet backplane support on DPAA1 Florinel Iordache
@ 2020-06-22 13:35 ` Florinel Iordache
  2020-06-22 13:35 ` [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt bindings Florinel Iordache
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 24+ messages in thread
From: Florinel Iordache @ 2020-06-22 13:35 UTC (permalink / raw)
  To: davem, netdev, andrew, f.fainelli, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, leoyang.li, madalin.bucur, ioana.ciornei, linux-kernel,
	Florinel Iordache

Add ethernet backplane documentation

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 Documentation/networking/backplane.rst | 159 +++++++++++++++++++++++++++++++++
 Documentation/networking/phy.rst       |   9 +-
 2 files changed, 165 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/networking/backplane.rst

diff --git a/Documentation/networking/backplane.rst b/Documentation/networking/backplane.rst
new file mode 100644
index 0000000..fb91ba8
--- /dev/null
+++ b/Documentation/networking/backplane.rst
@@ -0,0 +1,159 @@
+.. SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+
+=========================
+Ethernet Backplane Driver
+=========================
+
+Author:
+Florinel Iordache <florinel.iordache@nxp.com>
+
+Contents
+========
+
+	- Ethernet Backplane Overview
+	- Equalization
+	- Auto-negotiation
+	- Link training
+	- Enable backplane support in Linux kernel
+	- Ethernet Backplane support architecture
+	- Supported equalization algorithms
+	- Supported backplane protocols
+	- Supported platforms
+
+Ethernet Backplane Overview
+===========================
+
+Ethernet operation over electrical backplanes, also referred to as Ethernet
+Backplane, combines the IEEE 802.3 Media Access Control (MAC) and MAC
+Control sublayers with a family of Physical Layers defined to support
+operation over a modular chassis backplane.
+The main standard specification for Ethernet Backplane is: IEEE802.3ap-2007
+Amendment 4: Ethernet Operation over Electrical Backplanes
+which includes the new Clause 69 through Clause 74.
+Additional specifications define support for various speeds and 4-lanes:
+IEEE802.3ba-2010.
+Signal equalization is required based on the link quality. The standard
+specifies that a start-up algorithm should be in place in order to get the
+link up.
+
+Equalization
+============
+
+Equalization represents the procedure required to minimize the effects of signal
+distortion, noise, interference occurred in high-speed communication channels.
+The equalizer purpose is to improve signal integrity in terms of bit error rate
+(BER) in order to allow accurate recovery of the transmitted symbols.
+
+A simplified view of channel equalization:
+
+            LD       <======== channel =========>      LP
+       Local Device                                Link Partner
+
+         |-----|                                         ___
+         |     |     <======== channel =========>       /   |
+         |     |      witout signal Equalization       /     \
+         |     |                                      /      |
+     ____|     |____                              ___/        \___
+
+         |\   _                                        |-----|
+         | \_/ |     <======== channel =========>      |     |
+         |     |       with signal Equalization        |     |
+         |     |                                       |     |
+     ____|     |____                               ____|     |____
+
+      LD Tx waveform                                LP Rx waveform
+
+Auto-negotiation
+================
+
+Auto-negotiation allows the devices at both ends of a link segment to advertise
+abilities, acknowledge receipt, and discover the common modes of operation that
+both devices share. It also rejects the use of operational modes not shared by
+both devices. Auto-negotiation does not test link segment characteristics.
+
+Link training
+=============
+
+Link training occurs after auto-negotiation has determined the link to be a
+Base-KR, but before auto-negotiation is done. It continuously exchanges messages
+(training frames) between the local and the remote device as part of the
+start-up phase. Link training tunes the equalization parameters of the remote and
+local transmitter to improve the link quality in terms of bit error rate.
+Both LP (link partner/remote device) and LD (local device) perform link training
+in parallel. Link training is finished when both sides decide that the channel is
+equalized and then the link is considered up.
+
+Enable backplane support in Linux kernel
+========================================
+
+To enable the Ethernet Backplane, the following Kconfig options are available:
+
+# enable generic Ethernet Backplane support:
+CONFIG_ETH_BACKPLANE=y
+# enable Fixed (No Equalization) algorithm:
+CONFIG_ETH_BACKPLANE_FIXED=y
+# enable 3-Taps Bit Edge Equalization (BEE) algorithm:
+CONFIG_ETH_BACKPLANE_BEE=y
+# enable QorIQ Ethernet Backplane driver:
+CONFIG_ETH_BACKPLANE_QORIQ=y
+
+Ethernet Backplane support architecture
+=======================================
+
+Ethernet Backplane support in Linux kernel complies with the following standard
+design concepts:
+* Modularity:
+    # internal components are separated in well defined functional modules
+* Reusability:
+    # lower layer components provide basic functionalities which are reused by
+    the upper layer modules
+* Extensibility:
+    # architecture can be easily extended with support for new:
+    	- backplane protocols
+    	- equalization algorithms
+    	- supported devices
+It is designed as a loosely coupled architecture in order to allow the
+possibility to easily create desired backplane system configurations according
+to user needs by specifying different components and initialization parameters
+without recompiling the kernel.
+
+       ------------------            ------------------------------------
+       |  EQ Algorithms |            |    Specific device drivers       |
+       |  ------------  |            |       Backplane support          |
+       |  |  Fixed   |  |            | ------------------   ----------- |
+       |  ------------  |            | |     QorIQ      |   |         | |
+       |  |   BEE    |  |            | |    devices     |   |         | |
+       |  ------------  |            | | -------------- |   |  other  | |
+       |  |  others  |  |            | | | Serdes 10G | |   | devices | |
+  ----------------------------       | | -------------- |   | support | |
+  |      Link Training       |       | | | Serdes 28G | |   |         | |
+  |   and Auto-negotiation   |       | | -------------- |   |         | |
+  |    (IEEE 802.3-ap/ba)    |       | |----------------|   |---------| |
+  ---------------------------------------------------------------------------
+  |                   Ethernet Backplane Generic Driver                     |
+  ---------------------------------------------------------------------------
+  |                         PHY Abstraction Layer                           |
+  ---------------------------------------------------------------------------
+
+Supported equalization algorithms
+=================================
+
+Ethernet Backplane supports the following equalization algorithms:
+
+- Fixed setup (No Equalization algorithm)
+- 3-Taps Bit Edge Equalization (BEE) algorithm
+
+Supported backplane protocols
+=============================
+
+Ethernet Backplane supports the following protocols:
+
+- Single-lane:
+10GBase-KR
+
+Supported platforms
+===================
+
+Ethernet Backplane is enabled on the following platforms:
+
+LS1046A
diff --git a/Documentation/networking/phy.rst b/Documentation/networking/phy.rst
index 2561060..ec17c31 100644
--- a/Documentation/networking/phy.rst
+++ b/Documentation/networking/phy.rst
@@ -279,9 +279,12 @@ Some of the interface modes are described below:
     XFI and SFI are not PHY interface types in their own right.
 
 ``PHY_INTERFACE_MODE_10GKR``
-    This is the IEEE 802.3 Clause 49 defined 10GBASE-R with Clause 73
-    autonegotiation. Please refer to the IEEE standard for further
-    information.
+    This is 10G Ethernet Backplane over single lane specified in
+    IEEE802.3ap-2007 Amendment 4: Ethernet Operation over Electrical
+    Backplanes which includes the new Clause 69 through Clause 74
+    including autonegotiation. 10GKR uses the same physical layer
+    encoding as 10GBASE-R defined in IEEE802.3 Clause 49. Please refer
+    to the IEEE standard for further information.
 
     Note: due to legacy usage, some 10GBASE-R usage incorrectly makes
     use of this definition.
-- 
1.9.1


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

* [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt bindings
  2020-06-22 13:35 [PATCH net-next v2 0/9] net: ethernet backplane support on DPAA1 Florinel Iordache
  2020-06-22 13:35 ` [PATCH net-next v3 1/7] doc: net: add backplane documentation Florinel Iordache
@ 2020-06-22 13:35 ` Florinel Iordache
  2020-06-22 22:20   ` Florian Fainelli
  2020-06-29 21:58   ` Rob Herring
  2020-06-22 13:35 ` [PATCH net-next v3 3/7] net: fman: add kr support for dpaa1 mac Florinel Iordache
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 24+ messages in thread
From: Florinel Iordache @ 2020-06-22 13:35 UTC (permalink / raw)
  To: davem, netdev, andrew, f.fainelli, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, leoyang.li, madalin.bucur, ioana.ciornei, linux-kernel,
	Florinel Iordache

Add ethernet backplane device tree bindings

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 .../bindings/net/ethernet-controller.yaml          |  7 ++-
 .../devicetree/bindings/net/ethernet-phy.yaml      | 50 ++++++++++++++++++++++
 .../devicetree/bindings/net/serdes-lane.yaml       | 49 +++++++++++++++++++++
 Documentation/devicetree/bindings/net/serdes.yaml  | 42 ++++++++++++++++++
 4 files changed, 146 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/serdes-lane.yaml
 create mode 100644 Documentation/devicetree/bindings/net/serdes.yaml

diff --git a/Documentation/devicetree/bindings/net/ethernet-controller.yaml b/Documentation/devicetree/bindings/net/ethernet-controller.yaml
index 1c44740..6c4c7d8 100644
--- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml
+++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml
@@ -91,10 +91,13 @@ properties:
       - rxaui
       - xaui
 
-      # 10GBASE-KR, XFI, SFI
-      - 10gbase-kr
+      # 10GBASE-R, XFI, SFI
+      - 10gbase-r
       - usxgmii
 
+      # 10GBASE-KR (10G Ethernet Backplane with autonegotiation)
+      - 10gbase-kr
+
   phy-mode:
     $ref: "#/properties/phy-connection-type"
 
diff --git a/Documentation/devicetree/bindings/net/ethernet-phy.yaml b/Documentation/devicetree/bindings/net/ethernet-phy.yaml
index 9b1f114..a23a7d6 100644
--- a/Documentation/devicetree/bindings/net/ethernet-phy.yaml
+++ b/Documentation/devicetree/bindings/net/ethernet-phy.yaml
@@ -162,6 +162,42 @@ properties:
     description:
       Specifies a reference to a node representing a SFP cage.
 
+  eq-algorithm:
+    description:
+      Specifies the desired equalization algorithm to be used
+      by the KR link training
+    oneOf:
+      - const: fixed
+        description:
+          Backplane KR using fixed coefficients meaning no
+          equalization algorithm
+      - const: bee
+        description:
+          Backplane KR using 3-Taps Bit Edge Equalization (BEE)
+          algorithm
+
+  eq-init:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    minItems: 3
+    maxItems: 3
+    description:
+      Triplet of KR coefficients. Specifies the initialization
+      values for standard KR equalization coefficients used by
+      the link training (pre-cursor, main-cursor, post-cursor)
+
+  eq-params:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Variable size array of KR parameters. Specifies the HW
+      specific parameters used by the link training.
+
+  lane-handle:
+    $ref: /schemas/types.yaml#definitions/phandle
+    description:
+      Specifies a reference (or array of references) to a node
+      representing the desired SERDES lane (or lanes) used in
+      backplane mode.
+
 required:
   - reg
 
@@ -184,3 +220,17 @@ examples:
             reset-deassert-us = <2000>;
         };
     };
+  - |
+    ethernet {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        ethernet-phy@0 {
+            compatible = "ethernet-phy-ieee802.3-c45";
+            reg = <0x0>;
+            lane-handle = <&lane_d>;
+            eq-algorithm = "fixed";
+            eq-init = <0x2 0x29 0x5>;
+            eq-params = <0>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/net/serdes-lane.yaml b/Documentation/devicetree/bindings/net/serdes-lane.yaml
new file mode 100644
index 0000000..d83a6a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/serdes-lane.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/serdes-lane.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Serdes Lane Binding
+
+maintainers:
+  - Florinel Iordache <florinel.iordache@nxp.com>
+
+properties:
+  $nodename:
+    pattern: "^lane(@[a-f0-9]+)?$"
+
+  compatible:
+    oneOf:
+      - const: lane-10g
+        description: Lane part of a 10G SerDes module
+
+  reg:
+    description:
+      Registers memory map offset and size for this lane
+
+  reg-names:
+    description:
+      Names of the register map given in "reg" node.
+
+examples:
+  - |
+    serdes1: serdes@1ea0000 {
+        compatible = "serdes-10g";
+        reg = <0x0 0x1ea0000 0 0x00002000>;
+        reg-names = "serdes", "serdes-10g";
+        little-endian;
+
+        #address-cells = <1>;
+        #size-cells = <1>;
+        lane_a: lane@800 {
+            compatible = "lane-10g";
+            reg = <0x800 0x40>;
+            reg-names = "lane", "serdes-lane";
+        };
+        lane_b: lane@840 {
+            compatible = "lane-10g";
+            reg = <0x840 0x40>;
+            reg-names = "lane", "serdes-lane";
+        };
+    };
diff --git a/Documentation/devicetree/bindings/net/serdes.yaml b/Documentation/devicetree/bindings/net/serdes.yaml
new file mode 100644
index 0000000..ed77689c
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/serdes.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/serdes.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Serdes Module Binding
+
+maintainers:
+  - Florinel Iordache <florinel.iordache@nxp.com>
+
+properties:
+  $nodename:
+    pattern: "^serdes(@[a-f0-9]+)?$"
+
+  compatible:
+    oneOf:
+      - const: serdes-10g
+        description: SerDes module type of 10G
+
+  reg:
+    description:
+      Registers memory map offset and size for this serdes module
+
+  reg-names:
+    description:
+      Names of the register map given in "reg" node.
+
+  little-endian:
+    description:
+      Specifies the endianness of serdes module
+      For complete definition see
+      Documentation/devicetree/bindings/common-properties.txt
+
+examples:
+  - |
+    serdes1: serdes@1ea0000 {
+        compatible = "serdes-10g";
+        reg = <0x0 0x1ea0000 0 0x00002000>;
+        reg-names = "serdes", "serdes-10g";
+        little-endian;
+    };
-- 
1.9.1


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

* [PATCH net-next v3 3/7] net: fman: add kr support for dpaa1 mac
  2020-06-22 13:35 [PATCH net-next v2 0/9] net: ethernet backplane support on DPAA1 Florinel Iordache
  2020-06-22 13:35 ` [PATCH net-next v3 1/7] doc: net: add backplane documentation Florinel Iordache
  2020-06-22 13:35 ` [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt bindings Florinel Iordache
@ 2020-06-22 13:35 ` Florinel Iordache
  2020-06-22 13:35 ` [PATCH net-next v3 5/7] net: phy: enable qoriq backplane support Florinel Iordache
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 24+ messages in thread
From: Florinel Iordache @ 2020-06-22 13:35 UTC (permalink / raw)
  To: davem, netdev, andrew, f.fainelli, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, leoyang.li, madalin.bucur, ioana.ciornei, linux-kernel,
	Florinel Iordache

Add kr support in mac driver for dpaa1

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 drivers/net/ethernet/freescale/fman/mac.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c
index 43427c5..90fe594 100644
--- a/drivers/net/ethernet/freescale/fman/mac.c
+++ b/drivers/net/ethernet/freescale/fman/mac.c
@@ -1,4 +1,5 @@
 /* Copyright 2008-2015 Freescale Semiconductor, Inc.
+ * Copyright 2020 NXP
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -220,6 +221,7 @@ static int memac_initialization(struct mac_device *mac_dev)
 
 	set_fman_mac_params(mac_dev, &params);
 
+	/* use XGMII mode for all 10G interfaces to setup memac */
 	if (priv->max_speed == SPEED_10000)
 		params.phy_if = PHY_INTERFACE_MODE_XGMII;
 
@@ -540,7 +542,8 @@ static void setup_memac(struct mac_device *mac_dev)
 	[PHY_INTERFACE_MODE_RGMII_TXID]	= SPEED_1000,
 	[PHY_INTERFACE_MODE_RTBI]		= SPEED_1000,
 	[PHY_INTERFACE_MODE_QSGMII]		= SPEED_1000,
-	[PHY_INTERFACE_MODE_XGMII]		= SPEED_10000
+	[PHY_INTERFACE_MODE_XGMII]		= SPEED_10000,
+	[PHY_INTERFACE_MODE_10GKR]		= SPEED_10000
 };
 
 static struct platform_device *dpaa_eth_add_device(int fman_id,
@@ -795,9 +798,12 @@ static int mac_probe(struct platform_device *_of_dev)
 	if (priv->max_speed == 1000)
 		mac_dev->if_support |= SUPPORTED_1000baseT_Full;
 
-	/* The 10G interface only supports one mode */
+	/* Supported 10G interfaces */
 	if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
 		mac_dev->if_support = SUPPORTED_10000baseT_Full;
+	/* Supported KR interfaces */
+	if (mac_dev->phy_if == PHY_INTERFACE_MODE_10GKR)
+		mac_dev->if_support = SUPPORTED_10000baseKR_Full;
 
 	/* Get the rest of the PHY information */
 	mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
-- 
1.9.1


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

* [PATCH net-next v3 5/7] net: phy: enable qoriq backplane support
  2020-06-22 13:35 [PATCH net-next v2 0/9] net: ethernet backplane support on DPAA1 Florinel Iordache
                   ` (2 preceding siblings ...)
  2020-06-22 13:35 ` [PATCH net-next v3 3/7] net: fman: add kr support for dpaa1 mac Florinel Iordache
@ 2020-06-22 13:35 ` Florinel Iordache
  2020-06-22 17:47   ` kernel test robot
  2020-06-22 13:35 ` [PATCH net-next v3 6/7] net: phy: add bee algorithm for kr training Florinel Iordache
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 24+ messages in thread
From: Florinel Iordache @ 2020-06-22 13:35 UTC (permalink / raw)
  To: davem, netdev, andrew, f.fainelli, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, leoyang.li, madalin.bucur, ioana.ciornei, linux-kernel,
	Florinel Iordache

Enable backplane support for qoriq family of devices

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 drivers/net/phy/backplane/Kconfig            |  11 +-
 drivers/net/phy/backplane/Makefile           |   2 +
 drivers/net/phy/backplane/qoriq_backplane.c  | 473 ++++++++++++++++++++++++++
 drivers/net/phy/backplane/qoriq_backplane.h  |  42 +++
 drivers/net/phy/backplane/qoriq_serdes_10g.c | 486 +++++++++++++++++++++++++++
 5 files changed, 1013 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/backplane/qoriq_backplane.c
 create mode 100644 drivers/net/phy/backplane/qoriq_backplane.h
 create mode 100644 drivers/net/phy/backplane/qoriq_serdes_10g.c

diff --git a/drivers/net/phy/backplane/Kconfig b/drivers/net/phy/backplane/Kconfig
index 9ec54b5..3e20a78 100644
--- a/drivers/net/phy/backplane/Kconfig
+++ b/drivers/net/phy/backplane/Kconfig
@@ -17,4 +17,13 @@ config ETH_BACKPLANE_FIXED
 	  This module provides a driver to setup fixed user configurable
 	  coefficient values for backplanes equalization. This means
 	  No Equalization algorithm is used to adapt the initial coefficients
-	  initially set by the user.
\ No newline at end of file
+	  initially set by the user.
+
+config ETH_BACKPLANE_QORIQ
+	tristate "QorIQ Ethernet Backplane driver"
+	depends on ETH_BACKPLANE
+	help
+	  This module provides a driver for Ethernet Operation over
+	  Electrical Backplanes enabled for QorIQ family of devices.
+	  This driver is using the services provided by the generic
+	  backplane and link training modules.
\ No newline at end of file
diff --git a/drivers/net/phy/backplane/Makefile b/drivers/net/phy/backplane/Makefile
index ded6f2d..3ae3d8b 100644
--- a/drivers/net/phy/backplane/Makefile
+++ b/drivers/net/phy/backplane/Makefile
@@ -5,5 +5,7 @@
 
 obj-$(CONFIG_ETH_BACKPLANE) += eth_backplane.o
 obj-$(CONFIG_ETH_BACKPLANE_FIXED) += eq_fixed.o
+obj-$(CONFIG_ETH_BACKPLANE_QORIQ) += eth_backplane_qoriq.o
 
 eth_backplane-objs	:= backplane.o link_training.o
+eth_backplane_qoriq-objs	:= qoriq_backplane.o qoriq_serdes_10g.o
diff --git a/drivers/net/phy/backplane/qoriq_backplane.c b/drivers/net/phy/backplane/qoriq_backplane.c
new file mode 100644
index 0000000..eb22e02
--- /dev/null
+++ b/drivers/net/phy/backplane/qoriq_backplane.c
@@ -0,0 +1,473 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/* QorIQ Backplane driver
+ *
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ * Copyright 2018-2020 NXP
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/mdio.h>
+#include <linux/io.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "qoriq_backplane.h"
+
+/* QorIQ Backplane Driver name */
+#define QORIQ_BACKPLANE_DRIVER_NAME		"backplane_qoriq"
+
+/* QorIQ Backplane Driver version */
+#define QORIQ_BACKPLANE_DRIVER_VERSION		"1.0.0"
+
+/* PCS Device Identifier */
+#define PCS_PHY_DEVICE_ID			0x0083e400
+#define PCS_PHY_DEVICE_ID_MASK			0xffffffff
+
+/* Max/Min coefficients range values */
+#define PRE_COEF_MAX				0x0
+#define PRE_COEF_MIN				0x8
+#define POST_COEF_MAX				0x0
+#define POST_COEF_MIN				0x10
+#define ZERO_COEF_MIN				0x1A
+#define ZERO_COEF_MAX				0x30
+
+/* Coefficients sum ratio: (their sum divided by their difference) */
+#define COEF_SUM_RATIO_NUMERATOR		17
+#define COEF_SUM_RATIO_DENOMINATOR		4
+
+/* Number of equalization custom parameters */
+#define EQ_PARAMS_NO				1
+
+/* Serdes types supported by QorIQ devices */
+enum serdes_type {
+	SERDES_10G,
+	SERDES_INVAL
+};
+
+static void an_advertisement_init(struct lane_device *lane)
+{
+	struct backplane_device *bpdev = lane->bpdev;
+	struct phy_device *phydev = lane->phydev;
+	struct qoriq_driver *qoriq_drv;
+	u32 init_an_adv1;
+	int err;
+
+	qoriq_drv = (struct qoriq_driver *)bpdev->drv.priv;
+	init_an_adv1 = backplane_get_an_adv1_init(phydev->interface);
+
+	err = backplane_write_mmd(lane, MDIO_MMD_AN, qoriq_drv->an_adv1,
+				  init_an_adv1);
+	if (err)
+		phydev_err(phydev,
+			   "Setting AN register 0x%02x on lane %d failed with error code: 0x%08x\n",
+			   qoriq_drv->an_adv1, lane->idx, err);
+}
+
+static bool is_an_link_detected(struct lane_device *lane)
+{
+	struct backplane_device *bpdev = lane->bpdev;
+	struct phy_device *phydev = lane->phydev;
+	struct qoriq_driver *qoriq_drv;
+	struct lane_device *masterln;
+	u32 an_bp_eth_status;
+	int an_state;
+	u32 an_mask;
+
+	qoriq_drv = (struct qoriq_driver *)bpdev->drv.priv;
+	an_bp_eth_status = qoriq_drv->an_bp_eth_status;
+
+	/* Check AN state only on Master Lane */
+	masterln = &bpdev->lane[MASTER_LANE];
+
+	/* The link training occurs after auto-negotiation
+	 * has determined the link to be a Base-KR link.
+	 * This is indicated by asserting the corresponding
+	 * technology bit within the BP_ETH_STATUS register.
+	 * Note that this occurs before auto-negotiation can declare
+	 * auto-negotiation complete,
+	 * as this requires the PCS to report a valid link.
+	 */
+	an_mask = backplane_get_an_bp_eth_status_bit(phydev->interface);
+	an_state = backplane_read_mmd(masterln, MDIO_MMD_AN, an_bp_eth_status);
+
+	return (an_state & an_mask);
+}
+
+static void qoriq_setup_default_settings(struct lane_device *lane)
+{
+	const struct lane_ops *lane_ops = lane->bpdev->drv.lane_ops;
+	struct qoriq_lane_ops *qoriq_lane_ops;
+	u32 def_amp_red;
+
+	qoriq_lane_ops = (struct qoriq_lane_ops *)lane_ops->priv;
+
+	if (lane->bpdev->bpkr.valid_eq_params)
+		def_amp_red = lane->bpdev->bpkr.def_kr.dev_coef[IDX_AMP_RED];
+	else
+		def_amp_red = qoriq_lane_ops->read_amp_red(lane->reg_base);
+
+	lane->krln.def_kr.dev_coef[IDX_AMP_RED] = def_amp_red;
+}
+
+/* LT HW restrictions:
+ * Section 5.3.1 10GBaseKR Transmit Adaptive Equalization Control
+ * additional restrictions set down by 802.3 specification Clause 72,
+ * specifically 72.7.1.11 Transmitter output waveform requirements
+ *
+ * Maintaining the following relationships limit transmit equalization
+ * to reasonable levels compliant with the KR specification
+ */
+static int lt_qoriq_validation(struct lane_device *lane, u32 *ld_coef)
+{
+	struct backplane_kr *bpkr = &lane->bpdev->bpkr;
+	u32 mainq = ld_coef[C_Z0];
+	u32 postq = ld_coef[C_P1];
+	u32 preq = ld_coef[C_M1];
+
+	/* Additional HW restrictions:
+	 * 1. MIN_C(0) <= tx_preq + tx_mainq + tx_ratio_post1q <= MAX_C(0)
+	 */
+	if ((preq + postq + mainq) < bpkr->min_kr.mainq)
+		return -ERANGE;
+	if ((preq + postq + mainq) > bpkr->max_kr.mainq)
+		return -ERANGE;
+
+	/* 2.
+	 * ( tx_mainq + tx_preq + tx_ratio_post1q ) /
+	 * ( tx_mainq - tx_preq - tx_ratio_post1q ) <
+	 * coef_sum_ratio_numerator / coef_sum_ratio_denominator
+	 */
+	if (((mainq + preq + postq) * COEF_SUM_RATIO_DENOMINATOR) >=
+	    ((mainq - preq - postq) * COEF_SUM_RATIO_NUMERATOR))
+		return -ERANGE;
+
+	return 0;
+}
+
+enum serdes_type get_serdes_type(struct device_node *serdes_node)
+{
+	enum serdes_type serdes = SERDES_INVAL;
+	const char *serdes_comp;
+	int comp_no, i, ret;
+
+	comp_no = of_property_count_strings(serdes_node, "compatible");
+	for (i = 0; i < comp_no; i++) {
+		ret = of_property_read_string_index(serdes_node, "compatible",
+						    i, &serdes_comp);
+		if (ret == 0) {
+			if (!strcasecmp(serdes_comp, "serdes-10g")) {
+				serdes = SERDES_10G;
+				break;
+			}
+		}
+	}
+
+	return serdes;
+}
+
+/* install QorIQ specific backplane callbacks:
+ * for AN start/decoding, hw specific defaults and lt validation
+ */
+static const struct backplane_ops qoriq_ops = {
+	.an_advertisement_init = an_advertisement_init,
+	.is_an_link_detected = is_an_link_detected,
+	.setup_default_settings = qoriq_setup_default_settings,
+	.lt_validation = lt_qoriq_validation,
+};
+
+/* qoriq_backplane_probe
+ *
+ * Probe function for QorIQ backplane driver to provide QorIQ device specific
+ * behavior
+ *
+ * phydev: backplane phy device
+ *	this is an internal phy block controlled by the software
+ *	which contains other component blocks like: PMA/PMD, PCS, AN
+ *
+ * Return: Zero for success or error code in case of failure
+ */
+static int qoriq_backplane_probe(struct phy_device *phydev)
+{
+	pr_info_once("%s: QorIQ Backplane driver version %s\n",
+		     QORIQ_BACKPLANE_DRIVER_NAME,
+		     QORIQ_BACKPLANE_DRIVER_VERSION);
+
+	/* call generic driver probe */
+	return backplane_probe(phydev);
+}
+
+/* qoriq_backplane_config_init
+ *
+ * Config_Init function for QorIQ devices to provide QorIQ specific behavior
+ *
+ * phydev: backplane phy device
+ *
+ * Return: Zero for success or error code in case of failure
+ */
+static int qoriq_backplane_config_init(struct phy_device *phydev)
+{
+	struct device_node *dev_node, *serdes_node, *lane_node;
+	const struct equalizer_device *qoriq_equalizer = NULL;
+	struct backplane_device *bpdev = phydev->priv;
+	struct qoriq_lane_ops *qoriq_lane_ops = NULL;
+	const struct qoriq_driver *qoriq_drv = NULL;
+	const struct lane_ops *lane_ops = NULL;
+	enum serdes_type serdes = SERDES_INVAL;
+	u32 eqparams[EQ_PARAMS_NO];
+	struct resource res;
+	int proplen;
+	int i, ret;
+
+	dev_node = phydev->mdio.dev.of_node;
+	if (!dev_node) {
+		phydev_err(phydev, "No associated device tree node\n");
+		return -EINVAL;
+	}
+	if (!bpdev) {
+		phydev_err(phydev, "Backplane phy info is not allocated\n");
+		return -EINVAL;
+	}
+
+	if (!backplane_is_valid_mode(phydev->interface))
+		return -EINVAL;
+
+	/* call generic driver parse DT */
+	ret = backplane_parse_dt(phydev);
+	if (ret)
+		return ret;
+
+	bpdev->num_lanes = backplane_num_lanes(phydev->interface);
+	if (bpdev->num_lanes > MAX_KR_LANES_PER_PHY) {
+		phydev_err(phydev, "Unsupported number of lanes per phy: %d\n",
+			   bpdev->num_lanes);
+		return -EINVAL;
+	}
+
+	proplen = of_property_count_u32_elems(dev_node, "lane-handle");
+	if (proplen < bpdev->num_lanes) {
+		phydev_err(phydev, "Unspecified lane handles\n");
+		return -EINVAL;
+	}
+	serdes_node = NULL;
+	for (i = 0; i < bpdev->num_lanes; i++) {
+		lane_node = of_parse_phandle(dev_node, "lane-handle", i);
+		if (!lane_node) {
+			phydev_err(phydev, "parse lane-handle failed\n");
+			return -EINVAL;
+		}
+		if (i == 0)
+			serdes_node = lane_node->parent;
+		ret = of_address_to_resource(lane_node, 0, &res);
+		if (ret) {
+			phydev_err(phydev,
+				   "could not obtain lane memory map for index=%d, ret = %d\n",
+				   i, ret);
+			return ret;
+		}
+		/* setup lane address */
+		bpdev->lane[i].lane_addr = res.start;
+
+		of_node_put(lane_node);
+	}
+	if (!serdes_node) {
+		phydev_err(phydev, "serdes node not found\n");
+		return -EINVAL;
+	}
+	bpdev->drv.is_little_endian = of_property_read_bool(serdes_node,
+							    "little-endian");
+
+	ret = of_address_to_resource(serdes_node, 0, &res);
+	if (ret) {
+		phydev_err(phydev,
+			   "could not obtain serdes memory map, ret = %d\n",
+			   ret);
+		return ret;
+	}
+	bpdev->drv.base_addr = res.start;
+	bpdev->drv.memmap_size = res.end - res.start + 1;
+
+	serdes = get_serdes_type(serdes_node);
+	if (serdes == SERDES_INVAL) {
+		phydev_err(phydev, "Unknown serdes-type\n");
+		return 0;
+	}
+
+	/* if eq-params node exists then use the DTS specified values
+	 * if eq-params node doesn't exist then use values already found in HW
+	 * eq-params is a custom node and variable in size
+	 */
+	proplen = of_property_count_u32_elems(dev_node, "eq-params");
+	if (proplen > 0) {
+		/* we use only 1 custom coefficient tap: amp_red */
+		if (proplen > EQ_PARAMS_NO)
+			proplen = EQ_PARAMS_NO;
+		ret = of_property_read_u32_array(dev_node, "eq-params",
+						 (u32 *)eqparams, proplen);
+		if (ret == 0) {
+			bpdev->bpkr.valid_eq_params = true;
+			bpdev->bpkr.def_kr.dev_coef[IDX_AMP_RED] =
+							eqparams[IDX_AMP_RED];
+		}
+	}
+
+	/* call generic driver setup memio after reading serdes endianness */
+	ret = backplane_setup_memio(phydev);
+	if (ret)
+		return ret;
+
+	/* call generic driver setup mmd */
+	ret = backplane_setup_mmd(phydev);
+	if (ret)
+		return ret;
+
+	/* override default mdio setup and get qoriq specific info */
+	switch (serdes) {
+	case SERDES_10G:
+		lane_ops = qoriq_get_lane_ops_10g();
+		qoriq_drv = get_qoriq_driver_10g();
+		qoriq_setup_mem_io_10g(bpdev->drv.io);
+		qoriq_equalizer = qoriq_get_equalizer_10g();
+		break;
+	default:
+		phydev_err(phydev, "Serdes type not supported\n");
+		return -EINVAL;
+	}
+	if (!lane_ops) {
+		phydev_err(phydev, "Lane ops not available\n");
+		return -EINVAL;
+	}
+	if (!qoriq_drv) {
+		phydev_err(phydev, "Qoriq driver not available\n");
+		return -EINVAL;
+	}
+	if (!qoriq_equalizer) {
+		phydev_err(phydev, "Qoriq Equalizer not available\n");
+		return -EINVAL;
+	}
+
+	/* setup ops and equalizer */
+	bpdev->drv.lane_ops = lane_ops;
+	bpdev->drv.bp_ops = qoriq_ops;
+	bpdev->drv.priv = (void *)qoriq_drv;
+	bpdev->bpkr.equalizer = qoriq_equalizer;
+	qoriq_lane_ops = (struct qoriq_lane_ops *)lane_ops->priv;
+
+	if (!qoriq_lane_ops) {
+		phydev_err(phydev, "QorIQ lane ops not available\n");
+		return -EINVAL;
+	}
+
+	/* setup KR LT MMD registers space */
+	backplane_kr_lt_mmd_setup(&bpdev->bpkr, qoriq_drv->kr_lt_devad,
+				  qoriq_drv->kr_lt_base);
+
+	if (backplane_is_mode_kr(phydev->interface)) {
+		/* setup kr coefficients limits */
+		bpdev->bpkr.min_kr.preq = PRE_COEF_MIN;
+		bpdev->bpkr.max_kr.preq = PRE_COEF_MAX;
+		bpdev->bpkr.min_kr.mainq = ZERO_COEF_MIN;
+		bpdev->bpkr.max_kr.mainq = ZERO_COEF_MAX;
+		bpdev->bpkr.min_kr.postq = POST_COEF_MIN;
+		bpdev->bpkr.max_kr.postq = POST_COEF_MAX;
+	}
+
+	/* call generic driver setup lanes */
+	ret = backplane_setup_lanes(phydev);
+	if (ret)
+		return ret;
+
+	/* call generic driver initialize
+	 * start the lane timers used to run the algorithm
+	 */
+	ret = backplane_initialize(phydev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int qoriq_backplane_match_phy_device(struct phy_device *phydev)
+{
+	struct device_node *dev_node, *serdes_node, *lane_node;
+	enum serdes_type serdes = SERDES_INVAL;
+	int i;
+
+	if (!phydev->mdio.dev.of_node)
+		return 0;
+
+	if (!phydev->is_c45)
+		return 0;
+
+	dev_node = phydev->mdio.dev.of_node;
+	if (!dev_node) {
+		phydev_err(phydev, "No associated device tree node\n");
+		return 0;
+	}
+
+	/* Get Master lane node */
+	lane_node = of_parse_phandle(dev_node, "lane-handle", 0);
+	if (!lane_node)
+		return 0;
+	serdes_node = lane_node->parent;
+	of_node_put(lane_node);
+	if (!serdes_node)
+		return 0;
+
+	serdes = get_serdes_type(serdes_node);
+
+	switch (serdes) {
+	case SERDES_10G:
+		/* On LS devices we must find the c45 device with correct PHY ID
+		 * Implementation similar with the one existent in phy_device:
+		 * @function: phy_bus_match
+		 */
+		for (i = 1; i < ARRAY_SIZE(phydev->c45_ids.device_ids); i++) {
+			if (!(phydev->c45_ids.devices_in_package & (1 << i)))
+				continue;
+
+			if ((PCS_PHY_DEVICE_ID & PCS_PHY_DEVICE_ID_MASK) ==
+			    (phydev->c45_ids.device_ids[i] &
+			     PCS_PHY_DEVICE_ID_MASK))
+				return 1;
+		}
+		break;
+	default:
+		phydev_err(phydev, "Unknown serdes-type\n");
+		return 0;
+	}
+	return 0;
+}
+
+static struct phy_driver qoriq_backplane_driver[] = {
+	{
+	.phy_id		= PCS_PHY_DEVICE_ID,
+	.name		= QORIQ_BACKPLANE_DRIVER_NAME,
+	.phy_id_mask	= PCS_PHY_DEVICE_ID_MASK,
+	.features       = BACKPLANE_FEATURES,
+	.probe          = qoriq_backplane_probe,
+	.remove         = backplane_remove,
+	.config_init    = qoriq_backplane_config_init,
+	.aneg_done      = backplane_aneg_done,
+	.config_aneg	= backplane_config_aneg,
+	.read_status	= backplane_read_status,
+	.suspend	= backplane_suspend,
+	.resume		= backplane_resume,
+	.match_phy_device = qoriq_backplane_match_phy_device,
+	},
+};
+
+module_phy_driver(qoriq_backplane_driver);
+
+static struct mdio_device_id __maybe_unused qoriq_backplane_tbl[] = {
+	{ PCS_PHY_DEVICE_ID, PCS_PHY_DEVICE_ID_MASK },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(mdio, qoriq_backplane_tbl);
+
+MODULE_DESCRIPTION("QorIQ Backplane driver");
+MODULE_AUTHOR("Florinel Iordache <florinel.iordache@nxp.com>");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/phy/backplane/qoriq_backplane.h b/drivers/net/phy/backplane/qoriq_backplane.h
new file mode 100644
index 0000000..09a3600
--- /dev/null
+++ b/drivers/net/phy/backplane/qoriq_backplane.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/* QorIQ Backplane driver
+ *
+ * Copyright 2018-2020 NXP
+ */
+
+#ifndef __QORIQ_BACKPLANE_H
+#define __QORIQ_BACKPLANE_H
+
+#include "backplane.h"
+
+/* Bins thresholds */
+#define QORIQ_BIN_M1_THRESHOLD			3
+#define QORIQ_BIN_LONG_THRESHOLD		2
+
+/* Index of custom parameter: AMP_RED (amplitude reduction) */
+#define IDX_AMP_RED				0
+
+struct qoriq_lane_ops {
+	u32 (*read_tecr0)(void __iomem *reg);
+	u32 (*read_tecr1)(void __iomem *reg);
+	u32 (*read_amp_red)(void __iomem *reg);
+};
+
+struct qoriq_driver {
+	/* KR LT MMD registers */
+	int kr_lt_devad;
+	u32 kr_lt_base;
+	/* KR AN MMD registers */
+	u32 an_adv1;
+	u32 an_bp_eth_status;
+};
+
+const struct lane_ops *qoriq_get_lane_ops_10g(void);
+
+const struct equalizer_device *qoriq_get_equalizer_10g(void);
+
+const struct qoriq_driver *get_qoriq_driver_10g(void);
+
+void qoriq_setup_mem_io_10g(struct mem_io memio);
+
+#endif /* __QORIQ_BACKPLANE_H */
diff --git a/drivers/net/phy/backplane/qoriq_serdes_10g.c b/drivers/net/phy/backplane/qoriq_serdes_10g.c
new file mode 100644
index 0000000..e4e5991
--- /dev/null
+++ b/drivers/net/phy/backplane/qoriq_serdes_10g.c
@@ -0,0 +1,486 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/* QorIQ Backplane driver for SerDes 10G
+ *
+ * Copyright 2018-2020 NXP
+ */
+
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include "qoriq_backplane.h"
+
+#define EQUALIZER_NAME				"qoriq_serdes_10g"
+#define EQUALIZER_VERSION			"1.0.0"
+
+#define BIN_1_SEL				0x00000000
+#define BIN_2_SEL				0x00010000
+#define BIN_3_SEL				0x00020000
+#define BIN_OFFSET_SEL				0x00030000
+#define BIN_BLW_SEL				0x00040000
+#define BIN_AVG_SEL				0x00050000
+#define BIN_M1_SEL				0x00060000
+#define BIN_LONG_SEL				0x00070000
+#define CDR_SEL_MASK				0x00070000
+
+#define RATIO_PREQ_SHIFT			22
+#define RATIO_PST1Q_SHIFT			16
+#define ADPT_EQ_SHIFT				8
+#define AMP_RED_SHIFT				0
+
+#define RATIO_PREQ_MASK				0x03c00000
+#define RATIO_PST1Q_MASK			0x001f0000
+#define ADPT_EQ_MASK				0x00003f00
+#define AMP_RED_MASK				0x0000003f
+
+#define TECR0_INIT				0x24200000
+
+#define GCR0_RESET_MASK				0x00600000
+#define GCR0_TRST_MASK				0x00200000
+#define GCR0_RRST_MASK				0x00400000
+
+#define GCR1_SNP_START_MASK			0x00000040
+#define GCR1_CTL_SNP_START_MASK			0x00002000
+
+#define RECR1_CTL_SNP_DONE_MASK			0x00000002
+#define RECR1_SNP_DONE_MASK			0x00000004
+#define TCSR1_SNP_DATA_MASK			0x00007fc0
+#define TCSR1_SNP_DATA_SHIFT			6
+#define TCSR1_EQ_SNPBIN_SIGN_MASK		0x100
+
+#define TCSR3_CDR_LCK_MASK			0x08000000
+
+#define RECR1_GAINK2_MASK			0x0f000000
+#define RECR1_GAINK2_SHIFT			24
+
+#define RECR1_GAINK3_MASK			0x000f0000
+#define RECR1_GAINK3_SHIFT			16
+
+#define RECR1_EQ_OFFSET_MASK			0x00001f80
+#define RECR1_EQ_OFFSET_SHIFT			7
+
+/* AN advertisement register 7.17 */
+#define AN_AD_ABILITY_1				0x11
+
+/* Backplane Ethernet status (Register 7.48) */
+#define AN_BP_ETH_STATUS_OFFSET			0x30
+
+/* KR PMD control register (Register 1.150) */
+#define KR_PMD_BASE_OFFSET			0x96
+
+/* Bin snapshots thresholds range */
+#define EQ_BIN_MIN				-256
+#define EQ_BIN_MAX				255
+/* Bin snapshots average thresholds range */
+#define EQ_BIN_SNP_AV_THR_LOW			-150
+#define EQ_BIN_SNP_AV_THR_HIGH			150
+
+#define EQ_GAINK_MIN				0xF
+#define EQ_GAINK_MAX				0x0
+#define EQ_GAINK_MIDRANGE_LOW			0xE
+#define EQ_GAINK_MIDRANGE_HIGH			0x1
+
+#define EQ_OFFSET_MIN				0
+#define EQ_OFFSET_MAX				0x3F
+#define EQ_OFFSET_MIDRANGE_LOW			0x10
+#define EQ_OFFSET_MIDRANGE_HIGH			0x2F
+
+#define MEMORY_MAP_SIZE				0x40
+
+struct qoriq_lane_regs {
+	u32 gcr0;	/* 0x00: General Control Register 0 */
+	u32 gcr1;	/* 0x04: General Control Register 1 */
+	u32 gcr2;	/* 0x08: General Control Register 2 */
+	u32 res_0c;	/* 0x0C: Reserved */
+	u32 recr0;	/* 0x10: Receive Equalization Control Register 0 */
+	u32 recr1;	/* 0x14: Receive Equalization Control Register 1 */
+	u32 tecr0;	/* 0x18: Transmit Equalization Control Register 0 */
+	u32 res_1c;	/* 0x1C: Reserved */
+	u32 tlcr0;	/* 0x20: TTL Control Register 0 */
+	u32 tlcr1;	/* 0x24: TTL Control Register 1 */
+	u32 tlcr2;	/* 0x28: TTL Control Register 2 */
+	u32 tlcr3;	/* 0x2C: TTL Control Register 3 */
+	u32 tcsr0;	/* 0x30: Test Control/Status Register 0 */
+	u32 tcsr1;	/* 0x34: Test Control/Status Register 1 */
+	u32 tcsr2;	/* 0x38: Test Control/Status Register 2 */
+	u32 tcsr3;	/* 0x3C: Test Control/Status Register 3 */
+};
+
+static struct mem_io io;
+
+static void reset_lane(void __iomem *reg, enum lane_req ln_req)
+{
+	struct qoriq_lane_regs __iomem *reg_base = reg;
+
+	/* reset Tx lane: send reset request */
+	if (ln_req | LANE_TX) {
+		io.write32(io.read32(&reg_base->gcr0) & ~GCR0_TRST_MASK,
+			   &reg_base->gcr0);
+	}
+	/* reset Rx lane: send reset request */
+	if (ln_req | LANE_RX) {
+		io.write32(io.read32(&reg_base->gcr0) & ~GCR0_RRST_MASK,
+			   &reg_base->gcr0);
+	}
+	/* unreset the lane */
+	if (ln_req != LANE_INVALID) {
+		udelay(1);
+		io.write32(io.read32(&reg_base->gcr0) | GCR0_RESET_MASK,
+			   &reg_base->gcr0);
+		udelay(1);
+	}
+}
+
+static u32 read_tecr0(void __iomem *reg)
+{
+	struct qoriq_lane_regs __iomem *reg_base = reg;
+
+	return io.read32(&reg_base->tecr0);
+}
+
+static u32 read_tecr1(void __iomem *reg)
+{
+	return 0;
+}
+
+static u32 read_amp_red(void __iomem *reg)
+{
+	struct qoriq_lane_regs __iomem *reg_base = reg;
+	u32 val, amp_red;
+
+	val = io.read32(&reg_base->tecr0);
+	amp_red = (val & AMP_RED_MASK) >> AMP_RED_SHIFT;
+
+	return amp_red;
+}
+
+static void read_kr_coef(void __iomem *reg, struct kr_coef *coef)
+{
+	struct qoriq_lane_regs __iomem *reg_base = reg;
+	u32 val;
+
+	val = io.read32(&reg_base->tecr0);
+
+	coef->preq = (val & RATIO_PREQ_MASK) >> RATIO_PREQ_SHIFT;
+	coef->postq = (val & RATIO_PST1Q_MASK) >> RATIO_PST1Q_SHIFT;
+	coef->mainq = (val & ADPT_EQ_MASK) >> ADPT_EQ_SHIFT;
+	coef->dev_coef[IDX_AMP_RED] = (val & AMP_RED_MASK) >> AMP_RED_SHIFT;
+}
+
+static void tune_tecr(void __iomem *reg, struct kr_coef *coef, bool reset)
+{
+	struct qoriq_lane_regs __iomem *reg_base = reg;
+	u32 val;
+
+	val = TECR0_INIT |
+		coef->mainq << ADPT_EQ_SHIFT |
+		coef->preq << RATIO_PREQ_SHIFT |
+		coef->postq << RATIO_PST1Q_SHIFT |
+		coef->dev_coef[IDX_AMP_RED] << AMP_RED_SHIFT;
+
+	if (reset) {
+		/* reset the lane */
+		io.write32(io.read32(&reg_base->gcr0) &
+			   ~GCR0_RESET_MASK, &reg_base->gcr0);
+		udelay(1);
+	}
+
+	io.write32(val, &reg_base->tecr0);
+	udelay(1);
+
+	if (reset) {
+		/* unreset the lane */
+		io.write32(io.read32(&reg_base->gcr0) | GCR0_RESET_MASK,
+			   &reg_base->gcr0);
+		udelay(1);
+	}
+}
+
+/* collect_gains
+ *
+ * reg: serdes registers memory map
+ * gaink2: High-frequency gain of the equalizer amplifier
+ *         the high-frequency gain of the equalizer amplifier is increased by
+ *         decrementing the value of eq_gaink2 by one
+ * gaink3: Middle-frequency gain of the equalizer amplifier
+ *         the mid-frequency gain of the equalizer amplifier is increased by
+ *         decrementing the value of eq_gaink3 by one
+ * osestat: equalization offset status
+ *          the equalizer offset is reduced by decrementing the value of osestat
+ * size: size of snapshots data collection
+ */
+static int collect_gains(void __iomem *reg, s16 *gaink2, s16 *gaink3,
+			 s16 *osestat, u8 size)
+{
+	struct qoriq_lane_regs __iomem *reg_base = reg;
+	u32 rx_eq_snp;
+	int timeout;
+	int i;
+
+	for (i = 0; i < size; i++) {
+		/* wait RECR1_CTL_SNP_DONE_MASK has cleared */
+		timeout = 100;
+		while (io.read32(&reg_base->recr1) &
+		       RECR1_CTL_SNP_DONE_MASK) {
+			udelay(1);
+			timeout--;
+			if (timeout == 0)
+				break;
+		}
+
+		/* start snapshot */
+		io.write32((io.read32(&reg_base->gcr1) |
+			    GCR1_CTL_SNP_START_MASK), &reg_base->gcr1);
+
+		/* wait for SNP done */
+		timeout = 100;
+		while (!(io.read32(&reg_base->recr1) &
+		       RECR1_CTL_SNP_DONE_MASK)) {
+			udelay(1);
+			timeout--;
+			if (timeout == 0)
+				break;
+		}
+
+		/* read and save the snapshot */
+		rx_eq_snp = io.read32(&reg_base->recr1);
+
+		if (gaink2)
+			gaink2[i] = (u8)((rx_eq_snp & RECR1_GAINK2_MASK) >>
+					 RECR1_GAINK2_SHIFT);
+		if (gaink3)
+			gaink3[i] = (u8)((rx_eq_snp & RECR1_GAINK3_MASK) >>
+					 RECR1_GAINK3_SHIFT);
+		if (osestat)
+			osestat[i] = (u8)((rx_eq_snp & RECR1_EQ_OFFSET_MASK) >>
+					  RECR1_EQ_OFFSET_SHIFT);
+
+		/* terminate the snapshot by setting GCR1[REQ_CTL_SNP] */
+		io.write32((io.read32(&reg_base->gcr1) &
+			   ~GCR1_CTL_SNP_START_MASK), &reg_base->gcr1);
+	}
+	return i;
+}
+
+static int collect_eq_status(void __iomem *reg, enum eqc_type type[],
+			     u8 type_no, s16 *counters, u8 size)
+{
+	s16 *gaink2 = NULL, *gaink3 = NULL, *osestat = NULL;
+	u8 i;
+
+	for (i = 0; i < type_no; i++) {
+		switch (type[i]) {
+		case EQC_GAIN_HF:
+			gaink2 = counters;
+			break;
+		case EQC_GAIN_MF:
+			gaink3 = counters + size;
+			break;
+		case EQC_EQOFFSET:
+			osestat = counters + 2 * size;
+			break;
+		default:
+			/* invalid type */
+			break;
+		}
+	}
+
+	return collect_gains(reg, gaink2, gaink3, osestat, size);
+}
+
+static int collect_bin_snapshots(void __iomem *reg, enum eqc_type type,
+				 s16 *bin_counters, u8 bin_size)
+{
+	struct qoriq_lane_regs __iomem *reg_base = reg;
+	int bin_snapshot;
+	int i, timeout;
+	u32 bin_sel;
+
+	/* calculate TCSR1[CDR_SEL] */
+	switch (type) {
+	case EQC_BIN_1:
+		bin_sel = BIN_1_SEL;
+		break;
+	case EQC_BIN_2:
+		bin_sel = BIN_2_SEL;
+		break;
+	case EQC_BIN_3:
+		bin_sel = BIN_3_SEL;
+		break;
+	case EQC_BIN_LONG:
+		bin_sel = BIN_LONG_SEL;
+		break;
+	case EQC_BIN_M1:
+		bin_sel = BIN_M1_SEL;
+		break;
+	case EQC_BIN_OFFSET:
+		bin_sel = BIN_OFFSET_SEL;
+		break;
+	case EQC_BIN_AVG:
+		bin_sel = BIN_AVG_SEL;
+		break;
+	case EQC_BIN_BLW:
+		bin_sel = BIN_BLW_SEL;
+		break;
+	default:
+		/* invalid bin type */
+		return 0;
+	}
+
+	for (i = 0; i < bin_size; i++) {
+		/* wait RECR1_SNP_DONE_MASK has cleared */
+		timeout = 100;
+		while ((io.read32(&reg_base->recr1) &
+			RECR1_SNP_DONE_MASK)) {
+			udelay(1);
+			timeout--;
+			if (timeout == 0)
+				break;
+		}
+
+		/* set TCSR1[CDR_SEL] */
+		io.write32((io.read32(&reg_base->tcsr1) &
+			    ~CDR_SEL_MASK) | bin_sel, &reg_base->tcsr1);
+
+		/* start snapshot */
+		io.write32(io.read32(&reg_base->gcr1) |
+			   GCR1_SNP_START_MASK, &reg_base->gcr1);
+
+		/* wait for SNP done */
+		timeout = 100;
+		while (!(io.read32(&reg_base->recr1) &
+			 RECR1_SNP_DONE_MASK)) {
+			udelay(1);
+			timeout--;
+			if (timeout == 0)
+				break;
+		}
+
+		/* read and save the snapshot:
+		 * 2's complement 9 bit long value (-256 to 255)
+		 */
+		bin_snapshot = (io.read32(&reg_base->tcsr1) &
+				TCSR1_SNP_DATA_MASK) >> TCSR1_SNP_DATA_SHIFT;
+		if (bin_snapshot & TCSR1_EQ_SNPBIN_SIGN_MASK) {
+			/* 2's complement 9 bit long negative number */
+			bin_snapshot &= ~TCSR1_EQ_SNPBIN_SIGN_MASK;
+			bin_snapshot -= 256;
+		}
+
+		/* save collected Bin snapshot */
+		bin_counters[i] = (s16)bin_snapshot;
+
+		/* terminate the snapshot by setting GCR1[REQ_CTL_SNP] */
+		io.write32(io.read32(&reg_base->gcr1) &
+			   ~GCR1_SNP_START_MASK, &reg_base->gcr1);
+	}
+	return i;
+}
+
+static struct eqc_range bin_range = {
+	.min = EQ_BIN_MIN,
+	.max = EQ_BIN_MAX,
+	.mid_low = EQ_BIN_SNP_AV_THR_LOW,
+	.mid_high = EQ_BIN_SNP_AV_THR_HIGH,
+};
+
+static struct eqc_range gaink_range = {
+	.min = EQ_GAINK_MIN,
+	.max = EQ_GAINK_MAX,
+	.mid_low = EQ_GAINK_MIDRANGE_LOW,
+	.mid_high = EQ_GAINK_MIDRANGE_HIGH,
+};
+
+static struct eqc_range osestat_range = {
+	.min = EQ_OFFSET_MIN,
+	.max = EQ_OFFSET_MAX,
+	.mid_low = EQ_OFFSET_MIDRANGE_LOW,
+	.mid_high = EQ_OFFSET_MIDRANGE_HIGH,
+};
+
+static struct eqc_range *get_counter_range(enum eqc_type type)
+{
+	switch (type) {
+	case EQC_BIN_1:
+	case EQC_BIN_2:
+	case EQC_BIN_3:
+	case EQC_BIN_LONG:
+	case EQC_BIN_M1:
+	case EQC_BIN_OFFSET:
+	case EQC_BIN_AVG:
+	case EQC_BIN_BLW:
+		return &bin_range;
+	case EQC_GAIN_HF:
+	case EQC_GAIN_MF:
+		return &gaink_range;
+	case EQC_EQOFFSET:
+		return &osestat_range;
+	default:
+		/* invalid counter type */
+		return NULL;
+	}
+	return NULL;
+}
+
+static bool is_cdr_lock_bit(void __iomem *reg)
+{
+	struct qoriq_lane_regs __iomem *reg_base = reg;
+
+	if (io.read32(&reg_base->tcsr3) & TCSR3_CDR_LCK_MASK)
+		return true;
+
+	return false;
+}
+
+static const struct qoriq_lane_ops qoriq_lane_ops_10g = {
+	.read_tecr0 = read_tecr0,
+	.read_tecr1 = read_tecr1,
+	.read_amp_red = read_amp_red,
+};
+
+static const struct lane_ops lane_ops_10g = {
+	.priv = &qoriq_lane_ops_10g,
+	.memmap_size = MEMORY_MAP_SIZE,
+	.reset_lane = reset_lane,
+	.tune_lane_kr = tune_tecr,
+	.read_lane_kr = read_kr_coef,
+	.is_cdr_lock = is_cdr_lock_bit,
+};
+
+const struct lane_ops *qoriq_get_lane_ops_10g(void)
+{
+	return &lane_ops_10g;
+}
+
+static const struct equalizer_device qoriq_equalizer = {
+	.name = EQUALIZER_NAME,
+	.version = EQUALIZER_VERSION,
+	.ops = {
+		.collect_counters = collect_bin_snapshots,
+		.collect_multiple_counters = collect_eq_status,
+		.get_counter_range = get_counter_range,
+	},
+};
+
+const struct equalizer_device *qoriq_get_equalizer_10g(void)
+{
+	return &qoriq_equalizer;
+}
+
+static const struct qoriq_driver qoriq_drv = {
+	/* KR PMD registers */
+	.kr_lt_devad = MDIO_MMD_PMAPMD,
+	.kr_lt_base = KR_PMD_BASE_OFFSET,
+	/* KR AN registers: IEEE802.3 Clause 45 MMD 7 */
+	.an_adv1 = AN_AD_ABILITY_1,
+	.an_bp_eth_status = AN_BP_ETH_STATUS_OFFSET,
+};
+
+const struct qoriq_driver *get_qoriq_driver_10g(void)
+{
+	return &qoriq_drv;
+}
+
+void qoriq_setup_mem_io_10g(struct mem_io memio)
+{
+	io = memio;
+}
-- 
1.9.1


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

* [PATCH net-next v3 6/7] net: phy: add bee algorithm for kr training
  2020-06-22 13:35 [PATCH net-next v2 0/9] net: ethernet backplane support on DPAA1 Florinel Iordache
                   ` (3 preceding siblings ...)
  2020-06-22 13:35 ` [PATCH net-next v3 5/7] net: phy: enable qoriq backplane support Florinel Iordache
@ 2020-06-22 13:35 ` Florinel Iordache
  2020-06-22 13:35 ` [PATCH net-next v3 7/7] arm64: dts: add serdes and mdio description Florinel Iordache
       [not found] ` <1592832924-31733-5-git-send-email-florinel.iordache@nxp.com>
  6 siblings, 0 replies; 24+ messages in thread
From: Florinel Iordache @ 2020-06-22 13:35 UTC (permalink / raw)
  To: davem, netdev, andrew, f.fainelli, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, leoyang.li, madalin.bucur, ioana.ciornei, linux-kernel,
	Florinel Iordache

Add support for bee equalization algorithm used by kr training:
3-Taps Bit Edge Equalization (BEE) algorithm

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 drivers/net/phy/backplane/Kconfig  |   11 +
 drivers/net/phy/backplane/Makefile |    1 +
 drivers/net/phy/backplane/eq_bee.c | 1076 ++++++++++++++++++++++++++++++++++++
 3 files changed, 1088 insertions(+)
 create mode 100644 drivers/net/phy/backplane/eq_bee.c

diff --git a/drivers/net/phy/backplane/Kconfig b/drivers/net/phy/backplane/Kconfig
index 3e20a78..ee5cf1c 100644
--- a/drivers/net/phy/backplane/Kconfig
+++ b/drivers/net/phy/backplane/Kconfig
@@ -19,6 +19,17 @@ config ETH_BACKPLANE_FIXED
 	  No Equalization algorithm is used to adapt the initial coefficients
 	  initially set by the user.
 
+config ETH_BACKPLANE_BEE
+	tristate "3-Taps Bit Edge Equalization (BEE) algorithm"
+	depends on ETH_BACKPLANE
+	help
+	  This module provides a driver for BEE algorithm: 3-Taps
+	  Bit Edge Equalization. This algorithm is using a method
+	  based on 3-taps coefficients for mitigating intersymbol
+	  interference (ISI) in high-speed backplane applications.
+	  The initial values for algorithm coefficient values are
+	  user configurable and used as a starting point of the algorithm.
+
 config ETH_BACKPLANE_QORIQ
 	tristate "QorIQ Ethernet Backplane driver"
 	depends on ETH_BACKPLANE
diff --git a/drivers/net/phy/backplane/Makefile b/drivers/net/phy/backplane/Makefile
index 3ae3d8b..30a2ebb 100644
--- a/drivers/net/phy/backplane/Makefile
+++ b/drivers/net/phy/backplane/Makefile
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_ETH_BACKPLANE) += eth_backplane.o
 obj-$(CONFIG_ETH_BACKPLANE_FIXED) += eq_fixed.o
+obj-$(CONFIG_ETH_BACKPLANE_BEE) += eq_bee.o
 obj-$(CONFIG_ETH_BACKPLANE_QORIQ) += eth_backplane_qoriq.o
 
 eth_backplane-objs	:= backplane.o link_training.o
diff --git a/drivers/net/phy/backplane/eq_bee.c b/drivers/net/phy/backplane/eq_bee.c
new file mode 100644
index 0000000..045ed7e
--- /dev/null
+++ b/drivers/net/phy/backplane/eq_bee.c
@@ -0,0 +1,1076 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/* 3-Taps Bit Edge Equalization (BEE) algorithm
+ *
+ * Copyright 2019-2020 NXP
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "equalization.h"
+
+#define ALGORITHM_NAME		"backplane_bee_3tap"
+#define ALGORITHM_DESCR		"3-Taps Bit Edge Equalization"
+#define ALGORITHM_VERSION	"1.5.5"
+
+/* BEE algorithm timeouts */
+#define TIMEOUT_LONG				3
+#define TIMEOUT_M1				3
+
+/* Size of equalization snapshots data collection */
+#define EQ_SNAPSHOTS_SIZE			10
+
+/* Rx link quality conditions:
+ * The following macros are used to determine the Rx link quality
+ * which is used to decide if/when to proceed with BinLong/BinM1 modules.
+ * The code that considers Rx in good quality is always in place:
+ * Rx link is in 'good quality' if:
+ * Bin1, Bin2 and Bin3 are toggling
+ *
+ * These macros are used to enable less quality link conditions.
+ * If Rx link quality is considered good enough then proceed to BinLong/BinM1
+ */
+
+/* Rx is 'less quality' if:
+ * Bin1 is toggling
+ * AND
+ *   Bin2 is Early, GainMF stuck at max_eq_gain and Bin3 is Late
+ *   OR
+ *   Bin2 is Late, GainMF stuck at min_eq_gain and Bin3 is Early
+ */
+#define ENABLE_LESS_QUALITY_CONDITION
+
+/* Rx is 'even less quality' if:
+ * Bin1 is Early AND GainHF stuck at max_eq_gain and Bin2 is Late AND
+ *     GainMF stuck at min_eq_gain
+ * OR
+ * Bin1 is Late AND GainHF stuck at min_eq_gain AND
+ *     Bin2 is Early, GainMF stuck at max_eq_gain
+ */
+#define ENABLE_EVEN_LESS_QUALITY_CONDITION
+
+/* Rx is 'seemingly quality' if:
+ * Bin1 is always Late for all snapshots AND
+ *     GainHF is stuck at min_eq_gain
+ * AND
+ * Bin2 and Bin3 are both Toggling
+ */
+#define ENABLE_SEEMINGLY_QUALITY_CONDITION
+
+enum bin_state {
+	BIN_INVALID,
+	BIN_EARLY,
+	BIN_TOGGLE,
+	BIN_LATE
+};
+
+struct eq_data_priv {
+	/* Equalization Algorithm setup data */
+	struct equalizer_driver eqdrv;
+
+	/* Bin state */
+	enum bin_state bin_m1_state;
+	enum bin_state bin_long_state;
+	enum bin_state prev_bin_m1_state;
+	enum bin_state prev_bin_long_state;
+
+	/* Bin training status */
+	bool bin_m1_stop;
+	bool bin_long_stop;
+	int m1_min_max_cnt;
+	int long_min_max_cnt;
+
+	/* Algorithm controlled value */
+	u32 ld_update;
+
+	/* Bit edge statistics: Bin snapshots */
+	s16 bin1_snapshot[EQ_SNAPSHOTS_SIZE];
+	s16 bin2_snapshot[EQ_SNAPSHOTS_SIZE];
+	s16 bin3_snapshot[EQ_SNAPSHOTS_SIZE];
+	s16 bin_long_snapshot[EQ_SNAPSHOTS_SIZE];
+	s16 bin_m1_snapshot[EQ_SNAPSHOTS_SIZE];
+	s16 bin_offset_snapshot[EQ_SNAPSHOTS_SIZE];
+
+	/* Gain snapshots */
+	u8 gain_hf_snapshot[EQ_SNAPSHOTS_SIZE];
+	u8 gain_mf_snapshot[EQ_SNAPSHOTS_SIZE];
+
+	/* Offset status snapshot */
+	u8 osestat_snapshot[EQ_SNAPSHOTS_SIZE];
+};
+
+static enum bin_state get_bin_snapshots_state(struct eq_data_priv *priv,
+					      enum eqc_type type)
+{
+	s16 bin_snp_av_thr_low, bin_snp_av_thr_high;
+	s16 snapshot_average, snapshot_sum = 0;
+	struct eqc_range *bin_range;
+	s16 *bin_snapshot;
+	int i;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return BIN_INVALID;
+	}
+
+	switch (type) {
+	case EQC_BIN_1:
+		bin_snapshot = priv->bin1_snapshot;
+		break;
+	case EQC_BIN_2:
+		bin_snapshot = priv->bin2_snapshot;
+		break;
+	case EQC_BIN_3:
+		bin_snapshot = priv->bin3_snapshot;
+		break;
+	case EQC_BIN_LONG:
+		bin_snapshot = priv->bin_long_snapshot;
+		break;
+	case EQC_BIN_OFFSET:
+		bin_snapshot = priv->bin_offset_snapshot;
+		break;
+	case EQC_BIN_M1:
+		bin_snapshot = priv->bin_m1_snapshot;
+		break;
+	default:
+		/* invalid bin type */
+		return BIN_INVALID;
+	}
+	if (!bin_snapshot)
+		return BIN_INVALID;
+
+	bin_range = priv->eqdrv.equalizer->ops.get_counter_range(type);
+	if (!bin_range)
+		return BIN_INVALID;
+
+	bin_snp_av_thr_low = bin_range->mid_low;
+	bin_snp_av_thr_high = bin_range->mid_high;
+
+	for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++)
+		snapshot_sum += bin_snapshot[i];
+
+	snapshot_average = (s16)(snapshot_sum / EQ_SNAPSHOTS_SIZE);
+
+	if (snapshot_average >= -256 && snapshot_average < bin_snp_av_thr_low)
+		return BIN_EARLY;
+	else if (snapshot_average >= bin_snp_av_thr_low &&
+		 snapshot_average < bin_snp_av_thr_high)
+		return BIN_TOGGLE;
+	else if (snapshot_average >= bin_snp_av_thr_high &&
+		 snapshot_average <= 255)
+		return BIN_LATE;
+
+	return BIN_INVALID;
+}
+
+static u32 process_bin_m1_toggle(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+	enum req_type prev_req_cm1;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return update;
+	}
+
+	prev_req_cm1 = lt_decode_coef_update(priv->ld_update, C_M1);
+
+	/* Toggle path */
+	if (priv->prev_bin_m1_state == priv->bin_m1_state) {
+		/* Hold C- */
+		update = lt_encode_startup_request(REQ_HOLD);
+	} else {
+		update = lt_encode_startup_request(REQ_HOLD);
+		/* If previous step moved C- repeat C- move */
+		if (prev_req_cm1 == REQ_INC ||
+		    prev_req_cm1 == REQ_DEC)
+			update = lt_encode_request(update, prev_req_cm1, C_M1);
+	}
+
+	return update;
+}
+
+static u32 process_bin_m1_prev_toggle(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+	enum req_type prev_req_cm1;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return update;
+	}
+
+	prev_req_cm1 = lt_decode_coef_update(priv->ld_update, C_M1);
+
+	update = lt_encode_startup_request(REQ_HOLD);
+	/* If previous step moved C- go back on C- */
+	if (prev_req_cm1 == REQ_INC)
+		update = lt_encode_request(update, REQ_DEC, C_M1);
+	if (prev_req_cm1 == REQ_DEC)
+		update = lt_encode_request(update, REQ_INC, C_M1);
+
+	return update;
+}
+
+static u32 process_bin_m1_early(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+	enum coef_status lpst_cm1;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return update;
+	}
+
+	/* Get LP coefficient status to determine
+	 * if coefficient is in range or reached the limit thresholds
+	 * IF the coefficient is at MIN/MAX and still want to INC/DEC
+	 * THEN do we are done with this module
+	 */
+	lpst_cm1 = lt_get_lp_coef_status(priv->eqdrv.lane, C_M1);
+
+	/* Early path */
+	if (lpst_cm1 == COEF_MAX) {
+		/* Hold C- */
+		update = lt_encode_startup_request(REQ_HOLD);
+	} else {
+		/* request Increment C- */
+		update = lt_encode_request(update, REQ_INC, C_M1);
+	}
+
+	return update;
+}
+
+static u32 process_bin_m1_late(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+	enum coef_status lpst_cm1;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return update;
+	}
+
+	/* Get LP coefficient status to determine
+	 * if coefficient is in range or reached the limit thresholds
+	 * IF the coefficient is at MIN/MAX and still want to INC/DEC
+	 * THEN do we are done with this module
+	 */
+	lpst_cm1 = lt_get_lp_coef_status(priv->eqdrv.lane, C_M1);
+
+	/* Late path */
+	if (lpst_cm1 == COEF_MIN) {
+		/* Hold C- */
+		update = lt_encode_startup_request(REQ_HOLD);
+	} else {
+		/* request Decrement C- */
+		update = lt_encode_request(update, REQ_DEC, C_M1);
+	}
+
+	return update;
+}
+
+static u32 process_bin_m1_antipodal(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return update;
+	}
+
+	if (priv->bin_m1_state == BIN_LATE) {
+		/* request Decrement C- */
+		update = lt_encode_request(update, REQ_DEC, C_M1);
+	} else {
+		/* Hold C- */
+		update = lt_encode_startup_request(REQ_HOLD);
+	}
+
+	return update;
+}
+
+/* process_bin_m1
+ *
+ * Bin_M1:
+ *   contains the scoring of initial edges on pulses that are 1UI long
+ *      following non-single bits
+ *   used to adjust LP coefficient: C_M1
+ */
+static void process_bin_m1(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return;
+	}
+
+	if (priv->bin_m1_state == BIN_INVALID) {
+		phydev_err(priv->eqdrv.phydev, "Invalid Bin_M1 state\n");
+		return;
+	}
+
+	if (priv->bin_m1_state == BIN_TOGGLE) {
+		update = process_bin_m1_toggle(priv);
+	} else {
+		if (priv->prev_bin_m1_state == BIN_TOGGLE) {
+			update = process_bin_m1_prev_toggle(priv);
+		} else {
+			if (priv->prev_bin_m1_state == priv->bin_m1_state) {
+				if (priv->bin_m1_state == BIN_LATE)
+					update = process_bin_m1_late(priv);
+				else
+					update = process_bin_m1_early(priv);
+			} else {
+				update = process_bin_m1_antipodal(priv);
+			}
+		}
+	}
+
+	/* Store current algorithm decision
+	 * as previous algorithm ld_update for next step
+	 */
+	priv->ld_update = update;
+}
+
+static u32 process_bin_long_toggle(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+	enum req_type prev_req_cp1, prev_req_cz0;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return update;
+	}
+
+	prev_req_cp1 = lt_decode_coef_update(priv->ld_update, C_P1);
+	prev_req_cz0 = lt_decode_coef_update(priv->ld_update, C_Z0);
+
+	/* Toggle path */
+	if (priv->prev_bin_long_state == priv->bin_long_state) {
+		/* Hold C+ and C0 */
+		update = lt_encode_startup_request(REQ_HOLD);
+	} else {
+		update = lt_encode_startup_request(REQ_HOLD);
+		/* If previous step moved C+/C0 repeat C+/C0 move */
+		if (prev_req_cp1 == REQ_INC ||
+		    prev_req_cp1 == REQ_DEC ||
+		    prev_req_cz0 == REQ_INC ||
+		    prev_req_cz0 == REQ_DEC) {
+			update = lt_encode_request(update, prev_req_cp1, C_P1);
+			update = lt_encode_request(update, prev_req_cz0, C_Z0);
+		}
+	}
+
+	return update;
+}
+
+static u32 process_bin_long_prev_toggle(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+	enum req_type prev_req_cp1, prev_req_cz0;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return update;
+	}
+
+	prev_req_cp1 = lt_decode_coef_update(priv->ld_update, C_P1);
+	prev_req_cz0 = lt_decode_coef_update(priv->ld_update, C_Z0);
+
+	/* If previous step moved C+/C0 then go back on C+/C0 */
+	if (prev_req_cp1 == REQ_INC)
+		update = lt_encode_request(update, REQ_DEC, C_P1);
+	if (prev_req_cp1 == REQ_DEC)
+		update = lt_encode_request(update, REQ_INC, C_P1);
+	if (prev_req_cz0 == REQ_INC)
+		update = lt_encode_request(update, REQ_DEC, C_Z0);
+	if (prev_req_cz0 == REQ_DEC)
+		update = lt_encode_request(update, REQ_INC, C_Z0);
+
+	return update;
+}
+
+static u32 process_bin_long_early(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+	enum coef_status lpst_cp1, lpst_cz0;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return update;
+	}
+
+	/* Get LP coefficient status to determine
+	 * if coefficient is in range or reached the limit thresholds
+	 * IF the coefficient is at MIN/MAX and still want to INC/DEC
+	 * THEN do we are done with this module
+	 */
+	lpst_cp1 = lt_get_lp_coef_status(priv->eqdrv.lane, C_P1);
+	lpst_cz0 = lt_get_lp_coef_status(priv->eqdrv.lane, C_Z0);
+
+	/* Early path (make edge later) */
+	if (lpst_cp1 == COEF_MAX) {
+		if (lpst_cz0 == COEF_MAX) {
+			/* Hold C+, C0 */
+			update = lt_encode_startup_request(REQ_HOLD);
+		} else {
+			/* request Increment C0 and
+			 * Decrement C+
+			 */
+			update = lt_encode_request(update, REQ_INC, C_Z0);
+			update = lt_encode_request(update, REQ_DEC, C_P1);
+		}
+	} else {
+		/* request Increment C+ */
+		update = lt_encode_request(update, REQ_INC, C_P1);
+	}
+
+	return update;
+}
+
+static u32 process_bin_long_late(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+	enum coef_status lpst_cp1, lpst_cz0;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return update;
+	}
+
+	/* Get LP coefficient status to determine
+	 * if coefficient is in range or reached the limit thresholds
+	 * IF the coefficient is at MIN/MAX and still want to INC/DEC
+	 * THEN do we are done with this module
+	 */
+	lpst_cp1 = lt_get_lp_coef_status(priv->eqdrv.lane, C_P1);
+	lpst_cz0 = lt_get_lp_coef_status(priv->eqdrv.lane, C_Z0);
+
+	/* Late path (make edge earlier) */
+	if (lpst_cp1 == COEF_MIN) {
+		if (lpst_cz0 == COEF_MIN) {
+			/* Hold C0 */
+			update = lt_encode_startup_request(REQ_HOLD);
+		} else {
+			/* request Decrement C0 */
+			update = lt_encode_request(update, REQ_DEC, C_Z0);
+		}
+	} else {
+		/* request Decrement C+ */
+		update = lt_encode_request(update, REQ_DEC, C_P1);
+	}
+
+	return update;
+}
+
+static u32 process_bin_long_antipodal(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+	enum req_type prev_req_cp1;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return update;
+	}
+
+	prev_req_cp1 = lt_decode_coef_update(priv->ld_update, C_P1);
+
+	/* Request move on C+ and C0 */
+	/* If previous step moved C+ then go back on C+ */
+	if (prev_req_cp1 == REQ_INC)
+		update = lt_encode_request(update, REQ_DEC, C_P1);
+	if (prev_req_cp1 == REQ_DEC)
+		update = lt_encode_request(update, REQ_INC, C_P1);
+
+	if (priv->bin_long_state == BIN_LATE) {
+		/* request Decrement C0 */
+		update = lt_encode_request(update, REQ_DEC, C_Z0);
+	} else {
+		/* request Increment C0 */
+		update = lt_encode_request(update, REQ_INC, C_Z0);
+	}
+
+	return update;
+}
+
+/* process_bin_long
+ *
+ * Bin_Long:
+ *   contains the scoring of final edges on pulses longer than 7UI long
+ *   used to adjust LP coefficients: C_P1 and C_Z0
+ */
+static void process_bin_long(struct eq_data_priv *priv)
+{
+	u32 update = lt_encode_startup_request(REQ_HOLD);
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return;
+	}
+
+	if (priv->bin_long_state == BIN_INVALID) {
+		phydev_err(priv->eqdrv.phydev, "Invalid Bin_Long state\n");
+		return;
+	}
+
+	if (priv->bin_long_state == BIN_TOGGLE) {
+		update = process_bin_long_toggle(priv);
+	} else {
+		if (priv->prev_bin_long_state == BIN_TOGGLE) {
+			update = process_bin_long_prev_toggle(priv);
+		} else {
+			if (priv->prev_bin_long_state == priv->bin_long_state) {
+				if (priv->bin_long_state == BIN_LATE)
+					update = process_bin_long_late(priv);
+				else
+					update = process_bin_long_early(priv);
+			} else {
+				update = process_bin_long_antipodal(priv);
+			}
+		}
+	}
+
+	/* Store current algorithm decision
+	 * as previous algorithm ld_update for next step
+	 */
+	priv->ld_update = update;
+}
+
+/* Callbacks:
+ * required by generic equalization_algorithm
+ */
+static void process_bad_state(struct eq_data_priv *priv)
+{
+	bool lp_at_init, lp_at_preset;
+	u32 req;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return;
+	}
+
+	lp_at_init = lt_is_lp_at_startup(priv->eqdrv.lane, REQ_INIT);
+	lp_at_preset = lt_is_lp_at_startup(priv->eqdrv.lane, REQ_PRESET);
+
+	if (lp_at_init) {
+		/* Try Request Preset */
+		req = lt_encode_startup_request(REQ_PRESET);
+		lt_lp_update(priv->eqdrv.lane, req);
+	} else if (lp_at_preset) {
+		/* LT ERROR
+		 * set lt_error flag to prevent reaching
+		 * training state = TRAINED
+		 * and resume training in case of LT error
+		 */
+		lt_set_error(priv->eqdrv.lane, true);
+		phydev_err(priv->eqdrv.phydev,
+			   "LT Error: CDR_LOCK is zero on Preset\n");
+	} else {
+		/* Move LP back to previous C-, C0, C+ and HOLD */
+		lt_move_lp_back(priv->eqdrv.lane);
+	}
+}
+
+static bool collect_bin_counters(struct eq_data_priv *priv,
+				 enum eqc_type type)
+{
+	const struct equalizer_ops *eqops;
+	s16 *bin_snapshot = NULL;
+	int snp_size;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return false;
+	}
+
+	/* collect Bin snapshots */
+	switch (type) {
+	case EQC_BIN_1:
+		bin_snapshot = priv->bin1_snapshot;
+		break;
+	case EQC_BIN_2:
+		bin_snapshot = priv->bin2_snapshot;
+		break;
+	case EQC_BIN_3:
+		bin_snapshot = priv->bin3_snapshot;
+		break;
+	case EQC_BIN_LONG:
+		bin_snapshot = priv->bin_long_snapshot;
+		break;
+	case EQC_BIN_OFFSET:
+		bin_snapshot = priv->bin_offset_snapshot;
+		break;
+	case EQC_BIN_M1:
+		bin_snapshot = priv->bin_m1_snapshot;
+		break;
+	default:
+		/* invalid bin type */
+		return false;
+	}
+	if (!bin_snapshot)
+		return false;
+
+	eqops = &priv->eqdrv.equalizer->ops;
+	if (!eqops) {
+		phydev_err(priv->eqdrv.phydev,
+			   "No operations for equalizer %s %s\n",
+			   priv->eqdrv.equalizer->name,
+			   priv->eqdrv.equalizer->version);
+		return false;
+	}
+	snp_size = eqops->collect_counters(priv->eqdrv.reg_base, type,
+					   bin_snapshot, EQ_SNAPSHOTS_SIZE);
+	/* Check if snapshots collection failed */
+	if (snp_size < EQ_SNAPSHOTS_SIZE) {
+		phydev_err(priv->eqdrv.phydev,
+			   "Counters collection failed for equalizer %s %s\n",
+			   priv->eqdrv.equalizer->name,
+			   priv->eqdrv.equalizer->version);
+		return false;
+	}
+
+	/* if CDR_LOCK = 0: Statistics are invalid */
+	if (!backplane_is_cdr_lock(priv->eqdrv.lane, true)) {
+		process_bad_state(priv);
+		return false;
+	}
+
+	return true;
+}
+
+static bool collect_bit_edge_statistics(struct eq_data_priv *priv)
+{
+	enum eqc_type st_types[] = { EQC_GAIN_HF, EQC_GAIN_MF, EQC_EQOFFSET };
+	s16 status_counters[ARRAY_SIZE(st_types)][EQ_SNAPSHOTS_SIZE];
+	const struct equalizer_ops *eqops;
+	int i, snp_size;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return false;
+	}
+
+	/* collect Bin snapshots */
+	if (!collect_bin_counters(priv, EQC_BIN_1))
+		return false;
+	if (!collect_bin_counters(priv, EQC_BIN_2))
+		return false;
+	if (!collect_bin_counters(priv, EQC_BIN_3))
+		return false;
+	if (!collect_bin_counters(priv, EQC_BIN_LONG))
+		return false;
+	if (!collect_bin_counters(priv, EQC_BIN_OFFSET))
+		return false;
+	if (!collect_bin_counters(priv, EQC_BIN_M1))
+		return false;
+
+	/* collect Gains */
+	eqops = &priv->eqdrv.equalizer->ops;
+	if (!eqops) {
+		phydev_err(priv->eqdrv.phydev,
+			   "No operations for equalizer %s %s\n",
+			   priv->eqdrv.equalizer->name,
+			   priv->eqdrv.equalizer->version);
+		return false;
+	}
+	snp_size = eqops->collect_multiple_counters(priv->eqdrv.reg_base,
+						    st_types,
+						    ARRAY_SIZE(st_types),
+						    (s16 *)status_counters,
+						    EQ_SNAPSHOTS_SIZE);
+	/* Check if snapshots collection failed */
+	if (snp_size < EQ_SNAPSHOTS_SIZE) {
+		phydev_err(priv->eqdrv.phydev,
+			   "Counters collection failed for equalizer %s %s\n",
+			   priv->eqdrv.equalizer->name,
+			   priv->eqdrv.equalizer->version);
+		return false;
+	}
+
+	for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++) {
+		priv->gain_hf_snapshot[i] = (u8)status_counters[0][i];
+		priv->gain_mf_snapshot[i] = (u8)status_counters[1][i];
+		priv->osestat_snapshot[i] = (u8)status_counters[2][i];
+	}
+
+	return true;
+}
+
+static void generate_3taps_request(struct eq_data_priv *priv)
+{
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return;
+	}
+
+	/* Store current state as previous state */
+	priv->prev_bin_m1_state = priv->bin_m1_state;
+	priv->prev_bin_long_state = priv->bin_long_state;
+
+	priv->bin_m1_state = get_bin_snapshots_state(priv, EQC_BIN_M1);
+	if (priv->bin_m1_state == BIN_INVALID) {
+		/* invalid state: should never happen */
+		return;
+	}
+
+	priv->bin_long_state = get_bin_snapshots_state(priv, EQC_BIN_LONG);
+	if (priv->bin_long_state == BIN_INVALID) {
+		/* invalid state: should never happen */
+		return;
+	}
+
+	/* Move to BinLong/BinM1 modules:
+	 * Bin Modules order: BinLong before BinM1
+	 * We try to finish BinLong before we do BinM1
+	 */
+
+	/* Process BinLong module
+	 * decide and ask for movement of C+/C0
+	 */
+	if (!priv->bin_long_stop) {
+		process_bin_long(priv);
+		lt_lp_update(priv->eqdrv.lane, priv->ld_update);
+		if (lt_is_update_of_type(priv->ld_update, REQ_HOLD)) {
+			/* Sent All Hold request */
+			priv->long_min_max_cnt++;
+			if (priv->long_min_max_cnt >= TIMEOUT_LONG)
+				priv->bin_long_stop = true;
+		} else {
+			/* Sent C Inc/Dec request */
+			priv->long_min_max_cnt = 0;
+		}
+		return;
+	}
+
+	/* Process BinM1 module
+	 * decide and ask for movement of C-
+	 */
+	if (!priv->bin_m1_stop) {
+		process_bin_m1(priv);
+		lt_lp_update(priv->eqdrv.lane, priv->ld_update);
+		if (lt_is_update_of_type(priv->ld_update, REQ_HOLD)) {
+			/* Sent All Hold request */
+			priv->m1_min_max_cnt++;
+			if (priv->m1_min_max_cnt >= TIMEOUT_M1)
+				priv->bin_m1_stop = true;
+		} else {
+			/* Sent C Inc/Dec request */
+			priv->m1_min_max_cnt = 0;
+		}
+		return;
+	}
+}
+
+static bool is_rx_ok(struct eq_data_priv *priv)
+{
+	struct eqc_range *gain_range, *osestat_range;
+	u8 osestat_mid_low, osestat_mid_high;
+	enum bin_state bin1_snapshot_state;
+	enum bin_state bin2_snapshot_state;
+	enum bin_state bin3_snapshot_state;
+	const struct equalizer_ops *eqops;
+	bool rx_quality_1, rx_quality_2;
+	bool is_ok, rx_good_quality;
+	u8 min_eq_gain, max_eq_gain;
+	u8 min_snp, max_snp;
+	s16 snapshot;
+	int i;
+
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return false;
+	}
+
+	/* Checking Bins/Gains after LP has updated its TX */
+	eqops = &priv->eqdrv.equalizer->ops;
+	if (!eqops)
+		return false;
+	gain_range = eqops->get_counter_range(EQC_GAIN_HF);
+	if (!gain_range)
+		return false;
+	osestat_range = eqops->get_counter_range(EQC_EQOFFSET);
+	if (!osestat_range)
+		return false;
+
+	min_eq_gain = (u8)gain_range->min;
+	max_eq_gain = (u8)gain_range->max;
+	osestat_mid_low = (u8)osestat_range->mid_low;
+	osestat_mid_high = (u8)osestat_range->mid_high;
+
+	/* CDR_LOCK must be 1 */
+	if (!backplane_is_cdr_lock(priv->eqdrv.lane, true))
+		return false;
+
+	/* Offset Bin must NOT be 10 of the same value */
+	rx_good_quality = false;
+	snapshot = priv->bin_offset_snapshot[0];
+	for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++) {
+		if (snapshot != priv->bin_offset_snapshot[i]) {
+			rx_good_quality = true;
+			break;
+		}
+	}
+	if (!rx_good_quality)
+		return false;
+
+	/* Offset status must dither (+/-2) around MidRange value
+	 * What we want to see is that the Offset has settled to a value
+	 * somewhere between: mid-range low and mid-range high and that
+	 * the series of snapshot values are +/-2 of the settled value.
+	 */
+	rx_good_quality = true;
+	min_snp = priv->osestat_snapshot[0];
+	max_snp = priv->osestat_snapshot[0];
+	for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++) {
+		if (priv->osestat_snapshot[i] < osestat_mid_low ||
+		    priv->osestat_snapshot[i] > osestat_mid_high) {
+			rx_good_quality = false;
+			break;
+		}
+		if (priv->osestat_snapshot[i] < min_snp)
+			min_snp = priv->osestat_snapshot[i];
+		if (priv->osestat_snapshot[i] > max_snp)
+			max_snp = priv->osestat_snapshot[i];
+	}
+	if (max_snp - min_snp > 4)
+		rx_good_quality = false;
+	if (!rx_good_quality)
+		return false;
+
+	/* The Rx is in good quality if:
+	 * Bin1, Bin2, and Bin3 are toggling
+	 * Proceed to BinLong/BinM1 modules
+	 */
+	bin1_snapshot_state = get_bin_snapshots_state(priv, EQC_BIN_1);
+	bin2_snapshot_state = get_bin_snapshots_state(priv, EQC_BIN_2);
+	bin3_snapshot_state = get_bin_snapshots_state(priv, EQC_BIN_3);
+
+	rx_good_quality = (bin1_snapshot_state == BIN_TOGGLE &&
+			   bin2_snapshot_state == BIN_TOGGLE &&
+			   bin3_snapshot_state == BIN_TOGGLE);
+
+	/* If Rx is in good quality then proceed to BinLong/BinM1 */
+	if (rx_good_quality)
+		return true;
+
+#ifdef ENABLE_LESS_QUALITY_CONDITION
+	rx_quality_1 = false;
+	rx_quality_2 = false;
+	if (bin1_snapshot_state == BIN_TOGGLE) {
+		if (bin2_snapshot_state == BIN_EARLY &&
+		    bin3_snapshot_state == BIN_LATE) {
+			/* check if GainMF is stuck at max_eq_gain */
+			rx_quality_1 = true;
+			for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++) {
+				if (priv->gain_mf_snapshot[i] != max_eq_gain) {
+					rx_quality_1 = false;
+					break;
+				}
+			}
+		}
+		if (bin2_snapshot_state == BIN_LATE &&
+		    bin3_snapshot_state == BIN_EARLY) {
+			/* check if GainMF is stuck at min_eq_gain */
+			rx_quality_2 = true;
+			for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++) {
+				if (priv->gain_mf_snapshot[i] != min_eq_gain) {
+					rx_quality_2 = false;
+					break;
+				}
+			}
+		}
+	}
+
+	/* If Rx is less quality then proceed to BinLong/BinM1 */
+	if (rx_quality_1 || rx_quality_2)
+		return true;
+#endif
+
+#ifdef ENABLE_EVEN_LESS_QUALITY_CONDITION
+	rx_quality_1 = false;
+	rx_quality_2 = false;
+	if (bin1_snapshot_state == BIN_EARLY &&
+	    bin2_snapshot_state == BIN_LATE) {
+		/* check if GainHF is stuck at max_eq_gain */
+		is_ok = true;
+		for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++) {
+			if (priv->gain_hf_snapshot[i] != max_eq_gain) {
+				is_ok = false;
+				break;
+			}
+		}
+		if (is_ok) {
+			/* check if GainMF is stuck at min_eq_gain */
+			is_ok = true;
+			for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++) {
+				if (priv->gain_mf_snapshot[i] != min_eq_gain) {
+					is_ok = false;
+					break;
+				}
+			}
+			if (is_ok)
+				rx_quality_1 = true;
+		}
+	}
+	if (bin1_snapshot_state == BIN_LATE &&
+	    bin2_snapshot_state == BIN_EARLY) {
+		/* check if GainHF is stuck at min_eq_gain */
+		is_ok = true;
+		for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++) {
+			if (priv->gain_hf_snapshot[i] != min_eq_gain) {
+				is_ok = false;
+				break;
+			}
+		}
+		if (is_ok) {
+			/* check if GainMF is stuck at max_eq_gain */
+			is_ok = true;
+			for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++) {
+				if (priv->gain_mf_snapshot[i] != max_eq_gain) {
+					is_ok = false;
+					break;
+				}
+			}
+			if (is_ok)
+				rx_quality_2 = true;
+		}
+	}
+
+	/* If Rx is in good quality then proceed to BinLong/BinM1 */
+	if (rx_quality_1 || rx_quality_2)
+		return true;
+#endif
+
+#ifdef ENABLE_SEEMINGLY_QUALITY_CONDITION
+	rx_quality_1 = false;
+	if (bin1_snapshot_state == BIN_LATE &&
+	    bin2_snapshot_state == BIN_TOGGLE &&
+	    bin3_snapshot_state == BIN_TOGGLE) {
+		/* check if GainHF is stuck at min_eq_gain */
+		rx_quality_1 = true;
+		for (i = 0; i < EQ_SNAPSHOTS_SIZE; i++) {
+			if (priv->gain_hf_snapshot[i] != min_eq_gain) {
+				rx_quality_1 = false;
+				break;
+			}
+		}
+	}
+
+	if (rx_quality_1)
+		return true;
+#endif
+
+	return false;
+}
+
+static bool is_eq_done(struct eq_data_priv *priv)
+{
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return false;
+	}
+
+	return (priv->bin_m1_stop && priv->bin_long_stop);
+}
+
+/* BEE 3 TAP Algorithm API */
+
+/* Create BEE 3-TAP Equalization Algorithm */
+static struct eq_data_priv *create(struct equalizer_driver eqdrv)
+{
+	struct eq_data_priv *bee_data;
+
+	bee_data = devm_kzalloc(&eqdrv.phydev->mdio.dev,
+				sizeof(*bee_data), GFP_KERNEL);
+	if (!bee_data)
+		return NULL;
+
+	/* initialize algorithm setup data */
+	bee_data->eqdrv = eqdrv;
+
+	/* initialize specific BEE algorithm data */
+	bee_data->bin_m1_state = BIN_INVALID;
+	bee_data->bin_long_state = BIN_INVALID;
+	bee_data->prev_bin_m1_state = BIN_INVALID;
+	bee_data->prev_bin_long_state = BIN_INVALID;
+	bee_data->m1_min_max_cnt = 0;
+	bee_data->long_min_max_cnt = 0;
+	bee_data->bin_m1_stop = false;
+	bee_data->bin_long_stop = false;
+	bee_data->ld_update = 0;
+
+	return bee_data;
+}
+
+static void destroy(struct eq_data_priv *priv)
+{
+	if (!priv) {
+		pr_err("%s: NULL private data\n", ALGORITHM_NAME);
+		return;
+	}
+
+	kfree(priv);
+}
+
+static const struct equalization_algorithm eq_alg = {
+	.name = ALGORITHM_NAME,
+	.descr = ALGORITHM_DESCR,
+	.version = ALGORITHM_VERSION,
+	.use_local_tx_training = true,
+	.use_remote_tx_training = true,
+	.ops = {
+		.create = create,
+		.destroy = destroy,
+		.is_rx_ok = is_rx_ok,
+		.is_eq_done = is_eq_done,
+		.collect_statistics = collect_bit_edge_statistics,
+		.generate_request = generate_3taps_request,
+		.process_bad_state = process_bad_state,
+		.dump_algorithm_context = NULL,
+	}
+};
+
+static const char * const alg_keys[] = {
+	"bee",
+	"BEE",
+};
+
+static int __init bee_init(void)
+{
+	int i, err;
+
+	pr_info("%s: %s algorithm version %s\n",
+		ALGORITHM_NAME, ALGORITHM_DESCR, ALGORITHM_VERSION);
+
+	/* register BEE algorithm: */
+	for (i = 0; i < ARRAY_SIZE(alg_keys); i++) {
+		err = backplane_eq_register(alg_keys[i], &eq_alg);
+		if (err) {
+			pr_err("%s: '%s' equalization algorithm registration failed\n",
+			       ALGORITHM_NAME, alg_keys[i]);
+		}
+	}
+
+	return 0;
+}
+
+static void __exit bee_exit(void)
+{
+	int i;
+
+	/* unregister BEE algorithm: */
+	for (i = 0; i < ARRAY_SIZE(alg_keys); i++)
+		backplane_eq_unregister(alg_keys[i]);
+
+	pr_info("%s: %s algorithm version %s unloaded\n",
+		ALGORITHM_NAME, ALGORITHM_DESCR, ALGORITHM_VERSION);
+}
+
+module_init(bee_init);
+module_exit(bee_exit);
+
+MODULE_DESCRIPTION("Bit Edge Equalization Algorithm");
+MODULE_AUTHOR("Florinel Iordache <florinel.iordache@nxp.com>");
+MODULE_LICENSE("Dual BSD/GPL");
-- 
1.9.1


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

* [PATCH net-next v3 7/7] arm64: dts: add serdes and mdio description
  2020-06-22 13:35 [PATCH net-next v2 0/9] net: ethernet backplane support on DPAA1 Florinel Iordache
                   ` (4 preceding siblings ...)
  2020-06-22 13:35 ` [PATCH net-next v3 6/7] net: phy: add bee algorithm for kr training Florinel Iordache
@ 2020-06-22 13:35 ` Florinel Iordache
  2020-06-26 19:08   ` Florian Fainelli
       [not found] ` <1592832924-31733-5-git-send-email-florinel.iordache@nxp.com>
  6 siblings, 1 reply; 24+ messages in thread
From: Florinel Iordache @ 2020-06-22 13:35 UTC (permalink / raw)
  To: davem, netdev, andrew, f.fainelli, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, leoyang.li, madalin.bucur, ioana.ciornei, linux-kernel,
	Florinel Iordache

Add dt nodes with serdes, lanes, mdio generic description for supported
platform: ls1046. This is a prerequisite to enable backplane on device
tree for these platforms.

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi     | 33 +++++++++++++++++++++-
 .../boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi    |  5 ++--
 .../boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi    |  5 ++--
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index d4c1da3..c7d845f 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -3,7 +3,7 @@
  * Device Tree Include file for Freescale Layerscape-1046A family SoC.
  *
  * Copyright 2016 Freescale Semiconductor, Inc.
- * Copyright 2018 NXP
+ * Copyright 2018, 2020 NXP
  *
  * Mingkai Hu <mingkai.hu@nxp.com>
  */
@@ -735,6 +735,37 @@
 			status = "disabled";
 		};
 
+		serdes1: serdes@1ea0000 {
+			compatible = "serdes-10g";
+			reg = <0x0 0x1ea0000 0 0x00002000>;
+			reg-names = "serdes", "serdes-10g";
+			big-endian;
+
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x00 0x1ea0000 0x00002000>;
+			lane_a: lane@800 {
+				compatible = "lane-10g";
+				reg = <0x800 0x40>;
+				reg-names = "lane", "serdes-lane";
+			};
+			lane_b: lane@840 {
+				compatible = "lane-10g";
+				reg = <0x840 0x40>;
+				reg-names = "lane", "serdes-lane";
+			};
+			lane_c: lane@880 {
+				compatible = "lane-10g";
+				reg = <0x880 0x40>;
+				reg-names = "lane", "serdes-lane";
+			};
+			lane_d: lane@8c0 {
+				compatible = "lane-10g";
+				reg = <0x8c0 0x40>;
+				reg-names = "lane", "serdes-lane";
+			};
+		};
+
 		pcie_ep@3600000 {
 			compatible = "fsl,ls1046a-pcie-ep", "fsl,ls-pcie-ep";
 			reg = <0x00 0x03600000 0x0 0x00100000
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi
index dbd2fc3..d6191f1 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi
@@ -3,6 +3,7 @@
  * QorIQ FMan v3 10g port #0 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
+ * Copyright 2020 NXP
  *
  */
 
@@ -21,7 +22,7 @@ fman@1a00000 {
 		fsl,fman-10g-port;
 	};
 
-	ethernet@f0000 {
+	mac9: ethernet@f0000 {
 		cell-index = <0x8>;
 		compatible = "fsl,fman-memac";
 		reg = <0xf0000 0x1000>;
@@ -29,7 +30,7 @@ fman@1a00000 {
 		pcsphy-handle = <&pcsphy6>;
 	};
 
-	mdio@f1000 {
+	mdio9: mdio@f1000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi
index 6fc5d25..1f6f28f 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi
@@ -3,6 +3,7 @@
  * QorIQ FMan v3 10g port #1 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
+ * Copyright 2020 NXP
  *
  */
 
@@ -21,7 +22,7 @@ fman@1a00000 {
 		fsl,fman-10g-port;
 	};
 
-	ethernet@f2000 {
+	mac10: ethernet@f2000 {
 		cell-index = <0x9>;
 		compatible = "fsl,fman-memac";
 		reg = <0xf2000 0x1000>;
@@ -29,7 +30,7 @@ fman@1a00000 {
 		pcsphy-handle = <&pcsphy7>;
 	};
 
-	mdio@f3000 {
+	mdio10: mdio@f3000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
-- 
1.9.1


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

* Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver support
       [not found] ` <1592832924-31733-5-git-send-email-florinel.iordache@nxp.com>
@ 2020-06-22 14:24   ` Andrew Lunn
  2020-06-22 14:39     ` [EXT] " Florinel Iordache
  2020-06-22 15:08     ` Madalin Bucur (OSS)
  2020-06-22 16:29   ` kernel test robot
  2020-06-22 21:46   ` Jakub Kicinski
  2 siblings, 2 replies; 24+ messages in thread
From: Andrew Lunn @ 2020-06-22 14:24 UTC (permalink / raw)
  To: Florinel Iordache
  Cc: davem, netdev, f.fainelli, hkallweit1, linux, devicetree,
	linux-doc, robh+dt, mark.rutland, kuba, corbet, shawnguo,
	leoyang.li, madalin.bucur, ioana.ciornei, linux-kernel

On Mon, Jun 22, 2020 at 04:35:21PM +0300, Florinel Iordache wrote:
> Add support for backplane kr generic driver including link training
> (ieee802.3ap/ba) and fixed equalization algorithm

Hi Florinel

This is still a PHY device. I don't remember any discussions which
resolved the issues of if at the end of the backplane there is another
PHY.

It makes little sense to repost this code until we have this problem
discussed and a way forward decided on. It fits into the discussion
Russell and Ioana are having about representing PCS drivers. Please
contribute to that.

	Andrew

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

* RE: [EXT] Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver support
  2020-06-22 14:24   ` [PATCH net-next v3 4/7] net: phy: add backplane kr driver support Andrew Lunn
@ 2020-06-22 14:39     ` Florinel Iordache
  2020-06-26 19:05       ` Florian Fainelli
  2020-06-22 15:08     ` Madalin Bucur (OSS)
  1 sibling, 1 reply; 24+ messages in thread
From: Florinel Iordache @ 2020-06-22 14:39 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: davem, netdev, f.fainelli, hkallweit1, linux, devicetree,
	linux-doc, robh+dt, mark.rutland, kuba, corbet, shawnguo, Leo Li,
	Madalin Bucur (OSS),
	Ioana Ciornei, linux-kernel, Florinel Iordache

> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Monday, June 22, 2020 5:25 PM
> To: Florinel Iordache <florinel.iordache@nxp.com>
> Cc: davem@davemloft.net; netdev@vger.kernel.org; f.fainelli@gmail.com;
> hkallweit1@gmail.com; linux@armlinux.org.uk; devicetree@vger.kernel.org;
> linux-doc@vger.kernel.org; robh+dt@kernel.org; mark.rutland@arm.com;
> kuba@kernel.org; corbet@lwn.net; shawnguo@kernel.org; Leo Li
> <leoyang.li@nxp.com>; Madalin Bucur (OSS) <madalin.bucur@oss.nxp.com>;
> Ioana Ciornei <ioana.ciornei@nxp.com>; linux-kernel@vger.kernel.org
> Subject: [EXT] Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver
> support
> 
> Caution: EXT Email
> 
> On Mon, Jun 22, 2020 at 04:35:21PM +0300, Florinel Iordache wrote:
> > Add support for backplane kr generic driver including link training
> > (ieee802.3ap/ba) and fixed equalization algorithm
> 
> Hi Florinel
> 
> This is still a PHY device. I don't remember any discussions which resolved the
> issues of if at the end of the backplane there is another PHY.
> 
> It makes little sense to repost this code until we have this problem discussed and
> a way forward decided on. It fits into the discussion Russell and Ioana are having
> about representing PCS drivers. Please contribute to that.
> 
>         Andrew

Hi Andrew,

Yes, you are right: we decided to send only support for DPAA1 using current approach as a PHY device
(as mentioned in cover-letter), until PCS representation will be fully clarified.
The entire DPAA2 support was removed for now, together with phylink changes.
DPAA1 maintainer (Madalin Bucur) agrees with current representation as a PHY device for DPAA1.
So we would like to have some discussions around this approach for DPAA1 only, as it seems suitable for us.

Regards,
Florinel.

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

* RE: [PATCH net-next v3 4/7] net: phy: add backplane kr driver support
  2020-06-22 14:24   ` [PATCH net-next v3 4/7] net: phy: add backplane kr driver support Andrew Lunn
  2020-06-22 14:39     ` [EXT] " Florinel Iordache
@ 2020-06-22 15:08     ` Madalin Bucur (OSS)
  2020-06-26 19:02       ` Florian Fainelli
  1 sibling, 1 reply; 24+ messages in thread
From: Madalin Bucur (OSS) @ 2020-06-22 15:08 UTC (permalink / raw)
  To: Andrew Lunn, Florinel Iordache
  Cc: davem, netdev, f.fainelli, hkallweit1, linux, devicetree,
	linux-doc, robh+dt, mark.rutland, kuba, corbet, shawnguo, Leo Li,
	Madalin Bucur (OSS),
	Ioana Ciornei, linux-kernel

> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Monday, June 22, 2020 5:25 PM
> To: Florinel Iordache <florinel.iordache@nxp.com>
> Cc: davem@davemloft.net; netdev@vger.kernel.org; f.fainelli@gmail.com;
> hkallweit1@gmail.com; linux@armlinux.org.uk; devicetree@vger.kernel.org;
> linux-doc@vger.kernel.org; robh+dt@kernel.org; mark.rutland@arm.com;
> kuba@kernel.org; corbet@lwn.net; shawnguo@kernel.org; Leo Li
> <leoyang.li@nxp.com>; Madalin Bucur (OSS) <madalin.bucur@oss.nxp.com>;
> Ioana Ciornei <ioana.ciornei@nxp.com>; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver
> support
> 
> On Mon, Jun 22, 2020 at 04:35:21PM +0300, Florinel Iordache wrote:
> > Add support for backplane kr generic driver including link training
> > (ieee802.3ap/ba) and fixed equalization algorithm
> 
> Hi Florinel
> 
> This is still a PHY device. I don't remember any discussions which
> resolved the issues of if at the end of the backplane there is another
> PHY.
> 
> It makes little sense to repost this code until we have this problem
> discussed and a way forward decided on. It fits into the discussion
> Russell and Ioana are having about representing PCS drivers. Please
> contribute to that.
> 
> 	Andrew

Hi Andrew, the reasons behind this selection:

- the PCS that is controlled by the backplane driver belongs to the PHY
layer so the representation as a PHY device is legitimate
- the PHY driver provides the state machine that is required, not using
this representation backplane would need to add a separate, duplicate
state machine
- the limitation, that only one PHY layer entity can be managed by the
PHYLib, is a known limitation that always existed, is not introduced by
the backplane support; the unsupported scenario with a backplane connection
to a PHY entity that needs to be managed relates to that limitation and
a solution for it should not be added through the backplane support
- afaik, Russell and Ioana are discussing the PCS representation in the
context of PHYLink, this submission is using PHYLib. If we are to discuss
about the PCS representation, it's the problem of the simplistic "one device
in the PHY layer" issue that needs to be addressed to have a proper PCS
representation at all times.

Madalin

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

* Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver support
       [not found] ` <1592832924-31733-5-git-send-email-florinel.iordache@nxp.com>
  2020-06-22 14:24   ` [PATCH net-next v3 4/7] net: phy: add backplane kr driver support Andrew Lunn
@ 2020-06-22 16:29   ` kernel test robot
  2020-06-22 21:46   ` Jakub Kicinski
  2 siblings, 0 replies; 24+ messages in thread
From: kernel test robot @ 2020-06-22 16:29 UTC (permalink / raw)
  To: Florinel Iordache, davem, netdev, andrew, f.fainelli, hkallweit1, linux
  Cc: kbuild-all, devicetree, linux-doc, robh+dt, mark.rutland

[-- Attachment #1: Type: text/plain, Size: 3321 bytes --]

Hi Florinel,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Florinel-Iordache/doc-net-add-backplane-documentation/20200622-223623
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 29a720c1042f469c8fea317cb5e7f496b116e07d
config: mips-allyesconfig (attached as .config)
compiler: mips-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>, old ones prefixed by <<):

drivers/net/phy/backplane/backplane.c: In function 'bp_kr_state_machine':
>> drivers/net/phy/backplane/backplane.c:590:27: warning: variable 'bpdev' set but not used [-Wunused-but-set-variable]
590 |  struct backplane_device *bpdev;
|                           ^~~~~
--
drivers/net/phy/backplane/link_training.c: In function 'lt_train_remote_tx':
>> drivers/net/phy/backplane/link_training.c:557:6: warning: variable 'lp_resp_time' set but not used [-Wunused-but-set-variable]
557 |  u64 lp_resp_time;
|      ^~~~~~~~~~~~
drivers/net/phy/backplane/link_training.c: In function 'lt_train_local_tx':
>> drivers/net/phy/backplane/link_training.c:1143:15: warning: variable 'old_ld_status' set but not used [-Wunused-but-set-variable]
1143 |  int request, old_ld_status;
|               ^~~~~~~~~~~~~

vim +/bpdev +590 drivers/net/phy/backplane/backplane.c

   586	
   587	static void bp_kr_state_machine(struct work_struct *work)
   588	{
   589		struct delayed_work *dwork = to_delayed_work(work);
 > 590		struct backplane_device *bpdev;
   591		u32 kr_timeout = KR_TIMEOUT_1;
   592		struct phy_device *phydev;
   593		struct lane_device *lane;
   594		bool start_train = false;
   595	
   596		lane = container_of(dwork, struct lane_device, krwk);
   597		if (!lane)
   598			return;
   599	
   600		bpdev = lane->bpdev;
   601		phydev = lane->phydev;
   602	
   603		if (!backplane_is_mode_kr(phydev->interface))
   604			return;
   605	
   606		/* Check if equalization algorithm is installed */
   607		if (!lane->krln.eq_alg)
   608			return;
   609	
   610		/* Check if link training is used */
   611		if (!lane->krln.eq_alg->use_local_tx_training &&
   612		    !lane->krln.eq_alg->use_remote_tx_training)
   613			return;
   614	
   615		mutex_lock(&lane->lane_lock);
   616		switch (lane->krln.state) {
   617		case DETECTING_LP:
   618			start_train = detect_lp(lane);
   619			break;
   620		case TRAINED:
   621			kr_timeout = KR_TIMEOUT_2;
   622			if (!backplane_is_link_up(phydev)) {
   623				kr_timeout = KR_TIMEOUT_1;
   624				detect_hotplug(lane);
   625			}
   626			break;
   627		}
   628	
   629		if (start_train)
   630			kr_train_step(lane);
   631	
   632		mutex_unlock(&lane->lane_lock);
   633		start_kr_state_machine(lane, kr_timeout);
   634	}
   635	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 67062 bytes --]

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

* Re: [PATCH net-next v3 5/7] net: phy: enable qoriq backplane support
  2020-06-22 13:35 ` [PATCH net-next v3 5/7] net: phy: enable qoriq backplane support Florinel Iordache
@ 2020-06-22 17:47   ` kernel test robot
  0 siblings, 0 replies; 24+ messages in thread
From: kernel test robot @ 2020-06-22 17:47 UTC (permalink / raw)
  To: Florinel Iordache, davem, netdev, andrew, f.fainelli, hkallweit1, linux
  Cc: kbuild-all, devicetree, linux-doc, robh+dt, mark.rutland

[-- Attachment #1: Type: text/plain, Size: 1988 bytes --]

Hi Florinel,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Florinel-Iordache/doc-net-add-backplane-documentation/20200622-223623
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 29a720c1042f469c8fea317cb5e7f496b116e07d
config: mips-allyesconfig (attached as .config)
compiler: mips-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>, old ones prefixed by <<):

>> drivers/net/phy/backplane/qoriq_backplane.c:150:18: warning: no previous prototype for 'get_serdes_type' [-Wmissing-prototypes]
150 | enum serdes_type get_serdes_type(struct device_node *serdes_node)
|                  ^~~~~~~~~~~~~~~

vim +/get_serdes_type +150 drivers/net/phy/backplane/qoriq_backplane.c

   149	
 > 150	enum serdes_type get_serdes_type(struct device_node *serdes_node)
   151	{
   152		enum serdes_type serdes = SERDES_INVAL;
   153		const char *serdes_comp;
   154		int comp_no, i, ret;
   155	
   156		comp_no = of_property_count_strings(serdes_node, "compatible");
   157		for (i = 0; i < comp_no; i++) {
   158			ret = of_property_read_string_index(serdes_node, "compatible",
   159							    i, &serdes_comp);
   160			if (ret == 0) {
   161				if (!strcasecmp(serdes_comp, "serdes-10g")) {
   162					serdes = SERDES_10G;
   163					break;
   164				}
   165			}
   166		}
   167	
   168		return serdes;
   169	}
   170	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 67063 bytes --]

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

* Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver support
       [not found] ` <1592832924-31733-5-git-send-email-florinel.iordache@nxp.com>
  2020-06-22 14:24   ` [PATCH net-next v3 4/7] net: phy: add backplane kr driver support Andrew Lunn
  2020-06-22 16:29   ` kernel test robot
@ 2020-06-22 21:46   ` Jakub Kicinski
  2 siblings, 0 replies; 24+ messages in thread
From: Jakub Kicinski @ 2020-06-22 21:46 UTC (permalink / raw)
  To: Florinel Iordache
  Cc: davem, netdev, andrew, f.fainelli, hkallweit1, linux, devicetree,
	linux-doc, robh+dt, mark.rutland, corbet, shawnguo, leoyang.li,
	madalin.bucur, ioana.ciornei, linux-kernel

On Mon, 22 Jun 2020 16:35:21 +0300 Florinel Iordache wrote:
> Add support for backplane kr generic driver including link training
> (ieee802.3ap/ba) and fixed equalization algorithm
> 
> Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>

drivers/net/phy/backplane/backplane.c:60:11: warning: symbol 'backplane_common_features_array' was not declared. Should it be static?
drivers/net/phy/backplane/backplane.c:66:11: warning: symbol 'backplane_protocol_features_array' was not declared. Should it be static?
drivers/net/phy/backplane/backplane.c:1204:40: warning: incorrect type in assignment (different address spaces)
drivers/net/phy/backplane/backplane.c:1204:40:    expected void *[assigned] reg_base
drivers/net/phy/backplane/backplane.c:1204:40:    got void [noderef] <asn:2> *reg_base
drivers/net/phy/backplane/backplane.c: In function ‘bp_kr_state_machine’:
drivers/net/phy/backplane/backplane.c:590:27: warning: variable ‘bpdev’ set but not used [-Wunused-but-set-variable]
  590 |  struct backplane_device *bpdev;
      |                           ^~~~~
drivers/net/phy/backplane/link_training.c: In function ‘lt_train_remote_tx’:
drivers/net/phy/backplane/link_training.c:557:6: warning: variable ‘lp_resp_time’ set but not used [-Wunused-but-set-variable]
  557 |  u64 lp_resp_time;
      |      ^~~~~~~~~~~~
drivers/net/phy/backplane/link_training.c: In function ‘lt_train_local_tx’:
drivers/net/phy/backplane/link_training.c:1143:15: warning: variable ‘old_ld_status’ set but not used [-Wunused-but-set-variable]
 1143 |  int request, old_ld_status;
      |               ^~~~~~~~~~~~~

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

* Re: [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt bindings
  2020-06-22 13:35 ` [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt bindings Florinel Iordache
@ 2020-06-22 22:20   ` Florian Fainelli
  2020-06-24 12:55     ` [EXT] " Florinel Iordache
  2020-06-29 21:58   ` Rob Herring
  1 sibling, 1 reply; 24+ messages in thread
From: Florian Fainelli @ 2020-06-22 22:20 UTC (permalink / raw)
  To: florinel.iordache, davem, netdev, andrew, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, leoyang.li, madalin.bucur, ioana.ciornei, linux-kernel

On 6/22/20 6:35 AM, Florinel Iordache wrote:
> Add ethernet backplane device tree bindings
> 
> Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
> ---

[snip]

> +properties:
> +  $nodename:
> +    pattern: "^serdes(@[a-f0-9]+)?$"
> +
> +  compatible:
> +    oneOf:
> +      - const: serdes-10g
> +        description: SerDes module type of 10G

Since this appears to be memory mapped in your case, it does not sound
like "serdes-10g" alone is going to be sufficient, should not we have a
SoC specific compatible string if nothing else?

> +
> +  reg:
> +    description:
> +      Registers memory map offset and size for this serdes module
> +
> +  reg-names:
> +    description:
> +      Names of the register map given in "reg" node.

You would also need to describe how many of these two properties are
expected.

> +
> +  little-endian:
> +    description:
> +      Specifies the endianness of serdes module
> +      For complete definition see
> +      Documentation/devicetree/bindings/common-properties.txt

This is redundant with the default binding then, and if it is not
already in the common YAML binding, can you please add little-endian and
native-endian added there?

> +
> +examples:
> +  - |
> +    serdes1: serdes@1ea0000 {
> +        compatible = "serdes-10g";
> +        reg = <0x0 0x1ea0000 0 0x00002000>;
> +        reg-names = "serdes", "serdes-10g";
> +        little-endian;
> +    };
> 


-- 
Florian

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

* RE: [EXT] Re: [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt bindings
  2020-06-22 22:20   ` Florian Fainelli
@ 2020-06-24 12:55     ` Florinel Iordache
  2020-06-26 18:55       ` Florian Fainelli
  0 siblings, 1 reply; 24+ messages in thread
From: Florinel Iordache @ 2020-06-24 12:55 UTC (permalink / raw)
  To: Florian Fainelli, davem, netdev, andrew, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, Leo Li, Madalin Bucur (OSS),
	Ioana Ciornei, linux-kernel, Florinel Iordache

> -----Original Message-----
> From: Florian Fainelli <f.fainelli@gmail.com>
> Sent: Tuesday, June 23, 2020 1:21 AM
> To: Florinel Iordache <florinel.iordache@nxp.com>; davem@davemloft.net;
> netdev@vger.kernel.org; andrew@lunn.ch; hkallweit1@gmail.com;
> linux@armlinux.org.uk
> Cc: devicetree@vger.kernel.org; linux-doc@vger.kernel.org;
> robh+dt@kernel.org; mark.rutland@arm.com; kuba@kernel.org;
> corbet@lwn.net; shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>; Madalin
> Bucur (OSS) <madalin.bucur@oss.nxp.com>; Ioana Ciornei
> <ioana.ciornei@nxp.com>; linux-kernel@vger.kernel.org
> Subject: [EXT] Re: [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt
> bindings
> 
> Caution: EXT Email
> 
> On 6/22/20 6:35 AM, Florinel Iordache wrote:
> > Add ethernet backplane device tree bindings
> >
> > Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
> > ---
> 
> [snip]
> 
> > +properties:
> > +  $nodename:
> > +    pattern: "^serdes(@[a-f0-9]+)?$"
> > +
> > +  compatible:
> > +    oneOf:
> > +      - const: serdes-10g
> > +        description: SerDes module type of 10G
> 
> Since this appears to be memory mapped in your case, it does not sound like
> "serdes-10g" alone is going to be sufficient, should not we have a SoC specific
> compatible string if nothing else?

My intention was to make it generic enough to be used by any SerDes (Serializer/Deserializer) block.
So I was thinking that specifying serdes as HW block and the type: 10g (or 28g for example) should be enough.
I could add SoC specific (or family of SoC) to the compatible string
like for example Freescale/NXP QorIQ Soc: "fsl,ls1046a-serdes-10g" or "fsl,qoriq-serdes-10g"

> 
> > +
> > +  reg:
> > +    description:
> > +      Registers memory map offset and size for this serdes module
> > +
> > +  reg-names:
> > +    description:
> > +      Names of the register map given in "reg" node.
> 
> You would also need to describe how many of these two properties are
> expected.

Only one memory map is required since the memory maps for lanes are individually described
(as it is documented in serdes-lane.yaml).
I will specify this.

> 
> > +
> > +  little-endian:
> > +    description:
> > +      Specifies the endianness of serdes module
> > +      For complete definition see
> > +      Documentation/devicetree/bindings/common-properties.txt
> 
> This is redundant with the default binding then, and if it is not already in the
> common YAML binding, can you please add little-endian and native-endian
> added there?

The endianness of the serdes block must be specified as little-endian or big-endian.
The serdes endianness may be different than the cores endianness.
This is also the case for QorIQ LS1043/LS1046 platforms with ARM cores which
are little endian but serdes block is big endian.
So endianness must be specified in device tree in order for the driver to know how to access it.
This is the generic binding description (with an example below)
but for LS1046 platform for example we should put: big-endian
(as it is in the last patch: 0007-arm64-dts-add-serdes-and-mdio-description.patch
in file: /arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi )

> 
> > +
> > +examples:
> > +  - |
> > +    serdes1: serdes@1ea0000 {
> > +        compatible = "serdes-10g";
> > +        reg = <0x0 0x1ea0000 0 0x00002000>;
> > +        reg-names = "serdes", "serdes-10g";
> > +        little-endian;
> > +    };
> >
> 
> 
> --
> Florian

Thank you for feedback
Florinel.

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

* Re: [EXT] Re: [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt bindings
  2020-06-24 12:55     ` [EXT] " Florinel Iordache
@ 2020-06-26 18:55       ` Florian Fainelli
  0 siblings, 0 replies; 24+ messages in thread
From: Florian Fainelli @ 2020-06-26 18:55 UTC (permalink / raw)
  To: Florinel Iordache, davem, netdev, andrew, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, Leo Li, Madalin Bucur (OSS),
	Ioana Ciornei, linux-kernel

On 6/24/20 5:55 AM, Florinel Iordache wrote:
>> -----Original Message-----
>> From: Florian Fainelli <f.fainelli@gmail.com>
>> Sent: Tuesday, June 23, 2020 1:21 AM
>> To: Florinel Iordache <florinel.iordache@nxp.com>; davem@davemloft.net;
>> netdev@vger.kernel.org; andrew@lunn.ch; hkallweit1@gmail.com;
>> linux@armlinux.org.uk
>> Cc: devicetree@vger.kernel.org; linux-doc@vger.kernel.org;
>> robh+dt@kernel.org; mark.rutland@arm.com; kuba@kernel.org;
>> corbet@lwn.net; shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>; Madalin
>> Bucur (OSS) <madalin.bucur@oss.nxp.com>; Ioana Ciornei
>> <ioana.ciornei@nxp.com>; linux-kernel@vger.kernel.org
>> Subject: [EXT] Re: [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt
>> bindings
>>
>> Caution: EXT Email
>>
>> On 6/22/20 6:35 AM, Florinel Iordache wrote:
>>> Add ethernet backplane device tree bindings
>>>
>>> Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
>>> ---
>>
>> [snip]
>>
>>> +properties:
>>> +  $nodename:
>>> +    pattern: "^serdes(@[a-f0-9]+)?$"
>>> +
>>> +  compatible:
>>> +    oneOf:
>>> +      - const: serdes-10g
>>> +        description: SerDes module type of 10G
>>
>> Since this appears to be memory mapped in your case, it does not sound like
>> "serdes-10g" alone is going to be sufficient, should not we have a SoC specific
>> compatible string if nothing else?
> 
> My intention was to make it generic enough to be used by any SerDes (Serializer/Deserializer) block.
> So I was thinking that specifying serdes as HW block and the type: 10g (or 28g for example) should be enough.
> I could add SoC specific (or family of SoC) to the compatible string
> like for example Freescale/NXP QorIQ Soc: "fsl,ls1046a-serdes-10g" or "fsl,qoriq-serdes-10g"

It does not seem to me that the register interface is going to be
anything but generic, therefore using SoC specific compatible strings
would be a safer and forward looking approach. If a generic/fall back
compatibility string can be added, it can be added later on, that is
much less problematic than the opposite.

> 
>>
>>> +
>>> +  reg:
>>> +    description:
>>> +      Registers memory map offset and size for this serdes module
>>> +
>>> +  reg-names:
>>> +    description:
>>> +      Names of the register map given in "reg" node.
>>
>> You would also need to describe how many of these two properties are
>> expected.
> 
> Only one memory map is required since the memory maps for lanes are individually described
> (as it is documented in serdes-lane.yaml).
> I will specify this.

Then I believe you need to advertise that with maxItems property to
denote how many.

> 
>>
>>> +
>>> +  little-endian:
>>> +    description:
>>> +      Specifies the endianness of serdes module
>>> +      For complete definition see
>>> +      Documentation/devicetree/bindings/common-properties.txt
>>
>> This is redundant with the default binding then, and if it is not already in the
>> common YAML binding, can you please add little-endian and native-endian
>> added there?
> 
> The endianness of the serdes block must be specified as little-endian or big-endian.
> The serdes endianness may be different than the cores endianness.
> This is also the case for QorIQ LS1043/LS1046 platforms with ARM cores which
> are little endian but serdes block is big endian.
> So endianness must be specified in device tree in order for the driver to know how to access it.

I understand that part, my point was more than these properties are
generic properties, therefore it should not be necessary to provide a
description, and their definition belongs in the common properties
binding. If the common binding does not have a definition for those
(that is, in a YAML way), then please add them there.
-- 
Florian

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

* Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver support
  2020-06-22 15:08     ` Madalin Bucur (OSS)
@ 2020-06-26 19:02       ` Florian Fainelli
  2020-06-29 13:58         ` Russell King - ARM Linux admin
  0 siblings, 1 reply; 24+ messages in thread
From: Florian Fainelli @ 2020-06-26 19:02 UTC (permalink / raw)
  To: Madalin Bucur (OSS), Andrew Lunn, Florinel Iordache
  Cc: davem, netdev, hkallweit1, linux, devicetree, linux-doc, robh+dt,
	mark.rutland, kuba, corbet, shawnguo, Leo Li, Ioana Ciornei,
	linux-kernel

On 6/22/20 8:08 AM, Madalin Bucur (OSS) wrote:
>> -----Original Message-----
>> From: Andrew Lunn <andrew@lunn.ch>
>> Sent: Monday, June 22, 2020 5:25 PM
>> To: Florinel Iordache <florinel.iordache@nxp.com>
>> Cc: davem@davemloft.net; netdev@vger.kernel.org; f.fainelli@gmail.com;
>> hkallweit1@gmail.com; linux@armlinux.org.uk; devicetree@vger.kernel.org;
>> linux-doc@vger.kernel.org; robh+dt@kernel.org; mark.rutland@arm.com;
>> kuba@kernel.org; corbet@lwn.net; shawnguo@kernel.org; Leo Li
>> <leoyang.li@nxp.com>; Madalin Bucur (OSS) <madalin.bucur@oss.nxp.com>;
>> Ioana Ciornei <ioana.ciornei@nxp.com>; linux-kernel@vger.kernel.org
>> Subject: Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver
>> support
>>
>> On Mon, Jun 22, 2020 at 04:35:21PM +0300, Florinel Iordache wrote:
>>> Add support for backplane kr generic driver including link training
>>> (ieee802.3ap/ba) and fixed equalization algorithm
>>
>> Hi Florinel
>>
>> This is still a PHY device. I don't remember any discussions which
>> resolved the issues of if at the end of the backplane there is another
>> PHY.
>>
>> It makes little sense to repost this code until we have this problem
>> discussed and a way forward decided on. It fits into the discussion
>> Russell and Ioana are having about representing PCS drivers. Please
>> contribute to that.
>>
>> 	Andrew
> 
> Hi Andrew, the reasons behind this selection:
> 
> - the PCS that is controlled by the backplane driver belongs to the PHY
> layer so the representation as a PHY device is legitimate

That argument makes sense.

> - the PHY driver provides the state machine that is required, not using
> this representation backplane would need to add a separate, duplicate
> state machine

Which is entirely permissible according to the PHY library
documentation, not that we have seen many people do it though, even less
so when the PHY driver is providing the state machine.

> - the limitation, that only one PHY layer entity can be managed by the
> PHYLib, is a known limitation that always existed, is not introduced by
> the backplane support; the unsupported scenario with a backplane connection
> to a PHY entity that needs to be managed relates to that limitation and
> a solution for it should not be added through the backplane support
> - afaik, Russell and Ioana are discussing the PCS representation in the
> context of PHYLink, this submission is using PHYLib. If we are to discuss
> about the PCS representation, it's the problem of the simplistic "one device
> in the PHY layer" issue that needs to be addressed to have a proper PCS
> representation at all times.

So would not it make sense for the PCS representation to be settled and
then add the backplane driver implementation such that there is no
double work happening for Florinel and for reviewers and the PCS
implementation als factors in the backplane use case and requirements?
-- 
Florian

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

* Re: [EXT] Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver support
  2020-06-22 14:39     ` [EXT] " Florinel Iordache
@ 2020-06-26 19:05       ` Florian Fainelli
  2020-06-29 13:23         ` Florinel Iordache
  0 siblings, 1 reply; 24+ messages in thread
From: Florian Fainelli @ 2020-06-26 19:05 UTC (permalink / raw)
  To: Florinel Iordache, Andrew Lunn
  Cc: davem, netdev, hkallweit1, linux, devicetree, linux-doc, robh+dt,
	mark.rutland, kuba, corbet, shawnguo, Leo Li, Madalin Bucur (OSS),
	Ioana Ciornei, linux-kernel

On 6/22/20 7:39 AM, Florinel Iordache wrote:
>> -----Original Message-----
>> From: Andrew Lunn <andrew@lunn.ch>
>> Sent: Monday, June 22, 2020 5:25 PM
>> To: Florinel Iordache <florinel.iordache@nxp.com>
>> Cc: davem@davemloft.net; netdev@vger.kernel.org; f.fainelli@gmail.com;
>> hkallweit1@gmail.com; linux@armlinux.org.uk; devicetree@vger.kernel.org;
>> linux-doc@vger.kernel.org; robh+dt@kernel.org; mark.rutland@arm.com;
>> kuba@kernel.org; corbet@lwn.net; shawnguo@kernel.org; Leo Li
>> <leoyang.li@nxp.com>; Madalin Bucur (OSS) <madalin.bucur@oss.nxp.com>;
>> Ioana Ciornei <ioana.ciornei@nxp.com>; linux-kernel@vger.kernel.org
>> Subject: [EXT] Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver
>> support
>>
>> Caution: EXT Email
>>
>> On Mon, Jun 22, 2020 at 04:35:21PM +0300, Florinel Iordache wrote:
>>> Add support for backplane kr generic driver including link training
>>> (ieee802.3ap/ba) and fixed equalization algorithm
>>
>> Hi Florinel
>>
>> This is still a PHY device. I don't remember any discussions which resolved the
>> issues of if at the end of the backplane there is another PHY.
>>
>> It makes little sense to repost this code until we have this problem discussed and
>> a way forward decided on. It fits into the discussion Russell and Ioana are having
>> about representing PCS drivers. Please contribute to that.
>>
>>         Andrew
> 
> Hi Andrew,
> 
> Yes, you are right: we decided to send only support for DPAA1 using current approach as a PHY device
> (as mentioned in cover-letter), until PCS representation will be fully clarified.
> The entire DPAA2 support was removed for now, together with phylink changes.
> DPAA1 maintainer (Madalin Bucur) agrees with current representation as a PHY device for DPAA1.
> So we would like to have some discussions around this approach for DPAA1 only, as it seems suitable for us.

The question is really whether it is suitable for others beyond NXP, the
drivers are certainly organized in such a way that there is little NXP
specifics in them so the intent is clearly there.

We will probably not know, either because vendors have decided to hide
all of this stuff under firmware, or they do not use Linux or they just
are not following what is going on upstream and have no desire to
participate.
-- 
Florian

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

* Re: [PATCH net-next v3 7/7] arm64: dts: add serdes and mdio description
  2020-06-22 13:35 ` [PATCH net-next v3 7/7] arm64: dts: add serdes and mdio description Florinel Iordache
@ 2020-06-26 19:08   ` Florian Fainelli
  2020-06-29 12:32     ` [EXT] " Florinel Iordache
  0 siblings, 1 reply; 24+ messages in thread
From: Florian Fainelli @ 2020-06-26 19:08 UTC (permalink / raw)
  To: florinel.iordache, davem, netdev, andrew, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, leoyang.li, madalin.bucur, ioana.ciornei, linux-kernel

On 6/22/20 6:35 AM, Florinel Iordache wrote:
> Add dt nodes with serdes, lanes, mdio generic description for supported
> platform: ls1046. This is a prerequisite to enable backplane on device
> tree for these platforms.
> 
> Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
> ---

[snip]

> @@ -21,7 +22,7 @@ fman@1a00000 {
>  		fsl,fman-10g-port;
>  	};
>  
> -	ethernet@f2000 {
> +	mac10: ethernet@f2000 {
>  		cell-index = <0x9>;
>  		compatible = "fsl,fman-memac";
>  		reg = <0xf2000 0x1000>;
> @@ -29,7 +30,7 @@ fman@1a00000 {
>  		pcsphy-handle = <&pcsphy7>;
>  	};
>  
> -	mdio@f3000 {
> +	mdio10: mdio@f3000 {
>  		#address-cells = <1>;
>  		#size-cells = <0>;
>  		compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";

That part of the patch does not seem to have any users, there is nothing
in your patch series that references mac9, mdio9 or mac10, mdio10
AFAICT. Maybe you can split it up and send it aside from this series?
-- 
Florian

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

* RE: [EXT] Re: [PATCH net-next v3 7/7] arm64: dts: add serdes and mdio description
  2020-06-26 19:08   ` Florian Fainelli
@ 2020-06-29 12:32     ` Florinel Iordache
  0 siblings, 0 replies; 24+ messages in thread
From: Florinel Iordache @ 2020-06-29 12:32 UTC (permalink / raw)
  To: Florian Fainelli, davem, netdev, andrew, hkallweit1, linux
  Cc: devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, Leo Li, Madalin Bucur (OSS),
	Ioana Ciornei, linux-kernel, Florinel Iordache


> -----Original Message-----
> From: Florian Fainelli <f.fainelli@gmail.com>
> Sent: Friday, June 26, 2020 10:08 PM
> To: Florinel Iordache <florinel.iordache@nxp.com>; davem@davemloft.net;
> netdev@vger.kernel.org; andrew@lunn.ch; hkallweit1@gmail.com;
> linux@armlinux.org.uk
> Cc: devicetree@vger.kernel.org; linux-doc@vger.kernel.org;
> robh+dt@kernel.org; mark.rutland@arm.com; kuba@kernel.org;
> corbet@lwn.net; shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>; Madalin
> Bucur (OSS) <madalin.bucur@oss.nxp.com>; Ioana Ciornei
> <ioana.ciornei@nxp.com>; linux-kernel@vger.kernel.org
> Subject: [EXT] Re: [PATCH net-next v3 7/7] arm64: dts: add serdes and mdio
> description
> 
> Caution: EXT Email
> 
> On 6/22/20 6:35 AM, Florinel Iordache wrote:
> > Add dt nodes with serdes, lanes, mdio generic description for
> > supported
> > platform: ls1046. This is a prerequisite to enable backplane on device
> > tree for these platforms.
> >
> > Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
> > ---
> 
> [snip]
> 
> > @@ -21,7 +22,7 @@ fman@1a00000 {
> >               fsl,fman-10g-port;
> >       };
> >
> > -     ethernet@f2000 {
> > +     mac10: ethernet@f2000 {
> >               cell-index = <0x9>;
> >               compatible = "fsl,fman-memac";
> >               reg = <0xf2000 0x1000>;
> > @@ -29,7 +30,7 @@ fman@1a00000 {
> >               pcsphy-handle = <&pcsphy7>;
> >       };
> >
> > -     mdio@f3000 {
> > +     mdio10: mdio@f3000 {
> >               #address-cells = <1>;
> >               #size-cells = <0>;
> >               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
> 
> That part of the patch does not seem to have any users, there is nothing in your
> patch series that references mac9, mdio9 or mac10, mdio10 AFAICT. Maybe you
> can split it up and send it aside from this series?
> --
> Florian

Hi Florian,

These labels are used in the platform DTS (e.g.: fsl-ls1046a-rdb.dts for DPAA1 / LS1046).
They are not used in the patch because backplane mode is NOT the default mode.
Backplane mode is enabled by users for custom boards by editing the DTS.
Interfaces must be used by default with a PHY like: phy-handle = <&aqr106_phy>
How to enable backplane mode in DTS is described in devicetree bindings file: ethernet-phy.yaml
(which includes an example at the end).

Here is an example of how the labels are used to enable backplane mode:
&mdio9 {
	pcsphy6: ethernet-phy@0 {
		compatible = "ethernet-phy-ieee802.3-c45";
		eq-algorithm = "bee";
		/* 10G Short cables setup: up to 30 cm cable */
		eq-init = <0x2 0x29 0x5>;
		eq-params = <0>;
		reg = <0x0>;
		lane-handle = <&lane_d>;   /* lane D */
	};
};
/* Update MAC connections to backplane PHYs */
&mac9 {
	phy-connection-type = "10gbase-kr";
	phy-handle = <&pcsphy6>;
};

However, the users could write DTS by using ethernet@f0000 instead of &mac9.
Something like this:
ethernet@f0000 { /* 10GEC1 */
	phy-connection-type = "10gbase-kr";
	phy-handle = <&pcsphy6>;
};
(and similar for mdio9/mdio10)
So ultimately that part of the patch could be removed indeed.
I put it there just to be more user friendly to enable backplane in DTS.

Thank you for feedback.
Florinel.

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

* RE: [EXT] Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver support
  2020-06-26 19:05       ` Florian Fainelli
@ 2020-06-29 13:23         ` Florinel Iordache
  0 siblings, 0 replies; 24+ messages in thread
From: Florinel Iordache @ 2020-06-29 13:23 UTC (permalink / raw)
  To: Florian Fainelli, Andrew Lunn
  Cc: davem, netdev, hkallweit1, linux, devicetree, linux-doc, robh+dt,
	mark.rutland, kuba, corbet, shawnguo, Leo Li, Madalin Bucur (OSS),
	Ioana Ciornei, linux-kernel, Florinel Iordache

> -----Original Message-----
> From: Florian Fainelli <f.fainelli@gmail.com>
> Sent: Friday, June 26, 2020 10:05 PM
> To: Florinel Iordache <florinel.iordache@nxp.com>; Andrew Lunn
> <andrew@lunn.ch>
> Cc: davem@davemloft.net; netdev@vger.kernel.org; hkallweit1@gmail.com;
> linux@armlinux.org.uk; devicetree@vger.kernel.org; linux-doc@vger.kernel.org;
> robh+dt@kernel.org; mark.rutland@arm.com; kuba@kernel.org;
> corbet@lwn.net; shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>; Madalin
> Bucur (OSS) <madalin.bucur@oss.nxp.com>; Ioana Ciornei
> <ioana.ciornei@nxp.com>; linux-kernel@vger.kernel.org
> Subject: Re: [EXT] Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver
> support
> 
> Caution: EXT Email
> 
> On 6/22/20 7:39 AM, Florinel Iordache wrote:
> >> -----Original Message-----
> >> From: Andrew Lunn <andrew@lunn.ch>
> >> Sent: Monday, June 22, 2020 5:25 PM
> >> To: Florinel Iordache <florinel.iordache@nxp.com>
> >> Cc: davem@davemloft.net; netdev@vger.kernel.org;
> >> f.fainelli@gmail.com; hkallweit1@gmail.com; linux@armlinux.org.uk;
> >> devicetree@vger.kernel.org; linux-doc@vger.kernel.org;
> >> robh+dt@kernel.org; mark.rutland@arm.com; kuba@kernel.org;
> >> corbet@lwn.net; shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>;
> >> Madalin Bucur (OSS) <madalin.bucur@oss.nxp.com>; Ioana Ciornei
> >> <ioana.ciornei@nxp.com>; linux-kernel@vger.kernel.org
> >> Subject: [EXT] Re: [PATCH net-next v3 4/7] net: phy: add backplane kr
> >> driver support
> >>
> >> Caution: EXT Email
> >>
> >> On Mon, Jun 22, 2020 at 04:35:21PM +0300, Florinel Iordache wrote:
> >>> Add support for backplane kr generic driver including link training
> >>> (ieee802.3ap/ba) and fixed equalization algorithm
> >>
> >> Hi Florinel
> >>
> >> This is still a PHY device. I don't remember any discussions which
> >> resolved the issues of if at the end of the backplane there is another PHY.
> >>
> >> It makes little sense to repost this code until we have this problem
> >> discussed and a way forward decided on. It fits into the discussion
> >> Russell and Ioana are having about representing PCS drivers. Please
> contribute to that.
> >>
> >>         Andrew
> >
> > Hi Andrew,
> >
> > Yes, you are right: we decided to send only support for DPAA1 using
> > current approach as a PHY device (as mentioned in cover-letter), until PCS
> representation will be fully clarified.
> > The entire DPAA2 support was removed for now, together with phylink
> changes.
> > DPAA1 maintainer (Madalin Bucur) agrees with current representation as a PHY
> device for DPAA1.
> > So we would like to have some discussions around this approach for DPAA1
> only, as it seems suitable for us.
> 
> The question is really whether it is suitable for others beyond NXP, the drivers
> are certainly organized in such a way that there is little NXP specifics in them so
> the intent is clearly there.
> 
> We will probably not know, either because vendors have decided to hide all of
> this stuff under firmware, or they do not use Linux or they just are not following
> what is going on upstream and have no desire to participate.
> --
> Florian

Hi Florian,
This is correct: backplane support has a modular, extensible, generic architecture
and the modules are completely disconnected
so they can be reused among different configurations setups.
Therefore we have encapsulated the standard backplane functionality in several
generic modules like: Ethernet Backplane Generic Driver, Link Training and
Auto-negotiation including: IEEE 802.3-ap/ba standards, Equalization Algorithms
(that include: Fixed algorithm and BEE - Bit Edge equalization algorithm).
Device specific modules are used to enable QorIQ family of devices.
This architecture is described in detail in Doc file: backplane.rst
Other vendors that want to enable backplane for their devices should
add only their device specific modules (similar with qoriq modules).
These modules basically must describe device specific registers and
make the connection between backplane generic API services and device specific operations.
All generic modules that encapsulate standard backplane functionality can be
reused by other vendors but this is not mandatory.
Other vendors can extend current architecture with new generic modules:
for example other equalization algorithms and standards can be added in the future
if currently existing ones are not desired or considered inappropriate.
There are several other standard algorithms available that can be used for
Signal equalization: they just have to be implemented and integrated here.
Of course we validated this backplane architecture only on NXP platforms (by using QorIQ devices)
but other vendors will be able to use it in the future on their own platforms.
Thank you for feedback,
Florinel.

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

* Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver support
  2020-06-26 19:02       ` Florian Fainelli
@ 2020-06-29 13:58         ` Russell King - ARM Linux admin
  2020-06-30  0:51           ` Andrew Lunn
  0 siblings, 1 reply; 24+ messages in thread
From: Russell King - ARM Linux admin @ 2020-06-29 13:58 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Madalin Bucur (OSS),
	Andrew Lunn, Florinel Iordache, davem, netdev, hkallweit1,
	devicetree, linux-doc, robh+dt, mark.rutland, kuba, corbet,
	shawnguo, Leo Li, Ioana Ciornei, linux-kernel

On Fri, Jun 26, 2020 at 12:02:05PM -0700, Florian Fainelli wrote:
> On 6/22/20 8:08 AM, Madalin Bucur (OSS) wrote:
> > Hi Andrew, the reasons behind this selection:
> > 
> > - the PCS that is controlled by the backplane driver belongs to the PHY
> > layer so the representation as a PHY device is legitimate
> 
> That argument makes sense.

It doesn't when you also are subjected to other parts of NXP arguing
that the PCS is tightly bound inside the SoC and therefore should be
effectively a library - as has been discussed in the threads about
the Lynx PCS.

> > - the PHY driver provides the state machine that is required, not using
> > this representation backplane would need to add a separate, duplicate
> > state machine
> 
> Which is entirely permissible according to the PHY library
> documentation, not that we have seen many people do it though, even less
> so when the PHY driver is providing the state machine.

It seems the PHYlib state machine is getting smaller and smaller
as we move forward; phy_state_machine() is now looking very bare
compared to what it used to look like.  I think it's not that far
off being eliminated.

> > - the limitation, that only one PHY layer entity can be managed by the
> > PHYLib, is a known limitation that always existed, is not introduced by
> > the backplane support; the unsupported scenario with a backplane connection
> > to a PHY entity that needs to be managed relates to that limitation and
> > a solution for it should not be added through the backplane support
> > - afaik, Russell and Ioana are discussing the PCS representation in the
> > context of PHYLink, this submission is using PHYLib. If we are to discuss
> > about the PCS representation, it's the problem of the simplistic "one device
> > in the PHY layer" issue that needs to be addressed to have a proper PCS
> > representation at all times.
> 
> So would not it make sense for the PCS representation to be settled and
> then add the backplane driver implementation such that there is no
> double work happening for Florinel and for reviewers and the PCS
> implementation als factors in the backplane use case and requirements?

Yes, that is my assessment; there's a lot of work going on in different
areas in QoriQ networking, and it seems people are pulling things in
quite diverse directions.

If we're not careful, we're going to end up with the Lynx PCS being
implemented one way, and backplane PCS being implemented completely
differently and preventing any hope of having a backplane PCS
connected to a conventional copper PHY.

I think folk at NXP need to stop, stand back, and look at the bigger
picture about how they want to integrate all these individual,
independent strands of development into the kernel, and come up with
a common approach that also satisfies the mainline kernel, rather
than having individual discussions with mainline kernel maintainers
on public lists.  What I'm saying is, it isn't our job to co-ordinate
between the different parts of NXP - that's fairly and squarely
NXP's problem to sort out themselves.

So, I think, further progress in public on backplane support needs to
wait until we have the general situation for PCS resolved.

Makes sense?

-- 
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] 24+ messages in thread

* Re: [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt bindings
  2020-06-22 13:35 ` [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt bindings Florinel Iordache
  2020-06-22 22:20   ` Florian Fainelli
@ 2020-06-29 21:58   ` Rob Herring
  1 sibling, 0 replies; 24+ messages in thread
From: Rob Herring @ 2020-06-29 21:58 UTC (permalink / raw)
  To: Florinel Iordache
  Cc: kuba, robh+dt, shawnguo, linux-doc, devicetree, davem, andrew,
	mark.rutland, linux, corbet, ioana.ciornei, linux-kernel,
	hkallweit1, f.fainelli, leoyang.li, netdev, madalin.bucur

On Mon, 22 Jun 2020 16:35:19 +0300, Florinel Iordache wrote:
> Add ethernet backplane device tree bindings
> 
> Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
> ---
>  .../bindings/net/ethernet-controller.yaml          |  7 ++-
>  .../devicetree/bindings/net/ethernet-phy.yaml      | 50 ++++++++++++++++++++++
>  .../devicetree/bindings/net/serdes-lane.yaml       | 49 +++++++++++++++++++++
>  Documentation/devicetree/bindings/net/serdes.yaml  | 42 ++++++++++++++++++
>  4 files changed, 146 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/net/serdes-lane.yaml
>  create mode 100644 Documentation/devicetree/bindings/net/serdes.yaml
> 


My bot found errors running 'make dt_binding_check' on your patch:

/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/net/serdes.example.dt.yaml: example-0: serdes@1ea0000:reg:0: [0, 32112640, 0, 8192] is too long
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/net/serdes-lane.example.dt.yaml: example-0: serdes@1ea0000:reg:0: [0, 32112640, 0, 8192] is too long


See https://patchwork.ozlabs.org/patch/1314386

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure dt-schema is up to date:

pip3 install git+https://github.com/devicetree-org/dt-schema.git@master --upgrade

Please check and re-submit.


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

* Re: [PATCH net-next v3 4/7] net: phy: add backplane kr driver support
  2020-06-29 13:58         ` Russell King - ARM Linux admin
@ 2020-06-30  0:51           ` Andrew Lunn
  0 siblings, 0 replies; 24+ messages in thread
From: Andrew Lunn @ 2020-06-30  0:51 UTC (permalink / raw)
  To: Russell King - ARM Linux admin
  Cc: Florian Fainelli, Madalin Bucur (OSS),
	Florinel Iordache, davem, netdev, hkallweit1, devicetree,
	linux-doc, robh+dt, mark.rutland, kuba, corbet, shawnguo, Leo Li,
	Ioana Ciornei, linux-kernel

> So, I think, further progress in public on backplane support needs to
> wait until we have the general situation for PCS resolved.
> 
> Makes sense?

Hi Russell

Does to me.

Thanks
	Andrew

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

end of thread, other threads:[~2020-06-30  0:51 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-22 13:35 [PATCH net-next v2 0/9] net: ethernet backplane support on DPAA1 Florinel Iordache
2020-06-22 13:35 ` [PATCH net-next v3 1/7] doc: net: add backplane documentation Florinel Iordache
2020-06-22 13:35 ` [PATCH net-next v3 2/7] dt-bindings: net: add backplane dt bindings Florinel Iordache
2020-06-22 22:20   ` Florian Fainelli
2020-06-24 12:55     ` [EXT] " Florinel Iordache
2020-06-26 18:55       ` Florian Fainelli
2020-06-29 21:58   ` Rob Herring
2020-06-22 13:35 ` [PATCH net-next v3 3/7] net: fman: add kr support for dpaa1 mac Florinel Iordache
2020-06-22 13:35 ` [PATCH net-next v3 5/7] net: phy: enable qoriq backplane support Florinel Iordache
2020-06-22 17:47   ` kernel test robot
2020-06-22 13:35 ` [PATCH net-next v3 6/7] net: phy: add bee algorithm for kr training Florinel Iordache
2020-06-22 13:35 ` [PATCH net-next v3 7/7] arm64: dts: add serdes and mdio description Florinel Iordache
2020-06-26 19:08   ` Florian Fainelli
2020-06-29 12:32     ` [EXT] " Florinel Iordache
     [not found] ` <1592832924-31733-5-git-send-email-florinel.iordache@nxp.com>
2020-06-22 14:24   ` [PATCH net-next v3 4/7] net: phy: add backplane kr driver support Andrew Lunn
2020-06-22 14:39     ` [EXT] " Florinel Iordache
2020-06-26 19:05       ` Florian Fainelli
2020-06-29 13:23         ` Florinel Iordache
2020-06-22 15:08     ` Madalin Bucur (OSS)
2020-06-26 19:02       ` Florian Fainelli
2020-06-29 13:58         ` Russell King - ARM Linux admin
2020-06-30  0:51           ` Andrew Lunn
2020-06-22 16:29   ` kernel test robot
2020-06-22 21:46   ` Jakub Kicinski

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