drivers/net/pcs/pcs-xpcs-plat.c

Source file repositories/reference/linux-study-clean/drivers/net/pcs/pcs-xpcs-plat.c

File Facts

System
Linux kernel
Corpus path
drivers/net/pcs/pcs-xpcs-plat.c
Extension
.c
Size
11088 bytes
Lines
458
Domain
Driver Families
Bucket
drivers/net
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

struct dw_xpcs_plat {
	struct platform_device *pdev;
	struct mii_bus *bus;
	bool reg_indir;
	int reg_width;
	void __iomem *reg_base;
	struct clk *cclk;
};

static ptrdiff_t xpcs_mmio_addr_format(int dev, int reg)
{
	return FIELD_PREP(0x1f0000, dev) | FIELD_PREP(0xffff, reg);
}

static u16 xpcs_mmio_addr_page(ptrdiff_t csr)
{
	return FIELD_GET(0x1fff00, csr);
}

static ptrdiff_t xpcs_mmio_addr_offset(ptrdiff_t csr)
{
	return FIELD_GET(0xff, csr);
}

static int xpcs_mmio_read_reg_indirect(struct dw_xpcs_plat *pxpcs,
				       int dev, int reg)
{
	ptrdiff_t csr, ofs;
	u16 page;
	int ret;

	csr = xpcs_mmio_addr_format(dev, reg);
	page = xpcs_mmio_addr_page(csr);
	ofs = xpcs_mmio_addr_offset(csr);

	ret = pm_runtime_resume_and_get(&pxpcs->pdev->dev);
	if (ret)
		return ret;

	switch (pxpcs->reg_width) {
	case 4:
		writel(page, pxpcs->reg_base + (DW_VR_CSR_VIEWPORT << 2));
		ret = readl(pxpcs->reg_base + (ofs << 2)) & 0xffff;
		break;
	default:
		writew(page, pxpcs->reg_base + (DW_VR_CSR_VIEWPORT << 1));
		ret = readw(pxpcs->reg_base + (ofs << 1));
		break;
	}

	pm_runtime_put(&pxpcs->pdev->dev);

	return ret;
}

static int xpcs_mmio_write_reg_indirect(struct dw_xpcs_plat *pxpcs,
					int dev, int reg, u16 val)
{
	ptrdiff_t csr, ofs;
	u16 page;
	int ret;

	csr = xpcs_mmio_addr_format(dev, reg);
	page = xpcs_mmio_addr_page(csr);
	ofs = xpcs_mmio_addr_offset(csr);

	ret = pm_runtime_resume_and_get(&pxpcs->pdev->dev);
	if (ret)
		return ret;

	switch (pxpcs->reg_width) {
	case 4:
		writel(page, pxpcs->reg_base + (DW_VR_CSR_VIEWPORT << 2));
		writel(val, pxpcs->reg_base + (ofs << 2));
		break;
	default:
		writew(page, pxpcs->reg_base + (DW_VR_CSR_VIEWPORT << 1));
		writew(val, pxpcs->reg_base + (ofs << 1));
		break;
	}

	pm_runtime_put(&pxpcs->pdev->dev);

	return 0;
}

static int xpcs_mmio_read_reg_direct(struct dw_xpcs_plat *pxpcs,
				     int dev, int reg)
{
	ptrdiff_t csr;

Annotation

Implementation Notes