diff options
author | Eugene Surovegin <ebs@ebshome.net> | 2005-10-25 02:29:27 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-25 02:29:27 -0400 |
commit | a69768a4266ef72fb6936334013a4183269732f2 (patch) | |
tree | 234141620e95f34ef5a300ca6a0410b6d0e23885 | |
parent | 6960d52a9dff61f0c6d5c788d0cd4b691d28c7e7 (diff) | |
download | ethtool-a69768a4266ef72fb6936334013a4183269732f2.tar.gz |
Add PPC4xx EMAC support.
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile.am | 7 | ||||
-rw-r--r-- | ethtool-util.h | 3 | ||||
-rw-r--r-- | ethtool.c | 1 | ||||
-rw-r--r-- | ibm_emac.c | 244 |
5 files changed, 254 insertions, 3 deletions
@@ -16,6 +16,8 @@ config.* aclocal.m4 configure *.tar.gz +push +.dotest autom4te.cache .deps diff --git a/Makefile.am b/Makefile.am index e6b83cd..6eb2c08 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,9 +4,10 @@ man_MANS = ethtool.8 EXTRA_DIST = ethtool.8 ethtool.spec.in aclocal.m4 ChangeLog autogen.sh sbin_PROGRAMS = ethtool -ethtool_SOURCES = de2104x.c ethtool.c ethtool-copy.h ethtool-util.h natsemi.c \ - e1000.c realtek.c e100.c tg3.c amd8111e.c pcnet32.c \ - fec_8xx.c +ethtool_SOURCES = ethtool.c ethtool-copy.h ethtool-util.h \ + amd8111e.c de2104x.c e100.c e1000.c \ + fec_8xx.c ibm_emac.c natsemi.c pcnet32.c \ + realtek.c tg3.c dist-hook: cp $(top_srcdir)/ethtool.spec $(distdir) diff --git a/ethtool-util.h b/ethtool-util.h index a69fa86..e95d75c 100644 --- a/ethtool-util.h +++ b/ethtool-util.h @@ -39,4 +39,7 @@ int pcnet32_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); /* Motorola 8xx FEC Ethernet controller */ int fec_8xx_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); +/* PowerPC 4xx on-chip Ethernet controller */ +int ibm_emac_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + #endif @@ -938,6 +938,7 @@ static struct { { "amd8111e", amd8111e_dump_regs }, { "pcnet32", pcnet32_dump_regs }, { "fec_8xx", fec_8xx_dump_regs }, + { "ibm_emac", ibm_emac_dump_regs }, }; static int dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs) diff --git a/ibm_emac.c b/ibm_emac.c new file mode 100644 index 0000000..b2dfffa --- /dev/null +++ b/ibm_emac.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2004, 2005 Zultys Technologies + * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> + */ +#include <stdio.h> +#include <stdint.h> +#include <stddef.h> + +#include "ethtool-util.h" + +/* Ethtool get_regs complex data. + * we want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH + * when available. + * + * Returned BLOB consists of the ibm_emac_ethtool_regs_hdr, + * MAL registers, EMAC registers and optional ZMII, RGMII, TAH registers. + * Each register component is preceded with emac_ethtool_regs_subhdr. + * Order of the optional headers follows their relative bit posititions + * in emac_ethtool_regs_hdr.components + */ +#define EMAC_ETHTOOL_REGS_ZMII 0x00000001 +#define EMAC_ETHTOOL_REGS_RGMII 0x00000002 +#define EMAC_ETHTOOL_REGS_TAH 0x00000004 + +struct emac_ethtool_regs_hdr { + u32 components; +}; + +struct emac_ethtool_regs_subhdr { + u32 version; + u32 index; +}; + +struct emac_regs { + u32 mr0; + u32 mr1; + u32 tmr0; + u32 tmr1; + u32 rmr; + u32 isr; + u32 iser; + u32 iahr; + u32 ialr; + u32 vtpid; + u32 vtci; + u32 ptr; + u32 iaht1; + u32 iaht2; + u32 iaht3; + u32 iaht4; + u32 gaht1; + u32 gaht2; + u32 gaht3; + u32 gaht4; + u32 lsah; + u32 lsal; + u32 ipgvr; + u32 stacr; + u32 trtr; + u32 rwmr; + u32 octx; + u32 ocrx; + u32 ipcr; +}; + +struct mal_regs { + u32 tx_count; + u32 rx_count; + + u32 cfg; + u32 esr; + u32 ier; + u32 tx_casr; + u32 tx_carr; + u32 tx_eobisr; + u32 tx_deir; + u32 rx_casr; + u32 rx_carr; + u32 rx_eobisr; + u32 rx_deir; + u32 tx_ctpr[32]; + u32 rx_ctpr[32]; + u32 rcbs[32]; +}; + +struct zmii_regs { + u32 fer; + u32 ssr; + u32 smiisr; +}; + +struct rgmii_regs { + u32 fer; + u32 ssr; +}; + +struct tah_regs { + u32 revid; + u32 pad[3]; + u32 mr; + u32 ssr0; + u32 ssr1; + u32 ssr2; + u32 ssr3; + u32 ssr4; + u32 ssr5; + u32 tsr; +}; + +static void *print_emac_regs(void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct emac_regs *p = (struct emac_regs *)(hdr + 1); + void *res = p + 1; + + printf("EMAC%d Registers\n", hdr->index); + printf("-----------------\n"); + printf("MR0 = 0x%08x MR1 = 0x%08x RMR = 0x%08x\n" + "ISR = 0x%08x ISER = 0x%08x\n" + "TMR0 = 0x%08x TMR1 = 0x%08x\n" + "TRTR = 0x%08x RWMR = 0x%08x\n" + "IAR = %04x%08x\n" + "LSA = %04x%08x\n" + "IAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n" + "GAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n" + "VTPID = 0x%04x VTCI = 0x%04x\n" + "IPGVR = 0x%04x STACR = 0x%08x\n" + "OCTX = 0x%08x OCRX = 0x%08x\n", + p->mr0, p->mr1, p->rmr, + p->isr, p->iser, + p->tmr0, p->tmr1, + p->trtr, p->rwmr, + p->iahr, p->ialr, + p->lsah, p->lsal, + p->iaht1, p->iaht2, p->iaht3, p->iaht4, + p->gaht1, p->gaht2, p->gaht3, p->gaht4, + p->vtpid, p->vtci, p->ipgvr, p->stacr, p->octx, p->ocrx); + + if (hdr->version) + printf(" IPCR = 0x%08x\n\n", p->ipcr); + else { + printf("\n\n"); + res -= sizeof(u32); + } + return res; +} + +static void *print_mal_regs(void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct mal_regs *p = (struct mal_regs *)(hdr + 1); + int i; + + printf("MAL%d Registers\n", hdr->index); + printf("-----------------\n"); + printf("CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n" + "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n" + "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n", + p->cfg, p->esr, p->ier, + p->tx_casr, p->tx_carr, p->tx_eobisr, p->tx_deir, + p->rx_casr, p->rx_carr, p->rx_eobisr, p->rx_deir); + + printf("TX|"); + for (i = 0; i < p->tx_count; ++i) { + if (i && !(i % 4)) + printf("\n "); + printf("CTP%d = 0x%08x ", i, p->tx_ctpr[i]); + } + printf("\nRX|"); + for (i = 0; i < p->rx_count; ++i) { + if (i && !(i % 4)) + printf("\n "); + printf("CTP%d = 0x%08x ", i, p->rx_ctpr[i]); + } + printf("\n "); + for (i = 0; i < p->rx_count; ++i) { + u32 r = p->rcbs[i]; + if (i && !(i % 3)) + printf("\n "); + printf("RCBS%d = 0x%08x (%d) ", i, r, r * 16); + } + printf("\n\n"); + return p + 1; +} + +static void *print_zmii_regs(void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct zmii_regs *p = (struct zmii_regs *)(hdr + 1); + + printf("ZMII%d Registers\n", hdr->index); + printf("-----------------\n"); + printf("FER = %08x SSR = %08x\n" + "SMIISR = %08x\n\n", p->fer, p->ssr, p->smiisr); + + return p + 1; +} + +static void *print_rgmii_regs(void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct rgmii_regs *p = (struct rgmii_regs *)(hdr + 1); + + printf("RGMII%d Registers\n", hdr->index); + printf("-----------------\n"); + printf("FER = %08x SSR = %08x\n\n", p->fer, p->ssr); + + return p + 1; +} + +static void *print_tah_regs(void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct tah_regs *p = (struct tah_regs *)(hdr + 1); + + printf("TAH%d Registers\n", hdr->index); + printf("-----------------\n"); + + printf("REVID = %08x MR = %08x TSR = %08x\n" + "SSR0 = %08x SSR1 = %08x SSR2 = %08x\n" + "SSR3 = %08x SSR4 = %08x SSR5 = %08x\n\n", + p->revid, p->mr, p->tsr, + p->ssr0, p->ssr1, p->ssr2, p->ssr3, p->ssr4, p->ssr5); + + return p + 1; +} + +int ibm_emac_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs) +{ + struct emac_ethtool_regs_hdr *hdr = + (struct emac_ethtool_regs_hdr *)regs->data; + void *buf = hdr + 1; + + buf = print_mal_regs(buf); + buf = print_emac_regs(buf); + if (hdr->components & EMAC_ETHTOOL_REGS_ZMII) + buf = print_zmii_regs(buf); + if (hdr->components & EMAC_ETHTOOL_REGS_RGMII) + buf = print_rgmii_regs(buf); + if (hdr->components & EMAC_ETHTOOL_REGS_TAH) + print_tah_regs(buf); + + return 0; +} |