Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/609822/?format=api
{ "id": 609822, "url": "http://patchwork.ozlabs.org/api/patches/609822/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1460475052-6348-6-git-send-email-harshitha.ramamurthy@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": "<1460475052-6348-6-git-send-email-harshitha.ramamurthy@intel.com>", "list_archive_url": null, "date": "2016-04-12T15:30:44", "name": "[next,S33,05/13] i40evf: Allow PF driver to configure RSS", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "d514f4f39d5f142d79c55cafcad78034929e793e", "submitter": { "id": 68642, "url": "http://patchwork.ozlabs.org/api/people/68642/?format=api", "name": "Harshitha Ramamurthy", "email": "harshitha.ramamurthy@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/1460475052-6348-6-git-send-email-harshitha.ramamurthy@intel.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/609822/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/609822/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\tby ozlabs.org (Postfix) with ESMTP id 3ql3K66963z9sRZ\n\tfor <incoming@patchwork.ozlabs.org>;\n\tWed, 13 Apr 2016 09:38:18 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id 2827631A56;\n\tTue, 12 Apr 2016 23:38:18 +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 Z085iS-AtA6U; Tue, 12 Apr 2016 23:38:06 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby silver.osuosl.org (Postfix) with ESMTP id 3B1B33303C;\n\tTue, 12 Apr 2016 23:38:05 +0000 (UTC)", "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\tby ash.osuosl.org (Postfix) with ESMTP id 1DC631C0E44\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue, 12 Apr 2016 23:38:03 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 19952C01EC\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue, 12 Apr 2016 23:38:03 +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 aELwAwtecRdB for <intel-wired-lan@lists.osuosl.org>;\n\tTue, 12 Apr 2016 23:38:01 +0000 (UTC)", "from mga01.intel.com (mga01.intel.com [192.55.52.88])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 5B987C02DF\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue, 12 Apr 2016 23:38:01 +0000 (UTC)", "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby fmsmga101.fm.intel.com with ESMTP; 12 Apr 2016 16:36:30 -0700", "from harshitha-linux1.jf.intel.com ([10.166.45.81])\n\tby orsmga002.jf.intel.com with ESMTP; 12 Apr 2016 16:36:30 -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-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.24,476,1455004800\"; d=\"scan'208\";a=\"953677397\"", "From": "Harshitha Ramamurthy <harshitha.ramamurthy@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Tue, 12 Apr 2016 08:30:44 -0700", "Message-Id": "<1460475052-6348-6-git-send-email-harshitha.ramamurthy@intel.com>", "X-Mailer": "git-send-email 2.4.3", "In-Reply-To": "<1460475052-6348-1-git-send-email-harshitha.ramamurthy@intel.com>", "References": "<1460475052-6348-1-git-send-email-harshitha.ramamurthy@intel.com>", "Subject": "[Intel-wired-lan] [next PATCH S33 05/13] i40evf: Allow PF driver to\n\tconfigure RSS", "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": "From: Mitch Williams <mitch.a.williams@intel.com>\n\nIf the PF driver reports proper support, allow the PF driver to\nconfigure RSS on the behalf of the VF driver. This will allow for RSS\nsupport on future hardware without changes to the VF driver.\n\nUnfortunately, the old RSS code still needs to stay as the driver needs\nto be compatible with PF drivers that don't support this interface. But\nthis change still simplifies the data structures a bunch and makes this\ncode simpler to read and maintain.\n\nSigned-off-by: Mitch Williams <mitch.a.williams@intel.com>\nChange-ID: I0375aad40788ecdc0cb24d5cfeccf07804e69771\n---\nTesting Hints : Use ethtool to change RSS params and\nmake sure they stick and work correctly.\n\n drivers/net/ethernet/intel/i40evf/i40evf.h | 30 +-\n drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 121 ++++----\n drivers/net/ethernet/intel/i40evf/i40evf_main.c | 308 +++++++--------------\n .../net/ethernet/intel/i40evf/i40evf_virtchnl.c | 119 ++++++++\n 4 files changed, 294 insertions(+), 284 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h\nindex 017c83b..63f7aae 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf.h\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf.h\n@@ -67,8 +67,6 @@ struct i40e_vsi {\n \tu16 rx_itr_setting;\n \tu16 tx_itr_setting;\n \tu16 qs_handle;\n-\tu8 *rss_hkey_user; /* User configured hash keys */\n-\tu8 *rss_lut_user; /* User configured lookup table entries */\n };\n \n /* How many Rx Buffers do we bundle into one write to the hardware ? */\n@@ -239,8 +237,13 @@ struct i40evf_adapter {\n #define I40EVF_FLAG_AQ_CONFIGURE_QUEUES\t\tBIT(6)\n #define I40EVF_FLAG_AQ_MAP_VECTORS\t\tBIT(7)\n #define I40EVF_FLAG_AQ_HANDLE_RESET\t\tBIT(8)\n-#define I40EVF_FLAG_AQ_CONFIGURE_RSS\t\tBIT(9)\n+#define I40EVF_FLAG_AQ_CONFIGURE_RSS\t\tBIT(9)\t/* direct AQ config */\n #define I40EVF_FLAG_AQ_GET_CONFIG\t\tBIT(10)\n+/* Newer style, RSS done by the PF so we can ignore hardware vagaries. */\n+#define I40EVF_FLAG_AQ_GET_HENA\t\t\tBIT(11)\n+#define I40EVF_FLAG_AQ_SET_HENA\t\t\tBIT(12)\n+#define I40EVF_FLAG_AQ_SET_RSS_KEY\t\tBIT(13)\n+#define I40EVF_FLAG_AQ_SET_RSS_LUT\t\tBIT(14)\n \n \t/* OS defined structs */\n \tstruct net_device *netdev;\n@@ -260,8 +263,14 @@ struct i40evf_adapter {\n \t\t\t (_a)->vf_res->vf_offload_flags & \\\n \t\t\t\tI40E_VIRTCHNL_VF_OFFLOAD_IWARP : \\\n \t\t\t 0)\n+/* RSS by the PF should be preferred over RSS via other methods. */\n+#define RSS_PF(_a) ((_a)->vf_res->vf_offload_flags & \\\n+\t\t I40E_VIRTCHNL_VF_OFFLOAD_RSS_PF)\n #define RSS_AQ(_a) ((_a)->vf_res->vf_offload_flags & \\\n \t\t I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ)\n+#define RSS_REG(_a) (!((_a)->vf_res->vf_offload_flags & \\\n+\t\t (I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ | \\\n+\t\t\tI40E_VIRTCHNL_VF_OFFLOAD_RSS_PF)))\n #define VLAN_ALLOWED(_a) ((_a)->vf_res->vf_offload_flags & \\\n \t\t\t I40E_VIRTCHNL_VF_OFFLOAD_VLAN)\n \tstruct i40e_virtchnl_vf_resource *vf_res; /* incl. all VSIs */\n@@ -273,6 +282,12 @@ struct i40evf_adapter {\n \tstruct i40e_eth_stats current_stats;\n \tstruct i40e_vsi vsi;\n \tu32 aq_wait_count;\n+\t/* RSS stuff */\n+\tu64 hena;\n+\tu16 rss_key_size;\n+\tu16 rss_lut_size;\n+\tu8 *rss_key;\n+\tu8 *rss_lut;\n };\n \n \n@@ -316,11 +331,12 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter);\n void i40evf_set_promiscuous(struct i40evf_adapter *adapter, int flags);\n void i40evf_request_stats(struct i40evf_adapter *adapter);\n void i40evf_request_reset(struct i40evf_adapter *adapter);\n+void i40evf_get_hena(struct i40evf_adapter *adapter);\n+void i40evf_set_hena(struct i40evf_adapter *adapter);\n+void i40evf_set_rss_key(struct i40evf_adapter *adapter);\n+void i40evf_set_rss_lut(struct i40evf_adapter *adapter);\n void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,\n \t\t\t\tenum i40e_virtchnl_ops v_opcode,\n \t\t\t\ti40e_status v_retval, u8 *msg, u16 msglen);\n-int i40evf_config_rss(struct i40e_vsi *vsi, const u8 *seed, u8 *lut,\n-\t\t u16 lut_size);\n-int i40evf_get_rss(struct i40e_vsi *vsi, const u8 *seed, u8 *lut,\n-\t\t u16 lut_size);\n+int i40evf_config_rss(struct i40evf_adapter *adapter);\n #endif /* _I40EVF_H_ */\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c\nindex dd4430a..8a5cafb 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c\n@@ -387,20 +387,16 @@ static int i40evf_set_coalesce(struct net_device *netdev,\n static int i40evf_get_rss_hash_opts(struct i40evf_adapter *adapter,\n \t\t\t\t struct ethtool_rxnfc *cmd)\n {\n-\tstruct i40e_hw *hw = &adapter->hw;\n-\tu64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |\n-\t\t ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);\n-\n \t/* We always hash on IP src and dest addresses */\n \tcmd->data = RXH_IP_SRC | RXH_IP_DST;\n \n \tswitch (cmd->flow_type) {\n \tcase TCP_V4_FLOW:\n-\t\tif (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP))\n+\t\tif (adapter->hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP))\n \t\t\tcmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;\n \t\tbreak;\n \tcase UDP_V4_FLOW:\n-\t\tif (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP))\n+\t\tif (adapter->hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP))\n \t\t\tcmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;\n \t\tbreak;\n \n@@ -412,11 +408,11 @@ static int i40evf_get_rss_hash_opts(struct i40evf_adapter *adapter,\n \t\tbreak;\n \n \tcase TCP_V6_FLOW:\n-\t\tif (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP))\n+\t\tif (adapter->hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP))\n \t\t\tcmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;\n \t\tbreak;\n \tcase UDP_V6_FLOW:\n-\t\tif (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP))\n+\t\tif (adapter->hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP))\n \t\t\tcmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;\n \t\tbreak;\n \n@@ -476,9 +472,6 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,\n \tstruct i40e_hw *hw = &adapter->hw;\n \tu32 flags = adapter->vf_res->vf_offload_flags;\n \n-\tu64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |\n-\t\t ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);\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@@ -495,10 +488,11 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,\n \tcase TCP_V4_FLOW:\n \t\tif (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {\n \t\t\tif (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)\n-\t\t\t\thena |=\n+\t\t\t\tadapter->hena |=\n \t\t\t BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);\n \n-\t\t\thena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);\n+\t\t\tadapter->hena |=\n+\t\t BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);\n \t\t} else {\n \t\t\treturn -EINVAL;\n \t\t}\n@@ -506,10 +500,11 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,\n \tcase TCP_V6_FLOW:\n \t\tif (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {\n \t\t\tif (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)\n-\t\t\t\thena |=\n+\t\t\t\tadapter->hena |=\n \t\t\t BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);\n \n-\t\t\thena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);\n+\t\t\tadapter->hena |=\n+\t\t BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);\n \t\t} else {\n \t\t\treturn -EINVAL;\n \t\t}\n@@ -517,11 +512,12 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,\n \tcase UDP_V4_FLOW:\n \t\tif (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {\n \t\t\tif (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)\n-\t\t\t\thena |=\n+\t\t\t\tadapter->hena |=\n \t\t\t BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |\n \t\t\t BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);\n \n-\t\t\thena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |\n+\t\t\tadapter->hena |=\n+\t\t\t\t(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |\n \t\t\t\t BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));\n \t\t} else {\n \t\t\treturn -EINVAL;\n@@ -530,11 +526,12 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,\n \tcase UDP_V6_FLOW:\n \t\tif (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {\n \t\t\tif (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)\n-\t\t\t\thena |=\n+\t\t\t\tadapter->hena |=\n \t\t\t BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |\n \t\t\t BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);\n \n-\t\t\thena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |\n+\t\t\tadapter->hena |=\n+\t\t\t\t(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |\n \t\t\t\t BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));\n \t\t} else {\n \t\t\treturn -EINVAL;\n@@ -547,7 +544,7 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,\n \t\tif ((nfc->data & RXH_L4_B_0_1) ||\n \t\t (nfc->data & RXH_L4_B_2_3))\n \t\t\treturn -EINVAL;\n-\t\thena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);\n+\t\tadapter->hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);\n \t\tbreak;\n \tcase AH_ESP_V6_FLOW:\n \tcase AH_V6_FLOW:\n@@ -556,23 +553,27 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,\n \t\tif ((nfc->data & RXH_L4_B_0_1) ||\n \t\t (nfc->data & RXH_L4_B_2_3))\n \t\t\treturn -EINVAL;\n-\t\thena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);\n+\t\tadapter->hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);\n \t\tbreak;\n \tcase IPV4_FLOW:\n-\t\thena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |\n-\t\t\t BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));\n+\t\tadapter->hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |\n+\t\t\t\t BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));\n \t\tbreak;\n \tcase IPV6_FLOW:\n-\t\thena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |\n-\t\t\t BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));\n+\t\tadapter->hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |\n+\t\t\t\t BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));\n \t\tbreak;\n \tdefault:\n \t\treturn -EINVAL;\n \t}\n \n-\twr32(hw, I40E_VFQF_HENA(0), (u32)hena);\n-\twr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32));\n-\ti40e_flush(hw);\n+\tif (RSS_PF(adapter)) {\n+\t\tadapter->aq_required = I40EVF_FLAG_AQ_SET_HENA;\n+\t} else {\n+\t\twr32(hw, I40E_VFQF_HENA(0), (u32)adapter->hena);\n+\t\twr32(hw, I40E_VFQF_HENA(1), (u32)(adapter->hena >> 32));\n+\t\ti40e_flush(hw);\n+\t}\n \n \treturn 0;\n }\n@@ -624,6 +625,19 @@ static void i40evf_get_channels(struct net_device *netdev,\n }\n \n /**\n+ * i40evf_get_rxfh_key_size - get the RSS hash key size\n+ * @netdev: network interface device structure\n+ *\n+ * Returns the table size.\n+ **/\n+static u32 i40evf_get_rxfh_key_size(struct net_device *netdev)\n+{\n+\tstruct i40evf_adapter *adapter = netdev_priv(netdev);\n+\n+\treturn adapter->rss_key_size;\n+}\n+\n+/**\n * i40evf_get_rxfh_indir_size - get the rx flow hash indirection table size\n * @netdev: network interface device structure\n *\n@@ -631,7 +645,9 @@ static void i40evf_get_channels(struct net_device *netdev,\n **/\n static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)\n {\n-\treturn (I40E_VFQF_HLUT_MAX_INDEX + 1) * 4;\n+\tstruct i40evf_adapter *adapter = netdev_priv(netdev);\n+\n+\treturn adapter->rss_lut_size;\n }\n \n /**\n@@ -646,9 +662,6 @@ static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,\n \t\t\t u8 *hfunc)\n {\n \tstruct i40evf_adapter *adapter = netdev_priv(netdev);\n-\tstruct i40e_vsi *vsi = &adapter->vsi;\n-\tu8 *seed = NULL, *lut;\n-\tint ret;\n \tu16 i;\n \n \tif (hfunc)\n@@ -656,24 +669,13 @@ static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,\n \tif (!indir)\n \t\treturn 0;\n \n-\tseed = key;\n-\n-\tlut = kzalloc(I40EVF_HLUT_ARRAY_SIZE, GFP_KERNEL);\n-\tif (!lut)\n-\t\treturn -ENOMEM;\n-\n-\tret = i40evf_get_rss(vsi, seed, lut, I40EVF_HLUT_ARRAY_SIZE);\n-\tif (ret)\n-\t\tgoto out;\n+\tmemcpy(key, adapter->rss_key, adapter->rss_key_size);\n \n \t/* Each 32 bits pointed by 'indir' is stored with a lut entry */\n-\tfor (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)\n-\t\tindir[i] = (u32)lut[i];\n+\tfor (i = 0; i < adapter->rss_lut_size; i++)\n+\t\tindir[i] = (u32)adapter->rss_lut[i];\n \n-out:\n-\tkfree(lut);\n-\n-\treturn ret;\n+\treturn 0;\n }\n \n /**\n@@ -689,8 +691,6 @@ static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,\n \t\t\t const u8 *key, const u8 hfunc)\n {\n \tstruct i40evf_adapter *adapter = netdev_priv(netdev);\n-\tstruct i40e_vsi *vsi = &adapter->vsi;\n-\tu8 *seed = NULL;\n \tu16 i;\n \n \t/* We do not allow change in unsupported parameters */\n@@ -701,28 +701,14 @@ static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,\n \t\treturn 0;\n \n \tif (key) {\n-\t\tif (!vsi->rss_hkey_user) {\n-\t\t\tvsi->rss_hkey_user = kzalloc(I40EVF_HKEY_ARRAY_SIZE,\n-\t\t\t\t\t\t GFP_KERNEL);\n-\t\t\tif (!vsi->rss_hkey_user)\n-\t\t\t\treturn -ENOMEM;\n-\t\t}\n-\t\tmemcpy(vsi->rss_hkey_user, key, I40EVF_HKEY_ARRAY_SIZE);\n-\t\tseed = vsi->rss_hkey_user;\n-\t}\n-\tif (!vsi->rss_lut_user) {\n-\t\tvsi->rss_lut_user = kzalloc(I40EVF_HLUT_ARRAY_SIZE,\n-\t\t\t\t\t GFP_KERNEL);\n-\t\tif (!vsi->rss_lut_user)\n-\t\t\treturn -ENOMEM;\n+\t\tmemcpy(adapter->rss_key, key, adapter->rss_key_size);\n \t}\n \n \t/* Each 32 bits pointed by 'indir' is stored with a lut entry */\n-\tfor (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)\n-\t\tvsi->rss_lut_user[i] = (u8)(indir[i]);\n+\tfor (i = 0; i < adapter->rss_lut_size; i++)\n+\t\tadapter->rss_lut[i] = (u8)(indir[i]);\n \n-\treturn i40evf_config_rss(vsi, seed, vsi->rss_lut_user,\n-\t\t\t\t I40EVF_HLUT_ARRAY_SIZE);\n+\treturn i40evf_config_rss(adapter);\n }\n \n /**\n@@ -794,6 +780,7 @@ static const struct ethtool_ops i40evf_ethtool_ops = {\n \t.get_rxfh\t\t= i40evf_get_rxfh,\n \t.set_rxfh\t\t= i40evf_set_rxfh,\n \t.get_channels\t\t= i40evf_get_channels,\n+\t.get_rxfh_key_size = i40evf_get_rxfh_key_size,\n };\n \n /**\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c\nindex 806da26..af53159 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c\n@@ -1224,24 +1224,18 @@ out:\n }\n \n /**\n- * i40e_config_rss_aq - Prepare for RSS using AQ commands\n- * @vsi: vsi structure\n- * @seed: RSS hash seed\n- * @lut: Lookup table\n- * @lut_size: Lookup table size\n+ * i40e_config_rss_aq - Configure RSS keys and lut by using AQ commands\n+ * @adapter: board private structure\n *\n * Return 0 on success, negative on failure\n **/\n-static int i40evf_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,\n-\t\t\t\tu8 *lut, u16 lut_size)\n+static int i40evf_config_rss_aq(struct i40evf_adapter *adapter)\n {\n-\tstruct i40evf_adapter *adapter = vsi->back;\n+\tstruct i40e_aqc_get_set_rss_key_data *rss_key =\n+\t\t(struct i40e_aqc_get_set_rss_key_data *)adapter->rss_key;\n \tstruct i40e_hw *hw = &adapter->hw;\n \tint ret = 0;\n \n-\tif (!vsi->id)\n-\t\treturn -EINVAL;\n-\n \tif (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {\n \t\t/* bail because we already have a command pending */\n \t\tdev_err(&adapter->pdev->dev, \"Cannot configure RSS, command %d pending\\n\",\n@@ -1249,198 +1243,82 @@ static int i40evf_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,\n \t\treturn -EBUSY;\n \t}\n \n-\tif (seed) {\n-\t\tstruct i40e_aqc_get_set_rss_key_data *rss_key =\n-\t\t\t(struct i40e_aqc_get_set_rss_key_data *)seed;\n-\t\tret = i40evf_aq_set_rss_key(hw, vsi->id, rss_key);\n-\t\tif (ret) {\n-\t\t\tdev_err(&adapter->pdev->dev, \"Cannot set RSS key, err %s aq_err %s\\n\",\n-\t\t\t\ti40evf_stat_str(hw, ret),\n-\t\t\t\ti40evf_aq_str(hw, hw->aq.asq_last_status));\n-\t\t\treturn ret;\n-\t\t}\n+\tret = i40evf_aq_set_rss_key(hw, adapter->vsi.id, rss_key);\n+\tif (ret) {\n+\t\tdev_err(&adapter->pdev->dev, \"Cannot set RSS key, err %s aq_err %s\\n\",\n+\t\t\ti40evf_stat_str(hw, ret),\n+\t\t\ti40evf_aq_str(hw, hw->aq.asq_last_status));\n+\t\treturn ret;\n+\n \t}\n \n-\tif (lut) {\n-\t\tret = i40evf_aq_set_rss_lut(hw, vsi->id, false, lut, lut_size);\n-\t\tif (ret) {\n-\t\t\tdev_err(&adapter->pdev->dev,\n-\t\t\t\t\"Cannot set RSS lut, err %s aq_err %s\\n\",\n-\t\t\t\ti40evf_stat_str(hw, ret),\n-\t\t\t\ti40evf_aq_str(hw, hw->aq.asq_last_status));\n-\t\t\treturn ret;\n-\t\t}\n+\tret = i40evf_aq_set_rss_lut(hw, adapter->vsi.id, false,\n+\t\t\t\t adapter->rss_lut, adapter->rss_lut_size);\n+\tif (ret) {\n+\t\tdev_err(&adapter->pdev->dev, \"Cannot set RSS lut, err %s aq_err %s\\n\",\n+\t\t\ti40evf_stat_str(hw, ret),\n+\t\t\ti40evf_aq_str(hw, hw->aq.asq_last_status));\n \t}\n \n \treturn ret;\n+\n }\n \n /**\n * i40evf_config_rss_reg - Configure RSS keys and lut by writing registers\n- * @vsi: Pointer to vsi structure\n- * @seed: RSS hash seed\n- * @lut: Lookup table\n- * @lut_size: Lookup table size\n+ * @adapter: board private structure\n *\n * Returns 0 on success, negative on failure\n **/\n-static int i40evf_config_rss_reg(struct i40e_vsi *vsi, const u8 *seed,\n-\t\t\t\t const u8 *lut, u16 lut_size)\n+static int i40evf_config_rss_reg(struct i40evf_adapter *adapter)\n {\n-\tstruct i40evf_adapter *adapter = vsi->back;\n \tstruct i40e_hw *hw = &adapter->hw;\n+\tu32 *dw;\n \tu16 i;\n \n-\tif (seed) {\n-\t\tu32 *seed_dw = (u32 *)seed;\n-\n-\t\tfor (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++)\n-\t\t\twr32(hw, I40E_VFQF_HKEY(i), seed_dw[i]);\n-\t}\n-\n-\tif (lut) {\n-\t\tu32 *lut_dw = (u32 *)lut;\n+\tdw = (u32 *)adapter->rss_key;\n+\tfor (i = 0; i <= adapter->rss_key_size / 4; i++)\n+\t\twr32(hw, I40E_VFQF_HKEY(i), dw[i]);\n \n-\t\tif (lut_size != I40EVF_HLUT_ARRAY_SIZE)\n-\t\t\treturn -EINVAL;\n+\tdw = (u32 *)adapter->rss_lut;\n+\tfor (i = 0; i <= adapter->rss_lut_size / 4; i++)\n+\t\twr32(hw, I40E_VFQF_HLUT(i), dw[i]);\n \n-\t\tfor (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++)\n-\t\t\twr32(hw, I40E_VFQF_HLUT(i), lut_dw[i]);\n-\t}\n \ti40e_flush(hw);\n \n \treturn 0;\n }\n \n /**\n- * * i40evf_get_rss_aq - Get RSS keys and lut by using AQ commands\n- * @vsi: Pointer to vsi structure\n- * @seed: RSS hash seed\n- * @lut: Lookup table\n- * @lut_size: Lookup table size\n- *\n- * Return 0 on success, negative on failure\n- **/\n-static int i40evf_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,\n-\t\t\t u8 *lut, u16 lut_size)\n-{\n-\tstruct i40evf_adapter *adapter = vsi->back;\n-\tstruct i40e_hw *hw = &adapter->hw;\n-\tint ret = 0;\n-\n-\tif (seed) {\n-\t\tret = i40evf_aq_get_rss_key(hw, vsi->id,\n-\t\t\t(struct i40e_aqc_get_set_rss_key_data *)seed);\n-\t\tif (ret) {\n-\t\t\tdev_err(&adapter->pdev->dev,\n-\t\t\t\t\"Cannot get RSS key, err %s aq_err %s\\n\",\n-\t\t\t\ti40evf_stat_str(hw, ret),\n-\t\t\t\ti40evf_aq_str(hw, hw->aq.asq_last_status));\n-\t\t\treturn ret;\n-\t\t}\n-\t}\n-\n-\tif (lut) {\n-\t\tret = i40evf_aq_get_rss_lut(hw, vsi->id, false, lut, lut_size);\n-\t\tif (ret) {\n-\t\t\tdev_err(&adapter->pdev->dev,\n-\t\t\t\t\"Cannot get RSS lut, err %s aq_err %s\\n\",\n-\t\t\t\ti40evf_stat_str(hw, ret),\n-\t\t\t\ti40evf_aq_str(hw, hw->aq.asq_last_status));\n-\t\t\treturn ret;\n-\t\t}\n-\t}\n-\n-\treturn ret;\n-}\n-\n-/**\n- * * i40evf_get_rss_reg - Get RSS keys and lut by reading registers\n- * @vsi: Pointer to vsi structure\n- * @seed: RSS hash seed\n- * @lut: Lookup table\n- * @lut_size: Lookup table size\n- *\n- * Returns 0 on success, negative on failure\n- **/\n-static int i40evf_get_rss_reg(struct i40e_vsi *vsi, const u8 *seed,\n-\t\t\t const u8 *lut, u16 lut_size)\n-{\n-\tstruct i40evf_adapter *adapter = vsi->back;\n-\tstruct i40e_hw *hw = &adapter->hw;\n-\tu16 i;\n-\n-\tif (seed) {\n-\t\tu32 *seed_dw = (u32 *)seed;\n-\n-\t\tfor (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++)\n-\t\t\tseed_dw[i] = rd32(hw, I40E_VFQF_HKEY(i));\n-\t}\n-\n-\tif (lut) {\n-\t\tu32 *lut_dw = (u32 *)lut;\n-\n-\t\tif (lut_size != I40EVF_HLUT_ARRAY_SIZE)\n-\t\t\treturn -EINVAL;\n-\n-\t\tfor (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++)\n-\t\t\tlut_dw[i] = rd32(hw, I40E_VFQF_HLUT(i));\n-\t}\n-\n-\treturn 0;\n-}\n-\n-/**\n * i40evf_config_rss - Configure RSS keys and lut\n- * @vsi: Pointer to vsi structure\n- * @seed: RSS hash seed\n- * @lut: Lookup table\n- * @lut_size: Lookup table size\n- *\n- * Returns 0 on success, negative on failure\n- **/\n-int i40evf_config_rss(struct i40e_vsi *vsi, const u8 *seed,\n-\t\t u8 *lut, u16 lut_size)\n-{\n-\tstruct i40evf_adapter *adapter = vsi->back;\n-\n-\tif (RSS_AQ(adapter))\n-\t\treturn i40evf_config_rss_aq(vsi, seed, lut, lut_size);\n-\telse\n-\t\treturn i40evf_config_rss_reg(vsi, seed, lut, lut_size);\n-}\n-\n-/**\n- * i40evf_get_rss - Get RSS keys and lut\n- * @vsi: Pointer to vsi structure\n- * @seed: RSS hash seed\n- * @lut: Lookup table\n- * @lut_size: Lookup table size\n+ * @adapter: board private structure\n *\n * Returns 0 on success, negative on failure\n **/\n-int i40evf_get_rss(struct i40e_vsi *vsi, const u8 *seed, u8 *lut, u16 lut_size)\n+int i40evf_config_rss(struct i40evf_adapter *adapter)\n {\n-\tstruct i40evf_adapter *adapter = vsi->back;\n \n-\tif (RSS_AQ(adapter))\n-\t\treturn i40evf_get_rss_aq(vsi, seed, lut, lut_size);\n-\telse\n-\t\treturn i40evf_get_rss_reg(vsi, seed, lut, lut_size);\n+\tif (RSS_PF(adapter)) {\n+\t\tadapter->aq_required |= I40EVF_FLAG_AQ_SET_RSS_LUT |\n+\t\t\t\t\tI40EVF_FLAG_AQ_SET_RSS_KEY;\n+\t\treturn 0;\n+\t} else if (RSS_AQ(adapter)) {\n+\t\treturn i40evf_config_rss_aq(adapter);\n+\t} else {\n+\t\treturn i40evf_config_rss_reg(adapter);\n+\t}\n }\n \n /**\n * i40evf_fill_rss_lut - Fill the lut with default values\n- * @lut: Lookup table to be filled with\n- * @rss_table_size: Lookup table size\n- * @rss_size: Range of queue number for hashing\n+ * @adapter: board private structure\n **/\n-static void i40evf_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size)\n+static void i40evf_fill_rss_lut(struct i40evf_adapter *adapter)\n {\n \tu16 i;\n \n-\tfor (i = 0; i < rss_table_size; i++)\n-\t\tlut[i] = i % rss_size;\n+\tfor (i = 0; i < adapter->rss_lut_size; i++)\n+\t\tadapter->rss_lut[i] = i % adapter->num_active_queues;\n }\n \n /**\n@@ -1451,42 +1329,25 @@ static void i40evf_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size)\n **/\n static int i40evf_init_rss(struct i40evf_adapter *adapter)\n {\n-\tstruct i40e_vsi *vsi = &adapter->vsi;\n \tstruct i40e_hw *hw = &adapter->hw;\n-\tu8 seed[I40EVF_HKEY_ARRAY_SIZE];\n-\tu64 hena;\n-\tu8 *lut;\n \tint ret;\n \n-\t/* Enable PCTYPES for RSS, TCP/UDP with IPv4/IPv6 */\n-\tif (adapter->vf_res->vf_offload_flags &\n-\t\t\t\t\tI40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)\n-\t\thena = I40E_DEFAULT_RSS_HENA_EXPANDED;\n-\telse\n-\t\thena = I40E_DEFAULT_RSS_HENA;\n-\twr32(hw, I40E_VFQF_HENA(0), (u32)hena);\n-\twr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32));\n+\tif (!RSS_PF(adapter)) {\n+\t\t/* Enable PCTYPES for RSS, TCP/UDP with IPv4/IPv6 */\n+\t\tif (adapter->vf_res->vf_offload_flags &\n+\t\t I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)\n+\t\t\tadapter->hena = I40E_DEFAULT_RSS_HENA_EXPANDED;\n+\t\telse\n+\t\t\tadapter->hena = I40E_DEFAULT_RSS_HENA;\n \n-\tlut = kzalloc(I40EVF_HLUT_ARRAY_SIZE, GFP_KERNEL);\n-\tif (!lut)\n-\t\treturn -ENOMEM;\n+\t\twr32(hw, I40E_VFQF_HENA(0), (u32)adapter->hena);\n+\t\twr32(hw, I40E_VFQF_HENA(1), (u32)(adapter->hena >> 32));\n+\t}\n \n-\t/* Use user configured lut if there is one, otherwise use default */\n-\tif (vsi->rss_lut_user)\n-\t\tmemcpy(lut, vsi->rss_lut_user, I40EVF_HLUT_ARRAY_SIZE);\n-\telse\n-\t\ti40evf_fill_rss_lut(lut, I40EVF_HLUT_ARRAY_SIZE,\n-\t\t\t\t adapter->num_active_queues);\n+\ti40evf_fill_rss_lut(adapter);\n \n-\t/* Use user configured hash key if there is one, otherwise\n-\t * user default.\n-\t */\n-\tif (vsi->rss_hkey_user)\n-\t\tmemcpy(seed, vsi->rss_hkey_user, I40EVF_HKEY_ARRAY_SIZE);\n-\telse\n-\t\tnetdev_rss_key_fill((void *)seed, I40EVF_HKEY_ARRAY_SIZE);\n-\tret = i40evf_config_rss(vsi, seed, lut, I40EVF_HLUT_ARRAY_SIZE);\n-\tkfree(lut);\n+\tnetdev_rss_key_fill((void *)adapter->rss_key, adapter->rss_key_size);\n+\tret = i40evf_config_rss(adapter);\n \n \treturn ret;\n }\n@@ -1601,19 +1462,16 @@ err_set_interrupt:\n }\n \n /**\n- * i40evf_clear_rss_config_user - Clear user configurations of RSS\n- * @vsi: Pointer to VSI structure\n+ * i40evf_free_rss - Free memory used by RSS structs\n+ * @adapter: board private structure\n **/\n-static void i40evf_clear_rss_config_user(struct i40e_vsi *vsi)\n+static void i40evf_free_rss(struct i40evf_adapter *adapter)\n {\n-\tif (!vsi)\n-\t\treturn;\n-\n-\tkfree(vsi->rss_hkey_user);\n-\tvsi->rss_hkey_user = NULL;\n+\tkfree(adapter->rss_key);\n+\tadapter->rss_key = NULL;\n \n-\tkfree(vsi->rss_lut_user);\n-\tvsi->rss_lut_user = NULL;\n+\tkfree(adapter->rss_lut);\n+\tadapter->rss_lut = NULL;\n }\n \n /**\n@@ -1747,6 +1605,22 @@ static void i40evf_watchdog_task(struct work_struct *work)\n \t\tadapter->aq_required &= ~I40EVF_FLAG_AQ_CONFIGURE_RSS;\n \t\tgoto watchdog_done;\n \t}\n+\tif (adapter->aq_required & I40EVF_FLAG_AQ_GET_HENA) {\n+\t\ti40evf_get_hena(adapter);\n+\t\tgoto watchdog_done;\n+\t}\n+\tif (adapter->aq_required & I40EVF_FLAG_AQ_SET_HENA) {\n+\t\ti40evf_set_hena(adapter);\n+\t\tgoto watchdog_done;\n+\t}\n+\tif (adapter->aq_required & I40EVF_FLAG_AQ_SET_RSS_KEY) {\n+\t\ti40evf_set_rss_key(adapter);\n+\t\tgoto watchdog_done;\n+\t}\n+\tif (adapter->aq_required & I40EVF_FLAG_AQ_SET_RSS_LUT) {\n+\t\ti40evf_set_rss_lut(adapter);\n+\t\tgoto watchdog_done;\n+\t}\n \n \tif (adapter->state == __I40EVF_RUNNING)\n \t\ti40evf_request_stats(adapter);\n@@ -2325,6 +2199,7 @@ int i40evf_process_config(struct i40evf_adapter *adapter)\n {\n \tstruct i40e_virtchnl_vf_resource *vfres = adapter->vf_res;\n \tstruct net_device *netdev = adapter->netdev;\n+\tstruct i40e_vsi *vsi = &adapter->vsi;\n \tint i;\n \n \t/* got VF config message back from PF, now we can parse it */\n@@ -2381,8 +2256,16 @@ int i40evf_process_config(struct i40evf_adapter *adapter)\n \t\t\t\t ITR_REG_TO_USEC(I40E_ITR_RX_DEF));\n \tadapter->vsi.tx_itr_setting = (I40E_ITR_DYNAMIC |\n \t\t\t\t ITR_REG_TO_USEC(I40E_ITR_TX_DEF));\n-\tadapter->vsi.netdev = adapter->netdev;\n-\tadapter->vsi.qs_handle = adapter->vsi_res->qset_handle;\n+\tvsi->netdev = adapter->netdev;\n+\tvsi->qs_handle = adapter->vsi_res->qset_handle;\n+\tif (vfres->vf_offload_flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PF) {\n+\t\tadapter->rss_key_size = vfres->rss_key_size;\n+\t\tadapter->rss_lut_size = vfres->rss_lut_size;\n+\t} else {\n+\t\tadapter->rss_key_size = I40EVF_HKEY_ARRAY_SIZE;\n+\t\tadapter->rss_lut_size = I40EVF_HLUT_ARRAY_SIZE;\n+\t}\n+\n \treturn 0;\n }\n \n@@ -2578,6 +2461,11 @@ static void i40evf_init_task(struct work_struct *work)\n \tset_bit(__I40E_DOWN, &adapter->vsi.state);\n \ti40evf_misc_irq_enable(adapter);\n \n+\tadapter->rss_key = kzalloc(adapter->rss_key_size, GFP_KERNEL);\n+\tadapter->rss_lut = kzalloc(adapter->rss_lut_size, GFP_KERNEL);\n+\tif (!adapter->rss_key || !adapter->rss_lut)\n+\t\tgoto err_mem;\n+\n \tif (RSS_AQ(adapter)) {\n \t\tadapter->aq_required |= I40EVF_FLAG_AQ_CONFIGURE_RSS;\n \t\tmod_timer_pending(&adapter->watchdog_timer, jiffies + 1);\n@@ -2588,7 +2476,8 @@ static void i40evf_init_task(struct work_struct *work)\n restart:\n \tschedule_delayed_work(&adapter->init_task, msecs_to_jiffies(30));\n \treturn;\n-\n+err_mem:\n+\ti40evf_free_rss(adapter);\n err_register:\n \ti40evf_free_misc_irq(adapter);\n err_sw_init:\n@@ -2870,8 +2759,7 @@ static void i40evf_remove(struct pci_dev *pdev)\n \n \tflush_scheduled_work();\n \n-\t/* Clear user configurations for RSS */\n-\ti40evf_clear_rss_config_user(&adapter->vsi);\n+\ti40evf_free_rss(adapter);\n \n \tif (hw->aq.asq.count)\n \t\ti40evf_shutdown_adminq(hw);\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c\nindex 488e738..e62c56b 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c\n@@ -681,6 +681,115 @@ void i40evf_request_stats(struct i40evf_adapter *adapter)\n \t\t/* if the request failed, don't lock out others */\n \t\tadapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN;\n }\n+\n+/**\n+ * i40evf_get_hena\n+ * @adapter: adapter structure\n+ *\n+ * Request hash enable capabilities from PF\n+ **/\n+void i40evf_get_hena(struct i40evf_adapter *adapter)\n+{\n+\tif (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {\n+\t\t/* bail because we already have a command pending */\n+\t\tdev_err(&adapter->pdev->dev, \"Cannot get RSS hash capabilities, command %d pending\\n\",\n+\t\t\tadapter->current_op);\n+\t\treturn;\n+\t}\n+\tadapter->current_op = I40E_VIRTCHNL_OP_GET_RSS_HENA_CAPS;\n+\tadapter->aq_required &= ~I40EVF_FLAG_AQ_GET_HENA;\n+\ti40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_GET_RSS_HENA_CAPS,\n+\t\t\t NULL, 0);\n+}\n+\n+/**\n+ * i40evf_set_hena\n+ * @adapter: adapter structure\n+ *\n+ * Request the PF to set our RSS hash capabilities\n+ **/\n+void i40evf_set_hena(struct i40evf_adapter *adapter)\n+{\n+\tstruct i40e_virtchnl_rss_hena vrh;\n+\n+\tif (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {\n+\t\t/* bail because we already have a command pending */\n+\t\tdev_err(&adapter->pdev->dev, \"Cannot set RSS hash enable, command %d pending\\n\",\n+\t\t\tadapter->current_op);\n+\t\treturn;\n+\t}\n+\tvrh.hena = adapter->hena;\n+\tadapter->current_op = I40E_VIRTCHNL_OP_SET_RSS_HENA;\n+\tadapter->aq_required &= ~I40EVF_FLAG_AQ_SET_HENA;\n+\ti40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_SET_RSS_HENA,\n+\t\t\t (u8 *)&vrh, sizeof(vrh));\n+}\n+\n+/**\n+ * i40evf_set_rss_key\n+ * @adapter: adapter structure\n+ *\n+ * Request the PF to set our RSS hash key\n+ **/\n+void i40evf_set_rss_key(struct i40evf_adapter *adapter)\n+{\n+\tstruct i40e_virtchnl_rss_key *vrk;\n+\tint len;\n+\n+\tif (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {\n+\t\t/* bail because we already have a command pending */\n+\t\tdev_err(&adapter->pdev->dev, \"Cannot set RSS key, command %d pending\\n\",\n+\t\t\tadapter->current_op);\n+\t\treturn;\n+\t}\n+\tlen = sizeof(struct i40e_virtchnl_rss_key) +\n+\t (adapter->rss_key_size * sizeof(u8)) - 1;\n+\tvrk = kzalloc(len, GFP_KERNEL);\n+\tif (!vrk)\n+\t\treturn;\n+\tvrk->vsi_id = adapter->vsi.id;\n+\tvrk->key_len = adapter->rss_key_size;\n+\tmemcpy(vrk->key, adapter->rss_key, adapter->rss_key_size);\n+\n+\tadapter->current_op = I40E_VIRTCHNL_OP_CONFIG_RSS_KEY;\n+\tadapter->aq_required &= ~I40EVF_FLAG_AQ_SET_RSS_KEY;\n+\ti40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_CONFIG_RSS_KEY,\n+\t\t\t (u8 *)vrk, len);\n+\tkfree(vrk);\n+}\n+\n+/**\n+ * i40evf_set_rss_lut\n+ * @adapter: adapter structure\n+ *\n+ * Request the PF to set our RSS lookup table\n+ **/\n+void i40evf_set_rss_lut(struct i40evf_adapter *adapter)\n+{\n+\tstruct i40e_virtchnl_rss_lut *vrl;\n+\tint len;\n+\n+\tif (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {\n+\t\t/* bail because we already have a command pending */\n+\t\tdev_err(&adapter->pdev->dev, \"Cannot set RSS LUT, command %d pending\\n\",\n+\t\t\tadapter->current_op);\n+\t\treturn;\n+\t}\n+\tlen = sizeof(struct i40e_virtchnl_rss_lut) +\n+\t (adapter->rss_lut_size * sizeof(u8)) - 1;\n+\tvrl = kzalloc(len, GFP_KERNEL);\n+\tif (!vrl)\n+\t\treturn;\n+\tvrl->vsi_id = adapter->vsi.id;\n+\tvrl->lut_entries = adapter->rss_lut_size;\n+\tmemcpy(vrl->lut, adapter->rss_lut, adapter->rss_lut_size);\n+\tadapter->current_op = I40E_VIRTCHNL_OP_CONFIG_RSS_LUT;\n+\tadapter->aq_required &= ~I40EVF_FLAG_AQ_SET_RSS_LUT;\n+\ti40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_CONFIG_RSS_LUT,\n+\t\t\t (u8 *)vrl, len);\n+\tkfree(vrl);\n+}\n+\n /**\n * i40evf_request_reset\n * @adapter: adapter structure\n@@ -820,6 +929,16 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,\n \t\tif (v_opcode != adapter->current_op)\n \t\t\treturn;\n \t\tbreak;\n+\tcase I40E_VIRTCHNL_OP_GET_RSS_HENA_CAPS: {\n+\t\tstruct i40e_virtchnl_rss_hena *vrh =\n+\t\t\t(struct i40e_virtchnl_rss_hena *)msg;\n+\t\tif (msglen == sizeof(*vrh))\n+\t\t\tadapter->hena = vrh->hena;\n+\t\telse\n+\t\t\tdev_warn(&adapter->pdev->dev,\n+\t\t\t\t \"Invalid message %d from PF\\n\", v_opcode);\n+\t\t}\n+\t\tbreak;\n \tdefault:\n \t\tif (v_opcode != adapter->current_op)\n \t\t\tdev_warn(&adapter->pdev->dev, \"Expected response %d from PF, received %d\\n\",\n", "prefixes": [ "next", "S33", "05/13" ] }