[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