[U-Boot] [PATCH v3 2/3] net: Add a command to access the EEPROM from ethernet devices
Alban Bedel
alban.bedel at avionic-design.de
Tue Oct 14 18:26:10 CEST 2014
Many ethernet devices use an EEPROM to store various settings, most
commonly the device MAC address. But on some devices it can contains
a lot more, for example USB device might also have many USB related
parameters.
This commit add a set of commands to read/write this EEPROM, write a
default configuration and read/write the device MAC address. The
defaults command allow priming the EEPROM for devices that need more
than just a MAC address in the EEPROM.
Signed-off-by: Alban Bedel <alban.bedel at avionic-design.de>
---
v2: * No changes since v1
v3: * Replace the dedicated 'eth_eeprom' command with a subcommand
to the newly introduced 'eth' command
---
common/cmd_net.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/net.h | 28 +++++++++++++
net/eth.c | 46 +++++++++++++++++++++
3 files changed, 195 insertions(+)
diff --git a/common/cmd_net.c b/common/cmd_net.c
index 9cc0bdf..1c2e254 100644
--- a/common/cmd_net.c
+++ b/common/cmd_net.c
@@ -446,6 +446,109 @@ U_BOOT_CMD(
#endif /* CONFIG_CMD_LINK_LOCAL */
+#if defined(CONFIG_CMD_ETH_EEPROM)
+static int do_eth_eeprom_rw(struct eth_device *dev,
+ int argc, char * const argv[])
+{
+ ulong addr, offset, length = 1;
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ addr = simple_strtoul(argv[1], NULL, 16);
+ offset = simple_strtoul(argv[2], NULL, 16);
+ if (argc > 3)
+ length = simple_strtoul(argv[3], NULL, 16);
+
+ if (!strcmp(argv[0], "write")) {
+ if (eth_eeprom_write(dev, offset, length, (void *)addr)) {
+ printf("EEPROM write failed\n");
+ return CMD_RET_FAILURE;
+ }
+ return CMD_RET_SUCCESS;
+ } else if (!strcmp(argv[0], "read")) {
+ if (eth_eeprom_read(dev, offset, length, (void *)addr)) {
+ printf("EEPROM read failed\n");
+ return CMD_RET_FAILURE;
+ }
+ return CMD_RET_SUCCESS;
+ }
+
+ return CMD_RET_USAGE;
+}
+
+static int do_eth_eeprom_defaults(struct eth_device *dev,
+ int argc, char * const argv[])
+{
+ if (eth_eeprom_defaults(dev)) {
+ printf("EEPROM write failed\n");
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_eth_eeprom_set_mac(struct eth_device *dev,
+ int argc, char * const argv[])
+{
+ u8 mac[6];
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ eth_parse_enetaddr(argv[1], mac);
+ if (!is_valid_ether_addr(mac)) {
+ printf("Invalid mac address given\n");
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Writing MAC to EEPROM ....\n");
+ if (eth_eeprom_write_mac(dev, mac)) {
+ printf("EEPROM write failed\n");
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_eth_eeprom_show_mac(struct eth_device *dev,
+ int argc, char * const argv[])
+{
+ u8 data[6];
+
+ if (eth_eeprom_read_mac(dev, data)) {
+ printf("EEPROM read failed\n");
+ return CMD_RET_FAILURE;
+ }
+
+ printf("%pM\n", data);
+ if (!is_valid_ether_addr(data))
+ printf("Warning: MAC address is not valid!\n");
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_eth_eeprom(struct eth_device *dev,
+ int argc, char * const argv[])
+{
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ if (!strcmp(argv[1], "read") || !strcmp(argv[1], "write"))
+ return do_eth_eeprom_rw(dev, argc - 1, argv + 1);
+ if (!strcmp(argv[1], "defaults"))
+ return do_eth_eeprom_defaults(dev, argc - 1, argv + 1);
+ if (!strcmp(argv[1], "set_mac"))
+ return do_eth_eeprom_set_mac(dev, argc - 1, argv + 1);
+ if (!strcmp(argv[1], "show_mac"))
+ return do_eth_eeprom_show_mac(dev, argc - 1, argv + 1);
+
+ printf("Unknown eeprom sub command: %s\n", argv[1]);
+
+ return CMD_RET_USAGE;
+}
+#endif
+
static int do_eth_show(struct eth_device *dev,
int argc, char * const argv[])
{
@@ -478,6 +581,10 @@ static int do_eth(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (!strcmp(argv[2], "show"))
return do_eth_show(dev, argc - 2, argv + 2);
+#if defined(CONFIG_CMD_ETH_EEPROM)
+ if (!strcmp(argv[2], "eeprom"))
+ return do_eth_eeprom(dev, argc - 2, argv + 2);
+#endif
printf("Unknown eth sub command: %s\n", argv[2]);
@@ -492,4 +599,18 @@ U_BOOT_CMD(
"\n"
"eth <dev> show\n"
" - show basic information about the ethernet device\n"
+#if defined(CONFIG_CMD_ETH_EEPROM)
+ "eth <dev> eeprom <command> [<args>...]\n"
+ " - access the EEPROM of the ethernet device:\n"
+ " read <addr> <off> [<size>]\n"
+ " - read <size> bytes starting at offset <off> to memory address <addr>.\n"
+ " write <addr> <off> [<size>]\n"
+ " - write <size> bytes starting at offset <off> from memory address <addr>.\n"
+ " defaults\n"
+ " - write default settings in the EEPROM.\n"
+ " set_mac <mac>\n"
+ " - set the MAC address in the EEPROM to 'mac'\n"
+ " show_mac\n"
+ " - read the MAC address from the EEPROM."
+#endif
);
diff --git a/include/net.h b/include/net.h
index 18d279e..fba7572 100644
--- a/include/net.h
+++ b/include/net.h
@@ -92,6 +92,25 @@ struct eth_device {
int (*mcast) (struct eth_device *, const u8 *enetaddr, u8 set);
#endif
int (*write_hwaddr) (struct eth_device *);
+#ifdef CONFIG_CMD_ETH_EEPROM
+ /* Read data from the ethernet device eeprom */
+ int (*eeprom_read)(struct eth_device *,
+ u32 offset, u32 length, u8 *data);
+ /* Write data to the ethernet device eeprom */
+ int (*eeprom_write)(struct eth_device *,
+ u32 offset, u32 length, u8 *data);
+ /* Write the default settings to the eeprom */
+ int (*eeprom_defaults)(struct eth_device *);
+ /* Read the MAC stored in the eeprom, if not implemented
+ * the MAC is assumed to be at the given offset. */
+ int (*eeprom_read_mac)(struct eth_device *, u8 *enetaddr);
+ /* Write the MAC in the eeprom, if not implemented
+ * the MAC is assumed to be at the given offset. */
+ int (*eeprom_write_mac)(struct eth_device *, u8 *enetaddr);
+ /* Offset of the MAC address for the default implementation.
+ * Set to a negative value if the MAC is not in the EEPROM. */
+ int eeprom_mac_offset;
+#endif
struct eth_device *next;
int index;
void *priv;
@@ -172,6 +191,15 @@ int eth_mcast_join(IPaddr_t mcast_addr, u8 join);
u32 ether_crc(size_t len, unsigned char const *p);
#endif
+#ifdef CONFIG_CMD_ETH_EEPROM
+int eth_eeprom_read(struct eth_device *dev, u32 offset,
+ u32 length, u8 *data);
+int eth_eeprom_write(struct eth_device *dev, u32 offset,
+ u32 length, u8 *data);
+int eth_eeprom_defaults(struct eth_device *dev);
+int eth_eeprom_read_mac(struct eth_device *, u8 *enetaddr);
+int eth_eeprom_write_mac(struct eth_device *, u8 *enetaddr);
+#endif
/**********************************************************************/
/*
diff --git a/net/eth.c b/net/eth.c
index 76ffa05..2cde72c 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -542,3 +542,49 @@ char *eth_get_name(void)
{
return eth_current ? eth_current->name : "unknown";
}
+
+#ifdef CONFIG_CMD_ETH_EEPROM
+int eth_eeprom_read(struct eth_device *dev, u32 offset,
+ u32 length, u8 *data)
+{
+ return dev->eeprom_read ?
+ dev->eeprom_read(dev, offset, length, data) :
+ -ENOSYS;
+}
+
+int eth_eeprom_write(struct eth_device *dev, u32 offset,
+ u32 length, u8 *data)
+{
+ return dev->eeprom_write ?
+ dev->eeprom_write(dev, offset, length, data) :
+ -ENOSYS;
+}
+
+int eth_eeprom_defaults(struct eth_device *dev)
+{
+ return dev->eeprom_defaults ? dev->eeprom_defaults(dev) :
+ -ENOSYS;
+}
+
+int eth_eeprom_read_mac(struct eth_device *dev, u8 *enetaddr)
+{
+ if (dev->eeprom_read_mac)
+ return dev->eeprom_read_mac(dev, enetaddr);
+
+ return dev->eeprom_mac_offset >= 0 ?
+ eth_eeprom_read(dev, dev->eeprom_mac_offset,
+ 6, enetaddr) :
+ -ENOSYS;
+}
+
+int eth_eeprom_write_mac(struct eth_device *dev, u8 *enetaddr)
+{
+ if (dev->eeprom_write_mac)
+ return dev->eeprom_write_mac(dev, enetaddr);
+
+ return dev->eeprom_mac_offset >= 0 ?
+ eth_eeprom_write(dev, dev->eeprom_mac_offset,
+ 6, enetaddr) :
+ -ENOSYS;
+}
+#endif
--
2.1.1
More information about the U-Boot
mailing list