pds_core: devlink params for enabling VIF support
authorShannon Nelson <shannon.nelson@amd.com>
Wed, 19 Apr 2023 17:04:24 +0000 (10:04 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 21 Apr 2023 07:29:13 +0000 (08:29 +0100)
Add the devlink parameter switches so the user can enable
the features supported by the VFs.  The only feature supported
at the moment is vDPA.

Example:
    devlink dev param set pci/0000:2b:00.0 \
    name enable_vnet cmode runtime value true

Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/networking/device_drivers/ethernet/amd/pds_core.rst
drivers/net/ethernet/amd/pds_core/core.h
drivers/net/ethernet/amd/pds_core/devlink.c
drivers/net/ethernet/amd/pds_core/main.c

index 932ac03..b9f310d 100644 (file)
@@ -73,6 +73,25 @@ The ``pds_core`` driver reports the following versions
      - fixed
      - The revision of the ASIC for this device
 
+Parameters
+==========
+
+The ``pds_core`` driver implements the following generic
+parameters for controlling the functionality to be made available
+as auxiliary_bus devices.
+
+.. list-table:: Generic parameters implemented
+   :widths: 5 5 8 82
+
+   * - Name
+     - Mode
+     - Type
+     - Description
+   * - ``enable_vnet``
+     - runtime
+     - Boolean
+     - Enables vDPA functionality through an auxiliary_bus device
+
 Firmware Management
 ===================
 
index 36099d3..9e01a9e 100644 (file)
@@ -251,6 +251,13 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
 int pdsc_dl_flash_update(struct devlink *dl,
                         struct devlink_flash_update_params *params,
                         struct netlink_ext_ack *extack);
+int pdsc_dl_enable_get(struct devlink *dl, u32 id,
+                      struct devlink_param_gset_ctx *ctx);
+int pdsc_dl_enable_set(struct devlink *dl, u32 id,
+                      struct devlink_param_gset_ctx *ctx);
+int pdsc_dl_enable_validate(struct devlink *dl, u32 id,
+                           union devlink_param_value val,
+                           struct netlink_ext_ack *extack);
 
 void __iomem *pdsc_map_dbpage(struct pdsc *pdsc, int page_num);
 
index f91d65c..9c6b365 100644 (file)
@@ -2,6 +2,79 @@
 /* Copyright(c) 2023 Advanced Micro Devices, Inc */
 
 #include "core.h"
+#include <linux/pds/pds_auxbus.h>
+
+static struct
+pdsc_viftype *pdsc_dl_find_viftype_by_id(struct pdsc *pdsc,
+                                        enum devlink_param_type dl_id)
+{
+       int vt;
+
+       for (vt = 0; vt < PDS_DEV_TYPE_MAX; vt++) {
+               if (pdsc->viftype_status[vt].dl_id == dl_id)
+                       return &pdsc->viftype_status[vt];
+       }
+
+       return NULL;
+}
+
+int pdsc_dl_enable_get(struct devlink *dl, u32 id,
+                      struct devlink_param_gset_ctx *ctx)
+{
+       struct pdsc *pdsc = devlink_priv(dl);
+       struct pdsc_viftype *vt_entry;
+
+       vt_entry = pdsc_dl_find_viftype_by_id(pdsc, id);
+       if (!vt_entry)
+               return -ENOENT;
+
+       ctx->val.vbool = vt_entry->enabled;
+
+       return 0;
+}
+
+int pdsc_dl_enable_set(struct devlink *dl, u32 id,
+                      struct devlink_param_gset_ctx *ctx)
+{
+       struct pdsc *pdsc = devlink_priv(dl);
+       struct pdsc_viftype *vt_entry;
+       int err = 0;
+       int vf_id;
+
+       vt_entry = pdsc_dl_find_viftype_by_id(pdsc, id);
+       if (!vt_entry || !vt_entry->supported)
+               return -EOPNOTSUPP;
+
+       if (vt_entry->enabled == ctx->val.vbool)
+               return 0;
+
+       vt_entry->enabled = ctx->val.vbool;
+       for (vf_id = 0; vf_id < pdsc->num_vfs; vf_id++) {
+               struct pdsc *vf = pdsc->vfs[vf_id].vf;
+
+               err = ctx->val.vbool ? pdsc_auxbus_dev_add(vf, pdsc) :
+                                      pdsc_auxbus_dev_del(vf, pdsc);
+       }
+
+       return err;
+}
+
+int pdsc_dl_enable_validate(struct devlink *dl, u32 id,
+                           union devlink_param_value val,
+                           struct netlink_ext_ack *extack)
+{
+       struct pdsc *pdsc = devlink_priv(dl);
+       struct pdsc_viftype *vt_entry;
+
+       vt_entry = pdsc_dl_find_viftype_by_id(pdsc, id);
+       if (!vt_entry || !vt_entry->supported)
+               return -EOPNOTSUPP;
+
+       if (!pdsc->viftype_status[vt_entry->vif_id].supported)
+               return -ENODEV;
+
+       return 0;
+}
 
 int pdsc_dl_flash_update(struct devlink *dl,
                         struct devlink_flash_update_params *params,
index b848f33..e2d14b1 100644 (file)
@@ -199,6 +199,14 @@ static const struct devlink_health_reporter_ops pdsc_fw_reporter_ops = {
        .diagnose = pdsc_fw_reporter_diagnose,
 };
 
+static const struct devlink_param pdsc_dl_params[] = {
+       DEVLINK_PARAM_GENERIC(ENABLE_VNET,
+                             BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+                             pdsc_dl_enable_get,
+                             pdsc_dl_enable_set,
+                             pdsc_dl_enable_validate),
+};
+
 #define PDSC_WQ_NAME_LEN 24
 
 static int pdsc_init_pf(struct pdsc *pdsc)
@@ -246,13 +254,19 @@ static int pdsc_init_pf(struct pdsc *pdsc)
 
        dl = priv_to_devlink(pdsc);
        devl_lock(dl);
+       err = devl_params_register(dl, pdsc_dl_params,
+                                  ARRAY_SIZE(pdsc_dl_params));
+       if (err) {
+               dev_warn(pdsc->dev, "Failed to register devlink params: %pe\n",
+                        ERR_PTR(err));
+               goto err_out_unlock_dl;
+       }
 
        hr = devl_health_reporter_create(dl, &pdsc_fw_reporter_ops, 0, pdsc);
        if (IS_ERR(hr)) {
                dev_warn(pdsc->dev, "Failed to create fw reporter: %pe\n", hr);
                err = PTR_ERR(hr);
-               devl_unlock(dl);
-               goto err_out_stop;
+               goto err_out_unreg_params;
        }
        pdsc->fw_reporter = hr;
 
@@ -264,7 +278,11 @@ static int pdsc_init_pf(struct pdsc *pdsc)
 
        return 0;
 
-err_out_stop:
+err_out_unreg_params:
+       devl_params_unregister(dl, pdsc_dl_params,
+                              ARRAY_SIZE(pdsc_dl_params));
+err_out_unlock_dl:
+       devl_unlock(dl);
        pdsc_stop(pdsc);
 err_out_teardown:
        pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING);
@@ -373,9 +391,13 @@ static void pdsc_remove(struct pci_dev *pdev)
        dl = priv_to_devlink(pdsc);
        devl_lock(dl);
        devl_unregister(dl);
-       if (pdsc->fw_reporter) {
-               devl_health_reporter_destroy(pdsc->fw_reporter);
-               pdsc->fw_reporter = NULL;
+       if (!pdev->is_virtfn) {
+               if (pdsc->fw_reporter) {
+                       devl_health_reporter_destroy(pdsc->fw_reporter);
+                       pdsc->fw_reporter = NULL;
+               }
+               devl_params_unregister(dl, pdsc_dl_params,
+                                      ARRAY_SIZE(pdsc_dl_params));
        }
        devl_unlock(dl);