drivers/net/ethernet/8390/xsurf100.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/8390/xsurf100.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/8390/xsurf100.c
Extension
.c
Size
10649 bytes
Lines
378
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 xsurf100_ax_plat_data {
	struct ax_plat_data ax;
	void __iomem *base_regs;
	void __iomem *data_area;
};

static int is_xsurf100_network_irq(struct platform_device *pdev)
{
	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);

	return (readw(xs100->base_regs + XS100_IRQSTATUS_BASE) & 0xaaaa) != 0;
}

/* These functions guarantee that the iomem is accessed with 32 bit
 * cycles only. z_memcpy_fromio / z_memcpy_toio don't
 */
static void z_memcpy_fromio32(void *dst, const void __iomem *src, size_t bytes)
{
	while (bytes > 32) {
		asm __volatile__
		   ("movem.l (%0)+,%%d0-%%d7\n"
		    "movem.l %%d0-%%d7,(%1)\n"
		    "adda.l #32,%1" : "=a"(src), "=a"(dst)
		    : "0"(src), "1"(dst) : "d0", "d1", "d2", "d3", "d4",
					   "d5", "d6", "d7", "memory");
		bytes -= 32;
	}
	while (bytes) {
		*(uint32_t *)dst = z_readl(src);
		src += 4;
		dst += 4;
		bytes -= 4;
	}
}

static void z_memcpy_toio32(void __iomem *dst, const void *src, size_t bytes)
{
	while (bytes) {
		z_writel(*(const uint32_t *)src, dst);
		src += 4;
		dst += 4;
		bytes -= 4;
	}
}

static void xs100_write(struct net_device *dev, const void *src,
			unsigned int count)
{
	struct ei_device *ei_local = netdev_priv(dev);
	struct platform_device *pdev = to_platform_device(dev->dev.parent);
	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);

	/* copy whole blocks */
	while (count > XS100_8390_DATA_AREA_SIZE) {
		z_memcpy_toio32(xs100->data_area +
				XS100_8390_DATA_WRITE32_BASE, src,
				XS100_8390_DATA_AREA_SIZE);
		src += XS100_8390_DATA_AREA_SIZE;
		count -= XS100_8390_DATA_AREA_SIZE;
	}
	/* copy whole dwords */
	z_memcpy_toio32(xs100->data_area + XS100_8390_DATA_WRITE32_BASE,
			src, count & ~3);
	src += count & ~3;
	if (count & 2) {
		ei_outw(*(uint16_t *)src, ei_local->mem + NE_DATAPORT);
		src += 2;
	}
	if (count & 1)
		ei_outb(*(uint8_t *)src, ei_local->mem + NE_DATAPORT);
}

static void xs100_read(struct net_device *dev, void *dst, unsigned int count)
{
	struct ei_device *ei_local = netdev_priv(dev);
	struct platform_device *pdev = to_platform_device(dev->dev.parent);
	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);

	/* copy whole blocks */
	while (count > XS100_8390_DATA_AREA_SIZE) {
		z_memcpy_fromio32(dst, xs100->data_area +
				  XS100_8390_DATA_READ32_BASE,
				  XS100_8390_DATA_AREA_SIZE);
		dst += XS100_8390_DATA_AREA_SIZE;
		count -= XS100_8390_DATA_AREA_SIZE;
	}
	/* copy whole dwords */
	z_memcpy_fromio32(dst, xs100->data_area + XS100_8390_DATA_READ32_BASE,
			  count & ~3);
	dst += count & ~3;

Annotation

Implementation Notes