aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>2016-03-31 16:53:44 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-04 21:31:35 -0400
commit11ea809f1a74b006f08e7dad0b257e06c817f313 (patch)
tree26743b6a2f56d3a0ed06b8c8e12bf8eb029f77e2 /drivers
parentf74df0be82d7d29747bfd68d955f4f573f9e5691 (diff)
net: dsa: mv88e6xxx: support 256 databases
The 6185 family of devices has only 256 address databases. Their 8-bit FID for ATU and VTU operations are split into ATU Control and ATU/VTU Operation registers. Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/dsa/mv88e6xxx.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index f103319dbe14..75a4abc595b1 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -1003,6 +1003,20 @@ static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, u16 fid, u16 cmd)
1003 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID, fid); 1003 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID, fid);
1004 if (ret < 0) 1004 if (ret < 0)
1005 return ret; 1005 return ret;
1006 } else if (mv88e6xxx_num_databases(ds) == 256) {
1007 /* ATU DBNum[7:4] are located in ATU Control 15:12 */
1008 ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_ATU_CONTROL);
1009 if (ret < 0)
1010 return ret;
1011
1012 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_CONTROL,
1013 (ret & 0xfff) |
1014 ((fid << 8) & 0xf000));
1015 if (ret < 0)
1016 return ret;
1017
1018 /* ATU DBNum[3:0] are located in ATU Operation 3:0 */
1019 cmd |= fid & 0xf;
1006 } 1020 }
1007 1021
1008 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_OP, cmd); 1022 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_OP, cmd);
@@ -1373,6 +1387,17 @@ static int _mv88e6xxx_vtu_getnext(struct dsa_switch *ds,
1373 return ret; 1387 return ret;
1374 1388
1375 next.fid = ret & GLOBAL_VTU_FID_MASK; 1389 next.fid = ret & GLOBAL_VTU_FID_MASK;
1390 } else if (mv88e6xxx_num_databases(ds) == 256) {
1391 /* VTU DBNum[7:4] are located in VTU Operation 11:8, and
1392 * VTU DBNum[3:0] are located in VTU Operation 3:0
1393 */
1394 ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL,
1395 GLOBAL_VTU_OP);
1396 if (ret < 0)
1397 return ret;
1398
1399 next.fid = (ret & 0xf00) >> 4;
1400 next.fid |= ret & 0xf;
1376 } 1401 }
1377 1402
1378 if (mv88e6xxx_has_stu(ds)) { 1403 if (mv88e6xxx_has_stu(ds)) {
@@ -1443,6 +1468,7 @@ unlock:
1443static int _mv88e6xxx_vtu_loadpurge(struct dsa_switch *ds, 1468static int _mv88e6xxx_vtu_loadpurge(struct dsa_switch *ds,
1444 struct mv88e6xxx_vtu_stu_entry *entry) 1469 struct mv88e6xxx_vtu_stu_entry *entry)
1445{ 1470{
1471 u16 op = GLOBAL_VTU_OP_VTU_LOAD_PURGE;
1446 u16 reg = 0; 1472 u16 reg = 0;
1447 int ret; 1473 int ret;
1448 1474
@@ -1470,6 +1496,12 @@ static int _mv88e6xxx_vtu_loadpurge(struct dsa_switch *ds,
1470 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_FID, reg); 1496 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_FID, reg);
1471 if (ret < 0) 1497 if (ret < 0)
1472 return ret; 1498 return ret;
1499 } else if (mv88e6xxx_num_databases(ds) == 256) {
1500 /* VTU DBNum[7:4] are located in VTU Operation 11:8, and
1501 * VTU DBNum[3:0] are located in VTU Operation 3:0
1502 */
1503 op |= (entry->fid & 0xf0) << 8;
1504 op |= entry->fid & 0xf;
1473 } 1505 }
1474 1506
1475 reg = GLOBAL_VTU_VID_VALID; 1507 reg = GLOBAL_VTU_VID_VALID;
@@ -1479,7 +1511,7 @@ loadpurge:
1479 if (ret < 0) 1511 if (ret < 0)
1480 return ret; 1512 return ret;
1481 1513
1482 return _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_VTU_LOAD_PURGE); 1514 return _mv88e6xxx_vtu_cmd(ds, op);
1483} 1515}
1484 1516
1485static int _mv88e6xxx_stu_getnext(struct dsa_switch *ds, u8 sid, 1517static int _mv88e6xxx_stu_getnext(struct dsa_switch *ds, u8 sid,
@@ -1564,6 +1596,8 @@ static int _mv88e6xxx_port_fid(struct dsa_switch *ds, int port, u16 *new,
1564 1596
1565 if (mv88e6xxx_num_databases(ds) == 4096) 1597 if (mv88e6xxx_num_databases(ds) == 4096)
1566 upper_mask = 0xff; 1598 upper_mask = 0xff;
1599 else if (mv88e6xxx_num_databases(ds) == 256)
1600 upper_mask = 0xf;
1567 else 1601 else
1568 return -EOPNOTSUPP; 1602 return -EOPNOTSUPP;
1569 1603