drivers/infiniband/hw/irdma/hw.c

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

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/irdma/hw.c
Extension
.c
Size
80187 bytes
Lines
2907
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

if (status) {
			ibdev_dbg(to_ibdev(dev), "ERR: puda status = %d\n", status);
			break;
		}
		if (compl_error) {
			ibdev_dbg(to_ibdev(dev), "ERR: puda compl_err  =0x%x\n",
				  compl_error);
			break;
		}
	} while (1);

	irdma_sc_ccq_arm(cq);
}

/**
 * irdma_process_normal_ceqe - Handle a CEQE for a normal CQ.
 * @rf: RDMA PCI function.
 * @dev: iWARP device.
 * @cq_idx: CQ ID. Must be in table bounds.
 *
 * Context: Atomic (CEQ lock must be held)
 */
static void irdma_process_normal_ceqe(struct irdma_pci_f *rf,
				      struct irdma_sc_dev *dev, u32 cq_idx)
{
	/* cq_idx bounds validated in irdma_sc_process_ceq. */
	struct irdma_cq *icq = READ_ONCE(rf->cq_table[cq_idx]);
	struct irdma_sc_cq *cq;

	if (unlikely(!icq)) {
		/* Should not happen since CEQ is scrubbed upon CQ delete. */
		ibdev_warn_ratelimited(to_ibdev(dev), "Stale CEQE for CQ %u",
				       cq_idx);
		return;
	}

	cq = &icq->sc_cq;

	if (unlikely(cq->cq_type != IRDMA_CQ_TYPE_IWARP)) {
		ibdev_warn_ratelimited(to_ibdev(dev), "Unexpected CQ type %u",
				       cq->cq_type);
		return;
	}

	writel(cq->cq_uk.cq_id, cq->cq_uk.cq_ack_db);
	irdma_iwarp_ce_handler(cq);
}

/**
 * irdma_process_reserved_ceqe - Handle a CEQE for a reserved CQ.
 * @rf: RDMA PCI function.
 * @dev: iWARP device.
 * @cq_idx: CQ ID.
 *
 * Context: Atomic
 */
static void irdma_process_reserved_ceqe(struct irdma_pci_f *rf,
					struct irdma_sc_dev *dev, u32 cq_idx)
{
	struct irdma_sc_cq *cq;

	if (cq_idx == IRDMA_RSVD_CQ_ID_CQP) {
		cq = &rf->ccq.sc_cq;
		/* CQP CQ lifetime > CEQ. */
		writel(cq->cq_uk.cq_id, cq->cq_uk.cq_ack_db);
		queue_work(rf->cqp_cmpl_wq, &rf->cqp_cmpl_work);
	} else if (cq_idx == IRDMA_RSVD_CQ_ID_ILQ ||
		   cq_idx == IRDMA_RSVD_CQ_ID_IEQ) {
		scoped_guard(spinlock_irqsave, &dev->puda_cq_lock) {
			cq = (cq_idx == IRDMA_RSVD_CQ_ID_ILQ) ?
				dev->ilq_cq : dev->ieq_cq;
			if (!cq) {
				ibdev_warn_ratelimited(to_ibdev(dev),
						       "Stale ILQ/IEQ CEQE");
				return;
			}
			writel(cq->cq_uk.cq_id, cq->cq_uk.cq_ack_db);
			irdma_puda_ce_handler(rf, cq);
		}
	}
}

/**
 * irdma_process_ceq - handle ceq for completions
 * @rf: RDMA PCI function
 * @ceq: ceq having cq for completion
 */
static void irdma_process_ceq(struct irdma_pci_f *rf, struct irdma_ceq *ceq)
{
	struct irdma_sc_dev *dev = &rf->sc_dev;

Annotation

Implementation Notes