Skip to content

Commit e3f96b3

Browse files
committed
Merge branch 'net-dsa-microchip-add-ksz8463-switch-support'
Tristram Ha says: ==================== net: dsa: microchip: Add KSZ8463 switch support This series of patches is to add KSZ8463 switch support to the KSZ DSA driver. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents d1f3dba + 620e239 commit e3f96b3

File tree

9 files changed

+522
-32
lines changed

9 files changed

+522
-32
lines changed

Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ properties:
1818
# required and optional properties.
1919
compatible:
2020
enum:
21+
- microchip,ksz8463
2122
- microchip,ksz8765
2223
- microchip,ksz8794
2324
- microchip,ksz8795

drivers/net/dsa/microchip/ksz8.c

Lines changed: 166 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
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)
4142
static 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

12661279
void 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

12761292
void 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,
14341456
int 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

14511473
static 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,
15871616
void 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+
19502094
int ksz8_switch_init(struct ksz_device *dev)
19512095
{
19522096
dev->cpu_port = fls(dev->info->cpu_ports) - 1;

drivers/net/dsa/microchip/ksz8.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,8 @@ void ksz8_phylink_mac_link_up(struct phylink_config *config,
6363
bool tx_pause, bool rx_pause);
6464
int ksz8_all_queues_split(struct ksz_device *dev, int queues);
6565

66+
u32 ksz8463_get_port_addr(int port, int offset);
67+
int ksz8463_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val);
68+
int ksz8463_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val);
69+
6670
#endif

0 commit comments

Comments
 (0)