e286869b24
- Why I did it 1. Update Mellanox HW-MGMT package to newer version V.7.0030.1011 2. Replace the SONiC PMON Thermal control algorithm with the one inside the HW-MGMT package on all Nvidia platforms 3. Support Spectrum-4 systems - How I did it 1. Update the HW-MGMT package version number and submodule pointer 2. Remove the thermal control algorithm implementation from Mellanox platform API 3. Revise the patch to HW-MGMT package which will disable HW-MGMT from running on SIMX 4. Update the downstream kernel patch list Signed-off-by: Kebo Liu <kebol@nvidia.com>
341 lines
9.7 KiB
Diff
341 lines
9.7 KiB
Diff
From 9b0e85d738a43f737ed233e649fcda22b573d372 Mon Sep 17 00:00:00 2001
|
|
From: Shravan Kumar Ramani <shravankr@nvidia.com>
|
|
Date: Tue, 5 Jul 2022 12:43:45 -0400
|
|
Subject: [PATCH backport 5.10 22/63] UBUNTU: SAUCE: platform/mellanox: Add
|
|
mlxbf-livefish driver
|
|
|
|
BugLink: https://launchpad.net/bugs/1980761
|
|
|
|
This patch adds the mlxbf-livefish driver which supports update
|
|
of the HCA firmware when in livefish mode.
|
|
|
|
Signed-off-by: Shravan Kumar Ramani <shravankr@nvidia.com>
|
|
Signed-off-by: Ike Panhc <ike.pan@canonical.com>
|
|
---
|
|
drivers/platform/mellanox/Kconfig | 9 +
|
|
drivers/platform/mellanox/Makefile | 1 +
|
|
drivers/platform/mellanox/mlxbf-livefish.c | 279 +++++++++++++++++++++
|
|
3 files changed, 289 insertions(+)
|
|
create mode 100644 drivers/platform/mellanox/mlxbf-livefish.c
|
|
|
|
diff --git a/drivers/platform/mellanox/Kconfig b/drivers/platform/mellanox/Kconfig
|
|
index 946bc2375..a5231c23a 100644
|
|
--- a/drivers/platform/mellanox/Kconfig
|
|
+++ b/drivers/platform/mellanox/Kconfig
|
|
@@ -80,6 +80,15 @@ config MLXBF_BOOTCTL
|
|
to the userspace tools, to be used in conjunction with the eMMC
|
|
device driver to do necessary initial swap of the boot partition.
|
|
|
|
+config MLXBF_LIVEFISH
|
|
+ tristate "Mellanox BlueField livefish firmware update driver"
|
|
+ depends on ARM64
|
|
+ help
|
|
+ If you say yes to this option, support will added for the
|
|
+ mlxbf-livefish driver. This driver allows MFT tools to
|
|
+ update ConnectX HCA firmware on a Mellanox BlueField SoC
|
|
+ when it is in livefish mode.
|
|
+
|
|
config MLXBF_PMC
|
|
tristate "Mellanox BlueField Performance Monitoring Counters driver"
|
|
depends on ARM64
|
|
diff --git a/drivers/platform/mellanox/Makefile b/drivers/platform/mellanox/Makefile
|
|
index 046347d3a..7c6393ebe 100644
|
|
--- a/drivers/platform/mellanox/Makefile
|
|
+++ b/drivers/platform/mellanox/Makefile
|
|
@@ -8,6 +8,7 @@ obj-$(CONFIG_MLXBF_BOOTCTL) += mlxbf-bootctl.o
|
|
obj-$(CONFIG_MLXBF_PMC) += mlxbf-pmc.o
|
|
obj-$(CONFIG_MLXBF_TMFIFO) += mlxbf-tmfifo.o
|
|
obj-$(CONFIG_MLXBF_TRIO) += mlx-trio.o
|
|
+obj-$(CONFIG_MLXBF_LIVEFISH) += mlxbf-livefish.o
|
|
obj-$(CONFIG_MLXREG_HOTPLUG) += mlxreg-hotplug.o
|
|
obj-$(CONFIG_MLXREG_IO) += mlxreg-io.o
|
|
obj-$(CONFIG_MLXREG_LC) += mlxreg-lc.o
|
|
diff --git a/drivers/platform/mellanox/mlxbf-livefish.c b/drivers/platform/mellanox/mlxbf-livefish.c
|
|
new file mode 100644
|
|
index 000000000..c6150117d
|
|
--- /dev/null
|
|
+++ b/drivers/platform/mellanox/mlxbf-livefish.c
|
|
@@ -0,0 +1,279 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-only OR Linux-OpenIB
|
|
+
|
|
+/*
|
|
+ * Mellanox BlueField HCA firmware burning driver.
|
|
+ *
|
|
+ * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
|
|
+ *
|
|
+ * This driver supports burning firmware for the embedded HCA in the
|
|
+ * BlueField SoC. Typically firmware is burned through the PCI mlx5
|
|
+ * driver directly, but when the existing firmware is not yet installed
|
|
+ * or invalid, the PCI mlx5 driver has no endpoint to bind to, and we
|
|
+ * use this driver instead. It provides a character device that gives
|
|
+ * access to the same hardware registers at the same offsets as the
|
|
+ * mlx5 PCI configuration space does.
|
|
+ *
|
|
+ * The first 1 MB of the space is available through the TRIO HCA
|
|
+ * mapping. However, the efuse area (128 bytes at offset 0x1c1600) is
|
|
+ * not available through the HCA mapping, but is available by mapping
|
|
+ * the TYU via the RSHIM, so we make it virtually appear at the
|
|
+ * correct offset in this driver.
|
|
+ */
|
|
+
|
|
+#include <linux/acpi.h>
|
|
+#include <linux/errno.h>
|
|
+#include <linux/io.h>
|
|
+#include <linux/miscdevice.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/of.h>
|
|
+#include <linux/platform_device.h>
|
|
+#include <linux/uaccess.h>
|
|
+
|
|
+#define DRIVER_VERSION 2.0
|
|
+#define STRINGIFY(s) #s
|
|
+
|
|
+static size_t hca_size;
|
|
+static phys_addr_t hca_pa;
|
|
+static __iomem void *hca_va;
|
|
+
|
|
+#define TYU_SIZE 0x80UL
|
|
+#define TYU_OFFSET 0x1c1600
|
|
+static phys_addr_t tyu_pa;
|
|
+static __iomem void *tyu_va;
|
|
+
|
|
+#define MLXBF_LF_BF1 1
|
|
+#define MLXBF_LF_BF2 2
|
|
+static int chip_version;
|
|
+
|
|
+#define CRSPACE_SIZE (2 * 1024 * 1024)
|
|
+
|
|
+/*
|
|
+ * A valid I/O must be entirely within CR space and not extend into
|
|
+ * any unmapped areas of CR space. We don't truncate I/O that extends
|
|
+ * past the end of the CR space region (unlike the behavior of, for
|
|
+ * example, simple_read_from_buffer) but instead just call the whole
|
|
+ * I/O invalid. We also enforce 4-byte alignment for all I/O.
|
|
+ */
|
|
+static bool valid_range(loff_t offset, size_t len)
|
|
+{
|
|
+ if (offset % 4 != 0 || len % 4 != 0)
|
|
+ return false; /* unaligned */
|
|
+ if (offset >= 0 && offset + len <= hca_size)
|
|
+ return true; /* inside the HCA space */
|
|
+ if (offset >= TYU_OFFSET && offset + len <= TYU_OFFSET + TYU_SIZE)
|
|
+ return true; /* inside the TYU space */
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Read and write to CR space offsets; we assume valid_range().
|
|
+ * Data crossing the TRIO CR Space bridge gets byte-swapped, so we swap
|
|
+ * it back.
|
|
+ */
|
|
+
|
|
+static u32 crspace_readl(int offset)
|
|
+{
|
|
+ u32 data;
|
|
+ if (chip_version == MLXBF_LF_BF1) {
|
|
+ if (offset < TYU_OFFSET)
|
|
+ return swab32(readl_relaxed(hca_va + offset));
|
|
+ else
|
|
+ return readl_relaxed(tyu_va + offset - TYU_OFFSET);
|
|
+ } else {
|
|
+ data = readl_relaxed(hca_va + offset);
|
|
+ }
|
|
+ return data;
|
|
+}
|
|
+
|
|
+static void crspace_writel(u32 data, int offset)
|
|
+{
|
|
+ if (chip_version == MLXBF_LF_BF1) {
|
|
+ if (offset < TYU_OFFSET)
|
|
+ writel_relaxed(swab32(data), hca_va + offset);
|
|
+ else
|
|
+ writel_relaxed(data, tyu_va + offset - TYU_OFFSET);
|
|
+ } else {
|
|
+ writel_relaxed(data, hca_va + offset);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Note that you can seek to illegal areas within the livefish device,
|
|
+ * but you won't be able to read or write there.
|
|
+ */
|
|
+static loff_t livefish_llseek(struct file *filp, loff_t offset, int whence)
|
|
+{
|
|
+ if (offset % 4 != 0)
|
|
+ return -EINVAL;
|
|
+ return fixed_size_llseek(filp, offset, whence, CRSPACE_SIZE);
|
|
+}
|
|
+
|
|
+static ssize_t livefish_read(struct file *filp, char __user *to, size_t len,
|
|
+ loff_t *ppos)
|
|
+{
|
|
+ loff_t pos = *ppos;
|
|
+ size_t i;
|
|
+ int word;
|
|
+
|
|
+ if (!valid_range(pos, len))
|
|
+ return -EINVAL;
|
|
+ if (len == 0)
|
|
+ return 0;
|
|
+ for (i = 0; i < len; i += 4, pos += 4) {
|
|
+ word = crspace_readl(pos);
|
|
+ if (put_user(word, (int __user *)(to + i)) != 0)
|
|
+ break;
|
|
+ }
|
|
+ *ppos = pos;
|
|
+ return i ?: -EFAULT;
|
|
+}
|
|
+
|
|
+static ssize_t livefish_write(struct file *filp, const char __user *from,
|
|
+ size_t len, loff_t *ppos)
|
|
+{
|
|
+ loff_t pos = *ppos;
|
|
+ size_t i;
|
|
+ int word;
|
|
+
|
|
+ if (!valid_range(pos, len))
|
|
+ return -EINVAL;
|
|
+ if (len == 0)
|
|
+ return 0;
|
|
+ for (i = 0; i < len; i += 4, pos += 4) {
|
|
+ if (get_user(word, (int __user *)(from + i)) != 0)
|
|
+ break;
|
|
+ crspace_writel(word, pos);
|
|
+ }
|
|
+ *ppos = pos;
|
|
+ return i ?: -EFAULT;
|
|
+}
|
|
+
|
|
+static const struct file_operations livefish_fops = {
|
|
+ .owner = THIS_MODULE,
|
|
+ .llseek = livefish_llseek,
|
|
+ .read = livefish_read,
|
|
+ .write = livefish_write,
|
|
+};
|
|
+
|
|
+/* This name causes the correct semantics for the Mellanox MST tools. */
|
|
+static struct miscdevice livefish_dev = {
|
|
+ .minor = MISC_DYNAMIC_MINOR,
|
|
+ .name = "bf-livefish",
|
|
+ .mode = 0600,
|
|
+ .fops = &livefish_fops
|
|
+};
|
|
+
|
|
+/* Release any VA or PA mappings that have been set up. */
|
|
+static void livefish_cleanup_mappings(void)
|
|
+{
|
|
+ if (hca_va)
|
|
+ iounmap(hca_va);
|
|
+ if (hca_pa)
|
|
+ release_mem_region(hca_pa, hca_size);
|
|
+ if (tyu_va)
|
|
+ iounmap(tyu_va);
|
|
+ if (tyu_pa)
|
|
+ release_mem_region(tyu_pa, TYU_SIZE);
|
|
+}
|
|
+
|
|
+static int livefish_probe(struct platform_device *pdev)
|
|
+{
|
|
+ struct resource *res;
|
|
+ int ret = -EINVAL;
|
|
+ struct acpi_device *acpi_dev = ACPI_COMPANION(&pdev->dev);
|
|
+ const char *hid = acpi_device_hid(acpi_dev);
|
|
+
|
|
+ if (strcmp(hid, "MLNXBF05") == 0)
|
|
+ chip_version = MLXBF_LF_BF1;
|
|
+ else if (strcmp(hid, "MLNXBF25") == 0)
|
|
+ chip_version = MLXBF_LF_BF2;
|
|
+ else {
|
|
+ dev_err(&pdev->dev, "Invalid device ID %s\n", hid);
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ /* Find and map the HCA region */
|
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
+ if (res == NULL)
|
|
+ return -ENODEV;
|
|
+
|
|
+ if (request_mem_region(res->start, resource_size(res),
|
|
+ "LiveFish (HCA)") == NULL)
|
|
+ return -EINVAL;
|
|
+ hca_pa = res->start;
|
|
+ hca_va = ioremap(res->start, resource_size(res));
|
|
+ hca_size = resource_size(res);
|
|
+ dev_info(&pdev->dev, "HCA Region PA: 0x%llx Size: 0x%llx\n",
|
|
+ res->start, resource_size(res));
|
|
+ if (hca_va == NULL)
|
|
+ goto err;
|
|
+
|
|
+ if (chip_version == MLXBF_LF_BF1) {
|
|
+ /* Find and map the TYU efuse region */
|
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
|
+ if (res == NULL)
|
|
+ goto err;
|
|
+ if (resource_size(res) < TYU_SIZE) {
|
|
+ dev_warn(&pdev->dev, "TYU space too small: %#lx, not %#lx\n",
|
|
+ (long)resource_size(res), TYU_SIZE);
|
|
+ goto err;
|
|
+ }
|
|
+ if (request_mem_region(res->start, TYU_SIZE,
|
|
+ "LiveFish (TYU)") == NULL)
|
|
+ goto err;
|
|
+ tyu_pa = res->start;
|
|
+ tyu_va = ioremap(res->start, TYU_SIZE);
|
|
+ if (tyu_va == NULL)
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
+ ret = misc_register(&livefish_dev);
|
|
+ if (ret)
|
|
+ goto err;
|
|
+
|
|
+ dev_info(&pdev->dev, "probed\n");
|
|
+
|
|
+ return 0;
|
|
+
|
|
+err:
|
|
+ livefish_cleanup_mappings();
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int livefish_remove(struct platform_device *pdev)
|
|
+{
|
|
+ misc_deregister(&livefish_dev);
|
|
+ livefish_cleanup_mappings();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static const struct of_device_id livefish_of_match[] = {
|
|
+ { .compatible = "mellanox,mlxbf-livefish" },
|
|
+ {},
|
|
+};
|
|
+
|
|
+MODULE_DEVICE_TABLE(of, livefish_of_match);
|
|
+
|
|
+static const struct acpi_device_id livefish_acpi_match[] = {
|
|
+ { "MLNXBF05", 0 },
|
|
+ { "MLNXBF25", 0 },
|
|
+ {},
|
|
+};
|
|
+MODULE_DEVICE_TABLE(acpi, livefish_acpi_match);
|
|
+
|
|
+static struct platform_driver livefish_driver = {
|
|
+ .driver = {
|
|
+ .name = "mlxbf-livefish",
|
|
+ .of_match_table = livefish_of_match,
|
|
+ .acpi_match_table = ACPI_PTR(livefish_acpi_match),
|
|
+ },
|
|
+ .probe = livefish_probe,
|
|
+ .remove = livefish_remove,
|
|
+};
|
|
+
|
|
+module_platform_driver(livefish_driver);
|
|
+
|
|
+MODULE_DESCRIPTION("Mellanox BlueField LiveFish driver");
|
|
+MODULE_AUTHOR("Shravan Kumar Ramani <shravankr@nvidia.com>");
|
|
+MODULE_VERSION(STRINGIFY(DRIVER_VERSION));
|
|
+MODULE_LICENSE("Dual BSD/GPL");
|
|
--
|
|
2.20.1
|
|
|