Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1042026/?format=api
{ "id": 1042026, "url": "http://patchwork.ozlabs.org/api/patches/1042026/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20190214113137.17808-1-sasha.neftin@intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20190214113137.17808-1-sasha.neftin@intel.com>", "list_archive_url": null, "date": "2019-02-14T11:31:37", "name": "[v1,1/1] igc: Extend the ethtool supporting", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "cbe90210f4d9d4061c2f137fdc34789be8399b01", "submitter": { "id": 69860, "url": "http://patchwork.ozlabs.org/api/people/69860/?format=api", "name": "Sasha Neftin", "email": "sasha.neftin@intel.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20190214113137.17808-1-sasha.neftin@intel.com/mbox/", "series": [ { "id": 91960, "url": "http://patchwork.ozlabs.org/api/series/91960/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=91960", "date": "2019-02-14T11:31:37", "name": "[v1,1/1] igc: Extend the ethtool supporting", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/91960/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1042026/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1042026/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.133; helo=hemlock.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=intel.com" ], "Received": [ "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 440Z3l3clLz9sMp\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 14 Feb 2019 22:31:46 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 900C58753D;\n\tThu, 14 Feb 2019 11:31:45 +0000 (UTC)", "from hemlock.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id O8T-dVlmxp85; Thu, 14 Feb 2019 11:31:43 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id EA26287527;\n\tThu, 14 Feb 2019 11:31:43 +0000 (UTC)", "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id 6189F1BF42D\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Feb 2019 11:31:42 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 5CC2587527\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Feb 2019 11:31:42 +0000 (UTC)", "from hemlock.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id pnCBIdBup5dd for <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Feb 2019 11:31:40 +0000 (UTC)", "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby hemlock.osuosl.org (Postfix) with ESMTPS id 58B1487526\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Feb 2019 11:31:40 +0000 (UTC)", "from orsmga005.jf.intel.com ([10.7.209.41])\n\tby fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t14 Feb 2019 03:31:39 -0800", "from ccdlinuxdev08.iil.intel.com ([143.185.161.150])\n\tby orsmga005.jf.intel.com with ESMTP; 14 Feb 2019 03:31:38 -0800" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "X-Amp-Result": "SKIPPED(no attachment in message)", "X-Amp-File-Uploaded": "False", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.58,368,1544515200\"; d=\"scan'208\";a=\"299696281\"", "From": "Sasha Neftin <sasha.neftin@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Thu, 14 Feb 2019 13:31:37 +0200", "Message-Id": "<20190214113137.17808-1-sasha.neftin@intel.com>", "X-Mailer": "git-send-email 2.11.0", "Subject": "[Intel-wired-lan] [PATCH v1 1/1] igc: Extend the ethtool supporting", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "Add show and configure nfc methods to the ethtool.\nShow the specifies Rx ntuple filters.\nConfigures receive network flow classification option or rules.\n\nSigned-off-by: Sasha Neftin <sasha.neftin@intel.com>\n---\n drivers/net/ethernet/intel/igc/igc.h | 55 ++-\n drivers/net/ethernet/intel/igc/igc_defines.h | 4 +\n drivers/net/ethernet/intel/igc/igc_ethtool.c | 602 +++++++++++++++++++++++++++\n drivers/net/ethernet/intel/igc/igc_main.c | 145 +++++++\n drivers/net/ethernet/intel/igc/igc_regs.h | 11 +\n 5 files changed, 814 insertions(+), 3 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h\nindex 473a65c51382..7eee12972d86 100644\n--- a/drivers/net/ethernet/intel/igc/igc.h\n+++ b/drivers/net/ethernet/intel/igc/igc.h\n@@ -33,6 +33,10 @@ void igc_write_rss_indir_tbl(struct igc_adapter *adapter);\n bool igc_has_link(struct igc_adapter *adapter);\n void igc_reset(struct igc_adapter *adapter);\n int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx);\n+int igc_add_mac_steering_filter(struct igc_adapter *adapter,\n+\t\t\t\tconst u8 *addr, u8 queue, u8 flags);\n+int igc_del_mac_steering_filter(struct igc_adapter *adapter,\n+\t\t\t\tconst u8 *addr, u8 queue, u8 flags);\n \n extern char igc_driver_name[];\n extern char igc_driver_version[];\n@@ -292,15 +296,50 @@ struct igc_q_vector {\n \tstruct igc_ring ring[0] ____cacheline_internodealigned_in_smp;\n };\n \n+#define MAX_ETYPE_FILTER\t\t(4 - 1)\n+\n+enum igc_filter_match_flags {\n+\tIGC_FILTER_FLAG_ETHER_TYPE =\t0x1,\n+\tIGC_FILTER_FLAG_VLAN_TCI =\t0x2,\n+\tIGC_FILTER_FLAG_SRC_MAC_ADDR =\t0x4,\n+\tIGC_FILTER_FLAG_DST_MAC_ADDR =\t0x8,\n+};\n+\n+/* RX network flow classification data structure */\n+struct igc_nfc_input {\n+\t/* Byte layout in order, all values with MSB first:\n+\t * match_flags - 1 byte\n+\t * etype - 2 bytes\n+\t * vlan_tci - 2 bytes\n+\t */\n+\tu8 match_flags;\n+\t__be16 etype;\n+\t__be16 vlan_tci;\n+\tu8 src_addr[ETH_ALEN];\n+\tu8 dst_addr[ETH_ALEN];\n+};\n+\n+struct igc_nfc_filter {\n+\tstruct hlist_node nfc_node;\n+\tstruct igc_nfc_input filter;\n+\tunsigned long cookie;\n+\tu16 etype_reg_index;\n+\tu16 sw_idx;\n+\tu16 action;\n+};\n+\n struct igc_mac_addr {\n \tu8 addr[ETH_ALEN];\n \tu8 queue;\n \tu8 state; /* bitmask */\n };\n \n-#define IGC_MAC_STATE_DEFAULT\t0x1\n-#define IGC_MAC_STATE_MODIFIED\t0x2\n-#define IGC_MAC_STATE_IN_USE\t0x4\n+#define IGC_MAC_STATE_DEFAULT\t\t0x1\n+#define IGC_MAC_STATE_IN_USE\t\t0x2\n+#define IGC_MAC_STATE_SRC_ADDR\t\t0x4\n+#define IGC_MAC_STATE_QUEUE_STEERING\t0x8\n+\n+#define IGC_MAX_RXNFC_FILTERS\t\t16\n \n /* Board specific private data structure */\n struct igc_adapter {\n@@ -369,8 +408,14 @@ struct igc_adapter {\n \tu32 rss_queues;\n \tu32 rss_indir_tbl_init;\n \n+\t/* RX network flow classification support */\n+\tstruct hlist_head nfc_filter_list;\n+\tstruct hlist_head cls_flower_list;\n+\tunsigned int nfc_filter_count;\n+\n \t/* lock for RX network flow classification filter */\n \tspinlock_t nfc_lock;\n+\tbool etype_bitmap[MAX_ETYPE_FILTER];\n \n \tstruct igc_mac_addr *mac_table;\n \n@@ -456,6 +501,10 @@ static inline s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data)\n \n /* forward declaration */\n void igc_reinit_locked(struct igc_adapter *);\n+int igc_add_filter(struct igc_adapter *adapter,\n+\t\t struct igc_nfc_filter *input);\n+int igc_erase_filter(struct igc_adapter *adapter,\n+\t\t struct igc_nfc_filter *input);\n \n #define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))\n \ndiff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h\nindex 3666f8837cc8..925c89b57ec5 100644\n--- a/drivers/net/ethernet/intel/igc/igc_defines.h\n+++ b/drivers/net/ethernet/intel/igc/igc_defines.h\n@@ -400,4 +400,8 @@\n \n #define IGC_N0_QUEUE -1\n \n+#define IGC_VLAPQF_QUEUE_SEL(_n, q_idx) ((q_idx) << ((_n) * 4))\n+#define IGC_VLAPQF_P_VALID(_n)\t(0x1 << (3 + (_n) * 4))\n+#define IGC_VLAPQF_QUEUE_MASK\t0x03\n+\n #endif /* _IGC_DEFINES_H_ */\ndiff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c\nindex eff37a6c0afa..25d14fc82bf8 100644\n--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c\n+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c\n@@ -2,6 +2,7 @@\n /* Copyright (c) 2018 Intel Corporation */\n \n /* ethtool support for igc */\n+#include <linux/if_vlan.h>\n #include <linux/pm_runtime.h>\n \n #include \"igc.h\"\n@@ -643,6 +644,605 @@ static int igc_set_coalesce(struct net_device *netdev,\n \treturn 0;\n }\n \n+#define ETHER_TYPE_FULL_MASK ((__force __be16)~0)\n+static int igc_get_ethtool_nfc_entry(struct igc_adapter *adapter,\n+\t\t\t\t struct ethtool_rxnfc *cmd)\n+{\n+\tstruct ethtool_rx_flow_spec *fsp = &cmd->fs;\n+\tstruct igc_nfc_filter *rule = NULL;\n+\n+\t/* report total rule count */\n+\tcmd->data = IGC_MAX_RXNFC_FILTERS;\n+\n+\thlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) {\n+\t\tif (fsp->location <= rule->sw_idx)\n+\t\t\tbreak;\n+\t}\n+\n+\tif (!rule || fsp->location != rule->sw_idx)\n+\t\treturn -EINVAL;\n+\n+\tif (rule->filter.match_flags) {\n+\t\tfsp->flow_type = ETHER_FLOW;\n+\t\tfsp->ring_cookie = rule->action;\n+\t\tif (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {\n+\t\t\tfsp->h_u.ether_spec.h_proto = rule->filter.etype;\n+\t\t\tfsp->m_u.ether_spec.h_proto = ETHER_TYPE_FULL_MASK;\n+\t\t}\n+\t\tif (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {\n+\t\t\tfsp->flow_type |= FLOW_EXT;\n+\t\t\tfsp->h_ext.vlan_tci = rule->filter.vlan_tci;\n+\t\t\tfsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK);\n+\t\t}\n+\t\tif (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {\n+\t\t\tether_addr_copy(fsp->h_u.ether_spec.h_dest,\n+\t\t\t\t\trule->filter.dst_addr);\n+\t\t\t/* As we only support matching by the full\n+\t\t\t * mask, return the mask to userspace\n+\t\t\t */\n+\t\t\teth_broadcast_addr(fsp->m_u.ether_spec.h_dest);\n+\t\t}\n+\t\tif (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {\n+\t\t\tether_addr_copy(fsp->h_u.ether_spec.h_source,\n+\t\t\t\t\trule->filter.src_addr);\n+\t\t\t/* As we only support matching by the full\n+\t\t\t * mask, return the mask to userspace\n+\t\t\t */\n+\t\t\teth_broadcast_addr(fsp->m_u.ether_spec.h_source);\n+\t\t}\n+\n+\t\treturn 0;\n+\t}\n+\treturn -EINVAL;\n+}\n+\n+static int igc_get_ethtool_nfc_all(struct igc_adapter *adapter,\n+\t\t\t\t struct ethtool_rxnfc *cmd,\n+\t\t\t\t u32 *rule_locs)\n+{\n+\tstruct igc_nfc_filter *rule;\n+\tint cnt = 0;\n+\n+\t/* report total rule count */\n+\tcmd->data = IGC_MAX_RXNFC_FILTERS;\n+\n+\thlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) {\n+\t\tif (cnt == cmd->rule_cnt)\n+\t\t\treturn -EMSGSIZE;\n+\t\trule_locs[cnt] = rule->sw_idx;\n+\t\tcnt++;\n+\t}\n+\n+\tcmd->rule_cnt = cnt;\n+\n+\treturn 0;\n+}\n+\n+static int igc_get_rss_hash_opts(struct igc_adapter *adapter,\n+\t\t\t\t struct ethtool_rxnfc *cmd)\n+{\n+\tcmd->data = 0;\n+\n+\t/* Report default options for RSS on igc */\n+\tswitch (cmd->flow_type) {\n+\tcase TCP_V4_FLOW:\n+\t\tcmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;\n+\t\t/* Fall through */\n+\tcase UDP_V4_FLOW:\n+\t\tif (adapter->flags & IGC_FLAG_RSS_FIELD_IPV4_UDP)\n+\t\t\tcmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;\n+\t\t/* Fall through */\n+\tcase SCTP_V4_FLOW:\n+\t\t/* Fall through */\n+\tcase AH_ESP_V4_FLOW:\n+\t\t/* Fall through */\n+\tcase AH_V4_FLOW:\n+\t\t/* Fall through */\n+\tcase ESP_V4_FLOW:\n+\t\t/* Fall through */\n+\tcase IPV4_FLOW:\n+\t\tcmd->data |= RXH_IP_SRC | RXH_IP_DST;\n+\t\tbreak;\n+\tcase TCP_V6_FLOW:\n+\t\tcmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;\n+\t\t/* Fall through */\n+\tcase UDP_V6_FLOW:\n+\t\tif (adapter->flags & IGC_FLAG_RSS_FIELD_IPV6_UDP)\n+\t\t\tcmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;\n+\t\t/* Fall through */\n+\tcase SCTP_V6_FLOW:\n+\t\t/* Fall through */\n+\tcase AH_ESP_V6_FLOW:\n+\t\t/* Fall through */\n+\tcase AH_V6_FLOW:\n+\t\t/* Fall through */\n+\tcase ESP_V6_FLOW:\n+\t\t/* Fall through */\n+\tcase IPV6_FLOW:\n+\t\tcmd->data |= RXH_IP_SRC | RXH_IP_DST;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int igc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,\n+\t\t\t u32 *rule_locs)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(dev);\n+\tint ret = -EOPNOTSUPP;\n+\n+\tswitch (cmd->cmd) {\n+\tcase ETHTOOL_GRXRINGS:\n+\t\tcmd->data = adapter->num_rx_queues;\n+\t\tret = 0;\n+\t\tbreak;\n+\tcase ETHTOOL_GRXCLSRLCNT:\n+\t\tcmd->rule_cnt = adapter->nfc_filter_count;\n+\t\tret = 0;\n+\t\tbreak;\n+\tcase ETHTOOL_GRXCLSRULE:\n+\t\tret = igc_get_ethtool_nfc_entry(adapter, cmd);\n+\t\tbreak;\n+\tcase ETHTOOL_GRXCLSRLALL:\n+\t\tret = igc_get_ethtool_nfc_all(adapter, cmd, rule_locs);\n+\t\tbreak;\n+\tcase ETHTOOL_GRXFH:\n+\t\tret = igc_get_rss_hash_opts(adapter, cmd);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+#define UDP_RSS_FLAGS (IGC_FLAG_RSS_FIELD_IPV4_UDP | \\\n+\t\t IGC_FLAG_RSS_FIELD_IPV6_UDP)\n+static int igc_set_rss_hash_opt(struct igc_adapter *adapter,\n+\t\t\t\tstruct ethtool_rxnfc *nfc)\n+{\n+\tu32 flags = adapter->flags;\n+\n+\t/* RSS does not support anything other than hashing\n+\t * to queues on src and dst IPs and ports\n+\t */\n+\tif (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |\n+\t\t\t RXH_L4_B_0_1 | RXH_L4_B_2_3))\n+\t\treturn -EINVAL;\n+\n+\tswitch (nfc->flow_type) {\n+\tcase TCP_V4_FLOW:\n+\tcase TCP_V6_FLOW:\n+\t\tif (!(nfc->data & RXH_IP_SRC) ||\n+\t\t !(nfc->data & RXH_IP_DST) ||\n+\t\t !(nfc->data & RXH_L4_B_0_1) ||\n+\t\t !(nfc->data & RXH_L4_B_2_3))\n+\t\t\treturn -EINVAL;\n+\t\tbreak;\n+\tcase UDP_V4_FLOW:\n+\t\tif (!(nfc->data & RXH_IP_SRC) ||\n+\t\t !(nfc->data & RXH_IP_DST))\n+\t\t\treturn -EINVAL;\n+\t\tswitch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {\n+\t\tcase 0:\n+\t\t\tflags &= ~IGC_FLAG_RSS_FIELD_IPV4_UDP;\n+\t\t\tbreak;\n+\t\tcase (RXH_L4_B_0_1 | RXH_L4_B_2_3):\n+\t\t\tflags |= IGC_FLAG_RSS_FIELD_IPV4_UDP;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tbreak;\n+\tcase UDP_V6_FLOW:\n+\t\tif (!(nfc->data & RXH_IP_SRC) ||\n+\t\t !(nfc->data & RXH_IP_DST))\n+\t\t\treturn -EINVAL;\n+\t\tswitch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {\n+\t\tcase 0:\n+\t\t\tflags &= ~IGC_FLAG_RSS_FIELD_IPV6_UDP;\n+\t\t\tbreak;\n+\t\tcase (RXH_L4_B_0_1 | RXH_L4_B_2_3):\n+\t\t\tflags |= IGC_FLAG_RSS_FIELD_IPV6_UDP;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tbreak;\n+\tcase AH_ESP_V4_FLOW:\n+\tcase AH_V4_FLOW:\n+\tcase ESP_V4_FLOW:\n+\tcase SCTP_V4_FLOW:\n+\tcase AH_ESP_V6_FLOW:\n+\tcase AH_V6_FLOW:\n+\tcase ESP_V6_FLOW:\n+\tcase SCTP_V6_FLOW:\n+\t\tif (!(nfc->data & RXH_IP_SRC) ||\n+\t\t !(nfc->data & RXH_IP_DST) ||\n+\t\t (nfc->data & RXH_L4_B_0_1) ||\n+\t\t (nfc->data & RXH_L4_B_2_3))\n+\t\t\treturn -EINVAL;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* if we changed something we need to update flags */\n+\tif (flags != adapter->flags) {\n+\t\tstruct igc_hw *hw = &adapter->hw;\n+\t\tu32 mrqc = rd32(IGC_MRQC);\n+\n+\t\tif ((flags & UDP_RSS_FLAGS) &&\n+\t\t !(adapter->flags & UDP_RSS_FLAGS))\n+\t\t\tdev_err(&adapter->pdev->dev,\n+\t\t\t\t\"enabling UDP RSS: fragmented packets may arrive out of order to the stack above\\n\");\n+\n+\t\tadapter->flags = flags;\n+\n+\t\t/* Perform hash on these packet types */\n+\t\tmrqc |= IGC_MRQC_RSS_FIELD_IPV4 |\n+\t\t\tIGC_MRQC_RSS_FIELD_IPV4_TCP |\n+\t\t\tIGC_MRQC_RSS_FIELD_IPV6 |\n+\t\t\tIGC_MRQC_RSS_FIELD_IPV6_TCP;\n+\n+\t\tmrqc &= ~(IGC_MRQC_RSS_FIELD_IPV4_UDP |\n+\t\t\t IGC_MRQC_RSS_FIELD_IPV6_UDP);\n+\n+\t\tif (flags & IGC_FLAG_RSS_FIELD_IPV4_UDP)\n+\t\t\tmrqc |= IGC_MRQC_RSS_FIELD_IPV4_UDP;\n+\n+\t\tif (flags & IGC_FLAG_RSS_FIELD_IPV6_UDP)\n+\t\t\tmrqc |= IGC_MRQC_RSS_FIELD_IPV6_UDP;\n+\n+\t\twr32(IGC_MRQC, mrqc);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int igc_rxnfc_write_etype_filter(struct igc_adapter *adapter,\n+\t\t\t\t\tstruct igc_nfc_filter *input)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu8 i;\n+\tu32 etqf;\n+\tu16 etype;\n+\n+\t/* find an empty etype filter register */\n+\tfor (i = 0; i < MAX_ETYPE_FILTER; ++i) {\n+\t\tif (!adapter->etype_bitmap[i])\n+\t\t\tbreak;\n+\t}\n+\tif (i == MAX_ETYPE_FILTER) {\n+\t\tdev_err(&adapter->pdev->dev, \"ethtool -N: etype filters are all used.\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tadapter->etype_bitmap[i] = true;\n+\n+\tetqf = rd32(IGC_ETQF(i));\n+\tetype = ntohs(input->filter.etype & ETHER_TYPE_FULL_MASK);\n+\n+\tetqf |= IGC_ETQF_FILTER_ENABLE;\n+\tetqf &= ~IGC_ETQF_ETYPE_MASK;\n+\tetqf |= (etype & IGC_ETQF_ETYPE_MASK);\n+\n+\tetqf &= ~IGC_ETQF_QUEUE_MASK;\n+\tetqf |= ((input->action << IGC_ETQF_QUEUE_SHIFT)\n+\t\t& IGC_ETQF_QUEUE_MASK);\n+\tetqf |= IGC_ETQF_QUEUE_ENABLE;\n+\n+\twr32(IGC_ETQF(i), etqf);\n+\n+\tinput->etype_reg_index = i;\n+\n+\treturn 0;\n+}\n+\n+static int igc_rxnfc_write_vlan_prio_filter(struct igc_adapter *adapter,\n+\t\t\t\t\t struct igc_nfc_filter *input)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu8 vlan_priority;\n+\tu16 queue_index;\n+\tu32 vlapqf;\n+\n+\tvlapqf = rd32(IGC_VLAPQF);\n+\tvlan_priority = (ntohs(input->filter.vlan_tci) & VLAN_PRIO_MASK)\n+\t\t\t\t>> VLAN_PRIO_SHIFT;\n+\tqueue_index = (vlapqf >> (vlan_priority * 4)) & IGC_VLAPQF_QUEUE_MASK;\n+\n+\t/* check whether this vlan prio is already set */\n+\tif (vlapqf & IGC_VLAPQF_P_VALID(vlan_priority) &&\n+\t queue_index != input->action) {\n+\t\tdev_err(&adapter->pdev->dev, \"ethtool rxnfc set vlan prio filter failed.\\n\");\n+\t\treturn -EEXIST;\n+\t}\n+\n+\tvlapqf |= IGC_VLAPQF_P_VALID(vlan_priority);\n+\tvlapqf |= IGC_VLAPQF_QUEUE_SEL(vlan_priority, input->action);\n+\n+\twr32(IGC_VLAPQF, vlapqf);\n+\n+\treturn 0;\n+}\n+\n+int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tint err = -EINVAL;\n+\n+\tif (hw->mac.type == igc_i225 &&\n+\t !(input->filter.match_flags & ~IGC_FILTER_FLAG_SRC_MAC_ADDR)) {\n+\t\tdev_err(&adapter->pdev->dev,\n+\t\t\t\"i225 doesn't support flow classification rules specifying only source addresses.\\n\");\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\tif (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {\n+\t\terr = igc_rxnfc_write_etype_filter(adapter, input);\n+\t\tif (err)\n+\t\t\treturn err;\n+\t}\n+\n+\tif (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {\n+\t\terr = igc_add_mac_steering_filter(adapter,\n+\t\t\t\t\t\t input->filter.dst_addr,\n+\t\t\t\t\t\t input->action, 0);\n+\t\terr = min_t(int, err, 0);\n+\t\tif (err)\n+\t\t\treturn err;\n+\t}\n+\n+\tif (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {\n+\t\terr = igc_add_mac_steering_filter(adapter,\n+\t\t\t\t\t\t input->filter.src_addr,\n+\t\t\t\t\t\t input->action,\n+\t\t\t\t\t\t IGC_MAC_STATE_SRC_ADDR);\n+\t\terr = min_t(int, err, 0);\n+\t\tif (err)\n+\t\t\treturn err;\n+\t}\n+\n+\tif (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI)\n+\t\terr = igc_rxnfc_write_vlan_prio_filter(adapter, input);\n+\n+\treturn err;\n+}\n+\n+static void igc_clear_etype_filter_regs(struct igc_adapter *adapter,\n+\t\t\t\t\tu16 reg_index)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 etqf = rd32(IGC_ETQF(reg_index));\n+\n+\tetqf &= ~IGC_ETQF_QUEUE_ENABLE;\n+\tetqf &= ~IGC_ETQF_QUEUE_MASK;\n+\tetqf &= ~IGC_ETQF_FILTER_ENABLE;\n+\n+\twr32(IGC_ETQF(reg_index), etqf);\n+\n+\tadapter->etype_bitmap[reg_index] = false;\n+}\n+\n+static void igc_clear_vlan_prio_filter(struct igc_adapter *adapter,\n+\t\t\t\t u16 vlan_tci)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu8 vlan_priority;\n+\tu32 vlapqf;\n+\n+\tvlan_priority = (vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;\n+\n+\tvlapqf = rd32(IGC_VLAPQF);\n+\tvlapqf &= ~IGC_VLAPQF_P_VALID(vlan_priority);\n+\tvlapqf &= ~IGC_VLAPQF_QUEUE_SEL(vlan_priority,\n+\t\t\t\t\t\tIGC_VLAPQF_QUEUE_MASK);\n+\n+\twr32(IGC_VLAPQF, vlapqf);\n+}\n+\n+int igc_erase_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)\n+{\n+\tif (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE)\n+\t\tigc_clear_etype_filter_regs(adapter,\n+\t\t\t\t\t input->etype_reg_index);\n+\n+\tif (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI)\n+\t\tigc_clear_vlan_prio_filter(adapter,\n+\t\t\t\t\t ntohs(input->filter.vlan_tci));\n+\n+\tif (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR)\n+\t\tigc_del_mac_steering_filter(adapter, input->filter.src_addr,\n+\t\t\t\t\t input->action,\n+\t\t\t\t\t IGC_MAC_STATE_SRC_ADDR);\n+\n+\tif (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)\n+\t\tigc_del_mac_steering_filter(adapter, input->filter.dst_addr,\n+\t\t\t\t\t input->action, 0);\n+\n+\treturn 0;\n+}\n+\n+static int igc_update_ethtool_nfc_entry(struct igc_adapter *adapter,\n+\t\t\t\t\tstruct igc_nfc_filter *input,\n+\t\t\t\t\tu16 sw_idx)\n+{\n+\tstruct igc_nfc_filter *rule, *parent;\n+\tint err = -EINVAL;\n+\n+\tparent = NULL;\n+\trule = NULL;\n+\n+\thlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) {\n+\t\t/* hash found, or no matching entry */\n+\t\tif (rule->sw_idx >= sw_idx)\n+\t\t\tbreak;\n+\t\tparent = rule;\n+\t}\n+\n+\t/* if there is an old rule occupying our place remove it */\n+\tif (rule && rule->sw_idx == sw_idx) {\n+\t\tif (!input)\n+\t\t\terr = igc_erase_filter(adapter, rule);\n+\n+\t\thlist_del(&rule->nfc_node);\n+\t\tkfree(rule);\n+\t\tadapter->nfc_filter_count--;\n+\t}\n+\n+\t/* If no input this was a delete, err should be 0 if a rule was\n+\t * successfully found and removed from the list else -EINVAL\n+\t */\n+\tif (!input)\n+\t\treturn err;\n+\n+\t/* initialize node */\n+\tINIT_HLIST_NODE(&input->nfc_node);\n+\n+\t/* add filter to the list */\n+\tif (parent)\n+\t\thlist_add_behind(&input->nfc_node, &parent->nfc_node);\n+\telse\n+\t\thlist_add_head(&input->nfc_node, &adapter->nfc_filter_list);\n+\n+\t/* update counts */\n+\tadapter->nfc_filter_count++;\n+\n+\treturn 0;\n+}\n+\n+static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter,\n+\t\t\t\t struct ethtool_rxnfc *cmd)\n+{\n+\tstruct net_device *netdev = adapter->netdev;\n+\tstruct ethtool_rx_flow_spec *fsp =\n+\t\t(struct ethtool_rx_flow_spec *)&cmd->fs;\n+\tstruct igc_nfc_filter *input, *rule;\n+\tint err = 0;\n+\n+\tif (!(netdev->hw_features & NETIF_F_NTUPLE))\n+\t\treturn -EOPNOTSUPP;\n+\n+\t/* Don't allow programming if the action is a queue greater than\n+\t * the number of online Rx queues.\n+\t */\n+\tif (fsp->ring_cookie == RX_CLS_FLOW_DISC ||\n+\t fsp->ring_cookie >= adapter->num_rx_queues) {\n+\t\tdev_err(&adapter->pdev->dev, \"ethtool -N: The specified action is invalid\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Don't allow indexes to exist outside of available space */\n+\tif (fsp->location >= IGC_MAX_RXNFC_FILTERS) {\n+\t\tdev_err(&adapter->pdev->dev, \"Location out of range\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif ((fsp->flow_type & ~FLOW_EXT) != ETHER_FLOW)\n+\t\treturn -EINVAL;\n+\n+\tinput = kzalloc(sizeof(*input), GFP_KERNEL);\n+\tif (!input)\n+\t\treturn -ENOMEM;\n+\n+\tif (fsp->m_u.ether_spec.h_proto == ETHER_TYPE_FULL_MASK) {\n+\t\tinput->filter.etype = fsp->h_u.ether_spec.h_proto;\n+\t\tinput->filter.match_flags = IGC_FILTER_FLAG_ETHER_TYPE;\n+\t}\n+\n+\t/* Only support matching addresses by the full mask */\n+\tif (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_source)) {\n+\t\tinput->filter.match_flags |= IGC_FILTER_FLAG_SRC_MAC_ADDR;\n+\t\tether_addr_copy(input->filter.src_addr,\n+\t\t\t\tfsp->h_u.ether_spec.h_source);\n+\t}\n+\n+\t/* Only support matching addresses by the full mask */\n+\tif (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_dest)) {\n+\t\tinput->filter.match_flags |= IGC_FILTER_FLAG_DST_MAC_ADDR;\n+\t\tether_addr_copy(input->filter.dst_addr,\n+\t\t\t\tfsp->h_u.ether_spec.h_dest);\n+\t}\n+\n+\tif ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) {\n+\t\tif (fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) {\n+\t\t\terr = -EINVAL;\n+\t\t\tgoto err_out;\n+\t\t}\n+\t\tinput->filter.vlan_tci = fsp->h_ext.vlan_tci;\n+\t\tinput->filter.match_flags |= IGC_FILTER_FLAG_VLAN_TCI;\n+\t}\n+\n+\tinput->action = fsp->ring_cookie;\n+\tinput->sw_idx = fsp->location;\n+\n+\tspin_lock(&adapter->nfc_lock);\n+\n+\thlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) {\n+\t\tif (!memcmp(&input->filter, &rule->filter,\n+\t\t\t sizeof(input->filter))) {\n+\t\t\terr = -EEXIST;\n+\t\t\tdev_err(&adapter->pdev->dev,\n+\t\t\t\t\"ethtool: this filter is already set\\n\");\n+\t\t\tgoto err_out_w_lock;\n+\t\t}\n+\t}\n+\n+\terr = igc_add_filter(adapter, input);\n+\tif (err)\n+\t\tgoto err_out_w_lock;\n+\n+\tigc_update_ethtool_nfc_entry(adapter, input, input->sw_idx);\n+\n+\tspin_unlock(&adapter->nfc_lock);\n+\treturn 0;\n+\n+err_out_w_lock:\n+\tspin_unlock(&adapter->nfc_lock);\n+err_out:\n+\tkfree(input);\n+\treturn err;\n+}\n+\n+static int igc_del_ethtool_nfc_entry(struct igc_adapter *adapter,\n+\t\t\t\t struct ethtool_rxnfc *cmd)\n+{\n+\tstruct ethtool_rx_flow_spec *fsp =\n+\t\t(struct ethtool_rx_flow_spec *)&cmd->fs;\n+\tint err;\n+\n+\tspin_lock(&adapter->nfc_lock);\n+\terr = igc_update_ethtool_nfc_entry(adapter, NULL, fsp->location);\n+\tspin_unlock(&adapter->nfc_lock);\n+\n+\treturn err;\n+}\n+\n+static int igc_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(dev);\n+\tint ret = -EOPNOTSUPP;\n+\n+\tswitch (cmd->cmd) {\n+\tcase ETHTOOL_SRXFH:\n+\t\tret = igc_set_rss_hash_opt(adapter, cmd);\n+\t\tbreak;\n+\tcase ETHTOOL_SRXCLSRLINS:\n+\t\tret = igc_add_ethtool_nfc_entry(adapter, cmd);\n+\t\tbreak;\n+\tcase ETHTOOL_SRXCLSRLDEL:\n+\t\tret = igc_del_ethtool_nfc_entry(adapter, cmd);\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn ret;\n+}\n+\n void igc_write_rss_indir_tbl(struct igc_adapter *adapter)\n {\n \tstruct igc_hw *hw = &adapter->hw;\n@@ -1013,6 +1613,8 @@ static const struct ethtool_ops igc_ethtool_ops = {\n \t.set_pauseparam\t\t= igc_set_pauseparam,\n \t.get_coalesce\t\t= igc_get_coalesce,\n \t.set_coalesce\t\t= igc_set_coalesce,\n+\t.get_rxnfc\t\t= igc_get_rxnfc,\n+\t.set_rxnfc\t\t= igc_set_rxnfc,\n \t.get_rxfh_indir_size\t= igc_get_rxfh_indir_size,\n \t.get_rxfh\t\t= igc_get_rxfh,\n \t.set_rxfh\t\t= igc_set_rxfh,\ndiff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c\nindex 476d0a858bde..50c66c5b4acd 100644\n--- a/drivers/net/ethernet/intel/igc/igc_main.c\n+++ b/drivers/net/ethernet/intel/igc/igc_main.c\n@@ -1793,6 +1793,29 @@ static void igc_update_stats(struct igc_adapter *adapter)\n \n static void igc_nfc_filter_exit(struct igc_adapter *adapter)\n {\n+\tstruct igc_nfc_filter *rule;\n+\n+\tspin_lock(&adapter->nfc_lock);\n+\n+\thlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node)\n+\t\tigc_erase_filter(adapter, rule);\n+\n+\thlist_for_each_entry(rule, &adapter->cls_flower_list, nfc_node)\n+\t\tigc_erase_filter(adapter, rule);\n+\n+\tspin_unlock(&adapter->nfc_lock);\n+}\n+\n+static void igc_nfc_filter_restore(struct igc_adapter *adapter)\n+{\n+\tstruct igc_nfc_filter *rule;\n+\n+\tspin_lock(&adapter->nfc_lock);\n+\n+\thlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node)\n+\t\tigc_add_filter(adapter, rule);\n+\n+\tspin_unlock(&adapter->nfc_lock);\n }\n \n /**\n@@ -1955,6 +1978,7 @@ static void igc_configure(struct igc_adapter *adapter)\n \tigc_setup_mrqc(adapter);\n \tigc_setup_rctl(adapter);\n \n+\tigc_nfc_filter_restore(adapter);\n \tigc_configure_tx(adapter);\n \tigc_configure_rx(adapter);\n \n@@ -2016,6 +2040,127 @@ static void igc_set_default_mac_filter(struct igc_adapter *adapter)\n \tigc_rar_set_index(adapter, 0);\n }\n \n+/* If the filter to be added and an already existing filter express\n+ * the same address and address type, it should be possible to only\n+ * override the other configurations, for example the queue to steer\n+ * traffic.\n+ */\n+static bool igc_mac_entry_can_be_used(const struct igc_mac_addr *entry,\n+\t\t\t\t const u8 *addr, const u8 flags)\n+{\n+\tif (!(entry->state & IGC_MAC_STATE_IN_USE))\n+\t\treturn true;\n+\n+\tif ((entry->state & IGC_MAC_STATE_SRC_ADDR) !=\n+\t (flags & IGC_MAC_STATE_SRC_ADDR))\n+\t\treturn false;\n+\n+\tif (!ether_addr_equal(addr, entry->addr))\n+\t\treturn false;\n+\n+\treturn true;\n+}\n+\n+/* Add a MAC filter for 'addr' directing matching traffic to 'queue',\n+ * 'flags' is used to indicate what kind of match is made, match is by\n+ * default for the destination address, if matching by source address\n+ * is desired the flag IGC_MAC_STATE_SRC_ADDR can be used.\n+ */\n+static int igc_add_mac_filter_flags(struct igc_adapter *adapter,\n+\t\t\t\t const u8 *addr, const u8 queue,\n+\t\t\t\t const u8 flags)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tint rar_entries = hw->mac.rar_entry_count;\n+\tint i;\n+\n+\tif (is_zero_ether_addr(addr))\n+\t\treturn -EINVAL;\n+\n+\t/* Search for the first empty entry in the MAC table.\n+\t * Do not touch entries at the end of the table reserved for the VF MAC\n+\t * addresses.\n+\t */\n+\tfor (i = 0; i < rar_entries; i++) {\n+\t\tif (!igc_mac_entry_can_be_used(&adapter->mac_table[i],\n+\t\t\t\t\t addr, flags))\n+\t\t\tcontinue;\n+\n+\t\tether_addr_copy(adapter->mac_table[i].addr, addr);\n+\t\tadapter->mac_table[i].queue = queue;\n+\t\tadapter->mac_table[i].state |= IGC_MAC_STATE_IN_USE | flags;\n+\n+\t\tigc_rar_set_index(adapter, i);\n+\t\treturn i;\n+\t}\n+\n+\treturn -ENOSPC;\n+}\n+\n+int igc_add_mac_steering_filter(struct igc_adapter *adapter,\n+\t\t\t\tconst u8 *addr, u8 queue, u8 flags)\n+{\n+\treturn igc_add_mac_filter_flags(adapter, addr, queue,\n+\t\t\t\t\tIGC_MAC_STATE_QUEUE_STEERING | flags);\n+}\n+\n+/* Remove a MAC filter for 'addr' directing matching traffic to\n+ * 'queue', 'flags' is used to indicate what kind of match need to be\n+ * removed, match is by default for the destination address, if\n+ * matching by source address is to be removed the flag\n+ * IGC_MAC_STATE_SRC_ADDR can be used.\n+ */\n+static int igc_del_mac_filter_flags(struct igc_adapter *adapter,\n+\t\t\t\t const u8 *addr, const u8 queue,\n+\t\t\t\t const u8 flags)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tint rar_entries = hw->mac.rar_entry_count;\n+\tint i;\n+\n+\tif (is_zero_ether_addr(addr))\n+\t\treturn -EINVAL;\n+\n+\t/* Search for matching entry in the MAC table based on given address\n+\t * and queue. Do not touch entries at the end of the table reserved\n+\t * for the VF MAC addresses.\n+\t */\n+\tfor (i = 0; i < rar_entries; i++) {\n+\t\tif (!(adapter->mac_table[i].state & IGC_MAC_STATE_IN_USE))\n+\t\t\tcontinue;\n+\t\tif ((adapter->mac_table[i].state & flags) != flags)\n+\t\t\tcontinue;\n+\t\tif (adapter->mac_table[i].queue != queue)\n+\t\t\tcontinue;\n+\t\tif (!ether_addr_equal(adapter->mac_table[i].addr, addr))\n+\t\t\tcontinue;\n+\n+\t\t/* When a filter for the default address is \"deleted\",\n+\t\t * we return it to its initial configuration\n+\t\t */\n+\t\tif (adapter->mac_table[i].state & IGC_MAC_STATE_DEFAULT) {\n+\t\t\tadapter->mac_table[i].state =\n+\t\t\t\tIGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE;\n+\t\t} else {\n+\t\t\tadapter->mac_table[i].state = 0;\n+\t\t\tadapter->mac_table[i].queue = 0;\n+\t\t\tmemset(adapter->mac_table[i].addr, 0, ETH_ALEN);\n+\t\t}\n+\n+\t\tigc_rar_set_index(adapter, i);\n+\t\treturn 0;\n+\t}\n+\n+\treturn -ENOENT;\n+}\n+\n+int igc_del_mac_steering_filter(struct igc_adapter *adapter,\n+\t\t\t\tconst u8 *addr, u8 queue, u8 flags)\n+{\n+\treturn igc_del_mac_filter_flags(adapter, addr, queue,\n+\t\t\t\t\tIGC_MAC_STATE_QUEUE_STEERING | flags);\n+}\n+\n /**\n * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set\n * @netdev: network interface device structure\ndiff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h\nindex 325109cb20cc..50d7c04dccf5 100644\n--- a/drivers/net/ethernet/intel/igc/igc_regs.h\n+++ b/drivers/net/ethernet/intel/igc/igc_regs.h\n@@ -83,6 +83,16 @@\n /* RSS registers */\n #define IGC_MRQC\t\t0x05818 /* Multiple Receive Control - RW */\n \n+/* Filtering Registers */\n+#define IGC_ETQF(_n)\t\t(0x05CB0 + (4 * (_n))) /* EType Queue Fltr */\n+\n+/* ETQF register bit definitions */\n+#define IGC_ETQF_FILTER_ENABLE\tBIT(26)\n+#define IGC_ETQF_QUEUE_ENABLE\tBIT(31)\n+#define IGC_ETQF_QUEUE_SHIFT\t16\n+#define IGC_ETQF_QUEUE_MASK\t0x00070000\n+#define IGC_ETQF_ETYPE_MASK\t0x0000FFFF\n+\n /* Redirection Table - RW Array */\n #define IGC_RETA(_i)\t\t(0x05C00 + ((_i) * 4))\n /* RSS Random Key - RW Array */\n@@ -106,6 +116,7 @@\n #define IGC_UTA\t\t\t0x0A000 /* Unicast Table Array - RW */\n #define IGC_RAL(_n)\t\t(0x05400 + ((_n) * 0x08))\n #define IGC_RAH(_n)\t\t(0x05404 + ((_n) * 0x08))\n+#define IGC_VLAPQF\t\t0x055B0 /* VLAN Priority Queue Filter VLAPQF */\n \n /* Transmit Register Descriptions */\n #define IGC_TCTL\t\t0x00400 /* Tx Control - RW */\n", "prefixes": [ "v1", "1/1" ] }