drivers/net/ethernet/wiznet/w5100-spi.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/wiznet/w5100-spi.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/wiznet/w5100-spi.c
Extension
.c
Size
11050 bytes
Lines
484
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 w5200_spi_priv {
	/* Serialize access to cmd_buf */
	struct mutex cmd_lock;

	/* DMA (thus cache coherency maintenance) requires the
	 * transfer buffers to live in their own cache lines.
	 */
	u8 cmd_buf[4] ____cacheline_aligned;
};

static struct w5200_spi_priv *w5200_spi_priv(struct net_device *ndev)
{
	return w5100_ops_priv(ndev);
}

static int w5200_spi_init(struct net_device *ndev)
{
	struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);

	mutex_init(&spi_priv->cmd_lock);

	return 0;
}

static int w5200_spi_read(struct net_device *ndev, u32 addr)
{
	struct spi_device *spi = to_spi_device(ndev->dev.parent);
	u8 cmd[4] = { addr >> 8, addr & 0xff, 0, 1 };
	u8 data;
	int ret;

	ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, 1);

	return ret ? ret : data;
}

static int w5200_spi_write(struct net_device *ndev, u32 addr, u8 data)
{
	struct spi_device *spi = to_spi_device(ndev->dev.parent);
	u8 cmd[5] = { addr >> 8, addr & 0xff, W5200_SPI_WRITE_OPCODE, 1, data };

	return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
}

static int w5200_spi_read16(struct net_device *ndev, u32 addr)
{
	struct spi_device *spi = to_spi_device(ndev->dev.parent);
	u8 cmd[4] = { addr >> 8, addr & 0xff, 0, 2 };
	__be16 data;
	int ret;

	ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, sizeof(data));

	return ret ? ret : be16_to_cpu(data);
}

static int w5200_spi_write16(struct net_device *ndev, u32 addr, u16 data)
{
	struct spi_device *spi = to_spi_device(ndev->dev.parent);
	u8 cmd[6] = {
		addr >> 8, addr & 0xff,
		W5200_SPI_WRITE_OPCODE, 2,
		data >> 8, data & 0xff
	};

	return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
}

static int w5200_spi_readbulk(struct net_device *ndev, u32 addr, u8 *buf,
			      int len)
{
	struct spi_device *spi = to_spi_device(ndev->dev.parent);
	struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);
	struct spi_transfer xfer[] = {
		{
			.tx_buf = spi_priv->cmd_buf,
			.len = sizeof(spi_priv->cmd_buf),
		},
		{
			.rx_buf = buf,
			.len = len,
		},
	};
	int ret;

	mutex_lock(&spi_priv->cmd_lock);

	spi_priv->cmd_buf[0] = addr >> 8;
	spi_priv->cmd_buf[1] = addr;
	spi_priv->cmd_buf[2] = len >> 8;

Annotation

Implementation Notes