Skip to content

Commit 15b8d3e

Browse files
triha2workkuba-moo
authored andcommitted
net: dsa: microchip: Use different registers for KSZ8463
KSZ8463 does not use same set of registers as KSZ8863 so it is necessary to change some registers when using KSZ8463. Signed-off-by: Tristram Ha <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 84c47bf commit 15b8d3e

File tree

3 files changed

+92
-28
lines changed

3 files changed

+92
-28
lines changed

drivers/net/dsa/microchip/ksz8.c

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ int ksz8_reset_switch(struct ksz_device *dev)
142142
KSZ8863_GLOBAL_SOFTWARE_RESET | KSZ8863_PCS_RESET, true);
143143
ksz_cfg(dev, KSZ8863_REG_SW_RESET,
144144
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);
145150
} else {
146151
/* reset switch */
147152
ksz_write8(dev, REG_POWER_MANAGEMENT_1,
@@ -230,6 +235,11 @@ static int ksz8_port_queue_split(struct ksz_device *dev, int port, int queues)
230235
WEIGHTED_FAIR_QUEUE_ENABLE);
231236
if (ret)
232237
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;
233243
} else {
234244
mask_4q = KSZ8795_PORT_4QUEUE_SPLIT_EN;
235245
mask_2q = KSZ8795_PORT_2QUEUE_SPLIT_EN;
@@ -1268,19 +1278,24 @@ int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val)
12681278

12691279
void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member)
12701280
{
1281+
int offset = P_MIRROR_CTRL;
12711282
u8 data;
12721283

1273-
ksz_pread8(dev, port, P_MIRROR_CTRL, &data);
1274-
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;
12751288
data |= (member & dev->port_mask);
1276-
ksz_pwrite8(dev, port, P_MIRROR_CTRL, data);
1289+
ksz_pwrite8(dev, port, offset, data);
12771290
}
12781291

12791292
void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
12801293
{
12811294
u8 learn[DSA_MAX_PORTS];
12821295
int first, index, cnt;
12831296
const u16 *regs;
1297+
int reg = S_FLUSH_TABLE_CTRL;
1298+
int mask = SW_FLUSH_DYN_MAC_TABLE;
12841299

12851300
regs = dev->info->regs;
12861301

@@ -1298,7 +1313,11 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
12981313
ksz_pwrite8(dev, index, regs[P_STP_CTRL],
12991314
learn[index] | PORT_LEARN_DISABLE);
13001315
}
1301-
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);
13021321
for (index = first; index < cnt; index++) {
13031322
if (!(learn[index] & PORT_LEARN_DISABLE))
13041323
ksz_pwrite8(dev, index, regs[P_STP_CTRL], learn[index]);
@@ -1437,7 +1456,7 @@ int ksz8_fdb_del(struct ksz_device *dev, int port, const unsigned char *addr,
14371456
int ksz8_port_vlan_filtering(struct ksz_device *dev, int port, bool flag,
14381457
struct netlink_ext_ack *extack)
14391458
{
1440-
if (ksz_is_ksz88x3(dev))
1459+
if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev))
14411460
return -ENOTSUPP;
14421461

14431462
/* Discard packets with VID not enabled on the switch */
@@ -1453,9 +1472,12 @@ int ksz8_port_vlan_filtering(struct ksz_device *dev, int port, bool flag,
14531472

14541473
static void ksz8_port_enable_pvid(struct ksz_device *dev, int port, bool state)
14551474
{
1456-
if (ksz_is_ksz88x3(dev)) {
1457-
ksz_cfg(dev, REG_SW_INSERT_SRC_PVID,
1458-
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);
14591481
} else {
14601482
ksz_pwrite8(dev, port, REG_PORT_CTRL_12, state ? 0x0f : 0x00);
14611483
}
@@ -1470,7 +1492,7 @@ int ksz8_port_vlan_add(struct ksz_device *dev, int port,
14701492
u16 data, new_pvid = 0;
14711493
u8 fid, member, valid;
14721494

1473-
if (ksz_is_ksz88x3(dev))
1495+
if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev))
14741496
return -ENOTSUPP;
14751497

14761498
/* If a VLAN is added with untagged flag different from the
@@ -1539,7 +1561,7 @@ int ksz8_port_vlan_del(struct ksz_device *dev, int port,
15391561
u16 data, pvid;
15401562
u8 fid, member, valid;
15411563

1542-
if (ksz_is_ksz88x3(dev))
1564+
if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev))
15431565
return -ENOTSUPP;
15441566

15451567
ksz_pread16(dev, port, REG_PORT_CTRL_VID, &pvid);
@@ -1569,19 +1591,23 @@ int ksz8_port_mirror_add(struct ksz_device *dev, int port,
15691591
struct dsa_mall_mirror_tc_entry *mirror,
15701592
bool ingress, struct netlink_ext_ack *extack)
15711593
{
1594+
int offset = P_MIRROR_CTRL;
1595+
1596+
if (ksz_is_ksz8463(dev))
1597+
offset = P1CR2;
15721598
if (ingress) {
1573-
ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, true);
1599+
ksz_port_cfg(dev, port, offset, PORT_MIRROR_RX, true);
15741600
dev->mirror_rx |= BIT(port);
15751601
} else {
1576-
ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, true);
1602+
ksz_port_cfg(dev, port, offset, PORT_MIRROR_TX, true);
15771603
dev->mirror_tx |= BIT(port);
15781604
}
15791605

1580-
ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_SNIFFER, false);
1606+
ksz_port_cfg(dev, port, offset, PORT_MIRROR_SNIFFER, false);
15811607

15821608
/* configure mirror port */
15831609
if (dev->mirror_rx || dev->mirror_tx)
1584-
ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL,
1610+
ksz_port_cfg(dev, mirror->to_local_port, offset,
15851611
PORT_MIRROR_SNIFFER, true);
15861612

15871613
return 0;
@@ -1590,20 +1616,23 @@ int ksz8_port_mirror_add(struct ksz_device *dev, int port,
15901616
void ksz8_port_mirror_del(struct ksz_device *dev, int port,
15911617
struct dsa_mall_mirror_tc_entry *mirror)
15921618
{
1619+
int offset = P_MIRROR_CTRL;
15931620
u8 data;
15941621

1622+
if (ksz_is_ksz8463(dev))
1623+
offset = P1CR2;
15951624
if (mirror->ingress) {
1596-
ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, false);
1625+
ksz_port_cfg(dev, port, offset, PORT_MIRROR_RX, false);
15971626
dev->mirror_rx &= ~BIT(port);
15981627
} else {
1599-
ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, false);
1628+
ksz_port_cfg(dev, port, offset, PORT_MIRROR_TX, false);
16001629
dev->mirror_tx &= ~BIT(port);
16011630
}
16021631

1603-
ksz_pread8(dev, port, P_MIRROR_CTRL, &data);
1632+
ksz_pread8(dev, port, offset, &data);
16041633

16051634
if (!dev->mirror_rx && !dev->mirror_tx)
1606-
ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL,
1635+
ksz_port_cfg(dev, mirror->to_local_port, offset,
16071636
PORT_MIRROR_SNIFFER, false);
16081637
}
16091638

@@ -1628,17 +1657,24 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
16281657
const u16 *regs = dev->info->regs;
16291658
struct dsa_switch *ds = dev->ds;
16301659
const u32 *masks;
1660+
int offset;
16311661
u8 member;
16321662

16331663
masks = dev->info->masks;
16341664

16351665
/* enable broadcast storm limit */
1636-
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);
16371670

16381671
ksz8_port_queue_split(dev, port, dev->info->num_tx_queues);
16391672

16401673
/* replace priority */
1641-
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,
16421678
masks[PORT_802_1P_REMAPPING], false);
16431679

16441680
if (cpu_port)
@@ -1904,7 +1940,7 @@ int ksz8_setup(struct dsa_switch *ds)
19041940

19051941
ksz_cfg(dev, S_MIRROR_CTRL, SW_MIRROR_RX_TX, false);
19061942

1907-
if (!ksz_is_ksz88x3(dev))
1943+
if (!ksz_is_ksz88x3(dev) && !ksz_is_ksz8463(dev))
19081944
ksz_cfg(dev, REG_SW_CTRL_19, SW_INS_TAG_ENABLE, true);
19091945

19101946
for (i = 0; i < (dev->info->num_vlans / 4); i++)

drivers/net/dsa/microchip/ksz_common.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,6 +2951,7 @@ static int ksz_parse_drive_strength(struct ksz_device *dev);
29512951
static int ksz_setup(struct dsa_switch *ds)
29522952
{
29532953
struct ksz_device *dev = ds->priv;
2954+
u16 storm_mask, storm_rate;
29542955
struct dsa_port *dp;
29552956
struct ksz_port *p;
29562957
const u16 *regs;
@@ -2980,10 +2981,14 @@ static int ksz_setup(struct dsa_switch *ds)
29802981
}
29812982

29822983
/* set broadcast storm protection 10% rate */
2984+
storm_mask = BROADCAST_STORM_RATE;
2985+
storm_rate = (BROADCAST_STORM_VALUE * BROADCAST_STORM_PROT_RATE) / 100;
2986+
if (ksz_is_ksz8463(dev)) {
2987+
storm_mask = swab16(storm_mask);
2988+
storm_rate = swab16(storm_rate);
2989+
}
29832990
regmap_update_bits(ksz_regmap_16(dev), regs[S_BROADCAST_CTRL],
2984-
BROADCAST_STORM_RATE,
2985-
(BROADCAST_STORM_VALUE *
2986-
BROADCAST_STORM_PROT_RATE) / 100);
2991+
storm_mask, storm_rate);
29872992

29882993
dev->dev_ops->config_cpu_port(ds);
29892994

@@ -4221,6 +4226,17 @@ static int ksz_ets_band_to_queue(struct tc_ets_qopt_offload_replace_params *p,
42214226
return p->bands - 1 - band;
42224227
}
42234228

4229+
static u8 ksz8463_tc_ctrl(int port, int queue)
4230+
{
4231+
u8 reg;
4232+
4233+
reg = 0xC8 + port * 4;
4234+
reg += ((3 - queue) / 2) * 2;
4235+
reg++;
4236+
reg -= (queue & 1);
4237+
return reg;
4238+
}
4239+
42244240
/**
42254241
* ksz88x3_tc_ets_add - Configure ETS (Enhanced Transmission Selection)
42264242
* for a port on KSZ88x3 switch
@@ -4256,6 +4272,8 @@ static int ksz88x3_tc_ets_add(struct ksz_device *dev, int port,
42564272
* port/queue
42574273
*/
42584274
reg = KSZ8873_TXQ_SPLIT_CTRL_REG(port, queue);
4275+
if (ksz_is_ksz8463(dev))
4276+
reg = ksz8463_tc_ctrl(port, queue);
42594277

42604278
/* Clear WFQ enable bit to select strict priority scheduling */
42614279
ret = ksz_rmw8(dev, reg, KSZ8873_TXQ_WFQ_ENABLE, 0);
@@ -4291,6 +4309,8 @@ static int ksz88x3_tc_ets_del(struct ksz_device *dev, int port)
42914309
* port/queue
42924310
*/
42934311
reg = KSZ8873_TXQ_SPLIT_CTRL_REG(port, queue);
4312+
if (ksz_is_ksz8463(dev))
4313+
reg = ksz8463_tc_ctrl(port, queue);
42944314

42954315
/* Set WFQ enable bit to revert back to default scheduling
42964316
* mode
@@ -4438,7 +4458,7 @@ static int ksz_tc_setup_qdisc_ets(struct dsa_switch *ds, int port,
44384458
struct ksz_device *dev = ds->priv;
44394459
int ret;
44404460

4441-
if (is_ksz8(dev) && !ksz_is_ksz88x3(dev))
4461+
if (is_ksz8(dev) && !(ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev)))
44424462
return -EOPNOTSUPP;
44434463

44444464
if (qopt->parent != TC_H_ROOT) {
@@ -4452,13 +4472,13 @@ static int ksz_tc_setup_qdisc_ets(struct dsa_switch *ds, int port,
44524472
if (ret)
44534473
return ret;
44544474

4455-
if (ksz_is_ksz88x3(dev))
4475+
if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev))
44564476
return ksz88x3_tc_ets_add(dev, port,
44574477
&qopt->replace_params);
44584478
else
44594479
return ksz_tc_ets_add(dev, port, &qopt->replace_params);
44604480
case TC_ETS_DESTROY:
4461-
if (ksz_is_ksz88x3(dev))
4481+
if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev))
44624482
return ksz88x3_tc_ets_del(dev, port);
44634483
else
44644484
return ksz_tc_ets_del(dev, port);

drivers/net/dsa/microchip/ksz_dcb.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
* Therefore, we define the base offset as 0x00 here to align with that logic.
1717
*/
1818
#define KSZ8_REG_PORT_1_CTRL_0 0x00
19+
#define KSZ8463_REG_PORT_1_CTRL_0 0x6C
1920
#define KSZ8_PORT_DIFFSERV_ENABLE BIT(6)
2021
#define KSZ8_PORT_802_1P_ENABLE BIT(5)
2122
#define KSZ8_PORT_BASED_PRIO_M GENMASK(4, 3)
2223

24+
#define KSZ8463_REG_TOS_DSCP_CTRL 0x16
2325
#define KSZ88X3_REG_TOS_DSCP_CTRL 0x60
2426
#define KSZ8765_REG_TOS_DSCP_CTRL 0x90
2527

@@ -98,6 +100,8 @@ static void ksz_get_default_port_prio_reg(struct ksz_device *dev, int *reg,
98100
*reg = KSZ8_REG_PORT_1_CTRL_0;
99101
*mask = KSZ8_PORT_BASED_PRIO_M;
100102
*shift = __bf_shf(KSZ8_PORT_BASED_PRIO_M);
103+
if (ksz_is_ksz8463(dev))
104+
*reg = KSZ8463_REG_PORT_1_CTRL_0;
101105
} else {
102106
*reg = KSZ9477_REG_PORT_MRI_MAC_CTRL;
103107
*mask = KSZ9477_PORT_BASED_PRIO_M;
@@ -122,10 +126,12 @@ static void ksz_get_dscp_prio_reg(struct ksz_device *dev, int *reg,
122126
*reg = KSZ8765_REG_TOS_DSCP_CTRL;
123127
*per_reg = 4;
124128
*mask = GENMASK(1, 0);
125-
} else if (ksz_is_ksz88x3(dev)) {
129+
} else if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev)) {
126130
*reg = KSZ88X3_REG_TOS_DSCP_CTRL;
127131
*per_reg = 4;
128132
*mask = GENMASK(1, 0);
133+
if (ksz_is_ksz8463(dev))
134+
*reg = KSZ8463_REG_TOS_DSCP_CTRL;
129135
} else {
130136
*reg = KSZ9477_REG_DIFFSERV_PRIO_MAP;
131137
*per_reg = 2;
@@ -151,6 +157,8 @@ static void ksz_get_apptrust_map_and_reg(struct ksz_device *dev,
151157
*map = ksz8_apptrust_map_to_bit;
152158
*reg = KSZ8_REG_PORT_1_CTRL_0;
153159
*mask = KSZ8_PORT_DIFFSERV_ENABLE | KSZ8_PORT_802_1P_ENABLE;
160+
if (ksz_is_ksz8463(dev))
161+
*reg = KSZ8463_REG_PORT_1_CTRL_0;
154162
} else {
155163
*map = ksz9477_apptrust_map_to_bit;
156164
*reg = KSZ9477_REG_PORT_MRI_PRIO_CTRL;

0 commit comments

Comments
 (0)