drivers/crypto/hisilicon/sec2/sec_crypto.c

Source file repositories/reference/linux-study-clean/drivers/crypto/hisilicon/sec2/sec_crypto.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/hisilicon/sec2/sec_crypto.c
Extension
.c
Size
72835 bytes
Lines
2782
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

struct sec_skcipher {
	u64 alg_msk;
	struct skcipher_alg alg;
};

struct sec_aead {
	u64 alg_msk;
	struct aead_alg alg;
};

static int sec_aead_soft_crypto(struct sec_ctx *ctx,
				struct aead_request *aead_req,
				bool encrypt);
static int sec_skcipher_soft_crypto(struct sec_ctx *ctx,
				    struct skcipher_request *sreq, bool encrypt);

static int sec_alloc_req_id(struct sec_req *req, struct sec_qp_ctx *qp_ctx)
{
	int req_id;

	spin_lock_bh(&qp_ctx->id_lock);
	req_id = idr_alloc_cyclic(&qp_ctx->req_idr, NULL, 0, qp_ctx->qp->sq_depth, GFP_ATOMIC);
	spin_unlock_bh(&qp_ctx->id_lock);
	return req_id;
}

static void sec_free_req_id(struct sec_req *req)
{
	struct sec_qp_ctx *qp_ctx = req->qp_ctx;
	int req_id = req->req_id;

	if (unlikely(req_id < 0 || req_id >= qp_ctx->qp->sq_depth)) {
		dev_err(req->ctx->dev, "free request id invalid!\n");
		return;
	}

	spin_lock_bh(&qp_ctx->id_lock);
	idr_remove(&qp_ctx->req_idr, req_id);
	spin_unlock_bh(&qp_ctx->id_lock);
}

static void pre_parse_finished_bd(struct bd_status *status, void *resp)
{
	struct sec_sqe *bd = resp;

	status->done = le16_to_cpu(bd->type2.done_flag) & SEC_DONE_MASK;
	status->icv = (le16_to_cpu(bd->type2.done_flag) & SEC_ICV_MASK) >> 1;
	status->flag = (le16_to_cpu(bd->type2.done_flag) &
					SEC_FLAG_MASK) >> SEC_FLAG_OFFSET;
	status->tag = le16_to_cpu(bd->type2.tag);
	status->err_type = bd->type2.error_type;
}

static void pre_parse_finished_bd3(struct bd_status *status, void *resp)
{
	struct sec_sqe3 *bd3 = resp;

	status->done = le16_to_cpu(bd3->done_flag) & SEC_DONE_MASK;
	status->icv = (le16_to_cpu(bd3->done_flag) & SEC_ICV_MASK) >> 1;
	status->flag = (le16_to_cpu(bd3->done_flag) &
					SEC_FLAG_MASK) >> SEC_FLAG_OFFSET;
	status->tag = le64_to_cpu(bd3->tag);
	status->err_type = bd3->error_type;
}

static int sec_cb_status_check(struct sec_req *req,
			       struct bd_status *status)
{
	struct sec_ctx *ctx = req->ctx;

	if (unlikely(req->err_type || status->done != SEC_SQE_DONE)) {
		dev_err_ratelimited(ctx->dev, "err_type[%d], done[%u]\n",
				    req->err_type, status->done);
		return -EIO;
	}

	if (unlikely(ctx->alg_type == SEC_SKCIPHER)) {
		if (unlikely(status->flag != SEC_SQE_CFLAG)) {
			dev_err_ratelimited(ctx->dev, "flag[%u]\n",
					    status->flag);
			return -EIO;
		}
	} else if (unlikely(ctx->alg_type == SEC_AEAD)) {
		if (unlikely(status->flag != SEC_SQE_AEAD_FLAG ||
			     status->icv == SEC_ICV_ERR)) {
			dev_err_ratelimited(ctx->dev,
					    "flag[%u], icv[%u]\n",
					    status->flag, status->icv);
			return -EBADMSG;
		}

Annotation

Implementation Notes