blob: ab21d012c6b3a2dec91c272b63cee95327df0f10 [file] [log] [blame]
Vivien Didelotcb8e9802018-12-18 14:06:35 -05001#include <stdio.h>
2#include <string.h>
3
4#include "internal.h"
5
Vivien Didelotff99e462018-12-18 14:06:36 -05006/* Macros and dump functions for the 16-bit mv88e6xxx per-port registers */
7
8#define REG(_reg, _name, _val) \
9 printf("%.02u: %-38.38s 0x%.4x\n", _reg, _name, _val)
10
11#define FIELD(_name, _fmt, ...) \
12 printf(" %-36.36s " _fmt "\n", _name, ##__VA_ARGS__)
13
14#define FIELD_BITMAP(_name, _val) \
15 FIELD(_name, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", \
16 ((_val) & 0x0001) ? "0 " : "", \
17 ((_val) & 0x0002) ? "1 " : "", \
18 ((_val) & 0x0004) ? "2 " : "", \
19 ((_val) & 0x0008) ? "3 " : "", \
20 ((_val) & 0x0010) ? "4 " : "", \
21 ((_val) & 0x0020) ? "5 " : "", \
22 ((_val) & 0x0040) ? "6 " : "", \
23 ((_val) & 0x0080) ? "7 " : "", \
24 ((_val) & 0x0100) ? "8 " : "", \
25 ((_val) & 0x0200) ? "9 " : "", \
26 ((_val) & 0x0400) ? "10 " : "", \
27 ((_val) & 0x0800) ? "11 " : "", \
28 ((_val) & 0x1000) ? "12 " : "", \
29 ((_val) & 0x2000) ? "13 " : "", \
30 ((_val) & 0x4000) ? "14 " : "", \
31 ((_val) & 0x8000) ? "15 " : "")
32
Vivien Didelota13a0532018-12-18 14:06:38 -050033static void dsa_mv88e6161(int reg, u16 val)
34{
35 switch (reg) {
36 case 0:
37 REG(reg, "Port Status", val);
38 FIELD("Pause Enabled", "%u", !!(val & 0x8000));
39 FIELD("My Pause", "%u", !!(val & 0x4000));
40 FIELD("Half-duplex Flow Control", "%u", !!(val & 0x2000));
41 FIELD("802.3 PHY Detected", "%u", !!(val & 0x1000));
42 FIELD("Link Status", "%s", val & 0x0800 ? "Up" : "Down");
43 FIELD("Duplex", "%s", val & 0x0400 ? "Full" : "Half");
44 FIELD("Speed", "%s",
45 (val & 0x0300) == 0x0000 ? "10 Mbps" :
46 (val & 0x0300) == 0x0100 ? "100 Mbps" :
47 (val & 0x0300) == 0x0200 ? "1000 Mbps" :
48 (val & 0x0300) == 0x0300 ? "Reserved" : "?");
49 FIELD("Auto-Media Detect Disable", "%u", !!(val & 0x0040));
50 FIELD("Transmitter Paused", "%u", !!(val & 0x0020));
51 FIELD("Flow Control", "%u", !!(val & 0x0010));
52 FIELD("Config Duplex", "%s", val & 0x0008 ? "Full" : "Half");
53 FIELD("Config Mode", "0x%x", val & 0x0007);
54 break;
55 case 1:
56 REG(reg, "PCS Control", val);
57 FIELD("Flow Control's Forced value", "%u", !!(val & 0x0080));
58 FIELD("Force Flow Control", "%u", !!(val & 0x0040));
59 FIELD("Link's Forced value", "%s", val & 0x0020 ? "Up" : "Down");
60 FIELD("Force Link", "%u", !!(val & 0x0010));
61 FIELD("Duplex's Forced value", "%s", val & 0x0008 ? "Full" : "Half");
62 FIELD("Force Duplex", "%u", !!(val & 0x0004));
63 FIELD("Force Speed", "%s",
64 (val & 0x0003) == 0x0000 ? "10 Mbps" :
65 (val & 0x0003) == 0x0001 ? "100 Mbps" :
66 (val & 0x0003) == 0x0002 ? "1000 Mbps" :
67 (val & 0x0003) == 0x0003 ? "Not forced" : "?");
68 break;
69 case 2:
70 REG(reg, "Jamming Control", val);
71 break;
72 case 3:
73 REG(reg, "Switch Identifier", val);
74 break;
75 case 4:
76 REG(reg, "Port Control", val);
77 FIELD("Source Address Filtering controls", "%s",
78 (val & 0xc000) == 0x0000 ? "Disabled" :
79 (val & 0xc000) == 0x4000 ? "Drop On Lock" :
80 (val & 0xc000) == 0x8000 ? "Drop On Unlock" :
81 (val & 0xc000) == 0xc000 ? "Drop to CPU" : "?");
82 FIELD("Egress Mode", "%s",
83 (val & 0x3000) == 0x0000 ? "Unmodified" :
84 (val & 0x3000) == 0x1000 ? "Untagged" :
85 (val & 0x3000) == 0x2000 ? "Tagged" :
86 (val & 0x3000) == 0x3000 ? "Reserved" : "?");
87 FIELD("Ingress & Egress Header Mode", "%u", !!(val & 0x0800));
88 FIELD("IGMP and MLD Snooping", "%u", !!(val & 0x0400));
89 FIELD("Frame Mode", "%s",
90 (val & 0x0300) == 0x0000 ? "Normal" :
91 (val & 0x0300) == 0x0100 ? "DSA" :
92 (val & 0x0300) == 0x0200 ? "Provider" :
93 (val & 0x0300) == 0x0300 ? "Ether Type DSA" : "?");
94 FIELD("VLAN Tunnel", "%u", !!(val & 0x0080));
95 FIELD("TagIfBoth", "%u", !!(val & 0x0040));
96 FIELD("Initial Priority assignment", "%s",
97 (val & 0x0030) == 0x0000 ? "Defaults" :
98 (val & 0x0030) == 0x0010 ? "Tag Priority" :
99 (val & 0x0030) == 0x0020 ? "IP Priority" :
100 (val & 0x0030) == 0x0030 ? "Tag & IP Priority" : "?");
101 FIELD("Egress Flooding mode", "%s",
102 (val & 0x000c) == 0x0000 ? "No unknown DA" :
103 (val & 0x000c) == 0x0004 ? "No unknown multicast DA" :
104 (val & 0x000c) == 0x0008 ? "No unknown unicast DA" :
105 (val & 0x000c) == 0x000c ? "Allow unknown DA" : "?");
106 FIELD("Port State", "%s",
107 (val & 0x0003) == 0x0000 ? "Disabled" :
108 (val & 0x0003) == 0x0001 ? "Blocking/Listening" :
109 (val & 0x0003) == 0x0002 ? "Learning" :
110 (val & 0x0003) == 0x0003 ? "Forwarding" : "?");
111 break;
112 case 5:
113 REG(reg, "Port Control 1", val);
114 FIELD("Message Port", "%u", !!(val & 0x8000));
115 FIELD("Trunk Port", "%u", !!(val & 0x4000));
116 FIELD("Trunk ID", "%u", (val & 0x0f00) >> 8);
117 FIELD("FID[5:4]", "0x%.2x", (val & 0x0003) << 4);
118 break;
119 case 6:
120 REG(reg, "Port Base VLAN Map (Header)", val);
121 FIELD("FID[3:0]", "0x%.2x", (val & 0xf000) >> 12);
122 FIELD_BITMAP("VLANTable", val & 0x003f);
123 break;
124 case 7:
125 REG(reg, "Default VLAN ID & Priority", val);
126 FIELD("Default Priority", "0x%x", (val & 0xe000) >> 13);
127 FIELD("Force to use Default VID", "%u", !!(val & 0x1000));
128 FIELD("Default VLAN Identifier", "%u", val & 0x0fff);
129 break;
130 case 8:
131 REG(reg, "Port Control 2", val);
132 FIELD("Force good FCS in the frame", "%u", !!(val & 0x8000));
133 FIELD("Jumbo Mode", "%s",
134 (val & 0x3000) == 0x0000 ? "1522" :
135 (val & 0x3000) == 0x1000 ? "2048" :
136 (val & 0x3000) == 0x2000 ? "10240" :
137 (val & 0x3000) == 0x3000 ? "Reserved" : "?");
138 FIELD("802.1QMode", "%s",
139 (val & 0x0c00) == 0x0000 ? "Disabled" :
140 (val & 0x0c00) == 0x0400 ? "Fallback" :
141 (val & 0x0c00) == 0x0800 ? "Check" :
142 (val & 0x0c00) == 0x0c00 ? "Secure" : "?");
143 FIELD("Discard Tagged Frames", "%u", !!(val & 0x0200));
144 FIELD("Discard Untagged Frames", "%u", !!(val & 0x0100));
145 FIELD("Map using DA hits", "%u", !!(val & 0x0080));
146 FIELD("ARP Mirror enable", "%u", !!(val & 0x0040));
147 FIELD("Egress Monitor Source Port", "%u", !!(val & 0x0020));
148 FIELD("Ingress Monitor Source Port", "%u", !!(val & 0x0010));
149 break;
150 case 9:
151 REG(reg, "Egress Rate Control", val);
152 break;
153 case 10:
154 REG(reg, "Egress Rate Control 2", val);
155 break;
156 case 11:
157 REG(reg, "Port Association Vector", val);
158 break;
159 case 12:
160 REG(reg, "Port ATU Control", val);
161 break;
162 case 13:
163 REG(reg, "Priority Override", val);
164 break;
165 case 15:
166 REG(reg, "PortEType", val);
167 break;
168 case 16:
169 REG(reg, "InDiscardsLo Frame Counter", val);
170 break;
171 case 17:
172 REG(reg, "InDiscardsHi Frame Counter", val);
173 break;
174 case 18:
175 REG(reg, "InFiltered Frame Counter", val);
176 break;
177 case 19:
178 REG(reg, "OutFiltered Frame Counter", val);
179 break;
180 case 24:
181 REG(reg, "Tag Remap 0-3", val);
182 break;
183 case 25:
184 REG(reg, "Tag Remap 4-7", val);
185 break;
186 case 27:
187 REG(reg, "Queue Counters", val);
188 break;
189 default:
190 REG(reg, "Reserved", val);
191 break;
192 }
193}
194
Vivien Didelot4e980292018-12-18 14:06:37 -0500195static void dsa_mv88e6185(int reg, u16 val)
196{
197 switch (reg) {
198 case 0:
199 REG(reg, "Port Status", val);
200 break;
201 case 1:
202 REG(reg, "PCS Control", val);
203 break;
204 case 3:
205 REG(reg, "Switch Identifier", val);
206 break;
207 case 4:
208 REG(reg, "Port Control", val);
209 break;
210 case 5:
211 REG(reg, "Port Control 1", val);
212 break;
213 case 6:
214 REG(reg, "Port Base VLAN Map (Header)", val);
215 break;
216 case 7:
217 REG(reg, "Default VLAN ID & Priority", val);
218 break;
219 case 8:
220 REG(reg, "Port Control 2", val);
221 break;
222 case 9:
223 REG(reg, "Rate Control", val);
224 break;
225 case 10:
226 REG(reg, "Rate Control 2", val);
227 break;
228 case 11:
229 REG(reg, "Port Association Vector", val);
230 break;
231 case 16:
232 REG(reg, "InDiscardsLo Frame Counter", val);
233 break;
234 case 17:
235 REG(reg, "InDiscardsHi Frame Counter", val);
236 break;
237 case 18:
238 REG(reg, "InFiltered Frame Counter", val);
239 break;
240 case 19:
241 REG(reg, "OutFiltered Frame Counter", val);
242 break;
243 case 24:
244 REG(reg, "Tag Remap 0-3", val);
245 break;
246 case 25:
247 REG(reg, "Tag Remap 4-7", val);
248 break;
249 default:
250 REG(reg, "Reserved", val);
251 break;
252 }
253};
254
Vivien Didelotff99e462018-12-18 14:06:36 -0500255struct dsa_mv88e6xxx_switch {
256 void (*dump)(int reg, u16 val);
257 const char *name;
258 u16 id;
259};
260
261static const struct dsa_mv88e6xxx_switch dsa_mv88e6xxx_switches[] = {
Vivien Didelota13a0532018-12-18 14:06:38 -0500262 { .id = 0x1210, .name = "88E6123 ", .dump = dsa_mv88e6161 },
263 { .id = 0x1610, .name = "88E6161 ", .dump = dsa_mv88e6161 },
Vivien Didelot4e980292018-12-18 14:06:37 -0500264 { .id = 0x1a70, .name = "88E6185 ", .dump = dsa_mv88e6185 },
Vivien Didelotff99e462018-12-18 14:06:36 -0500265};
266
267static int dsa_mv88e6xxx_dump_regs(struct ethtool_regs *regs)
268{
269 const struct dsa_mv88e6xxx_switch *sw = NULL;
270 const u16 *data = (u16 *)regs->data;
271 u16 id;
272 int i;
273
274 /* Marvell chips have 32 per-port 16-bit registers */
275 if (regs->len < 32 * 2)
276 return 1;
277
278 id = regs->version & 0xfff0;
279
280 for (i = 0; i < ARRAY_SIZE(dsa_mv88e6xxx_switches); i++) {
281 if (id == dsa_mv88e6xxx_switches[i].id) {
282 sw = &dsa_mv88e6xxx_switches[i];
283 break;
284 }
285 }
286
287 if (!sw)
288 return 1;
289
290 printf("%s Switch Port Registers\n", sw->name);
291 printf("------------------------------\n");
292
293 for (i = 0; i < 32; i++)
294 if (sw->dump)
295 sw->dump(i, data[i]);
296 else
297 REG(i, "", data[i]);
298
299 return 0;
300}
301
302#undef FIELD_BITMAP
303#undef FIELD
304#undef REG
305
Vivien Didelotcb8e9802018-12-18 14:06:35 -0500306int dsa_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
307{
308 /* DSA per-driver register dump */
Vivien Didelotff99e462018-12-18 14:06:36 -0500309 if (!dsa_mv88e6xxx_dump_regs(regs))
310 return 0;
Vivien Didelotcb8e9802018-12-18 14:06:35 -0500311
312 /* Fallback to hexdump */
313 return 1;
314}