[PATCH net-next v3 07/15] gve: introduce gve_adminq_get_device_properties()
Harshitha Ramamurthy <[email protected]> Mon, 3 Aug 2026 18:46:22 +0000
| Newsgroups | org.kernel.vger.bpf,org.kernel.vger.linux-kernel,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
Move driver compatibility verification from gve_main.c to gve_adminq.c as gve_adminq_verify_driver_compatibility() and update gve_init_priv() to call it. Introduce gve_adminq_get_device_properties() which executes the first two Adminq commands: VERIFY_DRIVER_COMPATIBILITY and DESCRIBE_DEVICE so that this can be called during initialization. Mark it as unused since it's going to be hooked into initialization in the following patch. This is just code movement, no functional change. Reviewed-by: Willem de Bruijn <[email protected]> Reviewed-by: Jordan Rhee <[email protected]> Signed-off-by: Harshitha Ramamurthy <[email protected]> --- Changes v3: - move patch down so that the function is introduced just before usage - mark function as maybe_unused - update commit message drivers/net/ethernet/google/gve/gve.h | 2 + drivers/net/ethernet/google/gve/gve_adminq.c | 66 ++++++++++++++++++-- drivers/net/ethernet/google/gve/gve_adminq.h | 5 +- drivers/net/ethernet/google/gve/gve_main.c | 46 +------------- 4 files changed, 65 insertions(+), 54 deletions(-) diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h index 1bc5e32b6618..d6e7ab0649ac 100644 --- a/drivers/net/ethernet/google/gve/gve.h +++ b/drivers/net/ethernet/google/gve/gve.h @@ -16,6 +16,8 @@ #include <linux/timer.h> #include <linux/ptp_clock_kernel.h> #include <linux/u64_stats_sync.h> +#include <linux/utsname.h> +#include <linux/version.h> #include <net/page_pool/helpers.h> #include <net/xdp.h> diff --git a/drivers/net/ethernet/google/gve/gve_adminq.c b/drivers/net/ethernet/google/gve/gve_adminq.c index 1d9ae601cdeb..66a3e774b7c4 100644 --- a/drivers/net/ethernet/google/gve/gve_adminq.c +++ b/drivers/net/ethernet/google/gve/gve_adminq.c @@ -1143,6 +1143,27 @@ int gve_adminq_describe_device(struct gve_priv *priv) return err; } +int __maybe_unused gve_adminq_get_device_properties(struct gve_priv *priv) +{ + int err; + + err = gve_adminq_verify_driver_compatibility(priv); + if (err) { + dev_err(&priv->pdev->dev, + "Could not verify driver compatibility: err=%d\n", err); + return err; + } + + /* Get the initial information we need from the device */ + err = gve_adminq_describe_device(priv); + if (err) { + dev_err(&priv->pdev->dev, + "Could not get device information: err=%d\n", err); + return err; + } + return 0; +} + int gve_adminq_register_page_list(struct gve_priv *priv, struct gve_queue_page_list *qpl) { @@ -1205,20 +1226,53 @@ int gve_adminq_report_stats(struct gve_priv *priv, u64 stats_report_len, return gve_adminq_execute_cmd(priv, &cmd); } -int gve_adminq_verify_driver_compatibility(struct gve_priv *priv, - u64 driver_info_len, - dma_addr_t driver_info_addr) +int gve_adminq_verify_driver_compatibility(struct gve_priv *priv) { + struct gve_driver_info *driver_info; union gve_adminq_command cmd; + dma_addr_t driver_info_bus; + int err; + + driver_info = dma_alloc_coherent(&priv->pdev->dev, + sizeof(struct gve_driver_info), + &driver_info_bus, GFP_KERNEL); + if (!driver_info) + return -ENOMEM; + + *driver_info = (struct gve_driver_info) { + .os_type = 1, /* Linux */ + .os_version_major = cpu_to_be32(LINUX_VERSION_MAJOR), + .os_version_minor = cpu_to_be32(LINUX_VERSION_SUBLEVEL), + .os_version_sub = cpu_to_be32(LINUX_VERSION_PATCHLEVEL), + .driver_capability_flags = { + cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS1), + cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS2), + cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS3), + cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS4), + }, + }; + strscpy(driver_info->os_version_str1, utsname()->release, + sizeof(driver_info->os_version_str1)); + strscpy(driver_info->os_version_str2, utsname()->version, + sizeof(driver_info->os_version_str2)); memset(&cmd, 0, sizeof(cmd)); cmd.opcode = cpu_to_be32(GVE_ADMINQ_VERIFY_DRIVER_COMPATIBILITY); cmd.verify_driver_compatibility = (struct gve_adminq_verify_driver_compatibility) { - .driver_info_len = cpu_to_be64(driver_info_len), - .driver_info_addr = cpu_to_be64(driver_info_addr), + .driver_info_len = cpu_to_be64(sizeof(struct gve_driver_info)), + .driver_info_addr = cpu_to_be64(driver_info_bus), }; - return gve_adminq_execute_cmd(priv, &cmd); + err = gve_adminq_execute_cmd(priv, &cmd); + + /* It's ok if the device doesn't support this */ + if (err == -EOPNOTSUPP) + err = 0; + + dma_free_coherent(&priv->pdev->dev, + sizeof(struct gve_driver_info), + driver_info, driver_info_bus); + return err; } int gve_adminq_report_link_speed(struct gve_priv *priv) diff --git a/drivers/net/ethernet/google/gve/gve_adminq.h b/drivers/net/ethernet/google/gve/gve_adminq.h index 52fe4a9f7b87..ac3ef9fd8d24 100644 --- a/drivers/net/ethernet/google/gve/gve_adminq.h +++ b/drivers/net/ethernet/google/gve/gve_adminq.h @@ -640,9 +640,8 @@ int gve_adminq_register_page_list(struct gve_priv *priv, int gve_adminq_unregister_page_list(struct gve_priv *priv, u32 page_list_id); int gve_adminq_report_stats(struct gve_priv *priv, u64 stats_report_len, dma_addr_t stats_report_addr, u64 interval); -int gve_adminq_verify_driver_compatibility(struct gve_priv *priv, - u64 driver_info_len, - dma_addr_t driver_info_addr); +int gve_adminq_verify_driver_compatibility(struct gve_priv *priv); +int gve_adminq_get_device_properties(struct gve_priv *priv); int gve_adminq_report_link_speed(struct gve_priv *priv); int gve_adminq_add_flow_rule(struct gve_priv *priv, struct gve_adminq_flow_rule *rule, u32 loc); int gve_adminq_del_flow_rule(struct gve_priv *priv, u32 loc); diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index ce55f845a6f9..0d308bde52c8 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -17,7 +17,6 @@ #include <linux/sched.h> #include <linux/timer.h> #include <linux/workqueue.h> -#include <linux/utsname.h> #include <linux/version.h> #include <net/netdev_queues.h> #include <net/sch_generic.h> @@ -41,49 +40,6 @@ char gve_driver_name[] = "gve"; const char gve_version_str[] = GVE_VERSION; static const char gve_version_prefix[] = GVE_VERSION_PREFIX; -static int gve_verify_driver_compatibility(struct gve_priv *priv) -{ - int err; - struct gve_driver_info *driver_info; - dma_addr_t driver_info_bus; - - driver_info = dma_alloc_coherent(&priv->pdev->dev, - sizeof(struct gve_driver_info), - &driver_info_bus, GFP_KERNEL); - if (!driver_info) - return -ENOMEM; - - *driver_info = (struct gve_driver_info) { - .os_type = 1, /* Linux */ - .os_version_major = cpu_to_be32(LINUX_VERSION_MAJOR), - .os_version_minor = cpu_to_be32(LINUX_VERSION_SUBLEVEL), - .os_version_sub = cpu_to_be32(LINUX_VERSION_PATCHLEVEL), - .driver_capability_flags = { - cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS1), - cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS2), - cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS3), - cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS4), - }, - }; - strscpy(driver_info->os_version_str1, utsname()->release, - sizeof(driver_info->os_version_str1)); - strscpy(driver_info->os_version_str2, utsname()->version, - sizeof(driver_info->os_version_str2)); - - err = gve_adminq_verify_driver_compatibility(priv, - sizeof(struct gve_driver_info), - driver_info_bus); - - /* It's ok if the device doesn't support this */ - if (err == -EOPNOTSUPP) - err = 0; - - dma_free_coherent(&priv->pdev->dev, - sizeof(struct gve_driver_info), - driver_info, driver_info_bus); - return err; -} - static netdev_features_t gve_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) @@ -2478,7 +2434,7 @@ static int gve_init_priv(struct gve_priv *priv, bool skip_describe_device) return err; } - err = gve_verify_driver_compatibility(priv); + err = gve_adminq_verify_driver_compatibility(priv); if (err) { dev_err(&priv->pdev->dev, "Could not verify driver compatibility: err=%d\n", err); -- 2.55.0.571.g244d577d93-goog