Commit 42a09d93 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
40GbE Intel Wired LAN Driver Updates 2022-06-07

This series contains updates to i40e and iavf drivers.

Mateusz adds implementation for setting VF VLAN pruning to allow user to
specify visibility of VLAN tagged traffic to VFs for i40e. He also adds
waiting for result from PF for setting MAC address in iavf.
====================

Link: https://lore.kernel.org/r/20220607175506.696671-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents a84a434b 35a2443d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -565,6 +565,7 @@ struct i40e_pf {
#define I40E_FLAG_DISABLE_FW_LLDP		BIT(24)
#define I40E_FLAG_RS_FEC			BIT(25)
#define I40E_FLAG_BASE_R_FEC			BIT(26)
#define I40E_FLAG_VF_VLAN_PRUNING		BIT(27)
/* TOTAL_PORT_SHUTDOWN
 * Allows to physically disable the link on the NIC's port.
 * If enabled, (after link down request from the OS)
+9 −0
Original line number Diff line number Diff line
@@ -457,6 +457,8 @@ static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
	I40E_PRIV_FLAG("disable-fw-lldp", I40E_FLAG_DISABLE_FW_LLDP, 0),
	I40E_PRIV_FLAG("rs-fec", I40E_FLAG_RS_FEC, 0),
	I40E_PRIV_FLAG("base-r-fec", I40E_FLAG_BASE_R_FEC, 0),
	I40E_PRIV_FLAG("vf-vlan-pruning",
		       I40E_FLAG_VF_VLAN_PRUNING, 0),
};

#define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gstrings_priv_flags)
@@ -5285,6 +5287,13 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
		return -EOPNOTSUPP;
	}

	if ((changed_flags & I40E_FLAG_VF_VLAN_PRUNING) &&
	    pf->num_alloc_vfs) {
		dev_warn(&pf->pdev->dev,
			 "Changing vf-vlan-pruning flag while VF(s) are active is not supported\n");
		return -EOPNOTSUPP;
	}

	if ((changed_flags & new_flags &
	     I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&
	    (new_flags & I40E_FLAG_MFP_ENABLED))
+130 −5
Original line number Diff line number Diff line
@@ -1368,6 +1368,114 @@ static int i40e_correct_mac_vlan_filters(struct i40e_vsi *vsi,
	return 0;
}

/**
 * i40e_get_vf_new_vlan - Get new vlan id on a vf
 * @vsi: the vsi to configure
 * @new_mac: new mac filter to be added
 * @f: existing mac filter, replaced with new_mac->f if new_mac is not NULL
 * @vlan_filters: the number of active VLAN filters
 * @trusted: flag if the VF is trusted
 *
 * Get new VLAN id based on current VLAN filters, trust, PVID
 * and vf-vlan-prune-disable flag.
 *
 * Returns the value of the new vlan filter or
 * the old value if no new filter is needed.
 */
static s16 i40e_get_vf_new_vlan(struct i40e_vsi *vsi,
				struct i40e_new_mac_filter *new_mac,
				struct i40e_mac_filter *f,
				int vlan_filters,
				bool trusted)
{
	s16 pvid = le16_to_cpu(vsi->info.pvid);
	struct i40e_pf *pf = vsi->back;
	bool is_any;

	if (new_mac)
		f = new_mac->f;

	if (pvid && f->vlan != pvid)
		return pvid;

	is_any = (trusted ||
		  !(pf->flags & I40E_FLAG_VF_VLAN_PRUNING));

	if ((vlan_filters && f->vlan == I40E_VLAN_ANY) ||
	    (!is_any && !vlan_filters && f->vlan == I40E_VLAN_ANY) ||
	    (is_any && !vlan_filters && f->vlan == 0)) {
		if (is_any)
			return I40E_VLAN_ANY;
		else
			return 0;
	}

	return f->vlan;
}

/**
 * i40e_correct_vf_mac_vlan_filters - Correct non-VLAN VF filters if necessary
 * @vsi: the vsi to configure
 * @tmp_add_list: list of filters ready to be added
 * @tmp_del_list: list of filters ready to be deleted
 * @vlan_filters: the number of active VLAN filters
 * @trusted: flag if the VF is trusted
 *
 * Correct VF VLAN filters based on current VLAN filters, trust, PVID
 * and vf-vlan-prune-disable flag.
 *
 * In case of memory allocation failure return -ENOMEM. Otherwise, return 0.
 *
 * This function is only expected to be called from within
 * i40e_sync_vsi_filters.
 *
 * NOTE: This function expects to be called while under the
 * mac_filter_hash_lock
 */
static int i40e_correct_vf_mac_vlan_filters(struct i40e_vsi *vsi,
					    struct hlist_head *tmp_add_list,
					    struct hlist_head *tmp_del_list,
					    int vlan_filters,
					    bool trusted)
{
	struct i40e_mac_filter *f, *add_head;
	struct i40e_new_mac_filter *new_mac;
	struct hlist_node *h;
	int bkt, new_vlan;

	hlist_for_each_entry(new_mac, tmp_add_list, hlist) {
		new_mac->f->vlan = i40e_get_vf_new_vlan(vsi, new_mac, NULL,
							vlan_filters, trusted);
	}

	hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
		new_vlan = i40e_get_vf_new_vlan(vsi, NULL, f, vlan_filters,
						trusted);
		if (new_vlan != f->vlan) {
			add_head = i40e_add_filter(vsi, f->macaddr, new_vlan);
			if (!add_head)
				return -ENOMEM;
			/* Create a temporary i40e_new_mac_filter */
			new_mac = kzalloc(sizeof(*new_mac), GFP_ATOMIC);
			if (!new_mac)
				return -ENOMEM;
			new_mac->f = add_head;
			new_mac->state = add_head->state;

			/* Add the new filter to the tmp list */
			hlist_add_head(&new_mac->hlist, tmp_add_list);

			/* Put the original filter into the delete list */
			f->state = I40E_FILTER_REMOVE;
			hash_del(&f->hlist);
			hlist_add_head(&f->hlist, tmp_del_list);
		}
	}

	vsi->has_vlan_filter = !!vlan_filters;
	return 0;
}

/**
 * i40e_rm_default_mac_filter - Remove the default MAC filter set by NVM
 * @vsi: the PF Main VSI - inappropriate for any other VSI
@@ -2423,10 +2531,14 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
				vlan_filters++;
		}

		retval = i40e_correct_mac_vlan_filters(vsi,
						       &tmp_add_list,
						       &tmp_del_list,
		if (vsi->type != I40E_VSI_SRIOV)
			retval = i40e_correct_mac_vlan_filters
				(vsi, &tmp_add_list, &tmp_del_list,
				 vlan_filters);
		else
			retval = i40e_correct_vf_mac_vlan_filters
				(vsi, &tmp_add_list, &tmp_del_list,
				 vlan_filters, pf->vf[vsi->vf_id].trusted);

		hlist_for_each_entry(new, &tmp_add_list, hlist)
			netdev_hw_addr_refcnt(new->f, vsi->netdev, 1);
@@ -2855,8 +2967,21 @@ int i40e_add_vlan_all_mac(struct i40e_vsi *vsi, s16 vid)
	int bkt;

	hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
		if (f->state == I40E_FILTER_REMOVE)
		/* If we're asked to add a filter that has been marked for
		 * removal, it is safe to simply restore it to active state.
		 * __i40e_del_filter will have simply deleted any filters which
		 * were previously marked NEW or FAILED, so if it is currently
		 * marked REMOVE it must have previously been ACTIVE. Since we
		 * haven't yet run the sync filters task, just restore this
		 * filter to the ACTIVE state so that the sync task leaves it
		 * in place.
		 */
		if (f->state == I40E_FILTER_REMOVE && f->vlan == vid) {
			f->state = I40E_FILTER_ACTIVE;
			continue;
		} else if (f->state == I40E_FILTER_REMOVE) {
			continue;
		}
		add_f = i40e_add_filter(vsi, f->macaddr, vid);
		if (!add_f) {
			dev_info(&vsi->back->pdev->dev,
+7 −1
Original line number Diff line number Diff line
@@ -4349,6 +4349,7 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
		/* duplicate request, so just return success */
		goto error_pvid;

	i40e_vlan_stripping_enable(vsi);
	i40e_vc_reset_vf(vf, true);
	/* During reset the VF got a new VSI, so refresh a pointer. */
	vsi = pf->vsi[vf->lan_vsi_idx];
@@ -4727,6 +4728,11 @@ int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting)
		goto out;

	vf->trusted = setting;

	/* request PF to sync mac/vlan filters for the VF */
	set_bit(__I40E_MACVLAN_SYNC_PENDING, pf->state);
	pf->vsi[vf->lan_vsi_idx]->flags |= I40E_VSI_FLAG_FILTER_CHANGED;

	i40e_vc_reset_vf(vf, true);
	dev_info(&pf->pdev->dev, "VF %u is now %strusted\n",
		 vf_id, setting ? "" : "un");
+6 −1
Original line number Diff line number Diff line
@@ -146,7 +146,8 @@ struct iavf_mac_filter {
		u8 remove:1;        /* filter needs to be removed */
		u8 add:1;           /* filter needs to be added */
		u8 is_primary:1;    /* filter is a default VF MAC */
		u8 padding:4;
		u8 add_handled:1;   /* received response for filter add */
		u8 padding:3;
	};
};

@@ -248,6 +249,7 @@ struct iavf_adapter {
	struct work_struct adminq_task;
	struct delayed_work client_task;
	wait_queue_head_t down_waitqueue;
	wait_queue_head_t vc_waitqueue;
	struct iavf_q_vector *q_vectors;
	struct list_head vlan_filter_list;
	struct list_head mac_filter_list;
@@ -292,6 +294,7 @@ struct iavf_adapter {
#define IAVF_FLAG_QUEUES_DISABLED		BIT(17)
#define IAVF_FLAG_SETUP_NETDEV_FEATURES		BIT(18)
#define IAVF_FLAG_REINIT_MSIX_NEEDED		BIT(20)
#define IAVF_FLAG_INITIAL_MAC_SET		BIT(23)
/* duplicates for common code */
#define IAVF_FLAG_DCB_ENABLED			0
	/* flags for admin queue service task */
@@ -559,6 +562,8 @@ void iavf_enable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid);
void iavf_disable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid);
void iavf_enable_vlan_insertion_v2(struct iavf_adapter *adapter, u16 tpid);
void iavf_disable_vlan_insertion_v2(struct iavf_adapter *adapter, u16 tpid);
int iavf_replace_primary_mac(struct iavf_adapter *adapter,
			     const u8 *new_mac);
void
iavf_set_vlan_offload_features(struct iavf_adapter *adapter,
			       netdev_features_t prev_features,
Loading