summaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-11-16 14:01:34 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2012-11-16 14:01:34 +0100
commit856f60dbd157126241cf9033514137849bb5ca22 (patch)
treefca1784ef63b89a78127a0f4d1340f90eedd6848 /commands
parentec78bea331e195fff267ae949cee4777ef1add56 (diff)
parentf4ca20c4d27751ee749f382cfd4949d825534fce (diff)
downloadbarebox-856f60dbd157126241cf9033514137849bb5ca22.tar.gz
barebox-856f60dbd157126241cf9033514137849bb5ca22.tar.xz
Merge branch 'for-next/misc'
Conflicts: commands/Makefile Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'commands')
-rw-r--r--commands/Kconfig19
-rw-r--r--commands/Makefile1
-rw-r--r--commands/help.c7
-rw-r--r--commands/miitool.c268
-rw-r--r--commands/printenv.c22
5 files changed, 298 insertions, 19 deletions
diff --git a/commands/Kconfig b/commands/Kconfig
index 1336097671..5e4db90c21 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -57,10 +57,6 @@ config CMD_READLINE
tristate
prompt "readline"
-config CMD_LN
- tristate
- prompt "ln"
-
config CMD_TRUE
tristate
default y
@@ -216,6 +212,10 @@ config CMD_DIRNAME
Strip last component of file name and store the result in a
environment variable
+config CMD_LN
+ tristate
+ prompt "ln"
+
config CMD_READLINK
tristate
prompt "readlink"
@@ -630,6 +630,17 @@ config CMD_USB
help
The usb command allows to rescan for USB devices.
+config CMD_MIITOOL
+ tristate
+ depends on PHYLIB
+ prompt "miitool"
+ 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 53c8c51665..db431d35f1 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -78,3 +78,4 @@ obj-$(CONFIG_CMD_CLK) += clk.o
obj-$(CONFIG_CMD_TFTP) += tftp.o
obj-$(CONFIG_CMD_FILETYPE) += filetype.o
obj-$(CONFIG_CMD_BAREBOX_UPDATE)+= barebox-update.o
+obj-$(CONFIG_CMD_MIITOOL) += miitool.o
diff --git a/commands/help.c b/commands/help.c
index 72b0befecb..a12d9c3547 100644
--- a/commands/help.c
+++ b/commands/help.c
@@ -28,12 +28,17 @@
static int do_help(int argc, char *argv[])
{
struct command *cmdtp;
+ int max_length = 0;
if (argc == 1) { /* show list of commands */
+ for_each_command(cmdtp)
+ if(strlen(cmdtp->name) > max_length)
+ max_length = strlen(cmdtp->name);
+
for_each_command(cmdtp) {
if (!cmdtp->usage)
continue;
- printf("%10s - %s\n", cmdtp->name, cmdtp->usage);
+ printf("%*s - %s\n", max_length, cmdtp->name, cmdtp->usage);
}
return 0;
}
diff --git a/commands/miitool.c b/commands/miitool.c
new file mode 100644
index 0000000000..3a9ac45605
--- /dev/null
+++ b/commands/miitool.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2012 Antony Pavlov <antonynpavlov@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@pcmcia.sourceforge.org>
+ *
+ * mii-diag is written/copyright 1997-2000 by Donald Becker
+ * <becker@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
diff --git a/commands/printenv.c b/commands/printenv.c
index b18c7a137e..10e882ae9f 100644
--- a/commands/printenv.c
+++ b/commands/printenv.c
@@ -27,8 +27,8 @@
static int do_printenv(int argc, char *argv[])
{
- struct variable_d *var;
- struct env_context *c, *current_c;
+ struct variable_d *v;
+ struct env_context *c;
if (argc == 2) {
const char *val = getenv(argv[1]);
@@ -40,22 +40,16 @@ static int do_printenv(int argc, char *argv[])
return 1;
}
- current_c = get_current_context();
- var = current_c->local->next;
+ c = get_current_context();
printf("locals:\n");
- while (var) {
- printf("%s=%s\n", var_name(var), var_val(var));
- var = var->next;
- }
+ list_for_each_entry(v, &c->local, list)
+ printf("%s=%s\n", var_name(v), var_val(v));
printf("globals:\n");
c = get_current_context();
- while(c) {
- var = c->global->next;
- while (var) {
- printf("%s=%s\n", var_name(var), var_val(var));
- var = var->next;
- }
+ while (c) {
+ list_for_each_entry(v, &c->global, list)
+ printf("%s=%s\n", var_name(v), var_val(v));
c = c->parent;
}