drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
Extension
.c
Size
21482 bytes
Lines
883
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 otx2vf_netdev_ops = {
	.ndo_open = otx2vf_open,
	.ndo_stop = otx2vf_stop,
	.ndo_start_xmit = otx2vf_xmit,
	.ndo_select_queue = otx2_select_queue,
	.ndo_set_rx_mode = otx2vf_set_rx_mode,
	.ndo_set_mac_address = otx2_set_mac_address,
	.ndo_change_mtu = otx2vf_change_mtu,
	.ndo_set_features = otx2vf_set_features,
	.ndo_get_stats64 = otx2_get_stats64,
	.ndo_tx_timeout = otx2_tx_timeout,
	.ndo_setup_tc = otx2_setup_tc,
	.ndo_hwtstamp_get = otx2_config_hwtstamp_get,
	.ndo_hwtstamp_set = otx2_config_hwtstamp_set,
};

static int otx2_vf_wq_init(struct otx2_nic *vf)
{
	vf->otx2_wq = create_singlethread_workqueue("otx2vf_wq");
	if (!vf->otx2_wq)
		return -ENOMEM;

	INIT_WORK(&vf->rx_mode_work, otx2vf_do_set_rx_mode);
	INIT_WORK(&vf->reset_task, otx2vf_reset_task);
	return 0;
}

static int otx2vf_realloc_msix_vectors(struct otx2_nic *vf)
{
	struct otx2_hw *hw = &vf->hw;
	int num_vec, err;

	num_vec = hw->nix_msixoff;
	num_vec += NIX_LF_CINT_VEC_START + hw->max_queues;

	otx2vf_disable_mbox_intr(vf);
	pci_free_irq_vectors(hw->pdev);
	err = pci_alloc_irq_vectors(hw->pdev, num_vec, num_vec, PCI_IRQ_MSIX);
	if (err < 0) {
		dev_err(vf->dev, "%s: Failed to realloc %d IRQ vectors\n",
			__func__, num_vec);
		return err;
	}

	return otx2vf_register_mbox_intr(vf, false);
}

static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	int num_vec = pci_msix_vec_count(pdev);
	struct device *dev = &pdev->dev;
	int err, qcount, qos_txqs;
	struct net_device *netdev;
	struct otx2_nic *vf;
	struct otx2_hw *hw;

	err = pcim_enable_device(pdev);
	if (err) {
		dev_err(dev, "Failed to enable PCI device\n");
		return err;
	}

	err = pcim_request_all_regions(pdev, DRV_NAME);
	if (err) {
		dev_err(dev, "PCI request regions failed 0x%x\n", err);
		return err;
	}

	err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
	if (err) {
		dev_err(dev, "DMA mask config failed, abort\n");
		return err;
	}

	pci_set_master(pdev);

	qcount = num_online_cpus();
	qos_txqs = min_t(int, qcount, OTX2_QOS_MAX_LEAF_NODES);
	netdev = alloc_etherdev_mqs(sizeof(*vf), qcount + qos_txqs, qcount);
	if (!netdev)
		return -ENOMEM;

	pci_set_drvdata(pdev, netdev);
	SET_NETDEV_DEV(netdev, &pdev->dev);
	vf = netdev_priv(netdev);
	vf->netdev = netdev;
	vf->pdev = pdev;
	vf->dev = dev;
	vf->iommu_domain = iommu_get_domain_for_dev(dev);

Annotation

Implementation Notes