linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Introduce ICSSG based ethernet Driver
@ 2022-05-31  9:51 Puranjay Mohan
  2022-05-31  9:51 ` [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings Puranjay Mohan
       [not found] ` <20220531095108.21757-3-p-mohan@ti.com>
  0 siblings, 2 replies; 20+ messages in thread
From: Puranjay Mohan @ 2022-05-31  9:51 UTC (permalink / raw)
  To: linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, p-mohan, linux-arm-kernel, rogerq,
	grygorii.strashko, vigneshr, kishon, robh+dt, afd, andrew

The Programmable Real-time Unit and Industrial Communication Subsystem
Gigabit (PRU_ICSSG) is a low-latency microcontroller subsystem in the TI
SoCs. This subsystem is provided for the use cases like the implementation of
custom peripheral interfaces, offloading of tasks from the other
processor cores of the SoC, etc.

The subsystem includes many accelerators for data processing like
multiplier and multiplier-accumulator. It also has peripherals like
UART, MII/RGMII, MDIO, etc. Every ICSSG core includes two 32-bit
load/store RISC CPU cores called PRUs.

The above features allow it to be used for implementing custom firmware
based peripherals like ethernet.

This series adds the YAML documentation and the driver with basic EMAC
support for TI AM654 Silicon Rev 2 SoC with the PRU_ICSSG Sub-system.
running dual-EMAC firmware.
This currently supports basic EMAC with 1Gbps and 100Mbps link. 10M and
half-duplex modes are not yet supported because they require the support
of an IEP, which will be added later.
Advanced features like switch-dev and timestamping will be added later.

This series depends on two patch series that are not yet merged, one in
the remoteproc tree and another in the soc tree. the first one is titled
Introduce PRU remoteproc consumer API and the second one is titled
Introduce PRU platform consumer API.
Both of these are required for this driver.

To explain this dependency and to get reviews, I had earlier posted all
three of these as an RFC[1], this can be seen for understanding the
dependencies.

I then posted the remoteproc[2] and soc[3] series seperately to their
respective trees.

[1] https://lore.kernel.org/all/20220406094358.7895-1-p-mohan@ti.com/
[2] https://patchwork.kernel.org/project/linux-remoteproc/cover/20220418104118.12878-1-p-mohan@ti.com/
[3] https://patchwork.kernel.org/project/linux-remoteproc/cover/20220418123004.9332-1-p-mohan@ti.com/

[V1] https://lore.kernel.org/all/20220506052433.28087-1-p-mohan@ti.com/

Differences from V1 can be seen in the individual patches.

Thanks and Regards,
Puranjay Mohan

Puranjay Mohan (1):
  dt-bindings: net: Add ICSSG Ethernet Driver bindings

Roger Quadros (1):
  net: ti: icssg-prueth: Add ICSSG ethernet driver

 .../bindings/net/ti,icssg-prueth.yaml         |  181 ++
 drivers/net/ethernet/ti/Kconfig               |   15 +
 drivers/net/ethernet/ti/Makefile              |    3 +
 drivers/net/ethernet/ti/icssg_classifier.c    |  375 ++++
 drivers/net/ethernet/ti/icssg_config.c        |  440 ++++
 drivers/net/ethernet/ti/icssg_config.h        |  200 ++
 drivers/net/ethernet/ti/icssg_ethtool.c       |  319 +++
 drivers/net/ethernet/ti/icssg_mii_cfg.c       |  104 +
 drivers/net/ethernet/ti/icssg_mii_rt.h        |  151 ++
 drivers/net/ethernet/ti/icssg_prueth.c        | 1889 +++++++++++++++++
 drivers/net/ethernet/ti/icssg_prueth.h        |  246 +++
 drivers/net/ethernet/ti/icssg_switch_map.h    |  183 ++
 include/linux/pruss.h                         |    1 +
 13 files changed, 4107 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
 create mode 100644 drivers/net/ethernet/ti/icssg_classifier.c
 create mode 100644 drivers/net/ethernet/ti/icssg_config.c
 create mode 100644 drivers/net/ethernet/ti/icssg_config.h
 create mode 100644 drivers/net/ethernet/ti/icssg_ethtool.c
 create mode 100644 drivers/net/ethernet/ti/icssg_mii_cfg.c
 create mode 100644 drivers/net/ethernet/ti/icssg_mii_rt.h
 create mode 100644 drivers/net/ethernet/ti/icssg_prueth.c
 create mode 100644 drivers/net/ethernet/ti/icssg_prueth.h
 create mode 100644 drivers/net/ethernet/ti/icssg_switch_map.h

-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-05-31  9:51 [PATCH v2 0/2] Introduce ICSSG based ethernet Driver Puranjay Mohan
@ 2022-05-31  9:51 ` Puranjay Mohan
  2022-05-31 10:08   ` Krzysztof Kozlowski
  2022-05-31 13:21   ` Rob Herring
       [not found] ` <20220531095108.21757-3-p-mohan@ti.com>
  1 sibling, 2 replies; 20+ messages in thread
From: Puranjay Mohan @ 2022-05-31  9:51 UTC (permalink / raw)
  To: linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, p-mohan, linux-arm-kernel, rogerq,
	grygorii.strashko, vigneshr, kishon, robh+dt, afd, andrew

Add a YAML binding document for the ICSSG Programmable real time unit
based Ethernet driver. This driver uses the PRU and PRUSS consumer APIs
to interface the PRUs and load/run the firmware for supporting ethernet
functionality.

Signed-off-by: Puranjay Mohan <p-mohan@ti.com>
---
v1: https://lore.kernel.org/all/20220506052433.28087-2-p-mohan@ti.com/ 
v1 -> v2:
* Addressed Rob's Comments
* It includes indentation, formatting, and other minor changes.
---
 .../bindings/net/ti,icssg-prueth.yaml         | 181 ++++++++++++++++++
 1 file changed, 181 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml

diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
new file mode 100644
index 000000000000..40af968e9178
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
@@ -0,0 +1,181 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/ti,icssg-prueth.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: |+
+  Texas Instruments ICSSG PRUSS Ethernet
+
+maintainers:
+  - Puranjay Mohan <p-mohan@ti.com>
+
+description:
+  Ethernet based on the Programmable Real-Time
+  Unit and Industrial Communication Subsystem.
+
+allOf:
+  - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#
+
+properties:
+  compatible:
+    enum:
+      - ti,am654-icssg-prueth  # for AM65x SoC family
+
+  pinctrl-0:
+    maxItems: 1
+
+  pinctrl-names:
+    items:
+      - const: default
+
+  sram:
+    description:
+      phandle to MSMC SRAM node
+
+  dmas:
+    maxItems: 10
+    description:
+      list of phandles and specifiers to UDMA.
+
+  dma-names:
+    items:
+      - const: tx0-0
+      - const: tx0-1
+      - const: tx0-2
+      - const: tx0-3
+      - const: tx1-0
+      - const: tx1-1
+      - const: tx1-2
+      - const: tx1-3
+      - const: rx0
+      - const: rx1
+
+  ethernet-ports:
+    type: object
+    properties:
+      '#address-cells':
+        const: 1
+      '#size-cells':
+        const: 0
+
+    patternProperties:
+      ^port@[0-1]$:
+        type: object
+        description: ICSSG PRUETH external ports
+
+        $ref: ethernet-controller.yaml#
+
+        unevaluatedProperties: false
+        additionalProperties: true
+        properties:
+          reg:
+            items:
+              - enum: [0, 1]
+            description: ICSSG PRUETH port number
+
+          ti,syscon-rgmii-delay:
+            $ref: /schemas/types.yaml#/definitions/phandle-array
+            description:
+              phandle to system controller node and register offset
+              to ICSSG control register for RGMII transmit delay
+
+        required:
+          - reg
+
+  ti,mii-g-rt:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      phandle to MII_G_RT module's syscon regmap.
+
+  ti,mii-rt:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      phandle to MII_RT module's syscon regmap
+
+  interrupts:
+    minItems: 2
+    maxItems: 2
+    description: |
+      Interrupt specifiers to TX timestamp IRQ.
+
+  interrupt-names:
+    items:
+      - const: tx_ts0
+      - const: tx_ts1
+
+required:
+  - compatible
+  - sram
+  - ti,mii-g-rt
+  - dmas
+  - dma-names
+  - ethernet-ports
+  - interrupts
+  - interrupt-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+
+    /* Example k3-am654 base board SR2.0, dual-emac */
+    pruss2_eth: pruss2_eth {
+            compatible = "ti,am654-icssg-prueth";
+            pinctrl-names = "default";
+            pinctrl-0 = <&icssg2_rgmii_pins_default>;
+            sram = <&msmc_ram>;
+
+            ti,prus = <&pru2_0>, <&rtu2_0>, <&tx_pru2_0>, <&pru2_1>, <&rtu2_1>, <&tx_pru2_1>;
+            firmware-name = "ti-pruss/am65x-pru0-prueth-fw.elf",
+                            "ti-pruss/am65x-rtu0-prueth-fw.elf",
+                            "ti-pruss/am65x-txpru0-prueth-fw.elf",
+                            "ti-pruss/am65x-pru1-prueth-fw.elf",
+                            "ti-pruss/am65x-rtu1-prueth-fw.elf",
+                            "ti-pruss/am65x-txpru1-prueth-fw.elf";
+            ti,pruss-gp-mux-sel = <2>,      /* MII mode */
+                                  <2>,
+                                  <2>,
+                                  <2>,      /* MII mode */
+                                  <2>,
+                                  <2>;
+            ti,mii-g-rt = <&icssg2_mii_g_rt>;
+            dmas = <&main_udmap 0xc300>, /* egress slice 0 */
+                   <&main_udmap 0xc301>, /* egress slice 0 */
+                   <&main_udmap 0xc302>, /* egress slice 0 */
+                   <&main_udmap 0xc303>, /* egress slice 0 */
+                   <&main_udmap 0xc304>, /* egress slice 1 */
+                   <&main_udmap 0xc305>, /* egress slice 1 */
+                   <&main_udmap 0xc306>, /* egress slice 1 */
+                   <&main_udmap 0xc307>, /* egress slice 1 */
+                   <&main_udmap 0x4300>, /* ingress slice 0 */
+                   <&main_udmap 0x4301>; /* ingress slice 1 */
+            dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+                        "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+                        "rx0", "rx1";
+            interrupts = <24 0 2>, <25 1 3>;
+            interrupt-names = "tx_ts0", "tx_ts1";
+            ethernet-ports {
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+                    pruss2_emac0: port@0 {
+                            reg = <0>;
+                            phy-handle = <&pruss2_eth0_phy>;
+                            phy-mode = "rgmii-rxid";
+                            interrupts-extended = <&icssg2_intc 24>;
+                            ti,syscon-rgmii-delay = <&scm_conf 0x4120>;
+                            /* Filled in by bootloader */
+                            local-mac-address = [00 00 00 00 00 00];
+                    };
+
+                    pruss2_emac1: port@1 {
+                            reg = <1>;
+                            phy-handle = <&pruss2_eth1_phy>;
+                            phy-mode = "rgmii-rxid";
+                            interrupts-extended = <&icssg2_intc 25>;
+                            ti,syscon-rgmii-delay = <&scm_conf 0x4124>;
+                            /* Filled in by bootloader */
+                            local-mac-address = [00 00 00 00 00 00];
+                    };
+            };
+    };
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-05-31  9:51 ` [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings Puranjay Mohan
@ 2022-05-31 10:08   ` Krzysztof Kozlowski
  2022-05-31 11:27     ` Puranjay Mohan
  2022-11-04  7:28     ` Md Danish Anwar
  2022-05-31 13:21   ` Rob Herring
  1 sibling, 2 replies; 20+ messages in thread
From: Krzysztof Kozlowski @ 2022-05-31 10:08 UTC (permalink / raw)
  To: Puranjay Mohan, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, grygorii.strashko,
	vigneshr, kishon, robh+dt, afd, andrew

On 31/05/2022 11:51, Puranjay Mohan wrote:
> Add a YAML binding document for the ICSSG Programmable real time unit
> based Ethernet driver. This driver uses the PRU and PRUSS consumer APIs
> to interface the PRUs and load/run the firmware for supporting ethernet
> functionality.
> 
> Signed-off-by: Puranjay Mohan <p-mohan@ti.com>
> ---
> v1: https://lore.kernel.org/all/20220506052433.28087-2-p-mohan@ti.com/ 
> v1 -> v2:
> * Addressed Rob's Comments

Nope, they were not addressed.

> * It includes indentation, formatting, and other minor changes.
> ---
>  .../bindings/net/ti,icssg-prueth.yaml         | 181 ++++++++++++++++++
>  1 file changed, 181 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
> new file mode 100644
> index 000000000000..40af968e9178
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
> @@ -0,0 +1,181 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/ti,icssg-prueth.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: |+

Missed Rob's comment.

> +  Texas Instruments ICSSG PRUSS Ethernet
> +
> +maintainers:
> +  - Puranjay Mohan <p-mohan@ti.com>
> +
> +description:
> +  Ethernet based on the Programmable Real-Time
> +  Unit and Industrial Communication Subsystem.
> +
> +allOf:
> +  - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - ti,am654-icssg-prueth  # for AM65x SoC family
> +
> +  pinctrl-0:
> +    maxItems: 1
> +
> +  pinctrl-names:
> +    items:
> +      - const: default

You do not need these usually, they are coming from schema.

> +
> +  sram:
> +    description:
> +      phandle to MSMC SRAM node
> +
> +  dmas:
> +    maxItems: 10
> +    description:
> +      list of phandles and specifiers to UDMA.

Please follow Rob's comment - drop description.

> +
> +  dma-names:
> +    items:
> +      - const: tx0-0
> +      - const: tx0-1
> +      - const: tx0-2
> +      - const: tx0-3
> +      - const: tx1-0
> +      - const: tx1-1
> +      - const: tx1-2
> +      - const: tx1-3
> +      - const: rx0
> +      - const: rx1
> +
> +  ethernet-ports:
> +    type: object
> +    properties:
> +      '#address-cells':
> +        const: 1
> +      '#size-cells':
> +        const: 0
> +
> +    patternProperties:
> +      ^port@[0-1]$:

How did you implement Rob's comments here?

> +        type: object
> +        description: ICSSG PRUETH external ports
> +
> +        $ref: ethernet-controller.yaml#
> +
> +        unevaluatedProperties: false
> +        additionalProperties: true

No one proposed to add additionalProperties:true... Does it even work?

> +        properties:
> +          reg:
> +            items:
> +              - enum: [0, 1]
> +            description: ICSSG PRUETH port number
> +
> +          ti,syscon-rgmii-delay:
> +            $ref: /schemas/types.yaml#/definitions/phandle-array
> +            description:
> +              phandle to system controller node and register offset
> +              to ICSSG control register for RGMII transmit delay
> +
> +        required:
> +          - reg
> +
> +  ti,mii-g-rt:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: |
> +      phandle to MII_G_RT module's syscon regmap.
> +
> +  ti,mii-rt:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: |
> +      phandle to MII_RT module's syscon regmap
> +
> +  interrupts:
> +    minItems: 2
> +    maxItems: 2
> +    description: |
> +      Interrupt specifiers to TX timestamp IRQ.
> +
> +  interrupt-names:
> +    items:
> +      - const: tx_ts0
> +      - const: tx_ts1
> +
> +required:
> +  - compatible
> +  - sram
> +  - ti,mii-g-rt
> +  - dmas
> +  - dma-names
> +  - ethernet-ports
> +  - interrupts
> +  - interrupt-names
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +
> +    /* Example k3-am654 base board SR2.0, dual-emac */
> +    pruss2_eth: pruss2_eth {
> +            compatible = "ti,am654-icssg-prueth";

Again missed Rob's comment.

Really, you ignored four of his comments. Please respect reviewers time
but not forcing them to repeat same review comments.

Best regards,
Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
       [not found] ` <20220531095108.21757-3-p-mohan@ti.com>
@ 2022-05-31 10:20   ` Krzysztof Kozlowski
  2022-05-31 11:23   ` Paolo Abeni
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 20+ messages in thread
From: Krzysztof Kozlowski @ 2022-05-31 10:20 UTC (permalink / raw)
  To: Puranjay Mohan, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, grygorii.strashko,
	vigneshr, kishon, robh+dt, afd, andrew

On 31/05/2022 11:51, Puranjay Mohan wrote:
> From: Roger Quadros <rogerq@ti.com>
> 
> This is the Ethernet driver for TI AM654 Silicon rev. 2
> with the ICSSG PRU Sub-system running dual-EMAC firmware.
> 
> The Programmable Real-time Unit and Industrial Communication Subsystem
> Gigabit (PRU_ICSSG) is a low-latency microcontroller subsystem in the TI
> SoCs. This subsystem is provided for the use cases like implementation of
> custom peripheral interfaces, offloading of tasks from the other
> processor cores of the SoC, etc.
> 
> Every ICSSG core has two Programmable Real-Time Unit(PRUs),
> two auxiliary Real-Time Transfer Unit (RT_PRUs), and
> two Transmit Real-Time Transfer Units (TX_PRUs). Each one of these runs
> its own firmware. Every ICSSG core has two MII ports connect to these
> PRUs and also a MDIO port.
> 
> The cores can run different firmwares to support different protocols and
> features like switch-dev, timestamping, etc.
> 
> It uses System DMA to transfer and receive packets and
> shared memory register emulation between the firmware and
> driver for control and configuration.
> 
> This patch adds support for basic EMAC functionality with 1Gbps
> and 100Mbps link speed. 10M and half duplex mode are not supported
> currently as they require IEP, the support for which will be added later.
> Support for switch-dev, timestamp, etc. will be added later
> by subsequent patch series.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> [Vignesh Raghavendra: add 10M full duplex support]
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
> [Grygorii Strashko: add support for half duplex operation]
> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
> Signed-off-by: Puranjay Mohan <p-mohan@ti.com>
> ---
> v1: https://lore.kernel.org/all/20220506052433.28087-3-p-mohan@ti.com/
> v1 -> v2:
> * Addressed Andrew's comments
> * Used iopoll in place of a loop
> * Moved phydev from private data to ndev
> * Used netdev_err() in place of pr_err()
> * Used phy_ethtool_set_link_ksettings() in 
>   place of phy_ethtool_ksettings_set() and similar
> * Added error checking to DT logic.
> ---
>  drivers/net/ethernet/ti/Kconfig            |   15 +
>  drivers/net/ethernet/ti/Makefile           |    3 +
>  drivers/net/ethernet/ti/icssg_classifier.c |  375 ++++
>  drivers/net/ethernet/ti/icssg_config.c     |  440 +++++
>  drivers/net/ethernet/ti/icssg_config.h     |  200 +++
>  drivers/net/ethernet/ti/icssg_ethtool.c    |  319 ++++
>  drivers/net/ethernet/ti/icssg_mii_cfg.c    |  104 ++
>  drivers/net/ethernet/ti/icssg_mii_rt.h     |  151 ++
>  drivers/net/ethernet/ti/icssg_prueth.c     | 1889 ++++++++++++++++++++
>  drivers/net/ethernet/ti/icssg_prueth.h     |  246 +++
>  drivers/net/ethernet/ti/icssg_switch_map.h |  183 ++
>  include/linux/pruss.h                      |    1 +
>  12 files changed, 3926 insertions(+)
>  create mode 100644 drivers/net/ethernet/ti/icssg_classifier.c
>  create mode 100644 drivers/net/ethernet/ti/icssg_config.c
>  create mode 100644 drivers/net/ethernet/ti/icssg_config.h
>  create mode 100644 drivers/net/ethernet/ti/icssg_ethtool.c
>  create mode 100644 drivers/net/ethernet/ti/icssg_mii_cfg.c
>  create mode 100644 drivers/net/ethernet/ti/icssg_mii_rt.h
>  create mode 100644 drivers/net/ethernet/ti/icssg_prueth.c
>  create mode 100644 drivers/net/ethernet/ti/icssg_prueth.h
>  create mode 100644 drivers/net/ethernet/ti/icssg_switch_map.h
> 
> diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
> index fb30bc5d56cb..500d0591ad2a 100644
> --- a/drivers/net/ethernet/ti/Kconfig
> +++ b/drivers/net/ethernet/ti/Kconfig
> @@ -182,4 +182,19 @@ config CPMAC
>  	help
>  	  TI AR7 CPMAC Ethernet support
>  
> +config TI_ICSSG_PRUETH
> +	tristate "TI Gigabit PRU Ethernet driver"
> +	select PHYLIB
> +

No need for blank line.

> +	depends on PRU_REMOTEPROC
> +	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
> +	help
> +	  Support dual Gigabit Ethernet ports over the ICSSG PRU Subsystem
> +	  This subsystem is available starting with the AM65 platform.
> +
> +	  This driver requires firmware binaries which will run on the PRUs
> +	  to support the ethernet operation. Currently, it supports Ethernet
> +	  with 1G and 100M link speed.
> +
> +

Only one blank line.

>  endif # NET_VENDOR_TI
> diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile
> index 75f761efbea7..963691511357 100644
> --- a/drivers/net/ethernet/ti/Makefile
> +++ b/drivers/net/ethernet/ti/Makefile
> @@ -28,3 +28,6 @@ obj-$(CONFIG_TI_K3_AM65_CPSW_NUSS) += ti-am65-cpsw-nuss.o
>  ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o k3-cppi-desc-pool.o am65-cpsw-qos.o
>  ti-am65-cpsw-nuss-$(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV) += am65-cpsw-switchdev.o
>  obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o
> +

No need for blank line.

> +obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg-prueth.o
> +icssg-prueth-y := icssg_prueth.o icssg_classifier.o icssg_ethtool.o icssg_config.o k3-cppi-desc-pool.o icssg_mii_cfg.o
> diff --git a/drivers/net/ethernet/ti/icssg_classifier.c b/drivers/net/ethernet/ti/icssg_classifier.c
> new file mode 100644
> index 000000000000..0d3325822ce2
> --- /dev/null
> +++ b/drivers/net/ethernet/ti/icssg_classifier.c
> @@ -0,0 +1,375 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Texas Instruments ICSSG Ethernet Driver
> + *
> + * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
> + *
> + */
> +
> +#include <linux/etherdevice.h>
> +#include <linux/types.h>
> +#include <linux/regmap.h>
> +
> +#include "icssg_prueth.h"
> +
> +#define ICSSG_NUM_CLASSIFIERS	16
> +#define ICSSG_NUM_FT1_SLOTS	8
> +#define ICSSG_NUM_FT3_SLOTS	16
> +
> +#define ICSSG_NUM_CLASSIFIERS_IN_USE	5
> +
> +/* Filter 1 - FT1 */
> +#define FT1_NUM_SLOTS	8
> +#define FT1_SLOT_SIZE	0x10	/* bytes */
> +
> +/* offsets from FT1 slot base i.e. slot 1 start */
> +#define FT1_DA0		0x0
> +#define FT1_DA1		0x4
> +#define FT1_DA0_MASK	0x8
> +#define FT1_DA1_MASK	0xc
> +
> +#define FT1_N_REG(slize, n, reg)	(offs[slice].ft1_slot_base + FT1_SLOT_SIZE * (n) + (reg))
> +
> +#define FT1_LEN_MASK	GENMASK(19, 16)
> +#define FT1_LEN_SHIFT	16
> +#define FT1_LEN(len)	(((len) << FT1_LEN_SHIFT) & FT1_LEN_MASK)
> +
> +#define FT1_START_MASK	GENMASK(14, 0)
> +#define FT1_START(start)	((start) & FT1_START_MASK)
> +
> +#define FT1_MATCH_SLOT(n)	(GENMASK(23, 16) & (BIT(n) << 16))
> +
> +enum ft1_cfg_type {
> +	FT1_CFG_TYPE_DISABLED = 0,
> +	FT1_CFG_TYPE_EQ,
> +	FT1_CFG_TYPE_GT,
> +	FT1_CFG_TYPE_LT,
> +};
> +
> +#define FT1_CFG_SHIFT(n)	(2 * (n))
> +#define FT1_CFG_MASK(n)	(0x3 << FT1_CFG_SHIFT((n)))
> +
> +/* Filter 3 -  FT3 */
> +#define FT3_NUM_SLOTS	16
> +#define FT3_SLOT_SIZE	0x20	/* bytes */
> +
> +/* offsets from FT3 slot n's base */
> +#define FT3_START	0
> +#define FT3_START_AUTO	0x4
> +#define FT3_START_OFFSET	0x8
> +#define FT3_JUMP_OFFSET	0xc
> +#define FT3_LEN		0x10
> +#define FT3_CFG		0x14
> +#define FT3_T		0x18
> +#define FT3_T_MASK	0x1c
> +
> +#define FT3_N_REG(slize, n, reg)	(offs[slice].ft3_slot_base + FT3_SLOT_SIZE * (n) + (reg))
> +
> +/* offsets from rx_class n's base */
> +#define RX_CLASS_AND_EN	0
> +#define RX_CLASS_OR_EN	0x4
> +
> +#define RX_CLASS_NUM_SLOTS	16
> +#define RX_CLASS_EN_SIZE	0x8	/* bytes */
> +
> +#define RX_CLASS_N_REG(slice, n, reg)	(offs[slice].rx_class_base + RX_CLASS_EN_SIZE * (n) + (reg))
> +
> +/* RX Class Gates */
> +#define RX_CLASS_GATES_SIZE	0x4	/* bytes */
> +
> +#define RX_CLASS_GATES_N_REG(slice, n)	\
> +	(offs[slice].rx_class_gates_base + RX_CLASS_GATES_SIZE * (n))
> +
> +#define RX_CLASS_GATES_ALLOW_MASK	BIT(6)
> +#define RX_CLASS_GATES_RAW_MASK		BIT(5)
> +#define RX_CLASS_GATES_PHASE_MASK	BIT(4)
> +
> +/* RX Class traffic data matching bits */
> +#define RX_CLASS_FT_UC		BIT(31)
> +#define RX_CLASS_FT_MC		BIT(30)
> +#define RX_CLASS_FT_BC		BIT(29)
> +#define RX_CLASS_FT_FW		BIT(28)
> +#define RX_CLASS_FT_RCV		BIT(27)
> +#define RX_CLASS_FT_VLAN	BIT(26)
> +#define RX_CLASS_FT_DA_P	BIT(25)
> +#define RX_CLASS_FT_DA_I	BIT(24)
> +#define RX_CLASS_FT_FT1_MATCH_MASK	GENMASK(23, 16)
> +#define RX_CLASS_FT_FT1_MATCH_SHIFT	16
> +#define RX_CLASS_FT_FT3_MATCH_MASK	GENMASK(15, 0)
> +#define RX_CLASS_FT_FT3_MATCH_SHIFT	0
> +
> +#define RX_CLASS_FT_FT1_MATCH(slot)	\
> +	((BIT(slot) << RX_CLASS_FT_FT1_MATCH_SHIFT) & RX_CLASS_FT_FT1_MATCH_MASK)
> +
> +enum rx_class_sel_type {
> +	RX_CLASS_SEL_TYPE_OR = 0,
> +	RX_CLASS_SEL_TYPE_AND = 1,
> +	RX_CLASS_SEL_TYPE_OR_AND_AND = 2,
> +	RX_CLASS_SEL_TYPE_OR_OR_AND = 3,
> +};
> +
> +#define FT1_CFG_SHIFT(n)	(2 * (n))
> +#define FT1_CFG_MASK(n)		(0x3 << FT1_CFG_SHIFT((n)))
> +
> +#define RX_CLASS_SEL_SHIFT(n)	(2 * (n))
> +#define RX_CLASS_SEL_MASK(n)	(0x3 << RX_CLASS_SEL_SHIFT((n)))
> +
> +#define ICSSG_CFG_OFFSET	0
> +#define MAC_INTERFACE_0		0x18
> +#define MAC_INTERFACE_1		0x1c
> +
> +#define ICSSG_CFG_RX_L2_G_EN	BIT(2)
> +
> +/* these are register offsets per PRU */
> +struct miig_rt_offsets {
> +	u32 mac0;
> +	u32 mac1;
> +	u32 ft1_start_len;
> +	u32 ft1_cfg;
> +	u32 ft1_slot_base;
> +	u32 ft3_slot_base;
> +	u32 ft3_p_base;
> +	u32 ft_rx_ptr;
> +	u32 rx_class_base;
> +	u32 rx_class_cfg1;
> +	u32 rx_class_cfg2;
> +	u32 rx_class_gates_base;
> +	u32 rx_green;
> +	u32 rx_rate_cfg_base;
> +	u32 rx_rate_src_sel0;
> +	u32 rx_rate_src_sel1;
> +	u32 tx_rate_cfg_base;
> +	u32 stat_base;
> +	u32 tx_hsr_tag;
> +	u32 tx_hsr_seq;
> +	u32 tx_vlan_type;
> +	u32 tx_vlan_ins;
> +};
> +
> +static struct miig_rt_offsets offs[] = {

Isn't this const?

> +	/* PRU0 */
> +	{
> +		0x8,
> +		0xc,
> +		0x80,
> +		0x84,
> +		0x88,
> +		0x108,
> +		0x308,
> +		0x408,
> +		0x40c,
> +		0x48c,
> +		0x490,
> +		0x494,
> +		0x4d4,
> +		0x4e4,
> +		0x504,
> +		0x508,
> +		0x50c,
> +		0x54c,
> +		0x63c,
> +		0x640,
> +		0x644,
> +		0x648,
> +	},
> +	/* PRU1 */
> +	{
> +		0x10,
> +		0x14,
> +		0x64c,
> +		0x650,
> +		0x654,
> +		0x6d4,
> +		0x8d4,
> +		0x9d4,
> +		0x9d8,
> +		0xa58,
> +		0xa5c,
> +		0xa60,
> +		0xaa0,
> +		0xab0,
> +		0xad0,
> +		0xad4,
> +		0xad8,
> +		0xb18,
> +		0xc08,
> +		0xc0c,
> +		0xc10,
> +		0xc14,
> +	},
> +};
> +
> +static inline u32 addr_to_da0(const u8 *addr)
> +{
> +	return (u32)(addr[0] | addr[1] << 8 |
> +		addr[2] << 16 | addr[3] << 24);
> +};
> +
> +static inline u32 addr_to_da1(const u8 *addr)
> +{
> +	return (u32)(addr[4] | addr[5] << 8);
> +};
> +
> +static void rx_class_ft1_set_start_len(struct regmap *miig_rt, int slice,
> +				       u16 start, u8 len)
> +{
> +	u32 offset, val;
> +
> +	offset = offs[slice].ft1_start_len;
> +	val = FT1_LEN(len) | FT1_START(start);
> +	regmap_write(miig_rt, offset, val);
> +}
> +
> +static void rx_class_ft1_set_da(struct regmap *miig_rt, int slice,
> +				int n, const u8 *addr)
> +{
> +	u32 offset;
> +
> +	offset = FT1_N_REG(slice, n, FT1_DA0);
> +	regmap_write(miig_rt, offset, addr_to_da0(addr));
> +	offset = FT1_N_REG(slice, n, FT1_DA1);
> +	regmap_write(miig_rt, offset, addr_to_da1(addr));
> +}
> +
> +static void rx_class_ft1_set_da_mask(struct regmap *miig_rt, int slice,
> +				     int n, const u8 *addr)
> +{
> +	u32 offset;
> +
> +	offset = FT1_N_REG(slice, n, FT1_DA0_MASK);
> +	regmap_write(miig_rt, offset, addr_to_da0(addr));
> +	offset = FT1_N_REG(slice, n, FT1_DA1_MASK);
> +	regmap_write(miig_rt, offset, addr_to_da1(addr));
> +}
> +
> +static void rx_class_ft1_cfg_set_type(struct regmap *miig_rt, int slice, int n,
> +				      enum ft1_cfg_type type)
> +{
> +	u32 offset;
> +
> +	offset = offs[slice].ft1_cfg;
> +	regmap_update_bits(miig_rt, offset, FT1_CFG_MASK(n),
> +			   type << FT1_CFG_SHIFT(n));
> +}
> +
> +static void rx_class_sel_set_type(struct regmap *miig_rt, int slice, int n,
> +				  enum rx_class_sel_type type)
> +{
> +	u32 offset;
> +
> +	offset = offs[slice].rx_class_cfg1;
> +	regmap_update_bits(miig_rt, offset, RX_CLASS_SEL_MASK(n),
> +			   type << RX_CLASS_SEL_SHIFT(n));
> +}
> +
> +static void rx_class_set_and(struct regmap *miig_rt, int slice, int n,
> +			     u32 data)
> +{
> +	u32 offset;
> +
> +	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_AND_EN);
> +	regmap_write(miig_rt, offset, data);
> +}
> +
> +static void rx_class_set_or(struct regmap *miig_rt, int slice, int n,
> +			    u32 data)
> +{
> +	u32 offset;
> +
> +	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN);
> +	regmap_write(miig_rt, offset, data);
> +}
> +
> +void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac)
> +{
> +	regmap_write(miig_rt, MAC_INTERFACE_0, addr_to_da0(mac));
> +	regmap_write(miig_rt, MAC_INTERFACE_1, addr_to_da1(mac));
> +}
> +
> +void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac)
> +{
> +	regmap_write(miig_rt, offs[slice].mac0, addr_to_da0(mac));
> +	regmap_write(miig_rt, offs[slice].mac1, addr_to_da1(mac));
> +}
> +
> +/* disable all RX traffic */
> +void icssg_class_disable(struct regmap *miig_rt, int slice)
> +{
> +	u32 data, offset;
> +	int n;
> +
> +	/* Enable RX_L2_G */
> +	regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_RX_L2_G_EN,
> +			   ICSSG_CFG_RX_L2_G_EN);
> +
> +	for (n = 0; n < ICSSG_NUM_CLASSIFIERS; n++) {
> +		/* AND_EN = 0 */
> +		rx_class_set_and(miig_rt, slice, n, 0);
> +		/* OR_EN = 0 */
> +		rx_class_set_or(miig_rt, slice, n, 0);
> +
> +		/* set CFG1 to OR */
> +		rx_class_sel_set_type(miig_rt, slice, n, RX_CLASS_SEL_TYPE_OR);
> +
> +		/* configure gate */
> +		offset = RX_CLASS_GATES_N_REG(slice, n);
> +		regmap_read(miig_rt, offset, &data);
> +		/* clear class_raw so we go through filters */
> +		data &= ~RX_CLASS_GATES_RAW_MASK;
> +		/* set allow and phase mask */
> +		data |= RX_CLASS_GATES_ALLOW_MASK | RX_CLASS_GATES_PHASE_MASK;
> +		regmap_write(miig_rt, offset, data);
> +	}
> +
> +	/* FT1 Disabled */
> +	for (n = 0; n < ICSSG_NUM_FT1_SLOTS; n++) {
> +		u8 addr[] = { 0, 0, 0, 0, 0, 0, };

const

> +
> +		rx_class_ft1_cfg_set_type(miig_rt, slice, n,
> +					  FT1_CFG_TYPE_DISABLED);
> +		rx_class_ft1_set_da(miig_rt, slice, n, addr);
> +		rx_class_ft1_set_da_mask(miig_rt, slice, n, addr);
> +	}
> +
> +	/* clear CFG2 */
> +	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
> +}
> +
> +void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti)
> +{
> +	int classifiers_in_use = 1;
> +	u32 data;
> +	int n;
> +
> +	/* defaults */
> +	icssg_class_disable(miig_rt, slice);
> +
> +	/* Setup Classifier */
> +	for (n = 0; n < classifiers_in_use; n++) {
> +		/* match on Broadcast or MAC_PRU address */
> +		data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P;
> +
> +		/* multicast? */
> +		if (allmulti)
> +			data |= RX_CLASS_FT_MC;
> +
> +		rx_class_set_or(miig_rt, slice, n, data);
> +
> +		/* set CFG1 for OR_OR_AND for classifier */
> +		rx_class_sel_set_type(miig_rt, slice, n,
> +				      RX_CLASS_SEL_TYPE_OR_OR_AND);
> +	}
> +
> +	/* clear CFG2 */
> +	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
> +}
> +
> +/* required for SAV check */
> +void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr)
> +{
> +	u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, };

const

> +
> +	rx_class_ft1_set_start_len(miig_rt, slice, 0, 6);
> +	rx_class_ft1_set_da(miig_rt, slice, 0, mac_addr);
> +	rx_class_ft1_set_da_mask(miig_rt, slice, 0, mask_addr);
> +	rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ);
> +}
> diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c
> new file mode 100644
> index 000000000000..a88ea4933802
> --- /dev/null
> +++ b/drivers/net/ethernet/ti/icssg_config.c
> @@ -0,0 +1,440 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* ICSSG Ethernet driver
> + *
> + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com
> + */
> +
> +#include <linux/iopoll.h>
> +#include <linux/regmap.h>
> +#include <uapi/linux/if_ether.h>
> +#include "icssg_config.h"
> +#include "icssg_prueth.h"
> +#include "icssg_switch_map.h"
> +#include "icssg_mii_rt.h"
> +
> +/* TX IPG Values to be set for 100M link speed. These values are
> + * in ocp_clk cycles. So need change if ocp_clk is changed for a specific
> + * h/w design.
> + */
> +
> +/* IPG is in core_clk cycles */
> +#define MII_RT_TX_IPG_100M	0x17
> +#define MII_RT_TX_IPG_1G	0xb
> +
> +#define	ICSSG_QUEUES_MAX		64

Messed up space after #define

> +#define	ICSSG_QUEUE_OFFSET		0xd00
> +#define	ICSSG_QUEUE_PEEK_OFFSET		0xe00
> +#define	ICSSG_QUEUE_CNT_OFFSET		0xe40
> +#define	ICSSG_QUEUE_RESET_OFFSET	0xf40
> +
> +#define	ICSSG_NUM_TX_QUEUES	8
> +
> +#define	RECYCLE_Q_SLICE0	16
> +#define	RECYCLE_Q_SLICE1	17
> +
> +#define	ICSSG_NUM_OTHER_QUEUES	5	/* port, host and special queues */
> +
> +#define	PORT_HI_Q_SLICE0	32
> +#define	PORT_LO_Q_SLICE0	33
> +#define	HOST_HI_Q_SLICE0	34
> +#define	HOST_LO_Q_SLICE0	35
> +#define	HOST_SPL_Q_SLICE0	40	/* Special Queue */
> +
> +#define	PORT_HI_Q_SLICE1	36
> +#define	PORT_LO_Q_SLICE1	37
> +#define	HOST_HI_Q_SLICE1	38
> +#define	HOST_LO_Q_SLICE1	39
> +#define	HOST_SPL_Q_SLICE1	41	/* Special Queue */
> +
> +#define MII_RXCFG_DEFAULT	(PRUSS_MII_RT_RXCFG_RX_ENABLE | \
> +				 PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS | \
> +				 PRUSS_MII_RT_RXCFG_RX_L2_EN | \
> +				 PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS)
> +
> +#define MII_TXCFG_DEFAULT	(PRUSS_MII_RT_TXCFG_TX_ENABLE | \
> +				 PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE | \
> +				 PRUSS_MII_RT_TXCFG_TX_32_MODE_EN | \
> +				 PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN)
> +
> +#define ICSSG_CFG_DEFAULT	(ICSSG_CFG_TX_L1_EN | \
> +				 ICSSG_CFG_TX_L2_EN | ICSSG_CFG_RX_L2_G_EN | \
> +				 ICSSG_CFG_TX_PRU_EN | \
> +				 ICSSG_CFG_SGMII_MODE)
> +
> +#define FDB_GEN_CFG1		0x60
> +#define SMEM_VLAN_OFFSET	8
> +#define SMEM_VLAN_OFFSET_MASK	GENMASK(25, 8)
> +
> +#define FDB_GEN_CFG2		0x64
> +#define FDB_VLAN_EN		BIT(6)
> +#define FDB_HOST_EN		BIT(2)
> +#define FDB_PRU1_EN		BIT(1)
> +#define FDB_PRU0_EN		BIT(0)
> +#define FDB_EN_ALL		(FDB_PRU0_EN | FDB_PRU1_EN | \
> +				 FDB_HOST_EN | FDB_VLAN_EN)
> +
> +struct map {
> +	int queue;
> +	u32 pd_addr_start;
> +	u32 flags;
> +	bool special;
> +};
> +
> +struct map hwq_map[2][ICSSG_NUM_OTHER_QUEUES] = {

Isn't this const?

> +	{
> +		{ PORT_HI_Q_SLICE0, PORT_DESC0_HI, 0x200000, 0 },
> +		{ PORT_LO_Q_SLICE0, PORT_DESC0_LO, 0, 0 },
> +		{ HOST_HI_Q_SLICE0, HOST_DESC0_HI, 0x200000, 0 },
> +		{ HOST_LO_Q_SLICE0, HOST_DESC0_LO, 0, 0 },
> +		{ HOST_SPL_Q_SLICE0, HOST_SPPD0, 0x400000, 1 },
> +	},
> +	{
> +		{ PORT_HI_Q_SLICE1, PORT_DESC1_HI, 0xa00000, 0 },
> +		{ PORT_LO_Q_SLICE1, PORT_DESC1_LO, 0x800000, 0 },
> +		{ HOST_HI_Q_SLICE1, HOST_DESC1_HI, 0xa00000, 0 },
> +		{ HOST_LO_Q_SLICE1, HOST_DESC1_LO, 0x800000, 0 },
> +		{ HOST_SPL_Q_SLICE1, HOST_SPPD1, 0xc00000, 1 },
> +	},
> +};
> +
> +static void icssg_config_mii_init(struct prueth_emac *emac)
> +{
> +	struct prueth *prueth = emac->prueth;
> +	struct regmap *mii_rt = prueth->mii_rt;
> +	int slice = prueth_emac_slice(emac);
> +	u32 rxcfg_reg, txcfg_reg, pcnt_reg;
> +	u32 rxcfg, txcfg;
> +
> +	rxcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 :
> +				       PRUSS_MII_RT_RXCFG1;
> +	txcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 :
> +				       PRUSS_MII_RT_TXCFG1;
> +	pcnt_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 :
> +				       PRUSS_MII_RT_RX_PCNT1;
> +
> +	rxcfg = MII_RXCFG_DEFAULT;
> +	txcfg = MII_TXCFG_DEFAULT;
> +
> +	if (slice == ICSS_MII1)
> +		rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL;
> +
> +	/* In MII mode TX lines swapped inside ICSSG, so TX_MUX_SEL cfg need
> +	 * to be swapped also comparing to RGMII mode.
> +	 */
> +	if (emac->phy_if == PHY_INTERFACE_MODE_MII && slice == ICSS_MII0)
> +		txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
> +	else if (emac->phy_if != PHY_INTERFACE_MODE_MII && slice == ICSS_MII1)
> +		txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
> +
> +	regmap_write(mii_rt, rxcfg_reg, rxcfg);
> +	regmap_write(mii_rt, txcfg_reg, txcfg);
> +	regmap_write(mii_rt, pcnt_reg, 0x1);
> +}
> +
> +static void icssg_miig_queues_init(struct prueth *prueth, int slice)
> +{
> +	struct regmap *miig_rt = prueth->miig_rt;
> +	void __iomem *smem = prueth->shram.va;
> +	u8 pd[ICSSG_SPECIAL_PD_SIZE];
> +	int queue = 0, i, j;
> +	u32 *pdword;
> +
> +	/* reset hwqueues */
> +	if (slice)
> +		queue = ICSSG_NUM_TX_QUEUES;
> +
> +	for (i = 0; i < ICSSG_NUM_TX_QUEUES; i++) {
> +		regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
> +		queue++;
> +	}
> +
> +	queue = slice ? RECYCLE_Q_SLICE1 : RECYCLE_Q_SLICE0;
> +	regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
> +
> +	for (i = 0; i < ICSSG_NUM_OTHER_QUEUES; i++) {
> +		regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET,
> +			     hwq_map[slice][i].queue);
> +	}
> +
> +	/* initialize packet descriptors in SMEM */
> +	/* push pakcet descriptors to hwqueues */
> +
> +	pdword = (u32 *)pd;
> +	for (j = 0; j < ICSSG_NUM_OTHER_QUEUES; j++) {
> +		struct map *mp;
> +		int pd_size, num_pds;
> +		u32 pdaddr;
> +
> +		mp = &hwq_map[slice][j];
> +		if (mp->special) {
> +			pd_size = ICSSG_SPECIAL_PD_SIZE;
> +			num_pds = ICSSG_NUM_SPECIAL_PDS;
> +		} else	{
> +			pd_size = ICSSG_NORMAL_PD_SIZE;
> +			num_pds = ICSSG_NUM_NORMAL_PDS;
> +		}
> +
> +		for (i = 0; i < num_pds; i++) {
> +			memset(pd, 0, pd_size);
> +
> +			pdword[0] &= cpu_to_le32(ICSSG_FLAG_MASK);
> +			pdword[0] |= cpu_to_le32(mp->flags);
> +			pdaddr = mp->pd_addr_start + i * pd_size;
> +
> +			memcpy_toio(smem + pdaddr, pd, pd_size);
> +			queue = mp->queue;
> +			regmap_write(miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue,
> +				     pdaddr);
> +		}
> +	}
> +}
> +
> +void icssg_config_ipg(struct prueth_emac *emac)
> +{
> +	struct prueth *prueth = emac->prueth;
> +	int slice = prueth_emac_slice(emac);
> +
> +	switch (emac->speed) {
> +	case SPEED_1000:
> +		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_1G);
> +		break;
> +	case SPEED_100:
> +		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M);
> +		break;
> +	default:
> +		/* Other links speeds not supported */
> +		netdev_err(emac->ndev, "Unsupported link speed\n");
> +		return;
> +	}
> +}
> +
> +static void emac_r30_cmd_init(struct prueth_emac *emac)
> +{
> +	int i;
> +	struct icssg_r30_cmd *p;
> +
> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
> +
> +	for (i = 0; i < 4; i++)
> +		writel(EMAC_NONE, &p->cmd[i]);
> +}
> +
> +static int emac_r30_is_done(struct prueth_emac *emac)
> +{
> +	const struct icssg_r30_cmd *p;
> +	int i;
> +	u32 cmd;
> +
> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
> +
> +	for (i = 0; i < 4; i++) {
> +		cmd = readl(&p->cmd[i]);
> +		if (cmd != EMAC_NONE)
> +			return 0;
> +	}
> +
> +	return 1;
> +}
> +
> +static int prueth_emac_buffer_setup(struct prueth_emac *emac)
> +{
> +	struct icssg_buffer_pool_cfg *bpool_cfg;
> +	struct prueth *prueth = emac->prueth;
> +	int slice = prueth_emac_slice(emac);
> +	struct icssg_rxq_ctx *rxq_ctx;
> +	u32 addr;
> +	int i;
> +
> +	/* Layout to have 64KB aligned buffer pool
> +	 * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1|
> +	 */
> +
> +	addr = lower_32_bits(prueth->msmcram.pa);
> +	if (slice)
> +		addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
> +
> +	if (addr % SZ_64K) {
> +		dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n");
> +		return -EINVAL;
> +	}
> +
> +	bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET;
> +	/* workaround for f/w bug. bpool 0 needs to be initilalized */
> +	bpool_cfg[0].addr = cpu_to_le32(addr);
> +	bpool_cfg[0].len = 0;
> +
> +	for (i = PRUETH_EMAC_BUF_POOL_START;
> +	     i < (PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS);
> +	     i++) {
> +		bpool_cfg[i].addr = cpu_to_le32(addr);
> +		bpool_cfg[i].len = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE);
> +		addr += PRUETH_EMAC_BUF_POOL_SIZE;
> +	}
> +
> +	if (!slice)
> +		addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
> +	else
> +		addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2;
> +
> +	/* Pre-emptible RX buffer queue */
> +	rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET;
> +	for (i = 0; i < 3; i++)
> +		rxq_ctx->start[i] = cpu_to_le32(addr);
> +
> +	addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
> +	rxq_ctx->end = cpu_to_le32(addr);
> +
> +	/* Express RX buffer queue */
> +	rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET;
> +	for (i = 0; i < 3; i++)
> +		rxq_ctx->start[i] = cpu_to_le32(addr);
> +
> +	addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
> +	rxq_ctx->end = cpu_to_le32(addr);
> +
> +	return 0;
> +}
> +
> +static void icssg_init_emac_mode(struct prueth *prueth)
> +{
> +	/* When the device is configured as a bridge and it is being brought back
> +	 * to the emac mode, the host mac address has to be set as 0.
> +	 */
> +	u8 mac[ETH_ALEN] = { 0 };
> +
> +	if (prueth->emacs_initialized)
> +		return;
> +
> +	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, 0);
> +	regmap_write(prueth->miig_rt, FDB_GEN_CFG2, 0);
> +	/* Clear host MAC address */
> +	icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
> +}
> +
> +int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
> +{
> +	void *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
> +	u8 *cfg_byte_ptr = config;
> +	struct icssg_flow_cfg *flow_cfg;
> +	u32 mask;
> +	int ret;
> +
> +	icssg_init_emac_mode(prueth);
> +
> +	memset_io(config, 0, TAS_GATE_MASK_LIST0);
> +	icssg_miig_queues_init(prueth, slice);
> +
> +	emac->speed = SPEED_1000;
> +	emac->duplex = DUPLEX_FULL;
> +	if (!phy_interface_mode_is_rgmii(emac->phy_if)) {
> +		emac->speed = SPEED_100;
> +		emac->duplex = DUPLEX_FULL;
> +	}
> +	regmap_update_bits(prueth->miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_DEFAULT, ICSSG_CFG_DEFAULT);
> +	icssg_miig_set_interface_mode(prueth->miig_rt, slice, emac->phy_if);
> +	icssg_config_mii_init(emac);
> +	icssg_config_ipg(emac);
> +	icssg_update_rgmii_cfg(prueth->miig_rt, emac);
> +
> +	/* set GPI mode */
> +	pruss_cfg_gpimode(prueth->pruss, prueth->pru_id[slice],
> +			  PRUSS_GPI_MODE_MII);
> +
> +	/* enable XFR shift for PRU and RTU */
> +	mask = PRUSS_SPP_XFER_SHIFT_EN | PRUSS_SPP_RTU_XFR_SHIFT_EN;
> +	pruss_cfg_update(prueth->pruss, PRUSS_CFG_SPP, mask, mask);
> +
> +	/* set C28 to 0x100 */
> +	pru_rproc_set_ctable(prueth->pru[slice], PRU_C28, 0x100 << 8);
> +	pru_rproc_set_ctable(prueth->rtu[slice], PRU_C28, 0x100 << 8);
> +	pru_rproc_set_ctable(prueth->txpru[slice], PRU_C28, 0x100 << 8);
> +
> +	flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
> +	flow_cfg->rx_base_flow = cpu_to_le32(emac->rx_flow_id_base);
> +	flow_cfg->mgm_base_flow = 0;
> +	*(cfg_byte_ptr + SPL_PKT_DEFAULT_PRIORITY) = 0;
> +	*(cfg_byte_ptr + QUEUE_NUM_UNTAGGED) = 0x0;
> +
> +	ret = prueth_emac_buffer_setup(emac);
> +	if (ret)
> +		return ret;
> +
> +	emac_r30_cmd_init(emac);
> +
> +	return 0;
> +}
> +
> +static struct icssg_r30_cmd emac_r32_bitmask[] = {

Isn't this const?

> +	{{0xffff0004, 0xffff0100, 0xffff0100, EMAC_NONE}},	/* EMAC_PORT_DISABLE */
> +	{{0xfffb0040, 0xfeff0200, 0xfeff0200, EMAC_NONE}},	/* EMAC_PORT_BLOCK */
> +	{{0xffbb0000, 0xfcff0000, 0xdcff0000, EMAC_NONE}},	/* EMAC_PORT_FORWARD */
> +	{{0xffbb0000, 0xfcff0000, 0xfcff2000, EMAC_NONE}},	/* EMAC_PORT_FORWARD_WO_LEARNING */
> +	{{0xffff0001, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT ALL */
> +	{{0xfffe0002, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT TAGGED */
> +	{{0xfffc0000, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT UNTAGGED and PRIO */
> +	{{EMAC_NONE,  0xffff0020, EMAC_NONE, EMAC_NONE}},	/* TAS Trigger List change */
> +	{{EMAC_NONE,  0xdfff1000, EMAC_NONE, EMAC_NONE}},	/* TAS set state ENABLE*/
> +	{{EMAC_NONE,  0xefff2000, EMAC_NONE, EMAC_NONE}},	/* TAS set state RESET*/
> +	{{EMAC_NONE,  0xcfff0000, EMAC_NONE, EMAC_NONE}},	/* TAS set state DISABLE*/
> +	{{EMAC_NONE,  EMAC_NONE,  0xffff0400, EMAC_NONE}},	/* UC flooding ENABLE*/
> +	{{EMAC_NONE,  EMAC_NONE,  0xfbff0000, EMAC_NONE}},	/* UC flooding DISABLE*/
> +	{{EMAC_NONE,  EMAC_NONE,  0xffff0800, EMAC_NONE}},	/* MC flooding ENABLE*/
> +	{{EMAC_NONE,  EMAC_NONE,  0xf7ff0000, EMAC_NONE}},	/* MC flooding DISABLE*/
> +	{{EMAC_NONE,  0xffff4000, EMAC_NONE, EMAC_NONE}},	/* Preemption on Tx ENABLE*/
> +	{{EMAC_NONE,  0xbfff0000, EMAC_NONE, EMAC_NONE}},	/* Preemption on Tx DISABLE*/
> +	{{0xffff0010,  EMAC_NONE, 0xffff0010, EMAC_NONE}},	/* VLAN AWARE*/
> +	{{0xffef0000,  EMAC_NONE, 0xffef0000, EMAC_NONE}}	/* VLAN UNWARE*/
> +};
> +
> +int emac_set_port_state(struct prueth_emac *emac,
> +			enum icssg_port_state_cmd cmd)
> +{
> +	struct icssg_r30_cmd *p;
> +	int ret = -ETIMEDOUT;
> +	int done = 0;
> +	int i;
> +
> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
> +
> +	if (cmd >= ICSSG_EMAC_PORT_MAX_COMMANDS) {
> +		netdev_err(emac->ndev, "invalid port command\n");
> +		return -EINVAL;
> +	}
> +
> +	/* only one command at a time allowed to firmware */
> +	mutex_lock(&emac->cmd_lock);
> +
> +	for (i = 0; i < 4; i++)
> +		writel(emac_r32_bitmask[cmd].cmd[i], &p->cmd[i]);
> +
> +	/* wait for done */
> +	ret = read_poll_timeout(emac_r30_is_done, done, done == 1,
> +				1000, 10000, false, emac);
> +
> +	if (ret == -ETIMEDOUT)
> +		netdev_err(emac->ndev, "timeout waiting for command done\n");
> +
> +	mutex_unlock(&emac->cmd_lock);
> +
> +	return ret;
> +}
> +
> +void icssg_config_set_speed(struct prueth_emac *emac)
> +{
> +	u8 fw_speed;
> +
> +	switch (emac->speed) {
> +	case SPEED_1000:
> +		fw_speed = FW_LINK_SPEED_1G;
> +		break;
> +	case SPEED_100:
> +		fw_speed = FW_LINK_SPEED_100M;
> +		break;
> +	default:
> +		/* Other links speeds not supported */
> +		netdev_err(emac->ndev, "Unsupported link speed\n");
> +		return;
> +	}
> +
> +	writeb(fw_speed, emac->dram.va + PORT_LINK_SPEED_OFFSET);
> +}
> diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h
> new file mode 100644
> index 000000000000..43eb0922172a
> --- /dev/null
> +++ b/drivers/net/ethernet/ti/icssg_config.h
> @@ -0,0 +1,200 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Texas Instruments ICSSG Ethernet driver
> + *
> + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
> + *
> + */
> +
> +#ifndef __NET_TI_ICSSG_CONFIG_H
> +#define __NET_TI_ICSSG_CONFIG_H
> +
> +struct icssg_buffer_pool_cfg {
> +	__le32	addr;
> +	__le32	len;
> +} __packed;
> +
> +struct icssg_flow_cfg {
> +	__le16 rx_base_flow;
> +	__le16 mgm_base_flow;
> +} __packed;
> +
> +#define PRUETH_PKT_TYPE_CMD	0x10
> +#define PRUETH_NAV_PS_DATA_SIZE	16	/* Protocol specific data size */
> +#define PRUETH_NAV_SW_DATA_SIZE	16	/* SW related data size */
> +#define PRUETH_MAX_TX_DESC	512
> +#define PRUETH_MAX_RX_DESC	512
> +#define PRUETH_MAX_RX_FLOWS	1	/* excluding default flow */
> +#define PRUETH_RX_FLOW_DATA	0
> +
> +#define PRUETH_EMAC_BUF_POOL_SIZE	SZ_8K
> +#define PRUETH_EMAC_POOLS_PER_SLICE	24
> +#define PRUETH_EMAC_BUF_POOL_START	8
> +#define PRUETH_NUM_BUF_POOLS	8
> +#define PRUETH_EMAC_RX_CTX_BUF_SIZE	SZ_16K	/* per slice */
> +#define MSMC_RAM_SIZE	\
> +	(2 * (PRUETH_EMAC_BUF_POOL_SIZE * PRUETH_NUM_BUF_POOLS + \
> +	 PRUETH_EMAC_RX_CTX_BUF_SIZE * 2))
> +
> +struct icssg_rxq_ctx {
> +	__le32 start[3];
> +	__le32 end;
> +} __packed;
> +
> +/* Load time Fiwmware Configuration */
> +
> +#define ICSSG_FW_MGMT_CMD_HEADER	0x81
> +#define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
> +#define ICSSG_FW_MGMT_CMD_TYPE		0x04
> +#define ICSSG_FW_MGMT_PKT		0x80000000
> +
> +struct icssg_r30_cmd {
> +	u32 cmd[4];
> +} __packed;
> +
> +enum icssg_port_state_cmd {
> +	ICSSG_EMAC_PORT_DISABLE = 0,
> +	ICSSG_EMAC_PORT_BLOCK,
> +	ICSSG_EMAC_PORT_FORWARD,
> +	ICSSG_EMAC_PORT_FORWARD_WO_LEARNING,
> +	ICSSG_EMAC_PORT_ACCEPT_ALL,
> +	ICSSG_EMAC_PORT_ACCEPT_TAGGED,
> +	ICSSG_EMAC_PORT_ACCEPT_UNTAGGED_N_PRIO,
> +	ICSSG_EMAC_PORT_TAS_TRIGGER,
> +	ICSSG_EMAC_PORT_TAS_ENABLE,
> +	ICSSG_EMAC_PORT_TAS_RESET,
> +	ICSSG_EMAC_PORT_TAS_DISABLE,
> +	ICSSG_EMAC_PORT_UC_FLOODING_ENABLE,
> +	ICSSG_EMAC_PORT_UC_FLOODING_DISABLE,
> +	ICSSG_EMAC_PORT_MC_FLOODING_ENABLE,
> +	ICSSG_EMAC_PORT_MC_FLOODING_DISABLE,
> +	ICSSG_EMAC_PORT_PREMPT_TX_ENABLE,
> +	ICSSG_EMAC_PORT_PREMPT_TX_DISABLE,
> +	ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE,
> +	ICSSG_EMAC_PORT_VLAN_AWARE_DISABLE,
> +	ICSSG_EMAC_PORT_MAX_COMMANDS
> +};
> +
> +#define EMAC_NONE           0xffff0000
> +#define EMAC_PRU0_P_DI      0xffff0004
> +#define EMAC_PRU1_P_DI      0xffff0040
> +#define EMAC_TX_P_DI        0xffff0100
> +
> +#define EMAC_PRU0_P_EN      0xfffb0000
> +#define EMAC_PRU1_P_EN      0xffbf0000
> +#define EMAC_TX_P_EN        0xfeff0000
> +
> +#define EMAC_P_BLOCK        0xffff0040
> +#define EMAC_TX_P_BLOCK     0xffff0200
> +#define EMAC_P_UNBLOCK      0xffbf0000
> +#define EMAC_TX_P_UNBLOCK   0xfdff0000
> +#define EMAC_LEAN_EN        0xfff70000
> +#define EMAC_LEAN_DI        0xffff0008
> +
> +#define EMAC_ACCEPT_ALL     0xffff0001
> +#define EMAC_ACCEPT_TAG     0xfffe0002
> +#define EMAC_ACCEPT_PRIOR   0xfffc0000
> +
> +/* Config area lies in DRAM */
> +#define ICSSG_CONFIG_OFFSET	0x0
> +
> +/* Config area lies in shared RAM */
> +#define ICSSG_CONFIG_OFFSET_SLICE0   0
> +#define ICSSG_CONFIG_OFFSET_SLICE1   0x8000
> +
> +#define ICSSG_NUM_NORMAL_PDS	64
> +#define ICSSG_NUM_SPECIAL_PDS	16
> +
> +#define ICSSG_NORMAL_PD_SIZE	8
> +#define ICSSG_SPECIAL_PD_SIZE	20
> +
> +#define ICSSG_FLAG_MASK		0xff00ffff
> +
> +struct icssg_setclock_desc {
> +	u8 request;
> +	u8 restore;
> +	u8 acknowledgment;
> +	u8 cmp_status;
> +	u32 margin;
> +	u32 cyclecounter0_set;
> +	u32 cyclecounter1_set;
> +	u32 iepcount_set;
> +	u32 rsvd1;
> +	u32 rsvd2;
> +	u32 CMP0_current;
> +	u32 iepcount_current;
> +	u32 difference;
> +	u32 cyclecounter0_new;
> +	u32 cyclecounter1_new;
> +	u32 CMP0_new;
> +} __packed;
> +
> +#define ICSSG_CMD_POP_SLICE0	56
> +#define ICSSG_CMD_POP_SLICE1	60
> +
> +#define ICSSG_CMD_PUSH_SLICE0	57
> +#define ICSSG_CMD_PUSH_SLICE1	61
> +
> +#define ICSSG_RSP_POP_SLICE0	58
> +#define ICSSG_RSP_POP_SLICE1	62
> +
> +#define ICSSG_RSP_PUSH_SLICE0	56
> +#define ICSSG_RSP_PUSH_SLICE1	60
> +
> +#define ICSSG_TS_POP_SLICE0	59
> +#define ICSSG_TS_POP_SLICE1	63
> +
> +#define ICSSG_TS_PUSH_SLICE0	40
> +#define ICSSG_TS_PUSH_SLICE1	41
> +
> +/* FDB FID_C2 flag definitions */
> +/* Indicates host port membership.*/
> +#define ICSSG_FDB_ENTRY_P0_MEMBERSHIP         BIT(0)
> +/* Indicates that MAC ID is connected to physical port 1 */
> +#define ICSSG_FDB_ENTRY_P1_MEMBERSHIP         BIT(1)
> +/* Indicates that MAC ID is connected to physical port 2 */
> +#define ICSSG_FDB_ENTRY_P2_MEMBERSHIP         BIT(2)
> +/* Ageable bit is set for learned entries and cleared for static entries */
> +#define ICSSG_FDB_ENTRY_AGEABLE               BIT(3)
> +/* If set for DA then packet is determined to be a special packet */
> +#define ICSSG_FDB_ENTRY_BLOCK                 BIT(4)
> +/* If set for DA then the SA from the packet is not learned */
> +#define ICSSG_FDB_ENTRY_SECURE                BIT(5)
> +/* If set, it means packet has been seen recently with source address + FID
> + * matching MAC address/FID of entry
> + */
> +#define ICSSG_FDB_ENTRY_TOUCHED               BIT(6)
> +/* Set if entry is valid */
> +#define ICSSG_FDB_ENTRY_VALID                 BIT(7)
> +
> +/**
> + * struct prueth_vlan_tbl - VLAN table entries struct in ICSSG SMEM
> + * @fid_c1: membership and forwarding rules flag to this table. See
> + *          above to defines for bit definitions
> + * @fid: FDB index for this VID (there is 1-1 mapping b/w VID and FID)
> + */
> +struct prueth_vlan_tbl {
> +	u8 fid_c1;
> +	u8 fid;
> +} __packed;
> +
> +/**
> + * struct prueth_fdb_slot - Result of FDB slot lookup
> + * @mac: MAC address
> + * @fid: fid to be associated with MAC
> + * @fid_c2: FID_C2 entry for this MAC
> + */
> +struct prueth_fdb_slot {
> +	u8 mac[ETH_ALEN];
> +	u8 fid;
> +	u8 fid_c2;
> +} __packed;
> +
> +enum icssg_ietfpe_verify_states {
> +	ICSSG_IETFPE_STATE_UNKNOWN = 0,
> +	ICSSG_IETFPE_STATE_INITIAL,
> +	ICSSG_IETFPE_STATE_VERIFYING,
> +	ICSSG_IETFPE_STATE_SUCCEEDED,
> +	ICSSG_IETFPE_STATE_FAILED,
> +	ICSSG_IETFPE_STATE_DISABLED
> +};
> +#endif /* __NET_TI_ICSSG_CONFIG_H */
> diff --git a/drivers/net/ethernet/ti/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg_ethtool.c
> new file mode 100644
> index 000000000000..fd09d223b0ae
> --- /dev/null
> +++ b/drivers/net/ethernet/ti/icssg_ethtool.c
> @@ -0,0 +1,319 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Texas Instruments ICSSG Ethernet driver
> + *
> + * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
> + *
> + */
> +
> +#include "icssg_prueth.h"
> +#include <linux/regmap.h>
> +
> +static u32 stats_base[] = {	0x54c,	/* Slice 0 stats start */
> +				0xb18,	/* Slice 1 stats start */

This also looks const.
Definitions of variable should go after type declarations.

> +};
> +
> +struct miig_stats_regs {
> +	/* Rx */



Best regards,
Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
       [not found] ` <20220531095108.21757-3-p-mohan@ti.com>
  2022-05-31 10:20   ` [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver Krzysztof Kozlowski
@ 2022-05-31 11:23   ` Paolo Abeni
  2022-11-04  8:29     ` Md Danish Anwar
  2022-05-31 13:11   ` Randy Dunlap
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 20+ messages in thread
From: Paolo Abeni @ 2022-05-31 11:23 UTC (permalink / raw)
  To: Puranjay Mohan, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, grygorii.strashko,
	vigneshr, kishon, robh+dt, afd, andrew

On Tue, 2022-05-31 at 15:21 +0530, Puranjay Mohan wrote:
[...]
> +static int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
> +				    int budget)
> +{
> +	struct net_device *ndev = emac->ndev;
> +	struct cppi5_host_desc_t *desc_tx;
> +	struct netdev_queue *netif_txq;
> +	struct prueth_tx_chn *tx_chn;
> +	unsigned int total_bytes = 0;
> +	struct sk_buff *skb;
> +	dma_addr_t desc_dma;
> +	int res, num_tx = 0;
> +	void **swdata;
> +
> +	tx_chn = &emac->tx_chns[chn];
> +
> +	while (budget--) {
> +		res = k3_udma_glue_pop_tx_chn(tx_chn->tx_chn, &desc_dma);
> +		if (res == -ENODATA)
> +			break;
> +
> +		/* teardown completion */
> +		if (cppi5_desc_is_tdcm(desc_dma)) {
> +			if (atomic_dec_and_test(&emac->tdown_cnt))
> +				complete(&emac->tdown_complete);
> +			break;
> +		}
> +
> +		desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
> +						     desc_dma);
> +		swdata = cppi5_hdesc_get_swdata(desc_tx);
> +
> +		skb = *(swdata);
> +		prueth_xmit_free(tx_chn, desc_tx);
> +
> +		ndev = skb->dev;
> +		ndev->stats.tx_packets++;
> +		ndev->stats.tx_bytes += skb->len;
> +		total_bytes += skb->len;
> +		napi_consume_skb(skb, budget);

The above is uncorrect. In this loop's last iteration 'budget' will  be
0 and napi_consume_skb will wrongly assume the caller is not in NAPI
context. 

> +static int prueth_dma_rx_push(struct prueth_emac *emac,
> +			      struct sk_buff *skb,
> +			      struct prueth_rx_chn *rx_chn)
> +{
> +	struct cppi5_host_desc_t *desc_rx;
> +	struct net_device *ndev = emac->ndev;
> +	dma_addr_t desc_dma;
> +	dma_addr_t buf_dma;
> +	u32 pkt_len = skb_tailroom(skb);
> +	void **swdata;
> +
> +	desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool);
> +	if (!desc_rx) {
> +		netdev_err(ndev, "rx push: failed to allocate descriptor\n");
> +		return -ENOMEM;
> +	}
> +	desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx);
> +
> +	buf_dma = dma_map_single(rx_chn->dma_dev, skb->data, pkt_len, DMA_FROM_DEVICE);
> +	if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) {
> +		k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
> +		netdev_err(ndev, "rx push: failed to map rx pkt buffer\n");
> +		return -EINVAL;
> +	}
> +
> +	cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT,
> +			 PRUETH_NAV_PS_DATA_SIZE);
> +	k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chn, &buf_dma);
> +	cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_tailroom(skb));
> +
> +	swdata = cppi5_hdesc_get_swdata(desc_rx);
> +	*swdata = skb;
> +
> +	return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0,
> +					desc_rx, desc_dma);
> +}
> +
> +static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id)
> +{
> +	struct prueth_rx_chn *rx_chn = &emac->rx_chns;
> +	struct net_device *ndev = emac->ndev;
> +	struct cppi5_host_desc_t *desc_rx;
> +	dma_addr_t desc_dma, buf_dma;
> +	u32 buf_dma_len, pkt_len, port_id = 0;
> +	int ret;
> +	void **swdata;
> +	struct sk_buff *skb, *new_skb;
> +
> +	ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma);
> +	if (ret) {
> +		if (ret != -ENODATA)
> +			netdev_err(ndev, "rx pop: failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	if (cppi5_desc_is_tdcm(desc_dma)) /* Teardown ? */
> +		return 0;
> +
> +	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
> +
> +	swdata = cppi5_hdesc_get_swdata(desc_rx);
> +	skb = *swdata;
> +
> +	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
> +	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma);
> +	pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
> +	/* firmware adds 4 CRC bytes, strip them */
> +	pkt_len -= 4;
> +	cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL);
> +
> +	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
> +	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
> +
> +	skb->dev = ndev;
> +	if (!netif_running(skb->dev)) {
> +		dev_kfree_skb_any(skb);
> +		return 0;
> +	}
> +
> +	new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE);
> +	/* if allocation fails we drop the packet but push the
> +	 * descriptor back to the ring with old skb to prevent a stall
> +	 */
> +	if (!new_skb) {
> +		ndev->stats.rx_dropped++;
> +		new_skb = skb;
> +	} else {
> +		/* send the filled skb up the n/w stack */
> +		skb_put(skb, pkt_len);
> +		skb->protocol = eth_type_trans(skb, ndev);
> +		netif_receive_skb(skb);

This is (apparently) in napi context. You should use napi_gro_receive()
or napi_gro_frags()


Cheers!

Paolo


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-05-31 10:08   ` Krzysztof Kozlowski
@ 2022-05-31 11:27     ` Puranjay Mohan
  2022-05-31 11:48       ` Krzysztof Kozlowski
  2022-06-05 15:11       ` Andrew Lunn
  2022-11-04  7:28     ` Md Danish Anwar
  1 sibling, 2 replies; 20+ messages in thread
From: Puranjay Mohan @ 2022-05-31 11:27 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, grygorii.strashko,
	vigneshr, kishon, robh+dt, afd, andrew

Hi Krzysztof,

On 31/05/22 15:38, Krzysztof Kozlowski wrote:
> On 31/05/2022 11:51, Puranjay Mohan wrote:
>> Add a YAML binding document for the ICSSG Programmable real time unit
>> based Ethernet driver. This driver uses the PRU and PRUSS consumer APIs
>> to interface the PRUs and load/run the firmware for supporting ethernet
>> functionality.
>>
>> Signed-off-by: Puranjay Mohan <p-mohan@ti.com>
>> ---
>> v1: https://lore.kernel.org/all/20220506052433.28087-2-p-mohan@ti.com/ 
>> v1 -> v2:
>> * Addressed Rob's Comments
> 
> Nope, they were not addressed.

I am trying my best to address them but I am new to DT Schemas, so, I
misunderstood a few comments.

> 
>> * It includes indentation, formatting, and other minor changes.
>> ---
>>  .../bindings/net/ti,icssg-prueth.yaml         | 181 ++++++++++++++++++
>>  1 file changed, 181 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>> new file mode 100644
>> index 000000000000..40af968e9178
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>> @@ -0,0 +1,181 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/net/ti,icssg-prueth.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: |+
> 
> Missed Rob's comment.

Sorry, Will remove this in next version.

> 
>> +  Texas Instruments ICSSG PRUSS Ethernet
>> +
>> +maintainers:
>> +  - Puranjay Mohan <p-mohan@ti.com>
>> +
>> +description:
>> +  Ethernet based on the Programmable Real-Time
>> +  Unit and Industrial Communication Subsystem.
>> +
>> +allOf:
>> +  - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - ti,am654-icssg-prueth  # for AM65x SoC family
>> +
>> +  pinctrl-0:
>> +    maxItems: 1
>> +
>> +  pinctrl-names:
>> +    items:
>> +      - const: default
> 
> You do not need these usually, they are coming from schema.

Will remove in next version.

> 
>> +
>> +  sram:
>> +    description:
>> +      phandle to MSMC SRAM node
>> +
>> +  dmas:
>> +    maxItems: 10
>> +    description:
>> +      list of phandles and specifiers to UDMA.
> 
> Please follow Rob's comment - drop description.

I misunderstood his comment, I thought he is asking to remove the
reference to the .txt file (Which I removed). I will remove it in next
version.

> 
>> +
>> +  dma-names:
>> +    items:
>> +      - const: tx0-0
>> +      - const: tx0-1
>> +      - const: tx0-2
>> +      - const: tx0-3
>> +      - const: tx1-0
>> +      - const: tx1-1
>> +      - const: tx1-2
>> +      - const: tx1-3
>> +      - const: rx0
>> +      - const: rx1
>> +
>> +  ethernet-ports:
>> +    type: object
>> +    properties:
>> +      '#address-cells':
>> +        const: 1
>> +      '#size-cells':
>> +        const: 0
>> +
>> +    patternProperties:
>> +      ^port@[0-1]$:
> 
> How did you implement Rob's comments here?

He said ethernet-port is preferred but all other drivers were using
"port" so I though it is not compulsory. Will change it if it compulsory
to use ethernet-port

> 
>> +        type: object
>> +        description: ICSSG PRUETH external ports
>> +
>> +        $ref: ethernet-controller.yaml#
>> +
>> +        unevaluatedProperties: false
>> +        additionalProperties: true
> 
> No one proposed to add additionalProperties:true... Does it even work?

This is my mistake, will remove it in next version.

> 
>> +        properties:
>> +          reg:
>> +            items:
>> +              - enum: [0, 1]
>> +            description: ICSSG PRUETH port number
>> +
>> +          ti,syscon-rgmii-delay:
>> +            $ref: /schemas/types.yaml#/definitions/phandle-array
>> +            description:
>> +              phandle to system controller node and register offset
>> +              to ICSSG control register for RGMII transmit delay
>> +
>> +        required:
>> +          - reg
>> +
>> +  ti,mii-g-rt:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description: |
>> +      phandle to MII_G_RT module's syscon regmap.
>> +
>> +  ti,mii-rt:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description: |
>> +      phandle to MII_RT module's syscon regmap
>> +
>> +  interrupts:
>> +    minItems: 2
>> +    maxItems: 2
>> +    description: |
>> +      Interrupt specifiers to TX timestamp IRQ.
>> +
>> +  interrupt-names:
>> +    items:
>> +      - const: tx_ts0
>> +      - const: tx_ts1
>> +
>> +required:
>> +  - compatible
>> +  - sram
>> +  - ti,mii-g-rt
>> +  - dmas
>> +  - dma-names
>> +  - ethernet-ports
>> +  - interrupts
>> +  - interrupt-names
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +
>> +    /* Example k3-am654 base board SR2.0, dual-emac */
>> +    pruss2_eth: pruss2_eth {
>> +            compatible = "ti,am654-icssg-prueth";
> 
> Again missed Rob's comment.

One of Rob's comment was to make the indentation as 4 which I have done.

The second comment was about 'ti,prus'.

So, ti,prus , firmware-name, and ti,pruss-gp-mux-sel are a part of
remoteproc/ti,pru-consumer.yaml which I have included with

allOf:
  - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#

So, I thought it is not required to add them again.

I will add it in next version, if that is how it should be done.

> 
> Really, you ignored four of his comments. Please respect reviewers time
> but not forcing them to repeat same review comments.

I am really sorry for this.

Thanks,
Puranjay Mohan


> 
> Best regards,
> Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-05-31 11:27     ` Puranjay Mohan
@ 2022-05-31 11:48       ` Krzysztof Kozlowski
  2022-05-31 11:59         ` Puranjay Mohan
  2022-06-05 15:11       ` Andrew Lunn
  1 sibling, 1 reply; 20+ messages in thread
From: Krzysztof Kozlowski @ 2022-05-31 11:48 UTC (permalink / raw)
  To: Puranjay Mohan, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, grygorii.strashko,
	vigneshr, kishon, robh+dt, afd, andrew

On 31/05/2022 13:27, Puranjay Mohan wrote:
>>> +examples:
>>> +  - |
>>> +
>>> +    /* Example k3-am654 base board SR2.0, dual-emac */
>>> +    pruss2_eth: pruss2_eth {
>>> +            compatible = "ti,am654-icssg-prueth";
>>
>> Again missed Rob's comment.
> 
> One of Rob's comment was to make the indentation as 4 which I have done.

I clearly do not see indentation of 4, but there is 8 instead.

Let's count:
+    pruss2_eth: pruss2_eth {
+            compatible = "ti,am654-icssg-prueth";
     12345678^

It's 8...

> 
> The second comment was about 'ti,prus'.
> 
> So, ti,prus , firmware-name, and ti,pruss-gp-mux-sel are a part of
> remoteproc/ti,pru-consumer.yaml which I have included with
> 
> allOf:
>   - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#
> 
> So, I thought it is not required to add them again.
> 
> I will add it in next version, if that is how it should be done.
I was referring to the indentation.

Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-05-31 11:48       ` Krzysztof Kozlowski
@ 2022-05-31 11:59         ` Puranjay Mohan
  2022-05-31 12:01           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 20+ messages in thread
From: Puranjay Mohan @ 2022-05-31 11:59 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, grygorii.strashko,
	vigneshr, kishon, robh+dt, afd, andrew

Hi Krzysztof,

On 31/05/22 17:18, Krzysztof Kozlowski wrote:
> On 31/05/2022 13:27, Puranjay Mohan wrote:
>>>> +examples:
>>>> +  - |
>>>> +
>>>> +    /* Example k3-am654 base board SR2.0, dual-emac */
>>>> +    pruss2_eth: pruss2_eth {
>>>> +            compatible = "ti,am654-icssg-prueth";
>>>
>>> Again missed Rob's comment.
>>
>> One of Rob's comment was to make the indentation as 4 which I have done.
> 
> I clearly do not see indentation of 4, but there is 8 instead.

I changed the indentation at the wrong place.

> 
> Let's count:
> +    pruss2_eth: pruss2_eth {
^ here, it was 8 in v1 so, I changed it to 4

> +            compatible = "ti,am654-icssg-prueth";
>      12345678^
> 

Compatible is the child of pruss2_eth, so, It should have 4+4 = 8?

> It's 8...
> 
>>
>> The second comment was about 'ti,prus'.
>>
>> So, ti,prus , firmware-name, and ti,pruss-gp-mux-sel are a part of
>> remoteproc/ti,pru-consumer.yaml which I have included with
>>
>> allOf:
>>   - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#
>>
>> So, I thought it is not required to add them again.
>>
>> I will add it in next version, if that is how it should be done.
> I was referring to the indentation.
> 
> Krzysztof

Thanks,
Puranjay

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-05-31 11:59         ` Puranjay Mohan
@ 2022-05-31 12:01           ` Krzysztof Kozlowski
  2022-06-01  4:28             ` Puranjay Mohan
  0 siblings, 1 reply; 20+ messages in thread
From: Krzysztof Kozlowski @ 2022-05-31 12:01 UTC (permalink / raw)
  To: Puranjay Mohan, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, grygorii.strashko,
	vigneshr, kishon, robh+dt, afd, andrew

On 31/05/2022 13:59, Puranjay Mohan wrote:
> Hi Krzysztof,
> 
> On 31/05/22 17:18, Krzysztof Kozlowski wrote:
>> On 31/05/2022 13:27, Puranjay Mohan wrote:
>>>>> +examples:
>>>>> +  - |
>>>>> +
>>>>> +    /* Example k3-am654 base board SR2.0, dual-emac */
>>>>> +    pruss2_eth: pruss2_eth {
>>>>> +            compatible = "ti,am654-icssg-prueth";
>>>>
>>>> Again missed Rob's comment.
>>>
>>> One of Rob's comment was to make the indentation as 4 which I have done.
>>
>> I clearly do not see indentation of 4, but there is 8 instead.
> 
> I changed the indentation at the wrong place.
> 
>>
>> Let's count:
>> +    pruss2_eth: pruss2_eth {
> ^ here, it was 8 in v1 so, I changed it to 4
> 
>> +            compatible = "ti,am654-icssg-prueth";
>>      12345678^
>>
> 
> Compatible is the child of pruss2_eth, so, It should have 4+4 = 8?

Yes. Indentation of four means first block is indented with 4 spaces.
The next block 4+4. The next one 4+4+4.

Best regards,
Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
       [not found] ` <20220531095108.21757-3-p-mohan@ti.com>
  2022-05-31 10:20   ` [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver Krzysztof Kozlowski
  2022-05-31 11:23   ` Paolo Abeni
@ 2022-05-31 13:11   ` Randy Dunlap
  2022-06-05 15:37   ` Andrew Lunn
  2022-06-05 16:24   ` Christophe JAILLET
  4 siblings, 0 replies; 20+ messages in thread
From: Randy Dunlap @ 2022-05-31 13:11 UTC (permalink / raw)
  To: Puranjay Mohan, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, grygorii.strashko,
	vigneshr, kishon, robh+dt, afd, andrew

Hi--

On 5/31/22 02:51, Puranjay Mohan wrote:
> diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
> index fb30bc5d56cb..500d0591ad2a 100644
> --- a/drivers/net/ethernet/ti/Kconfig
> +++ b/drivers/net/ethernet/ti/Kconfig
> @@ -182,4 +182,19 @@ config CPMAC
>  	help
>  	  TI AR7 CPMAC Ethernet support
>  
> +config TI_ICSSG_PRUETH
> +	tristate "TI Gigabit PRU Ethernet driver"
> +	select PHYLIB
> +
> +	depends on PRU_REMOTEPROC
> +	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
> +	help
> +	  Support dual Gigabit Ethernet ports over the ICSSG PRU Subsystem

	End the sentence above with a period ('.').

> +	  This subsystem is available starting with the AM65 platform.
> +
> +	  This driver requires firmware binaries which will run on the PRUs
> +	  to support the ethernet operation. Currently, it supports Ethernet

	Be consistent:   ethernet                       or          Ethernet

> +	  with 1G and 100M link speed.

-- 
~Randy

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-05-31  9:51 ` [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings Puranjay Mohan
  2022-05-31 10:08   ` Krzysztof Kozlowski
@ 2022-05-31 13:21   ` Rob Herring
  1 sibling, 0 replies; 20+ messages in thread
From: Rob Herring @ 2022-05-31 13:21 UTC (permalink / raw)
  To: Puranjay Mohan
  Cc: linux-kernel, netdev, robh+dt, edumazet, vigneshr, kishon, afd,
	davem, ssantosh, andrew, krzysztof.kozlowski+dt,
	grygorii.strashko, devicetree, s-anna, nm, rogerq,
	linux-arm-kernel

On Tue, 31 May 2022 15:21:07 +0530, Puranjay Mohan wrote:
> Add a YAML binding document for the ICSSG Programmable real time unit
> based Ethernet driver. This driver uses the PRU and PRUSS consumer APIs
> to interface the PRUs and load/run the firmware for supporting ethernet
> functionality.
> 
> Signed-off-by: Puranjay Mohan <p-mohan@ti.com>
> ---
> v1: https://lore.kernel.org/all/20220506052433.28087-2-p-mohan@ti.com/
> v1 -> v2:
> * Addressed Rob's Comments
> * It includes indentation, formatting, and other minor changes.
> ---
>  .../bindings/net/ti,icssg-prueth.yaml         | 181 ++++++++++++++++++
>  1 file changed, 181 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
./Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml: Unable to find schema file matching $id: http://devicetree.org/schemas/remoteproc/ti,pru-consumer.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/net/ti,icssg-prueth.example.dtb: pruss2_eth: False schema does not allow {'compatible': ['ti,am654-icssg-prueth'], 'pinctrl-names': ['default'], 'pinctrl-0': [[4294967295]], 'sram': [[4294967295]], 'ti,prus': [[4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295]], 'firmware-name': ['ti-pruss/am65x-pru0-prueth-fw.elf', 'ti-pruss/am65x-rtu0-prueth-fw.elf', 'ti-pruss/am65x-txpru0-prueth-fw.elf', 'ti-pruss/am65x-pru1-prueth-fw.elf', 'ti-pruss/am65x-rtu1-prueth-fw.elf', 'ti-pruss/am65x-txpru1-prueth-fw.elf'], 'ti,pruss-gp-mux-sel': [[2, 2, 2, 2, 2, 2]], 'ti,mii-g-rt': [[4294967295]], 'dmas': [[4294967295, 49920], [4294967295, 49921], [4294967295, 49922], [4294967295, 49923], [4294967295, 49924], [4294967295, 49925], [4294967295, 49926], [4294967295, 49927], [4294967295, 17152], [4294967295, 17153]], 'dma-names': ['tx0-0', 'tx0-1', 'tx0-2', 'tx0-3', 'tx1-0', 'tx1-1', 'tx1-2', 'tx1-3', 'rx0', 'rx1'], 'interrupts': [[24, 0, 2], [25, 1, 3]], 'interrupt-names': ['tx_ts0', 'tx_ts1'], 'ethernet-ports': {'#address-cells': [[1]], '#size-cells': [[0]], 'port@0': {'reg': [[0]], 'phy-handle': [[4294967295]], 'phy-mode': ['rgmii-rxid'], 'interrupts-extended': [[4294967295, 24]], 'ti,syscon-rgmii-delay': [[4294967295, 16672]], 'local-mac-address': [[0, 0, 0, 0, 0, 0]]}, 'port@1': {'reg': [[1]], 'phy-handle': [[4294967295]], 'phy-mode': ['rgmii-rxid'], 'interrupts-extended': [[4294967295, 25]], 'ti,syscon-rgmii-delay': [[4294967295, 16676]], 'local-mac-address': [[0, 0, 0, 0, 0, 0]]}}, '$nodename': ['pruss2_eth']}
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/net/ti,icssg-prueth.example.dtb: pruss2_eth: Unevaluated properties are not allowed ('firmware-name', 'ti,prus', 'ti,pruss-gp-mux-sel' were unexpected)
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml

doc reference errors (make refcheckdocs):

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

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

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

pip3 install dtschema --upgrade

Please check and re-submit.


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-05-31 12:01           ` Krzysztof Kozlowski
@ 2022-06-01  4:28             ` Puranjay Mohan
  0 siblings, 0 replies; 20+ messages in thread
From: Puranjay Mohan @ 2022-06-01  4:28 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, grygorii.strashko,
	vigneshr, kishon, robh+dt, afd, andrew

Hi Krzysztof,

On 31/05/22 17:31, Krzysztof Kozlowski wrote:
> On 31/05/2022 13:59, Puranjay Mohan wrote:
>> Hi Krzysztof,
>>
>> On 31/05/22 17:18, Krzysztof Kozlowski wrote:
>>> On 31/05/2022 13:27, Puranjay Mohan wrote:
>>>>>> +examples:
>>>>>> +  - |
>>>>>> +
>>>>>> +    /* Example k3-am654 base board SR2.0, dual-emac */
>>>>>> +    pruss2_eth: pruss2_eth {
>>>>>> +            compatible = "ti,am654-icssg-prueth";
>>>>>
>>>>> Again missed Rob's comment.
>>>>
>>>> One of Rob's comment was to make the indentation as 4 which I have done.
>>>
>>> I clearly do not see indentation of 4, but there is 8 instead.
>>
>> I changed the indentation at the wrong place.
>>
>>>
>>> Let's count:
>>> +    pruss2_eth: pruss2_eth {
>> ^ here, it was 8 in v1 so, I changed it to 4
>>
>>> +            compatible = "ti,am654-icssg-prueth";
>>>      12345678^
>>>
>>
>> Compatible is the child of pruss2_eth, so, It should have 4+4 = 8?
> 
> Yes. Indentation of four means first block is indented with 4 spaces.
> The next block 4+4. The next one 4+4+4.

Thanks for clearing my misunderstanding. I will fix all this in the next
version.

Thanks,
Puranjay

> 
> Best regards,
> Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-05-31 11:27     ` Puranjay Mohan
  2022-05-31 11:48       ` Krzysztof Kozlowski
@ 2022-06-05 15:11       ` Andrew Lunn
  1 sibling, 0 replies; 20+ messages in thread
From: Andrew Lunn @ 2022-06-05 15:11 UTC (permalink / raw)
  To: Puranjay Mohan
  Cc: nm, devicetree, grygorii.strashko, vigneshr, edumazet, netdev,
	linux-kernel, kishon, rogerq, afd, Krzysztof Kozlowski, robh+dt,
	krzysztof.kozlowski+dt, ssantosh, davem, linux-arm-kernel

> He said ethernet-port is preferred but all other drivers were using
> "port" so I though it is not compulsory. Will change it if it compulsory
> to use ethernet-port
 
It is a good idea to mention this in the change history. It is then
clear you have considered it, but decided against it.

      Andrew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
       [not found] ` <20220531095108.21757-3-p-mohan@ti.com>
                     ` (2 preceding siblings ...)
  2022-05-31 13:11   ` Randy Dunlap
@ 2022-06-05 15:37   ` Andrew Lunn
  2022-11-04 10:26     ` Md Danish Anwar
  2022-06-05 16:24   ` Christophe JAILLET
  4 siblings, 1 reply; 20+ messages in thread
From: Andrew Lunn @ 2022-06-05 15:37 UTC (permalink / raw)
  To: Puranjay Mohan
  Cc: nm, devicetree, grygorii.strashko, vigneshr, netdev,
	linux-kernel, kishon, rogerq, afd, edumazet, robh+dt,
	krzysztof.kozlowski+dt, ssantosh, davem, linux-arm-kernel

> +static inline u32 addr_to_da0(const u8 *addr)
> +{
> +	return (u32)(addr[0] | addr[1] << 8 |
> +		addr[2] << 16 | addr[3] << 24);
> +};
> +
> +static inline u32 addr_to_da1(const u8 *addr)
> +{
> +	return (u32)(addr[4] | addr[5] << 8);
> +};

No inline functions please.

> +
> +static void rx_class_ft1_set_start_len(struct regmap *miig_rt, int slice,
> +				       u16 start, u8 len)
> +{
> +	u32 offset, val;
> +
> +	offset = offs[slice].ft1_start_len;
> +	val = FT1_LEN(len) | FT1_START(start);
> +	regmap_write(miig_rt, offset, val);
> +}
> +
> +static void rx_class_ft1_set_da(struct regmap *miig_rt, int slice,
> +				int n, const u8 *addr)
> +{
> +	u32 offset;
> +
> +	offset = FT1_N_REG(slice, n, FT1_DA0);
> +	regmap_write(miig_rt, offset, addr_to_da0(addr));
> +	offset = FT1_N_REG(slice, n, FT1_DA1);
> +	regmap_write(miig_rt, offset, addr_to_da1(addr));
> +}
> +
> +static void rx_class_ft1_set_da_mask(struct regmap *miig_rt, int slice,
> +				     int n, const u8 *addr)
> +{
> +	u32 offset;
> +
> +	offset = FT1_N_REG(slice, n, FT1_DA0_MASK);
> +	regmap_write(miig_rt, offset, addr_to_da0(addr));
> +	offset = FT1_N_REG(slice, n, FT1_DA1_MASK);
> +	regmap_write(miig_rt, offset, addr_to_da1(addr));
> +}
> +
> +static void rx_class_ft1_cfg_set_type(struct regmap *miig_rt, int slice, int n,
> +				      enum ft1_cfg_type type)
> +{
> +	u32 offset;
> +
> +	offset = offs[slice].ft1_cfg;
> +	regmap_update_bits(miig_rt, offset, FT1_CFG_MASK(n),
> +			   type << FT1_CFG_SHIFT(n));
> +}
> +
> +static void rx_class_sel_set_type(struct regmap *miig_rt, int slice, int n,
> +				  enum rx_class_sel_type type)
> +{
> +	u32 offset;
> +
> +	offset = offs[slice].rx_class_cfg1;
> +	regmap_update_bits(miig_rt, offset, RX_CLASS_SEL_MASK(n),
> +			   type << RX_CLASS_SEL_SHIFT(n));
> +}
> +
> +static void rx_class_set_and(struct regmap *miig_rt, int slice, int n,
> +			     u32 data)
> +{
> +	u32 offset;
> +
> +	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_AND_EN);
> +	regmap_write(miig_rt, offset, data);
> +}
> +
> +static void rx_class_set_or(struct regmap *miig_rt, int slice, int n,
> +			    u32 data)
> +{
> +	u32 offset;
> +
> +	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN);
> +	regmap_write(miig_rt, offset, data);
> +}
> +
> +void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac)
> +{
> +	regmap_write(miig_rt, MAC_INTERFACE_0, addr_to_da0(mac));
> +	regmap_write(miig_rt, MAC_INTERFACE_1, addr_to_da1(mac));
> +}
> +
> +void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac)
> +{
> +	regmap_write(miig_rt, offs[slice].mac0, addr_to_da0(mac));
> +	regmap_write(miig_rt, offs[slice].mac1, addr_to_da1(mac));
> +}
> +
> +/* disable all RX traffic */
> +void icssg_class_disable(struct regmap *miig_rt, int slice)
> +{
> +	u32 data, offset;
> +	int n;
> +
> +	/* Enable RX_L2_G */
> +	regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_RX_L2_G_EN,
> +			   ICSSG_CFG_RX_L2_G_EN);
> +
> +	for (n = 0; n < ICSSG_NUM_CLASSIFIERS; n++) {
> +		/* AND_EN = 0 */
> +		rx_class_set_and(miig_rt, slice, n, 0);
> +		/* OR_EN = 0 */
> +		rx_class_set_or(miig_rt, slice, n, 0);
> +
> +		/* set CFG1 to OR */
> +		rx_class_sel_set_type(miig_rt, slice, n, RX_CLASS_SEL_TYPE_OR);
> +
> +		/* configure gate */
> +		offset = RX_CLASS_GATES_N_REG(slice, n);
> +		regmap_read(miig_rt, offset, &data);
> +		/* clear class_raw so we go through filters */
> +		data &= ~RX_CLASS_GATES_RAW_MASK;
> +		/* set allow and phase mask */
> +		data |= RX_CLASS_GATES_ALLOW_MASK | RX_CLASS_GATES_PHASE_MASK;
> +		regmap_write(miig_rt, offset, data);
> +	}
> +
> +	/* FT1 Disabled */
> +	for (n = 0; n < ICSSG_NUM_FT1_SLOTS; n++) {
> +		u8 addr[] = { 0, 0, 0, 0, 0, 0, };
> +
> +		rx_class_ft1_cfg_set_type(miig_rt, slice, n,
> +					  FT1_CFG_TYPE_DISABLED);
> +		rx_class_ft1_set_da(miig_rt, slice, n, addr);
> +		rx_class_ft1_set_da_mask(miig_rt, slice, n, addr);
> +	}
> +
> +	/* clear CFG2 */
> +	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
> +}
> +
> +void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti)
> +{
> +	int classifiers_in_use = 1;
> +	u32 data;
> +	int n;
> +
> +	/* defaults */
> +	icssg_class_disable(miig_rt, slice);
> +
> +	/* Setup Classifier */
> +	for (n = 0; n < classifiers_in_use; n++) {
> +		/* match on Broadcast or MAC_PRU address */
> +		data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P;
> +
> +		/* multicast? */
> +		if (allmulti)
> +			data |= RX_CLASS_FT_MC;
> +
> +		rx_class_set_or(miig_rt, slice, n, data);
> +
> +		/* set CFG1 for OR_OR_AND for classifier */
> +		rx_class_sel_set_type(miig_rt, slice, n,
> +				      RX_CLASS_SEL_TYPE_OR_OR_AND);
> +	}
> +
> +	/* clear CFG2 */
> +	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
> +}
> +
> +/* required for SAV check */
> +void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr)
> +{
> +	u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, };
> +
> +	rx_class_ft1_set_start_len(miig_rt, slice, 0, 6);
> +	rx_class_ft1_set_da(miig_rt, slice, 0, mac_addr);
> +	rx_class_ft1_set_da_mask(miig_rt, slice, 0, mask_addr);
> +	rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ);
> +}
> diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c
> new file mode 100644
> index 000000000000..a88ea4933802
> --- /dev/null
> +++ b/drivers/net/ethernet/ti/icssg_config.c
> @@ -0,0 +1,440 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* ICSSG Ethernet driver
> + *
> + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com
> + */
> +
> +#include <linux/iopoll.h>
> +#include <linux/regmap.h>
> +#include <uapi/linux/if_ether.h>
> +#include "icssg_config.h"
> +#include "icssg_prueth.h"
> +#include "icssg_switch_map.h"
> +#include "icssg_mii_rt.h"
> +
> +/* TX IPG Values to be set for 100M link speed. These values are
> + * in ocp_clk cycles. So need change if ocp_clk is changed for a specific
> + * h/w design.
> + */
> +
> +/* IPG is in core_clk cycles */
> +#define MII_RT_TX_IPG_100M	0x17
> +#define MII_RT_TX_IPG_1G	0xb
> +
> +#define	ICSSG_QUEUES_MAX		64
> +#define	ICSSG_QUEUE_OFFSET		0xd00
> +#define	ICSSG_QUEUE_PEEK_OFFSET		0xe00
> +#define	ICSSG_QUEUE_CNT_OFFSET		0xe40
> +#define	ICSSG_QUEUE_RESET_OFFSET	0xf40
> +
> +#define	ICSSG_NUM_TX_QUEUES	8
> +
> +#define	RECYCLE_Q_SLICE0	16
> +#define	RECYCLE_Q_SLICE1	17
> +
> +#define	ICSSG_NUM_OTHER_QUEUES	5	/* port, host and special queues */
> +
> +#define	PORT_HI_Q_SLICE0	32
> +#define	PORT_LO_Q_SLICE0	33
> +#define	HOST_HI_Q_SLICE0	34
> +#define	HOST_LO_Q_SLICE0	35
> +#define	HOST_SPL_Q_SLICE0	40	/* Special Queue */
> +
> +#define	PORT_HI_Q_SLICE1	36
> +#define	PORT_LO_Q_SLICE1	37
> +#define	HOST_HI_Q_SLICE1	38
> +#define	HOST_LO_Q_SLICE1	39
> +#define	HOST_SPL_Q_SLICE1	41	/* Special Queue */
> +
> +#define MII_RXCFG_DEFAULT	(PRUSS_MII_RT_RXCFG_RX_ENABLE | \
> +				 PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS | \
> +				 PRUSS_MII_RT_RXCFG_RX_L2_EN | \
> +				 PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS)
> +
> +#define MII_TXCFG_DEFAULT	(PRUSS_MII_RT_TXCFG_TX_ENABLE | \
> +				 PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE | \
> +				 PRUSS_MII_RT_TXCFG_TX_32_MODE_EN | \
> +				 PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN)
> +
> +#define ICSSG_CFG_DEFAULT	(ICSSG_CFG_TX_L1_EN | \
> +				 ICSSG_CFG_TX_L2_EN | ICSSG_CFG_RX_L2_G_EN | \
> +				 ICSSG_CFG_TX_PRU_EN | \
> +				 ICSSG_CFG_SGMII_MODE)
> +
> +#define FDB_GEN_CFG1		0x60
> +#define SMEM_VLAN_OFFSET	8
> +#define SMEM_VLAN_OFFSET_MASK	GENMASK(25, 8)
> +
> +#define FDB_GEN_CFG2		0x64
> +#define FDB_VLAN_EN		BIT(6)
> +#define FDB_HOST_EN		BIT(2)
> +#define FDB_PRU1_EN		BIT(1)
> +#define FDB_PRU0_EN		BIT(0)
> +#define FDB_EN_ALL		(FDB_PRU0_EN | FDB_PRU1_EN | \
> +				 FDB_HOST_EN | FDB_VLAN_EN)
> +
> +struct map {
> +	int queue;
> +	u32 pd_addr_start;
> +	u32 flags;
> +	bool special;
> +};
> +
> +struct map hwq_map[2][ICSSG_NUM_OTHER_QUEUES] = {
> +	{
> +		{ PORT_HI_Q_SLICE0, PORT_DESC0_HI, 0x200000, 0 },
> +		{ PORT_LO_Q_SLICE0, PORT_DESC0_LO, 0, 0 },
> +		{ HOST_HI_Q_SLICE0, HOST_DESC0_HI, 0x200000, 0 },
> +		{ HOST_LO_Q_SLICE0, HOST_DESC0_LO, 0, 0 },
> +		{ HOST_SPL_Q_SLICE0, HOST_SPPD0, 0x400000, 1 },
> +	},
> +	{
> +		{ PORT_HI_Q_SLICE1, PORT_DESC1_HI, 0xa00000, 0 },
> +		{ PORT_LO_Q_SLICE1, PORT_DESC1_LO, 0x800000, 0 },
> +		{ HOST_HI_Q_SLICE1, HOST_DESC1_HI, 0xa00000, 0 },
> +		{ HOST_LO_Q_SLICE1, HOST_DESC1_LO, 0x800000, 0 },
> +		{ HOST_SPL_Q_SLICE1, HOST_SPPD1, 0xc00000, 1 },
> +	},
> +};
> +
> +static void icssg_config_mii_init(struct prueth_emac *emac)
> +{
> +	struct prueth *prueth = emac->prueth;
> +	struct regmap *mii_rt = prueth->mii_rt;
> +	int slice = prueth_emac_slice(emac);
> +	u32 rxcfg_reg, txcfg_reg, pcnt_reg;
> +	u32 rxcfg, txcfg;
> +
> +	rxcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 :
> +				       PRUSS_MII_RT_RXCFG1;
> +	txcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 :
> +				       PRUSS_MII_RT_TXCFG1;
> +	pcnt_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 :
> +				       PRUSS_MII_RT_RX_PCNT1;
> +
> +	rxcfg = MII_RXCFG_DEFAULT;
> +	txcfg = MII_TXCFG_DEFAULT;
> +
> +	if (slice == ICSS_MII1)
> +		rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL;
> +
> +	/* In MII mode TX lines swapped inside ICSSG, so TX_MUX_SEL cfg need
> +	 * to be swapped also comparing to RGMII mode.
> +	 */
> +	if (emac->phy_if == PHY_INTERFACE_MODE_MII && slice == ICSS_MII0)
> +		txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
> +	else if (emac->phy_if != PHY_INTERFACE_MODE_MII && slice == ICSS_MII1)
> +		txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
> +
> +	regmap_write(mii_rt, rxcfg_reg, rxcfg);
> +	regmap_write(mii_rt, txcfg_reg, txcfg);
> +	regmap_write(mii_rt, pcnt_reg, 0x1);
> +}
> +
> +static void icssg_miig_queues_init(struct prueth *prueth, int slice)
> +{
> +	struct regmap *miig_rt = prueth->miig_rt;
> +	void __iomem *smem = prueth->shram.va;
> +	u8 pd[ICSSG_SPECIAL_PD_SIZE];
> +	int queue = 0, i, j;
> +	u32 *pdword;
> +
> +	/* reset hwqueues */
> +	if (slice)
> +		queue = ICSSG_NUM_TX_QUEUES;
> +
> +	for (i = 0; i < ICSSG_NUM_TX_QUEUES; i++) {
> +		regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
> +		queue++;
> +	}
> +
> +	queue = slice ? RECYCLE_Q_SLICE1 : RECYCLE_Q_SLICE0;
> +	regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
> +
> +	for (i = 0; i < ICSSG_NUM_OTHER_QUEUES; i++) {
> +		regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET,
> +			     hwq_map[slice][i].queue);
> +	}
> +
> +	/* initialize packet descriptors in SMEM */
> +	/* push pakcet descriptors to hwqueues */
> +
> +	pdword = (u32 *)pd;
> +	for (j = 0; j < ICSSG_NUM_OTHER_QUEUES; j++) {
> +		struct map *mp;
> +		int pd_size, num_pds;
> +		u32 pdaddr;
> +
> +		mp = &hwq_map[slice][j];
> +		if (mp->special) {
> +			pd_size = ICSSG_SPECIAL_PD_SIZE;
> +			num_pds = ICSSG_NUM_SPECIAL_PDS;
> +		} else	{
> +			pd_size = ICSSG_NORMAL_PD_SIZE;
> +			num_pds = ICSSG_NUM_NORMAL_PDS;
> +		}
> +
> +		for (i = 0; i < num_pds; i++) {
> +			memset(pd, 0, pd_size);
> +
> +			pdword[0] &= cpu_to_le32(ICSSG_FLAG_MASK);
> +			pdword[0] |= cpu_to_le32(mp->flags);
> +			pdaddr = mp->pd_addr_start + i * pd_size;
> +
> +			memcpy_toio(smem + pdaddr, pd, pd_size);
> +			queue = mp->queue;
> +			regmap_write(miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue,
> +				     pdaddr);
> +		}
> +	}
> +}
> +
> +void icssg_config_ipg(struct prueth_emac *emac)
> +{
> +	struct prueth *prueth = emac->prueth;
> +	int slice = prueth_emac_slice(emac);
> +
> +	switch (emac->speed) {
> +	case SPEED_1000:
> +		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_1G);
> +		break;
> +	case SPEED_100:
> +		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M);
> +		break;
> +	default:
> +		/* Other links speeds not supported */
> +		netdev_err(emac->ndev, "Unsupported link speed\n");
> +		return;
> +	}
> +}
> +
> +static void emac_r30_cmd_init(struct prueth_emac *emac)
> +{
> +	int i;
> +	struct icssg_r30_cmd *p;
> +
> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
> +
> +	for (i = 0; i < 4; i++)
> +		writel(EMAC_NONE, &p->cmd[i]);
> +}
> +
> +static int emac_r30_is_done(struct prueth_emac *emac)
> +{
> +	const struct icssg_r30_cmd *p;
> +	int i;
> +	u32 cmd;
> +
> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
> +
> +	for (i = 0; i < 4; i++) {
> +		cmd = readl(&p->cmd[i]);
> +		if (cmd != EMAC_NONE)
> +			return 0;
> +	}
> +
> +	return 1;
> +}
> +
> +static int prueth_emac_buffer_setup(struct prueth_emac *emac)
> +{
> +	struct icssg_buffer_pool_cfg *bpool_cfg;
> +	struct prueth *prueth = emac->prueth;
> +	int slice = prueth_emac_slice(emac);
> +	struct icssg_rxq_ctx *rxq_ctx;
> +	u32 addr;
> +	int i;
> +
> +	/* Layout to have 64KB aligned buffer pool
> +	 * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1|
> +	 */
> +
> +	addr = lower_32_bits(prueth->msmcram.pa);
> +	if (slice)
> +		addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
> +
> +	if (addr % SZ_64K) {
> +		dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n");
> +		return -EINVAL;
> +	}
> +
> +	bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET;
> +	/* workaround for f/w bug. bpool 0 needs to be initilalized */
> +	bpool_cfg[0].addr = cpu_to_le32(addr);
> +	bpool_cfg[0].len = 0;
> +
> +	for (i = PRUETH_EMAC_BUF_POOL_START;
> +	     i < (PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS);
> +	     i++) {
> +		bpool_cfg[i].addr = cpu_to_le32(addr);
> +		bpool_cfg[i].len = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE);
> +		addr += PRUETH_EMAC_BUF_POOL_SIZE;
> +	}
> +
> +	if (!slice)
> +		addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
> +	else
> +		addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2;
> +
> +	/* Pre-emptible RX buffer queue */
> +	rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET;
> +	for (i = 0; i < 3; i++)
> +		rxq_ctx->start[i] = cpu_to_le32(addr);
> +
> +	addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
> +	rxq_ctx->end = cpu_to_le32(addr);
> +
> +	/* Express RX buffer queue */
> +	rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET;
> +	for (i = 0; i < 3; i++)
> +		rxq_ctx->start[i] = cpu_to_le32(addr);
> +
> +	addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
> +	rxq_ctx->end = cpu_to_le32(addr);
> +
> +	return 0;
> +}
> +
> +static void icssg_init_emac_mode(struct prueth *prueth)
> +{
> +	/* When the device is configured as a bridge and it is being brought back
> +	 * to the emac mode, the host mac address has to be set as 0.
> +	 */
> +	u8 mac[ETH_ALEN] = { 0 };
> +
> +	if (prueth->emacs_initialized)
> +		return;
> +
> +	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, 0);
> +	regmap_write(prueth->miig_rt, FDB_GEN_CFG2, 0);
> +	/* Clear host MAC address */
> +	icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
> +}
> +
> +int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
> +{
> +	void *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
> +	u8 *cfg_byte_ptr = config;
> +	struct icssg_flow_cfg *flow_cfg;
> +	u32 mask;
> +	int ret;
> +
> +	icssg_init_emac_mode(prueth);
> +
> +	memset_io(config, 0, TAS_GATE_MASK_LIST0);
> +	icssg_miig_queues_init(prueth, slice);
> +
> +	emac->speed = SPEED_1000;
> +	emac->duplex = DUPLEX_FULL;
> +	if (!phy_interface_mode_is_rgmii(emac->phy_if)) {
> +		emac->speed = SPEED_100;
> +		emac->duplex = DUPLEX_FULL;
> +	}
> +	regmap_update_bits(prueth->miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_DEFAULT, ICSSG_CFG_DEFAULT);
> +	icssg_miig_set_interface_mode(prueth->miig_rt, slice, emac->phy_if);
> +	icssg_config_mii_init(emac);
> +	icssg_config_ipg(emac);
> +	icssg_update_rgmii_cfg(prueth->miig_rt, emac);
> +
> +	/* set GPI mode */
> +	pruss_cfg_gpimode(prueth->pruss, prueth->pru_id[slice],
> +			  PRUSS_GPI_MODE_MII);
> +
> +	/* enable XFR shift for PRU and RTU */
> +	mask = PRUSS_SPP_XFER_SHIFT_EN | PRUSS_SPP_RTU_XFR_SHIFT_EN;
> +	pruss_cfg_update(prueth->pruss, PRUSS_CFG_SPP, mask, mask);
> +
> +	/* set C28 to 0x100 */
> +	pru_rproc_set_ctable(prueth->pru[slice], PRU_C28, 0x100 << 8);
> +	pru_rproc_set_ctable(prueth->rtu[slice], PRU_C28, 0x100 << 8);
> +	pru_rproc_set_ctable(prueth->txpru[slice], PRU_C28, 0x100 << 8);
> +
> +	flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
> +	flow_cfg->rx_base_flow = cpu_to_le32(emac->rx_flow_id_base);
> +	flow_cfg->mgm_base_flow = 0;
> +	*(cfg_byte_ptr + SPL_PKT_DEFAULT_PRIORITY) = 0;
> +	*(cfg_byte_ptr + QUEUE_NUM_UNTAGGED) = 0x0;
> +
> +	ret = prueth_emac_buffer_setup(emac);
> +	if (ret)
> +		return ret;
> +
> +	emac_r30_cmd_init(emac);
> +
> +	return 0;
> +}
> +
> +static struct icssg_r30_cmd emac_r32_bitmask[] = {
> +	{{0xffff0004, 0xffff0100, 0xffff0100, EMAC_NONE}},	/* EMAC_PORT_DISABLE */
> +	{{0xfffb0040, 0xfeff0200, 0xfeff0200, EMAC_NONE}},	/* EMAC_PORT_BLOCK */
> +	{{0xffbb0000, 0xfcff0000, 0xdcff0000, EMAC_NONE}},	/* EMAC_PORT_FORWARD */
> +	{{0xffbb0000, 0xfcff0000, 0xfcff2000, EMAC_NONE}},	/* EMAC_PORT_FORWARD_WO_LEARNING */
> +	{{0xffff0001, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT ALL */
> +	{{0xfffe0002, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT TAGGED */
> +	{{0xfffc0000, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT UNTAGGED and PRIO */
> +	{{EMAC_NONE,  0xffff0020, EMAC_NONE, EMAC_NONE}},	/* TAS Trigger List change */
> +	{{EMAC_NONE,  0xdfff1000, EMAC_NONE, EMAC_NONE}},	/* TAS set state ENABLE*/
> +	{{EMAC_NONE,  0xefff2000, EMAC_NONE, EMAC_NONE}},	/* TAS set state RESET*/
> +	{{EMAC_NONE,  0xcfff0000, EMAC_NONE, EMAC_NONE}},	/* TAS set state DISABLE*/
> +	{{EMAC_NONE,  EMAC_NONE,  0xffff0400, EMAC_NONE}},	/* UC flooding ENABLE*/
> +	{{EMAC_NONE,  EMAC_NONE,  0xfbff0000, EMAC_NONE}},	/* UC flooding DISABLE*/
> +	{{EMAC_NONE,  EMAC_NONE,  0xffff0800, EMAC_NONE}},	/* MC flooding ENABLE*/
> +	{{EMAC_NONE,  EMAC_NONE,  0xf7ff0000, EMAC_NONE}},	/* MC flooding DISABLE*/
> +	{{EMAC_NONE,  0xffff4000, EMAC_NONE, EMAC_NONE}},	/* Preemption on Tx ENABLE*/
> +	{{EMAC_NONE,  0xbfff0000, EMAC_NONE, EMAC_NONE}},	/* Preemption on Tx DISABLE*/
> +	{{0xffff0010,  EMAC_NONE, 0xffff0010, EMAC_NONE}},	/* VLAN AWARE*/
> +	{{0xffef0000,  EMAC_NONE, 0xffef0000, EMAC_NONE}}	/* VLAN UNWARE*/
> +};
> +
> +int emac_set_port_state(struct prueth_emac *emac,
> +			enum icssg_port_state_cmd cmd)
> +{
> +	struct icssg_r30_cmd *p;
> +	int ret = -ETIMEDOUT;
> +	int done = 0;
> +	int i;
> +
> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
> +
> +	if (cmd >= ICSSG_EMAC_PORT_MAX_COMMANDS) {
> +		netdev_err(emac->ndev, "invalid port command\n");
> +		return -EINVAL;
> +	}
> +
> +	/* only one command at a time allowed to firmware */
> +	mutex_lock(&emac->cmd_lock);
> +
> +	for (i = 0; i < 4; i++)
> +		writel(emac_r32_bitmask[cmd].cmd[i], &p->cmd[i]);
> +
> +	/* wait for done */
> +	ret = read_poll_timeout(emac_r30_is_done, done, done == 1,
> +				1000, 10000, false, emac);
> +
> +	if (ret == -ETIMEDOUT)
> +		netdev_err(emac->ndev, "timeout waiting for command done\n");
> +
> +	mutex_unlock(&emac->cmd_lock);
> +
> +	return ret;
> +}
> +
> +void icssg_config_set_speed(struct prueth_emac *emac)
> +{
> +	u8 fw_speed;
> +
> +	switch (emac->speed) {
> +	case SPEED_1000:
> +		fw_speed = FW_LINK_SPEED_1G;
> +		break;
> +	case SPEED_100:
> +		fw_speed = FW_LINK_SPEED_100M;
> +		break;
> +	default:
> +		/* Other links speeds not supported */
> +		netdev_err(emac->ndev, "Unsupported link speed\n");
> +		return;
> +	}
> +
> +	writeb(fw_speed, emac->dram.va + PORT_LINK_SPEED_OFFSET);
> +}
> diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h
> new file mode 100644
> index 000000000000..43eb0922172a
> --- /dev/null
> +++ b/drivers/net/ethernet/ti/icssg_config.h
> @@ -0,0 +1,200 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Texas Instruments ICSSG Ethernet driver
> + *
> + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
> + *
> + */
> +
> +#ifndef __NET_TI_ICSSG_CONFIG_H
> +#define __NET_TI_ICSSG_CONFIG_H
> +
> +struct icssg_buffer_pool_cfg {
> +	__le32	addr;
> +	__le32	len;
> +} __packed;
> +
> +struct icssg_flow_cfg {
> +	__le16 rx_base_flow;
> +	__le16 mgm_base_flow;
> +} __packed;
> +
> +#define PRUETH_PKT_TYPE_CMD	0x10
> +#define PRUETH_NAV_PS_DATA_SIZE	16	/* Protocol specific data size */
> +#define PRUETH_NAV_SW_DATA_SIZE	16	/* SW related data size */
> +#define PRUETH_MAX_TX_DESC	512
> +#define PRUETH_MAX_RX_DESC	512
> +#define PRUETH_MAX_RX_FLOWS	1	/* excluding default flow */
> +#define PRUETH_RX_FLOW_DATA	0
> +
> +#define PRUETH_EMAC_BUF_POOL_SIZE	SZ_8K
> +#define PRUETH_EMAC_POOLS_PER_SLICE	24
> +#define PRUETH_EMAC_BUF_POOL_START	8
> +#define PRUETH_NUM_BUF_POOLS	8
> +#define PRUETH_EMAC_RX_CTX_BUF_SIZE	SZ_16K	/* per slice */
> +#define MSMC_RAM_SIZE	\
> +	(2 * (PRUETH_EMAC_BUF_POOL_SIZE * PRUETH_NUM_BUF_POOLS + \
> +	 PRUETH_EMAC_RX_CTX_BUF_SIZE * 2))
> +
> +struct icssg_rxq_ctx {
> +	__le32 start[3];
> +	__le32 end;
> +} __packed;
> +
> +/* Load time Fiwmware Configuration */
> +
> +#define ICSSG_FW_MGMT_CMD_HEADER	0x81
> +#define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
> +#define ICSSG_FW_MGMT_CMD_TYPE		0x04
> +#define ICSSG_FW_MGMT_PKT		0x80000000
> +
> +struct icssg_r30_cmd {
> +	u32 cmd[4];
> +} __packed;
> +
> +enum icssg_port_state_cmd {
> +	ICSSG_EMAC_PORT_DISABLE = 0,
> +	ICSSG_EMAC_PORT_BLOCK,
> +	ICSSG_EMAC_PORT_FORWARD,
> +	ICSSG_EMAC_PORT_FORWARD_WO_LEARNING,
> +	ICSSG_EMAC_PORT_ACCEPT_ALL,
> +	ICSSG_EMAC_PORT_ACCEPT_TAGGED,
> +	ICSSG_EMAC_PORT_ACCEPT_UNTAGGED_N_PRIO,
> +	ICSSG_EMAC_PORT_TAS_TRIGGER,
> +	ICSSG_EMAC_PORT_TAS_ENABLE,
> +	ICSSG_EMAC_PORT_TAS_RESET,
> +	ICSSG_EMAC_PORT_TAS_DISABLE,
> +	ICSSG_EMAC_PORT_UC_FLOODING_ENABLE,
> +	ICSSG_EMAC_PORT_UC_FLOODING_DISABLE,
> +	ICSSG_EMAC_PORT_MC_FLOODING_ENABLE,
> +	ICSSG_EMAC_PORT_MC_FLOODING_DISABLE,
> +	ICSSG_EMAC_PORT_PREMPT_TX_ENABLE,
> +	ICSSG_EMAC_PORT_PREMPT_TX_DISABLE,
> +	ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE,
> +	ICSSG_EMAC_PORT_VLAN_AWARE_DISABLE,
> +	ICSSG_EMAC_PORT_MAX_COMMANDS
> +};
> +
> +#define EMAC_NONE           0xffff0000
> +#define EMAC_PRU0_P_DI      0xffff0004
> +#define EMAC_PRU1_P_DI      0xffff0040
> +#define EMAC_TX_P_DI        0xffff0100
> +
> +#define EMAC_PRU0_P_EN      0xfffb0000
> +#define EMAC_PRU1_P_EN      0xffbf0000
> +#define EMAC_TX_P_EN        0xfeff0000
> +
> +#define EMAC_P_BLOCK        0xffff0040
> +#define EMAC_TX_P_BLOCK     0xffff0200
> +#define EMAC_P_UNBLOCK      0xffbf0000
> +#define EMAC_TX_P_UNBLOCK   0xfdff0000
> +#define EMAC_LEAN_EN        0xfff70000
> +#define EMAC_LEAN_DI        0xffff0008
> +
> +#define EMAC_ACCEPT_ALL     0xffff0001
> +#define EMAC_ACCEPT_TAG     0xfffe0002
> +#define EMAC_ACCEPT_PRIOR   0xfffc0000
> +
> +/* Config area lies in DRAM */
> +#define ICSSG_CONFIG_OFFSET	0x0
> +
> +/* Config area lies in shared RAM */
> +#define ICSSG_CONFIG_OFFSET_SLICE0   0
> +#define ICSSG_CONFIG_OFFSET_SLICE1   0x8000
> +
> +#define ICSSG_NUM_NORMAL_PDS	64
> +#define ICSSG_NUM_SPECIAL_PDS	16
> +
> +#define ICSSG_NORMAL_PD_SIZE	8
> +#define ICSSG_SPECIAL_PD_SIZE	20
> +
> +#define ICSSG_FLAG_MASK		0xff00ffff
> +
> +struct icssg_setclock_desc {
> +	u8 request;
> +	u8 restore;
> +	u8 acknowledgment;
> +	u8 cmp_status;
> +	u32 margin;
> +	u32 cyclecounter0_set;
> +	u32 cyclecounter1_set;
> +	u32 iepcount_set;
> +	u32 rsvd1;
> +	u32 rsvd2;
> +	u32 CMP0_current;
> +	u32 iepcount_current;
> +	u32 difference;
> +	u32 cyclecounter0_new;
> +	u32 cyclecounter1_new;
> +	u32 CMP0_new;
> +} __packed;
> +
> +#define ICSSG_CMD_POP_SLICE0	56
> +#define ICSSG_CMD_POP_SLICE1	60
> +
> +#define ICSSG_CMD_PUSH_SLICE0	57
> +#define ICSSG_CMD_PUSH_SLICE1	61
> +
> +#define ICSSG_RSP_POP_SLICE0	58
> +#define ICSSG_RSP_POP_SLICE1	62
> +
> +#define ICSSG_RSP_PUSH_SLICE0	56
> +#define ICSSG_RSP_PUSH_SLICE1	60
> +
> +#define ICSSG_TS_POP_SLICE0	59
> +#define ICSSG_TS_POP_SLICE1	63
> +
> +#define ICSSG_TS_PUSH_SLICE0	40
> +#define ICSSG_TS_PUSH_SLICE1	41
> +
> +/* FDB FID_C2 flag definitions */
> +/* Indicates host port membership.*/
> +#define ICSSG_FDB_ENTRY_P0_MEMBERSHIP         BIT(0)
> +/* Indicates that MAC ID is connected to physical port 1 */
> +#define ICSSG_FDB_ENTRY_P1_MEMBERSHIP         BIT(1)
> +/* Indicates that MAC ID is connected to physical port 2 */
> +#define ICSSG_FDB_ENTRY_P2_MEMBERSHIP         BIT(2)
> +/* Ageable bit is set for learned entries and cleared for static entries */
> +#define ICSSG_FDB_ENTRY_AGEABLE               BIT(3)
> +/* If set for DA then packet is determined to be a special packet */
> +#define ICSSG_FDB_ENTRY_BLOCK                 BIT(4)
> +/* If set for DA then the SA from the packet is not learned */
> +#define ICSSG_FDB_ENTRY_SECURE                BIT(5)
> +/* If set, it means packet has been seen recently with source address + FID
> + * matching MAC address/FID of entry
> + */
> +#define ICSSG_FDB_ENTRY_TOUCHED               BIT(6)
> +/* Set if entry is valid */
> +#define ICSSG_FDB_ENTRY_VALID                 BIT(7)
> +
> +/**
> + * struct prueth_vlan_tbl - VLAN table entries struct in ICSSG SMEM
> + * @fid_c1: membership and forwarding rules flag to this table. See
> + *          above to defines for bit definitions
> + * @fid: FDB index for this VID (there is 1-1 mapping b/w VID and FID)
> + */
> +struct prueth_vlan_tbl {
> +	u8 fid_c1;
> +	u8 fid;
> +} __packed;
> +
> +/**
> + * struct prueth_fdb_slot - Result of FDB slot lookup
> + * @mac: MAC address
> + * @fid: fid to be associated with MAC
> + * @fid_c2: FID_C2 entry for this MAC
> + */
> +struct prueth_fdb_slot {
> +	u8 mac[ETH_ALEN];
> +	u8 fid;
> +	u8 fid_c2;
> +} __packed;
> +
> +enum icssg_ietfpe_verify_states {
> +	ICSSG_IETFPE_STATE_UNKNOWN = 0,
> +	ICSSG_IETFPE_STATE_INITIAL,
> +	ICSSG_IETFPE_STATE_VERIFYING,
> +	ICSSG_IETFPE_STATE_SUCCEEDED,
> +	ICSSG_IETFPE_STATE_FAILED,
> +	ICSSG_IETFPE_STATE_DISABLED
> +};
> +#endif /* __NET_TI_ICSSG_CONFIG_H */
> diff --git a/drivers/net/ethernet/ti/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg_ethtool.c
> new file mode 100644
> index 000000000000..fd09d223b0ae
> --- /dev/null
> +++ b/drivers/net/ethernet/ti/icssg_ethtool.c
> @@ -0,0 +1,319 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Texas Instruments ICSSG Ethernet driver
> + *
> + * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
> + *
> + */
> +
> +#include "icssg_prueth.h"
> +#include <linux/regmap.h>
> +
> +static u32 stats_base[] = {	0x54c,	/* Slice 0 stats start */
> +				0xb18,	/* Slice 1 stats start */
> +};
> +
> +struct miig_stats_regs {
> +	/* Rx */
> +	u32 rx_good_frames;
> +	u32 rx_broadcast_frames;
> +	u32 rx_multicast_frames;
> +	u32 rx_crc_error_frames;
> +	u32 rx_mii_error_frames;
> +	u32 rx_odd_nibble_frames;
> +	u32 rx_frame_max_size;
> +	u32 rx_max_size_error_frames;
> +	u32 rx_frame_min_size;
> +	u32 rx_min_size_error_frames;
> +	u32 rx_overrun_frames;
> +	u32 rx_class0_hits;
> +	u32 rx_class1_hits;
> +	u32 rx_class2_hits;
> +	u32 rx_class3_hits;
> +	u32 rx_class4_hits;
> +	u32 rx_class5_hits;
> +	u32 rx_class6_hits;
> +	u32 rx_class7_hits;
> +	u32 rx_class8_hits;
> +	u32 rx_class9_hits;
> +	u32 rx_class10_hits;
> +	u32 rx_class11_hits;
> +	u32 rx_class12_hits;
> +	u32 rx_class13_hits;
> +	u32 rx_class14_hits;
> +	u32 rx_class15_hits;
> +	u32 rx_smd_frags;
> +	u32 rx_bucket1_size;
> +	u32 rx_bucket2_size;
> +	u32 rx_bucket3_size;
> +	u32 rx_bucket4_size;
> +	u32 rx_64B_frames;
> +	u32 rx_bucket1_frames;
> +	u32 rx_bucket2_frames;
> +	u32 rx_bucket3_frames;
> +	u32 rx_bucket4_frames;
> +	u32 rx_bucket5_frames;
> +	u32 rx_total_bytes;
> +	u32 rx_tx_total_bytes;
> +	/* Tx */
> +	u32 tx_good_frames;
> +	u32 tx_broadcast_frames;
> +	u32 tx_multicast_frames;
> +	u32 tx_odd_nibble_frames;
> +	u32 tx_underflow_errors;
> +	u32 tx_frame_max_size;
> +	u32 tx_max_size_error_frames;
> +	u32 tx_frame_min_size;
> +	u32 tx_min_size_error_frames;
> +	u32 tx_bucket1_size;
> +	u32 tx_bucket2_size;
> +	u32 tx_bucket3_size;
> +	u32 tx_bucket4_size;
> +	u32 tx_64B_frames;
> +	u32 tx_bucket1_frames;
> +	u32 tx_bucket2_frames;
> +	u32 tx_bucket3_frames;
> +	u32 tx_bucket4_frames;
> +	u32 tx_bucket5_frames;
> +	u32 tx_total_bytes;
> +};
> +
> +#define ICSSG_STATS(field)				\
> +{							\
> +	#field,						\
> +	offsetof(struct miig_stats_regs, field),	\
> +}
> +
> +struct icssg_stats {
> +	char name[ETH_GSTRING_LEN];
> +	u32 offset;
> +};
> +
> +static const struct icssg_stats icssg_ethtool_stats[] = {
> +	/* Rx */
> +	ICSSG_STATS(rx_good_frames),
> +	ICSSG_STATS(rx_broadcast_frames),
> +	ICSSG_STATS(rx_multicast_frames),
> +	ICSSG_STATS(rx_crc_error_frames),
> +	ICSSG_STATS(rx_mii_error_frames),
> +	ICSSG_STATS(rx_odd_nibble_frames),
> +	ICSSG_STATS(rx_frame_max_size),
> +	ICSSG_STATS(rx_max_size_error_frames),
> +	ICSSG_STATS(rx_frame_min_size),
> +	ICSSG_STATS(rx_min_size_error_frames),
> +	ICSSG_STATS(rx_overrun_frames),
> +	ICSSG_STATS(rx_class0_hits),
> +	ICSSG_STATS(rx_class1_hits),
> +	ICSSG_STATS(rx_class2_hits),
> +	ICSSG_STATS(rx_class3_hits),
> +	ICSSG_STATS(rx_class4_hits),
> +	ICSSG_STATS(rx_class5_hits),
> +	ICSSG_STATS(rx_class6_hits),
> +	ICSSG_STATS(rx_class7_hits),
> +	ICSSG_STATS(rx_class8_hits),
> +	ICSSG_STATS(rx_class9_hits),
> +	ICSSG_STATS(rx_class10_hits),
> +	ICSSG_STATS(rx_class11_hits),
> +	ICSSG_STATS(rx_class12_hits),
> +	ICSSG_STATS(rx_class13_hits),
> +	ICSSG_STATS(rx_class14_hits),
> +	ICSSG_STATS(rx_class15_hits),
> +	ICSSG_STATS(rx_smd_frags),
> +	ICSSG_STATS(rx_bucket1_size),
> +	ICSSG_STATS(rx_bucket2_size),
> +	ICSSG_STATS(rx_bucket3_size),
> +	ICSSG_STATS(rx_bucket4_size),
> +	ICSSG_STATS(rx_64B_frames),
> +	ICSSG_STATS(rx_bucket1_frames),
> +	ICSSG_STATS(rx_bucket2_frames),
> +	ICSSG_STATS(rx_bucket3_frames),
> +	ICSSG_STATS(rx_bucket4_frames),
> +	ICSSG_STATS(rx_bucket5_frames),
> +	ICSSG_STATS(rx_total_bytes),
> +	ICSSG_STATS(rx_tx_total_bytes),
> +	/* Tx */
> +	ICSSG_STATS(tx_good_frames),
> +	ICSSG_STATS(tx_broadcast_frames),
> +	ICSSG_STATS(tx_multicast_frames),
> +	ICSSG_STATS(tx_odd_nibble_frames),
> +	ICSSG_STATS(tx_underflow_errors),
> +	ICSSG_STATS(tx_frame_max_size),
> +	ICSSG_STATS(tx_max_size_error_frames),
> +	ICSSG_STATS(tx_frame_min_size),
> +	ICSSG_STATS(tx_min_size_error_frames),
> +	ICSSG_STATS(tx_bucket1_size),
> +	ICSSG_STATS(tx_bucket2_size),
> +	ICSSG_STATS(tx_bucket3_size),
> +	ICSSG_STATS(tx_bucket4_size),
> +	ICSSG_STATS(tx_64B_frames),
> +	ICSSG_STATS(tx_bucket1_frames),
> +	ICSSG_STATS(tx_bucket2_frames),
> +	ICSSG_STATS(tx_bucket3_frames),
> +	ICSSG_STATS(tx_bucket4_frames),
> +	ICSSG_STATS(tx_bucket5_frames),
> +	ICSSG_STATS(tx_total_bytes),
> +};
> +
> +static void emac_get_drvinfo(struct net_device *ndev,
> +			     struct ethtool_drvinfo *info)
> +{
> +	struct prueth_emac *emac = netdev_priv(ndev);
> +	struct prueth *prueth = emac->prueth;
> +
> +	strscpy(info->driver, dev_driver_string(prueth->dev),
> +		sizeof(info->driver));
> +	strscpy(info->bus_info, dev_name(prueth->dev), sizeof(info->bus_info));
> +}
> +
> +static u32 emac_get_msglevel(struct net_device *ndev)
> +{
> +	struct prueth_emac *emac = netdev_priv(ndev);
> +
> +	return emac->msg_enable;
> +}
> +
> +static void emac_set_msglevel(struct net_device *ndev, u32 value)
> +{
> +	struct prueth_emac *emac = netdev_priv(ndev);
> +
> +	emac->msg_enable = value;
> +}
> +
> +static int emac_get_link_ksettings(struct net_device *ndev,
> +				   struct ethtool_link_ksettings *ecmd)
> +{
> +	return phy_ethtool_get_link_ksettings(ndev, ecmd);
> +}
> +
> +static int emac_set_link_ksettings(struct net_device *ndev,
> +				   const struct ethtool_link_ksettings *ecmd)
> +{
> +	return phy_ethtool_set_link_ksettings(ndev, ecmd);
> +}
> +
> +static int emac_get_eee(struct net_device *ndev, struct ethtool_eee *edata)
> +{
> +	if (!ndev->phydev)
> +		return -EOPNOTSUPP;
> +
> +	return phy_ethtool_get_eee(ndev->phydev, edata);
> +}
> +
> +static int emac_set_eee(struct net_device *ndev, struct ethtool_eee *edata)
> +{
> +	if (!ndev->phydev)
> +		return -EOPNOTSUPP;
> +
> +	return phy_ethtool_set_eee(ndev->phydev, edata);
> +}
> +
> +static int emac_nway_reset(struct net_device *ndev)
> +{
> +	return phy_ethtool_nway_reset(ndev);
> +}
> +
> +static const char emac_ethtool_priv_flags[][ETH_GSTRING_LEN] = {
> +#define EMAC_PRIV_IET_FRAME_PREEMPTION  BIT(0)
> +	"iet-frame-preemption",
> +#define EMAC_PRIV_IET_MAC_VERIFY                BIT(1)
> +	"iet-mac-verify",
> +};

Please move the #define outside of the array. They are not easy to
see.

	Andrew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
       [not found] ` <20220531095108.21757-3-p-mohan@ti.com>
                     ` (3 preceding siblings ...)
  2022-06-05 15:37   ` Andrew Lunn
@ 2022-06-05 16:24   ` Christophe JAILLET
  2022-11-04  9:50     ` Md Danish Anwar
  4 siblings, 1 reply; 20+ messages in thread
From: Christophe JAILLET @ 2022-06-05 16:24 UTC (permalink / raw)
  To: p-mohan
  Cc: nm, andrew, grygorii.strashko, vigneshr, devicetree, netdev,
	linux-kernel, afd, rogerq, edumazet, robh+dt,
	krzysztof.kozlowski+dt, ssantosh, kishon, davem,
	linux-arm-kernel

Hi,

Just a few comments below, for what they worth.

Le 31/05/2022 à 11:51, Puranjay Mohan a écrit :
> From: Roger Quadros <rogerq-l0cyMroinI0@public.gmane.org>
> 
> This is the Ethernet driver for TI AM654 Silicon rev. 2
> with the ICSSG PRU Sub-system running dual-EMAC firmware.
> 

[...]

> +static int prueth_netdev_init(struct prueth *prueth,
> +			      struct device_node *eth_node)
> +{
> +	int ret, num_tx_chn = PRUETH_MAX_TX_QUEUES;
> +	struct prueth_emac *emac;
> +	struct net_device *ndev;
> +	enum prueth_port port;
> +	enum prueth_mac mac;
> +
> +	port = prueth_node_port(eth_node);
> +	if (port < 0)
> +		return -EINVAL;
> +
> +	mac = prueth_node_mac(eth_node);
> +	if (mac < 0)
> +		return -EINVAL;
> +
> +	ndev = alloc_etherdev_mq(sizeof(*emac), num_tx_chn);
> +	if (!ndev)
> +		return -ENOMEM;
> +
> +	emac = netdev_priv(ndev);
> +	prueth->emac[mac] = emac;
> +	emac->prueth = prueth;
> +	emac->ndev = ndev;
> +	emac->port_id = port;
> +	emac->cmd_wq = create_singlethread_workqueue("icssg_cmd_wq");
> +	if (!emac->cmd_wq) {
> +		ret = -ENOMEM;
> +		goto free_ndev;
> +	}
> +	INIT_WORK(&emac->rx_mode_work, emac_ndo_set_rx_mode_work);
> +
> +	ret = pruss_request_mem_region(prueth->pruss,
> +				       port == PRUETH_PORT_MII0 ?
> +				       PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1,
> +				       &emac->dram);
> +	if (ret) {
> +		dev_err(prueth->dev, "unable to get DRAM: %d\n", ret);
> +		return -ENOMEM;

goto free_wq; ?

> +	}
> +
> +	emac->tx_ch_num = 1;
> +
> +	SET_NETDEV_DEV(ndev, prueth->dev);
> +	spin_lock_init(&emac->lock);
> +	mutex_init(&emac->cmd_lock);
> +
> +	emac->phy_node = of_parse_phandle(eth_node, "phy-handle", 0);
> +	if (!emac->phy_node && !of_phy_is_fixed_link(eth_node)) {
> +		dev_err(prueth->dev, "couldn't find phy-handle\n");
> +		ret = -ENODEV;
> +		goto free;
> +	} else if (of_phy_is_fixed_link(eth_node)) {
> +		ret = of_phy_register_fixed_link(eth_node);
> +		if (ret) {
> +			ret = dev_err_probe(prueth->dev, ret,
> +					    "failed to register fixed-link phy\n");
> +			goto free;
> +		}
> +
> +		emac->phy_node = eth_node;
> +	}
> +
> +	ret = of_get_phy_mode(eth_node, &emac->phy_if);
> +	if (ret) {
> +		dev_err(prueth->dev, "could not get phy-mode property\n");
> +		goto free;
> +	}
> +
> +	if (emac->phy_if != PHY_INTERFACE_MODE_MII &&
> +	    !phy_interface_mode_is_rgmii(emac->phy_if)) {
> +		dev_err(prueth->dev, "PHY mode unsupported %s\n", phy_modes(emac->phy_if));
> +		goto free;
> +	}
> +
> +	ret = prueth_config_rgmiidelay(prueth, eth_node, emac->phy_if);
> +	if (ret)
> +		goto free;
> +
> +	/* get mac address from DT and set private and netdev addr */
> +	ret = of_get_ethdev_address(eth_node, ndev);
> +	if (!is_valid_ether_addr(ndev->dev_addr)) {
> +		eth_hw_addr_random(ndev);
> +		dev_warn(prueth->dev, "port %d: using random MAC addr: %pM\n",
> +			 port, ndev->dev_addr);
> +	}
> +	ether_addr_copy(emac->mac_addr, ndev->dev_addr);
> +
> +	ndev->netdev_ops = &emac_netdev_ops;
> +	ndev->ethtool_ops = &icssg_ethtool_ops;
> +	ndev->hw_features = NETIF_F_SG;
> +	ndev->features = ndev->hw_features;
> +
> +	netif_napi_add(ndev, &emac->napi_rx,
> +		       emac_napi_rx_poll, NAPI_POLL_WEIGHT);
> +
> +	return 0;
> +
> +free:
> +	pruss_release_mem_region(prueth->pruss, &emac->dram);

free_wq:

> +	destroy_workqueue(emac->cmd_wq);
> +free_ndev:
> +	free_netdev(ndev);
> +	prueth->emac[mac] = NULL;
> +
> +	return ret;
> +}
> +
> +static void prueth_netdev_exit(struct prueth *prueth,
> +			       struct device_node *eth_node)
> +{
> +	struct prueth_emac *emac;
> +	enum prueth_mac mac;
> +
> +	mac = prueth_node_mac(eth_node);
> +	if (mac < 0)
> +		return;
> +
> +	emac = prueth->emac[mac];
> +	if (!emac)
> +		return;
> +
> +	if (of_phy_is_fixed_link(emac->phy_node))
> +		of_phy_deregister_fixed_link(emac->phy_node);
> +
> +	netif_napi_del(&emac->napi_rx);
> +
> +	pruss_release_mem_region(prueth->pruss, &emac->dram);
> +	destroy_workqueue(emac->cmd_wq);
> +	free_netdev(emac->ndev);
> +	prueth->emac[mac] = NULL;
> +}
> +
> +static int prueth_get_cores(struct prueth *prueth, int slice)
> +{
> +	enum pruss_pru_id pruss_id;
> +	struct device *dev = prueth->dev;
> +	struct device_node *np = dev->of_node;
> +	int idx = -1, ret;
> +
> +	switch (slice) {
> +	case ICSS_SLICE0:
> +		idx = 0;
> +		break;
> +	case ICSS_SLICE1:
> +		idx = 3;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	prueth->pru[slice] = pru_rproc_get(np, idx, &pruss_id);
> +	if (IS_ERR(prueth->pru[slice])) {
> +		ret = PTR_ERR(prueth->pru[slice]);
> +		prueth->pru[slice] = NULL;
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "unable to get PRU%d: %d\n", slice, ret);

return dev_err_probe()?

> +		return ret;
> +	}
> +	prueth->pru_id[slice] = pruss_id;
> +
> +	idx++;
> +	prueth->rtu[slice] = pru_rproc_get(np, idx, NULL);
> +	if (IS_ERR(prueth->rtu[slice])) {
> +		ret = PTR_ERR(prueth->rtu[slice]);
> +		prueth->rtu[slice] = NULL;
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "unable to get RTU%d: %d\n", slice, ret);

Same.

> +		return ret;
> +	}
> +
> +	idx++;
> +	prueth->txpru[slice] = pru_rproc_get(np, idx, NULL);
> +	if (IS_ERR(prueth->txpru[slice])) {
> +		ret = PTR_ERR(prueth->txpru[slice]);
> +		prueth->txpru[slice] = NULL;
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "unable to get TX_PRU%d: %d\n",
> +				slice, ret);

Same.

> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static void prueth_put_cores(struct prueth *prueth, int slice)
> +{
> +	if (prueth->txpru[slice])
> +		pru_rproc_put(prueth->txpru[slice]);
> +
> +	if (prueth->rtu[slice])
> +		pru_rproc_put(prueth->rtu[slice]);
> +
> +	if (prueth->pru[slice])
> +		pru_rproc_put(prueth->pru[slice]);
> +}
> +
> +static const struct of_device_id prueth_dt_match[];
> +
> +static int prueth_probe(struct platform_device *pdev)
> +{
> +	struct prueth *prueth;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct device_node *eth_ports_node;
> +	struct device_node *eth_node;
> +	struct device_node *eth0_node, *eth1_node;
> +	const struct of_device_id *match;
> +	struct pruss *pruss;
> +	int i, ret;
> +	u32 msmc_ram_size;
> +	struct genpool_data_align gp_data = {
> +		.align = SZ_64K,
> +	};
> +
> +	match = of_match_device(prueth_dt_match, dev);
> +	if (!match)
> +		return -ENODEV;
> +
> +	prueth = devm_kzalloc(dev, sizeof(*prueth), GFP_KERNEL);
> +	if (!prueth)
> +		return -ENOMEM;
> +
> +	dev_set_drvdata(dev, prueth);
> +	prueth->pdev = pdev;
> +	prueth->pdata = *(const struct prueth_pdata *)match->data;
> +
> +	prueth->dev = dev;
> +	eth_ports_node = of_get_child_by_name(np, "ethernet-ports");
> +	if (!eth_ports_node)
> +		return -ENOENT;
> +
> +	for_each_child_of_node(eth_ports_node, eth_node) {
> +		u32 reg;
> +
> +		if (strcmp(eth_node->name, "port"))
> +			continue;
> +		ret = of_property_read_u32(eth_node, "reg", &reg);
> +		if (ret < 0) {
> +			dev_err(dev, "%pOF error reading port_id %d\n",
> +				eth_node, ret);
> +		}
> +
> +		of_node_get(eth_node);
> +
> +		if (reg == 0)
> +			eth0_node = eth_node;
> +		else if (reg == 1)
> +			eth1_node = eth_node;
> +		else
> +			dev_err(dev, "port reg should be 0 or 1\n");
> +	}
> +
> +	of_node_put(eth_ports_node);
> +
> +	/* At least one node must be present and available else we fail */
> +	if (!eth0_node && !eth1_node) {
> +		dev_err(dev, "neither port0 nor port1 node available\n");
> +		return -ENODEV;
> +	}
> +
> +	if (eth0_node == eth1_node) {
> +		dev_err(dev, "port0 and port1 can't have same reg\n");
> +		of_node_put(eth0_node);
> +		return -ENODEV;
> +	}
> +
> +	prueth->eth_node[PRUETH_MAC0] = eth0_node;
> +	prueth->eth_node[PRUETH_MAC1] = eth1_node;
> +
> +	prueth->miig_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-g-rt");
> +	if (IS_ERR(prueth->miig_rt)) {
> +		dev_err(dev, "couldn't get ti,mii-g-rt syscon regmap\n");
> +		return -ENODEV;
> +	}
> +
> +	prueth->mii_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-rt");
> +	if (IS_ERR(prueth->mii_rt)) {
> +		dev_err(dev, "couldn't get ti,mii-rt syscon regmap\n");
> +		return -ENODEV;
> +	}
> +
> +	if (eth0_node) {
> +		ret = prueth_get_cores(prueth, ICSS_SLICE0);
> +		if (ret)
> +			goto put_cores;
> +	}
> +
> +	if (eth1_node) {
> +		ret = prueth_get_cores(prueth, ICSS_SLICE1);
> +		if (ret)
> +			goto put_cores;
> +	}
> +
> +	pruss = pruss_get(eth0_node ?
> +			  prueth->pru[ICSS_SLICE0] : prueth->pru[ICSS_SLICE1]);
> +	if (IS_ERR(pruss)) {
> +		ret = PTR_ERR(pruss);
> +		dev_err(dev, "unable to get pruss handle\n");
> +		goto put_cores;
> +	}
> +
> +	prueth->pruss = pruss;
> +
> +	ret = pruss_request_mem_region(pruss, PRUSS_MEM_SHRD_RAM2,
> +				       &prueth->shram);
> +	if (ret) {
> +		dev_err(dev, "unable to get PRUSS SHRD RAM2: %d\n", ret);
> +		goto put_mem;

Is it safe to call pruss_release_mem_region() if 
pruss_request_mem_region() has failed?

The other place where it is called it is not done the same way.

> +	}
> +
> +	prueth->sram_pool = of_gen_pool_get(np, "sram", 0);
> +	if (!prueth->sram_pool) {
> +		dev_err(dev, "unable to get SRAM pool\n");
> +		ret = -ENODEV;
> +
> +		goto put_mem;
> +	}
> +
> +	msmc_ram_size = MSMC_RAM_SIZE;
> +
> +	/* NOTE: FW bug needs buffer base to be 64KB aligned */
> +	prueth->msmcram.va =
> +		(void __iomem *)gen_pool_alloc_algo(prueth->sram_pool,
> +						    msmc_ram_size,
> +						    gen_pool_first_fit_align,
> +						    &gp_data);
> +
> +	if (!prueth->msmcram.va) {
> +		ret = -ENOMEM;
> +		dev_err(dev, "unable to allocate MSMC resource\n");
> +		goto put_mem;
> +	}
> +	prueth->msmcram.pa = gen_pool_virt_to_phys(prueth->sram_pool,
> +						   (unsigned long)prueth->msmcram.va);
> +	prueth->msmcram.size = msmc_ram_size;
> +	memset(prueth->msmcram.va, 0, msmc_ram_size);
> +	dev_dbg(dev, "sram: pa %llx va %p size %zx\n", prueth->msmcram.pa,
> +		prueth->msmcram.va, prueth->msmcram.size);
> +
> +	/* setup netdev interfaces */
> +	if (eth0_node) {
> +		ret = prueth_netdev_init(prueth, eth0_node);
> +		if (ret) {
> +			if (ret != -EPROBE_DEFER) {
> +				dev_err(dev, "netdev init %s failed: %d\n",
> +					eth0_node->name, ret);

dev_err_probe()?

> +			}
> +			goto netdev_exit;
> +		}
> +	}
> +
> +	if (eth1_node) {
> +		ret = prueth_netdev_init(prueth, eth1_node);
> +		if (ret) {
> +			if (ret != -EPROBE_DEFER) {
> +				dev_err(dev, "netdev init %s failed: %d\n",
> +					eth1_node->name, ret);

dev_err_probe()?

> +			}
> +			goto netdev_exit;
> +		}
> +	}
> +
> +	/* register the network devices */
> +	if (eth0_node) {
> +		ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev);
> +		if (ret) {
> +			dev_err(dev, "can't register netdev for port MII0");
> +			goto netdev_exit;
> +		}
> +
> +		prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev;
> +
> +		emac_phy_connect(prueth->emac[PRUETH_MAC0]);
> +		phy_attached_info(prueth->emac[PRUETH_MAC0]->ndev->phydev);
> +	}
> +
> +	if (eth1_node) {
> +		ret = register_netdev(prueth->emac[PRUETH_MAC1]->ndev);
> +		if (ret) {
> +			dev_err(dev, "can't register netdev for port MII1");
> +			goto netdev_unregister;
> +		}
> +
> +		prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev;
> +		emac_phy_connect(prueth->emac[PRUETH_MAC1]);
> +		phy_attached_info(prueth->emac[PRUETH_MAC1]->ndev->phydev);
> +	}
> +
> +	dev_info(dev, "TI PRU ethernet driver initialized: %s EMAC mode\n",
> +		 (!eth0_node || !eth1_node) ? "single" : "dual");
> +
> +	if (eth1_node)
> +		of_node_put(eth1_node);
> +	if (eth0_node)
> +		of_node_put(eth0_node);
> +	return 0;
> +
> +netdev_unregister:
> +	for (i = 0; i < PRUETH_NUM_MACS; i++) {
> +		if (!prueth->registered_netdevs[i])
> +			continue;
> +		if (prueth->emac[i]->ndev->phydev) {
> +			phy_disconnect(prueth->emac[i]->ndev->phydev);
> +			prueth->emac[i]->ndev->phydev = NULL;
> +		}
> +		unregister_netdev(prueth->registered_netdevs[i]);
> +	}
> +
> +netdev_exit:
> +	for (i = 0; i < PRUETH_NUM_MACS; i++) {
> +		struct device_node *eth_node;
> +
> +		eth_node = prueth->eth_node[i];
> +		if (!eth_node)
> +			continue;
> +
> +		prueth_netdev_exit(prueth, eth_node);
> +	}
> +
> +gen_pool_free(prueth->sram_pool,

1 tab missing.

> +	      (unsigned long)prueth->msmcram.va, msmc_ram_size);
> +
> +put_mem:
> +	pruss_release_mem_region(prueth->pruss, &prueth->shram);
> +	pruss_put(prueth->pruss);
> +
> +put_cores:
> +	if (eth1_node) {
> +		prueth_put_cores(prueth, ICSS_SLICE1);
> +		of_node_put(eth1_node);
> +	}
> +
> +	if (eth0_node) {
> +		prueth_put_cores(prueth, ICSS_SLICE0);
> +		of_node_put(eth0_node);
> +	}
> +
> +	return ret;
> +}

[...]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-05-31 10:08   ` Krzysztof Kozlowski
  2022-05-31 11:27     ` Puranjay Mohan
@ 2022-11-04  7:28     ` Md Danish Anwar
  2022-11-04 12:57       ` Krzysztof Kozlowski
  1 sibling, 1 reply; 20+ messages in thread
From: Md Danish Anwar @ 2022-11-04  7:28 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, vigneshr, kishon,
	robh+dt, afd, andrew

Hi Krzysztof,

I am Danish, new addition to TI team. Puranjay left TI, I'll be posting
upstream patches for Programmable Real-time Unit and Industrial Communication
Subsystem
Gigabit (PRU_ICSSG).

On 31/05/22 15:38, Krzysztof Kozlowski wrote:
> On 31/05/2022 11:51, Puranjay Mohan wrote:
>> Add a YAML binding document for the ICSSG Programmable real time unit
>> based Ethernet driver. This driver uses the PRU and PRUSS consumer APIs
>> to interface the PRUs and load/run the firmware for supporting ethernet
>> functionality.
>>
>> Signed-off-by: Puranjay Mohan <p-mohan@ti.com>
>> ---
>> v1: https://lore.kernel.org/all/20220506052433.28087-2-p-mohan@ti.com/ 
>> v1 -> v2:
>> * Addressed Rob's Comments
> 
> Nope, they were not addressed.
> 
>> * It includes indentation, formatting, and other minor changes.
>> ---
>>  .../bindings/net/ti,icssg-prueth.yaml         | 181 ++++++++++++++++++
>>  1 file changed, 181 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>> new file mode 100644
>> index 000000000000..40af968e9178
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>> @@ -0,0 +1,181 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/net/ti,icssg-prueth.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: |+
> 
> Missed Rob's comment.
> 

I'll remove this in the next version of this series.

>> +  Texas Instruments ICSSG PRUSS Ethernet
>> +
>> +maintainers:
>> +  - Puranjay Mohan <p-mohan@ti.com>
>> +
>> +description:
>> +  Ethernet based on the Programmable Real-Time
>> +  Unit and Industrial Communication Subsystem.
>> +
>> +allOf:
>> +  - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - ti,am654-icssg-prueth  # for AM65x SoC family
>> +
>> +  pinctrl-0:
>> +    maxItems: 1
>> +
>> +  pinctrl-names:
>> +    items:
>> +      - const: default
> 
> You do not need these usually, they are coming from schema.
>
Here from what I understand, I need to delete the below block, right?

  pinctrl-names:
    items:
     - const: default

>> +
>> +  sram:
>> +    description:
>> +      phandle to MSMC SRAM node
>> +
>> +  dmas:
>> +    maxItems: 10
>> +    description:
>> +      list of phandles and specifiers to UDMA.
> 
> Please follow Rob's comment - drop description.
> 

I'll drop desceeiption.

>> +
>> +  dma-names:
>> +    items:
>> +      - const: tx0-0
>> +      - const: tx0-1
>> +      - const: tx0-2
>> +      - const: tx0-3
>> +      - const: tx1-0
>> +      - const: tx1-1
>> +      - const: tx1-2
>> +      - const: tx1-3
>> +      - const: rx0
>> +      - const: rx1
>> +
>> +  ethernet-ports:
>> +    type: object
>> +    properties:
>> +      '#address-cells':
>> +        const: 1
>> +      '#size-cells':
>> +        const: 0
>> +
>> +    patternProperties:
>> +      ^port@[0-1]$:
> 
> How did you implement Rob's comments here?
> 
>> +        type: object
>> +        description: ICSSG PRUETH external ports
>> +
>> +        $ref: ethernet-controller.yaml#
>> +
>> +        unevaluatedProperties: false
>> +        additionalProperties: true
> 
> No one proposed to add additionalProperties:true... Does it even work?
> 

I'll remove additionalProperties:true and keep it as false, as it was in the
previous version.

>> +        properties:
>> +          reg:
>> +            items:
>> +              - enum: [0, 1]
>> +            description: ICSSG PRUETH port number
>> +
>> +          ti,syscon-rgmii-delay:
>> +            $ref: /schemas/types.yaml#/definitions/phandle-array
>> +            description:
>> +              phandle to system controller node and register offset
>> +              to ICSSG control register for RGMII transmit delay
>> +
>> +        required:
>> +          - reg
>> +
>> +  ti,mii-g-rt:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description: |
>> +      phandle to MII_G_RT module's syscon regmap.
>> +
>> +  ti,mii-rt:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description: |
>> +      phandle to MII_RT module's syscon regmap
>> +
>> +  interrupts:
>> +    minItems: 2
>> +    maxItems: 2
>> +    description: |
>> +      Interrupt specifiers to TX timestamp IRQ.
>> +
>> +  interrupt-names:
>> +    items:
>> +      - const: tx_ts0
>> +      - const: tx_ts1
>> +
>> +required:
>> +  - compatible
>> +  - sram
>> +  - ti,mii-g-rt
>> +  - dmas
>> +  - dma-names
>> +  - ethernet-ports
>> +  - interrupts
>> +  - interrupt-names
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +
>> +    /* Example k3-am654 base board SR2.0, dual-emac */
>> +    pruss2_eth: pruss2_eth {
>> +            compatible = "ti,am654-icssg-prueth";
> 
> Again missed Rob's comment.
> 

I'll keep the indentation in example as 4 for first block, 4+4 for second block
and so on.

> Really, you ignored four of his comments. Please respect reviewers time
> but not forcing them to repeat same review comments.
> 
> Best regards,
> Krzysztof
> 

Thanks and Regards,
Md Danish Anwar.

> From mboxrd@z Thu Jan  1 00:00:00 1970
> Return-Path: <linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org>
> X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
> 	aws-us-west-2-korg-lkml-1.web.codeaurora.org
> Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133])
> 	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
> 	(No client certificate requested)
> 	by smtp.lore.kernel.org (Postfix) with ESMTPS id D8E5FC433FE
> 	for <linux-arm-kernel@archiver.kernel.org>; Tue, 31 May 2022 10:10:18 +0000 (UTC)
> DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
> 	d=lists.infradead.org; s=bombadil.20210309; h=Sender:
> 	Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:
> 	List-Archive:List-Unsubscribe:List-Id:In-Reply-To:From:References:Cc:To:
> 	Subject:MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description:
> 	Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:
> 	List-Owner; bh=1a8R2aPtpN8VJ8nnKPmRS52Aa9f7VxdsHDMYjLy3Nec=; b=wIC+W0D4fCGLL2
> 	d62YYbdS41pfLBGPmRsc7zOtnryxJBMZ+3ranQeCbNLF852PAuSOHzYQlKfDiPG8G4rTileKr2zI4
> 	tgmrfHwiYz4zFLOrZSK/F0gUKRcXs+ivHNa5dEWipt2UaOnrPjVxJNPa2ExKalwxedTTlzXuOKvRp
> 	lBsupH/BY2Yhwdiy0YGYEQ06wug/wAJrHw6gVZ2A54brkI/Gh0MgQA3DX2vFqtAf+FRLB5o38KzD6
> 	uRsYf/QKOD1ixkP2Uh+isRMsVK1GJAY1BaxNnfisYDCJ31Y4auPV1TTJ5JsqOPIl+oAc+qQOoWhUt
> 	ZHtAzDsfrPhRteMR8nGA==;
> Received: from localhost ([::1] helo=bombadil.infradead.org)
> 	by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux))
> 	id 1nvyns-00A97O-Kp; Tue, 31 May 2022 10:08:44 +0000
> Received: from mail-ej1-x629.google.com ([2a00:1450:4864:20::629])
> 	by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))
> 	id 1nvynp-00A96p-Bi
> 	for linux-arm-kernel@lists.infradead.org; Tue, 31 May 2022 10:08:43 +0000
> Received: by mail-ej1-x629.google.com with SMTP id f9so25684073ejc.0
>         for <linux-arm-kernel@lists.infradead.org>; Tue, 31 May 2022 03:08:40 -0700 (PDT)
> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
>         d=linaro.org; s=google;
>         h=message-id:date:mime-version:user-agent:subject:content-language:to
>          :cc:references:from:in-reply-to:content-transfer-encoding;
>         bh=0xEDKtRJ1gFx9yMLHsbYq7kEF2/saJCmbQuGtwp5BAo=;
>         b=FJlTsAsgLQm8T7cg7ztoR+hVidoRf0V5AWOmRsLnTi0T7R1GvuT2r/FFDmqkIl53A6
>          DbHgnZvG+DyTKUwG/vdUmgZmVNF+w7UeZKwmdDVjGozRWvHTYOIaY1SWDxFECXfVzcy0
>          LAg5f9EqBC3WEIjvhOnIkvR7P+OsgIhI/OiivIkJBdzRo9jS9E+2yx+Sm8NDltnFTUwA
>          IYLDY1JDsLGwfIc2HtBk3jWG83NDp0Ea+TiENVqdmzdP+uv3rQqxCeGPQQRIR8kZ+lhz
>          EsPkUVZzzGoPnArdmSNQGceUzqD1QuOmhiLIlqBDnkgIxv0uDEGSG52wLOF3N4QCWRdj
>          7/7A==
> X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
>         d=1e100.net; s=20210112;
>         h=x-gm-message-state:message-id:date:mime-version:user-agent:subject
>          :content-language:to:cc:references:from:in-reply-to
>          :content-transfer-encoding;
>         bh=0xEDKtRJ1gFx9yMLHsbYq7kEF2/saJCmbQuGtwp5BAo=;
>         b=B8P1vdEHTMWSN4xCuq1bRYTxlQJ2WbgTX33+iZ64xwRYFE43op8cqxMLe8ItNeXhOa
>          ygVqXL+3FCMKHUz2qvOplSkkHDMwKumX+X/ErqhpU2u+Npqyo8EvNGH0toag3qflFryq
>          GsjzmWphffPt7/1Z/+K5+0dqvy92g9tDtBmNyRTn52i0RoOQ05LlbKBxkJOXEXxNaD/y
>          l9T9G26QAQaF7kT/gKe2Lrj+kCrTpJ/1yI05qKdrhZdka3xZa6GBIi6VRwJcynxUcxs8
>          aJQL70rRY4tfncRNUghETqpjQu8clZdj57R9HaO3LEBfq8uZlFvQVTr9u13RL2twT3aa
>          3UAA==
> X-Gm-Message-State: AOAM531dEZwptqWX2TF8w5F1B3CdGvkaOesF74IGrBLIeJeoH/LfzFiG
> 	4a4rxd2QE25vDQvfgJchJ+HUkw==
> X-Google-Smtp-Source: ABdhPJxvLTVkRm6gy9yj0yU6UO395ZmuZmGbmyxXWGwAn4IUJBt1uCvPDQ8Lpwmm1nn62gUGkldWYA==
> X-Received: by 2002:a17:906:5d0d:b0:6fe:b420:5eab with SMTP id g13-20020a1709065d0d00b006feb4205eabmr45855204ejt.23.1653991719238;
>         Tue, 31 May 2022 03:08:39 -0700 (PDT)
> Received: from [192.168.0.179] (xdsl-188-155-176-92.adslplus.ch. [188.155.176.92])
>         by smtp.gmail.com with ESMTPSA id i16-20020a1709063c5000b006fed85c1a72sm4802036ejg.223.2022.05.31.03.08.38
>         (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);
>         Tue, 31 May 2022 03:08:38 -0700 (PDT)
> Message-ID: <4ccba38a-ccde-83cd-195b-77db7a64477c@linaro.org>
> Date: Tue, 31 May 2022 12:08:37 +0200
> MIME-Version: 1.0
> User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101
>  Thunderbird/91.9.1
> Subject: Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver
>  bindings
> Content-Language: en-US
> To: Puranjay Mohan <p-mohan@ti.com>, linux-kernel@vger.kernel.org
> Cc: davem@davemloft.net, edumazet@google.com,
>  krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org,
>  devicetree@vger.kernel.org, nm@ti.com, ssantosh@kernel.org, s-anna@ti.com,
>  linux-arm-kernel@lists.infradead.org, rogerq@kernel.org,
>  grygorii.strashko@ti.com, vigneshr@ti.com, kishon@ti.com,
>  robh+dt@kernel.org, afd@ti.com, andrew@lunn.ch
> References: <20220531095108.21757-1-p-mohan@ti.com>
>  <20220531095108.21757-2-p-mohan@ti.com>
> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> In-Reply-To: <20220531095108.21757-2-p-mohan@ti.com>
> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
> X-CRM114-CacheID: sfid-20220531_030841_459584_A3DCA991 
> X-CRM114-Status: GOOD (  21.47  )
> X-BeenThere: linux-arm-kernel@lists.infradead.org
> X-Mailman-Version: 2.1.34
> Precedence: list
> List-Id: <linux-arm-kernel.lists.infradead.org>
> List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-arm-kernel>,
>  <mailto:linux-arm-kernel-request@lists.infradead.org?subject=unsubscribe>
> List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
> List-Post: <mailto:linux-arm-kernel@lists.infradead.org>
> List-Help: <mailto:linux-arm-kernel-request@lists.infradead.org?subject=help>
> List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>,
>  <mailto:linux-arm-kernel-request@lists.infradead.org?subject=subscribe>
> Content-Type: text/plain; charset="us-ascii"
> Content-Transfer-Encoding: 7bit
> Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
> Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org
> 
> On 31/05/2022 11:51, Puranjay Mohan wrote:
>> Add a YAML binding document for the ICSSG Programmable real time unit
>> based Ethernet driver. This driver uses the PRU and PRUSS consumer APIs
>> to interface the PRUs and load/run the firmware for supporting ethernet
>> functionality.
>>
>> Signed-off-by: Puranjay Mohan <p-mohan@ti.com>
>> ---
>> v1: https://lore.kernel.org/all/20220506052433.28087-2-p-mohan@ti.com/ 
>> v1 -> v2:
>> * Addressed Rob's Comments
> 
> Nope, they were not addressed.
> 
>> * It includes indentation, formatting, and other minor changes.
>> ---
>>  .../bindings/net/ti,icssg-prueth.yaml         | 181 ++++++++++++++++++
>>  1 file changed, 181 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>> new file mode 100644
>> index 000000000000..40af968e9178
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>> @@ -0,0 +1,181 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/net/ti,icssg-prueth.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: |+
> 
> Missed Rob's comment.
> 
>> +  Texas Instruments ICSSG PRUSS Ethernet
>> +
>> +maintainers:
>> +  - Puranjay Mohan <p-mohan@ti.com>
>> +
>> +description:
>> +  Ethernet based on the Programmable Real-Time
>> +  Unit and Industrial Communication Subsystem.
>> +
>> +allOf:
>> +  - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - ti,am654-icssg-prueth  # for AM65x SoC family
>> +
>> +  pinctrl-0:
>> +    maxItems: 1
>> +
>> +  pinctrl-names:
>> +    items:
>> +      - const: default
> 
> You do not need these usually, they are coming from schema.
> 
>> +
>> +  sram:
>> +    description:
>> +      phandle to MSMC SRAM node
>> +
>> +  dmas:
>> +    maxItems: 10
>> +    description:
>> +      list of phandles and specifiers to UDMA.
> 
> Please follow Rob's comment - drop description.
> 
>> +
>> +  dma-names:
>> +    items:
>> +      - const: tx0-0
>> +      - const: tx0-1
>> +      - const: tx0-2
>> +      - const: tx0-3
>> +      - const: tx1-0
>> +      - const: tx1-1
>> +      - const: tx1-2
>> +      - const: tx1-3
>> +      - const: rx0
>> +      - const: rx1
>> +
>> +  ethernet-ports:
>> +    type: object
>> +    properties:
>> +      '#address-cells':
>> +        const: 1
>> +      '#size-cells':
>> +        const: 0
>> +
>> +    patternProperties:
>> +      ^port@[0-1]$:
> 
> How did you implement Rob's comments here?
> 
>> +        type: object
>> +        description: ICSSG PRUETH external ports
>> +
>> +        $ref: ethernet-controller.yaml#
>> +
>> +        unevaluatedProperties: false
>> +        additionalProperties: true
> 
> No one proposed to add additionalProperties:true... Does it even work?
> 
>> +        properties:
>> +          reg:
>> +            items:
>> +              - enum: [0, 1]
>> +            description: ICSSG PRUETH port number
>> +
>> +          ti,syscon-rgmii-delay:
>> +            $ref: /schemas/types.yaml#/definitions/phandle-array
>> +            description:
>> +              phandle to system controller node and register offset
>> +              to ICSSG control register for RGMII transmit delay
>> +
>> +        required:
>> +          - reg
>> +
>> +  ti,mii-g-rt:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description: |
>> +      phandle to MII_G_RT module's syscon regmap.
>> +
>> +  ti,mii-rt:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description: |
>> +      phandle to MII_RT module's syscon regmap
>> +
>> +  interrupts:
>> +    minItems: 2
>> +    maxItems: 2
>> +    description: |
>> +      Interrupt specifiers to TX timestamp IRQ.
>> +
>> +  interrupt-names:
>> +    items:
>> +      - const: tx_ts0
>> +      - const: tx_ts1
>> +
>> +required:
>> +  - compatible
>> +  - sram
>> +  - ti,mii-g-rt
>> +  - dmas
>> +  - dma-names
>> +  - ethernet-ports
>> +  - interrupts
>> +  - interrupt-names
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +
>> +    /* Example k3-am654 base board SR2.0, dual-emac */
>> +    pruss2_eth: pruss2_eth {
>> +            compatible = "ti,am654-icssg-prueth";
> 
> Again missed Rob's comment.
> 
> Really, you ignored four of his comments. Please respect reviewers time
> but not forcing them to repeat same review comments.
> 
> Best regards,
> Krzysztof
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
  2022-05-31 11:23   ` Paolo Abeni
@ 2022-11-04  8:29     ` Md Danish Anwar
  0 siblings, 0 replies; 20+ messages in thread
From: Md Danish Anwar @ 2022-11-04  8:29 UTC (permalink / raw)
  To: Paolo Abeni, linux-kernel
  Cc: davem, edumazet, krzysztof.kozlowski+dt, netdev, devicetree, nm,
	ssantosh, s-anna, linux-arm-kernel, rogerq, vigneshr, robh+dt,
	afd, andrew

Hi Paolo,

I am Danish, new addition to TI team. Puranjay left TI, I'll be posting
upstream patches for Programmable Real-time Unit and Industrial Communication
Subsystem Gigabit (PRU_ICSSG).

On 31/05/22 16:53, Paolo Abeni wrote:
> On Tue, 2022-05-31 at 15:21 +0530, Puranjay Mohan wrote:
> [...]
>> +static int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
>> +				    int budget)
>> +{
>> +	struct net_device *ndev = emac->ndev;
>> +	struct cppi5_host_desc_t *desc_tx;
>> +	struct netdev_queue *netif_txq;
>> +	struct prueth_tx_chn *tx_chn;
>> +	unsigned int total_bytes = 0;
>> +	struct sk_buff *skb;
>> +	dma_addr_t desc_dma;
>> +	int res, num_tx = 0;
>> +	void **swdata;
>> +
>> +	tx_chn = &emac->tx_chns[chn];
>> +
>> +	while (budget--) {
>> +		res = k3_udma_glue_pop_tx_chn(tx_chn->tx_chn, &desc_dma);
>> +		if (res == -ENODATA)
>> +			break;
>> +
>> +		/* teardown completion */
>> +		if (cppi5_desc_is_tdcm(desc_dma)) {
>> +			if (atomic_dec_and_test(&emac->tdown_cnt))
>> +				complete(&emac->tdown_complete);
>> +			break;
>> +		}
>> +
>> +		desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
>> +						     desc_dma);
>> +		swdata = cppi5_hdesc_get_swdata(desc_tx);
>> +
>> +		skb = *(swdata);
>> +		prueth_xmit_free(tx_chn, desc_tx);
>> +
>> +		ndev = skb->dev;
>> +		ndev->stats.tx_packets++;
>> +		ndev->stats.tx_bytes += skb->len;
>> +		total_bytes += skb->len;
>> +		napi_consume_skb(skb, budget);
> 
> The above is uncorrect. In this loop's last iteration 'budget' will  be
> 0 and napi_consume_skb will wrongly assume the caller is not in NAPI
> context. 
> 

Yes, in the current approach, in last iteration budget will be zero. To avoid
this, we can change the looping condition. Instead of while(budget--), it could
be while(budget) and budget will be decreamented at the end of the loop.
This way in the last iteration budget value will not be zero.

The while loop will look like this.

while (budget) {
    res = k3_udma_glue_pop_tx_chn(tx_chn->tx_chn, &desc_dma);
	if (res == -ENODATA)
		break;

	/* teardown completion */
	if (cppi5_desc_is_tdcm(desc_dma)) {
		if (atomic_dec_and_test(&emac->tdown_cnt))
			complete(&emac->tdown_complete);
		break;
	}

	desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
					     desc_dma);
	swdata = cppi5_hdesc_get_swdata(desc_tx);

	skb = *(swdata);
	prueth_xmit_free(tx_chn, desc_tx);

	ndev = skb->dev;
	ndev->stats.tx_packets++;
	ndev->stats.tx_bytes += skb->len;
	total_bytes += skb->len;
	napi_consume_skb(skb, budget);
	num_tx++;
        budget--;
}

Please let me know if this seems ok.


>> +static int prueth_dma_rx_push(struct prueth_emac *emac,
>> +			      struct sk_buff *skb,
>> +			      struct prueth_rx_chn *rx_chn)
>> +{
>> +	struct cppi5_host_desc_t *desc_rx;
>> +	struct net_device *ndev = emac->ndev;
>> +	dma_addr_t desc_dma;
>> +	dma_addr_t buf_dma;
>> +	u32 pkt_len = skb_tailroom(skb);
>> +	void **swdata;
>> +
>> +	desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool);
>> +	if (!desc_rx) {
>> +		netdev_err(ndev, "rx push: failed to allocate descriptor\n");
>> +		return -ENOMEM;
>> +	}
>> +	desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx);
>> +
>> +	buf_dma = dma_map_single(rx_chn->dma_dev, skb->data, pkt_len, DMA_FROM_DEVICE);
>> +	if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) {
>> +		k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
>> +		netdev_err(ndev, "rx push: failed to map rx pkt buffer\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT,
>> +			 PRUETH_NAV_PS_DATA_SIZE);
>> +	k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chn, &buf_dma);
>> +	cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_tailroom(skb));
>> +
>> +	swdata = cppi5_hdesc_get_swdata(desc_rx);
>> +	*swdata = skb;
>> +
>> +	return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0,
>> +					desc_rx, desc_dma);
>> +}
>> +
>> +static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id)
>> +{
>> +	struct prueth_rx_chn *rx_chn = &emac->rx_chns;
>> +	struct net_device *ndev = emac->ndev;
>> +	struct cppi5_host_desc_t *desc_rx;
>> +	dma_addr_t desc_dma, buf_dma;
>> +	u32 buf_dma_len, pkt_len, port_id = 0;
>> +	int ret;
>> +	void **swdata;
>> +	struct sk_buff *skb, *new_skb;
>> +
>> +	ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma);
>> +	if (ret) {
>> +		if (ret != -ENODATA)
>> +			netdev_err(ndev, "rx pop: failed: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	if (cppi5_desc_is_tdcm(desc_dma)) /* Teardown ? */
>> +		return 0;
>> +
>> +	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
>> +
>> +	swdata = cppi5_hdesc_get_swdata(desc_rx);
>> +	skb = *swdata;
>> +
>> +	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
>> +	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma);
>> +	pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
>> +	/* firmware adds 4 CRC bytes, strip them */
>> +	pkt_len -= 4;
>> +	cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL);
>> +
>> +	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
>> +	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
>> +
>> +	skb->dev = ndev;
>> +	if (!netif_running(skb->dev)) {
>> +		dev_kfree_skb_any(skb);
>> +		return 0;
>> +	}
>> +
>> +	new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE);
>> +	/* if allocation fails we drop the packet but push the
>> +	 * descriptor back to the ring with old skb to prevent a stall
>> +	 */
>> +	if (!new_skb) {
>> +		ndev->stats.rx_dropped++;
>> +		new_skb = skb;
>> +	} else {
>> +		/* send the filled skb up the n/w stack */
>> +		skb_put(skb, pkt_len);
>> +		skb->protocol = eth_type_trans(skb, ndev);
>> +		netif_receive_skb(skb);
> 
> This is (apparently) in napi context. You should use napi_gro_receive()
> or napi_gro_frags()
> 

Here instead of the below line,
	netif_receive_skb(skb);
I will add the below line.
	napi_gro_receive(&emac->napi_rx,skb);

> 
> Cheers!
> 
> Paolo
> 
>

Thanks and Regards,
Md Danish Anwar.

> From mboxrd@z Thu Jan  1 00:00:00 1970
> Return-Path: <linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org>
> X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
> 	aws-us-west-2-korg-lkml-1.web.codeaurora.org
> Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133])
> 	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
> 	(No client certificate requested)
> 	by smtp.lore.kernel.org (Postfix) with ESMTPS id 4D786C433F5
> 	for <linux-arm-kernel@archiver.kernel.org>; Tue, 31 May 2022 11:25:15 +0000 (UTC)
> DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
> 	d=lists.infradead.org; s=bombadil.20210309; h=Sender:
> 	Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:
> 	List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:
> 	Date:Cc:To:From:Subject:Message-ID:Reply-To:Content-ID:Content-Description:
> 	Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:
> 	List-Owner; bh=G6tJbk7sQR1mDcrAEuhdOI2yoBQYm8IZy4P83gbmA5I=; b=b9Mfw3uDtLFHrB
> 	NWAtz9tl5UTBd63L1taDo96GeRFEK2UFO0N+PDA2axuNFxwGia7rnX77QsxtDIwcsIM54iQ4bqgkV
> 	cRjIWVy+hV15u6iqB4AOb8koWEtcNBOhHlkFdhEcaiBjSF3bkGVZfkevi5DXApAN7dRZ5RRIjoreK
> 	8Z2H7S5Ra1ySKmznpQuVTegkT1RWQOeRAEWBInn0tMY9IWAkDvgwaxLFMysYAr7l9nDwn5ZyPr9IH
> 	IxMiVdJl9Mm8oqCfD0sSjX2nMbCT5njTvzc+CNtUYq+QmowBNFA4dXRxjN5QTV8tFktoZohMNbE0b
> 	ku0VtX5brHWK2Ah+XLPw==;
> Received: from localhost ([::1] helo=bombadil.infradead.org)
> 	by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux))
> 	id 1nvzyl-00AQPx-Hr; Tue, 31 May 2022 11:24:03 +0000
> Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124])
> 	by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))
> 	id 1nvzyd-00AQGI-TY
> 	for linux-arm-kernel@lists.infradead.org; Tue, 31 May 2022 11:24:01 +0000
> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;
> 	s=mimecast20190719; t=1653996227;
> 	h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
> 	 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
> 	 content-transfer-encoding:content-transfer-encoding:
> 	 in-reply-to:in-reply-to:references:references;
> 	bh=cb0uCHMo8aU2h1eNWnUmV0rqWGFcvOyZ9KFWz5IpS3o=;
> 	b=h22ZTXxxwt9hyc7KbHSr62yigwFCCTio7owsb2WAm5cp6e8Kiuk3fJGffx8nfPDdVJJkFN
> 	OREBfOrrzVHd+ASgkpchKc0gLVuQ6fqS/T0+zTlFfQfviUXAQsUZyFBgXUB7+hYmxkX5n8
> 	F/2G78qChsTPJo2XWwVmmZHI/gYbzbw=
> Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com
>  [209.85.222.200]) by relay.mimecast.com with ESMTP with STARTTLS
>  (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
>  us-mta-571-TQPFR5jZOvmNDrKiJr3Xvg-1; Tue, 31 May 2022 07:23:46 -0400
> X-MC-Unique: TQPFR5jZOvmNDrKiJr3Xvg-1
> Received: by mail-qk1-f200.google.com with SMTP id v14-20020a05620a0f0e00b00699f4ea852cso10297976qkl.9
>         for <linux-arm-kernel@lists.infradead.org>; Tue, 31 May 2022 04:23:46 -0700 (PDT)
> X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
>         d=1e100.net; s=20210112;
>         h=x-gm-message-state:message-id:subject:from:to:cc:date:in-reply-to
>          :references:user-agent:mime-version:content-transfer-encoding;
>         bh=cb0uCHMo8aU2h1eNWnUmV0rqWGFcvOyZ9KFWz5IpS3o=;
>         b=LqfkbB8wXsz3y7UBmnT/YVVBZ7S0Y60UrJo5mC3q599z5+eFofo5rfCIPIAyXzm5JZ
>          3sHnSAp8Hp8XyFTwwCDRIXb6jJhKz4J9cBLmCaQ3d1/pjbTZUthlYYNnSKK0tjTqoPNI
>          iTiCrg26k39q9Znhg0nQ72/+TrHomUqUs0r17ymA1dVbA1hcySoC09m08SHtLS5eUOSH
>          u4FJ3qUwrJibIqrdObz2Pi29aPHOwhdi1ax5xk3EDrJM8RLtEWAexx8l1vsm9SiAuWdW
>          KnYidUxP+vsyesflHI38sjxaaFjde2vifXOrnyArcLRsAsHqyqwfqNVSjfTf4LbMzv0c
>          M3fQ==
> X-Gm-Message-State: AOAM532rTtItItwMr1nw+byJldJCXtJ/u45688HjEb4OLqmB4ExjHSKA
> 	cBaCX44yNzplF0RGG6P6cnWGPOU9aPqJ5KDHkieG7iqQYrjlpCaVkBWGv4mtJOwK/ksP+dlc1Oi
> 	Ojtg8QWc+0xb2gu+IBjsJsR72JtdOiLLrYWU=
> X-Received: by 2002:a05:620a:12fb:b0:6a5:816e:43d6 with SMTP id f27-20020a05620a12fb00b006a5816e43d6mr23692501qkl.692.1653996226020;
>         Tue, 31 May 2022 04:23:46 -0700 (PDT)
> X-Google-Smtp-Source: ABdhPJzcKltOlg/kYOsBwY4ck89LyJGn1h8RwebGLbLyGZQf6VOtbjGuWUhQQKGVPYXnPktvmybIag==
> X-Received: by 2002:a05:620a:12fb:b0:6a5:816e:43d6 with SMTP id f27-20020a05620a12fb00b006a5816e43d6mr23692486qkl.692.1653996225758;
>         Tue, 31 May 2022 04:23:45 -0700 (PDT)
> Received: from gerbillo.redhat.com (146-241-112-184.dyn.eolo.it. [146.241.112.184])
>         by smtp.gmail.com with ESMTPSA id b26-20020a05620a271a00b0069fe1fc72e7sm9204894qkp.90.2022.05.31.04.23.42
>         (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
>         Tue, 31 May 2022 04:23:45 -0700 (PDT)
> Message-ID: <fee7c767e1a57822bddc88fb6096673838e93ee4.camel@redhat.com>
> Subject: Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
> From: Paolo Abeni <pabeni@redhat.com>
> To: Puranjay Mohan <p-mohan@ti.com>, linux-kernel@vger.kernel.org
> Cc: davem@davemloft.net, edumazet@google.com,
>  krzysztof.kozlowski+dt@linaro.org,  netdev@vger.kernel.org,
>  devicetree@vger.kernel.org, nm@ti.com, ssantosh@kernel.org,  s-anna@ti.com,
>  linux-arm-kernel@lists.infradead.org, rogerq@kernel.org, 
>  grygorii.strashko@ti.com, vigneshr@ti.com, kishon@ti.com,
>  robh+dt@kernel.org,  afd@ti.com, andrew@lunn.ch
> Date: Tue, 31 May 2022 13:23:40 +0200
> In-Reply-To: <20220531095108.21757-3-p-mohan@ti.com>
> References: <20220531095108.21757-1-p-mohan@ti.com>
> 	 <20220531095108.21757-3-p-mohan@ti.com>
> User-Agent: Evolution 3.42.4 (3.42.4-2.fc35)
> MIME-Version: 1.0
> Authentication-Results: relay.mimecast.com;
> 	auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=pabeni@redhat.com
> X-Mimecast-Spam-Score: 0
> X-Mimecast-Originator: redhat.com
> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
> X-CRM114-CacheID: sfid-20220531_042356_091497_CF385DF2 
> X-CRM114-Status: GOOD (  17.59  )
> X-BeenThere: linux-arm-kernel@lists.infradead.org
> X-Mailman-Version: 2.1.34
> Precedence: list
> List-Id: <linux-arm-kernel.lists.infradead.org>
> List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-arm-kernel>,
>  <mailto:linux-arm-kernel-request@lists.infradead.org?subject=unsubscribe>
> List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
> List-Post: <mailto:linux-arm-kernel@lists.infradead.org>
> List-Help: <mailto:linux-arm-kernel-request@lists.infradead.org?subject=help>
> List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>,
>  <mailto:linux-arm-kernel-request@lists.infradead.org?subject=subscribe>
> Content-Type: text/plain; charset="us-ascii"
> Content-Transfer-Encoding: 7bit
> Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
> Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org
> 
> On Tue, 2022-05-31 at 15:21 +0530, Puranjay Mohan wrote:
> [...]
>> +static int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
>> +				    int budget)
>> +{
>> +	struct net_device *ndev = emac->ndev;
>> +	struct cppi5_host_desc_t *desc_tx;
>> +	struct netdev_queue *netif_txq;
>> +	struct prueth_tx_chn *tx_chn;
>> +	unsigned int total_bytes = 0;
>> +	struct sk_buff *skb;
>> +	dma_addr_t desc_dma;
>> +	int res, num_tx = 0;
>> +	void **swdata;
>> +
>> +	tx_chn = &emac->tx_chns[chn];
>> +
>> +	while (budget--) {
>> +		res = k3_udma_glue_pop_tx_chn(tx_chn->tx_chn, &desc_dma);
>> +		if (res == -ENODATA)
>> +			break;
>> +
>> +		/* teardown completion */
>> +		if (cppi5_desc_is_tdcm(desc_dma)) {
>> +			if (atomic_dec_and_test(&emac->tdown_cnt))
>> +				complete(&emac->tdown_complete);
>> +			break;
>> +		}
>> +
>> +		desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
>> +						     desc_dma);
>> +		swdata = cppi5_hdesc_get_swdata(desc_tx);
>> +
>> +		skb = *(swdata);
>> +		prueth_xmit_free(tx_chn, desc_tx);
>> +
>> +		ndev = skb->dev;
>> +		ndev->stats.tx_packets++;
>> +		ndev->stats.tx_bytes += skb->len;
>> +		total_bytes += skb->len;
>> +		napi_consume_skb(skb, budget);
> 
> The above is uncorrect. In this loop's last iteration 'budget' will  be
> 0 and napi_consume_skb will wrongly assume the caller is not in NAPI
> context. 
> 
>> +static int prueth_dma_rx_push(struct prueth_emac *emac,
>> +			      struct sk_buff *skb,
>> +			      struct prueth_rx_chn *rx_chn)
>> +{
>> +	struct cppi5_host_desc_t *desc_rx;
>> +	struct net_device *ndev = emac->ndev;
>> +	dma_addr_t desc_dma;
>> +	dma_addr_t buf_dma;
>> +	u32 pkt_len = skb_tailroom(skb);
>> +	void **swdata;
>> +
>> +	desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool);
>> +	if (!desc_rx) {
>> +		netdev_err(ndev, "rx push: failed to allocate descriptor\n");
>> +		return -ENOMEM;
>> +	}
>> +	desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx);
>> +
>> +	buf_dma = dma_map_single(rx_chn->dma_dev, skb->data, pkt_len, DMA_FROM_DEVICE);
>> +	if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) {
>> +		k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
>> +		netdev_err(ndev, "rx push: failed to map rx pkt buffer\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT,
>> +			 PRUETH_NAV_PS_DATA_SIZE);
>> +	k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chn, &buf_dma);
>> +	cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_tailroom(skb));
>> +
>> +	swdata = cppi5_hdesc_get_swdata(desc_rx);
>> +	*swdata = skb;
>> +
>> +	return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0,
>> +					desc_rx, desc_dma);
>> +}
>> +
>> +static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id)
>> +{
>> +	struct prueth_rx_chn *rx_chn = &emac->rx_chns;
>> +	struct net_device *ndev = emac->ndev;
>> +	struct cppi5_host_desc_t *desc_rx;
>> +	dma_addr_t desc_dma, buf_dma;
>> +	u32 buf_dma_len, pkt_len, port_id = 0;
>> +	int ret;
>> +	void **swdata;
>> +	struct sk_buff *skb, *new_skb;
>> +
>> +	ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma);
>> +	if (ret) {
>> +		if (ret != -ENODATA)
>> +			netdev_err(ndev, "rx pop: failed: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	if (cppi5_desc_is_tdcm(desc_dma)) /* Teardown ? */
>> +		return 0;
>> +
>> +	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
>> +
>> +	swdata = cppi5_hdesc_get_swdata(desc_rx);
>> +	skb = *swdata;
>> +
>> +	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
>> +	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma);
>> +	pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
>> +	/* firmware adds 4 CRC bytes, strip them */
>> +	pkt_len -= 4;
>> +	cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL);
>> +
>> +	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
>> +	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
>> +
>> +	skb->dev = ndev;
>> +	if (!netif_running(skb->dev)) {
>> +		dev_kfree_skb_any(skb);
>> +		return 0;
>> +	}
>> +
>> +	new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE);
>> +	/* if allocation fails we drop the packet but push the
>> +	 * descriptor back to the ring with old skb to prevent a stall
>> +	 */
>> +	if (!new_skb) {
>> +		ndev->stats.rx_dropped++;
>> +		new_skb = skb;
>> +	} else {
>> +		/* send the filled skb up the n/w stack */
>> +		skb_put(skb, pkt_len);
>> +		skb->protocol = eth_type_trans(skb, ndev);
>> +		netif_receive_skb(skb);
> 
> This is (apparently) in napi context. You should use napi_gro_receive()
> or napi_gro_frags()
> 
> 
> Cheers!
> 
> Paolo
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
  2022-06-05 16:24   ` Christophe JAILLET
@ 2022-11-04  9:50     ` Md Danish Anwar
  0 siblings, 0 replies; 20+ messages in thread
From: Md Danish Anwar @ 2022-11-04  9:50 UTC (permalink / raw)
  To: Christophe JAILLET
  Cc: afd, andrew, davem, devicetree, edumazet, krzysztof.kozlowski+dt,
	linux-arm-kernel, linux-kernel, netdev, nm, robh+dt, rogerq,
	s-anna, ssantosh, vigneshr



On 05/06/22 21:54, Christophe JAILLET wrote:
> Hi,
> 
> Just a few comments below, for what they worth.
> 
> Le 31/05/2022 à 11:51, Puranjay Mohan a écrit :
>> From: Roger Quadros <rogerq-l0cyMroinI0@public.gmane.org>
>>
>> This is the Ethernet driver for TI AM654 Silicon rev. 2
>> with the ICSSG PRU Sub-system running dual-EMAC firmware.
>>
> 
> [...]
> 
>> +static int prueth_netdev_init(struct prueth *prueth,
>> +                  struct device_node *eth_node)
>> +{
>> +    int ret, num_tx_chn = PRUETH_MAX_TX_QUEUES;
>> +    struct prueth_emac *emac;
>> +    struct net_device *ndev;
>> +    enum prueth_port port;
>> +    enum prueth_mac mac;
>> +
>> +    port = prueth_node_port(eth_node);
>> +    if (port < 0)
>> +        return -EINVAL;
>> +
>> +    mac = prueth_node_mac(eth_node);
>> +    if (mac < 0)
>> +        return -EINVAL;
>> +
>> +    ndev = alloc_etherdev_mq(sizeof(*emac), num_tx_chn);
>> +    if (!ndev)
>> +        return -ENOMEM;
>> +
>> +    emac = netdev_priv(ndev);
>> +    prueth->emac[mac] = emac;
>> +    emac->prueth = prueth;
>> +    emac->ndev = ndev;
>> +    emac->port_id = port;
>> +    emac->cmd_wq = create_singlethread_workqueue("icssg_cmd_wq");
>> +    if (!emac->cmd_wq) {
>> +        ret = -ENOMEM;
>> +        goto free_ndev;
>> +    }
>> +    INIT_WORK(&emac->rx_mode_work, emac_ndo_set_rx_mode_work);
>> +
>> +    ret = pruss_request_mem_region(prueth->pruss,
>> +                       port == PRUETH_PORT_MII0 ?
>> +                       PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1,
>> +                       &emac->dram);
>> +    if (ret) {
>> +        dev_err(prueth->dev, "unable to get DRAM: %d\n", ret);
>> +        return -ENOMEM;
> 
> goto free_wq; ?
> 

I'll add it.

>> +    }
>> +
>> +    emac->tx_ch_num = 1;
>> +
>> +    SET_NETDEV_DEV(ndev, prueth->dev);
>> +    spin_lock_init(&emac->lock);
>> +    mutex_init(&emac->cmd_lock);
>> +
>> +    emac->phy_node = of_parse_phandle(eth_node, "phy-handle", 0);
>> +    if (!emac->phy_node && !of_phy_is_fixed_link(eth_node)) {
>> +        dev_err(prueth->dev, "couldn't find phy-handle\n");
>> +        ret = -ENODEV;
>> +        goto free;
>> +    } else if (of_phy_is_fixed_link(eth_node)) {
>> +        ret = of_phy_register_fixed_link(eth_node);
>> +        if (ret) {
>> +            ret = dev_err_probe(prueth->dev, ret,
>> +                        "failed to register fixed-link phy\n");
>> +            goto free;
>> +        }
>> +
>> +        emac->phy_node = eth_node;
>> +    }
>> +
>> +    ret = of_get_phy_mode(eth_node, &emac->phy_if);
>> +    if (ret) {
>> +        dev_err(prueth->dev, "could not get phy-mode property\n");
>> +        goto free;
>> +    }
>> +
>> +    if (emac->phy_if != PHY_INTERFACE_MODE_MII &&
>> +        !phy_interface_mode_is_rgmii(emac->phy_if)) {
>> +        dev_err(prueth->dev, "PHY mode unsupported %s\n",
>> phy_modes(emac->phy_if));
>> +        goto free;
>> +    }
>> +
>> +    ret = prueth_config_rgmiidelay(prueth, eth_node, emac->phy_if);
>> +    if (ret)
>> +        goto free;
>> +
>> +    /* get mac address from DT and set private and netdev addr */
>> +    ret = of_get_ethdev_address(eth_node, ndev);
>> +    if (!is_valid_ether_addr(ndev->dev_addr)) {
>> +        eth_hw_addr_random(ndev);
>> +        dev_warn(prueth->dev, "port %d: using random MAC addr: %pM\n",
>> +             port, ndev->dev_addr);
>> +    }
>> +    ether_addr_copy(emac->mac_addr, ndev->dev_addr);
>> +
>> +    ndev->netdev_ops = &emac_netdev_ops;
>> +    ndev->ethtool_ops = &icssg_ethtool_ops;
>> +    ndev->hw_features = NETIF_F_SG;
>> +    ndev->features = ndev->hw_features;
>> +
>> +    netif_napi_add(ndev, &emac->napi_rx,
>> +               emac_napi_rx_poll, NAPI_POLL_WEIGHT);
>> +
>> +    return 0;
>> +
>> +free:
>> +    pruss_release_mem_region(prueth->pruss, &emac->dram);
> 
> free_wq:
> 

From what I understand, the labels would look like this.

free:
	pruss_release_mem_region(prueth->pruss, &emac->dram);
	destroy_workqueue(emac->cmd_wq);
free_wq:
	destroy_workqueue(emac->cmd_wq);

>> +    destroy_workqueue(emac->cmd_wq);
>> +free_ndev:
>> +    free_netdev(ndev);
>> +    prueth->emac[mac] = NULL;
>> +
>> +    return ret;
>> +}
>> +
>> +static void prueth_netdev_exit(struct prueth *prueth,
>> +                   struct device_node *eth_node)
>> +{
>> +    struct prueth_emac *emac;
>> +    enum prueth_mac mac;
>> +
>> +    mac = prueth_node_mac(eth_node);
>> +    if (mac < 0)
>> +        return;
>> +
>> +    emac = prueth->emac[mac];
>> +    if (!emac)
>> +        return;
>> +
>> +    if (of_phy_is_fixed_link(emac->phy_node))
>> +        of_phy_deregister_fixed_link(emac->phy_node);
>> +
>> +    netif_napi_del(&emac->napi_rx);
>> +
>> +    pruss_release_mem_region(prueth->pruss, &emac->dram);
>> +    destroy_workqueue(emac->cmd_wq);
>> +    free_netdev(emac->ndev);
>> +    prueth->emac[mac] = NULL;
>> +}
>> +
>> +static int prueth_get_cores(struct prueth *prueth, int slice)
>> +{
>> +    enum pruss_pru_id pruss_id;
>> +    struct device *dev = prueth->dev;
>> +    struct device_node *np = dev->of_node;
>> +    int idx = -1, ret;
>> +
>> +    switch (slice) {
>> +    case ICSS_SLICE0:
>> +        idx = 0;
>> +        break;
>> +    case ICSS_SLICE1:
>> +        idx = 3;
>> +        break;
>> +    default:
>> +        return -EINVAL;
>> +    }
>> +
>> +    prueth->pru[slice] = pru_rproc_get(np, idx, &pruss_id);
>> +    if (IS_ERR(prueth->pru[slice])) {
>> +        ret = PTR_ERR(prueth->pru[slice]);
>> +        prueth->pru[slice] = NULL;
>> +        if (ret != -EPROBE_DEFER)
>> +            dev_err(dev, "unable to get PRU%d: %d\n", slice, ret);
> 
> return dev_err_probe()?
> 

Sure I'll return dev_err_probe() instead of the above.

I'll add below line
return dev_err_probe(dev,ret,"unable to get PRU%d\n", slice);

>> +        return ret;
>> +    }
>> +    prueth->pru_id[slice] = pruss_id;
>> +
>> +    idx++;
>> +    prueth->rtu[slice] = pru_rproc_get(np, idx, NULL);
>> +    if (IS_ERR(prueth->rtu[slice])) {
>> +        ret = PTR_ERR(prueth->rtu[slice]);
>> +        prueth->rtu[slice] = NULL;
>> +        if (ret != -EPROBE_DEFER)
>> +            dev_err(dev, "unable to get RTU%d: %d\n", slice, ret);
> 
> Same.
> 

Sure, I'll do that.

>> +        return ret;
>> +    }
>> +
>> +    idx++;
>> +    prueth->txpru[slice] = pru_rproc_get(np, idx, NULL);
>> +    if (IS_ERR(prueth->txpru[slice])) {
>> +        ret = PTR_ERR(prueth->txpru[slice]);
>> +        prueth->txpru[slice] = NULL;
>> +        if (ret != -EPROBE_DEFER)
>> +            dev_err(dev, "unable to get TX_PRU%d: %d\n",
>> +                slice, ret);
> 
> Same.
> 

Sure, I'll do that.

>> +        return ret;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static void prueth_put_cores(struct prueth *prueth, int slice)
>> +{
>> +    if (prueth->txpru[slice])
>> +        pru_rproc_put(prueth->txpru[slice]);
>> +
>> +    if (prueth->rtu[slice])
>> +        pru_rproc_put(prueth->rtu[slice]);
>> +
>> +    if (prueth->pru[slice])
>> +        pru_rproc_put(prueth->pru[slice]);
>> +}
>> +
>> +static const struct of_device_id prueth_dt_match[];
>> +
>> +static int prueth_probe(struct platform_device *pdev)
>> +{
>> +    struct prueth *prueth;
>> +    struct device *dev = &pdev->dev;
>> +    struct device_node *np = dev->of_node;
>> +    struct device_node *eth_ports_node;
>> +    struct device_node *eth_node;
>> +    struct device_node *eth0_node, *eth1_node;
>> +    const struct of_device_id *match;
>> +    struct pruss *pruss;
>> +    int i, ret;
>> +    u32 msmc_ram_size;
>> +    struct genpool_data_align gp_data = {
>> +        .align = SZ_64K,
>> +    };
>> +
>> +    match = of_match_device(prueth_dt_match, dev);
>> +    if (!match)
>> +        return -ENODEV;
>> +
>> +    prueth = devm_kzalloc(dev, sizeof(*prueth), GFP_KERNEL);
>> +    if (!prueth)
>> +        return -ENOMEM;
>> +
>> +    dev_set_drvdata(dev, prueth);
>> +    prueth->pdev = pdev;
>> +    prueth->pdata = *(const struct prueth_pdata *)match->data;
>> +
>> +    prueth->dev = dev;
>> +    eth_ports_node = of_get_child_by_name(np, "ethernet-ports");
>> +    if (!eth_ports_node)
>> +        return -ENOENT;
>> +
>> +    for_each_child_of_node(eth_ports_node, eth_node) {
>> +        u32 reg;
>> +
>> +        if (strcmp(eth_node->name, "port"))
>> +            continue;
>> +        ret = of_property_read_u32(eth_node, "reg", &reg);
>> +        if (ret < 0) {
>> +            dev_err(dev, "%pOF error reading port_id %d\n",
>> +                eth_node, ret);
>> +        }
>> +
>> +        of_node_get(eth_node);
>> +
>> +        if (reg == 0)
>> +            eth0_node = eth_node;
>> +        else if (reg == 1)
>> +            eth1_node = eth_node;
>> +        else
>> +            dev_err(dev, "port reg should be 0 or 1\n");
>> +    }
>> +
>> +    of_node_put(eth_ports_node);
>> +
>> +    /* At least one node must be present and available else we fail */
>> +    if (!eth0_node && !eth1_node) {
>> +        dev_err(dev, "neither port0 nor port1 node available\n");
>> +        return -ENODEV;
>> +    }
>> +
>> +    if (eth0_node == eth1_node) {
>> +        dev_err(dev, "port0 and port1 can't have same reg\n");
>> +        of_node_put(eth0_node);
>> +        return -ENODEV;
>> +    }
>> +
>> +    prueth->eth_node[PRUETH_MAC0] = eth0_node;
>> +    prueth->eth_node[PRUETH_MAC1] = eth1_node;
>> +
>> +    prueth->miig_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-g-rt");
>> +    if (IS_ERR(prueth->miig_rt)) {
>> +        dev_err(dev, "couldn't get ti,mii-g-rt syscon regmap\n");
>> +        return -ENODEV;
>> +    }
>> +
>> +    prueth->mii_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-rt");
>> +    if (IS_ERR(prueth->mii_rt)) {
>> +        dev_err(dev, "couldn't get ti,mii-rt syscon regmap\n");
>> +        return -ENODEV;
>> +    }
>> +
>> +    if (eth0_node) {
>> +        ret = prueth_get_cores(prueth, ICSS_SLICE0);
>> +        if (ret)
>> +            goto put_cores;
>> +    }
>> +
>> +    if (eth1_node) {
>> +        ret = prueth_get_cores(prueth, ICSS_SLICE1);
>> +        if (ret)
>> +            goto put_cores;
>> +    }
>> +
>> +    pruss = pruss_get(eth0_node ?
>> +              prueth->pru[ICSS_SLICE0] : prueth->pru[ICSS_SLICE1]);
>> +    if (IS_ERR(pruss)) {
>> +        ret = PTR_ERR(pruss);
>> +        dev_err(dev, "unable to get pruss handle\n");
>> +        goto put_cores;
>> +    }
>> +
>> +    prueth->pruss = pruss;
>> +
>> +    ret = pruss_request_mem_region(pruss, PRUSS_MEM_SHRD_RAM2,
>> +                       &prueth->shram);
>> +    if (ret) {
>> +        dev_err(dev, "unable to get PRUSS SHRD RAM2: %d\n", ret);
>> +        goto put_mem;
> 
> Is it safe to call pruss_release_mem_region() if pruss_request_mem_region() has
> failed?
> 

There is no need to call pruss_release_mem_region() if
pruss_request_mem_region() has failed.

The label put_mem, calls pruss_release_mem_region() and pruss_put().

Here instead of going to label and calling both the functions, I will just call
pruss_put() function.

So the if condition would be something like this.

if (ret) {
    dev_err(dev, "unable to get PRUSS SHRD RAM2: %d\n", ret);
    pruss_put(prueth->pruss);
}

> The other place where it is called it is not done the same way.
> 

>> +    }
>> +
>> +    prueth->sram_pool = of_gen_pool_get(np, "sram", 0);
>> +    if (!prueth->sram_pool) {
>> +        dev_err(dev, "unable to get SRAM pool\n");
>> +        ret = -ENODEV;
>> +
>> +        goto put_mem;
>> +    }
>> +
>> +    msmc_ram_size = MSMC_RAM_SIZE;
>> +
>> +    /* NOTE: FW bug needs buffer base to be 64KB aligned */
>> +    prueth->msmcram.va =
>> +        (void __iomem *)gen_pool_alloc_algo(prueth->sram_pool,
>> +                            msmc_ram_size,
>> +                            gen_pool_first_fit_align,
>> +                            &gp_data);
>> +
>> +    if (!prueth->msmcram.va) {
>> +        ret = -ENOMEM;
>> +        dev_err(dev, "unable to allocate MSMC resource\n");
>> +        goto put_mem;
>> +    }
>> +    prueth->msmcram.pa = gen_pool_virt_to_phys(prueth->sram_pool,
>> +                           (unsigned long)prueth->msmcram.va);
>> +    prueth->msmcram.size = msmc_ram_size;
>> +    memset(prueth->msmcram.va, 0, msmc_ram_size);
>> +    dev_dbg(dev, "sram: pa %llx va %p size %zx\n", prueth->msmcram.pa,
>> +        prueth->msmcram.va, prueth->msmcram.size);
>> +
>> +    /* setup netdev interfaces */
>> +    if (eth0_node) {
>> +        ret = prueth_netdev_init(prueth, eth0_node);
>> +        if (ret) {
>> +            if (ret != -EPROBE_DEFER) {
>> +                dev_err(dev, "netdev init %s failed: %d\n",
>> +                    eth0_node->name, ret);
> 
> dev_err_probe()?
> 

Sure, I'll do that.

>> +            }
>> +            goto netdev_exit;
>> +        }
>> +    }
>> +
>> +    if (eth1_node) {
>> +        ret = prueth_netdev_init(prueth, eth1_node);
>> +        if (ret) {
>> +            if (ret != -EPROBE_DEFER) {
>> +                dev_err(dev, "netdev init %s failed: %d\n",
>> +                    eth1_node->name, ret);
> 
> dev_err_probe()?
> 

Sure, I'll do that.

>> +            }
>> +            goto netdev_exit;
>> +        }
>> +    }
>> +
>> +    /* register the network devices */
>> +    if (eth0_node) {
>> +        ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev);
>> +        if (ret) {
>> +            dev_err(dev, "can't register netdev for port MII0");
>> +            goto netdev_exit;
>> +        }
>> +
>> +        prueth->registered_netdevs[PRUETH_MAC0] =
>> prueth->emac[PRUETH_MAC0]->ndev;
>> +
>> +        emac_phy_connect(prueth->emac[PRUETH_MAC0]);
>> +        phy_attached_info(prueth->emac[PRUETH_MAC0]->ndev->phydev);
>> +    }
>> +
>> +    if (eth1_node) {
>> +        ret = register_netdev(prueth->emac[PRUETH_MAC1]->ndev);
>> +        if (ret) {
>> +            dev_err(dev, "can't register netdev for port MII1");
>> +            goto netdev_unregister;
>> +        }
>> +
>> +        prueth->registered_netdevs[PRUETH_MAC1] =
>> prueth->emac[PRUETH_MAC1]->ndev;
>> +        emac_phy_connect(prueth->emac[PRUETH_MAC1]);
>> +        phy_attached_info(prueth->emac[PRUETH_MAC1]->ndev->phydev);
>> +    }
>> +
>> +    dev_info(dev, "TI PRU ethernet driver initialized: %s EMAC mode\n",
>> +         (!eth0_node || !eth1_node) ? "single" : "dual");
>> +
>> +    if (eth1_node)
>> +        of_node_put(eth1_node);
>> +    if (eth0_node)
>> +        of_node_put(eth0_node);
>> +    return 0;
>> +
>> +netdev_unregister:
>> +    for (i = 0; i < PRUETH_NUM_MACS; i++) {
>> +        if (!prueth->registered_netdevs[i])
>> +            continue;
>> +        if (prueth->emac[i]->ndev->phydev) {
>> +            phy_disconnect(prueth->emac[i]->ndev->phydev);
>> +            prueth->emac[i]->ndev->phydev = NULL;
>> +        }
>> +        unregister_netdev(prueth->registered_netdevs[i]);
>> +    }
>> +
>> +netdev_exit:
>> +    for (i = 0; i < PRUETH_NUM_MACS; i++) {
>> +        struct device_node *eth_node;
>> +
>> +        eth_node = prueth->eth_node[i];
>> +        if (!eth_node)
>> +            continue;
>> +
>> +        prueth_netdev_exit(prueth, eth_node);
>> +    }
>> +
>> +gen_pool_free(prueth->sram_pool,
> 
> 1 tab missing.
> 

I'll indent it properly.

>> +          (unsigned long)prueth->msmcram.va, msmc_ram_size);
>> +
>> +put_mem:
>> +    pruss_release_mem_region(prueth->pruss, &prueth->shram);
>> +    pruss_put(prueth->pruss);
>> +
>> +put_cores:
>> +    if (eth1_node) {
>> +        prueth_put_cores(prueth, ICSS_SLICE1);
>> +        of_node_put(eth1_node);
>> +    }
>> +
>> +    if (eth0_node) {
>> +        prueth_put_cores(prueth, ICSS_SLICE0);
>> +        of_node_put(eth0_node);
>> +    }
>> +
>> +    return ret;
>> +}
> 
> [...]
> 
> From mboxrd@z Thu Jan  1 00:00:00 1970
> Return-Path:
> <linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org>
> X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
>     aws-us-west-2-korg-lkml-1.web.codeaurora.org
> Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133])
>     (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
>     (No client certificate requested)
>     by smtp.lore.kernel.org (Postfix) with ESMTPS id 6F7F7C433EF
>     for <linux-arm-kernel@archiver.kernel.org>; Sun,  5 Jun 2022 16:26:16 +0000
> (UTC)
> DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
>     d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type:
>     Content-Transfer-Encoding:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
>     List-Unsubscribe:List-Id:In-Reply-To:From:References:To:Subject:MIME-Version:
>     Date:Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date:
>     Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
>     bh=retw5Noo9wQ783k5GSJUTlmswtTyoF/rMXvDugAZLvo=; b=baY/vWlpdhEu2oKoaWVX7fSMqj
>     4iEPZKhU3fIP0fSrAWvp+GuLhE+xBGCyN7T3yk2KRiseFifslrcDKLsiwIAoHXrbu3xhjHwM5i5xT
>     N49Lq2ZnbXYPGUbm4JYJHjsVG+tHHTBzQRVlaY8lL97uSMGXjRfSgSfmjo5rLqzH+ejKHJDTTV5o5
>     Q86XVtFhutGBmY43N6lCef3dFCMXBtE4TkEFyoVxxt6kajelMNTwKeyVvjK4bu7SYSZUS7pcZQliy
>     oCVKL3fv5fSl/FMx/ju+BbQqWgMPohrLA+ENbjwio6icS1DL1t6W223iT27SebgyqR++YMYBp2Nyn
>     5BtT9Ajw==;
> Received: from localhost ([::1] helo=bombadil.infradead.org)
>     by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux))
>     id 1nxt3j-00Evbq-3A; Sun, 05 Jun 2022 16:24:59 +0000
> Received: from smtp05.smtpout.orange.fr ([80.12.242.127]
> helo=smtp.smtpout.orange.fr)
>     by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))
>     id 1nxt3e-00EvY2-57
>     for linux-arm-kernel@lists.infradead.org; Sun, 05 Jun 2022 16:24:57 +0000
> Received: from [192.168.1.18] ([90.11.190.129])
>     by smtp.orange.fr with ESMTPA
>     id xt3OnV5YAE80Kxt3OnoLAV; Sun, 05 Jun 2022 18:24:45 +0200
> X-ME-Helo: [192.168.1.18]
> X-ME-Auth:
> YWZlNiIxYWMyZDliZWIzOTcwYTEyYzlhMmU3ZiQ1M2U2MzfzZDfyZTMxZTBkMTYyNDBjNDJlZmQ3ZQ==
> X-ME-Date: Sun, 05 Jun 2022 18:24:45 +0200
> X-ME-IP: 90.11.190.129
> Message-ID: <3874cac9-cf3c-aa31-ecba-e2ae33935286@wanadoo.fr>
> Date: Sun, 5 Jun 2022 18:24:37 +0200
> MIME-Version: 1.0
> User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101
> Thunderbird/91.9.1
> Subject: Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
> Content-Language: fr
> To: p-mohan@ti.com
> References: <20220531095108.21757-1-p-mohan@ti.com>
> <20220531095108.21757-3-p-mohan@ti.com>
> From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
> In-Reply-To: <20220531095108.21757-3-p-mohan@ti.com>
> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3
> X-CRM114-CacheID: sfid-20220605_092454_526921_B7623337 X-CRM114-Status: GOOD ( 
> 26.10  )
> X-BeenThere: linux-arm-kernel@lists.infradead.org
> X-Mailman-Version: 2.1.34
> Precedence: list
> List-Id: <linux-arm-kernel.lists.infradead.org>
> List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-arm-kernel>,
> <mailto:linux-arm-kernel-request@lists.infradead.org?subject=unsubscribe>
> List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
> List-Post: <mailto:linux-arm-kernel@lists.infradead.org>
> List-Help: <mailto:linux-arm-kernel-request@lists.infradead.org?subject=help>
> List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>,
> <mailto:linux-arm-kernel-request@lists.infradead.org?subject=subscribe>
> Cc: nm@ti.com, andrew@lunn.ch, grygorii.strashko@ti.com, vigneshr@ti.com,
> devicetree@vger.kernel.org, netdev@vger.kernel.org,
> linux-kernel@vger.kernel.org, afd@ti.com, rogerq@kernel.org,
> edumazet@google.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org,
> ssantosh@kernel.org, kishon@ti.com, davem@davemloft.net,
> linux-arm-kernel@lists.infradead.org
> Content-Transfer-Encoding: base64
> Content-Type: text/plain; charset="utf-8"; Format="flowed"
> Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
> Errors-To:
> linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org
> 
> SGksCgpKdXN0IGEgZmV3IGNvbW1lbnRzIGJlbG93LCBmb3Igd2hhdCB0aGV5IHdvcnRoLgoKTGUg
> MzEvMDUvMjAyMiDDoCAxMTo1MSwgUHVyYW5qYXkgTW9oYW4gYSDDqWNyaXTCoDoKPiBGcm9tOiBS
> b2dlciBRdWFkcm9zIDxyb2dlcnEtbDBjeU1yb2luSTBAcHVibGljLmdtYW5lLm9yZz4KPiAKPiBU
> aGlzIGlzIHRoZSBFdGhlcm5ldCBkcml2ZXIgZm9yIFRJIEFNNjU0IFNpbGljb24gcmV2LiAyCj4g
> d2l0aCB0aGUgSUNTU0cgUFJVIFN1Yi1zeXN0ZW0gcnVubmluZyBkdWFsLUVNQUMgZmlybXdhcmUu
> Cj4gCgpbLi4uXQoKPiArc3RhdGljIGludCBwcnVldGhfbmV0ZGV2X2luaXQoc3RydWN0IHBydWV0
> aCAqcHJ1ZXRoLAo+ICsJCQkgICAgICBzdHJ1Y3QgZGV2aWNlX25vZGUgKmV0aF9ub2RlKQo+ICt7
> Cj4gKwlpbnQgcmV0LCBudW1fdHhfY2huID0gUFJVRVRIX01BWF9UWF9RVUVVRVM7Cj4gKwlzdHJ1
> Y3QgcHJ1ZXRoX2VtYWMgKmVtYWM7Cj4gKwlzdHJ1Y3QgbmV0X2RldmljZSAqbmRldjsKPiArCWVu
> dW0gcHJ1ZXRoX3BvcnQgcG9ydDsKPiArCWVudW0gcHJ1ZXRoX21hYyBtYWM7Cj4gKwo+ICsJcG9y
> dCA9IHBydWV0aF9ub2RlX3BvcnQoZXRoX25vZGUpOwo+ICsJaWYgKHBvcnQgPCAwKQo+ICsJCXJl
> dHVybiAtRUlOVkFMOwo+ICsKPiArCW1hYyA9IHBydWV0aF9ub2RlX21hYyhldGhfbm9kZSk7Cj4g
> KwlpZiAobWFjIDwgMCkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwluZGV2ID0gYWxsb2Nf
> ZXRoZXJkZXZfbXEoc2l6ZW9mKCplbWFjKSwgbnVtX3R4X2Nobik7Cj4gKwlpZiAoIW5kZXYpCj4g
> KwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJZW1hYyA9IG5ldGRldl9wcml2KG5kZXYpOwo+ICsJ
> cHJ1ZXRoLT5lbWFjW21hY10gPSBlbWFjOwo+ICsJZW1hYy0+cHJ1ZXRoID0gcHJ1ZXRoOwo+ICsJ
> ZW1hYy0+bmRldiA9IG5kZXY7Cj4gKwllbWFjLT5wb3J0X2lkID0gcG9ydDsKPiArCWVtYWMtPmNt
> ZF93cSA9IGNyZWF0ZV9zaW5nbGV0aHJlYWRfd29ya3F1ZXVlKCJpY3NzZ19jbWRfd3EiKTsKPiAr
> CWlmICghZW1hYy0+Y21kX3dxKSB7Cj4gKwkJcmV0ID0gLUVOT01FTTsKPiArCQlnb3RvIGZyZWVf
> bmRldjsKPiArCX0KPiArCUlOSVRfV09SSygmZW1hYy0+cnhfbW9kZV93b3JrLCBlbWFjX25kb19z
> ZXRfcnhfbW9kZV93b3JrKTsKPiArCj4gKwlyZXQgPSBwcnVzc19yZXF1ZXN0X21lbV9yZWdpb24o
> cHJ1ZXRoLT5wcnVzcywKPiArCQkJCSAgICAgICBwb3J0ID09IFBSVUVUSF9QT1JUX01JSTAgPwo+
> ICsJCQkJICAgICAgIFBSVVNTX01FTV9EUkFNMCA6IFBSVVNTX01FTV9EUkFNMSwKPiArCQkJCSAg
> ICAgICAmZW1hYy0+ZHJhbSk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJZGV2X2VycihwcnVldGgtPmRl
> diwgInVuYWJsZSB0byBnZXQgRFJBTTogJWRcbiIsIHJldCk7Cj4gKwkJcmV0dXJuIC1FTk9NRU07
> Cgpnb3RvIGZyZWVfd3E7ID8KCj4gKwl9Cj4gKwo+ICsJZW1hYy0+dHhfY2hfbnVtID0gMTsKPiAr
> Cj4gKwlTRVRfTkVUREVWX0RFVihuZGV2LCBwcnVldGgtPmRldik7Cj4gKwlzcGluX2xvY2tfaW5p
> dCgmZW1hYy0+bG9jayk7Cj4gKwltdXRleF9pbml0KCZlbWFjLT5jbWRfbG9jayk7Cj4gKwo+ICsJ
> ZW1hYy0+cGh5X25vZGUgPSBvZl9wYXJzZV9waGFuZGxlKGV0aF9ub2RlLCAicGh5LWhhbmRsZSIs
> IDApOwo+ICsJaWYgKCFlbWFjLT5waHlfbm9kZSAmJiAhb2ZfcGh5X2lzX2ZpeGVkX2xpbmsoZXRo
> X25vZGUpKSB7Cj4gKwkJZGV2X2VycihwcnVldGgtPmRldiwgImNvdWxkbid0IGZpbmQgcGh5LWhh
> bmRsZVxuIik7Cj4gKwkJcmV0ID0gLUVOT0RFVjsKPiArCQlnb3RvIGZyZWU7Cj4gKwl9IGVsc2Ug
> aWYgKG9mX3BoeV9pc19maXhlZF9saW5rKGV0aF9ub2RlKSkgewo+ICsJCXJldCA9IG9mX3BoeV9y
> ZWdpc3Rlcl9maXhlZF9saW5rKGV0aF9ub2RlKTsKPiArCQlpZiAocmV0KSB7Cj4gKwkJCXJldCA9
> IGRldl9lcnJfcHJvYmUocHJ1ZXRoLT5kZXYsIHJldCwKPiArCQkJCQkgICAgImZhaWxlZCB0byBy
> ZWdpc3RlciBmaXhlZC1saW5rIHBoeVxuIik7Cj4gKwkJCWdvdG8gZnJlZTsKPiArCQl9Cj4gKwo+
> ICsJCWVtYWMtPnBoeV9ub2RlID0gZXRoX25vZGU7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gb2ZfZ2V0
> X3BoeV9tb2RlKGV0aF9ub2RlLCAmZW1hYy0+cGh5X2lmKTsKPiArCWlmIChyZXQpIHsKPiArCQlk
> ZXZfZXJyKHBydWV0aC0+ZGV2LCAiY291bGQgbm90IGdldCBwaHktbW9kZSBwcm9wZXJ0eVxuIik7
> Cj4gKwkJZ290byBmcmVlOwo+ICsJfQo+ICsKPiArCWlmIChlbWFjLT5waHlfaWYgIT0gUEhZX0lO
> VEVSRkFDRV9NT0RFX01JSSAmJgo+ICsJICAgICFwaHlfaW50ZXJmYWNlX21vZGVfaXNfcmdtaWko
> ZW1hYy0+cGh5X2lmKSkgewo+ICsJCWRldl9lcnIocHJ1ZXRoLT5kZXYsICJQSFkgbW9kZSB1bnN1
> cHBvcnRlZCAlc1xuIiwgcGh5X21vZGVzKGVtYWMtPnBoeV9pZikpOwo+ICsJCWdvdG8gZnJlZTsK
> PiArCX0KPiArCj4gKwlyZXQgPSBwcnVldGhfY29uZmlnX3JnbWlpZGVsYXkocHJ1ZXRoLCBldGhf
> bm9kZSwgZW1hYy0+cGh5X2lmKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBmcmVlOwo+ICsKPiAr
> CS8qIGdldCBtYWMgYWRkcmVzcyBmcm9tIERUIGFuZCBzZXQgcHJpdmF0ZSBhbmQgbmV0ZGV2IGFk
> ZHIgKi8KPiArCXJldCA9IG9mX2dldF9ldGhkZXZfYWRkcmVzcyhldGhfbm9kZSwgbmRldik7Cj4g
> KwlpZiAoIWlzX3ZhbGlkX2V0aGVyX2FkZHIobmRldi0+ZGV2X2FkZHIpKSB7Cj4gKwkJZXRoX2h3
> X2FkZHJfcmFuZG9tKG5kZXYpOwo+ICsJCWRldl93YXJuKHBydWV0aC0+ZGV2LCAicG9ydCAlZDog
> dXNpbmcgcmFuZG9tIE1BQyBhZGRyOiAlcE1cbiIsCj4gKwkJCSBwb3J0LCBuZGV2LT5kZXZfYWRk
> cik7Cj4gKwl9Cj4gKwlldGhlcl9hZGRyX2NvcHkoZW1hYy0+bWFjX2FkZHIsIG5kZXYtPmRldl9h
> ZGRyKTsKPiArCj4gKwluZGV2LT5uZXRkZXZfb3BzID0gJmVtYWNfbmV0ZGV2X29wczsKPiArCW5k
> ZXYtPmV0aHRvb2xfb3BzID0gJmljc3NnX2V0aHRvb2xfb3BzOwo+ICsJbmRldi0+aHdfZmVhdHVy
> ZXMgPSBORVRJRl9GX1NHOwo+ICsJbmRldi0+ZmVhdHVyZXMgPSBuZGV2LT5od19mZWF0dXJlczsK
> PiArCj4gKwluZXRpZl9uYXBpX2FkZChuZGV2LCAmZW1hYy0+bmFwaV9yeCwKPiArCQkgICAgICAg
> ZW1hY19uYXBpX3J4X3BvbGwsIE5BUElfUE9MTF9XRUlHSFQpOwo+ICsKPiArCXJldHVybiAwOwo+
> ICsKPiArZnJlZToKPiArCXBydXNzX3JlbGVhc2VfbWVtX3JlZ2lvbihwcnVldGgtPnBydXNzLCAm
> ZW1hYy0+ZHJhbSk7CgpmcmVlX3dxOgoKPiArCWRlc3Ryb3lfd29ya3F1ZXVlKGVtYWMtPmNtZF93
> cSk7Cj4gK2ZyZWVfbmRldjoKPiArCWZyZWVfbmV0ZGV2KG5kZXYpOwo+ICsJcHJ1ZXRoLT5lbWFj
> W21hY10gPSBOVUxMOwo+ICsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lk
> IHBydWV0aF9uZXRkZXZfZXhpdChzdHJ1Y3QgcHJ1ZXRoICpwcnVldGgsCj4gKwkJCSAgICAgICBz
> dHJ1Y3QgZGV2aWNlX25vZGUgKmV0aF9ub2RlKQo+ICt7Cj4gKwlzdHJ1Y3QgcHJ1ZXRoX2VtYWMg
> KmVtYWM7Cj4gKwllbnVtIHBydWV0aF9tYWMgbWFjOwo+ICsKPiArCW1hYyA9IHBydWV0aF9ub2Rl
> X21hYyhldGhfbm9kZSk7Cj4gKwlpZiAobWFjIDwgMCkKPiArCQlyZXR1cm47Cj4gKwo+ICsJZW1h
> YyA9IHBydWV0aC0+ZW1hY1ttYWNdOwo+ICsJaWYgKCFlbWFjKQo+ICsJCXJldHVybjsKPiArCj4g
> KwlpZiAob2ZfcGh5X2lzX2ZpeGVkX2xpbmsoZW1hYy0+cGh5X25vZGUpKQo+ICsJCW9mX3BoeV9k
> ZXJlZ2lzdGVyX2ZpeGVkX2xpbmsoZW1hYy0+cGh5X25vZGUpOwo+ICsKPiArCW5ldGlmX25hcGlf
> ZGVsKCZlbWFjLT5uYXBpX3J4KTsKPiArCj4gKwlwcnVzc19yZWxlYXNlX21lbV9yZWdpb24ocHJ1
> ZXRoLT5wcnVzcywgJmVtYWMtPmRyYW0pOwo+ICsJZGVzdHJveV93b3JrcXVldWUoZW1hYy0+Y21k
> X3dxKTsKPiArCWZyZWVfbmV0ZGV2KGVtYWMtPm5kZXYpOwo+ICsJcHJ1ZXRoLT5lbWFjW21hY10g
> PSBOVUxMOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHBydWV0aF9nZXRfY29yZXMoc3RydWN0IHBy
> dWV0aCAqcHJ1ZXRoLCBpbnQgc2xpY2UpCj4gK3sKPiArCWVudW0gcHJ1c3NfcHJ1X2lkIHBydXNz
> X2lkOwo+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gcHJ1ZXRoLT5kZXY7Cj4gKwlzdHJ1Y3QgZGV2
> aWNlX25vZGUgKm5wID0gZGV2LT5vZl9ub2RlOwo+ICsJaW50IGlkeCA9IC0xLCByZXQ7Cj4gKwo+
> ICsJc3dpdGNoIChzbGljZSkgewo+ICsJY2FzZSBJQ1NTX1NMSUNFMDoKPiArCQlpZHggPSAwOwo+
> ICsJCWJyZWFrOwo+ICsJY2FzZSBJQ1NTX1NMSUNFMToKPiArCQlpZHggPSAzOwo+ICsJCWJyZWFr
> Owo+ICsJZGVmYXVsdDoKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCX0KPiArCj4gKwlwcnVldGgt
> PnBydVtzbGljZV0gPSBwcnVfcnByb2NfZ2V0KG5wLCBpZHgsICZwcnVzc19pZCk7Cj4gKwlpZiAo
> SVNfRVJSKHBydWV0aC0+cHJ1W3NsaWNlXSkpIHsKPiArCQlyZXQgPSBQVFJfRVJSKHBydWV0aC0+
> cHJ1W3NsaWNlXSk7Cj4gKwkJcHJ1ZXRoLT5wcnVbc2xpY2VdID0gTlVMTDsKPiArCQlpZiAocmV0
> ICE9IC1FUFJPQkVfREVGRVIpCj4gKwkJCWRldl9lcnIoZGV2LCAidW5hYmxlIHRvIGdldCBQUlUl
> ZDogJWRcbiIsIHNsaWNlLCByZXQpOwoKcmV0dXJuIGRldl9lcnJfcHJvYmUoKT8KCj4gKwkJcmV0
> dXJuIHJldDsKPiArCX0KPiArCXBydWV0aC0+cHJ1X2lkW3NsaWNlXSA9IHBydXNzX2lkOwo+ICsK
> PiArCWlkeCsrOwo+ICsJcHJ1ZXRoLT5ydHVbc2xpY2VdID0gcHJ1X3Jwcm9jX2dldChucCwgaWR4
> LCBOVUxMKTsKPiArCWlmIChJU19FUlIocHJ1ZXRoLT5ydHVbc2xpY2VdKSkgewo+ICsJCXJldCA9
> IFBUUl9FUlIocHJ1ZXRoLT5ydHVbc2xpY2VdKTsKPiArCQlwcnVldGgtPnJ0dVtzbGljZV0gPSBO
> VUxMOwo+ICsJCWlmIChyZXQgIT0gLUVQUk9CRV9ERUZFUikKPiArCQkJZGV2X2VycihkZXYsICJ1
> bmFibGUgdG8gZ2V0IFJUVSVkOiAlZFxuIiwgc2xpY2UsIHJldCk7CgpTYW1lLgoKPiArCQlyZXR1
> cm4gcmV0Owo+ICsJfQo+ICsKPiArCWlkeCsrOwo+ICsJcHJ1ZXRoLT50eHBydVtzbGljZV0gPSBw
> cnVfcnByb2NfZ2V0KG5wLCBpZHgsIE5VTEwpOwo+ICsJaWYgKElTX0VSUihwcnVldGgtPnR4cHJ1
> W3NsaWNlXSkpIHsKPiArCQlyZXQgPSBQVFJfRVJSKHBydWV0aC0+dHhwcnVbc2xpY2VdKTsKPiAr
> CQlwcnVldGgtPnR4cHJ1W3NsaWNlXSA9IE5VTEw7Cj4gKwkJaWYgKHJldCAhPSAtRVBST0JFX0RF
> RkVSKQo+ICsJCQlkZXZfZXJyKGRldiwgInVuYWJsZSB0byBnZXQgVFhfUFJVJWQ6ICVkXG4iLAo+
> ICsJCQkJc2xpY2UsIHJldCk7CgpTYW1lLgoKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiAr
> CXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBwcnVldGhfcHV0X2NvcmVzKHN0cnVj
> dCBwcnVldGggKnBydWV0aCwgaW50IHNsaWNlKQo+ICt7Cj4gKwlpZiAocHJ1ZXRoLT50eHBydVtz
> bGljZV0pCj4gKwkJcHJ1X3Jwcm9jX3B1dChwcnVldGgtPnR4cHJ1W3NsaWNlXSk7Cj4gKwo+ICsJ
> aWYgKHBydWV0aC0+cnR1W3NsaWNlXSkKPiArCQlwcnVfcnByb2NfcHV0KHBydWV0aC0+cnR1W3Ns
> aWNlXSk7Cj4gKwo+ICsJaWYgKHBydWV0aC0+cHJ1W3NsaWNlXSkKPiArCQlwcnVfcnByb2NfcHV0
> KHBydWV0aC0+cHJ1W3NsaWNlXSk7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2Zf
> ZGV2aWNlX2lkIHBydWV0aF9kdF9tYXRjaFtdOwo+ICsKPiArc3RhdGljIGludCBwcnVldGhfcHJv
> YmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IHBydWV0aCAq
> cHJ1ZXRoOwo+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKPiArCXN0cnVjdCBk
> ZXZpY2Vfbm9kZSAqbnAgPSBkZXYtPm9mX25vZGU7Cj4gKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKmV0
> aF9wb3J0c19ub2RlOwo+ICsJc3RydWN0IGRldmljZV9ub2RlICpldGhfbm9kZTsKPiArCXN0cnVj
> dCBkZXZpY2Vfbm9kZSAqZXRoMF9ub2RlLCAqZXRoMV9ub2RlOwo+ICsJY29uc3Qgc3RydWN0IG9m
> X2RldmljZV9pZCAqbWF0Y2g7Cj4gKwlzdHJ1Y3QgcHJ1c3MgKnBydXNzOwo+ICsJaW50IGksIHJl
> dDsKPiArCXUzMiBtc21jX3JhbV9zaXplOwo+ICsJc3RydWN0IGdlbnBvb2xfZGF0YV9hbGlnbiBn
> cF9kYXRhID0gewo+ICsJCS5hbGlnbiA9IFNaXzY0SywKPiArCX07Cj4gKwo+ICsJbWF0Y2ggPSBv
> Zl9tYXRjaF9kZXZpY2UocHJ1ZXRoX2R0X21hdGNoLCBkZXYpOwo+ICsJaWYgKCFtYXRjaCkKPiAr
> CQlyZXR1cm4gLUVOT0RFVjsKPiArCj4gKwlwcnVldGggPSBkZXZtX2t6YWxsb2MoZGV2LCBzaXpl
> b2YoKnBydWV0aCksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFwcnVldGgpCj4gKwkJcmV0dXJuIC1F
> Tk9NRU07Cj4gKwo+ICsJZGV2X3NldF9kcnZkYXRhKGRldiwgcHJ1ZXRoKTsKPiArCXBydWV0aC0+
> cGRldiA9IHBkZXY7Cj4gKwlwcnVldGgtPnBkYXRhID0gKihjb25zdCBzdHJ1Y3QgcHJ1ZXRoX3Bk
> YXRhICopbWF0Y2gtPmRhdGE7Cj4gKwo+ICsJcHJ1ZXRoLT5kZXYgPSBkZXY7Cj4gKwlldGhfcG9y
> dHNfbm9kZSA9IG9mX2dldF9jaGlsZF9ieV9uYW1lKG5wLCAiZXRoZXJuZXQtcG9ydHMiKTsKPiAr
> CWlmICghZXRoX3BvcnRzX25vZGUpCj4gKwkJcmV0dXJuIC1FTk9FTlQ7Cj4gKwo+ICsJZm9yX2Vh
> Y2hfY2hpbGRfb2Zfbm9kZShldGhfcG9ydHNfbm9kZSwgZXRoX25vZGUpIHsKPiArCQl1MzIgcmVn
> Owo+ICsKPiArCQlpZiAoc3RyY21wKGV0aF9ub2RlLT5uYW1lLCAicG9ydCIpKQo+ICsJCQljb250
> aW51ZTsKPiArCQlyZXQgPSBvZl9wcm9wZXJ0eV9yZWFkX3UzMihldGhfbm9kZSwgInJlZyIsICZy
> ZWcpOwo+ICsJCWlmIChyZXQgPCAwKSB7Cj4gKwkJCWRldl9lcnIoZGV2LCAiJXBPRiBlcnJvciBy
> ZWFkaW5nIHBvcnRfaWQgJWRcbiIsCj4gKwkJCQlldGhfbm9kZSwgcmV0KTsKPiArCQl9Cj4gKwo+
> ICsJCW9mX25vZGVfZ2V0KGV0aF9ub2RlKTsKPiArCj4gKwkJaWYgKHJlZyA9PSAwKQo+ICsJCQll
> dGgwX25vZGUgPSBldGhfbm9kZTsKPiArCQllbHNlIGlmIChyZWcgPT0gMSkKPiArCQkJZXRoMV9u
> b2RlID0gZXRoX25vZGU7Cj4gKwkJZWxzZQo+ICsJCQlkZXZfZXJyKGRldiwgInBvcnQgcmVnIHNo
> b3VsZCBiZSAwIG9yIDFcbiIpOwo+ICsJfQo+ICsKPiArCW9mX25vZGVfcHV0KGV0aF9wb3J0c19u
> b2RlKTsKPiArCj4gKwkvKiBBdCBsZWFzdCBvbmUgbm9kZSBtdXN0IGJlIHByZXNlbnQgYW5kIGF2
> YWlsYWJsZSBlbHNlIHdlIGZhaWwgKi8KPiArCWlmICghZXRoMF9ub2RlICYmICFldGgxX25vZGUp
> IHsKPiArCQlkZXZfZXJyKGRldiwgIm5laXRoZXIgcG9ydDAgbm9yIHBvcnQxIG5vZGUgYXZhaWxh
> YmxlXG4iKTsKPiArCQlyZXR1cm4gLUVOT0RFVjsKPiArCX0KPiArCj4gKwlpZiAoZXRoMF9ub2Rl
> ID09IGV0aDFfbm9kZSkgewo+ICsJCWRldl9lcnIoZGV2LCAicG9ydDAgYW5kIHBvcnQxIGNhbid0
> IGhhdmUgc2FtZSByZWdcbiIpOwo+ICsJCW9mX25vZGVfcHV0KGV0aDBfbm9kZSk7Cj4gKwkJcmV0
> dXJuIC1FTk9ERVY7Cj4gKwl9Cj4gKwo+ICsJcHJ1ZXRoLT5ldGhfbm9kZVtQUlVFVEhfTUFDMF0g
> PSBldGgwX25vZGU7Cj4gKwlwcnVldGgtPmV0aF9ub2RlW1BSVUVUSF9NQUMxXSA9IGV0aDFfbm9k
> ZTsKPiArCj4gKwlwcnVldGgtPm1paWdfcnQgPSBzeXNjb25fcmVnbWFwX2xvb2t1cF9ieV9waGFu
> ZGxlKG5wLCAidGksbWlpLWctcnQiKTsKPiArCWlmIChJU19FUlIocHJ1ZXRoLT5taWlnX3J0KSkg
> ewo+ICsJCWRldl9lcnIoZGV2LCAiY291bGRuJ3QgZ2V0IHRpLG1paS1nLXJ0IHN5c2NvbiByZWdt
> YXBcbiIpOwo+ICsJCXJldHVybiAtRU5PREVWOwo+ICsJfQo+ICsKPiArCXBydWV0aC0+bWlpX3J0
> ID0gc3lzY29uX3JlZ21hcF9sb29rdXBfYnlfcGhhbmRsZShucCwgInRpLG1paS1ydCIpOwo+ICsJ
> aWYgKElTX0VSUihwcnVldGgtPm1paV9ydCkpIHsKPiArCQlkZXZfZXJyKGRldiwgImNvdWxkbid0
> IGdldCB0aSxtaWktcnQgc3lzY29uIHJlZ21hcFxuIik7Cj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4g
> Kwl9Cj4gKwo+ICsJaWYgKGV0aDBfbm9kZSkgewo+ICsJCXJldCA9IHBydWV0aF9nZXRfY29yZXMo
> cHJ1ZXRoLCBJQ1NTX1NMSUNFMCk7Cj4gKwkJaWYgKHJldCkKPiArCQkJZ290byBwdXRfY29yZXM7
> Cj4gKwl9Cj4gKwo+ICsJaWYgKGV0aDFfbm9kZSkgewo+ICsJCXJldCA9IHBydWV0aF9nZXRfY29y
> ZXMocHJ1ZXRoLCBJQ1NTX1NMSUNFMSk7Cj4gKwkJaWYgKHJldCkKPiArCQkJZ290byBwdXRfY29y
> ZXM7Cj4gKwl9Cj4gKwo+ICsJcHJ1c3MgPSBwcnVzc19nZXQoZXRoMF9ub2RlID8KPiArCQkJICBw
> cnVldGgtPnBydVtJQ1NTX1NMSUNFMF0gOiBwcnVldGgtPnBydVtJQ1NTX1NMSUNFMV0pOwo+ICsJ
> aWYgKElTX0VSUihwcnVzcykpIHsKPiArCQlyZXQgPSBQVFJfRVJSKHBydXNzKTsKPiArCQlkZXZf
> ZXJyKGRldiwgInVuYWJsZSB0byBnZXQgcHJ1c3MgaGFuZGxlXG4iKTsKPiArCQlnb3RvIHB1dF9j
> b3JlczsKPiArCX0KPiArCj4gKwlwcnVldGgtPnBydXNzID0gcHJ1c3M7Cj4gKwo+ICsJcmV0ID0g
> cHJ1c3NfcmVxdWVzdF9tZW1fcmVnaW9uKHBydXNzLCBQUlVTU19NRU1fU0hSRF9SQU0yLAo+ICsJ
> CQkJICAgICAgICZwcnVldGgtPnNocmFtKTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKGRl
> diwgInVuYWJsZSB0byBnZXQgUFJVU1MgU0hSRCBSQU0yOiAlZFxuIiwgcmV0KTsKPiArCQlnb3Rv
> IHB1dF9tZW07CgpJcyBpdCBzYWZlIHRvIGNhbGwgcHJ1c3NfcmVsZWFzZV9tZW1fcmVnaW9uKCkg
> aWYgCnBydXNzX3JlcXVlc3RfbWVtX3JlZ2lvbigpIGhhcyBmYWlsZWQ/CgpUaGUgb3RoZXIgcGxh
> Y2Ugd2hlcmUgaXQgaXMgY2FsbGVkIGl0IGlzIG5vdCBkb25lIHRoZSBzYW1lIHdheS4KCj4gKwl9
> Cj4gKwo+ICsJcHJ1ZXRoLT5zcmFtX3Bvb2wgPSBvZl9nZW5fcG9vbF9nZXQobnAsICJzcmFtIiwg
> MCk7Cj4gKwlpZiAoIXBydWV0aC0+c3JhbV9wb29sKSB7Cj4gKwkJZGV2X2VycihkZXYsICJ1bmFi
> bGUgdG8gZ2V0IFNSQU0gcG9vbFxuIik7Cj4gKwkJcmV0ID0gLUVOT0RFVjsKPiArCj4gKwkJZ290
> byBwdXRfbWVtOwo+ICsJfQo+ICsKPiArCW1zbWNfcmFtX3NpemUgPSBNU01DX1JBTV9TSVpFOwo+
> ICsKPiArCS8qIE5PVEU6IEZXIGJ1ZyBuZWVkcyBidWZmZXIgYmFzZSB0byBiZSA2NEtCIGFsaWdu
> ZWQgKi8KPiArCXBydWV0aC0+bXNtY3JhbS52YSA9Cj4gKwkJKHZvaWQgX19pb21lbSAqKWdlbl9w
> b29sX2FsbG9jX2FsZ28ocHJ1ZXRoLT5zcmFtX3Bvb2wsCj4gKwkJCQkJCSAgICBtc21jX3JhbV9z
> aXplLAo+ICsJCQkJCQkgICAgZ2VuX3Bvb2xfZmlyc3RfZml0X2FsaWduLAo+ICsJCQkJCQkgICAg
> JmdwX2RhdGEpOwo+ICsKPiArCWlmICghcHJ1ZXRoLT5tc21jcmFtLnZhKSB7Cj4gKwkJcmV0ID0g
> LUVOT01FTTsKPiArCQlkZXZfZXJyKGRldiwgInVuYWJsZSB0byBhbGxvY2F0ZSBNU01DIHJlc291
> cmNlXG4iKTsKPiArCQlnb3RvIHB1dF9tZW07Cj4gKwl9Cj4gKwlwcnVldGgtPm1zbWNyYW0ucGEg
> PSBnZW5fcG9vbF92aXJ0X3RvX3BoeXMocHJ1ZXRoLT5zcmFtX3Bvb2wsCj4gKwkJCQkJCSAgICh1
> bnNpZ25lZCBsb25nKXBydWV0aC0+bXNtY3JhbS52YSk7Cj4gKwlwcnVldGgtPm1zbWNyYW0uc2l6
> ZSA9IG1zbWNfcmFtX3NpemU7Cj4gKwltZW1zZXQocHJ1ZXRoLT5tc21jcmFtLnZhLCAwLCBtc21j
> X3JhbV9zaXplKTsKPiArCWRldl9kYmcoZGV2LCAic3JhbTogcGEgJWxseCB2YSAlcCBzaXplICV6
> eFxuIiwgcHJ1ZXRoLT5tc21jcmFtLnBhLAo+ICsJCXBydWV0aC0+bXNtY3JhbS52YSwgcHJ1ZXRo
> LT5tc21jcmFtLnNpemUpOwo+ICsKPiArCS8qIHNldHVwIG5ldGRldiBpbnRlcmZhY2VzICovCj4g
> KwlpZiAoZXRoMF9ub2RlKSB7Cj4gKwkJcmV0ID0gcHJ1ZXRoX25ldGRldl9pbml0KHBydWV0aCwg
> ZXRoMF9ub2RlKTsKPiArCQlpZiAocmV0KSB7Cj4gKwkJCWlmIChyZXQgIT0gLUVQUk9CRV9ERUZF
> Uikgewo+ICsJCQkJZGV2X2VycihkZXYsICJuZXRkZXYgaW5pdCAlcyBmYWlsZWQ6ICVkXG4iLAo+
> ICsJCQkJCWV0aDBfbm9kZS0+bmFtZSwgcmV0KTsKCmRldl9lcnJfcHJvYmUoKT8KCj4gKwkJCX0K
> PiArCQkJZ290byBuZXRkZXZfZXhpdDsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJaWYgKGV0aDFfbm9k
> ZSkgewo+ICsJCXJldCA9IHBydWV0aF9uZXRkZXZfaW5pdChwcnVldGgsIGV0aDFfbm9kZSk7Cj4g
> KwkJaWYgKHJldCkgewo+ICsJCQlpZiAocmV0ICE9IC1FUFJPQkVfREVGRVIpIHsKPiArCQkJCWRl
> dl9lcnIoZGV2LCAibmV0ZGV2IGluaXQgJXMgZmFpbGVkOiAlZFxuIiwKPiArCQkJCQlldGgxX25v
> ZGUtPm5hbWUsIHJldCk7CgpkZXZfZXJyX3Byb2JlKCk/Cgo+ICsJCQl9Cj4gKwkJCWdvdG8gbmV0
> ZGV2X2V4aXQ7Cj4gKwkJfQo+ICsJfQo+ICsKPiArCS8qIHJlZ2lzdGVyIHRoZSBuZXR3b3JrIGRl
> dmljZXMgKi8KPiArCWlmIChldGgwX25vZGUpIHsKPiArCQlyZXQgPSByZWdpc3Rlcl9uZXRkZXYo
> cHJ1ZXRoLT5lbWFjW1BSVUVUSF9NQUMwXS0+bmRldik7Cj4gKwkJaWYgKHJldCkgewo+ICsJCQlk
> ZXZfZXJyKGRldiwgImNhbid0IHJlZ2lzdGVyIG5ldGRldiBmb3IgcG9ydCBNSUkwIik7Cj4gKwkJ
> CWdvdG8gbmV0ZGV2X2V4aXQ7Cj4gKwkJfQo+ICsKPiArCQlwcnVldGgtPnJlZ2lzdGVyZWRfbmV0
> ZGV2c1tQUlVFVEhfTUFDMF0gPSBwcnVldGgtPmVtYWNbUFJVRVRIX01BQzBdLT5uZGV2Owo+ICsK
> PiArCQllbWFjX3BoeV9jb25uZWN0KHBydWV0aC0+ZW1hY1tQUlVFVEhfTUFDMF0pOwo+ICsJCXBo
> eV9hdHRhY2hlZF9pbmZvKHBydWV0aC0+ZW1hY1tQUlVFVEhfTUFDMF0tPm5kZXYtPnBoeWRldik7
> Cj4gKwl9Cj4gKwo+ICsJaWYgKGV0aDFfbm9kZSkgewo+ICsJCXJldCA9IHJlZ2lzdGVyX25ldGRl
> dihwcnVldGgtPmVtYWNbUFJVRVRIX01BQzFdLT5uZGV2KTsKPiArCQlpZiAocmV0KSB7Cj4gKwkJ
> CWRldl9lcnIoZGV2LCAiY2FuJ3QgcmVnaXN0ZXIgbmV0ZGV2IGZvciBwb3J0IE1JSTEiKTsKPiAr
> CQkJZ290byBuZXRkZXZfdW5yZWdpc3RlcjsKPiArCQl9Cj4gKwo+ICsJCXBydWV0aC0+cmVnaXN0
> ZXJlZF9uZXRkZXZzW1BSVUVUSF9NQUMxXSA9IHBydWV0aC0+ZW1hY1tQUlVFVEhfTUFDMV0tPm5k
> ZXY7Cj4gKwkJZW1hY19waHlfY29ubmVjdChwcnVldGgtPmVtYWNbUFJVRVRIX01BQzFdKTsKPiAr
> CQlwaHlfYXR0YWNoZWRfaW5mbyhwcnVldGgtPmVtYWNbUFJVRVRIX01BQzFdLT5uZGV2LT5waHlk
> ZXYpOwo+ICsJfQo+ICsKPiArCWRldl9pbmZvKGRldiwgIlRJIFBSVSBldGhlcm5ldCBkcml2ZXIg
> aW5pdGlhbGl6ZWQ6ICVzIEVNQUMgbW9kZVxuIiwKPiArCQkgKCFldGgwX25vZGUgfHwgIWV0aDFf
> bm9kZSkgPyAic2luZ2xlIiA6ICJkdWFsIik7Cj4gKwo+ICsJaWYgKGV0aDFfbm9kZSkKPiArCQlv
> Zl9ub2RlX3B1dChldGgxX25vZGUpOwo+ICsJaWYgKGV0aDBfbm9kZSkKPiArCQlvZl9ub2RlX3B1
> dChldGgwX25vZGUpOwo+ICsJcmV0dXJuIDA7Cj4gKwo+ICtuZXRkZXZfdW5yZWdpc3RlcjoKPiAr
> CWZvciAoaSA9IDA7IGkgPCBQUlVFVEhfTlVNX01BQ1M7IGkrKykgewo+ICsJCWlmICghcHJ1ZXRo
> LT5yZWdpc3RlcmVkX25ldGRldnNbaV0pCj4gKwkJCWNvbnRpbnVlOwo+ICsJCWlmIChwcnVldGgt
> PmVtYWNbaV0tPm5kZXYtPnBoeWRldikgewo+ICsJCQlwaHlfZGlzY29ubmVjdChwcnVldGgtPmVt
> YWNbaV0tPm5kZXYtPnBoeWRldik7Cj4gKwkJCXBydWV0aC0+ZW1hY1tpXS0+bmRldi0+cGh5ZGV2
> ID0gTlVMTDsKPiArCQl9Cj4gKwkJdW5yZWdpc3Rlcl9uZXRkZXYocHJ1ZXRoLT5yZWdpc3RlcmVk
> X25ldGRldnNbaV0pOwo+ICsJfQo+ICsKPiArbmV0ZGV2X2V4aXQ6Cj4gKwlmb3IgKGkgPSAwOyBp
> IDwgUFJVRVRIX05VTV9NQUNTOyBpKyspIHsKPiArCQlzdHJ1Y3QgZGV2aWNlX25vZGUgKmV0aF9u
> b2RlOwo+ICsKPiArCQlldGhfbm9kZSA9IHBydWV0aC0+ZXRoX25vZGVbaV07Cj4gKwkJaWYgKCFl
> dGhfbm9kZSkKPiArCQkJY29udGludWU7Cj4gKwo+ICsJCXBydWV0aF9uZXRkZXZfZXhpdChwcnVl
> dGgsIGV0aF9ub2RlKTsKPiArCX0KPiArCj4gK2dlbl9wb29sX2ZyZWUocHJ1ZXRoLT5zcmFtX3Bv
> b2wsCgoxIHRhYiBtaXNzaW5nLgoKPiArCSAgICAgICh1bnNpZ25lZCBsb25nKXBydWV0aC0+bXNt
> Y3JhbS52YSwgbXNtY19yYW1fc2l6ZSk7Cj4gKwo+ICtwdXRfbWVtOgo+ICsJcHJ1c3NfcmVsZWFz
> ZV9tZW1fcmVnaW9uKHBydWV0aC0+cHJ1c3MsICZwcnVldGgtPnNocmFtKTsKPiArCXBydXNzX3B1
> dChwcnVldGgtPnBydXNzKTsKPiArCj4gK3B1dF9jb3JlczoKPiArCWlmIChldGgxX25vZGUpIHsK
> PiArCQlwcnVldGhfcHV0X2NvcmVzKHBydWV0aCwgSUNTU19TTElDRTEpOwo+ICsJCW9mX25vZGVf
> cHV0KGV0aDFfbm9kZSk7Cj4gKwl9Cj4gKwo+ICsJaWYgKGV0aDBfbm9kZSkgewo+ICsJCXBydWV0
> aF9wdXRfY29yZXMocHJ1ZXRoLCBJQ1NTX1NMSUNFMCk7Cj4gKwkJb2Zfbm9kZV9wdXQoZXRoMF9u
> b2RlKTsKPiArCX0KPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9CgpbLi4uXQoKX19fX19fX19fX19f
> X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWls
> aW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0
> cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
  2022-06-05 15:37   ` Andrew Lunn
@ 2022-11-04 10:26     ` Md Danish Anwar
  0 siblings, 0 replies; 20+ messages in thread
From: Md Danish Anwar @ 2022-11-04 10:26 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: linux-kernel, davem, edumazet, krzysztof.kozlowski+dt, netdev,
	devicetree, nm, ssantosh, s-anna, linux-arm-kernel, rogerq,
	vigneshr, robh+dt, afd

Hi Andrew,

I am Danish, new addition to TI team. Puranjay left TI, I'll be posting
upstream patches for Programmable Real-time Unit and Industrial Communication
Subsystem Gigabit (PRU_ICSSG).

On 05/06/22 21:07, Andrew Lunn wrote:
>> +static inline u32 addr_to_da0(const u8 *addr)
>> +{
>> +	return (u32)(addr[0] | addr[1] << 8 |
>> +		addr[2] << 16 | addr[3] << 24);
>> +};
>> +
>> +static inline u32 addr_to_da1(const u8 *addr)
>> +{
>> +	return (u32)(addr[4] | addr[5] << 8);
>> +};
> 
> No inline functions please.
> 

Sure I will remove the inline function.

There are total 8 instances where the above two inline functions are called.
So if I removed these inline functions there are two approaches to address the
8 instances.

1. Instead of calling these functions, I should use the return logic "(u32)
(addr[4] | addr[5] << 8);" at all the 8 instances.
2. I can define a macro for this logic and call the macro for all the 8 instances.

Please let me know which approach should I go with. Also if you have any other
approach, please let me know.

>> +
>> +static void rx_class_ft1_set_start_len(struct regmap *miig_rt, int slice,
>> +				       u16 start, u8 len)
>> +{
>> +	u32 offset, val;
>> +
>> +	offset = offs[slice].ft1_start_len;
>> +	val = FT1_LEN(len) | FT1_START(start);
>> +	regmap_write(miig_rt, offset, val);
>> +}
>> +
>> +static void rx_class_ft1_set_da(struct regmap *miig_rt, int slice,
>> +				int n, const u8 *addr)
>> +{
>> +	u32 offset;
>> +
>> +	offset = FT1_N_REG(slice, n, FT1_DA0);
>> +	regmap_write(miig_rt, offset, addr_to_da0(addr));
>> +	offset = FT1_N_REG(slice, n, FT1_DA1);
>> +	regmap_write(miig_rt, offset, addr_to_da1(addr));
>> +}
>> +
>> +static void rx_class_ft1_set_da_mask(struct regmap *miig_rt, int slice,
>> +				     int n, const u8 *addr)
>> +{
>> +	u32 offset;
>> +
>> +	offset = FT1_N_REG(slice, n, FT1_DA0_MASK);
>> +	regmap_write(miig_rt, offset, addr_to_da0(addr));
>> +	offset = FT1_N_REG(slice, n, FT1_DA1_MASK);
>> +	regmap_write(miig_rt, offset, addr_to_da1(addr));
>> +}
>> +
>> +static void rx_class_ft1_cfg_set_type(struct regmap *miig_rt, int slice, int n,
>> +				      enum ft1_cfg_type type)
>> +{
>> +	u32 offset;
>> +
>> +	offset = offs[slice].ft1_cfg;
>> +	regmap_update_bits(miig_rt, offset, FT1_CFG_MASK(n),
>> +			   type << FT1_CFG_SHIFT(n));
>> +}
>> +
>> +static void rx_class_sel_set_type(struct regmap *miig_rt, int slice, int n,
>> +				  enum rx_class_sel_type type)
>> +{
>> +	u32 offset;
>> +
>> +	offset = offs[slice].rx_class_cfg1;
>> +	regmap_update_bits(miig_rt, offset, RX_CLASS_SEL_MASK(n),
>> +			   type << RX_CLASS_SEL_SHIFT(n));
>> +}
>> +
>> +static void rx_class_set_and(struct regmap *miig_rt, int slice, int n,
>> +			     u32 data)
>> +{
>> +	u32 offset;
>> +
>> +	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_AND_EN);
>> +	regmap_write(miig_rt, offset, data);
>> +}
>> +
>> +static void rx_class_set_or(struct regmap *miig_rt, int slice, int n,
>> +			    u32 data)
>> +{
>> +	u32 offset;
>> +
>> +	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN);
>> +	regmap_write(miig_rt, offset, data);
>> +}
>> +
>> +void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac)
>> +{
>> +	regmap_write(miig_rt, MAC_INTERFACE_0, addr_to_da0(mac));
>> +	regmap_write(miig_rt, MAC_INTERFACE_1, addr_to_da1(mac));
>> +}
>> +
>> +void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac)
>> +{
>> +	regmap_write(miig_rt, offs[slice].mac0, addr_to_da0(mac));
>> +	regmap_write(miig_rt, offs[slice].mac1, addr_to_da1(mac));
>> +}
>> +
>> +/* disable all RX traffic */
>> +void icssg_class_disable(struct regmap *miig_rt, int slice)
>> +{
>> +	u32 data, offset;
>> +	int n;
>> +
>> +	/* Enable RX_L2_G */
>> +	regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_RX_L2_G_EN,
>> +			   ICSSG_CFG_RX_L2_G_EN);
>> +
>> +	for (n = 0; n < ICSSG_NUM_CLASSIFIERS; n++) {
>> +		/* AND_EN = 0 */
>> +		rx_class_set_and(miig_rt, slice, n, 0);
>> +		/* OR_EN = 0 */
>> +		rx_class_set_or(miig_rt, slice, n, 0);
>> +
>> +		/* set CFG1 to OR */
>> +		rx_class_sel_set_type(miig_rt, slice, n, RX_CLASS_SEL_TYPE_OR);
>> +
>> +		/* configure gate */
>> +		offset = RX_CLASS_GATES_N_REG(slice, n);
>> +		regmap_read(miig_rt, offset, &data);
>> +		/* clear class_raw so we go through filters */
>> +		data &= ~RX_CLASS_GATES_RAW_MASK;
>> +		/* set allow and phase mask */
>> +		data |= RX_CLASS_GATES_ALLOW_MASK | RX_CLASS_GATES_PHASE_MASK;
>> +		regmap_write(miig_rt, offset, data);
>> +	}
>> +
>> +	/* FT1 Disabled */
>> +	for (n = 0; n < ICSSG_NUM_FT1_SLOTS; n++) {
>> +		u8 addr[] = { 0, 0, 0, 0, 0, 0, };
>> +
>> +		rx_class_ft1_cfg_set_type(miig_rt, slice, n,
>> +					  FT1_CFG_TYPE_DISABLED);
>> +		rx_class_ft1_set_da(miig_rt, slice, n, addr);
>> +		rx_class_ft1_set_da_mask(miig_rt, slice, n, addr);
>> +	}
>> +
>> +	/* clear CFG2 */
>> +	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
>> +}
>> +
>> +void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti)
>> +{
>> +	int classifiers_in_use = 1;
>> +	u32 data;
>> +	int n;
>> +
>> +	/* defaults */
>> +	icssg_class_disable(miig_rt, slice);
>> +
>> +	/* Setup Classifier */
>> +	for (n = 0; n < classifiers_in_use; n++) {
>> +		/* match on Broadcast or MAC_PRU address */
>> +		data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P;
>> +
>> +		/* multicast? */
>> +		if (allmulti)
>> +			data |= RX_CLASS_FT_MC;
>> +
>> +		rx_class_set_or(miig_rt, slice, n, data);
>> +
>> +		/* set CFG1 for OR_OR_AND for classifier */
>> +		rx_class_sel_set_type(miig_rt, slice, n,
>> +				      RX_CLASS_SEL_TYPE_OR_OR_AND);
>> +	}
>> +
>> +	/* clear CFG2 */
>> +	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
>> +}
>> +
>> +/* required for SAV check */
>> +void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr)
>> +{
>> +	u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, };
>> +
>> +	rx_class_ft1_set_start_len(miig_rt, slice, 0, 6);
>> +	rx_class_ft1_set_da(miig_rt, slice, 0, mac_addr);
>> +	rx_class_ft1_set_da_mask(miig_rt, slice, 0, mask_addr);
>> +	rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ);
>> +}
>> diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c
>> new file mode 100644
>> index 000000000000..a88ea4933802
>> --- /dev/null
>> +++ b/drivers/net/ethernet/ti/icssg_config.c
>> @@ -0,0 +1,440 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* ICSSG Ethernet driver
>> + *
>> + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com
>> + */
>> +
>> +#include <linux/iopoll.h>
>> +#include <linux/regmap.h>
>> +#include <uapi/linux/if_ether.h>
>> +#include "icssg_config.h"
>> +#include "icssg_prueth.h"
>> +#include "icssg_switch_map.h"
>> +#include "icssg_mii_rt.h"
>> +
>> +/* TX IPG Values to be set for 100M link speed. These values are
>> + * in ocp_clk cycles. So need change if ocp_clk is changed for a specific
>> + * h/w design.
>> + */
>> +
>> +/* IPG is in core_clk cycles */
>> +#define MII_RT_TX_IPG_100M	0x17
>> +#define MII_RT_TX_IPG_1G	0xb
>> +
>> +#define	ICSSG_QUEUES_MAX		64
>> +#define	ICSSG_QUEUE_OFFSET		0xd00
>> +#define	ICSSG_QUEUE_PEEK_OFFSET		0xe00
>> +#define	ICSSG_QUEUE_CNT_OFFSET		0xe40
>> +#define	ICSSG_QUEUE_RESET_OFFSET	0xf40
>> +
>> +#define	ICSSG_NUM_TX_QUEUES	8
>> +
>> +#define	RECYCLE_Q_SLICE0	16
>> +#define	RECYCLE_Q_SLICE1	17
>> +
>> +#define	ICSSG_NUM_OTHER_QUEUES	5	/* port, host and special queues */
>> +
>> +#define	PORT_HI_Q_SLICE0	32
>> +#define	PORT_LO_Q_SLICE0	33
>> +#define	HOST_HI_Q_SLICE0	34
>> +#define	HOST_LO_Q_SLICE0	35
>> +#define	HOST_SPL_Q_SLICE0	40	/* Special Queue */
>> +
>> +#define	PORT_HI_Q_SLICE1	36
>> +#define	PORT_LO_Q_SLICE1	37
>> +#define	HOST_HI_Q_SLICE1	38
>> +#define	HOST_LO_Q_SLICE1	39
>> +#define	HOST_SPL_Q_SLICE1	41	/* Special Queue */
>> +
>> +#define MII_RXCFG_DEFAULT	(PRUSS_MII_RT_RXCFG_RX_ENABLE | \
>> +				 PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS | \
>> +				 PRUSS_MII_RT_RXCFG_RX_L2_EN | \
>> +				 PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS)
>> +
>> +#define MII_TXCFG_DEFAULT	(PRUSS_MII_RT_TXCFG_TX_ENABLE | \
>> +				 PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE | \
>> +				 PRUSS_MII_RT_TXCFG_TX_32_MODE_EN | \
>> +				 PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN)
>> +
>> +#define ICSSG_CFG_DEFAULT	(ICSSG_CFG_TX_L1_EN | \
>> +				 ICSSG_CFG_TX_L2_EN | ICSSG_CFG_RX_L2_G_EN | \
>> +				 ICSSG_CFG_TX_PRU_EN | \
>> +				 ICSSG_CFG_SGMII_MODE)
>> +
>> +#define FDB_GEN_CFG1		0x60
>> +#define SMEM_VLAN_OFFSET	8
>> +#define SMEM_VLAN_OFFSET_MASK	GENMASK(25, 8)
>> +
>> +#define FDB_GEN_CFG2		0x64
>> +#define FDB_VLAN_EN		BIT(6)
>> +#define FDB_HOST_EN		BIT(2)
>> +#define FDB_PRU1_EN		BIT(1)
>> +#define FDB_PRU0_EN		BIT(0)
>> +#define FDB_EN_ALL		(FDB_PRU0_EN | FDB_PRU1_EN | \
>> +				 FDB_HOST_EN | FDB_VLAN_EN)
>> +
>> +struct map {
>> +	int queue;
>> +	u32 pd_addr_start;
>> +	u32 flags;
>> +	bool special;
>> +};
>> +
>> +struct map hwq_map[2][ICSSG_NUM_OTHER_QUEUES] = {
>> +	{
>> +		{ PORT_HI_Q_SLICE0, PORT_DESC0_HI, 0x200000, 0 },
>> +		{ PORT_LO_Q_SLICE0, PORT_DESC0_LO, 0, 0 },
>> +		{ HOST_HI_Q_SLICE0, HOST_DESC0_HI, 0x200000, 0 },
>> +		{ HOST_LO_Q_SLICE0, HOST_DESC0_LO, 0, 0 },
>> +		{ HOST_SPL_Q_SLICE0, HOST_SPPD0, 0x400000, 1 },
>> +	},
>> +	{
>> +		{ PORT_HI_Q_SLICE1, PORT_DESC1_HI, 0xa00000, 0 },
>> +		{ PORT_LO_Q_SLICE1, PORT_DESC1_LO, 0x800000, 0 },
>> +		{ HOST_HI_Q_SLICE1, HOST_DESC1_HI, 0xa00000, 0 },
>> +		{ HOST_LO_Q_SLICE1, HOST_DESC1_LO, 0x800000, 0 },
>> +		{ HOST_SPL_Q_SLICE1, HOST_SPPD1, 0xc00000, 1 },
>> +	},
>> +};
>> +
>> +static void icssg_config_mii_init(struct prueth_emac *emac)
>> +{
>> +	struct prueth *prueth = emac->prueth;
>> +	struct regmap *mii_rt = prueth->mii_rt;
>> +	int slice = prueth_emac_slice(emac);
>> +	u32 rxcfg_reg, txcfg_reg, pcnt_reg;
>> +	u32 rxcfg, txcfg;
>> +
>> +	rxcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 :
>> +				       PRUSS_MII_RT_RXCFG1;
>> +	txcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 :
>> +				       PRUSS_MII_RT_TXCFG1;
>> +	pcnt_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 :
>> +				       PRUSS_MII_RT_RX_PCNT1;
>> +
>> +	rxcfg = MII_RXCFG_DEFAULT;
>> +	txcfg = MII_TXCFG_DEFAULT;
>> +
>> +	if (slice == ICSS_MII1)
>> +		rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL;
>> +
>> +	/* In MII mode TX lines swapped inside ICSSG, so TX_MUX_SEL cfg need
>> +	 * to be swapped also comparing to RGMII mode.
>> +	 */
>> +	if (emac->phy_if == PHY_INTERFACE_MODE_MII && slice == ICSS_MII0)
>> +		txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
>> +	else if (emac->phy_if != PHY_INTERFACE_MODE_MII && slice == ICSS_MII1)
>> +		txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
>> +
>> +	regmap_write(mii_rt, rxcfg_reg, rxcfg);
>> +	regmap_write(mii_rt, txcfg_reg, txcfg);
>> +	regmap_write(mii_rt, pcnt_reg, 0x1);
>> +}
>> +
>> +static void icssg_miig_queues_init(struct prueth *prueth, int slice)
>> +{
>> +	struct regmap *miig_rt = prueth->miig_rt;
>> +	void __iomem *smem = prueth->shram.va;
>> +	u8 pd[ICSSG_SPECIAL_PD_SIZE];
>> +	int queue = 0, i, j;
>> +	u32 *pdword;
>> +
>> +	/* reset hwqueues */
>> +	if (slice)
>> +		queue = ICSSG_NUM_TX_QUEUES;
>> +
>> +	for (i = 0; i < ICSSG_NUM_TX_QUEUES; i++) {
>> +		regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
>> +		queue++;
>> +	}
>> +
>> +	queue = slice ? RECYCLE_Q_SLICE1 : RECYCLE_Q_SLICE0;
>> +	regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
>> +
>> +	for (i = 0; i < ICSSG_NUM_OTHER_QUEUES; i++) {
>> +		regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET,
>> +			     hwq_map[slice][i].queue);
>> +	}
>> +
>> +	/* initialize packet descriptors in SMEM */
>> +	/* push pakcet descriptors to hwqueues */
>> +
>> +	pdword = (u32 *)pd;
>> +	for (j = 0; j < ICSSG_NUM_OTHER_QUEUES; j++) {
>> +		struct map *mp;
>> +		int pd_size, num_pds;
>> +		u32 pdaddr;
>> +
>> +		mp = &hwq_map[slice][j];
>> +		if (mp->special) {
>> +			pd_size = ICSSG_SPECIAL_PD_SIZE;
>> +			num_pds = ICSSG_NUM_SPECIAL_PDS;
>> +		} else	{
>> +			pd_size = ICSSG_NORMAL_PD_SIZE;
>> +			num_pds = ICSSG_NUM_NORMAL_PDS;
>> +		}
>> +
>> +		for (i = 0; i < num_pds; i++) {
>> +			memset(pd, 0, pd_size);
>> +
>> +			pdword[0] &= cpu_to_le32(ICSSG_FLAG_MASK);
>> +			pdword[0] |= cpu_to_le32(mp->flags);
>> +			pdaddr = mp->pd_addr_start + i * pd_size;
>> +
>> +			memcpy_toio(smem + pdaddr, pd, pd_size);
>> +			queue = mp->queue;
>> +			regmap_write(miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue,
>> +				     pdaddr);
>> +		}
>> +	}
>> +}
>> +
>> +void icssg_config_ipg(struct prueth_emac *emac)
>> +{
>> +	struct prueth *prueth = emac->prueth;
>> +	int slice = prueth_emac_slice(emac);
>> +
>> +	switch (emac->speed) {
>> +	case SPEED_1000:
>> +		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_1G);
>> +		break;
>> +	case SPEED_100:
>> +		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M);
>> +		break;
>> +	default:
>> +		/* Other links speeds not supported */
>> +		netdev_err(emac->ndev, "Unsupported link speed\n");
>> +		return;
>> +	}
>> +}
>> +
>> +static void emac_r30_cmd_init(struct prueth_emac *emac)
>> +{
>> +	int i;
>> +	struct icssg_r30_cmd *p;
>> +
>> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
>> +
>> +	for (i = 0; i < 4; i++)
>> +		writel(EMAC_NONE, &p->cmd[i]);
>> +}
>> +
>> +static int emac_r30_is_done(struct prueth_emac *emac)
>> +{
>> +	const struct icssg_r30_cmd *p;
>> +	int i;
>> +	u32 cmd;
>> +
>> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
>> +
>> +	for (i = 0; i < 4; i++) {
>> +		cmd = readl(&p->cmd[i]);
>> +		if (cmd != EMAC_NONE)
>> +			return 0;
>> +	}
>> +
>> +	return 1;
>> +}
>> +
>> +static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>> +{
>> +	struct icssg_buffer_pool_cfg *bpool_cfg;
>> +	struct prueth *prueth = emac->prueth;
>> +	int slice = prueth_emac_slice(emac);
>> +	struct icssg_rxq_ctx *rxq_ctx;
>> +	u32 addr;
>> +	int i;
>> +
>> +	/* Layout to have 64KB aligned buffer pool
>> +	 * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1|
>> +	 */
>> +
>> +	addr = lower_32_bits(prueth->msmcram.pa);
>> +	if (slice)
>> +		addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
>> +
>> +	if (addr % SZ_64K) {
>> +		dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET;
>> +	/* workaround for f/w bug. bpool 0 needs to be initilalized */
>> +	bpool_cfg[0].addr = cpu_to_le32(addr);
>> +	bpool_cfg[0].len = 0;
>> +
>> +	for (i = PRUETH_EMAC_BUF_POOL_START;
>> +	     i < (PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS);
>> +	     i++) {
>> +		bpool_cfg[i].addr = cpu_to_le32(addr);
>> +		bpool_cfg[i].len = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE);
>> +		addr += PRUETH_EMAC_BUF_POOL_SIZE;
>> +	}
>> +
>> +	if (!slice)
>> +		addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
>> +	else
>> +		addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2;
>> +
>> +	/* Pre-emptible RX buffer queue */
>> +	rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET;
>> +	for (i = 0; i < 3; i++)
>> +		rxq_ctx->start[i] = cpu_to_le32(addr);
>> +
>> +	addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
>> +	rxq_ctx->end = cpu_to_le32(addr);
>> +
>> +	/* Express RX buffer queue */
>> +	rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET;
>> +	for (i = 0; i < 3; i++)
>> +		rxq_ctx->start[i] = cpu_to_le32(addr);
>> +
>> +	addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
>> +	rxq_ctx->end = cpu_to_le32(addr);
>> +
>> +	return 0;
>> +}
>> +
>> +static void icssg_init_emac_mode(struct prueth *prueth)
>> +{
>> +	/* When the device is configured as a bridge and it is being brought back
>> +	 * to the emac mode, the host mac address has to be set as 0.
>> +	 */
>> +	u8 mac[ETH_ALEN] = { 0 };
>> +
>> +	if (prueth->emacs_initialized)
>> +		return;
>> +
>> +	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, 0);
>> +	regmap_write(prueth->miig_rt, FDB_GEN_CFG2, 0);
>> +	/* Clear host MAC address */
>> +	icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
>> +}
>> +
>> +int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>> +{
>> +	void *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
>> +	u8 *cfg_byte_ptr = config;
>> +	struct icssg_flow_cfg *flow_cfg;
>> +	u32 mask;
>> +	int ret;
>> +
>> +	icssg_init_emac_mode(prueth);
>> +
>> +	memset_io(config, 0, TAS_GATE_MASK_LIST0);
>> +	icssg_miig_queues_init(prueth, slice);
>> +
>> +	emac->speed = SPEED_1000;
>> +	emac->duplex = DUPLEX_FULL;
>> +	if (!phy_interface_mode_is_rgmii(emac->phy_if)) {
>> +		emac->speed = SPEED_100;
>> +		emac->duplex = DUPLEX_FULL;
>> +	}
>> +	regmap_update_bits(prueth->miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_DEFAULT, ICSSG_CFG_DEFAULT);
>> +	icssg_miig_set_interface_mode(prueth->miig_rt, slice, emac->phy_if);
>> +	icssg_config_mii_init(emac);
>> +	icssg_config_ipg(emac);
>> +	icssg_update_rgmii_cfg(prueth->miig_rt, emac);
>> +
>> +	/* set GPI mode */
>> +	pruss_cfg_gpimode(prueth->pruss, prueth->pru_id[slice],
>> +			  PRUSS_GPI_MODE_MII);
>> +
>> +	/* enable XFR shift for PRU and RTU */
>> +	mask = PRUSS_SPP_XFER_SHIFT_EN | PRUSS_SPP_RTU_XFR_SHIFT_EN;
>> +	pruss_cfg_update(prueth->pruss, PRUSS_CFG_SPP, mask, mask);
>> +
>> +	/* set C28 to 0x100 */
>> +	pru_rproc_set_ctable(prueth->pru[slice], PRU_C28, 0x100 << 8);
>> +	pru_rproc_set_ctable(prueth->rtu[slice], PRU_C28, 0x100 << 8);
>> +	pru_rproc_set_ctable(prueth->txpru[slice], PRU_C28, 0x100 << 8);
>> +
>> +	flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
>> +	flow_cfg->rx_base_flow = cpu_to_le32(emac->rx_flow_id_base);
>> +	flow_cfg->mgm_base_flow = 0;
>> +	*(cfg_byte_ptr + SPL_PKT_DEFAULT_PRIORITY) = 0;
>> +	*(cfg_byte_ptr + QUEUE_NUM_UNTAGGED) = 0x0;
>> +
>> +	ret = prueth_emac_buffer_setup(emac);
>> +	if (ret)
>> +		return ret;
>> +
>> +	emac_r30_cmd_init(emac);
>> +
>> +	return 0;
>> +}
>> +
>> +static struct icssg_r30_cmd emac_r32_bitmask[] = {
>> +	{{0xffff0004, 0xffff0100, 0xffff0100, EMAC_NONE}},	/* EMAC_PORT_DISABLE */
>> +	{{0xfffb0040, 0xfeff0200, 0xfeff0200, EMAC_NONE}},	/* EMAC_PORT_BLOCK */
>> +	{{0xffbb0000, 0xfcff0000, 0xdcff0000, EMAC_NONE}},	/* EMAC_PORT_FORWARD */
>> +	{{0xffbb0000, 0xfcff0000, 0xfcff2000, EMAC_NONE}},	/* EMAC_PORT_FORWARD_WO_LEARNING */
>> +	{{0xffff0001, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT ALL */
>> +	{{0xfffe0002, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT TAGGED */
>> +	{{0xfffc0000, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT UNTAGGED and PRIO */
>> +	{{EMAC_NONE,  0xffff0020, EMAC_NONE, EMAC_NONE}},	/* TAS Trigger List change */
>> +	{{EMAC_NONE,  0xdfff1000, EMAC_NONE, EMAC_NONE}},	/* TAS set state ENABLE*/
>> +	{{EMAC_NONE,  0xefff2000, EMAC_NONE, EMAC_NONE}},	/* TAS set state RESET*/
>> +	{{EMAC_NONE,  0xcfff0000, EMAC_NONE, EMAC_NONE}},	/* TAS set state DISABLE*/
>> +	{{EMAC_NONE,  EMAC_NONE,  0xffff0400, EMAC_NONE}},	/* UC flooding ENABLE*/
>> +	{{EMAC_NONE,  EMAC_NONE,  0xfbff0000, EMAC_NONE}},	/* UC flooding DISABLE*/
>> +	{{EMAC_NONE,  EMAC_NONE,  0xffff0800, EMAC_NONE}},	/* MC flooding ENABLE*/
>> +	{{EMAC_NONE,  EMAC_NONE,  0xf7ff0000, EMAC_NONE}},	/* MC flooding DISABLE*/
>> +	{{EMAC_NONE,  0xffff4000, EMAC_NONE, EMAC_NONE}},	/* Preemption on Tx ENABLE*/
>> +	{{EMAC_NONE,  0xbfff0000, EMAC_NONE, EMAC_NONE}},	/* Preemption on Tx DISABLE*/
>> +	{{0xffff0010,  EMAC_NONE, 0xffff0010, EMAC_NONE}},	/* VLAN AWARE*/
>> +	{{0xffef0000,  EMAC_NONE, 0xffef0000, EMAC_NONE}}	/* VLAN UNWARE*/
>> +};
>> +
>> +int emac_set_port_state(struct prueth_emac *emac,
>> +			enum icssg_port_state_cmd cmd)
>> +{
>> +	struct icssg_r30_cmd *p;
>> +	int ret = -ETIMEDOUT;
>> +	int done = 0;
>> +	int i;
>> +
>> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
>> +
>> +	if (cmd >= ICSSG_EMAC_PORT_MAX_COMMANDS) {
>> +		netdev_err(emac->ndev, "invalid port command\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* only one command at a time allowed to firmware */
>> +	mutex_lock(&emac->cmd_lock);
>> +
>> +	for (i = 0; i < 4; i++)
>> +		writel(emac_r32_bitmask[cmd].cmd[i], &p->cmd[i]);
>> +
>> +	/* wait for done */
>> +	ret = read_poll_timeout(emac_r30_is_done, done, done == 1,
>> +				1000, 10000, false, emac);
>> +
>> +	if (ret == -ETIMEDOUT)
>> +		netdev_err(emac->ndev, "timeout waiting for command done\n");
>> +
>> +	mutex_unlock(&emac->cmd_lock);
>> +
>> +	return ret;
>> +}
>> +
>> +void icssg_config_set_speed(struct prueth_emac *emac)
>> +{
>> +	u8 fw_speed;
>> +
>> +	switch (emac->speed) {
>> +	case SPEED_1000:
>> +		fw_speed = FW_LINK_SPEED_1G;
>> +		break;
>> +	case SPEED_100:
>> +		fw_speed = FW_LINK_SPEED_100M;
>> +		break;
>> +	default:
>> +		/* Other links speeds not supported */
>> +		netdev_err(emac->ndev, "Unsupported link speed\n");
>> +		return;
>> +	}
>> +
>> +	writeb(fw_speed, emac->dram.va + PORT_LINK_SPEED_OFFSET);
>> +}
>> diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h
>> new file mode 100644
>> index 000000000000..43eb0922172a
>> --- /dev/null
>> +++ b/drivers/net/ethernet/ti/icssg_config.h
>> @@ -0,0 +1,200 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Texas Instruments ICSSG Ethernet driver
>> + *
>> + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
>> + *
>> + */
>> +
>> +#ifndef __NET_TI_ICSSG_CONFIG_H
>> +#define __NET_TI_ICSSG_CONFIG_H
>> +
>> +struct icssg_buffer_pool_cfg {
>> +	__le32	addr;
>> +	__le32	len;
>> +} __packed;
>> +
>> +struct icssg_flow_cfg {
>> +	__le16 rx_base_flow;
>> +	__le16 mgm_base_flow;
>> +} __packed;
>> +
>> +#define PRUETH_PKT_TYPE_CMD	0x10
>> +#define PRUETH_NAV_PS_DATA_SIZE	16	/* Protocol specific data size */
>> +#define PRUETH_NAV_SW_DATA_SIZE	16	/* SW related data size */
>> +#define PRUETH_MAX_TX_DESC	512
>> +#define PRUETH_MAX_RX_DESC	512
>> +#define PRUETH_MAX_RX_FLOWS	1	/* excluding default flow */
>> +#define PRUETH_RX_FLOW_DATA	0
>> +
>> +#define PRUETH_EMAC_BUF_POOL_SIZE	SZ_8K
>> +#define PRUETH_EMAC_POOLS_PER_SLICE	24
>> +#define PRUETH_EMAC_BUF_POOL_START	8
>> +#define PRUETH_NUM_BUF_POOLS	8
>> +#define PRUETH_EMAC_RX_CTX_BUF_SIZE	SZ_16K	/* per slice */
>> +#define MSMC_RAM_SIZE	\
>> +	(2 * (PRUETH_EMAC_BUF_POOL_SIZE * PRUETH_NUM_BUF_POOLS + \
>> +	 PRUETH_EMAC_RX_CTX_BUF_SIZE * 2))
>> +
>> +struct icssg_rxq_ctx {
>> +	__le32 start[3];
>> +	__le32 end;
>> +} __packed;
>> +
>> +/* Load time Fiwmware Configuration */
>> +
>> +#define ICSSG_FW_MGMT_CMD_HEADER	0x81
>> +#define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
>> +#define ICSSG_FW_MGMT_CMD_TYPE		0x04
>> +#define ICSSG_FW_MGMT_PKT		0x80000000
>> +
>> +struct icssg_r30_cmd {
>> +	u32 cmd[4];
>> +} __packed;
>> +
>> +enum icssg_port_state_cmd {
>> +	ICSSG_EMAC_PORT_DISABLE = 0,
>> +	ICSSG_EMAC_PORT_BLOCK,
>> +	ICSSG_EMAC_PORT_FORWARD,
>> +	ICSSG_EMAC_PORT_FORWARD_WO_LEARNING,
>> +	ICSSG_EMAC_PORT_ACCEPT_ALL,
>> +	ICSSG_EMAC_PORT_ACCEPT_TAGGED,
>> +	ICSSG_EMAC_PORT_ACCEPT_UNTAGGED_N_PRIO,
>> +	ICSSG_EMAC_PORT_TAS_TRIGGER,
>> +	ICSSG_EMAC_PORT_TAS_ENABLE,
>> +	ICSSG_EMAC_PORT_TAS_RESET,
>> +	ICSSG_EMAC_PORT_TAS_DISABLE,
>> +	ICSSG_EMAC_PORT_UC_FLOODING_ENABLE,
>> +	ICSSG_EMAC_PORT_UC_FLOODING_DISABLE,
>> +	ICSSG_EMAC_PORT_MC_FLOODING_ENABLE,
>> +	ICSSG_EMAC_PORT_MC_FLOODING_DISABLE,
>> +	ICSSG_EMAC_PORT_PREMPT_TX_ENABLE,
>> +	ICSSG_EMAC_PORT_PREMPT_TX_DISABLE,
>> +	ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE,
>> +	ICSSG_EMAC_PORT_VLAN_AWARE_DISABLE,
>> +	ICSSG_EMAC_PORT_MAX_COMMANDS
>> +};
>> +
>> +#define EMAC_NONE           0xffff0000
>> +#define EMAC_PRU0_P_DI      0xffff0004
>> +#define EMAC_PRU1_P_DI      0xffff0040
>> +#define EMAC_TX_P_DI        0xffff0100
>> +
>> +#define EMAC_PRU0_P_EN      0xfffb0000
>> +#define EMAC_PRU1_P_EN      0xffbf0000
>> +#define EMAC_TX_P_EN        0xfeff0000
>> +
>> +#define EMAC_P_BLOCK        0xffff0040
>> +#define EMAC_TX_P_BLOCK     0xffff0200
>> +#define EMAC_P_UNBLOCK      0xffbf0000
>> +#define EMAC_TX_P_UNBLOCK   0xfdff0000
>> +#define EMAC_LEAN_EN        0xfff70000
>> +#define EMAC_LEAN_DI        0xffff0008
>> +
>> +#define EMAC_ACCEPT_ALL     0xffff0001
>> +#define EMAC_ACCEPT_TAG     0xfffe0002
>> +#define EMAC_ACCEPT_PRIOR   0xfffc0000
>> +
>> +/* Config area lies in DRAM */
>> +#define ICSSG_CONFIG_OFFSET	0x0
>> +
>> +/* Config area lies in shared RAM */
>> +#define ICSSG_CONFIG_OFFSET_SLICE0   0
>> +#define ICSSG_CONFIG_OFFSET_SLICE1   0x8000
>> +
>> +#define ICSSG_NUM_NORMAL_PDS	64
>> +#define ICSSG_NUM_SPECIAL_PDS	16
>> +
>> +#define ICSSG_NORMAL_PD_SIZE	8
>> +#define ICSSG_SPECIAL_PD_SIZE	20
>> +
>> +#define ICSSG_FLAG_MASK		0xff00ffff
>> +
>> +struct icssg_setclock_desc {
>> +	u8 request;
>> +	u8 restore;
>> +	u8 acknowledgment;
>> +	u8 cmp_status;
>> +	u32 margin;
>> +	u32 cyclecounter0_set;
>> +	u32 cyclecounter1_set;
>> +	u32 iepcount_set;
>> +	u32 rsvd1;
>> +	u32 rsvd2;
>> +	u32 CMP0_current;
>> +	u32 iepcount_current;
>> +	u32 difference;
>> +	u32 cyclecounter0_new;
>> +	u32 cyclecounter1_new;
>> +	u32 CMP0_new;
>> +} __packed;
>> +
>> +#define ICSSG_CMD_POP_SLICE0	56
>> +#define ICSSG_CMD_POP_SLICE1	60
>> +
>> +#define ICSSG_CMD_PUSH_SLICE0	57
>> +#define ICSSG_CMD_PUSH_SLICE1	61
>> +
>> +#define ICSSG_RSP_POP_SLICE0	58
>> +#define ICSSG_RSP_POP_SLICE1	62
>> +
>> +#define ICSSG_RSP_PUSH_SLICE0	56
>> +#define ICSSG_RSP_PUSH_SLICE1	60
>> +
>> +#define ICSSG_TS_POP_SLICE0	59
>> +#define ICSSG_TS_POP_SLICE1	63
>> +
>> +#define ICSSG_TS_PUSH_SLICE0	40
>> +#define ICSSG_TS_PUSH_SLICE1	41
>> +
>> +/* FDB FID_C2 flag definitions */
>> +/* Indicates host port membership.*/
>> +#define ICSSG_FDB_ENTRY_P0_MEMBERSHIP         BIT(0)
>> +/* Indicates that MAC ID is connected to physical port 1 */
>> +#define ICSSG_FDB_ENTRY_P1_MEMBERSHIP         BIT(1)
>> +/* Indicates that MAC ID is connected to physical port 2 */
>> +#define ICSSG_FDB_ENTRY_P2_MEMBERSHIP         BIT(2)
>> +/* Ageable bit is set for learned entries and cleared for static entries */
>> +#define ICSSG_FDB_ENTRY_AGEABLE               BIT(3)
>> +/* If set for DA then packet is determined to be a special packet */
>> +#define ICSSG_FDB_ENTRY_BLOCK                 BIT(4)
>> +/* If set for DA then the SA from the packet is not learned */
>> +#define ICSSG_FDB_ENTRY_SECURE                BIT(5)
>> +/* If set, it means packet has been seen recently with source address + FID
>> + * matching MAC address/FID of entry
>> + */
>> +#define ICSSG_FDB_ENTRY_TOUCHED               BIT(6)
>> +/* Set if entry is valid */
>> +#define ICSSG_FDB_ENTRY_VALID                 BIT(7)
>> +
>> +/**
>> + * struct prueth_vlan_tbl - VLAN table entries struct in ICSSG SMEM
>> + * @fid_c1: membership and forwarding rules flag to this table. See
>> + *          above to defines for bit definitions
>> + * @fid: FDB index for this VID (there is 1-1 mapping b/w VID and FID)
>> + */
>> +struct prueth_vlan_tbl {
>> +	u8 fid_c1;
>> +	u8 fid;
>> +} __packed;
>> +
>> +/**
>> + * struct prueth_fdb_slot - Result of FDB slot lookup
>> + * @mac: MAC address
>> + * @fid: fid to be associated with MAC
>> + * @fid_c2: FID_C2 entry for this MAC
>> + */
>> +struct prueth_fdb_slot {
>> +	u8 mac[ETH_ALEN];
>> +	u8 fid;
>> +	u8 fid_c2;
>> +} __packed;
>> +
>> +enum icssg_ietfpe_verify_states {
>> +	ICSSG_IETFPE_STATE_UNKNOWN = 0,
>> +	ICSSG_IETFPE_STATE_INITIAL,
>> +	ICSSG_IETFPE_STATE_VERIFYING,
>> +	ICSSG_IETFPE_STATE_SUCCEEDED,
>> +	ICSSG_IETFPE_STATE_FAILED,
>> +	ICSSG_IETFPE_STATE_DISABLED
>> +};
>> +#endif /* __NET_TI_ICSSG_CONFIG_H */
>> diff --git a/drivers/net/ethernet/ti/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg_ethtool.c
>> new file mode 100644
>> index 000000000000..fd09d223b0ae
>> --- /dev/null
>> +++ b/drivers/net/ethernet/ti/icssg_ethtool.c
>> @@ -0,0 +1,319 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* Texas Instruments ICSSG Ethernet driver
>> + *
>> + * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
>> + *
>> + */
>> +
>> +#include "icssg_prueth.h"
>> +#include <linux/regmap.h>
>> +
>> +static u32 stats_base[] = {	0x54c,	/* Slice 0 stats start */
>> +				0xb18,	/* Slice 1 stats start */
>> +};
>> +
>> +struct miig_stats_regs {
>> +	/* Rx */
>> +	u32 rx_good_frames;
>> +	u32 rx_broadcast_frames;
>> +	u32 rx_multicast_frames;
>> +	u32 rx_crc_error_frames;
>> +	u32 rx_mii_error_frames;
>> +	u32 rx_odd_nibble_frames;
>> +	u32 rx_frame_max_size;
>> +	u32 rx_max_size_error_frames;
>> +	u32 rx_frame_min_size;
>> +	u32 rx_min_size_error_frames;
>> +	u32 rx_overrun_frames;
>> +	u32 rx_class0_hits;
>> +	u32 rx_class1_hits;
>> +	u32 rx_class2_hits;
>> +	u32 rx_class3_hits;
>> +	u32 rx_class4_hits;
>> +	u32 rx_class5_hits;
>> +	u32 rx_class6_hits;
>> +	u32 rx_class7_hits;
>> +	u32 rx_class8_hits;
>> +	u32 rx_class9_hits;
>> +	u32 rx_class10_hits;
>> +	u32 rx_class11_hits;
>> +	u32 rx_class12_hits;
>> +	u32 rx_class13_hits;
>> +	u32 rx_class14_hits;
>> +	u32 rx_class15_hits;
>> +	u32 rx_smd_frags;
>> +	u32 rx_bucket1_size;
>> +	u32 rx_bucket2_size;
>> +	u32 rx_bucket3_size;
>> +	u32 rx_bucket4_size;
>> +	u32 rx_64B_frames;
>> +	u32 rx_bucket1_frames;
>> +	u32 rx_bucket2_frames;
>> +	u32 rx_bucket3_frames;
>> +	u32 rx_bucket4_frames;
>> +	u32 rx_bucket5_frames;
>> +	u32 rx_total_bytes;
>> +	u32 rx_tx_total_bytes;
>> +	/* Tx */
>> +	u32 tx_good_frames;
>> +	u32 tx_broadcast_frames;
>> +	u32 tx_multicast_frames;
>> +	u32 tx_odd_nibble_frames;
>> +	u32 tx_underflow_errors;
>> +	u32 tx_frame_max_size;
>> +	u32 tx_max_size_error_frames;
>> +	u32 tx_frame_min_size;
>> +	u32 tx_min_size_error_frames;
>> +	u32 tx_bucket1_size;
>> +	u32 tx_bucket2_size;
>> +	u32 tx_bucket3_size;
>> +	u32 tx_bucket4_size;
>> +	u32 tx_64B_frames;
>> +	u32 tx_bucket1_frames;
>> +	u32 tx_bucket2_frames;
>> +	u32 tx_bucket3_frames;
>> +	u32 tx_bucket4_frames;
>> +	u32 tx_bucket5_frames;
>> +	u32 tx_total_bytes;
>> +};
>> +
>> +#define ICSSG_STATS(field)				\
>> +{							\
>> +	#field,						\
>> +	offsetof(struct miig_stats_regs, field),	\
>> +}
>> +
>> +struct icssg_stats {
>> +	char name[ETH_GSTRING_LEN];
>> +	u32 offset;
>> +};
>> +
>> +static const struct icssg_stats icssg_ethtool_stats[] = {
>> +	/* Rx */
>> +	ICSSG_STATS(rx_good_frames),
>> +	ICSSG_STATS(rx_broadcast_frames),
>> +	ICSSG_STATS(rx_multicast_frames),
>> +	ICSSG_STATS(rx_crc_error_frames),
>> +	ICSSG_STATS(rx_mii_error_frames),
>> +	ICSSG_STATS(rx_odd_nibble_frames),
>> +	ICSSG_STATS(rx_frame_max_size),
>> +	ICSSG_STATS(rx_max_size_error_frames),
>> +	ICSSG_STATS(rx_frame_min_size),
>> +	ICSSG_STATS(rx_min_size_error_frames),
>> +	ICSSG_STATS(rx_overrun_frames),
>> +	ICSSG_STATS(rx_class0_hits),
>> +	ICSSG_STATS(rx_class1_hits),
>> +	ICSSG_STATS(rx_class2_hits),
>> +	ICSSG_STATS(rx_class3_hits),
>> +	ICSSG_STATS(rx_class4_hits),
>> +	ICSSG_STATS(rx_class5_hits),
>> +	ICSSG_STATS(rx_class6_hits),
>> +	ICSSG_STATS(rx_class7_hits),
>> +	ICSSG_STATS(rx_class8_hits),
>> +	ICSSG_STATS(rx_class9_hits),
>> +	ICSSG_STATS(rx_class10_hits),
>> +	ICSSG_STATS(rx_class11_hits),
>> +	ICSSG_STATS(rx_class12_hits),
>> +	ICSSG_STATS(rx_class13_hits),
>> +	ICSSG_STATS(rx_class14_hits),
>> +	ICSSG_STATS(rx_class15_hits),
>> +	ICSSG_STATS(rx_smd_frags),
>> +	ICSSG_STATS(rx_bucket1_size),
>> +	ICSSG_STATS(rx_bucket2_size),
>> +	ICSSG_STATS(rx_bucket3_size),
>> +	ICSSG_STATS(rx_bucket4_size),
>> +	ICSSG_STATS(rx_64B_frames),
>> +	ICSSG_STATS(rx_bucket1_frames),
>> +	ICSSG_STATS(rx_bucket2_frames),
>> +	ICSSG_STATS(rx_bucket3_frames),
>> +	ICSSG_STATS(rx_bucket4_frames),
>> +	ICSSG_STATS(rx_bucket5_frames),
>> +	ICSSG_STATS(rx_total_bytes),
>> +	ICSSG_STATS(rx_tx_total_bytes),
>> +	/* Tx */
>> +	ICSSG_STATS(tx_good_frames),
>> +	ICSSG_STATS(tx_broadcast_frames),
>> +	ICSSG_STATS(tx_multicast_frames),
>> +	ICSSG_STATS(tx_odd_nibble_frames),
>> +	ICSSG_STATS(tx_underflow_errors),
>> +	ICSSG_STATS(tx_frame_max_size),
>> +	ICSSG_STATS(tx_max_size_error_frames),
>> +	ICSSG_STATS(tx_frame_min_size),
>> +	ICSSG_STATS(tx_min_size_error_frames),
>> +	ICSSG_STATS(tx_bucket1_size),
>> +	ICSSG_STATS(tx_bucket2_size),
>> +	ICSSG_STATS(tx_bucket3_size),
>> +	ICSSG_STATS(tx_bucket4_size),
>> +	ICSSG_STATS(tx_64B_frames),
>> +	ICSSG_STATS(tx_bucket1_frames),
>> +	ICSSG_STATS(tx_bucket2_frames),
>> +	ICSSG_STATS(tx_bucket3_frames),
>> +	ICSSG_STATS(tx_bucket4_frames),
>> +	ICSSG_STATS(tx_bucket5_frames),
>> +	ICSSG_STATS(tx_total_bytes),
>> +};
>> +
>> +static void emac_get_drvinfo(struct net_device *ndev,
>> +			     struct ethtool_drvinfo *info)
>> +{
>> +	struct prueth_emac *emac = netdev_priv(ndev);
>> +	struct prueth *prueth = emac->prueth;
>> +
>> +	strscpy(info->driver, dev_driver_string(prueth->dev),
>> +		sizeof(info->driver));
>> +	strscpy(info->bus_info, dev_name(prueth->dev), sizeof(info->bus_info));
>> +}
>> +
>> +static u32 emac_get_msglevel(struct net_device *ndev)
>> +{
>> +	struct prueth_emac *emac = netdev_priv(ndev);
>> +
>> +	return emac->msg_enable;
>> +}
>> +
>> +static void emac_set_msglevel(struct net_device *ndev, u32 value)
>> +{
>> +	struct prueth_emac *emac = netdev_priv(ndev);
>> +
>> +	emac->msg_enable = value;
>> +}
>> +
>> +static int emac_get_link_ksettings(struct net_device *ndev,
>> +				   struct ethtool_link_ksettings *ecmd)
>> +{
>> +	return phy_ethtool_get_link_ksettings(ndev, ecmd);
>> +}
>> +
>> +static int emac_set_link_ksettings(struct net_device *ndev,
>> +				   const struct ethtool_link_ksettings *ecmd)
>> +{
>> +	return phy_ethtool_set_link_ksettings(ndev, ecmd);
>> +}
>> +
>> +static int emac_get_eee(struct net_device *ndev, struct ethtool_eee *edata)
>> +{
>> +	if (!ndev->phydev)
>> +		return -EOPNOTSUPP;
>> +
>> +	return phy_ethtool_get_eee(ndev->phydev, edata);
>> +}
>> +
>> +static int emac_set_eee(struct net_device *ndev, struct ethtool_eee *edata)
>> +{
>> +	if (!ndev->phydev)
>> +		return -EOPNOTSUPP;
>> +
>> +	return phy_ethtool_set_eee(ndev->phydev, edata);
>> +}
>> +
>> +static int emac_nway_reset(struct net_device *ndev)
>> +{
>> +	return phy_ethtool_nway_reset(ndev);
>> +}
>> +
>> +static const char emac_ethtool_priv_flags[][ETH_GSTRING_LEN] = {
>> +#define EMAC_PRIV_IET_FRAME_PREEMPTION  BIT(0)
>> +	"iet-frame-preemption",
>> +#define EMAC_PRIV_IET_MAC_VERIFY                BIT(1)
>> +	"iet-mac-verify",
>> +};
> 
> Please move the #define outside of the array. They are not easy to
> see.
> 

Sure, I'll move the #define to outside of the array.
This is how the structure would look like.

#define EMAC_PRIV_IET_FRAME_PREEMPTION  BIT(0)
#define EMAC_PRIV_IET_MAC_VERIFY		BIT(1)

static const char emac_ethtool_priv_flags[][ETH_GSTRING_LEN] = {
	"iet-frame-preemption",
	"iet-mac-verify",
};


> 	Andrew
> 

Thanks and Regards,
Danish.

> From mboxrd@z Thu Jan  1 00:00:00 1970
> Return-Path: <linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org>
> X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
> 	aws-us-west-2-korg-lkml-1.web.codeaurora.org
> Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133])
> 	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
> 	(No client certificate requested)
> 	by smtp.lore.kernel.org (Postfix) with ESMTPS id 13488C43334
> 	for <linux-arm-kernel@archiver.kernel.org>; Sun,  5 Jun 2022 15:39:36 +0000 (UTC)
> DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
> 	d=lists.infradead.org; s=bombadil.20210309; h=Sender:
> 	Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post:
> 	List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References:
> 	Message-ID:Subject:To:From:Date:Reply-To:Content-ID:Content-Description:
> 	Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:
> 	List-Owner; bh=b6fYa0q+XFwyIpbdKM0aAD9nKwyDSWVpkOMmA80Mzq4=; b=olQyG9xAfPyO0y
> 	vAK24MXpqlDj0lAj5hChVz0fLkJgC4quh9pGM4/44+YhRgd1I37AGAAlyVHxayUECyFmLPbOhXAhA
> 	iZbsNjL7uAcqj7t3J+dBL3BRQmgKGBpwEak18gYG7V+OnAOCvaQ3w+ccsYql0mlf96tMNK+JZTyZa
> 	qZdylMVGr8FKMbIFRyVZiE9wGsw0hLwZ64vIHOjs5SCqA8B6Qnq5AaXmpXLxLXgwj3IYg6IUIo3TP
> 	vFopdmNaVDm5xSbpMAQxrt49ita2lUHEzV41GfNocGgs3vSkn1T4uViaDIY5+mOwoOjDfK7lm3D1h
> 	LpsUsHl9aE5HlG5hMehA==;
> Received: from localhost ([::1] helo=bombadil.infradead.org)
> 	by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux))
> 	id 1nxsKN-00ElzW-35; Sun, 05 Jun 2022 15:38:07 +0000
> Received: from vps0.lunn.ch ([185.16.172.187])
> 	by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))
> 	id 1nxsKH-00ElyS-AH
> 	for linux-arm-kernel@lists.infradead.org; Sun, 05 Jun 2022 15:38:05 +0000
> DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lunn.ch;
> 	s=20171124; h=In-Reply-To:Content-Disposition:Content-Type:MIME-Version:
> 	References:Message-ID:Subject:Cc:To:From:Date:From:Sender:Reply-To:Subject:
> 	Date:Message-ID:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:
> 	Content-ID:Content-Description:Content-Disposition:In-Reply-To:References;
> 	bh=fage9o/WkrlxF6CHaFSVzs3PXs0ms4frqc7xdvWybXY=; b=Ld+ZYslRThTJYx7sMAt/vrjFI6
> 	IklFvvGj0QTnGKp/EkPLgktZvia+CIDqH9Imv+DaGiA5TyTs52f7vkeskXB7uj7d2HAOOmvf7NToQ
> 	nrLe9ZY8V0eos9i8IFGrSc3VLv6ivkVuHlzOCIqvXcDKoWtz9maiSDDZWQoAhLiDuS8o=;
> Received: from andrew by vps0.lunn.ch with local (Exim 4.94.2)
> 	(envelope-from <andrew@lunn.ch>)
> 	id 1nxsKA-005eXu-EB; Sun, 05 Jun 2022 17:37:54 +0200
> Date: Sun, 5 Jun 2022 17:37:54 +0200
> From: Andrew Lunn <andrew@lunn.ch>
> To: Puranjay Mohan <p-mohan@ti.com>
> Subject: Re: [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver
> Message-ID: <YpzN0u+hRgVuzPX9@lunn.ch>
> References: <20220531095108.21757-1-p-mohan@ti.com>
>  <20220531095108.21757-3-p-mohan@ti.com>
> MIME-Version: 1.0
> Content-Disposition: inline
> In-Reply-To: <20220531095108.21757-3-p-mohan@ti.com>
> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
> X-CRM114-CacheID: sfid-20220605_083801_726047_1B97979E 
> X-CRM114-Status: GOOD (  26.73  )
> X-BeenThere: linux-arm-kernel@lists.infradead.org
> X-Mailman-Version: 2.1.34
> Precedence: list
> List-Id: <linux-arm-kernel.lists.infradead.org>
> List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-arm-kernel>,
>  <mailto:linux-arm-kernel-request@lists.infradead.org?subject=unsubscribe>
> List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
> List-Post: <mailto:linux-arm-kernel@lists.infradead.org>
> List-Help: <mailto:linux-arm-kernel-request@lists.infradead.org?subject=help>
> List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>,
>  <mailto:linux-arm-kernel-request@lists.infradead.org?subject=subscribe>
> Cc: nm@ti.com, devicetree@vger.kernel.org, grygorii.strashko@ti.com, vigneshr@ti.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, kishon@ti.com, rogerq@kernel.org, afd@ti.com, edumazet@google.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, ssantosh@kernel.org, davem@davemloft.net, linux-arm-kernel@lists.infradead.org
> Content-Type: text/plain; charset="us-ascii"
> Content-Transfer-Encoding: 7bit
> Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
> Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org
> 
>> +static inline u32 addr_to_da0(const u8 *addr)
>> +{
>> +	return (u32)(addr[0] | addr[1] << 8 |
>> +		addr[2] << 16 | addr[3] << 24);
>> +};
>> +
>> +static inline u32 addr_to_da1(const u8 *addr)
>> +{
>> +	return (u32)(addr[4] | addr[5] << 8);
>> +};
> 
> No inline functions please.
> 
>> +
>> +static void rx_class_ft1_set_start_len(struct regmap *miig_rt, int slice,
>> +				       u16 start, u8 len)
>> +{
>> +	u32 offset, val;
>> +
>> +	offset = offs[slice].ft1_start_len;
>> +	val = FT1_LEN(len) | FT1_START(start);
>> +	regmap_write(miig_rt, offset, val);
>> +}
>> +
>> +static void rx_class_ft1_set_da(struct regmap *miig_rt, int slice,
>> +				int n, const u8 *addr)
>> +{
>> +	u32 offset;
>> +
>> +	offset = FT1_N_REG(slice, n, FT1_DA0);
>> +	regmap_write(miig_rt, offset, addr_to_da0(addr));
>> +	offset = FT1_N_REG(slice, n, FT1_DA1);
>> +	regmap_write(miig_rt, offset, addr_to_da1(addr));
>> +}
>> +
>> +static void rx_class_ft1_set_da_mask(struct regmap *miig_rt, int slice,
>> +				     int n, const u8 *addr)
>> +{
>> +	u32 offset;
>> +
>> +	offset = FT1_N_REG(slice, n, FT1_DA0_MASK);
>> +	regmap_write(miig_rt, offset, addr_to_da0(addr));
>> +	offset = FT1_N_REG(slice, n, FT1_DA1_MASK);
>> +	regmap_write(miig_rt, offset, addr_to_da1(addr));
>> +}
>> +
>> +static void rx_class_ft1_cfg_set_type(struct regmap *miig_rt, int slice, int n,
>> +				      enum ft1_cfg_type type)
>> +{
>> +	u32 offset;
>> +
>> +	offset = offs[slice].ft1_cfg;
>> +	regmap_update_bits(miig_rt, offset, FT1_CFG_MASK(n),
>> +			   type << FT1_CFG_SHIFT(n));
>> +}
>> +
>> +static void rx_class_sel_set_type(struct regmap *miig_rt, int slice, int n,
>> +				  enum rx_class_sel_type type)
>> +{
>> +	u32 offset;
>> +
>> +	offset = offs[slice].rx_class_cfg1;
>> +	regmap_update_bits(miig_rt, offset, RX_CLASS_SEL_MASK(n),
>> +			   type << RX_CLASS_SEL_SHIFT(n));
>> +}
>> +
>> +static void rx_class_set_and(struct regmap *miig_rt, int slice, int n,
>> +			     u32 data)
>> +{
>> +	u32 offset;
>> +
>> +	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_AND_EN);
>> +	regmap_write(miig_rt, offset, data);
>> +}
>> +
>> +static void rx_class_set_or(struct regmap *miig_rt, int slice, int n,
>> +			    u32 data)
>> +{
>> +	u32 offset;
>> +
>> +	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN);
>> +	regmap_write(miig_rt, offset, data);
>> +}
>> +
>> +void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac)
>> +{
>> +	regmap_write(miig_rt, MAC_INTERFACE_0, addr_to_da0(mac));
>> +	regmap_write(miig_rt, MAC_INTERFACE_1, addr_to_da1(mac));
>> +}
>> +
>> +void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac)
>> +{
>> +	regmap_write(miig_rt, offs[slice].mac0, addr_to_da0(mac));
>> +	regmap_write(miig_rt, offs[slice].mac1, addr_to_da1(mac));
>> +}
>> +
>> +/* disable all RX traffic */
>> +void icssg_class_disable(struct regmap *miig_rt, int slice)
>> +{
>> +	u32 data, offset;
>> +	int n;
>> +
>> +	/* Enable RX_L2_G */
>> +	regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_RX_L2_G_EN,
>> +			   ICSSG_CFG_RX_L2_G_EN);
>> +
>> +	for (n = 0; n < ICSSG_NUM_CLASSIFIERS; n++) {
>> +		/* AND_EN = 0 */
>> +		rx_class_set_and(miig_rt, slice, n, 0);
>> +		/* OR_EN = 0 */
>> +		rx_class_set_or(miig_rt, slice, n, 0);
>> +
>> +		/* set CFG1 to OR */
>> +		rx_class_sel_set_type(miig_rt, slice, n, RX_CLASS_SEL_TYPE_OR);
>> +
>> +		/* configure gate */
>> +		offset = RX_CLASS_GATES_N_REG(slice, n);
>> +		regmap_read(miig_rt, offset, &data);
>> +		/* clear class_raw so we go through filters */
>> +		data &= ~RX_CLASS_GATES_RAW_MASK;
>> +		/* set allow and phase mask */
>> +		data |= RX_CLASS_GATES_ALLOW_MASK | RX_CLASS_GATES_PHASE_MASK;
>> +		regmap_write(miig_rt, offset, data);
>> +	}
>> +
>> +	/* FT1 Disabled */
>> +	for (n = 0; n < ICSSG_NUM_FT1_SLOTS; n++) {
>> +		u8 addr[] = { 0, 0, 0, 0, 0, 0, };
>> +
>> +		rx_class_ft1_cfg_set_type(miig_rt, slice, n,
>> +					  FT1_CFG_TYPE_DISABLED);
>> +		rx_class_ft1_set_da(miig_rt, slice, n, addr);
>> +		rx_class_ft1_set_da_mask(miig_rt, slice, n, addr);
>> +	}
>> +
>> +	/* clear CFG2 */
>> +	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
>> +}
>> +
>> +void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti)
>> +{
>> +	int classifiers_in_use = 1;
>> +	u32 data;
>> +	int n;
>> +
>> +	/* defaults */
>> +	icssg_class_disable(miig_rt, slice);
>> +
>> +	/* Setup Classifier */
>> +	for (n = 0; n < classifiers_in_use; n++) {
>> +		/* match on Broadcast or MAC_PRU address */
>> +		data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P;
>> +
>> +		/* multicast? */
>> +		if (allmulti)
>> +			data |= RX_CLASS_FT_MC;
>> +
>> +		rx_class_set_or(miig_rt, slice, n, data);
>> +
>> +		/* set CFG1 for OR_OR_AND for classifier */
>> +		rx_class_sel_set_type(miig_rt, slice, n,
>> +				      RX_CLASS_SEL_TYPE_OR_OR_AND);
>> +	}
>> +
>> +	/* clear CFG2 */
>> +	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
>> +}
>> +
>> +/* required for SAV check */
>> +void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr)
>> +{
>> +	u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, };
>> +
>> +	rx_class_ft1_set_start_len(miig_rt, slice, 0, 6);
>> +	rx_class_ft1_set_da(miig_rt, slice, 0, mac_addr);
>> +	rx_class_ft1_set_da_mask(miig_rt, slice, 0, mask_addr);
>> +	rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ);
>> +}
>> diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c
>> new file mode 100644
>> index 000000000000..a88ea4933802
>> --- /dev/null
>> +++ b/drivers/net/ethernet/ti/icssg_config.c
>> @@ -0,0 +1,440 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* ICSSG Ethernet driver
>> + *
>> + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com
>> + */
>> +
>> +#include <linux/iopoll.h>
>> +#include <linux/regmap.h>
>> +#include <uapi/linux/if_ether.h>
>> +#include "icssg_config.h"
>> +#include "icssg_prueth.h"
>> +#include "icssg_switch_map.h"
>> +#include "icssg_mii_rt.h"
>> +
>> +/* TX IPG Values to be set for 100M link speed. These values are
>> + * in ocp_clk cycles. So need change if ocp_clk is changed for a specific
>> + * h/w design.
>> + */
>> +
>> +/* IPG is in core_clk cycles */
>> +#define MII_RT_TX_IPG_100M	0x17
>> +#define MII_RT_TX_IPG_1G	0xb
>> +
>> +#define	ICSSG_QUEUES_MAX		64
>> +#define	ICSSG_QUEUE_OFFSET		0xd00
>> +#define	ICSSG_QUEUE_PEEK_OFFSET		0xe00
>> +#define	ICSSG_QUEUE_CNT_OFFSET		0xe40
>> +#define	ICSSG_QUEUE_RESET_OFFSET	0xf40
>> +
>> +#define	ICSSG_NUM_TX_QUEUES	8
>> +
>> +#define	RECYCLE_Q_SLICE0	16
>> +#define	RECYCLE_Q_SLICE1	17
>> +
>> +#define	ICSSG_NUM_OTHER_QUEUES	5	/* port, host and special queues */
>> +
>> +#define	PORT_HI_Q_SLICE0	32
>> +#define	PORT_LO_Q_SLICE0	33
>> +#define	HOST_HI_Q_SLICE0	34
>> +#define	HOST_LO_Q_SLICE0	35
>> +#define	HOST_SPL_Q_SLICE0	40	/* Special Queue */
>> +
>> +#define	PORT_HI_Q_SLICE1	36
>> +#define	PORT_LO_Q_SLICE1	37
>> +#define	HOST_HI_Q_SLICE1	38
>> +#define	HOST_LO_Q_SLICE1	39
>> +#define	HOST_SPL_Q_SLICE1	41	/* Special Queue */
>> +
>> +#define MII_RXCFG_DEFAULT	(PRUSS_MII_RT_RXCFG_RX_ENABLE | \
>> +				 PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS | \
>> +				 PRUSS_MII_RT_RXCFG_RX_L2_EN | \
>> +				 PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS)
>> +
>> +#define MII_TXCFG_DEFAULT	(PRUSS_MII_RT_TXCFG_TX_ENABLE | \
>> +				 PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE | \
>> +				 PRUSS_MII_RT_TXCFG_TX_32_MODE_EN | \
>> +				 PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN)
>> +
>> +#define ICSSG_CFG_DEFAULT	(ICSSG_CFG_TX_L1_EN | \
>> +				 ICSSG_CFG_TX_L2_EN | ICSSG_CFG_RX_L2_G_EN | \
>> +				 ICSSG_CFG_TX_PRU_EN | \
>> +				 ICSSG_CFG_SGMII_MODE)
>> +
>> +#define FDB_GEN_CFG1		0x60
>> +#define SMEM_VLAN_OFFSET	8
>> +#define SMEM_VLAN_OFFSET_MASK	GENMASK(25, 8)
>> +
>> +#define FDB_GEN_CFG2		0x64
>> +#define FDB_VLAN_EN		BIT(6)
>> +#define FDB_HOST_EN		BIT(2)
>> +#define FDB_PRU1_EN		BIT(1)
>> +#define FDB_PRU0_EN		BIT(0)
>> +#define FDB_EN_ALL		(FDB_PRU0_EN | FDB_PRU1_EN | \
>> +				 FDB_HOST_EN | FDB_VLAN_EN)
>> +
>> +struct map {
>> +	int queue;
>> +	u32 pd_addr_start;
>> +	u32 flags;
>> +	bool special;
>> +};
>> +
>> +struct map hwq_map[2][ICSSG_NUM_OTHER_QUEUES] = {
>> +	{
>> +		{ PORT_HI_Q_SLICE0, PORT_DESC0_HI, 0x200000, 0 },
>> +		{ PORT_LO_Q_SLICE0, PORT_DESC0_LO, 0, 0 },
>> +		{ HOST_HI_Q_SLICE0, HOST_DESC0_HI, 0x200000, 0 },
>> +		{ HOST_LO_Q_SLICE0, HOST_DESC0_LO, 0, 0 },
>> +		{ HOST_SPL_Q_SLICE0, HOST_SPPD0, 0x400000, 1 },
>> +	},
>> +	{
>> +		{ PORT_HI_Q_SLICE1, PORT_DESC1_HI, 0xa00000, 0 },
>> +		{ PORT_LO_Q_SLICE1, PORT_DESC1_LO, 0x800000, 0 },
>> +		{ HOST_HI_Q_SLICE1, HOST_DESC1_HI, 0xa00000, 0 },
>> +		{ HOST_LO_Q_SLICE1, HOST_DESC1_LO, 0x800000, 0 },
>> +		{ HOST_SPL_Q_SLICE1, HOST_SPPD1, 0xc00000, 1 },
>> +	},
>> +};
>> +
>> +static void icssg_config_mii_init(struct prueth_emac *emac)
>> +{
>> +	struct prueth *prueth = emac->prueth;
>> +	struct regmap *mii_rt = prueth->mii_rt;
>> +	int slice = prueth_emac_slice(emac);
>> +	u32 rxcfg_reg, txcfg_reg, pcnt_reg;
>> +	u32 rxcfg, txcfg;
>> +
>> +	rxcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 :
>> +				       PRUSS_MII_RT_RXCFG1;
>> +	txcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 :
>> +				       PRUSS_MII_RT_TXCFG1;
>> +	pcnt_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 :
>> +				       PRUSS_MII_RT_RX_PCNT1;
>> +
>> +	rxcfg = MII_RXCFG_DEFAULT;
>> +	txcfg = MII_TXCFG_DEFAULT;
>> +
>> +	if (slice == ICSS_MII1)
>> +		rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL;
>> +
>> +	/* In MII mode TX lines swapped inside ICSSG, so TX_MUX_SEL cfg need
>> +	 * to be swapped also comparing to RGMII mode.
>> +	 */
>> +	if (emac->phy_if == PHY_INTERFACE_MODE_MII && slice == ICSS_MII0)
>> +		txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
>> +	else if (emac->phy_if != PHY_INTERFACE_MODE_MII && slice == ICSS_MII1)
>> +		txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
>> +
>> +	regmap_write(mii_rt, rxcfg_reg, rxcfg);
>> +	regmap_write(mii_rt, txcfg_reg, txcfg);
>> +	regmap_write(mii_rt, pcnt_reg, 0x1);
>> +}
>> +
>> +static void icssg_miig_queues_init(struct prueth *prueth, int slice)
>> +{
>> +	struct regmap *miig_rt = prueth->miig_rt;
>> +	void __iomem *smem = prueth->shram.va;
>> +	u8 pd[ICSSG_SPECIAL_PD_SIZE];
>> +	int queue = 0, i, j;
>> +	u32 *pdword;
>> +
>> +	/* reset hwqueues */
>> +	if (slice)
>> +		queue = ICSSG_NUM_TX_QUEUES;
>> +
>> +	for (i = 0; i < ICSSG_NUM_TX_QUEUES; i++) {
>> +		regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
>> +		queue++;
>> +	}
>> +
>> +	queue = slice ? RECYCLE_Q_SLICE1 : RECYCLE_Q_SLICE0;
>> +	regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
>> +
>> +	for (i = 0; i < ICSSG_NUM_OTHER_QUEUES; i++) {
>> +		regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET,
>> +			     hwq_map[slice][i].queue);
>> +	}
>> +
>> +	/* initialize packet descriptors in SMEM */
>> +	/* push pakcet descriptors to hwqueues */
>> +
>> +	pdword = (u32 *)pd;
>> +	for (j = 0; j < ICSSG_NUM_OTHER_QUEUES; j++) {
>> +		struct map *mp;
>> +		int pd_size, num_pds;
>> +		u32 pdaddr;
>> +
>> +		mp = &hwq_map[slice][j];
>> +		if (mp->special) {
>> +			pd_size = ICSSG_SPECIAL_PD_SIZE;
>> +			num_pds = ICSSG_NUM_SPECIAL_PDS;
>> +		} else	{
>> +			pd_size = ICSSG_NORMAL_PD_SIZE;
>> +			num_pds = ICSSG_NUM_NORMAL_PDS;
>> +		}
>> +
>> +		for (i = 0; i < num_pds; i++) {
>> +			memset(pd, 0, pd_size);
>> +
>> +			pdword[0] &= cpu_to_le32(ICSSG_FLAG_MASK);
>> +			pdword[0] |= cpu_to_le32(mp->flags);
>> +			pdaddr = mp->pd_addr_start + i * pd_size;
>> +
>> +			memcpy_toio(smem + pdaddr, pd, pd_size);
>> +			queue = mp->queue;
>> +			regmap_write(miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue,
>> +				     pdaddr);
>> +		}
>> +	}
>> +}
>> +
>> +void icssg_config_ipg(struct prueth_emac *emac)
>> +{
>> +	struct prueth *prueth = emac->prueth;
>> +	int slice = prueth_emac_slice(emac);
>> +
>> +	switch (emac->speed) {
>> +	case SPEED_1000:
>> +		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_1G);
>> +		break;
>> +	case SPEED_100:
>> +		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M);
>> +		break;
>> +	default:
>> +		/* Other links speeds not supported */
>> +		netdev_err(emac->ndev, "Unsupported link speed\n");
>> +		return;
>> +	}
>> +}
>> +
>> +static void emac_r30_cmd_init(struct prueth_emac *emac)
>> +{
>> +	int i;
>> +	struct icssg_r30_cmd *p;
>> +
>> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
>> +
>> +	for (i = 0; i < 4; i++)
>> +		writel(EMAC_NONE, &p->cmd[i]);
>> +}
>> +
>> +static int emac_r30_is_done(struct prueth_emac *emac)
>> +{
>> +	const struct icssg_r30_cmd *p;
>> +	int i;
>> +	u32 cmd;
>> +
>> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
>> +
>> +	for (i = 0; i < 4; i++) {
>> +		cmd = readl(&p->cmd[i]);
>> +		if (cmd != EMAC_NONE)
>> +			return 0;
>> +	}
>> +
>> +	return 1;
>> +}
>> +
>> +static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>> +{
>> +	struct icssg_buffer_pool_cfg *bpool_cfg;
>> +	struct prueth *prueth = emac->prueth;
>> +	int slice = prueth_emac_slice(emac);
>> +	struct icssg_rxq_ctx *rxq_ctx;
>> +	u32 addr;
>> +	int i;
>> +
>> +	/* Layout to have 64KB aligned buffer pool
>> +	 * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1|
>> +	 */
>> +
>> +	addr = lower_32_bits(prueth->msmcram.pa);
>> +	if (slice)
>> +		addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
>> +
>> +	if (addr % SZ_64K) {
>> +		dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET;
>> +	/* workaround for f/w bug. bpool 0 needs to be initilalized */
>> +	bpool_cfg[0].addr = cpu_to_le32(addr);
>> +	bpool_cfg[0].len = 0;
>> +
>> +	for (i = PRUETH_EMAC_BUF_POOL_START;
>> +	     i < (PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS);
>> +	     i++) {
>> +		bpool_cfg[i].addr = cpu_to_le32(addr);
>> +		bpool_cfg[i].len = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE);
>> +		addr += PRUETH_EMAC_BUF_POOL_SIZE;
>> +	}
>> +
>> +	if (!slice)
>> +		addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
>> +	else
>> +		addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2;
>> +
>> +	/* Pre-emptible RX buffer queue */
>> +	rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET;
>> +	for (i = 0; i < 3; i++)
>> +		rxq_ctx->start[i] = cpu_to_le32(addr);
>> +
>> +	addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
>> +	rxq_ctx->end = cpu_to_le32(addr);
>> +
>> +	/* Express RX buffer queue */
>> +	rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET;
>> +	for (i = 0; i < 3; i++)
>> +		rxq_ctx->start[i] = cpu_to_le32(addr);
>> +
>> +	addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
>> +	rxq_ctx->end = cpu_to_le32(addr);
>> +
>> +	return 0;
>> +}
>> +
>> +static void icssg_init_emac_mode(struct prueth *prueth)
>> +{
>> +	/* When the device is configured as a bridge and it is being brought back
>> +	 * to the emac mode, the host mac address has to be set as 0.
>> +	 */
>> +	u8 mac[ETH_ALEN] = { 0 };
>> +
>> +	if (prueth->emacs_initialized)
>> +		return;
>> +
>> +	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, 0);
>> +	regmap_write(prueth->miig_rt, FDB_GEN_CFG2, 0);
>> +	/* Clear host MAC address */
>> +	icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
>> +}
>> +
>> +int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>> +{
>> +	void *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
>> +	u8 *cfg_byte_ptr = config;
>> +	struct icssg_flow_cfg *flow_cfg;
>> +	u32 mask;
>> +	int ret;
>> +
>> +	icssg_init_emac_mode(prueth);
>> +
>> +	memset_io(config, 0, TAS_GATE_MASK_LIST0);
>> +	icssg_miig_queues_init(prueth, slice);
>> +
>> +	emac->speed = SPEED_1000;
>> +	emac->duplex = DUPLEX_FULL;
>> +	if (!phy_interface_mode_is_rgmii(emac->phy_if)) {
>> +		emac->speed = SPEED_100;
>> +		emac->duplex = DUPLEX_FULL;
>> +	}
>> +	regmap_update_bits(prueth->miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_DEFAULT, ICSSG_CFG_DEFAULT);
>> +	icssg_miig_set_interface_mode(prueth->miig_rt, slice, emac->phy_if);
>> +	icssg_config_mii_init(emac);
>> +	icssg_config_ipg(emac);
>> +	icssg_update_rgmii_cfg(prueth->miig_rt, emac);
>> +
>> +	/* set GPI mode */
>> +	pruss_cfg_gpimode(prueth->pruss, prueth->pru_id[slice],
>> +			  PRUSS_GPI_MODE_MII);
>> +
>> +	/* enable XFR shift for PRU and RTU */
>> +	mask = PRUSS_SPP_XFER_SHIFT_EN | PRUSS_SPP_RTU_XFR_SHIFT_EN;
>> +	pruss_cfg_update(prueth->pruss, PRUSS_CFG_SPP, mask, mask);
>> +
>> +	/* set C28 to 0x100 */
>> +	pru_rproc_set_ctable(prueth->pru[slice], PRU_C28, 0x100 << 8);
>> +	pru_rproc_set_ctable(prueth->rtu[slice], PRU_C28, 0x100 << 8);
>> +	pru_rproc_set_ctable(prueth->txpru[slice], PRU_C28, 0x100 << 8);
>> +
>> +	flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
>> +	flow_cfg->rx_base_flow = cpu_to_le32(emac->rx_flow_id_base);
>> +	flow_cfg->mgm_base_flow = 0;
>> +	*(cfg_byte_ptr + SPL_PKT_DEFAULT_PRIORITY) = 0;
>> +	*(cfg_byte_ptr + QUEUE_NUM_UNTAGGED) = 0x0;
>> +
>> +	ret = prueth_emac_buffer_setup(emac);
>> +	if (ret)
>> +		return ret;
>> +
>> +	emac_r30_cmd_init(emac);
>> +
>> +	return 0;
>> +}
>> +
>> +static struct icssg_r30_cmd emac_r32_bitmask[] = {
>> +	{{0xffff0004, 0xffff0100, 0xffff0100, EMAC_NONE}},	/* EMAC_PORT_DISABLE */
>> +	{{0xfffb0040, 0xfeff0200, 0xfeff0200, EMAC_NONE}},	/* EMAC_PORT_BLOCK */
>> +	{{0xffbb0000, 0xfcff0000, 0xdcff0000, EMAC_NONE}},	/* EMAC_PORT_FORWARD */
>> +	{{0xffbb0000, 0xfcff0000, 0xfcff2000, EMAC_NONE}},	/* EMAC_PORT_FORWARD_WO_LEARNING */
>> +	{{0xffff0001, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT ALL */
>> +	{{0xfffe0002, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT TAGGED */
>> +	{{0xfffc0000, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},	/* ACCEPT UNTAGGED and PRIO */
>> +	{{EMAC_NONE,  0xffff0020, EMAC_NONE, EMAC_NONE}},	/* TAS Trigger List change */
>> +	{{EMAC_NONE,  0xdfff1000, EMAC_NONE, EMAC_NONE}},	/* TAS set state ENABLE*/
>> +	{{EMAC_NONE,  0xefff2000, EMAC_NONE, EMAC_NONE}},	/* TAS set state RESET*/
>> +	{{EMAC_NONE,  0xcfff0000, EMAC_NONE, EMAC_NONE}},	/* TAS set state DISABLE*/
>> +	{{EMAC_NONE,  EMAC_NONE,  0xffff0400, EMAC_NONE}},	/* UC flooding ENABLE*/
>> +	{{EMAC_NONE,  EMAC_NONE,  0xfbff0000, EMAC_NONE}},	/* UC flooding DISABLE*/
>> +	{{EMAC_NONE,  EMAC_NONE,  0xffff0800, EMAC_NONE}},	/* MC flooding ENABLE*/
>> +	{{EMAC_NONE,  EMAC_NONE,  0xf7ff0000, EMAC_NONE}},	/* MC flooding DISABLE*/
>> +	{{EMAC_NONE,  0xffff4000, EMAC_NONE, EMAC_NONE}},	/* Preemption on Tx ENABLE*/
>> +	{{EMAC_NONE,  0xbfff0000, EMAC_NONE, EMAC_NONE}},	/* Preemption on Tx DISABLE*/
>> +	{{0xffff0010,  EMAC_NONE, 0xffff0010, EMAC_NONE}},	/* VLAN AWARE*/
>> +	{{0xffef0000,  EMAC_NONE, 0xffef0000, EMAC_NONE}}	/* VLAN UNWARE*/
>> +};
>> +
>> +int emac_set_port_state(struct prueth_emac *emac,
>> +			enum icssg_port_state_cmd cmd)
>> +{
>> +	struct icssg_r30_cmd *p;
>> +	int ret = -ETIMEDOUT;
>> +	int done = 0;
>> +	int i;
>> +
>> +	p = emac->dram.va + MGR_R30_CMD_OFFSET;
>> +
>> +	if (cmd >= ICSSG_EMAC_PORT_MAX_COMMANDS) {
>> +		netdev_err(emac->ndev, "invalid port command\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* only one command at a time allowed to firmware */
>> +	mutex_lock(&emac->cmd_lock);
>> +
>> +	for (i = 0; i < 4; i++)
>> +		writel(emac_r32_bitmask[cmd].cmd[i], &p->cmd[i]);
>> +
>> +	/* wait for done */
>> +	ret = read_poll_timeout(emac_r30_is_done, done, done == 1,
>> +				1000, 10000, false, emac);
>> +
>> +	if (ret == -ETIMEDOUT)
>> +		netdev_err(emac->ndev, "timeout waiting for command done\n");
>> +
>> +	mutex_unlock(&emac->cmd_lock);
>> +
>> +	return ret;
>> +}
>> +
>> +void icssg_config_set_speed(struct prueth_emac *emac)
>> +{
>> +	u8 fw_speed;
>> +
>> +	switch (emac->speed) {
>> +	case SPEED_1000:
>> +		fw_speed = FW_LINK_SPEED_1G;
>> +		break;
>> +	case SPEED_100:
>> +		fw_speed = FW_LINK_SPEED_100M;
>> +		break;
>> +	default:
>> +		/* Other links speeds not supported */
>> +		netdev_err(emac->ndev, "Unsupported link speed\n");
>> +		return;
>> +	}
>> +
>> +	writeb(fw_speed, emac->dram.va + PORT_LINK_SPEED_OFFSET);
>> +}
>> diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h
>> new file mode 100644
>> index 000000000000..43eb0922172a
>> --- /dev/null
>> +++ b/drivers/net/ethernet/ti/icssg_config.h
>> @@ -0,0 +1,200 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Texas Instruments ICSSG Ethernet driver
>> + *
>> + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
>> + *
>> + */
>> +
>> +#ifndef __NET_TI_ICSSG_CONFIG_H
>> +#define __NET_TI_ICSSG_CONFIG_H
>> +
>> +struct icssg_buffer_pool_cfg {
>> +	__le32	addr;
>> +	__le32	len;
>> +} __packed;
>> +
>> +struct icssg_flow_cfg {
>> +	__le16 rx_base_flow;
>> +	__le16 mgm_base_flow;
>> +} __packed;
>> +
>> +#define PRUETH_PKT_TYPE_CMD	0x10
>> +#define PRUETH_NAV_PS_DATA_SIZE	16	/* Protocol specific data size */
>> +#define PRUETH_NAV_SW_DATA_SIZE	16	/* SW related data size */
>> +#define PRUETH_MAX_TX_DESC	512
>> +#define PRUETH_MAX_RX_DESC	512
>> +#define PRUETH_MAX_RX_FLOWS	1	/* excluding default flow */
>> +#define PRUETH_RX_FLOW_DATA	0
>> +
>> +#define PRUETH_EMAC_BUF_POOL_SIZE	SZ_8K
>> +#define PRUETH_EMAC_POOLS_PER_SLICE	24
>> +#define PRUETH_EMAC_BUF_POOL_START	8
>> +#define PRUETH_NUM_BUF_POOLS	8
>> +#define PRUETH_EMAC_RX_CTX_BUF_SIZE	SZ_16K	/* per slice */
>> +#define MSMC_RAM_SIZE	\
>> +	(2 * (PRUETH_EMAC_BUF_POOL_SIZE * PRUETH_NUM_BUF_POOLS + \
>> +	 PRUETH_EMAC_RX_CTX_BUF_SIZE * 2))
>> +
>> +struct icssg_rxq_ctx {
>> +	__le32 start[3];
>> +	__le32 end;
>> +} __packed;
>> +
>> +/* Load time Fiwmware Configuration */
>> +
>> +#define ICSSG_FW_MGMT_CMD_HEADER	0x81
>> +#define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
>> +#define ICSSG_FW_MGMT_CMD_TYPE		0x04
>> +#define ICSSG_FW_MGMT_PKT		0x80000000
>> +
>> +struct icssg_r30_cmd {
>> +	u32 cmd[4];
>> +} __packed;
>> +
>> +enum icssg_port_state_cmd {
>> +	ICSSG_EMAC_PORT_DISABLE = 0,
>> +	ICSSG_EMAC_PORT_BLOCK,
>> +	ICSSG_EMAC_PORT_FORWARD,
>> +	ICSSG_EMAC_PORT_FORWARD_WO_LEARNING,
>> +	ICSSG_EMAC_PORT_ACCEPT_ALL,
>> +	ICSSG_EMAC_PORT_ACCEPT_TAGGED,
>> +	ICSSG_EMAC_PORT_ACCEPT_UNTAGGED_N_PRIO,
>> +	ICSSG_EMAC_PORT_TAS_TRIGGER,
>> +	ICSSG_EMAC_PORT_TAS_ENABLE,
>> +	ICSSG_EMAC_PORT_TAS_RESET,
>> +	ICSSG_EMAC_PORT_TAS_DISABLE,
>> +	ICSSG_EMAC_PORT_UC_FLOODING_ENABLE,
>> +	ICSSG_EMAC_PORT_UC_FLOODING_DISABLE,
>> +	ICSSG_EMAC_PORT_MC_FLOODING_ENABLE,
>> +	ICSSG_EMAC_PORT_MC_FLOODING_DISABLE,
>> +	ICSSG_EMAC_PORT_PREMPT_TX_ENABLE,
>> +	ICSSG_EMAC_PORT_PREMPT_TX_DISABLE,
>> +	ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE,
>> +	ICSSG_EMAC_PORT_VLAN_AWARE_DISABLE,
>> +	ICSSG_EMAC_PORT_MAX_COMMANDS
>> +};
>> +
>> +#define EMAC_NONE           0xffff0000
>> +#define EMAC_PRU0_P_DI      0xffff0004
>> +#define EMAC_PRU1_P_DI      0xffff0040
>> +#define EMAC_TX_P_DI        0xffff0100
>> +
>> +#define EMAC_PRU0_P_EN      0xfffb0000
>> +#define EMAC_PRU1_P_EN      0xffbf0000
>> +#define EMAC_TX_P_EN        0xfeff0000
>> +
>> +#define EMAC_P_BLOCK        0xffff0040
>> +#define EMAC_TX_P_BLOCK     0xffff0200
>> +#define EMAC_P_UNBLOCK      0xffbf0000
>> +#define EMAC_TX_P_UNBLOCK   0xfdff0000
>> +#define EMAC_LEAN_EN        0xfff70000
>> +#define EMAC_LEAN_DI        0xffff0008
>> +
>> +#define EMAC_ACCEPT_ALL     0xffff0001
>> +#define EMAC_ACCEPT_TAG     0xfffe0002
>> +#define EMAC_ACCEPT_PRIOR   0xfffc0000
>> +
>> +/* Config area lies in DRAM */
>> +#define ICSSG_CONFIG_OFFSET	0x0
>> +
>> +/* Config area lies in shared RAM */
>> +#define ICSSG_CONFIG_OFFSET_SLICE0   0
>> +#define ICSSG_CONFIG_OFFSET_SLICE1   0x8000
>> +
>> +#define ICSSG_NUM_NORMAL_PDS	64
>> +#define ICSSG_NUM_SPECIAL_PDS	16
>> +
>> +#define ICSSG_NORMAL_PD_SIZE	8
>> +#define ICSSG_SPECIAL_PD_SIZE	20
>> +
>> +#define ICSSG_FLAG_MASK		0xff00ffff
>> +
>> +struct icssg_setclock_desc {
>> +	u8 request;
>> +	u8 restore;
>> +	u8 acknowledgment;
>> +	u8 cmp_status;
>> +	u32 margin;
>> +	u32 cyclecounter0_set;
>> +	u32 cyclecounter1_set;
>> +	u32 iepcount_set;
>> +	u32 rsvd1;
>> +	u32 rsvd2;
>> +	u32 CMP0_current;
>> +	u32 iepcount_current;
>> +	u32 difference;
>> +	u32 cyclecounter0_new;
>> +	u32 cyclecounter1_new;
>> +	u32 CMP0_new;
>> +} __packed;
>> +
>> +#define ICSSG_CMD_POP_SLICE0	56
>> +#define ICSSG_CMD_POP_SLICE1	60
>> +
>> +#define ICSSG_CMD_PUSH_SLICE0	57
>> +#define ICSSG_CMD_PUSH_SLICE1	61
>> +
>> +#define ICSSG_RSP_POP_SLICE0	58
>> +#define ICSSG_RSP_POP_SLICE1	62
>> +
>> +#define ICSSG_RSP_PUSH_SLICE0	56
>> +#define ICSSG_RSP_PUSH_SLICE1	60
>> +
>> +#define ICSSG_TS_POP_SLICE0	59
>> +#define ICSSG_TS_POP_SLICE1	63
>> +
>> +#define ICSSG_TS_PUSH_SLICE0	40
>> +#define ICSSG_TS_PUSH_SLICE1	41
>> +
>> +/* FDB FID_C2 flag definitions */
>> +/* Indicates host port membership.*/
>> +#define ICSSG_FDB_ENTRY_P0_MEMBERSHIP         BIT(0)
>> +/* Indicates that MAC ID is connected to physical port 1 */
>> +#define ICSSG_FDB_ENTRY_P1_MEMBERSHIP         BIT(1)
>> +/* Indicates that MAC ID is connected to physical port 2 */
>> +#define ICSSG_FDB_ENTRY_P2_MEMBERSHIP         BIT(2)
>> +/* Ageable bit is set for learned entries and cleared for static entries */
>> +#define ICSSG_FDB_ENTRY_AGEABLE               BIT(3)
>> +/* If set for DA then packet is determined to be a special packet */
>> +#define ICSSG_FDB_ENTRY_BLOCK                 BIT(4)
>> +/* If set for DA then the SA from the packet is not learned */
>> +#define ICSSG_FDB_ENTRY_SECURE                BIT(5)
>> +/* If set, it means packet has been seen recently with source address + FID
>> + * matching MAC address/FID of entry
>> + */
>> +#define ICSSG_FDB_ENTRY_TOUCHED               BIT(6)
>> +/* Set if entry is valid */
>> +#define ICSSG_FDB_ENTRY_VALID                 BIT(7)
>> +
>> +/**
>> + * struct prueth_vlan_tbl - VLAN table entries struct in ICSSG SMEM
>> + * @fid_c1: membership and forwarding rules flag to this table. See
>> + *          above to defines for bit definitions
>> + * @fid: FDB index for this VID (there is 1-1 mapping b/w VID and FID)
>> + */
>> +struct prueth_vlan_tbl {
>> +	u8 fid_c1;
>> +	u8 fid;
>> +} __packed;
>> +
>> +/**
>> + * struct prueth_fdb_slot - Result of FDB slot lookup
>> + * @mac: MAC address
>> + * @fid: fid to be associated with MAC
>> + * @fid_c2: FID_C2 entry for this MAC
>> + */
>> +struct prueth_fdb_slot {
>> +	u8 mac[ETH_ALEN];
>> +	u8 fid;
>> +	u8 fid_c2;
>> +} __packed;
>> +
>> +enum icssg_ietfpe_verify_states {
>> +	ICSSG_IETFPE_STATE_UNKNOWN = 0,
>> +	ICSSG_IETFPE_STATE_INITIAL,
>> +	ICSSG_IETFPE_STATE_VERIFYING,
>> +	ICSSG_IETFPE_STATE_SUCCEEDED,
>> +	ICSSG_IETFPE_STATE_FAILED,
>> +	ICSSG_IETFPE_STATE_DISABLED
>> +};
>> +#endif /* __NET_TI_ICSSG_CONFIG_H */
>> diff --git a/drivers/net/ethernet/ti/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg_ethtool.c
>> new file mode 100644
>> index 000000000000..fd09d223b0ae
>> --- /dev/null
>> +++ b/drivers/net/ethernet/ti/icssg_ethtool.c
>> @@ -0,0 +1,319 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* Texas Instruments ICSSG Ethernet driver
>> + *
>> + * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
>> + *
>> + */
>> +
>> +#include "icssg_prueth.h"
>> +#include <linux/regmap.h>
>> +
>> +static u32 stats_base[] = {	0x54c,	/* Slice 0 stats start */
>> +				0xb18,	/* Slice 1 stats start */
>> +};
>> +
>> +struct miig_stats_regs {
>> +	/* Rx */
>> +	u32 rx_good_frames;
>> +	u32 rx_broadcast_frames;
>> +	u32 rx_multicast_frames;
>> +	u32 rx_crc_error_frames;
>> +	u32 rx_mii_error_frames;
>> +	u32 rx_odd_nibble_frames;
>> +	u32 rx_frame_max_size;
>> +	u32 rx_max_size_error_frames;
>> +	u32 rx_frame_min_size;
>> +	u32 rx_min_size_error_frames;
>> +	u32 rx_overrun_frames;
>> +	u32 rx_class0_hits;
>> +	u32 rx_class1_hits;
>> +	u32 rx_class2_hits;
>> +	u32 rx_class3_hits;
>> +	u32 rx_class4_hits;
>> +	u32 rx_class5_hits;
>> +	u32 rx_class6_hits;
>> +	u32 rx_class7_hits;
>> +	u32 rx_class8_hits;
>> +	u32 rx_class9_hits;
>> +	u32 rx_class10_hits;
>> +	u32 rx_class11_hits;
>> +	u32 rx_class12_hits;
>> +	u32 rx_class13_hits;
>> +	u32 rx_class14_hits;
>> +	u32 rx_class15_hits;
>> +	u32 rx_smd_frags;
>> +	u32 rx_bucket1_size;
>> +	u32 rx_bucket2_size;
>> +	u32 rx_bucket3_size;
>> +	u32 rx_bucket4_size;
>> +	u32 rx_64B_frames;
>> +	u32 rx_bucket1_frames;
>> +	u32 rx_bucket2_frames;
>> +	u32 rx_bucket3_frames;
>> +	u32 rx_bucket4_frames;
>> +	u32 rx_bucket5_frames;
>> +	u32 rx_total_bytes;
>> +	u32 rx_tx_total_bytes;
>> +	/* Tx */
>> +	u32 tx_good_frames;
>> +	u32 tx_broadcast_frames;
>> +	u32 tx_multicast_frames;
>> +	u32 tx_odd_nibble_frames;
>> +	u32 tx_underflow_errors;
>> +	u32 tx_frame_max_size;
>> +	u32 tx_max_size_error_frames;
>> +	u32 tx_frame_min_size;
>> +	u32 tx_min_size_error_frames;
>> +	u32 tx_bucket1_size;
>> +	u32 tx_bucket2_size;
>> +	u32 tx_bucket3_size;
>> +	u32 tx_bucket4_size;
>> +	u32 tx_64B_frames;
>> +	u32 tx_bucket1_frames;
>> +	u32 tx_bucket2_frames;
>> +	u32 tx_bucket3_frames;
>> +	u32 tx_bucket4_frames;
>> +	u32 tx_bucket5_frames;
>> +	u32 tx_total_bytes;
>> +};
>> +
>> +#define ICSSG_STATS(field)				\
>> +{							\
>> +	#field,						\
>> +	offsetof(struct miig_stats_regs, field),	\
>> +}
>> +
>> +struct icssg_stats {
>> +	char name[ETH_GSTRING_LEN];
>> +	u32 offset;
>> +};
>> +
>> +static const struct icssg_stats icssg_ethtool_stats[] = {
>> +	/* Rx */
>> +	ICSSG_STATS(rx_good_frames),
>> +	ICSSG_STATS(rx_broadcast_frames),
>> +	ICSSG_STATS(rx_multicast_frames),
>> +	ICSSG_STATS(rx_crc_error_frames),
>> +	ICSSG_STATS(rx_mii_error_frames),
>> +	ICSSG_STATS(rx_odd_nibble_frames),
>> +	ICSSG_STATS(rx_frame_max_size),
>> +	ICSSG_STATS(rx_max_size_error_frames),
>> +	ICSSG_STATS(rx_frame_min_size),
>> +	ICSSG_STATS(rx_min_size_error_frames),
>> +	ICSSG_STATS(rx_overrun_frames),
>> +	ICSSG_STATS(rx_class0_hits),
>> +	ICSSG_STATS(rx_class1_hits),
>> +	ICSSG_STATS(rx_class2_hits),
>> +	ICSSG_STATS(rx_class3_hits),
>> +	ICSSG_STATS(rx_class4_hits),
>> +	ICSSG_STATS(rx_class5_hits),
>> +	ICSSG_STATS(rx_class6_hits),
>> +	ICSSG_STATS(rx_class7_hits),
>> +	ICSSG_STATS(rx_class8_hits),
>> +	ICSSG_STATS(rx_class9_hits),
>> +	ICSSG_STATS(rx_class10_hits),
>> +	ICSSG_STATS(rx_class11_hits),
>> +	ICSSG_STATS(rx_class12_hits),
>> +	ICSSG_STATS(rx_class13_hits),
>> +	ICSSG_STATS(rx_class14_hits),
>> +	ICSSG_STATS(rx_class15_hits),
>> +	ICSSG_STATS(rx_smd_frags),
>> +	ICSSG_STATS(rx_bucket1_size),
>> +	ICSSG_STATS(rx_bucket2_size),
>> +	ICSSG_STATS(rx_bucket3_size),
>> +	ICSSG_STATS(rx_bucket4_size),
>> +	ICSSG_STATS(rx_64B_frames),
>> +	ICSSG_STATS(rx_bucket1_frames),
>> +	ICSSG_STATS(rx_bucket2_frames),
>> +	ICSSG_STATS(rx_bucket3_frames),
>> +	ICSSG_STATS(rx_bucket4_frames),
>> +	ICSSG_STATS(rx_bucket5_frames),
>> +	ICSSG_STATS(rx_total_bytes),
>> +	ICSSG_STATS(rx_tx_total_bytes),
>> +	/* Tx */
>> +	ICSSG_STATS(tx_good_frames),
>> +	ICSSG_STATS(tx_broadcast_frames),
>> +	ICSSG_STATS(tx_multicast_frames),
>> +	ICSSG_STATS(tx_odd_nibble_frames),
>> +	ICSSG_STATS(tx_underflow_errors),
>> +	ICSSG_STATS(tx_frame_max_size),
>> +	ICSSG_STATS(tx_max_size_error_frames),
>> +	ICSSG_STATS(tx_frame_min_size),
>> +	ICSSG_STATS(tx_min_size_error_frames),
>> +	ICSSG_STATS(tx_bucket1_size),
>> +	ICSSG_STATS(tx_bucket2_size),
>> +	ICSSG_STATS(tx_bucket3_size),
>> +	ICSSG_STATS(tx_bucket4_size),
>> +	ICSSG_STATS(tx_64B_frames),
>> +	ICSSG_STATS(tx_bucket1_frames),
>> +	ICSSG_STATS(tx_bucket2_frames),
>> +	ICSSG_STATS(tx_bucket3_frames),
>> +	ICSSG_STATS(tx_bucket4_frames),
>> +	ICSSG_STATS(tx_bucket5_frames),
>> +	ICSSG_STATS(tx_total_bytes),
>> +};
>> +
>> +static void emac_get_drvinfo(struct net_device *ndev,
>> +			     struct ethtool_drvinfo *info)
>> +{
>> +	struct prueth_emac *emac = netdev_priv(ndev);
>> +	struct prueth *prueth = emac->prueth;
>> +
>> +	strscpy(info->driver, dev_driver_string(prueth->dev),
>> +		sizeof(info->driver));
>> +	strscpy(info->bus_info, dev_name(prueth->dev), sizeof(info->bus_info));
>> +}
>> +
>> +static u32 emac_get_msglevel(struct net_device *ndev)
>> +{
>> +	struct prueth_emac *emac = netdev_priv(ndev);
>> +
>> +	return emac->msg_enable;
>> +}
>> +
>> +static void emac_set_msglevel(struct net_device *ndev, u32 value)
>> +{
>> +	struct prueth_emac *emac = netdev_priv(ndev);
>> +
>> +	emac->msg_enable = value;
>> +}
>> +
>> +static int emac_get_link_ksettings(struct net_device *ndev,
>> +				   struct ethtool_link_ksettings *ecmd)
>> +{
>> +	return phy_ethtool_get_link_ksettings(ndev, ecmd);
>> +}
>> +
>> +static int emac_set_link_ksettings(struct net_device *ndev,
>> +				   const struct ethtool_link_ksettings *ecmd)
>> +{
>> +	return phy_ethtool_set_link_ksettings(ndev, ecmd);
>> +}
>> +
>> +static int emac_get_eee(struct net_device *ndev, struct ethtool_eee *edata)
>> +{
>> +	if (!ndev->phydev)
>> +		return -EOPNOTSUPP;
>> +
>> +	return phy_ethtool_get_eee(ndev->phydev, edata);
>> +}
>> +
>> +static int emac_set_eee(struct net_device *ndev, struct ethtool_eee *edata)
>> +{
>> +	if (!ndev->phydev)
>> +		return -EOPNOTSUPP;
>> +
>> +	return phy_ethtool_set_eee(ndev->phydev, edata);
>> +}
>> +
>> +static int emac_nway_reset(struct net_device *ndev)
>> +{
>> +	return phy_ethtool_nway_reset(ndev);
>> +}
>> +
>> +static const char emac_ethtool_priv_flags[][ETH_GSTRING_LEN] = {
>> +#define EMAC_PRIV_IET_FRAME_PREEMPTION  BIT(0)
>> +	"iet-frame-preemption",
>> +#define EMAC_PRIV_IET_MAC_VERIFY                BIT(1)
>> +	"iet-mac-verify",
>> +};
> 
> Please move the #define outside of the array. They are not easy to
> see.
> 
> 	Andrew
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings
  2022-11-04  7:28     ` Md Danish Anwar
@ 2022-11-04 12:57       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 20+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-04 12:57 UTC (permalink / raw)
  To: Md Danish Anwar, linux-kernel
  Cc: nm, devicetree, vigneshr, andrew, netdev, kishon, rogerq, afd,
	edumazet, robh+dt, krzysztof.kozlowski+dt, ssantosh, davem,
	linux-arm-kernel

On 04/11/2022 03:28, Md Danish Anwar wrote:
>>> * It includes indentation, formatting, and other minor changes.
>>> ---
>>>  .../bindings/net/ti,icssg-prueth.yaml         | 181 ++++++++++++++++++
>>>  1 file changed, 181 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>>> new file mode 100644
>>> index 000000000000..40af968e9178
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
>>> @@ -0,0 +1,181 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/net/ti,icssg-prueth.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: |+
>>
>> Missed Rob's comment.
>>
> 
> I'll remove this in the next version of this series.
> 
>>> +  Texas Instruments ICSSG PRUSS Ethernet
>>> +
>>> +maintainers:
>>> +  - Puranjay Mohan <p-mohan@ti.com>
>>> +
>>> +description:
>>> +  Ethernet based on the Programmable Real-Time
>>> +  Unit and Industrial Communication Subsystem.
>>> +
>>> +allOf:
>>> +  - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#
>>> +
>>> +properties:
>>> +  compatible:
>>> +    enum:
>>> +      - ti,am654-icssg-prueth  # for AM65x SoC family
>>> +
>>> +  pinctrl-0:
>>> +    maxItems: 1
>>> +
>>> +  pinctrl-names:
>>> +    items:
>>> +      - const: default
>>
>> You do not need these usually, they are coming from schema.
>>
> Here from what I understand, I need to delete the below block, right?

Yes, entire pinctrl-0 and pinctr-names are not needed. You specify them
ony if they differ from usual.

Best regards,
Krzysztof


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2022-11-04 12:58 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-31  9:51 [PATCH v2 0/2] Introduce ICSSG based ethernet Driver Puranjay Mohan
2022-05-31  9:51 ` [PATCH v2 1/2] dt-bindings: net: Add ICSSG Ethernet Driver bindings Puranjay Mohan
2022-05-31 10:08   ` Krzysztof Kozlowski
2022-05-31 11:27     ` Puranjay Mohan
2022-05-31 11:48       ` Krzysztof Kozlowski
2022-05-31 11:59         ` Puranjay Mohan
2022-05-31 12:01           ` Krzysztof Kozlowski
2022-06-01  4:28             ` Puranjay Mohan
2022-06-05 15:11       ` Andrew Lunn
2022-11-04  7:28     ` Md Danish Anwar
2022-11-04 12:57       ` Krzysztof Kozlowski
2022-05-31 13:21   ` Rob Herring
     [not found] ` <20220531095108.21757-3-p-mohan@ti.com>
2022-05-31 10:20   ` [PATCH v2 2/2] net: ti: icssg-prueth: Add ICSSG ethernet driver Krzysztof Kozlowski
2022-05-31 11:23   ` Paolo Abeni
2022-11-04  8:29     ` Md Danish Anwar
2022-05-31 13:11   ` Randy Dunlap
2022-06-05 15:37   ` Andrew Lunn
2022-11-04 10:26     ` Md Danish Anwar
2022-06-05 16:24   ` Christophe JAILLET
2022-11-04  9:50     ` Md Danish Anwar

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