11 #include <linux/list.h>
12 #include <linux/module.h>
13 #include <linux/netdevice.h>
21 #define ID_6085 0x04a0
22 #define ID_6095 0x0950
23 #define ID_6131 0x1060
25 static char *mv88e6131_probe(
struct mii_bus *
bus,
int sw_addr)
33 return "Marvell 88E6085";
35 return "Marvell 88E6095/88E6095F";
37 return "Marvell 88E6131";
51 for (i = 0; i < 11; i++) {
69 for (i = 0; i < 1000; i++) {
71 if ((ret & 0xc800) == 0xc800)
82 static int mv88e6131_setup_global(
struct dsa_switch *ds)
126 if (ds->
dst->pd->nr_chips > 1)
148 for (i = 0; i < 32; i++) {
152 if (i != ds->
index && i < ds->
dst->pd->nr_chips)
153 nexthop = ds->
pd->rtable[
i] & 0x1f;
161 for (i = 0; i < 8; i++)
167 for (i = 0; i < 16; i++)
179 static int mv88e6131_setup_port(
struct dsa_switch *ds,
int p)
215 if (p == dsa_upstream_port(ds)) {
232 REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
240 val = (p & 0xf) << 12;
241 if (dsa_is_cpu_port(ds, p))
244 val |= 1 << dsa_upstream_port(ds);
274 val = 0x0080 | dsa_upstream_port(ds);
275 if (p == dsa_upstream_port(ds))
313 static int mv88e6131_setup(
struct dsa_switch *ds)
325 ret = mv88e6131_switch_reset(ds);
331 ret = mv88e6131_setup_global(ds);
335 for (i = 0; i < 11; i++) {
336 ret = mv88e6131_setup_port(ds, i);
344 static int mv88e6131_port_to_phy_addr(
int port)
346 if (port >= 0 && port <= 11)
352 mv88e6131_phy_read(
struct dsa_switch *ds,
int port,
int regnum)
354 int addr = mv88e6131_port_to_phy_addr(port);
360 int port,
int regnum,
u16 val)
362 int addr = mv88e6131_port_to_phy_addr(port);
367 {
"in_good_octets", 8, 0x00, },
368 {
"in_bad_octets", 4, 0x02, },
369 {
"in_unicast", 4, 0x04, },
370 {
"in_broadcasts", 4, 0x06, },
371 {
"in_multicasts", 4, 0x07, },
372 {
"in_pause", 4, 0x16, },
373 {
"in_undersize", 4, 0x18, },
374 {
"in_fragments", 4, 0x19, },
375 {
"in_oversize", 4, 0x1a, },
376 {
"in_jabber", 4, 0x1b, },
377 {
"in_rx_error", 4, 0x1c, },
378 {
"in_fcs_error", 4, 0x1d, },
379 {
"out_octets", 8, 0x0e, },
380 {
"out_unicast", 4, 0x10, },
381 {
"out_broadcasts", 4, 0x13, },
382 {
"out_multicasts", 4, 0x12, },
383 {
"out_pause", 4, 0x15, },
384 {
"excessive", 4, 0x11, },
385 {
"collisions", 4, 0x1e, },
386 {
"deferred", 4, 0x05, },
387 {
"single", 4, 0x14, },
388 {
"multiple", 4, 0x17, },
389 {
"out_fcs_error", 4, 0x03, },
390 {
"late", 4, 0x1f, },
391 {
"hist_64bytes", 4, 0x08, },
392 {
"hist_65_127bytes", 4, 0x09, },
393 {
"hist_128_255bytes", 4, 0x0a, },
394 {
"hist_256_511bytes", 4, 0x0b, },
395 {
"hist_512_1023bytes", 4, 0x0c, },
396 {
"hist_1024_max_bytes", 4, 0x0d, },
403 mv88e6131_hw_stats, port, data);
407 mv88e6131_get_ethtool_stats(
struct dsa_switch *ds,
411 mv88e6131_hw_stats, port, data);
414 static int mv88e6131_get_sset_count(
struct dsa_switch *ds)
422 .probe = mv88e6131_probe,
423 .setup = mv88e6131_setup,
425 .phy_read = mv88e6131_phy_read,
426 .phy_write = mv88e6131_phy_write,
428 .get_strings = mv88e6131_get_strings,
429 .get_ethtool_stats = mv88e6131_get_ethtool_stats,
430 .get_sset_count = mv88e6131_get_sset_count,