[PATCH v2 7/7] ARM: socfpga: AA1: support MAC from secure eeprom

Marek Vasut marex at denx.de
Sun Sep 22 23:40:45 CEST 2024


On 9/17/24 8:21 AM, Lothar Rubusch wrote:

[...]

> +int enclustra_get_mac_from_eeprom(unsigned char *enetaddr, const char *alias)
> +{
> +	struct udevice *dev;
> +	u32 hwaddr_h;
> +	u8 data[4];
> +	int i, j, eeprom_addr, mac_len, ret;
> +
> +	ret = uclass_get_device_by_name(UCLASS_MISC, alias, &dev);
> +	if (ret) {
> +		printf("%s: Failed, cannot find EEPROM! ret = %d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	/* Make sure atsha204a is in a defined state (part of protocol) */
> +	if (atsha204a_sleep(dev)) {

Please propagate return values.

> +		printf("%s(): Failed to bring EEPROM in defined state\n", __func__);
> +		return -ENODEV;
> +	}
> +
> +	if (atsha204a_wakeup(dev)) {
> +		printf("%s(): Failed to wakeup EEPROM\n", __func__);
> +		return -ENODEV;
> +	}
> +
> +	/* Read twice portions of 4 bytes (atsha204 protocol). One from address 4

Use Linux comment style, not netdev:

/*
  * Read some
  * stuff
  * and so on
  */

> +	 * the other from address 5 of the OTP zone. Then convert the data to
> +	 * the 6 elements of the MAC address.
> +	 */
> +	eeprom_addr = 4;
> +	mac_len = 6;

These can be const variables assigned at the beginning of this function.

> +	for (i = 0; i < 2; i++) {
> +		eeprom_addr += i;
> +		if (atsha204a_read(dev, ATSHA204A_ZONE_OTP, false, eeprom_addr, data)) {
> +			printf("%s(): Failed to parse ATSHA204A_ZONE_OTP of EEPROM\n",
> +			       __func__);
> +			return -EFAULT;
> +		}
> +
> +		for (j = 0; j < 4 && j + i * 4 < mac_len; j++)
> +			enetaddr[j + i * 4] = data[j];
> +	}
> +
> +	/* Check if the value is a valid mac registered for
> +	 * Enclustra  GmbH
> +	 */
> +	hwaddr_h = enetaddr[0] | enetaddr[1] << 8 | enetaddr[2] << 16;
> +	if ((hwaddr_h & 0xFFFFFF) != ENCLUSTRA_MAC) {
> +		printf("%s(): Failed, parsed MAC is no Enclustra MAC\n", __func__);
> +		return -ENOENT;
> +	}
> +
> +	if (!is_valid_ethaddr(enetaddr)) {
> +		printf("%s(): Failed, address read from EEPROM is invalid!\n",
> +		       __func__);
> +		return -EINVAL;
> +	}
> +
> +	printf("ethaddr set to %02X:%02X:%02X:%02X:%02X:%02X\n",
> +	       enetaddr[0], enetaddr[1], enetaddr[2],
> +	       enetaddr[3], enetaddr[4], enetaddr[5]);

This should be:

debug("ethaddr set to %pM\n", ethaddr);

see lib/vsprintf.c for the formatting strings.

> +	return 0;
> +}
> +
> +__weak int enclustra_setup_mac_address(void)
> +{
> +	unsigned char enetaddr[6];
> +
> +	if (enclustra_mac_is_in_env("ethaddr"))
> +		return 0;
> +
> +	if (enclustra_get_mac_is_enabled("ethernet0"))
> +		return 0;
> +
> +	if (enclustra_get_mac_from_eeprom(enetaddr, "atsha204a at 64"))

Please propagate return values, fix globally.

> +		return -ENXIO;
> +
> +	if (eth_env_set_enetaddr("ethaddr", enetaddr))
> +		return -ENXIO;
> +
> +	if (!enclustra_get_mac1_from_mac(enetaddr))
> +		return eth_env_set_enetaddr("eth1addr", enetaddr);
> +
> +	printf("%s(): Failed, unable to set mac address!\n", __func__);
> +	return -ENXIO;
> +}

[...]

> +int enclustra_get_mac1_from_mac(unsigned char *enetaddr)
> +{
> +	u32 hwaddr_h;
> +
> +	/* Increment MAC addr */
> +	hwaddr_h = (enetaddr[3] << 16) | (enetaddr[4] << 8) | enetaddr[5];
> +	hwaddr_h = (hwaddr_h + 1) & 0xFFFFFF;
> +	enetaddr[3] = (hwaddr_h >> 16) & 0xFF;
> +	enetaddr[4] = (hwaddr_h >> 8) & 0xFF;
> +	enetaddr[5] = hwaddr_h & 0xFF;
> +
> +	if (!is_valid_ethaddr(enetaddr)) {
> +		printf("%s(): Failed, address computed from enetaddr is invalid!\n",
> +		       __func__);
> +		return -EINVAL;
> +	}
> +
> +	printf("eth1addr set to %02X:%02X:%02X:%02X:%02X:%02X\n",
> +	       enetaddr[0], enetaddr[1], enetaddr[2],
> +	       enetaddr[3], enetaddr[4], enetaddr[5]);

debug("... %pM\n", enetaddr);

> +	return 0;
> +}
> diff --git a/board/enclustra/common/mac_ds28.c b/board/enclustra/common/mac_ds28.c
> new file mode 100644
> index 0000000000..9aed4f1de1
> --- /dev/null
> +++ b/board/enclustra/common/mac_ds28.c
> @@ -0,0 +1,88 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2024 Enclustra GmbH
> + */
> +
> +#include <linux/compat.h>
> +#include <dm.h>
> +#include <i2c.h>
> +#include <net.h>
> +
> +#include "enclustra_mac.h"
> +
> +#define DS28_I2C_ADDR 0x5C
> +#define DS28_SYS_I2C_EEPROM_BUS 0
> +
> +int enclustra_get_mac_from_eeprom(unsigned char *enetaddr, const char *alias)
> +{
> +	struct udevice *dev;
> +	u32 hwaddr_h;
> +	struct dm_i2c_chip *chip;
> +	uint chip_addr = DS28_I2C_ADDR;
> +	int alen = 1;
> +	int ret;
> +
> +	if (i2c_get_chip_for_busnum(DS28_SYS_I2C_EEPROM_BUS, chip_addr,
> +				    alen, &dev))
> +		return -ENODEV;
> +
> +	chip = dev_get_parent_plat(dev);
> +	if (chip->offset_len != alen) {
> +		debug("I2C chip %x: alen %d does not match offset_len %d\n",
> +		      chip_addr, alen, chip->offset_len);
> +		return -EADDRNOTAVAIL;
> +	}
> +
> +	ret = dm_i2c_read(dev, 0x10, enetaddr, 6);
> +	if (ret) {
> +		printf("%s(): Failed reading EEPROM! ret = %d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	/* Check if the value is a valid mac registered for
> +	 * Enclustra  GmbH
> +	 */
> +	hwaddr_h = enetaddr[0] | enetaddr[1] << 8 | enetaddr[2] << 16;

Better use () around the shifts, i.e. ... | (enetaddr[i] << 8) | ...

> +	if ((hwaddr_h & 0xFFFFFF) != ENCLUSTRA_MAC) {
> +		printf("%s(): Failed, parsed MAC is no Enclustra MAC\n", __func__);
> +		return -ENOENT;
> +	}
> +
> +	if (!is_valid_ethaddr(enetaddr)) {
> +		printf("%s(): Failed, address read from EEPROM is invalid!\n",
> +		       __func__);
> +		return -EINVAL;
> +	}
> +
> +	printf("ethaddr set to %02X:%02X:%02X:%02X:%02X:%02X\n",
> +	       enetaddr[0], enetaddr[1], enetaddr[2],
> +	       enetaddr[3], enetaddr[4], enetaddr[5]);
> +
> +	return 0;
> +}
> +
> +__weak int enclustra_setup_mac_address(void)

Is the __weak really necessary ?

> +{
> +	unsigned char enetaddr[6];
> +
> +	if (enclustra_mac_is_in_env("ethaddr"))
> +		return 0;
> +
> +	if (enclustra_get_mac_is_enabled("ethernet0"))
> +		return 0;
> +
> +	// NB: DS28 is still not available in official DT, so referencing
> +	// here by i2c busnumber and address directly
> +	// preparation for DT access here, though

Use C comment style /* */

> +	if (enclustra_get_mac_from_eeprom(enetaddr, ""))
> +		return -ENXIO;
> +
> +	if (eth_env_set_enetaddr("ethaddr", enetaddr))
> +		return -ENXIO;
> +
> +	if (!enclustra_get_mac1_from_mac(enetaddr))
> +		return eth_env_set_enetaddr("eth1addr", enetaddr);
> +
> +	printf("%s(): Failed, unable to set mac address!\n", __func__);

MAC address, MAC in capitals.

[...]

> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -73,7 +73,7 @@ config ATSHA204A
>   	help
>   	   Enable support for I2C connected Atmel's ATSHA204A
>   	   CryptoAuthentication module found for example on the Turris Omnia
> -	   board.
> +	   board and Enclustra SoC FPGA boards.
This change should be elsewhere in this series ?


More information about the U-Boot mailing list