aboutsummaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorTom Rini2020-01-07 08:44:56 -0500
committerTom Rini2020-01-07 08:44:56 -0500
commitac0f978afd4b8d388b0b194bc6e5982efc383a59 (patch)
tree14d2f8683c0b6425147b3531a071a347b38bef94 /board
parent5a8fa095cb848c60c630a83edf30d4fc46101e90 (diff)
parent96b225b0c8359d6873bc09d651ab8d57a2be3aa5 (diff)
Merge tag 'u-boot-atmel-2020.04-a' of https://gitlab.denx.de/u-boot/custodians/u-boot-atmel
First set of u-boot-atmel features for 2020.04 cycle This feature set is a patch series from Tudor Ambarus which includes parsing of the spi flash SFDP parser for SST flashes, and using those tables to retrieve unique saved per device MAC address. This is then used as base mac address on the SAMA5D2 Wireless SOM EK board.
Diffstat (limited to 'board')
-rw-r--r--board/atmel/common/Makefile1
-rw-r--r--board/atmel/common/mac-spi-nor.c127
-rw-r--r--board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c3
3 files changed, 131 insertions, 0 deletions
diff --git a/board/atmel/common/Makefile b/board/atmel/common/Makefile
index 4de0912f22e..6bc8cabb8d6 100644
--- a/board/atmel/common/Makefile
+++ b/board/atmel/common/Makefile
@@ -5,4 +5,5 @@
obj-y += board.o
obj-$(CONFIG_I2C_EEPROM) += mac_eeprom.o
+obj-$(CONFIG_SPI_FLASH_SFDP_SUPPORT) += mac-spi-nor.o
obj-$(CONFIG_DM_VIDEO) += video_display.o
diff --git a/board/atmel/common/mac-spi-nor.c b/board/atmel/common/mac-spi-nor.c
new file mode 100644
index 00000000000..96343678e0b
--- /dev/null
+++ b/board/atmel/common/mac-spi-nor.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Tudor Ambarus <tudor.ambarus@microchip.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <env.h>
+#include <linux/mtd/spi-nor.h>
+#include <netdev.h>
+
+#define ETH_ADDR_SIZE 6
+
+#ifdef CONFIG_SPI_FLASH_SST
+#define SFDP_MICROCHIP_MANUF_ID 0xbf
+#define SFDP_MICROCHIP_MEM_TYPE 0x26
+#define SFDP_MICROCHIP_DEV_ID 0x43
+
+#define SFDP_MICROCHIP_EUI_OFFSET 0x60
+#define SFDP_MICROCHIP_EUI48 0x30
+
+struct sst26vf064beui {
+ u8 manufacturer_id;
+ u8 memory_type;
+ u8 device_id;
+ u8 reserved;
+};
+
+/**
+ * sst26vf064beui_check() - Check the validity of the EUI-48 information from
+ * the sst26vf064beui SPI NOR Microchip SFDP table.
+ * @manufacturer_sfdp: pointer to the Microchip manufacturer specific SFDP
+ * table.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int sst26vf064beui_check(const u8 *manufacturer_sfdp)
+{
+ struct sst26vf064beui *sst26vf064beui =
+ (struct sst26vf064beui *)manufacturer_sfdp;
+
+ if (sst26vf064beui->manufacturer_id != SFDP_MICROCHIP_MANUF_ID)
+ return -EINVAL;
+
+ if (sst26vf064beui->memory_type != SFDP_MICROCHIP_MEM_TYPE)
+ return -EINVAL;
+
+ if (sst26vf064beui->device_id != SFDP_MICROCHIP_DEV_ID)
+ return -EINVAL;
+
+ /*
+ * Check if the EUI-48 MAC address is programmed in the next six address
+ * locations.
+ */
+ if (manufacturer_sfdp[SFDP_MICROCHIP_EUI_OFFSET] !=
+ SFDP_MICROCHIP_EUI48)
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * sst26vf064beui_get_ethaddr() - Get the ethernet address from the
+ * sst26vf064beui SPI NOR Microchip SFDP table.
+ * @manufacturer_sfdp: pointer to the Microchip manufacturer specific SFDP
+ * table.
+ * @ethaddr: pointer where to fill the ethernet address
+ * @size: size of the ethernet address.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int sst26vf064beui_get_ethaddr(const u8 *manufacturer_sfdp,
+ u8 *ethaddr, size_t size)
+{
+ u64 eui_table[2];
+ u64 *p = (u64 *)&manufacturer_sfdp[SFDP_MICROCHIP_EUI_OFFSET];
+ int i, ret;
+
+ ret = sst26vf064beui_check(manufacturer_sfdp);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < 2; i++)
+ eui_table[i] = le64_to_cpu(p[i]);
+
+ /* Ethaddr starts at offset one. */
+ memcpy(ethaddr, &((u8 *)eui_table)[1], size);
+
+ return 0;
+}
+#endif
+
+/**
+ * at91_spi_nor_set_ethaddr() - Retrieve and set the ethernet address from the
+ * SPI NOR manufacturer specific SFDP table.
+ */
+void at91_spi_nor_set_ethaddr(void)
+{
+ struct udevice *dev;
+ struct spi_nor *nor;
+ const char *ethaddr_name = "ethaddr";
+ u8 ethaddr[ETH_ADDR_SIZE] = {0};
+
+ if (env_get(ethaddr_name))
+ return;
+
+ if (uclass_first_device_err(UCLASS_SPI_FLASH, &dev))
+ return;
+
+ nor = dev_get_uclass_priv(dev);
+ if (!nor)
+ return;
+
+ if (!nor->manufacturer_sfdp)
+ return;
+
+#ifdef CONFIG_SPI_FLASH_SST
+ if (sst26vf064beui_get_ethaddr(nor->manufacturer_sfdp, ethaddr,
+ ETH_ADDR_SIZE))
+ return;
+#endif
+
+ if (is_valid_ethaddr(ethaddr))
+ eth_env_set_enetaddr(ethaddr_name, ethaddr);
+}
diff --git a/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c b/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c
index fda06c824d5..fc563ebb715 100644
--- a/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c
+++ b/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c
@@ -68,6 +68,9 @@ int board_init(void)
#ifdef CONFIG_MISC_INIT_R
int misc_init_r(void)
{
+#ifdef CONFIG_SPI_FLASH_SFDP_SUPPORT
+ at91_spi_nor_set_ethaddr();
+#endif
return 0;
}
#endif