Linux kernel and device drivers for NXP i.MX platforms
 help / color / mirror / Atom feed
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
>
>

  reply	other threads:[~2026-07-23 18:34 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox