get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 136079,
    "url": "http://patchwork.dpdk.org/api/patches/136079/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20240124000426.418527-4-joshwash@google.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20240124000426.418527-4-joshwash@google.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240124000426.418527-4-joshwash@google.com",
    "date": "2024-01-24T00:04:21",
    "name": "[v3,3/7] net/gve: add gve_rss library for handling RSS-related behaviors",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "08966d55a6decaea6f235f6007584a48819580f5",
    "submitter": {
        "id": 2921,
        "url": "http://patchwork.dpdk.org/api/people/2921/?format=api",
        "name": "Joshua Washington",
        "email": "joshwash@google.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20240124000426.418527-4-joshwash@google.com/mbox/",
    "series": [
        {
            "id": 30888,
            "url": "http://patchwork.dpdk.org/api/series/30888/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=30888",
            "date": "2024-01-24T00:04:19",
            "name": "[v3,1/7] net/gve: fully expose RSS offload support in dev_info",
            "version": 3,
            "mbox": "http://patchwork.dpdk.org/series/30888/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/136079/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/136079/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id CB28D439AD;\n\tWed, 24 Jan 2024 01:05:01 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id A56C940E72;\n\tWed, 24 Jan 2024 01:04:44 +0100 (CET)",
            "from mail-pl1-f201.google.com (mail-pl1-f201.google.com\n [209.85.214.201])\n by mails.dpdk.org (Postfix) with ESMTP id 0B6BB40E25\n for <dev@dpdk.org>; Wed, 24 Jan 2024 01:04:43 +0100 (CET)",
            "by mail-pl1-f201.google.com with SMTP id\n d9443c01a7336-1d542680c9cso39675685ad.2\n for <dev@dpdk.org>; Tue, 23 Jan 2024 16:04:42 -0800 (PST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=google.com; s=20230601; t=1706054682; x=1706659482; darn=dpdk.org;\n h=cc:to:from:subject:message-id:references:mime-version:in-reply-to\n :date:from:to:cc:subject:date:message-id:reply-to;\n bh=lE83ibws4iol+07GnUwZfVFlpT4qXWCdez5K1s/6jhI=;\n b=hYZl8JNJFG8pVxDpQVakD72zPmnodfyda0Zd7gQgACVh9POJpjvtzJ6Pir+6qKyIs0\n FlBAeOnBHf1dOKCSzda9j/2Auvq9kLNfGwb70h2aI261tsWFjpJXJHOZRd/acAjCs8zd\n GBaPviiUhkOmzBiAaY/3PNK1BQOlIAaGMTrfc1ACTnpSZptAvOwO3bL2FD1KP1JipWk/\n KEZA4ZZXKET7c7xAQKTyIrVE6AvrmyBNmkjZTh8tbvAD8eeza22e0AOvdPbwUuOea39X\n Mwfw5B7TCwKdAep4E0sWVLhwI9PY0un4KjEDZW6Ecm3uhNvgryx28A5OwX+dpp9rR2vK\n as4w==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1706054682; x=1706659482;\n h=cc:to:from:subject:message-id:references:mime-version:in-reply-to\n :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n bh=lE83ibws4iol+07GnUwZfVFlpT4qXWCdez5K1s/6jhI=;\n b=IsvIw+5aHD/zm4JPEAqdXWX4IEkkrNGVg5S8K9UkWjpP1X7Xy9R0vME9Xlmd8Vi1t+\n oPh+s76bSsOR8v8Osax0UbUR2E5u/WA/MDBwzAG5Iczx4DYCQUc+6DdlJSxDWcB+Z3hl\n sOBkJbMms9Zlgw2H5oLVN6RdHW62qmYw7JghBB/jdpDHtZSBoS7WEd3rLF9cgy2jr5GE\n eWyJtpaMDuD4ue/pbeGt9InRNSYS86PMCEF/nKBztaDqq6O/lQWejgfejNvBwFUJ+G0H\n rp2Ea+UWQxZEsFA5fwiNL7vGzCowN5p1W1SGPUuIxc9L27QRleDn1Z1gNv+HQum2KVjN\n tvqg==",
        "X-Gm-Message-State": "AOJu0YzlP+/m90iOrGF1Y/p33rurlbP16Z9pLPMqf/BDBnE9FK0O6chn\n BIMrWf07lD6NyLCOsWe3ExQu1RX+BfAnilwxbUPsDezTz13jpAs+Ac0nuCNV4H584HK/g3hH7p0\n dJ0QIP1OKcg==",
        "X-Google-Smtp-Source": "\n AGHT+IHGhmvxLIrszpCMBNmublrkXL+yKjJtCFtnjWBrQ+Lsvhda0HOf90kBtif3r0kWB0QKtOhb2l1/VeIstA==",
        "X-Received": "from joshwash.sea.corp.google.com\n ([2620:15c:11c:202:b9a2:fa74:abc3:bc47])\n (user=joshwash job=sendgmr) by 2002:a17:903:41c3:b0:1d7:6afc:61b4 with SMTP\n id u3-20020a17090341c300b001d76afc61b4mr40ple.7.1706054681969; Tue, 23 Jan\n 2024 16:04:41 -0800 (PST)",
        "Date": "Tue, 23 Jan 2024 16:04:21 -0800",
        "In-Reply-To": "<20240124000426.418527-1-joshwash@google.com>",
        "Mime-Version": "1.0",
        "References": "<20240123175831.3219292-1-joshwash@google.com>\n <20240124000426.418527-1-joshwash@google.com>",
        "X-Mailer": "git-send-email 2.43.0.429.g432eaa2c6b-goog",
        "Message-ID": "<20240124000426.418527-4-joshwash@google.com>",
        "Subject": "[PATCH v3 3/7] net/gve: add gve_rss library for handling RSS-related\n behaviors",
        "From": "Joshua Washington <joshwash@google.com>",
        "To": "Junfeng Guo <junfeng.guo@intel.com>,\n Jeroen de Borst <jeroendb@google.com>,\n Rushil Gupta <rushilg@google.com>, Joshua Washington <joshwash@google.com>",
        "Cc": "dev@dpdk.org, Ferruh Yigit <ferruh.yigit@amd.com>",
        "Content-Type": "text/plain; charset=\"UTF-8\"",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "This change includes a number of helper functions to facilitate RSS\nconfiguration on the GVE DPDK driver. These methods are declared in\ngve_rss.h.\n\nSigned-off-by: Joshua Washington <joshwash@google.com>\nReviewed-by: Rushil Gupta <rushilg@google.com>\nReviewed-by: Jeroen de Borst <jeroendb@google.com>\n---\n drivers/net/gve/base/gve_adminq.h |  10 +-\n drivers/net/gve/gve_ethdev.c      |   2 +-\n drivers/net/gve/gve_ethdev.h      |   4 +-\n drivers/net/gve/gve_rss.c         | 206 ++++++++++++++++++++++++++++++\n drivers/net/gve/gve_rss.h         | 107 ++++++++++++++++\n drivers/net/gve/meson.build       |   1 +\n 6 files changed, 319 insertions(+), 11 deletions(-)\n create mode 100644 drivers/net/gve/gve_rss.c\n create mode 100644 drivers/net/gve/gve_rss.h",
    "diff": "diff --git a/drivers/net/gve/base/gve_adminq.h b/drivers/net/gve/base/gve_adminq.h\nindex 95f4960561..24abd945cc 100644\n--- a/drivers/net/gve/base/gve_adminq.h\n+++ b/drivers/net/gve/base/gve_adminq.h\n@@ -378,15 +378,6 @@ struct gve_adminq_get_ptype_map {\n \t__be64 ptype_map_addr;\n };\n \n-#define GVE_RSS_HASH_IPV4\t\tBIT(0)\n-#define GVE_RSS_HASH_TCPV4\t\tBIT(1)\n-#define GVE_RSS_HASH_IPV6\t\tBIT(2)\n-#define GVE_RSS_HASH_IPV6_EX\t\tBIT(3)\n-#define GVE_RSS_HASH_TCPV6\t\tBIT(4)\n-#define GVE_RSS_HASH_TCPV6_EX\t\tBIT(5)\n-#define GVE_RSS_HASH_UDPV4\t\tBIT(6)\n-#define GVE_RSS_HASH_UDPV6\t\tBIT(7)\n-#define GVE_RSS_HASH_UDPV6_EX\t\tBIT(8)\n \n /* RSS configuration command */\n struct gve_adminq_configure_rss {\n@@ -428,6 +419,7 @@ union gve_adminq_command {\n GVE_CHECK_UNION_LEN(64, gve_adminq_command);\n \n struct gve_priv;\n+struct gve_rss_config;\n struct gve_queue_page_list;\n int gve_adminq_alloc(struct gve_priv *priv);\n void gve_adminq_free(struct gve_priv *priv);\ndiff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c\nindex 6acdb4e13b..936ca22cb9 100644\n--- a/drivers/net/gve/gve_ethdev.c\n+++ b/drivers/net/gve/gve_ethdev.c\n@@ -442,7 +442,7 @@ gve_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n \t\t.nb_align = 1,\n \t};\n \n-\tdev_info->flow_type_rss_offloads = GVE_RSS_OFFLOAD_ALL;\n+\tdev_info->flow_type_rss_offloads = GVE_RTE_RSS_OFFLOAD_ALL;\n \n \treturn 0;\n }\ndiff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h\nindex f7635e829c..bc486cb941 100644\n--- a/drivers/net/gve/gve_ethdev.h\n+++ b/drivers/net/gve/gve_ethdev.h\n@@ -33,7 +33,7 @@\n \t\tRTE_MBUF_F_TX_L4_MASK  |\t\\\n \t\tRTE_MBUF_F_TX_TCP_SEG)\n \n-#define GVE_RSS_OFFLOAD_ALL (\t\t\\\n+#define GVE_RTE_RSS_OFFLOAD_ALL (\t\\\n \tRTE_ETH_RSS_IPV4 |\t\t\\\n \tRTE_ETH_RSS_NONFRAG_IPV4_TCP |\t\\\n \tRTE_ETH_RSS_IPV6 |\t\t\\\n@@ -290,6 +290,8 @@ struct gve_priv {\n \tconst struct rte_memzone *stats_report_mem;\n \tuint16_t stats_start_idx; /* start index of array of stats written by NIC */\n \tuint16_t stats_end_idx; /* end index of array of stats written by NIC */\n+\n+\tstruct gve_rss_config rss_config;\n };\n \n static inline bool\ndiff --git a/drivers/net/gve/gve_rss.c b/drivers/net/gve/gve_rss.c\nnew file mode 100644\nindex 0000000000..931180f8f2\n--- /dev/null\n+++ b/drivers/net/gve/gve_rss.c\n@@ -0,0 +1,206 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2023 Google LLC\n+ */\n+\n+#include \"gve_rss.h\"\n+\n+int\n+gve_generate_rss_reta(struct rte_eth_dev *dev, struct gve_rss_config *config)\n+{\n+\tint i;\n+\tif (!config || !config->indir)\n+\t\treturn -EINVAL;\n+\n+\tfor (i = 0; i < config->indir_size; i++)\n+\t\tconfig->indir[i] = i % dev->data->nb_rx_queues;\n+\n+\treturn 0;\n+}\n+\n+\n+int\n+gve_init_rss_config(struct gve_rss_config *gve_rss_conf,\n+\t\tuint16_t key_size, uint16_t indir_size)\n+{\n+\tint err;\n+\n+\tgve_rss_conf->alg = GVE_RSS_HASH_TOEPLITZ;\n+\n+\tgve_rss_conf->key_size = key_size;\n+\tgve_rss_conf->key = rte_zmalloc(\"rss key\",\n+\t\tkey_size * sizeof(*gve_rss_conf->key),\n+\t\tRTE_CACHE_LINE_SIZE);\n+\tif (!gve_rss_conf->key)\n+\t\treturn -ENOMEM;\n+\n+\tgve_rss_conf->indir_size = indir_size;\n+\tgve_rss_conf->indir = rte_zmalloc(\"rss reta\",\n+\t\tindir_size * sizeof(*gve_rss_conf->indir),\n+\t\tRTE_CACHE_LINE_SIZE);\n+\tif (!gve_rss_conf->indir) {\n+\t\terr = -ENOMEM;\n+\t\tgoto err_with_key;\n+\t}\n+\n+\treturn 0;\n+err_with_key:\n+\trte_free(gve_rss_conf->key);\n+\treturn err;\n+}\n+\n+int\n+gve_init_rss_config_from_priv(struct gve_priv *priv,\n+\tstruct gve_rss_config *gve_rss_conf)\n+{\n+\tint err = gve_init_rss_config(gve_rss_conf, priv->rss_config.key_size,\n+\t\tpriv->rss_config.indir_size);\n+\tif (err)\n+\t\treturn err;\n+\n+\tgve_rss_conf->hash_types = priv->rss_config.hash_types;\n+\tgve_rss_conf->alg = priv->rss_config.alg;\n+\tmemcpy(gve_rss_conf->key, priv->rss_config.key,\n+\t\tgve_rss_conf->key_size * sizeof(*gve_rss_conf->key));\n+\tmemcpy(gve_rss_conf->indir, priv->rss_config.indir,\n+\t\tgve_rss_conf->indir_size * sizeof(*gve_rss_conf->indir));\n+\n+\treturn 0;\n+}\n+\n+void\n+gve_free_rss_config(struct gve_rss_config *gve_rss_conf)\n+{\n+\trte_free(gve_rss_conf->indir);\n+\tgve_rss_conf->indir = NULL;\n+\trte_free(gve_rss_conf->key);\n+\tgve_rss_conf->key = NULL;\n+}\n+\n+int\n+gve_update_priv_rss_config(struct gve_priv *priv, struct gve_rss_config *config)\n+{\n+\tstruct gve_rss_config *priv_config = &priv->rss_config;\n+\tint key_bytes, indir_bytes;\n+\n+\tif (!config)\n+\t\treturn -EINVAL;\n+\tif (config->key_size == 0 || !config->key)\n+\t\treturn -EINVAL;\n+\tif (config->indir_size == 0 || !config->indir)\n+\t\treturn -EINVAL;\n+\n+\tpriv_config->hash_types = config->hash_types;\n+\tpriv_config->alg = config->alg;\n+\n+\tpriv_config->key_size = config->key_size;\n+\tkey_bytes = priv_config->key_size * sizeof(*priv_config->key);\n+\tif (!priv_config->key)\n+\t\tpriv_config->key = rte_zmalloc(\"priv rss key\", key_bytes,\n+\t\t\tRTE_CACHE_LINE_SIZE);\n+\telse\n+\t\tpriv_config->key = rte_realloc(priv_config->key, key_bytes,\n+\t\t\tRTE_CACHE_LINE_SIZE);\n+\tif (!priv_config->key)\n+\t\treturn -ENOMEM;\n+\n+\tpriv_config->indir_size = config->indir_size;\n+\tindir_bytes = priv_config->indir_size * sizeof(*priv_config->indir);\n+\tif (!priv_config->indir)\n+\t\tpriv_config->indir = rte_zmalloc(\"priv rss reta\", indir_bytes,\n+\t\t\tRTE_CACHE_LINE_SIZE);\n+\telse\n+\t\tpriv_config->indir = rte_realloc(priv_config->indir,\n+\t\t\tindir_bytes, RTE_CACHE_LINE_SIZE);\n+\n+\tif (!priv_config->indir)\n+\t\treturn -ENOMEM;\n+\n+\tmemcpy(priv_config->indir, config->indir,\n+\t\tconfig->indir_size * sizeof(*priv_config->indir));\n+\tmemcpy(priv_config->key, config->key,\n+\t\tconfig->key_size * sizeof(*priv_config->key));\n+\n+\treturn 0;\n+}\n+\n+int\n+gve_update_rss_key(struct gve_priv *priv, struct gve_rss_config *gve_rss_conf,\n+\tstruct rte_eth_rss_conf *rss_conf)\n+{\n+\tif (rss_conf->rss_key_len && rss_conf->rss_key) {\n+\t\tgve_rss_conf->key_size = rss_conf->rss_key_len;\n+\t\tmemcpy(gve_rss_conf->key, rss_conf->rss_key,\n+\t\t\tgve_rss_conf->key_size * sizeof(*gve_rss_conf->key));\n+\t} else if (priv->rss_config.key_size && priv->rss_config.key) {\n+\t\tgve_rss_conf->key_size = priv->rss_config.key_size;\n+\t\tmemcpy(gve_rss_conf->key, priv->rss_config.key,\n+\t\t\tgve_rss_conf->key_size * sizeof(*gve_rss_conf->key));\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"RSS key must be set as part of initial RSS \"\n+\t\t\t\"configuration.\");\n+\t\treturn -EINVAL;\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+gve_update_rss_hash_types(struct gve_priv *priv,\n+\tstruct gve_rss_config *gve_rss_conf, struct rte_eth_rss_conf *rss_conf)\n+{\n+\t/* Initialize to 0 before modifying. */\n+\tgve_rss_conf->hash_types = 0;\n+\tif (rss_conf->rss_hf)\n+\t\trte_to_gve_rss_hf(rss_conf->rss_hf, gve_rss_conf);\n+\telse if (priv->rss_config.key_size && priv->rss_config.key)\n+\t\tgve_rss_conf->hash_types = priv->rss_config.hash_types;\n+\telse\n+\t\tgve_rss_conf->hash_types = GVE_RSS_OFFLOAD_DEFAULT;\n+\treturn 0;\n+}\n+\n+void\n+rte_to_gve_rss_hf(uint64_t rte_rss_hf, struct gve_rss_config *gve_rss_conf)\n+{\n+\tif (rte_rss_hf & RTE_ETH_RSS_IPV4)\n+\t\tgve_rss_conf->hash_types |= GVE_RSS_HASH_IPV4;\n+\tif (rte_rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP)\n+\t\tgve_rss_conf->hash_types |= GVE_RSS_HASH_TCPV4;\n+\tif (rte_rss_hf & RTE_ETH_RSS_IPV6)\n+\t\tgve_rss_conf->hash_types |= GVE_RSS_HASH_IPV6;\n+\tif (rte_rss_hf & RTE_ETH_RSS_IPV6_EX)\n+\t\tgve_rss_conf->hash_types |= GVE_RSS_HASH_IPV6_EX;\n+\tif (rte_rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP)\n+\t\tgve_rss_conf->hash_types |= GVE_RSS_HASH_TCPV6;\n+\tif (rte_rss_hf & RTE_ETH_RSS_IPV6_TCP_EX)\n+\t\tgve_rss_conf->hash_types |= GVE_RSS_HASH_TCPV6_EX;\n+\tif (rte_rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP)\n+\t\tgve_rss_conf->hash_types |= GVE_RSS_HASH_UDPV4;\n+\tif (rte_rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP)\n+\t\tgve_rss_conf->hash_types |= GVE_RSS_HASH_UDPV6;\n+\tif (rte_rss_hf & RTE_ETH_RSS_IPV6_UDP_EX)\n+\t\tgve_rss_conf->hash_types |= GVE_RSS_HASH_UDPV6_EX;\n+}\n+\n+void\n+gve_to_rte_rss_hf(uint16_t gve_rss_types, struct rte_eth_rss_conf *rss_conf)\n+{\n+\tif (gve_rss_types & GVE_RSS_HASH_IPV4)\n+\t\trss_conf->rss_hf |= RTE_ETH_RSS_IPV4;\n+\tif (gve_rss_types & GVE_RSS_HASH_TCPV4)\n+\t\trss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;\n+\tif (gve_rss_types & GVE_RSS_HASH_IPV6)\n+\t\trss_conf->rss_hf |= RTE_ETH_RSS_IPV6;\n+\tif (gve_rss_types & GVE_RSS_HASH_IPV6_EX)\n+\t\trss_conf->rss_hf |= RTE_ETH_RSS_IPV6_EX;\n+\tif (gve_rss_types & GVE_RSS_HASH_TCPV6)\n+\t\trss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;\n+\tif (gve_rss_types & GVE_RSS_HASH_TCPV6_EX)\n+\t\trss_conf->rss_hf |= RTE_ETH_RSS_IPV6_TCP_EX;\n+\tif (gve_rss_types & GVE_RSS_HASH_UDPV4)\n+\t\trss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;\n+\tif (gve_rss_types & GVE_RSS_HASH_UDPV6)\n+\t\trss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;\n+\tif (gve_rss_types & GVE_RSS_HASH_UDPV6_EX)\n+\t\trss_conf->rss_hf |= RTE_ETH_RSS_IPV6_UDP_EX;\n+}\n+\ndiff --git a/drivers/net/gve/gve_rss.h b/drivers/net/gve/gve_rss.h\nnew file mode 100644\nindex 0000000000..0cc235a19a\n--- /dev/null\n+++ b/drivers/net/gve/gve_rss.h\n@@ -0,0 +1,107 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2023 Google LLC\n+ */\n+\n+#include \"gve_adminq.h\"\n+#include \"gve_ethdev.h\"\n+\n+#define GVE_RSS_HASH_IPV4\t\tBIT(0)\n+#define GVE_RSS_HASH_TCPV4\t\tBIT(1)\n+#define GVE_RSS_HASH_IPV6\t\tBIT(2)\n+#define GVE_RSS_HASH_IPV6_EX\t\tBIT(3)\n+#define GVE_RSS_HASH_TCPV6\t\tBIT(4)\n+#define GVE_RSS_HASH_TCPV6_EX\t\tBIT(5)\n+#define GVE_RSS_HASH_UDPV4\t\tBIT(6)\n+#define GVE_RSS_HASH_UDPV6\t\tBIT(7)\n+#define GVE_RSS_HASH_UDPV6_EX\t\tBIT(8)\n+\n+#define GVE_RSS_OFFLOAD_DEFAULT (\t\\\n+\tGVE_RSS_HASH_IPV4 |\t\t\\\n+\tGVE_RSS_HASH_TCPV4 |\t\t\\\n+\tGVE_RSS_HASH_IPV6 |\t\t\\\n+\tGVE_RSS_HASH_IPV6_EX |\t\t\\\n+\tGVE_RSS_HASH_TCPV6 |\t\t\\\n+\tGVE_RSS_HASH_TCPV6_EX |\t\t\\\n+\tGVE_RSS_HASH_UDPV4 |\t\t\\\n+\tGVE_RSS_HASH_UDPV6 |\t\t\\\n+\tGVE_RSS_HASH_UDPV6_EX)\n+\n+/**\n+ * Generates default RSS redirection table based on the number of queues the\n+ * device is configured with. This assigns hash values to queues in a\n+ * round-robin manner.\n+ */\n+int\n+gve_generate_rss_reta(struct rte_eth_dev *dev, struct gve_rss_config *config);\n+\n+/**\n+ * Initializes `gve_rss_conf`, setting the fields to default values and\n+ * allocating memory for the RSS key and redirection table.\n+ */\n+int\n+gve_init_rss_config(struct gve_rss_config *gve_rss_conf,\n+\t\tuint16_t key_size, uint16_t indir_size);\n+\n+/**\n+ * Initializes `gve_rss_conf` based on the RSS configuration stored in `priv`.\n+ */\n+int\n+gve_init_rss_config_from_priv(struct gve_priv *priv,\n+\tstruct gve_rss_config *gve_rss_conf);\n+\n+/**\n+ * Frees RSS key and redriection table pointers stored in `gve_rss_conf`.\n+ */\n+void\n+gve_free_rss_config(struct gve_rss_config *gve_rss_conf);\n+\n+/**\n+ * Updates the rss_config stored in `priv` with the contents of `config`.\n+ */\n+int\n+gve_update_priv_rss_config(struct gve_priv *priv,\n+\t\t\t   struct gve_rss_config *config);\n+\n+/**\n+ * Updates the RSS key stored in `gve_rss_conf`. It is prioritized as follows:\n+ *\t1) retrieve from `rss_conf`, if non-null\n+ *\t2) retrieve from `priv`, if non-null\n+ * If keys from both sources are unset, return -EINVAL.\n+ */\n+int\n+gve_update_rss_key(struct gve_priv *priv, struct gve_rss_config *gve_rss_conf,\n+\t\t   struct rte_eth_rss_conf *rss_conf);\n+\n+/**\n+ * Updates the RSS hash types stored in `gve_rss_conf`. It is prioritized as\n+ * follows:\n+ *\t1) retrieve from `rss_conf`, if set\n+ *\t2) retrieve from priv, if RSS has been configured\n+ *\t3) set default RSS offload\n+ */\n+int\n+gve_update_rss_hash_types(struct gve_priv *priv,\n+\tstruct gve_rss_config *gve_rss_conf, struct rte_eth_rss_conf *rss_conf);\n+\n+/**\n+ * Ensures that only supported RSS hash fields are set in `rte_rss_hf`.\n+ */\n+static inline int\n+gve_validate_rss_hf(uint64_t rte_rss_hf) {\n+\treturn rte_rss_hf & ~GVE_RTE_RSS_OFFLOAD_ALL;\n+}\n+\n+/**\n+ * Converts RSS hash types from RTE values to GVE values, storing them in\n+ * `gve_rss_conf`.\n+ */\n+void\n+rte_to_gve_rss_hf(uint64_t rte_rss_hf, struct gve_rss_config *gve_rss_conf);\n+\n+/**\n+ * Converts RSS hash types from GVE values to RTE values, storing them in\n+ * `rss_conf`.\n+ */\n+void\n+gve_to_rte_rss_hf(uint16_t gve_rss_types, struct rte_eth_rss_conf *rss_conf);\n+\ndiff --git a/drivers/net/gve/meson.build b/drivers/net/gve/meson.build\nindex 61d195009c..6da13a8406 100644\n--- a/drivers/net/gve/meson.build\n+++ b/drivers/net/gve/meson.build\n@@ -15,5 +15,6 @@ sources = files(\n         'gve_tx_dqo.c',\n         'gve_ethdev.c',\n         'gve_version.c',\n+        'gve_rss.c',\n )\n includes += include_directories('base')\n",
    "prefixes": [
        "v3",
        "3/7"
    ]
}