3
3
* Microchip KSZ8XXX series switch driver
4
4
*
5
5
* It supports the following switches:
6
+ * - KSZ8463
6
7
* - KSZ8863, KSZ8873 aka KSZ88X3
7
8
* - KSZ8895, KSZ8864 aka KSZ8895 family
8
9
* - KSZ8794, KSZ8795, KSZ8765 aka KSZ87XX
@@ -41,7 +42,8 @@ static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
41
42
static void ksz_port_cfg (struct ksz_device * dev , int port , int offset , u8 bits ,
42
43
bool set )
43
44
{
44
- regmap_update_bits (ksz_regmap_8 (dev ), PORT_CTRL_ADDR (port , offset ),
45
+ regmap_update_bits (ksz_regmap_8 (dev ),
46
+ dev -> dev_ops -> get_port_addr (port , offset ),
45
47
bits , set ? bits : 0 );
46
48
}
47
49
@@ -140,6 +142,11 @@ int ksz8_reset_switch(struct ksz_device *dev)
140
142
KSZ8863_GLOBAL_SOFTWARE_RESET | KSZ8863_PCS_RESET , true);
141
143
ksz_cfg (dev , KSZ8863_REG_SW_RESET ,
142
144
KSZ8863_GLOBAL_SOFTWARE_RESET | KSZ8863_PCS_RESET , false);
145
+ } else if (ksz_is_ksz8463 (dev )) {
146
+ ksz_cfg (dev , KSZ8463_REG_SW_RESET ,
147
+ KSZ8463_GLOBAL_SOFTWARE_RESET , true);
148
+ ksz_cfg (dev , KSZ8463_REG_SW_RESET ,
149
+ KSZ8463_GLOBAL_SOFTWARE_RESET , false);
143
150
} else {
144
151
/* reset switch */
145
152
ksz_write8 (dev , REG_POWER_MANAGEMENT_1 ,
@@ -194,6 +201,7 @@ int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu)
194
201
case KSZ8794_CHIP_ID :
195
202
case KSZ8765_CHIP_ID :
196
203
return ksz8795_change_mtu (dev , frame_size );
204
+ case KSZ8463_CHIP_ID :
197
205
case KSZ88X3_CHIP_ID :
198
206
case KSZ8864_CHIP_ID :
199
207
case KSZ8895_CHIP_ID :
@@ -227,6 +235,11 @@ static int ksz8_port_queue_split(struct ksz_device *dev, int port, int queues)
227
235
WEIGHTED_FAIR_QUEUE_ENABLE );
228
236
if (ret )
229
237
return ret ;
238
+ } else if (ksz_is_ksz8463 (dev )) {
239
+ mask_4q = KSZ8873_PORT_4QUEUE_SPLIT_EN ;
240
+ mask_2q = KSZ8873_PORT_2QUEUE_SPLIT_EN ;
241
+ reg_4q = P1CR1 ;
242
+ reg_2q = P1CR1 + 1 ;
230
243
} else {
231
244
mask_4q = KSZ8795_PORT_4QUEUE_SPLIT_EN ;
232
245
mask_2q = KSZ8795_PORT_2QUEUE_SPLIT_EN ;
@@ -1265,19 +1278,24 @@ int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val)
1265
1278
1266
1279
void ksz8_cfg_port_member (struct ksz_device * dev , int port , u8 member )
1267
1280
{
1281
+ int offset = P_MIRROR_CTRL ;
1268
1282
u8 data ;
1269
1283
1270
- ksz_pread8 (dev , port , P_MIRROR_CTRL , & data );
1271
- data &= ~PORT_VLAN_MEMBERSHIP ;
1284
+ if (ksz_is_ksz8463 (dev ))
1285
+ offset = P1CR2 ;
1286
+ ksz_pread8 (dev , port , offset , & data );
1287
+ data &= ~dev -> port_mask ;
1272
1288
data |= (member & dev -> port_mask );
1273
- ksz_pwrite8 (dev , port , P_MIRROR_CTRL , data );
1289
+ ksz_pwrite8 (dev , port , offset , data );
1274
1290
}
1275
1291
1276
1292
void ksz8_flush_dyn_mac_table (struct ksz_device * dev , int port )
1277
1293
{
1278
1294
u8 learn [DSA_MAX_PORTS ];
1279
1295
int first , index , cnt ;
1280
1296
const u16 * regs ;
1297
+ int reg = S_FLUSH_TABLE_CTRL ;
1298
+ int mask = SW_FLUSH_DYN_MAC_TABLE ;
1281
1299
1282
1300
regs = dev -> info -> regs ;
1283
1301
@@ -1295,7 +1313,11 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
1295
1313
ksz_pwrite8 (dev , index , regs [P_STP_CTRL ],
1296
1314
learn [index ] | PORT_LEARN_DISABLE );
1297
1315
}
1298
- ksz_cfg (dev , S_FLUSH_TABLE_CTRL , SW_FLUSH_DYN_MAC_TABLE , true);
1316
+ if (ksz_is_ksz8463 (dev )) {
1317
+ reg = KSZ8463_FLUSH_TABLE_CTRL ;
1318
+ mask = KSZ8463_FLUSH_DYN_MAC_TABLE ;
1319
+ }
1320
+ ksz_cfg (dev , reg , mask , true);
1299
1321
for (index = first ; index < cnt ; index ++ ) {
1300
1322
if (!(learn [index ] & PORT_LEARN_DISABLE ))
1301
1323
ksz_pwrite8 (dev , index , regs [P_STP_CTRL ], learn [index ]);
@@ -1434,7 +1456,7 @@ int ksz8_fdb_del(struct ksz_device *dev, int port, const unsigned char *addr,
1434
1456
int ksz8_port_vlan_filtering (struct ksz_device * dev , int port , bool flag ,
1435
1457
struct netlink_ext_ack * extack )
1436
1458
{
1437
- if (ksz_is_ksz88x3 (dev ))
1459
+ if (ksz_is_ksz88x3 (dev ) || ksz_is_ksz8463 ( dev ) )
1438
1460
return - ENOTSUPP ;
1439
1461
1440
1462
/* Discard packets with VID not enabled on the switch */
@@ -1450,9 +1472,12 @@ int ksz8_port_vlan_filtering(struct ksz_device *dev, int port, bool flag,
1450
1472
1451
1473
static void ksz8_port_enable_pvid (struct ksz_device * dev , int port , bool state )
1452
1474
{
1453
- if (ksz_is_ksz88x3 (dev )) {
1454
- ksz_cfg (dev , REG_SW_INSERT_SRC_PVID ,
1455
- 0x03 << (4 - 2 * port ), state );
1475
+ if (ksz_is_ksz88x3 (dev ) || ksz_is_ksz8463 (dev )) {
1476
+ int reg = REG_SW_INSERT_SRC_PVID ;
1477
+
1478
+ if (ksz_is_ksz8463 (dev ))
1479
+ reg = KSZ8463_REG_SW_CTRL_9 ;
1480
+ ksz_cfg (dev , reg , 0x03 << (4 - 2 * port ), state );
1456
1481
} else {
1457
1482
ksz_pwrite8 (dev , port , REG_PORT_CTRL_12 , state ? 0x0f : 0x00 );
1458
1483
}
@@ -1467,7 +1492,7 @@ int ksz8_port_vlan_add(struct ksz_device *dev, int port,
1467
1492
u16 data , new_pvid = 0 ;
1468
1493
u8 fid , member , valid ;
1469
1494
1470
- if (ksz_is_ksz88x3 (dev ))
1495
+ if (ksz_is_ksz88x3 (dev ) || ksz_is_ksz8463 ( dev ) )
1471
1496
return - ENOTSUPP ;
1472
1497
1473
1498
/* If a VLAN is added with untagged flag different from the
@@ -1536,7 +1561,7 @@ int ksz8_port_vlan_del(struct ksz_device *dev, int port,
1536
1561
u16 data , pvid ;
1537
1562
u8 fid , member , valid ;
1538
1563
1539
- if (ksz_is_ksz88x3 (dev ))
1564
+ if (ksz_is_ksz88x3 (dev ) || ksz_is_ksz8463 ( dev ) )
1540
1565
return - ENOTSUPP ;
1541
1566
1542
1567
ksz_pread16 (dev , port , REG_PORT_CTRL_VID , & pvid );
@@ -1566,19 +1591,23 @@ int ksz8_port_mirror_add(struct ksz_device *dev, int port,
1566
1591
struct dsa_mall_mirror_tc_entry * mirror ,
1567
1592
bool ingress , struct netlink_ext_ack * extack )
1568
1593
{
1594
+ int offset = P_MIRROR_CTRL ;
1595
+
1596
+ if (ksz_is_ksz8463 (dev ))
1597
+ offset = P1CR2 ;
1569
1598
if (ingress ) {
1570
- ksz_port_cfg (dev , port , P_MIRROR_CTRL , PORT_MIRROR_RX , true);
1599
+ ksz_port_cfg (dev , port , offset , PORT_MIRROR_RX , true);
1571
1600
dev -> mirror_rx |= BIT (port );
1572
1601
} else {
1573
- ksz_port_cfg (dev , port , P_MIRROR_CTRL , PORT_MIRROR_TX , true);
1602
+ ksz_port_cfg (dev , port , offset , PORT_MIRROR_TX , true);
1574
1603
dev -> mirror_tx |= BIT (port );
1575
1604
}
1576
1605
1577
- ksz_port_cfg (dev , port , P_MIRROR_CTRL , PORT_MIRROR_SNIFFER , false);
1606
+ ksz_port_cfg (dev , port , offset , PORT_MIRROR_SNIFFER , false);
1578
1607
1579
1608
/* configure mirror port */
1580
1609
if (dev -> mirror_rx || dev -> mirror_tx )
1581
- ksz_port_cfg (dev , mirror -> to_local_port , P_MIRROR_CTRL ,
1610
+ ksz_port_cfg (dev , mirror -> to_local_port , offset ,
1582
1611
PORT_MIRROR_SNIFFER , true);
1583
1612
1584
1613
return 0 ;
@@ -1587,20 +1616,23 @@ int ksz8_port_mirror_add(struct ksz_device *dev, int port,
1587
1616
void ksz8_port_mirror_del (struct ksz_device * dev , int port ,
1588
1617
struct dsa_mall_mirror_tc_entry * mirror )
1589
1618
{
1619
+ int offset = P_MIRROR_CTRL ;
1590
1620
u8 data ;
1591
1621
1622
+ if (ksz_is_ksz8463 (dev ))
1623
+ offset = P1CR2 ;
1592
1624
if (mirror -> ingress ) {
1593
- ksz_port_cfg (dev , port , P_MIRROR_CTRL , PORT_MIRROR_RX , false);
1625
+ ksz_port_cfg (dev , port , offset , PORT_MIRROR_RX , false);
1594
1626
dev -> mirror_rx &= ~BIT (port );
1595
1627
} else {
1596
- ksz_port_cfg (dev , port , P_MIRROR_CTRL , PORT_MIRROR_TX , false);
1628
+ ksz_port_cfg (dev , port , offset , PORT_MIRROR_TX , false);
1597
1629
dev -> mirror_tx &= ~BIT (port );
1598
1630
}
1599
1631
1600
- ksz_pread8 (dev , port , P_MIRROR_CTRL , & data );
1632
+ ksz_pread8 (dev , port , offset , & data );
1601
1633
1602
1634
if (!dev -> mirror_rx && !dev -> mirror_tx )
1603
- ksz_port_cfg (dev , mirror -> to_local_port , P_MIRROR_CTRL ,
1635
+ ksz_port_cfg (dev , mirror -> to_local_port , offset ,
1604
1636
PORT_MIRROR_SNIFFER , false);
1605
1637
}
1606
1638
@@ -1625,17 +1657,24 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
1625
1657
const u16 * regs = dev -> info -> regs ;
1626
1658
struct dsa_switch * ds = dev -> ds ;
1627
1659
const u32 * masks ;
1660
+ int offset ;
1628
1661
u8 member ;
1629
1662
1630
1663
masks = dev -> info -> masks ;
1631
1664
1632
1665
/* enable broadcast storm limit */
1633
- ksz_port_cfg (dev , port , P_BCAST_STORM_CTRL , PORT_BROADCAST_STORM , true);
1666
+ offset = P_BCAST_STORM_CTRL ;
1667
+ if (ksz_is_ksz8463 (dev ))
1668
+ offset = P1CR1 ;
1669
+ ksz_port_cfg (dev , port , offset , PORT_BROADCAST_STORM , true);
1634
1670
1635
1671
ksz8_port_queue_split (dev , port , dev -> info -> num_tx_queues );
1636
1672
1637
1673
/* replace priority */
1638
- ksz_port_cfg (dev , port , P_802_1P_CTRL ,
1674
+ offset = P_802_1P_CTRL ;
1675
+ if (ksz_is_ksz8463 (dev ))
1676
+ offset = P1CR2 ;
1677
+ ksz_port_cfg (dev , port , offset ,
1639
1678
masks [PORT_802_1P_REMAPPING ], false);
1640
1679
1641
1680
if (cpu_port )
@@ -1675,6 +1714,7 @@ void ksz8_config_cpu_port(struct dsa_switch *ds)
1675
1714
const u32 * masks ;
1676
1715
const u16 * regs ;
1677
1716
u8 remote ;
1717
+ u8 fiber_ports = 0 ;
1678
1718
int i ;
1679
1719
1680
1720
masks = dev -> info -> masks ;
@@ -1705,6 +1745,32 @@ void ksz8_config_cpu_port(struct dsa_switch *ds)
1705
1745
else
1706
1746
ksz_port_cfg (dev , i , regs [P_STP_CTRL ],
1707
1747
PORT_FORCE_FLOW_CTRL , false);
1748
+ if (p -> fiber )
1749
+ fiber_ports |= (1 << i );
1750
+ }
1751
+ if (ksz_is_ksz8463 (dev )) {
1752
+ /* Setup fiber ports. */
1753
+ if (fiber_ports ) {
1754
+ fiber_ports &= 3 ;
1755
+ regmap_update_bits (ksz_regmap_16 (dev ),
1756
+ KSZ8463_REG_CFG_CTRL ,
1757
+ fiber_ports << PORT_COPPER_MODE_S ,
1758
+ 0 );
1759
+ regmap_update_bits (ksz_regmap_16 (dev ),
1760
+ KSZ8463_REG_DSP_CTRL_6 ,
1761
+ COPPER_RECEIVE_ADJUSTMENT , 0 );
1762
+ }
1763
+
1764
+ /* Turn off PTP function as the switch's proprietary way of
1765
+ * handling timestamp is not supported in current Linux PTP
1766
+ * stack implementation.
1767
+ */
1768
+ regmap_update_bits (ksz_regmap_16 (dev ),
1769
+ KSZ8463_PTP_MSG_CONF1 ,
1770
+ PTP_ENABLE , 0 );
1771
+ regmap_update_bits (ksz_regmap_16 (dev ),
1772
+ KSZ8463_PTP_CLK_CTRL ,
1773
+ PTP_CLK_ENABLE , 0 );
1708
1774
}
1709
1775
}
1710
1776
@@ -1901,7 +1967,7 @@ int ksz8_setup(struct dsa_switch *ds)
1901
1967
1902
1968
ksz_cfg (dev , S_MIRROR_CTRL , SW_MIRROR_RX_TX , false);
1903
1969
1904
- if (!ksz_is_ksz88x3 (dev ))
1970
+ if (!ksz_is_ksz88x3 (dev ) && ! ksz_is_ksz8463 ( dev ) )
1905
1971
ksz_cfg (dev , REG_SW_CTRL_19 , SW_INS_TAG_ENABLE , true);
1906
1972
1907
1973
for (i = 0 ; i < (dev -> info -> num_vlans / 4 ); i ++ )
@@ -1947,6 +2013,84 @@ u32 ksz8_get_port_addr(int port, int offset)
1947
2013
return PORT_CTRL_ADDR (port , offset );
1948
2014
}
1949
2015
2016
+ u32 ksz8463_get_port_addr (int port , int offset )
2017
+ {
2018
+ return offset + 0x18 * port ;
2019
+ }
2020
+
2021
+ static u16 ksz8463_get_phy_addr (u16 phy , u16 reg , u16 offset )
2022
+ {
2023
+ return offset + reg * 2 + phy * (P2MBCR - P1MBCR );
2024
+ }
2025
+
2026
+ int ksz8463_r_phy (struct ksz_device * dev , u16 phy , u16 reg , u16 * val )
2027
+ {
2028
+ u16 sw_reg = 0 ;
2029
+ u16 data = 0 ;
2030
+ int ret ;
2031
+
2032
+ if (phy > 1 )
2033
+ return - ENOSPC ;
2034
+ switch (reg ) {
2035
+ case MII_PHYSID1 :
2036
+ sw_reg = ksz8463_get_phy_addr (phy , 0 , PHY1IHR );
2037
+ break ;
2038
+ case MII_PHYSID2 :
2039
+ sw_reg = ksz8463_get_phy_addr (phy , 0 , PHY1ILR );
2040
+ break ;
2041
+ case MII_BMCR :
2042
+ case MII_BMSR :
2043
+ case MII_ADVERTISE :
2044
+ case MII_LPA :
2045
+ sw_reg = ksz8463_get_phy_addr (phy , reg , P1MBCR );
2046
+ break ;
2047
+ case MII_TPISTATUS :
2048
+ /* This register holds the PHY interrupt status for simulated
2049
+ * Micrel KSZ PHY.
2050
+ */
2051
+ data = 0x0505 ;
2052
+ break ;
2053
+ default :
2054
+ break ;
2055
+ }
2056
+ if (sw_reg ) {
2057
+ ret = ksz_read16 (dev , sw_reg , & data );
2058
+ if (ret )
2059
+ return ret ;
2060
+ }
2061
+ * val = data ;
2062
+
2063
+ return 0 ;
2064
+ }
2065
+
2066
+ int ksz8463_w_phy (struct ksz_device * dev , u16 phy , u16 reg , u16 val )
2067
+ {
2068
+ u16 sw_reg = 0 ;
2069
+ int ret ;
2070
+
2071
+ if (phy > 1 )
2072
+ return - ENOSPC ;
2073
+
2074
+ /* No write to fiber port. */
2075
+ if (dev -> ports [phy ].fiber )
2076
+ return 0 ;
2077
+ switch (reg ) {
2078
+ case MII_BMCR :
2079
+ case MII_ADVERTISE :
2080
+ sw_reg = ksz8463_get_phy_addr (phy , reg , P1MBCR );
2081
+ break ;
2082
+ default :
2083
+ break ;
2084
+ }
2085
+ if (sw_reg ) {
2086
+ ret = ksz_write16 (dev , sw_reg , val );
2087
+ if (ret )
2088
+ return ret ;
2089
+ }
2090
+
2091
+ return 0 ;
2092
+ }
2093
+
1950
2094
int ksz8_switch_init (struct ksz_device * dev )
1951
2095
{
1952
2096
dev -> cpu_port = fls (dev -> info -> cpu_ports ) - 1 ;
0 commit comments