drivers/net/ethernet/qualcomm/qca_spi.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/qualcomm/qca_spi.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/qualcomm/qca_spi.c
Extension
.c
Size
25374 bytes
Lines
1051
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct net_device_ops qcaspi_netdev_ops = {
	.ndo_init = qcaspi_netdev_init,
	.ndo_uninit = qcaspi_netdev_uninit,
	.ndo_open = qcaspi_netdev_open,
	.ndo_stop = qcaspi_netdev_close,
	.ndo_start_xmit = qcaspi_netdev_xmit,
	.ndo_set_mac_address = eth_mac_addr,
	.ndo_tx_timeout = qcaspi_netdev_tx_timeout,
	.ndo_validate_addr = eth_validate_addr,
};

static void
qcaspi_netdev_setup(struct net_device *dev)
{
	struct qcaspi *qca = NULL;

	dev->netdev_ops = &qcaspi_netdev_ops;
	qcaspi_set_ethtool_ops(dev);
	dev->watchdog_timeo = QCASPI_TX_TIMEOUT;
	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
	dev->needed_tailroom = ALIGN(QCAFRM_FOOTER_LEN + QCAFRM_MIN_LEN, 4);
	dev->needed_headroom = ALIGN(QCAFRM_HEADER_LEN, 4);
	dev->tx_queue_len = 100;

	/* MTU range: 46 - 1500 */
	dev->min_mtu = QCAFRM_MIN_MTU;
	dev->max_mtu = QCAFRM_MAX_MTU;

	qca = netdev_priv(dev);
	memset(qca, 0, sizeof(struct qcaspi));

	memset(&qca->txr, 0, sizeof(qca->txr));
	qca->txr.count = QCASPI_TX_RING_MAX_LEN;
}

static const struct of_device_id qca_spi_of_match[] = {
	{ .compatible = "qca,qca7000" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, qca_spi_of_match);

static int
qca_spi_probe(struct spi_device *spi)
{
	struct qcaspi *qca = NULL;
	struct net_device *qcaspi_devs = NULL;
	u8 legacy_mode = 0;
	u16 signature;
	int ret;

	if (!spi->dev.of_node) {
		dev_err(&spi->dev, "Missing device tree\n");
		return -EINVAL;
	}

	legacy_mode = of_property_read_bool(spi->dev.of_node,
					    "qca,legacy-mode");

	if (qcaspi_clkspeed)
		spi->max_speed_hz = qcaspi_clkspeed;
	else if (!spi->max_speed_hz)
		spi->max_speed_hz = QCASPI_CLK_SPEED;

	if (spi->max_speed_hz < QCASPI_CLK_SPEED_MIN ||
	    spi->max_speed_hz > QCASPI_CLK_SPEED_MAX) {
		dev_err(&spi->dev, "Invalid clkspeed: %u\n",
			spi->max_speed_hz);
		return -EINVAL;
	}

	if ((qcaspi_burst_len < QCASPI_BURST_LEN_MIN) ||
	    (qcaspi_burst_len > QCASPI_BURST_LEN_MAX)) {
		dev_err(&spi->dev, "Invalid burst len: %d\n",
			qcaspi_burst_len);
		return -EINVAL;
	}

	if ((qcaspi_pluggable < QCASPI_PLUGGABLE_MIN) ||
	    (qcaspi_pluggable > QCASPI_PLUGGABLE_MAX)) {
		dev_err(&spi->dev, "Invalid pluggable: %d\n",
			qcaspi_pluggable);
		return -EINVAL;
	}

	if (wr_verify < QCASPI_WRITE_VERIFY_MIN ||
	    wr_verify > QCASPI_WRITE_VERIFY_MAX) {
		dev_err(&spi->dev, "Invalid write verify: %d\n",
			wr_verify);
		return -EINVAL;
	}

Annotation

Implementation Notes