drivers/infiniband/hw/mana/device.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/mana/device.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/mana/device.c
Extension
.c
Size
8152 bytes
Lines
272
Domain
Driver Families
Bucket
drivers/infiniband
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

if (event_dev == mc->ports[i]) {
			switch (event) {
			case NETDEV_CHANGEUPPER:
				ndev = mana_get_primary_netdev(mc, i, &dev->dev_tracker);
				/*
				 * RDMA core will setup GID based on updated netdev.
				 * It's not possible to race with the core as rtnl lock is being
				 * held.
				 */
				ib_device_set_netdev(&dev->ib_dev, ndev, i + 1);

				/* mana_get_primary_netdev() returns ndev with refcount held */
				if (ndev)
					netdev_put(ndev, &dev->dev_tracker);

				return NOTIFY_OK;
			default:
				return NOTIFY_DONE;
			}
		}
	return NOTIFY_DONE;
}

static int mana_ib_probe(struct auxiliary_device *adev,
			 const struct auxiliary_device_id *id)
{
	struct mana_adev *madev = container_of(adev, struct mana_adev, adev);
	struct gdma_context *gc = madev->mdev->gdma_context;
	struct mana_context *mc = gc->mana.driver_data;
	struct gdma_dev *mdev = madev->mdev;
	struct net_device *ndev;
	struct mana_ib_dev *dev;
	u8 mac_addr[ETH_ALEN];
	int ret, i;

	dev = ib_alloc_device(mana_ib_dev, ib_dev);
	if (!dev)
		return -ENOMEM;

	ib_set_device_ops(&dev->ib_dev, &mana_ib_dev_ops);
	dev->ib_dev.node_type = RDMA_NODE_IB_CA;
	dev->ib_dev.num_comp_vectors = gc->max_num_queues;
	dev->ib_dev.dev.parent = gc->dev;
	dev->gdma_dev = mdev;
	xa_init_flags(&dev->qp_table_wq, XA_FLAGS_LOCK_IRQ);

	if (mana_ib_is_rnic(dev)) {
		dev->ib_dev.phys_port_cnt = 1;
		addrconf_addr_eui48((u8 *)&dev->ib_dev.node_guid, mc->ports[0]->dev_addr);
		ret = mana_ib_gd_query_adapter_caps(dev);
		if (ret) {
			ibdev_err(&dev->ib_dev, "Failed to query device caps, ret %d", ret);
			goto free_ib_device;
		}

		ib_set_device_ops(&dev->ib_dev, &mana_ib_stats_ops);
		if (dev->adapter_caps.feature_flags & MANA_IB_FEATURE_DEV_COUNTERS_SUPPORT)
			ib_set_device_ops(&dev->ib_dev, &mana_ib_device_stats_ops);
		ib_set_device_ops(&dev->ib_dev, &mana_ib_dev_dm_ops);

		ret = mana_ib_create_eqs(dev);
		if (ret) {
			ibdev_err(&dev->ib_dev, "Failed to create EQs, ret %d", ret);
			goto free_ib_device;
		}

		ret = mana_ib_gd_create_rnic_adapter(dev);
		if (ret)
			goto destroy_eqs;

		if (dev->adapter_caps.feature_flags & MANA_IB_FEATURE_MULTI_PORTS_SUPPORT)
			dev->ib_dev.phys_port_cnt = mc->num_ports;

		for (i = 0; i < dev->ib_dev.phys_port_cnt; i++) {
			ndev = mana_get_primary_netdev(mc, i, &dev->dev_tracker);
			if (!ndev) {
				ret = -ENODEV;
				ibdev_err(&dev->ib_dev,
					  "Failed to get netdev for IB port %d", i + 1);
				goto destroy_rnic;
			}
			ether_addr_copy(mac_addr, ndev->dev_addr);
			ret = ib_device_set_netdev(&dev->ib_dev, ndev, i + 1);
			/* mana_get_primary_netdev() returns ndev with refcount held */
			netdev_put(ndev, &dev->dev_tracker);
			if (ret) {
				ibdev_err(&dev->ib_dev, "Failed to set ib netdev, ret %d", ret);
				goto destroy_rnic;
			}
			ret = mana_ib_gd_config_mac(dev, ADDR_OP_ADD, mac_addr);

Annotation

Implementation Notes