drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c
Extension
.c
Size
7149 bytes
Lines
331
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 (retries > VSC_MAX_RETRIES) {
			ret = -EBUSY;
			goto pci_unlock;
		}
		if (pci_channel_offline(dev->pdev)) {
			ret = -EACCES;
			goto pci_unlock;
		}

		/* Check if semaphore is already locked */
		ret = vsc_read(dev, VSC_SEMAPHORE_OFFSET, &lock_val);
		if (ret)
			goto pci_unlock;

		if (lock_val) {
			retries++;
			usleep_range(1000, 2000);
			continue;
		}

		/* Read and write counter value, if written value is
		 * the same, semaphore was acquired successfully.
		 */
		ret = vsc_read(dev, VSC_COUNTER_OFFSET, &counter);
		if (ret)
			goto pci_unlock;

		ret = vsc_write(dev, VSC_SEMAPHORE_OFFSET, counter);
		if (ret)
			goto pci_unlock;

		ret = vsc_read(dev, VSC_SEMAPHORE_OFFSET, &lock_val);
		if (ret)
			goto pci_unlock;

		retries++;
	} while (counter != lock_val);

	return 0;

pci_unlock:
	pci_cfg_access_unlock(dev->pdev);
	return ret;
}

int mlx5_vsc_gw_unlock(struct mlx5_core_dev *dev)
{
	int ret;

	ret = vsc_write(dev, VSC_SEMAPHORE_OFFSET, MLX5_VSC_UNLOCK);
	pci_cfg_access_unlock(dev->pdev);
	return ret;
}

int mlx5_vsc_gw_set_space(struct mlx5_core_dev *dev, u16 space,
			  u32 *ret_space_size)
{
	int ret;
	u32 val = 0;

	if (!mlx5_vsc_accessible(dev))
		return -EINVAL;

	if (ret_space_size)
		*ret_space_size = 0;

	/* Get a unique val */
	ret = vsc_read(dev, VSC_CTRL_OFFSET, &val);
	if (ret)
		goto out;

	/* Try to modify the lock */
	val = MLX5_MERGE(val, space, VSC_SPACE_BIT_OFFS, VSC_SPACE_BIT_LEN);
	ret = vsc_write(dev, VSC_CTRL_OFFSET, val);
	if (ret)
		goto out;

	/* Verify lock was modified */
	ret = vsc_read(dev, VSC_CTRL_OFFSET, &val);
	if (ret)
		goto out;

	if (MLX5_EXTRACT(val, VSC_STATUS_BIT_OFFS, VSC_STATUS_BIT_LEN) == 0)
		return -EINVAL;

	/* Get space max address if indicated by size valid bit */
	if (ret_space_size &&
	    MLX5_EXTRACT(val, VSC_SIZE_VLD_BIT_OFFS, VSC_SIZE_VLD_BIT_LEN)) {
		ret = vsc_read(dev, VSC_ADDR_OFFSET, &val);
		if (ret) {

Annotation

Implementation Notes