drivers/crypto/hisilicon/sgl.c

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

File Facts

System
Linux kernel
Corpus path
drivers/crypto/hisilicon/sgl.c
Extension
.c
Size
7583 bytes
Lines
291
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 acc_hw_sge {
	dma_addr_t buf;
	void *page_ctrl;
	__le32 len;
	__le32 pad;
	__le32 pad0;
	__le32 pad1;
};

/* use default sgl head size 64B */
struct hisi_acc_hw_sgl {
	dma_addr_t next_dma;
	__le16 entry_sum_in_chain;
	__le16 entry_sum_in_sgl;
	__le16 entry_length_in_sgl;
	__le16 pad0;
	__le64 pad1[5];
	struct hisi_acc_hw_sgl *next;
	struct acc_hw_sge sge_entries[];
} __aligned(1);

struct hisi_acc_sgl_pool {
	struct mem_block {
		struct hisi_acc_hw_sgl *sgl;
		dma_addr_t sgl_dma;
		size_t size;
	} mem_block[HISI_ACC_MEM_BLOCK_NR];
	u32 sgl_num_per_block;
	u32 block_num;
	u32 count;
	u32 sge_nr;
	size_t sgl_size;
};

/**
 * hisi_acc_create_sgl_pool() - Create a hw sgl pool.
 * @dev: The device which hw sgl pool belongs to.
 * @count: Count of hisi_acc_hw_sgl in pool.
 * @sge_nr: The count of sge in hw_sgl
 *
 * This function creates a hw sgl pool, after this user can get hw sgl memory
 * from it.
 */
struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,
						   u32 count, u32 sge_nr)
{
	u32 sgl_size, block_size, sgl_num_per_block, block_num, remain_sgl;
	struct hisi_acc_sgl_pool *pool;
	struct mem_block *block;
	u32 i, j;

	if (!dev || !count || !sge_nr || sge_nr > HISI_ACC_SGL_SGE_NR_MAX)
		return ERR_PTR(-EINVAL);

	sgl_size = ALIGN(sizeof(struct acc_hw_sge) * sge_nr +
			 sizeof(struct hisi_acc_hw_sgl),
			 HISI_ACC_SGL_ALIGN_SIZE);

	/*
	 * the pool may allocate a block of memory of size PAGE_SIZE * 2^MAX_PAGE_ORDER,
	 * block size may exceed 2^31 on ia64, so the max of block size is 2^31
	 */
	block_size = 1 << (PAGE_SHIFT + MAX_PAGE_ORDER < 32 ?
			   PAGE_SHIFT + MAX_PAGE_ORDER : 31);
	sgl_num_per_block = block_size / sgl_size;
	block_num = count / sgl_num_per_block;
	remain_sgl = count % sgl_num_per_block;

	if ((!remain_sgl && block_num > HISI_ACC_MEM_BLOCK_NR) ||
	    (remain_sgl > 0 && block_num > HISI_ACC_MEM_BLOCK_NR - 1))
		return ERR_PTR(-EINVAL);

	pool = kzalloc_obj(*pool);
	if (!pool)
		return ERR_PTR(-ENOMEM);
	block = pool->mem_block;

	for (i = 0; i < block_num; i++) {
		block[i].sgl = dma_alloc_coherent(dev, block_size,
						  &block[i].sgl_dma,
						  GFP_KERNEL);
		if (!block[i].sgl) {
			dev_err(dev, "Fail to allocate hw SG buffer!\n");
			goto err_free_mem;
		}

		block[i].size = block_size;
	}

	if (remain_sgl > 0) {

Annotation

Implementation Notes