1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 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;
}
|