get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/887910/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 887910,
    "url": "http://patchwork.ozlabs.org/api/patches/887910/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180319215644.31978-15-jeffrey.t.kirsher@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": "<20180319215644.31978-15-jeffrey.t.kirsher@intel.com>",
    "list_archive_url": null,
    "date": "2018-03-19T21:56:44",
    "name": "[v3,15/15] ice: Implement filter sync, NDO operations and bump version",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "2f0a0fac7a3f18072a3f68b849416de10f6103bd",
    "submitter": {
        "id": 473,
        "url": "http://patchwork.ozlabs.org/api/people/473/?format=api",
        "name": "Kirsher, Jeffrey T",
        "email": "jeffrey.t.kirsher@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/20180319215644.31978-15-jeffrey.t.kirsher@intel.com/mbox/",
    "series": [
        {
            "id": 34702,
            "url": "http://patchwork.ozlabs.org/api/series/34702/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=34702",
            "date": "2018-03-19T21:56:30",
            "name": "[v3,01/15] ice: Add basic driver framework for Intel(R) E800 Series",
            "version": 3,
            "mbox": "http://patchwork.ozlabs.org/series/34702/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/887910/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/887910/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=none (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 AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 404qdp5yJLz9sVr\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 20 Mar 2018 08:56:30 +1100 (AEDT)",
            "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 7793788EE2;\n\tMon, 19 Mar 2018 21:56:28 +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 EJSHLUfVzO3x; Mon, 19 Mar 2018 21:56:20 +0000 (UTC)",
            "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id D24BB88ED6;\n\tMon, 19 Mar 2018 21:56:20 +0000 (UTC)",
            "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id 00B981C2272\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Mar 2018 21:56:20 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id F170E88ED1\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Mar 2018 21:56:19 +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 vA1nLJoHgPBe for <intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Mar 2018 21:56:15 +0000 (UTC)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby hemlock.osuosl.org (Postfix) with ESMTPS id 1D5FF8915C\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Mar 2018 21:56:10 +0000 (UTC)",
            "from orsmga008.jf.intel.com ([10.7.209.65])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Mar 2018 14:56:07 -0700",
            "from jtkirshe-nuc.jf.intel.com ([134.134.177.59])\n\tby orsmga008.jf.intel.com with ESMTP; 19 Mar 2018 14:56:07 -0700"
        ],
        "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.48,332,1517904000\"; d=\"scan'208\";a=\"26667092\"",
        "From": "Jeff Kirsher <jeffrey.t.kirsher@intel.com>",
        "To": "intel-wired-lan@lists.osuosl.org",
        "Date": "Mon, 19 Mar 2018 14:56:44 -0700",
        "Message-Id": "<20180319215644.31978-15-jeffrey.t.kirsher@intel.com>",
        "X-Mailer": "git-send-email 2.14.3",
        "In-Reply-To": "<20180319215644.31978-1-jeffrey.t.kirsher@intel.com>",
        "References": "<20180319215644.31978-1-jeffrey.t.kirsher@intel.com>",
        "Subject": "[Intel-wired-lan] [PATCH v3 15/15] ice: Implement filter sync,\n\tNDO operations and bump version",
        "X-BeenThere": "intel-wired-lan@osuosl.org",
        "X-Mailman-Version": "2.1.24",
        "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": "From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>\n\nThis patch implements multiple pieces of functionality:\n\n1. Added ice_vsi_sync_filters, which is called through the service task\n   to push filter updates to the hardware.\n\n2. Add support to enable/disable promiscuous mode on an interface.\n   Enabling/disabling promiscuous mode on an interface results in\n   addition/removal of a promisc filter rule through ice_vsi_sync_filters.\n\n3. Implement handlers for ndo_set_mac_address, ndo_change_mtu,\n   ndo_poll_controller and ndo_set_rx_mode.\n\nThis patch also marks the end of the driver addition by bumping up the\ndriver version.\n\nSigned-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>\n---\n drivers/net/ethernet/intel/ice/ice.h            |  14 +\n drivers/net/ethernet/intel/ice/ice_adminq_cmd.h |  21 +\n drivers/net/ethernet/intel/ice/ice_common.c     |  28 ++\n drivers/net/ethernet/intel/ice/ice_common.h     |   3 +\n drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h  |  12 +\n drivers/net/ethernet/intel/ice/ice_main.c       | 567 +++++++++++++++++++++++-\n drivers/net/ethernet/intel/ice/ice_switch.c     |  77 ++++\n drivers/net/ethernet/intel/ice/ice_switch.h     |   2 +\n drivers/net/ethernet/intel/ice/ice_type.h       |   5 +\n 9 files changed, 728 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h\nindex 6d7d03b80dbf..9bb8a99b929e 100644\n--- a/drivers/net/ethernet/intel/ice/ice.h\n+++ b/drivers/net/ethernet/intel/ice/ice.h\n@@ -139,11 +139,20 @@ enum ice_state {\n \t__ICE_SUSPENDED,\t\t/* set on module remove path */\n \t__ICE_RESET_FAILED,\t\t/* set by reset/rebuild */\n \t__ICE_ADMINQ_EVENT_PENDING,\n+\t__ICE_FLTR_OVERFLOW_PROMISC,\n \t__ICE_CFG_BUSY,\n \t__ICE_SERVICE_SCHED,\n \t__ICE_STATE_NBITS\t\t/* must be last */\n };\n \n+enum ice_vsi_flags {\n+\tICE_VSI_FLAG_UMAC_FLTR_CHANGED,\n+\tICE_VSI_FLAG_MMAC_FLTR_CHANGED,\n+\tICE_VSI_FLAG_VLAN_FLTR_CHANGED,\n+\tICE_VSI_FLAG_PROMISC_CHANGED,\n+\tICE_VSI_FLAG_NBITS\t\t/* must be last */\n+};\n+\n /* struct that defines a VSI, associated with a dev */\n struct ice_vsi {\n \tstruct net_device *netdev;\n@@ -158,7 +167,9 @@ struct ice_vsi {\n \n \tu64 tx_linearize;\n \tDECLARE_BITMAP(state, __ICE_STATE_NBITS);\n+\tDECLARE_BITMAP(flags, ICE_VSI_FLAG_NBITS);\n \tunsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];\n+\tunsigned int current_netdev_flags;\n \tu32 tx_restart;\n \tu32 tx_busy;\n \tu32 rx_buf_failed;\n@@ -189,6 +200,9 @@ struct ice_vsi {\n \tstruct ice_eth_stats eth_stats;\n \tstruct ice_eth_stats eth_stats_prev;\n \n+\tstruct list_head tmp_sync_list;\t\t/* MAC filters to be synced */\n+\tstruct list_head tmp_unsync_list;\t/* MAC filters to be unsynced */\n+\n \tbool irqs_ready;\n \tbool current_isup;\t\t /* Sync 'link up' logging */\n \tbool stat_offsets_loaded;\ndiff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\nindex 8cade22c1cf6..fc19c287ebc5 100644\n--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\n+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\n@@ -149,6 +149,24 @@ struct ice_aqc_manage_mac_read_resp {\n \tu8 mac_addr[ETH_ALEN];\n };\n \n+/* Manage MAC address, write command - direct (0x0108) */\n+struct ice_aqc_manage_mac_write {\n+\tu8 port_num;\n+\tu8 flags;\n+#define ICE_AQC_MAN_MAC_WR_MC_MAG_EN\t\tBIT(0)\n+#define ICE_AQC_MAN_MAC_WR_WOL_LAA_PFR_KEEP\tBIT(1)\n+#define ICE_AQC_MAN_MAC_WR_S\t\t6\n+#define ICE_AQC_MAN_MAC_WR_M\t\t(3 << ICE_AQC_MAN_MAC_WR_S)\n+#define ICE_AQC_MAN_MAC_UPDATE_LAA\t0\n+#define ICE_AQC_MAN_MAC_UPDATE_LAA_WOL\t(BIT(0) << ICE_AQC_MAN_MAC_WR_S)\n+\t/* High 16 bits of MAC address in big endian order */\n+\t__be16 sah;\n+\t/* Low 32 bits of MAC address in big endian order */\n+\t__be32 sal;\n+\t__le32 addr_high;\n+\t__le32 addr_low;\n+};\n+\n /* Clear PXE Command and response (direct 0x0110) */\n struct ice_aqc_clear_pxe {\n \tu8 rx_cnt;\n@@ -1228,6 +1246,7 @@ struct ice_aq_desc {\n \t\tstruct ice_aqc_q_shutdown q_shutdown;\n \t\tstruct ice_aqc_req_res res_owner;\n \t\tstruct ice_aqc_manage_mac_read mac_read;\n+\t\tstruct ice_aqc_manage_mac_write mac_write;\n \t\tstruct ice_aqc_clear_pxe clear_pxe;\n \t\tstruct ice_aqc_list_caps get_cap;\n \t\tstruct ice_aqc_get_phy_caps get_phy;\n@@ -1272,6 +1291,7 @@ enum ice_aq_err {\n \tICE_AQ_RC_ENOMEM\t= 9,  /* Out of memory */\n \tICE_AQ_RC_EBUSY\t\t= 12, /* Device or resource busy */\n \tICE_AQ_RC_EEXIST\t= 13, /* object already exists */\n+\tICE_AQ_RC_ENOSPC\t= 16, /* No space left or allocation failure */\n };\n \n /* Admin Queue command opcodes */\n@@ -1290,6 +1310,7 @@ enum ice_adminq_opc {\n \n \t/* manage MAC address */\n \tice_aqc_opc_manage_mac_read\t\t\t= 0x0107,\n+\tice_aqc_opc_manage_mac_write\t\t\t= 0x0108,\n \n \t/* PXE */\n \tice_aqc_opc_clear_pxe_mode\t\t\t= 0x0110,\ndiff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c\nindex 316262b3c7a0..a36220792026 100644\n--- a/drivers/net/ethernet/intel/ice/ice_common.c\n+++ b/drivers/net/ethernet/intel/ice/ice_common.c\n@@ -1246,6 +1246,34 @@ enum ice_status ice_get_caps(struct ice_hw *hw)\n \treturn status;\n }\n \n+/**\n+ * ice_aq_manage_mac_write - manage MAC address write command\n+ * @hw: pointer to the hw struct\n+ * @mac_addr: MAC address to be written as LAA/LAA+WoL/Port address\n+ * @flags: flags to control write behavior\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * This function is used to write MAC address to the NVM (0x0108).\n+ */\n+enum ice_status\n+ice_aq_manage_mac_write(struct ice_hw *hw, u8 *mac_addr, u8 flags,\n+\t\t\tstruct ice_sq_cd *cd)\n+{\n+\tstruct ice_aqc_manage_mac_write *cmd;\n+\tstruct ice_aq_desc desc;\n+\n+\tcmd = &desc.params.mac_write;\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_write);\n+\n+\tcmd->flags = flags;\n+\n+\t/* Prep values for flags, sah, sal */\n+\tcmd->sah = htons(*((u16 *)mac_addr));\n+\tcmd->sal = htonl(*((u32 *)(mac_addr + 2)));\n+\n+\treturn ice_aq_send_cmd(hw, &desc, NULL, 0, cd);\n+}\n+\n /**\n  * ice_aq_clear_pxe_mode\n  * @hw: pointer to the hw struct\ndiff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h\nindex 2921f3c6ce4b..8e87d3b95d5f 100644\n--- a/drivers/net/ethernet/intel/ice/ice_common.h\n+++ b/drivers/net/ethernet/intel/ice/ice_common.h\n@@ -72,6 +72,9 @@ enum ice_status\n ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc,\n \t\tvoid *buf, u16 buf_size, struct ice_sq_cd *cd);\n enum ice_status ice_aq_get_fw_ver(struct ice_hw *hw, struct ice_sq_cd *cd);\n+enum ice_status\n+ice_aq_manage_mac_write(struct ice_hw *hw, u8 *mac_addr, u8 flags,\n+\t\t\tstruct ice_sq_cd *cd);\n enum ice_status ice_clear_pf_cfg(struct ice_hw *hw);\n enum ice_status\n ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool atomic_restart);\ndiff --git a/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h b/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h\nindex b1f38624da21..67fb0a9ba0df 100644\n--- a/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h\n+++ b/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h\n@@ -367,6 +367,18 @@ enum ice_tx_desc_len_fields {\n \tICE_TX_DESC_LEN_L4_LEN_S\t= 14 /* 4 BITS */\n };\n \n+#define ICE_TXD_QW1_MACLEN_M (0x7FUL << ICE_TX_DESC_LEN_MACLEN_S)\n+#define ICE_TXD_QW1_IPLEN_M  (0x7FUL << ICE_TX_DESC_LEN_IPLEN_S)\n+#define ICE_TXD_QW1_L4LEN_M  (0xFUL << ICE_TX_DESC_LEN_L4_LEN_S)\n+\n+/* Tx descriptor field limits in bytes */\n+#define ICE_TXD_MACLEN_MAX ((ICE_TXD_QW1_MACLEN_M >> \\\n+\t\t\t     ICE_TX_DESC_LEN_MACLEN_S) * ICE_BYTES_PER_WORD)\n+#define ICE_TXD_IPLEN_MAX ((ICE_TXD_QW1_IPLEN_M >> \\\n+\t\t\t    ICE_TX_DESC_LEN_IPLEN_S) * ICE_BYTES_PER_DWORD)\n+#define ICE_TXD_L4LEN_MAX ((ICE_TXD_QW1_L4LEN_M >> \\\n+\t\t\t    ICE_TX_DESC_LEN_L4_LEN_S) * ICE_BYTES_PER_DWORD)\n+\n #define ICE_TXD_QW1_TX_BUF_SZ_S\t34\n #define ICE_TXD_QW1_L2TAG1_S\t48\n \ndiff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c\nindex 90f44be5f858..faffb6c8f05c 100644\n--- a/drivers/net/ethernet/intel/ice/ice_main.c\n+++ b/drivers/net/ethernet/intel/ice/ice_main.c\n@@ -21,7 +21,7 @@\n \n #include \"ice.h\"\n \n-#define DRV_VERSION\t\"ice-0.0.1-k\"\n+#define DRV_VERSION\t\"ice-0.7.0-k\"\n #define DRV_SUMMARY\t\"Intel(R) Ethernet Connection E800 Series Linux Driver\"\n const char ice_drv_ver[] = DRV_VERSION;\n static const char ice_driver_string[] = DRV_SUMMARY;\n@@ -214,6 +214,48 @@ static int ice_add_mac_to_list(struct ice_vsi *vsi, struct list_head *add_list,\n \treturn 0;\n }\n \n+/**\n+ * ice_add_mac_to_sync_list - creates list of mac addresses to be synced\n+ * @netdev: the net device on which the sync is happening\n+ * @addr: mac address to sync\n+ *\n+ * This is a callback function which is called by the in kernel device sync\n+ * functions (like __dev_uc_sync, __dev_mc_sync, etc). This function only\n+ * populates the tmp_sync_list, which is later used by ice_add_mac to add the\n+ * mac filters from the hardware.\n+ */\n+static int ice_add_mac_to_sync_list(struct net_device *netdev, const u8 *addr)\n+{\n+\tstruct ice_netdev_priv *np = netdev_priv(netdev);\n+\tstruct ice_vsi *vsi = np->vsi;\n+\n+\tif (ice_add_mac_to_list(vsi, &vsi->tmp_sync_list, addr))\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_add_mac_to_unsync_list - creates list of mac addresses to be unsynced\n+ * @netdev: the net device on which the unsync is happening\n+ * @addr: mac address to unsync\n+ *\n+ * This is a callback function which is called by the in kernel device unsync\n+ * functions (like __dev_uc_unsync, __dev_mc_unsync, etc). This function only\n+ * populates the tmp_unsync_list, which is later used by ice_remove_mac to\n+ * delete the mac filters from the hardware.\n+ */\n+static int ice_add_mac_to_unsync_list(struct net_device *netdev, const u8 *addr)\n+{\n+\tstruct ice_netdev_priv *np = netdev_priv(netdev);\n+\tstruct ice_vsi *vsi = np->vsi;\n+\n+\tif (ice_add_mac_to_list(vsi, &vsi->tmp_unsync_list, addr))\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n /**\n  * ice_free_fltr_list - free filter lists helper\n  * @dev: pointer to the device struct\n@@ -232,6 +274,183 @@ static void ice_free_fltr_list(struct device *dev, struct list_head *h)\n \t}\n }\n \n+/**\n+ * ice_vsi_fltr_changed - check if filter state changed\n+ * @vsi: VSI to be checked\n+ *\n+ * returns true if filter state has changed, false otherwise.\n+ */\n+static bool ice_vsi_fltr_changed(struct ice_vsi *vsi)\n+{\n+\treturn test_bit(ICE_VSI_FLAG_UMAC_FLTR_CHANGED, vsi->flags) ||\n+\t       test_bit(ICE_VSI_FLAG_MMAC_FLTR_CHANGED, vsi->flags) ||\n+\t       test_bit(ICE_VSI_FLAG_VLAN_FLTR_CHANGED, vsi->flags);\n+}\n+\n+/**\n+ * ice_vsi_sync_fltr - Update the VSI filter list to the HW\n+ * @vsi: ptr to the VSI\n+ *\n+ * Push any outstanding VSI filter changes through the AdminQ.\n+ */\n+static int ice_vsi_sync_fltr(struct ice_vsi *vsi)\n+{\n+\tstruct device *dev = &vsi->back->pdev->dev;\n+\tstruct net_device *netdev = vsi->netdev;\n+\tbool promisc_forced_on = false;\n+\tstruct ice_pf *pf = vsi->back;\n+\tstruct ice_hw *hw = &pf->hw;\n+\tenum ice_status status = 0;\n+\tu32 changed_flags = 0;\n+\tint err = 0;\n+\n+\tif (!vsi->netdev)\n+\t\treturn -EINVAL;\n+\n+\twhile (test_and_set_bit(__ICE_CFG_BUSY, vsi->state))\n+\t\tusleep_range(1000, 2000);\n+\n+\tchanged_flags = vsi->current_netdev_flags ^ vsi->netdev->flags;\n+\tvsi->current_netdev_flags = vsi->netdev->flags;\n+\n+\tINIT_LIST_HEAD(&vsi->tmp_sync_list);\n+\tINIT_LIST_HEAD(&vsi->tmp_unsync_list);\n+\n+\tif (ice_vsi_fltr_changed(vsi)) {\n+\t\tclear_bit(ICE_VSI_FLAG_UMAC_FLTR_CHANGED, vsi->flags);\n+\t\tclear_bit(ICE_VSI_FLAG_MMAC_FLTR_CHANGED, vsi->flags);\n+\t\tclear_bit(ICE_VSI_FLAG_VLAN_FLTR_CHANGED, vsi->flags);\n+\n+\t\t/* grab the netdev's addr_list_lock */\n+\t\tnetif_addr_lock_bh(netdev);\n+\t\t__dev_uc_sync(netdev, ice_add_mac_to_sync_list,\n+\t\t\t      ice_add_mac_to_unsync_list);\n+\t\t__dev_mc_sync(netdev, ice_add_mac_to_sync_list,\n+\t\t\t      ice_add_mac_to_unsync_list);\n+\t\t/* our temp lists are populated. release lock */\n+\t\tnetif_addr_unlock_bh(netdev);\n+\t}\n+\n+\t/* Remove mac addresses in the unsync list */\n+\tstatus = ice_remove_mac(hw, &vsi->tmp_unsync_list);\n+\tice_free_fltr_list(dev, &vsi->tmp_unsync_list);\n+\tif (status) {\n+\t\tnetdev_err(netdev, \"Failed to delete MAC filters\\n\");\n+\t\t/* if we failed because of alloc failures, just bail */\n+\t\tif (status == ICE_ERR_NO_MEMORY) {\n+\t\t\terr = -ENOMEM;\n+\t\t\tgoto out;\n+\t\t}\n+\t}\n+\n+\t/* Add mac addresses in the sync list */\n+\tstatus = ice_add_mac(hw, &vsi->tmp_sync_list);\n+\tice_free_fltr_list(dev, &vsi->tmp_sync_list);\n+\tif (status) {\n+\t\tnetdev_err(netdev, \"Failed to add MAC filters\\n\");\n+\t\t/* If there is no more space for new umac filters, vsi\n+\t\t * should go into promiscuous mode. There should be some\n+\t\t * space reserved for promiscuous filters.\n+\t\t */\n+\t\tif (hw->adminq.sq_last_status == ICE_AQ_RC_ENOSPC &&\n+\t\t    !test_and_set_bit(__ICE_FLTR_OVERFLOW_PROMISC,\n+\t\t\t\t      vsi->state)) {\n+\t\t\tpromisc_forced_on = true;\n+\t\t\tnetdev_warn(netdev,\n+\t\t\t\t    \"Reached MAC filter limit, forcing promisc mode on VSI %d\\n\",\n+\t\t\t\t    vsi->vsi_num);\n+\t\t} else {\n+\t\t\terr = -EIO;\n+\t\t\tgoto out;\n+\t\t}\n+\t}\n+\t/* check for changes in promiscuous modes */\n+\tif (changed_flags & IFF_ALLMULTI)\n+\t\tnetdev_warn(netdev, \"Unsupported configuration\\n\");\n+\n+\tif (((changed_flags & IFF_PROMISC) || promisc_forced_on) ||\n+\t    test_bit(ICE_VSI_FLAG_PROMISC_CHANGED, vsi->flags)) {\n+\t\tclear_bit(ICE_VSI_FLAG_PROMISC_CHANGED, vsi->flags);\n+\t\tif (vsi->current_netdev_flags & IFF_PROMISC) {\n+\t\t\t/* Apply TX filter rule to get traffic from VMs */\n+\t\t\tstatus = ice_cfg_dflt_vsi(hw, vsi->vsi_num, true,\n+\t\t\t\t\t\t  ICE_FLTR_TX);\n+\t\t\tif (status) {\n+\t\t\t\tnetdev_err(netdev, \"Error setting default VSI %i tx rule\\n\",\n+\t\t\t\t\t   vsi->vsi_num);\n+\t\t\t\tvsi->current_netdev_flags &= ~IFF_PROMISC;\n+\t\t\t\terr = -EIO;\n+\t\t\t\tgoto out_promisc;\n+\t\t\t}\n+\t\t\t/* Apply RX filter rule to get traffic from wire */\n+\t\t\tstatus = ice_cfg_dflt_vsi(hw, vsi->vsi_num, true,\n+\t\t\t\t\t\t  ICE_FLTR_RX);\n+\t\t\tif (status) {\n+\t\t\t\tnetdev_err(netdev, \"Error setting default VSI %i rx rule\\n\",\n+\t\t\t\t\t   vsi->vsi_num);\n+\t\t\t\tvsi->current_netdev_flags &= ~IFF_PROMISC;\n+\t\t\t\terr = -EIO;\n+\t\t\t\tgoto out_promisc;\n+\t\t\t}\n+\t\t} else {\n+\t\t\t/* Clear TX filter rule to stop traffic from VMs */\n+\t\t\tstatus = ice_cfg_dflt_vsi(hw, vsi->vsi_num, false,\n+\t\t\t\t\t\t  ICE_FLTR_TX);\n+\t\t\tif (status) {\n+\t\t\t\tnetdev_err(netdev, \"Error clearing default VSI %i tx rule\\n\",\n+\t\t\t\t\t   vsi->vsi_num);\n+\t\t\t\tvsi->current_netdev_flags |= IFF_PROMISC;\n+\t\t\t\terr = -EIO;\n+\t\t\t\tgoto out_promisc;\n+\t\t\t}\n+\t\t\t/* Clear filter RX to remove traffic from wire */\n+\t\t\tstatus = ice_cfg_dflt_vsi(hw, vsi->vsi_num, false,\n+\t\t\t\t\t\t  ICE_FLTR_RX);\n+\t\t\tif (status) {\n+\t\t\t\tnetdev_err(netdev, \"Error clearing default VSI %i rx rule\\n\",\n+\t\t\t\t\t   vsi->vsi_num);\n+\t\t\t\tvsi->current_netdev_flags |= IFF_PROMISC;\n+\t\t\t\terr = -EIO;\n+\t\t\t\tgoto out_promisc;\n+\t\t\t}\n+\t\t}\n+\t}\n+\tgoto exit;\n+\n+out_promisc:\n+\tset_bit(ICE_VSI_FLAG_PROMISC_CHANGED, vsi->flags);\n+\tgoto exit;\n+out:\n+\t/* if something went wrong then set the changed flag so we try again */\n+\tset_bit(ICE_VSI_FLAG_UMAC_FLTR_CHANGED, vsi->flags);\n+\tset_bit(ICE_VSI_FLAG_MMAC_FLTR_CHANGED, vsi->flags);\n+exit:\n+\tclear_bit(__ICE_CFG_BUSY, vsi->state);\n+\treturn err;\n+}\n+\n+/**\n+ * ice_sync_fltr_subtask - Sync the VSI filter list with HW\n+ * @pf: board private structure\n+ */\n+static void ice_sync_fltr_subtask(struct ice_pf *pf)\n+{\n+\tint v;\n+\n+\tif (!pf || !(test_bit(ICE_FLAG_FLTR_SYNC, pf->flags)))\n+\t\treturn;\n+\n+\tclear_bit(ICE_FLAG_FLTR_SYNC, pf->flags);\n+\n+\tfor (v = 0; v < pf->num_alloc_vsi; v++)\n+\t\tif (pf->vsi[v] && ice_vsi_fltr_changed(pf->vsi[v]) &&\n+\t\t    ice_vsi_sync_fltr(pf->vsi[v])) {\n+\t\t\t/* come back and try again later */\n+\t\t\tset_bit(ICE_FLAG_FLTR_SYNC, pf->flags);\n+\t\t\tbreak;\n+\t\t}\n+}\n+\n /**\n  * ice_is_reset_recovery_pending - schedule a reset\n  * @state: pf state field\n@@ -794,6 +1013,7 @@ static void ice_service_task(struct work_struct *work)\n \t\treturn;\n \t}\n \n+\tice_sync_fltr_subtask(pf);\n \tice_watchdog_subtask(pf);\n \tice_clean_adminq_subtask(pf);\n \n@@ -2505,6 +2725,7 @@ static int ice_vsi_reinit_setup(struct ice_vsi *vsi)\n \tice_vsi_free_q_vectors(vsi);\n err_rings:\n \tif (vsi->netdev) {\n+\t\tvsi->current_netdev_flags = 0;\n \t\tunregister_netdev(vsi->netdev);\n \t\tfree_netdev(vsi->netdev);\n \t\tvsi->netdev = NULL;\n@@ -3314,6 +3535,197 @@ static void __exit ice_module_exit(void)\n }\n module_exit(ice_module_exit);\n \n+/**\n+ * ice_set_mac_address - NDO callback to set mac address\n+ * @netdev: network interface device structure\n+ * @pi: pointer to an address structure\n+ *\n+ * Returns 0 on success, negative on failure\n+ */\n+static int ice_set_mac_address(struct net_device *netdev, void *pi)\n+{\n+\tstruct ice_netdev_priv *np = netdev_priv(netdev);\n+\tstruct ice_vsi *vsi = np->vsi;\n+\tstruct ice_pf *pf = vsi->back;\n+\tstruct ice_hw *hw = &pf->hw;\n+\tstruct sockaddr *addr = pi;\n+\tenum ice_status status;\n+\tLIST_HEAD(a_mac_list);\n+\tLIST_HEAD(r_mac_list);\n+\tu8 flags = 0;\n+\tint err;\n+\tu8 *mac;\n+\n+\tmac = (u8 *)addr->sa_data;\n+\n+\tif (!is_valid_ether_addr(mac))\n+\t\treturn -EADDRNOTAVAIL;\n+\n+\tif (ether_addr_equal(netdev->dev_addr, mac)) {\n+\t\tnetdev_warn(netdev, \"already using mac %pM\\n\", mac);\n+\t\treturn 0;\n+\t}\n+\n+\tif (test_bit(__ICE_DOWN, pf->state) ||\n+\t    ice_is_reset_recovery_pending(pf->state)) {\n+\t\tnetdev_err(netdev, \"can't set mac %pM. device not ready\\n\",\n+\t\t\t   mac);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\t/* When we change the mac address we also have to change the mac address\n+\t * based filter rules that were created previously for the old mac\n+\t * address. So first, we remove the old filter rule using ice_remove_mac\n+\t * and then create a new filter rule using ice_add_mac. Note that for\n+\t * both these operations, we first need to form a \"list\" of mac\n+\t * addresses (even though in this case, we have only 1 mac address to be\n+\t * added/removed) and this done using ice_add_mac_to_list. Depending on\n+\t * the ensuing operation this \"list\" of mac addresses is either to be\n+\t * added or removed from the filter.\n+\t */\n+\terr = ice_add_mac_to_list(vsi, &r_mac_list, netdev->dev_addr);\n+\tif (err) {\n+\t\terr = -EADDRNOTAVAIL;\n+\t\tgoto free_lists;\n+\t}\n+\n+\tstatus = ice_remove_mac(hw, &r_mac_list);\n+\tif (status) {\n+\t\terr = -EADDRNOTAVAIL;\n+\t\tgoto free_lists;\n+\t}\n+\n+\terr = ice_add_mac_to_list(vsi, &a_mac_list, mac);\n+\tif (err) {\n+\t\terr = -EADDRNOTAVAIL;\n+\t\tgoto free_lists;\n+\t}\n+\n+\tstatus = ice_add_mac(hw, &a_mac_list);\n+\tif (status) {\n+\t\terr = -EADDRNOTAVAIL;\n+\t\tgoto free_lists;\n+\t}\n+\n+free_lists:\n+\t/* free list entries */\n+\tice_free_fltr_list(&pf->pdev->dev, &r_mac_list);\n+\tice_free_fltr_list(&pf->pdev->dev, &a_mac_list);\n+\n+\tif (err) {\n+\t\tnetdev_err(netdev, \"can't set mac %pM. filter update failed\\n\",\n+\t\t\t   mac);\n+\t\treturn err;\n+\t}\n+\n+\t/* change the netdev's mac address */\n+\tmemcpy(netdev->dev_addr, mac, netdev->addr_len);\n+\tnetdev_dbg(vsi->netdev, \"updated mac address to %pM\\n\",\n+\t\t   netdev->dev_addr);\n+\n+\t/* write new mac address to the firmware */\n+\tflags = ICE_AQC_MAN_MAC_UPDATE_LAA_WOL;\n+\tstatus = ice_aq_manage_mac_write(hw, mac, flags, NULL);\n+\tif (status) {\n+\t\tnetdev_err(netdev, \"can't set mac %pM. write to firmware failed.\\n\",\n+\t\t\t   mac);\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_set_rx_mode - NDO callback to set the netdev filters\n+ * @netdev: network interface device structure\n+ */\n+static void ice_set_rx_mode(struct net_device *netdev)\n+{\n+\tstruct ice_netdev_priv *np = netdev_priv(netdev);\n+\tstruct ice_vsi *vsi = np->vsi;\n+\n+\tif (!vsi)\n+\t\treturn;\n+\n+\t/* Set the flags to synchronize filters\n+\t * ndo_set_rx_mode may be triggered even without a change in netdev\n+\t * flags\n+\t */\n+\tset_bit(ICE_VSI_FLAG_UMAC_FLTR_CHANGED, vsi->flags);\n+\tset_bit(ICE_VSI_FLAG_MMAC_FLTR_CHANGED, vsi->flags);\n+\tset_bit(ICE_FLAG_FLTR_SYNC, vsi->back->flags);\n+\n+\t/* schedule our worker thread which will take care of\n+\t * applying the new filter changes\n+\t */\n+\tice_service_task_schedule(vsi->back);\n+}\n+\n+/**\n+ * ice_fdb_add - add an entry to the hardware database\n+ * @ndm: the input from the stack\n+ * @tb: pointer to array of nladdr (unused)\n+ * @dev: the net device pointer\n+ * @addr: the MAC address entry being added\n+ * @vid: VLAN id\n+ * @flags: instructions from stack about fdb operation\n+ */\n+static int ice_fdb_add(struct ndmsg *ndm, struct nlattr __always_unused *tb[],\n+\t\t       struct net_device *dev, const unsigned char *addr,\n+\t\t       u16 vid, u16 flags)\n+{\n+\tint err;\n+\n+\tif (vid) {\n+\t\tnetdev_err(dev, \"VLANs aren't supported yet for dev_uc|mc_add()\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tif (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) {\n+\t\tnetdev_err(dev, \"FDB only supports static addresses\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))\n+\t\terr = dev_uc_add_excl(dev, addr);\n+\telse if (is_multicast_ether_addr(addr))\n+\t\terr = dev_mc_add_excl(dev, addr);\n+\telse\n+\t\terr = -EINVAL;\n+\n+\t/* Only return duplicate errors if NLM_F_EXCL is set */\n+\tif (err == -EEXIST && !(flags & NLM_F_EXCL))\n+\t\terr = 0;\n+\n+\treturn err;\n+}\n+\n+/**\n+ * ice_fdb_del - delete an entry from the hardware database\n+ * @ndm: the input from the stack\n+ * @tb: pointer to array of nladdr (unused)\n+ * @dev: the net device pointer\n+ * @addr: the MAC address entry being added\n+ * @vid: VLAN id\n+ */\n+static int ice_fdb_del(struct ndmsg *ndm, __always_unused struct nlattr *tb[],\n+\t\t       struct net_device *dev, const unsigned char *addr,\n+\t\t       __always_unused u16 vid)\n+{\n+\tint err;\n+\n+\tif (ndm->ndm_state & NUD_PERMANENT) {\n+\t\tnetdev_err(dev, \"FDB only supports static addresses\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (is_unicast_ether_addr(addr))\n+\t\terr = dev_uc_del(dev, addr);\n+\telse if (is_multicast_ether_addr(addr))\n+\t\terr = dev_mc_del(dev, addr);\n+\telse\n+\t\terr = -EINVAL;\n+\n+\treturn err;\n+}\n+\n /**\n  * ice_vsi_manage_vlan_insertion - Manage VLAN insertion for the VSI for Tx\n  * @vsi: the vsi being changed\n@@ -3704,6 +4116,8 @@ static int ice_vsi_cfg(struct ice_vsi *vsi)\n {\n \tint err;\n \n+\tice_set_rx_mode(vsi->netdev);\n+\n \terr = ice_restore_vlan(vsi);\n \tif (err)\n \t\treturn err;\n@@ -4393,6 +4807,30 @@ void ice_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)\n \tstats->rx_length_errors = vsi_stats->rx_length_errors;\n }\n \n+#ifdef CONFIG_NET_POLL_CONTROLLER\n+/**\n+ * ice_netpoll - polling \"interrupt\" handler\n+ * @netdev: network interface device structure\n+ *\n+ * Used by netconsole to send skbs without having to re-enable interrupts.\n+ * This is not called in the normal interrupt path.\n+ */\n+static void ice_netpoll(struct net_device *netdev)\n+{\n+\tstruct ice_netdev_priv *np = netdev_priv(netdev);\n+\tstruct ice_vsi *vsi = np->vsi;\n+\tstruct ice_pf *pf = vsi->back;\n+\tint i;\n+\n+\tif (test_bit(__ICE_DOWN, vsi->state) ||\n+\t    !test_bit(ICE_FLAG_MSIX_ENA, pf->flags))\n+\t\treturn;\n+\n+\tfor (i = 0; i < vsi->num_q_vectors; i++)\n+\t\tice_msix_clean_rings(0, vsi->q_vectors[i]);\n+}\n+#endif /* CONFIG_NET_POLL_CONTROLLER */\n+\n /**\n  * ice_napi_disable_all - Disable NAPI for all q_vectors in the VSI\n  * @vsi: VSI having NAPI disabled\n@@ -4800,6 +5238,73 @@ static void ice_rebuild(struct ice_pf *pf)\n \tset_bit(__ICE_RESET_RECOVERY_PENDING, pf->state);\n }\n \n+/**\n+ * ice_change_mtu - NDO callback to change the MTU\n+ * @netdev: network interface device structure\n+ * @new_mtu: new value for maximum frame size\n+ *\n+ * Returns 0 on success, negative on failure\n+ */\n+static int ice_change_mtu(struct net_device *netdev, int new_mtu)\n+{\n+\tstruct ice_netdev_priv *np = netdev_priv(netdev);\n+\tstruct ice_vsi *vsi = np->vsi;\n+\tstruct ice_pf *pf = vsi->back;\n+\tu8 count = 0;\n+\n+\tif (new_mtu == netdev->mtu) {\n+\t\tnetdev_warn(netdev, \"mtu is already %d\\n\", netdev->mtu);\n+\t\treturn 0;\n+\t}\n+\n+\tif (new_mtu < netdev->min_mtu) {\n+\t\tnetdev_err(netdev, \"new mtu invalid. min_mtu is %d\\n\",\n+\t\t\t   netdev->min_mtu);\n+\t\treturn -EINVAL;\n+\t} else if (new_mtu > netdev->max_mtu) {\n+\t\tnetdev_err(netdev, \"new mtu invalid. max_mtu is %d\\n\",\n+\t\t\t   netdev->min_mtu);\n+\t\treturn -EINVAL;\n+\t}\n+\t/* if a reset is in progress, wait for some time for it to complete */\n+\tdo {\n+\t\tif (ice_is_reset_recovery_pending(pf->state)) {\n+\t\t\tcount++;\n+\t\t\tusleep_range(1000, 2000);\n+\t\t} else {\n+\t\t\tbreak;\n+\t\t}\n+\n+\t} while (count < 100);\n+\n+\tif (count == 100) {\n+\t\tnetdev_err(netdev, \"can't change mtu. Device is busy\\n\");\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tnetdev->mtu = new_mtu;\n+\n+\t/* if VSI is up, bring it down and then back up */\n+\tif (!test_and_set_bit(__ICE_DOWN, vsi->state)) {\n+\t\tint err;\n+\n+\t\terr = ice_down(vsi);\n+\t\tif (err) {\n+\t\t\tnetdev_err(netdev, \"change mtu if_up err %d\\n\", err);\n+\t\t\treturn err;\n+\t\t}\n+\n+\t\terr = ice_up(vsi);\n+\t\tif (err) {\n+\t\t\tnetdev_err(netdev, \"change mtu if_up err %d\\n\", err);\n+\t\t\treturn err;\n+\t\t}\n+\t}\n+\n+\tnetdev_dbg(netdev, \"changed mtu to %d\\n\", new_mtu);\n+\treturn 0;\n+}\n+\n /**\n  * ice_set_rss - Set RSS keys and lut\n  * @vsi: Pointer to VSI structure\n@@ -4933,12 +5438,72 @@ static int ice_stop(struct net_device *netdev)\n \treturn 0;\n }\n \n+/**\n+ * ice_features_check - Validate encapsulated packet conforms to limits\n+ * @skb: skb buffer\n+ * @netdev: This port's netdev\n+ * @features: Offload features that the stack believes apply\n+ */\n+static netdev_features_t\n+ice_features_check(struct sk_buff *skb,\n+\t\t   struct net_device __always_unused *netdev,\n+\t\t   netdev_features_t features)\n+{\n+\tsize_t len;\n+\n+\t/* No point in doing any of this if neither checksum nor GSO are\n+\t * being requested for this frame.  We can rule out both by just\n+\t * checking for CHECKSUM_PARTIAL\n+\t */\n+\tif (skb->ip_summed != CHECKSUM_PARTIAL)\n+\t\treturn features;\n+\n+\t/* We cannot support GSO if the MSS is going to be less than\n+\t * 64 bytes.  If it is then we need to drop support for GSO.\n+\t */\n+\tif (skb_is_gso(skb) && (skb_shinfo(skb)->gso_size < 64))\n+\t\tfeatures &= ~NETIF_F_GSO_MASK;\n+\n+\tlen = skb_network_header(skb) - skb->data;\n+\tif (len & ~(ICE_TXD_MACLEN_MAX))\n+\t\tgoto out_rm_features;\n+\n+\tlen = skb_transport_header(skb) - skb_network_header(skb);\n+\tif (len & ~(ICE_TXD_IPLEN_MAX))\n+\t\tgoto out_rm_features;\n+\n+\tif (skb->encapsulation) {\n+\t\tlen = skb_inner_network_header(skb) - skb_transport_header(skb);\n+\t\tif (len & ~(ICE_TXD_L4LEN_MAX))\n+\t\t\tgoto out_rm_features;\n+\n+\t\tlen = skb_inner_transport_header(skb) -\n+\t\t      skb_inner_network_header(skb);\n+\t\tif (len & ~(ICE_TXD_IPLEN_MAX))\n+\t\t\tgoto out_rm_features;\n+\t}\n+\n+\treturn features;\n+out_rm_features:\n+\treturn features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);\n+}\n+\n static const struct net_device_ops ice_netdev_ops = {\n \t.ndo_open = ice_open,\n \t.ndo_stop = ice_stop,\n \t.ndo_start_xmit = ice_start_xmit,\n+\t.ndo_features_check = ice_features_check,\n+\t.ndo_set_rx_mode = ice_set_rx_mode,\n+\t.ndo_set_mac_address = ice_set_mac_address,\n+\t.ndo_validate_addr = eth_validate_addr,\n+\t.ndo_change_mtu = ice_change_mtu,\n \t.ndo_get_stats64 = ice_get_stats64,\n+#ifdef CONFIG_NET_POLL_CONTROLLER\n+\t.ndo_poll_controller = ice_netpoll,\n+#endif /* CONFIG_NET_POLL_CONTROLLER */\n \t.ndo_vlan_rx_add_vid = ice_vlan_rx_add_vid,\n \t.ndo_vlan_rx_kill_vid = ice_vlan_rx_kill_vid,\n \t.ndo_set_features = ice_set_features,\n+\t.ndo_fdb_add = ice_fdb_add,\n+\t.ndo_fdb_del = ice_fdb_del,\n };\ndiff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c\nindex 424090f598c3..fbdfeed6aa4e 100644\n--- a/drivers/net/ethernet/intel/ice/ice_switch.c\n+++ b/drivers/net/ethernet/intel/ice/ice_switch.c\n@@ -1640,6 +1640,83 @@ ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)\n \treturn status;\n }\n \n+/**\n+ * ice_cfg_dflt_vsi - add filter rule to set/unset given VSI as default\n+ * VSI for the switch (represented by swid)\n+ * @hw: pointer to the hardware structure\n+ * @vsi_id: number of VSI to set as default\n+ * @set: true to add the above mentioned switch rule, false to remove it\n+ * @direction: ICE_FLTR_RX or ICE_FLTR_TX\n+ */\n+enum ice_status\n+ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_id, bool set, u8 direction)\n+{\n+\tstruct ice_aqc_sw_rules_elem *s_rule;\n+\tstruct ice_fltr_info f_info;\n+\tenum ice_adminq_opc opcode;\n+\tenum ice_status status;\n+\tu16 s_rule_size;\n+\n+\ts_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :\n+\t\t\t    ICE_SW_RULE_RX_TX_NO_HDR_SIZE;\n+\ts_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);\n+\tif (!s_rule)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\n+\tmemset(&f_info, 0, sizeof(f_info));\n+\n+\tf_info.lkup_type = ICE_SW_LKUP_DFLT;\n+\tf_info.flag = direction;\n+\tf_info.fltr_act = ICE_FWD_TO_VSI;\n+\tf_info.fwd_id.vsi_id = vsi_id;\n+\n+\tif (f_info.flag & ICE_FLTR_RX) {\n+\t\tf_info.src = hw->port_info->lport;\n+\t\tif (!set)\n+\t\t\tf_info.fltr_rule_id =\n+\t\t\t\thw->port_info->dflt_rx_vsi_rule_id;\n+\t} else if (f_info.flag & ICE_FLTR_TX) {\n+\t\tf_info.src = vsi_id;\n+\t\tif (!set)\n+\t\t\tf_info.fltr_rule_id =\n+\t\t\t\thw->port_info->dflt_tx_vsi_rule_id;\n+\t}\n+\n+\tif (set)\n+\t\topcode = ice_aqc_opc_add_sw_rules;\n+\telse\n+\t\topcode = ice_aqc_opc_remove_sw_rules;\n+\n+\tice_fill_sw_rule(hw, &f_info, s_rule, opcode);\n+\n+\tstatus = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opcode, NULL);\n+\tif (status || !(f_info.flag & ICE_FLTR_TX_RX))\n+\t\tgoto out;\n+\tif (set) {\n+\t\tu16 index = le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);\n+\n+\t\tif (f_info.flag & ICE_FLTR_TX) {\n+\t\t\thw->port_info->dflt_tx_vsi_num = vsi_id;\n+\t\t\thw->port_info->dflt_tx_vsi_rule_id = index;\n+\t\t} else if (f_info.flag & ICE_FLTR_RX) {\n+\t\t\thw->port_info->dflt_rx_vsi_num = vsi_id;\n+\t\t\thw->port_info->dflt_rx_vsi_rule_id = index;\n+\t\t}\n+\t} else {\n+\t\tif (f_info.flag & ICE_FLTR_TX) {\n+\t\t\thw->port_info->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;\n+\t\t\thw->port_info->dflt_tx_vsi_rule_id = ICE_INVAL_ACT;\n+\t\t} else if (f_info.flag & ICE_FLTR_RX) {\n+\t\t\thw->port_info->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;\n+\t\t\thw->port_info->dflt_rx_vsi_rule_id = ICE_INVAL_ACT;\n+\t\t}\n+\t}\n+\n+out:\n+\tdevm_kfree(ice_hw_to_dev(hw), s_rule);\n+\treturn status;\n+}\n+\n /**\n  * ice_remove_vlan_internal - Remove one VLAN based filter rule\n  * @hw: pointer to the hardware structure\ndiff --git a/drivers/net/ethernet/intel/ice/ice_switch.h b/drivers/net/ethernet/intel/ice/ice_switch.h\nindex 60c63264a393..b063b87f1558 100644\n--- a/drivers/net/ethernet/intel/ice/ice_switch.h\n+++ b/drivers/net/ethernet/intel/ice/ice_switch.h\n@@ -169,5 +169,7 @@ enum ice_status ice_remove_mac(struct ice_hw *hw, struct list_head *m_lst);\n void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_id);\n enum ice_status ice_add_vlan(struct ice_hw *hw, struct list_head *m_list);\n enum ice_status ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list);\n+enum ice_status\n+ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_id, bool set, u8 direction);\n \n #endif /* _ICE_SWITCH_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h\nindex 100cb3cf8364..a9e8e28b64be 100644\n--- a/drivers/net/ethernet/intel/ice/ice_type.h\n+++ b/drivers/net/ethernet/intel/ice/ice_type.h\n@@ -24,6 +24,9 @@\n #include \"ice_controlq.h\"\n #include \"ice_lan_tx_rx.h\"\n \n+#define ICE_BYTES_PER_WORD\t2\n+#define ICE_BYTES_PER_DWORD\t4\n+\n static inline bool ice_is_tc_ena(u8 bitmap, u8 tc)\n {\n \treturn test_bit(tc, (unsigned long *)&bitmap);\n@@ -241,7 +244,9 @@ struct ice_port_info {\n \tu8 port_state;\n #define ICE_SCHED_PORT_STATE_INIT\t0x0\n #define ICE_SCHED_PORT_STATE_READY\t0x1\n+\tu16 dflt_tx_vsi_rule_id;\n \tu16 dflt_tx_vsi_num;\n+\tu16 dflt_rx_vsi_rule_id;\n \tu16 dflt_rx_vsi_num;\n \tstruct ice_fc_info fc;\n \tstruct ice_mac_info mac;\n",
    "prefixes": [
        "v3",
        "15/15"
    ]
}