From nobody Tue Sep 29 13:20:39 2026 Received: from BN8PR05CU002.outbound.protection.outlook.com (mail-eastus2azon11011041.outbound.protection.outlook.com [52.101.57.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E1A1B41E6A0; Fri, 7 Aug 2026 10:44:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.57.41 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099492; cv=fail; b=XGwmxwUkTROHk0Gk8sKdqwXUVswd3Z7KCOQhvwr/dyFP5ypZE7dbSEcoD1xCxKNM2eHsrTlDNe0qTDHYsy2MbQRVFeRORlh226wxgEQnxllNSnlH29b63loKDbd3XukMvs1KfACa6IdKQiZO0EfcXu3j92vtNEoQ6YFSO0ZXegw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099492; c=relaxed/simple; bh=JHdwCUAsoDUIqTaEuV7SzoPyZ7KKBXdOv3Rzukpuaj4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pJ3jesbcSl6I/bHfvZox/bEo8gcJivQ7thLW9NFbFc0fUI9KqYDeFpCwpwry0iTnAehxIYnk5slgLB3jxVIkIbonQLw18bXwAPtrB9L2bs0rZSas+36PrYL9EaPOb5RjZbdIn52BBw4hOESME4l+3YxYVQDLreC4h177EZQPDzY= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=bTK9NAII; arc=fail smtp.client-ip=52.101.57.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="bTK9NAII" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=I25w3L4xf0mQTztydqwhkPemPuUndRB/AP3YKk9t8p6CJHyH1y4WHMboRQ22o8SyWCBAa53y64Jh7NH9ljEkmsxXhbW32AtwWM5sHioa0gWEQbz0MGIN42yDTYbl5LyUKVfKlZBpWIrfzdqYDhpwiKyXVh4rntmmnykzoTWChYaurNhXj5RdLACPtPnk1B+U9GPBsh0vlkKxei5T9dC4OTUeZ7pd//z7kSrsPcIaJ4+6qWQ9zvo4aiocLqq3z7wr1PztRxpl1jk3GdZGMNTPDKBtPXWUITWE/y8+bluNN3iEXTGRxPib8CGjQ6wy5+P70Wf1InidTDdBMi7DWZut3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ZwDFAAwhDGamXidQKlPRtNz5yEQ4iJrIf04JdEwzaG0=; b=pDZ0QKEdBHExrcD8IzST9yw16fkfqByOYaHRFQs4aRCC0QghCEDbdS+9mg2pScMj8vkVv7mLNa66GNagVlLz+rF5n/NKTtH7rrFMsb9htYHjl91tFoskyeMPTeuuJXHqsCK95lgS1lYlP/pmWIqT8mLoi6KfAH6g4sgV77reOKCOEoRCx3GFu8+oblFWMx+ON9gNyQ+LCqgMxP2hGC7vKgk1Hmn/61MaSHo7KqpMzg4iew4rSEvR5sqMpUnhKMgSbHccy0XW+D7K4lffmBoUdsHcromd7M84g0AASqFoeahLQTfDy43xTTdcqpn5sTXKUk8KwllMSLL06Hk1DHfWrQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ZwDFAAwhDGamXidQKlPRtNz5yEQ4iJrIf04JdEwzaG0=; b=bTK9NAIIqSzyA6qPlFuQmRi+mtnph27a5E1h15VSvkuTAOXfGNQvRa6HcuW4g1xkd/r3JD/0LdheApPNu3hJyUcTZDVPiDDlc4Xuk8nzrvmL5rcy2DjRoJQd9xkjqRmUY32RxDCNmoHLJ9YyfHQuFV11ZXYafmDF5N4XF3h0NfM= Received: from PH7P220CA0077.NAMP220.PROD.OUTLOOK.COM (2603:10b6:510:32c::12) by CY8PR12MB8195.namprd12.prod.outlook.com (2603:10b6:930:77::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.19; Fri, 7 Aug 2026 10:44:44 +0000 Received: from SJ1PEPF000023D3.namprd21.prod.outlook.com (2603:10b6:510:32c:cafe::81) by PH7P220CA0077.outlook.office365.com (2603:10b6:510:32c::12) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.23 via Frontend Transport; Fri, 7 Aug 2026 10:44:44 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D3.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:44:44 +0000 Received: from satlexmb10.amd.com (10.181.42.219) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:44:43 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb10.amd.com (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:44:42 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:44:37 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 01/20] dt-bindings: net: add Xilinx TSN Endpoint Ethernet MAC Date: Fri, 7 Aug 2026 16:14:12 +0530 Message-ID: <20260807104431.157230-2-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D3:EE_|CY8PR12MB8195:EE_ X-MS-Office365-Filtering-Correlation-Id: 14e6013d-703f-4460-3ae8-08def470e4c0 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|1800799024|376014|7416014|36860700016|23010399003|22082099003|11063799006|56012099006|18002099003|3023799007|13003099007|921020|6133799003|10067099003; X-Microsoft-Antispam-Message-Info: UoPiA84y4htBAi3Z5aiDdZii9w6V7DOQKqP5jel+4er/KSkAiNUHGWx4HNjjBBAkf0zScRKPoIvRhddchykFtOViWHf3bs26BsAWzVoAAu/JU1I3Rbmp5P3YdELqNWgef8mWjOTvyvCUflvGFD2R948mzpgn8cgY6FTc0vfuPsfO4V5Y8VCgn8PI7m6c5UeukPqbtlTKIrrCQ/LZ42bbg70IOz+WB3P+aNpUAmz9OO5uO2FQDzYpPd1i3sj9k3I//2ofV2jvu4ZJHMmogc8mLYkJfnLJVGb+x/TqRXcgtNLlAY+WQANb5NwRpoS1D0PSaGCp6yR28Oq400Hm4VJzshDBAkFFje00vIF/OBGIC98vEaQWoKXEx6vOGXwEZzuW2Nwv6V7L8IU21cTalnzENjKTUs2n2ZE/TbaS11RULac/ubNJvYuSVGp4C8Z1P1VKub+n/APnfqH3iULeIVe/QNgs3PEtwCz4NGJUiLtdVzyiJ8aBGSwPb9czI3ttFP2tpDuZYioOlFgkiPyB/ZQqp52kX5DKnj4ww4Z/CWq4V+r53eNW636MRvkKNMu4HS5STW0NplN9j5tqBECIvDfrUjs4Lm9JMPLH6BhErAonOG7UxeIfMbt1/Hxtsz+pVzX1BHJw2Hiw10WymWqmvXBW9++zcEU/mHQ7zTo+fSbbTZgJGMJhobdzaH26fcGuckmpXzzyHTu+vdIjV9LZffWWBK53UJxfTvhaR078O8d3kxV/ghfuoVb6BIZ3oi8wSIMu X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(1800799024)(376014)(7416014)(36860700016)(23010399003)(22082099003)(11063799006)(56012099006)(18002099003)(3023799007)(13003099007)(921020)(6133799003)(10067099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: skmnr10Qh/lyEOgUxEA7FFROJCj8uPlzOscRn3/he4OCiGePiWUswEUoQw9GPdL1CU4VaA3MifyeSWrmRccNBPk0QKxg7y9/qlFmVcPtX6MCXITQcJhXKvkS/tY+dXvAmQUCh8r4Fx3RPVGixTXR1XSWbbokvYWD3OdGHRiQz32Pi9mypdRupTSpeU6VugoTsP//E+HbUjzNqoc9Ka3IfsZ7mlAIYbfuT7S3lOwdbp1E2v4/yX47Yd0vLHcTrNXEVXsq2Y9MT5dg2iHD5M9No5veAp3J4RckcalmZEYKPJX47zE+3ex8zyp24ii/DzgH8A+gVMm/w6CZSY02q2eTjcDLOC2CHAHLMaq4r+YLVYx3YAieiRUQ90IR2nwpbSW6h90bAfoT3BIPetKs9KFd2j+cI1t3/hiSYUkiS2/ACRubOKiCE0IQw9GN32BlPAtl X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:44:44.3241 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 14e6013d-703f-4460-3ae8-08def470e4c0 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D3.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY8PR12MB8195 Content-Type: text/plain; charset="utf-8" From: Srinivas Neeli Add a binding for the Xilinx TSN Endpoint Ethernet MAC IP. The top-level node describes the IP wrapper, which owns the six shared IP clocks and the xlnx,num-priorities parameter, and has two children: - xlnx,tsn-ep-mac: the endpoint MAC, owning the host-side DMA channels (dmas / dma-names / tx-queues-config). - xlnx,tsn-switch: the three-port Ethernet switch covering the switch fabric and the two per-MAC register windows. The MDIO controllers and PTP register blocks sit at fixed offsets inside the per-MAC windows, accessed through the mdio-mac1 / mdio-mac2 children and per-MAC interrupt-names entries. Each external port@N references its PHY through a phy-handle in the matching mdio-mac child. Signed-off-by: Srinivas Neeli Co-developed-by: Nagadheeraj Rottela Signed-off-by: Nagadheeraj Rottela --- .../net/xlnx,tsn-endpoint-ethernet-mac.yaml | 343 ++++++++++++++++++ MAINTAINERS | 7 + 2 files changed, 350 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/xlnx,tsn-endpoint= -ethernet-mac.yaml diff --git a/Documentation/devicetree/bindings/net/xlnx,tsn-endpoint-ethern= et-mac.yaml b/Documentation/devicetree/bindings/net/xlnx,tsn-endpoint-ether= net-mac.yaml new file mode 100644 index 000000000000..00f52b7b623c --- /dev/null +++ b/Documentation/devicetree/bindings/net/xlnx,tsn-endpoint-ethernet-mac.= yaml @@ -0,0 +1,343 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/xlnx,tsn-endpoint-ethernet-mac.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx TSN Endpoint Ethernet MAC + +description: + TSN Endpoint Ethernet MAC IP implements IEEE 802.1 Time-Sensitive + Networking (TSN) standards and provides low-latency network connectivity + in either Endpoint-only or Bridged Endpoint configurations. In the + Bridged Endpoint mode, the IP integrates a three-port switch, with two + ports connected to the external network and one port connected to an + internal endpoint. It also supports GMII/RGMII interfaces for connection + to an external PHY, enabling full-duplex operation at 100 Mb/s and + 1 Gb/s speeds. + +maintainers: + - Srinivas Neeli + - Nagadheeraj Rottela + +properties: + compatible: + const: xlnx,tsn-endpoint-ethernet-mac-3.0 + + reg: + maxItems: 1 + + clocks: + items: + - description: GTX clock for transmitter logic and RTC + - description: GTX 90-degree phase shifted clock for RGMII + - description: Host RX FIFO clock + - description: Host TX FIFO clock + - description: Reference clock for IDELAY control + - description: AXI-Lite register interface clock + + clock-names: + items: + - const: gtx + - const: gtx90 + - const: host_rxfifo + - const: host_txfifo + - const: ref + - const: s_axi + + ranges: true + + xlnx,num-priorities: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 2 + maximum: 8 + description: + Number of traffic classes (priorities) configured in the IP. + This is an IP configuration parameter that determines the number of + priority queues available for QoS scheduling. Traffic classes map to + IEEE 802.1Q priority levels (0-7). + + '#address-cells': + const: 1 + + '#size-cells': + const: 1 + +patternProperties: + "^ep-mac@": + type: object + $ref: /schemas/net/ethernet-controller.yaml# + description: + Endpoint MAC sub-node. Provides the host-side data path through the + DMA channels described by its dmas / dma-names. + properties: + compatible: + const: xlnx,tsn-ep-mac + + reg: + maxItems: 1 + + dmas: + minItems: 2 + maxItems: 32 + + dma-names: + minItems: 2 + maxItems: 32 + items: + pattern: "^(tx|rx)_chan(1[0-5]|[0-9])$" + description: | + Names matching the entries in 'dmas', one per DMA channel and in + the same order. TX channel names use "tx_chan" and RX channel + names use "rx_chan", where N is 0..15. Example: "tx_chan0", + "tx_chan1", ..., "rx_chan0", "rx_chan1", .... + + tx-queues-config: + type: object + description: + TX queue configuration node that maps IP priority queues to + DMA TX channels. The TSN IP supports multiple priority queues for + QoS scheduling, and each queue can be connected to a specific DMA + channel. This mapping defines which DMA TX channel is used to + transmit packets for each priority queue. For example, queue0 + with xlnx,dma-channel-num set to 5 means priority queue 0 uses + tx_chan5 for data transfer. + + patternProperties: + "^queue[0-7]$": + description: + Each subnode represents a priority queue. The + xlnx,dma-channel-num property specifies which DMA TX channel + (tx_chan0 to tx_chan15) is connected to this queue for + transmitting packets. + type: object + properties: + xlnx,dma-channel-num: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + DMA TX channel number connected to this priority queue. + minimum: 0 + maximum: 15 + + required: + - xlnx,dma-channel-num + + additionalProperties: false + + additionalProperties: false + + required: + - compatible + - reg + - dmas + - dma-names + - tx-queues-config + + unevaluatedProperties: false + + "^switch@": + type: object + $ref: /schemas/net/dsa/dsa.yaml#/$defs/ethernet-ports + description: + Three-port Ethernet switch sub-node. Contains the switch fabric + register window and the two per-MAC register windows; each per-MAC + window houses an MDIO controller and a PTP register block at fixed + offsets. The IP's per-MAC and PTP-timer interrupts are exposed here. + + properties: + compatible: + const: xlnx,tsn-switch + + reg: + items: + - description: Switch fabric register window + - description: MAC1 register window (includes MDIO and PTP) + - description: MAC2 register window (includes MDIO and PTP) + + reg-names: + items: + - const: switch + - const: mac1 + - const: mac2 + + interrupts: + maxItems: 7 + + interrupt-names: + items: + - const: ptp_rx_mac1 + - const: ptp_tx_mac1 + - const: mac_irq_mac1 + - const: ptp_timer + - const: ptp_rx_mac2 + - const: ptp_tx_mac2 + - const: mac_irq_mac2 + + mdio-mac1: + $ref: /schemas/net/mdio.yaml# + description: + MDIO bus controller for MAC1. Registers reside inside the mac1 + reg-names window. + unevaluatedProperties: false + + mdio-mac2: + $ref: /schemas/net/mdio.yaml# + description: + MDIO bus controller for MAC2. Registers reside inside the mac2 + reg-names window. + unevaluatedProperties: false + + ethernet-ports: + type: object + additionalProperties: true + + properties: + port@0: + type: object + additionalProperties: true + description: + CPU port. Wired internally to the ep-mac sibling. + + properties: + reg: + const: 0 + + phy-mode: + const: internal + + patternProperties: + "^port@[1-2]$": + type: object + additionalProperties: true + description: + External Ethernet port (port@1 is wired to MAC1, port@2 to + MAC2). Its PHY is reached through the corresponding + mdio-mac bus. + + properties: + phy-mode: + enum: + - gmii + - rgmii + - rgmii-id + + required: + - compatible + - reg + - reg-names + - interrupts + - interrupt-names + + unevaluatedProperties: false + +additionalProperties: false + +required: + - compatible + - reg + - clocks + - clock-names + - xlnx,num-priorities + - ranges + - '#address-cells' + - '#size-cells' + +examples: + - | + tsn_ip: tsn@80040000 { + compatible =3D "xlnx,tsn-endpoint-ethernet-mac-3.0"; + reg =3D <0x80040000 0x40000>; + clocks =3D <&misc_clk_2>, <&misc_clk_2>, <&misc_clk_1>, <&misc_clk= _1>, + <&misc_clk_3>, <&misc_clk_0>; + clock-names =3D "gtx", "gtx90", "host_rxfifo", "host_txfifo", + "ref", "s_axi"; + xlnx,num-priorities =3D <8>; + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0x80040000 0x40000>; + + ep_mac: ep-mac@16000 { + compatible =3D "xlnx,tsn-ep-mac"; + reg =3D <0x16000 0xa000>; + dmas =3D <&axi_mcdma_0 0>, <&axi_mcdma_0 1>, <&axi_mcdma_0 2>, + <&axi_mcdma_0 3>, <&axi_mcdma_0 4>, <&axi_mcdma_0 5>, + <&axi_mcdma_0 6>, <&axi_mcdma_0 7>, <&axi_mcdma_0 16>, + <&axi_mcdma_0 17>, <&axi_mcdma_0 18>, <&axi_mcdma_0 19>, + <&axi_mcdma_0 20>, <&axi_mcdma_0 21>, <&axi_mcdma_0 22>, + <&axi_mcdma_0 23>; + dma-names =3D "tx_chan0", "tx_chan1", "tx_chan2", "tx_chan3", + "tx_chan4", "tx_chan5", "tx_chan6", "tx_chan7", + "rx_chan0", "rx_chan1", "rx_chan2", "rx_chan3", + "rx_chan4", "rx_chan5", "rx_chan6", "rx_chan7"; + tx-queues-config { + queue0 { xlnx,dma-channel-num =3D <0x7>; }; + queue1 { xlnx,dma-channel-num =3D <0x6>; }; + queue2 { xlnx,dma-channel-num =3D <0x5>; }; + queue3 { xlnx,dma-channel-num =3D <0x4>; }; + queue4 { xlnx,dma-channel-num =3D <0x3>; }; + queue5 { xlnx,dma-channel-num =3D <0x2>; }; + queue6 { xlnx,dma-channel-num =3D <0x1>; }; + queue7 { xlnx,dma-channel-num =3D <0x0>; }; + }; + }; + + tsn_switch: switch@38000 { + compatible =3D "xlnx,tsn-switch"; + reg =3D <0x38000 0x8000>, + <0x00000 0x14000>, + <0x20000 0x14000>; + reg-names =3D "switch", "mac1", "mac2"; + + interrupt-parent =3D <&intc>; + interrupts =3D <0 2>, <2 2>, <4 2>, <6 2>, + <1 2>, <3 2>, <5 2>; + interrupt-names =3D "ptp_rx_mac1", "ptp_tx_mac1", + "mac_irq_mac1", "ptp_timer", + "ptp_rx_mac2", "ptp_tx_mac2", + "mac_irq_mac2"; + + mdio-mac1 { + #address-cells =3D <1>; + #size-cells =3D <0>; + phy0: ethernet-phy@0 { + reg =3D <0>; + }; + }; + + mdio-mac2 { + #address-cells =3D <1>; + #size-cells =3D <0>; + phy1: ethernet-phy@1 { + reg =3D <1>; + }; + }; + + ethernet-ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + ethernet =3D <&ep_mac>; + phy-mode =3D "internal"; + + fixed-link { + speed =3D <1000>; + full-duplex; + }; + }; + + port@1 { + reg =3D <1>; + phy-handle =3D <&phy0>; + phy-mode =3D "rgmii-id"; + }; + + port@2 { + reg =3D <2>; + phy-handle =3D <&phy1>; + phy-mode =3D "rgmii-id"; + }; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 08e43bc09735..ba41c224dd02 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -29607,6 +29607,13 @@ M: Harsh Jain S: Maintained F: drivers/char/hw_random/xilinx-trng.c =20 +XILINX TSN ENDPOINT ETHERNET MAC DRIVER +M: Nagadheeraj Rottela +M: Srinivas Neeli +L: netdev@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/net/xlnx,tsn-endpoint-ethernet-mac.ya= ml + XILINX UARTLITE SERIAL DRIVER M: Peter Korsgaard L: linux-serial@vger.kernel.org --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from PH8PR06CU001.outbound.protection.outlook.com (mail-westus3azon11012007.outbound.protection.outlook.com [40.107.209.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CE2EF374195; Fri, 7 Aug 2026 10:44:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.209.7 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099499; cv=fail; b=OpOWmOFQ2yPvQj9R35vGeK2K//KJr2b/KdzApe9hdk+rVusX6mLwa8II2/R1Nj+bu5KHI/LXAfNzKutLAMeHsZTcIruNzDNEqiaZWRaeGb2jPHjQz33knw7ZN7hRWkyNzeXQK8MFqezL0X9RrwenSmdepMj2b2kMwF0uYTPI9ns= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099499; c=relaxed/simple; bh=bVLXGWP+tkvlarabBDNsJRmiq/8gkmNDCPnkVCOQbLs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Da5jVLbuxY9/CEzaP/XPEsUJHDeYqR8rtK7r4LvgarMa/2q4erjOklH3+gPPplmaQKV/e0lDkHrP7P0IIIJkR+RMjgClFMunmPYr6gZXOwTwq6/7eKxR5BVLnGS2LtBfvoPIFk+21IejlBeqJpiRDBztMVRi4WpOZnSYnviZmdk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=FtG5yJng; arc=fail smtp.client-ip=40.107.209.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="FtG5yJng" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=NlPkHKyEbBZvM3sLVWXVF0+ahu/SD2WdFtsJ5aY0uHKSbfXPnbO4rZ2yzrOgcgYTm7LGb9RlJ+tSFYB965BobH4Ocz7NNouEs4wuMSfpxcp37aE/c8ElKg5l5hECWccx5wmLyopGdqzCN/slGfFt97zlzo2lSTOQOhGhzNU4UcnA++73pFjaYa1iZUTXa/VfmNhaGTwrAWca5Kln6ixyuidBbbADXkLfpbCMMRE7sGIRZ5g2lTJQYpz1mm/ZbuAB/TFUp3Q+emy65+JGSOjJyiapZUZsvCp8gzP+e9suNXDaMcbzr8WOHqJ4cXC9QDKlgVh0lLPOSWrK7M4HCFwAzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=8UHbBhxfwNJqMbysL5dAOz8G3ClHDME2r4umW53mAFU=; b=BfOL/jGtG9UpiFiqsAez6u3W6rcwdRWK25ILbeVsNkxw0aTLgQjmBjBnWr4Z9JNqwK/DY3p3ZqwqcdPIvupzrd5mTolfsE1G0BioLp2XkErQq3fnAbpZOHudY3wCI4G4J01Q1AAM2bmlEflqCj13+4hFHEJ+lDJphPx0N2H67rJRjL/vzHoJ6tpdXbn78aaBcy9M2zniU6kdO9nWvGOJ7DcD+SM0UuA3APUnv0pn/g+4fVZmCV8QvFl8vLwJbDkR9gYcJllR27H3eG4eUcQcSG8FufdYWjczDco+M5UiZcy0rguKEdj9GrLmGuUOls88KyasrGUIlbM5X5+KZCPBuQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8UHbBhxfwNJqMbysL5dAOz8G3ClHDME2r4umW53mAFU=; b=FtG5yJng4Dw2nk4RuelwkGLq+cNziVDfLKtTBF5nUO9WfKhJ5Lm+HXK+WUnVq1A70HSo09/nwjvy7HzunmAxez9ySdIJeI7N+SGnH66E372lZjKUWBqk5x9Q1hOiIix2kK9pOS4EL02oMs4EKdCnC1rujxl6lY9P6GHIx9GVnvk= Received: from PH7P220CA0067.NAMP220.PROD.OUTLOOK.COM (2603:10b6:510:32c::9) by SAWPR12MB999141.namprd12.prod.outlook.com (2603:10b6:806:4e1::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.16; Fri, 7 Aug 2026 10:44:50 +0000 Received: from SJ1PEPF000023D3.namprd21.prod.outlook.com (2603:10b6:510:32c:cafe::1a) by PH7P220CA0067.outlook.office365.com (2603:10b6:510:32c::9) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.23 via Frontend Transport; Fri, 7 Aug 2026 10:44:50 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D3.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:44:50 +0000 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:44:47 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:44:42 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 02/20] net: xilinx: tsn: add TSN endpoint wrapper driver Date: Fri, 7 Aug 2026 16:14:13 +0530 Message-ID: <20260807104431.157230-3-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D3:EE_|SAWPR12MB999141:EE_ X-MS-Office365-Filtering-Correlation-Id: 8b921f22-af4b-4439-0a5e-08def470e86c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700016|7416014|82310400026|376014|1800799024|23010399003|10067099003|56012099006|11063799006|6133799003|18002099003|22082099003|921020; X-Microsoft-Antispam-Message-Info: miwT/ok7fzuck7JyvDgHu4Zjjqrazj9NE96ppP/h6TFZ61ZOWH6LbukCZqQ24a7coq8Lvh1rJ40x7avuVblfDkJ2OjhnPWxfrmRYIQ1Jj2y2mr/6eexcta5RoTXGJNDYzoq7aOx1JkEj8J5FkDr/5xKIGUqQ3PVXXRgqb6sAIhHovjdVRmFciuYIGrWY83lMxzVNERziVP0RFZxTy6M+mLpwJBbrjJcLFs1yWzDgKgHVgiDcFn+r59q5zmo/7DrEdGO/ebvF4IoTgkN8//+kP0RUNGjsa/4IRGydbhKny1V2u8nBCQYnr3eneQT85V9ZgiyOBWFciHdt8IatHGUvmsJxpDJJZ8D2PGn3bBEKp5xmjiW5kJrx9L+TICEzDOg+oi3JXuKWNLARtGKBXEI1xQSjkpoXTllLlwmt11mIvSLrmC08Q/5xSqqTlAYcTtmQdHqU/jKjQjxZFVIejS3zRCivPgXr6vLaOGI2ChhPzer2tUxusrF+xcIqA4L/Z+E4BjkzXhcuHlF9t7hK6PjV8JqtXKEF1rHf81/8ihcZoZWV2nJRVk2tDFtb1wjAneZ0PpIRBqxUmDu3XopVP8D9j7n18R43yzLiw3tSwebf/KVig5aPCa2kE8y7g2z7Wq9DUOmlBoTyDA9qy0JeuLLniNYt7hbGlFNieoaz6BTkUrGgHYO71FkrHZ+sYN31dZ4bOwXF0rxsclwy36LA8UE2eJPkESxC7srVGXcKTLhIg74eWiWYpkT8qAj2V8EVLIsB X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700016)(7416014)(82310400026)(376014)(1800799024)(23010399003)(10067099003)(56012099006)(11063799006)(6133799003)(18002099003)(22082099003)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: T56Hz/ivpQ5GI0cnKpUuK4spESVekOOck7/qmmJ857y5VAKlg44i3ydb+zeA4TYULo51DlEEdu969X/Oc8LwC0lg8FgbjRHJ+i/1DxN46Rb1J5FDcfWTYTXYg++sGpBQINuy/+FAll0Ol1HVHi7/Y3a42Ych6FWu6nK3Dv6yy6502ZlFrHQSDq7wZTHSNU33o8WUBYxi+JM1UgQtc9z7+q01XMouYT+SGGc1KvZH83u6BWLFIcp00vd3uuNFIxt2AOqTB2ep/QM9nH1R4JSv1xQ6bmp9miWG+IYeWnvlAZ+dmHzofbgYoVRnLRRYsvNcUJkpffwbHlOKoW9Z7EBgrXicFlFAcTWAzF5DZ4ihfTvPYR2RMLZBuHdJD58u22eU4veow+986FypwCprIev7kEZirnQAXPsgxHQwk8mMtg4h7aaipHeN/O6xaFIpWKhL X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:44:50.4827 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8b921f22-af4b-4439-0a5e-08def470e86c X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D3.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SAWPR12MB999141 Content-Type: text/plain; charset="utf-8" From: Srinivas Neeli The TSN Endpoint Ethernet MAC IP groups several sub-nodes under one IP node with a set of IP-wide clocks. Each sub-node needs its own driver, and the shared clocks must be running before any of them probe. Add a thin wrapper platform driver for the IP node. Enable the IP-wide clocks from the device tree and bind each sub-node to its own driver. Signed-off-by: Srinivas Neeli Co-developed-by: Nagadheeraj Rottela Signed-off-by: Nagadheeraj Rottela --- MAINTAINERS | 1 + drivers/net/ethernet/xilinx/Kconfig | 1 + drivers/net/ethernet/xilinx/Makefile | 1 + drivers/net/ethernet/xilinx/tsn/Kconfig | 15 +++ drivers/net/ethernet/xilinx/tsn/Makefile | 2 + .../net/ethernet/xilinx/tsn/xilinx_tsn_main.c | 105 ++++++++++++++++++ 6 files changed, 125 insertions(+) create mode 100644 drivers/net/ethernet/xilinx/tsn/Kconfig create mode 100644 drivers/net/ethernet/xilinx/tsn/Makefile create mode 100644 drivers/net/ethernet/xilinx/tsn/xilinx_tsn_main.c diff --git a/MAINTAINERS b/MAINTAINERS index ba41c224dd02..e5b95b3bfa21 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -29613,6 +29613,7 @@ M: Srinivas Neeli L: netdev@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/net/xlnx,tsn-endpoint-ethernet-mac.ya= ml +F: drivers/net/ethernet/xilinx/tsn/ =20 XILINX UARTLITE SERIAL DRIVER M: Peter Korsgaard diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xil= inx/Kconfig index 7502214cc7d5..c6d704c8d3d4 100644 --- a/drivers/net/ethernet/xilinx/Kconfig +++ b/drivers/net/ethernet/xilinx/Kconfig @@ -41,4 +41,5 @@ config XILINX_LL_TEMAC This driver supports the Xilinx 10/100/1000 LocalLink TEMAC core used in Xilinx Spartan and Virtex FPGAs =20 +source "drivers/net/ethernet/xilinx/tsn/Kconfig" endif # NET_VENDOR_XILINX diff --git a/drivers/net/ethernet/xilinx/Makefile b/drivers/net/ethernet/xi= linx/Makefile index 7d7dc1771423..66dab012650b 100644 --- a/drivers/net/ethernet/xilinx/Makefile +++ b/drivers/net/ethernet/xilinx/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_XILINX_LL_TEMAC) +=3D ll_temac.o obj-$(CONFIG_XILINX_EMACLITE) +=3D xilinx_emaclite.o xilinx_emac-objs :=3D xilinx_axienet_main.o xilinx_axienet_mdio.o obj-$(CONFIG_XILINX_AXI_EMAC) +=3D xilinx_emac.o +obj-$(CONFIG_XILINX_TSN) +=3D tsn/ diff --git a/drivers/net/ethernet/xilinx/tsn/Kconfig b/drivers/net/ethernet= /xilinx/tsn/Kconfig new file mode 100644 index 000000000000..45af4d3f10e6 --- /dev/null +++ b/drivers/net/ethernet/xilinx/tsn/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Xilinx TSN device configuration +# + +config XILINX_TSN + tristate "Xilinx TSN Ethernet driver" + depends on OF && HAS_IOMEM + help + This driver supports the AMD/Xilinx Time-Sensitive Networking + (TSN) Endpoint Ethernet MAC IP. It provides the wrapper device + and the endpoint MAC that connects the IP to the host CPU. The + three-port switch is supported by NET_DSA_XILINX_TSN. + + If unsure, say N. diff --git a/drivers/net/ethernet/xilinx/tsn/Makefile b/drivers/net/etherne= t/xilinx/tsn/Makefile new file mode 100644 index 000000000000..6f99226f3dc8 --- /dev/null +++ b/drivers/net/ethernet/xilinx/tsn/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_XILINX_TSN) +=3D xilinx_tsn.o +xilinx_tsn-y :=3D xilinx_tsn_main.o diff --git a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_main.c b/drivers/ne= t/ethernet/xilinx/tsn/xilinx_tsn_main.c new file mode 100644 index 000000000000..1ef1b0c2ee6e --- /dev/null +++ b/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_main.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Time Sensitive Networking (TSN) Ethernet MAC wrapper driver. + * + * Copyright (C) 2026 Advanced Micro Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TSN_NUM_CLOCKS 6 + +/** + * struct xlnx_tsn_ip - wrapper-private IP state + * @clks: bulk-managed IP clocks + */ +struct xlnx_tsn_ip { + struct clk_bulk_data clks[TSN_NUM_CLOCKS]; +}; + +static const char * const tsn_clk_names[TSN_NUM_CLOCKS] =3D { + "gtx", + "gtx90", + "host_rxfifo", + "host_txfifo", + "ref", + "s_axi", +}; + +static void tsn_clk_bulk_disable(void *data) +{ + struct xlnx_tsn_ip *w =3D data; + + clk_bulk_disable_unprepare(TSN_NUM_CLOCKS, w->clks); +} + +static int tsn_ip_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct xlnx_tsn_ip *w; + int ret; + + w =3D devm_kzalloc(dev, sizeof(*w), GFP_KERNEL); + if (!w) + return -ENOMEM; + + for (int i =3D 0; i < TSN_NUM_CLOCKS; i++) + w->clks[i].id =3D tsn_clk_names[i]; + + ret =3D devm_clk_bulk_get(dev, TSN_NUM_CLOCKS, w->clks); + if (ret) + return dev_err_probe(dev, ret, "failed to get clocks\n"); + + ret =3D clk_bulk_prepare_enable(TSN_NUM_CLOCKS, w->clks); + if (ret) + return dev_err_probe(dev, ret, "failed to enable clocks\n"); + + ret =3D devm_add_action_or_reset(dev, tsn_clk_bulk_disable, w); + if (ret) + return ret; + + return devm_of_platform_populate(dev); +} + +static const struct of_device_id tsn_of_match[] =3D { + { .compatible =3D "xlnx,tsn-endpoint-ethernet-mac-3.0" }, + { } +}; +MODULE_DEVICE_TABLE(of, tsn_of_match); + +static struct platform_driver tsn_driver =3D { + .probe =3D tsn_ip_probe, + .driver =3D { + .name =3D "xilinx-tsn", + .of_match_table =3D tsn_of_match, + }, +}; + +static struct platform_driver * const tsn_drivers[] =3D { + &tsn_driver, +}; + +static int __init xlnx_tsn_init(void) +{ + return platform_register_drivers(tsn_drivers, ARRAY_SIZE(tsn_drivers)); +} +module_init(xlnx_tsn_init); + +static void __exit xlnx_tsn_exit(void) +{ + platform_unregister_drivers(tsn_drivers, ARRAY_SIZE(tsn_drivers)); +} +module_exit(xlnx_tsn_exit); + +MODULE_AUTHOR("Srinivas Neeli "); +MODULE_DESCRIPTION("AMD/Xilinx TSN Endpoint Ethernet MAC wrapper driver"); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from PH7PR06CU001.outbound.protection.outlook.com (mail-westus3azon11010021.outbound.protection.outlook.com [52.101.201.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 408E936E489; Fri, 7 Aug 2026 10:45:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.201.21 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099507; cv=fail; b=JIXFR4kqb+xwL4thyUf3Utz/aVn4hNQJIF7MFMySJouqbrHx2vsjjW7zpGm48Atu1in0y2++5praP8HftDaZbsyYJ1QBiYyk3OfO8UU67brTnGGpLnIJv7FHnnaAius59v2Y5GS2OEiYzIj7mPOK9CL1qcc49R+lmzxHxuZ8wKc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099507; c=relaxed/simple; bh=nWa95cwKh/XRnZJfsI4ZtXvtR9Fd3C8JqgJDDgCELbw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Y4jLV+LmQEMJ+mWkl3ocxLfr2IGf/6D2Id0kRB29V+nk0YltWuTCWMzLn73bpVVzCVhgLdVuFg0uLwQalZNLkBxy8rb6i7ZKOpKIQnpU9VCq48K0KsbgXE+zGcgbpSxUPDdpVv6fWYc4d++2lA0n6g5spW9GZIHELqhlUrSDRVM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=HErSrf4x; arc=fail smtp.client-ip=52.101.201.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="HErSrf4x" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=lyV7f3kAxhoqSFU1MA8lxuoDaDndGVzUAS+60lWKv4RcYMHNeqgkVc+L96Cgf5rqWHQCi24SZf5XSVw74AXZ9CkpituodfPirgWkJLYXZ8igfVTIbztpws/ux3zdPRD35kL0MYn2LDlbPuLw35l50j7jRz8phxmcn62tV5T34gogkP5n29sk5W8aMEog0oSMbrZ2Dg9WTXY/Pmt+po793qyHFdbC9IgXJEtIWzMSLO6fpsyS8oWxxC4TC5YbwJsumOv2VWXHGYzM9hDTlMYPbU+HBILCSlO/MqBdJjGkC17g907inQvfgteHDk9lP7oOvuOcSxJsdD+iP+mXGIAjNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5z7YSlLcSEWihjddIE9/NWotmgKRdM2161jQscE9tlc=; b=obTryEfriDE8nEdN7awPnPOmuc1z+0FQvQVi5sTw3/OgN80SJLLNFQiknxKMlrQ9mJ9uwWmw+6osX55oGU1ZNdgYLIOAxnv3mjw5E2KQ5MnNL0YejXSKy+7Iu3DVZM2Q0pznj4KQWuNp2VGfn/KI3hbmFgFlXZnMBWsIK9bedjvHy1ECiuo7FI8lLkzpiPc/UYrBFJHkvXZX+83krzXZiS0DngQ0kWeUKw0Qq92S1xpKt7wAUaYf6Ap/CjAzX/Wz/N9AqmagrPY+3GitYSz6lkQFgDjdaKZ7C5jy8jKyIJEXUOvBIRneFUiSRYsVnrmatpmPmTmr2Q/6yVmK+IUjgw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5z7YSlLcSEWihjddIE9/NWotmgKRdM2161jQscE9tlc=; b=HErSrf4xoQj+ZdODPg9YI+as3iIsHvhHeAQhw8reiWTCh/HgwRpMzK74+NqMTBUnsWpgR8L5h9+9ALufwvAE+c8/tAsEecBzhzztL8byuWkKxuYj5di7Go3+hSAnaI0rbaXJntHHiy6x+ubHTGlqPONALZ25/UnBxBfXJXFfdfo= Received: from SJ0PR05CA0010.namprd05.prod.outlook.com (2603:10b6:a03:33b::15) by CY5PR12MB6597.namprd12.prod.outlook.com (2603:10b6:930:43::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.23; Fri, 7 Aug 2026 10:44:56 +0000 Received: from SJ1PEPF000023D8.namprd21.prod.outlook.com (2603:10b6:a03:33b:cafe::a9) by SJ0PR05CA0010.outlook.office365.com (2603:10b6:a03:33b::15) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.315.9 via Frontend Transport; Fri, 7 Aug 2026 10:44:56 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D8.mail.protection.outlook.com (10.167.244.73) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:44:55 +0000 Received: from Satlexmb09.amd.com (10.181.42.218) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:44:55 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb09.amd.com (10.181.42.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 03:44:53 -0700 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:44:48 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 03/20] net: xilinx: tsn: add endpoint MAC driver skeleton Date: Fri, 7 Aug 2026 16:14:14 +0530 Message-ID: <20260807104431.157230-4-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D8:EE_|CY5PR12MB6597:EE_ X-MS-Office365-Filtering-Correlation-Id: 2be49f92-972b-4186-c213-08def470eb8e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|376014|23010399003|36860700016|1800799024|82310400026|921020|10067099003|11063799006|56012099006|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: Kk7HYo+hZHoy60mAGpGdF2wbOf5SZdW4L3Rht0K5wa9xPN/xvmB4X0PZN6QBfFP9POzQB95PScnYNivpVPWNdcS+quFdFgPJZfpPE230c3x7bgK+Bua47xZI+NFhWs7SU3QOiHOPJgGNJxqRldUFmQ6xYBfAiqOX1jKhSxfmciwwKVcSMlFfQ7a5STeAIRXHrmRbaKSbtcyUr9+Q+9kO00dD2H5RRRtakcDq0ESd+yFD0JofrM8oX/LzOBgriUmkp1laXIL1rjcW94ioeGhRotZmX4SCeHvQV94/AUa1sepHgo97TQjEOBENizoctygQd3qfBXUm1zxZGUv/Xue3PG2uuwdCxK9VQAZf9rpfwcszbeswlkI1HabaNXeO0qcora4T0lzDTvYZ7H/NHoAmKEZF4c32ZZdvsIy7T9tfSM/InVQFqpMq2cxcYF5TtrUbSenlWKf5YkBLhvakpOfFBiR12N2UuqD0fvnkQiELjqkEotvRet1GlUpjGVHeh7z0jmmo1JnJcKuR/mseLgYuXK6bHoAiYQirFVqKzvIPJdM9nmzx1UhWtGk4wmD6gliV5wdcXxYkfS4xk8fMSwY6JL6J9DUo3btFm4OVFJjMs+tGxUUQ5b63K6zaLO6F7r4ygmsjrSpmMhxSDaNgfGDk6rr3ysVqc3u7ZTmqX5DtunstvXChKYLFSdBJLFXeCh08P7BA9vjzNrAmQ+lrfXxjhTWitLigej8rCsoW+tYMqaTPnghXCZKZafF2aDgXi0bJ X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(7416014)(376014)(23010399003)(36860700016)(1800799024)(82310400026)(921020)(10067099003)(11063799006)(56012099006)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: BWrBl0ybsT6Y0P+cyWUlXgZDbyrXgcEnWrX0U/t3KUGi3bmU2ApryyjjnensiigKOFHwS7B5JxtwyQhjb3NKVI2zRLojfMjZ4icG5wq9OVRH/xz5hzZcnDg1uuxmU9c1s5ndjeXHfhNm4OP2lCgBX+sUE9jR41LPbSL2SIDdGrxc/cbnUOOoyZasO3vQjqKA7EC+KxA6YctTpoPMI049a1Kfg6bv7ZcvsfXG26Ma7k2+6jGzGTbRNrhbtXc1Va1chwwF1rsiiyP1IH3Fb31KNQX2ukl8lI86UmnVvHokSmlPD2LozmFz3cUJQ6DI2Zg+dW89l3iTydjhZn4z0/ho/jzSMab+fvSBVyNzVDoBcHJBpl/7A0qhXK8o+K1LJ7nqgDSTIZwCvUAUrLXCGd3CntQjp237sEAld84RWv0070l4cjloQfcsFZGQOXAPTLud X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:44:55.7360 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2be49f92-972b-4186-c213-08def470eb8e X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D8.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY5PR12MB6597 Content-Type: text/plain; charset="utf-8" From: Srinivas Neeli The TSN Endpoint MAC owns the IP's host-side MCDMA data path and is the netdev physically wired to the CPU. The DSA switch needs this netdev to exist as its conduit. Add a platform driver (compatible "xlnx,tsn-ep-mac") for the endpoint. Register the netdev named "ep", set its MAC address, and provide minimal netdev and ethtool ops. This skeleton handles device bring-up only, with no data path yet. So ndo_open just starts the queues and ndo_start_xmit drops frames. Signed-off-by: Srinivas Neeli Co-developed-by: Nagadheeraj Rottela Signed-off-by: Nagadheeraj Rottela --- drivers/net/ethernet/xilinx/tsn/Makefile | 2 +- drivers/net/ethernet/xilinx/tsn/xilinx_tsn.h | 15 ++ .../net/ethernet/xilinx/tsn/xilinx_tsn_ep.c | 152 ++++++++++++++++++ .../net/ethernet/xilinx/tsn/xilinx_tsn_main.c | 3 + 4 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/xilinx/tsn/xilinx_tsn.h create mode 100644 drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c diff --git a/drivers/net/ethernet/xilinx/tsn/Makefile b/drivers/net/etherne= t/xilinx/tsn/Makefile index 6f99226f3dc8..5886828b386f 100644 --- a/drivers/net/ethernet/xilinx/tsn/Makefile +++ b/drivers/net/ethernet/xilinx/tsn/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_XILINX_TSN) +=3D xilinx_tsn.o -xilinx_tsn-y :=3D xilinx_tsn_main.o +xilinx_tsn-y :=3D xilinx_tsn_main.o xilinx_tsn_ep.o diff --git a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn.h b/drivers/net/eth= ernet/xilinx/tsn/xilinx_tsn.h new file mode 100644 index 000000000000..b0757e22d1fd --- /dev/null +++ b/drivers/net/ethernet/xilinx/tsn/xilinx_tsn.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * AMD/Xilinx TSN Endpoint Ethernet MAC driver, shared definitions. + * + * Copyright (C) 2026 Advanced Micro Devices, Inc. + */ + +#ifndef _XILINX_TSN_H +#define _XILINX_TSN_H + +#include + +extern struct platform_driver xlnx_tsn_ep_driver; + +#endif /* _XILINX_TSN_H */ diff --git a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c b/drivers/net/= ethernet/xilinx/tsn/xilinx_tsn_ep.c new file mode 100644 index 000000000000..9b556edf5423 --- /dev/null +++ b/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD/Xilinx TSN Endpoint MAC driver. + * + * Copyright (C) 2026 Advanced Micro Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xilinx_tsn.h" + +#define DRIVER_NAME "xilinx_tsn_ep" + +/** + * struct xlnx_tsn_ep - EP MAC private data, embedded in net_device priv a= rea + * @ndev: the conduit netdev ("ep") + * @dev: backing device + * @regs: EP MAC register window + */ +struct xlnx_tsn_ep { + struct net_device *ndev; + struct device *dev; + void __iomem *regs; +}; + +static netdev_tx_t ep_start_xmit(struct sk_buff *skb, struct net_device *n= dev) +{ + dev_kfree_skb(skb); + DEV_STATS_INC(ndev, tx_dropped); + return NETDEV_TX_OK; +} + +static int ep_open(struct net_device *ndev) +{ + netif_tx_start_all_queues(ndev); + + return 0; +} + +static int ep_stop(struct net_device *ndev) +{ + netif_tx_disable(ndev); + + return 0; +} + +static void ep_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo= *ed) +{ + strscpy(ed->driver, DRIVER_NAME, sizeof(ed->driver)); +} + +static const struct net_device_ops ep_netdev_ops =3D { + .ndo_open =3D ep_open, + .ndo_stop =3D ep_stop, + .ndo_start_xmit =3D ep_start_xmit, + .ndo_validate_addr =3D eth_validate_addr, + .ndo_set_mac_address =3D eth_mac_addr, +}; + +static const struct ethtool_ops ep_ethtool_ops =3D { + .get_drvinfo =3D ep_get_drvinfo, +}; + +static int xlnx_tsn_ep_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct net_device *ndev; + struct xlnx_tsn_ep *ep; + u8 mac_addr[ETH_ALEN]; + int ret; + + ndev =3D alloc_netdev(sizeof(*ep), "ep", NET_NAME_UNKNOWN, ether_setup); + if (!ndev) + return -ENOMEM; + + SET_NETDEV_DEV(ndev, dev); + ndev->netdev_ops =3D &ep_netdev_ops; + ndev->ethtool_ops =3D &ep_ethtool_ops; + ndev->features =3D NETIF_F_SG; + + ep =3D netdev_priv(ndev); + ep->ndev =3D ndev; + ep->dev =3D dev; + + ep->regs =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ep->regs)) { + ret =3D PTR_ERR(ep->regs); + goto err_free_ndev; + } + + ret =3D of_get_mac_address(dev->of_node, mac_addr); + if (ret =3D=3D -EPROBE_DEFER) { + goto err_free_ndev; + } else if (!ret && is_valid_ether_addr(mac_addr)) { + eth_hw_addr_set(ndev, mac_addr); + } else { + eth_hw_addr_random(ndev); + dev_info(dev, "no valid MAC in DT, using random address %pM\n", + ndev->dev_addr); + } + + platform_set_drvdata(pdev, ep); + + ret =3D register_netdev(ndev); + if (ret) { + dev_err_probe(dev, ret, "failed to register net device\n"); + goto err_free_ndev; + } + + return 0; + +err_free_ndev: + free_netdev(ndev); + return ret; +} + +static void xlnx_tsn_ep_remove(struct platform_device *pdev) +{ + struct xlnx_tsn_ep *ep =3D platform_get_drvdata(pdev); + + if (!ep) + return; + + unregister_netdev(ep->ndev); + free_netdev(ep->ndev); +} + +static const struct of_device_id xlnx_tsn_ep_of_match[] =3D { + { .compatible =3D "xlnx,tsn-ep-mac" }, + { } +}; +MODULE_DEVICE_TABLE(of, xlnx_tsn_ep_of_match); + +struct platform_driver xlnx_tsn_ep_driver =3D { + .probe =3D xlnx_tsn_ep_probe, + .remove =3D xlnx_tsn_ep_remove, + .driver =3D { + .name =3D DRIVER_NAME, + .of_match_table =3D xlnx_tsn_ep_of_match, + }, +}; diff --git a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_main.c b/drivers/ne= t/ethernet/xilinx/tsn/xilinx_tsn_main.c index 1ef1b0c2ee6e..3df8c026741f 100644 --- a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_main.c +++ b/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_main.c @@ -16,6 +16,8 @@ #include #include =20 +#include "xilinx_tsn.h" + #define TSN_NUM_CLOCKS 6 =20 /** @@ -86,6 +88,7 @@ static struct platform_driver tsn_driver =3D { =20 static struct platform_driver * const tsn_drivers[] =3D { &tsn_driver, + &xlnx_tsn_ep_driver, }; =20 static int __init xlnx_tsn_init(void) --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from BL0PR03CU003.outbound.protection.outlook.com (mail-eastusazon11012031.outbound.protection.outlook.com [52.101.53.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A6E0940A956; Fri, 7 Aug 2026 10:45:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.53.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099518; cv=fail; b=VzbuSM7QqpLFKvfaYENiD8oDCP1866F2jyoxO9YWU6XR8TS9pXgahpqfI/rWVZQWLU5Kjp6qRr1h96mbAimMI4vtjJILAFbvklPd17oEtdezn12LbRiKDVkoYhjM4J2Z4wzpEL8me27vWaEyTojtX5F+sFsRqttnDGOtTgev96I= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099518; c=relaxed/simple; bh=M1sdlrXDtDD2wvvjD9bqelSMb4AdHUmJW7mSm8PfX30=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=aKn0GNN/kx4Dnx4mL6X4HsIhRsqANPbtthteY0M9bpwKi7Yy18QYP4c/1LMz4RFCn+xU6znAn5F07ZgdZHLHbuRGa5lFQIFC1mQ4SRcqfwUEq4UwGRKCnTfA4HPs9x3heL3Dj9KQuYHvCkm+/DdaOe2SVsjgwiZcyevVLFz0foM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=3XYIFeN7; arc=fail smtp.client-ip=52.101.53.31 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="3XYIFeN7" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=G0rcpEJwzi9Bbu4KO0PihsOyzVpbFgdun6/NgCk5m8EsP6OHFGQc+x0wZWCz2lu7DGwrR6X9XUD/LGUifIQ8KH9vDg/J+i+CoRyWad05XwLphASeI1xMy1RU3wEEpYva9aGi5SCZoOAwAu+4YpDtSONt7jVGcK9Y0FHy3rCKAKZ/s2gZix+NKSQR9JEBcjxHW9kHGhlUUSaf7CTRSUm/VTKaQxPtN40hME2qORvykvvmzcpINkjcX/sHkDkVYPfcBdbmQEej9Dw7a30+hZj7BEoaZESt0+XduWyy3vP/ObAfUqnSERuU82fyObRQ4A0DbmDll+XYxG9vTOKpbGAVqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=mrfcMwPIUWQ9ezVOmLyMWVvwWV8Hb23WZBtJvN5Utvw=; b=gOQ+2cdvwK5f75bH257Dw7o9B6E/MSk1uoD2w2GaTjyIP/RbfoKQfa4HJED0gKr1cnFqce8kgIqawVx+JPc3iIxEZss2khZkzSz/ZWUnz7jQZQZBwIWlspKQoHz9Fnt6UVmPUpi5pnv0f/aq2KmXQWiEoMFLx6SFrsOW6HZuZAjaWH19EEACjNq3upEo7H1at4Ho/xp4OJDQXrFfLfyhnjLEoQVbWnqpCtJpL+zRaOriomdlWscf3SzN3vRxygWUhdooj90ndTwDsjvBMNh5UYO6K0ukcYt6wg795LgzsHfzBI6iRJVQIegVqaviUxBbwy4FSIWFnU5mwNMjVDKi+w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mrfcMwPIUWQ9ezVOmLyMWVvwWV8Hb23WZBtJvN5Utvw=; b=3XYIFeN7iagizt/s6Xmu2CWcZtj58XJrzQIFd51ltUQsfuOj9CDnb1gmaCj5d3iFnvS2FVXKggQ/D5T9ZaUigBYamfHDuajUJ7mLy4RePOi0sSh5F5y7d4h/sBPfX+UlxvtyP5/9kgSztTH60hZRo3RIAQNPz58fJaIk77zdAIs= Received: from PH7P220CA0064.NAMP220.PROD.OUTLOOK.COM (2603:10b6:510:32c::8) by IA1PR12MB6436.namprd12.prod.outlook.com (2603:10b6:208:3ac::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.19; Fri, 7 Aug 2026 10:45:09 +0000 Received: from SJ1PEPF000023D3.namprd21.prod.outlook.com (2603:10b6:510:32c:cafe::ad) by PH7P220CA0064.outlook.office365.com (2603:10b6:510:32c::8) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.24 via Frontend Transport; Fri, 7 Aug 2026 10:45:09 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D3.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:45:09 +0000 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:44:59 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:44:54 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 04/20] net: xilinx: tsn: parse endpoint DMA channel configuration Date: Fri, 7 Aug 2026 16:14:15 +0530 Message-ID: <20260807104431.157230-5-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D3:EE_|IA1PR12MB6436:EE_ X-MS-Office365-Filtering-Correlation-Id: caf8ae03-bcd9-429c-3062-08def470f38a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700016|7416014|23010399003|376014|1800799024|82310400026|921020|10067099003|11063799006|56012099006|18002099003|22082099003; X-Microsoft-Antispam-Message-Info: STV13yRW9LHkv7g7Y4E9uGIVKIEGEynS5gngEEEHNYj1LQtEKIaxVF0FqHjoTrl4GmdLzrnMs/P7kzJtx1cIV7q0LMr/bWhWoBURgjhpJHW0gbYL+3hgnyK+Z4sItTuqQQQHWr9PJt3NCtN7qq1B7GGEj3V2UGMRrl9zpjuExsnmFpkfKWtSiazr31MrUDV6mOX4plTzjljUakCQqoB+BggHQc8y6YfbVWbwkGW/Jj2tafaETPilOJEFvHwX6Xkb/ZB7qe7/GPVBx8G8vMK8GFTmkbPUAANd+aQIDnY4Sjt4Dle0dQ6KjRc72NY2e5eciBi1eU5xictq4tpx6zKIBQxhR/RNCFM8DDHD0UdD/6AkQJD/79DFi7ASvXhkBpT0xiW5P693K1ErliRoVLWaVwkFVLJlzvwQGjmDpLRBcCVA6lVSqEmLAfFpjy8V7WY09pEW8px+iDbnO6QYP04DvJtfknbX4ng/yPeOaoW6FuueOq46rYI5paH1SIL8rUoOdxnHkWS6Q5MRCIrMGM/9C/QoWUA2i/LBIAF1mFPHD0vZ3N+5lwbJ6zj33DzWPMWJHi3F/lZk0kp3mFm6XDtBoY3A/loU346mLX1f8CtRkq30xEMxUqvTGpKXDjY7Ubf0JHc3oYd6HK4ao3zEoiTOGMhGUuz02iKS49pF88bKHlGuSmVGXGYec97YtALY0z11Gws+7pRV70PpVd6Coh6F0D2l3LsFj252o6f66ZkuJVyw+xvZrt7Yekvu5yE1AYl+ X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700016)(7416014)(23010399003)(376014)(1800799024)(82310400026)(921020)(10067099003)(11063799006)(56012099006)(18002099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: dVSZEVVoRGGQaA7G0N8d3Cd6KYNHLFOEiWV5Au0yEs2fMjj6Decvfc1gWitimld0EL8koPPZw9tdpGlBpC0uOoJgtDlu5IQSMd6t1VasRwsUNHo4+WwMKPIylMrRn+hfudK+6K5/xhgien5OnEg0Jdnt6OR9Wv+fw7fTYqZDeEriufEiLv/DhbkDuqdL4Zyekqe2P3cnv4TgdnEsxt3vX1ssTw5ooKoa0wX1aB6sLG3C7DZsVQcsbKCJSmdMEEsochfUF3eDXYIPlHYo8p4zI7HGuVdLryULzjpPERIuQjYdjYlT+wRlHOO/kemod/m/0bYzbQCClhM6MAKwDj4nxWUNSGgmBFdraGwWiq/vSZlTuvw5gJmF6f41Q21lVeFgCsiFUPL1pccWyUDCqkd8KusRyUnpVymHEwpBFaDljwy6EZ02njjoFDpECgy1lC2T X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:09.1885 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: caf8ae03-bcd9-429c-3062-08def470f38a X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D3.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB6436 Content-Type: text/plain; charset="utf-8" From: Srinivas Neeli The endpoint has one MCDMA channel per TX queue and per RX queue, and the device tree lists them in "dma-names". The transmit path needs to know which physical DMA channel backs each logical TX queue. Count the TX and RX channels in "dma-names" and allocate the conduit netdev with that many hardware queues. Parse the "tx-queues-config" child node to map each logical TX queue to its physical DMA channel. Signed-off-by: Srinivas Neeli Co-developed-by: Nagadheeraj Rottela Signed-off-by: Nagadheeraj Rottela --- .../net/ethernet/xilinx/tsn/xilinx_tsn_ep.c | 138 +++++++++++++++++- 1 file changed, 137 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c b/drivers/net/= ethernet/xilinx/tsn/xilinx_tsn_ep.c index 9b556edf5423..062cb94c2153 100644 --- a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c +++ b/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c @@ -5,9 +5,11 @@ * Copyright (C) 2026 Advanced Micro Devices, Inc. */ =20 +#include #include #include #include +#include #include #include #include @@ -22,16 +24,32 @@ =20 #define DRIVER_NAME "xilinx_tsn_ep" =20 +#define TSN_DMA_CH_INVALID 0xFFU +#define TSN_MAX_TX_QUEUE 8 +#define TSN_MAX_RX_QUEUE 16 + +#define TSN_MAX_VLAN_FRAME_SIZE (ETH_DATA_LEN + VLAN_ETH_HLEN + \ + ETH_FCS_LEN) + /** * struct xlnx_tsn_ep - EP MAC private data, embedded in net_device priv a= rea * @ndev: the conduit netdev ("ep") * @dev: backing device * @regs: EP MAC register window + * @num_tx_queues: number of TX DMA channels (one per priority) + * @num_rx_queues: number of RX DMA channels + * @tx_dma_chan_map: logical TX queue index -> physical DMA channel number + * @max_frm_size: maximum frame size accepted on RX */ struct xlnx_tsn_ep { struct net_device *ndev; struct device *dev; void __iomem *regs; + + u32 num_tx_queues; + u32 num_rx_queues; + u32 tx_dma_chan_map[TSN_MAX_TX_QUEUE]; + u32 max_frm_size; }; =20 static netdev_tx_t ep_start_xmit(struct sk_buff *skb, struct net_device *n= dev) @@ -72,15 +90,116 @@ static const struct ethtool_ops ep_ethtool_ops =3D { .get_drvinfo =3D ep_get_drvinfo, }; =20 +/* + * Parse the "tx-queues-config" child of the EP node. The logical queue + * index is taken from the "queue" node name, so the mapping does not + * depend on the order the child nodes appear in the device tree. + */ +static int ep_parse_tx_queue_config(struct xlnx_tsn_ep *ep, + struct device_node *txcfg_np) +{ + DECLARE_BITMAP(chan_seen, TSN_MAX_TX_QUEUE) =3D {}; + DECLARE_BITMAP(queue_seen, TSN_MAX_TX_QUEUE) =3D {}; + unsigned int count =3D 0; + int ret; + + for_each_child_of_node_scoped(txcfg_np, qnode) { + u32 chan, queue; + + if (!str_has_prefix(qnode->name, "queue") || + kstrtou32(qnode->name + strlen("queue"), 10, &queue) || + queue >=3D ep->num_tx_queues) + return dev_err_probe(ep->dev, -EINVAL, + "tx-config: invalid queue node %pOFn (have %u queues)\n", + qnode, ep->num_tx_queues); + + if (test_and_set_bit(queue, queue_seen)) + return dev_err_probe(ep->dev, -EINVAL, + "tx-config: queue %u described twice\n", + queue); + + ret =3D of_property_read_u32(qnode, "xlnx,dma-channel-num", &chan); + if (ret) + return dev_err_probe(ep->dev, ret, + "tx-config: queue %u missing xlnx,dma-channel-num\n", + queue); + + if (chan >=3D ep->num_tx_queues) + return dev_err_probe(ep->dev, -EINVAL, + "tx-config: queue %u channel %u has no matching tx_chan (have %u= )\n", + queue, chan, ep->num_tx_queues); + + if (test_and_set_bit(chan, chan_seen)) + return dev_err_probe(ep->dev, -EINVAL, + "tx-config: channel %u already assigned to another queue\n", + chan); + + ep->tx_dma_chan_map[queue] =3D chan; + count++; + } + + if (count !=3D ep->num_tx_queues) + return dev_err_probe(ep->dev, -EINVAL, + "tx-config: described %u queues but expected %u\n", + count, ep->num_tx_queues); + + return 0; +} + +static int ep_count_dma_queues(struct device *dev, u32 *out_tx, u32 *out_r= x) +{ + u32 tx =3D 0, rx =3D 0; + int n, i; + + n =3D of_property_count_strings(dev->of_node, "dma-names"); + if (n < 0) + return dev_err_probe(dev, n, "failed to read dma-names\n"); + + for (i =3D 0; i < n; i++) { + const char *name; + + if (of_property_read_string_index(dev->of_node, "dma-names", + i, &name)) + continue; + if (str_has_prefix(name, "tx_chan")) + tx++; + else if (str_has_prefix(name, "rx_chan")) + rx++; + } + + if (!tx || tx > TSN_MAX_TX_QUEUE) + return dev_err_probe(dev, -EINVAL, + "invalid TX queue count (%u, max %u)\n", + tx, TSN_MAX_TX_QUEUE); + + if (!rx || rx > TSN_MAX_RX_QUEUE) + return dev_err_probe(dev, -EINVAL, + "invalid RX queue count (%u, max %u)\n", + rx, TSN_MAX_RX_QUEUE); + + *out_tx =3D tx; + *out_rx =3D rx; + + return 0; +} + static int xlnx_tsn_ep_probe(struct platform_device *pdev) { struct device *dev =3D &pdev->dev; + struct device_node *txcfg_np; struct net_device *ndev; struct xlnx_tsn_ep *ep; u8 mac_addr[ETH_ALEN]; + u32 num_tx, num_rx; int ret; + int i; =20 - ndev =3D alloc_netdev(sizeof(*ep), "ep", NET_NAME_UNKNOWN, ether_setup); + ret =3D ep_count_dma_queues(dev, &num_tx, &num_rx); + if (ret) + return ret; + + ndev =3D alloc_netdev_mqs(sizeof(*ep), "ep", NET_NAME_UNKNOWN, + ether_setup, num_tx, num_rx); if (!ndev) return -ENOMEM; =20 @@ -92,6 +211,12 @@ static int xlnx_tsn_ep_probe(struct platform_device *pd= ev) ep =3D netdev_priv(ndev); ep->ndev =3D ndev; ep->dev =3D dev; + ep->num_tx_queues =3D num_tx; + ep->num_rx_queues =3D num_rx; + ep->max_frm_size =3D TSN_MAX_VLAN_FRAME_SIZE; + + for (i =3D 0; i < TSN_MAX_TX_QUEUE; i++) + ep->tx_dma_chan_map[i] =3D TSN_DMA_CH_INVALID; =20 ep->regs =3D devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(ep->regs)) { @@ -99,6 +224,17 @@ static int xlnx_tsn_ep_probe(struct platform_device *pd= ev) goto err_free_ndev; } =20 + txcfg_np =3D of_get_child_by_name(dev->of_node, "tx-queues-config"); + if (!txcfg_np) { + ret =3D dev_err_probe(dev, -EINVAL, + "missing tx-queues-config node\n"); + goto err_free_ndev; + } + ret =3D ep_parse_tx_queue_config(ep, txcfg_np); + of_node_put(txcfg_np); + if (ret) + goto err_free_ndev; + ret =3D of_get_mac_address(dev->of_node, mac_addr); if (ret =3D=3D -EPROBE_DEFER) { goto err_free_ndev; --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from CY3PR05CU001.outbound.protection.outlook.com (mail-westcentralusazon11013022.outbound.protection.outlook.com [40.93.201.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 046E142CAFC; Fri, 7 Aug 2026 10:45:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.201.22 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099521; cv=fail; b=OUo7YtqVTIxxvi/lXIasg+yccaREwP9odD5pCEYlSQTibnZm+4zksFECh5ukvq6YJwIak8HiZl0/wBm9L1fuZ4sbbeHZPkXN0sqVOvXTfCUBG5tUIzb/Q58eVxVPsV/emBcEclB3N9l7t1DkFIdbPqVBZUQlg78f6HhQt3AoF7w= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099521; c=relaxed/simple; bh=7IiN7WEX4eerRphMITxeGDNf1+Oj5oE3/27Ztmj5//g=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VgMBOP6MyySEm4vp8x0IaQsbjESMX3tbJ/PXCpwd3yj343qRapeLYfQMmeDxFbnuYx0MT+tEr4kerixkPo3MAnnfBUbVlO7hpWUtvRUo1DgF5FSwgBeugURrQ0/zX9txZfQSyKcsBw2mzeWl9qqDUWjLtA/Tg7meUSJaxkzr598= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=pPeGhjwT; arc=fail smtp.client-ip=40.93.201.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="pPeGhjwT" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=yh7K3E34HD29Ybfzl8vLou9nDLhtDe9qFRyEe8u1ar458Ilc1evH8YvPg0HKbUjbGNTxXHsDpHOz4tFeGXTHPJ7Uc5xw7LBBo9KgfWv9sT0yC+ji2eXfOrhgIzspgswVq+lsf8KBjY//0wq8uc+Okcbc4T5MubGbOMn7NnQREX2fOzxGq/Yc+TxyFAHsGUOVzuPaNRwW9rGP6eE6eEzcnYFiZ0E+Sw6jNEKEwP9QU3gDywPkLCGrOgp6MQEA64LiNSo4EHOIbPolygrtMLdhdDfQynujcba8DJBnYsblVqf47vRga2NPteOzXAaRm9x9G7aI6AId+SSoEtgvz1y6dQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=E4FTbUBPo/A855TyJNiIV2016LvcdHxqF2S9gCkk0Ro=; b=roydPjsn28vksm+k4Bn1kcN9tU0XUH6iQS2SbA6+/FLpPpATZ407SfBOwD6I6GJpyIlfZ+gLoOIz4H5IeCm64RpotNK+1YmLeQKEGhWddR5bojGLDVA7mdYlseWgHbFPb+IOfwz3tqdF2INsNEN+EevbfMTrHqDYBHRy5UgVDNUvhR5eX9XvbSSVxd5LR8b7l8aepsAiD3xP+TmPB2gxbq8921YKKooSV6XsE+qaTZEHVKf21ZxmliW8VNbZWaxaxm2hOVH8dcF9/W4dhfwK/L/uQzzi1YHMrpyKnG1IvJR50kZWJFHUzHdN6oJSMhrVPxmICR6C4H2HjF3M/7XdkQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=E4FTbUBPo/A855TyJNiIV2016LvcdHxqF2S9gCkk0Ro=; b=pPeGhjwTkGhXJCwRpaJPBVbZR9H3OEWuye0RLKduAlziK48NEbtWT+Ln0ekKfO5ki3fd33t+Fvr3ZUOMeSbJtUOJ0DAnVSQ8hR4cnqwSSX+d0mnaIUQDP+4x474HEh6ptAeTJZsS/n7DtlpOhcqn+LVPW8DKVeTtZeoGdGC6uV8= Received: from PH7P220CA0082.NAMP220.PROD.OUTLOOK.COM (2603:10b6:510:32c::17) by SJ5PPF4C62B9E70.namprd12.prod.outlook.com (2603:10b6:a0f:fc02::991) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.19; Fri, 7 Aug 2026 10:45:14 +0000 Received: from SJ1PEPF000023D3.namprd21.prod.outlook.com (2603:10b6:510:32c:cafe::54) by PH7P220CA0082.outlook.office365.com (2603:10b6:510:32c::17) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.23 via Frontend Transport; Fri, 7 Aug 2026 10:45:14 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D3.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:45:14 +0000 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:05 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:00 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 05/20] net: xilinx: tsn: bring up the endpoint MCDMA channels Date: Fri, 7 Aug 2026 16:14:16 +0530 Message-ID: <20260807104431.157230-6-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D3:EE_|SJ5PPF4C62B9E70:EE_ X-MS-Office365-Filtering-Correlation-Id: f0022b7c-14f7-46aa-8f21-08def470f6d9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|1800799024|376014|36860700016|23010399003|7416014|18002099003|22082099003|56012099006|11063799006|6133799003|10067099003|921020; X-Microsoft-Antispam-Message-Info: PkTQKo7mzmOqzJ9dvLzdsqVQ0DhFHPr6VbqDbWaQpUtSJnKnZL8wQ/qi9Q5MpPPENl3vnu6aIWJbee1FOtSBCt5bMtXF/momZlhW6nfRK+pVvUqu5mioM98tQf+C9KZkLFmjcz5f6YWjmjsl3Z85/bVgTtS1JzdKiig5gq+nb+Gr9QqiPr543Rb94ch7JD4cLYmuEvr/DKLXiNMQ6hXyFJ/Q5ZDz/lZXJ+4jW39cXJ0ixO1jg0Y6WeRn4Y4T4A+am2vn/o1MxIre9ldsz+94Pqun+C8ZTR5k65bSwgkSdjIUG8VzHZ6fgnZoDt2VDPfUP7yQXZH/UYAoK3bvnLiR0Cb28H5TMW7IIdD5RPpQBzuWcbevCvpLEkn32zx9qwAqskCRoMLrBOevmVHTvYSBD0j0N57pdNOrML10szrBNXA8+mWDuUH1w6m8lPxt4sHyu/Z6WE2+0Yn766uOA3xF9mkaP0S3danq267foPpqOPj31x/cLjINh0SV0WR1/gJX24b20fuMPyFUImaLaLuHVsZiAM7z9TA+dDWejjDq0lU8FGPaGKbz+aItW1ZRClw+UjLDEaxztQy0RDuG/HXxwMuSGuZHY29jWMGMiWZ4+/x+QeQOmeb7LFGvfVeCEZ13QAY/CZszukZ6tFsqGBcb0PlhXwWhdkTRgvEaUiugxiOwxkGZP5FJkj9EzLdVFg1ivthXZkB3nmMWaa7l9i/zoI6bqrBOCT58giZwtAR5lvb8FU+CJs2DcuiGJkmDqoGG X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(1800799024)(376014)(36860700016)(23010399003)(7416014)(18002099003)(22082099003)(56012099006)(11063799006)(6133799003)(10067099003)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 4/tdOhYd8KV8F1aLunROk/YTTU563XNaFdmnLLf5z4iQ3KLYAMoMr38oyxHwqt+ZsrnlD6NWeslGFbI8Is8M4YRonRpnq/e0aaFA2NME2c80uKBUnaKJrLW0flIZ51zYO9DNz8C+QKoE0mJAnILZuoZ2twlwIN9JAAEE2b0jEDlwu/EhReq3uVgUxXTMSiUNKEX41kyl8BSwqUZg1sc9/7gmIk2smJve2w8wor4Qe73S4zgrGCSQRBB541shOyFN/Y9dWBFJh267bfxBvmhtQjB81css2qy3K7saAZUtlzrKVbWLngzESifDHmxgRxzKtp+6f2kprI4jmOhGq7mwh70jSK2Vp/UD3jRGEWaL141mCxb93h0nHeZX5br1+tTXwnKCvVDi4RhdbTG9Zj/pWImzBly4vjwiDR6bm+DCiNYssg1snQ16IAZrNeAPGdfi X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:14.6816 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f0022b7c-14f7-46aa-8f21-08def470f6d9 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D3.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ5PPF4C62B9E70 Content-Type: text/plain; charset="utf-8" From: Srinivas Neeli Before the endpoint can move frames, each MCDMA channel needs a ring of buffers and a live dmaengine channel. Request every TX and RX channel named in the device tree when the interface opens, and give each one a ring of preallocated SKB descriptor slots. Reset the controller through tx_chan0 on open, and release the channels on stop. Add the XILINX_DMA dependency for the dmaengine and Xilinx DMA APIs. Signed-off-by: Srinivas Neeli Co-developed-by: Nagadheeraj Rottela Signed-off-by: Nagadheeraj Rottela --- drivers/net/ethernet/xilinx/tsn/Kconfig | 1 + .../net/ethernet/xilinx/tsn/xilinx_tsn_ep.c | 274 ++++++++++++++++++ 2 files changed, 275 insertions(+) diff --git a/drivers/net/ethernet/xilinx/tsn/Kconfig b/drivers/net/ethernet= /xilinx/tsn/Kconfig index 45af4d3f10e6..551139a220ef 100644 --- a/drivers/net/ethernet/xilinx/tsn/Kconfig +++ b/drivers/net/ethernet/xilinx/tsn/Kconfig @@ -6,6 +6,7 @@ config XILINX_TSN tristate "Xilinx TSN Ethernet driver" depends on OF && HAS_IOMEM + depends on XILINX_DMA help This driver supports the AMD/Xilinx Time-Sensitive Networking (TSN) Endpoint Ethernet MAC IP. It provides the wrapper device diff --git a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c b/drivers/net/= ethernet/xilinx/tsn/xilinx_tsn_ep.c index 062cb94c2153..fa21d59ade16 100644 --- a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c +++ b/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c @@ -6,10 +6,15 @@ */ =20 #include +#include +#include +#include +#include #include #include #include #include +#include #include #include #include @@ -17,6 +22,9 @@ #include #include #include +#include +#include +#include #include #include =20 @@ -31,6 +39,47 @@ #define TSN_MAX_VLAN_FRAME_SIZE (ETH_DATA_LEN + VLAN_ETH_HLEN + \ ETH_FCS_LEN) =20 +#define TX_BD_NUM_DEFAULT 64 +#define RX_BD_NUM_DEFAULT 128 + +/** + * struct skbuf_dma_descriptor - skb container for each in-flight DMA desc= riptor + * @sgl: scatter-gather list backing the DMA mapping + * @desc: dmaengine descriptor handle + * @dma_address: physical address of the first sgl entry (RX path) + * @skb: SKB owning the buffer + * @sg_len: number of valid entries in @sgl (TX path) + */ +struct skbuf_dma_descriptor { + struct scatterlist sgl[MAX_SKB_FRAGS + 1]; + struct dma_async_tx_descriptor *desc; + dma_addr_t dma_address; + struct sk_buff *skb; + int sg_len; +}; + +/** + * struct xlnx_tsn_ep_dma_chan - one DMA channel and its SKB ring + * @skb_ring: per-slot SKB descriptors + * @ep: pointer back to the owning EP instance + * @chan: dmaengine channel handle + * @dma_dev: device used for DMA mapping (the DMA engine, not the EP) + * @ring_head: producer index + * @ring_tail: consumer index + * @ring_size: number of slots in @skb_ring + * @is_tx: true for TX channels, false for RX + */ +struct xlnx_tsn_ep_dma_chan { + struct skbuf_dma_descriptor **skb_ring; + struct xlnx_tsn_ep *ep; + struct dma_chan *chan; + struct device *dma_dev; + u32 ring_head; + u32 ring_tail; + u32 ring_size; + bool is_tx; +}; + /** * struct xlnx_tsn_ep - EP MAC private data, embedded in net_device priv a= rea * @ndev: the conduit netdev ("ep") @@ -40,6 +89,9 @@ * @num_rx_queues: number of RX DMA channels * @tx_dma_chan_map: logical TX queue index -> physical DMA channel number * @max_frm_size: maximum frame size accepted on RX + * @tx_chans: array of TX channels (size @num_tx_queues) + * @rx_chans: array of RX channels (size @num_rx_queues) + * @closing: set in ndo_stop so the RX completion callback stops re-arming */ struct xlnx_tsn_ep { struct net_device *ndev; @@ -50,8 +102,19 @@ struct xlnx_tsn_ep { u32 num_rx_queues; u32 tx_dma_chan_map[TSN_MAX_TX_QUEUE]; u32 max_frm_size; + + struct xlnx_tsn_ep_dma_chan **tx_chans; + struct xlnx_tsn_ep_dma_chan **rx_chans; + + bool closing; }; =20 +static inline struct skbuf_dma_descriptor * +ep_get_desc(struct xlnx_tsn_ep_dma_chan *xchan, int idx) +{ + return xchan->skb_ring[idx]; +} + static netdev_tx_t ep_start_xmit(struct sk_buff *skb, struct net_device *n= dev) { dev_kfree_skb(skb); @@ -59,8 +122,27 @@ static netdev_tx_t ep_start_xmit(struct sk_buff *skb, s= truct net_device *ndev) return NETDEV_TX_OK; } =20 +static int ep_reset_dma_controller(struct xlnx_tsn_ep *ep); +static int ep_init_dmaengine(struct xlnx_tsn_ep *ep); +static void ep_exit_dmaengine(struct xlnx_tsn_ep *ep); + static int ep_open(struct net_device *ndev) { + struct xlnx_tsn_ep *ep =3D netdev_priv(ndev); + int ret; + + WRITE_ONCE(ep->closing, false); + + ret =3D ep_reset_dma_controller(ep); + if (ret) + return ret; + + ret =3D ep_init_dmaengine(ep); + if (ret) { + netdev_err(ndev, "failed to initialize DMA engine\n"); + return ret; + } + netif_tx_start_all_queues(ndev); =20 return 0; @@ -68,7 +150,11 @@ static int ep_open(struct net_device *ndev) =20 static int ep_stop(struct net_device *ndev) { + struct xlnx_tsn_ep *ep =3D netdev_priv(ndev); + netif_tx_disable(ndev); + WRITE_ONCE(ep->closing, true); + ep_exit_dmaengine(ep); =20 return 0; } @@ -90,6 +176,194 @@ static const struct ethtool_ops ep_ethtool_ops =3D { .get_drvinfo =3D ep_get_drvinfo, }; =20 +static struct xlnx_tsn_ep_dma_chan * +ep_alloc_dma_chan(struct xlnx_tsn_ep *ep, const char *name, bool is_tx, + int ring_size) +{ + struct xlnx_tsn_ep_dma_chan *chan; + struct dma_chan *err_chan; + int i; + + chan =3D kzalloc_obj(*chan); + if (!chan) + return ERR_PTR(-ENOMEM); + + chan->chan =3D dma_request_chan(ep->dev, name); + if (IS_ERR(chan->chan)) { + err_chan =3D chan->chan; + kfree(chan); + return ERR_CAST(err_chan); + } + + chan->skb_ring =3D kcalloc(ring_size, sizeof(*chan->skb_ring), GFP_KERNEL= ); + if (!chan->skb_ring) { + dma_release_channel(chan->chan); + kfree(chan); + return ERR_PTR(-ENOMEM); + } + + for (i =3D 0; i < ring_size; i++) { + chan->skb_ring[i] =3D kzalloc_obj(*chan->skb_ring[i]); + if (!chan->skb_ring[i]) { + while (--i >=3D 0) + kfree(chan->skb_ring[i]); + kfree(chan->skb_ring); + dma_release_channel(chan->chan); + kfree(chan); + return ERR_PTR(-ENOMEM); + } + } + + chan->is_tx =3D is_tx; + chan->ep =3D ep; + chan->ring_size =3D ring_size; + chan->dma_dev =3D dmaengine_get_dma_device(chan->chan); + + return chan; +} + +static void ep_free_dma_chan(struct xlnx_tsn_ep_dma_chan *chan) +{ + int i; + + if (!chan) + return; + + if (chan->chan) + dmaengine_terminate_sync(chan->chan); + + if (chan->is_tx) { + while (chan->ring_tail !=3D chan->ring_head) { + struct skbuf_dma_descriptor *skbuf_dma; + + skbuf_dma =3D chan->skb_ring[chan->ring_tail & + (chan->ring_size - 1)]; + if (skbuf_dma && skbuf_dma->skb) { + dma_unmap_sg(chan->dma_dev, skbuf_dma->sgl, + skbuf_dma->sg_len, DMA_TO_DEVICE); + dev_kfree_skb_any(skbuf_dma->skb); + skbuf_dma->skb =3D NULL; + } + chan->ring_tail++; + } + } + + if (chan->skb_ring) { + for (i =3D 0; i < chan->ring_size; i++) { + struct skbuf_dma_descriptor *skbuf_dma =3D chan->skb_ring[i]; + + if (skbuf_dma && !chan->is_tx && skbuf_dma->skb) { + dma_unmap_single(chan->dma_dev, + skbuf_dma->dma_address, + chan->ep->max_frm_size, + DMA_FROM_DEVICE); + dev_kfree_skb_any(skbuf_dma->skb); + } + kfree(chan->skb_ring[i]); + } + kfree(chan->skb_ring); + } + if (chan->chan) + dma_release_channel(chan->chan); + + kfree(chan); +} + +static void ep_exit_dmaengine(struct xlnx_tsn_ep *ep) +{ + int i; + + if (ep->tx_chans) { + for (i =3D 0; i < ep->num_tx_queues; i++) + ep_free_dma_chan(ep->tx_chans[i]); + kfree(ep->tx_chans); + ep->tx_chans =3D NULL; + } + if (ep->rx_chans) { + for (i =3D 0; i < ep->num_rx_queues; i++) + ep_free_dma_chan(ep->rx_chans[i]); + kfree(ep->rx_chans); + ep->rx_chans =3D NULL; + } +} + +static int ep_init_dmaengine(struct xlnx_tsn_ep *ep) +{ + int tx_allocated =3D 0, rx_allocated =3D 0; + char name[16]; + int i, ret; + + ep->tx_chans =3D kcalloc(ep->num_tx_queues, sizeof(*ep->tx_chans), + GFP_KERNEL); + if (!ep->tx_chans) + return -ENOMEM; + + ep->rx_chans =3D kcalloc(ep->num_rx_queues, sizeof(*ep->rx_chans), + GFP_KERNEL); + if (!ep->rx_chans) { + ret =3D -ENOMEM; + goto err_free_tx; + } + + for (i =3D 0; i < ep->num_tx_queues; i++) { + snprintf(name, sizeof(name), "tx_chan%d", i); + ep->tx_chans[i] =3D ep_alloc_dma_chan(ep, name, true, + TX_BD_NUM_DEFAULT); + if (IS_ERR(ep->tx_chans[i])) { + ret =3D PTR_ERR(ep->tx_chans[i]); + ep->tx_chans[i] =3D NULL; + goto err_free_chans; + } + tx_allocated++; + } + + for (i =3D 0; i < ep->num_rx_queues; i++) { + snprintf(name, sizeof(name), "rx_chan%d", i); + ep->rx_chans[i] =3D ep_alloc_dma_chan(ep, name, false, + RX_BD_NUM_DEFAULT); + if (IS_ERR(ep->rx_chans[i])) { + ret =3D PTR_ERR(ep->rx_chans[i]); + ep->rx_chans[i] =3D NULL; + goto err_free_chans; + } + rx_allocated++; + } + + return 0; + +err_free_chans: + while (--rx_allocated >=3D 0) + ep_free_dma_chan(ep->rx_chans[rx_allocated]); + while (--tx_allocated >=3D 0) + ep_free_dma_chan(ep->tx_chans[tx_allocated]); + kfree(ep->rx_chans); + ep->rx_chans =3D NULL; +err_free_tx: + kfree(ep->tx_chans); + ep->tx_chans =3D NULL; + return ret; +} + +static int ep_reset_dma_controller(struct xlnx_tsn_ep *ep) +{ + struct xilinx_vdma_config cfg =3D { .reset =3D 1 }; + struct dma_chan *tx_chan0; + int ret; + + tx_chan0 =3D dma_request_chan(ep->dev, "tx_chan0"); + if (IS_ERR(tx_chan0)) + return dev_err_probe(ep->dev, PTR_ERR(tx_chan0), + "failed to request tx_chan0 for reset\n"); + + ret =3D xilinx_vdma_channel_set_config(tx_chan0, &cfg); + dma_release_channel(tx_chan0); + if (ret < 0) + return dev_err_probe(ep->dev, ret, + "failed to reset DMA controller\n"); + + return 0; +} + /* * Parse the "tx-queues-config" child of the EP node. The logical queue * index is taken from the "queue" node name, so the mapping does not --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from CY7PR03CU001.outbound.protection.outlook.com (mail-westcentralusazon11010003.outbound.protection.outlook.com [40.93.198.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 43B6C42B746; Fri, 7 Aug 2026 10:45:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.198.3 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099528; cv=fail; b=IHO/eu/2aaR3kJeYReim04wKKmeEimn4diF6RgZyTfaSQ2tmyBJfXP2weqYjJVKS7kbEQarVArST3sDeXu0WK+zVpZbVZ5z7B9OtoTv5txAVibJ1lmKkXcCUYSAAuFO+d+OBD7TP0hqNtSswkGBeftmfp14qOLFWFWGdwTZDSAc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099528; c=relaxed/simple; bh=kD1xruRi+XdDUifA+83J28TvxbL3wCYZ4ZyJ0xmIehg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uPA8lrNDlxflyJu9wl1WxLA+aSgaiF2jDaA+bVYQ1I2DZFCkpvS0oMY7lVDbXFgGIt3lQHB1aKh5LQZT/Q5/KzTKudl4CgrbiA6DZAt1JMDAoQwQZj93y16HRWZVkDS+eTv2poGK61a72eLqnnM4mbPqH0vzqUtCTD8Gkh4Ndg8= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=yyQrLZL/; arc=fail smtp.client-ip=40.93.198.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="yyQrLZL/" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=bhE104VYvXVfmUd+iKCFAI8YaZno+Gwhx/IKmfO/34nagwgzPTp0oMrmM4NsNSu4UdI/LZggbcRADUzH/UtwmZWDkY7Y/C7QBkrelBG6Y/JETICr/47QoeK9aFCY3jKm7mchu3Dr4R65HYFmOMRgZ21AYPgtCg0HTp/3FQWckRCgLqMl07X/41urg8c2XGYnQ+DV4/jLIt6RSWHf5QpmuqLMX1uCSOfHkLMdkWPraWfcqWGAxXNrakJqFmP7dAeOZfaVUk5GbqjglKUpR1iPYTlJN4nlM7NpFf8IM3GN6PE141t9INjz1xrA0ubsWan+K/+yBNjycy2aMcwUJWKQhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=e7YqW8RqVCsY7BihRJc5llFw0kBsE6hvfXegAWfrUg8=; b=fXkoW8nigcCw8QoX0wDc/+8qfRgpA4SrBn2w9TkQRwe/fFmHkggMZ8VlyiHBINg+6yVS66FxkzVWQHMQCKnpPQBJLJwrmRSMlUhB5sGuNZkaTjH6tJYrUaeNQb6g1L4tryumQTM4h/7uhmOWScbWiV8iVF85fCX9SbS/ohko2ZBiGXx6l+OLut8E9BB/WzIjhdxFZiYQJD6mm7A9DKvFlCrwf7q9qUuPLoLtDPsdFANvnYQ7VpmxD1kmjqJylOEm/oHql6QApdWt2p9hNY8OGHk3OBpr+x82ucbSas4wlxgatZFbTC7wpYCHT+EQwhd/fhPf+z0axbOFtEgF701lvA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=e7YqW8RqVCsY7BihRJc5llFw0kBsE6hvfXegAWfrUg8=; b=yyQrLZL/3nmFFtPvFftaHOpsrMqtWJLNtlsCC1bvI3vgU/rZcXhJpemilaYz39kxiMNM991uBVTPy78hUqRnvWlA/v3sMZCfDqlP17GDAIZA9JyfQbqWiETSL//aEKxWFDRI/YkifHKsAqiyli01iRN++bH32idHOaoIObxMU6w= Received: from SJ2P220CA0008.NAMP220.PROD.OUTLOOK.COM (2603:10b6:a03:5da::18) by SJ2PR12MB8883.namprd12.prod.outlook.com (2603:10b6:a03:538::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.24; Fri, 7 Aug 2026 10:45:19 +0000 Received: from SJ5PEPF000001EA.namprd05.prod.outlook.com (2603:10b6:a03:5da:cafe::8b) by SJ2P220CA0008.outlook.office365.com (2603:10b6:a03:5da::18) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.24 via Frontend Transport; Fri, 7 Aug 2026 10:45:19 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SJ5PEPF000001EA.mail.protection.outlook.com (10.167.242.198) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.6 via Frontend Transport; Fri, 7 Aug 2026 10:45:18 +0000 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:10 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:05 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 06/20] net: xilinx: tsn: add the endpoint RX data path Date: Fri, 7 Aug 2026 16:14:17 +0530 Message-ID: <20260807104431.157230-7-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001EA:EE_|SJ2PR12MB8883:EE_ X-MS-Office365-Filtering-Correlation-Id: 667d6715-d178-47a6-87b0-08def470f947 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700016|82310400026|23010399003|1800799024|376014|7416014|921020|3023799007|56012099006|11063799006|10067099003|18002099003|22082099003; X-Microsoft-Antispam-Message-Info: dS2Y1+NxCrXEYO7Ihl7pFRFe5De4FJ6qQMhOjXLVFE13Y8Um2Wy0LRn8XXKYVYXgHEhgQOpWD8JATWR7ONqGaSmNP9JFNcizBstiH083LzDnLgKCm3J97ApssPfVgV5sgJE6Fm3Y7JZhFrhThWDWO2Ncv1bCA2Z2+eHvK7zMJyZ9CeK8Yuds8y/5Ap5M2oxUyVWy8tS8oT5EGK/0z2Log490eOKVVNyMsHzi0CafG7zzRPdLHhukMJW79Ne6xquiXWhXWwpl2mvH/bNGeSLnRAQO5pIW4D1UDtzSY66JlxWlOIumNpHb+n/leO21ahijnRcWCIjZOvh6b78QjmrRJ7hZaDnrZPQSSZm7Zpw15bkxKhezlv4A0FqMkvTKAU4NCliAheI3cc2PTRNX9nxx+qHgyKFqOxw8i7b3tstUNf53Ad9y0feYQ35puJOhyEcDymXAn+zfeBIFfLPnRNQoIh7J+lAoHcBJ8EFwO35k3YbdBHsIBvJ82YtvrIEfLUuLqfwF5a1r7LMc4r19bS491wxrsNtV+2lRaLQZ/Px9637/Ic2mJ/2pht4027FxykIbRT2tvZrGu+DGlZDV23kWtBJeHj0JU9isNCvNSZoLrG6nLgHJcK9bENCzk8bpGhpRhWYSJlatd1ppgffy2mkGNHKM6cPQ+6YGUmpZ3oQnlMZDxUGxyXwH69+J0eZu+6k8i3M6AF4L0WpOIqqfsbn/Es2bHRkroFqSIU9qGv74bqpZwA+hlIl7eMP3+CoWz7gN X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700016)(82310400026)(23010399003)(1800799024)(376014)(7416014)(921020)(3023799007)(56012099006)(11063799006)(10067099003)(18002099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: axZDcNXi8S8Q5J1V0qBIwr/SOJDpHDw4yOYRYfzzHj5DzsEgmHZebDdTE92sUqtfgvgicVSLbK/v2yRFUAoCtnShMGnNnNLe3/6fNC0B5NMIgiubqOziaSURnFezsIDZyGKHe/nnyZrraPUmm20PhEOT8aLZWh/d9TzYzm7FwyH/RBtkVFanEeRSTEusFlgh5ZwaUVu0lRkxVHi3FtxA7PVnvCWqmUt3Gi/wy4kytd68xmO+S0Ydr2gqzEAt4GxctDOxCNbWwSjym51+aAaKJ48DkugG37+NzbqQ0PDlKrq8KsDLfcaB8rr503vw8hMKzyJj6l1nX+Hiif71tPPYeaCVkRdPfs96RdT/JcmQjafP5KEu40cEFDGhFIA4+2g2wryWvMBg2/S/j7mf/FhmFCR7mS42Lvd6ltq9hr/KHE8XhE3/soMPZZBwPTr/9+Iq X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:18.7813 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 667d6715-d178-47a6-87b0-08def470f947 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001EA.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ2PR12MB8883 Content-Type: text/plain; charset="utf-8" From: Srinivas Neeli With the RX channels armed, the endpoint can start receiving frames. Post RX buffers to every RX channel on open and reap them from the completion callback. Each inbound frame carries a TUSER port_id in the descriptor sideband. Accept frames from MAC1 (port_id 1) and MAC2 (port_id 2) and pass them up the stack. Drop any other port_id, since the bridged-only model never produces it. Drop and count frames with bad descriptor status, an invalid length or no metadata pointer. Refill each slot from the completion callback unless the interface is closing, which keeps the ring full without a separate refill worker. Delivery to the correct DSA user port needs the per-port metadata, which is not added yet. Signed-off-by: Srinivas Neeli Co-developed-by: Nagadheeraj Rottela Signed-off-by: Nagadheeraj Rottela --- .../net/ethernet/xilinx/tsn/xilinx_tsn_ep.c | 173 +++++++++++++++++- 1 file changed, 171 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c b/drivers/net/= ethernet/xilinx/tsn/xilinx_tsn_ep.c index fa21d59ade16..207ca3242a12 100644 --- a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c +++ b/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c @@ -5,6 +5,7 @@ * Copyright (C) 2026 Advanced Micro Devices, Inc. */ =20 +#include #include #include #include @@ -42,6 +43,17 @@ #define TX_BD_NUM_DEFAULT 64 #define RX_BD_NUM_DEFAULT 128 =20 +/* + * The DMA descriptor sideband status word packs TID/TDEST/TUSER together; + * TUSER occupies the low byte, TID/TDEST sit in the upper bits. + */ +#define TSN_TUSER_MASK GENMASK(7, 0) +/* TUSER Input Port ID field (bits [5:4] of the TUSER field) */ +#define TSN_TUSER_PORT_ID_MASK GENMASK(5, 4) +#define TSN_TUSER_PORT_EP 0x0 +#define TSN_TUSER_PORT_MAC1 0x1 +#define TSN_TUSER_PORT_MAC2 0x2 + /** * struct skbuf_dma_descriptor - skb container for each in-flight DMA desc= riptor * @sgl: scatter-gather list backing the DMA mapping @@ -115,6 +127,147 @@ ep_get_desc(struct xlnx_tsn_ep_dma_chan *xchan, int i= dx) return xchan->skb_ring[idx]; } =20 +static void ep_dma_rx_cb(void *data, const struct dmaengine_result *result= ); + +static void ep_rx_submit_desc(struct xlnx_tsn_ep_dma_chan *xchan) +{ + struct dma_async_tx_descriptor *dma_rx_desc; + struct skbuf_dma_descriptor *skbuf_dma; + struct xlnx_tsn_ep *ep =3D xchan->ep; + struct sk_buff *skb; + dma_addr_t addr; + + skbuf_dma =3D ep_get_desc(xchan, xchan->ring_head & (RX_BD_NUM_DEFAULT - = 1)); + if (!skbuf_dma) + return; + + skb =3D dev_alloc_skb(ep->max_frm_size); + if (!skb) + return; + + sg_init_table(skbuf_dma->sgl, 1); + addr =3D dma_map_single(xchan->dma_dev, skb->data, ep->max_frm_size, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(xchan->dma_dev, addr))) { + if (net_ratelimit()) + dev_warn(ep->dev, "DMA mapping error on RX submit\n"); + + goto err_free_skb; + } + sg_dma_address(skbuf_dma->sgl) =3D addr; + sg_dma_len(skbuf_dma->sgl) =3D ep->max_frm_size; + dma_rx_desc =3D dmaengine_prep_slave_sg(xchan->chan, skbuf_dma->sgl, + 1, DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT); + if (!dma_rx_desc) + goto err_unmap_skb; + + skbuf_dma->skb =3D skb; + skbuf_dma->dma_address =3D sg_dma_address(skbuf_dma->sgl); + skbuf_dma->desc =3D dma_rx_desc; + dma_rx_desc->callback_param =3D xchan; + dma_rx_desc->callback_result =3D ep_dma_rx_cb; + xchan->ring_head++; + dmaengine_submit(dma_rx_desc); + + return; + +err_unmap_skb: + dma_unmap_single(xchan->dma_dev, addr, ep->max_frm_size, DMA_FROM_DEVICE); +err_free_skb: + dev_kfree_skb(skb); +} + +static void ep_dma_rx_cb(void *data, const struct dmaengine_result *result) +{ + struct xlnx_tsn_ep_dma_chan *xchan =3D data; + struct skbuf_dma_descriptor *skbuf_dma; + size_t meta_len, meta_max_len, rx_len; + struct xlnx_tsn_ep *ep =3D xchan->ep; + struct net_device *ndev =3D ep->ndev; + struct sk_buff *skb; + u32 port_id, tuser; + u32 *metadata; + int i, avail; + + skbuf_dma =3D ep_get_desc(xchan, xchan->ring_tail & (RX_BD_NUM_DEFAULT - = 1)); + xchan->ring_tail++; + skb =3D skbuf_dma->skb; + skbuf_dma->skb =3D NULL; + + dma_unmap_single(xchan->dma_dev, skbuf_dma->dma_address, + ep->max_frm_size, DMA_FROM_DEVICE); + + if (result->result !=3D DMA_TRANS_NOERROR) { + if (net_ratelimit()) + dev_warn(ep->dev, "RX DMA transfer error %d\n", + result->result); + + dev_kfree_skb_any(skb); + DEV_STATS_INC(ndev, rx_dropped); + DEV_STATS_INC(ndev, rx_errors); + goto submit_new; + } + + metadata =3D dmaengine_desc_get_metadata_ptr(skbuf_dma->desc, + &meta_len, + &meta_max_len); + if (IS_ERR_OR_NULL(metadata)) { + if (net_ratelimit()) + dev_warn(ep->dev, "Failed to get RX metadata pointer\n"); + + dev_kfree_skb_any(skb); + DEV_STATS_INC(ndev, rx_dropped); + DEV_STATS_INC(ndev, rx_errors); + goto submit_new; + } + + /* MCDMA metadata: [0] =3D status, [1] =3D sideband (TID/TDEST/TUSER), [2= ..] =3D app */ + tuser =3D metadata[1] & TSN_TUSER_MASK; + rx_len =3D ep->max_frm_size - result->residue; + + if (rx_len > ep->max_frm_size || rx_len < ETH_HLEN) { + if (net_ratelimit()) + dev_warn(ep->dev, "Invalid RX length %zu (max=3D%u, min=3D%u)\n", + rx_len, ep->max_frm_size, ETH_HLEN); + + dev_kfree_skb_any(skb); + DEV_STATS_INC(ndev, rx_dropped); + DEV_STATS_INC(ndev, rx_errors); + goto submit_new; + } + + port_id =3D FIELD_GET(TSN_TUSER_PORT_ID_MASK, tuser); + if (port_id !=3D TSN_TUSER_PORT_MAC1 && port_id !=3D TSN_TUSER_PORT_MAC2)= { + if (net_ratelimit()) + dev_dbg(ep->dev, "RX dropping unexpected TUSER port_id=3D%u\n", + port_id); + + dev_kfree_skb_any(skb); + DEV_STATS_INC(ndev, rx_dropped); + goto submit_new; + } + + skb_put(skb, rx_len); + skb->dev =3D ndev; + skb->protocol =3D eth_type_trans(skb, ndev); + skb->ip_summed =3D CHECKSUM_NONE; + __netif_rx(skb); + + DEV_STATS_INC(ndev, rx_packets); + DEV_STATS_ADD(ndev, rx_bytes, rx_len); + +submit_new: + if (READ_ONCE(ep->closing)) + return; + + avail =3D CIRC_SPACE(xchan->ring_head, xchan->ring_tail, + RX_BD_NUM_DEFAULT); + for (i =3D 0; i < avail; i++) + ep_rx_submit_desc(xchan); + dma_async_issue_pending(xchan->chan); +} + static netdev_tx_t ep_start_xmit(struct sk_buff *skb, struct net_device *n= dev) { dev_kfree_skb(skb); @@ -229,8 +382,18 @@ static void ep_free_dma_chan(struct xlnx_tsn_ep_dma_ch= an *chan) if (!chan) return; =20 - if (chan->chan) + if (chan->chan) { + /* Drain the in-flight completion callback, then synchronize in + * case that callback re-armed a descriptor before it observed + * ep->closing. xilinx_dma_tx_submit() clears chan->terminating + * on every submit, so a single terminate does not cover a + * re-arm. The final terminate is a barrier before the channel + * memory is freed. + */ dmaengine_terminate_sync(chan->chan); + dmaengine_synchronize(chan->chan); + dmaengine_terminate_sync(chan->chan); + } =20 if (chan->is_tx) { while (chan->ring_tail !=3D chan->ring_head) { @@ -291,7 +454,7 @@ static int ep_init_dmaengine(struct xlnx_tsn_ep *ep) { int tx_allocated =3D 0, rx_allocated =3D 0; char name[16]; - int i, ret; + int i, j, ret; =20 ep->tx_chans =3D kcalloc(ep->num_tx_queues, sizeof(*ep->tx_chans), GFP_KERNEL); @@ -329,6 +492,12 @@ static int ep_init_dmaengine(struct xlnx_tsn_ep *ep) rx_allocated++; } =20 + for (i =3D 0; i < ep->num_rx_queues; i++) { + for (j =3D 0; j < RX_BD_NUM_DEFAULT - 1; j++) + ep_rx_submit_desc(ep->rx_chans[i]); + dma_async_issue_pending(ep->rx_chans[i]->chan); + } + return 0; =20 err_free_chans: --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from CY7PR03CU001.outbound.protection.outlook.com (mail-westcentralusazon11010057.outbound.protection.outlook.com [40.93.198.57]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1354E3F8254; Fri, 7 Aug 2026 10:45:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.198.57 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099530; cv=fail; b=ScXXTNfh2IT2PKlJ/zw+7DW8Pdm6q+63xffyiUmPvSCcIOJbRZpqRv9r5uJdHnUEa33wN4TXYH3hQJqFgfsfqCqrP1v8dADEc51qKPAmJVyAr17W1Lg3KvJ1ks2IKtP850KItj0EFesRyLSUGx/gQgS1BGyGUgeeeY6FajxR/3c= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099530; c=relaxed/simple; bh=UiU3tFN537uyleTd7V5ZiBeSOVkhT5DiXveu+PLTDy8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SBZwp7GLsW9UlkZctDfLSTXx1rfkazKtvtRmZ2fC7uf4SHFPmDZSNt7Ps9bN2Ud9Gi7rm50PiZZaRkUbsNlTdC2SlbUNRMbfoqdf63reBh1RTi+gkWU1oExj60jmc6JQ+xGFHw7FzmG6aUh305Q6X/i8sAIJihiQJLao8SwC6ZU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=Lj6e8cu9; arc=fail smtp.client-ip=40.93.198.57 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="Lj6e8cu9" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=pXj8dFMG/cj/ugm7nsCo8upZY9BV6UjDV92IcvFwSfO1Il7yql0nc+HPI00tvFag3k3cd2NkBepe5GoWFfFrF58ZvWqOgTmdoIos00QolBK8+JNWOEAqS0AbrViadPelGd6IEKpkflUyqsedpMD48mTBDL2A3dz/mfCbdUZwiol/cj8z6yUdYsKbvTdXwMDpkVhHZdASMU8cVNuRIBPJcBGr9TqTrJ+aSIJPoWxt4ypUukNIl5HgDNXqILQTFGXbDas93VrAeCbzrnb9zjlBRKpJRyEzJK4ZwLPwpabzFLBnJ2wIY2AVhJzzasyg0CGq+fYhne96oyUE9wIEyCNI8g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=BWSMB89lny2+NMlqwqsh9DqJnKEzeM3Z8dwn3yQxYrY=; b=EeujGCZ4oC0dIt4wxyWdILEL93HLkLF7dWjH1HPJvG9M0U0A+gqf3x0QMH+s6o0jmDPbB/zjW+0YsSRZ/QY9sH6peBmTmPG2/rGgJaV1F1V6hR48rL2SturpbgkpG0MlknbUtRAUV7irW9gaG4LC32qdXNA6eYTcxOZS1kGUla0y+xOM1Ccph2KF9XHnAUxZ/vy0tKbQXZx13nGgWVhwQGKyREr/W3oZnxxGSaGlYG3NGPa2TvIxi/SAx7X/bQV6GH93OTaNit3huPihRLikiUaDDMr7tSZN1QYmMXkeXZAds+HzDgSyuTU2siodNWMC1g+OECQMm/Ub3LyQOv9C9g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=BWSMB89lny2+NMlqwqsh9DqJnKEzeM3Z8dwn3yQxYrY=; b=Lj6e8cu9/x51FmLNq5g7AHshz0uB8UC3jn+feD940cfTC1jUsXqIEWge3btJ8d0fXnasWSaHXMwIOg/dmFG4cuPa/H1IcCrVJ0/BIjYvFYjqZl1nJ4QiWa9F3aooHG3oTbtu/JOeBZ+vA1dB+mRm5dqkgdORxTjBlqeR3NqU17s= Received: from SJ2PR07CA0012.namprd07.prod.outlook.com (2603:10b6:a03:505::13) by CYYPR12MB8871.namprd12.prod.outlook.com (2603:10b6:930:c2::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.16; Fri, 7 Aug 2026 10:45:23 +0000 Received: from SJ5PEPF000001EE.namprd05.prod.outlook.com (2603:10b6:a03:505:cafe::8f) by SJ2PR07CA0012.outlook.office365.com (2603:10b6:a03:505::13) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.24 via Frontend Transport; Fri, 7 Aug 2026 10:45:23 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SJ5PEPF000001EE.mail.protection.outlook.com (10.167.242.202) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.6 via Frontend Transport; Fri, 7 Aug 2026 10:45:22 +0000 Received: from satlexmb10.amd.com (10.181.42.219) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:17 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb10.amd.com (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:16 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:11 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 07/20] net: xilinx: tsn: add the endpoint TX data path Date: Fri, 7 Aug 2026 16:14:18 +0530 Message-ID: <20260807104431.157230-8-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001EE:EE_|CYYPR12MB8871:EE_ X-MS-Office365-Filtering-Correlation-Id: f61ba497-c98e-4b64-b72b-08def470fbc3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700016|7416014|376014|23010399003|82310400026|1800799024|921020|10067099003|56012099006|11063799006|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: V12IWZ2zOKKkFhXNrionyfKbS2++D2Akge5PDRnan0vxzUcoQvXunswNNnrzF6XqnXUMPzXu6stPooCVgZs8jI6SQF0A42W30mxUkrmXG8C30m5EAQ+zqcbrZph4uRIaZt6dSy2+h5jJ+qyLtndAX8IM6FvtHQQy8fPimrii63FyFnAhYQ8IUNCe8QwDvHfP4tzozHyMGuK7IckZsQJzFQhHLa9ANzwB61QpUv+TuzSZ5jvsPXpVw1uaH6d/9a7c+DYajxHXJ91nt8QEwJncALvMVhVDRFytCnjopmsBOTRhwiphP7s6IvgyiNkFDxF27LMT0yjzMWbJrdRViMnv5u/ktgmVO5XLU9vTVOqnun+wq5faaDuhRkWWoGhb5Agsk2DyT3EPENo5FxyL95h1UWz/XcEaIGEE1xKFUeKOLyWWsucZSWVreS1DOp4vE8Knuz7r/Tp/q39eTei5pBG+geo0tQt2/wv9GK+yjs78Y+LMVjBKKAeajEVwlnZTX7BN6PyOMR6lJPnx73Ts3kGsmWNVKoCEpPlSbUZJrWQDHCNgOMoWoRw2RCfjYQbJbc3UMXIIQls9+P7JpltgA+o5xvQ5NLY1siU0EWDgdO0g/YRFEvjqgEBxkkLqj5yA1ZJLJnWgp4gn7tF481LsP2DY0MmZG6ta8OEY09iDvuwXW5x8wxiqXQIPSw59S/GHX6eVEvSQzIEvWaqSoCMJqmdGYasBnqt5y0aiM7+kq8CFnNm1x+BkM643djszGDueTw+e X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700016)(7416014)(376014)(23010399003)(82310400026)(1800799024)(921020)(10067099003)(56012099006)(11063799006)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 8tFq4JfGYmQUSHCDe4UywnEtxTfNnYu8gVuXJYTL+y4q4P0uRgQvsfyStzAsg85hdpP9AzEGjVSxPfZx0pyUSyk13rZnPVfx2dzV2HZ/kOp34jr6FxYjsVb1jjoKepCE2rsDXyHp0wYPVfZCS0NZm/kzuuUFnESRDe/yHwWsc62zfIomy6Sk1zJAW/3yDjmlnZdwlHGUmlY+uhEa2FFFF4P8DNPvPvZ5dQncEUs/L772PWdNVur7PINthJOJRyW6rSpz2UpEu36QNyB7u3PDkRjK1cyZt+SxgTTzmGyrR+qDCHJCB38ErlZR2XKVklPBQch0/DzAOjRF9BAYCcUMsR/LL5lrUFYwFm4nH6L7lPVOmGQXzZ/su4hQX/S6+1SQmlBEePelvYTovyR34hpWwzNI3ZTlANWB4PTJkUIK9cJfINlRVYTtli9fp4elrXS+ X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:22.9617 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f61ba497-c98e-4b64-b72b-08def470fbc3 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001EE.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CYYPR12MB8871 Content-Type: text/plain; charset="utf-8" From: Srinivas Neeli Add the transmit path so the endpoint can send frames. Look up the physical DMA channel for the frame's queue through the map built at probe, map the frame and submit it to that channel. Stop the queue when the ring runs out of space, and wake it from the completion callback once a slot frees up. Signed-off-by: Srinivas Neeli Co-developed-by: Nagadheeraj Rottela Signed-off-by: Nagadheeraj Rottela --- .../net/ethernet/xilinx/tsn/xilinx_tsn_ep.c | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c b/drivers/net/= ethernet/xilinx/tsn/xilinx_tsn_ep.c index 207ca3242a12..7615d27f3b36 100644 --- a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c +++ b/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c @@ -29,6 +29,8 @@ #include #include =20 +#include + #include "xilinx_tsn.h" =20 #define DRIVER_NAME "xilinx_tsn_ep" @@ -97,6 +99,7 @@ struct xlnx_tsn_ep_dma_chan { * @ndev: the conduit netdev ("ep") * @dev: backing device * @regs: EP MAC register window + * @tx_lock: protects TX ring head/tail and SKB ring slots * @num_tx_queues: number of TX DMA channels (one per priority) * @num_rx_queues: number of RX DMA channels * @tx_dma_chan_map: logical TX queue index -> physical DMA channel number @@ -110,6 +113,8 @@ struct xlnx_tsn_ep { struct device *dev; void __iomem *regs; =20 + spinlock_t tx_lock; /* protects TX ring buffers */ + u32 num_tx_queues; u32 num_rx_queues; u32 tx_dma_chan_map[TSN_MAX_TX_QUEUE]; @@ -268,8 +273,145 @@ static void ep_dma_rx_cb(void *data, const struct dma= engine_result *result) dma_async_issue_pending(xchan->chan); } =20 +static void ep_dma_tx_cb(void *data, const struct dmaengine_result *result) +{ + struct xlnx_tsn_ep_dma_chan *xchan =3D data; + struct skbuf_dma_descriptor *skbuf_dma; + struct xlnx_tsn_ep *ep =3D xchan->ep; + struct netdev_queue *txq; + struct net_device *ndev; + struct scatterlist *sgl; + struct sk_buff *skb; + int sg_len; + int len; + + scoped_guard(spinlock, &ep->tx_lock) { + skbuf_dma =3D ep_get_desc(xchan, + xchan->ring_tail & (TX_BD_NUM_DEFAULT - 1)); + if (!skbuf_dma || !skbuf_dma->skb) + return; + + skb =3D skbuf_dma->skb; + sgl =3D skbuf_dma->sgl; + sg_len =3D skbuf_dma->sg_len; + + dma_unmap_sg(xchan->dma_dev, sgl, sg_len, DMA_TO_DEVICE); + + skbuf_dma->skb =3D NULL; + xchan->ring_tail++; + } + + ndev =3D skb->dev; + txq =3D netdev_get_tx_queue(ndev, skb_get_queue_mapping(skb)); + len =3D skb->len; + + if (unlikely(result->result !=3D DMA_TRANS_NOERROR)) { + DEV_STATS_INC(ndev, tx_errors); + } else { + DEV_STATS_INC(ndev, tx_packets); + DEV_STATS_ADD(ndev, tx_bytes, len); + } + + dev_consume_skb_any(skb); + netif_txq_completed_wake(txq, 1, len, + CIRC_SPACE(READ_ONCE(xchan->ring_head), + READ_ONCE(xchan->ring_tail), + TX_BD_NUM_DEFAULT), 2); +} + static netdev_tx_t ep_start_xmit(struct sk_buff *skb, struct net_device *n= dev) { + struct dma_async_tx_descriptor *dma_tx_desc; + struct xlnx_tsn_ep *ep =3D netdev_priv(ndev); + struct skbuf_dma_descriptor *skbuf_dma; + int queue =3D skb_get_queue_mapping(skb); + struct xlnx_tsn_ep_dma_chan *xchan; + struct dma_device *dma_dev; + struct netdev_queue *txq; + int sg_len, nents, ret; + u32 phys_chan; + + if (unlikely(queue >=3D ep->num_tx_queues)) { + if (net_ratelimit()) + netdev_warn(ndev, "Invalid TX queue %d (max %u)\n", + queue, ep->num_tx_queues); + goto err_drop_skb; + } + + phys_chan =3D ep->tx_dma_chan_map[queue]; + if (phys_chan =3D=3D TSN_DMA_CH_INVALID) { + if (net_ratelimit()) + netdev_warn(ndev, "Logical TX queue %d has invalid DMA mapping\n", + queue); + goto err_drop_skb; + } + + xchan =3D ep->tx_chans[phys_chan]; + dma_dev =3D xchan->chan->device; + + sg_len =3D skb_shinfo(skb)->nr_frags + 1; + txq =3D netdev_get_tx_queue(ndev, queue); + + spin_lock_bh(&ep->tx_lock); + if (CIRC_SPACE(xchan->ring_head, READ_ONCE(xchan->ring_tail), + TX_BD_NUM_DEFAULT) <=3D 1) { + netif_txq_try_stop(txq, + CIRC_SPACE(xchan->ring_head, + READ_ONCE(xchan->ring_tail), + TX_BD_NUM_DEFAULT), + 2); + spin_unlock_bh(&ep->tx_lock); + if (net_ratelimit()) + netdev_warn(ndev, "TSN TX ring full\n"); + + return NETDEV_TX_BUSY; + } + + skbuf_dma =3D ep_get_desc(xchan, xchan->ring_head & (TX_BD_NUM_DEFAULT - = 1)); + if (!skbuf_dma) { + spin_unlock_bh(&ep->tx_lock); + goto err_drop_skb; + } + spin_unlock_bh(&ep->tx_lock); + + sg_init_table(skbuf_dma->sgl, sg_len); + ret =3D skb_to_sgvec(skb, skbuf_dma->sgl, 0, skb->len); + if (ret < 0) + goto err_drop_skb; + + nents =3D dma_map_sg(xchan->dma_dev, skbuf_dma->sgl, sg_len, DMA_TO_DEVIC= E); + if (!nents) + goto err_drop_skb; + + dma_tx_desc =3D dma_dev->device_prep_slave_sg(xchan->chan, skbuf_dma->sgl, + nents, DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT, NULL); + if (!dma_tx_desc) + goto err_unmap_sg; + + skbuf_dma->skb =3D skb; + skbuf_dma->sg_len =3D sg_len; + dma_tx_desc->callback_param =3D xchan; + dma_tx_desc->callback_result =3D ep_dma_tx_cb; + + spin_lock_bh(&ep->tx_lock); + xchan->ring_head++; + netdev_tx_sent_queue(txq, skb->len); + netif_txq_maybe_stop(txq, + CIRC_SPACE(xchan->ring_head, + READ_ONCE(xchan->ring_tail), + TX_BD_NUM_DEFAULT), + 2, 2); + spin_unlock_bh(&ep->tx_lock); + + dmaengine_submit(dma_tx_desc); + dma_async_issue_pending(xchan->chan); + + return NETDEV_TX_OK; + +err_unmap_sg: + dma_unmap_sg(xchan->dma_dev, skbuf_dma->sgl, sg_len, DMA_TO_DEVICE); +err_drop_skb: dev_kfree_skb(skb); DEV_STATS_INC(ndev, tx_dropped); return NETDEV_TX_OK; @@ -304,10 +446,13 @@ static int ep_open(struct net_device *ndev) static int ep_stop(struct net_device *ndev) { struct xlnx_tsn_ep *ep =3D netdev_priv(ndev); + unsigned int i; =20 netif_tx_disable(ndev); WRITE_ONCE(ep->closing, true); ep_exit_dmaengine(ep); + for (i =3D 0; i < ndev->num_tx_queues; i++) + netdev_tx_reset_subqueue(ndev, i); =20 return 0; } @@ -657,6 +802,7 @@ static int xlnx_tsn_ep_probe(struct platform_device *pd= ev) ep->num_tx_queues =3D num_tx; ep->num_rx_queues =3D num_rx; ep->max_frm_size =3D TSN_MAX_VLAN_FRAME_SIZE; + spin_lock_init(&ep->tx_lock); =20 for (i =3D 0; i < TSN_MAX_TX_QUEUE; i++) ep->tx_dma_chan_map[i] =3D TSN_DMA_CH_INVALID; --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from BL2PR02CU003.outbound.protection.outlook.com (mail-eastusazon11011028.outbound.protection.outlook.com [52.101.52.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA1DA3F8254; Fri, 7 Aug 2026 10:45:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.52.28 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099537; cv=fail; b=mC6Vp/cf0ui/+jBEVovFAMRkWZtFE/1ZvSNlvEE1vOtxU0VuQWX0iJvnvCpFveGo4g8Q1qyPdvqKqAi9xEoWXRPnbyGK28Cr/5XM3+lX1HUf7hozxHA5eXNtGo6+ng3keznAMr/cu1bJl6O4hGVSVv2JXw1ONZUcFeMb2ubfLqU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099537; c=relaxed/simple; bh=x9GMH2d8vJvuK+0C5VD1zQLhb2kfYFbXBqfEsb1lQJw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XfQ+Vk86B7kcRHXerMXr7Xacy6DnlG98g8In28k0AdCFWWZKK6utCm348ATz1hKXWpepGeKR7mjAj++iupNXP27HCnIr1KGu9/MamywUxxQq+mxL3LSFTeHclnlvHymOR/q4sssPTdXedvc0Fq5zbQMi9amNC/L1r97w50A6Qdk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=ncgWw7jD; arc=fail smtp.client-ip=52.101.52.28 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="ncgWw7jD" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=xYu4lF+ndBbTDZOFFsSEKRlJyut+J0DApJjMNHmMIHKH4hHjxyY9yN1Zfw9f+QtqhLzsb91NN8+8zOXNxm0Zx8MEtWfEj81w5Fa9SJNon5AhTx2ztU5mY1UNVEHgNS77CkBpVizZCEWacvr7DWo3wys3Lhm/MqZuPJbHjSQaFlbU6h9fNSMf1eYkZ6jLqa7QIy/a9JNU/BAiFXS8dbsPfOQupQxuE37bKAfuveUJahGK1HuZ+oeDCeTNI26GFd3NhGaroM9tqNPgtzcK5JUGuyM5w25WCmj/L8O6AgKOASSjtUtGfAtK9DMjJ+vdLpiXyKIQmnLRDdvmZD48wtqokw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=n0onyrmUWbRTSXOvvNu2iNNwP6EWh035g0IcBtOo5LY=; b=ITZySOV7+rg/YFhhg14IbHFSWzrh7Q+rU10196FX3n+H927AdCEI3p/zbbnr/irAadbzS6nny8Av5Fq8LHpgu8YUz7j23QrqR5PYfYSxY35q6K+7GNR+ugB4GHjkiBmcu22mGITZX4t35C0Lshl8NpbM9vOR3f0ChtDs9dLZIb07KGNrP7AipPjIWkN2a3wQXl7UMDrQku4+GvBS2uqjAWZe+LRXXbtpmS7p6jRg5YrdICr1mri5R/cXqOM6IVpteAE7/fPs3pwlBjvoI5axVo5HRKsO8Fah8NIBWX//bQOSHpoltJS1T/UDmjBmn8YJev+LnS5GnqAhe+7qQvMG1g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=n0onyrmUWbRTSXOvvNu2iNNwP6EWh035g0IcBtOo5LY=; b=ncgWw7jD7ESTaRe5CayKjY9z50bH1VWG/lF/9F5Br8FA8B/ovGdSeKVZrwrqIwZWTbwiRx+IOp2k8kP/PvAJB3mm1GxCobjT/NUya/kf29pawj9dZ6Vl2Fv1bBeBrTgL5noQzqp9n3pzS7OLDhFp/xO0d/F8qYlVXiczBBkp4mo= Received: from SJ2PR07CA0019.namprd07.prod.outlook.com (2603:10b6:a03:505::21) by CH1PR12MB9624.namprd12.prod.outlook.com (2603:10b6:610:2b3::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.24; Fri, 7 Aug 2026 10:45:27 +0000 Received: from SJ5PEPF000001EE.namprd05.prod.outlook.com (2603:10b6:a03:505:cafe::23) by SJ2PR07CA0019.outlook.office365.com (2603:10b6:a03:505::21) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.23 via Frontend Transport; Fri, 7 Aug 2026 10:45:27 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SJ5PEPF000001EE.mail.protection.outlook.com (10.167.242.202) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.6 via Frontend Transport; Fri, 7 Aug 2026 10:45:27 +0000 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:21 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:16 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 08/20] net: xilinx: tsn: deliver endpoint RX frames to DSA user ports Date: Fri, 7 Aug 2026 16:14:19 +0530 Message-ID: <20260807104431.157230-9-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001EE:EE_|CH1PR12MB9624:EE_ X-MS-Office365-Filtering-Correlation-Id: dd619b0c-e256-4043-8aae-08def470fe4c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|82310400026|7416014|376014|23010399003|36860700016|18002099003|22082099003|11063799006|56012099006|3023799007|10067099003|921020; X-Microsoft-Antispam-Message-Info: NFHBXVje98Bx+GP0PCuN/zP193E2lE71FHlermhfXty7Zp8+P+T+iRPdHVTtgVSclELJ28wDRK2TGQCeBlFEy6DlTWg7D46jNgi8pFxnL5ZISRCA3PFn8LMpfXvGhECMCp41qpibH4xnSmNpLIAQQ8XvVSf1lJt3PmfofwSEloSWLGYcvEEN8HBn3sJxGsj7b7G/tJHdUhY/Q8RZmNiTOAw+1T5SwSHhYgHTsyiEfuqDD6hbWaK0WZ8HnuWUA1afBMYtpp1gLNdj1GAJleaJMX++mj2pk1wzVISm/ZoniGqvFoK3+EFGjZ8egZVBxAzI3OzMX1upVI6LJGh530Rpnyb2ONOiMxI1fbzErShRrkt7IAn4daf4r4X+iWrNTQ3W0/Y1J/ZoWI4p9CTNm8PlhSt/CYbuI2gejbFDfOAi+CkrCXFHuEZRcJmeAeedIU9xs9Ybai1SoPiqpTDFlu3Zoe2Hllseb3ZRfJ/naW8QIcMNKiap4J3oAtRj2d4XImgQtcPlkVyGXOMmC5bEN4TLyuVWcuUwdUgjmUiJpagciRUaz4FU7Y9SKiJVUlvoOXlNxfx8Eozm0RmjrGM996xTYXDpRuabLPtKCUNTV55U9R+GqXv8mD1TE42tNDhMzpdyzLSnf6m/p9OnItxOYh87O8C96n3SCQE7/rErav7Zi4tmQcyd3VS373jd9qImhDUk4zZsQ4BQIanvq+GB+A2frOOHLD/E5yycp7lZh70sEtGezHKLlRH4S80s0xW6Vy2c X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(82310400026)(7416014)(376014)(23010399003)(36860700016)(18002099003)(22082099003)(11063799006)(56012099006)(3023799007)(10067099003)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: w74rfV5/q7XbSrb0+4YaT7tB97vMwCmTgq+NJKwx/QndpFZA7XfRaPn/RV694mYg59HIA9boJ5ksO+6PRe9u61WtYr/JHWfoxG9jzyNLbvagqPDQYG8ZsnlGLO7SwtDF+0kt4jKBMKwsMK+8ZfoAQb4UD6ehpqwW2qV85rdm+177gVcwgEbI8uhRRxUfaR1LjBmkYYdJmNisCp7qMr1en/720+hlWls2CFI2aO/4RyJXTefIb6pPffXpcYcWlJXnpD6M/apmMlQAQdjmn1YImqxA9qinsFK0d6Fj5Bq4gVJTsV7DOx6d9uRR2KcHznE+r10kPwrO/JI6Qf8ASRbGApB4Ixdhu9ba9gvBJ2e7a+VHnNDqJk2yZkjJUplFwvPwKd0tCnT4YoCUCXjfew9GUQn6Cm4ef/4+YFMo7DSrNKOCLSC+V6MoCB8PlzqYUQ5h X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:27.1853 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: dd619b0c-e256-4043-8aae-08def470fe4c X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001EE.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH1PR12MB9624 Content-Type: text/plain; charset="utf-8" The DSA core routes an RX frame to a user port from the port metadata attached to the skb. Without that metadata, frames from the two MACs cannot reach their swpN netdevs. Allocate a METADATA_HW_PORT_MUX entry per MAC port at probe and attach the matching entry to each RX frame by its TUSER port_id. Frames from MAC1 and MAC2 now reach the correct user netdev, which completes the conduit data path. Signed-off-by: Nagadheeraj Rottela --- .../net/ethernet/xilinx/tsn/xilinx_tsn_ep.c | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c b/drivers/net/= ethernet/xilinx/tsn/xilinx_tsn_ep.c index 7615d27f3b36..051285b47ddb 100644 --- a/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c +++ b/drivers/net/ethernet/xilinx/tsn/xilinx_tsn_ep.c @@ -29,6 +29,7 @@ #include #include =20 +#include #include =20 #include "xilinx_tsn.h" @@ -56,6 +57,9 @@ #define TSN_TUSER_PORT_MAC1 0x1 #define TSN_TUSER_PORT_MAC2 0x2 =20 +/* Sized to index port_md[] by TUSER port_id (1 or 2, slot 0 unused) */ +#define XLNX_TSN_EP_PORT_MD_SLOTS (TSN_TUSER_PORT_MAC2 + 1) + /** * struct skbuf_dma_descriptor - skb container for each in-flight DMA desc= riptor * @sgl: scatter-gather list backing the DMA mapping @@ -107,6 +111,8 @@ struct xlnx_tsn_ep_dma_chan { * @tx_chans: array of TX channels (size @num_tx_queues) * @rx_chans: array of RX channels (size @num_rx_queues) * @closing: set in ndo_stop so the RX completion callback stops re-arming + * @port_md: per-TUSER-port METADATA_HW_PORT_MUX entries attached on RX, + * indexed by port_id (1 for MAC1, 2 for MAC2) */ struct xlnx_tsn_ep { struct net_device *ndev; @@ -124,6 +130,8 @@ struct xlnx_tsn_ep { struct xlnx_tsn_ep_dma_chan **rx_chans; =20 bool closing; + + struct metadata_dst *port_md[XLNX_TSN_EP_PORT_MD_SLOTS]; }; =20 static inline struct skbuf_dma_descriptor * @@ -254,6 +262,7 @@ static void ep_dma_rx_cb(void *data, const struct dmaen= gine_result *result) } =20 skb_put(skb, rx_len); + skb_dst_set_noref(skb, &ep->port_md[port_id]->dst); skb->dev =3D ndev; skb->protocol =3D eth_type_trans(skb, ndev); skb->ip_summed =3D CHECKSUM_NONE; @@ -771,6 +780,37 @@ static int ep_count_dma_queues(struct device *dev, u32= *out_tx, u32 *out_rx) return 0; } =20 +static void ep_free_port_md(struct xlnx_tsn_ep *ep) +{ + int i; + + for (i =3D 0; i < XLNX_TSN_EP_PORT_MD_SLOTS; i++) { + if (ep->port_md[i]) { + metadata_dst_free(ep->port_md[i]); + ep->port_md[i] =3D NULL; + } + } +} + +static int ep_alloc_port_md(struct xlnx_tsn_ep *ep) +{ + int i; + + for (i =3D TSN_TUSER_PORT_MAC1; i <=3D TSN_TUSER_PORT_MAC2; i++) { + struct metadata_dst *md; + + md =3D metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL); + if (!md) { + ep_free_port_md(ep); + return -ENOMEM; + } + md->u.port_info.port_id =3D i; + ep->port_md[i] =3D md; + } + + return 0; +} + static int xlnx_tsn_ep_probe(struct platform_device *pdev) { struct device *dev =3D &pdev->dev; @@ -835,16 +875,24 @@ static int xlnx_tsn_ep_probe(struct platform_device *= pdev) ndev->dev_addr); } =20 + ret =3D ep_alloc_port_md(ep); + if (ret) { + dev_err_probe(dev, ret, "failed to allocate per-port metadata\n"); + goto err_free_ndev; + } + platform_set_drvdata(pdev, ep); =20 ret =3D register_netdev(ndev); if (ret) { dev_err_probe(dev, ret, "failed to register net device\n"); - goto err_free_ndev; + goto err_free_md; } =20 return 0; =20 +err_free_md: + ep_free_port_md(ep); err_free_ndev: free_netdev(ndev); return ret; @@ -858,6 +906,7 @@ static void xlnx_tsn_ep_remove(struct platform_device *= pdev) return; =20 unregister_netdev(ep->ndev); + ep_free_port_md(ep); free_netdev(ep->ndev); } =20 --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from SA9PR02CU001.outbound.protection.outlook.com (mail-southcentralusazon11013025.outbound.protection.outlook.com [40.93.196.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7FBE42FCC2; Fri, 7 Aug 2026 10:45:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.196.25 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099542; cv=fail; b=PII4qSlhCKlwfpD8JY2t42nr5dTpvnCo7PYTFGuytFpImZiJ0LK24McUI4EHAJwBvSgaH2m+3nmEO3mjVwiZxdbs7r/h55g9Y3Go4IQCzhO+El2OP/mmS618PCnxNFpA9S52sCtqvVjMgclnpOYvXIYygU8oUsOMv4H40xxmT6E= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099542; c=relaxed/simple; bh=xiOdPf+JmIIavDsBUHotwIfRTJkYLABoRX9gBHFlf70=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NmIxoegir34muzWCVT+okJJxJ/oj3Wy5kicBtAVGlIQg0Qiv0vbkVAVerAYrRn0OoUOFuuDFbQUzZFLUI2kazXoW/BsOAHXbXMdXOPRkUj8/KYc6MV2XIPf9DtsZY5wiGD6RrrAIcIj+CYPwgEVJOu8Ll/SwY90VLg3jB3jEqrM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=OqWED1Cq; arc=fail smtp.client-ip=40.93.196.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="OqWED1Cq" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=NCYqem8rBI2QZjGuHSFfWxTUFIw5WpOmTlZo5YkKh3ZNMCqExEWPw3wdHqtqz78kt3GUhp30cLyw/FaWh9I3DXtxTEqapE84s5GFcxRQmCcpi8j8f4U2zinUz4ioIIzB0cZLmAKCoavH1HAFKgbyGea1vOjKx7Qc75cicft831fYfHoSYbnZIE1iSTNQSImAdEdFzRV811oHipu79m1d3M3mBSHm7nMxkPyLczjZYkEMFhYORhl1pZ0g9g2rzqfI2pp7+ebX3F3OrsmX3fGdDmm9aECHHpFp0QuVTnLDhfqzCgM5mp8cKx5Ch0L2uVvSDd1RTTK/ojHtFK9zfUT23A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=FJPoxpUO28vkt+Xzt2+HLrMEFtqmCbP0XZfa4v90xPo=; b=tF06/hFbY+efs6hbCHes7DiGbvjOF/vV9/tUIDWLUBp5RX17nkFTEy69CMwPIB1kUEGZm75dVR53hVbTGvlqCUeHebHiBR0Wqw4vSKet4ikq5w2ht+Of5iuNZ2r33xX56KzWbfovfWcsD0cS+4ZryNy6HhcY9glMPZ93bTyxYvAyf4oIaclObSJciud6nB8DDWs2JG5mOYy+rCL4/0MqJNTscqjPZ73QWmfCUaxdpMS1inJXyru7XATZY7lZYGdyF/LPLMlM/92YUTIjplXwSfXXZwgYLOyuN52LptagseaZ9/q825ldG9qONX/Us8IuxbgBG9BqiNz5JV/S1Q5mFw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=FJPoxpUO28vkt+Xzt2+HLrMEFtqmCbP0XZfa4v90xPo=; b=OqWED1CqJLPVsY0mm22+TsJI25TkuubGfvWFmu69thmjkmPDVQlVykUYqHaO5oPlnT5zbxHaMgJVsbjapkxQwIPjLyrjDNIW+ep6GMJQIXMw5dOAaBZoVoXh9t/EgzDJABx8+v7XL/t+b6hKVs1eCVGh0bJOZSa+dcqNNV/a2K0= Received: from PH7P220CA0084.NAMP220.PROD.OUTLOOK.COM (2603:10b6:510:32c::7) by IA4PR12MB9809.namprd12.prod.outlook.com (2603:10b6:208:54f::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.23; Fri, 7 Aug 2026 10:45:36 +0000 Received: from SJ1PEPF000023D3.namprd21.prod.outlook.com (2603:10b6:510:32c:cafe::86) by PH7P220CA0084.outlook.office365.com (2603:10b6:510:32c::7) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.24 via Frontend Transport; Fri, 7 Aug 2026 10:45:36 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D3.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:45:36 +0000 Received: from satlexmb10.amd.com (10.181.42.219) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:28 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb10.amd.com (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:27 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:22 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 09/20] net: dsa: tag_xlnx_tsn: add skeleton tag protocol Date: Fri, 7 Aug 2026 16:14:20 +0530 Message-ID: <20260807104431.157230-10-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D3:EE_|IA4PR12MB9809:EE_ X-MS-Office365-Filtering-Correlation-Id: ecaaf5b4-d13a-4df9-a9f7-08def471039b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700016|23010399003|7416014|376014|82310400026|1800799024|921020|56012099006|11063799006|10067099003|18002099003|3023799007|22082099003; X-Microsoft-Antispam-Message-Info: aBTDdXK9oDgbTTJXqaC0RoK+9KKlfcrQfwdREJUtHKF9oomfWXvA4qHvMdSsICVGYUpr5/wpsTFlvvPF77kcVpYUt7bN5kp89fnHdmH/K+re7r95VqNbkXzdlTUNAx0IoM6TtyJCLF3u9Nc+LGSFGuDtFXmkX+k8Kudu9WulqapKsDWAcpSCkFpo7IeptFOgIshorCtalWOu48yQ3C7k7NkfvBOonRWL42flzE3Av+/69Ivf3SKrZzjevRbUXvWDEcTiBN/MHMtNN0e167nbnPn0M5Cb30UGwXws4S0E83hlh+SaLMUpyFrhF2PintKSjtHnxA+6dafy79TSXb/rrKRLAunS9LYyq2HxXjX7c3R6sxQcT9dSLAAAsM+Cv8UUq9pvDjUjq8T6yEi5hMTUx6esHPvK2OvUd8uU5QSvKvIADK5YyVWErju/zmz37Pp+hd8xcX8uwNa/MuChbfyT4aH9JyOIN+HfwWFokXxiFqisBkOl1d6fsxKy0I0N6lL4fPvX/r5AF9vAY0GfcbDkTPmKb6CHVbjXai845VdFNo59ntan3jBHE1huE0kr016Xv45c3h6vM9SHc5JFeY7sb+oTdaAvgbiWeRktMw81DiCwAPOmJD92T/geeVdljoTCtNyKMgJ49DdLVtkFrueFnZYq/HLv0TcrqTgx9j0tzPfHtAJ4xrlOIOtZUCbPHskVNL5SKksTLOSAmhV1uoZiZadFF159FV7WS/r7agoanrVDgXOtkd3/BeNovglL3MXD X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700016)(23010399003)(7416014)(376014)(82310400026)(1800799024)(921020)(56012099006)(11063799006)(10067099003)(18002099003)(3023799007)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: jeEm+a6Hq921y4TDImadQjdRIsTmYeyGNV+ElgnY6nzhQaYTNaWHXYIgrIYewQxlGAzmEcoKTRIhS85ZbwyP218Ew5vlnHj9z1frbHWPTL0c8Vxh07cM54WiK9/v1Vj2FSKoIdjuOTf16sSL6/7AtzWsARV9hxCko+ZZbKuKJJlhJUaWbPnGbeMDqY/t/jwXo1T9Xw62/2Awxm58KDnYecyQHPfTjPK7iiu3Wywd96o258esYVSBoqY9kl9aW1xHOKxB04WTu168fbABbMPniDtNVpFr+qNUn0Y8n/SPGC5pFO9/WkA1h49/MqqFiJX7w/6FNcx5yraNYRcfY/7z4/ktjb1Y3RNBtZQh7cHpfry+vkS95iV6K5xH0fgCxsDzOi0Kuvs0IbbGHx5QP43JiUx13xhTWHBh4qV/zmfHOg3ntAFS+PrVVeXW2K29ZaNm X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:36.0863 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ecaaf5b4-d13a-4df9-a9f7-08def471039b X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D3.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA4PR12MB9809 Content-Type: text/plain; charset="utf-8" The AMD/Xilinx TSN Endpoint Ethernet MAC IP does not insert an in-band CPU tag on the wire. The EP MAC driver attaches a per-port metadata_dst (METADATA_HW_PORT_MUX) on RX to carry the port classification out of band. The tag protocol therefore has no tag bytes to add or strip. Add DSA_TAG_PROTO_XLNX_TSN and register NET_DSA_TAG_XLNX_TSN as a no-op tag driver. A later patch adds the PTP TX intercept to reroute PTP frames through the per-MAC PTP TX path. Signed-off-by: Nagadheeraj Rottela --- MAINTAINERS | 1 + include/net/dsa.h | 2 ++ net/dsa/Kconfig | 9 +++++++++ net/dsa/Makefile | 1 + net/dsa/tag_xlnx_tsn.c | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 46 insertions(+) create mode 100644 net/dsa/tag_xlnx_tsn.c diff --git a/MAINTAINERS b/MAINTAINERS index e5b95b3bfa21..6fbe83fb3953 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -29614,6 +29614,7 @@ L: netdev@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/net/xlnx,tsn-endpoint-ethernet-mac.ya= ml F: drivers/net/ethernet/xilinx/tsn/ +F: net/dsa/tag_xlnx_tsn.c =20 XILINX UARTLITE SERIAL DRIVER M: Peter Korsgaard diff --git a/include/net/dsa.h b/include/net/dsa.h index 6f7f5c17b532..f0cc5b49407a 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -60,6 +60,7 @@ struct tc_action; #define DSA_TAG_PROTO_MXL862_VALUE 32 #define DSA_TAG_PROTO_NETC_VALUE 33 #define DSA_TAG_PROTO_KSZ8463_VALUE 34 +#define DSA_TAG_PROTO_XLNX_TSN_VALUE 35 =20 enum dsa_tag_protocol { DSA_TAG_PROTO_NONE =3D DSA_TAG_PROTO_NONE_VALUE, @@ -97,6 +98,7 @@ enum dsa_tag_protocol { DSA_TAG_PROTO_MXL862 =3D DSA_TAG_PROTO_MXL862_VALUE, DSA_TAG_PROTO_NETC =3D DSA_TAG_PROTO_NETC_VALUE, DSA_TAG_PROTO_KSZ8463 =3D DSA_TAG_PROTO_KSZ8463_VALUE, + DSA_TAG_PROTO_XLNX_TSN =3D DSA_TAG_PROTO_XLNX_TSN_VALUE, }; =20 struct dsa_switch; diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig index d5e725b90d78..8ca48ce46ec1 100644 --- a/net/dsa/Kconfig +++ b/net/dsa/Kconfig @@ -221,4 +221,13 @@ config NET_DSA_TAG_YT921X Say Y or M if you want to enable support for tagging frames for Motorcomm YT921x switches. =20 +config NET_DSA_TAG_XLNX_TSN + tristate "Tag driver for AMD/Xilinx TSN Endpoint Ethernet MAC" + help + Say Y or M if you want to enable support for the AMD/Xilinx TSN + Endpoint Ethernet MAC IP. The IP does not insert an in-band CPU + tag; port classification is conveyed via metadata_dst attached on + RX by the EP MAC driver, and PTP TX frames are intercepted in the + xmit hook to be steered into the per-MAC PTP TX register window. + endif diff --git a/net/dsa/Makefile b/net/dsa/Makefile index b8c2667cd14a..6ba6c3a95976 100644 --- a/net/dsa/Makefile +++ b/net/dsa/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_NET_DSA_TAG_RZN1_A5PSW) +=3D tag_rzn1_a5psw.o obj-$(CONFIG_NET_DSA_TAG_SJA1105) +=3D tag_sja1105.o obj-$(CONFIG_NET_DSA_TAG_TRAILER) +=3D tag_trailer.o obj-$(CONFIG_NET_DSA_TAG_VSC73XX_8021Q) +=3D tag_vsc73xx_8021q.o +obj-$(CONFIG_NET_DSA_TAG_XLNX_TSN) +=3D tag_xlnx_tsn.o obj-$(CONFIG_NET_DSA_TAG_XRS700X) +=3D tag_xrs700x.o obj-$(CONFIG_NET_DSA_TAG_YT921X) +=3D tag_yt921x.o =20 diff --git a/net/dsa/tag_xlnx_tsn.c b/net/dsa/tag_xlnx_tsn.c new file mode 100644 index 000000000000..de352aa3d9a8 --- /dev/null +++ b/net/dsa/tag_xlnx_tsn.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AMD/Xilinx TSN Endpoint Ethernet MAC tag protocol. + */ + +#include "tag.h" + +#define XLNX_TSN_NAME "xlnx_tsn" + +static struct sk_buff *xlnx_tsn_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + return skb; +} + +static struct sk_buff *xlnx_tsn_rcv(struct sk_buff *skb, + struct net_device *dev) +{ + kfree_skb(skb); + return NULL; +} + +static const struct dsa_device_ops xlnx_tsn_netdev_ops =3D { + .name =3D XLNX_TSN_NAME, + .proto =3D DSA_TAG_PROTO_XLNX_TSN, + .xmit =3D xlnx_tsn_xmit, + .rcv =3D xlnx_tsn_rcv, +}; + +module_dsa_tag_driver(xlnx_tsn_netdev_ops); +MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_XLNX_TSN, XLNX_TSN_NAME); +MODULE_DESCRIPTION("DSA tag driver for AMD/Xilinx TSN Endpoint Ethernet MA= C"); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from BN1PR04CU002.outbound.protection.outlook.com (mail-eastus2azon11010009.outbound.protection.outlook.com [52.101.56.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB79442BC42; Fri, 7 Aug 2026 10:45:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.56.9 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099542; cv=fail; b=cbtMHigPbCSFjrJlLJ7VnC5KqpCQ0mtyFNAruzTKScZ31HG0AAYd8860IJ1ZBEMAclxDnvkXtsNu1WXytrwKPMRSCdzPM99FugBmtwQGgi/BjTSHec02Fl2SiHzvwEY8PTGzTq0Lhb6u8JiD40BczH8T9KcRza4kxlpBRgOW9Ks= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099542; c=relaxed/simple; bh=Jl3KG6DeHv/x3TwuuaqHy6v5DPfMZ0/LxRUwI98fRxU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WuaHQduf2qf+ckfSU95vYxHvDrPh1PDsJr8sXtosoPt8Eogk9h7DuWZpGOJ5RcPRrFLFm3yLDB7B2NBwhIrP7PP1DHhpyikibNtO9bTpBfbT7kAdUDHNpubZWpQepbO3PzUXQ2QKEHL+rxVr2INs7/zYSY7VmCm87kSez/I2nwU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=SbtW7Lcz; arc=fail smtp.client-ip=52.101.56.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="SbtW7Lcz" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=JZCBcU1FQDk6tIg2UgRTmjpGHcHpoUw1rhwsSxbAcmr6DzWDcRvUf32J9W9v60SwumWd8j0TL5zrX58c3xjE6D4U5KSl7aRffzpgpmY/VY0ZoxFTlLpJsDdTvh15LsW4sViBEDpz28FnoV+ckaPfyW4seJNZyEcIIfLxOstk4wOJqkwq5QEn5fePnequXyr8aVJBhdkN5gPOJ71ox81YtbnW/LTBsiPI8hblgjV+1vTMxOwjE4O59wGxpMXwhfRW5DW4zeZ7SD5YplUyVyhuqrTROpA687zhK/5bhJ5HeelMM6utI+1DkuH4TdKbYHUk14ho1SM7/kVgqNOfYHuc6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=EjRCnsRS8PgVP4le0P885dYY+YZS/CRkd66GnBdteN8=; b=R6w0ChcYHigx5iQNhwi9gPWmuwi1WY+1HFW27fgAjMGmCjMvNcL7ac9hgVtH2+KnqdReiSxNtx6DvpFm9gOsuVGwKt5hk+2d9kVKLoWBTuabK7WgKjKJGDbENrtqWah9oRYyszc6YHIODUdDO1/It4OO7iMLEJWnM6q5IHYASeoxSfCNMtN1TlCzvGxZjABHeOsCfiCKRRar9rSa4gRF+nk6nURPkbhv4rc9FtTJwz7rgBgF0nl/Q1ZcjDdCAmFHCl4E5W9o7OlKLOv6MKnh4GVJM6gISHrZbGAd910BktKCp3Sm11FpcUnyzTmTyf7haGhklFzEF2s23xOvksCIEw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=EjRCnsRS8PgVP4le0P885dYY+YZS/CRkd66GnBdteN8=; b=SbtW7LczoEWiA29cLf5Qh3b28CV2OevHEitWaz5Q/9SzMae14Uaeeq6ZsNwFi4aBqQAlYKmrtFZ3RGm53f+FaRSX/9S0fzonmVKHp2D5bTiXCeenLvqSFnq5W0BxnlpX3Z9FOl5Sn7qwzpLnQ6wTPSPqIsTn5Gn6mrAPuVrpIcY= Received: from SJ0PR05CA0051.namprd05.prod.outlook.com (2603:10b6:a03:33f::26) by SA0PR12MB7074.namprd12.prod.outlook.com (2603:10b6:806:2d5::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.19; Fri, 7 Aug 2026 10:45:35 +0000 Received: from SJ5PEPF000001E8.namprd05.prod.outlook.com (2603:10b6:a03:33f:cafe::7d) by SJ0PR05CA0051.outlook.office365.com (2603:10b6:a03:33f::26) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.315.8 via Frontend Transport; Fri, 7 Aug 2026 10:45:35 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SJ5PEPF000001E8.mail.protection.outlook.com (10.167.242.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.6 via Frontend Transport; Fri, 7 Aug 2026 10:45:34 +0000 Received: from satlexmb10.amd.com (10.181.42.219) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:33 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb10.amd.com (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:32 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:27 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 10/20] net: dsa: xilinx: add skeleton driver for TSN switch Date: Fri, 7 Aug 2026 16:14:21 +0530 Message-ID: <20260807104431.157230-11-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001E8:EE_|SA0PR12MB7074:EE_ X-MS-Office365-Filtering-Correlation-Id: 119e406c-600e-4415-8c88-08def47102de X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|36860700016|1800799024|82310400026|921020|10067099003|11063799006|56012099006|18002099003|22082099003|3023799007; X-Microsoft-Antispam-Message-Info: Y2PN6FqMoIVp48AKYJMnHH+cD2i5gzlR1CZCthhQNI5B2I9qdW9VUmsVYrUko5V2rd1MwKBZRuxyT72qVCg1tSNaapH1Keam/b/sY49l2prkFF4qH3m7WMFxb2LCtULQEtekKrxPOlqgHMF2tPdvmc3Sj66WXp44fhgkb/qxpwZBzkKUM36gFL7ItI939BpohL870sTTIGa2spzmDPLEPlbjSI4Cnk7VCtFo6FEDb/JVQAimRF9oej5QpEhpKRGnAcKmVj1PdHAl0P7Grjy2KHHP6UOU/GnT8uUTLbqeU7XoCLFSR8YBfg4P4+pLP4eqD5TNvCiEG8NaTRQlap8Ma9DqzwBV60YgD9ZoRLKdCVcHwnaGvQWCcClvR+acjJ7o4FKYF+SDWRLXUjwMu9DuYYYCEwKpES6Lx5bjRqEX9JVJZPBZfK34SYasjeF9yCC3Crmli3p6D4TyVtk6CLKY6aG3SXNzi/hlYAgaGw/N90ep9H5aOOOh9uX4C9tNf2G5Io4VN8MS9gF9GvjLYVybbo3xiwI8sXUu0LFZIY6U3Oc2INI/jmZGcmc4+EM+xk5Qgu9BUNHrKXuiSuuMp4CLCWUPCJlJblmdoymc5qjHOtvM5MXS6j67Co0ecu+yMt0hxyPciQ5gwsi4lE5QunjvwhX1fyiu2d8E4IxO10xmLdJTa4Hu/Eh3MdSND6ZIkjSgl2ofoqkElOrCFhqd4ytyrovGDwpv3IMc7ByJgIrFzjuUfHf7lmSXghkXwKSsIZbW X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(36860700016)(1800799024)(82310400026)(921020)(10067099003)(11063799006)(56012099006)(18002099003)(22082099003)(3023799007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 5C0kFU/0Pt8AbcZThcsbZR+SsZDeJKuCjgLKCIQoD9HvNihkQg4JZoSLDeBnkrp9T9YLBAb+VhJXVPHpng+RddfuvZ2Fa0fRQvfIihrbKPuNtKDY6mG1xWPP+CVfP4lWrspH+ABA7t8GTL5nm4xIyZ6npj9hCtuK2ZtS1Mtzogji/XNbTR8i+bjO1ZynZb79A/+xtcH/oRNpuwmJ2pPpf4Uc42xZ+fZLowolJHf1QZwsZjrHGgI9bXsl8ZekFsfc3DQZRl00N7D8/lwocT8stdav+w99rRTWvN/nJJ5NZmgwjRd+OtK3GJNkU2AKnnAAWB+feL7CbV71CoIcQ0Y279VhMPFTBZwl7sllC3YXhxqxEWOZUVsOMKuX7lR8CJteos95/TJwg4/Ekzk8N4OOjh7GNuYqkgLQpOgLetVllb0UzKGud1cZWwIkVeGxBCYu X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:34.8466 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 119e406c-600e-4415-8c88-08def47102de X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001E8.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB7074 Content-Type: text/plain; charset="utf-8" Add a skeleton DSA driver for the three-port switch block of the AMD/Xilinx TSN Endpoint Ethernet MAC IP. It binds "xlnx,tsn-switch", maps the switch fabric and two per-MAC register windows ("switch", "mac1", "mac2"), and registers a dsa_switch with num_ports =3D 3. Port 0 is the CPU port, wired internally to the endpoint MAC. Ports 1 and 2 are the external user ports backed by MAC1 and MAC2. At this stage only get_tag_protocol is wired. setup and teardown are stubs. MDIO, phylink, frame filtering, and PTP follow in subsequent patches. Signed-off-by: Nagadheeraj Rottela --- MAINTAINERS | 1 + drivers/net/dsa/Kconfig | 2 + drivers/net/dsa/Makefile | 1 + drivers/net/dsa/xilinx/Kconfig | 11 +++ drivers/net/dsa/xilinx/Makefile | 3 + drivers/net/dsa/xilinx/xilinx_tsn.c | 126 ++++++++++++++++++++++++++++ drivers/net/dsa/xilinx/xilinx_tsn.h | 31 +++++++ 7 files changed, 175 insertions(+) create mode 100644 drivers/net/dsa/xilinx/Kconfig create mode 100644 drivers/net/dsa/xilinx/Makefile create mode 100644 drivers/net/dsa/xilinx/xilinx_tsn.c create mode 100644 drivers/net/dsa/xilinx/xilinx_tsn.h diff --git a/MAINTAINERS b/MAINTAINERS index 6fbe83fb3953..0e91cb2a307d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -29613,6 +29613,7 @@ M: Srinivas Neeli L: netdev@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/net/xlnx,tsn-endpoint-ethernet-mac.ya= ml +F: drivers/net/dsa/xilinx/ F: drivers/net/ethernet/xilinx/tsn/ F: net/dsa/tag_xlnx_tsn.c =20 diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 4ab567c5bbaf..1404a77579f1 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -84,6 +84,8 @@ source "drivers/net/dsa/qca/Kconfig" =20 source "drivers/net/dsa/sja1105/Kconfig" =20 +source "drivers/net/dsa/xilinx/Kconfig" + source "drivers/net/dsa/xrs700x/Kconfig" =20 source "drivers/net/dsa/realtek/Kconfig" diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile index d2975badffc0..75b8449b575e 100644 --- a/drivers/net/dsa/Makefile +++ b/drivers/net/dsa/Makefile @@ -26,4 +26,5 @@ obj-y +=3D ocelot/ obj-y +=3D qca/ obj-y +=3D realtek/ obj-y +=3D sja1105/ +obj-y +=3D xilinx/ obj-y +=3D xrs700x/ diff --git a/drivers/net/dsa/xilinx/Kconfig b/drivers/net/dsa/xilinx/Kconfig new file mode 100644 index 000000000000..0bd5efe8490b --- /dev/null +++ b/drivers/net/dsa/xilinx/Kconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +config NET_DSA_XILINX_TSN + tristate "AMD/Xilinx TSN Endpoint Ethernet MAC switch support" + depends on OF && HAS_IOMEM + depends on NET_DSA + select NET_DSA_TAG_XLNX_TSN + help + This enables DSA switch support for the three-port switch + block of the AMD/Xilinx TSN Endpoint Ethernet MAC IP. Port 0 + is the CPU port, wired internally to the endpoint MAC; ports 1 + and 2 are external Ethernet ports backed by MAC1 and MAC2. diff --git a/drivers/net/dsa/xilinx/Makefile b/drivers/net/dsa/xilinx/Makef= ile new file mode 100644 index 000000000000..334f0f979276 --- /dev/null +++ b/drivers/net/dsa/xilinx/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +obj-$(CONFIG_NET_DSA_XILINX_TSN) +=3D xlnx_tsn_dsa.o +xlnx_tsn_dsa-y :=3D xilinx_tsn.o diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c new file mode 100644 index 000000000000..6b285c528724 --- /dev/null +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AMD/Xilinx TSN Endpoint Ethernet MAC DSA switch driver. + */ + +#include +#include +#include +#include +#include + +#include "xilinx_tsn.h" + +static enum dsa_tag_protocol xlnx_tsn_get_tag_protocol(struct dsa_switch *= ds, + int port, + enum dsa_tag_protocol mp) +{ + return DSA_TAG_PROTO_XLNX_TSN; +} + +static int xlnx_tsn_setup(struct dsa_switch *ds) +{ + return 0; +} + +static void xlnx_tsn_teardown(struct dsa_switch *ds) +{ +} + +static const struct dsa_switch_ops xlnx_tsn_switch_ops =3D { + .get_tag_protocol =3D xlnx_tsn_get_tag_protocol, + .setup =3D xlnx_tsn_setup, + .teardown =3D xlnx_tsn_teardown, +}; + +static int xlnx_tsn_map_reg(struct platform_device *pdev, const char *name, + void __iomem **out) +{ + void __iomem *base; + + base =3D devm_platform_ioremap_resource_byname(pdev, name); + if (IS_ERR(base)) + return dev_err_probe(&pdev->dev, PTR_ERR(base), + "failed to map %s reg window\n", name); + + *out =3D base; + return 0; +} + +static int xlnx_tsn_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct dsa_switch *ds; + struct xlnx_tsn *sw; + int ret; + + sw =3D devm_kzalloc(dev, sizeof(*sw), GFP_KERNEL); + if (!sw) + return -ENOMEM; + + sw->dev =3D dev; + + ret =3D xlnx_tsn_map_reg(pdev, "switch", &sw->sw_base); + if (ret) + return ret; + + ret =3D xlnx_tsn_map_reg(pdev, "mac1", &sw->mac_base[XLNX_TSN_PORT_MAC1]); + if (ret) + return ret; + + ret =3D xlnx_tsn_map_reg(pdev, "mac2", &sw->mac_base[XLNX_TSN_PORT_MAC2]); + if (ret) + return ret; + + ds =3D &sw->ds; + ds->dev =3D dev; + ds->num_ports =3D XLNX_TSN_NUM_PORTS; + ds->ops =3D &xlnx_tsn_switch_ops; + ds->priv =3D sw; + + platform_set_drvdata(pdev, sw); + + return dsa_register_switch(ds); +} + +static void xlnx_tsn_remove(struct platform_device *pdev) +{ + struct xlnx_tsn *sw =3D platform_get_drvdata(pdev); + + if (!sw) + return; + + dsa_unregister_switch(&sw->ds); +} + +static void xlnx_tsn_shutdown(struct platform_device *pdev) +{ + struct xlnx_tsn *sw =3D platform_get_drvdata(pdev); + + if (!sw) + return; + + dsa_switch_shutdown(&sw->ds); + platform_set_drvdata(pdev, NULL); +} + +static const struct of_device_id xlnx_tsn_of_match[] =3D { + { .compatible =3D "xlnx,tsn-switch" }, + { } +}; +MODULE_DEVICE_TABLE(of, xlnx_tsn_of_match); + +static struct platform_driver xlnx_tsn_driver =3D { + .driver =3D { + .name =3D "xlnx-tsn-switch", + .of_match_table =3D xlnx_tsn_of_match, + }, + .probe =3D xlnx_tsn_probe, + .remove =3D xlnx_tsn_remove, + .shutdown =3D xlnx_tsn_shutdown, +}; +module_platform_driver(xlnx_tsn_driver); + +MODULE_AUTHOR("Nagadheeraj Rottela "); +MODULE_DESCRIPTION("AMD/Xilinx TSN Endpoint Ethernet MAC DSA switch driver= "); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/x= ilinx_tsn.h new file mode 100644 index 000000000000..0f9af866bd18 --- /dev/null +++ b/drivers/net/dsa/xilinx/xilinx_tsn.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * AMD/Xilinx TSN Endpoint Ethernet MAC DSA switch driver. + */ +#ifndef _XILINX_TSN_H +#define _XILINX_TSN_H + +#include +#include + +#define XLNX_TSN_NUM_PORTS 3 +#define XLNX_TSN_CPU_PORT 0 +#define XLNX_TSN_PORT_MAC1 1 +#define XLNX_TSN_PORT_MAC2 2 + +/** + * struct xlnx_tsn - per-IP switch state + * @ds: DSA switch + * @dev: backing device + * @sw_base: switch fabric register window + * @mac_base: per-MAC register windows, indexed by user-port number + * (index 0 unused; MAC1 at [1], MAC2 at [2]) + */ +struct xlnx_tsn { + struct dsa_switch ds; + struct device *dev; + void __iomem *sw_base; + void __iomem *mac_base[XLNX_TSN_NUM_PORTS]; +}; + +#endif /* _XILINX_TSN_H */ --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from BN8PR05CU002.outbound.protection.outlook.com (mail-eastus2azon11011063.outbound.protection.outlook.com [52.101.57.63]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6692E432309; Fri, 7 Aug 2026 10:45:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.57.63 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099551; cv=fail; b=sweuudhlqZdY2nCP417UeWQPJpWBXLidQG3HijlztrKKn4TkuZIZOR3EgL8wmbvBZegXAXSSkPwB1P255IPRkg4XOtXN2xlbGLejrCZC8k1SaY2SPnhdTifmrXF8nDP+9RW3W8Qrj1c6bIRMNxEbD1hiDIVoj1GSyksKNaq5Iso= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099551; c=relaxed/simple; bh=YiLe7PB1/31ATns3pl3UoytcqheppHuYFomZbbV7jEY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fZyUma6tY0i5GRu2MkPeSkrUO9nLmeHiokGToqaEV3mu2tV4Fxc45R+1onvkLd8lmDuViRRJN799x8/UjXmkcZgxokQZMf7rSIqNG5C8udmJN05l45W7r1sL1W4etVzre7OFH5b7F0z8OjAg3vi94mxv6UHsM5UUklsv3mbIqrI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=KCAl8mYo; arc=fail smtp.client-ip=52.101.57.63 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="KCAl8mYo" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=bgqbvFvKDjMGSAewa16OOt++zOC3qdXWNgRSb81U+GcyiNB3d2YZoxOt4FIIIn8AVU27Oq9Trz0HpSxCOvvFKqzcJJRALt4HLhTLVPYSDkvZoG7Wx5xyACqodI2B04SDa64guXt/fOp6H5m3sW4HndnhPDG/sbgZjtCd6npB+UA/LT2Rgt4IORRsmm0g6ECdhAOnnLBJND0VY6nHq7Jt5O6XqVupXrZcwj2saaM02850rUA/o6xkuYI+sTdDQvnW/0SqVaxsRU+oueeWmc/Y4JbYhtKTz9UJbmA7GVITbsS1U2koQ9NU2D/sErqz0dhM1uMoRTd5Mt671AJfGzCyQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=+rIsPd5DvgYIJc8JzS+AAKx+PsBr87OZdjS81f7ABzg=; b=lhscueEL0s7/rhLrEKVZH5z7Ml1FMxKEA4PkYLcgClAJ4THnIFaSHrzdm4v8IS5AY7Buiq29JyBLPFOZGuAEA62ctO3ekU0mMPuBxvHC7rJjuGxXCGM8FUtqR78cscgMMTw8sLDQnVo/hFaWHP6IIw6ztp5gyyEv1MpMVjkVhD8Ej7VWzSosFLShaLsE0rNF4vRjTU6WSe9Y26CgFfedrL/tgVqMpIutsIitJgEMUN8aZkeuOaRvJf8aYUFXkg1mKOVmFma5WqdLTN778ckSw11matdnt8kCQlZA9IuS7cbw+3too95rvSKFjdQYeyF9PubBy3kRN3XJk0QB4UsT+g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+rIsPd5DvgYIJc8JzS+AAKx+PsBr87OZdjS81f7ABzg=; b=KCAl8mYolEx+zGO4hP+PMbcBRGo5tszvx98QnEHVe55AENIzkeSzsYI00BQO5jth6pW7bhqOZUGhiurhVBEES35ddpfZZqMQVCge/ER9ZMq3YUMGnCQ459q/1tOfFvAajzD01LIgEB424ArALJBjLpSN65+JGW2ItpC+UoA7J8M= Received: from PH7P222CA0009.NAMP222.PROD.OUTLOOK.COM (2603:10b6:510:33a::23) by CH3PR12MB8725.namprd12.prod.outlook.com (2603:10b6:610:170::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.23; Fri, 7 Aug 2026 10:45:41 +0000 Received: from SJ1PEPF000023D4.namprd21.prod.outlook.com (2603:10b6:510:33a:cafe::72) by PH7P222CA0009.outlook.office365.com (2603:10b6:510:33a::23) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.24 via Frontend Transport; Fri, 7 Aug 2026 10:45:40 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D4.mail.protection.outlook.com (10.167.244.69) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:45:40 +0000 Received: from Satlexmb09.amd.com (10.181.42.218) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:39 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb09.amd.com (10.181.42.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 03:45:38 -0700 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:33 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 11/20] net: dsa: xilinx: implement port_stp_state_set Date: Fri, 7 Aug 2026 16:14:22 +0530 Message-ID: <20260807104431.157230-12-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D4:EE_|CH3PR12MB8725:EE_ X-MS-Office365-Filtering-Correlation-Id: 5f26e3c7-5dca-49f1-433a-08def4710601 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|36860700016|1800799024|82310400026|7416014|376014|11063799006|56012099006|10067099003|18002099003|3023799007|22082099003|921020; X-Microsoft-Antispam-Message-Info: 8P921VhYJa7Yj0jVsGgi+410dv32cT5g0BrVLDDBZHcmo5e6BxjaXO/Ud5TVllZevHg3GIX4lKh4bfVFv5uxzBynj5MNsP9jwPbPDs+2aLFCjHkZPM6EPeaybCAWvbI27OAU/Pm1YWyHPkuVZHELcufefEu1l/Ito+h26sx2bBUX2eULnaagJjzvo8nvMY/5NivpnQ1tXWU0Unx5T67OL6plc5Yh728A6JKUM+bsNIoPcoNSJ/50fcRond5QfmMT0f3WgYLjTqXk2q+jfVoHI7i+rB7UADwfvro5Krey6Byc0Sy9/tul629sPs8VopF1L6AHbdJRuT/8ZqJAw07OOBRVeIJzccwAaS48cgFDYBvz0M2IljYo2xaevPuE8+/8C5u4UPQXkEu4hbC5IiCYjhZ/W6WQ/GhJ6eQP7fatFakeUgTnxjaVQJCCZzouv06NcAjsq5uwJgSNFSKB7iGB6WK5ZqOqQvP1z4W+ltehajmGeSN5HrD5aCIVS6WsnranIw+KiCnh2CVrhntPdGioNcqI1VHKbjIZWqt6cgdGLmwwEc2Tjp7xd1s/u+w5n1K23mHIWTgwNGigCpNjUEdcillkJI3zJrNd61vcM5GvShFvM4Q+rFWf1uktVAFM/MgO0GSBugsUu7m0i5qt5htMA064CtFNexoy8v8oRbYWIRO10YYETpf+WvAf9b/cVLIslz7EZ5dHIDJ7HEQOEzVlYhothBPW5N4rZMK2aXBRv6U5u9kq23cCSLx4ueX7HLN4 X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(23010399003)(36860700016)(1800799024)(82310400026)(7416014)(376014)(11063799006)(56012099006)(10067099003)(18002099003)(3023799007)(22082099003)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ybU6l0GGxNPi0rrmxJjabq5HhvWPcUH0z6wJ01BJwk+F2ATebfxs6cjA6XjAs9HaAlees210SEcRJ2+2MG5jIY3vaAA6Hu7S1AGDV5Y0GFc4Jj7owIVltfC+j4wmkV2LiEmwu9Arrtwu6oumH9z5ZboaZX54gFqxdEGgmvzua96K3lcVpAHsspszzCt1ptwiLlNTss3I9Q4FRxbU1QXfYojVyGjrIt1nSC/9Jla4JJqf0YFztE+pSBZuHTzTTMnOtEMEW9D3+mDLNyRXgshWInuL4esR0jnnysH8icD33kbGDx/1x+8tActqGuO0wJOV7I0E30U26kKldEn5tDEP7TZnvHCxaUDu0HC5Ia2FI095yQpkxnTGqOj/SwiaR2WM6rwPLttoiQqKJ1OtY2x6LdCpoi2DoZtakdbkPgykINhQ7Ygi1la/m2WrvvHLSLkf X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:40.1077 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5f26e3c7-5dca-49f1-433a-08def4710601 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D4.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR12MB8725 Content-Type: text/plain; charset="utf-8" Wire up the bridge STP state machine to the Switch Port State Control register at +0x004C. Each port has a 3-bit state field and a self-clearing commit bit. The hardware applies the new state only when the commit bit transitions from 0 to 1. Follow each write with readl_poll_timeout() until the hardware acknowledges. All five STP states map to distinct hardware encodings on the MAC ports. Put the CPU port in FORWARDING so host traffic always flows, and the user ports in DISABLED so the bridge STP machine drives all further transitions. On teardown, return the user ports to DISABLED. The bridge STP machine does not manage the CPU port. Its forwarding state does not change after setup(). Co-developed-by: Srinivas Neeli Signed-off-by: Srinivas Neeli Signed-off-by: Nagadheeraj Rottela --- drivers/net/dsa/xilinx/xilinx_tsn.c | 148 ++++++++++++++++++++++++++++ drivers/net/dsa/xilinx/xilinx_tsn.h | 32 ++++++ 2 files changed, 180 insertions(+) diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c index 6b285c528724..020b1622670c 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -3,6 +3,10 @@ * AMD/Xilinx TSN Endpoint Ethernet MAC DSA switch driver. */ =20 +#include +#include +#include +#include #include #include #include @@ -11,6 +15,86 @@ =20 #include "xilinx_tsn.h" =20 +static void sw_iow(struct xlnx_tsn *sw, u32 off, u32 val) +{ + iowrite32(val, sw->sw_base + off); +} + +static u32 sw_ior(struct xlnx_tsn *sw, u32 off) +{ + return ioread32(sw->sw_base + off); +} + +static int xlnx_tsn_switch_status_ready(struct xlnx_tsn *sw) +{ + u32 reg; + + return readl_poll_timeout(sw->sw_base + TSN_SW_STATUS_OFFSET, reg, + reg & TSN_SW_STATUS_READY, + TSN_SW_POLL_DELAY_US, TSN_SW_POLL_TIMEOUT_US); +} + +static int xlnx_tsn_port_state_bits(int port, u32 *mask, u32 *chg_bit) +{ + switch (port) { + case XLNX_TSN_CPU_PORT: + *mask =3D EP_PORT_STATUS_MASK; + *chg_bit =3D EP_PORT_STATUS_CHG_BIT; + return 0; + case XLNX_TSN_PORT_MAC1: + *mask =3D MAC1_PORT_STATUS_MASK; + *chg_bit =3D MAC1_PORT_STATUS_CHG_BIT; + return 0; + case XLNX_TSN_PORT_MAC2: + *mask =3D MAC2_PORT_STATUS_MASK; + *chg_bit =3D MAC2_PORT_STATUS_CHG_BIT; + return 0; + default: + return -EINVAL; + } +} + +static int xlnx_tsn_set_port_state(struct xlnx_tsn *sw, int port, + enum tsn_port_state state) +{ + u32 chg_bit, mask, val, reg; + int err; + + err =3D xlnx_tsn_port_state_bits(port, &mask, &chg_bit); + if (err) + return err; + + err =3D xlnx_tsn_switch_status_ready(sw); + if (err) { + dev_err(sw->dev, "port %d: switch not ready for state change\n", + port); + return err; + } + + /* Bit won't re-arm if a previous change never cleared it. */ + val =3D sw_ior(sw, TSN_PORT_STATE_CTRL_OFFSET); + if (val & chg_bit) { + dev_err(sw->dev, "port %d: previous state change still pending\n", + port); + return -EBUSY; + } + + val &=3D ~mask; + val |=3D (state << __ffs(mask)) & mask; + val |=3D chg_bit; + sw_iow(sw, TSN_PORT_STATE_CTRL_OFFSET, val); + + err =3D readl_poll_timeout(sw->sw_base + TSN_PORT_STATE_CTRL_OFFSET, reg, + !(reg & chg_bit), TSN_SW_POLL_DELAY_US, + TSN_SW_POLL_TIMEOUT_US); + if (err) { + dev_err(sw->dev, "port %d: state change ack timed out\n", port); + return -ETIMEDOUT; + } + + return 0; +} + static enum dsa_tag_protocol xlnx_tsn_get_tag_protocol(struct dsa_switch *= ds, int port, enum dsa_tag_protocol mp) @@ -18,19 +102,83 @@ static enum dsa_tag_protocol xlnx_tsn_get_tag_protocol= (struct dsa_switch *ds, return DSA_TAG_PROTO_XLNX_TSN; } =20 +static void xlnx_tsn_port_stp_state_set(struct dsa_switch *ds, int port, + u8 state) +{ + struct xlnx_tsn *sw =3D ds->priv; + enum tsn_port_state hw_state; + + switch (state) { + case BR_STATE_DISABLED: + hw_state =3D TSN_PORT_STATE_DISABLED; + break; + case BR_STATE_BLOCKING: + hw_state =3D TSN_PORT_STATE_BLOCKING; + break; + case BR_STATE_LISTENING: + hw_state =3D TSN_PORT_STATE_LISTENING; + break; + case BR_STATE_LEARNING: + hw_state =3D TSN_PORT_STATE_LEARNING; + break; + case BR_STATE_FORWARDING: + hw_state =3D TSN_PORT_STATE_FORWARDING; + break; + default: + dev_warn(sw->dev, "port %d: unsupported STP state %u\n", + port, state); + return; + } + + xlnx_tsn_set_port_state(sw, port, hw_state); +} + static int xlnx_tsn_setup(struct dsa_switch *ds) { + struct xlnx_tsn *sw =3D ds->priv; + struct dsa_port *dp; + int ret; + + if (!dsa_is_user_port(ds, XLNX_TSN_PORT_MAC1) || + !dsa_is_user_port(ds, XLNX_TSN_PORT_MAC2)) + return dev_err_probe(sw->dev, -EINVAL, + "both MAC1 and MAC2 must be enabled as switch ports\n"); + + /* CPU port stays in FORWARDING so host traffic always flows. + * User ports start in DISABLED and transition from there under + * bridge STP control. + */ + ret =3D xlnx_tsn_set_port_state(sw, XLNX_TSN_CPU_PORT, + TSN_PORT_STATE_FORWARDING); + if (ret) + return ret; + + dsa_switch_for_each_user_port(dp, ds) { + ret =3D xlnx_tsn_set_port_state(sw, dp->index, + TSN_PORT_STATE_DISABLED); + if (ret) + return ret; + } + return 0; } =20 static void xlnx_tsn_teardown(struct dsa_switch *ds) { + struct xlnx_tsn *sw =3D ds->priv; + struct dsa_port *dp; + + dsa_switch_for_each_user_port(dp, ds) + xlnx_tsn_set_port_state(sw, dp->index, TSN_PORT_STATE_DISABLED); + + xlnx_tsn_set_port_state(sw, XLNX_TSN_CPU_PORT, TSN_PORT_STATE_DISABLED); } =20 static const struct dsa_switch_ops xlnx_tsn_switch_ops =3D { .get_tag_protocol =3D xlnx_tsn_get_tag_protocol, .setup =3D xlnx_tsn_setup, .teardown =3D xlnx_tsn_teardown, + .port_stp_state_set =3D xlnx_tsn_port_stp_state_set, }; =20 static int xlnx_tsn_map_reg(struct platform_device *pdev, const char *name, diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/x= ilinx_tsn.h index 0f9af866bd18..1064cf1ce66e 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.h +++ b/drivers/net/dsa/xilinx/xilinx_tsn.h @@ -5,6 +5,8 @@ #ifndef _XILINX_TSN_H #define _XILINX_TSN_H =20 +#include +#include #include #include =20 @@ -13,6 +15,36 @@ #define XLNX_TSN_PORT_MAC1 1 #define XLNX_TSN_PORT_MAC2 2 =20 +#define TSN_SW_STATUS_OFFSET 0x00000 +/* Poll this before changing port state. */ +#define TSN_SW_STATUS_READY BIT(0) + +/* Switch Port State Control register: packs per-port STP state and + * change-commit bits into one 32-bit word. + */ +#define TSN_PORT_STATE_CTRL_OFFSET 0x0004c + +#define EP_PORT_STATUS_CHG_BIT BIT(0) +#define EP_PORT_STATUS_MASK GENMASK(3, 1) +#define MAC1_PORT_STATUS_CHG_BIT BIT(8) +#define MAC1_PORT_STATUS_MASK GENMASK(11, 9) +#define MAC2_PORT_STATUS_CHG_BIT BIT(16) +#define MAC2_PORT_STATUS_MASK GENMASK(19, 17) + +/* readl_poll_timeout() parameters (in microseconds): poll until + * the port-state change-commit bit self-clears. + */ +#define TSN_SW_POLL_DELAY_US 10 +#define TSN_SW_POLL_TIMEOUT_US 5000 + +enum tsn_port_state { + TSN_PORT_STATE_DISABLED =3D 0, + TSN_PORT_STATE_BLOCKING, + TSN_PORT_STATE_LISTENING, + TSN_PORT_STATE_LEARNING, + TSN_PORT_STATE_FORWARDING, +}; + /** * struct xlnx_tsn - per-IP switch state * @ds: DSA switch --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from BL2PR02CU003.outbound.protection.outlook.com (mail-eastusazon11011008.outbound.protection.outlook.com [52.101.52.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EEC2542FCD4; Fri, 7 Aug 2026 10:45:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.52.8 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099552; cv=fail; b=fh3xO1k6xVrSZOxBgSMKfrrOqr6VHknF1IqS3dD3AeJt1SLe2myzziV7RNhLWY4YPVT/NpQdC2tlGpQUF8OLH+OjPWBN2GDq3IiOQxMJhxFwjxKUKfpgS303nuGqsBUWcspHA+5t07nTTeERPlC/jX/YZvRfoKVQcIka3+afhmo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099552; c=relaxed/simple; bh=JRSjAaFrfAlYdJ4lG9p2oNgL2Gl+OibOFGaLbOn0pjI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lp7caHxWXs5I1XdDEW/b7n/jed9RxkHG3h0RUBQEagbwCIQKzYaUY0Tzw/gXxbuteqpxWZkvNkVbf2UYQLRPDPW0it7pqxXweNhbXyIxZ+tgk5dgWvO3Vg6NVe0F7TUSRrd3e8Kbdh80AjLUbE6GqheqfxlYA/fBcJaBb6rD33M= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=VddpJUdH; arc=fail smtp.client-ip=52.101.52.8 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="VddpJUdH" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=EhajPZhU1BYNwUIbNtVGefh6N0OvQOHQ764y0309AZM+Jsp/6I1eZmM/X70NQr66CG9UY4rt7ON+ldnN6if/D2eNE02zaeGoSVyRUZSk20dGbhu/vZOLtrPeaR8Gzzfkn1K7yFp41f9xQH3sMrwMWJxxcrJP7Uu7jvfauItYq3u29JDuZBjCbJGxbvIPau1gVpXErrd9kmM5eLVGHvbDGl3gjs0rKXpGFKiwzXfY3YG8mmECjAl+k83ddbqZT/kUjH5ZG0yrsv9i4TVx2wN6VWZrkA60TiFDO2ZAgYNtODCrYqdBoxAjx8MNj05vvlRk8sYypfCuoe4qGg8uBl5Sqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=jPOeu0CoNKd2KdnippYDzdSf360pLV/BSVzDzxhxSzQ=; b=WDygq9PE8JmSI6kykKs4+xhmTfHYoC+WLl3QxObxv721sg6lGDW10wTRThk5rJN9eN7I+36KGtGRdBnukqeNqukjzklgEcj1ltQC1dkrNno45e0bYEBQ1eiYix9Vwt7cHnb/JG1HpdhE1ndaVtNERAE29C7paYQ7jCYVzJ38JygmMdM5iXx0BuJrINV/ad0J7GtrOOj8xqgkgIpTbWpXpZvVGoNG+fk3Zp+U484sN9JCG7FFVyt4hbCUMcBlffcPgP0fTsHW/o2rk88yTeIPYSYuS4mrcuWJgAYFbRXE+ZdfRmYUZZUK4fb32JOZci4zwtiDd3nN1RPwLHOSOVGsHQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jPOeu0CoNKd2KdnippYDzdSf360pLV/BSVzDzxhxSzQ=; b=VddpJUdH9vvPu2Drkk9YKEzTi/VAV/yQQKgYN7l2zOlcVR3hOWiJ+xY+Ko/78JTy4t1RIPTvesc4wdU2ThGB63rOGh9m9j4gNMw3LIx/CgVt3MZHgjcyZcCG19zoWClj8xSbXNGo9Zknm/nuGkzVIPVfRCNpJwrQeFbih2//hL8= Received: from MW4P220CA0021.NAMP220.PROD.OUTLOOK.COM (2603:10b6:303:115::26) by MN0PR12MB6029.namprd12.prod.outlook.com (2603:10b6:208:3cf::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.24; Fri, 7 Aug 2026 10:45:46 +0000 Received: from SJ1PEPF000023D7.namprd21.prod.outlook.com (2603:10b6:303:115:cafe::96) by MW4P220CA0021.outlook.office365.com (2603:10b6:303:115::26) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.23 via Frontend Transport; Fri, 7 Aug 2026 10:45:45 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D7.mail.protection.outlook.com (10.167.244.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:45:45 +0000 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:43 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:38 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 12/20] net: dsa: xilinx: register per-MAC MDIO buses Date: Fri, 7 Aug 2026 16:14:23 +0530 Message-ID: <20260807104431.157230-13-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D7:EE_|MN0PR12MB6029:EE_ X-MS-Office365-Filtering-Correlation-Id: 26ead036-2a87-4f97-ad10-08def471092c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|376014|23010399003|36860700016|1800799024|82310400026|921020|6133799003|10067099003|11063799006|56012099006|22082099003|18002099003|3023799007; X-Microsoft-Antispam-Message-Info: y6C2utmDFOxz1+7bxW2RK0wmMui9JZnCncrIyVpAps55p40ChEqzNrfGJkmdBDRoD0zR20zgtPOVy5bHYMVsFE+zpVWQzsGJQrt4C9aZeWQXHJiEwqqiWaZgXHkZ1p7oEfprlDsD1Vcd1w3DQibNFlK2J9/8TQeDaa9a+Dagwpno1Z4AYXleyEw34oHiB90v6Z7/z85ShdSiM8JQsYXUkk0JyOW9ePVt+QcH3e0HCLrH184iYOvfPK4XS5XJjY8SuMqeUKO6QS7izgrJTzU5FZGs+Tx09qYzwaRijenrHb9KwbN+0JA1asTod3g9gcdfE6gRX7rdKn2Z99c6YtL6cJ7NuVsGYomnMFq5jn2AiPIKKBcayU0cLJJSAFcSslxcCKDmq4B5jqYzQ+kfmeJq+YDBvbn99itusSuh/ZYK2LGQMDOKFwHkUbLV4/JnjyJWIbTIQs91psEJChThL+7fkHaTxxsF/r9ZygBpMarIdQkwOgW1SET3/NBsDse4uBXcKOFspbq60l0WIY68nScRr3I031culGjZBK6hMn3VlfPTK3lSbe83sWxCn0ZOdCT6wTyXF0ciUoPcJn7/dwaRw7zGkv4Si4G827d1giFdSoeTrK8KVYB/Nincc6Swo8pNv02ffm32XWCpbqhg0NJy8fPyKmOMj/kT1D83mgWcEiZfdEWolKCLfQUEaEAeFIRa0H0w8FC/dPLqigpoXN/XB+i3fF9GOK/EeZAxyew6kfxwZm1XaJ1dIqQv3gg3mcJg X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(7416014)(376014)(23010399003)(36860700016)(1800799024)(82310400026)(921020)(6133799003)(10067099003)(11063799006)(56012099006)(22082099003)(18002099003)(3023799007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: SETF4ugH9MadoLD3LaUJovhx8hwk+kFslREP0I+BUVpx6YupJGrN2zfg6W59NDpe6MZ4NviGKcaiu3+TwkNaLppuZC0KWv6toZqKjxNOy1fzyjUNc1MXY/PBl3l61AciouxvSvGsXU2RB7SAeSwH2F8uNtBaMAbDhKuAT77BC4htf+mAB+L0t1OCjWHIi4fU5qEb4ozNlOzQoeKzLCLDOoJVuC5pbBZ+MY2Rai5R5kavTYweY2jayQO7RtT180gxEQ1ZuaViTeaVZuOalPYZiaHXK/UX5x9L8VZdX+U6EIyk/QMfpgE74hdvKUCJK2eAE+l3kU0qLXW4P+kbxhlYa5fT7gxOJwnyKHC/hmijhEWpRaMnPWHo1T1HgyrZx1njbdFfAIk11WIXF/76Hn4ww0Z582tJ8fT979Ljy/i8Qkw85/yBP/ay50A5k2aM0AZy X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:45.4338 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 26ead036-2a87-4f97-ad10-08def471092c X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D7.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN0PR12MB6029 Content-Type: text/plain; charset="utf-8" The TSN IP exposes one MDIO controller per MAC at +0x500 inside each MAC's register window. Register each bus under the matching mdio-mac1 / mdio-mac2 child of the switch node. A new struct xlnx_tsn_mac groups the per-MAC register window and the back-pointer to the parent switch. MDIO callbacks and log helpers pull what they need from it. The clock divisor comes from the IP-wide s_axi clock, owned by the parent IP wrapper node, so read its rate from there rather than holding a private reference. Co-developed-by: Srinivas Neeli Signed-off-by: Srinivas Neeli Signed-off-by: Nagadheeraj Rottela --- drivers/net/dsa/xilinx/xilinx_tsn.c | 203 +++++++++++++++++++++++++++- drivers/net/dsa/xilinx/xilinx_tsn.h | 54 +++++++- 2 files changed, 251 insertions(+), 6 deletions(-) diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c index 020b1622670c..542b74514ed3 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -4,17 +4,24 @@ */ =20 #include +#include #include #include #include #include +#include #include #include +#include +#include #include #include =20 #include "xilinx_tsn.h" =20 +#define TSN_MDIO_MAX_FREQ_HZ 2500000 +#define TSN_MDIO_READY_TIMEOUT_US 20000 + static void sw_iow(struct xlnx_tsn *sw, u32 off, u32 val) { iowrite32(val, sw->sw_base + off); @@ -95,6 +102,190 @@ static int xlnx_tsn_set_port_state(struct xlnx_tsn *sw= , int port, return 0; } =20 +static int xlnx_tsn_mdio_wait_ready(struct xlnx_tsn_mac *m) +{ + u32 val; + + return readl_poll_timeout(m->regs + TSN_MDIO_MCR_OFFSET, val, + val & TSN_MDIO_MCR_READY, 1, + TSN_MDIO_READY_TIMEOUT_US); +} + +static int xlnx_tsn_mdio_read(struct mii_bus *bus, int phy_id, int reg) +{ + struct xlnx_tsn_mac *m =3D bus->priv; + int ret; + + ret =3D xlnx_tsn_mdio_wait_ready(m); + if (ret < 0) + return ret; + + mac_iow(m, TSN_MDIO_MCR_OFFSET, + FIELD_PREP(TSN_MDIO_MCR_PHYAD_MASK, phy_id) | + FIELD_PREP(TSN_MDIO_MCR_REGAD_MASK, reg) | + TSN_MDIO_MCR_INITIATE | TSN_MDIO_MCR_OP_READ); + + ret =3D xlnx_tsn_mdio_wait_ready(m); + if (ret < 0) + return ret; + + return FIELD_GET(TSN_MDIO_MRD_MASK, + mac_ior(m, TSN_MDIO_MRD_OFFSET)); +} + +static int xlnx_tsn_mdio_write(struct mii_bus *bus, int phy_id, int reg, + u16 val) +{ + struct xlnx_tsn_mac *m =3D bus->priv; + int ret; + + ret =3D xlnx_tsn_mdio_wait_ready(m); + if (ret < 0) + return ret; + + mac_iow(m, TSN_MDIO_MWD_OFFSET, val); + mac_iow(m, TSN_MDIO_MCR_OFFSET, + FIELD_PREP(TSN_MDIO_MCR_PHYAD_MASK, phy_id) | + FIELD_PREP(TSN_MDIO_MCR_REGAD_MASK, reg) | + TSN_MDIO_MCR_INITIATE | TSN_MDIO_MCR_OP_WRITE); + + return xlnx_tsn_mdio_wait_ready(m); +} + +/* Round up so the MDC frequency stays at or below TSN_MDIO_MAX_FREQ_HZ, + * then clamp to the 6-bit field maximum so the value stays within the + * field and does not corrupt TSN_MDIO_MC_MDIOEN. + */ +static u32 xlnx_tsn_mdio_clk_div(struct xlnx_tsn *sw, unsigned long host_h= z) +{ + u32 div; + + if (!host_hz) { + dev_warn(sw->dev, + "s_axi clock rate unknown; clamping MDIO divisor to max\n"); + return TSN_MDIO_MC_CLOCK_DIVIDE_MAX; + } + + div =3D DIV_ROUND_UP(host_hz, TSN_MDIO_MAX_FREQ_HZ * 2) - 1; + + /* HW ignores MDIO Enable when Clock Divide is 0 */ + if (!div) + div =3D 1; + + if (div > TSN_MDIO_MC_CLOCK_DIVIDE_MAX) { + dev_warn(sw->dev, + "MDIO divisor %u exceeds max %u, clamping\n", + div, TSN_MDIO_MC_CLOCK_DIVIDE_MAX); + div =3D TSN_MDIO_MC_CLOCK_DIVIDE_MAX; + } + + return div; +} + +static int xlnx_tsn_mdio_register_one(struct xlnx_tsn *sw, int port, + const char *child_name, + unsigned long host_hz) +{ + struct xlnx_tsn_mac *m =3D &sw->mac[port]; + struct device_node *mdio_np; + struct mii_bus *bus; + int ret; + + mdio_np =3D of_get_child_by_name(sw->dev->of_node, child_name); + if (!mdio_np) + return 0; + + bus =3D devm_mdiobus_alloc(sw->dev); + if (!bus) { + of_node_put(mdio_np); + return -ENOMEM; + } + + snprintf(bus->id, MII_BUS_ID_SIZE, "%s:%s", + dev_name(sw->dev), child_name); + bus->name =3D "Xilinx TSN MDIO"; + bus->priv =3D m; + bus->parent =3D sw->dev; + bus->read =3D xlnx_tsn_mdio_read; + bus->write =3D xlnx_tsn_mdio_write; + + mac_iow(m, TSN_MDIO_MC_OFFSET, + xlnx_tsn_mdio_clk_div(sw, host_hz) | TSN_MDIO_MC_MDIOEN); + + ret =3D xlnx_tsn_mdio_wait_ready(m); + if (ret) { + dev_err(sw->dev, "%s: MDIO controller not ready: %d\n", + child_name, ret); + goto err_put_np; + } + + ret =3D of_mdiobus_register(bus, mdio_np); + if (ret) { + dev_err(sw->dev, "%s: failed to register MDIO bus: %d\n", + child_name, ret); + goto err_put_np; + } + + m->mii_bus =3D bus; + of_node_put(mdio_np); + return 0; + +err_put_np: + of_node_put(mdio_np); + return ret; +} + +static void xlnx_tsn_mdio_unregister_all(struct xlnx_tsn *sw) +{ + int port; + + for (port =3D XLNX_TSN_PORT_MAC1; port <=3D XLNX_TSN_PORT_MAC2; port++) { + struct xlnx_tsn_mac *m =3D &sw->mac[port]; + + if (m->mii_bus) { + mdiobus_unregister(m->mii_bus); + m->mii_bus =3D NULL; + } + + /* clear the enable bit even when no bus was registered (failed probe) */ + mac_iow(m, TSN_MDIO_MC_OFFSET, 0); + } +} + +static int xlnx_tsn_mdio_register_all(struct xlnx_tsn *sw) +{ + unsigned long host_hz; + struct clk *s_axi; + int ret; + + /* per-MAC MDIO divisor comes from the wrapper node's s_axi + * clock + */ + s_axi =3D clk_get(sw->dev->parent, "s_axi"); + if (IS_ERR(s_axi)) + return dev_err_probe(sw->dev, PTR_ERR(s_axi), + "failed to get s_axi clock\n"); + + host_hz =3D clk_get_rate(s_axi); + clk_put(s_axi); + + ret =3D xlnx_tsn_mdio_register_one(sw, XLNX_TSN_PORT_MAC1, "mdio-mac1", + host_hz); + if (ret) + goto err_unregister; + + ret =3D xlnx_tsn_mdio_register_one(sw, XLNX_TSN_PORT_MAC2, "mdio-mac2", + host_hz); + if (ret) + goto err_unregister; + + return 0; + +err_unregister: + xlnx_tsn_mdio_unregister_all(sw); + return ret; +} + static enum dsa_tag_protocol xlnx_tsn_get_tag_protocol(struct dsa_switch *= ds, int port, enum dsa_tag_protocol mp) @@ -160,7 +351,7 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) return ret; } =20 - return 0; + return xlnx_tsn_mdio_register_all(sw); } =20 static void xlnx_tsn_teardown(struct dsa_switch *ds) @@ -168,6 +359,8 @@ static void xlnx_tsn_teardown(struct dsa_switch *ds) struct xlnx_tsn *sw =3D ds->priv; struct dsa_port *dp; =20 + xlnx_tsn_mdio_unregister_all(sw); + dsa_switch_for_each_user_port(dp, ds) xlnx_tsn_set_port_state(sw, dp->index, TSN_PORT_STATE_DISABLED); =20 @@ -207,16 +400,20 @@ static int xlnx_tsn_probe(struct platform_device *pde= v) return -ENOMEM; =20 sw->dev =3D dev; + sw->mac[XLNX_TSN_PORT_MAC1].sw =3D sw; + sw->mac[XLNX_TSN_PORT_MAC2].sw =3D sw; =20 ret =3D xlnx_tsn_map_reg(pdev, "switch", &sw->sw_base); if (ret) return ret; =20 - ret =3D xlnx_tsn_map_reg(pdev, "mac1", &sw->mac_base[XLNX_TSN_PORT_MAC1]); + ret =3D xlnx_tsn_map_reg(pdev, "mac1", + &sw->mac[XLNX_TSN_PORT_MAC1].regs); if (ret) return ret; =20 - ret =3D xlnx_tsn_map_reg(pdev, "mac2", &sw->mac_base[XLNX_TSN_PORT_MAC2]); + ret =3D xlnx_tsn_map_reg(pdev, "mac2", + &sw->mac[XLNX_TSN_PORT_MAC2].regs); if (ret) return ret; =20 diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/x= ilinx_tsn.h index 1064cf1ce66e..025645a83992 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.h +++ b/drivers/net/dsa/xilinx/xilinx_tsn.h @@ -7,6 +7,7 @@ =20 #include #include +#include #include #include =20 @@ -45,19 +46,66 @@ enum tsn_port_state { TSN_PORT_STATE_FORWARDING, }; =20 +/* Per-MAC MDIO controller register window, sitting at +0x500 inside + * each MAC's reg space owned via reg-names =3D "mac1", "mac2". + */ +#define TSN_MDIO_MC_OFFSET 0x00000500 +#define TSN_MDIO_MCR_OFFSET 0x00000504 +#define TSN_MDIO_MWD_OFFSET 0x00000508 +#define TSN_MDIO_MRD_OFFSET 0x0000050c + +#define TSN_MDIO_MC_MDIOEN BIT(6) +#define TSN_MDIO_MC_CLOCK_DIVIDE_MAX 0x3f + +#define TSN_MDIO_MCR_PHYAD_MASK GENMASK(28, 24) +#define TSN_MDIO_MCR_REGAD_MASK GENMASK(20, 16) +#define TSN_MDIO_MCR_OP_READ BIT(15) +#define TSN_MDIO_MCR_OP_WRITE BIT(14) +#define TSN_MDIO_MCR_INITIATE BIT(11) +#define TSN_MDIO_MCR_READY BIT(7) + +#define TSN_MDIO_MRD_MASK GENMASK(15, 0) + +struct mii_bus; +struct xlnx_tsn; + +/** + * struct xlnx_tsn_mac - per-MAC switch-side state + * @sw: back-pointer to the parent switch (for dev_* logging in + * bus callbacks) + * @regs: per-MAC register window, from reg-name "macN" + * @mii_bus: MDIO bus registered under the "mdio-macN" DT child, + * or NULL if absent + */ +struct xlnx_tsn_mac { + struct xlnx_tsn *sw; + void __iomem *regs; + struct mii_bus *mii_bus; +}; + /** * struct xlnx_tsn - per-IP switch state * @ds: DSA switch * @dev: backing device * @sw_base: switch fabric register window - * @mac_base: per-MAC register windows, indexed by user-port number - * (index 0 unused; MAC1 at [1], MAC2 at [2]) + * @mac: per-MAC state, indexed by user-port number (index 0 unused; + * MAC1 at [1], MAC2 at [2]) */ struct xlnx_tsn { struct dsa_switch ds; struct device *dev; void __iomem *sw_base; - void __iomem *mac_base[XLNX_TSN_NUM_PORTS]; + struct xlnx_tsn_mac mac[XLNX_TSN_NUM_PORTS]; }; =20 +static inline void mac_iow(struct xlnx_tsn_mac *m, u32 off, u32 val) +{ + iowrite32(val, m->regs + off); +} + +static inline u32 mac_ior(struct xlnx_tsn_mac *m, u32 off) +{ + return ioread32(m->regs + off); +} + #endif /* _XILINX_TSN_H */ --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from PH0PR06CU001.outbound.protection.outlook.com (mail-westus3azon11011032.outbound.protection.outlook.com [40.107.208.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 53C9047013C; Fri, 7 Aug 2026 10:45:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.208.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099558; cv=fail; b=D2JC5ukOIOP12YJ0fu2Y6f+UPT01h9cz0gOI2+oe7oeXf16KA5S0Ck9ZXfe1BUB6MAUqxdsdrOYNDpzbGt2eAwlE1gDpXxvtjoEOD+ebnLuXGJPpMfQbq0x1CXoLq36UatMYssLX2NjSEIER8fBYk+iyMrA5PA+n0Lqmt9n+r88= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099558; c=relaxed/simple; bh=HoadEGgT7ytmADUnWVHtSZuE4Y01JvSSnw88nkjI4Eo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=oa8Y+JnJ1AgxPwWrN5ZlRAZttgpBisGFRTso03ZxstGp+8BzDnMv8OLkU+A5B6zO6L6LtQQR+BE+MDIWjrYWoyM5yzIF1AfCtQtSKfD9/dlXLWWarul9lrEpBL4XYMTBU+wNgz8zry3BXiq7qCp1dOpJk2E/44KLrTA2x0VuE4s= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=h/lHZVK1; arc=fail smtp.client-ip=40.107.208.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="h/lHZVK1" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=aBQRaK/IE20f66g5PqLsSZNRjbdWmeJjIv9HG9uGlszvEnj+wCZSAvgUrM03Ke4l+CepY0UamkDlHamnA+3TcjelOf532NjTAnUMjE8h/lm3jFLwC/tA1542lvAXyzE2017hXyuzFf52O6299NCw5rWstRt2osK3k2+0M+XKPAYqd622uBVR9UJl3NnxAeNgZSu4cFRVDE1RKoCEyvodDCd/xsfnJ/G3vploOZPOfEnGSkr9c2aoO8RMse/J8QM08CPiAI5UXZl58hxU8FyO7rgMXr/8hRjby8+Fk5RwBzOno6HGqsFYEglgKBECwaDC7+LK2pukJWq8ya7rMWfidg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=l9E8Oh4rIprG7h/tFPK9w7jSI7Ylms4PmocRKtjCTLU=; b=UhOCK2bDonLev3MwX7mw24rGtQrE+TxYUN0iQeMg7CSrCs+j8eXZ17ggflvejfJf0yV1rVYmgY9ggX/AGhitaIDA2sKcD7+XixjBqFxAlYzGzU2IFEiLk97UkMD0oSG1fsuw90ImaOz8in9YYg/ZuvgaaHPmgTmkwoRZhFteH8iFGQt/IV2JLN/k/kna3UNGYSdy6KZc361qJpm4c9MT3mn2w7XvfQ9RP9K9XeoO/E8cM7eWr3YLZoF9pMXC/L7Kv75513FEDqKwyEcPxKETLSoQGDEsH2oPzkT6bkRoeJyqStlxHjdlSxc1VCT6+LB9MAO4Az/0Qtwd4SKL0roGGQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=l9E8Oh4rIprG7h/tFPK9w7jSI7Ylms4PmocRKtjCTLU=; b=h/lHZVK1BWmDvwMRCS7RYD9+jz549ES/Dpar/WVeFJdWLFXBV0PKeqZMIdjCdPMF9MVMjn1SYV5x/R86/Qt9IfrlkKiqPR1ZWPJrWy8ydhePjTKk2sGEMb5ywWnC8z1CGXr0FHLwQtu1R4+20Ih0oAnSo9lVn7mEVUv+nwvzJW8= Received: from SJ0PR05CA0045.namprd05.prod.outlook.com (2603:10b6:a03:33f::20) by PH7PR12MB7308.namprd12.prod.outlook.com (2603:10b6:510:20c::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.21; Fri, 7 Aug 2026 10:45:51 +0000 Received: from SJ5PEPF000001E8.namprd05.prod.outlook.com (2603:10b6:a03:33f:cafe::1e) by SJ0PR05CA0045.outlook.office365.com (2603:10b6:a03:33f::20) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.315.8 via Frontend Transport; Fri, 7 Aug 2026 10:45:51 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SJ5PEPF000001E8.mail.protection.outlook.com (10.167.242.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.6 via Frontend Transport; Fri, 7 Aug 2026 10:45:51 +0000 Received: from Satlexmb09.amd.com (10.181.42.218) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:50 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb09.amd.com (10.181.42.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 03:45:49 -0700 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:44 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 13/20] net: dsa: xilinx: wire up phylink for the switch ports Date: Fri, 7 Aug 2026 16:14:24 +0530 Message-ID: <20260807104431.157230-14-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001E8:EE_|PH7PR12MB7308:EE_ X-MS-Office365-Filtering-Correlation-Id: abb933ad-e773-4947-5061-08def4710c9b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|1800799024|36860700016|7416014|23010399003|82310400026|18002099003|22082099003|921020|6133799003|10067099003|5023799004|56012099006|11063799006; X-Microsoft-Antispam-Message-Info: r1CkI5wsU4jjW9zEWWpzDslYpmQU/ALfAr551+ys3bJJ9OPwuxJ4BhR+HtO+uzaKzVv8AyAg0iQuQ/wpNxUhkArRTPvy799rZXj6GVIdxzRfa/fuXx+oaeC8MEj95Dd2Y8z94798zOpxV9/GXB6Xe/WN4Fln32Ma09xoecvQ/lUq/BoYUxg/mp6Eye4iRsfmvnELkK0PIN3DtMoWFF2tOFnjhA4KKj4xNp5JIaVr7cbXHvDN7ieToKiL22vbTrDLZa7xf21J+lsLK/xggugvTcLhvii3ebO/7wNN2b3ufTAqtWRSQ8pOPuRTGHFnAqZ90vPMVRRHLZoAUZTV7gMnWvn2f92YY54YImnG/7jNHxCXOq3QRzZS1OgCwWRrug1uTT9KL2rhGnoVUCcYdh7UsIWFo86X8wsDfu7JOvlAEr75lJWJOYlg6I+7CdpR9N7ONUpMzxdLdq/VHuttVkoqRtiZ1fCxN8fHX5hA77av2OtQvS9cl0is2QoPfctom2kjKqXonn8rS4H8+WBcdT+wArbvwAV5buFW8gnpmBaxTYFSm9qfy7ti1JXrwPReu60Lkc8D+6MrH6/NCIyBFix1fc4GyJCq8UvZLK8VeSJ94zm1zqsDQzwvi1HoLK760H1ci192fEWwLtMndgt5V1R+MqJFKnWs1EuE96Zh5V9hvAE4Bji3JPPw3uolaOANGnVY91pR2OTw0yt8w8TBi4d170mK0zbRPceqGbUtDjgiMtcAWsnvC9bjwbHl1p5fyKOn X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(1800799024)(36860700016)(7416014)(23010399003)(82310400026)(18002099003)(22082099003)(921020)(6133799003)(10067099003)(5023799004)(56012099006)(11063799006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: yofZsWMQKYf66pVqe/0CTlTFNaYWkLSRymwGOL3QqinSGjpQs7Ip+sXZdtYHnFakId464+37I1ChOYoXP7+r/5kVtOinHkRMGU89CUUjx3ZIbhx8Z98cg5EVKhiYelar5BP2jlHG8p/oQNqgzHwTxTrGj6w0b+MudK+ZHvEtGYzu6GEZko2ou7EpMW2UgOht8gTx959ZS6iC0s7OIXWDeYtJAmWM78iNCAuTV9AxEapglH6gkY+jOZCw2XSnOSmI3jMd9bnmVSNHXLykoM4IK0u219rFTlW0Vg0upl6s9vWKOxTNgKoGltLnIx9cRdwLNXZNTUqh4JxTSgp6TSoDfqQ2EbGfZNM2NZpsjQELkZxb763k0rwLLaYOR2URHkRewXI+f4BtrDIEpOHLlWMse7cE4ZICFl7/kIBFON6Jd+zKZIhu4J12kJBw1s568Cnv X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:51.1828 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: abb933ad-e773-4947-5061-08def4710c9b X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001E8.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB7308 Content-Type: text/plain; charset="utf-8" Wire up the MAC-side phylink ops for all three switch ports. For the two external user ports, phylink_get_caps fills supported_interfaces with RGMII variants, SGMII, and GMII, and sets mac_capabilities to MAC_100FD and MAC_1000FD. The speed-config field only encodes those two speeds, so 10 Mbps and half-duplex are not reachable in hardware. The CPU port has no external PHY. Its link is internal and fixed at MAC_1000FD, so phylink_get_caps sets PHY_INTERFACE_MODE_INTERNAL and returns early for it. mac_link_up programs the resolved speed into the speed-config field and sets TX_EN and RX_EN to allow frames to flow. mac_link_down clears them. mac_config is intentionally empty. The interface mode is fixed at IP synthesis time and there is no runtime register to program. Co-developed-by: Srinivas Neeli Signed-off-by: Srinivas Neeli Signed-off-by: Nagadheeraj Rottela --- drivers/net/dsa/xilinx/xilinx_tsn.c | 102 ++++++++++++++++++++++++++++ drivers/net/dsa/xilinx/xilinx_tsn.h | 12 ++++ 2 files changed, 114 insertions(+) diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c index 542b74514ed3..86aba2e8b6e9 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include =20 @@ -324,6 +325,105 @@ static void xlnx_tsn_port_stp_state_set(struct dsa_sw= itch *ds, int port, xlnx_tsn_set_port_state(sw, port, hw_state); } =20 +static void xlnx_tsn_phylink_get_caps(struct dsa_switch *ds, int port, + struct phylink_config *config) +{ + if (port =3D=3D XLNX_TSN_CPU_PORT) { + config->mac_capabilities =3D MAC_1000FD; + __set_bit(PHY_INTERFACE_MODE_INTERNAL, + config->supported_interfaces); + return; + } + + /* The MAC's speed-config field only encodes 100 / 1000. + * Half-duplex and 10 Mbps are not supported. + */ + config->mac_capabilities =3D MAC_100FD | MAC_1000FD; + phy_interface_set_rgmii(config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_SGMII, config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_GMII, config->supported_interfaces); +} + +static void xlnx_tsn_mac_config(struct phylink_config *config, + unsigned int mode, + const struct phylink_link_state *state) +{ + /* Interface mode (RGMII / SGMII / GMII) is fixed at IP synthesis + * time. There is no runtime register to program it here. + */ +} + +static void xlnx_tsn_mac_link_down(struct phylink_config *config, + unsigned int mode, + phy_interface_t interface) +{ + struct dsa_port *dp =3D dsa_phylink_to_port(config); + struct xlnx_tsn *sw =3D dp->ds->priv; + struct xlnx_tsn_mac *m; + u32 rcw1, tc; + + m =3D &sw->mac[dp->index]; + + /* The CPU port has no switch-side MAC registers. Nothing to + * tear down here (see xlnx_tsn_mac_link_up). + */ + if (dp->index =3D=3D XLNX_TSN_CPU_PORT) + return; + + tc =3D mac_ior(m, TSN_TC_OFFSET) & ~TSN_TC_TX_EN; + mac_iow(m, TSN_TC_OFFSET, tc); + + rcw1 =3D mac_ior(m, TSN_RCW1_OFFSET) & ~TSN_RCW1_RX_EN; + mac_iow(m, TSN_RCW1_OFFSET, rcw1); +} + +static void xlnx_tsn_mac_link_up(struct phylink_config *config, + struct phy_device *phy, unsigned int mode, + phy_interface_t interface, int speed, + int duplex, bool tx_pause, bool rx_pause) +{ + struct dsa_port *dp =3D dsa_phylink_to_port(config); + struct xlnx_tsn *sw =3D dp->ds->priv; + u32 speed_cfg, rcw1, tc; + struct xlnx_tsn_mac *m; + + m =3D &sw->mac[dp->index]; + + /* The CPU port is the internal endpoint MAC. It has no switch-side + * MAC registers and is managed by the endpoint driver, not here. + */ + if (dp->index =3D=3D XLNX_TSN_CPU_PORT) + return; + + speed_cfg =3D mac_ior(m, TSN_SPEED_CFG_OFFSET) & ~TSN_SPEED_CFG_MASK; + switch (speed) { + case SPEED_1000: + speed_cfg |=3D TSN_SPEED_CFG_1000; + break; + case SPEED_100: + speed_cfg |=3D TSN_SPEED_CFG_100; + break; + default: + dev_warn(sw->dev, + "port %d: unsupported link speed %d Mbps\n", + dp->index, speed); + return; + } + mac_iow(m, TSN_SPEED_CFG_OFFSET, speed_cfg); + + rcw1 =3D mac_ior(m, TSN_RCW1_OFFSET) | TSN_RCW1_RX_EN; + mac_iow(m, TSN_RCW1_OFFSET, rcw1); + + tc =3D mac_ior(m, TSN_TC_OFFSET) | TSN_TC_TX_EN; + mac_iow(m, TSN_TC_OFFSET, tc); +} + +static const struct phylink_mac_ops xlnx_tsn_phylink_mac_ops =3D { + .mac_config =3D xlnx_tsn_mac_config, + .mac_link_up =3D xlnx_tsn_mac_link_up, + .mac_link_down =3D xlnx_tsn_mac_link_down, +}; + static int xlnx_tsn_setup(struct dsa_switch *ds) { struct xlnx_tsn *sw =3D ds->priv; @@ -372,6 +472,7 @@ static const struct dsa_switch_ops xlnx_tsn_switch_ops = =3D { .setup =3D xlnx_tsn_setup, .teardown =3D xlnx_tsn_teardown, .port_stp_state_set =3D xlnx_tsn_port_stp_state_set, + .phylink_get_caps =3D xlnx_tsn_phylink_get_caps, }; =20 static int xlnx_tsn_map_reg(struct platform_device *pdev, const char *name, @@ -421,6 +522,7 @@ static int xlnx_tsn_probe(struct platform_device *pdev) ds->dev =3D dev; ds->num_ports =3D XLNX_TSN_NUM_PORTS; ds->ops =3D &xlnx_tsn_switch_ops; + ds->phylink_mac_ops =3D &xlnx_tsn_phylink_mac_ops; ds->priv =3D sw; =20 platform_set_drvdata(pdev, sw); diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/x= ilinx_tsn.h index 025645a83992..6286caff7a1c 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.h +++ b/drivers/net/dsa/xilinx/xilinx_tsn.h @@ -66,6 +66,18 @@ enum tsn_port_state { =20 #define TSN_MDIO_MRD_MASK GENMASK(15, 0) =20 +/* Per-MAC receive / transmit / speed configuration registers. */ +#define TSN_RCW1_OFFSET 0x00000404 +#define TSN_RCW1_RX_EN BIT(28) + +#define TSN_TC_OFFSET 0x00000408 +#define TSN_TC_TX_EN BIT(28) + +#define TSN_SPEED_CFG_OFFSET 0x00000410 +#define TSN_SPEED_CFG_MASK GENMASK(31, 30) +#define TSN_SPEED_CFG_100 BIT(30) +#define TSN_SPEED_CFG_1000 BIT(31) + struct mii_bus; struct xlnx_tsn; =20 --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from SJ2PR03CU001.outbound.protection.outlook.com (mail-westusazon11012009.outbound.protection.outlook.com [52.101.43.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6270B470EA2; Fri, 7 Aug 2026 10:46:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.43.9 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099564; cv=fail; b=ELv89Sf80azevaMj00rLkHLUGwBr+R2dP0y8c2bd7aWI1Ao9MQq0fhviiYWFm2t5wjKc5zHJ1n7YJoQHb7pC5JFHJCiZ+lEsR2W7f7ZyAgrdNIHUlO/FFWDv8sRV+Olxubrj5nsbNCybEksnm42k+1AMfO11kLl1BjfUWCrMcX0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099564; c=relaxed/simple; bh=Qi3WN1vMCqZV6up4If/VMYNsugPjmvF0XJrsPz62Gzo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OSOOma4WLHmYbIdhbCBwPCkoB2a6JaLYLkgGIwaFF/ABvrQTz8jA0ksGFYchPXwnVHJfTun//zsSyeHmd57iTxqreW8kEWw7G1AgKnhbiEBkBII9R1shiXxQ6v8APFLINfuow0UQBcxQoDS5nl2Fso1uwTgduTv78SojtnoAZGc= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=0N+psR4N; arc=fail smtp.client-ip=52.101.43.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="0N+psR4N" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=OXECfYn6nSpwsI7FFe/VEN6gkQyVWRqREZRGjp3hRCAPz3jRrEkGxuX63zmZVutgQmSGlg9f4j4AH7EtUwELhZDHeqio85tRV1/+PUBfLTT5sq1rulpb1PtCje0NHr/IaML2TK+HpEseGBrQBBYsvDWcLAplQ0Qsd/BEdv7YHbzBXe6pNfj9+issNLksvAOpJdBQo7YoFwHntdUa3lAOu2lK3cgXWhZvS7/lf4KdO2l8DGYK544eE/5Ifos3VFCiUiks9vYenK2YqW81NNWXX2AMpUm324PMv9SuNn2VYrj53dK+ES/7Vr/KWfmRVWX7EjaSBQvIbNbEQbXRUmZifQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=6Sr1sb/O0aCK8QKKzAyL/9lHzwht58GnRXMrOOp4IwY=; b=S5shMqPDn6wQAOeQcnlVS4h6SWhV3R81iXC/y7MkKmzRfpX5pfQDGv53300o0SRzUDa8Khn/pOgC9zZR/pR6UW+B+CM/pwDwMR3n1DkDxq+zjcnSStxYKhyaJFW7l0OaxPebbx3JOOc0EwZuOYIYsxXsEygiutgt6HU+PNGKqKy38RaeCZj6V8xBDFPhjD9EIjPFghricQsdT8RP/4Vgnrase3iF5VrDmB0JtpkagOW7P1wOHDhQ4vfDM81+FP+BQdnNi7m4XENqOXnIZStyzY7bDLhRO12GfajeCvgDtIF04YxomNI4MMIpEoA5CwC0ihIoQcZv/qR56qJDGg+feg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6Sr1sb/O0aCK8QKKzAyL/9lHzwht58GnRXMrOOp4IwY=; b=0N+psR4NvAreSWXqwo8/j0P7/Xr2+Vvo+rr9bGevOfHuY9l4inFBvhiFZqHh153N4D0JR+dBNGr25+pqnSVtrJZv3b/nuaS2NvgMB/bBFngFQRLRd0Lru/4Aki4VISNFFjxRDaKUV3mr7QMBkTO9WhuFCfBJT8yRB1q5KntA88A= Received: from SJ0PR13CA0221.namprd13.prod.outlook.com (2603:10b6:a03:2c1::16) by MW3PR12MB4474.namprd12.prod.outlook.com (2603:10b6:303:2e::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.15; Fri, 7 Aug 2026 10:45:57 +0000 Received: from SJ1PEPF000023D6.namprd21.prod.outlook.com (2603:10b6:a03:2c1:cafe::a6) by SJ0PR13CA0221.outlook.office365.com (2603:10b6:a03:2c1::16) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.315.8 via Frontend Transport; Fri, 7 Aug 2026 10:45:57 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D6.mail.protection.outlook.com (10.167.244.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.339.0 via Frontend Transport; Fri, 7 Aug 2026 10:45:56 +0000 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:45:54 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:49 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 14/20] net: dsa: xilinx: program MAC frame filter and per-port nibbles Date: Fri, 7 Aug 2026 16:14:25 +0530 Message-ID: <20260807104431.157230-15-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D6:EE_|MW3PR12MB4474:EE_ X-MS-Office365-Filtering-Correlation-Id: 1e48f40f-b9f7-451b-79e9-08def4710fb9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|1800799024|36860700016|7416014|376014|23010399003|11063799006|56012099006|10067099003|22082099003|18002099003|3023799007|921020; X-Microsoft-Antispam-Message-Info: ody5cAQAlHjix3lXw+ajYsiTqHURoiGPXbl8UcTnhlvbVIcRBl8o97DdJhMQY5gM+s0fgt6R4L7rPWu/WvKmHdhMAIsTIUfk2l+dcXtWWlHKN0NMDbZR0pxy964UweOlSTpTyn7xs4b5gZcEgW1JZclikssNsQgd8LTWEkhmTmTbNBt/vge01vr7OjZsdZl2NlWL/RP4Zj0G4z9xYRzXTA2wZFJ9dlp66hLXOIloXoD28iiMl4FZ7lpOlS0zhxTWs0ra/58TYtyPkdFEJ9DPl8DxgvDydgvVFvKXvEpBeU6a8kYt/SM5sMQuRuZzocT+/6DOcZGcxbF6C1RF/ZoYEqkt8fpcbJxEoPoEj+d2+Bi7soCdr6YD3XZMQPkPqGmDMYHXgM1YzI1bfA4accS6hPkIirIeRjWw5LN7lsyIReQOpk2gpQ6CIgG9dqhzbpCUbD+b24BNY6xML200siXbjsoQOISx9FJk/RpjxeZjmqhSJmL2jsD+oBa7jF0RNaPZSxhpWzJZRgeQuZlhP3sdPESTsXL2JpkQAhoyKQ36EwtqFSOwR8+QdeAxPrRyr1TBDV3VIGCA9wy+747XKyZl9OpgiEsyNtQTLmIR7cDxUOi2MCmncDplvEiP9Fsr44DclqMzGZMXnubf1LOP7zfjejWbA8fmFSRTohtRhML4jmD4hSm/ZgNytrF45oH64e9lKgZxX+a4xC6WD132Xan8Ao0aGYHhWSZGorxlN78FlG6+aftsoun7TSatrhc9I//+ X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(1800799024)(36860700016)(7416014)(376014)(23010399003)(11063799006)(56012099006)(10067099003)(22082099003)(18002099003)(3023799007)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: oX3337Y64yZKBa2ElCQeQf8MZjRlsf4/j0MPtwIs5cVR4hUtADuhgZN2dVSYOiqUqJhz8f/zx0NCZtM+ssdBXwS31FcRGcDbTX9lwSgFgB0KYdsHlPO1oQBYwUlMjWTo087fufL7HkyJl7NXuATTof3hWGzW+N3I3iDcH4M6DcBtxh6ZdPpCbXUv9qxP378F0MmybDgzxX4sV5hK+eVsEQ05D9mPH3Ht6McsM65VQXxldfx3QZlACNas3C8eMStMHIYIg2vCy74j2J9jyMl3bXuPEESArblcqPwpFHaGgx63C1QFiQ0pkwOsOVVYdU/DCLDXoEOgYQIeDDJ8XhM+sQD13udb4Wz1JwAr8cxifOtg5s8RTIc5aM3w8SfP0R/qk8YghKVjrBYdFg4BZE4ND7BDHATZ7M5ZlA+dmXaRsDD2FN0BsymFtZLyIxm4j5yX X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:45:56.4196 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 1e48f40f-b9f7-451b-79e9-08def4710fb9 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D6.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW3PR12MB4474 Content-Type: text/plain; charset="utf-8" The switch fabric identifies a frame's destination port by matching its MAC against a 48-bit address in TSN_SW_MAC_LSB/TSN_SW_MAC_MSB, with a 16-bit mask covering bytes 4 and 5. Until the filter is programmed, every frame misses the classifier. Take the DSA conduit's MAC as a 44-bit prefix, wildcarding the low nibble of byte 5, and program both registers. Each of the three ports also owns a 4-bit MAC nibble field in the Switch Port State Control register at +0x004C. The field holds the low nibble of byte 5 of that port's MAC and covers the wildcarded bits, so the fabric can still tell the ports apart. Drive all of this from a netdev notifier. On the conduit's NETDEV_REGISTER, derive the prefix, program the frame filter, and set the CPU port nibbles for all ports. Handle NETDEV_REGISTER for each swpN to set its nibble. Reject port_set_mac_address whenever the requested address does not match the conduit's prefix, or its low nibble collides with the CPU port or another user port. The nibble is the only thing that tells ports apart once the top 44 bits are shared. Also route CPU-originated bridge control frames (STP, LLDP) to a single port by nibble match instead of flooding both, since the classifier can now tell one port's source MAC from the other's. Co-developed-by: Srinivas Neeli Signed-off-by: Srinivas Neeli Signed-off-by: Nagadheeraj Rottela --- drivers/net/dsa/xilinx/xilinx_tsn.c | 232 +++++++++++++++++++++++++++- drivers/net/dsa/xilinx/xilinx_tsn.h | 39 ++++- 2 files changed, 268 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c index 86aba2e8b6e9..9826f006b078 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -5,12 +5,14 @@ =20 #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -33,6 +35,74 @@ static u32 sw_ior(struct xlnx_tsn *sw, u32 off) return ioread32(sw->sw_base + off); } =20 +/* Cache the conduit MAC with byte 5's low nibble zeroed out. The + * frame-filter mask covers those 4 bits. The per-port MAC-nibble + * fields in +0x004C supply the actual values. + */ +static void xlnx_tsn_derive_prefix(struct xlnx_tsn *sw) +{ + memcpy(sw->mac_prefix, sw->conduit->dev_addr, ETH_ALEN); + sw->mac_prefix[5] &=3D ~TSN_SW_MAC_NIBBLE_WILDCARD; +} + +static void xlnx_tsn_program_frame_filter(struct xlnx_tsn *sw) +{ + const u8 *p =3D sw->mac_prefix; + u32 lsb, msb; + + lsb =3D ((u32)p[2] << 24) | ((u32)p[3] << 16) | + ((u32)p[4] << 8) | p[5]; + msb =3D FIELD_PREP(TSN_SW_MAC_MSB_MASK_MASK, TSN_SW_MAC_NIBBLE_WILDCARD) | + FIELD_PREP(TSN_SW_MAC_MSB_ADDR_MASK, + ((u32)p[0] << 8) | p[1]); + + sw_iow(sw, TSN_SW_MAC_LSB_OFFSET, lsb); + sw_iow(sw, TSN_SW_MAC_MSB_OFFSET, msb); +} + +/* True when addr's upper 44 bits match the cached prefix. The + * prefix has byte 5's low nibble already cleared, so byte 5 of addr + * is masked the same way before comparison. + */ +static bool xlnx_tsn_prefix_matches(struct xlnx_tsn *sw, const u8 *addr) +{ + if (memcmp(addr, sw->mac_prefix, ETH_ALEN - 1) !=3D 0) + return false; + + return (addr[5] & ~TSN_SW_MAC_NIBBLE_WILDCARD) =3D=3D sw->mac_prefix[5]; +} + +static int xlnx_tsn_set_port_mac_nibble(struct xlnx_tsn *sw, int port, + u8 nibble) +{ + u32 mask, new_field, reg; + + nibble &=3D TSN_SW_MAC_NIBBLE_WILDCARD; + + switch (port) { + case XLNX_TSN_CPU_PORT: + mask =3D EP_PORT_MAC_NIBBLE_MASK; + new_field =3D FIELD_PREP(EP_PORT_MAC_NIBBLE_MASK, nibble); + break; + case XLNX_TSN_PORT_MAC1: + mask =3D MAC1_PORT_MAC_NIBBLE_MASK; + new_field =3D FIELD_PREP(MAC1_PORT_MAC_NIBBLE_MASK, nibble); + break; + case XLNX_TSN_PORT_MAC2: + mask =3D MAC2_PORT_MAC_NIBBLE_MASK; + new_field =3D FIELD_PREP(MAC2_PORT_MAC_NIBBLE_MASK, nibble); + break; + default: + return -EINVAL; + } + + reg =3D sw_ior(sw, TSN_PORT_STATE_CTRL_OFFSET); + reg =3D (reg & ~mask) | new_field; + sw_iow(sw, TSN_PORT_STATE_CTRL_OFFSET, reg); + + return 0; +} + static int xlnx_tsn_switch_status_ready(struct xlnx_tsn *sw) { u32 reg; @@ -287,6 +357,112 @@ static int xlnx_tsn_mdio_register_all(struct xlnx_tsn= *sw) return ret; } =20 +/* Build a per-port MAC from the shared prefix. */ +static void xlnx_tsn_synth_port_mac(struct xlnx_tsn *sw, int port, + u8 *out) +{ + u8 ep_nibble =3D sw->conduit->dev_addr[5] & TSN_SW_MAC_NIBBLE_WILDCARD; + + memcpy(out, sw->mac_prefix, ETH_ALEN); + out[5] |=3D (ep_nibble + port) & TSN_SW_MAC_NIBBLE_WILDCARD; +} + +static int xlnx_tsn_user_port_index(struct xlnx_tsn *sw, + const struct net_device *dev) +{ + struct dsa_port *dp; + + dsa_switch_for_each_user_port(dp, &sw->ds) + if (dp->user =3D=3D dev) + return dp->index; + + return -1; +} + +static int xlnx_tsn_handle_user_register(struct xlnx_tsn *sw, + struct net_device *dev, int port) +{ + u8 want[ETH_ALEN]; + u8 nibble; + + if (!xlnx_tsn_prefix_matches(sw, dev->dev_addr)) { + xlnx_tsn_synth_port_mac(sw, port, want); + dev_warn(sw->dev, + "port %d: MAC %pM does not match conduit prefix; overriding to %pM\n", + port, dev->dev_addr, want); + dev_addr_mod(dev, 0, want, ETH_ALEN); + nibble =3D want[5] & TSN_SW_MAC_NIBBLE_WILDCARD; + } else if (ether_addr_equal(dev->dev_addr, sw->conduit->dev_addr)) { + /* Either DSA inherited the conduit MAC, or DT gave port@N + * the same address explicitly. Either way, assign a unique + * per-port nibble. + */ + xlnx_tsn_synth_port_mac(sw, port, want); + dev_addr_mod(dev, 0, want, ETH_ALEN); + nibble =3D want[5] & TSN_SW_MAC_NIBBLE_WILDCARD; + } else { + nibble =3D dev->dev_addr[5] & TSN_SW_MAC_NIBBLE_WILDCARD; + } + + return xlnx_tsn_set_port_mac_nibble(sw, port, nibble); +} + +static void xlnx_tsn_handle_conduit_changeaddr(struct xlnx_tsn *sw) +{ + struct dsa_port *dp; + + xlnx_tsn_derive_prefix(sw); + xlnx_tsn_program_frame_filter(sw); + xlnx_tsn_set_port_mac_nibble(sw, XLNX_TSN_CPU_PORT, + sw->conduit->dev_addr[5]); + + dsa_switch_for_each_user_port(dp, &sw->ds) { + u8 want[ETH_ALEN]; + + if (!dp->user) + continue; + + xlnx_tsn_synth_port_mac(sw, dp->index, want); + dev_addr_mod(dp->user, 0, want, ETH_ALEN); + call_netdevice_notifiers(NETDEV_CHANGEADDR, dp->user); + } +} + +static int xlnx_tsn_netdev_event(struct notifier_block *nb, + unsigned long event, void *ptr) +{ + struct xlnx_tsn *sw =3D container_of(nb, struct xlnx_tsn, nb); + struct net_device *dev =3D netdev_notifier_info_to_dev(ptr); + int port; + + switch (event) { + case NETDEV_REGISTER: + if (dev =3D=3D sw->conduit) { + xlnx_tsn_handle_conduit_changeaddr(sw); + } else { + port =3D xlnx_tsn_user_port_index(sw, dev); + if (port < 0) + return NOTIFY_DONE; + + xlnx_tsn_handle_user_register(sw, dev, port); + } + break; + case NETDEV_CHANGEADDR: + if (dev =3D=3D sw->conduit) { + xlnx_tsn_handle_conduit_changeaddr(sw); + } else { + port =3D xlnx_tsn_user_port_index(sw, dev); + if (port < 0) + return NOTIFY_DONE; + + xlnx_tsn_set_port_mac_nibble(sw, port, dev->dev_addr[5]); + } + break; + } + + return NOTIFY_DONE; +} + static enum dsa_tag_protocol xlnx_tsn_get_tag_protocol(struct dsa_switch *= ds, int port, enum dsa_tag_protocol mp) @@ -294,6 +470,30 @@ static enum dsa_tag_protocol xlnx_tsn_get_tag_protocol= (struct dsa_switch *ds, return DSA_TAG_PROTO_XLNX_TSN; } =20 +static int xlnx_tsn_port_set_mac_address(struct dsa_switch *ds, int port, + const unsigned char *addr) +{ + u8 nibble =3D addr[5] & TSN_SW_MAC_NIBBLE_WILDCARD; + struct xlnx_tsn *sw =3D ds->priv; + struct dsa_port *dp; + + if (!xlnx_tsn_prefix_matches(sw, addr)) + return -EINVAL; + + if (nibble =3D=3D (sw->conduit->dev_addr[5] & TSN_SW_MAC_NIBBLE_WILDCARD)) + return -EADDRINUSE; + + dsa_switch_for_each_user_port(dp, ds) { + if (dp->index =3D=3D port || !dp->user) + continue; + + if ((dp->user->dev_addr[5] & TSN_SW_MAC_NIBBLE_WILDCARD) =3D=3D nibble) + return -EADDRINUSE; + } + + return 0; +} + static void xlnx_tsn_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) { @@ -426,8 +626,10 @@ static const struct phylink_mac_ops xlnx_tsn_phylink_m= ac_ops =3D { =20 static int xlnx_tsn_setup(struct dsa_switch *ds) { + struct dsa_port *cpu_dp =3D dsa_to_port(ds, XLNX_TSN_CPU_PORT); struct xlnx_tsn *sw =3D ds->priv; struct dsa_port *dp; + u32 mgmt; int ret; =20 if (!dsa_is_user_port(ds, XLNX_TSN_PORT_MAC1) || @@ -435,6 +637,19 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) return dev_err_probe(sw->dev, -EINVAL, "both MAC1 and MAC2 must be enabled as switch ports\n"); =20 + if (!cpu_dp || !cpu_dp->conduit) + return -ENODEV; + + sw->conduit =3D cpu_dp->conduit; + + /* Route CPU-originated bridge-group control frames (STP, LLDP) to + * the single wire port whose MAC-nibble field matches the frame's + * source-MAC low nibble, instead of flooding to both. + */ + mgmt =3D sw_ior(sw, TSN_SW_MGMT_QUEUING_OFFSET); + mgmt |=3D TSN_SW_MGMT_QUEUING_EP_SA_EGRESS; + sw_iow(sw, TSN_SW_MGMT_QUEUING_OFFSET, mgmt); + /* CPU port stays in FORWARDING so host traffic always flows. * User ports start in DISABLED and transition from there under * bridge STP control. @@ -451,7 +666,20 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) return ret; } =20 - return xlnx_tsn_mdio_register_all(sw); + ret =3D xlnx_tsn_mdio_register_all(sw); + if (ret) + return ret; + + sw->nb.notifier_call =3D xlnx_tsn_netdev_event; + ret =3D register_netdevice_notifier(&sw->nb); + if (ret) + goto err_mdio; + + return 0; + +err_mdio: + xlnx_tsn_mdio_unregister_all(sw); + return ret; } =20 static void xlnx_tsn_teardown(struct dsa_switch *ds) @@ -459,6 +687,7 @@ static void xlnx_tsn_teardown(struct dsa_switch *ds) struct xlnx_tsn *sw =3D ds->priv; struct dsa_port *dp; =20 + unregister_netdevice_notifier(&sw->nb); xlnx_tsn_mdio_unregister_all(sw); =20 dsa_switch_for_each_user_port(dp, ds) @@ -471,6 +700,7 @@ static const struct dsa_switch_ops xlnx_tsn_switch_ops = =3D { .get_tag_protocol =3D xlnx_tsn_get_tag_protocol, .setup =3D xlnx_tsn_setup, .teardown =3D xlnx_tsn_teardown, + .port_set_mac_address =3D xlnx_tsn_port_set_mac_address, .port_stp_state_set =3D xlnx_tsn_port_stp_state_set, .phylink_get_caps =3D xlnx_tsn_phylink_get_caps, }; diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/x= ilinx_tsn.h index 6286caff7a1c..a228a7bebd53 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.h +++ b/drivers/net/dsa/xilinx/xilinx_tsn.h @@ -7,7 +7,9 @@ =20 #include #include +#include #include +#include #include #include =20 @@ -16,12 +18,29 @@ #define XLNX_TSN_PORT_MAC1 1 #define XLNX_TSN_PORT_MAC2 2 =20 +/* Unicast Frame Filter: the switch accepts an incoming frame when + * its destination MAC matches this 48-bit address under the 16-bit + * mask in the MSB register's upper half. A set mask bit acts as a + * wildcard for the corresponding bit of bytes 4..5. + */ +#define TSN_SW_MAC_LSB_OFFSET 0x0000c +#define TSN_SW_MAC_MSB_OFFSET 0x00010 +#define TSN_SW_MAC_MSB_ADDR_MASK GENMASK(15, 0) +#define TSN_SW_MAC_MSB_MASK_MASK GENMASK(31, 16) + +/* Mask value that covers the low nibble of byte 5, leaving a + * 44-bit prefix common to all switch-port MACs. Those 4 bits are + * filled in by the per-port MAC-nibble fields in the Switch Port + * State Control register below. + */ +#define TSN_SW_MAC_NIBBLE_WILDCARD 0x000f + #define TSN_SW_STATUS_OFFSET 0x00000 /* Poll this before changing port state. */ #define TSN_SW_STATUS_READY BIT(0) =20 -/* Switch Port State Control register: packs per-port STP state and - * change-commit bits into one 32-bit word. +/* Switch Port State Control register: packs per-port STP state, + * change-commit bits, and MAC-nibble fields into one 32-bit word. */ #define TSN_PORT_STATE_CTRL_OFFSET 0x0004c =20 @@ -31,6 +50,12 @@ #define MAC1_PORT_STATUS_MASK GENMASK(11, 9) #define MAC2_PORT_STATUS_CHG_BIT BIT(16) #define MAC2_PORT_STATUS_MASK GENMASK(19, 17) +#define EP_PORT_MAC_NIBBLE_MASK GENMASK(7, 4) +#define MAC1_PORT_MAC_NIBBLE_MASK GENMASK(15, 12) +#define MAC2_PORT_MAC_NIBBLE_MASK GENMASK(23, 20) + +#define TSN_SW_MGMT_QUEUING_OFFSET 0x00054 +#define TSN_SW_MGMT_QUEUING_EP_SA_EGRESS BIT(4) =20 /* readl_poll_timeout() parameters (in microseconds): poll until * the port-state change-commit bit self-clears. @@ -100,6 +125,13 @@ struct xlnx_tsn_mac { * @ds: DSA switch * @dev: backing device * @sw_base: switch fabric register window + * @conduit: DSA conduit netdev (EP MAC), used as the source of the + * shared 44-bit frame-filter prefix + * @mac_prefix: conduit MAC with byte 5's low nibble cleared to zero, + * forming the 44-bit prefix common to all switch-port MACs + * @nb: netdev notifier that handles NETDEV_REGISTER on each swpN + * to set its final MAC, and NETDEV_CHANGEADDR on the conduit + * to refresh the shared prefix * @mac: per-MAC state, indexed by user-port number (index 0 unused; * MAC1 at [1], MAC2 at [2]) */ @@ -107,6 +139,9 @@ struct xlnx_tsn { struct dsa_switch ds; struct device *dev; void __iomem *sw_base; + struct net_device *conduit; + u8 mac_prefix[ETH_ALEN]; + struct notifier_block nb; struct xlnx_tsn_mac mac[XLNX_TSN_NUM_PORTS]; }; =20 --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from SA9PR02CU001.outbound.protection.outlook.com (mail-southcentralusazon11013000.outbound.protection.outlook.com [40.93.196.0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32F32471240; Fri, 7 Aug 2026 10:46:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.196.0 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099571; cv=fail; b=JZtXf43kem3UJPNK/5OP7xmxRtFHLyQVdhgbdjfvQNDbAmIq5WIrctffNcUK7Vfi18lr6Hbldd43lr0hr2o1Ce8tMtAbMLZlsgKeuot71XQY3kQneHITCcVDUdVX3Au0O52BDFCE9mgqoVuTeqW+4MOGh1gSBOt6IcFD+sZLrmY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099571; c=relaxed/simple; bh=QHs49KGKTYlza0U1ClVTX3bgwWX1mF9H2H6rThosWQw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=R+ASyvmJJtk+ayIiX63aiwlDXxPls+mzu2zNvJ5jCfmgNJKdLqM0zbLifTcbC9bUpyQhbauIsszK3jzBIyDqR50t+0Ucn89NNyewkFO69wSsLc2hIbsBdKYhSASZzT0KbmhcVC5JfZnQMlQH4vKcWEwVz2yh0FFjbQrJOP/aeUU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=eikyHUGS; arc=fail smtp.client-ip=40.93.196.0 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="eikyHUGS" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=PXsQSe1n6FR9ScnBvV0xyP+vLUzrMfRUo0lAHI/XeOq1Ransgp/aqqc0xcKADLH8P7Ta2tmhoS49C+L5e82bExK6xIngLhRD296OLLA4e8Bhtac+bzm/DKF5zO1bwUG9UrU+QtPBUlfPnOZOCmfTpMxYZhVBoA0vKkCrlbjoL/46KVzPd7ZmqjgmCaRJwPxfDvpzavxpXhf+g2ivyKirdXiFJQRvE3eZXSvNeT0ssxqLTjicERKM9CmCSJziTNlWAgDTzYoqrEBl0rgkYilX31+X3NzIuoG1ZEVbqF3IaXkAwjvc7udHsnEKkUH1bPgx0PA/r5mMOiXdoAs0ooz+dw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=jU90HtZcndDjdkSJRpzeTbHZEKz4/7SHX4H2UMaTe3g=; b=L+u8T/5YPP6yb8CQuOmTc8CsXBOkXwwMRSuiqMaPjIf0pBIKF/w+C/WXDW5u+nPD3T4WcxiNpTphdKaro5hpe0/+MWLtEtiJYEoWxzWMK0ARW0lrFe3exZOT7O+WvQdbwSbS5dtOOoGOv+A7/81d2vtOBbCUnY4lB2Kd/t8fze9NcZU6ypPG/tvtLnfBst55XUZPzIR0EdXDwyHmIpEgMNbznVPRjw0sDLkea8Ngh5BaPFh9EWBWLQjQHZiLv9ymaZxAaTq+nczEbjJFOoXUZ0GmDw6w+zMPzaFb+mIaaQZOyDzcKyHEG2b1MPFPZ8OZVUdNwpVH8wpeGOHUIWnlUQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jU90HtZcndDjdkSJRpzeTbHZEKz4/7SHX4H2UMaTe3g=; b=eikyHUGSSXD1MRJSk1lYb0pOz12p38FJgH0KgEtQAVftTjyKfFpoTIwJCC537dwy87aNTTlHt8WsAP5l2oU8Nno0x9B+/hXsid18xeml2k5zkOYEViFVO0G+rZ0HRGXT/wwuQZSUWDXZA5WPCV+wmpafemyD1FNWz1EMF1ouE6E= Received: from PH7P220CA0082.NAMP220.PROD.OUTLOOK.COM (2603:10b6:510:32c::17) by CH3PR12MB7667.namprd12.prod.outlook.com (2603:10b6:610:14f::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.23; Fri, 7 Aug 2026 10:46:02 +0000 Received: from SJ1PEPF000023D3.namprd21.prod.outlook.com (2603:10b6:510:32c:cafe::98) by PH7P220CA0082.outlook.office365.com (2603:10b6:510:32c::17) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.23 via Frontend Transport; Fri, 7 Aug 2026 10:46:02 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D3.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:46:02 +0000 Received: from satlexmb10.amd.com (10.181.42.219) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:01 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb10.amd.com (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:00 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:45:55 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 15/20] net: dsa: xilinx: register PHC backed by the RTC timer block Date: Fri, 7 Aug 2026 16:14:26 +0530 Message-ID: <20260807104431.157230-16-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D3:EE_|CH3PR12MB7667:EE_ X-MS-Office365-Filtering-Correlation-Id: ffee11da-aab9-456f-ce97-08def4711312 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|82310400026|1800799024|36860700016|376014|7416014|921020|18002099003|22082099003|10067099003|6133799003|56012099006|11063799006; X-Microsoft-Antispam-Message-Info: K0E8LjlXAH+pErEOm+OjZlfepsrV2giR+YKra1YVKGqV4vzXHzUHjSg1ckwLPgLLBvAm6qveaNPgs7NnghpZtdG36QcdDxtYMW4GEQ3A3XEXa7zvJkngbo6VSSDJCe4XGD9clwU6bV87qmflwVgGweGEGHWvqOjc0T48lGM2M09Fd/e+7yTRQ+oO0wtyiuM77C5ti3n/H1b2MjssWAQSQOYK5wibpGYwIHhWgcBOXTokvlLiuKXO+VdAUDQTVUsBwiW0uRhnQTOvQko0XFCedfZoht9ROaOhMvGDJ1K6H5mY/zH+zapiGHLq8XpcvKDOnFUvdi97tQvvqcoqIJklROC4AM+xfjicFocbxv7Fx1pW7yl+e9QyZsUnjDcXXDvQa+PDX1mvmIqLhNeYaHCNM4b4wHGd550qCx7usaiV+KKbrdyQTL/NsVR3Ga9N8/+P/BofAQsTJ41gip9Acr+Ynjo9b6CP+kieaQARyZAFDOgVesxOjRlxt0eEB7vzbxRgsS7MOONqSkkYZFaUYbymeBIbuRdZr62EwgVswXARiugr+HZqFiXveSF0CbqenZrLDs4KLAzMAq6jQWTR4G9qbfUAPbYhRBHvobGE7BMlPIG7YepjSLi6+goyMNUswn7un02hq662UknGJds6cbrn6SNc/sDPEAGkkvOfsXW77aaa6VtE5+TiJ8ckqcPfZ4SJePwuKLmSBJPUmQlqSxsgmy8dmJrTyE3e4VQ4NXmOSkEIAMhVvhYC4Ty6vpg2dqIq X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(23010399003)(82310400026)(1800799024)(36860700016)(376014)(7416014)(921020)(18002099003)(22082099003)(10067099003)(6133799003)(56012099006)(11063799006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: GjS3t30NO+j2S6XVqLOOy+rc9NnS7EV6FrkHyBL/wnfB2/GERROwJhNDas0ZnC2X8jD0WVY/irFaa2WzIrucFOgnqEQknuBdw4Mr18YEfYdRqBSYNi/wPgDcSFoxWbHSVrMl+zrmLCJiJs9NmJaW61okCyXis78Xw/9LxqED9BX37gCOt+9sog99Zrsw6CAMxLakFPSiHTx0RIKM6APGuJKJ9ziMF/CbjtCR0V3OVqz2PnV3JfooUc04KFtccKv4tYTVult/Q93yWdupCsaXkAdrwOWKw+CDfMyxJuclRDevJ1KJbcVr7Hpv49Nj8tCzF3OK+7rHz0jp6wOqFE0XXr1HO+yar1i48qskoFWj2W15wrv3LXJ2trDZ8Tlz7DG+CQt5pOMVyh9l0Xu1R+LwTHvTR5DTVyq28FbU6yw6B5Qg7ebWn8Mz30AWD/Mt4D+m X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:46:02.0421 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ffee11da-aab9-456f-ce97-08def4711312 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D3.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR12MB7667 Content-Type: text/plain; charset="utf-8" Bring the IP-wide RTC timer block up under the switch driver and expose it as a PTP hardware clock. The timer block sits at a fixed offset inside MAC1's per-MAC register window, which the switch driver already owns via the "mac1" reg-name. Map it in probe() and register the PHC in setup(). A per-switch spinlock serializes concurrent PHC operations, since gettime/settime/adjtime can run concurrently from different file descriptors. Reading the nanoseconds register latches a full RTC snapshot, so gettime reads nanoseconds before seconds. The timer block fires 128 ticks per second. The ISR delivers PTP_CLOCK_PPS on every 128th tick. Co-developed-by: Srinivas Neeli Signed-off-by: Srinivas Neeli Signed-off-by: Nagadheeraj Rottela --- drivers/net/dsa/xilinx/Kconfig | 1 + drivers/net/dsa/xilinx/Makefile | 2 +- drivers/net/dsa/xilinx/xilinx_tsn.c | 7 + drivers/net/dsa/xilinx/xilinx_tsn.h | 43 +++++ drivers/net/dsa/xilinx/xilinx_tsn_ptp.c | 235 ++++++++++++++++++++++++ 5 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 drivers/net/dsa/xilinx/xilinx_tsn_ptp.c diff --git a/drivers/net/dsa/xilinx/Kconfig b/drivers/net/dsa/xilinx/Kconfig index 0bd5efe8490b..0e675295914b 100644 --- a/drivers/net/dsa/xilinx/Kconfig +++ b/drivers/net/dsa/xilinx/Kconfig @@ -3,6 +3,7 @@ config NET_DSA_XILINX_TSN tristate "AMD/Xilinx TSN Endpoint Ethernet MAC switch support" depends on OF && HAS_IOMEM depends on NET_DSA + depends on PTP_1588_CLOCK select NET_DSA_TAG_XLNX_TSN help This enables DSA switch support for the three-port switch diff --git a/drivers/net/dsa/xilinx/Makefile b/drivers/net/dsa/xilinx/Makef= ile index 334f0f979276..8d63749104a4 100644 --- a/drivers/net/dsa/xilinx/Makefile +++ b/drivers/net/dsa/xilinx/Makefile @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-or-later obj-$(CONFIG_NET_DSA_XILINX_TSN) +=3D xlnx_tsn_dsa.o -xlnx_tsn_dsa-y :=3D xilinx_tsn.o +xlnx_tsn_dsa-y :=3D xilinx_tsn.o xilinx_tsn_ptp.o diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c index 9826f006b078..318d8b332208 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -675,8 +675,14 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) if (ret) goto err_mdio; =20 + ret =3D xlnx_tsn_ptp_init(sw); + if (ret) + goto err_nb; + return 0; =20 +err_nb: + unregister_netdevice_notifier(&sw->nb); err_mdio: xlnx_tsn_mdio_unregister_all(sw); return ret; @@ -687,6 +693,7 @@ static void xlnx_tsn_teardown(struct dsa_switch *ds) struct xlnx_tsn *sw =3D ds->priv; struct dsa_port *dp; =20 + xlnx_tsn_ptp_exit(sw); unregister_netdevice_notifier(&sw->nb); xlnx_tsn_mdio_unregister_all(sw); =20 diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/x= ilinx_tsn.h index a228a7bebd53..6063763b5c17 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.h +++ b/drivers/net/dsa/xilinx/xilinx_tsn.h @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include =20 @@ -103,6 +105,28 @@ enum tsn_port_state { #define TSN_SPEED_CFG_100 BIT(30) #define TSN_SPEED_CFG_1000 BIT(31) =20 +/* PTP RTC timer block: a single block per IP, physically housed + * inside MAC1's per-MAC reg window. Owned by the switch driver + * because the PHC it backs is IP-wide, not per-MAC. + */ +#define TSN_TIMER_RTC_OFFSET_NS 0x00012800 +#define TSN_TIMER_RTC_OFFSET_SEC_L 0x00012808 +#define TSN_TIMER_RTC_OFFSET_SEC_H 0x0001280c +#define TSN_TIMER_RTC_INCREMENT 0x00012810 +#define TSN_TIMER_CURRENT_RTC_NS 0x00012814 +#define TSN_TIMER_CURRENT_RTC_SEC_L 0x00012818 +#define TSN_TIMER_CURRENT_RTC_SEC_H 0x0001281c +#define TSN_TIMER_INTERRUPT 0x00012820 + +#define TSN_TIMER_MAX_NSEC_SIZE 30 +#define TSN_TIMER_MAX_NSEC_MASK GENMASK_ULL(TSN_TIMER_MAX_NSEC_SIZE - 1, = 0) +#define TSN_TIMER_MAX_SEC_SIZE 48 +#define TSN_TIMER_MAX_SEC_MASK GENMASK_ULL(TSN_TIMER_MAX_SEC_SIZE - 1, 0) +#define TSN_TIMER_INT_CLEAR BIT(0) +#define TSN_TIMER_RTC_NS_SHIFT 20 +#define TSN_TIMER_PULSES_PER_PPS 128 +#define TSN_TIMER_GTX_CLK_FREQ 125000000U + struct mii_bus; struct xlnx_tsn; =20 @@ -134,6 +158,15 @@ struct xlnx_tsn_mac { * to refresh the shared prefix * @mac: per-MAC state, indexed by user-port number (index 0 unused; * MAC1 at [1], MAC2 at [2]) + * @ptp_timer_irq: 1 PPS / RTC-overflow interrupt + * @ptp_clock: registered PHC; NULL until setup() succeeds + * @ptp_clock_info: PHC capability + ops descriptor + * @reg_lock: serialises RTC offset / increment register accesses + * from process context and the PHC ops + * @rtc_value: base RTC increment word for the GTX clock frequency, + * used as the starting point for adjust_by_scaled_ppm() + * @pps_enable: user requested PPS event delivery + * @countpulse: timer-tick counter, reset to zero every TSN_TIMER_PULSES_P= ER_PPS ticks */ struct xlnx_tsn { struct dsa_switch ds; @@ -143,6 +176,13 @@ struct xlnx_tsn { u8 mac_prefix[ETH_ALEN]; struct notifier_block nb; struct xlnx_tsn_mac mac[XLNX_TSN_NUM_PORTS]; + int ptp_timer_irq; + struct ptp_clock *ptp_clock; + struct ptp_clock_info ptp_clock_info; + spinlock_t reg_lock; /* serialises RTC offset/increment registers */ + u64 rtc_value; + int pps_enable; + int countpulse; }; =20 static inline void mac_iow(struct xlnx_tsn_mac *m, u32 off, u32 val) @@ -155,4 +195,7 @@ static inline u32 mac_ior(struct xlnx_tsn_mac *m, u32 o= ff) return ioread32(m->regs + off); } =20 +int xlnx_tsn_ptp_init(struct xlnx_tsn *sw); +void xlnx_tsn_ptp_exit(struct xlnx_tsn *sw); + #endif /* _XILINX_TSN_H */ diff --git a/drivers/net/dsa/xilinx/xilinx_tsn_ptp.c b/drivers/net/dsa/xili= nx/xilinx_tsn_ptp.c new file mode 100644 index 000000000000..75c177f752f1 --- /dev/null +++ b/drivers/net/dsa/xilinx/xilinx_tsn_ptp.c @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AMD/Xilinx TSN Endpoint Ethernet MAC DSA switch driver: + * PTP hardware clock. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xilinx_tsn.h" + +/* Reading the nanoseconds register latches a full RTC snapshot + * (ns + sec_low + sec_high). The subsequent seconds reads return + * those latched values, so nanoseconds must be read first. + */ +static void xlnx_tsn_tod_read(struct xlnx_tsn *sw, struct timespec64 *ts) +{ + struct xlnx_tsn_mac *m =3D &sw->mac[XLNX_TSN_PORT_MAC1]; + u32 secl, sech, nsec; + + nsec =3D mac_ior(m, TSN_TIMER_CURRENT_RTC_NS); + secl =3D mac_ior(m, TSN_TIMER_CURRENT_RTC_SEC_L); + sech =3D mac_ior(m, TSN_TIMER_CURRENT_RTC_SEC_H); + + ts->tv_sec =3D (((u64)sech << 32) | secl) & TSN_TIMER_MAX_SEC_MASK; + ts->tv_nsec =3D nsec & TSN_TIMER_MAX_NSEC_MASK; +} + +static void xlnx_tsn_rtc_offset_write(struct xlnx_tsn *sw, + const struct timespec64 *ts) +{ + struct xlnx_tsn_mac *m =3D &sw->mac[XLNX_TSN_PORT_MAC1]; + + mac_iow(m, TSN_TIMER_RTC_OFFSET_SEC_H, upper_32_bits(ts->tv_sec)); + mac_iow(m, TSN_TIMER_RTC_OFFSET_SEC_L, lower_32_bits(ts->tv_sec)); + mac_iow(m, TSN_TIMER_RTC_OFFSET_NS, ts->tv_nsec); +} + +static void xlnx_tsn_rtc_offset_read(struct xlnx_tsn *sw, + struct timespec64 *ts) +{ + struct xlnx_tsn_mac *m =3D &sw->mac[XLNX_TSN_PORT_MAC1]; + u32 secl, sech, nsec; + + secl =3D mac_ior(m, TSN_TIMER_RTC_OFFSET_SEC_L); + sech =3D mac_ior(m, TSN_TIMER_RTC_OFFSET_SEC_H); + nsec =3D mac_ior(m, TSN_TIMER_RTC_OFFSET_NS); + + ts->tv_sec =3D (((u64)sech << 32) | secl) & TSN_TIMER_MAX_SEC_MASK; + ts->tv_nsec =3D nsec & TSN_TIMER_MAX_NSEC_MASK; +} + +static int xlnx_tsn_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_pp= m) +{ + struct xlnx_tsn *sw =3D container_of(ptp, struct xlnx_tsn, ptp_clock_info= ); + u64 incval; + + /* adjust_by_scaled_ppm() returns u64 but the increment register is + * 32 bits, so clamp to U32_MAX to avoid overflow. + */ + incval =3D adjust_by_scaled_ppm(sw->rtc_value, scaled_ppm); + if (incval > U32_MAX) + incval =3D U32_MAX; + + guard(spinlock_irqsave)(&sw->reg_lock); + mac_iow(&sw->mac[XLNX_TSN_PORT_MAC1], TSN_TIMER_RTC_INCREMENT, + (u32)incval); + + return 0; +} + +static int xlnx_tsn_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + struct xlnx_tsn *sw =3D container_of(ptp, struct xlnx_tsn, ptp_clock_info= ); + struct timespec64 now, then =3D ns_to_timespec64(delta); + + guard(spinlock_irqsave)(&sw->reg_lock); + + xlnx_tsn_rtc_offset_read(sw, &now); + now =3D timespec64_add(now, then); + + /* Stepping time backwards is fine and just lowers the offset. In + * practice the offset never goes negative. Reject it only as a + * safety net, since the offset register cannot store a negative value. + */ + if (now.tv_sec < 0) + return -ERANGE; + + xlnx_tsn_rtc_offset_write(sw, &now); + + return 0; +} + +static int xlnx_tsn_ptp_gettime(struct ptp_clock_info *ptp, + struct timespec64 *ts) +{ + struct xlnx_tsn *sw =3D container_of(ptp, struct xlnx_tsn, ptp_clock_info= ); + + guard(spinlock_irqsave)(&sw->reg_lock); + xlnx_tsn_tod_read(sw, ts); + + return 0; +} + +static int xlnx_tsn_ptp_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts) +{ + struct xlnx_tsn *sw =3D container_of(ptp, struct xlnx_tsn, ptp_clock_info= ); + struct timespec64 delta, tod, offset, counter; + + guard(spinlock_irqsave)(&sw->reg_lock); + + xlnx_tsn_tod_read(sw, &tod); + xlnx_tsn_rtc_offset_read(sw, &offset); + counter =3D timespec64_sub(tod, offset); + + delta =3D timespec64_sub(*ts, counter); + + /* A real wall-clock time is always far above the free-running counter, + * so this never triggers in practice. Reject it only as a safety net, + * since the offset register cannot store a negative value. + */ + if (delta.tv_sec < 0) + return -ERANGE; + + xlnx_tsn_rtc_offset_write(sw, &delta); + + return 0; +} + +static int xlnx_tsn_ptp_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + struct xlnx_tsn *sw =3D container_of(ptp, struct xlnx_tsn, ptp_clock_info= ); + + switch (rq->type) { + case PTP_CLK_REQ_PPS: + WRITE_ONCE(sw->pps_enable, on ? 1 : 0); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static irqreturn_t xlnx_tsn_ptp_timer_isr(int irq, void *priv) +{ + struct ptp_clock_event event =3D { .type =3D PTP_CLOCK_PPS }; + struct xlnx_tsn *sw =3D priv; + + sw->countpulse++; + if (sw->countpulse >=3D TSN_TIMER_PULSES_PER_PPS) { + sw->countpulse =3D 0; + if (sw->ptp_clock && READ_ONCE(sw->pps_enable)) + ptp_clock_event(sw->ptp_clock, &event); + } + + mac_iow(&sw->mac[XLNX_TSN_PORT_MAC1], TSN_TIMER_INTERRUPT, + TSN_TIMER_INT_CLEAR); + + return IRQ_HANDLED; +} + +int xlnx_tsn_ptp_init(struct xlnx_tsn *sw) +{ + struct timespec64 ts; + int ret; + + spin_lock_init(&sw->reg_lock); + + sw->ptp_timer_irq =3D of_irq_get_byname(sw->dev->of_node, "ptp_timer"); + if (sw->ptp_timer_irq <=3D 0) + return dev_err_probe(sw->dev, sw->ptp_timer_irq ? : -ENXIO, + "failed to get ptp_timer IRQ\n"); + + sw->ptp_clock_info.owner =3D THIS_MODULE; + snprintf(sw->ptp_clock_info.name, sizeof(sw->ptp_clock_info.name), + "TSN PHC"); + sw->ptp_clock_info.max_adj =3D 999999999; + sw->ptp_clock_info.pps =3D 1; + sw->ptp_clock_info.adjfine =3D xlnx_tsn_ptp_adjfine; + sw->ptp_clock_info.adjtime =3D xlnx_tsn_ptp_adjtime; + sw->ptp_clock_info.gettime64 =3D xlnx_tsn_ptp_gettime; + sw->ptp_clock_info.settime64 =3D xlnx_tsn_ptp_settime; + sw->ptp_clock_info.enable =3D xlnx_tsn_ptp_enable; + + sw->ptp_clock =3D ptp_clock_register(&sw->ptp_clock_info, sw->dev); + if (IS_ERR_OR_NULL(sw->ptp_clock)) { + ret =3D sw->ptp_clock ? PTR_ERR(sw->ptp_clock) : -ENODEV; + sw->ptp_clock =3D NULL; + return dev_err_probe(sw->dev, ret, + "failed to register PTP clock\n"); + } + + sw->rtc_value =3D div_u64(NSEC_PER_SEC, TSN_TIMER_GTX_CLK_FREQ) << + TSN_TIMER_RTC_NS_SHIFT; + mac_iow(&sw->mac[XLNX_TSN_PORT_MAC1], TSN_TIMER_RTC_INCREMENT, + (u32)sw->rtc_value); + + ts =3D ktime_to_timespec64(ktime_get_real()); + xlnx_tsn_ptp_settime(&sw->ptp_clock_info, &ts); + + ret =3D request_irq(sw->ptp_timer_irq, xlnx_tsn_ptp_timer_isr, 0, + "xlnx-tsn-ptp-timer", sw); + if (ret) { + dev_err_probe(sw->dev, ret, + "failed to request ptp_timer IRQ %d\n", + sw->ptp_timer_irq); + goto err_unregister_clock; + } + + return 0; + +err_unregister_clock: + ptp_clock_unregister(sw->ptp_clock); + sw->ptp_clock =3D NULL; + return ret; +} + +void xlnx_tsn_ptp_exit(struct xlnx_tsn *sw) +{ + if (!sw->ptp_clock) + return; + + free_irq(sw->ptp_timer_irq, sw); + ptp_clock_unregister(sw->ptp_clock); + sw->ptp_clock =3D NULL; +} --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from SN4PR2101CU001.outbound.protection.outlook.com (mail-southcentralusazon11012021.outbound.protection.outlook.com [40.93.195.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C0BA42FCC2; Fri, 7 Aug 2026 10:46:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.195.21 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099581; cv=fail; b=lHL5kT47Eq/wZSo/irGa049lV9LeWtjwyY8+6MG7pVqtB05xg8/SrrlDvMbNU8Jtmn+9n3xuDao/2iVmOO2a0Ox2WFo2Fs/PK0sU2K9/m+khJOAjcBfjBeLNez/OFymRq4OdJW4Wh6fsbel8Xue6mocubVcOnYZOBzr5FsdL6YY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099581; c=relaxed/simple; bh=NfDQit/H3Gqagh4Sws8RM546+9gVhGWID3TQusJHj/M=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Hrer07OJBhXOkfDGZD2jstfzz+kKlr3s3fnT830/PIzvswx6zc7n6DcDqPHm3gqttOUbHJhFxvSIyAaSEpxINj3qt2EQgxjJJKnNfkeHulfT8vgQbxaLb68tuuQ8H5jE8f63a3LS28GFWRS1xZTQ4712YCBbnQHAZHg7dbta9aQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=eAbRrOeP; arc=fail smtp.client-ip=40.93.195.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="eAbRrOeP" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=F+buBpvt5JsCgdxPLSp6vCIZnajXZ5Yl2SgJxOvCoxAcLrIWxehrvuge7M7g9a8v5Ededg7dZ9C3Af0WX4/YMAqsO2IBwlZ75foI3hp5uDnxBcFiZEW7EkRHQmrrIFUUEFMzBxM125/is+fgle9ilmkUOwUEOpVMn2FvQTlZxtnV6NDxenmwzfjdGdhF9NO43ZvvxsVQfO76a9lcRJNFSfh3i5aBZ0yTX2VlXZsxjLcs1rf1OospHC4Ay4gotPh3KAzK6QtMBu1iCgMfOfnw/OnyWIP5xjj+iLcSExH+tgLtZLAz07A0OaF/1rRF0zBPSOwQ2P1ZdAVRJRJbyseztw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ixdVkEx13j+MHIM09cGrssA2HKr9JeWH00Mqxzi/0N8=; b=eHJsiP7xkGpuTMP+okf+j670lBqzp6Qt43GXAhB4D3LGxt5Fjnvf8kAozm8NQz7/YU84dz5zocu1VY1pbL4xKjhX85lZi120K0K2CtUMgMTS9Vh6rZzq4qZK+LvbC1+U8lvP1bfZopIgGX2cn9RrKUR+l82rUYQhpCRzzD1QcZZirQ7iXzIh4pIbre0iCnUyLsi5Zb7dPt50sPfgnWNgMUPgVUCqt5Ro9unPdSkoLEPW1jlzrHV1ab8fxicwne+fqqO50D+ke42qEkcWH4qaxYS6HUsGGAa4itDNvNS0h2RkBLWswlFsXOOmqquFmiDy94E7BTbnf6QGcXqq602kOA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ixdVkEx13j+MHIM09cGrssA2HKr9JeWH00Mqxzi/0N8=; b=eAbRrOeP3HB3LZSr78K8BskcTKdNmafr+47iNlAff6bt6zaVoEAb0teXZ2XjTzeJih+p/2uppb7PZrshYiMAaKLBWLFrw7FbCbVD7PkZKI4VhKpxdO5NO8xOGVAZYDsWNCtZwXVMlciW5lFQWTbPgQ926WLt5MIc8X2Govm0L+c= Received: from SJ0PR13CA0114.namprd13.prod.outlook.com (2603:10b6:a03:2c5::29) by DS0PR12MB6534.namprd12.prod.outlook.com (2603:10b6:8:c1::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.23; Fri, 7 Aug 2026 10:46:11 +0000 Received: from SJ5PEPF000001EB.namprd05.prod.outlook.com (2603:10b6:a03:2c5:cafe::2a) by SJ0PR13CA0114.outlook.office365.com (2603:10b6:a03:2c5::29) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.315.9 via Frontend Transport; Fri, 7 Aug 2026 10:46:11 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SJ5PEPF000001EB.mail.protection.outlook.com (10.167.242.199) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.6 via Frontend Transport; Fri, 7 Aug 2026 10:46:10 +0000 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:05 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:46:00 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 16/20] net: dsa: xilinx: drive per-MAC PTP TX/RX hardware paths Date: Fri, 7 Aug 2026 16:14:27 +0530 Message-ID: <20260807104431.157230-17-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001EB:EE_|DS0PR12MB6534:EE_ X-MS-Office365-Filtering-Correlation-Id: d0863d66-0f5e-4e50-dab3-08def471181a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700016|376014|7416014|23010399003|82310400026|56012099006|22082099003|18002099003|3023799007|10067099003|11063799006|921020; X-Microsoft-Antispam-Message-Info: J/J1uEZVnoAILiLAJ518ZiKILdvpViOqiKWQYuDmkT9oEedaQzSb8PjQipcPY+xK1CP2Sml39z+JNgVqMJMb9dzKaKULA3rwFtOxtXLc7rgkxhIBdNHBD0aPyAm2B8sYJ77Iyy2MGBq+jcC3mXST43/Tic2TmvCtYoPLXh+WxDxlxBhSMtQFf8W52nxaXXcbhVBTZ4ILvKrEi+pzK9sV1EbA7mgswT//MNsGJdFitEXv+53G7G6u4fPXbBpvIXPnv58ofnwYggDGOzrNFiWUOBEvqZAV3fX1gQBCyuZq/k7C6BCQWVpipHnOwnvcsdmuqNy73iWZe9VlGGzhDQfNJwLxvArCGSJCSSlDG87/npWo/2A5zXI1BfZ8CrR07i0lmHzoQ368HYBv+Ryq7v+c7IXxMjnxTF5K2SkzSDFic/pqVvn7a+v3X8zl/WEDBiZSFrdCy5hYBbRbxj1eyRpV2j4U7POurctVNzmpkic/pyk7RoYlzWeXvhER+aG/Y19u9ZB1B9xYv240xDttWFEv5ztcODhvm6E6NOrIEg0nAUB3XZ2dKU/8pig04460FY0tBwVz3ddfmSahouIdRSSE4RCM4r8pl+hnGgfkpOLjvOCCoCNwyJdJnrxdGQNwA0S2bRNOi5xJDy4bI1af4ZHtHvszRWmKLaYTsR8oHgwvCYj/X8hZdU8AdCL6TErjb5Iu/X8DPHev1YTEuJQT3vWttKxOugdA5fEvIO7L49wUI6CnWtrptNYQpKI9N/61gPdw X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700016)(376014)(7416014)(23010399003)(82310400026)(56012099006)(22082099003)(18002099003)(3023799007)(10067099003)(11063799006)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 3YZLnVdmNJVpG5KD16k0CDwbLVIga6Pb7/pUMHB5yVPEhBsVq/riWejXQcpzTyTZ0UoBKfdthtxhGcMnWkN5DtBbg2GNHiUhGAu3nNSUILr8XeI51+Mi/E30Fha5HvACf3Lsx5Ca1+/Qolan4CqknzC3pmaQNt2qjodVa6A9Nk8OsNS+g6opMUp2FsNeEwIbFRu2cXUub8OeW6KKySCIrHptwohRUgJ1vuQ91ft5lv24BD89JCjPv9OUZXDb+4YBrr8SpKGCXF51MDQSPhujgWaqPpTLW6hes3tmuI2+Q97c6f4ivve414QDfYwvZtE2QEdQsKd65tiqG60Pnvhwwvul/At7ZGTChXEFmP7z/wdL+9fYbtFWvhhNGhEVBHsvwr3Twn6Pe7GzcMnq4wDhuX0GMrWSkT1LdrZYUIJzF07J1ZwPRbQQNx/zm3YHEQe4 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:46:10.4990 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d0863d66-0f5e-4e50-dab3-08def471181a X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001EB.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB6534 Content-Type: text/plain; charset="utf-8" PTP event frames bypass the switch fabric. Each MAC has its own PTP TX and PTP RX register windows in the per-MAC register space, plus two dedicated interrupts. A frame captured in a MAC's PTP RX buffer goes directly to the matching user port. A frame pushed to a MAC's PTP TX buffer transmits out the same port without ever entering the conduit or switch. Publish the TX path to the tag protocol through ds->tagger_data in setup(). Using a function pointer through tagger_data rather than an exported symbol avoids a link-time dependency from the tag module to the switch module. TX timestamping accepts HWTSTAMP_TX_OFF and HWTSTAMP_TX_ON. Accept any PTP v2 event RX filter and promote it to HWTSTAMP_FILTER_PTP_V2_L2_EVENT. The per-MAC frame-filter block cannot narrow the filter by message type. Co-developed-by: Srinivas Neeli Signed-off-by: Srinivas Neeli Signed-off-by: Nagadheeraj Rottela --- MAINTAINERS | 1 + drivers/net/dsa/xilinx/xilinx_tsn.c | 24 ++ drivers/net/dsa/xilinx/xilinx_tsn.h | 76 +++++ drivers/net/dsa/xilinx/xilinx_tsn_ptp.c | 357 +++++++++++++++++++++++- include/linux/dsa/xlnx_tsn.h | 25 ++ net/dsa/tag_xlnx_tsn.c | 29 +- 6 files changed, 510 insertions(+), 2 deletions(-) create mode 100644 include/linux/dsa/xlnx_tsn.h diff --git a/MAINTAINERS b/MAINTAINERS index 0e91cb2a307d..c44b6fdd5b4a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -29615,6 +29615,7 @@ S: Maintained F: Documentation/devicetree/bindings/net/xlnx,tsn-endpoint-ethernet-mac.ya= ml F: drivers/net/dsa/xilinx/ F: drivers/net/ethernet/xilinx/tsn/ +F: include/linux/dsa/xlnx_tsn.h F: net/dsa/tag_xlnx_tsn.c =20 XILINX UARTLITE SERIAL DRIVER diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c index 318d8b332208..e48c81f18d6e 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -18,6 +18,7 @@ #include #include #include +#include #include =20 #include "xilinx_tsn.h" @@ -679,8 +680,25 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) if (ret) goto err_nb; =20 + ret =3D xlnx_tsn_port_ptp_init(sw, XLNX_TSN_PORT_MAC1, + "ptp_rx_mac1", "ptp_tx_mac1"); + if (ret) + goto err_ptp_exit; + + ret =3D xlnx_tsn_port_ptp_init(sw, XLNX_TSN_PORT_MAC2, + "ptp_rx_mac2", "ptp_tx_mac2"); + if (ret) + goto err_ptp_mac1; + + sw->tagger_data.ptp_tx =3D xlnx_tsn_ptp_tx; + ds->tagger_data =3D &sw->tagger_data; + return 0; =20 +err_ptp_mac1: + xlnx_tsn_port_ptp_exit(sw, XLNX_TSN_PORT_MAC1); +err_ptp_exit: + xlnx_tsn_ptp_exit(sw); err_nb: unregister_netdevice_notifier(&sw->nb); err_mdio: @@ -692,7 +710,10 @@ static void xlnx_tsn_teardown(struct dsa_switch *ds) { struct xlnx_tsn *sw =3D ds->priv; struct dsa_port *dp; + int port; =20 + for (port =3D XLNX_TSN_PORT_MAC1; port <=3D XLNX_TSN_PORT_MAC2; port++) + xlnx_tsn_port_ptp_exit(sw, port); xlnx_tsn_ptp_exit(sw); unregister_netdevice_notifier(&sw->nb); xlnx_tsn_mdio_unregister_all(sw); @@ -709,6 +730,9 @@ static const struct dsa_switch_ops xlnx_tsn_switch_ops = =3D { .teardown =3D xlnx_tsn_teardown, .port_set_mac_address =3D xlnx_tsn_port_set_mac_address, .port_stp_state_set =3D xlnx_tsn_port_stp_state_set, + .port_hwtstamp_get =3D xlnx_tsn_port_hwtstamp_get, + .port_hwtstamp_set =3D xlnx_tsn_port_hwtstamp_set, + .get_ts_info =3D xlnx_tsn_get_ts_info, .phylink_get_caps =3D xlnx_tsn_phylink_get_caps, }; =20 diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/x= ilinx_tsn.h index 6063763b5c17..d46150535775 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.h +++ b/drivers/net/dsa/xilinx/xilinx_tsn.h @@ -9,10 +9,14 @@ #include #include #include +#include #include #include +#include #include #include +#include +#include #include =20 #define XLNX_TSN_NUM_PORTS 3 @@ -127,7 +131,44 @@ enum tsn_port_state { #define TSN_TIMER_PULSES_PER_PPS 128 #define TSN_TIMER_GTX_CLK_FREQ 125000000U =20 +/* Per-MAC PTP TX / RX register windows, sitting inside each per-MAC + * reg space. Each PTP TX slot is 256 B wide; the first 8 B hold the + * cmd1/cmd2 header, leaving 248 B for frame data. HW provides 8 slots. + * The PTP RX buffer mirrors the layout with a 252 B usable area and + * an 8 B HW timestamp footer. + */ +#define TSN_PTP_TX_CONTROL_OFFSET 0x00012000 +#define TSN_PTP_RX_CONTROL_OFFSET 0x00012004 + +#define TSN_PTP_RX_BASE_OFFSET 0x00010000 +#define TSN_PTP_RX_PACKET_FIELD_MASK GENMASK(11, 8) +#define TSN_PTP_RX_PACKET_CLEAR BIT(0) + +#define TSN_PTP_TX_BASE_OFFSET 0x00011000 +#define TSN_PTP_TX_HWBUF_SIZE 0x100 +#define TSN_PTP_TX_BUFFERS 8 +#define TSN_PTP_TX_BUFFER_OFFSET(i) (TSN_PTP_TX_BASE_OFFSET + \ + (i) * TSN_PTP_TX_HWBUF_SIZE) +#define TSN_PTP_TX_CMD_FIELD_LEN 8 +#define TSN_PTP_TX_MAX_FRAME_SIZE (TSN_PTP_TX_HWBUF_SIZE - \ + TSN_PTP_TX_CMD_FIELD_LEN) +#define TSN_PTP_TX_BUFFER_CMD2_FIELD 0x4 + +#define TSN_PTP_TX_FRAME_WAITING_MASK GENMASK(15, 8) +#define TSN_PTP_TX_BUFFERS_FULL_MASK BIT(TSN_PTP_TX_BUFFERS - 1) +#define TSN_PTP_TX_PACKET_FIELD_MASK GENMASK(18, 16) + +#define TSN_PTP_HW_TSTAMP_SIZE 8 +#define TSN_PTP_RX_HWBUF_SIZE 256 +#define TSN_PTP_RX_FRAME_SIZE 252 +#define TSN_PTP_HW_TSTAMP_OFFSET (TSN_PTP_RX_HWBUF_SIZE - \ + TSN_PTP_HW_TSTAMP_SIZE) + +#define TSN_PTP_MSG_TYPE_MASK BIT(3) + +struct kernel_ethtool_ts_info; struct mii_bus; +struct netlink_ext_ack; struct xlnx_tsn; =20 /** @@ -137,11 +178,32 @@ struct xlnx_tsn; * @regs: per-MAC register window, from reg-name "macN" * @mii_bus: MDIO bus registered under the "mdio-macN" DT child, * or NULL if absent + * @ptp_tx_irq: per-MAC PTP TX-completion interrupt + * @ptp_rx_irq: per-MAC PTP RX interrupt + * @ptp_tx_lock: serialises the PTP TX slot allocator and the TX + * completion path + * @ptp_txq: in-flight PTP TX frames awaiting timestamp completion. + * Each frame's slot index is kept in skb->cb[0]. + * @tx_tstamp_work: work item queued by the PTP TX IRQ to drain + * ptp_txq and deliver timestamps through skb_tstamp_tx() + * @ptp_rx_hw_pointer: HW write pointer snapshot read in the RX ISR + * @ptp_rx_sw_pointer: SW read pointer; drained until it catches up + * @hwtstamp_tx_type: current SO_TIMESTAMPING TX type for this port + * @hwtstamp_rx_filter: current SO_TIMESTAMPING RX filter for this port */ struct xlnx_tsn_mac { struct xlnx_tsn *sw; void __iomem *regs; struct mii_bus *mii_bus; + int ptp_tx_irq; + int ptp_rx_irq; + spinlock_t ptp_tx_lock; /* serialises PTP TX slot alloc + completion */ + struct sk_buff_head ptp_txq; + struct work_struct tx_tstamp_work; + u32 ptp_rx_hw_pointer; + u32 ptp_rx_sw_pointer; + int hwtstamp_tx_type; + int hwtstamp_rx_filter; }; =20 /** @@ -167,6 +229,8 @@ struct xlnx_tsn_mac { * used as the starting point for adjust_by_scaled_ppm() * @pps_enable: user requested PPS event delivery * @countpulse: timer-tick counter, reset to zero every TSN_TIMER_PULSES_P= ER_PPS ticks + * @tagger_data: PTP TX callback descriptor handed to the tag protocol + * via @dsa_switch.tagger_data */ struct xlnx_tsn { struct dsa_switch ds; @@ -183,6 +247,7 @@ struct xlnx_tsn { u64 rtc_value; int pps_enable; int countpulse; + struct xlnx_tsn_tagger_data tagger_data; }; =20 static inline void mac_iow(struct xlnx_tsn_mac *m, u32 off, u32 val) @@ -197,5 +262,16 @@ static inline u32 mac_ior(struct xlnx_tsn_mac *m, u32 = off) =20 int xlnx_tsn_ptp_init(struct xlnx_tsn *sw); void xlnx_tsn_ptp_exit(struct xlnx_tsn *sw); +int xlnx_tsn_port_ptp_init(struct xlnx_tsn *sw, int port, + const char *rx_name, const char *tx_name); +void xlnx_tsn_port_ptp_exit(struct xlnx_tsn *sw, int port); +void xlnx_tsn_ptp_tx(struct dsa_port *dp, struct sk_buff *skb); +int xlnx_tsn_port_hwtstamp_get(struct dsa_switch *ds, int port, + struct kernel_hwtstamp_config *config); +int xlnx_tsn_port_hwtstamp_set(struct dsa_switch *ds, int port, + struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack); +int xlnx_tsn_get_ts_info(struct dsa_switch *ds, int port, + struct kernel_ethtool_ts_info *info); =20 #endif /* _XILINX_TSN_H */ diff --git a/drivers/net/dsa/xilinx/xilinx_tsn_ptp.c b/drivers/net/dsa/xili= nx/xilinx_tsn_ptp.c index 75c177f752f1..740d92e3e80d 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn_ptp.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn_ptp.c @@ -1,18 +1,26 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* * AMD/Xilinx TSN Endpoint Ethernet MAC DSA switch driver: - * PTP hardware clock. + * PTP hardware clock and per-MAC PTP TX/RX paths. */ =20 +#include #include +#include +#include #include #include #include #include +#include +#include #include #include +#include #include #include +#include +#include #include =20 #include "xilinx_tsn.h" @@ -233,3 +241,350 @@ void xlnx_tsn_ptp_exit(struct xlnx_tsn *sw) ptp_clock_unregister(sw->ptp_clock); sw->ptp_clock =3D NULL; } + +static void memcpy_toio_32(struct xlnx_tsn_mac *m, unsigned long off, + const u8 *data, size_t len) +{ + while (len >=3D 4) { + mac_iow(m, off, get_unaligned((const u32 *)data)); + off +=3D 4; + data +=3D 4; + len -=3D 4; + } + + if (len) { + u32 leftover =3D 0; + u8 *dst =3D (u8 *)&leftover; + + while (len--) + *dst++ =3D *data++; + mac_iow(m, off, leftover); + } +} + +static void memcpy_fromio_32(struct xlnx_tsn_mac *m, unsigned long off, + u8 *data, size_t len) +{ + while (len >=3D 4) { + put_unaligned(mac_ior(m, off), (u32 *)data); + off +=3D 4; + data +=3D 4; + len -=3D 4; + } + + if (len) { + u32 leftover =3D mac_ior(m, off); + u8 *src =3D (u8 *)&leftover; + + while (len--) + *data++ =3D *src++; + } +} + +static void xlnx_tsn_read_tstamp(struct xlnx_tsn_mac *m, + struct skb_shared_hwtstamps *hwtstamps, + unsigned int off) +{ + u32 captured_ns, captured_sec; + + memset(hwtstamps, 0, sizeof(*hwtstamps)); + + captured_ns =3D mac_ior(m, off + 4); + captured_sec =3D mac_ior(m, off); + + hwtstamps->hwtstamp =3D ktime_set(captured_sec, captured_ns); +} + +void xlnx_tsn_ptp_tx(struct dsa_port *dp, struct sk_buff *skb) +{ + struct xlnx_tsn *sw =3D dp->ds->priv; + u32 frame_waiting, cmd1, cmd2 =3D 0; + struct xlnx_tsn_mac *m; + u8 free_index; + + m =3D &sw->mac[dp->index]; + + if (unlikely(skb->len > TSN_PTP_TX_MAX_FRAME_SIZE)) { + dev_kfree_skb_any(skb); + return; + } + + scoped_guard(spinlock_irqsave, &m->ptp_tx_lock) { + frame_waiting =3D FIELD_GET(TSN_PTP_TX_FRAME_WAITING_MASK, + mac_ior(m, TSN_PTP_TX_CONTROL_OFFSET)); + if (frame_waiting & TSN_PTP_TX_BUFFERS_FULL_MASK) { + dev_kfree_skb_any(skb); + return; + } + + free_index =3D fls(frame_waiting); + cmd1 =3D skb->len; + + mac_iow(m, TSN_PTP_TX_BUFFER_OFFSET(free_index), cmd1); + mac_iow(m, TSN_PTP_TX_BUFFER_OFFSET(free_index) + + TSN_PTP_TX_BUFFER_CMD2_FIELD, cmd2); + memcpy_toio_32(m, + TSN_PTP_TX_BUFFER_OFFSET(free_index) + + TSN_PTP_TX_CMD_FIELD_LEN, + skb->data, skb->len); + + skb->cb[0] =3D free_index; + __skb_queue_tail(&m->ptp_txq, skb); + + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) + skb_shinfo(skb)->tx_flags |=3D SKBTX_IN_PROGRESS; + + skb_tx_timestamp(skb); + mac_iow(m, TSN_PTP_TX_CONTROL_OFFSET, BIT(free_index)); + } +} + +static void xlnx_tsn_ptp_recv(struct xlnx_tsn *sw, int port) +{ + struct net_device *user =3D dsa_to_port(&sw->ds, port)->user; + struct xlnx_tsn_mac *m =3D &sw->mac[port]; + unsigned long frame_base; + struct sk_buff *skb; + u16 msg_len; + u8 msg_type; + + if (!user || !netif_running(user)) + return; + + while ((m->ptp_rx_hw_pointer & 0xf) !=3D (m->ptp_rx_sw_pointer & 0xf)) { + m->ptp_rx_sw_pointer++; + + frame_base =3D TSN_PTP_RX_BASE_OFFSET + + (m->ptp_rx_sw_pointer & 0xf) * + TSN_PTP_RX_HWBUF_SIZE; + + skb =3D netdev_alloc_skb(user, TSN_PTP_RX_FRAME_SIZE); + if (!skb) { + DEV_STATS_INC(user, rx_dropped); + continue; + } + + memcpy_fromio_32(m, frame_base, skb->data, + TSN_PTP_RX_FRAME_SIZE); + + msg_type =3D *(u8 *)(skb->data + ETH_HLEN) & 0xf; + msg_len =3D get_unaligned_be16(skb->data + ETH_HLEN + 2); + + if (msg_len + ETH_HLEN > TSN_PTP_RX_FRAME_SIZE) { + dev_kfree_skb_any(skb); + DEV_STATS_INC(user, rx_length_errors); + continue; + } + + skb_put(skb, msg_len + ETH_HLEN); + skb->protocol =3D eth_type_trans(skb, user); + skb->ip_summed =3D CHECKSUM_UNNECESSARY; + + if (READ_ONCE(m->hwtstamp_rx_filter) !=3D HWTSTAMP_FILTER_NONE && + !(msg_type & TSN_PTP_MSG_TYPE_MASK)) + xlnx_tsn_read_tstamp(m, skb_hwtstamps(skb), + frame_base + + TSN_PTP_HW_TSTAMP_OFFSET); + + dev_sw_netstats_rx_add(user, skb->len); + netif_rx(skb); + } +} + +static irqreturn_t xlnx_tsn_ptp_rx_isr(int irq, void *data) +{ + struct xlnx_tsn_mac *m =3D data; + struct xlnx_tsn *sw =3D m->sw; + int port =3D m - sw->mac; + + m->ptp_rx_hw_pointer =3D FIELD_GET(TSN_PTP_RX_PACKET_FIELD_MASK, + mac_ior(m, TSN_PTP_RX_CONTROL_OFFSET)); + xlnx_tsn_ptp_recv(sw, port); + + return IRQ_HANDLED; +} + +static void xlnx_tsn_tx_tstamp_work(struct work_struct *work) +{ + struct xlnx_tsn_mac *m =3D container_of(work, struct xlnx_tsn_mac, + tx_tstamp_work); + struct skb_shared_hwtstamps hwtstamps; + unsigned long ts_off; + struct sk_buff *skb; + u8 tx_packet, index; + + guard(spinlock_irqsave)(&m->ptp_tx_lock); + + tx_packet =3D FIELD_GET(TSN_PTP_TX_PACKET_FIELD_MASK, + mac_ior(m, TSN_PTP_TX_CONTROL_OFFSET)); + + while ((skb =3D __skb_dequeue(&m->ptp_txq)) !=3D NULL) { + index =3D skb->cb[0]; + + /* HW writes ascending slot indices into the TX status field + * as frames depart. Any queued skb with index > tx_packet + * has not been timestamped yet, so requeue it and stop. + */ + if (index > tx_packet) { + __skb_queue_head(&m->ptp_txq, skb); + break; + } + + ts_off =3D TSN_PTP_TX_BUFFER_OFFSET(index) + + TSN_PTP_HW_TSTAMP_OFFSET; + + if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) { + xlnx_tsn_read_tstamp(m, &hwtstamps, ts_off); + skb_tstamp_tx(skb, &hwtstamps); + } + consume_skb(skb); + } +} + +static irqreturn_t xlnx_tsn_ptp_tx_isr(int irq, void *data) +{ + struct xlnx_tsn_mac *m =3D data; + + mac_ior(m, TSN_PTP_TX_CONTROL_OFFSET); + schedule_work(&m->tx_tstamp_work); + + return IRQ_HANDLED; +} + +int xlnx_tsn_port_ptp_init(struct xlnx_tsn *sw, int port, + const char *rx_name, const char *tx_name) +{ + struct xlnx_tsn_mac *m =3D &sw->mac[port]; + int ret; + + skb_queue_head_init(&m->ptp_txq); + spin_lock_init(&m->ptp_tx_lock); + INIT_WORK(&m->tx_tstamp_work, xlnx_tsn_tx_tstamp_work); + m->ptp_rx_hw_pointer =3D 0; + m->ptp_rx_sw_pointer =3D 0xff; + m->hwtstamp_tx_type =3D HWTSTAMP_TX_OFF; + m->hwtstamp_rx_filter =3D HWTSTAMP_FILTER_NONE; + + m->ptp_rx_irq =3D of_irq_get_byname(sw->dev->of_node, rx_name); + if (m->ptp_rx_irq <=3D 0) + return dev_err_probe(sw->dev, m->ptp_rx_irq ? : -ENXIO, + "failed to get %s IRQ\n", rx_name); + + m->ptp_tx_irq =3D of_irq_get_byname(sw->dev->of_node, tx_name); + if (m->ptp_tx_irq <=3D 0) + return dev_err_probe(sw->dev, m->ptp_tx_irq ? : -ENXIO, + "failed to get %s IRQ\n", tx_name); + + mac_iow(m, TSN_PTP_RX_CONTROL_OFFSET, TSN_PTP_RX_PACKET_CLEAR); + + ret =3D request_irq(m->ptp_rx_irq, xlnx_tsn_ptp_rx_isr, 0, rx_name, m); + if (ret) + return dev_err_probe(sw->dev, ret, + "failed to request %s IRQ %d\n", + rx_name, m->ptp_rx_irq); + + ret =3D request_irq(m->ptp_tx_irq, xlnx_tsn_ptp_tx_isr, 0, tx_name, m); + if (ret) { + free_irq(m->ptp_rx_irq, m); + return dev_err_probe(sw->dev, ret, + "failed to request %s IRQ %d\n", + tx_name, m->ptp_tx_irq); + } + + return 0; +} + +void xlnx_tsn_port_ptp_exit(struct xlnx_tsn *sw, int port) +{ + struct xlnx_tsn_mac *m =3D &sw->mac[port]; + struct sk_buff *skb; + + if (m->ptp_tx_irq > 0) + free_irq(m->ptp_tx_irq, m); + + if (m->ptp_rx_irq > 0) + free_irq(m->ptp_rx_irq, m); + + cancel_work_sync(&m->tx_tstamp_work); + + scoped_guard(spinlock_irqsave, &m->ptp_tx_lock) + while ((skb =3D __skb_dequeue(&m->ptp_txq)) !=3D NULL) + dev_kfree_skb_any(skb); +} + +int xlnx_tsn_port_hwtstamp_get(struct dsa_switch *ds, int port, + struct kernel_hwtstamp_config *config) +{ + struct xlnx_tsn *sw =3D ds->priv; + struct xlnx_tsn_mac *m; + + m =3D &sw->mac[port]; + + if (port =3D=3D XLNX_TSN_CPU_PORT) + return -EOPNOTSUPP; + + config->tx_type =3D m->hwtstamp_tx_type; + config->rx_filter =3D m->hwtstamp_rx_filter; + + return 0; +} + +int xlnx_tsn_port_hwtstamp_set(struct dsa_switch *ds, int port, + struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack) +{ + struct xlnx_tsn *sw =3D ds->priv; + struct xlnx_tsn_mac *m; + + m =3D &sw->mac[port]; + + if (port =3D=3D XLNX_TSN_CPU_PORT) + return -EOPNOTSUPP; + + switch (config->tx_type) { + case HWTSTAMP_TX_OFF: + case HWTSTAMP_TX_ON: + break; + default: + return -ERANGE; + } + + /* The per-MAC RX filter is left at its power-on default, which + * captures L2 gPTP event frames (ethertype 0x88f7) only. PTP over + * UDP is not supported. The filter cannot narrow by message type, + * so any L2 PTPv2 event request is promoted to + * HWTSTAMP_FILTER_PTP_V2_L2_EVENT. + */ + switch (config->rx_filter) { + case HWTSTAMP_FILTER_NONE: + break; + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + config->rx_filter =3D HWTSTAMP_FILTER_PTP_V2_L2_EVENT; + break; + default: + return -ERANGE; + } + + m->hwtstamp_tx_type =3D config->tx_type; + WRITE_ONCE(m->hwtstamp_rx_filter, config->rx_filter); + + return 0; +} + +int xlnx_tsn_get_ts_info(struct dsa_switch *ds, int port, + struct kernel_ethtool_ts_info *info) +{ + struct xlnx_tsn *sw =3D ds->priv; + + info->phc_index =3D sw->ptp_clock ? ptp_clock_index(sw->ptp_clock) : -1; + info->so_timestamping =3D SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + info->tx_types =3D BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON); + info->rx_filters =3D BIT(HWTSTAMP_FILTER_NONE) | + BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT); + + return 0; +} diff --git a/include/linux/dsa/xlnx_tsn.h b/include/linux/dsa/xlnx_tsn.h new file mode 100644 index 000000000000..34a451f4568a --- /dev/null +++ b/include/linux/dsa/xlnx_tsn.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * AMD/Xilinx TSN Endpoint Ethernet MAC: shared tagger / switch + * private interface. + */ +#ifndef _NET_DSA_XLNX_TSN_H +#define _NET_DSA_XLNX_TSN_H + +#include +#include + +/** + * struct xlnx_tsn_tagger_data - per-switch context for the tag protocol + * @ptp_tx: callback that copies a PTP event frame into the per-port + * hardware TX buffer and holds the skb until the TX IRQ + * delivers the timestamp. Consumes one reference to @skb. + * + * Set on @dsa_switch.tagger_data by the switch driver in setup() + * and read by the tag protocol's xmit hook. + */ +struct xlnx_tsn_tagger_data { + void (*ptp_tx)(struct dsa_port *dp, struct sk_buff *skb); +}; + +#endif /* _NET_DSA_XLNX_TSN_H */ diff --git a/net/dsa/tag_xlnx_tsn.c b/net/dsa/tag_xlnx_tsn.c index de352aa3d9a8..6f487ad7bcf9 100644 --- a/net/dsa/tag_xlnx_tsn.c +++ b/net/dsa/tag_xlnx_tsn.c @@ -3,14 +3,41 @@ * AMD/Xilinx TSN Endpoint Ethernet MAC tag protocol. */ =20 +#include +#include + #include "tag.h" =20 #define XLNX_TSN_NAME "xlnx_tsn" =20 +/* PTP frames must go directly into the egress MAC's hardware TX buffer, + * not through the switch fabric or conduit DMA. Intercept here before + * dsa_enqueue_skb() takes the frame and hand off our reference: ptp_tx() + * consumes it, freeing the skb once the HW timestamp is read (or on + * error). + * + * VLAN-tagged PTP is not supported. Match on the L2 ethertype and + * skip any VLAN-tagged frame. + */ static struct sk_buff *xlnx_tsn_xmit(struct sk_buff *skb, struct net_device *dev) { - return skb; + struct xlnx_tsn_tagger_data *tagger_data; + struct dsa_port *dp; + + dp =3D dsa_user_to_port(dev); + tagger_data =3D dp->ds->tagger_data; + + if (!tagger_data || !tagger_data->ptp_tx) + return skb; + + if (eth_hdr(skb)->h_proto !=3D htons(ETH_P_1588) || + skb_vlan_tag_present(skb)) + return skb; + + tagger_data->ptp_tx(dp, skb); + + return NULL; } =20 static struct sk_buff *xlnx_tsn_rcv(struct sk_buff *skb, --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from PH8PR06CU001.outbound.protection.outlook.com (mail-westus3azon11012060.outbound.protection.outlook.com [40.107.209.60]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 280EC430306; Fri, 7 Aug 2026 10:46:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.209.60 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099580; cv=fail; b=oMnLMJm97fiqA9BgeMVKjRYJC0wWA/TlBbBLt1axDSmS3j0xsR3cnRqG8G6tw2c3TV4jCvtwYVFNddVED/bT9OzHpk48dShLMSeuo42HC315JYdfjuCQ08l+cW9wZi59UMGYvxtxD60zBLMzNWEiZAT5VXx/kofi35qDRPGkY8Y= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099580; c=relaxed/simple; bh=gMWpJfSseFH+3wQQU1yhevcjSEv0nC8eq6jg94/MjKQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=al8PyVna5WP/vH50Ht9JtL6VkYR3SrK0hLVtFcG7GiDLQAaprshjDvTUeuayj9wG2acT8qQNa98jLWmnn05Vvz+mT4ukSDtxNDVVb01Byt6AGijLkAkaL429+9qEuLtMdEOGQ6TUWXu77CAiPaGewf0+qmGCD1w9eXImFh1Ewzk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=wiYal0zc; arc=fail smtp.client-ip=40.107.209.60 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="wiYal0zc" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=hWI86B8JRdHCE4g8KgL6lBDOUK1W6B5l9ThoM0NEtV/Z0vQb4fv38Fw6lfefGcLnAbEAt7Sr1nqtR2N+4jVtI3Ra/jUHkJHPxPykRcHaKMRv/uPdVgnjiC0wBHvNJ7sSM2AzZNSUjx+HzgljaEm4oioQc0aE3a09VmKogZ9vWUqZYbpwg4HUcZZnUs30G0Neu8LloLcpHQlc1rOvzbYMrxAfpX0MLMR/nozgHh1GBAj1DAugN/kVggyNBYtX7wAxpvhWiSHMCDRpm7xVyEK1xv2SPcjGRAvZu5kK1doR81obHUs56j+WXE9WtE0pNi24CNQoVVcoE41chqvKHsw9Ew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=b/iV3m62o/n22HBm8ytnCnDNr4sVxWvgGfyMbJKoD84=; b=QAJHCulcptMPd33ry0+RFKak9WCCxuRO9gHFwkF+OuH4A3VImtPx+nwbjOKGuqvkNRr9B+JmrwBcifwdrCKgzOggwEnWU00jxERKbE5ThpGhPm38c8hO2sQ+TlqsweI9YKMFqCbaLTCwIczpq+IcIhvYaRQJkP5d11Ph/6xFjHvgAJbZTtEayM8GKiD+sRrYT9vifT5YUT8Uy1YjmsA0BCxJxtot62xCmaHsj3EYpSNEjPhW5WczP8bDYoZDcS+7yWhVeRDa/RkgHEMO7a5tZXwfIcX+6EaovJ/lS6NpR0sgOJxiPC83PA6mDu/B+0rYwn2hxdSUvV0HN9NAH1CFLA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=b/iV3m62o/n22HBm8ytnCnDNr4sVxWvgGfyMbJKoD84=; b=wiYal0zchggyIUzAykVVIIDLGQRPHvMGNH/UsJvox+d+LrA0IW/41mGLKVShWQfidgb79YHlYkqg2IfgLZP5XXn4izYkfQXrbI2c3KcF5w/c+Tk9QnYf7ApVtsQPlQ8vJZX612eGmYPFSaIyNucjypBCDU+3tKs+Ql6fB98mVSI= Received: from PH7P222CA0027.NAMP222.PROD.OUTLOOK.COM (2603:10b6:510:33a::10) by DM6PR12MB4481.namprd12.prod.outlook.com (2603:10b6:5:2af::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.24; Fri, 7 Aug 2026 10:46:15 +0000 Received: from SJ1PEPF000023D9.namprd21.prod.outlook.com (2603:10b6:510:33a:cafe::40) by PH7P222CA0027.outlook.office365.com (2603:10b6:510:33a::10) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.24 via Frontend Transport; Fri, 7 Aug 2026 10:46:14 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D9.mail.protection.outlook.com (10.167.244.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:46:14 +0000 Received: from satlexmb10.amd.com (10.181.42.219) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:12 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb10.amd.com (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:11 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:46:06 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 17/20] net: dsa: xilinx: opt into TX forwarding offload on bridge join Date: Fri, 7 Aug 2026 16:14:28 +0530 Message-ID: <20260807104431.157230-18-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D9:EE_|DM6PR12MB4481:EE_ X-MS-Office365-Filtering-Correlation-Id: 17ebe81a-1e6a-470c-8a1e-08def4711a8f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|7416014|36860700016|376014|23010399003|82310400026|56012099006|18002099003|22082099003|10067099003|11063799006|921020; X-Microsoft-Antispam-Message-Info: 8shSmklXTXEfybsSsJbXGM7C2rEJuq1zXJ+rqW0FvC4NtQN8poMlU7Jc4cpRYaQjhBzuICDV1lw9BFj7HCZANFbllby7ORQ/nK+sA5aFMJ+B2U4lv1o0cwuaYuUgx8foClRLSvmw5BubUVi3ZmETmr6qqm6lIBI1AjaSnAmByM2x1WLpZ0EQW579KwdMy1mGuf4GCJNS0ehPi99asY/OkJXQlkrXxeMZaMjOA+/haVr0rkedZ8E6A8MmOwImJZ3Kp4YOQ1XJ7EPz53K05ksPx9TDsd/Ev/hDdv/7iTaa8i0ZMmZqv6L7cJVojWt9QkXZ8D2QMTCkbWBd+OsUkbI9ZeJtL8XIMQh/I0QM38nemBSkQFJkZRLGacKpR0M9mKTOKzIE2fKs+Jy51uwEN5rhuHqYvGX5Pbsqcvoy+XILdOjIfaOIRNy0eNYnTv3U2UlXYfvLyhpL/w49xSQ5sJojpASzhaoPgv1Cu9hIRDtU2+RMh+FCoZf1++Mm5jBm1Gw+k+bQx2vK4pZWNx0Vsl9CtQSAKokZ5UHL0lNckAF2eNJM9lEyoPtqJQ/zYvKWz2ocld6yF5Yc9LbvjBiZNnMPtlKQFJ5i+5hpUJ8w4TFzSoZwH1S5DXRKh8wNbgo7LZ31bGtMKN72MHL+zyj80vUqXGga26OJnpfd1lW7jBoiXr5Mp1hAJ/Pxi4vp1YY3Ujva8kzdEO9QBs/kkhNFmAp6610AdUafKAgZzLQ51tGInQ0h/V0NUtM8F7xjXxfEaweX X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(7416014)(36860700016)(376014)(23010399003)(82310400026)(56012099006)(18002099003)(22082099003)(10067099003)(11063799006)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: yom7T2hiOdhzSapQ8OEx5uzHHA2WbtXulqYTKpz/Qksdqs5IdZRAqCWLwP/hGxqYRjc53qHRP4Quwn/v+caa7RmShzyT9X38YheKevsB/h7zXmSpr5eLUo1fX+0vGaPBXOn4qR4tnspL71AhpcDhkaRUIGF9ZTwTtZ5oz66C77niDv5SY+vZ5ONiu/e2sS/SE5ro/s6jCDOQVUeAileIPEpcWgw35bTqwex26Jrr7uANUTv2C2hSoqqsP6/qiQ9rBHF3drkhZZHold3SMfG/QQf0j1gLrWxSX/kGlduAY5gGNaUri+S79g9k8RzGEYshqGGAnj1cWzlwqRhUPFccEyuTPIwW+45aLJn9Hc55EBEZJMjEFyYoK3LapAKlr6CFDqiaOIVEY64Y5tS7pWY2IR24ylqUsGUEym+oSE6vnMg4namSQuCBpslDm1qkVv9q X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:46:14.5895 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 17ebe81a-1e6a-470c-8a1e-08def4711a8f X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D9.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4481 Content-Type: text/plain; charset="utf-8" Set *tx_fwd_offload in port_bridge_join. The bridge then sends one copy via the offloaded TX path and the fabric handles per-port replication. The fabric offloads a single bridge across the user ports. Set ds->max_num_bridges to 1 so the DSA core rejects a second bridge instead of silently merging the ports. Signed-off-by: Nagadheeraj Rottela --- drivers/net/dsa/xilinx/xilinx_tsn.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c index e48c81f18d6e..9a4d4a2fb892 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -495,6 +495,19 @@ static int xlnx_tsn_port_set_mac_address(struct dsa_sw= itch *ds, int port, return 0; } =20 +static int xlnx_tsn_port_bridge_join(struct dsa_switch *ds, int port, + struct dsa_bridge bridge, + bool *tx_fwd_offload, + struct netlink_ext_ack *extack) +{ + /* The switch fabric replicates flooded frames per egress port + * on its own, so the bridge does not need to clone-and-send. + */ + *tx_fwd_offload =3D true; + + return 0; +} + static void xlnx_tsn_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) { @@ -729,6 +742,7 @@ static const struct dsa_switch_ops xlnx_tsn_switch_ops = =3D { .setup =3D xlnx_tsn_setup, .teardown =3D xlnx_tsn_teardown, .port_set_mac_address =3D xlnx_tsn_port_set_mac_address, + .port_bridge_join =3D xlnx_tsn_port_bridge_join, .port_stp_state_set =3D xlnx_tsn_port_stp_state_set, .port_hwtstamp_get =3D xlnx_tsn_port_hwtstamp_get, .port_hwtstamp_set =3D xlnx_tsn_port_hwtstamp_set, @@ -786,6 +800,9 @@ static int xlnx_tsn_probe(struct platform_device *pdev) ds->phylink_mac_ops =3D &xlnx_tsn_phylink_mac_ops; ds->priv =3D sw; =20 + /* The fabric offloads a single bridge across the user ports. */ + ds->max_num_bridges =3D 1; + platform_set_drvdata(pdev, sw); =20 return dsa_register_switch(ds); --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from SA9PR02CU001.outbound.protection.outlook.com (mail-southcentralusazon11013063.outbound.protection.outlook.com [40.93.196.63]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F31940A956; Fri, 7 Aug 2026 10:46:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.196.63 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099589; cv=fail; b=bc7u7V5ZkD06TtzwfjjFf+FetIfJiJy9thHUkX05eK3o0E6nlvbqFGIqJRdXeA/t8UZiN7AOOEgAYcvDt8r/12Cb5PRfRf3r7AUnSSDituTC/EXIqHeu9lZbIMfKUexyQZHWFF+rqjnbiwqhe18EXdg0vuVAXvmKpfAKp7bjmXc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099589; c=relaxed/simple; bh=rPkMvDBAYh4TM25RljQL4omfv7FPlgVv6iA1YYgXaHY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dwP2bUQCfaTQ6tYn7rDh9pEC+wegiT7mCdJUDA70VKVe0riiDaGhOCyfnbBEXCOPWawd6paj5lmDEwLtKkaMC4eO23jEOZi00dzVYc4FcGWATVjAPf3NlBKM6l8KWw4y+rks7uh2g0ZnGAzWJR9ow4AmF7vt/LKVj6CS72wtWLU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=wAkYpUnt; arc=fail smtp.client-ip=40.93.196.63 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="wAkYpUnt" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ZZVbqsOMHmG74cWK4hivqcKg/8NCOBRK3aoyGaBSoRoiNVC5s0GAT/6tTKylaselmrdCaX1eEgIkw22YdPX+JpHGzOeC8VuvnE1GiHZw6WDEhLsn2ddlTi211zXIVomKcE6d42rInXXhXyJsQbzRFLeuFqqrcioUBwtowGRpbSNi0ldKIWZKo0sdfR87r4ZO3BiGAUj1UoI4XsEX3gcriUFtgJsN21i6ef/bExvqSGKQX3mAJHTZDl4rWcWuoINI7Yz7kIPoyuAtNDjaT97DuEOKQn3rUw5JMWuR0gQ8u5pwH8X23ouQGcB8JCBOe/edHS2671N9mu9hO3WopdRUGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=7CUphzZKQw89pUogMi5SHkAL8gVvfeiITpu2q/Xf3/s=; b=nqEwJaKcXRQhQZmDHB+zhDSYMjul26iI24XqHgBJ5MRh+FqyxK/u4ovy9usj5JK/4dIMBd3q/HfliQbQvo2BcAhtFRbl6YaEa12vPLHUHGFGV8owzyHaB+Rtp0jvX91X+aApARPpZORP7e71OBCJ/+ue25ldCEhlVb6xN+RQtJiBRz9ean+gNrnH/c+Kz+Q8fyqvaYrY4nC8znTFamIlf+LkFE2+qxXKshlUGeGJXcqRVwzETOFfqcybgTs3YXFTlBsT6FAIIgqKV6CSrCdias71igc/tihyHDu2swc+KiMBYYRYC1PTYnty1GzaYf2LL78akBX0lN0QuixLpwgNvQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=7CUphzZKQw89pUogMi5SHkAL8gVvfeiITpu2q/Xf3/s=; b=wAkYpUntG7IhQngbbKK2qZz2Fkq3lqjqebbEt8mYWN43Ra/valRT0vxmKqhRr7+Nm9yGz39i2vM4UV3+UYP6lpAWkPZPCi6MQeAsgxi6CpBXKH60Pwv2DlVTB+AgMJtBHbiUo3z4FcX8El+PWdpL7MzUCrJAbS7X1Wxl7x7+Yfc= Received: from SJ0PR05CA0040.namprd05.prod.outlook.com (2603:10b6:a03:33f::15) by PH7PR12MB7115.namprd12.prod.outlook.com (2603:10b6:510:1ee::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.19; Fri, 7 Aug 2026 10:46:19 +0000 Received: from SJ5PEPF000001E8.namprd05.prod.outlook.com (2603:10b6:a03:33f:cafe::5f) by SJ0PR05CA0040.outlook.office365.com (2603:10b6:a03:33f::15) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.315.9 via Frontend Transport; Fri, 7 Aug 2026 10:46:19 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SJ5PEPF000001E8.mail.protection.outlook.com (10.167.242.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.6 via Frontend Transport; Fri, 7 Aug 2026 10:46:19 +0000 Received: from satlexmb10.amd.com (10.181.42.219) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:18 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb10.amd.com (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:17 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:46:12 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 18/20] net: dsa: xilinx: offload the bridge FDB to the switch CAM Date: Fri, 7 Aug 2026 16:14:29 +0530 Message-ID: <20260807104431.157230-19-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001E8:EE_|PH7PR12MB7115:EE_ X-MS-Office365-Filtering-Correlation-Id: 4b3c2e77-7177-4fa9-13f5-08def4711d2f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|7416014|82310400026|376014|1800799024|36860700016|921020|6133799003|56012099006|11063799006|10067099003|3023799007|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: ZN/ltZ0Ynx6mg6lD2jF1NxxOkOIeO3JTolwHEmFFbmt10K+ebQs/ayuMC2z5RlmE5sK6W3oLEBcwLog/aKWSrUT3WZDpu5EWFZ51DKcfnaXFyzgnAKuaqRzDM3QJTuW0uew+l2YIKAgWtIhLe4HydivDf4KScnznzsg38NWmDtVgFMbQsgjVxInAjcpMbLE4n96D5FkhO/f4vk4RASXu6BlgNAk2TaOfRBB8M3EXzDib+eZ/Y1GG9PuCQ2RR7OvJ+6cFqTJtYV9QT3+WXPwB0ao4jNA+hI9EWKMtAxMAgeArglRsj0RThHHEV67NeO0Za+0oGU12XeE67hacS/85wCNl7G4HPMLkSvEjx6VkuvygZe52wxgj+pjtniWQmeMqHDCK5RTgTZsjIsYKzov14W9t1hDbA/b17CkweLFfJfGzhrDn7rM7z+RweLpmCImZEnoPvz8/WAd3mjVFlatnkV0JPwGoh++JWEvgvC1oyFa9PnWYdYxQiiCbmm0LbW3yiBM1gxQmV+FyLhuUad70qYVkedKFfpe7R114dcYTAdNbyYNXpv74Sfk0bpsFC3Rrs4fNnU1/dtAxt4ShOOBNbJWhzYf/wgogud2T1wIua3kC+if19sB/Cmd9NQbrIX3/Kn+N8tlmtaALgWddoE/M5UMbJGEaca4o6+8AuG9gRVc6s+8eVCmxDXA5kdbDeLF0w4LVd+nO4U0dpU9T/w5TJkth/PXyIvIHH6HQjRg1auIxsZRSXw70L63wfDvy7b2F X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(23010399003)(7416014)(82310400026)(376014)(1800799024)(36860700016)(921020)(6133799003)(56012099006)(11063799006)(10067099003)(3023799007)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: KPV/rQQrsEJn6WVtgR/OPCYTnBXyxkbHcjkQRvZmAmEVCzHX1eWvKSiz+RGP/Is1cQMetuy8pXofg1oLAQI1O5GodkHlKHYSf/cOU9zyc29lmUjtpNIDHfH0Al9g4damUGjDXqQW1p4FBeunNTigwhOPcTdeAfWQG0JOxN2i8OPh0DbImez1fLnQ6MKXNSs9a/kN1uRbLY3CLVrrylo69PS0W1qEYsGwEilOuuR8pgHxhq6ERxkoVFkwcNFLf210J4nyF8LGImPdIizFNCGf48J5HMS4Kqmhy7A87znjDUQlfqpe4GpHekxPCu65jrxRSxEvaqcBiNM4yD3Q86wRs1OyxF25ns7L65r82YlxwbNG76ZS/bD7z4re2p/XZxYJOH1L5fYj6K9vDrxfIneLe7/92KMsG7HfUOLMyJqAzu+8rZ17zWknDqjdDQKj4Izn X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:46:19.0015 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 4b3c2e77-7177-4fa9-13f5-08def4711d2f X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001E8.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB7115 Content-Type: text/plain; charset="utf-8" The switch resolves forwarding through a stream-destination lookup CAM that maps a (destination MAC, VLAN ID) key to an egress port list. Back the bridge FDB with it. The CAM is an indirect register block. Load the key and port-list registers, write the opcode (add, delete, read, or read-key) to the control register, and wait for the operation to finish. Add a mutex to serialise these sequences. The fabric also learns source MACs into the same CAM. Enable the learning engine in port_bridge_join, and add port_bridge_leave to disable it once the last user port leaves, so entries accumulate only while a bridge spans the ports. port_fdb_add and port_fdb_del read the entry, set or clear the calling port's bit in the port list, and write it back. Delete the entry once no port references it. A (MAC, VID) reachable on several ports then carries a correct multi-port list. The DSA "no VLAN" key (vid 0) maps to the default native VID that an untagged frame uses. port_fdb_dump reports a port's learnt entries. The hardware scatters them across the port's read-key region. Scan all of it and report every slot that is present. The CPU port has no such region. port_fast_age flushes a port's learnt addresses from the CAM. Signed-off-by: Nagadheeraj Rottela --- drivers/net/dsa/xilinx/xilinx_tsn.c | 301 +++++++++++++++++++++++++++- drivers/net/dsa/xilinx/xilinx_tsn.h | 93 ++++++++- 2 files changed, 391 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c index 9a4d4a2fb892..57558b0e2613 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -174,6 +174,31 @@ static int xlnx_tsn_set_port_state(struct xlnx_tsn *sw= , int port, return 0; } =20 +static enum tsn_port_state xlnx_tsn_get_port_state(struct xlnx_tsn *sw, + int port) +{ + u32 mask, chg_bit, reg; + + if (xlnx_tsn_port_state_bits(port, &mask, &chg_bit)) + return TSN_PORT_STATE_DISABLED; + + reg =3D sw_ior(sw, TSN_PORT_STATE_CTRL_OFFSET); + return (reg & mask) >> __ffs(mask); +} + +static int xlnx_tsn_port_state_cycle(struct xlnx_tsn *sw, int port, + enum tsn_port_state state) +{ + enum tsn_port_state saved =3D xlnx_tsn_get_port_state(sw, port); + int err; + + err =3D xlnx_tsn_set_port_state(sw, port, state); + if (err) + return err; + + return xlnx_tsn_set_port_state(sw, port, saved); +} + static int xlnx_tsn_mdio_wait_ready(struct xlnx_tsn_mac *m) { u32 val; @@ -495,11 +520,32 @@ static int xlnx_tsn_port_set_mac_address(struct dsa_s= witch *ds, int port, return 0; } =20 +/* Enable or disable the hardware address learning engine globally. + * Standalone ports do not learn. Enable when a port joins a bridge, + * disable when the last one leaves. The sub-qualifier bits below are + * inert while learning is disabled. Caller holds indirect_lock. + */ +static void xlnx_tsn_set_global_learning(struct xlnx_tsn *sw, bool on) +{ + u32 reg =3D sw_ior(sw, TSN_SW_ADDR_LEARN_OFFSET); + + if (on) + reg &=3D ~TSN_SW_ADDR_LEARN_DISABLE; + else + reg |=3D TSN_SW_ADDR_LEARN_DISABLE; + sw_iow(sw, TSN_SW_ADDR_LEARN_OFFSET, reg); +} + static int xlnx_tsn_port_bridge_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge, bool *tx_fwd_offload, struct netlink_ext_ack *extack) { + struct xlnx_tsn *sw =3D ds->priv; + + scoped_guard(mutex, &sw->indirect_lock) + xlnx_tsn_set_global_learning(sw, true); + /* The switch fabric replicates flooded frames per egress port * on its own, so the bridge does not need to clone-and-send. */ @@ -508,6 +554,24 @@ static int xlnx_tsn_port_bridge_join(struct dsa_switch= *ds, int port, return 0; } =20 +static void xlnx_tsn_port_bridge_leave(struct dsa_switch *ds, int port, + struct dsa_bridge bridge) +{ + struct xlnx_tsn *sw =3D ds->priv; + struct dsa_port *dp; + + dsa_switch_for_each_user_port(dp, ds) { + if (dp->index =3D=3D port) + continue; + + if (dp->bridge) + return; + } + + scoped_guard(mutex, &sw->indirect_lock) + xlnx_tsn_set_global_learning(sw, false); +} + static void xlnx_tsn_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) { @@ -539,6 +603,217 @@ static void xlnx_tsn_port_stp_state_set(struct dsa_sw= itch *ds, int port, xlnx_tsn_set_port_state(sw, port, hw_state); } =20 +/* The CAM status enable bit reads 1 when the block is ready to accept the + * next operation. + */ +static int xlnx_tsn_cam_wait_ready(struct xlnx_tsn *sw) +{ + u32 reg; + + return readl_poll_timeout(sw->sw_base + TSN_CAM_STATUS_OFFSET, reg, + reg & TSN_CAM_STATUS_READY, TSN_SW_POLL_DELAY_US, + TSN_SW_POLL_TIMEOUT_US); +} + +/* The CAM control enable bit self-clears when the operation completes. */ +static int xlnx_tsn_cam_wait_done(struct xlnx_tsn *sw) +{ + u32 reg; + + return readl_poll_timeout(sw->sw_base + TSN_CAM_CTRL_OFFSET, reg, + !(reg & TSN_CAM_OP_ENABLE), + TSN_SW_POLL_DELAY_US, TSN_SW_POLL_TIMEOUT_US); +} + +static void xlnx_tsn_cam_load_key(struct xlnx_tsn *sw, + const unsigned char *addr, u16 vid) +{ + sw_iow(sw, TSN_CAM_KEY1_OFFSET, + ((u32)addr[0] << 24) | ((u32)addr[1] << 16) | + ((u32)addr[2] << 8) | addr[3]); + sw_iow(sw, TSN_CAM_KEY2_OFFSET, + ((u32)addr[4] << 8) | addr[5] | + FIELD_PREP(TSN_CAM_VLAN, vid)); +} + +/* Look up a (MAC, VID) key and return its current egress port list, or 0 + * if the entry is absent. Caller holds indirect_lock. + */ +static int xlnx_tsn_cam_read_portlist(struct xlnx_tsn *sw, + const unsigned char *addr, u16 vid, + u8 *portlist) +{ + u32 ctrl; + int ret; + + ret =3D xlnx_tsn_cam_wait_ready(sw); + if (ret) + return ret; + + xlnx_tsn_cam_load_key(sw, addr, vid); + sw_iow(sw, TSN_CAM_CTRL_OFFSET, + FIELD_PREP(TSN_CAM_OP_MASK, TSN_CAM_OP_READ) | TSN_CAM_OP_ENABLE); + + ret =3D xlnx_tsn_cam_wait_done(sw); + if (ret) + return ret; + + ctrl =3D sw_ior(sw, TSN_CAM_CTRL_OFFSET); + if (!(ctrl & TSN_CAM_FOUND)) { + *portlist =3D 0; + return 0; + } + + *portlist =3D FIELD_GET(TSN_CAM_PORT_LIST, + sw_ior(sw, TSN_CAM_PORT_ACT_OFFSET)); + return 0; +} + +/* Add (add=3Dtrue) or delete (add=3Dfalse) the (MAC, VID) entry carrying = the + * given port list. Caller holds indirect_lock. + */ +static int xlnx_tsn_cam_write(struct xlnx_tsn *sw, const unsigned char *ad= dr, + u16 vid, u8 portlist, bool add) +{ + int ret; + + ret =3D xlnx_tsn_cam_wait_ready(sw); + if (ret) + return ret; + + xlnx_tsn_cam_load_key(sw, addr, vid); + sw_iow(sw, TSN_CAM_TV1_OFFSET, 0); + sw_iow(sw, TSN_CAM_TV2_OFFSET, 0); + sw_iow(sw, TSN_CAM_PORT_ACT_OFFSET, + FIELD_PREP(TSN_CAM_PORT_LIST, portlist)); + sw_iow(sw, TSN_CAM_CTRL_OFFSET, + FIELD_PREP(TSN_CAM_OP_MASK, add ? TSN_CAM_OP_ADD : TSN_CAM_OP_DELE= TE) | + TSN_CAM_OP_ENABLE); + + return xlnx_tsn_cam_wait_done(sw); +} + +static void xlnx_tsn_port_fast_age(struct dsa_switch *ds, int port) +{ + struct xlnx_tsn *sw =3D ds->priv; + int err; + + err =3D xlnx_tsn_port_state_cycle(sw, port, TSN_PORT_STATE_FLUSH); + if (err) + dev_err(sw->dev, "port %d: fast age failed (%d)\n", port, err); +} + +static int xlnx_tsn_port_fdb_add(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid, + struct dsa_db db) +{ + struct xlnx_tsn *sw =3D ds->priv; + u8 portlist; + int ret; + + if (!vid) + vid =3D TSN_SW_DEFAULT_VID; + + guard(mutex)(&sw->indirect_lock); + ret =3D xlnx_tsn_cam_read_portlist(sw, addr, vid, &portlist); + if (!ret) { + portlist |=3D TSN_PORT_BIT(port); + ret =3D xlnx_tsn_cam_write(sw, addr, vid, portlist, true); + } + + return ret; +} + +static int xlnx_tsn_port_fdb_del(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid, + struct dsa_db db) +{ + struct xlnx_tsn *sw =3D ds->priv; + u8 portlist; + int ret; + + if (!vid) + vid =3D TSN_SW_DEFAULT_VID; + + guard(mutex)(&sw->indirect_lock); + ret =3D xlnx_tsn_cam_read_portlist(sw, addr, vid, &portlist); + if (!ret) { + if (!portlist) + return 0; + + /* Drop the entry once no port references it. Otherwise + * rewrite it with the updated port list. + */ + portlist &=3D ~TSN_PORT_BIT(port); + ret =3D xlnx_tsn_cam_write(sw, addr, vid, portlist, portlist !=3D 0); + } + + return ret; +} + +static int xlnx_tsn_port_fdb_dump(struct dsa_switch *ds, int port, + dsa_fdb_dump_cb_t *cb, void *data) +{ + struct xlnx_tsn *sw =3D ds->priv; + unsigned char addr[ETH_ALEN]; + u32 base, ctrl, key1, key2; + int ret =3D 0; + u16 vid; + u32 i; + + /* Learnt entries live in a per-MAC-port read-key region. The CPU + * port has no such region. + */ + if (port =3D=3D XLNX_TSN_CPU_PORT) + return 0; + + guard(mutex)(&sw->indirect_lock); + + if (port =3D=3D XLNX_TSN_PORT_MAC2) + base =3D TSN_CAM_MAC2_READ_KEY_BASE; + else + base =3D 0; + + /* Learnt entries occupy non-consecutive slots, so scan the whole + * region and report each slot marked found. + */ + for (i =3D 0; i < TSN_CAM_READ_KEY_COUNT; i++) { + ret =3D xlnx_tsn_cam_wait_ready(sw); + if (ret) + return ret; + + sw_iow(sw, TSN_CAM_CTRL_OFFSET, + FIELD_PREP(TSN_CAM_READ_KEY_ADDR, base + i) | + FIELD_PREP(TSN_CAM_OP_MASK, TSN_CAM_OP_READ_KEY) | + TSN_CAM_OP_ENABLE); + + ret =3D xlnx_tsn_cam_wait_done(sw); + if (ret) + return ret; + + ctrl =3D sw_ior(sw, TSN_CAM_CTRL_OFFSET); + if (!(ctrl & TSN_CAM_FOUND)) + continue; + + key1 =3D sw_ior(sw, TSN_CAM_KEY1_OFFSET); + key2 =3D sw_ior(sw, TSN_CAM_KEY2_OFFSET); + addr[0] =3D key1 >> 24; + addr[1] =3D key1 >> 16; + addr[2] =3D key1 >> 8; + addr[3] =3D key1; + addr[4] =3D key2 >> 8; + addr[5] =3D key2; + vid =3D FIELD_GET(TSN_CAM_VLAN, key2); + if (vid =3D=3D TSN_SW_DEFAULT_VID) + vid =3D 0; + + ret =3D cb(addr, vid, false, data); + if (ret) + return ret; + } + return ret; +} + static void xlnx_tsn_phylink_get_caps(struct dsa_switch *ds, int port, struct phylink_config *config) { @@ -643,7 +918,7 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) struct dsa_port *cpu_dp =3D dsa_to_port(ds, XLNX_TSN_CPU_PORT); struct xlnx_tsn *sw =3D ds->priv; struct dsa_port *dp; - u32 mgmt; + u32 mgmt, reg; int ret; =20 if (!dsa_is_user_port(ds, XLNX_TSN_PORT_MAC1) || @@ -656,6 +931,22 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) =20 sw->conduit =3D cpu_dp->conduit; =20 + /* Pre-arm the learning sub-qualifiers for when a port joins a bridge: + * learn untagged frames under their ingress native VID, and allow + * learning on VIDs with no membership entry while the bridge is + * VLAN-unaware. Both bits are inert while global learning is disabled. + */ + reg =3D sw_ior(sw, TSN_SW_ADDR_LEARN_OFFSET); + reg |=3D TSN_SW_ADDR_LEARN_DISABLE | TSN_SW_ADDR_LEARN_UNTAGGED_EN | + TSN_SW_ADDR_LEARN_NO_VLAN_EN; + sw_iow(sw, TSN_SW_ADDR_LEARN_OFFSET, reg); + + /* On a CAM miss flood unknown tagged unicast frames to all ports. */ + reg =3D sw_ior(sw, TSN_SW_CTRL_OFFSET); + reg &=3D ~TSN_SW_CTRL_UCAST_MISS_MASK; + reg |=3D FIELD_PREP(TSN_SW_CTRL_UCAST_MISS_MASK, TSN_SW_CTRL_UCAST_MISS_F= LOOD); + sw_iow(sw, TSN_SW_CTRL_OFFSET, reg); + /* Route CPU-originated bridge-group control frames (STP, LLDP) to * the single wire port whose MAC-nibble field matches the frame's * source-MAC low nibble, instead of flooding to both. @@ -743,7 +1034,12 @@ static const struct dsa_switch_ops xlnx_tsn_switch_op= s =3D { .teardown =3D xlnx_tsn_teardown, .port_set_mac_address =3D xlnx_tsn_port_set_mac_address, .port_bridge_join =3D xlnx_tsn_port_bridge_join, + .port_bridge_leave =3D xlnx_tsn_port_bridge_leave, .port_stp_state_set =3D xlnx_tsn_port_stp_state_set, + .port_fdb_add =3D xlnx_tsn_port_fdb_add, + .port_fdb_del =3D xlnx_tsn_port_fdb_del, + .port_fdb_dump =3D xlnx_tsn_port_fdb_dump, + .port_fast_age =3D xlnx_tsn_port_fast_age, .port_hwtstamp_get =3D xlnx_tsn_port_hwtstamp_get, .port_hwtstamp_set =3D xlnx_tsn_port_hwtstamp_set, .get_ts_info =3D xlnx_tsn_get_ts_info, @@ -778,6 +1074,9 @@ static int xlnx_tsn_probe(struct platform_device *pdev) sw->dev =3D dev; sw->mac[XLNX_TSN_PORT_MAC1].sw =3D sw; sw->mac[XLNX_TSN_PORT_MAC2].sw =3D sw; + ret =3D devm_mutex_init(dev, &sw->indirect_lock); + if (ret) + return ret; =20 ret =3D xlnx_tsn_map_reg(pdev, "switch", &sw->sw_base); if (ret) diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/x= ilinx_tsn.h index d46150535775..a94f5124a33d 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.h +++ b/drivers/net/dsa/xilinx/xilinx_tsn.h @@ -63,18 +63,104 @@ #define TSN_SW_MGMT_QUEUING_OFFSET 0x00054 #define TSN_SW_MGMT_QUEUING_EP_SA_EGRESS BIT(4) =20 -/* readl_poll_timeout() parameters (in microseconds): poll until - * the port-state change-commit bit self-clears. +/* Shared readl_poll_timeout() parameters (in microseconds) used at + * two call sites: the port-state change-commit bit and the CAM + * operation enable bit. Both self-clear when the operation completes. */ #define TSN_SW_POLL_DELAY_US 10 #define TSN_SW_POLL_TIMEOUT_US 5000 =20 +/* Stream-destination-lookup CAM: maps a (destination MAC, VLAN ID) key + * to an egress port list, backing the bridge FDB. Access is indirect: + * load the key, value, and port-list registers, write the opcode, then + * set the Enable Operation bit in the control register. Poll CAM Init + * Done in the status register to 1 before each operation to confirm the + * block is ready. Enable Operation self-clears when the operation + * finishes. + */ +#define TSN_CAM_CTRL_OFFSET 0x01000 +#define TSN_CAM_STATUS_OFFSET 0x01004 +#define TSN_CAM_KEY1_OFFSET 0x01008 +#define TSN_CAM_KEY2_OFFSET 0x0100c +#define TSN_CAM_TV1_OFFSET 0x01010 +#define TSN_CAM_TV2_OFFSET 0x01014 +#define TSN_CAM_PORT_ACT_OFFSET 0x01018 + +/* Control register: set to start an operation, self-clears when done. */ +#define TSN_CAM_OP_ENABLE BIT(0) +/* Status register: reads 1 when the CAM is ready for the next operation. = */ +#define TSN_CAM_STATUS_READY BIT(0) +#define TSN_CAM_OP_MASK GENMASK(2, 1) +#define TSN_CAM_OP_READ_KEY 0x0 +#define TSN_CAM_OP_ADD 0x1 +#define TSN_CAM_OP_DELETE 0x2 +#define TSN_CAM_OP_READ 0x3 +#define TSN_CAM_FOUND BIT(7) +#define TSN_CAM_VLAN GENMASK(27, 16) +#define TSN_CAM_PORT_LIST GENMASK(10, 8) +#define TSN_CAM_READ_KEY_ADDR GENMASK(19, 8) +#define TSN_CAM_MAC2_READ_KEY_BASE 0x800 +#define TSN_CAM_READ_KEY_COUNT 2048 + +/* HW reset-default native VID; DSA's "no VLAN" (vid 0) maps onto it. */ +#define TSN_SW_DEFAULT_VID 1 + +/* Switch Control Register: switch-wide control fields. */ +#define TSN_SW_CTRL_OFFSET 0x00004 +/* Per-port native-VLAN untag enables: strip the tag on egress when the + * frame VID equals the egress port's native VID. Only the wire ports are + * untagged; the endpoint port is left tagged so the host keeps the VID for + * software classification. + */ +#define TSN_SW_CTRL_MAC1_NATIVE_UNTAG_EN BIT(18) +#define TSN_SW_CTRL_MAC2_NATIVE_UNTAG_EN BIT(19) +/* Action for an ingress frame whose port is not in its VLAN's member + * list: forward to the processor or discard. Pinned to discard. This only + * matters once a VID's Port-List-Valid bit is set, which happens only + * while VLAN filtering is on. + */ +#define TSN_SW_CTRL_MEMBER_VIOL_MASK GENMASK(9, 8) +#define TSN_SW_CTRL_MEMBER_VIOL_DISCARD 0x1 + +/* Forwarding action for a tagged unicast or multicast frame that misses + * both the CAM and the VLAN membership list: flood, to processor, to MAC, + * or discard. + */ +#define TSN_SW_CTRL_UCAST_MISS_MASK GENMASK(1, 0) +#define TSN_SW_CTRL_MCAST_MISS_MASK GENMASK(3, 2) +#define TSN_SW_CTRL_UCAST_MISS_FLOOD 0x1 +#define TSN_SW_CTRL_MCAST_MISS_FLOOD 0x1 +#define TSN_SW_CTRL_MISS_DISCARD 0x3 + +/* Hardware Address Learning Control: switch-wide learning behaviour. */ +#define TSN_SW_ADDR_LEARN_OFFSET 0x00048 +/* Disable the global learning engine; set to 1 while every user port is + * standalone, cleared to 0 when at least one port joins a bridge. The + * sub-qualifier bits below are inert while this bit is set. + */ +#define TSN_SW_ADDR_LEARN_DISABLE BIT(0) +/* Learn the source MAC of untagged and priority-tagged frames against the + * ingress port's native VID; the reset default excludes them from learnin= g. + */ +#define TSN_SW_ADDR_LEARN_UNTAGGED_EN BIT(1) +/* Permit learning on a VID that has no member entry programmed in the VLAN + * membership memory; the reset default only learns already-configured VID= s. + */ +#define TSN_SW_ADDR_LEARN_NO_VLAN_EN BIT(3) + +/* Map a DSA port index to its bit in a switch port list. */ +#define TSN_PORT_BIT(port) BIT(port) + enum tsn_port_state { TSN_PORT_STATE_DISABLED =3D 0, TSN_PORT_STATE_BLOCKING, TSN_PORT_STATE_LISTENING, TSN_PORT_STATE_LEARNING, TSN_PORT_STATE_FORWARDING, + /* Not an STP state. Writing it flushes the port's dynamic learnt + * entries and leaves static FDB entries in place. + */ + TSN_PORT_STATE_FLUSH, }; =20 /* Per-MAC MDIO controller register window, sitting at +0x500 inside @@ -218,6 +304,8 @@ struct xlnx_tsn_mac { * @nb: netdev notifier that handles NETDEV_REGISTER on each swpN * to set its final MAC, and NETDEV_CHANGEADDR on the conduit * to refresh the shared prefix + * @indirect_lock: serialises the CAM and VLAN-membership indirect + * register sequences * @mac: per-MAC state, indexed by user-port number (index 0 unused; * MAC1 at [1], MAC2 at [2]) * @ptp_timer_irq: 1 PPS / RTC-overflow interrupt @@ -239,6 +327,7 @@ struct xlnx_tsn { struct net_device *conduit; u8 mac_prefix[ETH_ALEN]; struct notifier_block nb; + struct mutex indirect_lock; /* serialises CAM indirect access */ struct xlnx_tsn_mac mac[XLNX_TSN_NUM_PORTS]; int ptp_timer_irq; struct ptp_clock *ptp_clock; --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from MW6PR02CU001.outbound.protection.outlook.com (mail-westus2azon11012033.outbound.protection.outlook.com [52.101.48.33]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 95BCB46D577; Fri, 7 Aug 2026 10:46:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.48.33 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099592; cv=fail; b=QqjjM2ZlrtheLnaotdJw97SaQEoNRX4Ws7v0nDdnI3/rCYPEK/Bc15Ccg45vI+C5qSIfYVnsc/objuUA+BkTUanRiCmyzt2l8oa01JlJmFBFKExA6exkNTzg6cF8WiJ9UGwwtAGEcu5Rb7TgC/silAeDNkuDqCFRz+nvJPHEnYs= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099592; c=relaxed/simple; bh=RX7UdVq9aCUT+geaJ+GUSkDIp4ZfM3uzZswTVViPEmM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NIsGJGiFinQ2+BYxg8dmOkAepBHhJXOvnKw9nskWmu0j842ppWrDerU/rzWpzn213d5To/P5U7EutSJLTgPO5GPWDCo5aDbiwhxOYJg7syEUHPp1cvpAAW7WlrppJ9aEYIrI8LmPpdnnimGMcEORoIAxkty1OVmDNerFVjnHzBo= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=EnkIxH8c; arc=fail smtp.client-ip=52.101.48.33 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="EnkIxH8c" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=mG2qiq6ulEvbrsZhyt6OT9tPBKjEZvVS63aQESMC2R7g06vHPAmORRqLQF6d6i1CzkfMwgKjc0eDndcArMA2vxwXc388M59f5hfWCRR3BmOAEP+MRTVg13BWtc0VfyMPA7REq+jPVaThl0Z+97ptDu9ehPmADQm8QcvSEkw3uD3DtoR1pzxznn47f4Gbq/jD7xQCZ27RtB4i1e5fnilk75MK2cx9Jpn1SGwmk3z2/naFzt68Z/vM0XasRtfoPoX6pE4B+EXSWKRYR73lGxzu5qTSp4NnBk17bCnD3nwdVqgY2iQ3JYj7UE0pOCWgatmHPB8f6lg48YZEzVzov6f17Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ElPrYku5hZS69V5JsbOr73/5/q9Y6OBUCb4suy4hExA=; b=o4dVH1pE+m+M8bTOAcQAjIUJDBYPDHWstEFFh26wMDydym3RFOSLd3uLHOv1WBusa5GnfA2QQLVnW4uHFZ8oismlRSFFSfag6kEbHViU3z5PWshsPvcMwoDWRjDb24aC8J5bCryz3p+99er16SAdyzn0bX0nTmXQ/94kQOue3kayEqArm0g8F1k4q7R02zwwrIqJlT8FxThwsd8qT79wv7ALyI/A4Mi3C/wPLOCMtIJjSQqM6Z3eU4FyfjLgrZR03GlX86QCD64fhek4f2CnKXUK9pMxuuKi6WAsgySEU01jR9BaZGbp75A4r6eC7eqCZfWPKiaiaEi9UxrJtwXOaA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ElPrYku5hZS69V5JsbOr73/5/q9Y6OBUCb4suy4hExA=; b=EnkIxH8cHjzas6bAfXupyp46Vs00VkjcIYDkt+NRFjjVHX/ge/K2IA+4d/YVyDuGww5AmcXIK8MFtF78+vbqaph/e0XhBQRePp5mwfdYMHTUXmF1/2vy0kWXGSSjSb29eSgURqk6OpYlY5jMzQwoY7v8P3BBJT6U9gWTiQKdxGM= Received: from PH7P222CA0014.NAMP222.PROD.OUTLOOK.COM (2603:10b6:510:33a::16) by CH3PR12MB9196.namprd12.prod.outlook.com (2603:10b6:610:197::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.23; Fri, 7 Aug 2026 10:46:25 +0000 Received: from SJ1PEPF000023D9.namprd21.prod.outlook.com (2603:10b6:510:33a:cafe::5) by PH7P222CA0014.outlook.office365.com (2603:10b6:510:33a::16) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.23 via Frontend Transport; Fri, 7 Aug 2026 10:46:24 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ1PEPF000023D9.mail.protection.outlook.com (10.167.244.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.0 via Frontend Transport; Fri, 7 Aug 2026 10:46:24 +0000 Received: from satlexmb10.amd.com (10.181.42.219) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:23 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb10.amd.com (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:22 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:46:17 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 19/20] net: dsa: xilinx: offload bridge VLAN filtering to the switch Date: Fri, 7 Aug 2026 16:14:30 +0530 Message-ID: <20260807104431.157230-20-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D9:EE_|CH3PR12MB9196:EE_ X-MS-Office365-Filtering-Correlation-Id: 11bdf564-8392-498e-be2b-08def4712089 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|36860700016|1800799024|82310400026|7416014|376014|11063799006|56012099006|10067099003|6133799003|18002099003|3023799007|22082099003|921020; X-Microsoft-Antispam-Message-Info: zwXavk3eJfTJOYrkphTZSUyTZFl6UcKvy8G6KsUwp4399YJT67TC6TuOXykTX6baMcMXkhzw+hFBHybxURzZGSxXAQcqXha5Ad7PF+H+L9L3Mib+BCF0uK7lUhx9Togq+J9Atu6zygdSbIZ7zLUKnRpIN9DXRrkF4dp6hk8sCPZPsgClOtzN+H3yo8L60mINNyJjeFFiUU9ttAepQjznOaqOK0cOy3YfG6Uv3WxiZORRN9g32uT4JZjLF107kX4+G8oay0D3W8eRxkFWXmDnhm/upv73fMnv5UcOac1Fx/7qEhMHsu73yM9JSXKy6yJNS17d4fZ/CtCQlpl5MN77UJb6FQaXw56J7UeL/DBn9Wvv2f8XLLWB4LFo64MvuA0l9Gow+aaCbXWQ7FJ3xWkcfqYeCHmpCx1p8vMv6A4FQopKXYFEMOxEYflNxzDBT4xiRbRve/c0uxP2qDCde1UP+OXN+AHMwk80uXUWwl1ZvsB3hP/YlZX3hCw7YP8pafL0SjI6lQeCeTg7LRDCS+mFiUGV5SxN2Ukdl+G6F7qafsSiHe4Cp82vo3jFvgHlmsjyU3XrhNw4vjEueN/UKuWt9Y73Rw1Yv8tz07w6uJrRBmvGXalIFc05wH3Lc00sngygseXhsHiUF7PMjQ8y1Nqt0z5cw2ou3tjoFpw3q6jzNYUQpM+/GmnrpZJPK6ri8h6e5LtfSihw6SlUyO8tj6B36CeSdzTC4MR+4TaHdYzj4pfXrrwCZ9LWCkF01rQR4Bmd X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(23010399003)(36860700016)(1800799024)(82310400026)(7416014)(376014)(11063799006)(56012099006)(10067099003)(6133799003)(18002099003)(3023799007)(22082099003)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: B5EFtou5SBXqkxpoGV6F6aaGmRcP1L+d5uAdZ+VxmvvSQ7YtEjHjAm26RF+R2BlGBk3rgmbBkv2tBcGI4p1M+0lRxpAZ5knr7z1CJ2u1QOsaoxp8C/882agc13VqdrkcQ1ZB0j1i4BYTnfC04WAyvvAmkf29EwqI8Ve3WeX2mugC4ECYo694YPoPoQy4SwrQly1OxdR6pUV9CN4cpTbv7QJhKEBuCa1QNdXhKjIfWBM0LhorGPLYQ2PtuPo72GacZOyhVoMlQGmNyW/oF6UgYHsmxjqYAukO2neGHRbfI/w7Bc1ZYi432nc91fludo6wyi8tATLCeNruMXv0KBRnHjjBl/TDSKqeORpIhZP1XUu0hd74wAHlWp/XcE1le80s8/ymZLd0SEhkQEsUAkOTAXAeYaJW2Oh4UZ13Gy8Slyh4Qgi1k+Hed8O77pco4zEu X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:46:24.5633 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 11bdf564-8392-498e-be2b-08def4712089 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D9.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR12MB9196 Content-Type: text/plain; charset="utf-8" The switch always keys the L2 forwarding lookup on {DMAC, VID}. A per-VID port-membership table controls which ports each VLAN spans. The ingress parser assigns untagged frames the native VID of the receiving port before lookup, so tagged and untagged traffic share the same {DMAC, VID} key throughout. Wire bridge VLAN filtering to the port-membership table and native-VID registers so bridge VLAN commands take effect in hardware. Program the native-VID register on PVID changes so untagged ingress lands in the right VLAN. Filtering is switch-wide, so declare it global. The per-MAC VLAN-enable bit adjusts the MAC's maximum frame length to account for the 4-byte tag. Signed-off-by: Nagadheeraj Rottela --- drivers/net/dsa/xilinx/xilinx_tsn.c | 329 +++++++++++++++++++++++++++- drivers/net/dsa/xilinx/xilinx_tsn.h | 50 ++++- 2 files changed, 367 insertions(+), 12 deletions(-) diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c index 57558b0e2613..7e5cf77cfa66 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -20,6 +20,7 @@ #include #include #include +#include =20 #include "xilinx_tsn.h" =20 @@ -804,7 +805,7 @@ static int xlnx_tsn_port_fdb_dump(struct dsa_switch *ds= , int port, addr[4] =3D key2 >> 8; addr[5] =3D key2; vid =3D FIELD_GET(TSN_CAM_VLAN, key2); - if (vid =3D=3D TSN_SW_DEFAULT_VID) + if (!sw->vlan_aware && vid =3D=3D TSN_SW_DEFAULT_VID) vid =3D 0; =20 ret =3D cb(addr, vid, false, data); @@ -814,6 +815,297 @@ static int xlnx_tsn_port_fdb_dump(struct dsa_switch *= ds, int port, return ret; } =20 +/* The VLAN-membership control enable bit self-clears once the indirect + * read or write completes. + */ +static int xlnx_tsn_vlan_wait_done(struct xlnx_tsn *sw) +{ + u32 reg; + + return readl_poll_timeout(sw->sw_base + TSN_VLAN_CTRL_OFFSET, reg, + !(reg & TSN_VLAN_EN), TSN_SW_POLL_DELAY_US, + TSN_SW_POLL_TIMEOUT_US); +} + +/* Caller holds indirect_lock. */ +static int xlnx_tsn_vlan_read(struct xlnx_tsn *sw, u16 vid, u32 *data) +{ + int ret; + + sw_iow(sw, TSN_VLAN_CTRL_OFFSET, + FIELD_PREP(TSN_VLAN_CTRL_VID_MASK, vid) | TSN_VLAN_ACCESS_READ | T= SN_VLAN_EN); + ret =3D xlnx_tsn_vlan_wait_done(sw); + if (ret) + return ret; + + *data =3D sw_ior(sw, TSN_VLAN_DATA_OFFSET); + return 0; +} + +/* Caller holds indirect_lock. */ +static int xlnx_tsn_vlan_write(struct xlnx_tsn *sw, u16 vid, u32 data) +{ + sw_iow(sw, TSN_VLAN_DATA_OFFSET, data); + sw_iow(sw, TSN_VLAN_CTRL_OFFSET, + FIELD_PREP(TSN_VLAN_CTRL_VID_MASK, vid) | TSN_VLAN_ACCESS_WRITE | = TSN_VLAN_EN); + + return xlnx_tsn_vlan_wait_done(sw); +} + +static void xlnx_tsn_set_native_vid(struct xlnx_tsn *sw, int port, u16 vid) +{ + u32 reg; + + switch (port) { + case XLNX_TSN_CPU_PORT: + reg =3D sw_ior(sw, TSN_EP_NATIVE_VLAN_OFFSET); + reg =3D (reg & ~TSN_NATIVE_EP_VLAN_MASK) | + FIELD_PREP(TSN_NATIVE_EP_VLAN_MASK, vid); + sw_iow(sw, TSN_EP_NATIVE_VLAN_OFFSET, reg); + break; + case XLNX_TSN_PORT_MAC1: + reg =3D sw_ior(sw, TSN_MAC_NATIVE_VLAN_OFFSET); + reg =3D (reg & ~TSN_NATIVE_MAC1_VLAN_MASK) | + FIELD_PREP(TSN_NATIVE_MAC1_VLAN_MASK, vid); + sw_iow(sw, TSN_MAC_NATIVE_VLAN_OFFSET, reg); + break; + case XLNX_TSN_PORT_MAC2: + reg =3D sw_ior(sw, TSN_MAC_NATIVE_VLAN_OFFSET); + reg =3D (reg & ~TSN_NATIVE_MAC2_VLAN_MASK) | + FIELD_PREP(TSN_NATIVE_MAC2_VLAN_MASK, vid); + sw_iow(sw, TSN_MAC_NATIVE_VLAN_OFFSET, reg); + break; + } +} + +/* Enable or disable native-VLAN egress untagging for a wire port. + * The endpoint port always sends frames tagged toward the host, so + * it is not handled here. + */ +static void xlnx_tsn_set_native_untag(struct xlnx_tsn *sw, int port, bool = en) +{ + u32 bit, reg; + + switch (port) { + case XLNX_TSN_PORT_MAC1: + bit =3D TSN_SW_CTRL_MAC1_NATIVE_UNTAG_EN; + break; + case XLNX_TSN_PORT_MAC2: + bit =3D TSN_SW_CTRL_MAC2_NATIVE_UNTAG_EN; + break; + default: + return; + } + + reg =3D sw_ior(sw, TSN_SW_CTRL_OFFSET); + if (en) + reg |=3D bit; + else + reg &=3D ~bit; + sw_iow(sw, TSN_SW_CTRL_OFFSET, reg); +} + +/* Write a port's native VID and egress-untag setting to hardware. + * While VLAN filtering is off, every port uses the reset-default + * native VID and stays tagged, so committed VLANs have no effect + * until the bridge goes VLAN-aware. Caller holds indirect_lock. + */ +static void xlnx_tsn_apply_pvid(struct xlnx_tsn *sw, int port) +{ + u16 vid =3D sw->vlan_aware ? sw->pvid[port] : TSN_SW_DEFAULT_VID; + bool untag =3D sw->vlan_aware && sw->pvid_untagged[port]; + + xlnx_tsn_set_native_vid(sw, port, vid); + xlnx_tsn_set_native_untag(sw, port, untag); +} + +/* Restrict learning to VIDs that already have a membership entry. + * When on, frames with an unregistered VID are not learned, preventing + * a spurious CAM entry that would bypass the membership check on a + * later hit. When off, learning is allowed on any VID, as required + * while the bridge is VLAN-unaware. Caller holds indirect_lock. + */ +static void xlnx_tsn_set_vlan_only_learning(struct xlnx_tsn *sw, bool on) +{ + u32 reg =3D sw_ior(sw, TSN_SW_ADDR_LEARN_OFFSET); + + if (on) + reg &=3D ~TSN_SW_ADDR_LEARN_NO_VLAN_EN; + else + reg |=3D TSN_SW_ADDR_LEARN_NO_VLAN_EN; + sw_iow(sw, TSN_SW_ADDR_LEARN_OFFSET, reg); +} + +static int xlnx_tsn_port_vlan_filtering(struct dsa_switch *ds, int port, + bool vlan_filtering, + struct netlink_ext_ack *extack) +{ + struct xlnx_tsn *sw =3D ds->priv; + struct dsa_port *dp; + unsigned long bit; + u32 reg, data; + int ret; + + guard(mutex)(&sw->indirect_lock); + + /* Flip Port-List-Valid on every configured VID: set it to enforce + * membership, clear it so VLANs added while filtering was off stay + * inert. + */ + for_each_set_bit(bit, sw->cfg_vids, VLAN_N_VID) { + ret =3D xlnx_tsn_vlan_read(sw, bit, &data); + if (ret) + return ret; + + if (vlan_filtering) + data |=3D TSN_VLAN_PORT_LIST_VALID; + else + data &=3D ~TSN_VLAN_PORT_LIST_VALID; + + ret =3D xlnx_tsn_vlan_write(sw, bit, data); + if (ret) + return ret; + } + + sw->vlan_aware =3D vlan_filtering; + + /* Miss policy for unicast and multicast. It only kicks in when the + * CAM misses and the VID has no membership entry either. So flood the + * unregistered ones while VLAN-unaware, and drop them once filtering + * is on. + */ + reg =3D sw_ior(sw, TSN_SW_CTRL_OFFSET); + reg &=3D ~(TSN_SW_CTRL_UCAST_MISS_MASK | TSN_SW_CTRL_MCAST_MISS_MASK); + if (vlan_filtering) { + reg |=3D FIELD_PREP(TSN_SW_CTRL_UCAST_MISS_MASK, TSN_SW_CTRL_MISS_DISCAR= D) | + FIELD_PREP(TSN_SW_CTRL_MCAST_MISS_MASK, TSN_SW_CTRL_MISS_DISCARD); + } else { + reg |=3D FIELD_PREP(TSN_SW_CTRL_UCAST_MISS_MASK, TSN_SW_CTRL_UCAST_MISS_= FLOOD) | + FIELD_PREP(TSN_SW_CTRL_MCAST_MISS_MASK, TSN_SW_CTRL_MCAST_MISS_FL= OOD); + } + sw_iow(sw, TSN_SW_CTRL_OFFSET, reg); + + xlnx_tsn_set_vlan_only_learning(sw, vlan_filtering); + + /* Apply the native VID and egress-untag settings saved while + * filtering was off, or restore defaults when filtering is turned + * off. VLANs added while filtering is already on are applied + * directly by port_vlan_add(). + */ + dsa_switch_for_each_user_port(dp, ds) + xlnx_tsn_apply_pvid(sw, dp->index); + + /* The learning-control bits latch only when a port passes through + * blocking, so cycle each port to make the new setting take hold. + * The transition does not drop learnt entries, so flush them too - + * they were keyed on the old native VID and are now stale. + */ + dsa_switch_for_each_user_port(dp, ds) { + ret =3D xlnx_tsn_port_state_cycle(sw, dp->index, + TSN_PORT_STATE_BLOCKING); + if (ret) + return ret; + + ret =3D xlnx_tsn_port_state_cycle(sw, dp->index, + TSN_PORT_STATE_FLUSH); + if (ret) + return ret; + } + + return 0; +} + +static int xlnx_tsn_port_vlan_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack) +{ + bool untagged =3D vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; + bool pvid =3D vlan->flags & BRIDGE_VLAN_INFO_PVID; + struct xlnx_tsn *sw =3D ds->priv; + u32 data; + int ret; + + guard(mutex)(&sw->indirect_lock); + + /* The hardware strips the tag on egress only for a wire port's native + * VLAN. Reject an untagged request for any other VID. The CPU port is + * exempt as it always trunks tagged toward the host. + */ + if (port !=3D XLNX_TSN_CPU_PORT && untagged && !pvid && + vlan->vid !=3D sw->pvid[port]) { + NL_SET_ERR_MSG_MOD(extack, + "untagged egress is only supported for the port PVID"); + return -EINVAL; + } + + ret =3D xlnx_tsn_vlan_read(sw, vlan->vid, &data); + if (ret) + return ret; + + data |=3D TSN_PORT_BIT(port); + if (sw->vlan_aware) + data |=3D TSN_VLAN_PORT_LIST_VALID; + else + data &=3D ~TSN_VLAN_PORT_LIST_VALID; + ret =3D xlnx_tsn_vlan_write(sw, vlan->vid, data); + if (ret) + return ret; + + set_bit(vlan->vid, sw->cfg_vids); + + /* The CPU port needs membership only. */ + if (port =3D=3D XLNX_TSN_CPU_PORT) + return 0; + + if (pvid) { + sw->pvid[port] =3D vlan->vid; + sw->pvid_untagged[port] =3D untagged; + xlnx_tsn_apply_pvid(sw, port); + } + + if (vlan->vid =3D=3D sw->pvid[port] && + sw->pvid_untagged[port] !=3D untagged) { + sw->pvid_untagged[port] =3D untagged; + xlnx_tsn_apply_pvid(sw, port); + } + + return 0; +} + +static int xlnx_tsn_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan) +{ + struct xlnx_tsn *sw =3D ds->priv; + bool last_member; + u32 data; + int ret; + + guard(mutex)(&sw->indirect_lock); + ret =3D xlnx_tsn_vlan_read(sw, vlan->vid, &data); + if (ret) + return ret; + + data &=3D ~TSN_PORT_BIT(port); + last_member =3D !(data & TSN_VLAN_PORT_LIST_MASK); + if (last_member) + data &=3D ~TSN_VLAN_PORT_LIST_VALID; + + ret =3D xlnx_tsn_vlan_write(sw, vlan->vid, data); + if (ret) + return ret; + + if (last_member) + clear_bit(vlan->vid, sw->cfg_vids); + + if (sw->pvid[port] =3D=3D vlan->vid) { + sw->pvid[port] =3D TSN_SW_DEFAULT_VID; + sw->pvid_untagged[port] =3D false; + xlnx_tsn_apply_pvid(sw, port); + } + + return 0; +} + static void xlnx_tsn_phylink_get_caps(struct dsa_switch *ds, int port, struct phylink_config *config) { @@ -900,10 +1192,9 @@ static void xlnx_tsn_mac_link_up(struct phylink_confi= g *config, } mac_iow(m, TSN_SPEED_CFG_OFFSET, speed_cfg); =20 - rcw1 =3D mac_ior(m, TSN_RCW1_OFFSET) | TSN_RCW1_RX_EN; + rcw1 =3D mac_ior(m, TSN_RCW1_OFFSET) | TSN_RCW1_RX_EN | TSN_RCW1_VLAN_EN; + tc =3D mac_ior(m, TSN_TC_OFFSET) | TSN_TC_TX_EN | TSN_TC_VLAN_EN; mac_iow(m, TSN_RCW1_OFFSET, rcw1); - - tc =3D mac_ior(m, TSN_TC_OFFSET) | TSN_TC_TX_EN; mac_iow(m, TSN_TC_OFFSET, tc); } =20 @@ -919,7 +1210,7 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) struct xlnx_tsn *sw =3D ds->priv; struct dsa_port *dp; u32 mgmt, reg; - int ret; + int port, ret; =20 if (!dsa_is_user_port(ds, XLNX_TSN_PORT_MAC1) || !dsa_is_user_port(ds, XLNX_TSN_PORT_MAC2)) @@ -941,12 +1232,26 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) TSN_SW_ADDR_LEARN_NO_VLAN_EN; sw_iow(sw, TSN_SW_ADDR_LEARN_OFFSET, reg); =20 - /* On a CAM miss flood unknown tagged unicast frames to all ports. */ + /* On a CAM miss flood unknown tagged unicast frames to all ports. + * Also drop tagged frames whose ingress port is not in the VLAN + * member list. The membership check only bites once VLANs exist. + */ reg =3D sw_ior(sw, TSN_SW_CTRL_OFFSET); - reg &=3D ~TSN_SW_CTRL_UCAST_MISS_MASK; - reg |=3D FIELD_PREP(TSN_SW_CTRL_UCAST_MISS_MASK, TSN_SW_CTRL_UCAST_MISS_F= LOOD); + reg &=3D ~(TSN_SW_CTRL_UCAST_MISS_MASK | TSN_SW_CTRL_MEMBER_VIOL_MASK); + reg |=3D FIELD_PREP(TSN_SW_CTRL_UCAST_MISS_MASK, TSN_SW_CTRL_UCAST_MISS_F= LOOD) | + FIELD_PREP(TSN_SW_CTRL_MEMBER_VIOL_MASK, TSN_SW_CTRL_MEMBER_VIOL_D= ISCARD); sw_iow(sw, TSN_SW_CTRL_OFFSET, reg); =20 + /* Every port uses the default native VID until VLAN filtering is + * enabled. Seed the PVID shadow and program the native VID + * registers to match. + */ + scoped_guard(mutex, &sw->indirect_lock) + for (port =3D XLNX_TSN_CPU_PORT; port < XLNX_TSN_NUM_PORTS; port++) { + sw->pvid[port] =3D TSN_SW_DEFAULT_VID; + xlnx_tsn_apply_pvid(sw, port); + } + /* Route CPU-originated bridge-group control frames (STP, LLDP) to * the single wire port whose MAC-nibble field matches the frame's * source-MAC low nibble, instead of flooding to both. @@ -1040,6 +1345,9 @@ static const struct dsa_switch_ops xlnx_tsn_switch_op= s =3D { .port_fdb_del =3D xlnx_tsn_port_fdb_del, .port_fdb_dump =3D xlnx_tsn_port_fdb_dump, .port_fast_age =3D xlnx_tsn_port_fast_age, + .port_vlan_filtering =3D xlnx_tsn_port_vlan_filtering, + .port_vlan_add =3D xlnx_tsn_port_vlan_add, + .port_vlan_del =3D xlnx_tsn_port_vlan_del, .port_hwtstamp_get =3D xlnx_tsn_port_hwtstamp_get, .port_hwtstamp_set =3D xlnx_tsn_port_hwtstamp_set, .get_ts_info =3D xlnx_tsn_get_ts_info, @@ -1102,6 +1410,11 @@ static int xlnx_tsn_probe(struct platform_device *pd= ev) /* The fabric offloads a single bridge across the user ports. */ ds->max_num_bridges =3D 1; =20 + /* The switch fabric is a single VLAN domain shared by all ports, so + * VLAN filtering is configured switch-wide rather than per port. + */ + ds->vlan_filtering_is_global =3D true; + platform_set_drvdata(pdev, sw); =20 return dsa_register_switch(ds); diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/x= ilinx_tsn.h index a94f5124a33d..955041cde564 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.h +++ b/drivers/net/dsa/xilinx/xilinx_tsn.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -64,8 +65,9 @@ #define TSN_SW_MGMT_QUEUING_EP_SA_EGRESS BIT(4) =20 /* Shared readl_poll_timeout() parameters (in microseconds) used at - * two call sites: the port-state change-commit bit and the CAM - * operation enable bit. Both self-clear when the operation completes. + * three call sites: the port-state change-commit bit, the CAM + * operation enable bit, and the VLAN-memory operation enable bit. + * All three self-clear when the hardware completes the operation. */ #define TSN_SW_POLL_DELAY_US 10 #define TSN_SW_POLL_TIMEOUT_US 5000 @@ -102,6 +104,28 @@ #define TSN_CAM_MAC2_READ_KEY_BASE 0x800 #define TSN_CAM_READ_KEY_COUNT 2048 =20 +/* Port VLAN membership memory: per-VID egress port list, accessed + * indirectly through a control/data register pair. The control + * register's enable bit self-clears when the read or write completes. + */ +#define TSN_VLAN_CTRL_OFFSET 0x01100 +#define TSN_VLAN_DATA_OFFSET 0x01104 +#define TSN_VLAN_CTRL_VID_MASK GENMASK(27, 16) +#define TSN_VLAN_ACCESS_READ 0 +#define TSN_VLAN_ACCESS_WRITE BIT(1) +#define TSN_VLAN_EN BIT(0) +#define TSN_VLAN_PORT_LIST_VALID BIT(3) +#define TSN_VLAN_PORT_LIST_MASK GENMASK(2, 0) + +/* Per-port native (PVID) registers: the endpoint port at +0x40, the two + * MAC ports packed into +0x44 (MAC1 in the low half, MAC2 in the high). + */ +#define TSN_EP_NATIVE_VLAN_OFFSET 0x00040 +#define TSN_MAC_NATIVE_VLAN_OFFSET 0x00044 +#define TSN_NATIVE_EP_VLAN_MASK GENMASK(11, 0) +#define TSN_NATIVE_MAC1_VLAN_MASK GENMASK(11, 0) +#define TSN_NATIVE_MAC2_VLAN_MASK GENMASK(27, 16) + /* HW reset-default native VID; DSA's "no VLAN" (vid 0) maps onto it. */ #define TSN_SW_DEFAULT_VID 1 =20 @@ -183,12 +207,17 @@ enum tsn_port_state { =20 #define TSN_MDIO_MRD_MASK GENMASK(15, 0) =20 -/* Per-MAC receive / transmit / speed configuration registers. */ +/* Per-MAC receive / transmit / speed configuration registers. Setting + * the VLAN enable bit makes the MAC accept full-size VLAN-tagged frames + * without treating the extra 4 bytes as an oversize error. + */ #define TSN_RCW1_OFFSET 0x00000404 #define TSN_RCW1_RX_EN BIT(28) +#define TSN_RCW1_VLAN_EN BIT(27) =20 #define TSN_TC_OFFSET 0x00000408 #define TSN_TC_TX_EN BIT(28) +#define TSN_TC_VLAN_EN BIT(27) =20 #define TSN_SPEED_CFG_OFFSET 0x00000410 #define TSN_SPEED_CFG_MASK GENMASK(31, 30) @@ -304,6 +333,15 @@ struct xlnx_tsn_mac { * @nb: netdev notifier that handles NETDEV_REGISTER on each swpN * to set its final MAC, and NETDEV_CHANGEADDR on the conduit * to refresh the shared prefix + * @vlan_aware: true once bridge VLAN filtering is on. Until then the + * native VID, egress untag, and membership enforcement are + * all held back. + * @pvid: per-port bridge PVID shadow, written to the native VID register + * while @vlan_aware; defaults to TSN_SW_DEFAULT_VID + * @pvid_untagged: per-port flag tracking whether the PVID egresses + * untagged; drives the native-VLAN untag enable + * @cfg_vids: VIDs with a membership entry in the VLAN-membership memory, + * used to walk and update Port-List-Valid when @vlan_aware changes * @indirect_lock: serialises the CAM and VLAN-membership indirect * register sequences * @mac: per-MAC state, indexed by user-port number (index 0 unused; @@ -327,7 +365,11 @@ struct xlnx_tsn { struct net_device *conduit; u8 mac_prefix[ETH_ALEN]; struct notifier_block nb; - struct mutex indirect_lock; /* serialises CAM indirect access */ + bool vlan_aware; + u16 pvid[XLNX_TSN_NUM_PORTS]; + bool pvid_untagged[XLNX_TSN_NUM_PORTS]; + DECLARE_BITMAP(cfg_vids, VLAN_N_VID); + struct mutex indirect_lock; /* serialises CAM + VLAN-memory access */ struct xlnx_tsn_mac mac[XLNX_TSN_NUM_PORTS]; int ptp_timer_irq; struct ptp_clock *ptp_clock; --=20 2.34.1 From nobody Tue Sep 29 13:20:39 2026 Received: from PH7PR06CU001.outbound.protection.outlook.com (mail-westus3azon11010006.outbound.protection.outlook.com [52.101.201.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55F554334C0; Fri, 7 Aug 2026 10:46:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.201.6 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099598; cv=fail; b=VhKc5PODw7KfcrotaO3fmV8bbOA+zPx3LbkHlvO+AllEm4O1GD8cq0n3xGv/z9Zt5TsC7fVsRTnnztfN7W5dybWOgbGtYkNEOQuXHJsX9TK0hjxGnD1r1IHUtEBfAAVRLKzyKoo/g2+IAJz3NrPfgK5qbo2PDo4MkJAKKG8ChfA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099598; c=relaxed/simple; bh=ZoUuuRRKWiJ4geVvBui8Ujgx96KFMArmlaAjrS6fZaE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=eVVAoFlelhr8HvpdBMDtVw1aEw5ApVnfQLDIC6nEGKs28HcqKhQqQYScv/hgR0v59tcg3BRbVWSmHjO70Aesj2JQ/fBvKjawjwrpst9nOBZOw6hKmQJfYKvmbYAheHaELhdyu+0HYPGWd3ikzYDv4+mX+l6PW6O9MhKEotJ6YuA= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=QoGSTnbY; arc=fail smtp.client-ip=52.101.201.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="QoGSTnbY" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=kZNE0OCBFKm85DKz5jhw2eDzah6RjLoV2Tvj7ek+ZNOIiIH1HVwfIbbAuvW0D+T5r0FXse1XU9Gp7NS//mLGgvB8ViJFQ7m+e7owyUd8wKe/1hTjZxPO//ahqtxGhoV0YsMnD+d77Xa44KcE2Rb12F6ZicmjPR2P8PThb+yYhjumbcGAT5kWyn7NXdoJikDKf6vTxCSkdiw4X7cfsDHuR7J5PEdpuXZSlJa0BZAVtZS8VRQ+/nbc9uFeYN/myLvM7sZcyn14Fo3zXjP2+PQ7ttdHATTHywF3YZcgaTazdwUOZ8kRnR+7hmV5FG53odAUep6JxQXQqVLP50NowZAfyw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=JyVpYFDqp7DKzmvb3OYbYySE/GVOTMB2NAk3snkagzM=; b=nqlQjhNPFQcx47CEr+n1rMCU+tCrwRuM3vRCLPDYX4zfBQk7+OLXn9C2OGN+SKups7ym0we1xAtNFCA2OH/ahKf0PmT0QQmco3Fa3TEN4wLtCeGq6kwpzLbaEk9uSLoopBnY8v8MpVpNj2PpFMqEQCIcU673J4KbobqV9E45dyvkfyQNflul9jYv25mPoWvgxg6Fn0usQiIX8XdeH3h8wozJm2ldDBnadqqF7YnCPmbcyrY15kQYgRYDa7NtA/8cGHR+excpvWbCnBKOiFxBxDTXWDAwhXTKcg7xWzmeNmfUXfgAEDAkXriMc/vbmOWXBre6iSafB7Dr5YSDT/lfkQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lunn.ch smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=JyVpYFDqp7DKzmvb3OYbYySE/GVOTMB2NAk3snkagzM=; b=QoGSTnbYcP2lHymLGcCDfzZ90mPHEYbHw8KoGtgYff1x55ih5+4kC8n4PyTGDETR10tmG9etMjzeKUcGZvjgA+Zrn+r3LlzqtXXW59no3ECMKZTxagNBBIxX2fkAAAomIWMNZncsRehKw0tFPgPncqU/T9EqkDkneJ1tF71Rnis= Received: from BY3PR05CA0050.namprd05.prod.outlook.com (2603:10b6:a03:39b::25) by CY5PR12MB6623.namprd12.prod.outlook.com (2603:10b6:930:41::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.23; Fri, 7 Aug 2026 10:46:30 +0000 Received: from SJ5PEPF000001EF.namprd05.prod.outlook.com (2603:10b6:a03:39b:cafe::47) by BY3PR05CA0050.outlook.office365.com (2603:10b6:a03:39b::25) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.315.10 via Frontend Transport; Fri, 7 Aug 2026 10:46:30 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SJ5PEPF000001EF.mail.protection.outlook.com (10.167.242.203) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.315.6 via Frontend Transport; Fri, 7 Aug 2026 10:46:30 +0000 Received: from satlexmb10.amd.com (10.181.42.219) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:29 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb10.amd.com (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Fri, 7 Aug 2026 05:46:28 -0500 Received: from xhdnrottela40.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 7 Aug 2026 05:46:23 -0500 From: Nagadheeraj Rottela To: Srinivas Neeli , Andrew Lunn , "David S . Miller" , "Eric Dumazet" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Cochran , Michal Simek , Andrew Lunn , Vladimir Oltean , Simon Horman , Russell King CC: , , , , , Subject: [PATCH 20/20] net: dsa: xilinx: trap link-local control frames to the CPU port Date: Fri, 7 Aug 2026 16:14:31 +0530 Message-ID: <20260807104431.157230-21-nagadheeraj.rottela@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> References: <20260807104431.157230-1-nagadheeraj.rottela@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001EF:EE_|CY5PR12MB6623:EE_ X-MS-Office365-Filtering-Correlation-Id: a27e4b98-7617-44d0-80df-08def47123cc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|376014|23010399003|36860700016|1800799024|82310400026|921020|6133799003|10067099003|11063799006|56012099006|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: lZNwlreApoTFzauDRTpv9o3YYW5yLAH6nGnxf9bwxdT46xpJyGdI7xkFchsPhOSLNMKqcC3k+yu6fqPK9+a7QzeZgZcVpPVrpm1g1VxKpMLWakethIwPaCQvqYfh3lH9cy9aNEcTxSd+TILnUTYz3utOzVueHWfBQwVfRSsdM2dxk/dSNCpueRWEuOSf4oVrHWc6oOakSXYDaals1T38DnVB0Ciag9OE5W/hK+sEQSnz2AzRJCu6Onq7VOA00Engq6QqQHD5UPqpkYdZB4+jPsjr3LpuhnVyqH2KlLGaqAIIdu5qn6n/cbU4y1xgifUlSE+ThYxs+AMGvmphYVrvDy9EFynHWPyZB7CJHQtp2p04E8ESMpzN5oWQdkAk0ESNnzRoSbm0ef0OKkbgT0gO2uZv0bkjBkFRCutU5M6Qk3yRM7Zlj7QTga+ewWQ1tKEW/PeSmIP4MWnbaLM9ZJ42xhr58vdd7DuPdmDVES4u6QGU7qV7Yp+yPDXs+ATu54ZgM7tyhbS0YTSyl+ZSQv1azyrX5+80OGEQHslDyCjwlY6u+7vvrcrlz2RHGUyuOrCCXpQeeSL39FuVw/6fKCgu6WyUSjDWtNjxNC3+qEIu+trR0oCmNO3pf0+xhiRaxbshj59qNa5NevuaMpflW+TI4RtZKQLkmzK6+cjx/3l4uA6/kCTij+nj3FJr0MVXv3Y8AEnBu6LXnY8yPEjsMUCTvFEmHI0OdBXcXdZwgmrJ890dYiH5PbAGfdWp3VuOwcyB X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(7416014)(376014)(23010399003)(36860700016)(1800799024)(82310400026)(921020)(6133799003)(10067099003)(11063799006)(56012099006)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: L0+sRRuIcGsibYC1Eo8B4BzNrob8Q/KNJhzH8c13TMzf+Ucq+YXe5FYjeNGyeYUaPbg3O0ZghkKDoPDI3LkCRQ6L6umnMhNxoPdRACMyyvTGsJkBGZqawKxdXwuHVZOALd6hnfVOuZXyGec1aC0E3SGOPKpZr6V5+KcfWLv+wkLUA+6AjfDG3CBgqXVkQJY+M9+wEWyfV/rckFeoaLomvFy/V5115UCx5LqQoa1E1Hjl2+0D3H3u9mtMBFb0zTvCoaKDg214YkhbVUJ36Jtinm/LMe1bU4NeVN8yaOQ6i7cKUAVkb6cWOFdnB5Z+iVnymAJn6PZykRh6v/UNGkLp3vfz9PzG7S09q3Hc7dODiHSt07OTqwADyABh0y4fwa5eE62AX//dck0jO7kLSHfnlojTJmrPdv/HJhsaH6Jk/0LHxMSiJgkS9xIbi5FoUB7A X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2026 10:46:30.1018 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a27e4b98-7617-44d0-80df-08def47123cc X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001EF.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY5PR12MB6623 Content-Type: text/plain; charset="utf-8" The TSN switch fabric forwards frames by CAM lookup. A frame whose destination MAC misses the CAM is treated as unknown and flooded to all ports except the ingress port. Link-local control frames (STP BPDUs, LLDPDUs) use destination MACs in the IEEE 802.1 bridge-group address range 01:80:c2:00:00:00..0f, which a bridge must consume locally and never relay between ports. Install CAM entries for the in-use bridge-group addresses (STP at 01:80:c2:00:00:00 and LLDP at 01:80:c2:00:00:0e). Set the forwarding port list to the CPU port only and set the endpoint management queuing bit in the port-action register. The switch then delivers trapped frames on the management queue. The CAM matches on (DA, VID) exactly. Untagged control frames are looked up under the ingress port's native VID, so a trap entry must exist for every native VID in use. Keep entries in sync with each wire port's current native VID. The CAM has no DA-mask capability, so covering all 16 bridge-group addresses would cost 16 entries per VID. Only the addresses in active use are trapped. Signed-off-by: Nagadheeraj Rottela --- drivers/net/dsa/xilinx/xilinx_tsn.c | 176 ++++++++++++++++++++++++++-- drivers/net/dsa/xilinx/xilinx_tsn.h | 9 ++ 2 files changed, 176 insertions(+), 9 deletions(-) diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/x= ilinx_tsn.c index 7e5cf77cfa66..e35dbcdfcbda 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.c +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c @@ -671,11 +671,14 @@ static int xlnx_tsn_cam_read_portlist(struct xlnx_tsn= *sw, } =20 /* Add (add=3Dtrue) or delete (add=3Dfalse) the (MAC, VID) entry carrying = the - * given port list. Caller holds indirect_lock. + * given port list. Set mgmt for entries whose frames must be classified as + * endpoint management traffic; clear it for plain forwarding/FDB entries. + * Caller holds indirect_lock. */ static int xlnx_tsn_cam_write(struct xlnx_tsn *sw, const unsigned char *ad= dr, - u16 vid, u8 portlist, bool add) + u16 vid, u8 portlist, bool mgmt, bool add) { + u32 port_act; int ret; =20 ret =3D xlnx_tsn_cam_wait_ready(sw); @@ -685,8 +688,13 @@ static int xlnx_tsn_cam_write(struct xlnx_tsn *sw, con= st unsigned char *addr, xlnx_tsn_cam_load_key(sw, addr, vid); sw_iow(sw, TSN_CAM_TV1_OFFSET, 0); sw_iow(sw, TSN_CAM_TV2_OFFSET, 0); - sw_iow(sw, TSN_CAM_PORT_ACT_OFFSET, - FIELD_PREP(TSN_CAM_PORT_LIST, portlist)); + + port_act =3D FIELD_PREP(TSN_CAM_PORT_LIST, portlist); + if (mgmt) + port_act |=3D TSN_CAM_EP_MGMTQ_EN; + + sw_iow(sw, TSN_CAM_PORT_ACT_OFFSET, port_act); + sw_iow(sw, TSN_CAM_CTRL_OFFSET, FIELD_PREP(TSN_CAM_OP_MASK, add ? TSN_CAM_OP_ADD : TSN_CAM_OP_DELE= TE) | TSN_CAM_OP_ENABLE); @@ -694,6 +702,28 @@ static int xlnx_tsn_cam_write(struct xlnx_tsn *sw, con= st unsigned char *addr, return xlnx_tsn_cam_wait_done(sw); } =20 +/* IEEE 802.1 bridge-group destination MACs. A bridge must consume + * these locally rather than relay them between ports. Each address + * gets a CAM trap entry pointing to the CPU port only. The CAM + * matches the destination MAC exactly, so only the addresses in + * active use are listed here. + */ +static const u8 xlnx_tsn_ctrl_das[][ETH_ALEN] =3D { + { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }, /* STP / RSTP / MSTP */ + { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }, /* LLDP */ +}; + +static bool xlnx_tsn_addr_is_ctrl_trap(const unsigned char *addr) +{ + int i; + + for (i =3D 0; i < ARRAY_SIZE(xlnx_tsn_ctrl_das); i++) + if (ether_addr_equal(addr, xlnx_tsn_ctrl_das[i])) + return true; + + return false; +} + static void xlnx_tsn_port_fast_age(struct dsa_switch *ds, int port) { struct xlnx_tsn *sw =3D ds->priv; @@ -712,6 +742,9 @@ static int xlnx_tsn_port_fdb_add(struct dsa_switch *ds,= int port, u8 portlist; int ret; =20 + if (xlnx_tsn_addr_is_ctrl_trap(addr)) + return 0; + if (!vid) vid =3D TSN_SW_DEFAULT_VID; =20 @@ -719,7 +752,7 @@ static int xlnx_tsn_port_fdb_add(struct dsa_switch *ds,= int port, ret =3D xlnx_tsn_cam_read_portlist(sw, addr, vid, &portlist); if (!ret) { portlist |=3D TSN_PORT_BIT(port); - ret =3D xlnx_tsn_cam_write(sw, addr, vid, portlist, true); + ret =3D xlnx_tsn_cam_write(sw, addr, vid, portlist, false, true); } =20 return ret; @@ -733,6 +766,9 @@ static int xlnx_tsn_port_fdb_del(struct dsa_switch *ds,= int port, u8 portlist; int ret; =20 + if (xlnx_tsn_addr_is_ctrl_trap(addr)) + return 0; + if (!vid) vid =3D TSN_SW_DEFAULT_VID; =20 @@ -746,7 +782,8 @@ static int xlnx_tsn_port_fdb_del(struct dsa_switch *ds,= int port, * rewrite it with the updated port list. */ portlist &=3D ~TSN_PORT_BIT(port); - ret =3D xlnx_tsn_cam_write(sw, addr, vid, portlist, portlist !=3D 0); + ret =3D xlnx_tsn_cam_write(sw, addr, vid, portlist, false, + portlist !=3D 0); } =20 return ret; @@ -936,12 +973,93 @@ static void xlnx_tsn_set_vlan_only_learning(struct xl= nx_tsn *sw, bool on) sw_iow(sw, TSN_SW_ADDR_LEARN_OFFSET, reg); } =20 +/* Install or remove link-local control-frame traps for one VID. + * Each entry points to the CPU port and marks frames as management + * traffic for delivery on the management queue. Caller holds + * indirect_lock. + */ +static int xlnx_tsn_set_ctrl_traps(struct xlnx_tsn *sw, u16 vid, bool add) +{ + int i, ret; + + for (i =3D 0; i < ARRAY_SIZE(xlnx_tsn_ctrl_das); i++) { + ret =3D xlnx_tsn_cam_write(sw, xlnx_tsn_ctrl_das[i], vid, + TSN_PORT_BIT(XLNX_TSN_CPU_PORT), + true, add); + if (ret) + return ret; + } + + return 0; +} + +static bool xlnx_tsn_vid_in(const u16 *vids, int count, u16 vid) +{ + int i; + + for (i =3D 0; i < count; i++) + if (vids[i] =3D=3D vid) + return true; + + return false; +} + +/* Keep CAM traps in sync with the native VIDs the wire ports use. An + * untagged BPDU or LLDP frame is looked up under the ingress port's + * native VID, so a trap must exist at each native VID in use. While + * the bridge is not VLAN-aware every port uses the default VID. Call + * again whenever a native VID changes. Caller holds indirect_lock. + */ +static int xlnx_tsn_sync_ctrl_traps(struct xlnx_tsn *sw) +{ + u16 want[XLNX_TSN_NUM_PORTS - 1], vid; + struct dsa_port *dp; + int i, n, ret; + + n =3D 0; + dsa_switch_for_each_user_port(dp, &sw->ds) { + vid =3D sw->vlan_aware ? sw->pvid[dp->index] : TSN_SW_DEFAULT_VID; + if (!xlnx_tsn_vid_in(want, n, vid)) + want[n++] =3D vid; + } + + /* Remove traps at VIDs no longer used as any wire port's native VID. */ + i =3D 0; + while (i < sw->ctrl_trap_count) { + vid =3D sw->ctrl_trap_vid[i]; + if (xlnx_tsn_vid_in(want, n, vid)) { + i++; + continue; + } + ret =3D xlnx_tsn_set_ctrl_traps(sw, vid, false); + if (ret) + return ret; + + sw->ctrl_trap_vid[i] =3D sw->ctrl_trap_vid[--sw->ctrl_trap_count]; + } + + /* Add traps at native VIDs not yet installed. */ + for (i =3D 0; i < n; i++) { + if (xlnx_tsn_vid_in(sw->ctrl_trap_vid, sw->ctrl_trap_count, + want[i])) + continue; + ret =3D xlnx_tsn_set_ctrl_traps(sw, want[i], true); + if (ret) + return ret; + + sw->ctrl_trap_vid[sw->ctrl_trap_count++] =3D want[i]; + } + + return 0; +} + static int xlnx_tsn_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, struct netlink_ext_ack *extack) { struct xlnx_tsn *sw =3D ds->priv; struct dsa_port *dp; + bool old_vlan_aware; unsigned long bit; u32 reg, data; int ret; @@ -967,6 +1085,7 @@ static int xlnx_tsn_port_vlan_filtering(struct dsa_swi= tch *ds, int port, return ret; } =20 + old_vlan_aware =3D sw->vlan_aware; sw->vlan_aware =3D vlan_filtering; =20 /* Miss policy for unicast and multicast. It only kicks in when the @@ -1004,15 +1123,23 @@ static int xlnx_tsn_port_vlan_filtering(struct dsa_= switch *ds, int port, ret =3D xlnx_tsn_port_state_cycle(sw, dp->index, TSN_PORT_STATE_BLOCKING); if (ret) - return ret; + goto restore; =20 ret =3D xlnx_tsn_port_state_cycle(sw, dp->index, TSN_PORT_STATE_FLUSH); if (ret) - return ret; + goto restore; } =20 + ret =3D xlnx_tsn_sync_ctrl_traps(sw); + if (ret) + goto restore; + return 0; + +restore: + sw->vlan_aware =3D old_vlan_aware; + return ret; } =20 static int xlnx_tsn_port_vlan_add(struct dsa_switch *ds, int port, @@ -1061,6 +1188,7 @@ static int xlnx_tsn_port_vlan_add(struct dsa_switch *= ds, int port, sw->pvid[port] =3D vlan->vid; sw->pvid_untagged[port] =3D untagged; xlnx_tsn_apply_pvid(sw, port); + return xlnx_tsn_sync_ctrl_traps(sw); } =20 if (vlan->vid =3D=3D sw->pvid[port] && @@ -1101,6 +1229,7 @@ static int xlnx_tsn_port_vlan_del(struct dsa_switch *= ds, int port, sw->pvid[port] =3D TSN_SW_DEFAULT_VID; sw->pvid_untagged[port] =3D false; xlnx_tsn_apply_pvid(sw, port); + return xlnx_tsn_sync_ctrl_traps(sw); } =20 return 0; @@ -1204,6 +1333,21 @@ static const struct phylink_mac_ops xlnx_tsn_phylink= _mac_ops =3D { .mac_link_down =3D xlnx_tsn_mac_link_down, }; =20 +static void xlnx_tsn_remove_ctrl_traps(struct xlnx_tsn *sw) +{ + int i; + + guard(mutex)(&sw->indirect_lock); + + for (i =3D 0; i < sw->ctrl_trap_count; i++) + if (xlnx_tsn_set_ctrl_traps(sw, sw->ctrl_trap_vid[i], false)) + dev_warn(sw->dev, + "failed to remove control trap vid %u\n", + sw->ctrl_trap_vid[i]); + + sw->ctrl_trap_count =3D 0; +} + static int xlnx_tsn_setup(struct dsa_switch *ds) { struct dsa_port *cpu_dp =3D dsa_to_port(ds, XLNX_TSN_CPU_PORT); @@ -1276,9 +1420,19 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) return ret; } =20 + /* Trap link-local control frames (STP, LLDP) to the CPU port. + * Without this, a frame arriving on one wire port would be + * flooded out the other instead of reaching the host bridge. + */ + scoped_guard(mutex, &sw->indirect_lock) { + ret =3D xlnx_tsn_sync_ctrl_traps(sw); + if (ret) + return ret; + } + ret =3D xlnx_tsn_mdio_register_all(sw); if (ret) - return ret; + goto err_traps; =20 sw->nb.notifier_call =3D xlnx_tsn_netdev_event; ret =3D register_netdevice_notifier(&sw->nb); @@ -1312,6 +1466,8 @@ static int xlnx_tsn_setup(struct dsa_switch *ds) unregister_netdevice_notifier(&sw->nb); err_mdio: xlnx_tsn_mdio_unregister_all(sw); +err_traps: + xlnx_tsn_remove_ctrl_traps(sw); return ret; } =20 @@ -1327,6 +1483,8 @@ static void xlnx_tsn_teardown(struct dsa_switch *ds) unregister_netdevice_notifier(&sw->nb); xlnx_tsn_mdio_unregister_all(sw); =20 + xlnx_tsn_remove_ctrl_traps(sw); + dsa_switch_for_each_user_port(dp, ds) xlnx_tsn_set_port_state(sw, dp->index, TSN_PORT_STATE_DISABLED); =20 diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/x= ilinx_tsn.h index 955041cde564..dbf330d3d615 100644 --- a/drivers/net/dsa/xilinx/xilinx_tsn.h +++ b/drivers/net/dsa/xilinx/xilinx_tsn.h @@ -100,6 +100,10 @@ #define TSN_CAM_FOUND BIT(7) #define TSN_CAM_VLAN GENMASK(27, 16) #define TSN_CAM_PORT_LIST GENMASK(10, 8) +/* Classify a CAM-matched frame as endpoint management traffic so the + * switch delivers it on the management queue. + */ +#define TSN_CAM_EP_MGMTQ_EN BIT(15) #define TSN_CAM_READ_KEY_ADDR GENMASK(19, 8) #define TSN_CAM_MAC2_READ_KEY_BASE 0x800 #define TSN_CAM_READ_KEY_COUNT 2048 @@ -342,6 +346,9 @@ struct xlnx_tsn_mac { * untagged; drives the native-VLAN untag enable * @cfg_vids: VIDs with a membership entry in the VLAN-membership memory, * used to walk and update Port-List-Valid when @vlan_aware changes + * @ctrl_trap_vid: native VIDs that currently carry link-local control-fra= me + * traps, kept in sync with the wire ports' native VIDs + * @ctrl_trap_count: number of valid entries in @ctrl_trap_vid * @indirect_lock: serialises the CAM and VLAN-membership indirect * register sequences * @mac: per-MAC state, indexed by user-port number (index 0 unused; @@ -369,6 +376,8 @@ struct xlnx_tsn { u16 pvid[XLNX_TSN_NUM_PORTS]; bool pvid_untagged[XLNX_TSN_NUM_PORTS]; DECLARE_BITMAP(cfg_vids, VLAN_N_VID); + u16 ctrl_trap_vid[XLNX_TSN_NUM_PORTS - 1]; + u8 ctrl_trap_count; struct mutex indirect_lock; /* serialises CAM + VLAN-memory access */ struct xlnx_tsn_mac mac[XLNX_TSN_NUM_PORTS]; int ptp_timer_irq; --=20 2.34.1