get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 736080,
    "url": "http://patchwork.ozlabs.org/api/patches/736080/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1488874826-5978-3-git-send-email-yury.kylulin@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": "<1488874826-5978-3-git-send-email-yury.kylulin@intel.com>",
    "list_archive_url": null,
    "date": "2017-03-07T08:20:26",
    "name": "[2/2] igb/igbvf: Add VF MAC filter request capabilities",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "9666d3f026670c57e7fea04bc3888d8d182801b8",
    "submitter": {
        "id": 66563,
        "url": "http://patchwork.ozlabs.org/api/people/66563/?format=api",
        "name": "Yury Kylulin",
        "email": "yury.kylulin@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/1488874826-5978-3-git-send-email-yury.kylulin@intel.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/736080/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/736080/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<intel-wired-lan-bounces@lists.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"
        ],
        "Received": [
            "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\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 3vcqNq0lTdz9sN1\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue,  7 Mar 2017 19:20:59 +1100 (AEDT)",
            "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id 7404F31278;\n\tTue,  7 Mar 2017 08:20:57 +0000 (UTC)",
            "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id zoee1BZWJKGt; Tue,  7 Mar 2017 08:20:53 +0000 (UTC)",
            "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby silver.osuosl.org (Postfix) with ESMTP id 08B6F31280;\n\tTue,  7 Mar 2017 08:20:52 +0000 (UTC)",
            "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\tby ash.osuosl.org (Postfix) with ESMTP id 60DC41C2B48\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue,  7 Mar 2017 08:20:50 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 57BFBC1BC4\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue,  7 Mar 2017 08:20:50 +0000 (UTC)",
            "from fraxinus.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id vbOhxAC63spF for <intel-wired-lan@lists.osuosl.org>;\n\tTue,  7 Mar 2017 08:20:48 +0000 (UTC)",
            "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n\tby fraxinus.osuosl.org (Postfix) with ESMTPS id E0810C1BC7\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue,  7 Mar 2017 08:20:47 +0000 (UTC)",
            "from orsmga001.jf.intel.com ([10.7.209.18])\n\tby fmsmga105.fm.intel.com with ESMTP; 07 Mar 2017 00:20:47 -0800",
            "from devnode2.inn.intel.com ([10.125.24.131])\n\tby orsmga001.jf.intel.com with ESMTP; 07 Mar 2017 00:20:46 -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-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos; i=\"5.35,257,1484035200\"; d=\"scan'208\";\n\ta=\"1105667148\"",
        "From": "Yury Kylulin <yury.kylulin@intel.com>",
        "To": "intel-wired-lan@lists.osuosl.org",
        "Date": "Tue,  7 Mar 2017 11:20:26 +0300",
        "Message-Id": "<1488874826-5978-3-git-send-email-yury.kylulin@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1488874826-5978-1-git-send-email-yury.kylulin@intel.com>",
        "References": "<1488874826-5978-1-git-send-email-yury.kylulin@intel.com>",
        "Subject": "[Intel-wired-lan] [PATCH 2/2] igb/igbvf: Add VF MAC filter request\n\tcapabilities",
        "X-BeenThere": "intel-wired-lan@lists.osuosl.org",
        "X-Mailman-Version": "2.1.18-1",
        "Precedence": "list",
        "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.lists.osuosl.org>",
        "List-Unsubscribe": "<http://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.osuosl.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>",
        "List-Post": "<mailto:intel-wired-lan@lists.osuosl.org>",
        "List-Help": "<mailto:intel-wired-lan-request@lists.osuosl.org?subject=help>",
        "List-Subscribe": "<http://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.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@lists.osuosl.org",
        "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@lists.osuosl.org>"
    },
    "content": "Add functionality for the VF to request up to 3 additional MAC filters.\nThis is done using existing E1000_VF_SET_MAC_ADDR message, but with\nadditional message info - E1000_VF_MAC_FILTER_CLR to clear all unicast\nMAC filters previously set for this VF and E1000_VF_MAC_FILTER_ADD to\nadd MAC filter.\n\nAdditional filters can be added only in case if administrator did not\nset VF MAC explicitly and allowed to change default MAC to the VF.\n\nDue to the limmited number of RAR entries reserve at least 3 MAC filters\nfor the PF.\n\nIf SRIOV is supported by the NIC after this change RAR entries starting\nfrom 1 to (RAR MAX ENTRIES - NUM SRIOV VFS) will be used for PF and VF\nMAC filters.\n\nSigned-off-by: Yury Kylulin <yury.kylulin@intel.com>\n---\n drivers/net/ethernet/intel/igb/e1000_mbx.h |   4 +\n drivers/net/ethernet/intel/igb/igb.h       |  12 +++\n drivers/net/ethernet/intel/igb/igb_main.c  | 147 ++++++++++++++++++++++++++---\n drivers/net/ethernet/intel/igbvf/igbvf.h   |   2 +\n drivers/net/ethernet/intel/igbvf/mbx.h     |   4 +\n drivers/net/ethernet/intel/igbvf/netdev.c  |  44 ++++++++-\n drivers/net/ethernet/intel/igbvf/vf.c      |  42 +++++++++\n drivers/net/ethernet/intel/igbvf/vf.h      |   1 +\n 8 files changed, 241 insertions(+), 15 deletions(-)",
    "diff": "diff --git a/drivers/net/ethernet/intel/igb/e1000_mbx.h b/drivers/net/ethernet/intel/igb/e1000_mbx.h\nindex d20af6b..3e7fed7 100644\n--- a/drivers/net/ethernet/intel/igb/e1000_mbx.h\n+++ b/drivers/net/ethernet/intel/igb/e1000_mbx.h\n@@ -55,6 +55,10 @@\n \n #define E1000_VF_RESET\t\t0x01 /* VF requests reset */\n #define E1000_VF_SET_MAC_ADDR\t0x02 /* VF requests to set MAC addr */\n+/* VF requests to clear all unicast MAC filters */\n+#define E1000_VF_MAC_FILTER_CLR\t(0x01 << E1000_VT_MSGINFO_SHIFT)\n+/* VF requests to add unicast MAC filter */\n+#define E1000_VF_MAC_FILTER_ADD\t(0x02 << E1000_VT_MSGINFO_SHIFT)\n #define E1000_VF_SET_MULTICAST\t0x03 /* VF requests to set MC addr */\n #define E1000_VF_SET_VLAN\t0x04 /* VF requests to set VLAN */\n #define E1000_VF_SET_LPE\t0x05 /* VF requests to set VMOLR.LPE */\ndiff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h\nindex 97f348a..bf9bf90 100644\n--- a/drivers/net/ethernet/intel/igb/igb.h\n+++ b/drivers/net/ethernet/intel/igb/igb.h\n@@ -111,6 +111,16 @@ struct vf_data_storage {\n \tbool spoofchk_enabled;\n };\n \n+/* Number of unicast MAC filters reserved for the PF in the RAR registers */\n+#define IGB_PF_MAC_FILTERS_RESERVED\t3\n+\n+struct vf_mac_filter {\n+\tstruct list_head l;\n+\tint vf;\n+\tbool free;\n+\tu8 vf_mac[ETH_ALEN];\n+};\n+\n #define IGB_VF_FLAG_CTS            0x00000001 /* VF is clear to send data */\n #define IGB_VF_FLAG_UNI_PROMISC    0x00000002 /* VF has unicast promisc */\n #define IGB_VF_FLAG_MULTI_PROMISC  0x00000004 /* VF has multicast promisc */\n@@ -586,6 +596,8 @@ struct igb_adapter {\n \tbool etype_bitmap[MAX_ETYPE_FILTER];\n \n \tstruct igb_mac_addr *mac_table;\n+\tstruct vf_mac_filter vf_macs;\n+\tstruct vf_mac_filter *vf_mac_list;\n };\n \n /* flags controlling PTP/1588 function */\ndiff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c\nindex bb5d5ac..53e66c8 100644\n--- a/drivers/net/ethernet/intel/igb/igb_main.c\n+++ b/drivers/net/ethernet/intel/igb/igb_main.c\n@@ -1158,6 +1158,8 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter, bool msix)\n \t\tpci_disable_sriov(adapter->pdev);\n \t\tmsleep(500);\n \n+\t\tkfree(adapter->vf_mac_list);\n+\t\tadapter->vf_mac_list = NULL;\n \t\tkfree(adapter->vf_data);\n \t\tadapter->vf_data = NULL;\n \t\twr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);\n@@ -2809,6 +2811,8 @@ static int igb_disable_sriov(struct pci_dev *pdev)\n \t\t\tmsleep(500);\n \t\t}\n \n+\t\tkfree(adapter->vf_mac_list);\n+\t\tadapter->vf_mac_list = NULL;\n \t\tkfree(adapter->vf_data);\n \t\tadapter->vf_data = NULL;\n \t\tadapter->vfs_allocated_count = 0;\n@@ -2829,8 +2833,9 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)\n \tstruct net_device *netdev = pci_get_drvdata(pdev);\n \tstruct igb_adapter *adapter = netdev_priv(netdev);\n \tint old_vfs = pci_num_vf(pdev);\n+\tstruct vf_mac_filter *mac_list;\n \tint err = 0;\n-\tint i;\n+\tint num_vf_mac_filters, i;\n \n \tif (!(adapter->flags & IGB_FLAG_HAS_MSIX) || num_vfs > 7) {\n \t\terr = -EPERM;\n@@ -2858,6 +2863,38 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)\n \t\tgoto out;\n \t}\n \n+\t/* Due to the limited number of RAR entries calculate potential\n+\t * number of MAC filters available for the VFs. Reserve entries\n+\t * for PF default MAC, PF MAC filters and at least one RAR entry\n+\t * for each VF for VF MAC.\n+\t */\n+\tnum_vf_mac_filters = adapter->hw.mac.rar_entry_count -\n+\t\t\t     (1 + IGB_PF_MAC_FILTERS_RESERVED +\n+\t\t\t      adapter->vfs_allocated_count);\n+\n+\tadapter->vf_mac_list = kcalloc(num_vf_mac_filters,\n+\t\t\t\t       sizeof(struct vf_mac_filter),\n+\t\t\t\t       GFP_KERNEL);\n+\n+\tmac_list = adapter->vf_mac_list;\n+\tINIT_LIST_HEAD(&adapter->vf_macs.l);\n+\n+\tif (adapter->vf_mac_list) {\n+\t\t/* Initialize list of VF MAC filters */\n+\t\tfor (i = 0; i < num_vf_mac_filters; i++) {\n+\t\t\tmac_list->vf = -1;\n+\t\t\tmac_list->free = true;\n+\t\t\tlist_add(&mac_list->l, &adapter->vf_macs.l);\n+\t\t\tmac_list++;\n+\t\t}\n+\t} else {\n+\t\t/* If we could not allocate memory for the VF MAC filters\n+\t\t * we can continue without this feature but warn user.\n+\t\t */\n+\t\tdev_err(&pdev->dev,\n+\t\t\t\"Unable to allocate memory for VF MAC filter list\\n\");\n+\t}\n+\n \t/* only call pci_enable_sriov() if no VFs are allocated already */\n \tif (!old_vfs) {\n \t\terr = pci_enable_sriov(pdev, adapter->vfs_allocated_count);\n@@ -2874,6 +2911,8 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)\n \tgoto out;\n \n err_out:\n+\tkfree(adapter->vf_mac_list);\n+\tadapter->vf_mac_list = NULL;\n \tkfree(adapter->vf_data);\n \tadapter->vf_data = NULL;\n \tadapter->vfs_allocated_count = 0;\n@@ -6501,18 +6540,106 @@ static int igb_uc_unsync(struct net_device *netdev, const unsigned char *addr)\n \treturn 0;\n }\n \n+int igb_set_vf_mac_filter(struct igb_adapter *adapter, const int vf,\n+\t\t\t  const u32 info, const u8 *addr)\n+{\n+\tstruct pci_dev *pdev = adapter->pdev;\n+\tstruct vf_data_storage *vf_data = &adapter->vf_data[vf];\n+\tstruct list_head *pos;\n+\tstruct vf_mac_filter *entry = NULL;\n+\tint ret = 0;\n+\n+\tswitch (info) {\n+\tcase E1000_VF_MAC_FILTER_CLR:\n+\t\t/* remove all unicast MAC filters related to the current VF */\n+\t\tlist_for_each(pos, &adapter->vf_macs.l) {\n+\t\t\tentry = list_entry(pos, struct vf_mac_filter, l);\n+\t\t\tif (entry->vf == vf) {\n+\t\t\t\tentry->vf = -1;\n+\t\t\t\tentry->free = true;\n+\t\t\t\tigb_del_mac_filter(adapter, entry->vf_mac, vf);\n+\t\t\t}\n+\t\t}\n+\t\tbreak;\n+\tcase E1000_VF_MAC_FILTER_ADD:\n+\t\tif (vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) {\n+\t\t\tdev_warn(&pdev->dev,\n+\t\t\t\t \"VF %d requested MAC filter but is administratively denied\\n\",\n+\t\t\t\t vf);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (!is_valid_ether_addr(addr)) {\n+\t\t\tdev_warn(&pdev->dev,\n+\t\t\t\t \"VF %d attempted to set invalid MAC filter\\n\",\n+\t\t\t\t vf);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\t/* try to find empty slot in the list */\n+\t\tlist_for_each(pos, &adapter->vf_macs.l) {\n+\t\t\tentry = list_entry(pos, struct vf_mac_filter, l);\n+\t\t\tif (entry->free)\n+\t\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (entry && entry->free) {\n+\t\t\tentry->free = false;\n+\t\t\tentry->vf = vf;\n+\t\t\tether_addr_copy(entry->vf_mac, addr);\n+\n+\t\t\tret = igb_add_mac_filter(adapter, addr, vf);\n+\t\t\tret = min_t(int, ret, 0);\n+\t\t} else {\n+\t\t\tret = -ENOSPC;\n+\t\t}\n+\n+\t\tif (ret == -ENOSPC)\n+\t\t\tdev_warn(&pdev->dev,\n+\t\t\t\t \"VF %d has requested MAC filter but there is no space for it\\n\",\n+\t\t\t\t vf);\n+\t\tbreak;\n+\tdefault:\n+\t\tret = -EINVAL;\n+\t\tbreak;\n+\t}\n+\n+\treturn ret;\n+}\n+\n static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf)\n {\n+\tstruct pci_dev *pdev = adapter->pdev;\n+\tstruct vf_data_storage *vf_data = &adapter->vf_data[vf];\n+\tu32 info = msg[0] & E1000_VT_MSGINFO_MASK;\n+\n \t/* The VF MAC Address is stored in a packed array of bytes\n \t * starting at the second 32 bit word of the msg array\n \t */\n-\tunsigned char *addr = (char *)&msg[1];\n-\tint err = -1;\n+\tunsigned char *addr = (unsigned char *)&msg[1];\n+\tint ret = 0;\n \n-\tif (is_valid_ether_addr(addr))\n-\t\terr = igb_set_vf_mac(adapter, vf, addr);\n+\tif (!info) {\n+\t\tif (vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) {\n+\t\t\tdev_warn(&pdev->dev,\n+\t\t\t\t \"VF %d attempted to override administratively set MAC address\\nReload the VF driver to resume operations\\n\",\n+\t\t\t\t vf);\n+\t\t\treturn -EINVAL;\n+\t\t}\n \n-\treturn err;\n+\t\tif (!is_valid_ether_addr(addr)) {\n+\t\t\tdev_warn(&pdev->dev,\n+\t\t\t\t \"VF %d attempted to set invalid MAC\\n\",\n+\t\t\t\t vf);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tret = igb_set_vf_mac(adapter, vf, addr);\n+\t} else {\n+\t\tret = igb_set_vf_mac_filter(adapter, vf, info, addr);\n+\t}\n+\n+\treturn ret;\n }\n \n static void igb_rcv_ack_from_vf(struct igb_adapter *adapter, u32 vf)\n@@ -6569,13 +6696,7 @@ static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)\n \n \tswitch ((msgbuf[0] & 0xFFFF)) {\n \tcase E1000_VF_SET_MAC_ADDR:\n-\t\tretval = -EINVAL;\n-\t\tif (!(vf_data->flags & IGB_VF_FLAG_PF_SET_MAC))\n-\t\t\tretval = igb_set_vf_mac_addr(adapter, msgbuf, vf);\n-\t\telse\n-\t\t\tdev_warn(&pdev->dev,\n-\t\t\t\t \"VF %d attempted to override administratively set MAC address\\nReload the VF driver to resume operations\\n\",\n-\t\t\t\t vf);\n+\t\tretval = igb_set_vf_mac_addr(adapter, msgbuf, vf);\n \t\tbreak;\n \tcase E1000_VF_SET_PROMISC:\n \t\tretval = igb_set_vf_promisc(adapter, msgbuf, vf);\ndiff --git a/drivers/net/ethernet/intel/igbvf/igbvf.h b/drivers/net/ethernet/intel/igbvf/igbvf.h\nindex 6f4290d..2a53ed8 100644\n--- a/drivers/net/ethernet/intel/igbvf/igbvf.h\n+++ b/drivers/net/ethernet/intel/igbvf/igbvf.h\n@@ -101,6 +101,8 @@ enum latency_range {\n \n #define IGBVF_MNG_VLAN_NONE\t(-1)\n \n+#define IGBVF_MAX_MAC_FILTERS\t3\n+\n /* Number of packet split data buffers (not including the header buffer) */\n #define PS_PAGE_BUFFERS\t\t(MAX_PS_BUFFERS - 1)\n \ndiff --git a/drivers/net/ethernet/intel/igbvf/mbx.h b/drivers/net/ethernet/intel/igbvf/mbx.h\nindex f800bf8..30d58c4 100644\n--- a/drivers/net/ethernet/intel/igbvf/mbx.h\n+++ b/drivers/net/ethernet/intel/igbvf/mbx.h\n@@ -62,6 +62,10 @@\n \n #define E1000_VF_RESET\t\t0x01 /* VF requests reset */\n #define E1000_VF_SET_MAC_ADDR\t0x02 /* VF requests PF to set MAC addr */\n+/* VF requests PF to clear all unicast MAC filters */\n+#define E1000_VF_MAC_FILTER_CLR (0x01 << E1000_VT_MSGINFO_SHIFT)\n+/* VF requests PF to add unicast MAC filter */\n+#define E1000_VF_MAC_FILTER_ADD (0x02 << E1000_VT_MSGINFO_SHIFT)\n #define E1000_VF_SET_MULTICAST\t0x03 /* VF requests PF to set MC addr */\n #define E1000_VF_SET_VLAN\t0x04 /* VF requests PF to set VLAN */\n #define E1000_VF_SET_LPE\t0x05 /* VF requests PF to set VMOLR.LPE */\ndiff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c\nindex 839ba11..6029854 100644\n--- a/drivers/net/ethernet/intel/igbvf/netdev.c\n+++ b/drivers/net/ethernet/intel/igbvf/netdev.c\n@@ -1433,12 +1433,52 @@ static void igbvf_set_multi(struct net_device *netdev)\n }\n \n /**\n+ * igbvf_set_uni - Configure unicast MAC filters\n+ * @netdev: network interface device structure\n+ *\n+ * This routine is responsible for configuring the hardware for proper\n+ * unicast filters.\n+ **/\n+static int igbvf_set_uni(struct net_device *netdev)\n+{\n+\tstruct igbvf_adapter *adapter = netdev_priv(netdev);\n+\tstruct e1000_hw *hw = &adapter->hw;\n+\n+\tif (netdev_uc_count(netdev) > IGBVF_MAX_MAC_FILTERS) {\n+\t\tpr_err(\"Too many unicast filters - No Space\\n\");\n+\t\treturn -ENOSPC;\n+\t}\n+\n+\t/* Clear all unicast MAC filters */\n+\thw->mac.ops.set_uc_addr(hw, E1000_VF_MAC_FILTER_CLR, NULL);\n+\n+\tif (!netdev_uc_empty(netdev)) {\n+\t\tstruct netdev_hw_addr *ha;\n+\n+\t\t/* Add MAC filters one by one */\n+\t\tnetdev_for_each_uc_addr(ha, netdev) {\n+\t\t\thw->mac.ops.set_uc_addr(hw, E1000_VF_MAC_FILTER_ADD,\n+\t\t\t\t\t\tha->addr);\n+\t\t\tudelay(200);\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void igbvf_set_rx_mode(struct net_device *netdev)\n+{\n+\tigbvf_set_multi(netdev);\n+\tigbvf_set_uni(netdev);\n+}\n+\n+/**\n  * igbvf_configure - configure the hardware for Rx and Tx\n  * @adapter: private board structure\n  **/\n static void igbvf_configure(struct igbvf_adapter *adapter)\n {\n-\tigbvf_set_multi(adapter->netdev);\n+\tigbvf_set_rx_mode(adapter->netdev);\n \n \tigbvf_restore_vlan(adapter);\n \n@@ -2636,7 +2676,7 @@ static const struct net_device_ops igbvf_netdev_ops = {\n \t.ndo_stop\t\t= igbvf_close,\n \t.ndo_start_xmit\t\t= igbvf_xmit_frame,\n \t.ndo_get_stats\t\t= igbvf_get_stats,\n-\t.ndo_set_rx_mode\t= igbvf_set_multi,\n+\t.ndo_set_rx_mode\t= igbvf_set_rx_mode,\n \t.ndo_set_mac_address\t= igbvf_set_mac,\n \t.ndo_change_mtu\t\t= igbvf_change_mtu,\n \t.ndo_do_ioctl\t\t= igbvf_ioctl,\ndiff --git a/drivers/net/ethernet/intel/igbvf/vf.c b/drivers/net/ethernet/intel/igbvf/vf.c\nindex 335ba66..dfa689b 100644\n--- a/drivers/net/ethernet/intel/igbvf/vf.c\n+++ b/drivers/net/ethernet/intel/igbvf/vf.c\n@@ -36,6 +36,7 @@ static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *,\n \t\t\t\t\t u32, u32, u32);\n static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);\n static s32 e1000_read_mac_addr_vf(struct e1000_hw *);\n+static s32 e1000_set_uc_addr_vf(struct e1000_hw *hw, u32 subcmd, u8 *addr);\n static s32 e1000_set_vfta_vf(struct e1000_hw *, u16, bool);\n \n /**\n@@ -66,6 +67,8 @@ static s32 e1000_init_mac_params_vf(struct e1000_hw *hw)\n \tmac->ops.rar_set = e1000_rar_set_vf;\n \t/* read mac address */\n \tmac->ops.read_mac_addr = e1000_read_mac_addr_vf;\n+\t/* set mac filter */\n+\tmac->ops.set_uc_addr = e1000_set_uc_addr_vf;\n \t/* set vlan filter table array */\n \tmac->ops.set_vfta = e1000_set_vfta_vf;\n \n@@ -338,6 +341,45 @@ static s32 e1000_read_mac_addr_vf(struct e1000_hw *hw)\n }\n \n /**\n+ *  e1000_set_uc_addr_vf - Set or clear unicast filters\n+ *  @hw: pointer to the HW structure\n+ *  @sub_cmd: add or clear filters\n+ *  @addr: pointer to the filter MAC address\n+ **/\n+\n+static s32 e1000_set_uc_addr_vf(struct e1000_hw *hw, u32 sub_cmd, u8 *addr)\n+{\n+\tstruct e1000_mbx_info *mbx = &hw->mbx;\n+\tu32 msgbuf[3], msgbuf_chk;\n+\tu8 *msg_addr = (u8 *)(&msgbuf[1]);\n+\ts32 ret_val;\n+\n+\tmemset(msgbuf, 0, sizeof(msgbuf));\n+\tmsgbuf[0] |= sub_cmd;\n+\tmsgbuf[0] |= E1000_VF_SET_MAC_ADDR;\n+\tmsgbuf_chk = msgbuf[0];\n+\n+\tif (addr)\n+\t\tmemcpy(msg_addr, addr, ETH_ALEN);\n+\n+\tret_val = mbx->ops.write_posted(hw, msgbuf, 3);\n+\n+\tif (!ret_val)\n+\t\tret_val = mbx->ops.read_posted(hw, msgbuf, 3);\n+\n+\tmsgbuf[0] &= ~E1000_VT_MSGTYPE_CTS;\n+\n+\tif (!ret_val) {\n+\t\tmsgbuf[0] &= ~E1000_VT_MSGTYPE_CTS;\n+\n+\t\tif (msgbuf[0] == (msgbuf_chk | E1000_VT_MSGTYPE_NACK))\n+\t\t\treturn -ENOSPC;\n+\t}\n+\n+\treturn ret_val;\n+}\n+\n+/**\n  *  e1000_check_for_link_vf - Check for link for a virtual interface\n  *  @hw: pointer to the HW structure\n  *\ndiff --git a/drivers/net/ethernet/intel/igbvf/vf.h b/drivers/net/ethernet/intel/igbvf/vf.h\nindex f00a41d..4cf78b0 100644\n--- a/drivers/net/ethernet/intel/igbvf/vf.h\n+++ b/drivers/net/ethernet/intel/igbvf/vf.h\n@@ -179,6 +179,7 @@ struct e1000_mac_operations {\n \ts32  (*get_bus_info)(struct e1000_hw *);\n \ts32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);\n \tvoid (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32);\n+\ts32  (*set_uc_addr)(struct e1000_hw *, u32, u8 *);\n \ts32  (*reset_hw)(struct e1000_hw *);\n \ts32  (*init_hw)(struct e1000_hw *);\n \ts32  (*setup_link)(struct e1000_hw *);\n",
    "prefixes": [
        "2/2"
    ]
}