sonic-buildimage/platform/mellanox/non-upstream-patches/patches/0221-UBUNTU-SAUCE-platform-mellanox-Add-mlxbf-livefish-dr.patch
Kebo Liu e286869b24
[Mellanox] Update HW-MGMT package to new version V.7.0030.1011 (#16239)
- 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>
2023-09-06 11:32:08 +03:00

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