Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dsa: mv88e6352/mv88e6xxx: Add support for Marvell 88E6320 and 88E6321

MV88E6320 and MV88E6321 are largely compatible to MV886352,
but are members of a different chip family.

Signed-off-by: Aleksey S. Kazantsev <ioctl@yandex.ru>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Aleksey S. Kazantsev and committed by
David S. Miller
7c3d0d67 986ca37e

+65 -22
+3 -3
drivers/net/dsa/Kconfig
··· 46 46 ethernet switches chips. 47 47 48 48 config NET_DSA_MV88E6352 49 - tristate "Marvell 88E6172/88E6176/88E6352 ethernet switch chip support" 49 + tristate "Marvell 88E6172/6176/6320/6321/6352 ethernet switch chip support" 50 50 depends on NET_DSA 51 51 select NET_DSA_MV88E6XXX 52 52 select NET_DSA_TAG_EDSA 53 53 ---help--- 54 - This enables support for the Marvell 88E6172, 88E6176 and 88E6352 55 - ethernet switch chips. 54 + This enables support for the Marvell 88E6172, 88E6176, 88E6320, 55 + 88E6321 and 88E6352 ethernet switch chips. 56 56 57 57 config NET_DSA_BCM_SF2 58 58 tristate "Broadcom Starfighter 2 Ethernet switch support"
+25 -6
drivers/net/dsa/mv88e6352.c
··· 36 36 return "Marvell 88E6172"; 37 37 if ((ret & 0xfff0) == PORT_SWITCH_ID_6176) 38 38 return "Marvell 88E6176"; 39 + if (ret == PORT_SWITCH_ID_6320_A1) 40 + return "Marvell 88E6320 (A1)"; 41 + if (ret == PORT_SWITCH_ID_6320_A2) 42 + return "Marvell 88e6320 (A2)"; 43 + if ((ret & 0xfff0) == PORT_SWITCH_ID_6320) 44 + return "Marvell 88E6320"; 45 + if (ret == PORT_SWITCH_ID_6321_A1) 46 + return "Marvell 88E6321 (A1)"; 47 + if (ret == PORT_SWITCH_ID_6321_A2) 48 + return "Marvell 88e6321 (A2)"; 49 + if ((ret & 0xfff0) == PORT_SWITCH_ID_6321) 50 + return "Marvell 88E6321"; 39 51 if (ret == PORT_SWITCH_ID_6352_A0) 40 52 return "Marvell 88E6352 (A0)"; 41 53 if (ret == PORT_SWITCH_ID_6352_A1) ··· 96 84 97 85 static int mv88e6352_get_temp(struct dsa_switch *ds, int *temp) 98 86 { 87 + int phy = mv88e6xxx_6320_family(ds) ? 3 : 0; 99 88 int ret; 100 89 101 90 *temp = 0; 102 91 103 - ret = mv88e6xxx_phy_page_read(ds, 0, 6, 27); 92 + ret = mv88e6xxx_phy_page_read(ds, phy, 6, 27); 104 93 if (ret < 0) 105 94 return ret; 106 95 ··· 112 99 113 100 static int mv88e6352_get_temp_limit(struct dsa_switch *ds, int *temp) 114 101 { 102 + int phy = mv88e6xxx_6320_family(ds) ? 3 : 0; 115 103 int ret; 116 104 117 105 *temp = 0; 118 106 119 - ret = mv88e6xxx_phy_page_read(ds, 0, 6, 26); 107 + ret = mv88e6xxx_phy_page_read(ds, phy, 6, 26); 120 108 if (ret < 0) 121 109 return ret; 122 110 ··· 128 114 129 115 static int mv88e6352_set_temp_limit(struct dsa_switch *ds, int temp) 130 116 { 117 + int phy = mv88e6xxx_6320_family(ds) ? 3 : 0; 131 118 int ret; 132 119 133 - ret = mv88e6xxx_phy_page_read(ds, 0, 6, 26); 120 + ret = mv88e6xxx_phy_page_read(ds, phy, 6, 26); 134 121 if (ret < 0) 135 122 return ret; 136 123 temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f); 137 - return mv88e6xxx_phy_page_write(ds, 0, 6, 26, 124 + return mv88e6xxx_phy_page_write(ds, phy, 6, 26, 138 125 (ret & 0xe0ff) | (temp << 8)); 139 126 } 140 127 141 128 static int mv88e6352_get_temp_alarm(struct dsa_switch *ds, bool *alarm) 142 129 { 130 + int phy = mv88e6xxx_6320_family(ds) ? 3 : 0; 143 131 int ret; 144 132 145 133 *alarm = false; 146 134 147 - ret = mv88e6xxx_phy_page_read(ds, 0, 6, 26); 135 + ret = mv88e6xxx_phy_page_read(ds, phy, 6, 26); 148 136 if (ret < 0) 149 137 return ret; 150 138 ··· 410 394 .fdb_getnext = mv88e6xxx_port_fdb_getnext, 411 395 }; 412 396 413 - MODULE_ALIAS("platform:mv88e6352"); 414 397 MODULE_ALIAS("platform:mv88e6172"); 398 + MODULE_ALIAS("platform:mv88e6176"); 399 + MODULE_ALIAS("platform:mv88e6320"); 400 + MODULE_ALIAS("platform:mv88e6321"); 401 + MODULE_ALIAS("platform:mv88e6352");
+30 -12
drivers/net/dsa/mv88e6xxx.c
··· 517 517 return false; 518 518 } 519 519 520 + bool mv88e6xxx_6320_family(struct dsa_switch *ds) 521 + { 522 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 523 + 524 + switch (ps->id) { 525 + case PORT_SWITCH_ID_6320: 526 + case PORT_SWITCH_ID_6321: 527 + return true; 528 + } 529 + return false; 530 + } 531 + 520 532 static bool mv88e6xxx_6351_family(struct dsa_switch *ds) 521 533 { 522 534 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); ··· 577 565 { 578 566 int ret; 579 567 580 - if (mv88e6xxx_6352_family(ds)) 568 + if (mv88e6xxx_6320_family(ds) || mv88e6xxx_6352_family(ds)) 581 569 port = (port + 1) << 5; 582 570 583 571 /* Snapshot the hardware statistics counters for this port. */ ··· 1389 1377 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 1390 1378 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || 1391 1379 mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds) || 1392 - mv88e6xxx_6065_family(ds)) { 1380 + mv88e6xxx_6065_family(ds) || mv88e6xxx_6320_family(ds)) { 1393 1381 /* MAC Forcing register: don't force link, speed, 1394 1382 * duplex or flow control state to any particular 1395 1383 * values on physical ports, but force the CPU port ··· 1435 1423 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 1436 1424 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || 1437 1425 mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds) || 1438 - mv88e6xxx_6185_family(ds)) 1426 + mv88e6xxx_6185_family(ds) || mv88e6xxx_6320_family(ds)) 1439 1427 reg = PORT_CONTROL_IGMP_MLD_SNOOP | 1440 1428 PORT_CONTROL_USE_TAG | PORT_CONTROL_USE_IP | 1441 1429 PORT_CONTROL_STATE_FORWARDING; ··· 1443 1431 if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds)) 1444 1432 reg |= PORT_CONTROL_DSA_TAG; 1445 1433 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 1446 - mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds)) { 1434 + mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || 1435 + mv88e6xxx_6320_family(ds)) { 1447 1436 if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA) 1448 1437 reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA; 1449 1438 else ··· 1454 1441 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 1455 1442 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || 1456 1443 mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds) || 1457 - mv88e6xxx_6185_family(ds)) { 1444 + mv88e6xxx_6185_family(ds) || mv88e6xxx_6320_family(ds)) { 1458 1445 if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA) 1459 1446 reg |= PORT_CONTROL_EGRESS_ADD_TAG; 1460 1447 } 1461 1448 } 1462 1449 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 1463 1450 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || 1464 - mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds)) { 1451 + mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds) || 1452 + mv88e6xxx_6320_family(ds)) { 1465 1453 if (ds->dsa_port_mask & (1 << port)) 1466 1454 reg |= PORT_CONTROL_FRAME_MODE_DSA; 1467 1455 if (port == dsa_upstream_port(ds)) ··· 1487 1473 reg = 0; 1488 1474 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 1489 1475 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || 1490 - mv88e6xxx_6095_family(ds)) 1476 + mv88e6xxx_6095_family(ds) || mv88e6xxx_6320_family(ds)) 1491 1477 reg = PORT_CONTROL_2_MAP_DA; 1492 1478 1493 1479 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 1494 - mv88e6xxx_6165_family(ds)) 1480 + mv88e6xxx_6165_family(ds) || mv88e6xxx_6320_family(ds)) 1495 1481 reg |= PORT_CONTROL_2_JUMBO_10240; 1496 1482 1497 1483 if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds)) { ··· 1528 1514 goto abort; 1529 1515 1530 1516 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 1531 - mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds)) { 1517 + mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || 1518 + mv88e6xxx_6320_family(ds)) { 1532 1519 /* Do not limit the period of time that this port can 1533 1520 * be paused for by the remote end or the period of 1534 1521 * time that this port can pause the remote end. ··· 1579 1564 1580 1565 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 1581 1566 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || 1582 - mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds)) { 1567 + mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds) || 1568 + mv88e6xxx_6320_family(ds)) { 1583 1569 /* Rate Control: disable ingress rate limiting. */ 1584 1570 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), 1585 1571 PORT_RATE_CONTROL, 0x0001); ··· 1992 1976 (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT)); 1993 1977 1994 1978 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 1995 - mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds)) { 1979 + mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || 1980 + mv88e6xxx_6320_family(ds)) { 1996 1981 /* Send all frames with destination addresses matching 1997 1982 * 01:80:c2:00:00:2x to the CPU port. 1998 1983 */ ··· 2012 1995 2013 1996 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || 2014 1997 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || 2015 - mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds)) { 1998 + mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds) || 1999 + mv88e6xxx_6320_family(ds)) { 2016 2000 /* Disable ingress rate limiting by resetting all 2017 2001 * ingress rate limit registers to their initial 2018 2002 * state.
+7 -1
drivers/net/dsa/mv88e6xxx.h
··· 89 89 #define PORT_SWITCH_ID_6182 0x1a60 90 90 #define PORT_SWITCH_ID_6185 0x1a70 91 91 #define PORT_SWITCH_ID_6240 0x2400 92 - #define PORT_SWITCH_ID_6320 0x1250 92 + #define PORT_SWITCH_ID_6320 0x1150 93 + #define PORT_SWITCH_ID_6320_A1 0x1151 94 + #define PORT_SWITCH_ID_6320_A2 0x1152 95 + #define PORT_SWITCH_ID_6321 0x3100 96 + #define PORT_SWITCH_ID_6321_A1 0x3101 97 + #define PORT_SWITCH_ID_6321_A2 0x3102 93 98 #define PORT_SWITCH_ID_6350 0x3710 94 99 #define PORT_SWITCH_ID_6351 0x3750 95 100 #define PORT_SWITCH_ID_6352 0x3520 ··· 415 410 int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg); 416 411 int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page, 417 412 int reg, int val); 413 + bool mv88e6xxx_6320_family(struct dsa_switch *ds); 418 414 extern struct dsa_switch_driver mv88e6131_switch_driver; 419 415 extern struct dsa_switch_driver mv88e6123_61_65_switch_driver; 420 416 extern struct dsa_switch_driver mv88e6352_switch_driver;