Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/17124/?format=api
http://patches.dpdk.org/api/patches/17124/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/1479740470-6723-22-git-send-email-arybchenko@solarflare.com/", "project": { "id": 1, "url": "http://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<1479740470-6723-22-git-send-email-arybchenko@solarflare.com>", "list_archive_url": "https://inbox.dpdk.org/dev/1479740470-6723-22-git-send-email-arybchenko@solarflare.com", "date": "2016-11-21T15:00:35", "name": "[dpdk-dev,21/56] net/sfc: import libefx RSS support", "commit_ref": null, "pull_url": null, "state": "changes-requested", "archived": true, "hash": "5b3c3b5f588116df64ccae4fb6ae4b98bebfc4c1", "submitter": { "id": 607, "url": "http://patches.dpdk.org/api/people/607/?format=api", "name": "Andrew Rybchenko", "email": "arybchenko@solarflare.com" }, "delegate": { "id": 319, "url": "http://patches.dpdk.org/api/users/319/?format=api", "username": "fyigit", "first_name": "Ferruh", "last_name": "Yigit", "email": "ferruh.yigit@amd.com" }, "mbox": "http://patches.dpdk.org/project/dpdk/patch/1479740470-6723-22-git-send-email-arybchenko@solarflare.com/mbox/", "series": [], "comments": "http://patches.dpdk.org/api/patches/17124/comments/", "check": "warning", "checks": "http://patches.dpdk.org/api/patches/17124/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@dpdk.org", "Delivered-To": "patchwork@dpdk.org", "Received": [ "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 2DC606CB7;\n\tMon, 21 Nov 2016 16:03:04 +0100 (CET)", "from nbfkord-smmo02.seg.att.com (nbfkord-smmo02.seg.att.com\n\t[209.65.160.78]) by dpdk.org (Postfix) with ESMTP id 8DF8B2A5D\n\tfor <dev@dpdk.org>; Mon, 21 Nov 2016 16:01:34 +0100 (CET)", "from unknown [12.187.104.26]\n\tby nbfkord-smmo02.seg.att.com(mxl_mta-7.2.4-7) with SMTP id\n\te4c03385.0.1541296.00-2367.3424211.nbfkord-smmo02.seg.att.com\n\t(envelope-from <arybchenko@solarflare.com>); \n\tMon, 21 Nov 2016 15:01:34 +0000 (UTC)", "from ocex03.SolarFlarecom.com (10.20.40.36) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id 15.0.1044.25; Mon, 21 Nov 2016 07:01:21 -0800", "from opal.uk.solarflarecom.com (10.17.10.1) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id\n\t15.0.1044.25 via Frontend Transport; Mon, 21 Nov 2016 07:01:21 -0800", "from uklogin.uk.solarflarecom.com (uklogin.uk.solarflarecom.com\n\t[10.17.10.10])\n\tby opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tuALF1KpP007159 for <dev@dpdk.org>; Mon, 21 Nov 2016 15:01:20 GMT", "from uklogin.uk.solarflarecom.com (localhost.localdomain\n\t[127.0.0.1])\n\tby uklogin.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tuALF1J3C006765 for <dev@dpdk.org>; Mon, 21 Nov 2016 15:01:20 GMT" ], "X-MXL-Hash": "58330c4e52641deb-83a4aa979660b6d52f1b69bfcb73ff1f6f0579a9", "From": "Andrew Rybchenko <arybchenko@solarflare.com>", "To": "<dev@dpdk.org>", "Date": "Mon, 21 Nov 2016 15:00:35 +0000", "Message-ID": "<1479740470-6723-22-git-send-email-arybchenko@solarflare.com>", "X-Mailer": "git-send-email 1.8.2.3", "In-Reply-To": "<1479740470-6723-1-git-send-email-arybchenko@solarflare.com>", "References": "<1479740470-6723-1-git-send-email-arybchenko@solarflare.com>", "MIME-Version": "1.0", "Content-Type": "text/plain", "X-AnalysisOut": [ "[v=2.1 cv=UI/baXry c=1 sm=1 tr=0 a=8BlWFWvVlq5taO8ncb8nKg==]", "[:17 a=L24OOQBejmoA:10 a=zRKbQ67AAAAA:8 a=AezZItFbjd6QWh_OE]", "[w0A:9 a=Fc9kBy1NRdrwtuim:21 a=ObILvudZC4k5_W12:21 a=P66vI9]", "[JvTZI2KTLT:21 a=PA03WX8tBzeizutn5_OT:22]" ], "X-Spam": "[F=0.5002514207; CM=0.500; S=0.500(2015072901)]", "X-MAIL-FROM": "<arybchenko@solarflare.com>", "X-SOURCE-IP": "[12.187.104.26]", "Subject": "[dpdk-dev] [PATCH 21/56] net/sfc: import libefx RSS support", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "patches and discussions about DPDK <dev.dpdk.org>", "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://dpdk.org/ml/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "EFSYS_OPT_RX_SCALE should be enabled to use it.\n\nFrom Solarflare Communications Inc.\n\nSigned-off-by: Andrew Rybchenko <arybchenko@solarflare.com>\n---\n drivers/net/sfc/efx/base/ef10_filter.c | 10 +\n drivers/net/sfc/efx/base/ef10_impl.h | 29 +++\n drivers/net/sfc/efx/base/ef10_rx.c | 443 ++++++++++++++++++++++++++++++++\n drivers/net/sfc/efx/base/efx.h | 67 +++++\n drivers/net/sfc/efx/base/efx_check.h | 7 +\n drivers/net/sfc/efx/base/efx_ev.c | 11 +\n drivers/net/sfc/efx/base/efx_filter.c | 4 +\n drivers/net/sfc/efx/base/efx_impl.h | 14 +\n drivers/net/sfc/efx/base/efx_rx.c | 456 +++++++++++++++++++++++++++++++++\n 9 files changed, 1041 insertions(+)", "diff": "diff --git a/drivers/net/sfc/efx/base/ef10_filter.c b/drivers/net/sfc/efx/base/ef10_filter.c\nindex 608a058..a881522 100644\n--- a/drivers/net/sfc/efx/base/ef10_filter.c\n+++ b/drivers/net/sfc/efx/base/ef10_filter.c\n@@ -562,6 +562,10 @@ ef10_filter_add_internal(\n \tEFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||\n \t\t enp->en_family == EFX_FAMILY_MEDFORD);\n \n+#if EFSYS_OPT_RX_SCALE\n+\tspec->efs_rss_context = enp->en_rss_context;\n+#endif\n+\n \thash = ef10_filter_hash(spec);\n \n \t/*\n@@ -1448,8 +1452,14 @@ ef10_filter_default_rxq_set(\n {\n \tef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table;\n \n+#if EFSYS_OPT_RX_SCALE\n+\tEFSYS_ASSERT((using_rss == B_FALSE) ||\n+\t (enp->en_rss_context != EF10_RSS_CONTEXT_INVALID));\n+\ttable->eft_using_rss = using_rss;\n+#else\n \tEFSYS_ASSERT(using_rss == B_FALSE);\n \ttable->eft_using_rss = B_FALSE;\n+#endif\n \ttable->eft_default_rxq = erp;\n }\n \ndiff --git a/drivers/net/sfc/efx/base/ef10_impl.h b/drivers/net/sfc/efx/base/ef10_impl.h\nindex eedf121..f70773c 100644\n--- a/drivers/net/sfc/efx/base/ef10_impl.h\n+++ b/drivers/net/sfc/efx/base/ef10_impl.h\n@@ -581,6 +581,35 @@ ef10_rx_scatter_enable(\n #endif\t/* EFSYS_OPT_RX_SCATTER */\n \n \n+#if EFSYS_OPT_RX_SCALE\n+\n+extern\t__checkReturn\tefx_rc_t\n+ef10_rx_scale_mode_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_rx_hash_alg_t alg,\n+\t__in\t\tefx_rx_hash_type_t type,\n+\t__in\t\tboolean_t insert);\n+\n+extern\t__checkReturn\tefx_rc_t\n+ef10_rx_scale_key_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tuint8_t *key,\n+\t__in\t\tsize_t n);\n+\n+extern\t__checkReturn\tefx_rc_t\n+ef10_rx_scale_tbl_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tunsigned int *table,\n+\t__in\t\tsize_t n);\n+\n+extern\t__checkReturn\tuint32_t\n+ef10_rx_prefix_hash(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_rx_hash_alg_t func,\n+\t__in\t\tuint8_t *buffer);\n+\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n extern\t__checkReturn\tefx_rc_t\n ef10_rx_prefix_pktlen(\n \t__in\t\tefx_nic_t *enp,\ndiff --git a/drivers/net/sfc/efx/base/ef10_rx.c b/drivers/net/sfc/efx/base/ef10_rx.c\nindex 95a182b..09a6314 100644\n--- a/drivers/net/sfc/efx/base/ef10_rx.c\n+++ b/drivers/net/sfc/efx/base/ef10_rx.c\n@@ -150,11 +150,325 @@ efx_mcdi_fini_rxq(\n \treturn (rc);\n }\n \n+#if EFSYS_OPT_RX_SCALE\n+static\t__checkReturn\tefx_rc_t\n+efx_mcdi_rss_context_alloc(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_rx_scale_support_t scale_support,\n+\t__in\t\tuint32_t num_queues,\n+\t__out\t\tuint32_t *rss_contextp)\n+{\n+\tefx_mcdi_req_t req;\n+\tuint8_t payload[MAX(MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,\n+\t\t\t MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN)];\n+\tuint32_t rss_context;\n+\tuint32_t context_type;\n+\tefx_rc_t rc;\n+\n+\tif (num_queues > EFX_MAXRSS) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tswitch (scale_support) {\n+\tcase EFX_RX_SCALE_EXCLUSIVE:\n+\t\tcontext_type = MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE;\n+\t\tbreak;\n+\tcase EFX_RX_SCALE_SHARED:\n+\t\tcontext_type = MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_SHARED;\n+\t\tbreak;\n+\tdefault:\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_RSS_CONTEXT_ALLOC;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN;\n+\n+\tMCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID,\n+\t EVB_PORT_ID_ASSIGNED);\n+\tMCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_TYPE, context_type);\n+\t/* NUM_QUEUES is only used to validate indirection table offsets */\n+\tMCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_NUM_QUEUES, num_queues);\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail3;\n+\t}\n+\n+\tif (req.emr_out_length_used < MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN) {\n+\t\trc = EMSGSIZE;\n+\t\tgoto fail4;\n+\t}\n+\n+\trss_context = MCDI_OUT_DWORD(req, RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID);\n+\tif (rss_context == EF10_RSS_CONTEXT_INVALID) {\n+\t\trc = ENOENT;\n+\t\tgoto fail5;\n+\t}\n+\n+\t*rss_contextp = rss_context;\n+\n+\treturn (0);\n+\n+fail5:\n+\tEFSYS_PROBE(fail5);\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n+#if EFSYS_OPT_RX_SCALE\n+static\t\t\tefx_rc_t\n+efx_mcdi_rss_context_free(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tuint32_t rss_context)\n+{\n+\tefx_mcdi_req_t req;\n+\tuint8_t payload[MAX(MC_CMD_RSS_CONTEXT_FREE_IN_LEN,\n+\t\t\t MC_CMD_RSS_CONTEXT_FREE_OUT_LEN)];\n+\tefx_rc_t rc;\n+\n+\tif (rss_context == EF10_RSS_CONTEXT_INVALID) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_RSS_CONTEXT_FREE;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_RSS_CONTEXT_FREE_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_RSS_CONTEXT_FREE_OUT_LEN;\n+\n+\tMCDI_IN_SET_DWORD(req, RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID, rss_context);\n+\n+\tefx_mcdi_execute_quiet(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail2;\n+\t}\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n+#if EFSYS_OPT_RX_SCALE\n+static\t\t\tefx_rc_t\n+efx_mcdi_rss_context_set_flags(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tuint32_t rss_context,\n+\t__in\t\tefx_rx_hash_type_t type)\n+{\n+\tefx_mcdi_req_t req;\n+\tuint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN,\n+\t\t\t MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)];\n+\tefx_rc_t rc;\n+\n+\tif (rss_context == EF10_RSS_CONTEXT_INVALID) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_RSS_CONTEXT_SET_FLAGS;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN;\n+\n+\tMCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID,\n+\t rss_context);\n+\n+\tMCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS,\n+\t RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN,\n+\t (type & (1U << EFX_RX_HASH_IPV4)) ? 1 : 0,\n+\t RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN,\n+\t (type & (1U << EFX_RX_HASH_TCPIPV4)) ? 1 : 0,\n+\t RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN,\n+\t (type & (1U << EFX_RX_HASH_IPV6)) ? 1 : 0,\n+\t RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN,\n+\t (type & (1U << EFX_RX_HASH_TCPIPV6)) ? 1 : 0);\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail2;\n+\t}\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n+#if EFSYS_OPT_RX_SCALE\n+static\t\t\tefx_rc_t\n+efx_mcdi_rss_context_set_key(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tuint32_t rss_context,\n+\t__in_ecount(n)\tuint8_t *key,\n+\t__in\t\tsize_t n)\n+{\n+\tefx_mcdi_req_t req;\n+\tuint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN,\n+\t\t\t MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN)];\n+\tefx_rc_t rc;\n+\n+\tif (rss_context == EF10_RSS_CONTEXT_INVALID) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_RSS_CONTEXT_SET_KEY;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN;\n+\n+\tMCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID,\n+\t rss_context);\n+\n+\tEFSYS_ASSERT3U(n, ==, MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);\n+\tif (n != MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN) {\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\n+\tmemcpy(MCDI_IN2(req, uint8_t, RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY),\n+\t key, n);\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail3;\n+\t}\n+\n+\treturn (0);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n+#if EFSYS_OPT_RX_SCALE\n+static\t\t\tefx_rc_t\n+efx_mcdi_rss_context_set_table(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tuint32_t rss_context,\n+\t__in_ecount(n)\tunsigned int *table,\n+\t__in\t\tsize_t n)\n+{\n+\tefx_mcdi_req_t req;\n+\tuint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN,\n+\t\t\t MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN)];\n+\tuint8_t *req_table;\n+\tint i, rc;\n+\n+\tif (rss_context == EF10_RSS_CONTEXT_INVALID) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_RSS_CONTEXT_SET_TABLE;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN;\n+\n+\tMCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID,\n+\t rss_context);\n+\n+\treq_table =\n+\t MCDI_IN2(req, uint8_t, RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE);\n+\n+\tfor (i = 0;\n+\t i < MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN;\n+\t i++) {\n+\t\treq_table[i] = (n > 0) ? (uint8_t)table[i % n] : 0;\n+\t}\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail2;\n+\t}\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n \n \t__checkReturn\tefx_rc_t\n ef10_rx_init(\n \t__in\t\tefx_nic_t *enp)\n {\n+#if EFSYS_OPT_RX_SCALE\n+\n+\tif (efx_mcdi_rss_context_alloc(enp, EFX_RX_SCALE_EXCLUSIVE, EFX_MAXRSS,\n+\t\t&enp->en_rss_context) == 0) {\n+\t\t/*\n+\t\t * Allocated an exclusive RSS context, which allows both the\n+\t\t * indirection table and key to be modified.\n+\t\t */\n+\t\tenp->en_rss_support = EFX_RX_SCALE_EXCLUSIVE;\n+\t\tenp->en_hash_support = EFX_RX_HASH_AVAILABLE;\n+\t} else {\n+\t\t/*\n+\t\t * Failed to allocate an exclusive RSS context. Continue\n+\t\t * operation without support for RSS. The pseudo-header in\n+\t\t * received packets will not contain a Toeplitz hash value.\n+\t\t */\n+\t\tenp->en_rss_support = EFX_RX_SCALE_UNAVAILABLE;\n+\t\tenp->en_hash_support = EFX_RX_HASH_UNAVAILABLE;\n+\t}\n+\n+#endif /* EFSYS_OPT_RX_SCALE */\n \n \treturn (0);\n }\n@@ -170,6 +484,104 @@ ef10_rx_scatter_enable(\n }\n #endif\t/* EFSYS_OPT_RX_SCATTER */\n \n+#if EFSYS_OPT_RX_SCALE\n+\t__checkReturn\tefx_rc_t\n+ef10_rx_scale_mode_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_rx_hash_alg_t alg,\n+\t__in\t\tefx_rx_hash_type_t type,\n+\t__in\t\tboolean_t insert)\n+{\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(alg, ==, EFX_RX_HASHALG_TOEPLITZ);\n+\tEFSYS_ASSERT3U(insert, ==, B_TRUE);\n+\n+\tif ((alg != EFX_RX_HASHALG_TOEPLITZ) || (insert == B_FALSE)) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {\n+\t\trc = ENOTSUP;\n+\t\tgoto fail2;\n+\t}\n+\n+\tif ((rc = efx_mcdi_rss_context_set_flags(enp,\n+\t\t enp->en_rss_context, type)) != 0)\n+\t\tgoto fail3;\n+\n+\treturn (0);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n+#if EFSYS_OPT_RX_SCALE\n+\t__checkReturn\tefx_rc_t\n+ef10_rx_scale_key_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tuint8_t *key,\n+\t__in\t\tsize_t n)\n+{\n+\tefx_rc_t rc;\n+\n+\tif (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {\n+\t\trc = ENOTSUP;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif ((rc = efx_mcdi_rss_context_set_key(enp,\n+\t enp->en_rss_context, key, n)) != 0)\n+\t\tgoto fail2;\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n+#if EFSYS_OPT_RX_SCALE\n+\t__checkReturn\tefx_rc_t\n+ef10_rx_scale_tbl_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tunsigned int *table,\n+\t__in\t\tsize_t n)\n+{\n+\tefx_rc_t rc;\n+\n+\tif (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {\n+\t\trc = ENOTSUP;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif ((rc = efx_mcdi_rss_context_set_table(enp,\n+\t enp->en_rss_context, table, n)) != 0)\n+\t\tgoto fail2;\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n \n /*\n * EF10 RX pseudo-header\n@@ -210,6 +622,29 @@ ef10_rx_prefix_pktlen(\n \treturn (0);\n }\n \n+#if EFSYS_OPT_RX_SCALE\n+\t__checkReturn\tuint32_t\n+ef10_rx_prefix_hash(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_rx_hash_alg_t func,\n+\t__in\t\tuint8_t *buffer)\n+{\n+\t_NOTE(ARGUNUSED(enp))\n+\n+\tswitch (func) {\n+\tcase EFX_RX_HASHALG_TOEPLITZ:\n+\t\treturn (buffer[0] |\n+\t\t (buffer[1] << 8) |\n+\t\t (buffer[2] << 16) |\n+\t\t (buffer[3] << 24));\n+\n+\tdefault:\n+\t\tEFSYS_ASSERT(0);\n+\t\treturn (0);\n+\t}\n+}\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n \t\t\tvoid\n ef10_rx_qpost(\n \t__in\t\tefx_rxq_t *erp,\n@@ -402,7 +837,15 @@ ef10_rx_qdestroy(\n ef10_rx_fini(\n \t__in\tefx_nic_t *enp)\n {\n+#if EFSYS_OPT_RX_SCALE\n+\tif (enp->en_rss_support != EFX_RX_SCALE_UNAVAILABLE) {\n+\t\t(void) efx_mcdi_rss_context_free(enp, enp->en_rss_context);\n+\t}\n+\tenp->en_rss_context = 0;\n+\tenp->en_rss_support = EFX_RX_SCALE_UNAVAILABLE;\n+#else\n \t_NOTE(ARGUNUSED(enp))\n+#endif /* EFSYS_OPT_RX_SCALE */\n }\n \n #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */\ndiff --git a/drivers/net/sfc/efx/base/efx.h b/drivers/net/sfc/efx/base/efx.h\nindex bd85f0b..9ca80f6 100644\n--- a/drivers/net/sfc/efx/base/efx.h\n+++ b/drivers/net/sfc/efx/base/efx.h\n@@ -1388,6 +1388,73 @@ efx_rx_scatter_enable(\n \t__in\t\tunsigned int buf_size);\n #endif\t/* EFSYS_OPT_RX_SCATTER */\n \n+#if EFSYS_OPT_RX_SCALE\n+\n+typedef enum efx_rx_hash_alg_e {\n+\tEFX_RX_HASHALG_LFSR = 0,\n+\tEFX_RX_HASHALG_TOEPLITZ\n+} efx_rx_hash_alg_t;\n+\n+typedef enum efx_rx_hash_type_e {\n+\tEFX_RX_HASH_IPV4 = 0,\n+\tEFX_RX_HASH_TCPIPV4,\n+\tEFX_RX_HASH_IPV6,\n+\tEFX_RX_HASH_TCPIPV6,\n+} efx_rx_hash_type_t;\n+\n+typedef enum efx_rx_hash_support_e {\n+\tEFX_RX_HASH_UNAVAILABLE = 0,\t/* Hardware hash not inserted */\n+\tEFX_RX_HASH_AVAILABLE\t\t/* Insert hash with/without RSS */\n+} efx_rx_hash_support_t;\n+\n+#define\tEFX_RSS_TBL_SIZE\t128\t/* Rows in RX indirection table */\n+#define\tEFX_MAXRSS\t\t64\t/* RX indirection entry range */\n+#define\tEFX_MAXRSS_LEGACY\t16\t/* See bug16611 and bug17213 */\n+\n+typedef enum efx_rx_scale_support_e {\n+\tEFX_RX_SCALE_UNAVAILABLE = 0,\t/* Not supported */\n+\tEFX_RX_SCALE_EXCLUSIVE,\t\t/* Writable key/indirection table */\n+\tEFX_RX_SCALE_SHARED\t\t/* Read-only key/indirection table */\n+} efx_rx_scale_support_t;\n+\n+extern\t__checkReturn\tefx_rc_t\n+efx_rx_hash_support_get(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tefx_rx_hash_support_t *supportp);\n+\n+\n+extern\t__checkReturn\tefx_rc_t\n+efx_rx_scale_support_get(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tefx_rx_scale_support_t *supportp);\n+\n+extern\t__checkReturn\tefx_rc_t\n+efx_rx_scale_mode_set(\n+\t__in\tefx_nic_t *enp,\n+\t__in\tefx_rx_hash_alg_t alg,\n+\t__in\tefx_rx_hash_type_t type,\n+\t__in\tboolean_t insert);\n+\n+extern\t__checkReturn\tefx_rc_t\n+efx_rx_scale_tbl_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tunsigned int *table,\n+\t__in\t\tsize_t n);\n+\n+extern\t__checkReturn\tefx_rc_t\n+efx_rx_scale_key_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tuint8_t *key,\n+\t__in\t\tsize_t n);\n+\n+extern\t__checkReturn\tuint32_t\n+efx_psuedo_hdr_hash_get(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in\t\tefx_rx_hash_alg_t func,\n+\t__in\t\tuint8_t *buffer);\n+\n+#endif\t/* EFSYS_OPT_RX_SCALE */\n+\n extern\t__checkReturn\tefx_rc_t\n efx_psuedo_hdr_pkt_length_get(\n \t__in\t\tefx_rxq_t *erp,\ndiff --git a/drivers/net/sfc/efx/base/efx_check.h b/drivers/net/sfc/efx/base/efx_check.h\nindex 91a764f..ac248b3 100644\n--- a/drivers/net/sfc/efx/base/efx_check.h\n+++ b/drivers/net/sfc/efx/base/efx_check.h\n@@ -244,6 +244,13 @@\n # error \"RX_HDR_SPLIT is obsolete and is not supported\"\n #endif\n \n+#if EFSYS_OPT_RX_SCALE\n+/* Support receive scaling (RSS) */\n+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)\n+# error \"RX_SCALE requires SIENA or HUNTINGTON or MEDFORD\"\n+# endif\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n #if EFSYS_OPT_RX_SCATTER\n /* Support receive scatter DMA */\n # if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)\ndiff --git a/drivers/net/sfc/efx/base/efx_ev.c b/drivers/net/sfc/efx/base/efx_ev.c\nindex a667124..9f6a309 100644\n--- a/drivers/net/sfc/efx/base/efx_ev.c\n+++ b/drivers/net/sfc/efx/base/efx_ev.c\n@@ -1285,6 +1285,13 @@ siena_ev_qcreate(\n \t\trc = EINVAL;\n \t\tgoto fail2;\n \t}\n+#if EFSYS_OPT_RX_SCALE\n+\tif (enp->en_intr.ei_type == EFX_INTR_LINE &&\n+\t index >= EFX_MAXRSS_LEGACY) {\n+\t\trc = EINVAL;\n+\t\tgoto fail3;\n+\t}\n+#endif\n \tfor (size = 0; (1 << size) <= (EFX_EVQ_MAXNEVS / EFX_EVQ_MINNEVS);\n \t size++)\n \t\tif ((1 << size) == (int)(n / EFX_EVQ_MINNEVS))\n@@ -1325,6 +1332,10 @@ siena_ev_qcreate(\n \n fail4:\n \tEFSYS_PROBE(fail4);\n+#if EFSYS_OPT_RX_SCALE\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+#endif\n fail2:\n \tEFSYS_PROBE(fail2);\n fail1:\ndiff --git a/drivers/net/sfc/efx/base/efx_filter.c b/drivers/net/sfc/efx/base/efx_filter.c\nindex 192f6f5..13f9f3a 100644\n--- a/drivers/net/sfc/efx/base/efx_filter.c\n+++ b/drivers/net/sfc/efx/base/efx_filter.c\n@@ -116,6 +116,10 @@ efx_filter_remove(\n \tEFSYS_ASSERT3P(spec, !=, NULL);\n \tEFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);\n \n+#if EFSYS_OPT_RX_SCALE\n+\tspec->efs_rss_context = enp->en_rss_context;\n+#endif\n+\n \treturn (efop->efo_delete(enp, spec));\n }\n \ndiff --git a/drivers/net/sfc/efx/base/efx_impl.h b/drivers/net/sfc/efx/base/efx_impl.h\nindex b7eeee7..e88e8a9 100644\n--- a/drivers/net/sfc/efx/base/efx_impl.h\n+++ b/drivers/net/sfc/efx/base/efx_impl.h\n@@ -151,6 +151,15 @@ typedef struct efx_rx_ops_s {\n #if EFSYS_OPT_RX_SCATTER\n \tefx_rc_t\t(*erxo_scatter_enable)(efx_nic_t *, unsigned int);\n #endif\n+#if EFSYS_OPT_RX_SCALE\n+\tefx_rc_t\t(*erxo_scale_mode_set)(efx_nic_t *, efx_rx_hash_alg_t,\n+\t\t\t\t\t efx_rx_hash_type_t, boolean_t);\n+\tefx_rc_t\t(*erxo_scale_key_set)(efx_nic_t *, uint8_t *, size_t);\n+\tefx_rc_t\t(*erxo_scale_tbl_set)(efx_nic_t *, unsigned int *,\n+\t\t\t\t\t size_t);\n+\tuint32_t\t(*erxo_prefix_hash)(efx_nic_t *, efx_rx_hash_alg_t,\n+\t\t\t\t\t uint8_t *);\n+#endif /* EFSYS_OPT_RX_SCALE */\n \tefx_rc_t\t(*erxo_prefix_pktlen)(efx_nic_t *, uint8_t *,\n \t\t\t\t\t uint16_t *);\n \tvoid\t\t(*erxo_qpost)(efx_rxq_t *, efsys_dma_addr_t *, size_t,\n@@ -461,6 +470,11 @@ struct efx_nic_s {\n #if EFSYS_OPT_MCDI\n \tefx_mcdi_t\t\ten_mcdi;\n #endif\t/* EFSYS_OPT_MCDI */\n+#if EFSYS_OPT_RX_SCALE\n+\tefx_rx_hash_support_t\ten_hash_support;\n+\tefx_rx_scale_support_t\ten_rss_support;\n+\tuint32_t\t\ten_rss_context;\n+#endif\t/* EFSYS_OPT_RX_SCALE */\n \tuint32_t\t\ten_vport_id;\n \tunion {\n #if EFSYS_OPT_SIENA\ndiff --git a/drivers/net/sfc/efx/base/efx_rx.c b/drivers/net/sfc/efx/base/efx_rx.c\nindex a6f4c55..a884d43 100644\n--- a/drivers/net/sfc/efx/base/efx_rx.c\n+++ b/drivers/net/sfc/efx/base/efx_rx.c\n@@ -49,6 +49,34 @@ siena_rx_scatter_enable(\n \t__in\t\tunsigned int buf_size);\n #endif /* EFSYS_OPT_RX_SCATTER */\n \n+#if EFSYS_OPT_RX_SCALE\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_scale_mode_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_rx_hash_alg_t alg,\n+\t__in\t\tefx_rx_hash_type_t type,\n+\t__in\t\tboolean_t insert);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_scale_key_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tuint8_t *key,\n+\t__in\t\tsize_t n);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_scale_tbl_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tunsigned int *table,\n+\t__in\t\tsize_t n);\n+\n+static\t__checkReturn\tuint32_t\n+siena_rx_prefix_hash(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_rx_hash_alg_t func,\n+\t__in\t\tuint8_t *buffer);\n+\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n static\t__checkReturn\tefx_rc_t\n siena_rx_prefix_pktlen(\n \t__in\t\tefx_nic_t *enp,\n@@ -104,6 +132,12 @@ static const efx_rx_ops_t __efx_rx_siena_ops = {\n #if EFSYS_OPT_RX_SCATTER\n \tsiena_rx_scatter_enable,\t\t/* erxo_scatter_enable */\n #endif\n+#if EFSYS_OPT_RX_SCALE\n+\tsiena_rx_scale_mode_set,\t\t/* erxo_scale_mode_set */\n+\tsiena_rx_scale_key_set,\t\t\t/* erxo_scale_key_set */\n+\tsiena_rx_scale_tbl_set,\t\t\t/* erxo_scale_tbl_set */\n+\tsiena_rx_prefix_hash,\t\t\t/* erxo_prefix_hash */\n+#endif\n \tsiena_rx_prefix_pktlen,\t\t\t/* erxo_prefix_pktlen */\n \tsiena_rx_qpost,\t\t\t\t/* erxo_qpost */\n \tsiena_rx_qpush,\t\t\t\t/* erxo_qpush */\n@@ -121,6 +155,12 @@ static const efx_rx_ops_t __efx_rx_ef10_ops = {\n #if EFSYS_OPT_RX_SCATTER\n \tef10_rx_scatter_enable,\t\t\t/* erxo_scatter_enable */\n #endif\n+#if EFSYS_OPT_RX_SCALE\n+\tef10_rx_scale_mode_set,\t\t\t/* erxo_scale_mode_set */\n+\tef10_rx_scale_key_set,\t\t\t/* erxo_scale_key_set */\n+\tef10_rx_scale_tbl_set,\t\t\t/* erxo_scale_tbl_set */\n+\tef10_rx_prefix_hash,\t\t\t/* erxo_prefix_hash */\n+#endif\n \tef10_rx_prefix_pktlen,\t\t\t/* erxo_prefix_pktlen */\n \tef10_rx_qpost,\t\t\t\t/* erxo_qpost */\n \tef10_rx_qpush,\t\t\t\t/* erxo_qpush */\n@@ -238,6 +278,136 @@ efx_rx_scatter_enable(\n }\n #endif\t/* EFSYS_OPT_RX_SCATTER */\n \n+#if EFSYS_OPT_RX_SCALE\n+\t__checkReturn\tefx_rc_t\n+efx_rx_hash_support_get(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tefx_rx_hash_support_t *supportp)\n+{\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);\n+\n+\tif (supportp == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\t/* Report if resources are available to insert RX hash value */\n+\t*supportp = enp->en_hash_support;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+efx_rx_scale_support_get(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tefx_rx_scale_support_t *supportp)\n+{\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);\n+\n+\tif (supportp == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\t/* Report if resources are available to support RSS */\n+\t*supportp = enp->en_rss_support;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+efx_rx_scale_mode_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_rx_hash_alg_t alg,\n+\t__in\t\tefx_rx_hash_type_t type,\n+\t__in\t\tboolean_t insert)\n+{\n+\tconst efx_rx_ops_t *erxop = enp->en_erxop;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);\n+\n+\tif (erxop->erxo_scale_mode_set != NULL) {\n+\t\tif ((rc = erxop->erxo_scale_mode_set(enp, alg,\n+\t\t\t type, insert)) != 0)\n+\t\t\tgoto fail1;\n+\t}\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\treturn (rc);\n+}\n+#endif\t/* EFSYS_OPT_RX_SCALE */\n+\n+#if EFSYS_OPT_RX_SCALE\n+\t__checkReturn\tefx_rc_t\n+efx_rx_scale_key_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tuint8_t *key,\n+\t__in\t\tsize_t n)\n+{\n+\tconst efx_rx_ops_t *erxop = enp->en_erxop;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);\n+\n+\tif ((rc = erxop->erxo_scale_key_set(enp, key, n)) != 0)\n+\t\tgoto fail1;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif\t/* EFSYS_OPT_RX_SCALE */\n+\n+#if EFSYS_OPT_RX_SCALE\n+\t__checkReturn\tefx_rc_t\n+efx_rx_scale_tbl_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tunsigned int *table,\n+\t__in\t\tsize_t n)\n+{\n+\tconst efx_rx_ops_t *erxop = enp->en_erxop;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);\n+\n+\tif ((rc = erxop->erxo_scale_tbl_set(enp, table, n)) != 0)\n+\t\tgoto fail1;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif\t/* EFSYS_OPT_RX_SCALE */\n+\n \t\t\tvoid\n efx_rx_qpost(\n \t__in\t\tefx_rxq_t *erp,\n@@ -380,6 +550,23 @@ efx_psuedo_hdr_pkt_length_get(\n \treturn (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));\n }\n \n+#if EFSYS_OPT_RX_SCALE\n+\t__checkReturn\tuint32_t\n+efx_psuedo_hdr_hash_get(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in\t\tefx_rx_hash_alg_t func,\n+\t__in\t\tuint8_t *buffer)\n+{\n+\tefx_nic_t *enp = erp->er_enp;\n+\tconst efx_rx_ops_t *erxop = enp->en_erxop;\n+\n+\tEFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);\n+\n+\tEFSYS_ASSERT3U(enp->en_hash_support, ==, EFX_RX_HASH_AVAILABLE);\n+\treturn (erxop->erxo_prefix_hash(enp, func, buffer));\n+}\n+#endif\t/* EFSYS_OPT_RX_SCALE */\n+\n #if EFSYS_OPT_SIENA\n \n static\t__checkReturn\tefx_rc_t\n@@ -407,6 +594,14 @@ siena_rx_init(\n \t\t\t\t index, &oword, B_TRUE);\n \t}\n \n+#if EFSYS_OPT_RX_SCALE\n+\t/* The RSS key and indirection table are writable. */\n+\tenp->en_rss_support = EFX_RX_SCALE_EXCLUSIVE;\n+\n+\t/* Hardware can insert RX hash with/without RSS */\n+\tenp->en_hash_support = EFX_RX_HASH_AVAILABLE;\n+#endif\t/* EFSYS_OPT_RX_SCALE */\n+\n \treturn (0);\n }\n \n@@ -515,6 +710,241 @@ siena_rx_scatter_enable(\n \t} while (B_FALSE)\n \n \n+#if EFSYS_OPT_RX_SCALE\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_scale_mode_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_rx_hash_alg_t alg,\n+\t__in\t\tefx_rx_hash_type_t type,\n+\t__in\t\tboolean_t insert)\n+{\n+\tefx_rc_t rc;\n+\n+\tswitch (alg) {\n+\tcase EFX_RX_HASHALG_LFSR:\n+\t\tEFX_RX_LFSR_HASH(enp, insert);\n+\t\tbreak;\n+\n+\tcase EFX_RX_HASHALG_TOEPLITZ:\n+\t\tEFX_RX_TOEPLITZ_IPV4_HASH(enp, insert,\n+\t\t type & (1 << EFX_RX_HASH_IPV4),\n+\t\t type & (1 << EFX_RX_HASH_TCPIPV4));\n+\n+\t\tEFX_RX_TOEPLITZ_IPV6_HASH(enp,\n+\t\t type & (1 << EFX_RX_HASH_IPV6),\n+\t\t type & (1 << EFX_RX_HASH_TCPIPV6),\n+\t\t rc);\n+\t\tif (rc != 0)\n+\t\t\tgoto fail1;\n+\n+\t\tbreak;\n+\n+\tdefault:\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\tEFX_RX_LFSR_HASH(enp, B_FALSE);\n+\n+\treturn (rc);\n+}\n+#endif\n+\n+#if EFSYS_OPT_RX_SCALE\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_scale_key_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tuint8_t *key,\n+\t__in\t\tsize_t n)\n+{\n+\tefx_oword_t oword;\n+\tunsigned int byte;\n+\tunsigned int offset;\n+\tefx_rc_t rc;\n+\n+\tbyte = 0;\n+\n+\t/* Write Toeplitz IPv4 hash key */\n+\tEFX_ZERO_OWORD(oword);\n+\tfor (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;\n+\t offset > 0 && byte < n;\n+\t --offset)\n+\t\toword.eo_u8[offset - 1] = key[byte++];\n+\n+\tEFX_BAR_WRITEO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);\n+\n+\tbyte = 0;\n+\n+\t/* Verify Toeplitz IPv4 hash key */\n+\tEFX_BAR_READO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);\n+\tfor (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;\n+\t offset > 0 && byte < n;\n+\t --offset) {\n+\t\tif (oword.eo_u8[offset - 1] != key[byte++]) {\n+\t\t\trc = EFAULT;\n+\t\t\tgoto fail1;\n+\t\t}\n+\t}\n+\n+\tif ((enp->en_features & EFX_FEATURE_IPV6) == 0)\n+\t\tgoto done;\n+\n+\tbyte = 0;\n+\n+\t/* Write Toeplitz IPv6 hash key 3 */\n+\tEFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);\n+\tfor (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +\n+\t FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;\n+\t offset > 0 && byte < n;\n+\t --offset)\n+\t\toword.eo_u8[offset - 1] = key[byte++];\n+\n+\tEFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);\n+\n+\t/* Write Toeplitz IPv6 hash key 2 */\n+\tEFX_ZERO_OWORD(oword);\n+\tfor (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +\n+\t FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;\n+\t offset > 0 && byte < n;\n+\t --offset)\n+\t\toword.eo_u8[offset - 1] = key[byte++];\n+\n+\tEFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);\n+\n+\t/* Write Toeplitz IPv6 hash key 1 */\n+\tEFX_ZERO_OWORD(oword);\n+\tfor (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +\n+\t FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;\n+\t offset > 0 && byte < n;\n+\t --offset)\n+\t\toword.eo_u8[offset - 1] = key[byte++];\n+\n+\tEFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);\n+\n+\tbyte = 0;\n+\n+\t/* Verify Toeplitz IPv6 hash key 3 */\n+\tEFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);\n+\tfor (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +\n+\t FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;\n+\t offset > 0 && byte < n;\n+\t --offset) {\n+\t\tif (oword.eo_u8[offset - 1] != key[byte++]) {\n+\t\t\trc = EFAULT;\n+\t\t\tgoto fail2;\n+\t\t}\n+\t}\n+\n+\t/* Verify Toeplitz IPv6 hash key 2 */\n+\tEFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);\n+\tfor (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +\n+\t FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;\n+\t offset > 0 && byte < n;\n+\t --offset) {\n+\t\tif (oword.eo_u8[offset - 1] != key[byte++]) {\n+\t\t\trc = EFAULT;\n+\t\t\tgoto fail3;\n+\t\t}\n+\t}\n+\n+\t/* Verify Toeplitz IPv6 hash key 1 */\n+\tEFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);\n+\tfor (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +\n+\t FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;\n+\t offset > 0 && byte < n;\n+\t --offset) {\n+\t\tif (oword.eo_u8[offset - 1] != key[byte++]) {\n+\t\t\trc = EFAULT;\n+\t\t\tgoto fail4;\n+\t\t}\n+\t}\n+\n+done:\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif\n+\n+#if EFSYS_OPT_RX_SCALE\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_scale_tbl_set(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in_ecount(n)\tunsigned int *table,\n+\t__in\t\tsize_t n)\n+{\n+\tefx_oword_t oword;\n+\tint index;\n+\tefx_rc_t rc;\n+\n+\tEFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS);\n+\tEFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH));\n+\n+\tif (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tfor (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS; index++) {\n+\t\tuint32_t byte;\n+\n+\t\t/* Calculate the entry to place in the table */\n+\t\tbyte = (n > 0) ? (uint32_t)table[index % n] : 0;\n+\n+\t\tEFSYS_PROBE2(table, int, index, uint32_t, byte);\n+\n+\t\tEFX_POPULATE_OWORD_1(oword, FRF_BZ_IT_QUEUE, byte);\n+\n+\t\t/* Write the table */\n+\t\tEFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,\n+\t\t\t\t index, &oword, B_TRUE);\n+\t}\n+\n+\tfor (index = FR_BZ_RX_INDIRECTION_TBL_ROWS - 1; index >= 0; --index) {\n+\t\tuint32_t byte;\n+\n+\t\t/* Determine if we're starting a new batch */\n+\t\tbyte = (n > 0) ? (uint32_t)table[index % n] : 0;\n+\n+\t\t/* Read the table */\n+\t\tEFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL,\n+\t\t\t\t index, &oword, B_TRUE);\n+\n+\t\t/* Verify the entry */\n+\t\tif (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) {\n+\t\t\trc = EFAULT;\n+\t\t\tgoto fail2;\n+\t\t}\n+\t}\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+#endif\n+\n /*\n * Falcon/Siena psuedo-header\n * --------------------------\n@@ -531,6 +961,32 @@ siena_rx_scatter_enable(\n * LL.LL LFSR hash (16-bit big-endian)\n */\n \n+#if EFSYS_OPT_RX_SCALE\n+static\t__checkReturn\tuint32_t\n+siena_rx_prefix_hash(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_rx_hash_alg_t func,\n+\t__in\t\tuint8_t *buffer)\n+{\n+\t_NOTE(ARGUNUSED(enp))\n+\n+\tswitch (func) {\n+\tcase EFX_RX_HASHALG_TOEPLITZ:\n+\t\treturn ((buffer[12] << 24) |\n+\t\t (buffer[13] << 16) |\n+\t\t (buffer[14] << 8) |\n+\t\t buffer[15]);\n+\n+\tcase EFX_RX_HASHALG_LFSR:\n+\t\treturn ((buffer[14] << 8) | buffer[15]);\n+\n+\tdefault:\n+\t\tEFSYS_ASSERT(0);\n+\t\treturn (0);\n+\t}\n+}\n+#endif /* EFSYS_OPT_RX_SCALE */\n+\n static\t__checkReturn\tefx_rc_t\n siena_rx_prefix_pktlen(\n \t__in\t\tefx_nic_t *enp,\n", "prefixes": [ "dpdk-dev", "21/56" ] }{ "id": 17124, "url": "