Add commands for low-level access to MDIO bus. Signed-off-by: Andrey Smirnov <andrew.smirnov@xxxxxxxxx> --- commands/Kconfig | 28 +++++++++ commands/Makefile | 1 + commands/mdio.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 commands/mdio.c diff --git a/commands/Kconfig b/commands/Kconfig index d93b5eb..f2e39e2 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -1850,6 +1850,34 @@ config CMD_I2C -w use word (16 bit) wide access -v verbose +config CMD_MDIO + bool + depends on PHYLIB + prompt "mdio_read and mdio_write" + help + mdio_read - read from a phy device + + Usage: mdio_read [-bacrwv] + + Options: + -b BUS mdio bus number (default 0) + -a ADDR phy device address + -r START start register + -c COUNT byte count + -v verbose + + + mdio_write - write to a phy device + + Usage: mdio_write [-barwv] WORD0 WORD1 WORD2... + + Options: + -b BUS mdio bus number (default 0) + -a ADDR mdio device address + -r START start register + -v verbose + + config CMD_LED bool depends on LED diff --git a/commands/Makefile b/commands/Makefile index 69892c4..1dfcf1a 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -63,6 +63,7 @@ obj-$(CONFIG_USB_GADGET_SERIAL) += usbserial.o obj-$(CONFIG_CMD_GPIO) += gpio.o obj-$(CONFIG_CMD_UNCOMPRESS) += uncompress.o obj-$(CONFIG_CMD_I2C) += i2c.o +obj-$(CONFIG_CMD_MDIO) += mdio.o obj-$(CONFIG_CMD_SPI) += spi.o obj-$(CONFIG_CMD_UBI) += ubi.o obj-$(CONFIG_CMD_UBIFORMAT) += ubiformat.o diff --git a/commands/mdio.c b/commands/mdio.c new file mode 100644 index 0000000..274b281 --- /dev/null +++ b/commands/mdio.c @@ -0,0 +1,182 @@ +/* + * mdio.c - MDIO commands + * + * Copyright (c) 2016 Zodiac Inflight Innovations + * Author: Andrey Smrinov <andrew.smirnov@xxxxxxxxx> + * + * Based on the code from commands/i2c.c: + * Copyright (c) 2010 Eric Bénard <eric@xxxxxxxxxx>, Eukréa Electromatique + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <common.h> +#include <command.h> +#include <errno.h> +#include <malloc.h> +#include <getopt.h> + +#include <fs.h> +#include <fcntl.h> +#include <linux/stat.h> +#include <xfuncs.h> +#include <net.h> +#include <linux/mii.h> +#include <linux/phy.h> +#include <linux/err.h> + + +static int do_mdio_write(int argc, char *argv[]) +{ + u16 *buf; + struct mii_bus *mdio; + int addr = -1, reg = -1, count = -1, verbose = 0, opt, i, bus = 0; + + while ((opt = getopt(argc, argv, "a:b:r:v")) > 0) { + switch (opt) { + case 'a': + addr = simple_strtol(optarg, NULL, 0); + break; + case 'r': + reg = simple_strtol(optarg, NULL, 0); + break; + case 'b': + bus = simple_strtoul(optarg, NULL, 0); + break; + case 'v': + verbose = 1; + break; + } + } + + count = argc - optind; + + if ((addr < 0) || (addr > PHY_MAX_ADDR) || + (reg < 0) || (reg + count > PHY_MAX_ADDR) || + (count == 0)) + return COMMAND_ERROR_USAGE; + + mdio = mdiobus_get_bus(bus); + if (!mdio) { + printf("mdio bus %d not found\n", bus); + return -ENODEV; + } + + buf = xzalloc(count * sizeof(buf[0])); + + for (i = 0; i < count; i++) { + buf[i] = (uint16_t) simple_strtol(argv[optind+i], NULL, 16); + + mdiobus_write(mdio, addr, reg + i, buf[i]); + } + + if (verbose) { + printf("wrote %i words starting at reg 0x%02x" + " to phydev 0x%02x on bus %i\n", + count, reg, addr, bus); + + memory_display(buf, reg, count * sizeof(buf[0]), + sizeof(buf[0]), false); + } + + free(buf); + return COMMAND_SUCCESS; +} + +BAREBOX_CMD_HELP_START(mdio_write) +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT ("-b BUS\t", "mdio bus number (default 0)") +BAREBOX_CMD_HELP_OPT ("-a ADDR\t", "phy device address") +BAREBOX_CMD_HELP_OPT ("-r START", "start register") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(mdio_write) + .cmd = do_mdio_write, + BAREBOX_CMD_DESC("write to a phy device") + BAREBOX_CMD_OPTS("[-bar] WORD0 WORD1 WORD2...") + BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP) + BAREBOX_CMD_HELP(cmd_mdio_write_help) +BAREBOX_CMD_END + +static int do_mdio_read(int argc, char *argv[]) +{ + u16 *buf; + struct mii_bus *mdio; + int i, count = -1, addr = -1, reg = -1, verbose = 0, opt, bus = 0; + + while ((opt = getopt(argc, argv, "a:b:c:r:v")) > 0) { + switch (opt) { + case 'a': + addr = simple_strtol(optarg, NULL, 0); + break; + case 'c': + count = simple_strtoul(optarg, NULL, 0); + break; + case 'b': + bus = simple_strtoul(optarg, NULL, 0); + break; + case 'r': + reg = simple_strtol(optarg, NULL, 0); + break; + case 'v': + verbose = 1; + break; + } + } + + if ((addr < 0) || (addr > PHY_MAX_ADDR) || + (reg < 0) || (reg + count > PHY_MAX_ADDR) || + (count <= 0)) + return COMMAND_ERROR_USAGE; + + mdio = mdiobus_get_bus(bus); + if (!mdio) { + printf("mdio bus %d not found\n", bus); + return -ENODEV; + } + + buf = xzalloc(count * sizeof(buf[0])); + + for (i = 0; i < count; i++) { + buf[i] = mdiobus_read(mdio, addr, reg + i); + + printf("%x\n", buf[i]); + } + + if (verbose) + printf("read %i bytes starting at reg 0x%04x" + " from phydev 0x%02x on bus %i\n", + count, reg, addr, bus); + + memory_display(buf, reg, count * sizeof(buf[0]), + sizeof(buf[0]), false); + free(buf); + return COMMAND_SUCCESS; +} + +BAREBOX_CMD_HELP_START(mdio_read) +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT("-b BUS\t", "mdio bus number (default 0)") +BAREBOX_CMD_HELP_OPT("-a ADDR\t", "phy device address") +BAREBOX_CMD_HELP_OPT("-r START", "start register") +BAREBOX_CMD_HELP_OPT("-c COUNT", "byte count") +BAREBOX_CMD_HELP_OPT("-v\t", "verbose") +BAREBOX_CMD_HELP_END + + +BAREBOX_CMD_START(mdio_read) + .cmd = do_mdio_read, + BAREBOX_CMD_DESC("read from a phy device") + BAREBOX_CMD_OPTS("[-bacrwv]") + BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP) + BAREBOX_CMD_HELP(cmd_mdio_read_help) +BAREBOX_CMD_END -- 2.5.0 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox