drivers/crypto/bcm/cipher.c

Source file repositories/reference/linux-study-clean/drivers/crypto/bcm/cipher.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/bcm/cipher.c
Extension
.c
Size
131997 bytes
Lines
4712
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

while ((err == -ENOBUFS) && (retry_cnt < SPU_MB_RETRY_MAX)) {
			/*
			 * Mailbox queue is full. Since MAY_SLEEP is set, assume
			 * not in atomic context and we can wait and try again.
			 */
			retry_cnt++;
			usleep_range(MBOX_SLEEP_MIN, MBOX_SLEEP_MAX);
			err = mbox_send_message(iproc_priv.mbox[chan_idx],
						mssg);
			atomic_inc(&iproc_priv.mb_no_spc);
		}
	}
	if (err < 0) {
		atomic_inc(&iproc_priv.mb_send_fail);
		return err;
	}

	/* Check error returned by mailbox controller */
	err = mssg->error;
	if (unlikely(err < 0)) {
		dev_err(dev, "message error %d", err);
		/* Signal txdone for mailbox channel */
	}

	/* Signal txdone for mailbox channel */
	mbox_client_txdone(iproc_priv.mbox[chan_idx], err);
	return err;
}

/**
 * handle_skcipher_req() - Submit as much of a block cipher request as fits in
 * a single SPU request message, starting at the current position in the request
 * data.
 * @rctx:	Crypto request context
 *
 * This may be called on the crypto API thread, or, when a request is so large
 * it must be broken into multiple SPU messages, on the thread used to invoke
 * the response callback. When requests are broken into multiple SPU
 * messages, we assume subsequent messages depend on previous results, and
 * thus always wait for previous results before submitting the next message.
 * Because requests are submitted in lock step like this, there is no need
 * to synchronize access to request data structures.
 *
 * Return: -EINPROGRESS: request has been accepted and result will be returned
 *			 asynchronously
 *         Any other value indicates an error
 */
static int handle_skcipher_req(struct iproc_reqctx_s *rctx)
{
	struct spu_hw *spu = &iproc_priv.spu;
	struct crypto_async_request *areq = rctx->parent;
	struct skcipher_request *req =
	    container_of(areq, struct skcipher_request, base);
	struct iproc_ctx_s *ctx = rctx->ctx;
	struct spu_cipher_parms cipher_parms;
	int err;
	unsigned int chunksize;	/* Num bytes of request to submit */
	int remaining;	/* Bytes of request still to process */
	int chunk_start;	/* Beginning of data for current SPU msg */

	/* IV or ctr value to use in this SPU msg */
	u8 local_iv_ctr[MAX_IV_SIZE];
	u32 stat_pad_len;	/* num bytes to align status field */
	u32 pad_len;		/* total length of all padding */
	struct brcm_message *mssg;	/* mailbox message */

	/* number of entries in src and dst sg in mailbox message. */
	u8 rx_frag_num = 2;	/* response header and STATUS */
	u8 tx_frag_num = 1;	/* request header */

	flow_log("%s\n", __func__);

	cipher_parms.alg = ctx->cipher.alg;
	cipher_parms.mode = ctx->cipher.mode;
	cipher_parms.type = ctx->cipher_type;
	cipher_parms.key_len = ctx->enckeylen;
	cipher_parms.key_buf = ctx->enckey;
	cipher_parms.iv_buf = local_iv_ctr;
	cipher_parms.iv_len = rctx->iv_ctr_len;

	mssg = &rctx->mb_mssg;
	chunk_start = rctx->src_sent;
	remaining = rctx->total_todo - chunk_start;

	/* determine the chunk we are breaking off and update the indexes */
	if ((ctx->max_payload != SPU_MAX_PAYLOAD_INF) &&
	    (remaining > ctx->max_payload))
		chunksize = ctx->max_payload;
	else
		chunksize = remaining;

Annotation

Implementation Notes