transobj.o vport.o sriov.o fs_cmd.o fs_core.o pci_irq.o \
fs_counters.o fs_ft_pool.o rl.o lag/debugfs.o lag/lag.o dev.o events.o wq.o lib/gid.o \
lib/devcom.o lib/pci_vsc.o lib/dm.o lib/fs_ttc.o diag/fs_tracepoint.o \
- diag/fw_tracer.o diag/crdump.o devlink.o diag/rsc_dump.o diag/reporter_vnic.o \
- fw_reset.o qos.o lib/tout.o lib/aso.o wc.o fs_pool.o lib/nv_param.o
+ diag/fw_tracer.o diag/crdump.o devlink.o sh_devlink.o diag/rsc_dump.o \
+ diag/reporter_vnic.o fw_reset.o qos.o lib/tout.o lib/aso.o wc.o fs_pool.o \
+ lib/nv_param.o
#
# Netdev basic
#include "mlx5_irq.h"
#include "hwmon.h"
#include "lag/lag.h"
+#include "sh_devlink.h"
MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) core driver");
int err;
devl_lock(devlink);
+ if (dev->shd) {
+ err = devl_nested_devlink_set(dev->shd, devlink);
+ if (err)
+ goto unlock;
+ }
devl_register(devlink);
err = mlx5_init_one_devl_locked(dev);
if (err)
devl_unregister(devlink);
+unlock:
devl_unlock(devlink);
return err;
}
goto pci_init_err;
}
+ err = mlx5_shd_init(dev);
+ if (err) {
+ mlx5_core_err(dev, "mlx5_shd_init failed with error code %d\n",
+ err);
+ goto shd_init_err;
+ }
+
err = mlx5_init_one(dev);
if (err) {
mlx5_core_err(dev, "mlx5_init_one failed with error code %d\n",
return 0;
err_init_one:
+ mlx5_shd_uninit(dev);
+shd_init_err:
mlx5_pci_close(dev);
pci_init_err:
mlx5_mdev_uninit(dev);
mlx5_drain_health_wq(dev);
mlx5_sriov_disable(pdev, false);
mlx5_uninit_one(dev);
+ mlx5_shd_uninit(dev);
mlx5_pci_close(dev);
mlx5_mdev_uninit(dev);
mlx5_adev_idx_free(dev->priv.adev_idx);
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/* Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
+
+#include <linux/mlx5/driver.h>
+#include <net/devlink.h>
+
+#include "sh_devlink.h"
+
+static const struct devlink_ops mlx5_shd_ops = {
+};
+
+int mlx5_shd_init(struct mlx5_core_dev *dev)
+{
+ u8 *vpd_data __free(kfree) = NULL;
+ struct pci_dev *pdev = dev->pdev;
+ unsigned int vpd_size, kw_len;
+ struct devlink *devlink;
+ char *sn, *end;
+ int start;
+ int err;
+
+ if (!mlx5_core_is_pf(dev))
+ return 0;
+
+ vpd_data = pci_vpd_alloc(pdev, &vpd_size);
+ if (IS_ERR(vpd_data)) {
+ err = PTR_ERR(vpd_data);
+ return err == -ENODEV ? 0 : err;
+ }
+ start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size, "V3", &kw_len);
+ if (start < 0) {
+ /* Fall-back to SN for older devices. */
+ start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size,
+ PCI_VPD_RO_KEYWORD_SERIALNO, &kw_len);
+ if (start < 0)
+ return -ENOENT;
+ }
+ sn = kstrndup(vpd_data + start, kw_len, GFP_KERNEL);
+ if (!sn)
+ return -ENOMEM;
+ /* Firmware may return spaces at the end of the string, strip it. */
+ end = strchrnul(sn, ' ');
+ *end = '\0';
+
+ /* Get or create shared devlink instance */
+ devlink = devlink_shd_get(sn, &mlx5_shd_ops, 0, pdev->dev.driver);
+ kfree(sn);
+ if (!devlink)
+ return -ENOMEM;
+
+ dev->shd = devlink;
+ return 0;
+}
+
+void mlx5_shd_uninit(struct mlx5_core_dev *dev)
+{
+ if (!dev->shd)
+ return;
+
+ devlink_shd_put(dev->shd);
+}
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
+
+#ifndef __MLX5_SH_DEVLINK_H__
+#define __MLX5_SH_DEVLINK_H__
+
+#include <linux/mlx5/driver.h>
+
+int mlx5_shd_init(struct mlx5_core_dev *dev);
+void mlx5_shd_uninit(struct mlx5_core_dev *dev);
+
+#endif /* __MLX5_SH_DEVLINK_H__ */