From: Frank Li <Frank.li@oss.nxp.com>
To: Frieder Schrempf <frieder@fris.de>
Cc: Srinivas Kandagatla <srini@kernel.org>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>, Frank Li <Frank.Li@nxp.com>,
Sascha Hauer <s.hauer@pengutronix.de>,
Pengutronix Kernel Team <kernel@pengutronix.de>,
Fabio Estevam <festevam@gmail.com>,
Shawn Guo <shawnguo@kernel.org>,
Pankaj Gupta <pankaj.gupta@nxp.com>,
"Peng Fan (OSS)" <peng.fan@oss.nxp.com>,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux@ew.tq-group.com,
Frieder Schrempf <frieder.schrempf@kontron.de>
Subject: Re: [PATCH v3 03/11] firmware: imx: ele: Export API functions
Date: Thu, 23 Jul 2026 13:34:43 -0500 [thread overview]
Message-ID: <amJew0ynuWRybpJm@SMW015318> (raw)
In-Reply-To: <20260723-upstreaming-next-20260609-imx-ocotp-ele-v3-3-e26930345b4c@kontron.de>
On Thu, Jul 23, 2026 at 09:27:25AM +0200, Frieder Schrempf wrote:
> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>
> Export generic ELE API functions to send and receive messages. This
> allows drivers to implement functions based on the ELE API.
>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/firmware/imx/ele_base_msg.c | 42 ++++++++++----------
> drivers/firmware/imx/ele_common.c | 35 ++++++++++++++++-
> drivers/firmware/imx/ele_common.h | 14 -------
> drivers/firmware/imx/se_ctrl.c | 6 +--
> drivers/firmware/imx/se_ctrl.h | 14 +------
> include/linux/firmware/imx/se_api.h | 78 +++++++++++++++++++++++++++++++++++++
> 6 files changed, 137 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
> index 28b835f2880f..a4ab45efdd63 100644
> --- a/drivers/firmware/imx/ele_base_msg.c
> +++ b/drivers/firmware/imx/ele_base_msg.c
> @@ -8,6 +8,7 @@
> #include <linux/cleanup.h>
> #include <linux/completion.h>
> #include <linux/dma-mapping.h>
> +#include <linux/firmware/imx/se_api.h>
> #include <linux/genalloc.h>
>
> #include "ele_base_msg.h"
> @@ -106,8 +107,8 @@ int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info)
> }
> }
>
> - se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
> - ELE_GET_INFO_REQ, ELE_GET_INFO_REQ_MSG_SZ, true);
> + imx_se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
> + ELE_GET_INFO_REQ, ELE_GET_INFO_REQ_MSG_SZ, true);
>
> tx_msg->data[0] = upper_32_bits(get_info_addr);
> tx_msg->data[1] = lower_32_bits(get_info_addr);
> @@ -120,8 +121,8 @@ int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info)
> return ret;
> }
>
> - ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_GET_INFO_REQ,
> - ELE_GET_INFO_RSP_MSG_SZ, true);
> + ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_GET_INFO_REQ,
> + ELE_GET_INFO_RSP_MSG_SZ, true);
> if (ret < 0) {
> ele_get_info_cleanup(priv, get_info_data, get_info_addr, get_info_len);
> return ret;
> @@ -156,16 +157,16 @@ int ele_ping(struct se_if_priv *priv)
> if (!rx_msg)
> return -ENOMEM;
>
> - se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
> - ELE_PING_REQ, ELE_PING_REQ_SZ, true);
> + imx_se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
> + ELE_PING_REQ, ELE_PING_REQ_SZ, true);
>
> ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_PING_REQ_SZ,
> rx_msg, ELE_PING_RSP_SZ);
> if (ret < 0)
> return ret;
>
> - ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_PING_REQ,
> - ELE_PING_RSP_SZ, true);
> + ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_PING_REQ,
> + ELE_PING_RSP_SZ, true);
>
> return ret;
> }
> @@ -196,8 +197,9 @@ int ele_service_swap(struct se_if_priv *priv,
> if (!rx_msg)
> return -ENOMEM;
>
> - se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
> - ELE_SERVICE_SWAP_REQ, ELE_SERVICE_SWAP_REQ_MSG_SZ, true);
> + imx_se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
> + ELE_SERVICE_SWAP_REQ, ELE_SERVICE_SWAP_REQ_MSG_SZ,
> + true);
>
> tx_msg->data[0] = flag;
> tx_msg->data[1] = addr_size;
> @@ -212,8 +214,8 @@ int ele_service_swap(struct se_if_priv *priv,
> if (ret < 0)
> return ret;
>
> - ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_SERVICE_SWAP_REQ,
> - ELE_SERVICE_SWAP_RSP_MSG_SZ, true);
> + ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_SERVICE_SWAP_REQ,
> + ELE_SERVICE_SWAP_RSP_MSG_SZ, true);
> if (ret)
> return ret;
>
> @@ -248,8 +250,8 @@ int ele_fw_authenticate(struct se_if_priv *priv, dma_addr_t contnr_addr,
> if (!rx_msg)
> return -ENOMEM;
>
> - se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
> - ELE_FW_AUTH_REQ, ELE_FW_AUTH_REQ_SZ, true);
> + imx_se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
> + ELE_FW_AUTH_REQ, ELE_FW_AUTH_REQ_SZ, true);
>
> tx_msg->data[0] = lower_32_bits(contnr_addr);
> tx_msg->data[1] = 0;
> @@ -260,8 +262,8 @@ int ele_fw_authenticate(struct se_if_priv *priv, dma_addr_t contnr_addr,
> if (ret < 0)
> return ret;
>
> - ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_FW_AUTH_REQ,
> - ELE_FW_AUTH_RSP_MSG_SZ, true);
> + ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_FW_AUTH_REQ,
> + ELE_FW_AUTH_RSP_MSG_SZ, true);
>
> return ret;
> }
> @@ -286,8 +288,8 @@ int ele_debug_dump(struct se_if_priv *priv)
> if (!rx_msg)
> return -ENOMEM;
>
> - se_fill_cmd_msg_hdr(priv, &tx_msg->header, ELE_DEBUG_DUMP_REQ,
> - ELE_DEBUG_DUMP_REQ_SZ, true);
> + imx_se_fill_cmd_msg_hdr(priv, &tx_msg->header, ELE_DEBUG_DUMP_REQ,
> + ELE_DEBUG_DUMP_REQ_SZ, true);
>
> msg_ex_cnt = 0;
> do {
> @@ -298,8 +300,8 @@ int ele_debug_dump(struct se_if_priv *priv)
> if (ret < 0)
> return ret;
>
> - ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_DEBUG_DUMP_REQ,
> - ELE_DEBUG_DUMP_RSP_SZ, true);
> + ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_DEBUG_DUMP_REQ,
> + ELE_DEBUG_DUMP_RSP_SZ, true);
> if (ret) {
> dev_err(priv->dev, "Dump_Debug_Buffer Error: %x.", ret);
> break;
> diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
> index fbb6e584341a..f9c56fd42af0 100644
> --- a/drivers/firmware/imx/ele_common.c
> +++ b/drivers/firmware/imx/ele_common.c
> @@ -3,11 +3,26 @@
> * Copyright 2025 NXP
> */
>
> +#include <linux/export.h>
> +
> #include "ele_base_msg.h"
> #include "ele_common.h"
> #include "ele_fw_api.h"
> #include "se_ctrl.h"
>
> +/* Fill a command message header with a given command ID and length in bytes. */
> +int imx_se_fill_cmd_msg_hdr(struct se_if_priv *priv, struct se_msg_hdr *hdr,
> + u8 cmd, u32 len, bool is_base_api)
> +{
> + hdr->tag = priv->if_defs->cmd_tag;
> + hdr->ver = (is_base_api) ? priv->if_defs->base_api_ver : priv->if_defs->fw_api_ver;
> + hdr->command = cmd;
> + hdr->size = len >> 2;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(imx_se_fill_cmd_msg_hdr);
> +
> int se_chk_tx_msg_hdr(struct se_if_device_ctx *dev_ctx, struct se_msg_hdr *header)
> {
> struct se_if_priv *priv = dev_ctx->priv;
> @@ -261,6 +276,21 @@ int ele_msg_send_rcv(struct se_if_device_ctx *dev_ctx, void *tx_msg,
> return err;
> }
>
> +/*
> + * Send/receive blocking call for external drivers, operating on the SE
> + * interface private data (the misc device context is resolved internally).
> + */
> +int imx_se_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz,
> + void *rx_msg, int exp_rx_msg_sz)
> +{
> + if (!priv)
> + return -EINVAL;
> +
> + return ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, tx_msg_sz,
> + rx_msg, exp_rx_msg_sz);
> +}
> +EXPORT_SYMBOL_GPL(imx_se_msg_send_rcv);
> +
> static bool check_hdr_exception_for_sz(struct se_if_priv *priv,
> struct se_msg_hdr *header)
> {
> @@ -402,8 +432,8 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
> }
> }
>
> -int se_val_rsp_hdr_n_status(struct se_if_priv *priv, struct se_api_msg *msg,
> - u8 msg_id, u8 sz, bool is_base_api)
> +int imx_se_val_rsp_hdr_n_status(struct se_if_priv *priv, struct se_api_msg *msg,
> + u8 msg_id, u8 sz, bool is_base_api)
> {
> struct se_msg_hdr *header = &msg->header;
> u32 status;
> @@ -450,6 +480,7 @@ int se_val_rsp_hdr_n_status(struct se_if_priv *priv, struct se_api_msg *msg,
>
> return 0;
> }
> +EXPORT_SYMBOL_GPL(imx_se_val_rsp_hdr_n_status);
>
> int se_save_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem)
> {
> diff --git a/drivers/firmware/imx/ele_common.h b/drivers/firmware/imx/ele_common.h
> index b63a3fbf087a..8f0739960d4d 100644
> --- a/drivers/firmware/imx/ele_common.h
> +++ b/drivers/firmware/imx/ele_common.h
> @@ -28,20 +28,6 @@ int ele_msg_send_rcv(struct se_if_device_ctx *dev_ctx, void *tx_msg,
> int tx_msg_sz, void *rx_msg, int exp_rx_msg_sz);
>
> void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg);
> -
> -int se_val_rsp_hdr_n_status(struct se_if_priv *priv, struct se_api_msg *msg,
> - u8 msg_id, u8 sz, bool is_base_api);
> -
> -/* Fill a command message header with a given command ID and length in bytes. */
> -static inline void se_fill_cmd_msg_hdr(struct se_if_priv *priv, struct se_msg_hdr *hdr,
> - u8 cmd, u32 len, bool is_base_api)
> -{
> - hdr->tag = priv->if_defs->cmd_tag;
> - hdr->ver = (is_base_api) ? priv->if_defs->base_api_ver : priv->if_defs->fw_api_ver;
> - hdr->command = cmd;
> - hdr->size = len >> 2;
> -}
> -
> int se_save_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem);
>
> int se_restore_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem);
> diff --git a/drivers/firmware/imx/se_ctrl.c b/drivers/firmware/imx/se_ctrl.c
> index 3c14964830a6..53f252d2f111 100644
> --- a/drivers/firmware/imx/se_ctrl.c
> +++ b/drivers/firmware/imx/se_ctrl.c
> @@ -911,9 +911,9 @@ static int se_ioctl_cmd_snd_rcv_rsp_handler(struct se_if_device_ctx *dev_ctx,
> "message received, start transmit to user");
>
> rsp_status_err =
> - se_val_rsp_hdr_n_status(priv, rx_msg, tx_msg->header.command,
> - cmd_snd_rcv_rsp_info.rx_buf_sz,
> - tx_msg->header.ver == priv->if_defs->base_api_ver);
> + imx_se_val_rsp_hdr_n_status(priv, rx_msg, tx_msg->header.command,
> + cmd_snd_rcv_rsp_info.rx_buf_sz,
> + tx_msg->header.ver == priv->if_defs->base_api_ver);
>
> if (!rsp_status_err) {
> err = se_dev_ctx_cpy_out_data(dev_ctx);
> diff --git a/drivers/firmware/imx/se_ctrl.h b/drivers/firmware/imx/se_ctrl.h
> index af7738ad76cd..76082e8b977c 100644
> --- a/drivers/firmware/imx/se_ctrl.h
> +++ b/drivers/firmware/imx/se_ctrl.h
> @@ -7,6 +7,7 @@
> #define SE_CTRL_H
>
> #include <linux/bitfield.h>
> +#include <linux/firmware/imx/se_api.h>
> #include <linux/miscdevice.h>
> #include <linux/mailbox_client.h>
> #include <linux/semaphore.h>
> @@ -95,22 +96,9 @@ struct se_if_device_ctx {
> struct kref refcount;
> };
>
> -/* Header of the messages exchange with the EdgeLock Enclave */
> -struct se_msg_hdr {
> - u8 ver;
> - u8 size;
> - u8 command;
> - u8 tag;
> -} __packed;
> -
> #define SE_MU_HDR_SZ 4
> #define SE_MU_HDR_WORD_SZ 1
>
> -struct se_api_msg {
> - struct se_msg_hdr header;
> - u32 data[];
> -};
> -
> struct se_if_defines {
> const u8 se_if_type;
> u8 cmd_tag;
> diff --git a/include/linux/firmware/imx/se_api.h b/include/linux/firmware/imx/se_api.h
> index b1c4c9115d7b..90104ecaaede 100644
> --- a/include/linux/firmware/imx/se_api.h
> +++ b/include/linux/firmware/imx/se_api.h
> @@ -11,4 +11,82 @@
> #define SOC_ID_OF_IMX8ULP 0x084d
> #define SOC_ID_OF_IMX93 0x9300
>
> +/**
> + * struct se_msg_hdr - Header of the messages exchanged with the secure enclave.
> + * @ver: API version the message conforms to (base or firmware API version).
> + * @size: Message size in 32-bit words, including the header.
> + * @command: Command identifier.
> + * @tag: Message tag identifying it as a command or a response.
> + */
> +struct se_msg_hdr {
> + u8 ver;
> + u8 size;
> + u8 command;
> + u8 tag;
> +} __packed;
> +
> +/**
> + * struct se_api_msg - A message exchanged with the secure enclave.
> + * @header: Message header describing the command and its length.
> + * @data: Command or response payload, sized per @header.size.
> + */
> +struct se_api_msg {
> + struct se_msg_hdr header;
> + u32 data[];
> +};
> +
> +/* Opaque handle to a secure-enclave interface instance. */
> +struct se_if_priv;
> +
> +/**
> + * imx_se_fill_cmd_msg_hdr() - Populate the header of a command message.
> + * @priv: Secure-enclave interface instance the command targets.
> + * @hdr: Message header to be filled in.
> + * @cmd: Command identifier to place in the header.
> + * @len: Total message length in bytes, including the header.
> + * @is_base_api: %true to tag the message with the base API version, %false to
> + * use the firmware API version.
> + *
> + * Fill in the tag, version, command and size fields of @hdr so that the message
> + * can be sent to the secure enclave.
> + *
> + * Return: 0 on success.
> + */
> +int imx_se_fill_cmd_msg_hdr(struct se_if_priv *priv, struct se_msg_hdr *hdr,
> + u8 cmd, u32 len, bool is_base_api);
> +
> +/**
> + * imx_se_msg_send_rcv() - Send a command to the secure enclave and wait for the
> + * response.
> + * @priv: Secure-enclave interface instance to communicate with.
> + * @tx_msg: Buffer holding the command message to send.
> + * @tx_msg_sz: Size of the command message in bytes.
> + * @rx_msg: Buffer receiving the response message.
> + * @exp_rx_msg_sz: Expected size of the response message in bytes.
> + *
> + * Blocking send/receive helper for external drivers. The transaction is
> + * serialized internally and the misc device context is resolved from @priv.
> + *
> + * Return: number of bytes received on success, or a negative error code.
> + */
> +int imx_se_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz,
> + void *rx_msg, int exp_rx_msg_sz);
> +
> +/**
> + * imx_se_val_rsp_hdr_n_status() - Validate a response header and status code.
> + * @priv: Secure-enclave interface instance the response came from.
> + * @msg: Response message to validate.
> + * @msg_id: Command identifier the response is expected to match.
> + * @sz: Expected response size in bytes.
> + * @is_base_api: %true if the command used the base API version, %false if it
> + * used the firmware API version.
> + *
> + * Check that the response tag, command identifier, size and API version match
> + * the expectations, and that the enclave reported a successful status.
> + *
> + * Return: 0 if the response is valid and successful, or a negative error code.
> + */
> +int imx_se_val_rsp_hdr_n_status(struct se_if_priv *priv, struct se_api_msg *msg,
> + u8 msg_id, u8 sz, bool is_base_api);
> +
> #endif /* __SE_API_H__ */
>
> --
> 2.55.0
>
>
next prev parent reply other threads:[~2026-07-23 18:35 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-23 7:27 [PATCH v3 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
2026-07-23 7:27 ` [PATCH v3 01/11] dt-bindings: nvmem: imx-ocotp: Add support for secure-enclave Frieder Schrempf
2026-07-24 6:26 ` Krzysztof Kozlowski
2026-07-23 7:27 ` [PATCH v3 02/11] firmware: imx: ele: Fix indentation in ele_base_msg.h Frieder Schrempf
2026-07-23 7:27 ` [PATCH v3 03/11] firmware: imx: ele: Export API functions Frieder Schrempf
2026-07-23 18:34 ` Frank Li [this message]
2026-07-23 7:27 ` [PATCH v3 04/11] nvmem: imx-ocotp-ele: Add keepout table for i.MX93 Frieder Schrempf
2026-07-23 7:27 ` [PATCH v3 05/11] nvmem: imx-ocotp-ele: Remove device-specific reg_read() Frieder Schrempf
2026-07-23 18:38 ` Frank Li
2026-07-23 7:27 ` [PATCH v3 06/11] nvmem: imx-ocotp-ele: Use __free(kfree) in imx_ocotp_reg_read() Frieder Schrempf
2026-07-23 18:42 ` Frank Li
2026-07-23 7:27 ` [PATCH v3 07/11] nvmem: imx-ocotp-ele: Support the ELE API Frieder Schrempf
2026-07-23 18:48 ` Frank Li
2026-07-23 7:27 ` [PATCH v3 08/11] nvmem: imx-ocotp-ele: Remove the FUSE_ELE type Frieder Schrempf
2026-07-23 7:27 ` [PATCH v3 09/11] nvmem: imx-ocotp-ele: Rename FSB access map Frieder Schrempf
2026-07-23 7:27 ` [PATCH v3 10/11] arm64: dts: Add common include for i.MX93 ELE firmware Frieder Schrempf
2026-07-23 7:27 ` [PATCH v3 11/11] arm64: dts: Enable EdgeLock Secure Enclave on all i.MX91/i.MX93 boards Frieder Schrempf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=amJew0ynuWRybpJm@SMW015318 \
--to=frank.li@oss.nxp.com \
--cc=Frank.Li@nxp.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=festevam@gmail.com \
--cc=frieder.schrempf@kontron.de \
--cc=frieder@fris.de \
--cc=imx@lists.linux.dev \
--cc=kernel@pengutronix.de \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@ew.tq-group.com \
--cc=pankaj.gupta@nxp.com \
--cc=peng.fan@oss.nxp.com \
--cc=robh@kernel.org \
--cc=s.hauer@pengutronix.de \
--cc=shawnguo@kernel.org \
--cc=srini@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.