All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/3] mips: mt7628: Change compatible property of the ethernet DT node
@ 2018-11-28  7:40 Stefan Roese
  2018-11-28  7:40 ` [U-Boot] [PATCH 2/3] mips: mt76xx: gardena-smart-gateway: Misc updates to defconfig Stefan Roese
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Stefan Roese @ 2018-11-28  7:40 UTC (permalink / raw)
  To: u-boot

As the driver has been changed to be more specific, the DT compatible
property also needs to be adapted.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
 arch/mips/dts/mt7628a.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi
index 70e34cfdbc..1e7d0a6ec5 100644
--- a/arch/mips/dts/mt7628a.dtsi
+++ b/arch/mips/dts/mt7628a.dtsi
@@ -164,7 +164,7 @@
 	};
 
 	eth at 10110000 {
-		compatible = "mediatek,mt7622-eth";
+		compatible = "mediatek,mt7628-eth";
 		reg = <0x10100000 0x10000
 		       0x10110000 0x8000>;
 
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH 2/3] mips: mt76xx: gardena-smart-gateway: Misc updates to defconfig
  2018-11-28  7:40 [U-Boot] [PATCH 1/3] mips: mt7628: Change compatible property of the ethernet DT node Stefan Roese
@ 2018-11-28  7:40 ` Stefan Roese
  2018-11-28 22:42   ` Daniel Schwierzeck
  2018-11-28  7:40 ` [U-Boot] [PATCH 3/3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling Stefan Roese
  2018-11-28 22:41 ` [U-Boot] [PATCH 1/3] mips: mt7628: Change compatible property of the ethernet DT node Daniel Schwierzeck
  2 siblings, 1 reply; 11+ messages in thread
From: Stefan Roese @ 2018-11-28  7:40 UTC (permalink / raw)
  To: u-boot

The following changes are made:
- Add default bootcmd which can be used for initial start-up
- Setup necessary MTD parts for Linux compatibility

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
 configs/gardena-smart-gateway-mt7688-ram_defconfig | 6 ++++--
 configs/gardena-smart-gateway-mt7688_defconfig     | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig
index 91359698ab..05e7cf9f88 100644
--- a/configs/gardena-smart-gateway-mt7688-ram_defconfig
+++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig
@@ -10,6 +10,8 @@ CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="cp.b 83000000 84000000 10000 && dhcp uEnv.txt && env import -t ${fileaddr} ${filesize} && run do_u_boot_init; reset"
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_BOARD_EARLY_INIT_F=y
@@ -31,8 +33,8 @@ CONFIG_CMD_BOOTCOUNT=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_UUID=y
 CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:-(nand)"
+CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)"
 CONFIG_CMD_UBI=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig
index bd8b035dea..a08d1dbc9c 100644
--- a/configs/gardena-smart-gateway-mt7688_defconfig
+++ b/configs/gardena-smart-gateway-mt7688_defconfig
@@ -13,6 +13,8 @@ CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="cp.b 83000000 84000000 10000 && dhcp uEnv.txt && env import -t ${fileaddr} ${filesize} && run do_u_boot_init; reset"
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_BOARD_EARLY_INIT_F=y
@@ -34,8 +36,8 @@ CONFIG_CMD_BOOTCOUNT=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_UUID=y
 CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:-(nand)"
+CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)"
 CONFIG_CMD_UBI=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH 3/3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling
  2018-11-28  7:40 [U-Boot] [PATCH 1/3] mips: mt7628: Change compatible property of the ethernet DT node Stefan Roese
  2018-11-28  7:40 ` [U-Boot] [PATCH 2/3] mips: mt76xx: gardena-smart-gateway: Misc updates to defconfig Stefan Roese
@ 2018-11-28  7:40 ` Stefan Roese
  2018-11-28 22:41   ` Daniel Schwierzeck
                     ` (3 more replies)
  2018-11-28 22:41 ` [U-Boot] [PATCH 1/3] mips: mt7628: Change compatible property of the ethernet DT node Daniel Schwierzeck
  2 siblings, 4 replies; 11+ messages in thread
From: Stefan Roese @ 2018-11-28  7:40 UTC (permalink / raw)
  To: u-boot

Some factory data is stored in the SPI NOR and needs to get extracted
from there into U-Boot environment variables.

This patch also includes a board-specific command "fd_write" to
provide some dummy / default values for this factory-data in the SPI
NOR flash. This should only be necessary for testing purposes though.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
 board/gardena/smart-gateway-mt7688/board.c | 266 +++++++++++++++++++++
 1 file changed, 266 insertions(+)

diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
index 3a1838e44a..185bdfb71d 100644
--- a/board/gardena/smart-gateway-mt7688/board.c
+++ b/board/gardena/smart-gateway-mt7688/board.c
@@ -4,11 +4,44 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <led.h>
+#include <net.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <uuid.h>
+#include <linux/ctype.h>
 #include <linux/io.h>
 
 #define MT76XX_AGPIO_CFG	0x1000003c
 
+#define FACTORY_DATA_OFFS	0xc0000
+#define FACTORY_DATA_SECT_SIZE	0x10000
+#if ((CONFIG_ENV_OFFSET_REDUND + CONFIG_ENV_SIZE_REDUND) > FACTORY_DATA_OFFS)
+#error "U-Boot image with environment too big (overlapping with factory-data)!"
+#endif
+#define FACTORY_DATA_USER_OFFS	0x140
+#define FACTORY_DATA_SIZE	0x1f0
+#define FACTORY_DATA_CRC_LEN	(FACTORY_DATA_SIZE -			\
+				 FACTORY_DATA_USER_OFFS - sizeof(u32))
+
+#define FACTORY_DATA_MAGIC	0xCAFEBABE
+
+struct factory_data_values {
+	u8 pad_1[4];
+	u8 wifi_mac[6];		/* offs: 0x004: binary value */
+	u8 pad_2[30];
+	u8 eth_mac[6];		/* offs: 0x028: binary value */
+	u8 pad_3[FACTORY_DATA_USER_OFFS - 4 - 6 - 30 - 6];
+	/* User values start here at offset 0x140 */
+	u32 crc;
+	u32 magic;
+	u32 version;
+	char ipr_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+	char hqv_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+	char unielec_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+};
+
 int board_early_init_f(void)
 {
 	void __iomem *gpio_mode;
@@ -20,10 +53,243 @@ int board_early_init_f(void)
 	return 0;
 }
 
+static int prepare_uuid_var(char *fd_ptr, char *env_var_name, char errorchar)
+{
+	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
+	bool env_updated = 0;
+	char *env;
+	int i;
+
+	memset(str, 0, sizeof(str));
+	memcpy(str, fd_ptr, UUID_STR_LEN);
+
+	/* Convert non-ascii character to 'X' */
+	for (i = 0; i < UUID_STR_LEN; i++) {
+		if (!(isascii(str[i]) && isprint(str[i])))
+			str[i] = errorchar;
+	}
+
+	env = env_get(env_var_name);
+	if (strcmp(env, str)) {
+		env_set(env_var_name, str);
+		env_updated = 1;
+	}
+
+	return env_updated;
+}
+
+static void factory_data_env_config(void)
+{
+	struct factory_data_values *fd;
+	struct spi_flash *sf;
+	int env_updated = 0;
+	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
+	char *env;
+	u8 *buf;
+	u32 crc;
+	int ret;
+	u8 *ptr;
+
+	buf = malloc(FACTORY_DATA_SIZE);
+	if (!buf) {
+		printf("F-Data:Unable to allocate buffer\n");
+		goto err;
+	}
+
+	/*
+	 * Get values from factory-data area in SPI NOR
+	 */
+	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+			     CONFIG_SF_DEFAULT_CS,
+			     CONFIG_SF_DEFAULT_SPEED,
+			     CONFIG_SF_DEFAULT_MODE);
+	if (!sf) {
+		printf("F-Data:Unable to access SPI NOR flash\n");
+		goto err;
+	}
+
+	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SIZE,
+			     (void *)buf);
+	if (ret) {
+		printf("F-Data:Unable to read factory-data from SPI NOR\n");
+		goto err;
+	}
+
+	fd = (struct factory_data_values *)buf;
+
+	if (fd->magic != FACTORY_DATA_MAGIC)
+		printf("F-Data:Magic value not correct\n");
+
+	crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
+	if (crc != fd->crc)
+		printf("F-Data:CRC not correct\n");
+	else
+		printf("F-Data:factory-data version %x detected\n",
+		       fd->version);
+
+	/* Handle wifi_mac env variable */
+	ptr = fd->wifi_mac;
+	sprintf(str, "%pM", ptr);
+	if (!is_valid_ethaddr(ptr))
+		printf("F-Data:Invalid MAC addr: wifi_mac %s\n", str);
+
+	env = env_get("wifiaddr");
+	if (strcmp(env, str)) {
+		env_set("wifiaddr", str);
+		env_updated = 1;
+	}
+
+	/* Handle eth_mac env variable */
+	ptr = fd->eth_mac;
+	sprintf(str, "%pM", ptr);
+	if (!is_valid_ethaddr(ptr))
+		printf("F-Data:Invalid MAC addr: eth_mac %s\n", str);
+
+	env = env_get("ethaddr");
+	if (strcmp(env, str)) {
+		env_set("ethaddr", str);
+		env_updated = 1;
+	}
+
+	/* Handle UUID env variables */
+	env_updated |= prepare_uuid_var(fd->ipr_id, "linuxmoduleid", 'X');
+	env_updated |= prepare_uuid_var(fd->hqv_id, "linuxmodulehqvid", '\0');
+	env_updated |= prepare_uuid_var(fd->unielec_id,
+					"linuxmoduleunielecid", 'X');
+
+	/* Check if the environment was updated and needs to get stored */
+	if (env_updated != 0) {
+		printf("F-Data:Values don't match env values -> saving\n");
+		env_save();
+	} else {
+		printf("F-Data:Values match current env values\n");
+	}
+
+err:
+	free(buf);
+}
+
 int board_late_init(void)
 {
 	if (IS_ENABLED(CONFIG_LED))
 		led_default_state();
 
+	factory_data_env_config();
+
 	return 0;
 }
+
+static void copy_or_generate_uuid(char *fd_ptr, char *env_var_name)
+{
+	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
+	char *env;
+
+	/* Don't use the UUID dest place, as the \0 char won't fit */
+	env = env_get(env_var_name);
+	if (env) {
+		memcpy(fd_ptr, env, UUID_STR_LEN);
+	} else {
+		gen_rand_uuid_str(str, UUID_STR_FORMAT_STD);
+		memcpy(fd_ptr, str, UUID_STR_LEN);
+	}
+}
+
+/*
+ * Helper function to provide some sane factory-data values for testing
+ * purpose, when these values are not programmed correctly
+ */
+int do_fd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct factory_data_values *fd;
+	struct spi_flash *sf;
+	u8 *buf;
+	int ret = CMD_RET_FAILURE;
+
+	buf = malloc(FACTORY_DATA_SECT_SIZE);
+	if (!buf) {
+		printf("F-Data:Unable to allocate buffer\n");
+		return CMD_RET_FAILURE;
+	}
+
+	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+			     CONFIG_SF_DEFAULT_CS,
+			     CONFIG_SF_DEFAULT_SPEED,
+			     CONFIG_SF_DEFAULT_MODE);
+	if (!sf) {
+		printf("F-Data:Unable to access SPI NOR flash\n");
+		goto err;
+	}
+
+	/* Generate the factory-data struct */
+
+	/* Fist read complete sector into buffer */
+	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
+			     (void *)buf);
+	if (ret) {
+		printf("F-Data:spi_flash_read failed (%d)\n", ret);
+		goto err;
+	}
+
+	fd = (struct factory_data_values *)buf;
+	fd->magic = FACTORY_DATA_MAGIC;
+	fd->version = 0x1;
+
+	/* Use existing MAC and UUID values or generate some random ones */
+	if (!eth_env_get_enetaddr("wifiaddr", fd->wifi_mac)) {
+		net_random_ethaddr(fd->wifi_mac);
+		/* to get a different seed value for the MAC address */
+		mdelay(10);
+	}
+
+	if (!eth_env_get_enetaddr("ethaddr", fd->eth_mac))
+		net_random_ethaddr(fd->eth_mac);
+
+	copy_or_generate_uuid(fd->ipr_id, "linuxmoduleid");
+	copy_or_generate_uuid(fd->hqv_id, "linuxmodulehqvid");
+	copy_or_generate_uuid(fd->unielec_id, "linuxmoduleunielecid");
+
+	printf("New factory-data values:\n");
+	printf("wifiaddr=%pM\n", fd->wifi_mac);
+	printf("ethaddr=%pM\n", fd->eth_mac);
+
+	/*
+	 * We don't have the \0 char at the end, so we need to specify the
+	 * length in the printf format instead
+	 */
+	printf("linuxmoduleid=%." __stringify(UUID_STR_LEN) "s\n", fd->ipr_id);
+	printf("linuxmodulehqvid=%." __stringify(UUID_STR_LEN) "s\n",
+	       fd->hqv_id);
+	printf("linuxmoduleunielecid=%." __stringify(UUID_STR_LEN) "s\n",
+	       fd->unielec_id);
+
+	fd->crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
+
+	ret = spi_flash_erase(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE);
+	if (ret) {
+		printf("F-Data:spi_flash_erase failed (%d)\n", ret);
+		goto err;
+	}
+
+	ret = spi_flash_write(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
+			      buf);
+	if (ret) {
+		printf("F-Data:spi_flash_write failed (%d)\n", ret);
+		goto err;
+	}
+
+	printf("F-Data:factory-data values written to SPI NOR flash\n");
+	ret = 0;
+
+err:
+	spi_flash_free(sf);
+
+	free(buf);
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	fd_write,	1,	0,	do_fd_write,
+	"Write test factory-data values to SPI NOR",
+	"\n"
+);
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH 3/3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling
  2018-11-28  7:40 ` [U-Boot] [PATCH 3/3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling Stefan Roese
@ 2018-11-28 22:41   ` Daniel Schwierzeck
  2018-11-29 10:01     ` Stefan Roese
  2018-11-29 10:07   ` [U-Boot] [PATCH 3/3 v2] " Stefan Roese
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Daniel Schwierzeck @ 2018-11-28 22:41 UTC (permalink / raw)
  To: u-boot



Am 28.11.18 um 08:40 schrieb Stefan Roese:
> Some factory data is stored in the SPI NOR and needs to get extracted
> from there into U-Boot environment variables.
> 
> This patch also includes a board-specific command "fd_write" to
> provide some dummy / default values for this factory-data in the SPI
> NOR flash. This should only be necessary for testing purposes though.
> 
> Signed-off-by: Stefan Roese <sr@denx.de>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> ---
>  board/gardena/smart-gateway-mt7688/board.c | 266 +++++++++++++++++++++
>  1 file changed, 266 insertions(+)

please send a v2 only of this patch. I already applied the other two
patches. Thanks.

> 
> diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
> index 3a1838e44a..185bdfb71d 100644
> --- a/board/gardena/smart-gateway-mt7688/board.c
> +++ b/board/gardena/smart-gateway-mt7688/board.c
> @@ -4,11 +4,44 @@
>   */
>  
>  #include <common.h>
> +#include <environment.h>
>  #include <led.h>
> +#include <net.h>
> +#include <spi.h>
> +#include <spi_flash.h>
> +#include <uuid.h>
> +#include <linux/ctype.h>
>  #include <linux/io.h>
>  
>  #define MT76XX_AGPIO_CFG	0x1000003c
>  
> +#define FACTORY_DATA_OFFS	0xc0000
> +#define FACTORY_DATA_SECT_SIZE	0x10000
> +#if ((CONFIG_ENV_OFFSET_REDUND + CONFIG_ENV_SIZE_REDUND) > FACTORY_DATA_OFFS)
> +#error "U-Boot image with environment too big (overlapping with factory-data)!"
> +#endif
> +#define FACTORY_DATA_USER_OFFS	0x140
> +#define FACTORY_DATA_SIZE	0x1f0
> +#define FACTORY_DATA_CRC_LEN	(FACTORY_DATA_SIZE -			\
> +				 FACTORY_DATA_USER_OFFS - sizeof(u32))
> +
> +#define FACTORY_DATA_MAGIC	0xCAFEBABE
> +
> +struct factory_data_values {
> +	u8 pad_1[4];
> +	u8 wifi_mac[6];		/* offs: 0x004: binary value */
> +	u8 pad_2[30];
> +	u8 eth_mac[6];		/* offs: 0x028: binary value */
> +	u8 pad_3[FACTORY_DATA_USER_OFFS - 4 - 6 - 30 - 6];
> +	/* User values start here at offset 0x140 */
> +	u32 crc;
> +	u32 magic;
> +	u32 version;
> +	char ipr_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
> +	char hqv_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
> +	char unielec_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
> +};
> +
>  int board_early_init_f(void)
>  {
>  	void __iomem *gpio_mode;
> @@ -20,10 +53,243 @@ int board_early_init_f(void)
>  	return 0;
>  }
>  
> +static int prepare_uuid_var(char *fd_ptr, char *env_var_name, char errorchar)

const for the char pointers and bool as return value?

> +{
> +	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
> +	bool env_updated = 0;
> +	char *env;
> +	int i;
> +
> +	memset(str, 0, sizeof(str));
> +	memcpy(str, fd_ptr, UUID_STR_LEN);

you can avoid the memset() with str[UUID_STR_LEN] = 0;

> +
> +	/* Convert non-ascii character to 'X' */
> +	for (i = 0; i < UUID_STR_LEN; i++) {
> +		if (!(isascii(str[i]) && isprint(str[i])))
> +			str[i] = errorchar;

can it happen that the string value is shorter than UUID_STR_LEN and is
zero-terminated? If yes is it intented to fill the remaining characters
with errorchar?

> +	}
> +
> +	env = env_get(env_var_name);
> +	if (strcmp(env, str)) {
> +		env_set(env_var_name, str);
> +		env_updated = 1;
> +	}
> +
> +	return env_updated;
> +}
> +
> +static void factory_data_env_config(void)
> +{
> +	struct factory_data_values *fd;
> +	struct spi_flash *sf;
> +	int env_updated = 0;
> +	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
> +	char *env;
> +	u8 *buf;
> +	u32 crc;
> +	int ret;
> +	u8 *ptr;
> +
> +	buf = malloc(FACTORY_DATA_SIZE);
> +	if (!buf) {
> +		printf("F-Data:Unable to allocate buffer\n");
> +		goto err;

this jump to 'err' is incorrect as you would free a NULL poinzer

> +	}
> +
> +	/*
> +	 * Get values from factory-data area in SPI NOR
> +	 */
> +	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
> +			     CONFIG_SF_DEFAULT_CS,
> +			     CONFIG_SF_DEFAULT_SPEED,
> +			     CONFIG_SF_DEFAULT_MODE);
> +	if (!sf) {
> +		printf("F-Data:Unable to access SPI NOR flash\n");
> +		goto err;
> +	}
> +
> +	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SIZE,
> +			     (void *)buf);
> +	if (ret) {
> +		printf("F-Data:Unable to read factory-data from SPI NOR\n");
> +		goto err;

you need another goto label with spi_flash_free(sf) from here on

> +	}
> +
> +	fd = (struct factory_data_values *)buf;
> +
> +	if (fd->magic != FACTORY_DATA_MAGIC)
> +		printf("F-Data:Magic value not correct\n");
> +
> +	crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
> +	if (crc != fd->crc)
> +		printf("F-Data:CRC not correct\n");
> +	else
> +		printf("F-Data:factory-data version %x detected\n",
> +		       fd->version);
> +
> +	/* Handle wifi_mac env variable */
> +	ptr = fd->wifi_mac;
> +	sprintf(str, "%pM", ptr);
> +	if (!is_valid_ethaddr(ptr))
> +		printf("F-Data:Invalid MAC addr: wifi_mac %s\n", str);
> +
> +	env = env_get("wifiaddr");
> +	if (strcmp(env, str)) {
> +		env_set("wifiaddr", str);
> +		env_updated = 1;
> +	}
> +
> +	/* Handle eth_mac env variable */
> +	ptr = fd->eth_mac;
> +	sprintf(str, "%pM", ptr);
> +	if (!is_valid_ethaddr(ptr))
> +		printf("F-Data:Invalid MAC addr: eth_mac %s\n", str);
> +
> +	env = env_get("ethaddr");
> +	if (strcmp(env, str)) {
> +		env_set("ethaddr", str);
> +		env_updated = 1;
> +	}
> +
> +	/* Handle UUID env variables */
> +	env_updated |= prepare_uuid_var(fd->ipr_id, "linuxmoduleid", 'X');
> +	env_updated |= prepare_uuid_var(fd->hqv_id, "linuxmodulehqvid", '\0');
> +	env_updated |= prepare_uuid_var(fd->unielec_id,
> +					"linuxmoduleunielecid", 'X');
> +
> +	/* Check if the environment was updated and needs to get stored */
> +	if (env_updated != 0) {
> +		printf("F-Data:Values don't match env values -> saving\n");
> +		env_save();
> +	} else {
> +		printf("F-Data:Values match current env values\n");

maybe debug() or do you want to see that at each boot?

> +	}
> +
> +err:
> +	free(buf);
> +}
> +
>  int board_late_init(void)
>  {
>  	if (IS_ENABLED(CONFIG_LED))
>  		led_default_state();
>  
> +	factory_data_env_config();
> +
>  	return 0;
>  }
> +
> +static void copy_or_generate_uuid(char *fd_ptr, char *env_var_name)

const char * ?

> +{
> +	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
> +	char *env;
> +
> +	/* Don't use the UUID dest place, as the \0 char won't fit */
> +	env = env_get(env_var_name);
> +	if (env) {
> +		memcpy(fd_ptr, env, UUID_STR_LEN);
> +	} else {
> +		gen_rand_uuid_str(str, UUID_STR_FORMAT_STD);
> +		memcpy(fd_ptr, str, UUID_STR_LEN);
> +	}
> +}
> +
> +/*
> + * Helper function to provide some sane factory-data values for testing
> + * purpose, when these values are not programmed correctly
> + */
> +int do_fd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	struct factory_data_values *fd;
> +	struct spi_flash *sf;
> +	u8 *buf;
> +	int ret = CMD_RET_FAILURE;
> +
> +	buf = malloc(FACTORY_DATA_SECT_SIZE);
> +	if (!buf) {
> +		printf("F-Data:Unable to allocate buffer\n");
> +		return CMD_RET_FAILURE;
> +	}
> +
> +	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
> +			     CONFIG_SF_DEFAULT_CS,
> +			     CONFIG_SF_DEFAULT_SPEED,
> +			     CONFIG_SF_DEFAULT_MODE);
> +	if (!sf) {
> +		printf("F-Data:Unable to access SPI NOR flash\n");
> +		goto err;

you should have two goto labels and you should only jump the free() in
this error path otherwise you call sf_flash_free() on a NULL pointer.

> +	}
> +
> +	/* Generate the factory-data struct */
> +
> +	/* Fist read complete sector into buffer */
> +	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
> +			     (void *)buf);
> +	if (ret) {
> +		printf("F-Data:spi_flash_read failed (%d)\n", ret);
> +		goto err;
> +	}
> +
> +	fd = (struct factory_data_values *)buf;
> +	fd->magic = FACTORY_DATA_MAGIC;
> +	fd->version = 0x1;
> +
> +	/* Use existing MAC and UUID values or generate some random ones */
> +	if (!eth_env_get_enetaddr("wifiaddr", fd->wifi_mac)) {
> +		net_random_ethaddr(fd->wifi_mac);
> +		/* to get a different seed value for the MAC address */
> +		mdelay(10);
> +	}
> +
> +	if (!eth_env_get_enetaddr("ethaddr", fd->eth_mac))
> +		net_random_ethaddr(fd->eth_mac);
> +
> +	copy_or_generate_uuid(fd->ipr_id, "linuxmoduleid");
> +	copy_or_generate_uuid(fd->hqv_id, "linuxmodulehqvid");
> +	copy_or_generate_uuid(fd->unielec_id, "linuxmoduleunielecid");
> +
> +	printf("New factory-data values:\n");
> +	printf("wifiaddr=%pM\n", fd->wifi_mac);
> +	printf("ethaddr=%pM\n", fd->eth_mac);
> +
> +	/*
> +	 * We don't have the \0 char at the end, so we need to specify the
> +	 * length in the printf format instead
> +	 */
> +	printf("linuxmoduleid=%." __stringify(UUID_STR_LEN) "s\n", fd->ipr_id);
> +	printf("linuxmodulehqvid=%." __stringify(UUID_STR_LEN) "s\n",
> +	       fd->hqv_id);
> +	printf("linuxmoduleunielecid=%." __stringify(UUID_STR_LEN) "s\n",
> +	       fd->unielec_id);
> +
> +	fd->crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
> +
> +	ret = spi_flash_erase(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE);
> +	if (ret) {
> +		printf("F-Data:spi_flash_erase failed (%d)\n", ret);
> +		goto err;
> +	}
> +
> +	ret = spi_flash_write(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
> +			      buf);
> +	if (ret) {
> +		printf("F-Data:spi_flash_write failed (%d)\n", ret);
> +		goto err;
> +	}
> +
> +	printf("F-Data:factory-data values written to SPI NOR flash\n");
> +	ret = 0;
> +
> +err:
> +	spi_flash_free(sf);
> +
> +	free(buf);
> +
> +	return ret;
> +}
> +
> +U_BOOT_CMD(
> +	fd_write,	1,	0,	do_fd_write,
> +	"Write test factory-data values to SPI NOR",
> +	"\n"
> +);
> 

-- 
- Daniel

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181128/fbbaa8e1/attachment.sig>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH 1/3] mips: mt7628: Change compatible property of the ethernet DT node
  2018-11-28  7:40 [U-Boot] [PATCH 1/3] mips: mt7628: Change compatible property of the ethernet DT node Stefan Roese
  2018-11-28  7:40 ` [U-Boot] [PATCH 2/3] mips: mt76xx: gardena-smart-gateway: Misc updates to defconfig Stefan Roese
  2018-11-28  7:40 ` [U-Boot] [PATCH 3/3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling Stefan Roese
@ 2018-11-28 22:41 ` Daniel Schwierzeck
  2 siblings, 0 replies; 11+ messages in thread
From: Daniel Schwierzeck @ 2018-11-28 22:41 UTC (permalink / raw)
  To: u-boot



Am 28.11.18 um 08:40 schrieb Stefan Roese:
> As the driver has been changed to be more specific, the DT compatible
> property also needs to be adapted.
> 
> Signed-off-by: Stefan Roese <sr@denx.de>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> ---
>  arch/mips/dts/mt7628a.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

applied to u-boot-mips, thanks.

-- 
- Daniel

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181128/ce8cc154/attachment.sig>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH 2/3] mips: mt76xx: gardena-smart-gateway: Misc updates to defconfig
  2018-11-28  7:40 ` [U-Boot] [PATCH 2/3] mips: mt76xx: gardena-smart-gateway: Misc updates to defconfig Stefan Roese
@ 2018-11-28 22:42   ` Daniel Schwierzeck
  0 siblings, 0 replies; 11+ messages in thread
From: Daniel Schwierzeck @ 2018-11-28 22:42 UTC (permalink / raw)
  To: u-boot



Am 28.11.18 um 08:40 schrieb Stefan Roese:
> The following changes are made:
> - Add default bootcmd which can be used for initial start-up
> - Setup necessary MTD parts for Linux compatibility
> 
> Signed-off-by: Stefan Roese <sr@denx.de>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> ---
>  configs/gardena-smart-gateway-mt7688-ram_defconfig | 6 ++++--
>  configs/gardena-smart-gateway-mt7688_defconfig     | 6 ++++--
>  2 files changed, 8 insertions(+), 4 deletions(-)
> 

applied to u-boot-mips, thanks.

-- 
- Daniel

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181128/e9b5d572/attachment.sig>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH 3/3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling
  2018-11-28 22:41   ` Daniel Schwierzeck
@ 2018-11-29 10:01     ` Stefan Roese
  0 siblings, 0 replies; 11+ messages in thread
From: Stefan Roese @ 2018-11-29 10:01 UTC (permalink / raw)
  To: u-boot

On 28.11.18 23:41, Daniel Schwierzeck wrote:
> 
> 
> Am 28.11.18 um 08:40 schrieb Stefan Roese:
>> Some factory data is stored in the SPI NOR and needs to get extracted
>> from there into U-Boot environment variables.
>>
>> This patch also includes a board-specific command "fd_write" to
>> provide some dummy / default values for this factory-data in the SPI
>> NOR flash. This should only be necessary for testing purposes though.
>>
>> Signed-off-by: Stefan Roese <sr@denx.de>
>> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
>> ---
>>   board/gardena/smart-gateway-mt7688/board.c | 266 +++++++++++++++++++++
>>   1 file changed, 266 insertions(+)
> 
> please send a v2 only of this patch. I already applied the other two
> patches. Thanks.

v2 will follow shortly.
  
>>
>> diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
>> index 3a1838e44a..185bdfb71d 100644
>> --- a/board/gardena/smart-gateway-mt7688/board.c
>> +++ b/board/gardena/smart-gateway-mt7688/board.c
>> @@ -4,11 +4,44 @@
>>    */
>>   
>>   #include <common.h>
>> +#include <environment.h>
>>   #include <led.h>
>> +#include <net.h>
>> +#include <spi.h>
>> +#include <spi_flash.h>
>> +#include <uuid.h>
>> +#include <linux/ctype.h>
>>   #include <linux/io.h>
>>   
>>   #define MT76XX_AGPIO_CFG	0x1000003c
>>   
>> +#define FACTORY_DATA_OFFS	0xc0000
>> +#define FACTORY_DATA_SECT_SIZE	0x10000
>> +#if ((CONFIG_ENV_OFFSET_REDUND + CONFIG_ENV_SIZE_REDUND) > FACTORY_DATA_OFFS)
>> +#error "U-Boot image with environment too big (overlapping with factory-data)!"
>> +#endif
>> +#define FACTORY_DATA_USER_OFFS	0x140
>> +#define FACTORY_DATA_SIZE	0x1f0
>> +#define FACTORY_DATA_CRC_LEN	(FACTORY_DATA_SIZE -			\
>> +				 FACTORY_DATA_USER_OFFS - sizeof(u32))
>> +
>> +#define FACTORY_DATA_MAGIC	0xCAFEBABE
>> +
>> +struct factory_data_values {
>> +	u8 pad_1[4];
>> +	u8 wifi_mac[6];		/* offs: 0x004: binary value */
>> +	u8 pad_2[30];
>> +	u8 eth_mac[6];		/* offs: 0x028: binary value */
>> +	u8 pad_3[FACTORY_DATA_USER_OFFS - 4 - 6 - 30 - 6];
>> +	/* User values start here at offset 0x140 */
>> +	u32 crc;
>> +	u32 magic;
>> +	u32 version;
>> +	char ipr_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
>> +	char hqv_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
>> +	char unielec_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
>> +};
>> +
>>   int board_early_init_f(void)
>>   {
>>   	void __iomem *gpio_mode;
>> @@ -20,10 +53,243 @@ int board_early_init_f(void)
>>   	return 0;
>>   }
>>   
>> +static int prepare_uuid_var(char *fd_ptr, char *env_var_name, char errorchar)
> 
> const for the char pointers and bool as return value?

Ack.
  
>> +{
>> +	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
>> +	bool env_updated = 0;
>> +	char *env;
>> +	int i;
>> +
>> +	memset(str, 0, sizeof(str));
>> +	memcpy(str, fd_ptr, UUID_STR_LEN);
> 
> you can avoid the memset() with str[UUID_STR_LEN] = 0;

Ack.
  
>> +
>> +	/* Convert non-ascii character to 'X' */
>> +	for (i = 0; i < UUID_STR_LEN; i++) {
>> +		if (!(isascii(str[i]) && isprint(str[i])))
>> +			str[i] = errorchar;
> 
> can it happen that the string value is shorter than UUID_STR_LEN and is
> zero-terminated? If yes is it intented to fill the remaining characters
> with errorchar?

The string might be shorter and we intentionally want to fill the string
with these chars. This makes not that much sense with '\0', but it
simplifies the code this way.

>> +	}
>> +
>> +	env = env_get(env_var_name);
>> +	if (strcmp(env, str)) {
>> +		env_set(env_var_name, str);
>> +		env_updated = 1;
>> +	}
>> +
>> +	return env_updated;
>> +}
>> +
>> +static void factory_data_env_config(void)
>> +{
>> +	struct factory_data_values *fd;
>> +	struct spi_flash *sf;
>> +	int env_updated = 0;
>> +	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
>> +	char *env;
>> +	u8 *buf;
>> +	u32 crc;
>> +	int ret;
>> +	u8 *ptr;
>> +
>> +	buf = malloc(FACTORY_DATA_SIZE);
>> +	if (!buf) {
>> +		printf("F-Data:Unable to allocate buffer\n");
>> +		goto err;
> 
> this jump to 'err' is incorrect as you would free a NULL poinzer

Ack.

Thanks for the review. I'll change all the other issues as well for
v2.

Thanks,
Stefan

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH 3/3 v2] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling
  2018-11-28  7:40 ` [U-Boot] [PATCH 3/3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling Stefan Roese
  2018-11-28 22:41   ` Daniel Schwierzeck
@ 2018-11-29 10:07   ` Stefan Roese
  2018-11-29 12:15   ` [U-Boot] [PATCH 3/3 v3] " Stefan Roese
  2018-11-30  6:46   ` [U-Boot] [PATCH 3/3 v4] " Stefan Roese
  3 siblings, 0 replies; 11+ messages in thread
From: Stefan Roese @ 2018-11-29 10:07 UTC (permalink / raw)
  To: u-boot

Some factory data is stored in the SPI NOR and needs to get extracted
from there into U-Boot environment variables.

This patch also includes a board-specific command "fd_write" to
provide some dummy / default values for this factory-data in the SPI
NOR flash. This should only be necessary for testing purposes though.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
v2:
- Use "const char *" where possible
- Avoid memset() by assigning value in variable declaration
- Fix goto's with correct cleanup (free, spi_flash_free)
- Change one printf to debug to be less verbose

board/gardena/smart-gateway-mt7688/board.c | 270 +++++++++++++++++++++
 1 file changed, 270 insertions(+)

diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
index 3a1838e44a..db677edd85 100644
--- a/board/gardena/smart-gateway-mt7688/board.c
+++ b/board/gardena/smart-gateway-mt7688/board.c
@@ -4,11 +4,44 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <led.h>
+#include <net.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <uuid.h>
+#include <linux/ctype.h>
 #include <linux/io.h>
 
 #define MT76XX_AGPIO_CFG	0x1000003c
 
+#define FACTORY_DATA_OFFS	0xc0000
+#define FACTORY_DATA_SECT_SIZE	0x10000
+#if ((CONFIG_ENV_OFFSET_REDUND + CONFIG_ENV_SIZE_REDUND) > FACTORY_DATA_OFFS)
+#error "U-Boot image with environment too big (overlapping with factory-data)!"
+#endif
+#define FACTORY_DATA_USER_OFFS	0x140
+#define FACTORY_DATA_SIZE	0x1f0
+#define FACTORY_DATA_CRC_LEN	(FACTORY_DATA_SIZE -			\
+				 FACTORY_DATA_USER_OFFS - sizeof(u32))
+
+#define FACTORY_DATA_MAGIC	0xCAFEBABE
+
+struct factory_data_values {
+	u8 pad_1[4];
+	u8 wifi_mac[6];		/* offs: 0x004: binary value */
+	u8 pad_2[30];
+	u8 eth_mac[6];		/* offs: 0x028: binary value */
+	u8 pad_3[FACTORY_DATA_USER_OFFS - 4 - 6 - 30 - 6];
+	/* User values start here at offset 0x140 */
+	u32 crc;
+	u32 magic;
+	u32 version;
+	char ipr_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+	char hqv_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+	char unielec_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+};
+
 int board_early_init_f(void)
 {
 	void __iomem *gpio_mode;
@@ -20,10 +53,247 @@ int board_early_init_f(void)
 	return 0;
 }
 
+static bool prepare_uuid_var(const char *fd_ptr, const char *env_var_name,
+			     char errorchar)
+{
+	char str[UUID_STR_LEN + 1] = { 0 };	/* Enough for UUID stuff */
+	bool env_updated = false;
+	char *env;
+	int i;
+
+	memcpy(str, fd_ptr, UUID_STR_LEN);
+
+	/* Convert non-ascii character to 'X' */
+	for (i = 0; i < UUID_STR_LEN; i++) {
+		if (!(isascii(str[i]) && isprint(str[i])))
+			str[i] = errorchar;
+	}
+
+	env = env_get(env_var_name);
+	if (strcmp(env, str)) {
+		env_set(env_var_name, str);
+		env_updated = true;
+	}
+
+	return env_updated;
+}
+
+static void factory_data_env_config(void)
+{
+	struct factory_data_values *fd;
+	struct spi_flash *sf;
+	int env_updated = 0;
+	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
+	char *env;
+	u8 *buf;
+	u32 crc;
+	int ret;
+	u8 *ptr;
+
+	buf = malloc(FACTORY_DATA_SIZE);
+	if (!buf) {
+		printf("F-Data:Unable to allocate buffer\n");
+		return;
+	}
+
+	/*
+	 * Get values from factory-data area in SPI NOR
+	 */
+	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+			     CONFIG_SF_DEFAULT_CS,
+			     CONFIG_SF_DEFAULT_SPEED,
+			     CONFIG_SF_DEFAULT_MODE);
+	if (!sf) {
+		printf("F-Data:Unable to access SPI NOR flash\n");
+		goto err_free;
+	}
+
+	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SIZE,
+			     (void *)buf);
+	if (ret) {
+		printf("F-Data:Unable to read factory-data from SPI NOR\n");
+		goto err_spi_flash;
+	}
+
+	fd = (struct factory_data_values *)buf;
+
+	if (fd->magic != FACTORY_DATA_MAGIC)
+		printf("F-Data:Magic value not correct\n");
+
+	crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
+	if (crc != fd->crc)
+		printf("F-Data:CRC not correct\n");
+	else
+		printf("F-Data:factory-data version %x detected\n",
+		       fd->version);
+
+	/* Handle wifi_mac env variable */
+	ptr = fd->wifi_mac;
+	sprintf(str, "%pM", ptr);
+	if (!is_valid_ethaddr(ptr))
+		printf("F-Data:Invalid MAC addr: wifi_mac %s\n", str);
+
+	env = env_get("wifiaddr");
+	if (strcmp(env, str)) {
+		env_set("wifiaddr", str);
+		env_updated = 1;
+	}
+
+	/* Handle eth_mac env variable */
+	ptr = fd->eth_mac;
+	sprintf(str, "%pM", ptr);
+	if (!is_valid_ethaddr(ptr))
+		printf("F-Data:Invalid MAC addr: eth_mac %s\n", str);
+
+	env = env_get("ethaddr");
+	if (strcmp(env, str)) {
+		env_set("ethaddr", str);
+		env_updated = 1;
+	}
+
+	/* Handle UUID env variables */
+	env_updated |= prepare_uuid_var(fd->ipr_id, "linuxmoduleid", 'X');
+	env_updated |= prepare_uuid_var(fd->hqv_id, "linuxmodulehqvid", '\0');
+	env_updated |= prepare_uuid_var(fd->unielec_id,
+					"linuxmoduleunielecid", 'X');
+
+	/* Check if the environment was updated and needs to get stored */
+	if (env_updated != 0) {
+		printf("F-Data:Values don't match env values -> saving\n");
+		env_save();
+	} else {
+		debug("F-Data:Values match current env values\n");
+	}
+
+err_spi_flash:
+	spi_flash_free(sf);
+
+err_free:
+	free(buf);
+}
+
 int board_late_init(void)
 {
 	if (IS_ENABLED(CONFIG_LED))
 		led_default_state();
 
+	factory_data_env_config();
+
 	return 0;
 }
+
+static void copy_or_generate_uuid(char *fd_ptr, const char *env_var_name)
+{
+	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
+	char *env;
+
+	/* Don't use the UUID dest place, as the \0 char won't fit */
+	env = env_get(env_var_name);
+	if (env) {
+		memcpy(fd_ptr, env, UUID_STR_LEN);
+	} else {
+		gen_rand_uuid_str(str, UUID_STR_FORMAT_STD);
+		memcpy(fd_ptr, str, UUID_STR_LEN);
+	}
+}
+
+/*
+ * Helper function to provide some sane factory-data values for testing
+ * purpose, when these values are not programmed correctly
+ */
+int do_fd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct factory_data_values *fd;
+	struct spi_flash *sf;
+	u8 *buf;
+	int ret = CMD_RET_FAILURE;
+
+	buf = malloc(FACTORY_DATA_SECT_SIZE);
+	if (!buf) {
+		printf("F-Data:Unable to allocate buffer\n");
+		return CMD_RET_FAILURE;
+	}
+
+	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+			     CONFIG_SF_DEFAULT_CS,
+			     CONFIG_SF_DEFAULT_SPEED,
+			     CONFIG_SF_DEFAULT_MODE);
+	if (!sf) {
+		printf("F-Data:Unable to access SPI NOR flash\n");
+		goto err_free;
+	}
+
+	/* Generate the factory-data struct */
+
+	/* Fist read complete sector into buffer */
+	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
+			     (void *)buf);
+	if (ret) {
+		printf("F-Data:spi_flash_read failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	fd = (struct factory_data_values *)buf;
+	fd->magic = FACTORY_DATA_MAGIC;
+	fd->version = 0x1;
+
+	/* Use existing MAC and UUID values or generate some random ones */
+	if (!eth_env_get_enetaddr("wifiaddr", fd->wifi_mac)) {
+		net_random_ethaddr(fd->wifi_mac);
+		/* to get a different seed value for the MAC address */
+		mdelay(10);
+	}
+
+	if (!eth_env_get_enetaddr("ethaddr", fd->eth_mac))
+		net_random_ethaddr(fd->eth_mac);
+
+	copy_or_generate_uuid(fd->ipr_id, "linuxmoduleid");
+	copy_or_generate_uuid(fd->hqv_id, "linuxmodulehqvid");
+	copy_or_generate_uuid(fd->unielec_id, "linuxmoduleunielecid");
+
+	printf("New factory-data values:\n");
+	printf("wifiaddr=%pM\n", fd->wifi_mac);
+	printf("ethaddr=%pM\n", fd->eth_mac);
+
+	/*
+	 * We don't have the \0 char at the end, so we need to specify the
+	 * length in the printf format instead
+	 */
+	printf("linuxmoduleid=%." __stringify(UUID_STR_LEN) "s\n", fd->ipr_id);
+	printf("linuxmodulehqvid=%." __stringify(UUID_STR_LEN) "s\n",
+	       fd->hqv_id);
+	printf("linuxmoduleunielecid=%." __stringify(UUID_STR_LEN) "s\n",
+	       fd->unielec_id);
+
+	fd->crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
+
+	ret = spi_flash_erase(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE);
+	if (ret) {
+		printf("F-Data:spi_flash_erase failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	ret = spi_flash_write(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
+			      buf);
+	if (ret) {
+		printf("F-Data:spi_flash_write failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	printf("F-Data:factory-data values written to SPI NOR flash\n");
+	ret = 0;
+
+err_spi_flash:
+	spi_flash_free(sf);
+
+err_free:
+	free(buf);
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	fd_write,	1,	0,	do_fd_write,
+	"Write test factory-data values to SPI NOR",
+	"\n"
+);
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH 3/3 v3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling
  2018-11-28  7:40 ` [U-Boot] [PATCH 3/3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling Stefan Roese
  2018-11-28 22:41   ` Daniel Schwierzeck
  2018-11-29 10:07   ` [U-Boot] [PATCH 3/3 v2] " Stefan Roese
@ 2018-11-29 12:15   ` Stefan Roese
  2018-11-30  6:46   ` [U-Boot] [PATCH 3/3 v4] " Stefan Roese
  3 siblings, 0 replies; 11+ messages in thread
From: Stefan Roese @ 2018-11-29 12:15 UTC (permalink / raw)
  To: u-boot

Some factory data is stored in the SPI NOR and needs to get extracted
from there into U-Boot environment variables.

This patch also includes a board-specific command "fd_write" to
provide some dummy / default values for this factory-data in the SPI
NOR flash. This should only be necessary for testing purposes though.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
v3:
- Remove unnecessary ret = 0 assignment in do_fd_write()
- Change copy_or_generate_uuid() to not generate random values after
  the terminating char

v2:
- Use "const char *" where possible
- Avoid memset() by assigning value in variable declaration
- Fix goto's with correct cleanup (free, spi_flash_free)
- Change one printf to debug to be less verbose

 board/gardena/smart-gateway-mt7688/board.c | 269 +++++++++++++++++++++
 1 file changed, 269 insertions(+)

diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
index 3a1838e44a..476139e1b2 100644
--- a/board/gardena/smart-gateway-mt7688/board.c
+++ b/board/gardena/smart-gateway-mt7688/board.c
@@ -4,11 +4,44 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <led.h>
+#include <net.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <uuid.h>
+#include <linux/ctype.h>
 #include <linux/io.h>
 
 #define MT76XX_AGPIO_CFG	0x1000003c
 
+#define FACTORY_DATA_OFFS	0xc0000
+#define FACTORY_DATA_SECT_SIZE	0x10000
+#if ((CONFIG_ENV_OFFSET_REDUND + CONFIG_ENV_SIZE_REDUND) > FACTORY_DATA_OFFS)
+#error "U-Boot image with environment too big (overlapping with factory-data)!"
+#endif
+#define FACTORY_DATA_USER_OFFS	0x140
+#define FACTORY_DATA_SIZE	0x1f0
+#define FACTORY_DATA_CRC_LEN	(FACTORY_DATA_SIZE -			\
+				 FACTORY_DATA_USER_OFFS - sizeof(u32))
+
+#define FACTORY_DATA_MAGIC	0xCAFEBABE
+
+struct factory_data_values {
+	u8 pad_1[4];
+	u8 wifi_mac[6];		/* offs: 0x004: binary value */
+	u8 pad_2[30];
+	u8 eth_mac[6];		/* offs: 0x028: binary value */
+	u8 pad_3[FACTORY_DATA_USER_OFFS - 4 - 6 - 30 - 6];
+	/* User values start here at offset 0x140 */
+	u32 crc;
+	u32 magic;
+	u32 version;
+	char ipr_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+	char hqv_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+	char unielec_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+};
+
 int board_early_init_f(void)
 {
 	void __iomem *gpio_mode;
@@ -20,10 +53,246 @@ int board_early_init_f(void)
 	return 0;
 }
 
+static bool prepare_uuid_var(const char *fd_ptr, const char *env_var_name,
+			     char errorchar)
+{
+	char str[UUID_STR_LEN + 1] = { 0 };	/* Enough for UUID stuff */
+	bool env_updated = false;
+	char *env;
+	int i;
+
+	memcpy(str, fd_ptr, UUID_STR_LEN);
+
+	/* Convert non-ascii character to 'X' */
+	for (i = 0; i < UUID_STR_LEN; i++) {
+		if (!(isascii(str[i]) && isprint(str[i])))
+			str[i] = errorchar;
+	}
+
+	env = env_get(env_var_name);
+	if (strcmp(env, str)) {
+		env_set(env_var_name, str);
+		env_updated = true;
+	}
+
+	return env_updated;
+}
+
+static void factory_data_env_config(void)
+{
+	struct factory_data_values *fd;
+	struct spi_flash *sf;
+	int env_updated = 0;
+	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
+	char *env;
+	u8 *buf;
+	u32 crc;
+	int ret;
+	u8 *ptr;
+
+	buf = malloc(FACTORY_DATA_SIZE);
+	if (!buf) {
+		printf("F-Data:Unable to allocate buffer\n");
+		return;
+	}
+
+	/*
+	 * Get values from factory-data area in SPI NOR
+	 */
+	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+			     CONFIG_SF_DEFAULT_CS,
+			     CONFIG_SF_DEFAULT_SPEED,
+			     CONFIG_SF_DEFAULT_MODE);
+	if (!sf) {
+		printf("F-Data:Unable to access SPI NOR flash\n");
+		goto err_free;
+	}
+
+	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SIZE,
+			     (void *)buf);
+	if (ret) {
+		printf("F-Data:Unable to read factory-data from SPI NOR\n");
+		goto err_spi_flash;
+	}
+
+	fd = (struct factory_data_values *)buf;
+
+	if (fd->magic != FACTORY_DATA_MAGIC)
+		printf("F-Data:Magic value not correct\n");
+
+	crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
+	if (crc != fd->crc)
+		printf("F-Data:CRC not correct\n");
+	else
+		printf("F-Data:factory-data version %x detected\n",
+		       fd->version);
+
+	/* Handle wifi_mac env variable */
+	ptr = fd->wifi_mac;
+	sprintf(str, "%pM", ptr);
+	if (!is_valid_ethaddr(ptr))
+		printf("F-Data:Invalid MAC addr: wifi_mac %s\n", str);
+
+	env = env_get("wifiaddr");
+	if (strcmp(env, str)) {
+		env_set("wifiaddr", str);
+		env_updated = 1;
+	}
+
+	/* Handle eth_mac env variable */
+	ptr = fd->eth_mac;
+	sprintf(str, "%pM", ptr);
+	if (!is_valid_ethaddr(ptr))
+		printf("F-Data:Invalid MAC addr: eth_mac %s\n", str);
+
+	env = env_get("ethaddr");
+	if (strcmp(env, str)) {
+		env_set("ethaddr", str);
+		env_updated = 1;
+	}
+
+	/* Handle UUID env variables */
+	env_updated |= prepare_uuid_var(fd->ipr_id, "linuxmoduleid", 'X');
+	env_updated |= prepare_uuid_var(fd->hqv_id, "linuxmodulehqvid", '\0');
+	env_updated |= prepare_uuid_var(fd->unielec_id,
+					"linuxmoduleunielecid", 'X');
+
+	/* Check if the environment was updated and needs to get stored */
+	if (env_updated != 0) {
+		printf("F-Data:Values don't match env values -> saving\n");
+		env_save();
+	} else {
+		debug("F-Data:Values match current env values\n");
+	}
+
+err_spi_flash:
+	spi_flash_free(sf);
+
+err_free:
+	free(buf);
+}
+
 int board_late_init(void)
 {
 	if (IS_ENABLED(CONFIG_LED))
 		led_default_state();
 
+	factory_data_env_config();
+
 	return 0;
 }
+
+static void copy_or_generate_uuid(char *fd_ptr, const char *env_var_name)
+{
+	char str[UUID_STR_LEN + 1] = { 0 };	/* Enough for UUID stuff */
+	char *env;
+
+	/* Don't use the UUID dest place, as the \0 char won't fit */
+	env = env_get(env_var_name);
+	if (env)
+		strncpy(str, env, UUID_STR_LEN);
+	else
+		gen_rand_uuid_str(str, UUID_STR_FORMAT_STD);
+
+	memcpy(fd_ptr, str, UUID_STR_LEN);
+}
+
+/*
+ * Helper function to provide some sane factory-data values for testing
+ * purpose, when these values are not programmed correctly
+ */
+int do_fd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct factory_data_values *fd;
+	struct spi_flash *sf;
+	u8 *buf;
+	int ret = CMD_RET_FAILURE;
+
+	buf = malloc(FACTORY_DATA_SECT_SIZE);
+	if (!buf) {
+		printf("F-Data:Unable to allocate buffer\n");
+		return CMD_RET_FAILURE;
+	}
+
+	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+			     CONFIG_SF_DEFAULT_CS,
+			     CONFIG_SF_DEFAULT_SPEED,
+			     CONFIG_SF_DEFAULT_MODE);
+	if (!sf) {
+		printf("F-Data:Unable to access SPI NOR flash\n");
+		goto err_free;
+	}
+
+	/* Generate the factory-data struct */
+
+	/* Fist read complete sector into buffer */
+	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
+			     (void *)buf);
+	if (ret) {
+		printf("F-Data:spi_flash_read failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	fd = (struct factory_data_values *)buf;
+	fd->magic = FACTORY_DATA_MAGIC;
+	fd->version = 0x1;
+
+	/* Use existing MAC and UUID values or generate some random ones */
+	if (!eth_env_get_enetaddr("wifiaddr", fd->wifi_mac)) {
+		net_random_ethaddr(fd->wifi_mac);
+		/* to get a different seed value for the MAC address */
+		mdelay(10);
+	}
+
+	if (!eth_env_get_enetaddr("ethaddr", fd->eth_mac))
+		net_random_ethaddr(fd->eth_mac);
+
+	copy_or_generate_uuid(fd->ipr_id, "linuxmoduleid");
+	copy_or_generate_uuid(fd->hqv_id, "linuxmodulehqvid");
+	copy_or_generate_uuid(fd->unielec_id, "linuxmoduleunielecid");
+
+	printf("New factory-data values:\n");
+	printf("wifiaddr=%pM\n", fd->wifi_mac);
+	printf("ethaddr=%pM\n", fd->eth_mac);
+
+	/*
+	 * We don't have the \0 char at the end, so we need to specify the
+	 * length in the printf format instead
+	 */
+	printf("linuxmoduleid=%." __stringify(UUID_STR_LEN) "s\n", fd->ipr_id);
+	printf("linuxmodulehqvid=%." __stringify(UUID_STR_LEN) "s\n",
+	       fd->hqv_id);
+	printf("linuxmoduleunielecid=%." __stringify(UUID_STR_LEN) "s\n",
+	       fd->unielec_id);
+
+	fd->crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
+
+	ret = spi_flash_erase(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE);
+	if (ret) {
+		printf("F-Data:spi_flash_erase failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	ret = spi_flash_write(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
+			      buf);
+	if (ret) {
+		printf("F-Data:spi_flash_write failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	printf("F-Data:factory-data values written to SPI NOR flash\n");
+
+err_spi_flash:
+	spi_flash_free(sf);
+
+err_free:
+	free(buf);
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	fd_write,	1,	0,	do_fd_write,
+	"Write test factory-data values to SPI NOR",
+	"\n"
+);
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH 3/3 v4] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling
  2018-11-28  7:40 ` [U-Boot] [PATCH 3/3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling Stefan Roese
                     ` (2 preceding siblings ...)
  2018-11-29 12:15   ` [U-Boot] [PATCH 3/3 v3] " Stefan Roese
@ 2018-11-30  6:46   ` Stefan Roese
  2018-11-30 16:16     ` Daniel Schwierzeck
  3 siblings, 1 reply; 11+ messages in thread
From: Stefan Roese @ 2018-11-30  6:46 UTC (permalink / raw)
  To: u-boot

Some factory data is stored in the SPI NOR and needs to get extracted
from there into U-Boot environment variables.

This patch also includes a board-specific command "fd_write" to
provide some dummy / default values for this factory-data in the SPI
NOR flash. This should only be necessary for testing purposes though.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
v4:
- Change end-char for "linuxmoduleunielecid"

v3:
- Remove unnecessary ret = 0 assignment in do_fd_write()
- Change copy_or_generate_uuid() to not generate random values after
  the terminating char

v2:
- Use "const char *" where possible
- Avoid memset() by assigning value in variable declaration
- Fix goto's with correct cleanup (free, spi_flash_free)
- Change one printf to debug to be less verbose

Daniel, sorry for all these version. I really hope that this is the
last version.

Thanks,
Stefan

 board/gardena/smart-gateway-mt7688/board.c | 269 +++++++++++++++++++++
 1 file changed, 269 insertions(+)

diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
index 3a1838e44a..6e11077977 100644
--- a/board/gardena/smart-gateway-mt7688/board.c
+++ b/board/gardena/smart-gateway-mt7688/board.c
@@ -4,11 +4,44 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <led.h>
+#include <net.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <uuid.h>
+#include <linux/ctype.h>
 #include <linux/io.h>
 
 #define MT76XX_AGPIO_CFG	0x1000003c
 
+#define FACTORY_DATA_OFFS	0xc0000
+#define FACTORY_DATA_SECT_SIZE	0x10000
+#if ((CONFIG_ENV_OFFSET_REDUND + CONFIG_ENV_SIZE_REDUND) > FACTORY_DATA_OFFS)
+#error "U-Boot image with environment too big (overlapping with factory-data)!"
+#endif
+#define FACTORY_DATA_USER_OFFS	0x140
+#define FACTORY_DATA_SIZE	0x1f0
+#define FACTORY_DATA_CRC_LEN	(FACTORY_DATA_SIZE -			\
+				 FACTORY_DATA_USER_OFFS - sizeof(u32))
+
+#define FACTORY_DATA_MAGIC	0xCAFEBABE
+
+struct factory_data_values {
+	u8 pad_1[4];
+	u8 wifi_mac[6];		/* offs: 0x004: binary value */
+	u8 pad_2[30];
+	u8 eth_mac[6];		/* offs: 0x028: binary value */
+	u8 pad_3[FACTORY_DATA_USER_OFFS - 4 - 6 - 30 - 6];
+	/* User values start here at offset 0x140 */
+	u32 crc;
+	u32 magic;
+	u32 version;
+	char ipr_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+	char hqv_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+	char unielec_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+};
+
 int board_early_init_f(void)
 {
 	void __iomem *gpio_mode;
@@ -20,10 +53,246 @@ int board_early_init_f(void)
 	return 0;
 }
 
+static bool prepare_uuid_var(const char *fd_ptr, const char *env_var_name,
+			     char errorchar)
+{
+	char str[UUID_STR_LEN + 1] = { 0 };	/* Enough for UUID stuff */
+	bool env_updated = false;
+	char *env;
+	int i;
+
+	memcpy(str, fd_ptr, UUID_STR_LEN);
+
+	/* Convert non-ascii character to 'X' */
+	for (i = 0; i < UUID_STR_LEN; i++) {
+		if (!(isascii(str[i]) && isprint(str[i])))
+			str[i] = errorchar;
+	}
+
+	env = env_get(env_var_name);
+	if (strcmp(env, str)) {
+		env_set(env_var_name, str);
+		env_updated = true;
+	}
+
+	return env_updated;
+}
+
+static void factory_data_env_config(void)
+{
+	struct factory_data_values *fd;
+	struct spi_flash *sf;
+	int env_updated = 0;
+	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
+	char *env;
+	u8 *buf;
+	u32 crc;
+	int ret;
+	u8 *ptr;
+
+	buf = malloc(FACTORY_DATA_SIZE);
+	if (!buf) {
+		printf("F-Data:Unable to allocate buffer\n");
+		return;
+	}
+
+	/*
+	 * Get values from factory-data area in SPI NOR
+	 */
+	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+			     CONFIG_SF_DEFAULT_CS,
+			     CONFIG_SF_DEFAULT_SPEED,
+			     CONFIG_SF_DEFAULT_MODE);
+	if (!sf) {
+		printf("F-Data:Unable to access SPI NOR flash\n");
+		goto err_free;
+	}
+
+	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SIZE,
+			     (void *)buf);
+	if (ret) {
+		printf("F-Data:Unable to read factory-data from SPI NOR\n");
+		goto err_spi_flash;
+	}
+
+	fd = (struct factory_data_values *)buf;
+
+	if (fd->magic != FACTORY_DATA_MAGIC)
+		printf("F-Data:Magic value not correct\n");
+
+	crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
+	if (crc != fd->crc)
+		printf("F-Data:CRC not correct\n");
+	else
+		printf("F-Data:factory-data version %x detected\n",
+		       fd->version);
+
+	/* Handle wifi_mac env variable */
+	ptr = fd->wifi_mac;
+	sprintf(str, "%pM", ptr);
+	if (!is_valid_ethaddr(ptr))
+		printf("F-Data:Invalid MAC addr: wifi_mac %s\n", str);
+
+	env = env_get("wifiaddr");
+	if (strcmp(env, str)) {
+		env_set("wifiaddr", str);
+		env_updated = 1;
+	}
+
+	/* Handle eth_mac env variable */
+	ptr = fd->eth_mac;
+	sprintf(str, "%pM", ptr);
+	if (!is_valid_ethaddr(ptr))
+		printf("F-Data:Invalid MAC addr: eth_mac %s\n", str);
+
+	env = env_get("ethaddr");
+	if (strcmp(env, str)) {
+		env_set("ethaddr", str);
+		env_updated = 1;
+	}
+
+	/* Handle UUID env variables */
+	env_updated |= prepare_uuid_var(fd->ipr_id, "linuxmoduleid", 'X');
+	env_updated |= prepare_uuid_var(fd->hqv_id, "linuxmodulehqvid", '\0');
+	env_updated |= prepare_uuid_var(fd->unielec_id,
+					"linuxmoduleunielecid", '\0');
+
+	/* Check if the environment was updated and needs to get stored */
+	if (env_updated != 0) {
+		printf("F-Data:Values don't match env values -> saving\n");
+		env_save();
+	} else {
+		debug("F-Data:Values match current env values\n");
+	}
+
+err_spi_flash:
+	spi_flash_free(sf);
+
+err_free:
+	free(buf);
+}
+
 int board_late_init(void)
 {
 	if (IS_ENABLED(CONFIG_LED))
 		led_default_state();
 
+	factory_data_env_config();
+
 	return 0;
 }
+
+static void copy_or_generate_uuid(char *fd_ptr, const char *env_var_name)
+{
+	char str[UUID_STR_LEN + 1] = { 0 };	/* Enough for UUID stuff */
+	char *env;
+
+	/* Don't use the UUID dest place, as the \0 char won't fit */
+	env = env_get(env_var_name);
+	if (env)
+		strncpy(str, env, UUID_STR_LEN);
+	else
+		gen_rand_uuid_str(str, UUID_STR_FORMAT_STD);
+
+	memcpy(fd_ptr, str, UUID_STR_LEN);
+}
+
+/*
+ * Helper function to provide some sane factory-data values for testing
+ * purpose, when these values are not programmed correctly
+ */
+int do_fd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct factory_data_values *fd;
+	struct spi_flash *sf;
+	u8 *buf;
+	int ret = CMD_RET_FAILURE;
+
+	buf = malloc(FACTORY_DATA_SECT_SIZE);
+	if (!buf) {
+		printf("F-Data:Unable to allocate buffer\n");
+		return CMD_RET_FAILURE;
+	}
+
+	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+			     CONFIG_SF_DEFAULT_CS,
+			     CONFIG_SF_DEFAULT_SPEED,
+			     CONFIG_SF_DEFAULT_MODE);
+	if (!sf) {
+		printf("F-Data:Unable to access SPI NOR flash\n");
+		goto err_free;
+	}
+
+	/* Generate the factory-data struct */
+
+	/* Fist read complete sector into buffer */
+	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
+			     (void *)buf);
+	if (ret) {
+		printf("F-Data:spi_flash_read failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	fd = (struct factory_data_values *)buf;
+	fd->magic = FACTORY_DATA_MAGIC;
+	fd->version = 0x1;
+
+	/* Use existing MAC and UUID values or generate some random ones */
+	if (!eth_env_get_enetaddr("wifiaddr", fd->wifi_mac)) {
+		net_random_ethaddr(fd->wifi_mac);
+		/* to get a different seed value for the MAC address */
+		mdelay(10);
+	}
+
+	if (!eth_env_get_enetaddr("ethaddr", fd->eth_mac))
+		net_random_ethaddr(fd->eth_mac);
+
+	copy_or_generate_uuid(fd->ipr_id, "linuxmoduleid");
+	copy_or_generate_uuid(fd->hqv_id, "linuxmodulehqvid");
+	copy_or_generate_uuid(fd->unielec_id, "linuxmoduleunielecid");
+
+	printf("New factory-data values:\n");
+	printf("wifiaddr=%pM\n", fd->wifi_mac);
+	printf("ethaddr=%pM\n", fd->eth_mac);
+
+	/*
+	 * We don't have the \0 char at the end, so we need to specify the
+	 * length in the printf format instead
+	 */
+	printf("linuxmoduleid=%." __stringify(UUID_STR_LEN) "s\n", fd->ipr_id);
+	printf("linuxmodulehqvid=%." __stringify(UUID_STR_LEN) "s\n",
+	       fd->hqv_id);
+	printf("linuxmoduleunielecid=%." __stringify(UUID_STR_LEN) "s\n",
+	       fd->unielec_id);
+
+	fd->crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
+
+	ret = spi_flash_erase(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE);
+	if (ret) {
+		printf("F-Data:spi_flash_erase failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	ret = spi_flash_write(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
+			      buf);
+	if (ret) {
+		printf("F-Data:spi_flash_write failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	printf("F-Data:factory-data values written to SPI NOR flash\n");
+
+err_spi_flash:
+	spi_flash_free(sf);
+
+err_free:
+	free(buf);
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	fd_write,	1,	0,	do_fd_write,
+	"Write test factory-data values to SPI NOR",
+	"\n"
+);
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH 3/3 v4] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling
  2018-11-30  6:46   ` [U-Boot] [PATCH 3/3 v4] " Stefan Roese
@ 2018-11-30 16:16     ` Daniel Schwierzeck
  0 siblings, 0 replies; 11+ messages in thread
From: Daniel Schwierzeck @ 2018-11-30 16:16 UTC (permalink / raw)
  To: u-boot



Am 30.11.18 um 07:46 schrieb Stefan Roese:
> Some factory data is stored in the SPI NOR and needs to get extracted
> from there into U-Boot environment variables.
> 
> This patch also includes a board-specific command "fd_write" to
> provide some dummy / default values for this factory-data in the SPI
> NOR flash. This should only be necessary for testing purposes though.
> 
> Signed-off-by: Stefan Roese <sr@denx.de>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> ---
> v4:
> - Change end-char for "linuxmoduleunielecid"
> 
> v3:
> - Remove unnecessary ret = 0 assignment in do_fd_write()
> - Change copy_or_generate_uuid() to not generate random values after
>   the terminating char
> 
> v2:
> - Use "const char *" where possible
> - Avoid memset() by assigning value in variable declaration
> - Fix goto's with correct cleanup (free, spi_flash_free)
> - Change one printf to debug to be less verbose
> 
> Daniel, sorry for all these version. I really hope that this is the
> last version.
> 
> Thanks,
> Stefan
> 
>  board/gardena/smart-gateway-mt7688/board.c | 269 +++++++++++++++++++++
>  1 file changed, 269 insertions(+)
> 

applied to u-boot-mips, thanks.

-- 
- Daniel

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181130/1e918bcf/attachment.sig>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-11-30 16:16 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-28  7:40 [U-Boot] [PATCH 1/3] mips: mt7628: Change compatible property of the ethernet DT node Stefan Roese
2018-11-28  7:40 ` [U-Boot] [PATCH 2/3] mips: mt76xx: gardena-smart-gateway: Misc updates to defconfig Stefan Roese
2018-11-28 22:42   ` Daniel Schwierzeck
2018-11-28  7:40 ` [U-Boot] [PATCH 3/3] mips: mt76xx: gardena-smart-gateway: Add factory data variable handling Stefan Roese
2018-11-28 22:41   ` Daniel Schwierzeck
2018-11-29 10:01     ` Stefan Roese
2018-11-29 10:07   ` [U-Boot] [PATCH 3/3 v2] " Stefan Roese
2018-11-29 12:15   ` [U-Boot] [PATCH 3/3 v3] " Stefan Roese
2018-11-30  6:46   ` [U-Boot] [PATCH 3/3 v4] " Stefan Roese
2018-11-30 16:16     ` Daniel Schwierzeck
2018-11-28 22:41 ` [U-Boot] [PATCH 1/3] mips: mt7628: Change compatible property of the ethernet DT node Daniel Schwierzeck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.