drivers/crypto/caam/qi.c

Source file repositories/reference/linux-study-clean/drivers/crypto/caam/qi.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/caam/qi.c
Extension
.c
Size
20038 bytes
Lines
814
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 caam_napi {
	struct napi_struct irqtask;
	struct qman_portal *p;
};

/*
 * caam_qi_pcpu_priv - percpu private data structure to main list of pending
 *                     responses expected on each cpu.
 * @caam_napi: CAAM NAPI params
 * @net_dev: netdev used by NAPI
 * @rsp_fq: response FQ from CAAM
 */
struct caam_qi_pcpu_priv {
	struct caam_napi caam_napi;
	struct net_device *net_dev;
	struct qman_fq *rsp_fq;
} ____cacheline_aligned;

static DEFINE_PER_CPU(struct caam_qi_pcpu_priv, pcpu_qipriv);
static DEFINE_PER_CPU(int, last_cpu);

/*
 * caam_qi_priv - CAAM QI backend private params
 * @cgr: QMan congestion group
 */
struct caam_qi_priv {
	struct qman_cgr cgr;
};

static struct caam_qi_priv qipriv ____cacheline_aligned;

/*
 * This is written by only one core - the one that initialized the CGR - and
 * read by multiple cores (all the others).
 */
bool caam_congested __read_mostly;
EXPORT_SYMBOL(caam_congested);

/*
 * This is a cache of buffers, from which the users of CAAM QI driver
 * can allocate short (CAAM_QI_MEMCACHE_SIZE) buffers. It's faster than
 * doing malloc on the hotpath.
 * NOTE: A more elegant solution would be to have some headroom in the frames
 *       being processed. This could be added by the dpaa-ethernet driver.
 *       This would pose a problem for userspace application processing which
 *       cannot know of this limitation. So for now, this will work.
 * NOTE: The memcache is SMP-safe. No need to handle spinlocks in-here
 */
static struct kmem_cache *qi_cache;

static void *caam_iova_to_virt(struct iommu_domain *domain,
			       dma_addr_t iova_addr)
{
	phys_addr_t phys_addr;

	phys_addr = domain ? iommu_iova_to_phys(domain, iova_addr) : iova_addr;

	return phys_to_virt(phys_addr);
}

int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req)
{
	struct qm_fd fd;
	dma_addr_t addr;
	int ret;
	int num_retries = 0;

	qm_fd_clear_fd(&fd);
	qm_fd_set_compound(&fd, qm_sg_entry_get_len(&req->fd_sgt[1]));

	addr = dma_map_single(qidev, req->fd_sgt, sizeof(req->fd_sgt),
			      DMA_BIDIRECTIONAL);
	if (dma_mapping_error(qidev, addr)) {
		dev_err(qidev, "DMA mapping error for QI enqueue request\n");
		return -EIO;
	}
	qm_fd_addr_set64(&fd, addr);

	do {
		refcount_inc(&req->drv_ctx->refcnt);
		ret = qman_enqueue(req->drv_ctx->req_fq, &fd);
		if (likely(!ret))
			return 0;

		refcount_dec(&req->drv_ctx->refcnt);
		if (ret != -EBUSY)
			break;
		num_retries++;
	} while (num_retries < CAAM_QI_ENQUEUE_RETRIES);

Annotation

Implementation Notes