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 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
|
/*
* 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 "internal.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
#define EMAC_VERSION 3
#define EMAC4_VERSION 4
#define EMAC4SYNC_VERSION 5
struct emac_ethtool_regs_hdr {
u32 components;
};
struct emac_ethtool_regs_subhdr {
u32 version;
u32 index;
};
struct emac_regs {
/* Common registers across all EMAC implementations. */
u32 mr0; /* Special */
u32 mr1; /* Reset */
u32 tmr0; /* Special */
u32 tmr1; /* Special */
u32 rmr; /* Reset */
u32 isr; /* Always */
u32 iser; /* Reset */
u32 iahr; /* Reset, R, T */
u32 ialr; /* Reset, R, T */
u32 vtpid; /* Reset, R, T */
u32 vtci; /* Reset, R, T */
u32 ptr; /* Reset, T */
union {
/* Registers unique to EMAC4 implementations */
struct {
u32 iaht1; /* Reset, R */
u32 iaht2; /* Reset, R */
u32 iaht3; /* Reset, R */
u32 iaht4; /* Reset, R */
u32 gaht1; /* Reset, R */
u32 gaht2; /* Reset, R */
u32 gaht3; /* Reset, R */
u32 gaht4; /* Reset, R */
} emac4;
/* Registers unique to EMAC4SYNC implementations */
struct {
u32 mahr; /* Reset, R, T */
u32 malr; /* Reset, R, T */
u32 mmahr; /* Reset, R, T */
u32 mmalr; /* Reset, R, T */
u32 rsvd0[4];
} emac4sync;
} u0;
/* Common registers across all EMAC implementations. */
u32 lsah;
u32 lsal;
u32 ipgvr; /* Reset, T */
u32 stacr; /* Special */
u32 trtr; /* Special */
u32 rwmr; /* Reset */
u32 octx;
u32 ocrx;
union {
/* Registers unique to EMAC4 implementations */
struct {
u32 ipcr;
} emac4;
/* Registers unique to EMAC4SYNC implementations */
struct {
u32 rsvd1;
u32 revid;
u32 rsvd2[2];
u32 iaht1; /* Reset, R */
u32 iaht2; /* Reset, R */
u32 iaht3; /* Reset, R */
u32 iaht4; /* Reset, R */
u32 iaht5; /* Reset, R */
u32 iaht6; /* Reset, R */
u32 iaht7; /* Reset, R */
u32 iaht8; /* Reset, R */
u32 gaht1; /* Reset, R */
u32 gaht2; /* Reset, R */
u32 gaht3; /* Reset, R */
u32 gaht4; /* Reset, R */
u32 gaht5; /* Reset, R */
u32 gaht6; /* Reset, R */
u32 gaht7; /* Reset, R */
u32 gaht8; /* Reset, R */
u32 tpc; /* Reset, T */
} emac4sync;
} u1;
};
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;
if (!((hdr->version == EMAC_VERSION) ||
(hdr->version == EMAC4_VERSION) ||
(hdr->version == EMAC4SYNC_VERSION)))
{
printf("This driver version doesn't support information\n"
" output for EMAC area, please update it or use older\n"
" ethtool version\n");
return res;
}
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"
"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->vtpid, p->vtci,
p->ipgvr, p->stacr, p->octx, p->ocrx);
if (hdr->version == EMAC4SYNC_VERSION) {
printf("MAHR = 0x%08x MALR = 0x%08x MMAHR = 0x%08x\n"
"MMALR = 0x%08x REVID = 0x%08x\n",
p->u0.emac4sync.mahr, p->u0.emac4sync.malr,
p->u0.emac4sync.mmahr, p->u0.emac4sync.mmalr,
p->u1.emac4sync.revid);
printf("IAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n",
p->u1.emac4sync.iaht1, p->u1.emac4sync.iaht2,
p->u1.emac4sync.iaht3, p->u1.emac4sync.iaht4);
printf(" 0x%04x 0x%04x 0x%04x 0x%04x\n",
p->u1.emac4sync.iaht5, p->u1.emac4sync.iaht6,
p->u1.emac4sync.iaht7, p->u1.emac4sync.iaht8);
printf("GAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n",
p->u1.emac4sync.gaht1, p->u1.emac4sync.gaht2,
p->u1.emac4sync.gaht3, p->u1.emac4sync.gaht4);
printf(" 0x%04x 0x%04x 0x%04x 0x%04x\n\n",
p->u1.emac4sync.gaht5, p->u1.emac4sync.gaht6,
p->u1.emac4sync.gaht7, p->u1.emac4sync.gaht8);
} else if (hdr->version == EMAC4_VERSION) {
printf("IAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n",
p->u0.emac4.iaht1, p->u0.emac4.iaht2,
p->u0.emac4.iaht3, p->u0.emac4.iaht4);
printf("GAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n",
p->u0.emac4.gaht1, p->u0.emac4.gaht2,
p->u0.emac4.gaht3, p->u0.emac4.gaht4);
printf(" IPCR = 0x%08x\n\n", p->u1.emac4.ipcr);
} else if (hdr->version == EMAC_VERSION) {
printf("IAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n",
p->u0.emac4.iaht1, p->u0.emac4.iaht2,
p->u0.emac4.iaht3, p->u0.emac4.iaht4);
printf("GAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n",
p->u0.emac4.gaht1, p->u0.emac4.gaht2,
p->u0.emac4.gaht3, p->u0.emac4.gaht4);
}
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);
unsigned 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 __maybe_unused,
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;
}
|