[PATCH v3 2/4] PCI: endpoint: Add DOE mailbox support for endpoint functions
Aksh Garg
a-garg7 at ti.com
Thu May 14 22:35:29 PDT 2026
On 14/05/26 13:33, Manivannan Sadhasivam wrote:
> On Mon, Apr 27, 2026 at 10:47:23AM +0530, Aksh Garg wrote:
>> DOE (Data Object Exchange) is a standard PCIe extended capability
>> feature introduced in the Data Object Exchange (DOE) ECN for
>> PCIe r5.0. It provides a communication mechanism primarily used for
>> implementing PCIe security features such as device authentication, and
>> secure link establishment. 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.
>>
>> Add the DOE support for PCIe endpoint devices, enabling endpoint
>> functions to process the DOE requests from the host. The implementation
>> provides framework APIs for EPC core driver and controller drivers to
>> register mailboxes, and request processing with workqueues ensuring
>> sequential handling per mailbox, and parallel handling across mailboxes.
>> The Discovery protocol is handled internally by the DOE core.
>>
>> This implementation complements the existing DOE implementation for
>> root complex in drivers/pci/doe.c.
>>
>> 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>
>> ---
>> +
>> +/*
>> + * Global registry of protocol handlers.
>> + * When a new DOE protocol, library is added, add an entry to this array.
>> + */
>> +static const struct pci_doe_protocol pci_doe_protocols[] = {
>> + {
>> + .vid = PCI_VENDOR_ID_PCI_SIG,
>> + .type = PCI_DOE_FEATURE_DISCOVERY,
>> + .handler = pci_ep_doe_handle_discovery,
>> + },
>> +};
>> +
>> +/*
>> + * Combines function number and capability offset into a unique lookup key
>> + * for storing/retrieving DOE mailboxes in an xarray.
>> + */
>> +#define PCI_DOE_MB_KEY(func, offset) \
>> + (((unsigned long)(func) << 16) | (offset))
>> +#define PCI_DOE_PROTOCOL_COUNT ARRAY_SIZE(pci_doe_protocols)
>> +
>> +/**
>> + * pci_ep_doe_init() - Initialize the DOE framework for a controller in EP mode
>> + * @epc: PCI endpoint controller
>> + *
>> + * Initialize the DOE framework data structures. This only initializes
>> + * the xarray that will hold the mailboxes.
>> + *
>> + * RETURNS: 0 on success, -errno on failure
>
> kernel-doc format to describe return value is 'Return:' or 'Returns:".
Thanks for pointing this out. I will update this.
>
>> + */
>> +int pci_ep_doe_init(struct pci_epc *epc)
>> +{
>> + if (!epc)
>> + return -EINVAL;
>> +
>> + xa_init(&epc->doe_mbs);
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(pci_ep_doe_init);
>> +
[...]
>> +
>> +/**
>> + * pci_ep_doe_process_request() - Process DOE request on endpoint
>> + * @epc: PCI endpoint controller
>> + * @func_no: Physical function number
>> + * @cap_offset: DOE capability offset
>> + * @vendor: Vendor ID from request header
>> + * @type: Protocol type from request header
>> + * @request: Request payload in CPU-native format
>> + * @request_sz: Size of request payload (bytes)
>> + * @complete: Callback to invoke upon completion
>> + *
>> + * Asynchronously process a DOE request received on the endpoint. The request
>> + * payload should not include the DOE header (vendor/type/length). The protocol
>> + * handler will allocate the response buffer, which the caller (controller driver)
>> + * must free after use.
>> + *
>> + * This function returns immediately after queuing the request. The completion
>> + * callback will be invoked asynchronously from workqueue context once the
>> + * request is processed. The callback receives the function number and capability
>> + * offset to identify the mailbox, along with a status code (0 on success, -errno
>> + * on failure), and other required arguments.
>> + *
>> + * As per DOE specification, a mailbox processes one request at a time.
>> + * Therefore, this function will never be called concurrently for the same
>> + * mailbox by different callers.
>> + *
>> + * The caller is responsible for the conversion of the received DOE request
>> + * with le32_to_cpu() before calling this function.
>> + * Similarly, it is responsible for converting the response payload with
>> + * cpu_to_le32() before sending it back over the DOE mailbox.
>> + *
>> + * The caller is also responsible for ensuring that the request size
>> + * is within the limits defined by PCI_DOE_MAX_LENGTH.
>> + *
>> + * RETURNS: 0 if the request was successfully queued, -errno on failure
>> + */
>> +int pci_ep_doe_process_request(struct pci_epc *epc, u8 func_no, u16 cap_offset,
>> + u16 vendor, u8 type, const void *request, size_t request_sz,
>> + pci_ep_doe_complete_t complete)
>> +{
>> + struct pci_ep_doe_mb *doe_mb;
>> + struct pci_ep_doe_task *task;
>> + int rc;
>> +
>> + doe_mb = pci_ep_doe_get_mailbox(epc, func_no, cap_offset);
>> + if (!doe_mb) {
>> + kfree(request);
>> + return -ENODEV;
>> + }
>> +
>> + task = kzalloc_obj(*task, GFP_KERNEL);
>> + if (!task) {
>> + kfree(request);
>> + return -ENOMEM;
>> + }
>> +
>> + task->feat.vid = vendor;
>> + task->feat.type = type;
>> + task->request_pl = request;
>> + task->request_pl_sz = request_sz;
>> + task->response_pl = NULL;
>> + task->response_pl_sz = 0;
>> + task->complete = complete;
>> +
>> + rc = pci_ep_doe_submit_task(doe_mb, task);
>> + if (rc) {
>> + kfree(request);
>> + kfree(task);
>> + return rc;
>> + }
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(pci_ep_doe_process_request);
>
> So who is supposed to call this API? EPC driver that receives the DOE interrupt?
Yes, the EPC drivers that receive the DOE interrupts are expected to
call this API.
> But I don't see the any callers of this and below exported APIs in this series.
> Either you should add the callers or limit this series just to adding the DOE
> skeleton implementation with a clear follow-up.
I currently am working on the EPC driver implementation for a platform
which has not been up-streamed yet. I plan to use these APIs to support
the DOE feature for that driver. Currently, I am not aware of any
platform whose EPC driver supports DOE feature and its interrupts, hence
I see no real callers of these APIs to include in this patch series.
Would it be appropriate to add a dummy [NOT-FOR-MERGING] demonstration
patch over an existing EPC driver, showing how these DOE APIs would be
integrated into an EPC driver?
>
> But since you've limited the scope of this series to support only DOE Discovery
> Data Object Protocol, it'd be good to add the EPC implementation to get the full
> picture.>
> - Mani
>
More information about the linux-arm-kernel
mailing list