summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2019-11-27 11:27:03 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2019-11-27 12:21:42 +0100
commit2217acb5362a9d7c1d8e1fe7420fa95e62c26cd7 (patch)
tree0c7cafd4cb6353155cb756550c4f39f513e9089b
parent08bad2f11575cb147a5d38822168672a2b83704c (diff)
downloadbarebox-2217acb5362a9d7c1d8e1fe7420fa95e62c26cd7.tar.gz
ARM Layerscape: ls1046ardb: read nxid eeprom
This adds support for reading the EEPROM which has a "NXID" data structure on it. The MAC addresses for the ethernet devices are found here which are registered with this patch. The NXID data structure is also found on other NXP Layerscape boards, so once we support other boards the code should be moved somewhere where it can be shared between boards. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--arch/arm/boards/ls1046ardb/board.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/arch/arm/boards/ls1046ardb/board.c b/arch/arm/boards/ls1046ardb/board.c
index 606f65c..d744737 100644
--- a/arch/arm/boards/ls1046ardb/board.c
+++ b/arch/arm/boards/ls1046ardb/board.c
@@ -3,7 +3,11 @@
#include <common.h>
#include <init.h>
#include <bbu.h>
+#include <net.h>
+#include <crc.h>
+#include <fs.h>
#include <envfs.h>
+#include <libfile.h>
#include <asm/memory.h>
#include <linux/sizes.h>
#include <linux/clk.h>
@@ -12,6 +16,104 @@
#include <mach/layerscape.h>
#include <mach/bbu.h>
+#define MAX_NUM_PORTS 16
+struct nxid {
+ u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'NXID' */
+ u8 sn[12]; /* 0x04 - 0x0F Serial Number */
+ u8 errata[5]; /* 0x10 - 0x14 Errata Level */
+ u8 date[6]; /* 0x15 - 0x1a Build Date */
+ u8 res_0; /* 0x1b Reserved */
+ u32 version; /* 0x1c - 0x1f NXID Version */
+ u8 tempcal[8]; /* 0x20 - 0x27 Temperature Calibration Factors */
+ u8 tempcalsys[2]; /* 0x28 - 0x29 System Temperature Calibration Factors */
+ u8 tempcalflags; /* 0x2a Temperature Calibration Flags */
+ u8 res_1[21]; /* 0x2b - 0x3f Reserved */
+ u8 mac_count; /* 0x40 Number of MAC addresses */
+ u8 mac_flag; /* 0x41 MAC table flags */
+ u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - 0xa1 MAC addresses */
+ u8 res_2[90]; /* 0xa2 - 0xfb Reserved */
+ u32 crc; /* 0xfc - 0xff CRC32 checksum */
+} __packed;
+
+static int nxid_is_valid(struct nxid *nxid)
+{
+ unsigned char id[] = { 'N', 'X', 'I', 'D' };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(id); i++)
+ if (nxid->id[i] != id[i])
+ return false;
+ return true;
+}
+
+static struct nxid *nxp_nxid_read(const char *filename, unsigned int offset)
+{
+ struct nxid *nxid;
+ int fd, ret, i;
+ struct device_node *root;
+ u32 crc, crc_expected;
+
+ nxid = xzalloc(sizeof(*nxid));
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ ret = -errno;
+ goto out;
+ }
+
+ ret = pread(fd, nxid, sizeof(*nxid), offset);
+ if (ret < 0) {
+ close(fd);
+ goto out;
+ }
+
+ if (!nxid_is_valid(nxid)) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ crc = crc32(0, nxid, 256 - 4);
+ crc_expected = be32_to_cpu(nxid->crc);
+ if (crc != crc_expected) {
+ pr_err("CRC mismatch (%08x != %08x)\n", crc, crc_expected);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ root = of_get_root_node();
+
+ for (i = 0; i < nxid->mac_count; i++) {
+ struct device_node *np;
+ char alias[sizeof("ethernetxxx")];
+ const char *ethaddr = nxid->mac[i];
+
+ sprintf(alias, "ethernet%d", i);
+
+ np = of_find_node_by_alias(root, alias);
+ if (!np)
+ continue;
+
+ of_eth_register_ethaddr(np, ethaddr);
+ }
+
+ ret = 0;
+out:
+ if (ret) {
+ free(nxid);
+ nxid = ERR_PTR(ret);
+ }
+
+ return nxid;
+}
+
+static int rdb_late_init(void)
+{
+ nxp_nxid_read("/dev/eeprom", 256);
+
+ return 0;
+}
+late_initcall(rdb_late_init);
+
static int rdb_mem_init(void)
{
int ret;