From nobody Mon May 25 04:34:29 2026 Received: from DM1PR04CU001.outbound.protection.outlook.com (mail-centralusazon11020081.outbound.protection.outlook.com [52.101.61.81]) (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 A55C5382F25; Mon, 18 May 2026 20:39:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.61.81 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779136767; cv=fail; b=YsnioB+qf1GiwIvJmyJA+oBRUPUGHkb6Hro0oiEBiC8nfmMjy9+8D3qmr5N/youfXRKr6ieSNTIM/OqBsEGCpoH/M0Xa5STJ2ZmxpkSYBpUblbp0s7Pb9kX0xH1NOSe4edU8E7O+p1fKKatOCQX/lpwWlJLTBADNxCSyczLB8v4= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779136767; c=relaxed/simple; bh=Wk+ZADPBrWKtJY6xhhI5tYcYfUsvYvPW8T+2OCc36Zc=; h=From:To:Cc:Subject:Date:Message-ID:Content-Type:MIME-Version; b=M/eoUaJtBZYjXcJxfvkRPkwx7LLn2ybxhj29dtjYLxaGaVAj015E4Jvxh8NDHlt8p1EIoOKcGDYi+nt6a+5y3UVzhrmGWKBTMTDWhcDUKQ2O1n/mRcCUY3Q5KH8atOB/miJSe0yCJz8jX5j+D02241Iq4DhjlSFxZF1WlIeqpMw= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=os.amperecomputing.com; spf=pass smtp.mailfrom=os.amperecomputing.com; dkim=pass (1024-bit key) header.d=os.amperecomputing.com header.i=@os.amperecomputing.com header.b=Ac17MMNp; arc=fail smtp.client-ip=52.101.61.81 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=os.amperecomputing.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=os.amperecomputing.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=os.amperecomputing.com header.i=@os.amperecomputing.com header.b="Ac17MMNp" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=W9y4uJbFFyYTh3xcZ2fg9zE+IJGm/P18CrGvepKpNqXYJ85CW86gRMGWPUbsu2mfOiA+R9TTM1Qol8XGR8YbTFpK8VsWHqYIfs2ekreGD611E6C9+yoaEjc90aWJVjnQX9ORnWXNdHlsZUb5smPbnEw1OZg813EpRzLA+WhuOInlFHvLmYWe71t8yjB6rS5ReS4OECUA/VwhhP9XFMjlcuX8wAkRrnVCnVyQKQXRAfpm1Y/ARmJVcQGy24LowPhae4Pvkf1SM42ak2hXpESqCEVkTaO7MT7Nx385m1zkqAQO3FK71p6BW/hnJ7dPwxMepsX3j3RuaWnMUlCkM70JAQ== 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=+/cIE0XWr5aS2uiYHbJlbxA7wfQgTYbv/H2UUM/JXLE=; b=JMz+6NtJnkNOtgZ5xlXkqc4hiBxtJr2Eo1FUeDC4xGpgCVV8azAO3S3phH0vQipkuALBtm4yE6P5HI4H1w8YntWjVla4mkbUCTjAD4dibFUHZ8o9uO9mr3yBK0RDgPaD6qY4oKUvFlJhYlYnktvuNSxMoTT+NnOTd6e9mympw/+V2uMmDXn77lDWr8PMpVGJB16L2Pfrz3ksZXyWyP9WDy5dgiCdmoLDfbTf/xQ3XoC2yuJ4HJimv5PsZxBZFycl609hN0cfo7ltUycMqB7fx58wJakESz5ho5LYgZHj1pBQvRUPFilYDIcTnZ1P3Boj5MiqRSuB6whFqUPZs5CKmg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=os.amperecomputing.com; dmarc=pass action=none header.from=os.amperecomputing.com; dkim=pass header.d=os.amperecomputing.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=os.amperecomputing.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+/cIE0XWr5aS2uiYHbJlbxA7wfQgTYbv/H2UUM/JXLE=; b=Ac17MMNpSvHrOe5IwvWl8tDMr4yMJSVJb1K/OamFN6gAif5wUOzeTpzBy+KZb3bot2V6ltzYfYst5fJIR8cSDthNZ4ZtmhPWxe7WUrRH/sGQETpZeloMy1OnnH0hT3AxmhRuJE0DPG3okllVM4M0Eo3/DxQV9quzt7RdtYX5ufY= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=os.amperecomputing.com; Received: from BN3PR01MB9212.prod.exchangelabs.com (2603:10b6:408:2cb::8) by LVTPR01MB994727.prod.exchangelabs.com (2603:10b6:408:3c7::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.25.24; Mon, 18 May 2026 20:39:07 +0000 Received: from BN3PR01MB9212.prod.exchangelabs.com ([fe80::44f3:1050:dce8:1ea9]) by BN3PR01MB9212.prod.exchangelabs.com ([fe80::44f3:1050:dce8:1ea9%6]) with mapi id 15.21.0025.023; Mon, 18 May 2026 20:39:07 +0000 From: Adam Young To: Tony Nguyen , Przemek Kitszel , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jeremy Kerr , Matt Johnston Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Sudeep Holla , Jonathan Cameron , Huisong Li Subject: [net-next v42] mctp pcc: Implement MCTP over PCC Transport Date: Mon, 18 May 2026 16:38:58 -0400 Message-ID: <20260518203900.30720-1-admiyo@os.amperecomputing.com> X-Mailer: git-send-email 2.43.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: CY5PR22CA0003.namprd22.prod.outlook.com (2603:10b6:930:16::17) To BN3PR01MB9212.prod.exchangelabs.com (2603:10b6:408:2cb::8) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN3PR01MB9212:EE_|LVTPR01MB994727:EE_ X-MS-Office365-Filtering-Correlation-Id: c21fc520-e2fd-42b3-6294-08deb51d8177 X-MS-Exchange-AtpMessageProperties: SA X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|376014|7416014|1800799024|10070799003|18002099003|56012099003|13003099007|55112099003|3023799003|11063799003|4133799003; X-Microsoft-Antispam-Message-Info: KcSYMpR2UzoDSnCuuxAJGS7mZHU3zER3lJRDSWojGGmV/d9zsuHQxT0YfnChWP8w19KPPuz2fphjor9WJP7pQ88GRLIsSQVimlewozZ/AyNTAjldtrJB4VRH9y9KgSkZF1ArKNExcMffqcnyCeawvMuP86/HzyLu0Vlfitj1eF+rDNBeE+TOAnItwrALKc37B2cgFkd+6XRNkK97B55X5nyU79Pd20VycHM+uL8jhP+OB+z+ZNR2qezBhL9mG7FCRyXj+LdubeWBsmGSi1FRkbYdR+hcezMkSU/d2bM2b9Jri5X2D4z1MhVvcIsVO0D//QJY8x6502QpbqdWedml7IJFmmJy4fOb48Dw5Yik14zXTBVdlTgEEt+jR9KxzzPlvIeDdf64vpUxX5MqgWkDydgq6FR3+gWsR4Yb9CVFv89sdIhpH0pwfa8jGsXL5yM5vTwJ+B0hyIWD7fXdh4pABeTJBzOkZRkyM4KQVj8CAELC+9kzvUf/X+/KeIWpieWV5o36SG1TgPrr/tL05/9u7Zwpr0u9lXswIistrPJ/qhdV1K8MHnNKpxTxb7wSmdUG4ALqywc0KgperzufHm2HbcwqCU+/Hdam4mde/aVwwjySku0E8LfStn1q7WwBFJ1yHDr+stQ0TxOksAYEHI4OtmFlMUUlUBnf7NKREMyjtWYmA4T+iad6LBhvnrZMaIFs X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BN3PR01MB9212.prod.exchangelabs.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(376014)(7416014)(1800799024)(10070799003)(18002099003)(56012099003)(13003099007)(55112099003)(3023799003)(11063799003)(4133799003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 2 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?YgOlKlSZrtRAl1gIqwgQA4R5WwC7iJyPH4mriuFlRmx3TviMO/2/GeewnzBY?= =?us-ascii?Q?E2olrbLgnFASITG7DLxks5yXQ3pUrwXPPe8nY39eesu9qZ2uGrVu/7c5j5+j?= =?us-ascii?Q?csarKQ3GyrXgPEzvGoUc9rQFkbMe7vee9qXpHcxQykc2nhachXE9/XwpNySZ?= =?us-ascii?Q?TtleS5HiC670tNrtYxO8TDPv1GEuYULOafZ4yVBgEj6lxetjYLt8bJRFr8EZ?= =?us-ascii?Q?wGN5kZn22IpfqTJyHWhs4iBxZbYQ8/7iVmHrvNqgM2PNglJQ+05epCaKi59X?= =?us-ascii?Q?Ab2zfkGSLamURfO1JRt+qaoehR0DPwovCmCK21teiCGFfkKzn+KjnZkS3+BY?= =?us-ascii?Q?3jFk6hrmMi1+MKsW70dvZMnmP4awvB1htAQSPE38NKYs31DGcG744Zv25pfi?= =?us-ascii?Q?icsbInQtoAnAK/sYN71iOoOSgaTyxBliVMy0PcRBOb4NdBmTdsVZYzXuZTPc?= =?us-ascii?Q?j+7xjpii9fmddeZrbzBWNkbq/JDytLYfK+S1jUjTq63wv3dZzrr5YcCXjizK?= =?us-ascii?Q?DM1/rUPGD+8POAnzLV+Y2GvZPFnu/4M3rb0aV3U9rdFPZiSTj1VMMGWlTZ4j?= =?us-ascii?Q?QWiGntTVKn+oLNkzkvlD9gAOC3gjokRPKOqehDU7QlvVHsZmXPOMeY6dY8L0?= =?us-ascii?Q?OM8/9yqqwpY1ZR8nM9jFIiQjOprA6FaAVEn6ODslHvq0rjkZGM2yO27+tvlF?= =?us-ascii?Q?TVw6UgUVSRqWC8VRZ72O3LVY/kRcbUDrsRFDG4mDAXuA5xWlW1uw93SFloYi?= =?us-ascii?Q?M9McS56G4ofOl3fKOZ2UJgzpK9BBU/LprKTFBnSCxRxv84KlPUUtZZtn9i41?= =?us-ascii?Q?aO4gjM+zRzdS58cP70JPBU0q8eIq8bfLPR/kiQvMp61tnxMtc+2UAUpQfwc4?= =?us-ascii?Q?bxyMRSLRT0ru2xtC3JhWzQmeVy4RyUS9GzXiKpJPZVmnjzIDQWQFodzrgSHW?= =?us-ascii?Q?NIN0kLcE1Je5ss90SshmqS8IXPXLb+fCaufpdKLWqTPhg8AlJcyena9N/F5m?= =?us-ascii?Q?+KSWaE5u0BcU12bW8wQxJgEqWPyHLk4lpJqqzi8J8ygWjUpZTJ/88AoCPTUv?= =?us-ascii?Q?SYDlLT3ImyXM3hBRFjz3WxySrvKAVDh3AGfsJDREEpF0oM5tMThioG4DT+V/?= =?us-ascii?Q?aGBxf5eoZPXpKVN/9WGdNF/kcrGLACTiWUy+0CbhbiwmMnRd28SeP2AwEUi2?= =?us-ascii?Q?kGqczX9wv3sB76QFspyCEWnpuZT6gKVT619RU5BhAgLYFCFWmjeug6zzMJG+?= =?us-ascii?Q?YqZC0zh+MBLqbRg3lidfgz3mKpIjWLTNpUHgs0WiuiLJIz0nc6oZ/DSEowWy?= =?us-ascii?Q?iPlcGr/gmhz4SM83RAk6agTXHCQwCBt+V9L41EgICok9eIiM1t6cemQFqAqX?= =?us-ascii?Q?p43OuSEYIstrtbJge+OeQBBWIrS3bpV/LJN91rkpzV2zaUNJjvP10QPFFEQS?= =?us-ascii?Q?/pFERsMQWny+QfMnETMLEtDqL30dm/ePas0nWjz/ZYp0vIglKwQXKR6Y5hyU?= =?us-ascii?Q?IzVNGuOMeQTSBAwls5oe9nu1hIxzyx6+qBSU4sPjCiKnjuLUUO2p/tmY6ToV?= =?us-ascii?Q?KDOw1YPcNASMZwja5lVXF9gXQxskyaNqOzDHZ1otDXTIqSIInffwXqxQ5d/F?= =?us-ascii?Q?Faw96ocL+pzceJKfC55LiBNG5Zoz3wNi3T7gqA9M2WzK6ryVTKRZol6rnY5r?= =?us-ascii?Q?RYH8SQSufZdz/l8CXj8ize+TyV0VG/EBgPOkD8FwfQhx5os8IsAJkyhsnrth?= =?us-ascii?Q?v1LvbIJN73G0DbCfGFGzmMHuWeuPtNl1q6/tidOqdCvP7EFNCJeucfXKZhBt?= X-MS-Exchange-AntiSpam-MessageData-1: C/oyV+OgSVrj0iDNd/Z2CFsHZ8doprjzkzHyROnC/CkBGLmdkaOT6Cs0 X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: c21fc520-e2fd-42b3-6294-08deb51d8177 X-MS-Exchange-CrossTenant-AuthSource: BN3PR01MB9212.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 May 2026 20:39:06.9103 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3bc2b170-fd94-476d-b0ce-4229bdc904a7 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 0wAYTloaSNGTFxTcByuVjI2mrPNqAVayV+WBbZ9cPwQrw92886pgPEnUllai4rVF4yzv7vnbDakmQxD+c/x4+H4x7mIHBPtrF65DgJglSISZeTLI9r4gH+Fx5ZXvlLyM X-MS-Exchange-Transport-CrossTenantHeadersStamped: LVTPR01MB994727 Content-Type: text/plain; charset="utf-8" Implementation of network driver for Management Component Transport Protocol(MCTP) over Platform Communication Channel(PCC) DMTF DSP:0292 Link: https://www.dmtf.org/sites/default/files/standards/documents/DSP0292_= 1.0.0WIP50.pdf The transport mechanism is called Platform Communication Channels (PCC) is part of the ACPI spec: Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/14_Platform_Communicati= ons_Channel/Platform_Comm_Channel.html The PCC mechanism is managed via a mailbox implemented at drivers/mailbox/pcc.c MCTP devices are specified via ACPI by entries in DSDT/SSDT and reference channels specified in the PCCT. Messages are sent on a type 3 and received on a type 4 channel. Communication with other devices use the PCC based doorbell mechanism; a shared memory segment with a corresponding interrupt and a memory register used to trigger remote interrupts. The shared buffer must be at least 68 bytes long as that is the minimum MTU as defined by the MCTP specification. Unlike the existing PCC Type 2 based drivers, the mssg parameter to mbox_send_msg is actively used. The data section of the struct sk_buff that contains the outgoing packet is sent to the mailbox, already properly formatted as a PCC exctended message. If the mailbox ring buffer is full, the driver stops the incoming packet queues until a message has been sent, freeing space in the ring buffer. When the Type 3 channel outbox receives a txdone response interrupt, it consumes the outgoing sk_buff, allowing it to be freed. Bringing up an interface creates the channel between the network driver and the mailbox driver. This enables communication with the remote endpoint, to include the receipt of new messages. Bringing down an interface removes the channel, and no new messages can be delivered. Stopping the interface will leave any packets that are cached in the mailbox ringbuffer. They cannot safely be freed until the PCC mailbox attempts to deliver them and has removed them from the ring buffer. PCC is based on a shared buffer and a set of I/O mapped memory locations that the Spec calls registers. This mechanism exists regardless of the existence of the driver. If the user has the ability to map these physical location to virtual locations, they have the ability to drive the hardware. Thus, there is a security aspect to this mechanism that extends beyond the responsibilities of the operating system. If the hardware does not expose the PCC in the ACPI table, this device will never be enabled. Thus it is only an issue on hardware that does support PCC. In that case, it is up to the remote controller to sanitize communication; MCTP will be exposed as a socket interface, and userland can send any crafted packet it wants. It would also be incumbent on the hardware manufacturer to allow the end user to disable MCTP over PCC communication if they did not want to expose it. Link: https://www.dmtf.org/sites/default/files/standards/documents/DSP0292_= 1.0.0WIP50.pdf Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/14_Platform_Communicati= ons_Channel/Platform_Comm_Channel.html Signed-off-by: Adam Young --- Previous Version: https://lore.kernel.org/lkml/20260510163228.443778-1-admiyo@os.amperecomput= ing.com/ Changes from Previous version Remove call to skb_linearize(skb) Spacing changes after gotos move final check of packet length to tx function use irq safe stats update in tx_done for sent and dropped mctp-pcc retry send_message to avoid permanent network stall --- MAINTAINERS | 5 + drivers/net/ethernet/intel/stYNFrCT | Bin 0 -> 564073 bytes drivers/net/mctp/Kconfig | 16 ++ drivers/net/mctp/Makefile | 1 + drivers/net/mctp/mctp-pcc.c | 426 ++++++++++++++++++++++++++++ 5 files changed, 448 insertions(+) create mode 100644 drivers/net/ethernet/intel/stYNFrCT create mode 100644 drivers/net/mctp/mctp-pcc.c diff --git a/MAINTAINERS b/MAINTAINERS index 5bbbbde6b907..252c77b24791 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15403,6 +15403,11 @@ F: include/net/mctpdevice.h F: include/net/netns/mctp.h F: net/mctp/ =20 +MANAGEMENT COMPONENT TRANSPORT PROTOCOL (MCTP) over PCC (MCTP-PCC) Driver +M: Adam Young +S: Maintained +F: drivers/net/mctp/mctp-pcc.c + MAPLE TREE M: Liam R. Howlett R: Alice Ryhl diff --git a/drivers/net/ethernet/intel/stYNFrCT b/drivers/net/ethernet/int= el/stYNFrCT new file mode 100644 index 0000000000000000000000000000000000000000..9b01d1e909f20fe037eea685116= d344a2165db52 GIT binary patch literal 564073 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 Jwwe{=3D{{!iY>!bhx literal 0 HcmV?d00001 diff --git a/drivers/net/mctp/Kconfig b/drivers/net/mctp/Kconfig index cf325ab0b1ef..e68d23794a80 100644 --- a/drivers/net/mctp/Kconfig +++ b/drivers/net/mctp/Kconfig @@ -47,6 +47,22 @@ config MCTP_TRANSPORT_I3C A MCTP protocol network device is created for each I3C bus having a "mctp-controller" devicetree property. =20 +config MCTP_TRANSPORT_PCC + tristate "MCTP PCC transport" + depends on ACPI + depends on PCC + depends on 64BIT + depends on CPU_LITTLE_ENDIAN + help + Provides a driver to access MCTP devices over PCC transport, + A MCTP protocol network device is created via ACPI for each + entry in the DSDT/SSDT that matches the identifier. The Platform + communication channels are selected from the corresponding + entries in the PCCT. + + Say y here if you need to connect to MCTP endpoints over PCC. To + compile as a module, use m; the module will be called mctp-pcc. + config MCTP_TRANSPORT_USB tristate "MCTP USB transport" depends on USB diff --git a/drivers/net/mctp/Makefile b/drivers/net/mctp/Makefile index c36006849a1e..0a591299ffa9 100644 --- a/drivers/net/mctp/Makefile +++ b/drivers/net/mctp/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_MCTP_SERIAL) +=3D mctp-serial.o obj-$(CONFIG_MCTP_TRANSPORT_I2C) +=3D mctp-i2c.o obj-$(CONFIG_MCTP_TRANSPORT_I3C) +=3D mctp-i3c.o +obj-$(CONFIG_MCTP_TRANSPORT_PCC) +=3D mctp-pcc.o obj-$(CONFIG_MCTP_TRANSPORT_USB) +=3D mctp-usb.o diff --git a/drivers/net/mctp/mctp-pcc.c b/drivers/net/mctp/mctp-pcc.c new file mode 100644 index 000000000000..2570cd379966 --- /dev/null +++ b/drivers/net/mctp/mctp-pcc.c @@ -0,0 +1,426 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mctp-pcc.c - Driver for MCTP over PCC. + * Copyright (c) 2024-2026, Ampere Computing LLC + * + */ + +/* Implementation of MCTP over PCC DMTF Specification DSP0256 + * https://www.dmtf.org/sites/default/files/standards/documents/DSP0292_1.= 0.0WIP50.pdf + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MCTP_SIGNATURE "MCTP" +#define MCTP_SIGNATURE_LENGTH (sizeof(MCTP_SIGNATURE) - 1) +#define MCTP_MIN_MTU 68 +#define PCC_HEADER_SIZE sizeof(struct acpi_pcct_ext_pcc_shared_mem= ory) +#define MCTP_PCC_MIN_SIZE (PCC_HEADER_SIZE + MCTP_MIN_MTU) +#define PCC_EXTRA_LEN (PCC_HEADER_SIZE - sizeof(pcc_header.comma= nd)) +struct mctp_pcc_mailbox { + u32 index; + struct pcc_mbox_chan *chan; + struct mbox_client client; +}; + +/* The netdev structure. One of these per PCC adapter. */ +struct mctp_pcc_ndev { + struct net_device *ndev; + struct acpi_device *acpi_device; + struct mctp_pcc_mailbox inbox; + struct mctp_pcc_mailbox outbox; +}; + +static void mctp_pcc_client_rx_callback(struct mbox_client *cl, void *mssg) +{ + struct acpi_pcct_ext_pcc_shared_memory pcc_header; + struct mctp_pcc_ndev *mctp_pcc_ndev; + struct mctp_pcc_mailbox *inbox; + struct mctp_skb_cb *cb; + struct sk_buff *skb; + u32 header_length; + int size; + + mctp_pcc_ndev =3D container_of(cl, struct mctp_pcc_ndev, inbox.client); + inbox =3D &mctp_pcc_ndev->inbox; + memcpy_fromio(&pcc_header, inbox->chan->shmem, sizeof(pcc_header)); + + // The message must at least have the PCC command indicating it is an MCTP + // message followed by the MCTP header, or we have a malformed message. + // This may be run on big endian system, but the data in the buffer is + // explicitly little endian. + header_length =3D le32_to_cpu(pcc_header.length); + + if (header_length < sizeof(pcc_header.command) + sizeof(struct mctp_hdr)) + goto error; + + // If the reported size is larger than the shared memory minus headers, + // something is wrong and treat the buffer as corrupted data. + if (header_length > inbox->chan->shmem_size - PCC_EXTRA_LEN) + goto error; + + if (memcmp(&pcc_header.command, MCTP_SIGNATURE, MCTP_SIGNATURE_LENGTH) != =3D 0) + goto error; + + size =3D header_length + PCC_EXTRA_LEN; + skb =3D netdev_alloc_skb(mctp_pcc_ndev->ndev, size); + if (!skb) + goto error; + + skb_put(skb, size); + skb->protocol =3D htons(ETH_P_MCTP); + memcpy_fromio(skb->data, inbox->chan->shmem, size); + dev_dstats_rx_add(mctp_pcc_ndev->ndev, size); + skb_pull(skb, sizeof(pcc_header)); + skb_reset_mac_header(skb); + skb_reset_network_header(skb); + cb =3D __mctp_cb(skb); + cb->halen =3D 0; + netif_rx(skb); + return; + +error: + dev_dstats_rx_dropped(mctp_pcc_ndev->ndev); +} + +static netdev_tx_t mctp_pcc_tx(struct sk_buff *skb, struct net_device *nde= v) +{ + struct acpi_pcct_ext_pcc_shared_memory *pcc_header; + struct mctp_pcc_ndev *mpnd =3D netdev_priv(ndev); + int len =3D skb->len; + + if (skb_cow_head(skb, sizeof(*pcc_header))) + goto error; + + pcc_header =3D skb_push(skb, sizeof(*pcc_header)); + pcc_header->signature =3D PCC_SIGNATURE | mpnd->outbox.index; + pcc_header->flags =3D PCC_CMD_COMPLETION_NOTIFY; + memcpy(&pcc_header->command, MCTP_SIGNATURE, MCTP_SIGNATURE_LENGTH); + pcc_header->length =3D len + MCTP_SIGNATURE_LENGTH; + + if (skb->len > mpnd->outbox.chan->shmem_size) + goto error; + + if (mbox_send_message(mpnd->outbox.chan->mchan, skb) < 0) { + netif_stop_queue(ndev); + /* + * There is a possibility that the mailbox was cleared on + * another thread between the failed send attempt and + * stopping the queue. If that is the case, and we don't restart + * the queue, it will remain permanently stopped. To test, + * try submitting the message again. If successful, restart the + * queue. + */ + if (mbox_send_message(mpnd->outbox.chan->mchan, skb) >=3D 0) { + netif_wake_queue(ndev); + } else { + // Remove the header in case it gets sent again + skb_pull(skb, sizeof(*pcc_header)); + return NETDEV_TX_BUSY; + } + } + return NETDEV_TX_OK; + +error: + dev_dstats_tx_dropped(ndev); + kfree_skb(skb); + return NETDEV_TX_OK; +} + +static void mctp_pcc_tx_prepare(struct mbox_client *cl, void *mssg) +{ + struct mctp_pcc_ndev *mctp_pcc_ndev; + struct mctp_pcc_mailbox *outbox; + struct sk_buff *skb =3D mssg; + + mctp_pcc_ndev =3D container_of(cl, struct mctp_pcc_ndev, outbox.client); + outbox =3D &mctp_pcc_ndev->outbox; + + /* The PCC Mailbox typically does not make use of the mssg pointer + * The mctp-over pcc driver is the only client that uses it. + * This value should always be non-null; it is possible + * that a change in the Mailbox level will break that assumption. + */ + if (!skb) { + netdev_warn_once(mctp_pcc_ndev->ndev, + "%s called with null message.\n", __func__); + return; + } + memcpy_toio(outbox->chan->shmem, skb->data, skb->len); +} + +static void mctp_pcc_tx_done(struct mbox_client *c, void *mssg, int rc) +{ + struct mctp_pcc_ndev *mctp_pcc_ndev; + struct pcpu_dstats *dstats; + struct sk_buff *skb =3D mssg; + unsigned long flags; + + /* + * If there is a packet in flight during driver cleanup + * It may have been freed already. + */ + if (!mssg) + return; + mctp_pcc_ndev =3D container_of(c, struct mctp_pcc_ndev, outbox.client); + + /* Use an IRQ safe update as this is called from HARD IRQ instead of + * dev_dstats_tx_add(mctp_pcc_ndev->ndev, skb->len); + */ + dstats =3D this_cpu_ptr(mctp_pcc_ndev->ndev->dstats); + flags =3D u64_stats_update_begin_irqsave(&dstats->syncp); + + if (rc) { + u64_stats_inc(&dstats->tx_drops); + } else { + u64_stats_inc(&dstats->tx_packets); + u64_stats_add(&dstats->tx_bytes, skb->len); + } + u64_stats_update_end_irqrestore(&dstats->syncp, flags); + dev_consume_skb_any(skb); + netif_wake_queue(mctp_pcc_ndev->ndev); +} + +static int mctp_pcc_open(struct net_device *ndev) +{ + struct mctp_pcc_ndev *mctp_pcc_ndev =3D netdev_priv(ndev); + struct mctp_pcc_mailbox *outbox, *inbox; + + outbox =3D &mctp_pcc_ndev->outbox; + inbox =3D &mctp_pcc_ndev->inbox; + + outbox->chan =3D pcc_mbox_request_channel(&outbox->client, outbox->index); + if (IS_ERR(outbox->chan)) + return PTR_ERR(outbox->chan); + if (outbox->chan->shmem_size < MCTP_PCC_MIN_SIZE) { + pcc_mbox_free_channel(outbox->chan); + return -EINVAL; + } + + inbox->client.rx_callback =3D mctp_pcc_client_rx_callback; + inbox->chan =3D pcc_mbox_request_channel(&inbox->client, inbox->index); + if (IS_ERR(inbox->chan)) { + pcc_mbox_free_channel(outbox->chan); + return PTR_ERR(inbox->chan); + } + if (inbox->chan->shmem_size < MCTP_PCC_MIN_SIZE) { + pcc_mbox_free_channel(outbox->chan); + pcc_mbox_free_channel(inbox->chan); + return -EINVAL; + } + return 0; +} + +static int mctp_pcc_stop(struct net_device *ndev) +{ + struct mctp_pcc_ndev *mctp_pcc_ndev; + unsigned int count, idx; + struct mbox_chan *chan; + struct sk_buff *skb; + + mctp_pcc_ndev =3D netdev_priv(ndev); + chan =3D mctp_pcc_ndev->outbox.chan->mchan; + pcc_mbox_free_channel(mctp_pcc_ndev->inbox.chan); + scoped_guard(spinlock_irqsave, &chan->lock) { + skb =3D chan->active_req; + chan->active_req =3D NULL; + if (skb) { + dev_dstats_tx_dropped(ndev); + dev_consume_skb_any(skb); + } + while (chan->msg_count > 0) { + count =3D chan->msg_count; + idx =3D chan->msg_free; + if (idx >=3D count) + idx -=3D count; + else + idx +=3D MBOX_TX_QUEUE_LEN - count; + skb =3D chan->msg_data[idx]; + dev_dstats_tx_dropped(ndev); + dev_consume_skb_any(skb); + chan->msg_count--; + } + } + pcc_mbox_free_channel(mctp_pcc_ndev->outbox.chan); + return 0; +} + +static const struct net_device_ops mctp_pcc_netdev_ops =3D { + .ndo_open =3D mctp_pcc_open, + .ndo_stop =3D mctp_pcc_stop, + .ndo_start_xmit =3D mctp_pcc_tx, +}; + +static void mctp_pcc_setup(struct net_device *ndev) +{ + ndev->type =3D ARPHRD_MCTP; + ndev->hard_header_len =3D sizeof(struct acpi_pcct_ext_pcc_shared_memory); + ndev->tx_queue_len =3D 0; + ndev->flags =3D IFF_NOARP; + ndev->netdev_ops =3D &mctp_pcc_netdev_ops; + ndev->needs_free_netdev =3D true; + ndev->pcpu_stat_type =3D NETDEV_PCPU_STAT_DSTATS; +} + +struct mctp_pcc_lookup_context { + int index; + u32 inbox_index; + u32 outbox_index; +}; + +static acpi_status lookup_pcct_indices(struct acpi_resource *ares, + void *context) +{ + struct mctp_pcc_lookup_context *luc =3D context; + struct acpi_resource_address32 *addr; + + if (ares->type !=3D ACPI_RESOURCE_TYPE_ADDRESS32) + return AE_OK; + + addr =3D ACPI_CAST_PTR(struct acpi_resource_address32, &ares->data); + switch (luc->index) { + case 0: + luc->outbox_index =3D addr[0].address.minimum; + break; + case 1: + luc->inbox_index =3D addr[0].address.minimum; + break; + default: + return AE_ERROR; + } + luc->index++; + return AE_OK; +} + +static void mctp_cleanup_netdev(void *data) +{ + struct net_device *ndev =3D data; + + mctp_unregister_netdev(ndev); +} + +static int initialize_mtu(struct net_device *ndev) +{ + struct mctp_pcc_ndev *mctp_pcc_ndev; + struct mctp_pcc_mailbox *outbox; + struct pcc_mbox_chan *pchan; + int mctp_pcc_max_mtu; + + mctp_pcc_ndev =3D netdev_priv(ndev); + outbox =3D &mctp_pcc_ndev->outbox; + pchan =3D pcc_mbox_request_channel(&outbox->client, outbox->index); + if (IS_ERR(pchan)) + return PTR_ERR(pchan); + if (pchan->shmem_size < MCTP_MIN_MTU + sizeof(struct acpi_pcct_ext_pcc_sh= ared_memory)) { + pcc_mbox_free_channel(pchan); + return -EINVAL; + } + mctp_pcc_max_mtu =3D pchan->shmem_size - sizeof(struct acpi_pcct_ext_pcc_= shared_memory); + pcc_mbox_free_channel(pchan); + + ndev->mtu =3D MCTP_MIN_MTU; + ndev->max_mtu =3D mctp_pcc_max_mtu; + ndev->min_mtu =3D MCTP_MIN_MTU; + + return 0; +} + +static int mctp_pcc_driver_add(struct acpi_device *acpi_dev) +{ + struct mctp_pcc_lookup_context context =3D {0}; + struct mctp_pcc_ndev *mctp_pcc_ndev; + struct device *dev =3D &acpi_dev->dev; + struct net_device *ndev; + acpi_handle dev_handle; + acpi_status status; + char name[32]; + int rc; + + dev_dbg(dev, "Adding mctp_pcc device for HID %s\n", + acpi_device_hid(acpi_dev)); + dev_handle =3D acpi_device_handle(acpi_dev); + status =3D acpi_walk_resources(dev_handle, "_CRS", lookup_pcct_indices, + &context); + if (!ACPI_SUCCESS(status)) { + dev_err(dev, "FAILED to lookup PCC indexes from CRS\n"); + return -EINVAL; + } + + /* + * Ensure we have exactly 2 channels: an outbox and an inbox. + */ + if (context.index !=3D 2) + return -EINVAL; + + snprintf(name, sizeof(name), "mctppcc%d", context.inbox_index); + ndev =3D alloc_netdev(sizeof(*mctp_pcc_ndev), name, NET_NAME_PREDICTABLE, + mctp_pcc_setup); + if (!ndev) + return -ENOMEM; + + mctp_pcc_ndev =3D netdev_priv(ndev); + + mctp_pcc_ndev->inbox.index =3D context.inbox_index; + mctp_pcc_ndev->inbox.client.dev =3D dev; + mctp_pcc_ndev->outbox.index =3D context.outbox_index; + mctp_pcc_ndev->outbox.client.dev =3D dev; + + mctp_pcc_ndev->outbox.client.tx_prepare =3D mctp_pcc_tx_prepare; + mctp_pcc_ndev->outbox.client.tx_done =3D mctp_pcc_tx_done; + mctp_pcc_ndev->acpi_device =3D acpi_dev; + mctp_pcc_ndev->ndev =3D ndev; + acpi_dev->driver_data =3D mctp_pcc_ndev; + + rc =3D initialize_mtu(ndev); + if (rc) + goto free_netdev; + + rc =3D mctp_register_netdev(ndev, NULL, MCTP_PHYS_BINDING_PCC); + if (rc) + goto free_netdev; + + return devm_add_action_or_reset(dev, mctp_cleanup_netdev, ndev); +free_netdev: + free_netdev(ndev); + return rc; +} + +static const struct acpi_device_id mctp_pcc_device_ids[] =3D { + { "DMT0001" }, + {} +}; + +static struct acpi_driver mctp_pcc_driver =3D { + .name =3D "mctp_pcc", + .class =3D "Unknown", + .ids =3D mctp_pcc_device_ids, + .ops =3D { + .add =3D mctp_pcc_driver_add, + }, +}; + +module_acpi_driver(mctp_pcc_driver); + +MODULE_DEVICE_TABLE(acpi, mctp_pcc_device_ids); + +MODULE_DESCRIPTION("MCTP PCC ACPI device"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Adam Young "); --=20 2.43.0