From patchwork Thu Apr 14 12:22:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813435 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1827C43219 for ; Thu, 14 Apr 2022 12:30:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239025AbiDNMdO (ORCPT ); Thu, 14 Apr 2022 08:33:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243268AbiDNMdK (ORCPT ); Thu, 14 Apr 2022 08:33:10 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E16027FE3 for ; Thu, 14 Apr 2022 05:30:45 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [217.70.183.194]) by mslow1.mail.gandi.net (Postfix) with ESMTP id 39C02CF22A for ; Thu, 14 Apr 2022 12:24:48 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 975D840012; Thu, 14 Apr 2022 12:24:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939082; 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=VZQJox6pfPHfC3qb+4Dol20vx3ou4eYt1gnOvwZ6wUI=; b=dhPtZSrAX6XBgNQiE5qpr4/oCiYzDuW+OW9z1Al3KuEWRBFR5NXP5hYiuDxDzZDHnD/mCo odGU725IrYUzzY1pFgYrZaZtGNhkdWHbcS4ePfu31ZZHfXgUJSYU1WqI8itvCR+n5WcfjK wwYSikUU4HfsFbkNfn4dUcA/yvYYlkSpdqCF3yP7GFjTsBDdqBFfV0WcSI/fgQ55wWKRbJ CVdZRsdtMtgEp8Ukcrb4zRdgF+8cT0k4mtOSoggIXVGtQahPXdmJVrMqXA6WAPawIWmmbn BGSAUPPtmHRRHiLfYKgzAne9VTMr15HCKH6eJKwYnQMUhXUOqGfWJkIraZvQLg== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 01/12] net: dsa: add support for Renesas RZ/N1 A5PSW switch tag code Date: Thu, 14 Apr 2022 14:22:39 +0200 Message-Id: <20220414122250.158113-2-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add DSA tag code for Renesas RZ/N1 Advanced 5 port switch. This switch uses a special VLAN type followed by 6 bytes which contains other useful information (port, timestamp, etc). Signed-off-by: Clément Léger --- include/net/dsa.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/net/dsa.h b/include/net/dsa.h index 934958fda962..2aa8eaae4eb9 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -53,6 +53,7 @@ struct phylink_link_state; #define DSA_TAG_PROTO_SJA1110_VALUE 23 #define DSA_TAG_PROTO_RTL8_4_VALUE 24 #define DSA_TAG_PROTO_RTL8_4T_VALUE 25 +#define DSA_TAG_PROTO_RZN1_A5PSW_VALUE 26 enum dsa_tag_protocol { DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, @@ -81,6 +82,7 @@ enum dsa_tag_protocol { DSA_TAG_PROTO_SJA1110 = DSA_TAG_PROTO_SJA1110_VALUE, DSA_TAG_PROTO_RTL8_4 = DSA_TAG_PROTO_RTL8_4_VALUE, DSA_TAG_PROTO_RTL8_4T = DSA_TAG_PROTO_RTL8_4T_VALUE, + DSA_TAG_PROTO_RZN1_A5PSW = DSA_TAG_PROTO_RZN1_A5PSW_VALUE, }; struct dsa_switch; From patchwork Thu Apr 14 12:22:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813433 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E10FFC433EF for ; Thu, 14 Apr 2022 12:30:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243256AbiDNMdN (ORCPT ); Thu, 14 Apr 2022 08:33:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50564 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239025AbiDNMdL (ORCPT ); Thu, 14 Apr 2022 08:33:11 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E372286E2 for ; Thu, 14 Apr 2022 05:30:45 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [217.70.183.194]) by mslow1.mail.gandi.net (Postfix) with ESMTP id BACB5CF22B for ; Thu, 14 Apr 2022 12:24:51 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 59F2940003; Thu, 14 Apr 2022 12:24:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939084; 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=TwDxNSRrfQ0fwbGL5JfChMYmoOedvb2POPLu1+VI9fs=; b=mxv/3mdrs1ZRE2G4jRlJUKnhx4QvHcUxICZ/dnBY1HfoYqvWx8UcKdWjJrPsVBPjO8lE5j 7N4AS6z5rgZOiJr9/qeBKRgAcJ9yD6EEgW2fHVrcxwgJSj5w572rVg2L81HSG50QfXX/RR fFv1z0h3Fin5WOgxYU6i/3goa+cweBWnJqnSTBjhZpisiV32NJOEz0rvoCaTwN6zCorD6C Jb7J5IKDtTI3zzpRnTIx6guWqjZrUqZxGXLrmzUSewlVP5YTmfS1nEIu/iIoTenFgSfPdn PQu/aEZQU1YKKPZEPzSNb97djG662523O4v/926xJXaAF1VNW1tq/yB6VLar7g== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 02/12] net: dsa: add Renesas RZ/N1 switch tag driver Date: Thu, 14 Apr 2022 14:22:40 +0200 Message-Id: <20220414122250.158113-3-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org The switch that is present on the Renesas RZ/N1 SoC uses a specific VLAN value followed by 6 bytes which contains forwarding configuration. Signed-off-by: Clément Léger --- net/dsa/Kconfig | 8 +++ net/dsa/Makefile | 1 + net/dsa/tag_rzn1_a5psw.c | 112 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 net/dsa/tag_rzn1_a5psw.c diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig index 8cb87b5067ee..e5b17108fa22 100644 --- a/net/dsa/Kconfig +++ b/net/dsa/Kconfig @@ -132,6 +132,13 @@ config NET_DSA_TAG_RTL8_4 Say Y or M if you want to enable support for tagging frames for Realtek switches with 8 byte protocol 4 tags, such as the Realtek RTL8365MB-VC. +config NET_DSA_TAG_RZN1_A5PSW + tristate "Tag driver for Renesas RZ/N1 A5PSW switch" + help + Say Y or M if you want to enable support for tagging frames for + Renesas RZ/N1 embedded switch that uses a 8 byte tag located after + destination MAC address. + config NET_DSA_TAG_LAN9303 tristate "Tag driver for SMSC/Microchip LAN9303 family of switches" help @@ -159,4 +166,5 @@ config NET_DSA_TAG_XRS700X Say Y or M if you want to enable support for tagging frames for Arrow SpeedChips XRS700x switches that use a single byte tag trailer. + endif diff --git a/net/dsa/Makefile b/net/dsa/Makefile index 9f75820e7c98..af28c24ead18 100644 --- a/net/dsa/Makefile +++ b/net/dsa/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_NET_DSA_TAG_OCELOT_8021Q) += tag_ocelot_8021q.o obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o obj-$(CONFIG_NET_DSA_TAG_RTL8_4) += tag_rtl8_4.o +obj-$(CONFIG_NET_DSA_TAG_RZN1_A5PSW) += tag_rzn1_a5psw.o obj-$(CONFIG_NET_DSA_TAG_SJA1105) += tag_sja1105.o obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o obj-$(CONFIG_NET_DSA_TAG_XRS700X) += tag_xrs700x.o diff --git a/net/dsa/tag_rzn1_a5psw.c b/net/dsa/tag_rzn1_a5psw.c new file mode 100644 index 000000000000..7818c1c0fca2 --- /dev/null +++ b/net/dsa/tag_rzn1_a5psw.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 Schneider Electric + * + * Clément Léger + */ + +#include +#include +#include + +#include "dsa_priv.h" + +/* To define the outgoing port and to discover the incoming port a TAG is + * inserted after Src MAC : + * + * Dest MAC Src MAC TAG Type + * ...| 1 2 3 4 5 6 | 1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 | 1 2 |... + * |<--------------->| + * + * See struct a5psw_tag for layout + */ + +#define A5PSW_TAG_VALUE 0xE001 +#define A5PSW_TAG_LEN 8 +#define A5PSW_CTRL_DATA_FORCE_FORWARD BIT(0) +/* This is both used for xmit tag and rcv tagging */ +#define A5PSW_CTRL_DATA_PORT GENMASK(3, 0) + +struct a5psw_tag { + u16 ctrl_tag; + u16 ctrl_data; + u32 ctrl_data2; +}; + +static struct sk_buff *a5psw_tag_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct a5psw_tag *ptag, tag = {0}; + struct dsa_port *dp = dsa_slave_to_port(dev); + u32 data2_val; + + /* The Ethernet switch we are interfaced with needs packets to be at + * least 64 bytes (including FCS) otherwise they will be discarded when + * they enter the switch port logic. When tagging is enabled, we need + * to make sure that packets are at least 68 bytes (including FCS and + * tag). + */ + if (__skb_put_padto(skb, ETH_ZLEN + sizeof(tag), false)) + return NULL; + + /* provide 'A5PSW_TAG_LEN' bytes additional space */ + skb_push(skb, A5PSW_TAG_LEN); + + /* make room between MACs and Ether-Type to insert tag */ + dsa_alloc_etype_header(skb, A5PSW_TAG_LEN); + + ptag = dsa_etype_header_pos_tx(skb); + + data2_val = FIELD_PREP(A5PSW_CTRL_DATA_PORT, BIT(dp->index)); + tag.ctrl_tag = htons(A5PSW_TAG_VALUE); + tag.ctrl_data = htons(A5PSW_CTRL_DATA_FORCE_FORWARD); + tag.ctrl_data2 = htonl(data2_val); + + memcpy(ptag, &tag, sizeof(struct a5psw_tag)); + + return skb; +} + +static struct sk_buff *a5psw_tag_rcv(struct sk_buff *skb, + struct net_device *dev) +{ + struct a5psw_tag *tag; + int port; + + if (unlikely(!pskb_may_pull(skb, A5PSW_TAG_LEN))) { + dev_warn_ratelimited(&dev->dev, + "Dropping packet, cannot pull\n"); + return NULL; + } + + tag = dsa_etype_header_pos_rx(skb); + + if (tag->ctrl_tag != htons(A5PSW_TAG_VALUE)) { + dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid TAG marker\n"); + return NULL; + } + + port = FIELD_GET(A5PSW_CTRL_DATA_PORT, ntohs(tag->ctrl_data)); + + skb->dev = dsa_master_find_slave(dev, 0, port); + if (!skb->dev) + return NULL; + + skb_pull_rcsum(skb, A5PSW_TAG_LEN); + dsa_strip_etype_header(skb, A5PSW_TAG_LEN); + + dsa_default_offload_fwd_mark(skb); + + return skb; +} + +static const struct dsa_device_ops a5psw_netdev_ops = { + .name = "a5psw", + .proto = DSA_TAG_PROTO_RZN1_A5PSW, + .xmit = a5psw_tag_xmit, + .rcv = a5psw_tag_rcv, + .needed_headroom = A5PSW_TAG_LEN, +}; + +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_A5PSW); +module_dsa_tag_driver(a5psw_netdev_ops); From patchwork Thu Apr 14 12:22:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813436 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D4A3C433FE for ; Thu, 14 Apr 2022 12:30:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243317AbiDNMdO (ORCPT ); Thu, 14 Apr 2022 08:33:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243270AbiDNMdK (ORCPT ); Thu, 14 Apr 2022 08:33:10 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E2F4286D0 for ; Thu, 14 Apr 2022 05:30:45 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [IPv6:2001:4b98:dc4:8::222]) by mslow1.mail.gandi.net (Postfix) with ESMTP id 64D3DCF22C for ; Thu, 14 Apr 2022 12:24:53 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 2ACBB40002; Thu, 14 Apr 2022 12:24:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939085; 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=GW6fHP12CGCUnj3fBoY6K+7JAZmoGfpnGpnZe2LXKhs=; b=Ee5dVQLCwmatzyF91lmKjLw2a2jDivZ0p8D2V55PS6DQ7rDqN1npB+0V15AqSg1U/ltb0C gi9m9ETzVnPegosBKauQizQHiNZIHj9DvZr2fOAYPEupy8icb1+kjpuZbmCimknDRGlLKi 2k/tE9u/3CNSObHDmhD40AFDdwaRK8umUl3WK+RfNtjCnshXsHaOzgjUu/tkjve5GnxxOA Zwiafn3JM7iWYLGo0+Ur1eafR6f+/Mm3wZ+XU45hMoEz/RtRUFVzYkB78vLs2WGCtfxjTh HjZ6a7a7owrF6up127ogvauEz/coJlUVpFaOW/F55+gtYXAzh3t6KhRP4I4DPA== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 03/12] dt-bindings: net: pcs: add bindings for Renesas RZ/N1 MII converter Date: Thu, 14 Apr 2022 14:22:41 +0200 Message-Id: <20220414122250.158113-4-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org This MII converter can be found on the RZ/N1 processor family. The MII converter ports are declared as subnodes which are then referenced by users of the PCS driver such as the switch. Signed-off-by: Clément Léger --- .../bindings/net/pcs/renesas,rzn1-miic.yaml | 95 +++++++++++++++++++ include/dt-bindings/net/pcs-rzn1-miic.h | 19 ++++ 2 files changed, 114 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml create mode 100644 include/dt-bindings/net/pcs-rzn1-miic.h diff --git a/Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml b/Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml new file mode 100644 index 000000000000..ccb25ce6cbde --- /dev/null +++ b/Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/pcs/renesas,rzn1-miic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/N1 MII converter + +maintainers: + - Clément Léger + +description: | + This MII converter is present on the Renesas RZ/N1 SoC family. It is + responsible to do MII passthrough or convert it to RMII/RGMII. + +properties: + compatible: + const: renesas,rzn1-miic + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + clocks: + items: + - description: MII reference clock + - description: RGMII reference clock + - description: RMII reference clock + - description: AHB clock used for the MII converter register interface + + renesas,miic-cfg-mode: + description: MII mux configuration mode. This value should use one of the + value defined in dt-bindings/net/pcs-rzn1-miic.h. + $ref: /schemas/types.yaml#/definitions/uint32 + +patternProperties: + "^mii-conv@[0-4]$": + type: object + description: MII converter port + + properties: + reg: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - renesas,miic-cfg-mode + - "#address-cells" + - "#size-cells" + +additionalProperties: false + +examples: + - | + #include + #include + + eth-miic@44030000 { + compatible = "renesas,rzn1-miic"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44030000 0x10000>; + clocks = <&sysctrl R9A06G032_CLK_MII_REF>, + <&sysctrl R9A06G032_CLK_RGMII_REF>, + <&sysctrl R9A06G032_CLK_RMII_REF>, + <&sysctrl R9A06G032_HCLK_SWITCH_RG>; + renesas,miic-cfg-mode = ; + + mii_conv0: mii-conv@0 { + reg = <0>; + }; + + mii_conv1: mii-conv@1 { + reg = <1>; + }; + + mii_conv2: mii-conv@2 { + reg = <2>; + }; + + mii_conv3: mii-conv@3 { + reg = <3>; + }; + + mii_conv4: mii-conv@4 { + reg = <4>; + }; + }; \ No newline at end of file diff --git a/include/dt-bindings/net/pcs-rzn1-miic.h b/include/dt-bindings/net/pcs-rzn1-miic.h new file mode 100644 index 000000000000..c5a0f382967b --- /dev/null +++ b/include/dt-bindings/net/pcs-rzn1-miic.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 Schneider-Electric + * + * Clément Léger + */ + +#ifndef _DT_BINDINGS_PCS_RZN1_MIIC +#define _DT_BINDINGS_PCS_RZN1_MIIC + +/* + * Reefer to the datasheet [1] section 8.2.1, Internal Connection of Ethernet + * Ports to check the meaning of these values. + * + * [1] REN_r01uh0750ej0140-rzn1-introduction_MAT_20210228.pdf + */ +#define MIIC_MUX_MAC2_MAC1_SWD_SWC_SWB_SWA 0x13 + +#endif From patchwork Thu Apr 14 12:22:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813434 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72175C4332F for ; Thu, 14 Apr 2022 12:30:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242748AbiDNMdN (ORCPT ); Thu, 14 Apr 2022 08:33:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243282AbiDNMdL (ORCPT ); Thu, 14 Apr 2022 08:33:11 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E540286F7 for ; Thu, 14 Apr 2022 05:30:45 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [IPv6:2001:4b98:dc4:8::222]) by mslow1.mail.gandi.net (Postfix) with ESMTP id 85B52CE04F for ; Thu, 14 Apr 2022 12:24:57 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 0E01D4000C; Thu, 14 Apr 2022 12:24:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939088; 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=ssNs5yXTL9mvQvG0qY2xgZ2mvkOGo3Ko6vSPOCq9GNo=; b=U+HJNqnvnsQEWFZyAznl6TMK1DIZELxWm2PPMsz2JJKDE5NXNbgJUT+k9S3QT91JCBAfcD YglLbqm+LIP/mQvWQ16EsJhdBbMrSYPM76IWJ0ByEX8VHVIzuQkzPVOjkeYhjspEssskH+ 2vAezjKNpSqLjKwFFFFjiCj+JSFQi7McYpT5I7ZuH3Uxs6dCRGZYVj2rKt/zUEkHqAZmoF u2Tg98gr6pfuibIm+TulEjCDfRvWZbWWcH/4JurYUQZGKqOH7w4sLNYhBl3iKQ2yI9MSI7 8nlwv3mrUyhkGhYeuBuRDH2KFYXy6/Wu9sLCIOIR9TwRWAZBJBvgDnQSbVc/UA== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 04/12] net: pcs: add Renesas MII converter driver Date: Thu, 14 Apr 2022 14:22:42 +0200 Message-Id: <20220414122250.158113-5-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add PCS driver for the MII converter that is present on Renesas RZ/N1 SoC. This MII converter is reponsible of converting MII to RMII/RGMII or act as a MII passtrough. Exposing it as a PCS allows to reuse it in both the switch driver and the stmmac driver. Currently, this driver only allows the PCS to be used by the dual Cortex-A7 subsystem since the register locking system is not used. Signed-off-by: Clément Léger --- drivers/net/pcs/Kconfig | 7 + drivers/net/pcs/Makefile | 1 + drivers/net/pcs/pcs-rzn1-miic.c | 350 ++++++++++++++++++++++++++++++++ include/linux/pcs-rzn1-miic.h | 18 ++ 4 files changed, 376 insertions(+) create mode 100644 drivers/net/pcs/pcs-rzn1-miic.c create mode 100644 include/linux/pcs-rzn1-miic.h diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig index 22ba7b0b476d..fb0d36d46ffb 100644 --- a/drivers/net/pcs/Kconfig +++ b/drivers/net/pcs/Kconfig @@ -18,4 +18,11 @@ config PCS_LYNX This module provides helpers to phylink for managing the Lynx PCS which is part of the Layerscape and QorIQ Ethernet SERDES. +config PCS_RZN1_MIIC + tristate "Renesas RZN1 MII converter" + help + This module provides a driver for the MII converter that is available + on RZN1 SoC. This PCS convert MII to RMII/RGMII or can be in + passthrough mode for MII. + endmenu diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile index 0603d469bd57..0ff5388fcdea 100644 --- a/drivers/net/pcs/Makefile +++ b/drivers/net/pcs/Makefile @@ -5,3 +5,4 @@ pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-nxp.o obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o +obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c new file mode 100644 index 000000000000..84599e767689 --- /dev/null +++ b/drivers/net/pcs/pcs-rzn1-miic.c @@ -0,0 +1,350 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Schneider Electric + * + * Clément Léger + */ + +#include +#include +#include +#include +#include +#include + +#define MIIC_PRCMD 0x0 +#define MIIC_ESID_CODE 0x4 + +#define MIIC_MODCTRL 0x20 +#define MIIC_MODCTRL_SW_MODE GENMASK(4, 0) + +#define MIIC_CONVCTRL(port) (0x100 + (port) * 4) +#define MIIC_CONVCTRL_CONV_MODE GENMASK(4, 0) +#define CONV_MODE_MII 0 +#define CONV_MODE_RMII BIT(2) +#define CONV_MODE_RGMII BIT(3) +#define CONV_MODE_10MBPS 0 +#define CONV_MODE_100MBPS BIT(0) +#define CONV_MODE_1000MBPS BIT(1) +#define MIIC_CONVCTRL_FULLD BIT(8) +#define MIIC_CONVCTRL_RGMII_LINK BIT(12) +#define MIIC_CONVCTRL_RGMII_DUPLEX BIT(13) +#define MIIC_CONVCTRL_RGMII_SPEED GENMASK(15, 14) + +#define MIIC_CONVRST 0x114 +#define MIIC_CONVRST_PHYIF_RST(port) BIT(port) +#define MIIC_CONVRST_PHYIF_RST_MASK GENMASK(4, 0) + +#define MIIC_SWCTRL 0x304 +#define MIIC_SWDUPC 0x308 + +#define MIIC_MAX_NR_PORTS 5 + +#define phylink_pcs_to_miic_port(pcs) container_of((pcs), struct miic_port, pcs) + +/** + * struct miic - MII converter structure + * @base: base address of the MII converter + * @dev: Device associated to the MII converter + * @lock: Lock used for read-modify-write access + */ +struct miic { + void __iomem *base; + struct device *dev; + spinlock_t lock; +}; + +/** + * struct miic_port - Per port MII converter struct + * @miic: backiling to MII converter structure + * @pcs: PCS structure associated to the port + * @port: port number + */ +struct miic_port { + struct miic *miic; + struct phylink_pcs pcs; + int port; +}; + +static void miic_reg_writel(struct miic *miic, int offset, u32 value) +{ + writel(value, miic->base + offset); +} + +static u32 miic_reg_readl(struct miic *miic, int offset) +{ + return readl(miic->base + offset); +} + +static void miic_reg_rmw(struct miic *miic, int offset, u32 mask, u32 val) +{ + u32 reg; + + spin_lock(&miic->lock); + + reg = miic_reg_readl(miic, offset); + reg &= ~mask; + reg |= val; + miic_reg_writel(miic, offset, reg); + + spin_unlock(&miic->lock); +} + +static void miic_converter_enable(struct miic *miic, int port, int enable) +{ + u32 val = 0; + + if (enable) + val = MIIC_CONVRST_PHYIF_RST(port); + + miic_reg_rmw(miic, MIIC_CONVRST, MIIC_CONVRST_PHYIF_RST(port), val); +} + +static int miic_config(struct phylink_pcs *pcs, unsigned int mode, + phy_interface_t interface, + const unsigned long *advertising, bool permit) +{ + struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); + struct miic *miic = miic_port->miic; + int port = miic_port->port; + u32 val; + + switch (interface) { + case PHY_INTERFACE_MODE_RMII: + val = CONV_MODE_RMII | CONV_MODE_1000MBPS; + break; + case PHY_INTERFACE_MODE_RGMII: + val = CONV_MODE_RGMII | CONV_MODE_1000MBPS; + break; + case PHY_INTERFACE_MODE_MII: + val = CONV_MODE_MII; + break; + default: + return -EOPNOTSUPP; + } + + miic_reg_rmw(miic, MIIC_CONVCTRL(port), MIIC_CONVCTRL_CONV_MODE, val); + miic_converter_enable(miic_port->miic, miic_port->port, 1); + + return 0; +} + +static void miic_link_up(struct phylink_pcs *pcs, unsigned int mode, + phy_interface_t interface, int speed, int duplex) +{ + struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); + struct miic *miic = miic_port->miic; + int port = miic_port->port; + u32 val = 0; + + if (duplex == DUPLEX_FULL) + val |= MIIC_CONVCTRL_FULLD; + + switch (interface) { + case PHY_INTERFACE_MODE_RMII: + val |= CONV_MODE_RMII; + break; + case PHY_INTERFACE_MODE_RGMII: + val |= CONV_MODE_RGMII; + break; + case PHY_INTERFACE_MODE_MII: + val |= CONV_MODE_MII; + break; + default: + dev_err(miic->dev, "Unsupported interface %s\n", + phy_modes(interface)); + return; + } + + /* No speed in MII through-mode */ + if (interface != PHY_INTERFACE_MODE_MII) { + switch (speed) { + case SPEED_1000: + val |= CONV_MODE_1000MBPS; + break; + case SPEED_100: + val |= CONV_MODE_100MBPS; + break; + case SPEED_10: + val |= CONV_MODE_10MBPS; + break; + case SPEED_UNKNOWN: + pr_err("Invalid speed\n"); + /* Silently don't do anything */ + return; + default: + dev_err(miic->dev, "Invalid PCS speed %d\n", speed); + return; + } + } + + miic_reg_rmw(miic, MIIC_CONVCTRL(port), + (MIIC_CONVCTRL_CONV_MODE | MIIC_CONVCTRL_FULLD), val); +} + +static bool miic_mode_supported(phy_interface_t interface) +{ + return (interface == PHY_INTERFACE_MODE_RGMII || + interface == PHY_INTERFACE_MODE_RMII || + interface == PHY_INTERFACE_MODE_MII); +} + +static int miic_validate(struct phylink_pcs *pcs, unsigned long *supported, + const struct phylink_link_state *state) +{ + struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); + struct miic *miic = miic_port->miic; + + if (state->interface != PHY_INTERFACE_MODE_NA && + !miic_mode_supported(state->interface)) { + dev_err(miic->dev, "phy mode %s is unsupported on port %d\n", + phy_modes(state->interface), miic_port->port); + linkmode_zero(supported); + return -EOPNOTSUPP; + } + + return 0; +} + +static const struct phylink_pcs_ops miic_phylink_ops = { + .pcs_config = miic_config, + .pcs_link_up = miic_link_up, + .pcs_validate = miic_validate, +}; + +struct phylink_pcs *miic_create(struct device_node *np) +{ + struct platform_device *pdev; + struct miic_port *miic_port; + struct device_node *pcs_np; + u32 port; + + if (of_property_read_u32(np, "reg", &port)) + return ERR_PTR(-EINVAL); + + if (port >= MIIC_MAX_NR_PORTS) + return ERR_PTR(-EINVAL); + + /* The PCS pdev is attached to the parent node */ + pcs_np = of_get_parent(np); + if (!pcs_np) + return ERR_PTR(-EINVAL); + + pdev = of_find_device_by_node(pcs_np); + if (!pdev || !platform_get_drvdata(pdev)) + return ERR_PTR(-EPROBE_DEFER); + + miic_port = kzalloc(sizeof(*miic_port), GFP_KERNEL); + if (!miic_port) + return ERR_PTR(-ENOMEM); + + miic_port->miic = platform_get_drvdata(pdev); + miic_port->port = port; + miic_port->pcs.ops = &miic_phylink_ops; + + return &miic_port->pcs; +} +EXPORT_SYMBOL(miic_create); + +void miic_destroy(struct phylink_pcs *pcs) +{ + struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); + + miic_converter_enable(miic_port->miic, miic_port->port, 0); + kfree(miic_port); +} +EXPORT_SYMBOL(miic_destroy); + +static int miic_init_hw(struct miic *miic, u32 mode) +{ + int port; + + /* Unlock write access to accessory registers (cf datasheet). If this + * is going to be used in conjunction with the Cortex-M3, this sequence + * will have to be moved in register write + */ + miic_reg_writel(miic, MIIC_PRCMD, 0x00A5); + miic_reg_writel(miic, MIIC_PRCMD, 0x0001); + miic_reg_writel(miic, MIIC_PRCMD, 0xFFFE); + miic_reg_writel(miic, MIIC_PRCMD, 0x0001); + + miic_reg_writel(miic, MIIC_MODCTRL, + FIELD_PREP(MIIC_MODCTRL_SW_MODE, mode)); + + for (port = 0; port < MIIC_MAX_NR_PORTS; port++) { + miic_converter_enable(miic, port, 0); + /* Disable speed/duplex control from these registers, datasheet + * says switch registers should be used to setup switch port + * speed and duplex. + */ + miic_reg_writel(miic, MIIC_SWCTRL, 0x0); + miic_reg_writel(miic, MIIC_SWDUPC, 0x0); + } + + return 0; +} + +static int miic_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct clk_bulk_data *clks; + struct miic *miic; + u32 mode_cfg; + int nclk; + int ret; + + if (of_property_read_u32(dev->of_node, "renesas,miic-cfg-mode", &mode_cfg)) { + dev_err(dev, "Missing renesas,miic-cfg-mode property for miic\n"); + return -EINVAL; + } + + miic = devm_kzalloc(dev, sizeof(*miic), GFP_KERNEL); + if (!miic) + return -ENOMEM; + + spin_lock_init(&miic->lock); + miic->dev = dev; + miic->base = devm_platform_ioremap_resource(pdev, 0); + if (!miic->base) + return -EINVAL; + + nclk = devm_clk_bulk_get_all(dev, &clks); + if (nclk < 0) + return nclk; + + ret = clk_bulk_prepare_enable(nclk, clks); + if (ret) + return ret; + + ret = miic_init_hw(miic, mode_cfg); + if (ret) + goto disable_clocks; + + platform_set_drvdata(pdev, miic); + + return 0; + +disable_clocks: + clk_bulk_disable_unprepare(nclk, clks); + + return ret; +} + +static const struct of_device_id miic_of_mtable[] = { + { .compatible = "renesas,rzn1-miic" }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, miic_of_mtable); + +static struct platform_driver miic_driver = { + .driver = { + .name = "mtip_miic", + .of_match_table = of_match_ptr(miic_of_mtable), + }, + .probe = miic_probe, +}; +module_platform_driver(miic_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Renesas MII converter PCS driver"); +MODULE_AUTHOR("Clément Léger "); diff --git a/include/linux/pcs-rzn1-miic.h b/include/linux/pcs-rzn1-miic.h new file mode 100644 index 000000000000..7a303af57e40 --- /dev/null +++ b/include/linux/pcs-rzn1-miic.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 Schneider Electric + * + * Clément Léger + */ + +#ifndef __LINUX_PCS_MIIC_H +#define __LINUX_PCS_MIIC_H + +struct phylink; +struct device_node; + +struct phylink_pcs *miic_create(struct device_node *np); + +void miic_destroy(struct phylink_pcs *pcs); + +#endif /* __LINUX_PCS_MIIC_H */ From patchwork Thu Apr 14 12:22:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813437 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E5D7C4167B for ; Thu, 14 Apr 2022 12:30:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243268AbiDNMdP (ORCPT ); Thu, 14 Apr 2022 08:33:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50742 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243302AbiDNMdM (ORCPT ); Thu, 14 Apr 2022 08:33:12 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BDC1F275E9 for ; Thu, 14 Apr 2022 05:30:47 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [IPv6:2001:4b98:dc4:8::222]) by mslow1.mail.gandi.net (Postfix) with ESMTP id 955DCCF22E for ; Thu, 14 Apr 2022 12:24:57 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 2856B4000A; Thu, 14 Apr 2022 12:24:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939089; 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=nLVj4RxeVcZSlN7RrIXkjxK+yKv2UDtPi0nH3YhWl5A=; b=CmgLvBJ+k2n/sbysbXTiDE6na/gZx8sIGbYhtZB4Pg6aGlvhkAfYyKLP2UQNPPrXWubMlO 7X31NnFVOL+9gJgvBXG/CIrAwFp5nWyqiVutrCFbmLl9X4nnfFLQSzr0SRX6bKSWAUhc16 1+whYd4ZB+ImTuRkReR52Fav27AdAxM3mAiLURfno/3DDYeEF8wWXCJsgmLGhjsFw2FIK/ AsNrEnuGBGuGxagHhnh8LWPTUxkQp7vaplGd6QoGBFM2hui//VMcg2aGCN0KYqfvxko03n +GAKPHVs1Qr65o+CK/ZwJf1boYEqPYkmJY+SqJ9l7z5nNVASuTp/zur+bT5O9g== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 05/12] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch Date: Thu, 14 Apr 2022 14:22:43 +0200 Message-Id: <20220414122250.158113-6-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add bindings for Renesas RZ/N1 Advanced 5 port switch. This switch is present on Renesas RZ/N1 SoC and was probably provided by MoreThanIP. This company does not exists anymore and has been bought by Synopsys. Since this IP can't be find anymore in the Synospsy portfolio, lets use Renesas as the vendor compatible for this IP. Signed-off-by: Clément Léger --- .../bindings/net/dsa/renesas,rzn1-a5psw.yaml | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml diff --git a/Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml b/Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml new file mode 100644 index 000000000000..54e7196a22b0 --- /dev/null +++ b/Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml @@ -0,0 +1,128 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/dsa/renesas,rzn1-a5psw.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/N1 Advanced 5 ports ethernet switch + +maintainers: + - Clément Léger + +description: | + The advanced 5 ports switch is present on the Renesas RZ/N1 SoC family and + handles 4 ports + 1 CPU management port. + +allOf: + - $ref: dsa.yaml# + +properties: + compatible: + const: renesas,rzn1-a5psw + + mdio: + $ref: mdio.yaml# + unevaluatedProperties: false + + clocks: + items: + - description: AHB clock used for the switch register interface + - description: Switch system clock + + clock-names: + items: + - const: hclk + - const: clk + +patternProperties: + "^(ethernet-)?ports$": + type: object + properties: + '#address-cells': + const: 1 + '#size-cells': + const: 0 + + patternProperties: + "^(ethernet-)?port@[0-6]$": + type: object + description: Ethernet switch ports + + properties: + pcs-handle: + description: + phandle pointing to a PCS sub-node compatible with + renesas,rzn1-miic.yaml# + $ref: /schemas/types.yaml#/definitions/phandle + +unevaluatedProperties: false + +required: + - compatible + - reg + - clocks + - clock-names + +examples: + - | + #include + #include + + switch@44050000 { + compatible = "renesas,rzn1-a5psw"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44050000 0x10000>; + clocks = <&sysctrl R9A06G032_HCLK_SWITCH>, <&sysctrl R9A06G032_CLK_SWITCH>; + clock-names = "hclk", "clk"; + pinctrl-names = "default"; + pinctrl-0 = <&pins_mdio1>, <&pins_eth3>, <&pins_eth4>; + + dsa,member = <0 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan0"; + phy-handle = <&switch0phy3>; + pcs-handle = <&mii_conv4>; + }; + + port@1 { + reg = <1>; + label = "lan1"; + phy-handle = <&switch0phy1>; + pcs-handle = <&mii_conv3>; + }; + + port@4 { + reg = <4>; + ethernet = <&gmac1>; + label = "cpu"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + reset-gpios = <&gpio0a 2 GPIO_ACTIVE_HIGH>; + reset-delay-us = <15>; + clock-frequency = <2500000>; + + switch0phy1: ethernet-phy@1{ + reg = <1>; + }; + + switch0phy3: ethernet-phy@3{ + reg = <3>; + }; + }; + }; From patchwork Thu Apr 14 12:22:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813443 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 692C5C433EF for ; Thu, 14 Apr 2022 12:30:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243327AbiDNMdT (ORCPT ); Thu, 14 Apr 2022 08:33:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243320AbiDNMdO (ORCPT ); Thu, 14 Apr 2022 08:33:14 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF144275EE for ; Thu, 14 Apr 2022 05:30:47 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [217.70.183.194]) by mslow1.mail.gandi.net (Postfix) with ESMTP id 9410CCF22F for ; Thu, 14 Apr 2022 12:24:59 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id A0F1540010; Thu, 14 Apr 2022 12:24:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939091; 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=1ygHBiiBBVmL9WKBLrCMImrTcr8MgXrMgyEiPqfbnBE=; b=j2l8nu/H8sB7Q/vrmcDQ8l0CqzZOel5ATf8GBBxXofhR9GGZQLnTGJSlJ9mm6/SG/t4bK9 TUBZFHdqgTfR53ivhlvd9tkTvQkiOMTV41+zSn5cvRQpkwhSSbNyqVozQkIZgAjoaH4PfY 7gG796NwT+rSGT0EF0lqBm6SXVRc0NeB/aI/qWoOHC1s2sxS63UMraLJbJrHSzgzv1iIZ2 jzpXNXsU0fFd1g0N4ad2ez8qmmF8cUbuxwNVj1r1mR25+q+vlnXH3H0gogYoGzjanrU8ae 7H3bXkddK74iQXNzmgek1bGAbAUMldwqsLM9/aEaEyJUGnG/IvcyDRA85hj4WQ== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org, Laurent Gonzales , Jean-Pierre Geslin , Phil Edworthy Subject: [PATCH net-next 06/12] net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port switch driver Date: Thu, 14 Apr 2022 14:22:44 +0200 Message-Id: <20220414122250.158113-7-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add Renesas RZ/N1 advanced 5 port switch driver. This switch handles 5 ports including 1 CPU management port. A MDIO bus is also exposed by this switch and allows to communicate with PHYs connected to the ports. Each switch port (except for the CPU management ports) are connected to the MII converter. This driver include basic bridging support, more support will be added later (vlan, etc). Suggested-by: Laurent Gonzales Suggested-by: Jean-Pierre Geslin Suggested-by: Phil Edworthy Signed-off-by: Clément Léger --- drivers/net/dsa/Kconfig | 9 + drivers/net/dsa/Makefile | 2 + drivers/net/dsa/rzn1_a5psw.c | 676 +++++++++++++++++++++++++++++++++++ drivers/net/dsa/rzn1_a5psw.h | 196 ++++++++++ 4 files changed, 883 insertions(+) create mode 100644 drivers/net/dsa/rzn1_a5psw.c create mode 100644 drivers/net/dsa/rzn1_a5psw.h diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 37a3dabdce31..0896c5fd9dec 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -70,6 +70,15 @@ config NET_DSA_QCA8K source "drivers/net/dsa/realtek/Kconfig" +config NET_DSA_RZN1_A5PSW + tristate "Renesas RZ/N1 A5PSW Ethernet switch support" + depends on NET_DSA + select NET_DSA_TAG_RZN1_A5PSW + select PCS_RZN1_MIIC + help + This driver supports the A5PSW switch, which is embedded in Renesas + RZ/N1 SoC. + config NET_DSA_SMSC_LAN9303 tristate depends on VLAN_8021Q || VLAN_8021Q=n diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile index e73838c12256..5daf3da4344e 100644 --- a/drivers/net/dsa/Makefile +++ b/drivers/net/dsa/Makefile @@ -9,12 +9,14 @@ obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o +obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o obj-$(CONFIG_NET_DSA_SMSC_LAN9303_I2C) += lan9303_i2c.o obj-$(CONFIG_NET_DSA_SMSC_LAN9303_MDIO) += lan9303_mdio.o obj-$(CONFIG_NET_DSA_VITESSE_VSC73XX) += vitesse-vsc73xx-core.o obj-$(CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM) += vitesse-vsc73xx-platform.o obj-$(CONFIG_NET_DSA_VITESSE_VSC73XX_SPI) += vitesse-vsc73xx-spi.o + obj-y += b53/ obj-y += hirschmann/ obj-y += microchip/ diff --git a/drivers/net/dsa/rzn1_a5psw.c b/drivers/net/dsa/rzn1_a5psw.c new file mode 100644 index 000000000000..5bee999f7050 --- /dev/null +++ b/drivers/net/dsa/rzn1_a5psw.c @@ -0,0 +1,676 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 Schneider-Electric + * + * Clément Léger + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rzn1_a5psw.h" + +static void a5psw_reg_writel(struct a5psw *a5psw, int offset, u32 value) +{ + writel(value, a5psw->base + offset); +} + +static u32 a5psw_reg_readl(struct a5psw *a5psw, int offset) +{ + return readl(a5psw->base + offset); +} + +static void a5psw_reg_rmw(struct a5psw *a5psw, int offset, u32 mask, u32 val) +{ + u32 reg; + + spin_lock(&a5psw->reg_lock); + + reg = a5psw_reg_readl(a5psw, offset); + reg &= ~mask; + reg |= val; + a5psw_reg_writel(a5psw, offset, reg); + + spin_unlock(&a5psw->reg_lock); +} + +static enum dsa_tag_protocol a5psw_get_tag_protocol(struct dsa_switch *ds, + int port, + enum dsa_tag_protocol mp) +{ + return DSA_TAG_PROTO_RZN1_A5PSW; +} + +static void a5psw_port_pattern_set(struct a5psw *a5psw, int port, int pattern, + bool enable) +{ + u32 rx_match = 0; + + if (enable) + rx_match |= A5PSW_RXMATCH_CONFIG_PATTERN(pattern); + + a5psw_reg_rmw(a5psw, A5PSW_RXMATCH_CONFIG(port), + A5PSW_RXMATCH_CONFIG_PATTERN(pattern), rx_match); +} + +static void a5psw_port_mgmtfwd_set(struct a5psw *a5psw, int port, bool enable) +{ + a5psw_port_pattern_set(a5psw, port, A5PSW_PATTERN_MGMTFWD, enable); +} + +static void a5psw_port_enable_set(struct a5psw *a5psw, int port, bool enable) +{ + u32 port_ena = 0; + + if (enable) + port_ena |= A5PSW_PORT_ENA_TX_RX(port); + + a5psw_reg_rmw(a5psw, A5PSW_PORT_ENA, A5PSW_PORT_ENA_TX_RX(port), + port_ena); +} + +static int a5psw_lk_execute_ctrl(struct a5psw *a5psw, u32 *ctrl) +{ + int ret; + + a5psw_reg_writel(a5psw, A5PSW_LK_ADDR_CTRL, *ctrl); + + ret = readl_poll_timeout(a5psw->base + A5PSW_LK_ADDR_CTRL, + *ctrl, + !(*ctrl & A5PSW_LK_ADDR_CTRL_BUSY), + A5PSW_LK_BUSY_USEC_POLL, + A5PSW_CTRL_TIMEOUT); + if (ret) + dev_err(a5psw->dev, "LK_CTRL timeout waiting for BUSY bit\n"); + + return ret; +} + +static void a5psw_port_fdb_flush(struct a5psw *a5psw, int port) +{ + u32 ctrl = A5PSW_LK_ADDR_CTRL_DELETE_PORT | BIT(port); + + spin_lock(&a5psw->lk_lock); + a5psw_lk_execute_ctrl(a5psw, &ctrl); + spin_unlock(&a5psw->lk_lock); +} + +static void a5psw_port_authorize_set(struct a5psw *a5psw, int port, + bool authorize) +{ + u32 reg = a5psw_reg_readl(a5psw, A5PSW_AUTH_PORT(port)); + + if (authorize) + reg |= A5PSW_AUTH_PORT_AUTHORIZED; + else + reg &= ~A5PSW_AUTH_PORT_AUTHORIZED; + + a5psw_reg_writel(a5psw, A5PSW_AUTH_PORT(port), reg); +} + +static void a5psw_port_disable(struct dsa_switch *ds, int port) +{ + struct a5psw *a5psw = ds->priv; + + a5psw_port_authorize_set(a5psw, port, false); + a5psw_port_enable_set(a5psw, port, false); + a5psw_port_fdb_flush(a5psw, port); +} + +static int a5psw_port_enable(struct dsa_switch *ds, int port, + struct phy_device *phy) +{ + struct a5psw *a5psw = ds->priv; + + a5psw_port_authorize_set(a5psw, port, true); + a5psw_port_enable_set(a5psw, port, true); + + return 0; +} + +static int a5psw_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) +{ + struct a5psw *a5psw = ds->priv; + + new_mtu += ETH_HLEN + A5PSW_EXTRA_MTU_LEN + ETH_FCS_LEN; + a5psw_reg_writel(a5psw, A5PSW_FRM_LENGTH(port), new_mtu); + + return 0; +} + +static int a5psw_port_max_mtu(struct dsa_switch *ds, int port) +{ + return A5PSW_JUMBO_LEN - A5PSW_TAG_LEN; +} + +static void a5psw_phylink_validate(struct dsa_switch *ds, int port, + unsigned long *supported, + struct phylink_link_state *state) +{ + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0 }; + + phylink_set_port_modes(mask); + + phylink_set(mask, Autoneg); + phylink_set(mask, Pause); + phylink_set(mask, Asym_Pause); + + phylink_set(mask, 1000baseT_Full); + if (!dsa_is_cpu_port(ds, port)) { + phylink_set(mask, 10baseT_Half); + phylink_set(mask, 10baseT_Full); + phylink_set(mask, 100baseT_Half); + phylink_set(mask, 100baseT_Full); + } + + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); +} + +static struct phylink_pcs * +a5psw_phylink_mac_select_pcs(struct dsa_switch *ds, int port, + phy_interface_t interface) +{ + struct dsa_port *dp = dsa_to_port(ds, port); + struct a5psw *a5psw = ds->priv; + + if (!dsa_port_is_cpu(dp) && a5psw->pcs[port]) + return a5psw->pcs[port]; + + return NULL; +} + +static void a5psw_phylink_mac_link_down(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface) +{ + struct a5psw *a5psw = ds->priv; + u32 cmd_cfg; + + cmd_cfg = a5psw_reg_readl(a5psw, A5PSW_CMD_CFG(port)); + cmd_cfg &= ~(A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA); + a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), cmd_cfg); +} + +static void a5psw_phylink_mac_link_up(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface, + struct phy_device *phydev, int speed, + int duplex, bool tx_pause, + bool rx_pause) +{ + u32 cmd_cfg = A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA | + A5PSW_CMD_CFG_TX_CRC_APPEND; + struct a5psw *a5psw = ds->priv; + + if (speed == SPEED_1000) + cmd_cfg |= A5PSW_CMD_CFG_ETH_SPEED; + + if (duplex == DUPLEX_HALF) + cmd_cfg |= A5PSW_CMD_CFG_HD_ENA; + + cmd_cfg |= A5PSW_CMD_CFG_CNTL_FRM_ENA; + + if (!rx_pause) + cmd_cfg &= ~A5PSW_CMD_CFG_PAUSE_IGNORE; + + a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), cmd_cfg); +} + +static int a5psw_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) +{ + struct a5psw *a5psw = ds->priv; + unsigned long rate; + u64 max, tmp; + u32 agetime; + + rate = clk_get_rate(a5psw->clk); + max = div64_ul(((u64)A5PSW_LK_AGETIME_MASK * A5PSW_TABLE_ENTRIES * 1024), + rate) * 1000; + if (msecs > max) + return -EINVAL; + + tmp = div_u64(rate, MSEC_PER_SEC); + agetime = div_u64(msecs * tmp, 1024 * A5PSW_TABLE_ENTRIES); + + a5psw_reg_writel(a5psw, A5PSW_LK_AGETIME, agetime); + + return 0; +} + +static void a5psw_flooding_set_resolution(struct a5psw *a5psw, int port, + bool set) +{ + u8 offsets[] = {A5PSW_UCAST_DEF_MASK, A5PSW_BCAST_DEF_MASK, + A5PSW_MCAST_DEF_MASK}; + int i; + + if (set) + a5psw->flooding_ports |= BIT(port); + else + a5psw->flooding_ports &= ~BIT(port); + + for (i = 0; i < ARRAY_SIZE(offsets); i++) + a5psw_reg_writel(a5psw, offsets[i], a5psw->flooding_ports); +} + +static int a5psw_port_bridge_join(struct dsa_switch *ds, int port, + struct dsa_bridge bridge, + bool *tx_fwd_offload, + struct netlink_ext_ack *extack) +{ + struct a5psw *a5psw = ds->priv; + + a5psw_flooding_set_resolution(a5psw, port, true); + a5psw_port_mgmtfwd_set(a5psw, port, false); + + return 0; +} + +static void a5psw_port_bridge_leave(struct dsa_switch *ds, int port, + struct dsa_bridge bridge) +{ + struct a5psw *a5psw = ds->priv; + + a5psw_flooding_set_resolution(a5psw, port, false); + a5psw_port_mgmtfwd_set(a5psw, port, true); +} + +static void a5psw_port_stp_state_set(struct dsa_switch *ds, int port, + u8 state) +{ + struct a5psw *a5psw = ds->priv; + u32 reg = 0; + u32 mask = A5PSW_INPUT_LEARN_DIS(port) | A5PSW_INPUT_LEARN_BLOCK(port); + + switch (state) { + case BR_STATE_DISABLED: + case BR_STATE_BLOCKING: + reg |= A5PSW_INPUT_LEARN_DIS(port); + reg |= A5PSW_INPUT_LEARN_BLOCK(port); + break; + case BR_STATE_LISTENING: + reg |= A5PSW_INPUT_LEARN_DIS(port); + break; + case BR_STATE_LEARNING: + reg |= A5PSW_INPUT_LEARN_BLOCK(port); + break; + case BR_STATE_FORWARDING: + default: + break; + } + + a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN, mask, reg); +} + +static void a5psw_port_fast_age(struct dsa_switch *ds, int port) +{ + struct a5psw *a5psw = ds->priv; + + a5psw_port_fdb_flush(a5psw, port); +} + +static int a5psw_setup(struct dsa_switch *ds) +{ + struct a5psw *a5psw = ds->priv; + int port, vlan, ret; + u32 reg; + + /* Configure management port */ + reg = A5PSW_CPU_PORT | A5PSW_MGMT_CFG_DISCARD; + a5psw_reg_writel(a5psw, A5PSW_MGMT_CFG, reg); + + /* Set pattern 0 to forward all frame to mgmt port */ + a5psw_reg_writel(a5psw, A5PSW_PATTERN_CTRL(0), + A5PSW_PATTERN_CTRL_MGMTFWD); + + /* Enable port tagging */ + reg = FIELD_PREP(A5PSW_MGMT_TAG_CFG_TAGFIELD, A5PSW_MGMT_TAG_VALUE); + reg |= A5PSW_MGMT_TAG_CFG_ENABLE | A5PSW_MGMT_TAG_CFG_ALL_FRAMES; + a5psw_reg_writel(a5psw, A5PSW_MGMT_TAG_CFG, reg); + + /* Enable normal switch operation */ + reg = A5PSW_LK_ADDR_CTRL_BLOCKING | A5PSW_LK_ADDR_CTRL_LEARNING | + A5PSW_LK_ADDR_CTRL_AGEING | A5PSW_LK_ADDR_CTRL_ALLOW_MIGR | + A5PSW_LK_ADDR_CTRL_CLEAR_TABLE; + a5psw_reg_writel(a5psw, A5PSW_LK_CTRL, reg); + + ret = readl_poll_timeout(a5psw->base + A5PSW_LK_CTRL, + reg, + !(reg & A5PSW_LK_ADDR_CTRL_CLEAR_TABLE), + A5PSW_LK_BUSY_USEC_POLL, + A5PSW_CTRL_TIMEOUT); + if (ret) { + dev_err(a5psw->dev, "Failed to clear lookup table\n"); + return ret; + } + + /* Reset learn count to 0 */ + reg = A5PSW_LK_LEARNCOUNT_MODE_SET; + a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg); + + /* Clear VLAN resource table */ + reg = A5PSW_VLAN_RES_WR_PORTMASK | A5PSW_VLAN_RES_WR_TAGMASK; + for (vlan = 0; vlan < A5PSW_VLAN_COUNT; vlan++) + a5psw_reg_writel(a5psw, A5PSW_VLAN_RES(vlan), reg); + + /* Reset all ports */ + for (port = 0; port < ds->num_ports; port++) { + /* Reset the port */ + a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), + A5PSW_CMD_CFG_SW_RESET); + + /* Enable only CPU port */ + a5psw_port_enable_set(a5psw, port, dsa_is_cpu_port(ds, port)); + + if (dsa_is_unused_port(ds, port)) + continue; + + /* Enable egress flooding for CPU port */ + if (dsa_is_cpu_port(ds, port)) + a5psw_flooding_set_resolution(a5psw, port, true); + + /* Enable management forward only for user ports */ + if (dsa_is_user_port(ds, port)) + a5psw_port_mgmtfwd_set(a5psw, port, true); + } + + return 0; +} + +const struct dsa_switch_ops a5psw_switch_ops = { + .get_tag_protocol = a5psw_get_tag_protocol, + .setup = a5psw_setup, + .port_disable = a5psw_port_disable, + .port_enable = a5psw_port_enable, + .phylink_validate = a5psw_phylink_validate, + .phylink_mac_select_pcs = a5psw_phylink_mac_select_pcs, + .phylink_mac_link_down = a5psw_phylink_mac_link_down, + .phylink_mac_link_up = a5psw_phylink_mac_link_up, + .port_change_mtu = a5psw_port_change_mtu, + .port_max_mtu = a5psw_port_max_mtu, + .set_ageing_time = a5psw_set_ageing_time, + .port_bridge_join = a5psw_port_bridge_join, + .port_bridge_leave = a5psw_port_bridge_leave, + .port_stp_state_set = a5psw_port_stp_state_set, + .port_fast_age = a5psw_port_fast_age, + +}; + +static int a5psw_mdio_wait_busy(struct a5psw *a5psw) +{ + u32 status; + int err; + + err = readl_poll_timeout(a5psw->base + A5PSW_MDIO_CFG_STATUS, + status, + !(status & A5PSW_MDIO_CFG_STATUS_BUSY), + 10, + 1000 * USEC_PER_MSEC); + if (err) + dev_err(a5psw->dev, "MDIO command timeout\n"); + + return err; +} + +static int a5psw_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg) +{ + struct a5psw *a5psw = bus->priv; + u32 cmd, status; + int ret; + + cmd = A5PSW_MDIO_COMMAND_READ; + cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_REG_ADDR, phy_reg); + cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_PHY_ADDR, phy_id); + + a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd); + + ret = a5psw_mdio_wait_busy(a5psw); + if (ret) + return ret; + + ret = a5psw_reg_readl(a5psw, A5PSW_MDIO_DATA) & A5PSW_MDIO_DATA_MASK; + + status = a5psw_reg_readl(a5psw, A5PSW_MDIO_CFG_STATUS); + if (status & A5PSW_MDIO_CFG_STATUS_READERR) + return -EIO; + + return ret; +} + +static int a5psw_mdio_write(struct mii_bus *bus, int phy_id, int phy_reg, + u16 phy_data) +{ + struct a5psw *a5psw = bus->priv; + u32 cmd; + + cmd = FIELD_PREP(A5PSW_MDIO_COMMAND_REG_ADDR, phy_reg); + cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_PHY_ADDR, phy_id); + + a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd); + a5psw_reg_writel(a5psw, A5PSW_MDIO_DATA, phy_data); + + return a5psw_mdio_wait_busy(a5psw); +} + +static int a5psw_mdio_reset(struct mii_bus *bus) +{ + struct a5psw *a5psw = bus->priv; + unsigned long rate; + unsigned long div; + u32 cfgstatus; + + rate = clk_get_rate(a5psw->hclk); + div = ((rate / a5psw->mdio_freq) / 2); + if (div >= 511 || div <= 5) { + dev_err(a5psw->dev, "MDIO clock div %ld out of range\n", div); + return -ERANGE; + } + + cfgstatus = FIELD_PREP(A5PSW_MDIO_CFG_STATUS_CLKDIV, div); + + a5psw_reg_writel(a5psw, A5PSW_MDIO_CFG_STATUS, cfgstatus); + + return 0; +} + +static int a5psw_probe_mdio(struct a5psw *a5psw) +{ + struct device *dev = a5psw->dev; + struct device_node *mdio_node; + struct mii_bus *bus; + int err; + + if (of_property_read_u32(dev->of_node, "clock-frequency", + &a5psw->mdio_freq)) + a5psw->mdio_freq = A5PSW_MDIO_DEF_FREQ; + + bus = devm_mdiobus_alloc(dev); + if (!bus) + return -ENOMEM; + + bus->name = "a5psw_mdio"; + bus->read = a5psw_mdio_read; + bus->write = a5psw_mdio_write; + bus->reset = a5psw_mdio_reset; + bus->priv = a5psw; + bus->parent = dev; + snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev)); + + a5psw->mii_bus = bus; + + mdio_node = of_get_child_by_name(dev->of_node, "mdio"); + err = devm_of_mdiobus_register(dev, bus, mdio_node); + of_node_put(mdio_node); + if (err) + return err; + + return 0; +} + +static void a5psw_pcs_free(struct a5psw *a5psw) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(a5psw->pcs); i++) { + if (a5psw->pcs[i]) + miic_destroy(a5psw->pcs[i]); + } +} + +static int a5psw_pcs_get(struct a5psw *a5psw) +{ + struct device_node *ports, *port, *pcs_node; + struct phylink_pcs *pcs; + int ret; + u32 reg; + + ports = of_get_child_by_name(a5psw->dev->of_node, "ports"); + if (!ports) + return -EINVAL; + + for_each_available_child_of_node(ports, port) { + pcs_node = of_parse_phandle(port, "pcs-handle", 0); + if (!pcs_node) + continue; + + if (of_property_read_u32(port, "reg", ®)) { + ret = -EINVAL; + goto free_pcs; + } + + if (reg >= ARRAY_SIZE(a5psw->pcs)) { + ret = -ENODEV; + goto free_pcs; + } + + pcs = miic_create(pcs_node); + if (IS_ERR(pcs)) { + ret = PTR_ERR(pcs); + goto free_pcs; + } + + a5psw->pcs[reg] = pcs; + } + of_node_put(ports); + + return 0; + +free_pcs: + a5psw_pcs_free(a5psw); + + return ret; +} + +static int a5psw_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct dsa_switch *ds; + struct a5psw *a5psw; + int ret; + + a5psw = devm_kzalloc(dev, sizeof(*a5psw), GFP_KERNEL); + if (!a5psw) + return -ENOMEM; + + a5psw->dev = dev; + spin_lock_init(&a5psw->lk_lock); + spin_lock_init(&a5psw->reg_lock); + a5psw->base = devm_platform_ioremap_resource(pdev, 0); + if (!a5psw->base) + return -EINVAL; + + /* Probe PCS */ + ret = a5psw_pcs_get(a5psw); + if (ret) + return ret; + + a5psw->hclk = devm_clk_get(dev, "hclk"); + if (IS_ERR(a5psw->hclk)) { + dev_err(dev, "failed get hclk clock\n"); + ret = PTR_ERR(a5psw->hclk); + goto free_pcs; + } + + a5psw->clk = devm_clk_get(dev, "clk"); + if (IS_ERR(a5psw->clk)) { + dev_err(dev, "failed get clk_switch clock\n"); + ret = PTR_ERR(a5psw->clk); + goto free_pcs; + } + + ret = clk_prepare_enable(a5psw->clk); + if (ret) + goto free_pcs; + + ret = clk_prepare_enable(a5psw->hclk); + if (ret) + goto clk_disable; + + ret = a5psw_probe_mdio(a5psw); + if (ret) { + dev_err(&pdev->dev, "Failed to register MDIO: %d\n", ret); + goto hclk_disable; + } + + ds = &a5psw->ds; + ds->dev = &pdev->dev; + ds->num_ports = A5PSW_PORTS_NUM; + ds->ops = &a5psw_switch_ops; + ds->priv = a5psw; + + ret = dsa_register_switch(ds); + if (ret) { + dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", ret); + goto hclk_disable; + } + + return 0; + +hclk_disable: + clk_disable_unprepare(a5psw->hclk); +clk_disable: + clk_disable_unprepare(a5psw->clk); +free_pcs: + a5psw_pcs_free(a5psw); + + return ret; +} + +static int a5psw_remove(struct platform_device *pdev) +{ + struct a5psw *a5psw = platform_get_drvdata(pdev); + + dsa_unregister_switch(&a5psw->ds); + a5psw_pcs_free(a5psw); + clk_disable_unprepare(a5psw->hclk); + clk_disable_unprepare(a5psw->clk); + + return 0; +} + +static const struct of_device_id a5psw_of_mtable[] = { + { .compatible = "renesas,rzn1-a5psw", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, a5psw_of_mtable); + +static struct platform_driver a5psw_driver = { + .driver = { + .name = "rzn1_a5psw", + .of_match_table = of_match_ptr(a5psw_of_mtable), + }, + .probe = a5psw_probe, + .remove = a5psw_remove, +}; +module_platform_driver(a5psw_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Renesas RZ/N1 Advanced 5-port Switch driver"); +MODULE_AUTHOR("Clément Léger "); diff --git a/drivers/net/dsa/rzn1_a5psw.h b/drivers/net/dsa/rzn1_a5psw.h new file mode 100644 index 000000000000..2d96a2afbc3a --- /dev/null +++ b/drivers/net/dsa/rzn1_a5psw.h @@ -0,0 +1,196 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2022 Schneider Electric + * + * Clément Léger + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define A5PSW_REVISION 0x0 +#define A5PSW_PORT_OFFSET(port) (0x400 * (port)) + +#define A5PSW_PORT_ENA 0x8 +#define A5PSW_PORT_ENA_RX_SHIFT 16 +#define A5PSW_PORT_ENA_TX_RX(port) (BIT((port) + A5PSW_PORT_ENA_RX_SHIFT) | \ + BIT(port)) +#define A5PSW_UCAST_DEF_MASK 0xC + +#define A5PSW_VLAN_VERIFY 0x10 +#define A5PSW_VLAN_VERI_SHIFT 0 +#define A5PSW_VLAN_DISC_SHIFT 16 + +#define A5PSW_BCAST_DEF_MASK 0x14 +#define A5PSW_MCAST_DEF_MASK 0x18 + +#define A5PSW_INPUT_LEARN 0x1C +#define A5PSW_INPUT_LEARN_DIS(p) BIT((p) + 16) +#define A5PSW_INPUT_LEARN_BLOCK(p) BIT(p) + +#define A5PSW_MGMT_CFG 0x20 +#define A5PSW_MGMT_CFG_DISCARD BIT(7) + +#define A5PSW_MODE_CFG 0x24 +#define A5PSW_MODE_STATS_RESET BIT(31) + +#define A5PSW_VLAN_IN_MODE 0x28 +#define A5PSW_VLAN_IN_MODE_PORT_SHIFT(port) ((port) * 2) +#define A5PSW_VLAN_IN_MODE_PORT(port) (GENMASK(1, 0) << \ + A5PSW_VLAN_IN_MODE_PORT_SHIFT(port)) +#define A5PSW_VLAN_IN_MODE_SINGLE_PASSTHROUGH 0x0 +#define A5PSW_VLAN_IN_MODE_SINGLE_REPLACE 0x1 +#define A5PSW_VLAN_IN_MODE_TAG_ALWAYS 0x2 + +#define A5PSW_VLAN_OUT_MODE 0x2C +#define A5PSW_VLAN_OUT_MODE_PORT(port) (GENMASK(1, 0) << ((port) * 2)) +#define A5PSW_VLAN_OUT_MODE_DIS 0x0 +#define A5PSW_VLAN_OUT_MODE_STRIP 0x1 +#define A5PSW_VLAN_OUT_MODE_TAG_THROUGH 0x2 +#define A5PSW_VLAN_OUT_MODE_TRANSPARENT 0x3 + +#define A5PSW_VLAN_IN_MODE_ENA 0x30 +#define A5PSW_VLAN_TAG_ID 0x34 + +#define A5PSW_SYSTEM_TAGINFO(port) (0x200 + A5PSW_PORT_OFFSET(port)) + +#define A5PSW_AUTH_PORT(port) (0x240 + 4 * (port)) +#define A5PSW_AUTH_PORT_AUTHORIZED BIT(0) + +#define A5PSW_VLAN_RES(entry) (0x280 + 4 * (entry)) +#define A5PSW_VLAN_RES_WR_PORTMASK BIT(30) +#define A5PSW_VLAN_RES_WR_TAGMASK BIT(29) +#define A5PSW_VLAN_RES_RD_TAGMASK BIT(28) +#define A5PSW_VLAN_RES_ID GENMASK(16, 5) +#define A5PSW_VLAN_RES_PORTMASK GENMASK(4, 0) + +#define A5PSW_RXMATCH_CONFIG(port) (0x3e80 + 4 * (port)) +#define A5PSW_RXMATCH_CONFIG_PATTERN(p) BIT(p) + +#define A5PSW_PATTERN_CTRL(p) (0x3eb0 + 4 * (p)) +#define A5PSW_PATTERN_CTRL_MGMTFWD BIT(1) + +#define A5PSW_LK_CTRL 0x400 +#define A5PSW_LK_ADDR_CTRL_BLOCKING BIT(0) +#define A5PSW_LK_ADDR_CTRL_LEARNING BIT(1) +#define A5PSW_LK_ADDR_CTRL_AGEING BIT(2) +#define A5PSW_LK_ADDR_CTRL_ALLOW_MIGR BIT(3) +#define A5PSW_LK_ADDR_CTRL_CLEAR_TABLE BIT(6) + +#define A5PSW_LK_ADDR_CTRL 0x408 +#define A5PSW_LK_ADDR_CTRL_BUSY BIT(31) +#define A5PSW_LK_ADDR_CTRL_DELETE_PORT BIT(30) +#define A5PSW_LK_ADDR_CTRL_CLEAR BIT(29) +#define A5PSW_LK_ADDR_CTRL_LOOKUP BIT(28) +#define A5PSW_LK_ADDR_CTRL_WAIT BIT(27) +#define A5PSW_LK_ADDR_CTRL_READ BIT(26) +#define A5PSW_LK_ADDR_CTRL_WRITE BIT(25) +#define A5PSW_LK_ADDR_CTRL_ADDRESS GENMASK(12, 0) + +#define A5PSW_LK_DATA_LO 0x40C +#define A5PSW_LK_DATA_HI 0x410 +#define A5PSW_LK_DATA_HI_VALID BIT(16) +#define A5PSW_LK_DATA_HI_PORT BIT(16) + +#define A5PSW_LK_LEARNCOUNT 0x418 +#define A5PSW_LK_LEARNCOUNT_COUNT GENMASK(13, 0) +#define A5PSW_LK_LEARNCOUNT_MODE GENMASK(31, 30) +#define A5PSW_LK_LEARNCOUNT_MODE_SET 0x0 +#define A5PSW_LK_LEARNCOUNT_MODE_INC 0x1 +#define A5PSW_LK_LEARNCOUNT_MODE_DEC 0x2 + +#define A5PSW_MGMT_TAG_CFG 0x480 +#define A5PSW_MGMT_TAG_CFG_TAGFIELD GENMASK(31, 16) +#define A5PSW_MGMT_TAG_CFG_ALL_FRAMES BIT(1) +#define A5PSW_MGMT_TAG_CFG_ENABLE BIT(0) + +#define A5PSW_LK_AGETIME 0x41C +#define A5PSW_LK_AGETIME_MASK GENMASK(23, 0) + +#define A5PSW_MDIO_CFG_STATUS 0x700 +#define A5PSW_MDIO_CFG_STATUS_CLKDIV GENMASK(15, 7) +#define A5PSW_MDIO_CFG_STATUS_READERR BIT(1) +#define A5PSW_MDIO_CFG_STATUS_BUSY BIT(0) + +#define A5PSW_MDIO_COMMAND 0x704 +/* Register is named TRAININIT in datasheet and should be set when reading */ +#define A5PSW_MDIO_COMMAND_READ BIT(15) +#define A5PSW_MDIO_COMMAND_PHY_ADDR GENMASK(9, 5) +#define A5PSW_MDIO_COMMAND_REG_ADDR GENMASK(4, 0) + +#define A5PSW_MDIO_DATA 0x708 +#define A5PSW_MDIO_DATA_MASK GENMASK(15, 0) + +#define A5PSW_CMD_CFG(port) (0x808 + A5PSW_PORT_OFFSET(port)) +#define A5PSW_CMD_CFG_CNTL_FRM_ENA BIT(23) +#define A5PSW_CMD_CFG_SW_RESET BIT(13) +#define A5PSW_CMD_CFG_TX_CRC_APPEND BIT(11) +#define A5PSW_CMD_CFG_HD_ENA BIT(10) +#define A5PSW_CMD_CFG_PAUSE_IGNORE BIT(8) +#define A5PSW_CMD_CFG_CRC_FWD BIT(6) +#define A5PSW_CMD_CFG_ETH_SPEED BIT(3) +#define A5PSW_CMD_CFG_RX_ENA BIT(1) +#define A5PSW_CMD_CFG_TX_ENA BIT(0) + +#define A5PSW_FRM_LENGTH(port) (0x814 + A5PSW_PORT_OFFSET(port)) +#define A5PSW_FRM_LENGTH_MASK GENMASK(13, 0) + +#define A5PSW_STATUS(port) (0x840 + A5PSW_PORT_OFFSET(port)) + +#define A5PSW_STATS_HIWORD 0x900 + +#define A5PSW_DUMMY_WORKAROUND 0x5000 + +#define A5PSW_VLAN_TAG(prio, id) (((prio) << 12) | (id)) +#define A5PSW_PORTS_NUM 5 +#define A5PSW_CPU_PORT (A5PSW_PORTS_NUM - 1) +#define A5PSW_MDIO_DEF_FREQ 2500000 +#define A5PSW_MDIO_TIMEOUT 100 +#define A5PSW_JUMBO_LEN (10 * SZ_1K) +#define A5PSW_TAG_LEN 8 +#define A5PSW_VLAN_COUNT 32 + +/* Ensure enough space for 2 VLAN tags */ +#define A5PSW_EXTRA_MTU_LEN (A5PSW_TAG_LEN + 8) +#define A5PSW_MGMT_TAG_VALUE 0xE001 + +#define A5PSW_PATTERN_MGMTFWD 0 + +#define A5PSW_LK_BUSY_USEC_POLL 10 +#define A5PSW_CTRL_TIMEOUT 1000 +#define A5PSW_TABLE_ENTRIES 8192 + +/** + * struct a5psw - switch struct + * @base: Base address of the switch + * @hclk_rate: hclk_switch clock rate + * @clk_rate: clk_switch clock rate + * @dev: Device associated to the switch + * @mii_bus: MDIO bus struct + * @mdio_freq: MDIO bus frequency requested + * @pcs: Array of PCS connected to the switch ports (not for the CPU) + * @ds: DSA switch struct + * @lk_lock: Lock for the lookup table + * @reg_lock: Lock for register read-modify-write operation + * @flooding_ports: List of ports that should be flooded + */ +struct a5psw { + void __iomem *base; + struct clk* hclk; + struct clk* clk; + struct device *dev; + struct mii_bus *mii_bus; + u32 mdio_freq; + struct phylink_pcs *pcs[A5PSW_PORTS_NUM - 1]; + struct dsa_switch ds; + spinlock_t lk_lock; + spinlock_t reg_lock; + u32 flooding_ports; +}; From patchwork Thu Apr 14 12:22:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813439 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3A6B1C433FE for ; Thu, 14 Apr 2022 12:30:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243288AbiDNMdQ (ORCPT ); Thu, 14 Apr 2022 08:33:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50798 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243310AbiDNMdN (ORCPT ); Thu, 14 Apr 2022 08:33:13 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D96F8275E3 for ; Thu, 14 Apr 2022 05:30:47 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [IPv6:2001:4b98:dc4:8::222]) by mslow1.mail.gandi.net (Postfix) with ESMTP id CB2C3CF231 for ; Thu, 14 Apr 2022 12:24:59 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id DB01040011; Thu, 14 Apr 2022 12:24:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939093; 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=cK1q3GoW1XIF/YF8LlVHAMZt+VQi14OcCuETPC0h7lg=; b=ktdbfLdoTLhrltw28ZpmX9o+ZahqCBw4lZHR1TrsNLUFjYV7ve7qb8CkVYm6MwLNT61lFp iAeJgkpap8p8+GfoFN+7pyiu5HIBZcgzPmDIhHRRgvD713Y15IdlphDDUGuzo/jt6HUrFR Oum0LWPPemQ5iY3lSBRKQS0wtSdf2LoGpftCsBI3THWQjJhw6SRtPdSIolak+BdTJyz5Ar Dz1guQ97kz/PCKXDwKO0uLygU7B2O9YrTTDAZuuBKGgRAQwkyDuiDhbU6HTkxsPTmjuzsX qxaMzo4nWLBu2wpHUSRfNkOgpu7khaH8d6Ee18HvLinNjC8J0H3KjRABNg/T3w== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 07/12] net: dsa: rzn1-a5psw: add statistics support Date: Thu, 14 Apr 2022 14:22:45 +0200 Message-Id: <20220414122250.158113-8-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add per-port statistics. This support requries to add a stat lock since statistics are stored in two 32 bits registers, the hi part one being global and latched when accessing the lo part. Signed-off-by: Clément Léger --- drivers/net/dsa/rzn1_a5psw.c | 101 +++++++++++++++++++++++++++++++++++ drivers/net/dsa/rzn1_a5psw.h | 2 + 2 files changed, 103 insertions(+) diff --git a/drivers/net/dsa/rzn1_a5psw.c b/drivers/net/dsa/rzn1_a5psw.c index 5bee999f7050..7ab7d9054427 100644 --- a/drivers/net/dsa/rzn1_a5psw.c +++ b/drivers/net/dsa/rzn1_a5psw.c @@ -16,6 +16,59 @@ #include "rzn1_a5psw.h" +struct a5psw_stats { + u16 offset; + const char *name; +}; + +#define STAT_DESC(_offset, _name) {.offset = _offset, .name = _name} + +static const struct a5psw_stats a5psw_stats[] = { + STAT_DESC(0x868, "aFrameTransmitted"), + STAT_DESC(0x86C, "aFrameReceived"), + STAT_DESC(0x870, "aFrameCheckSequenceErrors"), + STAT_DESC(0x874, "aAlignmentErrors"), + STAT_DESC(0x878, "aOctetsTransmitted"), + STAT_DESC(0x87C, "aOctetsReceived"), + STAT_DESC(0x880, "aTxPAUSEMACCtrlFrames"), + STAT_DESC(0x884, "aRxPAUSEMACCtrlFrames"), + /* If */ + STAT_DESC(0x888, "ifInErrors"), + STAT_DESC(0x88C, "ifOutErrors"), + STAT_DESC(0x890, "ifInUcastPkts"), + STAT_DESC(0x894, "ifInMulticastPkts"), + STAT_DESC(0x898, "ifInBroadcastPkts"), + STAT_DESC(0x89C, "ifOutDiscards"), + STAT_DESC(0x8A0, "ifOutUcastPkts"), + STAT_DESC(0x8A4, "ifOutMulticastPkts"), + STAT_DESC(0x8A8, "ifOutBroadcastPkts"), + /* Ether */ + STAT_DESC(0x8AC, "etherStatsDropEvents"), + STAT_DESC(0x8B0, "etherStatsOctets"), + STAT_DESC(0x8B4, "etherStatsPkts"), + STAT_DESC(0x8B8, "etherStatsUndersizePkts"), + STAT_DESC(0x8BC, "etherStatsetherStatsOversizePktsDropEvents"), + STAT_DESC(0x8C0, "etherStatsPkts64Octets"), + STAT_DESC(0x8C4, "etherStatsPkts65to127Octets"), + STAT_DESC(0x8C8, "etherStatsPkts128to255Octets"), + STAT_DESC(0x8CC, "etherStatsPkts256to511Octets"), + STAT_DESC(0x8D0, "etherStatsPkts512to1023Octets"), + STAT_DESC(0x8D4, "etherStatsPkts1024to1518Octets"), + STAT_DESC(0x8D8, "etherStatsPkts1519toXOctets"), + STAT_DESC(0x8DC, "etherStatsJabbers"), + STAT_DESC(0x8E0, "etherStatsFragments"), + + STAT_DESC(0x8E8, "VLANReceived"), + STAT_DESC(0x8EC, "VLANTransmitted"), + + STAT_DESC(0x910, "aDeferred"), + STAT_DESC(0x914, "aMultipleCollisions"), + STAT_DESC(0x918, "aSingleCollisions"), + STAT_DESC(0x91C, "aLateCollisions"), + STAT_DESC(0x920, "aExcessiveCollisions"), + STAT_DESC(0x924, "aCarrierSenseErrors"), +}; + static void a5psw_reg_writel(struct a5psw *a5psw, int offset, u32 value) { writel(value, a5psw->base + offset); @@ -316,6 +369,50 @@ static void a5psw_port_fast_age(struct dsa_switch *ds, int port) a5psw_port_fdb_flush(a5psw, port); } +static void a5psw_get_strings(struct dsa_switch *ds, int port, u32 stringset, + uint8_t *data) +{ + unsigned int u; + + if (stringset != ETH_SS_STATS) + return; + + for (u = 0; u < ARRAY_SIZE(a5psw_stats); u++) { + strncpy(data + u * ETH_GSTRING_LEN, a5psw_stats[u].name, + ETH_GSTRING_LEN); + } +} + +static void a5psw_get_ethtool_stats(struct dsa_switch *ds, int port, + uint64_t *data) +{ + struct a5psw *a5psw = ds->priv; + u32 reg_lo, reg_hi; + unsigned int u; + + for (u = 0; u < ARRAY_SIZE(a5psw_stats); u++) { + /* A5PSW_STATS_HIWORD is global and thus, access must be + * exclusive + */ + spin_lock(&a5psw->stats_lock); + reg_lo = a5psw_reg_readl(a5psw, a5psw_stats[u].offset + + A5PSW_PORT_OFFSET(port)); + /* A5PSW_STATS_HIWORD is latched on stat read */ + reg_hi = a5psw_reg_readl(a5psw, A5PSW_STATS_HIWORD); + + data[u] = ((u64)reg_hi << 32) | reg_lo; + spin_unlock(&a5psw->stats_lock); + } +} + +static int a5psw_get_sset_count(struct dsa_switch *ds, int port, int sset) +{ + if (sset != ETH_SS_STATS) + return 0; + + return ARRAY_SIZE(a5psw_stats); +} + static int a5psw_setup(struct dsa_switch *ds) { struct a5psw *a5psw = ds->priv; @@ -395,6 +492,9 @@ const struct dsa_switch_ops a5psw_switch_ops = { .phylink_mac_link_up = a5psw_phylink_mac_link_up, .port_change_mtu = a5psw_port_change_mtu, .port_max_mtu = a5psw_port_max_mtu, + .get_sset_count = a5psw_get_sset_count, + .get_strings = a5psw_get_strings, + .get_ethtool_stats = a5psw_get_ethtool_stats, .set_ageing_time = a5psw_set_ageing_time, .port_bridge_join = a5psw_port_bridge_join, .port_bridge_leave = a5psw_port_bridge_leave, @@ -580,6 +680,7 @@ static int a5psw_probe(struct platform_device *pdev) return -ENOMEM; a5psw->dev = dev; + spin_lock_init(&a5psw->stats_lock); spin_lock_init(&a5psw->lk_lock); spin_lock_init(&a5psw->reg_lock); a5psw->base = devm_platform_ioremap_resource(pdev, 0); diff --git a/drivers/net/dsa/rzn1_a5psw.h b/drivers/net/dsa/rzn1_a5psw.h index 2d96a2afbc3a..b34ea549e936 100644 --- a/drivers/net/dsa/rzn1_a5psw.h +++ b/drivers/net/dsa/rzn1_a5psw.h @@ -177,6 +177,7 @@ * @mdio_freq: MDIO bus frequency requested * @pcs: Array of PCS connected to the switch ports (not for the CPU) * @ds: DSA switch struct + * @stats_lock: lock to access statistics (shared HI counter) * @lk_lock: Lock for the lookup table * @reg_lock: Lock for register read-modify-write operation * @flooding_ports: List of ports that should be flooded @@ -190,6 +191,7 @@ struct a5psw { u32 mdio_freq; struct phylink_pcs *pcs[A5PSW_PORTS_NUM - 1]; struct dsa_switch ds; + spinlock_t stats_lock; spinlock_t lk_lock; spinlock_t reg_lock; u32 flooding_ports; From patchwork Thu Apr 14 12:22:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813438 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96347C433EF for ; Thu, 14 Apr 2022 12:30:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236509AbiDNMdQ (ORCPT ); Thu, 14 Apr 2022 08:33:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50804 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243314AbiDNMdN (ORCPT ); Thu, 14 Apr 2022 08:33:13 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D990728E0B for ; Thu, 14 Apr 2022 05:30:47 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [IPv6:2001:4b98:dc4:8::222]) by mslow1.mail.gandi.net (Postfix) with ESMTP id 9A745CF232 for ; Thu, 14 Apr 2022 12:25:01 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 962B340002; Thu, 14 Apr 2022 12:24:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939095; 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=h9gVl1WIs8Z8UsupszQpWZh1q9U2WdRb4t2hl3wiUik=; b=gKjrfFgN+jnimsR+rmxwFBH3T6yZjzEo8ElLzhryGLKSWNDc5As2AaD4XGvLzPtSDcuf8b /cjbl50pyr5ZAk+7GF5Y+a2TrPtChcpxXi6WiIPOEK7EkIQuNPHKQ0ffRG0zOtBtTlCgSr 324RC4kSe3kvQii9KuNLVaZekO21q/Se3m8A+/uRU9xPWV2mQ2qtw8bdLOhQns6DLVGYAX jvsr7mUMzuJ6s7aSLwtFgrYNjq0y9IvC0wSTVBCYSATOC7xlwVjA/7Ij/QFb235D0r8UdL 8S3tHOdJItw1dq6CQTC/LmYDx/KkDE3KeUK4txOJftxGnDWDCp3wnhOdOUFk2A== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 08/12] net: dsa: rzn1-a5psw: add FDB support Date: Thu, 14 Apr 2022 14:22:46 +0200 Message-Id: <20220414122250.158113-9-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org This commits add forwarding database support to the driver. It implements fdb_add(), fdb_del() and fdb_dump(). Signed-off-by: Clément Léger --- drivers/net/dsa/rzn1_a5psw.c | 163 +++++++++++++++++++++++++++++++++++ drivers/net/dsa/rzn1_a5psw.h | 16 ++++ 2 files changed, 179 insertions(+) diff --git a/drivers/net/dsa/rzn1_a5psw.c b/drivers/net/dsa/rzn1_a5psw.c index 7ab7d9054427..8c763c2a1a1f 100644 --- a/drivers/net/dsa/rzn1_a5psw.c +++ b/drivers/net/dsa/rzn1_a5psw.c @@ -369,6 +369,166 @@ static void a5psw_port_fast_age(struct dsa_switch *ds, int port) a5psw_port_fdb_flush(a5psw, port); } +static int a5psw_lk_execute_lookup(struct a5psw *a5psw, union lk_data *lk_data, + u16 *entry) +{ + u32 ctrl; + int ret; + + a5psw_reg_writel(a5psw, A5PSW_LK_DATA_LO, lk_data->lo); + a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data->hi); + + ctrl = A5PSW_LK_ADDR_CTRL_LOOKUP; + ret = a5psw_lk_execute_ctrl(a5psw, &ctrl); + if (ret) + return ret; + + *entry = ctrl & A5PSW_LK_ADDR_CTRL_ADDRESS; + + return 0; +} + +static int a5psw_port_fdb_add(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid, + struct dsa_db db) +{ + struct a5psw *a5psw = ds->priv; + union lk_data lk_data = {0}; + bool inc_learncount = false; + int ret = 0; + u16 entry; + u32 reg; + + ether_addr_copy(lk_data.entry.mac, addr); + lk_data.entry.port_mask = BIT(port); + + spin_lock(&a5psw->lk_lock); + + /* Set the value to be written in the lookup table */ + ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry); + if (ret) + goto lk_unlock; + + lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI); + if (!lk_data.entry.valid) { + inc_learncount = true; + /* port_mask set to 0x1f when entry is not valid, clear it */ + lk_data.entry.port_mask = 0; + lk_data.entry.prio = 0; + } + + lk_data.entry.port_mask |= BIT(port); + lk_data.entry.is_static = 1; + lk_data.entry.valid = 1; + + a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi); + + reg = A5PSW_LK_ADDR_CTRL_WRITE | entry; + ret = a5psw_lk_execute_ctrl(a5psw, ®); + if (ret) + goto lk_unlock; + + if (inc_learncount) { + reg = A5PSW_LK_LEARNCOUNT_MODE_INC; + a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg); + } + +lk_unlock: + spin_unlock(&a5psw->lk_lock); + + return ret; +} + +static int a5psw_port_fdb_del(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid, + struct dsa_db db) +{ + struct a5psw *a5psw = ds->priv; + union lk_data lk_data = {0}; + bool clear = false; + int ret = 0; + u16 entry; + u32 reg; + + ether_addr_copy(lk_data.entry.mac, addr); + + spin_lock(&a5psw->lk_lock); + + ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry); + if (ret) { + dev_err(a5psw->dev, "Failed to lookup mac address\n"); + goto lk_unlock; + } + + lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI); + if (!lk_data.entry.valid) { + dev_err(a5psw->dev, "Tried to remove non-existing entry\n"); + ret = -ENOENT; + goto lk_unlock; + } + + lk_data.entry.port_mask &= ~BIT(port); + /* If there is no more port in the mask, clear the entry */ + if (lk_data.entry.port_mask == 0) + clear = true; + + a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi); + + reg = entry; + if (clear) + reg |= A5PSW_LK_ADDR_CTRL_CLEAR; + else + reg |= A5PSW_LK_ADDR_CTRL_WRITE; + + ret = a5psw_lk_execute_ctrl(a5psw, ®); + if (ret) + goto lk_unlock; + + /* Decrement LEARNCOUNT */ + if (clear) { + reg = A5PSW_LK_LEARNCOUNT_MODE_DEC; + a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg); + } + +lk_unlock: + spin_unlock(&a5psw->lk_lock); + + return ret; +} + +static int a5psw_port_fdb_dump(struct dsa_switch *ds, int port, + dsa_fdb_dump_cb_t *cb, void *data) +{ + struct a5psw *a5psw = ds->priv; + union lk_data lk_data; + int i = 0, ret; + u32 reg; + + for (i = 0; i < A5PSW_TABLE_ENTRIES; i++) { + reg = A5PSW_LK_ADDR_CTRL_READ | A5PSW_LK_ADDR_CTRL_WAIT | i; + spin_lock(&a5psw->lk_lock); + + ret = a5psw_lk_execute_ctrl(a5psw, ®); + if (ret) + return ret; + + lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI); + /* If entry is not valid or does not contain the port, skip */ + if (!lk_data.entry.valid || + !(lk_data.entry.port_mask & BIT(port))) { + spin_unlock(&a5psw->lk_lock); + continue; + } + + lk_data.lo = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_LO); + spin_unlock(&a5psw->lk_lock); + + cb(lk_data.entry.mac, 0, lk_data.entry.is_static, data); + } + + return 0; +} + static void a5psw_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) { @@ -500,6 +660,9 @@ const struct dsa_switch_ops a5psw_switch_ops = { .port_bridge_leave = a5psw_port_bridge_leave, .port_stp_state_set = a5psw_port_stp_state_set, .port_fast_age = a5psw_port_fast_age, + .port_fdb_add = a5psw_port_fdb_add, + .port_fdb_del = a5psw_port_fdb_del, + .port_fdb_dump = a5psw_port_fdb_dump, }; diff --git a/drivers/net/dsa/rzn1_a5psw.h b/drivers/net/dsa/rzn1_a5psw.h index b34ea549e936..37aa89383e70 100644 --- a/drivers/net/dsa/rzn1_a5psw.h +++ b/drivers/net/dsa/rzn1_a5psw.h @@ -167,6 +167,22 @@ #define A5PSW_CTRL_TIMEOUT 1000 #define A5PSW_TABLE_ENTRIES 8192 +struct fdb_entry { + u8 mac[ETH_ALEN]; + u8 valid:1; + u8 is_static:1; + u8 prio:3; + u8 port_mask:5; +} __packed; + +union lk_data { + struct { + u32 lo; + u32 hi; + }; + struct fdb_entry entry; +}; + /** * struct a5psw - switch struct * @base: Base address of the switch From patchwork Thu Apr 14 12:22:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813440 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BEFD3C433EF for ; Thu, 14 Apr 2022 12:30:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238975AbiDNMdR (ORCPT ); Thu, 14 Apr 2022 08:33:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243279AbiDNMdN (ORCPT ); Thu, 14 Apr 2022 08:33:13 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7648C286F7 for ; Thu, 14 Apr 2022 05:30:48 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [217.70.183.194]) by mslow1.mail.gandi.net (Postfix) with ESMTP id D6D8FCF235 for ; Thu, 14 Apr 2022 12:25:02 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 37F4A40012; Thu, 14 Apr 2022 12:24:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939096; 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=LvyGZlJTusHjC+6cCCIqRpU/42tp9G7ZAYkwBVky9go=; b=GfGFZlgr9FzycVFAky/ByRitXjy+YGeUNyCd/YSu5hXmaHr5V2ZF3InpXsS/tz9tf1C6OB JtAv0ERemUIuRnsUUr3+FTalOdHvShv76MxPYxKvgi6GDcg6QqtMF7dJD5FFD63jSSekJ8 zL1MK+hd3FUp8M7N0phYiYsK98YSiQqGakuqmF9acJDj7x/VRsxxPtDyY2boAKRIzi3SsZ kP3RNmtjhOyOlbW0vUfFlYI0SzPEtQBYtkwZmiTm08kRK0rBoW1NtIiaExMCypjs/AGJYM AZkhyXGzRacRH3Z7D+AEMMKXknqgY1KwPSDk1k9iTSb9voF6ogwTwMtJDJE8Uw== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 09/12] ARM: dts: r9a06g032: describe MII converter Date: Thu, 14 Apr 2022 14:22:47 +0200 Message-Id: <20220414122250.158113-10-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add the MII converter node which describes the MII converter that is present on the RZ/N1 SoC. Signed-off-by: Clément Léger --- arch/arm/boot/dts/r9a06g032.dtsi | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi index 636a6ab31c58..fd174df268e8 100644 --- a/arch/arm/boot/dts/r9a06g032.dtsi +++ b/arch/arm/boot/dts/r9a06g032.dtsi @@ -200,6 +200,39 @@ nand_controller: nand-controller@40102000 { status = "disabled"; }; + eth_miic: eth-miic@44030000 { + compatible = "renesas,rzn1-miic"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44030000 0x10000>; + clocks = <&sysctrl R9A06G032_CLK_MII_REF>, + <&sysctrl R9A06G032_CLK_RGMII_REF>, + <&sysctrl R9A06G032_CLK_RMII_REF>, + <&sysctrl R9A06G032_HCLK_SWITCH_RG>; + clock-names = "mii_ref", "rgmii_ref", "rmii_ref", "hclk_switch_rg"; + status = "disabled"; + + mii_conv0: mii-conv@0 { + reg = <0>; + }; + + mii_conv1: mii-conv@1 { + reg = <1>; + }; + + mii_conv2: mii-conv@2 { + reg = <2>; + }; + + mii_conv3: mii-conv@3 { + reg = <3>; + }; + + mii_conv4: mii-conv@4 { + reg = <4>; + }; + }; + gic: interrupt-controller@44101000 { compatible = "arm,gic-400", "arm,cortex-a7-gic"; interrupt-controller; From patchwork Thu Apr 14 12:22:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813442 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0F92C433FE for ; Thu, 14 Apr 2022 12:30:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240407AbiDNMdV (ORCPT ); Thu, 14 Apr 2022 08:33:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243316AbiDNMdN (ORCPT ); Thu, 14 Apr 2022 08:33:13 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6772527FE2 for ; Thu, 14 Apr 2022 05:30:48 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [217.70.183.194]) by mslow1.mail.gandi.net (Postfix) with ESMTP id 2CF5DCF237 for ; Thu, 14 Apr 2022 12:25:04 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id F1E1B40013; Thu, 14 Apr 2022 12:24:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939098; 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=A5SPoF/jrN+0EvMd0R5U2Op+xdUtT8y+vbFNqEsgVU4=; b=INY4UfA0JSPgTf2g0XHJCOzX3dPW6/wkWHqnvjGaGSRgg1jOl6qQGCBNMvQYMnC8Q0WGvz g2BelnL3uPcoBgxLNiV6NqUzrK98VYTbvR4LXJDvq6TQOmhf48sICLLuxI9h3Q5h/DhS9W ucF2M+2KdzdxbN+2GGdPv43VzGvEnUbS1lcZJ8HlEIs4YI4WJjYs7E2UaKAxLrdUpAPR8G CLeIA6su/ED0hI/axufOkNgFu/WlZHn4VQ2x5uQAwovotU+VYv9fP73E9S5l0yry/wgKaD /55yHGTXNahO4DefJmcqKkROSO+/nc0yCMHTCt/yMgLtt6D91Mc8e95kcdgIaA== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 10/12] ARM: dts: r9a06g032: describe GMAC2 Date: Thu, 14 Apr 2022 14:22:48 +0200 Message-Id: <20220414122250.158113-11-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org RZ/N1 SoC includes two MAC named GMACx that are compatible with the "snps,dwmac" driver. GMAC1 is connected directly to the MII converter port 1. GMAC2 however can be used as the MAC for the switch CPU management port or can be muxed to be connected directly to the MII converter port 2. This commit add description for the GMAC2 which will be used by the switch description. Signed-off-by: Clément Léger --- arch/arm/boot/dts/r9a06g032.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi index fd174df268e8..9be55957b8e5 100644 --- a/arch/arm/boot/dts/r9a06g032.dtsi +++ b/arch/arm/boot/dts/r9a06g032.dtsi @@ -200,6 +200,23 @@ nand_controller: nand-controller@40102000 { status = "disabled"; }; + gmac2: ethernet@44002000 { + compatible = "snps,dwmac-3.72a", "snps,dwmac"; + reg = <0x44002000 0x2000>; + interrupt-parent = <&gic>; + interrupts = , + , + ; + interrupt-names = "macirq", "eth_lpi", "eth_wake_irq"; + clock-names = "stmmaceth"; + clocks = <&sysctrl R9A06G032_HCLK_GMAC1>; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <128>; + tx-fifo-depth = <2048>; + rx-fifo-depth = <4096>; + status = "disabled"; + }; + eth_miic: eth-miic@44030000 { compatible = "renesas,rzn1-miic"; #address-cells = <1>; From patchwork Thu Apr 14 12:22:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813444 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B0ED4C43217 for ; Thu, 14 Apr 2022 12:31:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243319AbiDNMdW (ORCPT ); Thu, 14 Apr 2022 08:33:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50802 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242794AbiDNMdN (ORCPT ); Thu, 14 Apr 2022 08:33:13 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 55E3928989 for ; Thu, 14 Apr 2022 05:30:48 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [217.70.183.194]) by mslow1.mail.gandi.net (Postfix) with ESMTP id 4688DCF239 for ; Thu, 14 Apr 2022 12:25:07 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 7530340016; Thu, 14 Apr 2022 12:24:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939100; 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=AVV9dorZosBq4Eyh1b2aaNZR5/BtAkbVcbEdxKlsk0U=; b=ZXZCFEZJZFOPGa3DQdbWkzZq1JfbrYDZrvBmdIbOvzc+GzBoh25nFw0FRAW/fgRxux76iR +HuXcfSuhHjOCJPhJ8T5Bt0nHCRmw8PG49EYPdGX1C1hYxo9B4D2WNEP6fnWJwOceuwujl vhkMjQ9SuruWqiX6CRrVl2JO4jPFcLtVhwO5y4teRCHr3o7V/P0B6CL4ImIzR6PJVRUeoT 3tpc2xjgxsaLjeg3N/A6LhD5DoB9dh+18jnzSRotcLGSrBjY5dt0lib8HiRj6PRdkY2FGM zS+t6CyrzBwHSs8Kg/lN1R8fydMT7MQXe+IHwxCQwX9lFfpdnzrYm1ShMysM1Q== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 11/12] ARM: dts: r9a06g032: describe switch Date: Thu, 14 Apr 2022 14:22:49 +0200 Message-Id: <20220414122250.158113-12-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add description of the switch that is present on the RZ/N1 SoC. Signed-off-by: Clément Léger --- arch/arm/boot/dts/r9a06g032.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi index 9be55957b8e5..c04b382a20f0 100644 --- a/arch/arm/boot/dts/r9a06g032.dtsi +++ b/arch/arm/boot/dts/r9a06g032.dtsi @@ -250,6 +250,17 @@ mii_conv4: mii-conv@4 { }; }; + switch: switch@44050000 { + compatible = "renesas,rzn1-a5psw"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44050000 0x10000>; + clocks = <&sysctrl R9A06G032_HCLK_SWITCH>, + <&sysctrl R9A06G032_CLK_SWITCH>; + clock-names = "hclk_switch", "clk_switch"; + status = "disabled"; + }; + gic: interrupt-controller@44101000 { compatible = "arm,gic-400", "arm,cortex-a7-gic"; interrupt-controller; From patchwork Thu Apr 14 12:22:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 12813441 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 291E8C4332F for ; Thu, 14 Apr 2022 12:30:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243279AbiDNMdT (ORCPT ); Thu, 14 Apr 2022 08:33:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50866 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243319AbiDNMdO (ORCPT ); Thu, 14 Apr 2022 08:33:14 -0400 Received: from mslow1.mail.gandi.net (mslow1.mail.gandi.net [217.70.178.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A438427FE3 for ; Thu, 14 Apr 2022 05:30:48 -0700 (PDT) Received: from relay2-d.mail.gandi.net (unknown [217.70.183.194]) by mslow1.mail.gandi.net (Postfix) with ESMTP id D5F7ECF23B for ; Thu, 14 Apr 2022 12:25:08 +0000 (UTC) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 24ED540004; Thu, 14 Apr 2022 12:25:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1649939101; 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=TQf1op9JK2uw4U3DShnLFodUXLKVqIi3dgErr72WmTA=; b=C3/JJsHQa7ZAIfun/QoN+GkUGHybDMyPWHJPRI59lYPTkStOSjNbm7z28yvfIulNvC6zPg x0uONaeFScWW8SozaVhnCM4bzsqfcYMiW7U9uOu3yXyX66uCSq4JxO5jb1D8YoZz80C0Hm wtqYT4Xami+BHE4VXhNMmzGLRvJHEtpZfGfS2xR/K3QurCqFuDhJ/VVDvJkHRzP1PjosNK 8ksZfW403ouYATPXEHlOB5z5bZayHMwLgyCMGhadubSWlgVZENBbMx0WJboCNkeTWegVyw fecZ/GElZOmYOZpyRhnzaYoBvVyTwmMDNwyHphvDcQfnCWOFbM6W5QbwaQs+fw== From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Geert Uytterhoeven , Magnus Damm , Heiner Kallweit , Russell King Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Thomas Petazzoni , Herve Codina , =?utf-8?q?Miqu=C3=A8l_Raynal?= , Milan Stevanovic , Jimmy Lalande , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH net-next 12/12] MAINTAINERS: add Renesas RZ/N1 switch related driver entry Date: Thu, 14 Apr 2022 14:22:50 +0200 Message-Id: <20220414122250.158113-13-clement.leger@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220414122250.158113-1-clement.leger@bootlin.com> References: <20220414122250.158113-1-clement.leger@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org After contributing the drivers, volunteer for maintenance and add myself as the maintainer for Renesas RZ/N1 switch related drivers. Signed-off-by: Clément Léger --- MAINTAINERS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 9b0480f1b153..8b25308d523e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16856,6 +16856,17 @@ S: Supported F: Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml F: drivers/iio/adc/rzg2l_adc.c +RENESAS RZ/N1 A5PSW SWITCH DRIVER +M: Clément Léger +S: Maintained +F: Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml +F: Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml +F: drivers/net/dsa/rzn1_a5psw* +F: drivers/net/pcs/pcs-rzn1-miic.c +F: include/dt-bindings/net/pcs-rzn1-miic.h +F: include/linux/pcs-rzn1-miic.h +F: net/dsa/tag_rzn1_a5psw.c + RENESAS R-CAR GEN3 & RZ/N1 NAND CONTROLLER DRIVER M: Miquel Raynal L: linux-mtd@lists.infradead.org