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

====================
Intel Wired LAN Driver Updates 2023-12-27 (igc)

This series contains updates to igc driver only.

Kurt Kanzenbach resolves issues around VLAN ntuple rules; correctly
reporting back added rules and checking for valid values.

* '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue:
  igc: Check VLAN EtherType mask
  igc: Check VLAN TCI mask
  igc: Report VLAN EtherType matching back to user
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 0fa4f912 7afd49a3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -568,6 +568,7 @@ struct igc_nfc_filter {
	u16 etype;
	__be16 vlan_etype;
	u16 vlan_tci;
	u16 vlan_tci_mask;
	u8 src_addr[ETH_ALEN];
	u8 dst_addr[ETH_ALEN];
	u8 user_data[8];
+39 −3
Original line number Diff line number Diff line
@@ -958,6 +958,7 @@ static int igc_ethtool_set_coalesce(struct net_device *netdev,
}

#define ETHER_TYPE_FULL_MASK ((__force __be16)~0)
#define VLAN_TCI_FULL_MASK ((__force __be16)~0)
static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter,
				    struct ethtool_rxnfc *cmd)
{
@@ -980,10 +981,16 @@ static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter,
		fsp->m_u.ether_spec.h_proto = ETHER_TYPE_FULL_MASK;
	}

	if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE) {
		fsp->flow_type |= FLOW_EXT;
		fsp->h_ext.vlan_etype = rule->filter.vlan_etype;
		fsp->m_ext.vlan_etype = ETHER_TYPE_FULL_MASK;
	}

	if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
		fsp->flow_type |= FLOW_EXT;
		fsp->h_ext.vlan_tci = htons(rule->filter.vlan_tci);
		fsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK);
		fsp->m_ext.vlan_tci = htons(rule->filter.vlan_tci_mask);
	}

	if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
@@ -1218,6 +1225,7 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule,

	if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) {
		rule->filter.vlan_tci = ntohs(fsp->h_ext.vlan_tci);
		rule->filter.vlan_tci_mask = ntohs(fsp->m_ext.vlan_tci);
		rule->filter.match_flags |= IGC_FILTER_FLAG_VLAN_TCI;
	}

@@ -1255,11 +1263,19 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule,
		memcpy(rule->filter.user_mask, fsp->m_ext.data, sizeof(fsp->m_ext.data));
	}

	/* When multiple filter options or user data or vlan etype is set, use a
	 * flex filter.
	/* The i225/i226 has various different filters. Flex filters provide a
	 * way to match up to the first 128 bytes of a packet. Use them for:
	 *   a) For specific user data
	 *   b) For VLAN EtherType
	 *   c) For full TCI match
	 *   d) Or in case multiple filter criteria are set
	 *
	 * Otherwise, use the simple MAC, VLAN PRIO or EtherType filters.
	 */
	if ((rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) ||
	    (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE) ||
	    ((rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) &&
	     rule->filter.vlan_tci_mask == ntohs(VLAN_TCI_FULL_MASK)) ||
	    (rule->filter.match_flags & (rule->filter.match_flags - 1)))
		rule->flex = true;
	else
@@ -1329,6 +1345,26 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter,
		return -EINVAL;
	}

	/* There are two ways to match the VLAN TCI:
	 *  1. Match on PCP field and use vlan prio filter for it
	 *  2. Match on complete TCI field and use flex filter for it
	 */
	if ((fsp->flow_type & FLOW_EXT) &&
	    fsp->m_ext.vlan_tci &&
	    fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK) &&
	    fsp->m_ext.vlan_tci != VLAN_TCI_FULL_MASK) {
		netdev_dbg(netdev, "VLAN mask not supported\n");
		return -EOPNOTSUPP;
	}

	/* VLAN EtherType can only be matched by full mask. */
	if ((fsp->flow_type & FLOW_EXT) &&
	    fsp->m_ext.vlan_etype &&
	    fsp->m_ext.vlan_etype != ETHER_TYPE_FULL_MASK) {
		netdev_dbg(netdev, "VLAN EtherType mask not supported\n");
		return -EOPNOTSUPP;
	}

	if (fsp->location >= IGC_MAX_RXNFC_RULES) {
		netdev_dbg(netdev, "Invalid location\n");
		return -EINVAL;