Commit 5a16448c authored by Gary R Hook's avatar Gary R Hook Committed by Greg Kroah-Hartman

crypto: ccp - Make some CCP DMA channels private

commit efc989fc upstream.

The CCP registers its queues as channels capable of handling
general DMA operations. The NTB driver will use DMA if
directed, but as public channels can be reserved for use in
asynchronous operations some channels should be held back
as private. Since the public/private determination is
handled at a device level, reserve the "other" (secondary)
CCP channels as private.

Add a module parameter that allows for override, to be
applied to all channels on all devices.
Signed-off-by: default avatarGary R Hook <gary.hook@amd.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 79105a2f
...@@ -1014,6 +1014,7 @@ const struct ccp_vdata ccpv5a = { ...@@ -1014,6 +1014,7 @@ const struct ccp_vdata ccpv5a = {
const struct ccp_vdata ccpv5b = { const struct ccp_vdata ccpv5b = {
.version = CCP_VERSION(5, 0), .version = CCP_VERSION(5, 0),
.dma_chan_attr = DMA_PRIVATE,
.setup = ccp5other_config, .setup = ccp5other_config,
.perform = &ccp5_actions, .perform = &ccp5_actions,
.bar = 2, .bar = 2,
......
...@@ -179,6 +179,10 @@ ...@@ -179,6 +179,10 @@
/* ------------------------ General CCP Defines ------------------------ */ /* ------------------------ General CCP Defines ------------------------ */
#define CCP_DMA_DFLT 0x0
#define CCP_DMA_PRIV 0x1
#define CCP_DMA_PUB 0x2
#define CCP_DMAPOOL_MAX_SIZE 64 #define CCP_DMAPOOL_MAX_SIZE 64
#define CCP_DMAPOOL_ALIGN BIT(5) #define CCP_DMAPOOL_ALIGN BIT(5)
...@@ -635,6 +639,7 @@ struct ccp_actions { ...@@ -635,6 +639,7 @@ struct ccp_actions {
/* Structure to hold CCP version-specific values */ /* Structure to hold CCP version-specific values */
struct ccp_vdata { struct ccp_vdata {
const unsigned int version; const unsigned int version;
const unsigned int dma_chan_attr;
void (*setup)(struct ccp_device *); void (*setup)(struct ccp_device *);
const struct ccp_actions *perform; const struct ccp_actions *perform;
const unsigned int bar; const unsigned int bar;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -25,6 +26,37 @@ ...@@ -25,6 +26,37 @@
(mask == 0) ? 64 : fls64(mask); \ (mask == 0) ? 64 : fls64(mask); \
}) })
/* The CCP as a DMA provider can be configured for public or private
* channels. Default is specified in the vdata for the device (PCI ID).
* This module parameter will override for all channels on all devices:
* dma_chan_attr = 0x2 to force all channels public
* = 0x1 to force all channels private
* = 0x0 to defer to the vdata setting
* = any other value: warning, revert to 0x0
*/
static unsigned int dma_chan_attr = CCP_DMA_DFLT;
module_param(dma_chan_attr, uint, 0444);
MODULE_PARM_DESC(dma_chan_attr, "Set DMA channel visibility: 0 (default) = device defaults, 1 = make private, 2 = make public");
unsigned int ccp_get_dma_chan_attr(struct ccp_device *ccp)
{
switch (dma_chan_attr) {
case CCP_DMA_DFLT:
return ccp->vdata->dma_chan_attr;
case CCP_DMA_PRIV:
return DMA_PRIVATE;
case CCP_DMA_PUB:
return 0;
default:
dev_info_once(ccp->dev, "Invalid value for dma_chan_attr: %d\n",
dma_chan_attr);
return ccp->vdata->dma_chan_attr;
}
}
static void ccp_free_cmd_resources(struct ccp_device *ccp, static void ccp_free_cmd_resources(struct ccp_device *ccp,
struct list_head *list) struct list_head *list)
{ {
...@@ -675,6 +707,15 @@ int ccp_dmaengine_register(struct ccp_device *ccp) ...@@ -675,6 +707,15 @@ int ccp_dmaengine_register(struct ccp_device *ccp)
dma_cap_set(DMA_SG, dma_dev->cap_mask); dma_cap_set(DMA_SG, dma_dev->cap_mask);
dma_cap_set(DMA_INTERRUPT, dma_dev->cap_mask); dma_cap_set(DMA_INTERRUPT, dma_dev->cap_mask);
/* The DMA channels for this device can be set to public or private,
* and overridden by the module parameter dma_chan_attr.
* Default: according to the value in vdata (dma_chan_attr=0)
* dma_chan_attr=0x1: all channels private (override vdata)
* dma_chan_attr=0x2: all channels public (override vdata)
*/
if (ccp_get_dma_chan_attr(ccp) == DMA_PRIVATE)
dma_cap_set(DMA_PRIVATE, dma_dev->cap_mask);
INIT_LIST_HEAD(&dma_dev->channels); INIT_LIST_HEAD(&dma_dev->channels);
for (i = 0; i < ccp->cmd_q_count; i++) { for (i = 0; i < ccp->cmd_q_count; i++) {
chan = ccp->ccp_dma_chan + i; chan = ccp->ccp_dma_chan + i;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment