mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-27 21:43:45 +00:00
f10b4006a6
The SST26VF064BEUI spi-nor flash is programmed at the factory with a globally unique address stored in the SFDP vendor parameter table and it is permanently writeprotected. Retrieve the EUI-48 address and set it as ethaddr env. Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
127 lines
2.9 KiB
C
127 lines
2.9 KiB
C
// 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);
|
|
}
|