[RFC PATCH 1/4] PCI: Add documentation for DOE endpoint support

Aksh Garg a-garg7 at ti.com
Fri Feb 13 04:36:00 PST 2026


From: Aksh Garg <a-garg7 at ti.com>

Document the architecture and implementation details for the Data Object
Exchange (DOE) framework for PCIe Endpoint devices.

Co-developed-by: Siddharth Vadapalli <s-vadapalli at ti.com>
Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
Signed-off-by: Aksh Garg <a-garg7 at ti.com>
---
 Documentation/PCI/index.rst      |   1 +
 Documentation/PCI/pci-doe-ep.rst | 291 +++++++++++++++++++++++++++++++
 2 files changed, 292 insertions(+)
 create mode 100644 Documentation/PCI/pci-doe-ep.rst

diff --git a/Documentation/PCI/index.rst b/Documentation/PCI/index.rst
index 5d720d2a415e..4c9a4e749442 100644
--- a/Documentation/PCI/index.rst
+++ b/Documentation/PCI/index.rst
@@ -20,3 +20,4 @@ PCI Bus Subsystem
    controller/index
    boot-interrupts
    tph
+   pci-doe-ep
diff --git a/Documentation/PCI/pci-doe-ep.rst b/Documentation/PCI/pci-doe-ep.rst
new file mode 100644
index 000000000000..d6715944c117
--- /dev/null
+++ b/Documentation/PCI/pci-doe-ep.rst
@@ -0,0 +1,291 @@
+.. SPDX-License-Identifier: GPL-2.0-only or MIT
+
+.. include:: <isonum.txt>
+
+=============================================
+Data Object Exchange (DOE) for PCIe Endpoint
+=============================================
+
+:Copyright: |copy| 2026 Texas Instruments Incorporated
+:Author: Aksh Garg <a-garg7 at ti.com>
+:Co-Author: Siddharth Vadapalli <s-vadapalli at ti.com>
+
+Overview
+========
+
+DOE (Data Object Exchange) is a standard PCIe extended capability feature as
+introduced in the Data Object Exchange (DOE) ECN for PCIe r5.0. It is an optional
+mechanism for system firmware/software running on root complex (host) to perform
+:ref:`data object <data-object-term>` exchanges with an endpoint function. Each
+data object is uniquely identified by the Vendor ID of the vendor publishing the
+data object definition and a Data Object Type value assigned by that vendor.
+
+Think of DOE as a sophisticated mailbox system built into PCIe. The root complex
+can send structured requests to the endpoint device through DOE mailboxes, and
+the endpoint device responds with appropriate data. DOE mailboxes are implemented
+as PCIe Extended Capabilities in endpoint devices, allowing multiple mailboxes
+per function, each potentially supporting different data object protocols.
+
+The DOE support for root complex devices has already been implemented in
+``drivers/pci/doe.c``.
+
+How DOE Works
+=============
+
+The DOE mailbox operates through a simple request-response model:
+
+1. **Host sends request**: The root complex writes a data object (vendor ID, type,
+   and payload) to the DOE write mailbox register (one DWORD at a time) of the
+   endpoint function's config space and sets the GO bit in the DOE Status register
+   to indicate that a request is ready for processing.
+2. **Endpoint processes**: The endpoint function reads the request from DOE write
+   mailbox register, sets the BUSY bit in the DOE Status register, identifies the
+   protocol of the data object, and executes the appropriate handler.
+3. **Endpoint responds**: The endpoint function writes the response data object to the
+   DOE read mailbox register (one DWORD at a time), and sets the READY bit in the DOE
+   Status register to indicate that the response is ready. If an error occurs during
+   request processing (such as unsupported protocol or handler failure), the endpoint
+   sets the ERROR bit in the DOE Status register instead of the READY bit.
+4. **Host reads response**: The root complex retrieves the response data from the DOE read
+   mailbox register once the READY bit is set in the DOE Status register, and then writes
+   any value to this register to indicate a successful read. If the ERROR bit was set,
+   the root complex discards the response and performs error handling as needed.
+
+Each mailbox operates independently and can handle one transaction at a time. The
+DOE specification supports data objects of size up to 256KB (2\ :sup:`18` dwords).
+
+For complete DOE capability details, refer to `PCI Express Base Specification Revision 7.0,
+Section 6.30 - Data Object Exchange (DOE)`.
+
+Key Terminologies
+=================
+
+.. _data-object-term:
+
+**Data Object**
+  A structured, vendor-defined, or standard-defined message exchanged between
+  root complex and endpoint function via DOE capability registers in configuration
+  space of the function.
+
+**Mailbox**
+  A DOE capability on the endpoint device, where each physical function can have
+  multiple mailboxes.
+
+**Protocol**
+  A specific type of DOE communication data object identified by a Vendor ID and Type.
+
+**Handler**
+  A function that processes DOE requests of a specific protocol and generates responses.
+
+Architecture of DOE Implementation for Endpoint
+===============================================
+
+.. code-block:: text
+
+       +------------------+
+       |                  |
+       |   Root Complex   |
+       |                  |
+       +--------^---------+
+                |
+                | Config space access
+                |   over PCIe link
+                |
+     +----------v-----------+
+     |                      |
+     |    PCIe Controller   |
+     |      as Endpoint     |
+     |                      |
+     |  +-----------------+ |
+     |  |   DOE Mailbox   | |
+     |  +-------^---------+ |
+     +----------|-----------+
+    +-----------|---------------------------------------------------------------+
+    |           |                                       +--------------------+  |
+    | +---------v--------+           Allocate           |  +--------------+  |  |
+    | |                  |-------------------------------->|   Request    |  |  |
+    | |   EP Controller  |-------------------------------->|    Buffer    |  |  |
+    | |      Driver      |             Free             |  +--------------+  |  |
+    | |                  |---+                          |                    |  |
+    | +--------^---------+   |         Free             |                    |  |
+    |          |             +-----------------------+  |                    |  |
+    |          |                                     |  |                    |  |
+    |          | pci_ep_doe_process_request()        |  |                    |  |
+    |          |                                     |  |                    |  |
+    | +--------v---------+                           |  |                    |  |
+    | |                  |<----+                     |  |         DDR        |  |
+    | |    DOE EP Core   |     |  Discovery          |  |                    |  |
+    | |    (doe-ep.c)    |     |  Protocol           |  |                    |  |
+    | |                  |-----+  Handler            |  |                    |  |
+    | +--------^---------+                           |  |                    |  |
+    |          |                                     |  |                    |  |
+    |          | protocol_handler()                  |  |                    |  |
+    |          |                                     |  |                    |  |
+    | +--------v---------+                           |  |                    |  |
+    | |                  |                           |  |  +--------------+  |  |
+    | | Protocol Handler |                           +---->|   Response   |  |  |
+    | |      Module      |-------------------------------->|    Buffer    |  |  |
+    | | (CMA/SPDM/Other) |           Allocate           |  +--------------+  |  |
+    | |                  |                              |                    |  |
+    | +------------------+                              |                    |  |
+    |                                                   +--------------------+  |
+    +---------------------------------------------------------------------------+
+
+Initialization and Cleanup
+--------------------------
+
+**Framework Initialization**
+
+The controller driver calls ``pci_ep_doe_init(epc)`` during its probe sequence.
+This initializes the xarray data structure (a resizable array data structure
+defined in linux) named ``doe_mbs`` that stores metadata of DOE mailboxes for
+the controller in ``struct pci_epc``.
+
+**Mailbox Registration**
+
+For each DOE capability found in the endpoint function's configuration space,
+the controller driver calls ``pci_ep_doe_add_mailbox(epc, func_no, cap_offset)``.
+This creates a mailbox structure and allocates an ordered workqueue for processing
+DOE requests sequentially for that mailbox, enabling concurrent request handling
+across different mailboxes. Each mailbox is uniquely identified by the combination
+of physical function number and capability offset for that controller.
+
+**Cleanup**
+
+During driver removal or controller shutdown, the controller driver calls
+``pci_ep_doe_destroy(epc)`` to clean up all DOE resources. This function
+destroys all registered mailboxes, cancels any pending tasks, flushes and
+destroys the workqueues, and frees all memory allocated to the mailboxes.
+
+Register and Unregister Protocol Handler
+----------------------------------------
+
+Protocol implementations (such as CMA, SPDM, or vendor-specific protocols)
+register their handlers with the DOE EP core during module initialization.
+
+**Registration**
+
+Protocol modules call ``pci_ep_doe_register_protocol(vendor_id, type, handler)``
+to register their handler function. The handler is stored in a global xarray
+and will be invoked when DOE requests matching the vendor ID and type are received.
+The discovery protocol (VID = 0x0001 (PCI-SIG vendor ID), Type = 0x00 (discovery
+protocol)) is handled internally by the DOE EP core and cannot be registered by
+external modules.
+
+**Unregistration**
+
+During module cleanup, protocol modules call
+``pci_ep_doe_unregister_protocol(vendor_id, type)`` to remove their handler
+from the registry.
+
+Request Handling
+----------------
+
+The complete flow of a DOE request from the root complex to the response:
+
+**Step 1: Root Complex → EP Controller Driver**
+
+The root complex writes a DOE request (Vendor ID, Type, and Payload) to the
+DOE write mailbox register in the endpoint function's configuration space and sets
+the GO bit in the DOE Control register, indicating that the request is ready for
+processing.
+
+**Step 2: EP Controller Driver → DOE EP Core**
+
+The controller driver reads the request header to determine the data object length.
+Based on this length field, it allocates a request buffer in memory (DDR) of the
+appropriate size. The driver then reads the complete request payload from the DOE
+write mailbox register and converts the data from little-endian format (the format
+followed in the PCIe transactions over the link) to CPU-native format using
+``le32_to_cpu()``. The driver creates pointers for the response buffer and response
+size, which will be populated by the protocol handler. Finally, the driver calls
+``pci_ep_doe_process_request(epc, func_no, cap_offset, vendor, type, request,
+request_sz, &response, &response_sz)`` to hand off the request to the DOE EP core,
+and sets the BUSY bit in the DOE Status register.
+
+**Step 3: DOE EP Core Processing**
+
+The DOE EP core looks up the protocol handler based on the Vendor ID and Type
+from the request header. It creates a task structure and submits it to the
+mailbox's ordered workqueue. This ensures that requests for each mailbox are
+processed sequentially, one at a time, as required by the DOE specification.
+
+**Step 4: Protocol Handler Execution**
+
+The workqueue executes the task by calling the registered protocol handler:
+``handler(request, request_sz, &response, &response_sz)``. The handler processes
+the request, allocates a response buffer in memory (DDR), builds the response
+data, and returns the response pointer and size. For the discovery protocol,
+the DOE EP core handles this directly without invoking an external handler.
+
+**Step 5: DOE EP Core → EP Controller Driver**
+
+The DOE EP core waits for the handler to complete by the work queue, and returns
+the response pointer and size to the controller driver.
+
+**Step 6: EP Controller Driver → Root Complex**
+
+The controller driver converts the response from CPU-native format to
+little-endian format using ``cpu_to_le32()``, writes the response to DOE read
+mailbox register, and sets the READY bit in the DOE Status register. The root
+complex then reads the response from the read mailbox register. Finally,
+the controller driver frees both the request buffer (which it allocated) and the
+response buffer (which the handler allocated).
+
+Abort Handling
+--------------
+
+The DOE specification allows the root complex to abort ongoing DOE operations
+by setting the ABORT bit in the DOE Control register.
+
+**Trigger**
+
+When the root complex sets the ABORT bit, the EP controller driver detects this
+condition (typically in an interrupt handler or register polling routine). The
+action taken depends on the timing of the abort:
+
+- **ABORT during request transfer**: If the ABORT bit is set while the root complex
+  is still transferring the request to the mailbox registers, the controller driver
+  discards the request and no call to ``pci_ep_doe_abort()`` is needed.
+
+- **ABORT after request submission**: If the ABORT bit is set after the request
+  has been fully received and submitted to the DOE EP core via
+  ``pci_ep_doe_process_request()``, the controller driver must call
+  ``pci_ep_doe_abort(epc, func_no, cap_offset)`` for the affected mailbox to
+  perform abort sequence in the DOE EP core.
+
+**Abort Sequence**
+
+The abort function performs the following actions:
+
+1. Sets the CANCEL flag on the mailbox to prevent queued requests from starting
+2. Flushes the workqueue to wait for any currently executing handler to complete
+   (handlers cannot be interrupted mid-execution)
+3. Clears the CANCEL flag to allow the mailbox to accept new requests
+
+Queued requests that have not started execution will be aborted with an error
+status. The currently executing request will complete normally, and the controller
+will reject the response if it arrives after the abort sequence has been triggered.
+
+.. note::
+   Independent of when the ABORT bit is triggered, the controller driver must
+   clear the ERROR, BUSY, and READY bits in the DOE Status register after
+   completing the abort operation to reset the mailbox to an idle state.
+
+Error Handling
+--------------
+
+Errors can occur during DOE request processing for various reasons, such as
+unsupported protocols, handler failures, or memory allocation failures.
+
+**Error Detection**
+
+When an error occurs during DOE request processing, the DOE EP core propagates this error
+back to the controller driver through the ``pci_ep_doe_process_request()`` return value.
+
+**Error Response**
+
+When the controller driver receives an error code from
+``pci_ep_doe_process_request()``, it sets the ERROR bit in the DOE Status
+register instead of writing a response to the read mailbox register,
+and frees the buffers.
-- 
2.34.1




More information about the linux-arm-kernel mailing list