33 * Microchip KSZ8XXX series switch driver
44 *
55 * It supports the following switches:
6+ * - KSZ8463
67 * - KSZ8863, KSZ8873 aka KSZ88X3
78 * - KSZ8895, KSZ8864 aka KSZ8895 family
89 * - KSZ8794, KSZ8795, KSZ8765 aka KSZ87XX
@@ -41,7 +42,8 @@ static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
4142static void ksz_port_cfg (struct ksz_device * dev , int port , int offset , u8 bits ,
4243 bool set )
4344{
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 ),
4547 bits , set ? bits : 0 );
4648}
4749
@@ -140,6 +142,11 @@ int ksz8_reset_switch(struct ksz_device *dev)
140142 KSZ8863_GLOBAL_SOFTWARE_RESET | KSZ8863_PCS_RESET , true);
141143 ksz_cfg (dev , KSZ8863_REG_SW_RESET ,
142144 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);
143150 } else {
144151 /* reset switch */
145152 ksz_write8 (dev , REG_POWER_MANAGEMENT_1 ,
@@ -194,6 +201,7 @@ int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu)
194201 case KSZ8794_CHIP_ID :
195202 case KSZ8765_CHIP_ID :
196203 return ksz8795_change_mtu (dev , frame_size );
204+ case KSZ8463_CHIP_ID :
197205 case KSZ88X3_CHIP_ID :
198206 case KSZ8864_CHIP_ID :
199207 case KSZ8895_CHIP_ID :
@@ -227,6 +235,11 @@ static int ksz8_port_queue_split(struct ksz_device *dev, int port, int queues)
227235 WEIGHTED_FAIR_QUEUE_ENABLE );
228236 if (ret )
229237 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 ;
230243 } else {
231244 mask_4q = KSZ8795_PORT_4QUEUE_SPLIT_EN ;
232245 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)
12651278
12661279void ksz8_cfg_port_member (struct ksz_device * dev , int port , u8 member )
12671280{
1281+ int offset = P_MIRROR_CTRL ;
12681282 u8 data ;
12691283
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 ;
12721288 data |= (member & dev -> port_mask );
1273- ksz_pwrite8 (dev , port , P_MIRROR_CTRL , data );
1289+ ksz_pwrite8 (dev , port , offset , data );
12741290}
12751291
12761292void ksz8_flush_dyn_mac_table (struct ksz_device * dev , int port )
12771293{
12781294 u8 learn [DSA_MAX_PORTS ];
12791295 int first , index , cnt ;
12801296 const u16 * regs ;
1297+ int reg = S_FLUSH_TABLE_CTRL ;
1298+ int mask = SW_FLUSH_DYN_MAC_TABLE ;
12811299
12821300 regs = dev -> info -> regs ;
12831301
@@ -1295,7 +1313,11 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
12951313 ksz_pwrite8 (dev , index , regs [P_STP_CTRL ],
12961314 learn [index ] | PORT_LEARN_DISABLE );
12971315 }
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);
12991321 for (index = first ; index < cnt ; index ++ ) {
13001322 if (!(learn [index ] & PORT_LEARN_DISABLE ))
13011323 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,
14341456int ksz8_port_vlan_filtering (struct ksz_device * dev , int port , bool flag ,
14351457 struct netlink_ext_ack * extack )
14361458{
1437- if (ksz_is_ksz88x3 (dev ))
1459+ if (ksz_is_ksz88x3 (dev ) || ksz_is_ksz8463 ( dev ) )
14381460 return - ENOTSUPP ;
14391461
14401462 /* 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,
14501472
14511473static void ksz8_port_enable_pvid (struct ksz_device * dev , int port , bool state )
14521474{
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 );
14561481 } else {
14571482 ksz_pwrite8 (dev , port , REG_PORT_CTRL_12 , state ? 0x0f : 0x00 );
14581483 }
@@ -1467,7 +1492,7 @@ int ksz8_port_vlan_add(struct ksz_device *dev, int port,
14671492 u16 data , new_pvid = 0 ;
14681493 u8 fid , member , valid ;
14691494
1470- if (ksz_is_ksz88x3 (dev ))
1495+ if (ksz_is_ksz88x3 (dev ) || ksz_is_ksz8463 ( dev ) )
14711496 return - ENOTSUPP ;
14721497
14731498 /* 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,
15361561 u16 data , pvid ;
15371562 u8 fid , member , valid ;
15381563
1539- if (ksz_is_ksz88x3 (dev ))
1564+ if (ksz_is_ksz88x3 (dev ) || ksz_is_ksz8463 ( dev ) )
15401565 return - ENOTSUPP ;
15411566
15421567 ksz_pread16 (dev , port , REG_PORT_CTRL_VID , & pvid );
@@ -1566,19 +1591,23 @@ int ksz8_port_mirror_add(struct ksz_device *dev, int port,
15661591 struct dsa_mall_mirror_tc_entry * mirror ,
15671592 bool ingress , struct netlink_ext_ack * extack )
15681593{
1594+ int offset = P_MIRROR_CTRL ;
1595+
1596+ if (ksz_is_ksz8463 (dev ))
1597+ offset = P1CR2 ;
15691598 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);
15711600 dev -> mirror_rx |= BIT (port );
15721601 } 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);
15741603 dev -> mirror_tx |= BIT (port );
15751604 }
15761605
1577- ksz_port_cfg (dev , port , P_MIRROR_CTRL , PORT_MIRROR_SNIFFER , false);
1606+ ksz_port_cfg (dev , port , offset , PORT_MIRROR_SNIFFER , false);
15781607
15791608 /* configure mirror port */
15801609 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 ,
15821611 PORT_MIRROR_SNIFFER , true);
15831612
15841613 return 0 ;
@@ -1587,20 +1616,23 @@ int ksz8_port_mirror_add(struct ksz_device *dev, int port,
15871616void ksz8_port_mirror_del (struct ksz_device * dev , int port ,
15881617 struct dsa_mall_mirror_tc_entry * mirror )
15891618{
1619+ int offset = P_MIRROR_CTRL ;
15901620 u8 data ;
15911621
1622+ if (ksz_is_ksz8463 (dev ))
1623+ offset = P1CR2 ;
15921624 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);
15941626 dev -> mirror_rx &= ~BIT (port );
15951627 } 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);
15971629 dev -> mirror_tx &= ~BIT (port );
15981630 }
15991631
1600- ksz_pread8 (dev , port , P_MIRROR_CTRL , & data );
1632+ ksz_pread8 (dev , port , offset , & data );
16011633
16021634 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 ,
16041636 PORT_MIRROR_SNIFFER , false);
16051637}
16061638
@@ -1625,17 +1657,24 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
16251657 const u16 * regs = dev -> info -> regs ;
16261658 struct dsa_switch * ds = dev -> ds ;
16271659 const u32 * masks ;
1660+ int offset ;
16281661 u8 member ;
16291662
16301663 masks = dev -> info -> masks ;
16311664
16321665 /* 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);
16341670
16351671 ksz8_port_queue_split (dev , port , dev -> info -> num_tx_queues );
16361672
16371673 /* 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 ,
16391678 masks [PORT_802_1P_REMAPPING ], false);
16401679
16411680 if (cpu_port )
@@ -1675,6 +1714,7 @@ void ksz8_config_cpu_port(struct dsa_switch *ds)
16751714 const u32 * masks ;
16761715 const u16 * regs ;
16771716 u8 remote ;
1717+ u8 fiber_ports = 0 ;
16781718 int i ;
16791719
16801720 masks = dev -> info -> masks ;
@@ -1705,6 +1745,32 @@ void ksz8_config_cpu_port(struct dsa_switch *ds)
17051745 else
17061746 ksz_port_cfg (dev , i , regs [P_STP_CTRL ],
17071747 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 );
17081774 }
17091775}
17101776
@@ -1901,7 +1967,7 @@ int ksz8_setup(struct dsa_switch *ds)
19011967
19021968 ksz_cfg (dev , S_MIRROR_CTRL , SW_MIRROR_RX_TX , false);
19031969
1904- if (!ksz_is_ksz88x3 (dev ))
1970+ if (!ksz_is_ksz88x3 (dev ) && ! ksz_is_ksz8463 ( dev ) )
19051971 ksz_cfg (dev , REG_SW_CTRL_19 , SW_INS_TAG_ENABLE , true);
19061972
19071973 for (i = 0 ; i < (dev -> info -> num_vlans / 4 ); i ++ )
@@ -1947,6 +2013,84 @@ u32 ksz8_get_port_addr(int port, int offset)
19472013 return PORT_CTRL_ADDR (port , offset );
19482014}
19492015
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+
19502094int ksz8_switch_init (struct ksz_device * dev )
19512095{
19522096 dev -> cpu_port = fls (dev -> info -> cpu_ports ) - 1 ;
0 commit comments