drivers/net/ethernet/amd/pds_core/core.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/amd/pds_core/core.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/amd/pds_core/core.c
Extension
.c
Size
16588 bytes
Lines
665
Domain
Driver Families
Bucket
drivers/net
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

if (!qcq->q_base) {
			err = -ENOMEM;
			goto err_out_free_cq_info;
		}
		q_base = PTR_ALIGN(qcq->q_base, PDS_PAGE_SIZE);
		q_base_pa = ALIGN(qcq->q_base_pa, PDS_PAGE_SIZE);
		pdsc_q_map(&qcq->q, q_base, q_base_pa);

		cq_base = PTR_ALIGN(q_base +
				    ALIGN(num_descs * desc_size, PDS_PAGE_SIZE),
				    PDS_PAGE_SIZE);
		cq_base_pa = ALIGN(qcq->q_base_pa +
				   ALIGN(num_descs * desc_size, PDS_PAGE_SIZE),
				   PDS_PAGE_SIZE);

	} else {
		/* q DMA descriptors */
		qcq->q_size = PDS_PAGE_SIZE + (num_descs * desc_size);
		qcq->q_base = dma_alloc_coherent(dev, qcq->q_size,
						 &qcq->q_base_pa,
						 GFP_KERNEL);
		if (!qcq->q_base) {
			err = -ENOMEM;
			goto err_out_free_cq_info;
		}
		q_base = PTR_ALIGN(qcq->q_base, PDS_PAGE_SIZE);
		q_base_pa = ALIGN(qcq->q_base_pa, PDS_PAGE_SIZE);
		pdsc_q_map(&qcq->q, q_base, q_base_pa);

		/* cq DMA descriptors */
		qcq->cq_size = PDS_PAGE_SIZE + (num_descs * cq_desc_size);
		qcq->cq_base = dma_alloc_coherent(dev, qcq->cq_size,
						  &qcq->cq_base_pa,
						  GFP_KERNEL);
		if (!qcq->cq_base) {
			err = -ENOMEM;
			goto err_out_free_q;
		}
		cq_base = PTR_ALIGN(qcq->cq_base, PDS_PAGE_SIZE);
		cq_base_pa = ALIGN(qcq->cq_base_pa, PDS_PAGE_SIZE);
	}

	pdsc_cq_map(&qcq->cq, cq_base, cq_base_pa);
	qcq->cq.bound_q = &qcq->q;

	pdsc_debugfs_add_qcq(pdsc, qcq);

	return 0;

err_out_free_q:
	dma_free_coherent(dev, qcq->q_size, qcq->q_base, qcq->q_base_pa);
err_out_free_cq_info:
	vfree(qcq->cq.info);
err_out_free_irq:
	pdsc_qcq_intr_free(pdsc, qcq);
err_out_free_q_info:
	vfree(qcq->q.info);
	memset(qcq, 0, sizeof(*qcq));
err_out:
	dev_err(dev, "qcq alloc of %s%d failed %d\n", name, index, err);
	return err;
}

static void pdsc_core_uninit(struct pdsc *pdsc)
{
	pdsc_qcq_free(pdsc, &pdsc->notifyqcq);
	pdsc_qcq_free(pdsc, &pdsc->adminqcq);

	if (pdsc->kern_dbpage) {
		iounmap(pdsc->kern_dbpage);
		pdsc->kern_dbpage = NULL;
	}
}

static int pdsc_core_init(struct pdsc *pdsc)
{
	union pds_core_dev_comp comp = {};
	union pds_core_dev_cmd cmd = {
		.init.opcode = PDS_CORE_CMD_INIT,
	};
	struct pds_core_dev_init_data_out cido;
	struct pds_core_dev_init_data_in cidi;
	u32 dbid_count;
	u32 dbpage_num;
	int numdescs;
	size_t sz;
	int err;

	numdescs = PDSC_ADMINQ_MAX_LENGTH;
	err = pdsc_qcq_alloc(pdsc, PDS_CORE_QTYPE_ADMINQ, 0, "adminq",

Annotation

Implementation Notes