diff options
| author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2016-03-31 16:53:44 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-04-04 21:31:35 -0400 |
| commit | 11ea809f1a74b006f08e7dad0b257e06c817f313 (patch) | |
| tree | 26743b6a2f56d3a0ed06b8c8e12bf8eb029f77e2 /drivers | |
| parent | f74df0be82d7d29747bfd68d955f4f573f9e5691 (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.c | 36 |
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: | |||
| 1443 | static int _mv88e6xxx_vtu_loadpurge(struct dsa_switch *ds, | 1468 | static 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 | ||
| 1485 | static int _mv88e6xxx_stu_getnext(struct dsa_switch *ds, u8 sid, | 1517 | static 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 | ||
