drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c
Extension
.c
Size
24293 bytes
Lines
847
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

// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2019-2021, Intel Corporation. */

#include "ice_vsi_vlan_lib.h"
#include "ice_lib.h"
#include "ice_fltr.h"
#include "ice.h"

static void print_invalid_tpid(struct ice_vsi *vsi, u16 tpid)
{
	dev_err(ice_pf_to_dev(vsi->back), "%s %d specified invalid VLAN tpid 0x%04x\n",
		ice_vsi_type_str(vsi->type), vsi->idx, tpid);
}

/**
 * validate_vlan - check if the ice_vlan passed in is valid
 * @vsi: VSI used for printing error message
 * @vlan: ice_vlan structure to validate
 *
 * Return true if the VLAN TPID is valid or if the VLAN TPID is 0 and the VLAN
 * VID is 0, which allows for non-zero VLAN filters with the specified VLAN TPID
 * and untagged VLAN 0 filters to be added to the prune list respectively.
 */
static bool validate_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
{
	if (vlan->tpid != ETH_P_8021Q && vlan->tpid != ETH_P_8021AD &&
	    vlan->tpid != ETH_P_QINQ1 && (vlan->tpid || vlan->vid)) {
		print_invalid_tpid(vsi, vlan->tpid);
		return false;
	}

	return true;
}

/**
 * ice_vsi_add_vlan - default add VLAN implementation for all VSI types
 * @vsi: VSI being configured
 * @vlan: VLAN filter to add
 */
int ice_vsi_add_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
{
	int err;

	if (!validate_vlan(vsi, vlan))
		return -EINVAL;

	err = ice_fltr_add_vlan(vsi, vlan);
	if (!err)
		vsi->num_vlan++;
	else if (err == -EEXIST)
		err = 0;
	else
		dev_err(ice_pf_to_dev(vsi->back), "Failure Adding VLAN %d on VSI %i, status %d\n",
			vlan->vid, vsi->vsi_num, err);

	return err;
}

/**
 * ice_vsi_del_vlan - default del VLAN implementation for all VSI types
 * @vsi: VSI being configured
 * @vlan: VLAN filter to delete
 */
int ice_vsi_del_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
{
	struct ice_pf *pf = vsi->back;
	struct device *dev;
	int err;

	if (!validate_vlan(vsi, vlan))
		return -EINVAL;

	dev = ice_pf_to_dev(pf);

	err = ice_fltr_remove_vlan(vsi, vlan);
	if (!err)
		vsi->num_vlan--;
	else if (err == -ENOENT || err == -EBUSY)
		err = 0;
	else
		dev_err(dev, "Error removing VLAN %d on VSI %i error: %d\n",
			vlan->vid, vsi->vsi_num, err);

	return err;
}

/**
 * ice_vsi_manage_vlan_insertion - Manage VLAN insertion for the VSI for Tx
 * @vsi: the VSI being changed
 */

Annotation

Implementation Notes