[PATCH 4/4] crypto: ccp - Add abstraction for device-specific calls

2016-03-01 Thread Gary R Hook
Support for different generations of the coprocessor
requires that an abstraction layer be implemented for
interacting with the hardware. This patch splits out
version-specific functions to a separate file and populates
the version structure (acting as a driver) with function
pointers.

Signed-off-by: Gary R Hook 
---
 drivers/crypto/ccp/Makefile   |2 
 drivers/crypto/ccp/ccp-dev-v3.c   |  534 +
 drivers/crypto/ccp/ccp-dev.c  |  306 +
 drivers/crypto/ccp/ccp-dev.h  |  138 +-
 drivers/crypto/ccp/ccp-ops.c  |  381 +-
 drivers/crypto/ccp/ccp-pci.c  |   10 -
 drivers/crypto/ccp/ccp-platform.c |7 
 7 files changed, 711 insertions(+), 667 deletions(-)
 create mode 100644 drivers/crypto/ccp/ccp-dev-v3.c

diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 55a1f39..b750592 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -1,5 +1,5 @@
 obj-$(CONFIG_CRYPTO_DEV_CCP_DD) += ccp.o
-ccp-objs := ccp-dev.o ccp-ops.o ccp-platform.o
+ccp-objs := ccp-dev.o ccp-ops.o ccp-dev-v3.o ccp-platform.o
 ccp-$(CONFIG_PCI) += ccp-pci.o
 
 obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o
diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c
new file mode 100644
index 000..4f81c9f
--- /dev/null
+++ b/drivers/crypto/ccp/ccp-dev-v3.c
@@ -0,0 +1,534 @@
+/*
+ * AMD Cryptographic Coprocessor (CCP) driver
+ *
+ * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
+ *
+ * Author: Tom Lendacky 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ccp-dev.h"
+
+static int ccp_do_cmd(struct ccp_op *op, u32 *cr, unsigned int cr_count)
+{
+   struct ccp_cmd_queue *cmd_q = op->cmd_q;
+   struct ccp_device *ccp = cmd_q->ccp;
+   void __iomem *cr_addr;
+   u32 cr0, cmd;
+   unsigned int i;
+   int ret = 0;
+
+   /* We could read a status register to see how many free slots
+* are actually available, but reading that register resets it
+* and you could lose some error information.
+*/
+   cmd_q->free_slots--;
+
+   cr0 = (cmd_q->id << REQ0_CMD_Q_SHIFT)
+ | (op->jobid << REQ0_JOBID_SHIFT)
+ | REQ0_WAIT_FOR_WRITE;
+
+   if (op->soc)
+   cr0 |= REQ0_STOP_ON_COMPLETE
+  | REQ0_INT_ON_COMPLETE;
+
+   if (op->ioc || !cmd_q->free_slots)
+   cr0 |= REQ0_INT_ON_COMPLETE;
+
+   /* Start at CMD_REQ1 */
+   cr_addr = ccp->io_regs + CMD_REQ0 + CMD_REQ_INCR;
+
+   mutex_lock(&ccp->req_mutex);
+
+   /* Write CMD_REQ1 through CMD_REQx first */
+   for (i = 0; i < cr_count; i++, cr_addr += CMD_REQ_INCR)
+   iowrite32(*(cr + i), cr_addr);
+
+   /* Tell the CCP to start */
+   wmb();
+   iowrite32(cr0, ccp->io_regs + CMD_REQ0);
+
+   mutex_unlock(&ccp->req_mutex);
+
+   if (cr0 & REQ0_INT_ON_COMPLETE) {
+   /* Wait for the job to complete */
+   ret = wait_event_interruptible(cmd_q->int_queue,
+  cmd_q->int_rcvd);
+   if (ret || cmd_q->cmd_error) {
+   /* On error delete all related jobs from the queue */
+   cmd = (cmd_q->id << DEL_Q_ID_SHIFT)
+ | op->jobid;
+
+   iowrite32(cmd, ccp->io_regs + DEL_CMD_Q_JOB);
+
+   if (!ret)
+   ret = -EIO;
+   } else if (op->soc) {
+   /* Delete just head job from the queue on SoC */
+   cmd = DEL_Q_ACTIVE
+ | (cmd_q->id << DEL_Q_ID_SHIFT)
+ | op->jobid;
+
+   iowrite32(cmd, ccp->io_regs + DEL_CMD_Q_JOB);
+   }
+
+   cmd_q->free_slots = CMD_Q_DEPTH(cmd_q->q_status);
+
+   cmd_q->int_rcvd = 0;
+   }
+
+   return ret;
+}
+
+static int ccp_perform_aes(struct ccp_op *op)
+{
+   u32 cr[6];
+
+   /* Fill out the register contents for REQ1 through REQ6 */
+   cr[0] = (CCP_ENGINE_AES << REQ1_ENGINE_SHIFT)
+   | (op->u.aes.type << REQ1_AES_TYPE_SHIFT)
+   | (op->u.aes.mode << REQ1_AES_MODE_SHIFT)
+   | (op->u.aes.action << REQ1_AES_ACTION_SHIFT)
+   | (op->ksb_key << REQ1_KEY_KSB_SHIFT);
+   cr[1] = op->src.u.dma.length - 1;
+   cr[2] = ccp_addr_lo(&op->src.u.dma);
+   cr[3] = (op->ksb_ctx << REQ4_KSB_SHIFT)
+   | (CCP_MEMTYPE_SYSTEM << REQ4_MEMTYPE_SHIFT)
+   | ccp_addr_hi(&op->src.u.dma);
+   cr[4] = ccp_addr_lo(&op->dst.u.dma);
+   cr[5] = (CCP_MEMTYPE_S

Re: [PATCH 4/4] crypto: ccp - Add abstraction for device-specific calls

2016-03-03 Thread Tom Lendacky
On 03/01/2016 01:49 PM, Gary R Hook wrote:
> Support for different generations of the coprocessor
> requires that an abstraction layer be implemented for
> interacting with the hardware. This patch splits out
> version-specific functions to a separate file and populates
> the version structure (acting as a driver) with function
> pointers.
> 
> Signed-off-by: Gary R Hook 

Acked-by: Tom Lendacky 

> ---
>  drivers/crypto/ccp/Makefile   |2 
>  drivers/crypto/ccp/ccp-dev-v3.c   |  534 
> +
>  drivers/crypto/ccp/ccp-dev.c  |  306 +
>  drivers/crypto/ccp/ccp-dev.h  |  138 +-
>  drivers/crypto/ccp/ccp-ops.c  |  381 +-
>  drivers/crypto/ccp/ccp-pci.c  |   10 -
>  drivers/crypto/ccp/ccp-platform.c |7 
>  7 files changed, 711 insertions(+), 667 deletions(-)
>  create mode 100644 drivers/crypto/ccp/ccp-dev-v3.c
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html