linux/drivers/crypto/ccp/ccp-dev.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * AMD Cryptographic Coprocessor (CCP) driver
 *
 * Copyright (C) 2013,2019 Advanced Micro Devices, Inc.
 *
 * Author: Tom Lendacky <[email protected]>
 * Author: Gary R Hook <[email protected]>
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/spinlock_types.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/hw_random.h>
#include <linux/cpu.h>
#include <linux/atomic.h>
#ifdef CONFIG_X86
#include <asm/cpu_device_id.h>
#endif
#include <linux/ccp.h>

#include "ccp-dev.h"

#define MAX_CCPS

/* Limit CCP use to a specifed number of queues per device */
static unsigned int nqueues;
module_param(nqueues, uint, 0444);
MODULE_PARM_DESC();

/* Limit the maximum number of configured CCPs */
static atomic_t dev_count =;
static unsigned int max_devs =;
module_param(max_devs, uint, 0444);
MODULE_PARM_DESC();

struct ccp_tasklet_data {};

/* Human-readable error strings */
#define CCP_MAX_ERROR_CODE
static char *ccp_error_codes[] =;

void ccp_log_error(struct ccp_device *d, unsigned int e)
{}

/* List of CCPs, CCP count, read-write access lock, and access functions
 *
 * Lock structure: get ccp_unit_lock for reading whenever we need to
 * examine the CCP list. While holding it for reading we can acquire
 * the RR lock to update the round-robin next-CCP pointer. The unit lock
 * must be acquired before the RR lock.
 *
 * If the unit-lock is acquired for writing, we have total control over
 * the list, so there's no value in getting the RR lock.
 */
static DEFINE_RWLOCK(ccp_unit_lock);
static LIST_HEAD(ccp_units);

/* Round-robin counter */
static DEFINE_SPINLOCK(ccp_rr_lock);
static struct ccp_device *ccp_rr;

/**
 * ccp_add_device - add a CCP device to the list
 *
 * @ccp: ccp_device struct pointer
 *
 * Put this CCP on the unit list, which makes it available
 * for use.
 *
 * Returns zero if a CCP device is present, -ENODEV otherwise.
 */
void ccp_add_device(struct ccp_device *ccp)
{}

/**
 * ccp_del_device - remove a CCP device from the list
 *
 * @ccp: ccp_device struct pointer
 *
 * Remove this unit from the list of devices. If the next device
 * up for use is this one, adjust the pointer. If this is the last
 * device, NULL the pointer.
 */
void ccp_del_device(struct ccp_device *ccp)
{}



int ccp_register_rng(struct ccp_device *ccp)
{}

void ccp_unregister_rng(struct ccp_device *ccp)
{}

static struct ccp_device *ccp_get_device(void)
{}

/**
 * ccp_present - check if a CCP device is present
 *
 * Returns zero if a CCP device is present, -ENODEV otherwise.
 */
int ccp_present(void)
{}
EXPORT_SYMBOL_GPL();

/**
 * ccp_version - get the version of the CCP device
 *
 * Returns the version from the first unit on the list;
 * otherwise a zero if no CCP device is present
 */
unsigned int ccp_version(void)
{}
EXPORT_SYMBOL_GPL();

/**
 * ccp_enqueue_cmd - queue an operation for processing by the CCP
 *
 * @cmd: ccp_cmd struct to be processed
 *
 * Queue a cmd to be processed by the CCP. If queueing the cmd
 * would exceed the defined length of the cmd queue the cmd will
 * only be queued if the CCP_CMD_MAY_BACKLOG flag is set and will
 * result in a return code of -EBUSY.
 *
 * The callback routine specified in the ccp_cmd struct will be
 * called to notify the caller of completion (if the cmd was not
 * backlogged) or advancement out of the backlog. If the cmd has
 * advanced out of the backlog the "err" value of the callback
 * will be -EINPROGRESS. Any other "err" value during callback is
 * the result of the operation.
 *
 * The cmd has been successfully queued if:
 *   the return code is -EINPROGRESS or
 *   the return code is -EBUSY and CCP_CMD_MAY_BACKLOG flag is set
 */
int ccp_enqueue_cmd(struct ccp_cmd *cmd)
{}
EXPORT_SYMBOL_GPL();

static void ccp_do_cmd_backlog(struct work_struct *work)
{}

static struct ccp_cmd *ccp_dequeue_cmd(struct ccp_cmd_queue *cmd_q)
{}

static void ccp_do_cmd_complete(unsigned long data)
{}

/**
 * ccp_cmd_queue_thread - create a kernel thread to manage a CCP queue
 *
 * @data: thread-specific data
 */
int ccp_cmd_queue_thread(void *data)
{}

/**
 * ccp_alloc_struct - allocate and initialize the ccp_device struct
 *
 * @sp: sp_device struct of the CCP
 */
struct ccp_device *ccp_alloc_struct(struct sp_device *sp)
{}

int ccp_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{}

bool ccp_queues_suspended(struct ccp_device *ccp)
{}

void ccp_dev_suspend(struct sp_device *sp)
{}

void ccp_dev_resume(struct sp_device *sp)
{}

int ccp_dev_init(struct sp_device *sp)
{}

void ccp_dev_destroy(struct sp_device *sp)
{}