1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries
5 * Author: Tudor Ambarus <tudor.ambarus@microchip.com>
12 #include <linux/mtd/spi-nor.h>
15 #define ETH_ADDR_SIZE 6
17 #ifdef CONFIG_SPI_FLASH_SST
18 #define SFDP_MICROCHIP_MANUF_ID 0xbf
19 #define SFDP_MICROCHIP_MEM_TYPE 0x26
20 #define SFDP_MICROCHIP_DEV_ID 0x43
22 #define SFDP_MICROCHIP_EUI_OFFSET 0x60
23 #define SFDP_MICROCHIP_EUI48 0x30
25 struct sst26vf064beui
{
33 * sst26vf064beui_check() - Check the validity of the EUI-48 information from
34 * the sst26vf064beui SPI NOR Microchip SFDP table.
35 * @manufacturer_sfdp: pointer to the Microchip manufacturer specific SFDP
38 * Return: 0 on success, -errno otherwise.
40 static int sst26vf064beui_check(const u8
*manufacturer_sfdp
)
42 struct sst26vf064beui
*sst26vf064beui
=
43 (struct sst26vf064beui
*)manufacturer_sfdp
;
45 if (sst26vf064beui
->manufacturer_id
!= SFDP_MICROCHIP_MANUF_ID
)
48 if (sst26vf064beui
->memory_type
!= SFDP_MICROCHIP_MEM_TYPE
)
51 if (sst26vf064beui
->device_id
!= SFDP_MICROCHIP_DEV_ID
)
55 * Check if the EUI-48 MAC address is programmed in the next six address
58 if (manufacturer_sfdp
[SFDP_MICROCHIP_EUI_OFFSET
] !=
66 * sst26vf064beui_get_ethaddr() - Get the ethernet address from the
67 * sst26vf064beui SPI NOR Microchip SFDP table.
68 * @manufacturer_sfdp: pointer to the Microchip manufacturer specific SFDP
70 * @ethaddr: pointer where to fill the ethernet address
71 * @size: size of the ethernet address.
73 * Return: 0 on success, -errno otherwise.
75 static int sst26vf064beui_get_ethaddr(const u8
*manufacturer_sfdp
,
76 u8
*ethaddr
, size_t size
)
79 u64
*p
= (u64
*)&manufacturer_sfdp
[SFDP_MICROCHIP_EUI_OFFSET
];
82 ret
= sst26vf064beui_check(manufacturer_sfdp
);
86 for (i
= 0; i
< 2; i
++)
87 eui_table
[i
] = le64_to_cpu(p
[i
]);
89 /* Ethaddr starts at offset one. */
90 memcpy(ethaddr
, &((u8
*)eui_table
)[1], size
);
97 * at91_spi_nor_set_ethaddr() - Retrieve and set the ethernet address from the
98 * SPI NOR manufacturer specific SFDP table.
100 void at91_spi_nor_set_ethaddr(void)
104 const char *ethaddr_name
= "ethaddr";
105 u8 ethaddr
[ETH_ADDR_SIZE
] = {0};
107 if (env_get(ethaddr_name
))
110 if (uclass_first_device_err(UCLASS_SPI_FLASH
, &dev
))
113 nor
= dev_get_uclass_priv(dev
);
117 if (!nor
->manufacturer_sfdp
)
120 #ifdef CONFIG_SPI_FLASH_SST
121 if (sst26vf064beui_get_ethaddr(nor
->manufacturer_sfdp
, ethaddr
,
126 if (is_valid_ethaddr(ethaddr
))
127 eth_env_set_enetaddr(ethaddr_name
, ethaddr
);