get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 124117,
    "url": "http://patchwork.dpdk.org/api/patches/124117/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20230217073228.340815-11-junfeng.guo@intel.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": "<20230217073228.340815-11-junfeng.guo@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230217073228.340815-11-junfeng.guo@intel.com",
    "date": "2023-02-17T07:32:28",
    "name": "[RFC,v3,10/10] net/gve: add AdminQ command to verify driver compatibility",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "054000f34f056018c005ca04ec8dc76cf4b0919b",
    "submitter": {
        "id": 1785,
        "url": "http://patchwork.dpdk.org/api/people/1785/?format=api",
        "name": "Junfeng Guo",
        "email": "junfeng.guo@intel.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/20230217073228.340815-11-junfeng.guo@intel.com/mbox/",
    "series": [
        {
            "id": 27056,
            "url": "http://patchwork.dpdk.org/api/series/27056/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=27056",
            "date": "2023-02-17T07:32:18",
            "name": "gve PMD enhancement",
            "version": 3,
            "mbox": "http://patchwork.dpdk.org/series/27056/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/124117/comments/",
    "check": "fail",
    "checks": "http://patchwork.dpdk.org/api/patches/124117/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 79BE541CBC;\n\tFri, 17 Feb 2023 08:40:00 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id D91F242D3A;\n\tFri, 17 Feb 2023 08:39:36 +0100 (CET)",
            "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n by mails.dpdk.org (Postfix) with ESMTP id 3F8E642D40\n for <dev@dpdk.org>; Fri, 17 Feb 2023 08:39:34 +0100 (CET)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 16 Feb 2023 23:39:33 -0800",
            "from dpdk-jf-ntb-one.sh.intel.com ([10.67.111.104])\n by orsmga002.jf.intel.com with ESMTP; 16 Feb 2023 23:39:29 -0800"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1676619574; x=1708155574;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=qTcAJ/bLyQy7RmVrc+/br9yND/iZ7f2pO/jlahuGRA0=;\n b=HgfVjnPAlyAP5RrdcXEUyARji5JQDJi+3fHLhpHkmzEg0EHnCRt+cDKo\n HsIy5ZCYzprK4Md75abzD17k0eTZ9nMtDdJCUaEu5td2Bh0vwu3ROp+iz\n uwzNMgWEIeQaTwS1SMinLYEv3qkNTx6bt6T+zUbcsbB0aqwVno04mCOnu\n AwlZYtedqbl4WQWrX+3nBvOaydUKaHhPpA1/0nrUF+XqePruasVG4z82f\n Mb+oZz8TEIu9Iixp5GjDwlSJXgjXgJFJuSpf6Dtan+SYRSewA1HvI0zkv\n ydO7A4HxxuXjgX1HreObRvFgz8PWWVYqoNUCSm0uTMLzTfSgTRwUHgWEj A==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6500,9779,10623\"; a=\"418153135\"",
            "E=Sophos;i=\"5.97,304,1669104000\"; d=\"scan'208\";a=\"418153135\"",
            "E=McAfee;i=\"6500,9779,10623\"; a=\"670458798\"",
            "E=Sophos;i=\"5.97,304,1669104000\"; d=\"scan'208\";a=\"670458798\""
        ],
        "X-ExtLoop1": "1",
        "From": "Junfeng Guo <junfeng.guo@intel.com>",
        "To": "qi.z.zhang@intel.com, jingjing.wu@intel.com, ferruh.yigit@amd.com,\n beilei.xing@intel.com",
        "Cc": "dev@dpdk.org, xiaoyun.li@intel.com, helin.zhang@intel.com,\n Junfeng Guo <junfeng.guo@intel.com>, Rushil Gupta <rushilg@google.com>,\n Joshua Washington <joshwash@google.com>,\n Jordan Kimbrough <jrkim@google.com>, Jeroen de Borst <jeroendb@google.com>",
        "Subject": "[RFC v3 10/10] net/gve: add AdminQ command to verify driver\n compatibility",
        "Date": "Fri, 17 Feb 2023 15:32:28 +0800",
        "Message-Id": "<20230217073228.340815-11-junfeng.guo@intel.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20230217073228.340815-1-junfeng.guo@intel.com>",
        "References": "<20230130062642.3337239-1-junfeng.guo@intel.com>\n <20230217073228.340815-1-junfeng.guo@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "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": "Check whether the driver is compatible with the device presented.\n\nChange gve_driver_info fields to report DPDK as OS type and DPDK RTE\nversion as OS version, reserving driver_version fields for GVE driver\nversion based on features.\n\nSigned-off-by: Rushil Gupta <rushilg@google.com>\nSigned-off-by: Joshua Washington <joshwash@google.com>\nSigned-off-by: Jordan Kimbrough <jrkim@google.com>\nSigned-off-by: Junfeng Guo <junfeng.guo@intel.com>\nSigned-off-by: Jeroen de Borst <jeroendb@google.com>\n---\n drivers/net/gve/base/gve.h        |  3 --\n drivers/net/gve/base/gve_adminq.c | 19 +++++++++\n drivers/net/gve/base/gve_adminq.h | 49 ++++++++++++++++++++++-\n drivers/net/gve/base/gve_osdep.h  | 34 ++++++++++++++++\n drivers/net/gve/gve_ethdev.c      | 66 +++++++++++++++++++++++++------\n drivers/net/gve/gve_ethdev.h      |  1 +\n drivers/net/gve/gve_version.c     | 14 +++++++\n drivers/net/gve/gve_version.h     | 25 ++++++++++++\n drivers/net/gve/meson.build       |  1 +\n 9 files changed, 197 insertions(+), 15 deletions(-)\n create mode 100644 drivers/net/gve/gve_version.c\n create mode 100644 drivers/net/gve/gve_version.h",
    "diff": "diff --git a/drivers/net/gve/base/gve.h b/drivers/net/gve/base/gve.h\nindex 22d175910d..52ffc057a2 100644\n--- a/drivers/net/gve/base/gve.h\n+++ b/drivers/net/gve/base/gve.h\n@@ -9,9 +9,6 @@\n #include \"gve_desc.h\"\n #include \"gve_desc_dqo.h\"\n \n-#define GVE_VERSION\t\t\"1.3.0\"\n-#define GVE_VERSION_PREFIX\t\"GVE-\"\n-\n #ifndef GOOGLE_VENDOR_ID\n #define GOOGLE_VENDOR_ID\t0x1ae0\n #endif\ndiff --git a/drivers/net/gve/base/gve_adminq.c b/drivers/net/gve/base/gve_adminq.c\nindex 650d520e3d..380bccf18a 100644\n--- a/drivers/net/gve/base/gve_adminq.c\n+++ b/drivers/net/gve/base/gve_adminq.c\n@@ -401,6 +401,9 @@ static int gve_adminq_issue_cmd(struct gve_priv *priv,\n \tcase GVE_ADMINQ_GET_PTYPE_MAP:\n \t\tpriv->adminq_get_ptype_map_cnt++;\n \t\tbreak;\n+\tcase GVE_ADMINQ_VERIFY_DRIVER_COMPATIBILITY:\n+\t\tpriv->adminq_verify_driver_compatibility_cnt++;\n+\t\tbreak;\n \tdefault:\n \t\tPMD_DRV_LOG(ERR, \"unknown AQ command opcode %d\", opcode);\n \t}\n@@ -859,6 +862,22 @@ int gve_adminq_report_stats(struct gve_priv *priv, u64 stats_report_len,\n \treturn gve_adminq_execute_cmd(priv, &cmd);\n }\n \n+int gve_adminq_verify_driver_compatibility(struct gve_priv *priv,\n+\t\t\t\t\t   u64 driver_info_len,\n+\t\t\t\t\t   dma_addr_t driver_info_addr)\n+{\n+\tunion gve_adminq_command cmd;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.opcode = cpu_to_be32(GVE_ADMINQ_VERIFY_DRIVER_COMPATIBILITY);\n+\tcmd.verify_driver_compatibility = (struct gve_adminq_verify_driver_compatibility) {\n+\t\t.driver_info_len = cpu_to_be64(driver_info_len),\n+\t\t.driver_info_addr = cpu_to_be64(driver_info_addr),\n+\t};\n+\n+\treturn gve_adminq_execute_cmd(priv, &cmd);\n+}\n+\n int gve_adminq_report_link_speed(struct gve_priv *priv)\n {\n \tstruct gve_dma_mem link_speed_region_dma_mem;\ndiff --git a/drivers/net/gve/base/gve_adminq.h b/drivers/net/gve/base/gve_adminq.h\nindex 05550119de..89722eef7a 100644\n--- a/drivers/net/gve/base/gve_adminq.h\n+++ b/drivers/net/gve/base/gve_adminq.h\n@@ -1,6 +1,6 @@\n /* SPDX-License-Identifier: MIT\n  * Google Virtual Ethernet (gve) driver\n- * Copyright (C) 2015-2022 Google, Inc.\n+ * Copyright (C) 2015-2023 Google, Inc.\n  */\n \n #ifndef _GVE_ADMINQ_H\n@@ -23,6 +23,7 @@ enum gve_adminq_opcodes {\n \tGVE_ADMINQ_REPORT_STATS\t\t\t= 0xC,\n \tGVE_ADMINQ_REPORT_LINK_SPEED\t\t= 0xD,\n \tGVE_ADMINQ_GET_PTYPE_MAP\t\t= 0xE,\n+\tGVE_ADMINQ_VERIFY_DRIVER_COMPATIBILITY\t= 0xF,\n };\n \n /* Admin queue status codes */\n@@ -146,6 +147,47 @@ enum gve_sup_feature_mask {\n \n #define GVE_DEV_OPT_LEN_GQI_RAW_ADDRESSING 0x0\n \n+enum gve_driver_capbility {\n+\tgve_driver_capability_gqi_qpl = 0,\n+\tgve_driver_capability_gqi_rda = 1,\n+\tgve_driver_capability_dqo_qpl = 2, /* reserved for future use */\n+\tgve_driver_capability_dqo_rda = 3,\n+};\n+\n+#define GVE_CAP1(a) BIT((int)a)\n+#define GVE_CAP2(a) BIT(((int)a) - 64)\n+#define GVE_CAP3(a) BIT(((int)a) - 128)\n+#define GVE_CAP4(a) BIT(((int)a) - 192)\n+\n+#define GVE_DRIVER_CAPABILITY_FLAGS1 \\\n+\t(GVE_CAP1(gve_driver_capability_gqi_qpl) | \\\n+\t GVE_CAP1(gve_driver_capability_gqi_rda) | \\\n+\t GVE_CAP1(gve_driver_capability_dqo_rda))\n+\n+#define GVE_DRIVER_CAPABILITY_FLAGS2 0x0\n+#define GVE_DRIVER_CAPABILITY_FLAGS3 0x0\n+#define GVE_DRIVER_CAPABILITY_FLAGS4 0x0\n+\n+struct gve_driver_info {\n+\tu8 os_type;\t/* 0x05 = DPDK */\n+\tu8 driver_major;\n+\tu8 driver_minor;\n+\tu8 driver_sub;\n+\t__be32 os_version_major;\n+\t__be32 os_version_minor;\n+\t__be32 os_version_sub;\n+\t__be64 driver_capability_flags[4];\n+\tu8 os_version_str1[OS_VERSION_STRLEN];\n+\tu8 os_version_str2[OS_VERSION_STRLEN];\n+};\n+\n+struct gve_adminq_verify_driver_compatibility {\n+\t__be64 driver_info_len;\n+\t__be64 driver_info_addr;\n+};\n+\n+GVE_CHECK_STRUCT_LEN(16,  gve_adminq_verify_driver_compatibility);\n+\n struct gve_adminq_configure_device_resources {\n \t__be64 counter_array;\n \t__be64 irq_db_addr;\n@@ -345,6 +387,8 @@ union gve_adminq_command {\n \t\t\tstruct gve_adminq_report_stats report_stats;\n \t\t\tstruct gve_adminq_report_link_speed report_link_speed;\n \t\t\tstruct gve_adminq_get_ptype_map get_ptype_map;\n+\t\t\tstruct gve_adminq_verify_driver_compatibility\n+\t\t\t\t\t\tverify_driver_compatibility;\n \t\t};\n \t};\n \tu8 reserved[64];\n@@ -377,5 +421,8 @@ int gve_adminq_report_link_speed(struct gve_priv *priv);\n struct gve_ptype_lut;\n int gve_adminq_get_ptype_map_dqo(struct gve_priv *priv,\n \t\t\t\t struct gve_ptype_lut *ptype_lut);\n+int gve_adminq_verify_driver_compatibility(struct gve_priv *priv,\n+\t\t\t\t\t   u64 driver_info_len,\n+\t\t\t\t\t   dma_addr_t driver_info_addr);\n \n #endif /* _GVE_ADMINQ_H */\ndiff --git a/drivers/net/gve/base/gve_osdep.h b/drivers/net/gve/base/gve_osdep.h\nindex 71759d254f..e642c9557e 100644\n--- a/drivers/net/gve/base/gve_osdep.h\n+++ b/drivers/net/gve/base/gve_osdep.h\n@@ -21,9 +21,14 @@\n #include <rte_malloc.h>\n #include <rte_memcpy.h>\n #include <rte_memzone.h>\n+#include <rte_version.h>\n \n #include \"../gve_logs.h\"\n \n+#ifdef __linux__\n+#include <sys/utsname.h>\n+#endif\n+\n typedef uint8_t u8;\n typedef uint16_t u16;\n typedef uint32_t u32;\n@@ -73,6 +78,12 @@ typedef rte_iova_t dma_addr_t;\n \n #define msleep(ms)\t\trte_delay_ms(ms)\n \n+#define OS_VERSION_STRLEN 128\n+struct os_version_string {\n+\tchar os_version_str1[OS_VERSION_STRLEN];\n+\tchar os_version_str2[OS_VERSION_STRLEN];\n+};\n+\n /* These macros are used to generate compilation errors if a struct/union\n  * is not exactly the correct length. It gives a divide by zero error if\n  * the struct/union is not of the correct size, otherwise it creates an\n@@ -82,6 +93,11 @@ typedef rte_iova_t dma_addr_t;\n \t{ gve_static_assert_##X = (n) / ((sizeof(struct X) == (n)) ? 1 : 0) }\n #define GVE_CHECK_UNION_LEN(n, X) enum gve_static_asset_enum_##X \\\n \t{ gve_static_assert_##X = (n) / ((sizeof(union X) == (n)) ? 1 : 0) }\n+#ifndef LINUX_VERSION_MAJOR\n+#define LINUX_VERSION_MAJOR (((LINUX_VERSION_CODE) >> 16) & 0xff)\n+#define LINUX_VERSION_SUBLEVEL (((LINUX_VERSION_CODE) >> 8) & 0xff)\n+#define LINUX_VERSION_PATCHLEVEL ((LINUX_VERSION_CODE) & 0xff)\n+#endif\n \n static __rte_always_inline u8\n readb(volatile void *addr)\n@@ -160,4 +176,22 @@ gve_free_dma_mem(struct gve_dma_mem *mem)\n \tmem->pa = 0;\n }\n \n+\n+static inline void\n+populate_driver_version_strings(struct os_version_string *os_version_str)\n+{\n+#ifdef __linux__\n+\tstruct utsname uts;\n+\tif (uname(&uts) >= 0) {\n+\t\t/* OS version */\n+\t\trte_strscpy(os_version_str->os_version_str1, uts.release,\n+\t\t\tsizeof(os_version_str->os_version_str1));\n+\t\t/* DPDK version */\n+\t\trte_strscpy(os_version_str->os_version_str2, uts.version,\n+\t\t\tsizeof(os_version_str->os_version_str2));\n+\t}\n+#endif\n+}\n+\n+\n #endif /* _GVE_OSDEP_H_ */\ndiff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c\nindex 2541738da1..0fed32fbe0 100644\n--- a/drivers/net/gve/gve_ethdev.c\n+++ b/drivers/net/gve/gve_ethdev.c\n@@ -5,21 +5,13 @@\n #include \"gve_ethdev.h\"\n #include \"base/gve_adminq.h\"\n #include \"base/gve_register.h\"\n-\n-const char gve_version_str[] = GVE_VERSION;\n-static const char gve_version_prefix[] = GVE_VERSION_PREFIX;\n+#include \"base/gve_osdep.h\"\n+#include \"gve_version.h\"\n \n static void\n gve_write_version(uint8_t *driver_version_register)\n {\n-\tconst char *c = gve_version_prefix;\n-\n-\twhile (*c) {\n-\t\twriteb(*c, driver_version_register);\n-\t\tc++;\n-\t}\n-\n-\tc = gve_version_str;\n+\tconst char *c = gve_version_string();\n \twhile (*c) {\n \t\twriteb(*c, driver_version_register);\n \t\tc++;\n@@ -314,6 +306,52 @@ gve_dev_close(struct rte_eth_dev *dev)\n \treturn err;\n }\n \n+static int\n+gve_verify_driver_compatibility(struct gve_priv *priv)\n+{\n+\tconst struct rte_memzone *driver_info_bus;\n+\tstruct gve_driver_info *driver_info;\n+\tint err;\n+\n+\tdriver_info_bus = rte_memzone_reserve_aligned(\"verify_driver_compatibility\",\n+\t\t\t\t\t\t      sizeof(struct gve_driver_info),\n+\t\t\t\t\t\t      rte_socket_id(),\n+\t\t\t\t\t\t      RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);\n+\tif (driver_info_bus == NULL) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Could not alloc memzone for driver compatibility\");\n+\t\treturn -ENOMEM;\n+\t}\n+\tdriver_info = (struct gve_driver_info *)driver_info_bus->addr;\n+\t*driver_info = (struct gve_driver_info) {\n+\t\t.os_type = 5, /* DPDK */\n+\t\t.driver_major = GVE_VERSION_MAJOR,\n+\t\t.driver_minor = GVE_VERSION_MINOR,\n+\t\t.driver_sub = GVE_VERSION_SUB,\n+\t\t.os_version_major = cpu_to_be32(DPDK_VERSION_MAJOR),\n+\t\t.os_version_minor = cpu_to_be32(DPDK_VERSION_MINOR),\n+\t\t.os_version_sub = cpu_to_be32(DPDK_VERSION_SUB),\n+\t\t.driver_capability_flags = {\n+\t\t\tcpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS1),\n+\t\t\tcpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS2),\n+\t\t\tcpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS3),\n+\t\t\tcpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS4),\n+\t\t},\n+\t};\n+\n+\tpopulate_driver_version_strings((struct os_version_string *)&driver_info->os_version_str1);\n+\n+\terr = gve_adminq_verify_driver_compatibility(priv,\n+\t\tsizeof(struct gve_driver_info), (dma_addr_t)driver_info_bus);\n+\n+\t/* It's ok if the device doesn't support this */\n+\tif (err == -EOPNOTSUPP)\n+\t\terr = 0;\n+\n+\trte_memzone_free(driver_info_bus);\n+\treturn err;\n+}\n+\n static int\n gve_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n {\n@@ -631,6 +669,12 @@ gve_init_priv(struct gve_priv *priv, bool skip_describe_device)\n \t\treturn err;\n \t}\n \n+\terr = gve_verify_driver_compatibility(priv);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not verify driver compatibility: err=%d\", err);\n+\t\tgoto free_adminq;\n+\t}\n+\n \tif (skip_describe_device)\n \t\tgoto setup_device;\n \ndiff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h\nindex 02b997312c..9e220cf4dc 100644\n--- a/drivers/net/gve/gve_ethdev.h\n+++ b/drivers/net/gve/gve_ethdev.h\n@@ -254,6 +254,7 @@ struct gve_priv {\n \tuint32_t adminq_report_stats_cnt;\n \tuint32_t adminq_report_link_speed_cnt;\n \tuint32_t adminq_get_ptype_map_cnt;\n+\tuint32_t adminq_verify_driver_compatibility_cnt;\n \n \tvolatile uint32_t state_flags;\n \ndiff --git a/drivers/net/gve/gve_version.c b/drivers/net/gve/gve_version.c\nnew file mode 100644\nindex 0000000000..7eaa689d90\n--- /dev/null\n+++ b/drivers/net/gve/gve_version.c\n@@ -0,0 +1,14 @@\n+/* SPDX-License-Identifier: MIT\n+ * Google Virtual Ethernet (gve) driver\n+ * Copyright (C) 2015-2023 Google, Inc.\n+ */\n+#include \"gve_version.h\"\n+\n+const char *gve_version_string(void)\n+{\n+\tstatic char gve_version[10];\n+\tsnprintf(gve_version, sizeof(gve_version), \"%s%d.%d.%d\",\n+\t\tGVE_VERSION_PREFIX, GVE_VERSION_MAJOR, GVE_VERSION_MINOR,\n+\t\tGVE_VERSION_SUB);\n+\treturn gve_version;\n+}\ndiff --git a/drivers/net/gve/gve_version.h b/drivers/net/gve/gve_version.h\nnew file mode 100644\nindex 0000000000..b1f626f95e\n--- /dev/null\n+++ b/drivers/net/gve/gve_version.h\n@@ -0,0 +1,25 @@\n+/* SPDX-License-Identifier: MIT\n+ * Google Virtual Ethernet (gve) driver\n+ * Copyright (C) 2015-2023 Google, Inc.\n+ */\n+\n+#ifndef _GVE_VERSION_H_\n+#define _GVE_VERSION_H_\n+\n+#include <rte_version.h>\n+\n+#define GVE_VERSION_PREFIX \"GVE-\"\n+#define GVE_VERSION_MAJOR 0\n+#define GVE_VERSION_MINOR 9\n+#define GVE_VERSION_SUB 0\n+\n+#define DPDK_VERSION_MAJOR (100 * RTE_VER_YEAR + RTE_VER_MONTH)\n+#define DPDK_VERSION_MINOR RTE_VER_MINOR\n+#define DPDK_VERSION_SUB RTE_VER_RELEASE\n+\n+\n+const char *\n+gve_version_string(void);\n+\n+\n+#endif /* GVE_VERSION_H */\ndiff --git a/drivers/net/gve/meson.build b/drivers/net/gve/meson.build\nindex 8caee3714b..9f10e98bf6 100644\n--- a/drivers/net/gve/meson.build\n+++ b/drivers/net/gve/meson.build\n@@ -14,5 +14,6 @@ sources = files(\n         'gve_rx_dqo.c',\n         'gve_tx_dqo.c',\n         'gve_ethdev.c',\n+        'gve_version.c',\n )\n includes += include_directories('base')\n",
    "prefixes": [
        "RFC",
        "v3",
        "10/10"
    ]
}