Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2196322/?format=api
{ "id": 2196322, "url": "http://patchwork.ozlabs.org/api/patches/2196322/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260213123603.420941-4-a-garg7@ti.com/", "project": { "id": 28, "url": "http://patchwork.ozlabs.org/api/projects/28/?format=api", "name": "Linux PCI development", "link_name": "linux-pci", "list_id": "linux-pci.vger.kernel.org", "list_email": "linux-pci@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260213123603.420941-4-a-garg7@ti.com>", "list_archive_url": null, "date": "2026-02-13T12:36:02", "name": "[RFC,3/4] PCI/DOE: Add DOE mailbox support for endpoint functions", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "4b6286aa6ef14ad33ebd45f4e6fb7cbc38a7ed32", "submitter": { "id": 92467, "url": "http://patchwork.ozlabs.org/api/people/92467/?format=api", "name": "Aksh Garg", "email": "a-garg7@ti.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260213123603.420941-4-a-garg7@ti.com/mbox/", "series": [ { "id": 492090, "url": "http://patchwork.ozlabs.org/api/series/492090/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/list/?series=492090", "date": "2026-02-13T12:35:59", "name": "PCI: Add DOE support for endpoint", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/492090/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2196322/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2196322/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-pci+bounces-47269-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-pci@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256\n header.s=selector1 header.b=wX60GjvA;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-pci+bounces-47269-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=\"wX60GjvA\"", "smtp.subspace.kernel.org;\n arc=fail smtp.client-ip=40.107.201.46", "smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=ti.com", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=ti.com" ], "Received": [ "from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fCBWn11DWz1xpl\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 13 Feb 2026 23:37:25 +1100 (AEDT)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id 63B8F30B2B2A\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 13 Feb 2026 12:36:35 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 1081234F24E;\n\tFri, 13 Feb 2026 12:36:30 +0000 (UTC)", "from CH4PR04CU002.outbound.protection.outlook.com\n (mail-northcentralusazon11013046.outbound.protection.outlook.com\n [40.107.201.46])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id CA624194A60;\n\tFri, 13 Feb 2026 12:36:27 +0000 (UTC)", "from MN2PR06CA0012.namprd06.prod.outlook.com (2603:10b6:208:23d::17)\n by BLAPR10MB4978.namprd10.prod.outlook.com (2603:10b6:208:30e::23) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9611.12; Fri, 13 Feb\n 2026 12:36:25 +0000", "from BL6PEPF00020E64.namprd04.prod.outlook.com\n (2603:10b6:208:23d:cafe::aa) by MN2PR06CA0012.outlook.office365.com\n (2603:10b6:208:23d::17) with Microsoft SMTP Server (version=TLS1_3,\n cipher=TLS_AES_256_GCM_SHA384) id 15.20.9611.11 via Frontend Transport; Fri,\n 13 Feb 2026 12:36:00 +0000", "from lewvzet200.ext.ti.com (198.47.23.194) by\n BL6PEPF00020E64.mail.protection.outlook.com (10.167.249.25) with Microsoft\n SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.9611.8 via Frontend Transport; Fri, 13 Feb 2026 12:36:25 +0000", "from DLEE212.ent.ti.com (157.170.170.114) by lewvzet200.ext.ti.com\n (10.4.14.103) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Fri, 13 Feb\n 2026 06:36:20 -0600", "from DLEE211.ent.ti.com (157.170.170.113) by DLEE212.ent.ti.com\n (157.170.170.114) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Fri, 13 Feb\n 2026 06:36:20 -0600", "from lelvem-mr06.itg.ti.com (10.180.75.8) by DLEE211.ent.ti.com\n (157.170.170.113) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20 via Frontend\n Transport; Fri, 13 Feb 2026 06:36:20 -0600", "from a0507033-hp.dhcp.ti.com (a0507033-hp.dhcp.ti.com\n [172.24.231.225])\n\tby lelvem-mr06.itg.ti.com (8.18.1/8.18.1) with ESMTP id 61DCa6A9751418;\n\tFri, 13 Feb 2026 06:36:17 -0600" ], "ARC-Seal": [ "i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1770986189; cv=fail;\n b=Ox5GocMVPJrOAXK2MtqxzfB1iOr2A1z2DojLur8gIzBB5whDTh6u17rZWDaunmgYrGZUUFbXtk2AetQ+of5SQRM6Q4WpwwpwNVrD0P8nYhaU0qljek6vSy2+O82ddrds8I5ZOqckLHkQbG7IGOfcONp3Vl916wtIZN6xVNdyGIc=", "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=JOgT21bFdVJSPQnG1rGkVFD+3v+0IsYdafBfZ0k4OrtiQ6jH1EwfwK45eJbQhwiGSTL+/de4CnTYBPZnjVGYR7cqZMN77Qu5A8THL8b66Ekl2JVhEn8GwA6Vwkz7zHXY4Wn8vOcPl1BGzc1RurROQoasieJbOMBW6+qlVDB3VsuE4lzsoIaBUPgKea8RkoZeLHFq5eXwb18nwpXfGvsNKlbOyPIpchlrGwij/eDFRdepqLWfAFsvmLLMzRiKZLWyGkheewr+a8sv1nWkx9iWY0UTxRX1HEHQD92AY0zh/nErkgkreMWyRZ/OM1gK5b+nMEs77o6RpGVeRPMDZrKTFg==" ], "ARC-Message-Signature": [ "i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1770986189; c=relaxed/simple;\n\tbh=lV4krPTq80TrpsDxt6Eof1zmbekY5TdnULH02Nv5di8=;\n\th=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=qfTUw/yf/9P7eSK9hcDDCbOTCvOxXn5CbuPpTu6QUkVa/wpo7Pv+ofmEn+PtD7T2dC2tz17eFfOuahnsQ7meUIrdrzqsmHTaKZPkN7xSpojMeM61Xv3vnoWk+FjFPXsSlAHjtswn9FGaLrGiZgOR2Rv3dvsEOQZIxAcJQBf/QHs=", "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n 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;\n bh=h8i+VEarwPPgSplceRgbvOra/909bZcUsFxzY2LDeOw=;\n b=b3Z41jITN90b5mOfLSSvMeU30LyY83zGTTLmkpRs/ThMHmmYMm42WDEunJa2hBT2p69yib1NyAPXGRY7UHHc0e5Yd+ilYz8e0xhAzRR+A10mq2sg/87fd6WKL0YIr0UHFn2g1YHHGQRePV8CQOA4cOWISF9fc3Ql6xxy5sYBkOUPCvYpTZbb8kW8OTQLeaVjYGU858Mwc/Zl29RZSeaz2Y42l0JY3EQamry36bye4e5omnEH4d2JVH54kSK4a9rkYnYMFs/qfXxeBnA8ItLpitgu5rKJr3bmb4y8GtI7p0HIQzTaM2bYul082xiwFQiiEAskSbHSVt5S8LNaKHyQcQ==" ], "ARC-Authentication-Results": [ "i=2; smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=ti.com;\n spf=pass smtp.mailfrom=ti.com;\n dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=wX60GjvA;\n arc=fail smtp.client-ip=40.107.201.46", "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 198.47.23.194) smtp.rcpttodomain=lists.infradead.org smtp.mailfrom=ti.com;\n dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=ti.com;\n dkim=none (message not signed); arc=none (0)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=h8i+VEarwPPgSplceRgbvOra/909bZcUsFxzY2LDeOw=;\n b=wX60GjvA2qqrH0uLtmB1fC3TpXLawKqWZWSDxvwQCCvktkuBuiNsZDz3LprT1WDK4O3df720BjDyGKxQG50ZHdQWHZPF26Dkfs0sivklIOHe8ZZiOuZlb97kjRkuk1lKBJ1q/Kevgdgq7CWzbTSPQg0d+iwT6XvTg/vdWl8mZpo=", "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 198.47.23.194)\n smtp.mailfrom=ti.com; dkim=none (message not signed) header.d=none;dmarc=pass\n action=none header.from=ti.com;", "Received-SPF": "Pass (protection.outlook.com: domain of ti.com designates\n 198.47.23.194 as permitted sender) receiver=protection.outlook.com;\n client-ip=198.47.23.194; helo=lewvzet200.ext.ti.com; pr=C", "From": "Aksh Garg <a-garg7@ti.com>", "To": "<linux-pci@vger.kernel.org>, <linux-doc@vger.kernel.org>,\n\t<bhelgaas@google.com>, <corbet@lwn.net>, <cassel@kernel.org>", "CC": "<linux-kernel@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org>,\n\t<s-vadapalli@ti.com>, <danishanwar@ti.com>, <srk@ti.com>, <a-garg7@ti.com>", "Subject": "[RFC PATCH 3/4] PCI/DOE: Add DOE mailbox support for endpoint\n functions", "Date": "Fri, 13 Feb 2026 18:06:02 +0530", "Message-ID": "<20260213123603.420941-4-a-garg7@ti.com>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20260213123603.420941-1-a-garg7@ti.com>", "References": "<20260213123603.420941-1-a-garg7@ti.com>", "Precedence": "bulk", "X-Mailing-List": "linux-pci@vger.kernel.org", "List-Id": "<linux-pci.vger.kernel.org>", "List-Subscribe": "<mailto:linux-pci+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-pci+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Content-Type": "text/plain", "X-C2ProcessedOrg": "333ef613-75bf-4e12-a4b1-8e3623f5dcea", "X-EOPAttributedMessage": "0", "X-MS-PublicTrafficType": "Email", "X-MS-TrafficTypeDiagnostic": "BL6PEPF00020E64:EE_|BLAPR10MB4978:EE_", "X-MS-Office365-Filtering-Correlation-Id": "78d5c94d-dc19-4539-5eff-08de6afc8073", "X-MS-Exchange-SenderADCheck": "1", "X-MS-Exchange-AntiSpam-Relay": "0", "X-Microsoft-Antispam": "\n\tBCL:0;ARA:13230040|376014|36860700013|1800799024|82310400026;", "X-Microsoft-Antispam-Message-Info": "\n GWi/b3DeHOapSNfB6xaIxqKgu6KOF5ZaloQWQIZfqj7c+h4eVE/EegxLskQlmalJvdsJMPwGA2/TUC6tvVml6udVSarO+qBtovzevZjEZ6C210BCMFJ54C7xyLRfJuqme7mxUcx6Ss5Eky1N6S6e3sfgdXh4FlSqBgeAgw7eq1rrk4b3JLuNFVWTywVEEy5wET8WXuVpAmQZ2Pw4sCBjKtdDReuB4RZnf948OxWQfk7Xrp5xteBPkyQSSylK6pCLN7HESlS2a9pLurGmUNuAcmoc+lUNh3OisWC1qvqAd/GxYiAVD+R+HRMJnVWdzRwHlO4DIms5xuAhRDy7jvdTq4aEMF4D6W1Kx9z55Bzzfo9Xi7jiyDqeafBOWwD7rQH/uRDyOsFeYEJNYCaRtzIoHJ2cwkvH+f4FQPDd/hEYh9jaNdyK5tN8d/AimsA3pQq0MDu3xdIMAh3XbsCyPBNCksMIkLFEqOIZ2Diayu1zKITd49QtbuWzL/CrPIlKEbENYFXwVX0st+MXWW5ieVZkcv/zz8w1yMqR7KNerzOamziv/Qws7SaK47GF4aA67jeua7apZ7Ogh6/3D3ncwoPjG/5nOcOAmg/miS4gnKl27QEhv/TDA1Wshxr8267gp1E8exSxl2DoBZ3CiCSGluVZvand7/LOS8n9UyXSxcuXnfqJtu3SV5i1sn2ydsM5kWwToj4ffz1Mo4rZ4dvxtSoP1arg8SmPAQ2zt0f701dLCJ5VTwyXFq9ehtvz85r0IiJ/Wip5W0OKxxMonhgaFQZQWdw5S8M7l/20Yn/jWCjIQLl8hyrcBNBEk1VJo09lQ0XOk6lLMrAvTU9XRA7XXcveAQ1AssGPuYPDy50tq6eygXRDLI3sr664mOt1TavyYyJZa66v52HEVZcXZCCfNVSVPaGRBM+cOGQwYamqDUQcv4IDIWP3DLXynEpGyjV0MjJzKh4/B1GLN+ip9wWbB+SzJ1Bj4ndT0fpz2qxrFGrzdp3HRDWJ9FO2RKAEKBPb9E/WKftq048xu5O7QupBXRln5XNRg9fas9VLv5Z9djn94s7aEHxOKR95QlKEktrYsph24wNX2t3hKgoPzyRlV2mJ/tbs5h9ri1I5kESKxnf22Xn0p6VKbdUpA2ChLHfVqc6sUmVAdndFaR5zkHLrmrwImuJgCgF/cxRansvc0dKvx6ghJH0Ns+Qf+yubFR5kooQnR4+p2a3+l/hdSTAQlcAyYHk5bVM72rzyqMI/r0dJXr8AvJKVvzldAVAT7jZT2vJEBRi2oyyYC3cbR6MqoO/kb8cuTzf9ymIwLvxRPi5b9/obRTzf+HGmAHBBscZqLo9GBwPHDi5mvAiVOoTTRDUeXbP0a0IlYk0txoPWic4LwmJr5sXYVAmSlSy6jb7hXR7Uad4z2aJsVo4qaRN1CQxhy/Ywz+ii29RZsnQEdkKRpkHCY5/N5KzmitRDl6TvrfXpsEEKu6qSWb2Ik+pDRTGOU/Sh3pEpkw72gRcRDzwZdtQXfgsznbCBX9sbDyvQQFZQTqjp6XAInZGi6wXHgdULcnyjZxNiNY77JA348fvC9gAuyIqp3kdgunEp/GAKEh2rpWz9slWyuroOCcdjJ7V/Eg==", "X-Forefront-Antispam-Report": "\n\tCIP:198.47.23.194;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:lewvzet200.ext.ti.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(36860700013)(1800799024)(82310400026);DIR:OUT;SFP:1101;", "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1", "X-MS-Exchange-AntiSpam-MessageData-0": "\n\tqM6wmj9CwE5bSFz1zgGMzYpwpoGck6/XSTxywBEyBv2YAZFfqWeljuvklKocGRxuhmq+Zm7pl6PZh0SXIodCRzxdzOHJuwOJRo/tRobQwgXTNWOEA0rXccAl43liyKGqr7TGEzBFDyCvxmuXZ+0cqwx58ldoDWwhO0LVEVE2EWg4IgEdoFB9wNNkcgChcmm+dGGc/Ozw1Vx4oxSGHQ1vvk6MaQ7kvVU2VgLePskQCw+1e6xkEUtmz4OKscaU6qVFd+3q+N4hqNBfRFdpl7riqwP4fB++keEu/++T8/6RmTjwR7G+H++9373R1e0B3syTwAmSfqJD3bPEesTVg3OBo2XPF4mUkF7vokzvmDl0gxk9F3kM5vKB31BkaycHgRL3wZGKy+el70+amELn3/LM2pedq3DC3YGls6YQD0Y0IbAzzAzZr16Ouix0aHwTCl4p", "X-OriginatorOrg": "ti.com", "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "13 Feb 2026 12:36:25.1301\n (UTC)", "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 78d5c94d-dc19-4539-5eff-08de6afc8073", "X-MS-Exchange-CrossTenant-Id": "e5b49634-450b-4709-8abb-1e2b19b982b7", "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=e5b49634-450b-4709-8abb-1e2b19b982b7;Ip=[198.47.23.194];Helo=[lewvzet200.ext.ti.com]", "X-MS-Exchange-CrossTenant-AuthSource": "\n\tBL6PEPF00020E64.namprd04.prod.outlook.com", "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous", "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem", "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "BLAPR10MB4978" }, "content": "From: Aksh Garg <a-garg7@ti.com>\n\nDOE (Data Object Exchange) is a standard PCIe extended capability\nfeature introduced in the Data Object Exchange (DOE) ECN for\nPCIe r5.0. It provides a communication mechanism primarily used for\nimplementing PCIe security features such as device authentication, and\nsecure link establishment. Think of DOE as a sophisticated mailbox\nsystem built into PCIe. The root complex can send structured requests\nto the endpoint device through DOE mailboxes, and the endpoint device\nresponds with appropriate data.\n\nAdd the DOE support for PCIe endpoint devices, enabling endpoint\nfunctions to process the DOE requests from the host. The implementation\nprovides framework APIs for controller drivers to register mailboxes,\nprotocol handler registration for different DOE data object types, and\nrequest processing with workqueues ensuring sequential handling per\nmailbox. The Discovery protocol is handled internally by the DOE core.\n\nThis implementation complements the existing DOE implementation for\nroot complex in drivers/pci/doe.c.\n\nCo-developed-by: Siddharth Vadapalli <s-vadapalli@ti.com>\nSigned-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>\nSigned-off-by: Aksh Garg <a-garg7@ti.com>\n---\n drivers/pci/Kconfig | 14 +\n drivers/pci/Makefile | 1 +\n drivers/pci/doe-ep.c | 671 ++++++++++++++++++++++++++++++++++++++++\n include/linux/pci-doe.h | 69 +++++\n include/linux/pci-epc.h | 4 +\n 5 files changed, 759 insertions(+)\n create mode 100644 drivers/pci/doe-ep.c", "diff": "diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig\nindex e3f848ffb52a..2a57a314054c 100644\n--- a/drivers/pci/Kconfig\n+++ b/drivers/pci/Kconfig\n@@ -146,6 +146,20 @@ config PCI_DOE\n \t Say Y here if you want be able to communicate with PCIe DOE\n \t mailboxes.\n \n+config PCI_DOE_EP\n+\tbool \"PCI Endpoint Data Object Exchange (DOE) support\"\n+\tdepends on PCI_ENDPOINT\n+\thelp\n+\t This enables support for Data Object Exchange (DOE) protocol\n+\t on PCI Endpoint controllers. It provides a communication\n+\t mechanism through mailboxes, primarily used for PCIe security\n+\t features.\n+\n+\t Say Y here if you want be able to communicate using PCIe DOE\n+\t mailboxes.\n+\n+\t If unsure, say N.\n+\n config PCI_ECAM\n \tbool\n \ndiff --git a/drivers/pci/Makefile b/drivers/pci/Makefile\nindex e10cfe5a280b..66084e2ef9b2 100644\n--- a/drivers/pci/Makefile\n+++ b/drivers/pci/Makefile\n@@ -34,6 +34,7 @@ obj-$(CONFIG_PCI_P2PDMA)\t+= p2pdma.o\n obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o\n obj-$(CONFIG_VGA_ARB)\t\t+= vgaarb.o\n obj-$(CONFIG_PCI_DOE)\t\t+= doe.o\n+obj-$(CONFIG_PCI_DOE_EP)\t+= doe-ep.o\n obj-$(CONFIG_PCI_IDE)\t\t+= ide.o\n obj-$(CONFIG_PCI_TSM)\t\t+= tsm.o\n obj-$(CONFIG_PCI_DYNAMIC_OF_NODES) += of_property.o\ndiff --git a/drivers/pci/doe-ep.c b/drivers/pci/doe-ep.c\nnew file mode 100644\nindex 000000000000..ff0551644f54\n--- /dev/null\n+++ b/drivers/pci/doe-ep.c\n@@ -0,0 +1,671 @@\n+// SPDX-License-Identifier: GPL-2.0-only or MIT\n+/*\n+ * Data Object Exchange for PCIe Endpoint\n+ *\tPCIe r7.0, sec 6.30 DOE\n+ *\n+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com\n+ *\tAksh Garg <a-garg7@ti.com>\n+ *\tSiddharth Vadapalli <s-vadapalli@ti.com>\n+ */\n+\n+#define dev_fmt(fmt) \"DOE EP: \" fmt\n+\n+#include <linux/bitfield.h>\n+#include <linux/completion.h>\n+#include <linux/device.h>\n+#include <linux/mutex.h>\n+#include <linux/pci.h>\n+#include <linux/pci-epc.h>\n+#include <linux/pci-doe.h>\n+#include <linux/slab.h>\n+#include <linux/workqueue.h>\n+#include <linux/xarray.h>\n+\n+/*\n+ * Combines function number and capability offset into a unique lookup key\n+ * for storing/retrieving DOE mailboxes in an xarray.\n+ */\n+#define PCI_DOE_MB_KEY(func, offset) \\\n+\t(((unsigned long)(func) << 16) | (offset))\n+\n+/**\n+ * struct pci_doe_protocol - DOE protocol handler entry\n+ * @vid: Vendor ID\n+ * @type: Protocol type\n+ * @handler: Handler function pointer\n+ */\n+struct pci_doe_protocol {\n+\tu16 vid;\n+\tu8 type;\n+\tpci_doe_protocol_handler_t handler;\n+};\n+\n+/*\n+ * Global registry of protocol handlers,\n+ * holding struct pci_doe_protocol\n+ */\n+static DEFINE_XARRAY_ALLOC(pci_doe_protocols);\n+\n+/* Serializes concurrent accesses to pci_doe_protocols xarray */\n+static DEFINE_MUTEX(protocols_mutex);\n+\n+/**\n+ * struct pci_ep_doe_mb - State for a single DOE mailbox on EP\n+ *\n+ * This state is used to manage a single DOE mailbox capability on the\n+ * endpoint side.\n+ *\n+ * @epc: PCI endpoint controller this mailbox belongs to\n+ * @func_no: Physical function number of the function this mailbox belongs to\n+ * @cap_offset: Capability offset\n+ * @work_queue: Queue of work items\n+ * @flags: Bit array of PCI_DOE_FLAG_* flags\n+ */\n+struct pci_ep_doe_mb {\n+\tstruct pci_epc *epc;\n+\tu8 func_no;\n+\tu16 cap_offset;\n+\tstruct workqueue_struct *work_queue;\n+\tunsigned long flags;\n+};\n+\n+/**\n+ * struct pci_ep_doe_task - Represents a single DOE request/response task\n+ *\n+ * @feat: DOE feature (vendor ID and type)\n+ * @request_pl: Request payload\n+ * @request_pl_sz: Size of request payload in bytes\n+ * @response_pl: Output pointer for response buffer\n+ * @response_pl_sz: Output pointer for response size\n+ * @task_status: Task completion status (0 on success, -errno on failure)\n+ * @complete: Completion callback\n+ * @private: Private data for completion\n+ * @work: Work structure for workqueue\n+ * @doe_mb: DOE mailbox handling this task\n+ */\n+struct pci_ep_doe_task {\n+\tstruct pci_doe_feature feat;\n+\tconst void *request_pl;\n+\tsize_t request_pl_sz;\n+\tvoid **response_pl;\n+\tsize_t *response_pl_sz;\n+\tint task_status;\n+\tvoid (*complete)(struct pci_ep_doe_task *task);\n+\tvoid *private;\n+\n+\t/* Initialized by pci_ep_doe_submit_task() */\n+\tstruct work_struct work;\n+\tstruct pci_ep_doe_mb *doe_mb;\n+};\n+\n+/**\n+ * pci_ep_doe_init() - Initialize the DOE framework for a controller in EP mode\n+ * @epc: PCI endpoint controller\n+ *\n+ * Initialize the DOE framework data structures. This only initializes\n+ * the xarray that will hold the mailboxes.\n+ *\n+ * RETURNS: 0 on success, -errno on failure\n+ */\n+int pci_ep_doe_init(struct pci_epc *epc)\n+{\n+\tif (!epc)\n+\t\treturn -EINVAL;\n+\n+\txa_init(&epc->doe_mbs);\n+\treturn 0;\n+}\n+EXPORT_SYMBOL_GPL(pci_ep_doe_init);\n+\n+/**\n+ * pci_ep_doe_add_mailbox() - Add a DOE mailbox for a physical function\n+ * @epc: PCI endpoint controller\n+ * @func_no: Physical function number\n+ * @cap_offset: Offset of the DOE capability\n+ *\n+ * Create and register a DOE mailbox for the specified physical function\n+ * and capability offset. The controller driver should call this for each\n+ * DOE capability it finds in its config space.\n+ *\n+ * RETURNS: 0 on success, -errno on failure\n+ */\n+int pci_ep_doe_add_mailbox(struct pci_epc *epc, u8 func_no, u16 cap_offset)\n+{\n+\tstruct pci_ep_doe_mb *doe_mb;\n+\tunsigned long key;\n+\tint ret;\n+\n+\tif (!epc)\n+\t\treturn -EINVAL;\n+\n+\tdoe_mb = kzalloc(sizeof(*doe_mb), GFP_KERNEL);\n+\tif (!doe_mb)\n+\t\treturn -ENOMEM;\n+\n+\tdoe_mb->epc = epc;\n+\tdoe_mb->func_no = func_no;\n+\tdoe_mb->cap_offset = cap_offset;\n+\n+\tdoe_mb->work_queue = alloc_ordered_workqueue(\"pci_ep_doe[%s:pf%d:offset%x]\", 0,\n+\t\t\t\t\t\t dev_name(&epc->dev),\n+\t\t\t\t\t\t func_no, cap_offset);\n+\tif (!doe_mb->work_queue) {\n+\t\tdev_err(epc->dev.parent,\n+\t\t\t\"[pf%d:offset%x] failed to allocate work queue\\n\",\n+\t\t\tfunc_no, cap_offset);\n+\t\tret = -ENOMEM;\n+\t\tgoto err_free;\n+\t}\n+\n+\t/* Add to xarray with composite key */\n+\tkey = PCI_DOE_MB_KEY(func_no, cap_offset);\n+\tret = xa_insert(&epc->doe_mbs, key, doe_mb, GFP_KERNEL);\n+\tif (ret) {\n+\t\tdev_err(epc->dev.parent,\n+\t\t\t\"[pf%d:offset%x] failed to insert mailbox: %d\\n\",\n+\t\t\tfunc_no, cap_offset, ret);\n+\t\tgoto err_destroy;\n+\t}\n+\n+\tdev_dbg(epc->dev.parent,\n+\t\t\"DOE mailbox added: pf%d offset 0x%x\\n\",\n+\t\tfunc_no, cap_offset);\n+\n+\treturn 0;\n+\n+err_destroy:\n+\tdestroy_workqueue(doe_mb->work_queue);\n+err_free:\n+\tkfree(doe_mb);\n+\treturn ret;\n+}\n+EXPORT_SYMBOL_GPL(pci_ep_doe_add_mailbox);\n+\n+/**\n+ * pci_ep_doe_register_protocol() - Register a protocol handler\n+ * @vendor: Vendor ID\n+ * @type: Protocol type\n+ * @handler: Handler function pointer\n+ *\n+ * Register a protocol handler that will be called when DOE requests\n+ * with the specified vendor ID and type are received. Protocol libraries\n+ * should call this during module initialization.\n+ *\n+ * RETURNS: 0 on success, -errno on failure\n+ */\n+int pci_ep_doe_register_protocol(u16 vendor, u8 type,\n+\t\t\t\t pci_doe_protocol_handler_t handler)\n+{\n+\tstruct pci_doe_protocol *protocol;\n+\tunsigned long index;\n+\tint ret;\n+\tu32 id;\n+\n+\tif (!handler)\n+\t\treturn -EINVAL;\n+\n+\t/* Don't allow registering discovery protocol */\n+\tif (vendor == PCI_VENDOR_ID_PCI_SIG && type == PCI_DOE_FEATURE_DISCOVERY)\n+\t\treturn -EINVAL;\n+\n+\tmutex_lock(&protocols_mutex);\n+\n+\t/* Check if already registered */\n+\txa_for_each(&pci_doe_protocols, index, protocol) {\n+\t\tif (protocol->vid == vendor && protocol->type == type) {\n+\t\t\tret = -EEXIST;\n+\t\t\tgoto err;\n+\t\t}\n+\t}\n+\n+\tprotocol = kzalloc(sizeof(*protocol), GFP_KERNEL);\n+\tif (!protocol) {\n+\t\tret = -ENOMEM;\n+\t\tgoto err;\n+\t}\n+\n+\tprotocol->vid = vendor;\n+\tprotocol->type = type;\n+\tprotocol->handler = handler;\n+\n+\tret = xa_alloc(&pci_doe_protocols, &id, protocol,\n+\t\t xa_limit_32b, GFP_KERNEL);\n+\tif (ret) {\n+\t\tkfree(protocol);\n+\t\tgoto err;\n+\t}\n+\n+\tmutex_unlock(&protocols_mutex);\n+\n+\tpr_debug(\"DOE EP: Registered protocol %04x:%02x at index %u\\n\",\n+\t\t vendor, type, id);\n+\n+\treturn 0;\n+\n+err:\n+\tmutex_unlock(&protocols_mutex);\n+\treturn ret;\n+}\n+EXPORT_SYMBOL_GPL(pci_ep_doe_register_protocol);\n+\n+/**\n+ * pci_ep_doe_unregister_protocol() - Unregister a protocol handler\n+ * @vendor: Vendor ID\n+ * @type: Protocol type\n+ *\n+ * Unregister a previously registered protocol handler. Protocol libraries\n+ * should call this during module cleanup.\n+ */\n+void pci_ep_doe_unregister_protocol(u16 vendor, u8 type)\n+{\n+\tstruct pci_doe_protocol *protocol;\n+\tunsigned long index;\n+\n+\tmutex_lock(&protocols_mutex);\n+\n+\t/* Find and remove the protocol entry */\n+\txa_for_each(&pci_doe_protocols, index, protocol) {\n+\t\tif (protocol->vid == vendor && protocol->type == type) {\n+\t\t\txa_erase(&pci_doe_protocols, index);\n+\t\t\tkfree(protocol);\n+\t\t\tmutex_unlock(&protocols_mutex);\n+\t\t\tpr_debug(\"DOE EP: Unregistered protocol %04x:%02x\\n\",\n+\t\t\t\t vendor, type);\n+\t\t\treturn;\n+\t\t}\n+\t}\n+\n+\tmutex_unlock(&protocols_mutex);\n+\tpr_warn(\"DOE EP: Attempted to unregister non-existent protocol %04x:%02x\\n\",\n+\t\tvendor, type);\n+}\n+EXPORT_SYMBOL_GPL(pci_ep_doe_unregister_protocol);\n+\n+/**\n+ * pci_ep_doe_cancel_tasks() - Cancel all pending tasks\n+ * @doe_mb: DOE mailbox\n+ *\n+ * Cancel all pending tasks in the mailbox. Mark the mailbox as dead\n+ * so no new tasks can be submitted.\n+ */\n+static void pci_ep_doe_cancel_tasks(struct pci_ep_doe_mb *doe_mb)\n+{\n+\tif (!doe_mb)\n+\t\treturn;\n+\n+\t/* Mark the mailbox as dead */\n+\tset_bit(PCI_DOE_FLAG_DEAD, &doe_mb->flags);\n+\n+\t/* Stop all pending work items from starting */\n+\tset_bit(PCI_DOE_FLAG_CANCEL, &doe_mb->flags);\n+}\n+\n+/**\n+ * pci_ep_doe_get_mailbox() - Get DOE mailbox by function and offset\n+ * @epc: PCI endpoint controller\n+ * @func_no: Physical function number\n+ * @cap_offset: Offset of the DOE capability\n+ *\n+ * Internal helper to look up a DOE mailbox by its function number and\n+ * capability offset.\n+ *\n+ * RETURNS: Pointer to the mailbox or NULL if not found\n+ */\n+static struct pci_ep_doe_mb *pci_ep_doe_get_mailbox(struct pci_epc *epc,\n+\t\t\t\t\t\t u8 func_no, u16 cap_offset)\n+{\n+\tunsigned long key;\n+\n+\tif (!epc)\n+\t\treturn NULL;\n+\n+\tkey = PCI_DOE_MB_KEY(func_no, cap_offset);\n+\treturn xa_load(&epc->doe_mbs, key);\n+}\n+\n+/**\n+ * pci_ep_doe_find_protocol() - Find protocol handler\n+ * @vendor: Vendor ID\n+ * @type: Protocol type\n+ *\n+ * Look up a protocol handler in the registered protocols.\n+ *\n+ * RETURNS: Handler function pointer or NULL if not found\n+ */\n+static pci_doe_protocol_handler_t pci_ep_doe_find_protocol(u16 vendor, u8 type)\n+{\n+\tpci_doe_protocol_handler_t handler = NULL;\n+\tstruct pci_doe_protocol *protocol;\n+\tunsigned long index;\n+\n+\tmutex_lock(&protocols_mutex);\n+\n+\txa_for_each(&pci_doe_protocols, index, protocol) {\n+\t\tif (protocol->vid == vendor && protocol->type == type) {\n+\t\t\thandler = protocol->handler;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tmutex_unlock(&protocols_mutex);\n+\treturn handler;\n+}\n+\n+/**\n+ * pci_ep_doe_handle_discovery() - Handle Discovery protocol request\n+ * @request: Request payload\n+ * @request_sz: Request size\n+ * @response: Output pointer for response buffer\n+ * @response_sz: Output pointer for response size\n+ *\n+ * Handle the DOE Discovery protocol. The request contains an index specifying\n+ * which protocol to query. This function creates a response containing the\n+ * vendor ID and protocol type for the requested index, along with the next\n+ * index value for further discovery:\n+ *\n+ * - next_index = 0: Signals this is the last protocol supported\n+ * - next_index = n (non-zero): Signals more protocols available,\n+ * query index n next\n+ *\n+ * RETURNS: 0 on success, -errno on failure\n+ */\n+static int pci_ep_doe_handle_discovery(const void *request, size_t request_sz,\n+\t\t\t\t void **response, size_t *response_sz)\n+{\n+\tstruct pci_doe_protocol *protocol;\n+\tu8 requested_index, next_index;\n+\tunsigned long index;\n+\tu8 xarray_count = 0;\n+\tu32 *response_pl;\n+\tu32 request_pl;\n+\tu16 vendor;\n+\tu8 type;\n+\n+\tif (request_sz != sizeof(u32))\n+\t\treturn -EINVAL;\n+\n+\trequest_pl = *(u32 *)request;\n+\trequested_index = FIELD_GET(PCI_DOE_DATA_OBJECT_DISC_REQ_3_INDEX, request_pl);\n+\n+\tmutex_lock(&protocols_mutex);\n+\n+\t/* Count protocols in xarray */\n+\txa_for_each(&pci_doe_protocols, index, protocol)\n+\t\txarray_count++;\n+\n+\tif (requested_index > xarray_count) {\n+\t\tmutex_unlock(&protocols_mutex);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Index 0 is always Discovery protocol */\n+\tif (requested_index == 0) {\n+\t\tvendor = PCI_VENDOR_ID_PCI_SIG;\n+\t\ttype = PCI_DOE_FEATURE_DISCOVERY;\n+\t} else {\n+\t\tprotocol = xa_load(&pci_doe_protocols, (unsigned long)(requested_index - 1));\n+\t\tif (!protocol) {\n+\t\t\tmutex_unlock(&protocols_mutex);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tvendor = protocol->vid;\n+\t\ttype = protocol->type;\n+\t}\n+\tmutex_unlock(&protocols_mutex);\n+\n+\t/* Calculate next index */\n+\tnext_index = (requested_index < xarray_count) ? requested_index + 1 : 0;\n+\n+\tresponse_pl = kzalloc(sizeof(*response_pl), GFP_KERNEL);\n+\tif (!response_pl)\n+\t\treturn -ENOMEM;\n+\n+\t/* Build response */\n+\t*response_pl = FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_RSP_3_VID, vendor) |\n+\t\t FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_RSP_3_TYPE, type) |\n+\t\t FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_RSP_3_NEXT_INDEX, next_index);\n+\n+\t*response = response_pl;\n+\t*response_sz = sizeof(*response_pl);\n+\n+\treturn 0;\n+}\n+\n+static void signal_task_complete(struct pci_ep_doe_task *task, int status)\n+{\n+\ttask->task_status = status;\n+\tdestroy_work_on_stack(&task->work);\n+\ttask->complete(task);\n+}\n+\n+/**\n+ * doe_ep_task_work() - Work function for processing DOE EP tasks\n+ * @work: Work structure\n+ *\n+ * Process a DOE request by calling the appropriate protocol handler.\n+ */\n+static void doe_ep_task_work(struct work_struct *work)\n+{\n+\tstruct pci_ep_doe_task *task = container_of(work, struct pci_ep_doe_task,\n+\t\t\t\t\t\t work);\n+\tstruct pci_ep_doe_mb *doe_mb = task->doe_mb;\n+\tpci_doe_protocol_handler_t handler;\n+\tint rc;\n+\n+\tif (test_bit(PCI_DOE_FLAG_DEAD, &doe_mb->flags)) {\n+\t\tsignal_task_complete(task, -EIO);\n+\t\treturn;\n+\t}\n+\n+\t/* Check if request was aborted */\n+\tif (test_bit(PCI_DOE_FLAG_CANCEL, &doe_mb->flags)) {\n+\t\tsignal_task_complete(task, -ECANCELED);\n+\t\treturn;\n+\t}\n+\n+\t/* Handle Discovery protocol directly */\n+\tif (task->feat.vid == PCI_VENDOR_ID_PCI_SIG &&\n+\t task->feat.type == PCI_DOE_FEATURE_DISCOVERY) {\n+\t\trc = pci_ep_doe_handle_discovery(task->request_pl,\n+\t\t\t\t\t\t task->request_pl_sz,\n+\t\t\t\t\t\t task->response_pl,\n+\t\t\t\t\t\t task->response_pl_sz);\n+\t\tsignal_task_complete(task, rc);\n+\t\treturn;\n+\t}\n+\n+\t/* Find protocol handler in xarray */\n+\thandler = pci_ep_doe_find_protocol(task->feat.vid, task->feat.type);\n+\tif (!handler) {\n+\t\tdev_warn(doe_mb->epc->dev.parent,\n+\t\t\t \"[%d:%x] Unsupported protocol VID=%04x TYPE=%02x\\n\",\n+\t\t\t doe_mb->func_no, doe_mb->cap_offset,\n+\t\t\t task->feat.vid, task->feat.type);\n+\t\tsignal_task_complete(task, -EOPNOTSUPP);\n+\t\treturn;\n+\t}\n+\n+\t/* Call protocol handler */\n+\trc = handler(task->request_pl, task->request_pl_sz,\n+\t\t task->response_pl, task->response_pl_sz);\n+\n+\tsignal_task_complete(task, rc);\n+}\n+\n+/**\n+ * pci_ep_doe_submit_task() - Submit a task to be processed\n+ * @doe_mb: DOE mailbox\n+ * @task: Task to submit\n+ *\n+ * Submit a DOE task to the workqueue for processing.\n+ * Task must be allocated on the stack.\n+ *\n+ * RETURNS: 0 on success, -errno on failure\n+ */\n+static int pci_ep_doe_submit_task(struct pci_ep_doe_mb *doe_mb,\n+\t\t\t\t struct pci_ep_doe_task *task)\n+{\n+\tif (test_bit(PCI_DOE_FLAG_DEAD, &doe_mb->flags))\n+\t\treturn -EIO;\n+\n+\ttask->doe_mb = doe_mb;\n+\tINIT_WORK_ONSTACK(&task->work, doe_ep_task_work);\n+\tqueue_work(doe_mb->work_queue, &task->work);\n+\treturn 0;\n+}\n+\n+static void pci_ep_doe_task_complete(struct pci_ep_doe_task *task)\n+{\n+\tcomplete(task->private);\n+}\n+\n+/**\n+ * pci_ep_doe_process_request() - Process DOE request on endpoint\n+ * @epc: PCI endpoint controller\n+ * @func_no: Physical function number\n+ * @cap_offset: DOE capability offset\n+ * @vendor: Vendor ID from request header\n+ * @type: Protocol type from request header\n+ * @request: Request payload in CPU-native format\n+ * @request_sz: Size of request payload (bytes)\n+ * @response: Output pointer for response buffer in CPU-native format\n+ * @response_sz: Output pointer for response size (bytes)\n+ *\n+ * Process a DOE request received on the endpoint. The request payload should\n+ * not include the DOE header (vendor/type/length). The protocol handler will\n+ * allocate the response buffer, which the caller (controller driver) must\n+ * free after use.\n+ *\n+ * As per DOE specification, a mailbox processes one request at a time.\n+ * Therefore, this function will never be called concurrently for the same\n+ * mailbox by different callers.\n+ *\n+ * The caller is responsible for the conversion of the received DOE request\n+ * with le32_to_cpu() before calling this function.\n+ * Similarly, it is responsible for converting the response payload with\n+ * cpu_to_le32() before sending it back over the DOE mailbox.\n+ *\n+ * The caller is also responsible for ensuring that the request size\n+ * is within the limits defined by PCI_DOE_MAX_LENGTH.\n+ *\n+ * RETURNS: 0 on success, -errno on failure\n+ */\n+int pci_ep_doe_process_request(struct pci_epc *epc, u8 func_no, u16 cap_offset,\n+\t\t\t u16 vendor, u8 type, const void *request,\n+\t\t\t size_t request_sz, void **response, size_t *response_sz)\n+{\n+\tDECLARE_COMPLETION_ONSTACK(c);\n+\tstruct pci_ep_doe_mb *doe_mb;\n+\tstruct pci_ep_doe_task task = {\n+\t\t.feat.vid = vendor,\n+\t\t.feat.type = type,\n+\t\t.request_pl = request,\n+\t\t.request_pl_sz = request_sz,\n+\t\t.response_pl = response,\n+\t\t.response_pl_sz = response_sz,\n+\t\t.complete = pci_ep_doe_task_complete,\n+\t\t.private = &c,\n+\t};\n+\tint rc;\n+\n+\tdoe_mb = pci_ep_doe_get_mailbox(epc, func_no, cap_offset);\n+\tif (!doe_mb)\n+\t\treturn -ENODEV;\n+\n+\trc = pci_ep_doe_submit_task(doe_mb, &task);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\twait_for_completion(&c);\n+\n+\treturn task.task_status;\n+}\n+EXPORT_SYMBOL_GPL(pci_ep_doe_process_request);\n+\n+/**\n+ * pci_ep_doe_abort() - Abort DOE operations on a mailbox\n+ * @epc: PCI endpoint controller\n+ * @func_no: Physical function number\n+ * @cap_offset: DOE capability offset\n+ *\n+ * Abort all queued and wait for in-flight DOE operations to complete for the\n+ * specified mailbox. This function is called by the EP controller driver\n+ * when the RC sets the ABORT bit in the DOE Control register.\n+ *\n+ * The function will:\n+ *\n+ * - Set CANCEL flag to prevent new requests in the queue from starting\n+ * - Wait for the currently executing handler to complete (cannot interrupt)\n+ * - Flush the workqueue to wait for all requests to be handled appropriately\n+ * - Clear CANCEL flag to prepare for new requests\n+ *\n+ * RETURNS: 0 on success, -errno on failure\n+ */\n+int pci_ep_doe_abort(struct pci_epc *epc, u8 func_no, u16 cap_offset)\n+{\n+\tstruct pci_ep_doe_mb *doe_mb;\n+\n+\tif (!epc)\n+\t\treturn -EINVAL;\n+\n+\tdoe_mb = pci_ep_doe_get_mailbox(epc, func_no, cap_offset);\n+\tif (!doe_mb)\n+\t\treturn -ENODEV;\n+\n+\t/* Set CANCEL flag - worker will abort queued requests */\n+\tset_bit(PCI_DOE_FLAG_CANCEL, &doe_mb->flags);\n+\tflush_workqueue(doe_mb->work_queue);\n+\n+\t/* Clear CANCEL flag - mailbox ready for new requests */\n+\tclear_bit(PCI_DOE_FLAG_CANCEL, &doe_mb->flags);\n+\n+\tdev_dbg(epc->dev.parent,\n+\t\t\"DOE mailbox aborted: PF%d offset 0x%x\\n\",\n+\t\tfunc_no, cap_offset);\n+\n+\treturn 0;\n+}\n+EXPORT_SYMBOL_GPL(pci_ep_doe_abort);\n+\n+/**\n+ * pci_ep_doe_destroy_mb() - Destroy a single DOE mailbox\n+ * @doe_mb: DOE mailbox to destroy\n+ *\n+ * Internal function to destroy a mailbox and free its resources.\n+ */\n+static void pci_ep_doe_destroy_mb(struct pci_ep_doe_mb *doe_mb)\n+{\n+\tif (!doe_mb)\n+\t\treturn;\n+\n+\tpci_ep_doe_cancel_tasks(doe_mb);\n+\n+\tif (doe_mb->work_queue)\n+\t\tdestroy_workqueue(doe_mb->work_queue);\n+\n+\tkfree(doe_mb);\n+}\n+\n+/**\n+ * pci_ep_doe_destroy() - Destroy all DOE mailboxes\n+ * @epc: PCI endpoint controller\n+ *\n+ * Destroy all DOE mailboxes and free associated resources.\n+ *\n+ * This function should be called during controller cleanup to free all\n+ * DOE resources.\n+ */\n+void pci_ep_doe_destroy(struct pci_epc *epc)\n+{\n+\tstruct pci_ep_doe_mb *doe_mb;\n+\tunsigned long index;\n+\n+\tif (!epc)\n+\t\treturn;\n+\n+\txa_for_each(&epc->doe_mbs, index, doe_mb)\n+\t\tpci_ep_doe_destroy_mb(doe_mb);\n+\n+\txa_destroy(&epc->doe_mbs);\n+}\n+EXPORT_SYMBOL_GPL(pci_ep_doe_destroy);\ndiff --git a/include/linux/pci-doe.h b/include/linux/pci-doe.h\nindex a966626c47f9..b353c3a1aa82 100644\n--- a/include/linux/pci-doe.h\n+++ b/include/linux/pci-doe.h\n@@ -13,6 +13,8 @@\n #ifndef LINUX_PCI_DOE_H\n #define LINUX_PCI_DOE_H\n \n+#include <linux/types.h>\n+\n /* Mailbox state flags */\n #define PCI_DOE_FLAG_CANCEL\t\t0\n #define PCI_DOE_FLAG_DEAD\t\t1\n@@ -24,12 +26,19 @@\n #define PCI_DOE_FEATURE_CMA\t\t1\n #define PCI_DOE_FEATURE_SSESSION\t2\n \n+typedef int (*pci_doe_protocol_handler_t)(const void *request,\n+\t\t\t\t\t size_t request_sz,\n+\t\t\t\t\t void **response,\n+\t\t\t\t\t size_t *response_sz);\n+\n struct pci_doe_feature {\n \tu16 vid;\n \tu8 type;\n };\n \n struct pci_doe_mb;\n+struct pci_dev;\n+struct pci_epc;\n \n #ifdef CONFIG_PCI_DOE\n struct pci_doe_mb *pci_find_doe_mailbox(struct pci_dev *pdev, u16 vendor,\n@@ -54,4 +63,64 @@ static inline int pci_doe(struct pci_doe_mb *doe_mb, u16 vendor, u8 type,\n }\n #endif /* CONFIG_PCI_DOE */\n \n+#ifdef CONFIG_PCI_DOE_EP\n+int pci_ep_doe_init(struct pci_epc *epc);\n+\n+int pci_ep_doe_add_mailbox(struct pci_epc *epc, u8 func_no, u16 cap_offset);\n+\n+int pci_ep_doe_register_protocol(u16 vendor, u8 type,\n+\t\t\t\t pci_doe_protocol_handler_t handler);\n+\n+void pci_ep_doe_unregister_protocol(u16 vendor, u8 type);\n+\n+int pci_ep_doe_process_request(struct pci_epc *epc, u8 func_no, u16 cap_offset,\n+\t\t\t u16 vendor, u8 type, const void *request,\n+\t\t\t size_t request_sz, void **response, size_t *response_sz);\n+\n+int pci_ep_doe_abort(struct pci_epc *epc, u8 func_no, u16 cap_offset);\n+\n+void pci_ep_doe_destroy(struct pci_epc *epc);\n+\n+#else\n+static inline int pci_ep_doe_init(struct pci_epc *epc)\n+{\n+\treturn -EOPNOTSUPP;\n+}\n+\n+static inline int pci_ep_doe_add_mailbox(struct pci_epc *epc, u8 func_no,\n+\t\t\t\t\t u16 cap_offset)\n+{\n+\treturn -EOPNOTSUPP;\n+}\n+\n+static inline int pci_ep_doe_register_protocol(u16 vendor, u8 type,\n+\t\t\t\t\t pci_doe_protocol_handler_t handler)\n+{\n+\treturn -EOPNOTSUPP;\n+}\n+\n+static inline void pci_ep_doe_unregister_protocol(u16 vendor, u8 type)\n+{\n+}\n+\n+static inline int pci_ep_doe_process_request(struct pci_epc *epc, u8 func_no, u16 cap_offset,\n+\t\t\t\t\t u16 vendor, u8 type,\n+\t\t\t\t\t const void *request, size_t request_sz,\n+\t\t\t\t\t void **response, size_t *response_sz)\n+{\n+\treturn -EOPNOTSUPP;\n+}\n+\n+static inline int pci_ep_doe_abort(struct pci_epc *epc, u8 func_no,\n+\t\t\t\t u16 cap_offset)\n+{\n+\treturn -EOPNOTSUPP;\n+}\n+\n+static inline void pci_ep_doe_destroy(struct pci_epc *epc)\n+{\n+}\n+\n+#endif /* CONFIG_PCI_DOE_EP */\n+\n #endif /* LINUX_PCI_DOE_H */\ndiff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h\nindex 4286bfdbfdfa..ad4de4d33da3 100644\n--- a/include/linux/pci-epc.h\n+++ b/include/linux/pci-epc.h\n@@ -165,6 +165,7 @@ struct pci_epc_mem {\n * @domain_nr: PCI domain number of the endpoint controller\n * @init_complete: flag to indicate whether the EPC initialization is complete\n * or not\n+ * @doe_mbs: array of DOE mailboxes (CONFIG_PCI_DOE_EP)\n */\n struct pci_epc {\n \tstruct device\t\t\tdev;\n@@ -182,6 +183,9 @@ struct pci_epc {\n \tunsigned long\t\t\tfunction_num_map;\n \tint\t\t\t\tdomain_nr;\n \tbool\t\t\t\tinit_complete;\n+#ifdef CONFIG_PCI_DOE_EP\n+\tstruct xarray\t\t\tdoe_mbs;\n+#endif\n };\n \n /**\n", "prefixes": [ "RFC", "3/4" ] }