X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cmd%2Fmii.c;h=b52a55dc3397244059de7414d4f0f1e689c02f22;hb=f1a69b8c733614ca8293891d4f7a1d1bdbe665c9;hp=7ef7532a502a01c955339f28269dc3fcee342c59;hpb=d82477748d641e60ba3e1a0b55d98362aed70f80;p=oweals%2Fu-boot.git diff --git a/cmd/mii.c b/cmd/mii.c index 7ef7532a50..b52a55dc33 100644 --- a/cmd/mii.c +++ b/cmd/mii.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2001 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com - * - * SPDX-License-Identifier: GPL-2.0+ */ /* @@ -13,25 +12,11 @@ #include #include -typedef struct _MII_reg_desc_t { - ushort regno; - char * name; -} MII_reg_desc_t; - -static const MII_reg_desc_t reg_0_5_desc_tbl[] = { - { MII_BMCR, "PHY control register" }, - { MII_BMSR, "PHY status register" }, - { MII_PHYSID1, "PHY ID 1 register" }, - { MII_PHYSID2, "PHY ID 2 register" }, - { MII_ADVERTISE, "Autonegotiation advertisement register" }, - { MII_LPA, "Autonegotiation partner abilities register" }, -}; - typedef struct _MII_field_desc_t { ushort hi; ushort lo; ushort mask; - char * name; + const char *name; } MII_field_desc_t; static const MII_field_desc_t reg_0_desc_tbl[] = { @@ -88,7 +73,7 @@ static const MII_field_desc_t reg_4_desc_tbl[] = { { 7, 7, 0x01, "100BASE-TX able" }, { 6, 6, 0x01, "10BASE-T full duplex able" }, { 5, 5, 0x01, "10BASE-T able" }, - { 4, 0, 0x1f, "xxx to do" }, + { 4, 0, 0x1f, "selector" }, }; static const MII_field_desc_t reg_5_desc_tbl[] = { @@ -103,50 +88,91 @@ static const MII_field_desc_t reg_5_desc_tbl[] = { { 7, 7, 0x01, "100BASE-TX able" }, { 6, 6, 0x01, "10BASE-T full duplex able" }, { 5, 5, 0x01, "10BASE-T able" }, - { 4, 0, 0x1f, "xxx to do" }, + { 4, 0, 0x1f, "partner selector" }, }; -typedef struct _MII_field_desc_and_len_t { + +static const MII_field_desc_t reg_9_desc_tbl[] = { + { 15, 13, 0x07, "test mode" }, + { 12, 12, 0x01, "manual master/slave enable" }, + { 11, 11, 0x01, "manual master/slave value" }, + { 10, 10, 0x01, "multi/single port" }, + { 9, 9, 0x01, "1000BASE-T full duplex able" }, + { 8, 8, 0x01, "1000BASE-T half duplex able" }, + { 7, 7, 0x01, "automatic TDR on link down" }, + { 6, 6, 0x7f, "(reserved)" }, +}; + +static const MII_field_desc_t reg_10_desc_tbl[] = { + { 15, 15, 0x01, "master/slave config fault" }, + { 14, 14, 0x01, "master/slave config result" }, + { 13, 13, 0x01, "local receiver status OK" }, + { 12, 12, 0x01, "remote receiver status OK" }, + { 11, 11, 0x01, "1000BASE-T full duplex able" }, + { 10, 10, 0x01, "1000BASE-T half duplex able" }, + { 9, 8, 0x03, "(reserved)" }, + { 7, 0, 0xff, "1000BASE-T idle error counter"}, +}; + +typedef struct _MII_reg_desc_t { + ushort regno; const MII_field_desc_t *pdesc; ushort len; -} MII_field_desc_and_len_t; - -static const MII_field_desc_and_len_t desc_and_len_tbl[] = { - { reg_0_desc_tbl, ARRAY_SIZE(reg_0_desc_tbl) }, - { reg_1_desc_tbl, ARRAY_SIZE(reg_1_desc_tbl) }, - { reg_2_desc_tbl, ARRAY_SIZE(reg_2_desc_tbl) }, - { reg_3_desc_tbl, ARRAY_SIZE(reg_3_desc_tbl) }, - { reg_4_desc_tbl, ARRAY_SIZE(reg_4_desc_tbl) }, - { reg_5_desc_tbl, ARRAY_SIZE(reg_5_desc_tbl) }, + const char *name; +} MII_reg_desc_t; + +static const MII_reg_desc_t mii_reg_desc_tbl[] = { + { MII_BMCR, reg_0_desc_tbl, ARRAY_SIZE(reg_0_desc_tbl), + "PHY control register" }, + { MII_BMSR, reg_1_desc_tbl, ARRAY_SIZE(reg_1_desc_tbl), + "PHY status register" }, + { MII_PHYSID1, reg_2_desc_tbl, ARRAY_SIZE(reg_2_desc_tbl), + "PHY ID 1 register" }, + { MII_PHYSID2, reg_3_desc_tbl, ARRAY_SIZE(reg_3_desc_tbl), + "PHY ID 2 register" }, + { MII_ADVERTISE, reg_4_desc_tbl, ARRAY_SIZE(reg_4_desc_tbl), + "Autonegotiation advertisement register" }, + { MII_LPA, reg_5_desc_tbl, ARRAY_SIZE(reg_5_desc_tbl), + "Autonegotiation partner abilities register" }, + { MII_CTRL1000, reg_9_desc_tbl, ARRAY_SIZE(reg_9_desc_tbl), + "1000BASE-T control register" }, + { MII_STAT1000, reg_10_desc_tbl, ARRAY_SIZE(reg_10_desc_tbl), + "1000BASE-T status register" }, }; static void dump_reg( ushort regval, - const MII_reg_desc_t *prd, - const MII_field_desc_and_len_t *pdl); - -static int special_field( - ushort regno, - const MII_field_desc_t *pdesc, - ushort regval); - -static void MII_dump_0_to_5( - ushort regvals[6], - uchar reglo, - uchar reghi) + const MII_reg_desc_t *prd); + +static bool special_field(ushort regno, const MII_field_desc_t *pdesc, + ushort regval); + +static void MII_dump(const ushort *regvals, uchar reglo, uchar reghi) { ulong i; - for (i = 0; i < 6; i++) { - if ((reglo <= i) && (i <= reghi)) - dump_reg(regvals[i], ®_0_5_desc_tbl[i], - &desc_and_len_tbl[i]); + for (i = 0; i < ARRAY_SIZE(mii_reg_desc_tbl); i++) { + const uchar reg = mii_reg_desc_tbl[i].regno; + + if (reg >= reglo && reg <= reghi) + dump_reg(regvals[reg - reglo], &mii_reg_desc_tbl[i]); } } +/* Print out field position, value, name */ +static void dump_field(const MII_field_desc_t *pdesc, ushort regval) +{ + if (pdesc->hi == pdesc->lo) + printf("%2u ", pdesc->lo); + else + printf("%2u-%2u", pdesc->hi, pdesc->lo); + + printf(" = %5u %s", (regval >> pdesc->lo) & pdesc->mask, + pdesc->name); +} + static void dump_reg( ushort regval, - const MII_reg_desc_t *prd, - const MII_field_desc_and_len_t *pdl) + const MII_reg_desc_t *prd) { ulong i; ushort mask_in_place; @@ -155,8 +181,8 @@ static void dump_reg( printf("%u. (%04hx) -- %s --\n", prd->regno, regval, prd->name); - for (i = 0; i < pdl->len; i++) { - pdesc = &pdl->pdesc[i]; + for (i = 0; i < prd->len; i++) { + pdesc = &prd->pdesc[i]; mask_in_place = pdesc->mask << pdesc->lo; @@ -165,17 +191,8 @@ static void dump_reg( regval & mask_in_place, prd->regno); - if (special_field(prd->regno, pdesc, regval)) { - } - else { - if (pdesc->hi == pdesc->lo) - printf("%2u ", pdesc->lo); - else - printf("%2u-%2u", pdesc->hi, pdesc->lo); - printf(" = %5u %s", - (regval & mask_in_place) >> pdesc->lo, - pdesc->name); - } + if (!special_field(prd->regno, pdesc, regval)) + dump_field(pdesc, regval); printf("\n"); } @@ -191,11 +208,11 @@ static void dump_reg( ** 5.4-0 */ -static int special_field( - ushort regno, - const MII_field_desc_t *pdesc, - ushort regval) +static bool special_field(ushort regno, const MII_field_desc_t *pdesc, + ushort regval) { + const ushort sel_bits = (regval >> pdesc->lo) & pdesc->mask; + if ((regno == MII_BMCR) && (pdesc->lo == 6)) { ushort speed_bits = regval & (BMCR_SPEED1000 | BMCR_SPEED100); printf("%2u,%2u = b%u%u speed selection = %s Mbps", @@ -209,34 +226,26 @@ static int special_field( } else if ((regno == MII_BMCR) && (pdesc->lo == 8)) { - printf("%2u = %5u duplex = %s", - pdesc->lo, - (regval >> pdesc->lo) & 1, - ((regval >> pdesc->lo) & 1) ? "full" : "half"); + dump_field(pdesc, regval); + printf(" = %s", ((regval >> pdesc->lo) & 1) ? "full" : "half"); return 1; } else if ((regno == MII_ADVERTISE) && (pdesc->lo == 0)) { - ushort sel_bits = (regval >> pdesc->lo) & pdesc->mask; - printf("%2u-%2u = %5u selector = %s", - pdesc->hi, pdesc->lo, sel_bits, - sel_bits == PHY_ANLPAR_PSB_802_3 ? - "IEEE 802.3" : - sel_bits == PHY_ANLPAR_PSB_802_9 ? - "IEEE 802.9 ISLAN-16T" : - "???"); + dump_field(pdesc, regval); + printf(" = %s", + sel_bits == PHY_ANLPAR_PSB_802_3 ? "IEEE 802.3 CSMA/CD" : + sel_bits == PHY_ANLPAR_PSB_802_9 ? + "IEEE 802.9 ISLAN-16T" : "???"); return 1; } else if ((regno == MII_LPA) && (pdesc->lo == 0)) { - ushort sel_bits = (regval >> pdesc->lo) & pdesc->mask; - printf("%2u-%2u = %u selector = %s", - pdesc->hi, pdesc->lo, sel_bits, - sel_bits == PHY_ANLPAR_PSB_802_3 ? - "IEEE 802.3" : - sel_bits == PHY_ANLPAR_PSB_802_9 ? - "IEEE 802.9 ISLAN-16T" : - "???"); + dump_field(pdesc, regval); + printf(" = %s", + sel_bits == PHY_ANLPAR_PSB_802_3 ? "IEEE 802.3 CSMA/CD" : + sel_bits == PHY_ANLPAR_PSB_802_9 ? + "IEEE 802.9 ISLAN-16T" : "???"); return 1; } @@ -268,7 +277,7 @@ static void extract_range( } /* ---------------------------------------------------------------- */ -static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_mii(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { char op[2]; unsigned char addrlo, addrhi, reglo, reghi; @@ -314,7 +323,7 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) mask = simple_strtoul(argv[5], NULL, 16); } - if (addrhi > 31) { + if (addrhi > 31 && strncmp(op, "de", 2)) { printf("Incorrect PHY address. Range should be 0-31\n"); return CMD_RET_USAGE; } @@ -407,17 +416,16 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } } } else if (strncmp(op, "du", 2) == 0) { - ushort regs[6]; + ushort regs[MII_STAT1000 + 1]; /* Last reg is 0x0a */ int ok = 1; - if ((reglo > 5) || (reghi > 5)) { - printf( - "The MII dump command only formats the " - "standard MII registers, 0-5.\n"); + if (reglo > MII_STAT1000 || reghi > MII_STAT1000) { + printf("The MII dump command only formats the standard MII registers, 0-5, 9-a.\n"); return 1; } for (addr = addrlo; addr <= addrhi; addr++) { - for (reg = reglo; reg < reghi + 1; reg++) { - if (miiphy_read(devname, addr, reg, ®s[reg]) != 0) { + for (reg = reglo; reg <= reghi; reg++) { + if (miiphy_read(devname, addr, reg, + ®s[reg - reglo]) != 0) { ok = 0; printf( "Error reading from the PHY addr=%02x reg=%02x\n", @@ -426,7 +434,7 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } } if (ok) - MII_dump_0_to_5(regs, reglo, reghi); + MII_dump(regs, reglo, reghi); printf("\n"); } } else if (strncmp(op, "de", 2) == 0) {