get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 17124,
    "url": "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"
    ]
}