drivers/net/mctp/mctp-i3c.c

Source file repositories/reference/linux-study-clean/drivers/net/mctp/mctp-i3c.c

File Facts

System
Linux kernel
Corpus path
drivers/net/mctp/mctp-i3c.c
Extension
.c
Size
17564 bytes
Lines
768
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 mctp_i3c_ops = {
	.ndo_start_xmit = mctp_i3c_start_xmit,
	.ndo_uninit = mctp_i3c_ndo_uninit,
};

static const struct header_ops mctp_i3c_headops = {
	.create = mctp_i3c_header_create,
};

static void mctp_i3c_net_setup(struct net_device *dev)
{
	dev->type = ARPHRD_MCTP;

	dev->mtu = MCTP_I3C_MAXMTU;
	dev->min_mtu = MCTP_I3C_MINMTU;
	dev->max_mtu = MCTP_I3C_MAXMTU;
	dev->tx_queue_len = MCTP_I3C_TX_QUEUE_LEN;

	dev->hard_header_len = sizeof(struct mctp_i3c_internal_hdr);
	dev->addr_len = PID_SIZE;

	dev->netdev_ops	= &mctp_i3c_ops;
	dev->header_ops	= &mctp_i3c_headops;
}

static bool mctp_i3c_is_mctp_controller(struct i3c_bus *bus)
{
	struct i3c_dev_desc *master = bus->cur_master;

	if (!master)
		return false;

	return of_property_read_bool(master->common.master->dev.of_node,
				     MCTP_I3C_OF_PROP);
}

/* Returns the Provisioned Id of a local bus master */
static int mctp_i3c_bus_local_pid(struct i3c_bus *bus, u64 *ret_pid)
{
	struct i3c_dev_desc *master;

	master = bus->cur_master;
	if (WARN_ON_ONCE(!master))
		return -ENOENT;
	*ret_pid = master->info.pid;

	return 0;
}

/* Returns an ERR_PTR on failure */
static struct mctp_i3c_bus *mctp_i3c_bus_add(struct i3c_bus *bus)
__must_hold(&busdevs_lock)
{
	struct mctp_i3c_bus *mbus = NULL;
	struct net_device *ndev = NULL;
	char namebuf[IFNAMSIZ];
	u8 addr[PID_SIZE];
	int rc;

	if (!mctp_i3c_is_mctp_controller(bus))
		return ERR_PTR(-ENOENT);

	snprintf(namebuf, sizeof(namebuf), "mctpi3c%d", bus->id);
	ndev = alloc_netdev(sizeof(*mbus), namebuf, NET_NAME_ENUM,
			    mctp_i3c_net_setup);
	if (!ndev) {
		rc = -ENOMEM;
		goto err;
	}

	mbus = netdev_priv(ndev);
	mbus->ndev = ndev;
	mbus->bus = bus;
	INIT_LIST_HEAD(&mbus->devs);
	list_add(&mbus->list, &busdevs);

	rc = mctp_i3c_bus_local_pid(bus, &mbus->pid);
	if (rc < 0) {
		dev_err(&ndev->dev, "No I3C PID available\n");
		goto err_free_uninit;
	}
	put_unaligned_be48(mbus->pid, addr);
	dev_addr_set(ndev, addr);

	init_waitqueue_head(&mbus->tx_wq);
	spin_lock_init(&mbus->tx_lock);
	mbus->tx_thread = kthread_run(mctp_i3c_tx_thread, mbus,
				      "%s/tx", ndev->name);
	if (IS_ERR(mbus->tx_thread)) {
		dev_warn(&ndev->dev, "Error creating thread: %pe\n",

Annotation

Implementation Notes