[RFC v2] add 'miitool' command to view media-independent interface status
Antony Pavlov
antonynpavlov at gmail.com
Sun Oct 14 01:25:08 EDT 2012
On 13 October 2012 16:13, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> 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?
I'll resend the patch with the "PATCH" title.
Shell I move my TODO lines to the TODO file?
> 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 |
--
Best regards,
Antony Pavlov
More information about the barebox
mailing list