From 70eb620ed6d38e171e5619313e99d31688d25010 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com>
Date: Wed, 10 Oct 2018 16:07:50 +0300
Subject: [PATCH] crypto: caam/qi2 - add OPR (Order Preservation) support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

During driver upstreaming OPR was removed due to lacking users.
Add OPR back, since in LSDK / LSDK-based ADKs there is at least
one user (ASF / VortiQa IPsec).

Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
---
 drivers/crypto/caam/dpseci.c     | 85 ++++++++++++++++++++++++++++++++++++++++
 drivers/crypto/caam/dpseci.h     | 26 +++++++++++-
 drivers/crypto/caam/dpseci_cmd.h | 51 ++++++++++++++++++++++++
 3 files changed, 160 insertions(+), 2 deletions(-)

--- a/drivers/crypto/caam/dpseci.c
+++ b/drivers/crypto/caam/dpseci.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/fsl/mc.h>
+#include <soc/fsl/dpaa2-io.h>
 #include "dpseci.h"
 #include "dpseci_cmd.h"
 
@@ -675,6 +676,90 @@ int dpseci_get_api_version(struct fsl_mc
 
 	return 0;
 }
+
+/**
+ * dpseci_set_opr() - Set Order Restoration configuration
+ * @mc_io:	Pointer to MC portal's I/O object
+ * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:	Token of DPSECI object
+ * @index:	The queue index
+ * @options:	Configuration mode options; can be OPR_OPT_CREATE or
+ *		OPR_OPT_RETIRE
+ * @cfg:	Configuration options for the OPR
+ *
+ * Return:	'0' on success, error code otherwise
+ */
+int dpseci_set_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index,
+		   u8 options, struct opr_cfg *cfg)
+{
+	struct fsl_mc_command cmd = { 0 };
+	struct dpseci_cmd_opr *cmd_params;
+
+	cmd.header = mc_encode_cmd_header(
+			DPSECI_CMDID_SET_OPR,
+			cmd_flags,
+			token);
+	cmd_params = (struct dpseci_cmd_opr *)cmd.params;
+	cmd_params->index = index;
+	cmd_params->options = options;
+	cmd_params->oloe = cfg->oloe;
+	cmd_params->oeane = cfg->oeane;
+	cmd_params->olws = cfg->olws;
+	cmd_params->oa = cfg->oa;
+	cmd_params->oprrws = cfg->oprrws;
+
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpseci_get_opr() - Retrieve Order Restoration config and query
+ * @mc_io:	Pointer to MC portal's I/O object
+ * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:	Token of DPSECI object
+ * @index:	The queue index
+ * @cfg:	Returned OPR configuration
+ * @qry:	Returned OPR query
+ *
+ * Return:	'0' on success, error code otherwise
+ */
+int dpseci_get_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index,
+		   struct opr_cfg *cfg, struct opr_qry *qry)
+{
+	struct fsl_mc_command cmd = { 0 };
+	struct dpseci_cmd_opr *cmd_params;
+	struct dpseci_rsp_get_opr *rsp_params;
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_OPR,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpseci_cmd_opr *)cmd.params;
+	cmd_params->index = index;
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	rsp_params = (struct dpseci_rsp_get_opr *)cmd.params;
+	qry->rip = dpseci_get_field(rsp_params->flags, OPR_RIP);
+	qry->enable = dpseci_get_field(rsp_params->flags, OPR_ENABLE);
+	cfg->oloe = rsp_params->oloe;
+	cfg->oeane = rsp_params->oeane;
+	cfg->olws = rsp_params->olws;
+	cfg->oa = rsp_params->oa;
+	cfg->oprrws = rsp_params->oprrws;
+	qry->nesn = le16_to_cpu(rsp_params->nesn);
+	qry->ndsn = le16_to_cpu(rsp_params->ndsn);
+	qry->ea_tseq = le16_to_cpu(rsp_params->ea_tseq);
+	qry->tseq_nlis = dpseci_get_field(rsp_params->tseq_nlis, OPR_TSEQ_NLIS);
+	qry->ea_hseq = le16_to_cpu(rsp_params->ea_hseq);
+	qry->hseq_nlis = dpseci_get_field(rsp_params->hseq_nlis, OPR_HSEQ_NLIS);
+	qry->ea_hptr = le16_to_cpu(rsp_params->ea_hptr);
+	qry->ea_tptr = le16_to_cpu(rsp_params->ea_tptr);
+	qry->opr_vid = le16_to_cpu(rsp_params->opr_vid);
+	qry->opr_id = le16_to_cpu(rsp_params->opr_id);
+
+	return 0;
+}
 
 /**
  * dpseci_set_congestion_notification() - Set congestion group
--- a/drivers/crypto/caam/dpseci.h
+++ b/drivers/crypto/caam/dpseci.h
@@ -12,6 +12,8 @@
  */
 
 struct fsl_mc_io;
+struct opr_cfg;
+struct opr_qry;
 
 /**
  * General DPSECI macros
@@ -38,9 +40,21 @@ int dpseci_close(struct fsl_mc_io *mc_io
 #define DPSECI_OPT_HAS_CG		0x000020
 
 /**
+ * Enable the Order Restoration support
+ */
+#define DPSECI_OPT_HAS_OPR		0x000040
+
+/**
+ * Order Point Records are shared for the entire DPSECI
+ */
+#define DPSECI_OPT_OPR_SHARED		0x000080
+
+/**
  * struct dpseci_cfg - Structure representing DPSECI configuration
- * @options: Any combination of the following flags:
+ * @options: Any combination of the following options:
  *		DPSECI_OPT_HAS_CG
+ *		DPSECI_OPT_HAS_OPR
+ *		DPSECI_OPT_OPR_SHARED
  * @num_tx_queues: num of queues towards the SEC
  * @num_rx_queues: num of queues back from the SEC
  * @priorities: Priorities for the SEC hardware processing;
@@ -93,8 +107,10 @@ int dpseci_clear_irq_status(struct fsl_m
  * @id: DPSECI object ID
  * @num_tx_queues: number of queues towards the SEC
  * @num_rx_queues: number of queues back from the SEC
- * @options: any combination of the following flags:
+ * @options: any combination of the following options:
  *		DPSECI_OPT_HAS_CG
+ *		DPSECI_OPT_HAS_OPR
+ *		DPSECI_OPT_OPR_SHARED
  */
 struct dpseci_attr {
 	int id;
@@ -301,6 +317,12 @@ int dpseci_get_sec_counters(struct fsl_m
 int dpseci_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags,
 			   u16 *major_ver, u16 *minor_ver);
 
+int dpseci_set_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index,
+		   u8 options, struct opr_cfg *cfg);
+
+int dpseci_get_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index,
+		   struct opr_cfg *cfg, struct opr_qry *qry);
+
 /**
  * enum dpseci_congestion_unit - DPSECI congestion units
  * @DPSECI_CONGESTION_UNIT_BYTES: bytes units
--- a/drivers/crypto/caam/dpseci_cmd.h
+++ b/drivers/crypto/caam/dpseci_cmd.h
@@ -54,6 +54,8 @@
 #define DPSECI_CMDID_GET_TX_QUEUE			DPSECI_CMD_V1(0x197)
 #define DPSECI_CMDID_GET_SEC_ATTR			DPSECI_CMD_V2(0x198)
 #define DPSECI_CMDID_GET_SEC_COUNTERS			DPSECI_CMD_V1(0x199)
+#define DPSECI_CMDID_SET_OPR				DPSECI_CMD_V1(0x19A)
+#define DPSECI_CMDID_GET_OPR				DPSECI_CMD_V1(0x19B)
 #define DPSECI_CMDID_SET_CONGESTION_NOTIFICATION	DPSECI_CMD_V1(0x170)
 #define DPSECI_CMDID_GET_CONGESTION_NOTIFICATION	DPSECI_CMD_V1(0x171)
 
@@ -189,6 +191,55 @@ struct dpseci_rsp_get_api_version {
 	__le16 minor;
 };
 
+struct dpseci_cmd_opr {
+	__le16 pad;
+	u8 index;
+	u8 options;
+	u8 pad1[7];
+	u8 oloe;
+	u8 oeane;
+	u8 olws;
+	u8 oa;
+	u8 oprrws;
+};
+
+#define DPSECI_OPR_RIP_SHIFT		0
+#define DPSECI_OPR_RIP_SIZE		1
+#define DPSECI_OPR_ENABLE_SHIFT		1
+#define DPSECI_OPR_ENABLE_SIZE		1
+#define DPSECI_OPR_TSEQ_NLIS_SHIFT	0
+#define DPSECI_OPR_TSEQ_NLIS_SIZE	1
+#define DPSECI_OPR_HSEQ_NLIS_SHIFT	0
+#define DPSECI_OPR_HSEQ_NLIS_SIZE	1
+
+struct dpseci_rsp_get_opr {
+	__le64 pad;
+	u8 flags;
+	u8 pad0[2];
+	u8 oloe;
+	u8 oeane;
+	u8 olws;
+	u8 oa;
+	u8 oprrws;
+	__le16 nesn;
+	__le16 pad1;
+	__le16 ndsn;
+	__le16 pad2;
+	__le16 ea_tseq;
+	u8 tseq_nlis;
+	u8 pad3;
+	__le16 ea_hseq;
+	u8 hseq_nlis;
+	u8 pad4;
+	__le16 ea_hptr;
+	__le16 pad5;
+	__le16 ea_tptr;
+	__le16 pad6;
+	__le16 opr_vid;
+	__le16 pad7;
+	__le16 opr_id;
+};
+
 #define DPSECI_CGN_DEST_TYPE_SHIFT	0
 #define DPSECI_CGN_DEST_TYPE_SIZE	4
 #define DPSECI_CGN_UNITS_SHIFT		4
