drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
Extension
.c
Size
52592 bytes
Lines
1982
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

if (err) {
			e_err(probe, "Failed to enable PCI sriov: %d\n", err);
			return;
		}
	}

	if (!__ixgbe_enable_sriov(adapter, num_vfs)) {
		ixgbe_get_vfs(adapter);
		return;
	}

	/* If we have gotten to this point then there is no memory available
	 * to manage the VF devices - print message and bail.
	 */
	e_err(probe, "Unable to allocate memory for VF Data Storage - "
	      "SRIOV disabled\n");
	ixgbe_disable_sriov(adapter);
}

#endif /* #ifdef CONFIG_PCI_IOV */
int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
{
	unsigned int num_vfs = adapter->num_vfs, vf;
	struct ixgbe_hw *hw = &adapter->hw;
	unsigned long flags;
	int rss;

	spin_lock_irqsave(&adapter->vfs_lock, flags);
	/* set num VFs to 0 to prevent access to vfinfo */
	adapter->num_vfs = 0;
	spin_unlock_irqrestore(&adapter->vfs_lock, flags);

	/* put the reference to all of the vf devices */
	for (vf = 0; vf < num_vfs; ++vf) {
		struct pci_dev *vfdev = adapter->vfinfo[vf].vfdev;

		if (!vfdev)
			continue;
		adapter->vfinfo[vf].vfdev = NULL;
		pci_dev_put(vfdev);
	}

	/* free VF control structures */
	kfree(adapter->vfinfo);
	adapter->vfinfo = NULL;

	/* free macvlan list */
	kfree(adapter->mv_list);
	adapter->mv_list = NULL;

	/* if SR-IOV is already disabled then there is nothing to do */
	if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
		return 0;

	if (hw->mac.ops.disable_mdd)
		hw->mac.ops.disable_mdd(hw);

#ifdef CONFIG_PCI_IOV
	/*
	 * If our VFs are assigned we cannot shut down SR-IOV
	 * without causing issues, so just leave the hardware
	 * available but disabled
	 */
	if (pci_vfs_assigned(adapter->pdev)) {
		e_dev_warn("Unloading driver while VFs are assigned - VFs will not be deallocated\n");
		return -EPERM;
	}
	/* disable iov and allow time for transactions to clear */
	pci_disable_sriov(adapter->pdev);
#endif

	/* Disable VMDq flag so device will be set in VM mode */
	if (bitmap_weight(adapter->fwd_bitmask, adapter->num_rx_pools) == 1) {
		adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED;
		adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
		rss = min_t(int, ixgbe_max_rss_indices(adapter),
			    num_online_cpus());
	} else {
		rss = min_t(int, IXGBE_MAX_L2A_QUEUES, num_online_cpus());
	}

	adapter->ring_feature[RING_F_VMDQ].offset = 0;
	adapter->ring_feature[RING_F_RSS].limit = rss;

	/* take a breather then clean up driver data */
	msleep(100);
	return 0;
}

static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs)

Annotation

Implementation Notes