1 /*
2  *  Copyright (c) 2004, 2005 Zultys Technologies
3  *  Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
4  */
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <stddef.h>
8 
9 #include "internal.h"
10 
11 /* Ethtool get_regs complex data.
12  * we want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH
13  * when available.
14  *
15  * Returned BLOB consists of the ibm_emac_ethtool_regs_hdr,
16  * MAL registers, EMAC registers and optional ZMII, RGMII, TAH registers.
17  * Each register component is preceded with emac_ethtool_regs_subhdr.
18  * Order of the optional headers follows their relative bit posititions
19  * in emac_ethtool_regs_hdr.components
20  */
21 #define EMAC_ETHTOOL_REGS_ZMII		0x00000001
22 #define EMAC_ETHTOOL_REGS_RGMII		0x00000002
23 #define EMAC_ETHTOOL_REGS_TAH		0x00000004
24 
25 #define EMAC_VERSION			3
26 #define EMAC4_VERSION			4
27 #define EMAC4SYNC_VERSION		5
28 
29 struct emac_ethtool_regs_hdr {
30 	u32 components;
31 };
32 
33 struct emac_ethtool_regs_subhdr {
34 	u32 version;
35 	u32 index;
36 };
37 
38 struct emac_regs {
39 	/* Common registers across all EMAC implementations. */
40 	u32 mr0;			/* Special 	*/
41 	u32 mr1;			/* Reset 	*/
42 	u32 tmr0;			/* Special 	*/
43 	u32 tmr1;			/* Special 	*/
44 	u32 rmr;			/* Reset 	*/
45 	u32 isr;			/* Always 	*/
46 	u32 iser;			/* Reset 	*/
47 	u32 iahr;			/* Reset, R, T 	*/
48 	u32 ialr;			/* Reset, R, T 	*/
49 	u32 vtpid;			/* Reset, R, T 	*/
50 	u32 vtci;			/* Reset, R, T 	*/
51 	u32 ptr;			/* Reset,    T 	*/
52 	union {
53 		/* Registers unique to EMAC4 implementations */
54 		struct {
55 			u32 iaht1;	/* Reset, R	*/
56 			u32 iaht2;	/* Reset, R	*/
57 			u32 iaht3;	/* Reset, R	*/
58 			u32 iaht4;	/* Reset, R	*/
59 			u32 gaht1;	/* Reset, R	*/
60 			u32 gaht2;	/* Reset, R	*/
61 			u32 gaht3;	/* Reset, R	*/
62 			u32 gaht4;	/* Reset, R	*/
63 		} emac4;
64 		/* Registers unique to EMAC4SYNC implementations */
65 		struct {
66 			u32 mahr;	/* Reset, R, T  */
67 			u32 malr;	/* Reset, R, T  */
68 			u32 mmahr;	/* Reset, R, T  */
69 			u32 mmalr;	/* Reset, R, T  */
70 			u32 rsvd0[4];
71 		} emac4sync;
72 	} u0;
73 	/* Common registers across all EMAC implementations. */
74 	u32 lsah;
75 	u32 lsal;
76 	u32 ipgvr;			/* Reset,    T 	*/
77 	u32 stacr;			/* Special 	*/
78 	u32 trtr;			/* Special 	*/
79 	u32 rwmr;			/* Reset 	*/
80 	u32 octx;
81 	u32 ocrx;
82 	union {
83 		/* Registers unique to EMAC4 implementations */
84 		struct {
85 			u32 ipcr;
86 		} emac4;
87 		/* Registers unique to EMAC4SYNC implementations */
88 		struct {
89 			u32 rsvd1;
90 			u32 revid;
91 			u32 rsvd2[2];
92 			u32 iaht1;	/* Reset, R     */
93 			u32 iaht2;	/* Reset, R     */
94 			u32 iaht3;	/* Reset, R     */
95 			u32 iaht4;	/* Reset, R     */
96 			u32 iaht5;	/* Reset, R     */
97 			u32 iaht6;	/* Reset, R     */
98 			u32 iaht7;	/* Reset, R     */
99 			u32 iaht8;	/* Reset, R     */
100 			u32 gaht1;	/* Reset, R     */
101 			u32 gaht2;	/* Reset, R     */
102 			u32 gaht3;	/* Reset, R     */
103 			u32 gaht4;	/* Reset, R     */
104 			u32 gaht5;	/* Reset, R     */
105 			u32 gaht6;	/* Reset, R     */
106 			u32 gaht7;	/* Reset, R     */
107 			u32 gaht8;	/* Reset, R     */
108 			u32 tpc;	/* Reset, T     */
109 		} emac4sync;
110 	} u1;
111 };
112 
113 struct mal_regs {
114 	u32 tx_count;
115 	u32 rx_count;
116 
117 	u32 cfg;
118 	u32 esr;
119 	u32 ier;
120 	u32 tx_casr;
121 	u32 tx_carr;
122 	u32 tx_eobisr;
123 	u32 tx_deir;
124 	u32 rx_casr;
125 	u32 rx_carr;
126 	u32 rx_eobisr;
127 	u32 rx_deir;
128 	u32 tx_ctpr[32];
129 	u32 rx_ctpr[32];
130 	u32 rcbs[32];
131 };
132 
133 struct zmii_regs {
134 	u32 fer;
135 	u32 ssr;
136 	u32 smiisr;
137 };
138 
139 struct rgmii_regs {
140 	u32 fer;
141 	u32 ssr;
142 };
143 
144 struct tah_regs {
145 	u32 revid;
146 	u32 pad[3];
147 	u32 mr;
148 	u32 ssr0;
149 	u32 ssr1;
150 	u32 ssr2;
151 	u32 ssr3;
152 	u32 ssr4;
153 	u32 ssr5;
154 	u32 tsr;
155 };
156 
print_emac_regs(void * buf)157 static void *print_emac_regs(void *buf)
158 {
159 	struct emac_ethtool_regs_subhdr *hdr = buf;
160 	struct emac_regs *p = (struct emac_regs *)(hdr + 1);
161 	void *res = p + 1;
162 
163 	if (!((hdr->version == EMAC_VERSION) ||
164 		(hdr->version == EMAC4_VERSION) ||
165 		(hdr->version == EMAC4SYNC_VERSION)))
166 	{
167 		printf("This driver version doesn't support information\n"
168 			" output for EMAC area, please update it or use older\n"
169 			" ethtool version\n");
170 		return res;
171 	}
172 
173 	printf("EMAC%d Registers\n", hdr->index);
174 	printf("-----------------\n");
175 	printf("MR0   = 0x%08x MR1  = 0x%08x RMR = 0x%08x\n"
176 	       "ISR   = 0x%08x ISER = 0x%08x\n"
177 	       "TMR0  = 0x%08x TMR1 = 0x%08x\n"
178 	       "TRTR  = 0x%08x RWMR = 0x%08x\n"
179 	       "IAR   = %04x%08x\n"
180 	       "LSA   = %04x%08x\n"
181 	       "VTPID = 0x%04x VTCI = 0x%04x\n"
182 	       "IPGVR = 0x%04x STACR = 0x%08x\n"
183 	       "OCTX  = 0x%08x OCRX = 0x%08x\n",
184 	       p->mr0, p->mr1, p->rmr,
185 	       p->isr, p->iser,
186 	       p->tmr0, p->tmr1,
187 	       p->trtr, p->rwmr,
188 	       p->iahr, p->ialr,
189 	       p->lsah, p->lsal,
190 	       p->vtpid, p->vtci,
191 	       p->ipgvr, p->stacr, p->octx, p->ocrx);
192 
193 	if (hdr->version == EMAC4SYNC_VERSION) {
194 		printf("MAHR  = 0x%08x MALR  = 0x%08x MMAHR = 0x%08x\n"
195 			"MMALR  = 0x%08x REVID  = 0x%08x\n",
196 			p->u0.emac4sync.mahr, p->u0.emac4sync.malr,
197 			p->u0.emac4sync.mmahr, p->u0.emac4sync.mmalr,
198 			p->u1.emac4sync.revid);
199 
200 		printf("IAHT  = 0x%04x 0x%04x 0x%04x 0x%04x\n",
201 			p->u1.emac4sync.iaht1, p->u1.emac4sync.iaht2,
202 			p->u1.emac4sync.iaht3, p->u1.emac4sync.iaht4);
203 		printf("        0x%04x 0x%04x 0x%04x 0x%04x\n",
204 			p->u1.emac4sync.iaht5, p->u1.emac4sync.iaht6,
205 			p->u1.emac4sync.iaht7, p->u1.emac4sync.iaht8);
206 
207 
208 		printf("GAHT  = 0x%04x 0x%04x 0x%04x 0x%04x\n",
209 			p->u1.emac4sync.gaht1, p->u1.emac4sync.gaht2,
210 			p->u1.emac4sync.gaht3, p->u1.emac4sync.gaht4);
211 		printf("        0x%04x 0x%04x 0x%04x 0x%04x\n\n",
212 			p->u1.emac4sync.gaht5, p->u1.emac4sync.gaht6,
213 			p->u1.emac4sync.gaht7, p->u1.emac4sync.gaht8);
214 
215 	} else if (hdr->version == EMAC4_VERSION) {
216 		printf("IAHT  = 0x%04x 0x%04x 0x%04x 0x%04x\n",
217 			p->u0.emac4.iaht1, p->u0.emac4.iaht2,
218 			p->u0.emac4.iaht3, p->u0.emac4.iaht4);
219 
220 		printf("GAHT  = 0x%04x 0x%04x 0x%04x 0x%04x\n",
221 			p->u0.emac4.gaht1, p->u0.emac4.gaht2,
222 			p->u0.emac4.gaht3, p->u0.emac4.gaht4);
223 
224 		printf(" IPCR = 0x%08x\n\n", p->u1.emac4.ipcr);
225 	} else if (hdr->version == EMAC_VERSION) {
226 		printf("IAHT  = 0x%04x 0x%04x 0x%04x 0x%04x\n",
227 			p->u0.emac4.iaht1, p->u0.emac4.iaht2,
228 			p->u0.emac4.iaht3, p->u0.emac4.iaht4);
229 
230 		printf("GAHT  = 0x%04x 0x%04x 0x%04x 0x%04x\n",
231 			p->u0.emac4.gaht1, p->u0.emac4.gaht2,
232 			p->u0.emac4.gaht3, p->u0.emac4.gaht4);
233 	}
234 	return res;
235 }
236 
print_mal_regs(void * buf)237 static void *print_mal_regs(void *buf)
238 {
239 	struct emac_ethtool_regs_subhdr *hdr = buf;
240 	struct mal_regs *p = (struct mal_regs *)(hdr + 1);
241 	int i;
242 
243 	printf("MAL%d Registers\n", hdr->index);
244 	printf("-----------------\n");
245 	printf("CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n"
246 	       "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n"
247 	       "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n",
248 	       p->cfg, p->esr, p->ier,
249 	       p->tx_casr, p->tx_carr, p->tx_eobisr, p->tx_deir,
250 	       p->rx_casr, p->rx_carr, p->rx_eobisr, p->rx_deir);
251 
252 	printf("TX|");
253 	for (i = 0; i < p->tx_count; ++i) {
254 		if (i && !(i % 4))
255 			printf("\n   ");
256 		printf("CTP%d = 0x%08x ", i, p->tx_ctpr[i]);
257 	}
258 	printf("\nRX|");
259 	for (i = 0; i < p->rx_count; ++i) {
260 		if (i && !(i % 4))
261 			printf("\n   ");
262 		printf("CTP%d = 0x%08x ", i, p->rx_ctpr[i]);
263 	}
264 	printf("\n   ");
265 	for (i = 0; i < p->rx_count; ++i) {
266 		u32 r = p->rcbs[i];
267 		if (i && !(i % 3))
268 			printf("\n   ");
269 		printf("RCBS%d = 0x%08x (%d) ", i, r, r * 16);
270 	}
271 	printf("\n\n");
272 	return p + 1;
273 }
274 
print_zmii_regs(void * buf)275 static void *print_zmii_regs(void *buf)
276 {
277 	struct emac_ethtool_regs_subhdr *hdr = buf;
278 	struct zmii_regs *p = (struct zmii_regs *)(hdr + 1);
279 
280 	printf("ZMII%d Registers\n", hdr->index);
281 	printf("-----------------\n");
282 	printf("FER    = %08x SSR = %08x\n"
283 	       "SMIISR = %08x\n\n", p->fer, p->ssr, p->smiisr);
284 
285 	return p + 1;
286 }
287 
print_rgmii_regs(void * buf)288 static void *print_rgmii_regs(void *buf)
289 {
290 	struct emac_ethtool_regs_subhdr *hdr = buf;
291 	struct rgmii_regs *p = (struct rgmii_regs *)(hdr + 1);
292 
293 	printf("RGMII%d Registers\n", hdr->index);
294 	printf("-----------------\n");
295 	printf("FER    = %08x SSR = %08x\n\n", p->fer, p->ssr);
296 
297 	return p + 1;
298 }
299 
print_tah_regs(void * buf)300 static void *print_tah_regs(void *buf)
301 {
302 	struct emac_ethtool_regs_subhdr *hdr = buf;
303 	struct tah_regs *p = (struct tah_regs *)(hdr + 1);
304 
305 	printf("TAH%d Registers\n", hdr->index);
306 	printf("-----------------\n");
307 
308 	printf("REVID = %08x MR = %08x TSR = %08x\n"
309 	       "SSR0  = %08x SSR1 = %08x SSR2 = %08x\n"
310 	       "SSR3  = %08x SSR4 = %08x SSR5 = %08x\n\n",
311 	       p->revid, p->mr, p->tsr,
312 	       p->ssr0, p->ssr1, p->ssr2, p->ssr3, p->ssr4, p->ssr5);
313 
314 	return p + 1;
315 }
316 
ibm_emac_dump_regs(struct ethtool_drvinfo * info maybe_unused,struct ethtool_regs * regs)317 int ibm_emac_dump_regs(struct ethtool_drvinfo *info maybe_unused,
318 		       struct ethtool_regs *regs)
319 {
320 	struct emac_ethtool_regs_hdr *hdr =
321 	    (struct emac_ethtool_regs_hdr *)regs->data;
322 	void *buf = hdr + 1;
323 
324 	buf = print_mal_regs(buf);
325 	buf = print_emac_regs(buf);
326 	if (hdr->components & EMAC_ETHTOOL_REGS_ZMII)
327 		buf = print_zmii_regs(buf);
328 	if (hdr->components & EMAC_ETHTOOL_REGS_RGMII)
329 		buf = print_rgmii_regs(buf);
330 	if (hdr->components & EMAC_ETHTOOL_REGS_TAH)
331 		print_tah_regs(buf);
332 
333 	return 0;
334 }
335