qed: Add qed devlink parameters table
authorMichal Kalderon <michal.kalderon@marvell.com>
Sun, 26 May 2019 12:22:26 +0000 (15:22 +0300)
committerDavid S. Miller <davem@davemloft.net>
Sun, 26 May 2019 20:04:12 +0000 (13:04 -0700)
The table currently contains a single parameter for
configuring whether iWARP should be enabled on a 100g
device. Enabling iWARP on a 100g device impacts L2
performance and is therefore not enabled by default.

Signed-off-by: Ariel Elior <ariel.elior@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qed/qed.h
drivers/net/ethernet/qlogic/qed/qed_main.c

index e8e8d7c4af5aa50907b0f0e118e9e65bff8dd341..89fe091c958d5546903cc62ecd0b02b9f6048f52 100644 (file)
@@ -863,6 +863,9 @@ struct qed_dev {
        u32 rdma_max_inline;
        u32 rdma_max_srq_sge;
        u16 tunn_feature_mask;
+
+       struct devlink                  *dl;
+       bool                            iwarp_cmt;
 };
 
 #define NUM_OF_VFS(dev)         (QED_IS_BB(dev) ? MAX_NUM_VFS_BB \
index 7f19fefe0d79dafb5020be370dee68ec3843634b..829dd60ab9370e3a1441b2f57c23478ffe4adcec 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/crc32.h>
 #include <linux/qed/qed_if.h>
 #include <linux/qed/qed_ll2_if.h>
+#include <net/devlink.h>
 
 #include "qed.h"
 #include "qed_sriov.h"
@@ -342,6 +343,107 @@ static int qed_set_power_state(struct qed_dev *cdev, pci_power_t state)
        return 0;
 }
 
+struct qed_devlink {
+       struct qed_dev *cdev;
+};
+
+enum qed_devlink_param_id {
+       QED_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
+       QED_DEVLINK_PARAM_ID_IWARP_CMT,
+};
+
+static int qed_dl_param_get(struct devlink *dl, u32 id,
+                           struct devlink_param_gset_ctx *ctx)
+{
+       struct qed_devlink *qed_dl;
+       struct qed_dev *cdev;
+
+       qed_dl = devlink_priv(dl);
+       cdev = qed_dl->cdev;
+       ctx->val.vbool = cdev->iwarp_cmt;
+
+       return 0;
+}
+
+static int qed_dl_param_set(struct devlink *dl, u32 id,
+                           struct devlink_param_gset_ctx *ctx)
+{
+       struct qed_devlink *qed_dl;
+       struct qed_dev *cdev;
+
+       qed_dl = devlink_priv(dl);
+       cdev = qed_dl->cdev;
+       cdev->iwarp_cmt = ctx->val.vbool;
+
+       return 0;
+}
+
+static const struct devlink_param qed_devlink_params[] = {
+       DEVLINK_PARAM_DRIVER(QED_DEVLINK_PARAM_ID_IWARP_CMT,
+                            "iwarp_cmt", DEVLINK_PARAM_TYPE_BOOL,
+                            BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+                            qed_dl_param_get, qed_dl_param_set, NULL),
+};
+
+static const struct devlink_ops qed_dl_ops;
+
+static int qed_devlink_register(struct qed_dev *cdev)
+{
+       union devlink_param_value value;
+       struct qed_devlink *qed_dl;
+       struct devlink *dl;
+       int rc;
+
+       dl = devlink_alloc(&qed_dl_ops, sizeof(*qed_dl));
+       if (!dl)
+               return -ENOMEM;
+
+       qed_dl = devlink_priv(dl);
+
+       cdev->dl = dl;
+       qed_dl->cdev = cdev;
+
+       rc = devlink_register(dl, &cdev->pdev->dev);
+       if (rc)
+               goto err_free;
+
+       rc = devlink_params_register(dl, qed_devlink_params,
+                                    ARRAY_SIZE(qed_devlink_params));
+       if (rc)
+               goto err_unregister;
+
+       value.vbool = false;
+       devlink_param_driverinit_value_set(dl,
+                                          QED_DEVLINK_PARAM_ID_IWARP_CMT,
+                                          value);
+
+       devlink_params_publish(dl);
+       cdev->iwarp_cmt = false;
+
+       return 0;
+
+err_unregister:
+       devlink_unregister(dl);
+
+err_free:
+       cdev->dl = NULL;
+       devlink_free(dl);
+
+       return rc;
+}
+
+static void qed_devlink_unregister(struct qed_dev *cdev)
+{
+       if (!cdev->dl)
+               return;
+
+       devlink_params_unregister(cdev->dl, qed_devlink_params,
+                                 ARRAY_SIZE(qed_devlink_params));
+
+       devlink_unregister(cdev->dl);
+       devlink_free(cdev->dl);
+}
+
 /* probing */
 static struct qed_dev *qed_probe(struct pci_dev *pdev,
                                 struct qed_probe_params *params)
@@ -370,6 +472,12 @@ static struct qed_dev *qed_probe(struct pci_dev *pdev,
        }
        DP_INFO(cdev, "PCI init completed successfully\n");
 
+       rc = qed_devlink_register(cdev);
+       if (rc) {
+               DP_INFO(cdev, "Failed to register devlink.\n");
+               goto err2;
+       }
+
        rc = qed_hw_prepare(cdev, QED_PCI_DEFAULT);
        if (rc) {
                DP_ERR(cdev, "hw prepare failed\n");
@@ -399,6 +507,8 @@ static void qed_remove(struct qed_dev *cdev)
 
        qed_set_power_state(cdev, PCI_D3hot);
 
+       qed_devlink_unregister(cdev);
+
        qed_free_cdev(cdev);
 }