@@ -33,6 +33,7 @@ static const u8 ksz8795_regs[] = {
33
33
[REG_IND_DATA_HI ] = 0x71 ,
34
34
[REG_IND_DATA_LO ] = 0x75 ,
35
35
[REG_IND_MIB_CHECK ] = 0x74 ,
36
+ [REG_IND_BYTE ] = 0xA0 ,
36
37
[P_FORCE_CTRL ] = 0x0C ,
37
38
[P_LINK_STATUS ] = 0x0E ,
38
39
[P_LOCAL_CTRL ] = 0x07 ,
@@ -222,6 +223,25 @@ static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits,
222
223
bits , set ? bits : 0 );
223
224
}
224
225
226
+ static int ksz8_ind_write8 (struct ksz_device * dev , u8 table , u16 addr , u8 data )
227
+ {
228
+ struct ksz8 * ksz8 = dev -> priv ;
229
+ const u8 * regs = ksz8 -> regs ;
230
+ u16 ctrl_addr ;
231
+ int ret = 0 ;
232
+
233
+ mutex_lock (& dev -> alu_mutex );
234
+
235
+ ctrl_addr = IND_ACC_TABLE (table ) | addr ;
236
+ ret = ksz_write8 (dev , regs [REG_IND_BYTE ], data );
237
+ if (!ret )
238
+ ret = ksz_write16 (dev , regs [REG_IND_CTRL_0 ], ctrl_addr );
239
+
240
+ mutex_unlock (& dev -> alu_mutex );
241
+
242
+ return ret ;
243
+ }
244
+
225
245
static int ksz8_reset_switch (struct ksz_device * dev )
226
246
{
227
247
if (ksz_is_ksz88x3 (dev )) {
@@ -1391,6 +1411,23 @@ static void ksz8_config_cpu_port(struct dsa_switch *ds)
1391
1411
}
1392
1412
}
1393
1413
1414
+ static int ksz8_handle_global_errata (struct dsa_switch * ds )
1415
+ {
1416
+ struct ksz_device * dev = ds -> priv ;
1417
+ int ret = 0 ;
1418
+
1419
+ /* KSZ87xx Errata DS80000687C.
1420
+ * Module 2: Link drops with some EEE link partners.
1421
+ * An issue with the EEE next page exchange between the
1422
+ * KSZ879x/KSZ877x/KSZ876x and some EEE link partners may result in
1423
+ * the link dropping.
1424
+ */
1425
+ if (dev -> ksz87xx_eee_link_erratum )
1426
+ ret = ksz8_ind_write8 (dev , TABLE_EEE , REG_IND_EEE_GLOB2_HI , 0 );
1427
+
1428
+ return ret ;
1429
+ }
1430
+
1394
1431
static int ksz8_setup (struct dsa_switch * ds )
1395
1432
{
1396
1433
struct ksz_device * dev = ds -> priv ;
@@ -1458,7 +1495,7 @@ static int ksz8_setup(struct dsa_switch *ds)
1458
1495
1459
1496
ds -> configure_vlan_while_not_filtering = false;
1460
1497
1461
- return 0 ;
1498
+ return ksz8_handle_global_errata ( ds ) ;
1462
1499
}
1463
1500
1464
1501
static void ksz8_get_caps (struct dsa_switch * ds , int port ,
@@ -1575,6 +1612,7 @@ struct ksz_chip_data {
1575
1612
int num_statics ;
1576
1613
int cpu_ports ;
1577
1614
int port_cnt ;
1615
+ bool ksz87xx_eee_link_erratum ;
1578
1616
};
1579
1617
1580
1618
static const struct ksz_chip_data ksz8_switch_chips [] = {
@@ -1586,6 +1624,7 @@ static const struct ksz_chip_data ksz8_switch_chips[] = {
1586
1624
.num_statics = 8 ,
1587
1625
.cpu_ports = 0x10 , /* can be configured as cpu port */
1588
1626
.port_cnt = 5 , /* total cpu and user ports */
1627
+ .ksz87xx_eee_link_erratum = true,
1589
1628
},
1590
1629
{
1591
1630
/*
@@ -1609,6 +1648,7 @@ static const struct ksz_chip_data ksz8_switch_chips[] = {
1609
1648
.num_statics = 8 ,
1610
1649
.cpu_ports = 0x10 , /* can be configured as cpu port */
1611
1650
.port_cnt = 4 , /* total cpu and user ports */
1651
+ .ksz87xx_eee_link_erratum = true,
1612
1652
},
1613
1653
{
1614
1654
.chip_id = 0x8765 ,
@@ -1618,6 +1658,7 @@ static const struct ksz_chip_data ksz8_switch_chips[] = {
1618
1658
.num_statics = 8 ,
1619
1659
.cpu_ports = 0x10 , /* can be configured as cpu port */
1620
1660
.port_cnt = 5 , /* total cpu and user ports */
1661
+ .ksz87xx_eee_link_erratum = true,
1621
1662
},
1622
1663
{
1623
1664
.chip_id = 0x8830 ,
@@ -1652,6 +1693,8 @@ static int ksz8_switch_init(struct ksz_device *dev)
1652
1693
dev -> host_mask = chip -> cpu_ports ;
1653
1694
dev -> port_mask = (BIT (dev -> phy_port_cnt ) - 1 ) |
1654
1695
chip -> cpu_ports ;
1696
+ dev -> ksz87xx_eee_link_erratum =
1697
+ chip -> ksz87xx_eee_link_erratum ;
1655
1698
break ;
1656
1699
}
1657
1700
}
0 commit comments