Commit b77c1e3b authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue

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.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 0fa4f912 7afd49a3
...@@ -568,6 +568,7 @@ struct igc_nfc_filter { ...@@ -568,6 +568,7 @@ struct igc_nfc_filter {
u16 etype; u16 etype;
__be16 vlan_etype; __be16 vlan_etype;
u16 vlan_tci; u16 vlan_tci;
u16 vlan_tci_mask;
u8 src_addr[ETH_ALEN]; u8 src_addr[ETH_ALEN];
u8 dst_addr[ETH_ALEN]; u8 dst_addr[ETH_ALEN];
u8 user_data[8]; u8 user_data[8];
......
...@@ -958,6 +958,7 @@ static int igc_ethtool_set_coalesce(struct net_device *netdev, ...@@ -958,6 +958,7 @@ static int igc_ethtool_set_coalesce(struct net_device *netdev,
} }
#define ETHER_TYPE_FULL_MASK ((__force __be16)~0) #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, static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter,
struct ethtool_rxnfc *cmd) struct ethtool_rxnfc *cmd)
{ {
...@@ -980,10 +981,16 @@ static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter, ...@@ -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; 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) { if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
fsp->flow_type |= FLOW_EXT; fsp->flow_type |= FLOW_EXT;
fsp->h_ext.vlan_tci = htons(rule->filter.vlan_tci); 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) { 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, ...@@ -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) { 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 = 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; 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, ...@@ -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)); 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 /* The i225/i226 has various different filters. Flex filters provide a
* flex filter. * 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) || 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_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->filter.match_flags & (rule->filter.match_flags - 1)))
rule->flex = true; rule->flex = true;
else else
...@@ -1329,6 +1345,26 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter, ...@@ -1329,6 +1345,26 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter,
return -EINVAL; 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) { if (fsp->location >= IGC_MAX_RXNFC_RULES) {
netdev_dbg(netdev, "Invalid location\n"); netdev_dbg(netdev, "Invalid location\n");
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment