[RFC v2] add 'miitool' command to view media-independent interface status
Sascha Hauer
s.hauer at pengutronix.de
Sat Oct 13 08:13:14 EDT 2012
Hi Antony,
On Wed, Oct 10, 2012 at 06:09:14PM +0400, Antony Pavlov wrote:
> This command is based on "mii-diag" and "mii-tool" programs.
>
> TODO:
> * add GbE support (see http://ftp.debian.org/debian/pool/main/n/net-tools/net-tools_1.60-24.2.diff.gz);
> * add routines to manipulate media-independent interface state.
Looks good. Since it still has RFC state, should I apply it?
Sascha
>
> EXAMPLES:
>
> barebox:/ miitool /dev/phy0
> negotiated 100baseTx-FD, link ok
>
> barebox:/ miitool -v /dev/phy0
> negotiated 100baseTx-FD, link ok
> product info: Level One LXT971A rev 2
> basic mode: autonegotiation enabled
> basic status: autonegotiation complete, link ok
> capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
> advertising: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
> link partner: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD flow-control
>
> barebox:/ miitool -vv /dev/phy0
> negotiated 100baseTx-FD, link ok
> registers for MII PHY:
> 3100 782d 0013 78e2 01e1 45e1 0007 2001
> 0000 ffff ffff ffff ffff ffff ffff ffff
> 0084 4780 0000 0000 0422 0000 0000 0000
> 0000 0000 0080 0000 ffff 0000 0000 3660
> product info: Level One LXT971A rev 2
> basic mode: autonegotiation enabled
> basic status: autonegotiation complete, link ok
> capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
> advertising: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
> link partner: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD flow-control
>
> Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
> ---
> commands/Kconfig | 11 +++
> commands/Makefile | 1 +
> commands/miitool.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 280 insertions(+)
> create mode 100644 commands/miitool.c
>
> diff --git a/commands/Kconfig b/commands/Kconfig
> index e934f29..c8cdd54 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -620,6 +620,17 @@ config CMD_USB
> help
> The usb command allows to rescan for USB devices.
>
> +config CMD_MIITOOL
> + bool
> + prompt "miitool command"
> + depends on NET
> + help
> + The miitool command allows to view media-independent interface status.
> + The default short output reports the negotiated link speed and
> + link status for selected MII. The '-v' option displays more
> + detailed MII status information, such as MII capabilities,
> + current advertising mode, and link partner capabilities.
> +
> config CMD_CLK
> tristate
> depends on COMMON_CLK
> diff --git a/commands/Makefile b/commands/Makefile
> index 610be55..c6416ca 100644
> --- a/commands/Makefile
> +++ b/commands/Makefile
> @@ -76,3 +76,4 @@ obj-$(CONFIG_CMD_READLINK) += readlink.o
> obj-$(CONFIG_CMD_LN) += ln.o
> obj-$(CONFIG_CMD_CLK) += clk.o
> obj-$(CONFIG_CMD_TFTP) += tftp.o
> +obj-$(CONFIG_CMD_MIITOOL) += miitool.o
> diff --git a/commands/miitool.c b/commands/miitool.c
> new file mode 100644
> index 0000000..3a9ac45
> --- /dev/null
> +++ b/commands/miitool.c
> @@ -0,0 +1,268 @@
> +/*
> + * Copyright (C) 2012 Antony Pavlov <antonynpavlov at gmail.com>
> + *
> + * This file is part of barebox.
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is based on Donald Becker's "mii-diag" and
> + * David A. Hinds' "mii-tool".
> + *
> + * mii-tool is written/copyright 2000 by David A. Hinds
> + * <dhinds at pcmcia.sourceforge.org>
> + *
> + * mii-diag is written/copyright 1997-2000 by Donald Becker
> + * <becker at scyld.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2
> + * as published by the Free Software Foundation.
> + *
> + * 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 <init.h>
> +#include <driver.h>
> +#include <malloc.h>
> +#include <errno.h>
> +#include <fs.h>
> +#include <fcntl.h>
> +#include <getopt.h>
> +#include <linux/stat.h>
> +#include <xfuncs.h>
> +#include <linux/mii.h>
> +
> +static u16 mdio_read(int fd, int offset)
> +{
> + int ret;
> + u16 buf;
> +
> + ret = lseek(fd, offset << 1, SEEK_SET);
> + if (ret < 0)
> + return 0;
> +
> + ret = read(fd, &buf, sizeof(u16));
> + if (ret < 0)
> + return 0;
> +
> + return buf;
> +}
> +
> +/* Table of known MII's */
> +static const struct {
> + u_short id1, id2;
> + u_short mask1, mask2;
> + char *name;
> +} mii_id[] = {
> + { 0x0013, 0x78e0, 0xffff, 0xfff0, "Level One LXT971A" },
> +};
> +#define NMII (sizeof(mii_id)/sizeof(mii_id[0]))
> +
> +const struct {
> + char *name;
> + u_short value;
> +} media[] = {
> + /* The order through 100baseT4 matches bits in the BMSR */
> + { "10baseT-HD", ADVERTISE_10HALF },
> + { "10baseT-FD", ADVERTISE_10FULL },
> + { "100baseTx-HD", ADVERTISE_100HALF },
> + { "100baseTx-FD", ADVERTISE_100FULL },
> + { "100baseT4", LPA_100BASE4 },
> + { "100baseTx", ADVERTISE_100FULL | ADVERTISE_100HALF },
> + { "10baseT", ADVERTISE_10FULL | ADVERTISE_10HALF },
> +};
> +#define NMEDIA (sizeof(media)/sizeof(media[0]))
> +
> +static char *media_list(int mask, int best)
> +{
> + static char buf[100];
> + int i;
> +
> + *buf = '\0';
> + mask >>= 5;
> + for (i = 4; i >= 0; i--) {
> + if (mask & (1 << i)) {
> + strcat(buf, " ");
> + strcat(buf, media[i].name);
> + if (best)
> + break;
> + }
> + }
> +
> + if (mask & (1 << 5))
> + strcat(buf, " flow-control");
> +
> + return buf;
> +}
> +
> +static int show_basic_mii(int fd, int verbose)
> +{
> + char buf[100];
> + int i, mii_val[32];
> + int bmcr, bmsr, advert, lkpar;
> +
> + /* Some bits in the BMSR are latched, but we can't rely on being
> + the only reader, so only the current values are meaningful */
> + mdio_read(fd, MII_BMSR);
> + for (i = 0; i < ((verbose > 1) ? 32 : 8); i++)
> + mii_val[i] = mdio_read(fd, i);
> +
> + if (mii_val[MII_BMCR] == 0xffff) {
> + fprintf(stderr, " No MII transceiver present!.\n");
> + return -1;
> + }
> +
> + /* Descriptive rename. */
> + bmcr = mii_val[MII_BMCR];
> + bmsr = mii_val[MII_BMSR];
> + advert = mii_val[MII_ADVERTISE];
> + lkpar = mii_val[MII_LPA];
> +
> + *buf = '\0';
> + if (bmcr & BMCR_ANENABLE) {
> + if (bmsr & BMSR_ANEGCOMPLETE) {
> + if (advert & lkpar) {
> + sprintf(buf, "%s%s, ", (lkpar & LPA_LPACK) ?
> + "negotiated" : "no autonegotiation,",
> + media_list(advert & lkpar, 1));
> + } else {
> + sprintf(buf, "autonegotiation failed, ");
> + }
> + } else if (bmcr & BMCR_ANRESTART) {
> + sprintf(buf, "autonegotiation restarted, ");
> + }
> + } else {
> + sprintf(buf, "%s Mbit, %s duplex, ",
> + (bmcr & BMCR_SPEED100) ? "100" : "10",
> + (bmcr & BMCR_FULLDPLX) ? "full" : "half");
> + }
> +
> + strcat(buf, (bmsr & BMSR_LSTATUS) ? "link ok" : "no link");
> +
> + printf("%s\n", buf);
> +
> + if (verbose > 1) {
> + printf(" registers for MII PHY: ");
> + for (i = 0; i < 32; i++)
> + printf("%s %4.4x",
> + ((i % 8) ? "" : "\n "), mii_val[i]);
> +
> + printf("\n");
> + }
> +
> + if (verbose) {
> + printf(" product info: ");
> + for (i = 0; i < NMII; i++)
> + if ((mii_id[i].id1 == (mii_val[2] & mii_id[i].mask1)) &&
> + (mii_id[i].id2 ==
> + (mii_val[3] & mii_id[i].mask2)))
> + break;
> +
> + if (i < NMII)
> + printf("%s rev %d\n", mii_id[i].name, mii_val[3]&0x0f);
> + else
> + printf("vendor %02x:%02x:%02x, model %d rev %d\n",
> + mii_val[2] >> 10, (mii_val[2] >> 2) & 0xff,
> + ((mii_val[2] << 6)|(mii_val[3] >> 10)) & 0xff,
> + (mii_val[3] >> 4) & 0x3f, mii_val[3] & 0x0f);
> +
> + printf(" basic mode: ");
> + if (bmcr & BMCR_RESET)
> + printf("software reset, ");
> + if (bmcr & BMCR_LOOPBACK)
> + printf("loopback, ");
> + if (bmcr & BMCR_ISOLATE)
> + printf("isolate, ");
> + if (bmcr & BMCR_CTST)
> + printf("collision test, ");
> + if (bmcr & BMCR_ANENABLE) {
> + printf("autonegotiation enabled\n");
> + } else {
> + printf("%s Mbit, %s duplex\n",
> + (bmcr & BMCR_SPEED100) ? "100" : "10",
> + (bmcr & BMCR_FULLDPLX) ? "full" : "half");
> + }
> + printf(" basic status: ");
> + if (bmsr & BMSR_ANEGCOMPLETE)
> + printf("autonegotiation complete, ");
> + else if (bmcr & BMCR_ANRESTART)
> + printf("autonegotiation restarted, ");
> + if (bmsr & BMSR_RFAULT)
> + printf("remote fault, ");
> + printf((bmsr & BMSR_LSTATUS) ? "link ok" : "no link");
> + printf("\n capabilities:%s", media_list(bmsr >> 6, 0));
> + printf("\n advertising: %s", media_list(advert, 0));
> +
> +#define LPA_ABILITY_MASK (LPA_10HALF | LPA_10FULL \
> + | LPA_100HALF | LPA_100FULL \
> + | LPA_100BASE4 | LPA_PAUSE_CAP)
> +
> + if (lkpar & LPA_ABILITY_MASK)
> + printf("\n link partner:%s", media_list(lkpar, 0));
> + printf("\n");
> + }
> +
> + return 0;
> +}
> +
> +static int do_miitool(int argc, char *argv[])
> +{
> + char *filename;
> + int opt;
> + int argc_min;
> + int fd;
> + int verbose;
> +
> + verbose = 0;
> + while ((opt = getopt(argc, argv, "v")) > 0) {
> + switch (opt) {
> + case 'v':
> + verbose++;
> + break;
> + default:
> + return COMMAND_ERROR_USAGE;
> + }
> + }
> +
> + argc_min = optind + 1;
> +
> + if (argc < argc_min)
> + return COMMAND_ERROR_USAGE;
> +
> + filename = argv[optind];
> +
> + fd = open(filename, O_RDONLY);
> + if (fd < 0) {
> + printf("unable to read %s\n", filename);
> + return COMMAND_ERROR;
> + }
> +
> + show_basic_mii(fd, verbose);
> +
> + close(fd);
> +
> + return COMMAND_SUCCESS;
> +}
> +
> +BAREBOX_CMD_HELP_START(miitool)
> +BAREBOX_CMD_HELP_USAGE("miitool [[[-v] -v] -v] <phy>\n")
> +BAREBOX_CMD_HELP_SHORT("view status for MII <phy>.\n")
> +BAREBOX_CMD_HELP_END
> +
> +/**
> + * @page miitool_command
> +This utility checks or sets the status of a network interface's
> +Media Independent Interface (MII) unit. Most fast ethernet
> +adapters use an MII to autonegotiate link speed and duplex setting.
> + */
> +BAREBOX_CMD_START(miitool)
> + .cmd = do_miitool,
> + .usage = "view media-independent interface status",
> + BAREBOX_CMD_HELP(cmd_miitool_help)
> +BAREBOX_CMD_END
> --
> 1.7.10.4
>
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
More information about the barebox
mailing list