drivers/infiniband/hw/erdma/erdma_eq.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/erdma/erdma_eq.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/erdma/erdma_eq.c
Extension
.c
Size
7474 bytes
Lines
328
Domain
Driver Families
Bucket
drivers/infiniband
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

le32_to_cpu(aeqe->hdr)) == ERDMA_AE_TYPE_CQ_ERR) {
			cqn = le32_to_cpu(aeqe->event_data0);
			cq = find_cq_by_cqn(dev, cqn);
			if (!cq)
				continue;

			event.device = cq->ibcq.device;
			event.element.cq = &cq->ibcq;
			event.event = IB_EVENT_CQ_ERR;
			if (cq->ibcq.event_handler)
				cq->ibcq.event_handler(&event,
						       cq->ibcq.cq_context);
		} else {
			qpn = le32_to_cpu(aeqe->event_data0);
			qp = find_qp_by_qpn(dev, qpn);
			if (!qp)
				continue;

			event.device = qp->ibqp.device;
			event.element.qp = &qp->ibqp;
			event.event = IB_EVENT_QP_FATAL;
			if (qp->ibqp.event_handler)
				qp->ibqp.event_handler(&event,
						       qp->ibqp.qp_context);
		}
	}

	notify_eq(&dev->aeq);
}

int erdma_eq_common_init(struct erdma_dev *dev, struct erdma_eq *eq, u32 depth)
{
	u32 buf_size = depth << EQE_SHIFT;

	eq->qbuf = dma_alloc_coherent(&dev->pdev->dev, buf_size,
				      &eq->qbuf_dma_addr, GFP_KERNEL);
	if (!eq->qbuf)
		return -ENOMEM;

	eq->dbrec = dma_pool_zalloc(dev->db_pool, GFP_KERNEL, &eq->dbrec_dma);
	if (!eq->dbrec)
		goto err_free_qbuf;

	spin_lock_init(&eq->lock);
	atomic64_set(&eq->event_num, 0);
	atomic64_set(&eq->notify_num, 0);
	eq->ci = 0;
	eq->depth = depth;

	return 0;

err_free_qbuf:
	dma_free_coherent(&dev->pdev->dev, buf_size, eq->qbuf,
			  eq->qbuf_dma_addr);

	return -ENOMEM;
}

void erdma_eq_destroy(struct erdma_dev *dev, struct erdma_eq *eq)
{
	dma_pool_free(dev->db_pool, eq->dbrec, eq->dbrec_dma);
	dma_free_coherent(&dev->pdev->dev, eq->depth << EQE_SHIFT, eq->qbuf,
			  eq->qbuf_dma_addr);
}

int erdma_aeq_init(struct erdma_dev *dev)
{
	struct erdma_eq *eq = &dev->aeq;
	int ret;

	ret = erdma_eq_common_init(dev, &dev->aeq, ERDMA_DEFAULT_EQ_DEPTH);
	if (ret)
		return ret;

	eq->db = dev->func_bar + ERDMA_REGS_AEQ_DB_REG;

	erdma_reg_write32(dev, ERDMA_REGS_AEQ_ADDR_H_REG,
			  upper_32_bits(eq->qbuf_dma_addr));
	erdma_reg_write32(dev, ERDMA_REGS_AEQ_ADDR_L_REG,
			  lower_32_bits(eq->qbuf_dma_addr));
	erdma_reg_write32(dev, ERDMA_REGS_AEQ_DEPTH_REG, eq->depth);
	erdma_reg_write64(dev, ERDMA_AEQ_DB_HOST_ADDR_REG, eq->dbrec_dma);

	return 0;
}

void erdma_ceq_completion_handler(struct erdma_eq_cb *ceq_cb)
{
	struct erdma_dev *dev = ceq_cb->dev;
	struct erdma_cq *cq;

Annotation

Implementation Notes