treewide: remove files for building 5.10 kernel
[openwrt/openwrt.git] / target / linux / generic / backport-5.10 / 814-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch
diff --git a/target/linux/generic/backport-5.10/814-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch b/target/linux/generic/backport-5.10/814-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch
deleted file mode 100644 (file)
index ca8b4bc..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-From d3c0d12f6474216bf386101e2449cc73e5c5b61d Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:31 +0100
-Subject: [PATCH] nvmem: layouts: onie-tlv: Add new layout driver
-
-This layout applies on top of any non volatile storage device containing
-an ONIE table factory flashed. This table follows the tlv
-(type-length-value) organization described in the link below. We cannot
-afford using regular parsers because the content of these tables is
-manufacturer specific and must be dynamically discovered.
-
-Link: https://opencomputeproject.github.io/onie/design-spec/hw_requirements.html
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-24-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/Kconfig    |   9 ++
- drivers/nvmem/layouts/Makefile   |   1 +
- drivers/nvmem/layouts/onie-tlv.c | 257 +++++++++++++++++++++++++++++++
- 3 files changed, 267 insertions(+)
- create mode 100644 drivers/nvmem/layouts/onie-tlv.c
-
---- a/drivers/nvmem/layouts/Kconfig
-+++ b/drivers/nvmem/layouts/Kconfig
-@@ -11,4 +11,13 @@ config NVMEM_LAYOUT_SL28_VPD
-         If unsure, say N.
-+config NVMEM_LAYOUT_ONIE_TLV
-+      tristate "ONIE tlv support"
-+      select CRC32
-+      help
-+        Say Y here if you want to support the Open Compute Project ONIE
-+        Type-Length-Value standard table.
-+
-+        If unsure, say N.
-+
- endmenu
---- a/drivers/nvmem/layouts/Makefile
-+++ b/drivers/nvmem/layouts/Makefile
-@@ -4,3 +4,4 @@
- #
- obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
-+obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
---- /dev/null
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -0,0 +1,257 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * ONIE tlv NVMEM cells provider
-+ *
-+ * Copyright (C) 2022 Open Compute Group ONIE
-+ * Author: Miquel Raynal <miquel.raynal@bootlin.com>
-+ * Based on the nvmem driver written by: Vadym Kochan <vadym.kochan@plvision.eu>
-+ * Inspired by the first layout written by: Rafał Miłecki <rafal@milecki.pl>
-+ */
-+
-+#include <linux/crc32.h>
-+#include <linux/etherdevice.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of.h>
-+
-+#define ONIE_TLV_MAX_LEN 2048
-+#define ONIE_TLV_CRC_FIELD_SZ 6
-+#define ONIE_TLV_CRC_SZ 4
-+#define ONIE_TLV_HDR_ID       "TlvInfo"
-+
-+struct onie_tlv_hdr {
-+      u8 id[8];
-+      u8 version;
-+      __be16 data_len;
-+} __packed;
-+
-+struct onie_tlv {
-+      u8 type;
-+      u8 len;
-+} __packed;
-+
-+static const char *onie_tlv_cell_name(u8 type)
-+{
-+      switch (type) {
-+      case 0x21:
-+              return "product-name";
-+      case 0x22:
-+              return "part-number";
-+      case 0x23:
-+              return "serial-number";
-+      case 0x24:
-+              return "mac-address";
-+      case 0x25:
-+              return "manufacture-date";
-+      case 0x26:
-+              return "device-version";
-+      case 0x27:
-+              return "label-revision";
-+      case 0x28:
-+              return "platform-name";
-+      case 0x29:
-+              return "onie-version";
-+      case 0x2A:
-+              return "num-macs";
-+      case 0x2B:
-+              return "manufacturer";
-+      case 0x2C:
-+              return "country-code";
-+      case 0x2D:
-+              return "vendor";
-+      case 0x2E:
-+              return "diag-version";
-+      case 0x2F:
-+              return "service-tag";
-+      case 0xFD:
-+              return "vendor-extension";
-+      case 0xFE:
-+              return "crc32";
-+      default:
-+              break;
-+      }
-+
-+      return NULL;
-+}
-+
-+static int onie_tlv_mac_read_cb(void *priv, const char *id, int index,
-+                              unsigned int offset, void *buf,
-+                              size_t bytes)
-+{
-+      eth_addr_add(buf, index);
-+
-+      return 0;
-+}
-+
-+static nvmem_cell_post_process_t onie_tlv_read_cb(u8 type, u8 *buf)
-+{
-+      switch (type) {
-+      case 0x24:
-+              return &onie_tlv_mac_read_cb;
-+      default:
-+              break;
-+      }
-+
-+      return NULL;
-+}
-+
-+static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem,
-+                            size_t data_len, u8 *data)
-+{
-+      struct nvmem_cell_info cell = {};
-+      struct device_node *layout;
-+      struct onie_tlv tlv;
-+      unsigned int hdr_len = sizeof(struct onie_tlv_hdr);
-+      unsigned int offset = 0;
-+      int ret;
-+
-+      layout = of_nvmem_layout_get_container(nvmem);
-+      if (!layout)
-+              return -ENOENT;
-+
-+      while (offset < data_len) {
-+              memcpy(&tlv, data + offset, sizeof(tlv));
-+              if (offset + tlv.len >= data_len) {
-+                      dev_err(dev, "Out of bounds field (0x%x bytes at 0x%x)\n",
-+                              tlv.len, hdr_len + offset);
-+                      break;
-+              }
-+
-+              cell.name = onie_tlv_cell_name(tlv.type);
-+              if (!cell.name)
-+                      continue;
-+
-+              cell.offset = hdr_len + offset + sizeof(tlv.type) + sizeof(tlv.len);
-+              cell.bytes = tlv.len;
-+              cell.np = of_get_child_by_name(layout, cell.name);
-+              cell.read_post_process = onie_tlv_read_cb(tlv.type, data + offset + sizeof(tlv));
-+
-+              ret = nvmem_add_one_cell(nvmem, &cell);
-+              if (ret) {
-+                      of_node_put(layout);
-+                      return ret;
-+              }
-+
-+              offset += sizeof(tlv) + tlv.len;
-+      }
-+
-+      of_node_put(layout);
-+
-+      return 0;
-+}
-+
-+static bool onie_tlv_hdr_is_valid(struct device *dev, struct onie_tlv_hdr *hdr)
-+{
-+      if (memcmp(hdr->id, ONIE_TLV_HDR_ID, sizeof(hdr->id))) {
-+              dev_err(dev, "Invalid header\n");
-+              return false;
-+      }
-+
-+      if (hdr->version != 0x1) {
-+              dev_err(dev, "Invalid version number\n");
-+              return false;
-+      }
-+
-+      return true;
-+}
-+
-+static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *table)
-+{
-+      struct onie_tlv crc_hdr;
-+      u32 read_crc, calc_crc;
-+      __be32 crc_be;
-+
-+      memcpy(&crc_hdr, table + table_len - ONIE_TLV_CRC_FIELD_SZ, sizeof(crc_hdr));
-+      if (crc_hdr.type != 0xfe || crc_hdr.len != ONIE_TLV_CRC_SZ) {
-+              dev_err(dev, "Invalid CRC field\n");
-+              return false;
-+      }
-+
-+      /* The table contains a JAMCRC, which is XOR'ed compared to the original
-+       * CRC32 implementation as known in the Ethernet world.
-+       */
-+      memcpy(&crc_be, table + table_len - ONIE_TLV_CRC_SZ, ONIE_TLV_CRC_SZ);
-+      read_crc = be32_to_cpu(crc_be);
-+      calc_crc = crc32(~0, table, table_len - ONIE_TLV_CRC_SZ) ^ 0xFFFFFFFF;
-+      if (read_crc != calc_crc) {
-+              dev_err(dev, "Invalid CRC read: 0x%08x, expected: 0x%08x\n",
-+                      read_crc, calc_crc);
-+              return false;
-+      }
-+
-+      return true;
-+}
-+
-+static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem,
-+                              struct nvmem_layout *layout)
-+{
-+      struct onie_tlv_hdr hdr;
-+      size_t table_len, data_len, hdr_len;
-+      u8 *table, *data;
-+      int ret;
-+
-+      ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr);
-+      if (ret < 0)
-+              return ret;
-+
-+      if (!onie_tlv_hdr_is_valid(dev, &hdr)) {
-+              dev_err(dev, "Invalid ONIE TLV header\n");
-+              return -EINVAL;
-+      }
-+
-+      hdr_len = sizeof(hdr.id) + sizeof(hdr.version) + sizeof(hdr.data_len);
-+      data_len = be16_to_cpu(hdr.data_len);
-+      table_len = hdr_len + data_len;
-+      if (table_len > ONIE_TLV_MAX_LEN) {
-+              dev_err(dev, "Invalid ONIE TLV data length\n");
-+              return -EINVAL;
-+      }
-+
-+      table = devm_kmalloc(dev, table_len, GFP_KERNEL);
-+      if (!table)
-+              return -ENOMEM;
-+
-+      ret = nvmem_device_read(nvmem, 0, table_len, table);
-+      if (ret != table_len)
-+              return ret;
-+
-+      if (!onie_tlv_crc_is_valid(dev, table_len, table))
-+              return -EINVAL;
-+
-+      data = table + hdr_len;
-+      ret = onie_tlv_add_cells(dev, nvmem, data_len, data);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static const struct of_device_id onie_tlv_of_match_table[] = {
-+      { .compatible = "onie,tlv-layout", },
-+      {},
-+};
-+MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table);
-+
-+static struct nvmem_layout onie_tlv_layout = {
-+      .name = "ONIE tlv layout",
-+      .of_match_table = onie_tlv_of_match_table,
-+      .add_cells = onie_tlv_parse_table,
-+};
-+
-+static int __init onie_tlv_init(void)
-+{
-+      return nvmem_layout_register(&onie_tlv_layout);
-+}
-+
-+static void __exit onie_tlv_exit(void)
-+{
-+      nvmem_layout_unregister(&onie_tlv_layout);
-+}
-+
-+module_init(onie_tlv_init);
-+module_exit(onie_tlv_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
-+MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing");
-+MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing");