Skip to content

Commit 9f481ce

Browse files
committed
Merge branch 'ksz-dcb-dscp'
Oleksij Rempel says: ==================== add DCB and DSCP support for KSZ switches This patch series is aimed at improving support for DCB (Data Center Bridging) and DSCP (Differentiated Services Code Point) on KSZ switches. The main goal is to introduce global DSCP and PCP (Priority Code Point) mapping support, addressing the limitation of KSZ switches not having per-port DSCP priority mapping. This involves extending the DSA framework with new callbacks for managing trust settings for global DSCP and PCP maps. Additionally, we introduce IEEE 802.1q helpers for default configurations, benefiting other drivers too. Change logs are in separate patches. Compared to v6 this series includes some new patches for DSCP global mapping support and QoS selftest script for KSZ9477 switches. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 09ca994 + cbc7aff commit 9f481ce

18 files changed

Lines changed: 2133 additions & 86 deletions

File tree

drivers/net/dsa/microchip/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ menuconfig NET_DSA_MICROCHIP_KSZ_COMMON
44
depends on NET_DSA
55
select NET_DSA_TAG_KSZ
66
select NET_DSA_TAG_NONE
7+
select NET_IEEE8021Q_HELPERS
8+
select DCB
79
help
810
This driver adds support for Microchip KSZ9477 series switch and
911
KSZ8795/KSZ88x3 switch chips.

drivers/net/dsa/microchip/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON) += ksz_switch.o
3-
ksz_switch-objs := ksz_common.o
3+
ksz_switch-objs := ksz_common.o ksz_dcb.o
44
ksz_switch-objs += ksz9477.o ksz9477_acl.o ksz9477_tc_flower.o
55
ksz_switch-objs += ksz8795.o
66
ksz_switch-objs += lan937x_main.o

drivers/net/dsa/microchip/ksz8.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@ void ksz8_phylink_mac_link_up(struct phylink_config *config,
5858
struct phy_device *phydev, unsigned int mode,
5959
phy_interface_t interface, int speed, int duplex,
6060
bool tx_pause, bool rx_pause);
61+
int ksz8_all_queues_split(struct ksz_device *dev, int queues);
6162

6263
#endif

drivers/net/dsa/microchip/ksz8795.c

Lines changed: 71 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -127,37 +127,71 @@ int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu)
127127
return -EOPNOTSUPP;
128128
}
129129

130-
static void ksz8795_set_prio_queue(struct ksz_device *dev, int port, int queue)
130+
static int ksz8_port_queue_split(struct ksz_device *dev, int port, int queues)
131131
{
132-
u8 hi, lo;
132+
u8 mask_4q, mask_2q;
133+
u8 reg_4q, reg_2q;
134+
u8 data_4q = 0;
135+
u8 data_2q = 0;
136+
int ret;
133137

134-
/* Number of queues can only be 1, 2, or 4. */
135-
switch (queue) {
136-
case 4:
137-
case 3:
138-
queue = PORT_QUEUE_SPLIT_4;
139-
break;
140-
case 2:
141-
queue = PORT_QUEUE_SPLIT_2;
142-
break;
143-
default:
144-
queue = PORT_QUEUE_SPLIT_1;
138+
if (ksz_is_ksz88x3(dev)) {
139+
mask_4q = KSZ8873_PORT_4QUEUE_SPLIT_EN;
140+
mask_2q = KSZ8873_PORT_2QUEUE_SPLIT_EN;
141+
reg_4q = REG_PORT_CTRL_0;
142+
reg_2q = REG_PORT_CTRL_2;
143+
144+
/* KSZ8795 family switches have Weighted Fair Queueing (WFQ)
145+
* enabled by default. Enable it for KSZ8873 family switches
146+
* too. Default value for KSZ8873 family is strict priority,
147+
* which should be enabled by using TC_SETUP_QDISC_ETS, not
148+
* by default.
149+
*/
150+
ret = ksz_rmw8(dev, REG_SW_CTRL_3, WEIGHTED_FAIR_QUEUE_ENABLE,
151+
WEIGHTED_FAIR_QUEUE_ENABLE);
152+
if (ret)
153+
return ret;
154+
} else {
155+
mask_4q = KSZ8795_PORT_4QUEUE_SPLIT_EN;
156+
mask_2q = KSZ8795_PORT_2QUEUE_SPLIT_EN;
157+
reg_4q = REG_PORT_CTRL_13;
158+
reg_2q = REG_PORT_CTRL_0;
159+
160+
/* TODO: this is legacy from initial KSZ8795 driver, should be
161+
* moved to appropriate place in the future.
162+
*/
163+
ret = ksz_rmw8(dev, REG_SW_CTRL_19,
164+
SW_OUT_RATE_LIMIT_QUEUE_BASED,
165+
SW_OUT_RATE_LIMIT_QUEUE_BASED);
166+
if (ret)
167+
return ret;
168+
}
169+
170+
if (queues == 4)
171+
data_4q = mask_4q;
172+
else if (queues == 2)
173+
data_2q = mask_2q;
174+
175+
ret = ksz_prmw8(dev, port, reg_4q, mask_4q, data_4q);
176+
if (ret)
177+
return ret;
178+
179+
return ksz_prmw8(dev, port, reg_2q, mask_2q, data_2q);
180+
}
181+
182+
int ksz8_all_queues_split(struct ksz_device *dev, int queues)
183+
{
184+
struct dsa_switch *ds = dev->ds;
185+
const struct dsa_port *dp;
186+
187+
dsa_switch_for_each_port(dp, ds) {
188+
int ret = ksz8_port_queue_split(dev, dp->index, queues);
189+
190+
if (ret)
191+
return ret;
145192
}
146-
ksz_pread8(dev, port, REG_PORT_CTRL_0, &lo);
147-
ksz_pread8(dev, port, P_DROP_TAG_CTRL, &hi);
148-
lo &= ~PORT_QUEUE_SPLIT_L;
149-
if (queue & PORT_QUEUE_SPLIT_2)
150-
lo |= PORT_QUEUE_SPLIT_L;
151-
hi &= ~PORT_QUEUE_SPLIT_H;
152-
if (queue & PORT_QUEUE_SPLIT_4)
153-
hi |= PORT_QUEUE_SPLIT_H;
154-
ksz_pwrite8(dev, port, REG_PORT_CTRL_0, lo);
155-
ksz_pwrite8(dev, port, P_DROP_TAG_CTRL, hi);
156-
157-
/* Default is port based for egress rate limit. */
158-
if (queue != PORT_QUEUE_SPLIT_1)
159-
ksz_cfg(dev, REG_SW_CTRL_19, SW_OUT_RATE_LIMIT_QUEUE_BASED,
160-
true);
193+
194+
return 0;
161195
}
162196

163197
void ksz8_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt)
@@ -1513,26 +1547,28 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
15131547
{
15141548
struct dsa_switch *ds = dev->ds;
15151549
const u32 *masks;
1550+
int queues;
15161551
u8 member;
15171552

15181553
masks = dev->info->masks;
15191554

15201555
/* enable broadcast storm limit */
15211556
ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true);
15221557

1523-
if (!ksz_is_ksz88x3(dev))
1524-
ksz8795_set_prio_queue(dev, port, 4);
1558+
/* For KSZ88x3 enable only one queue by default, otherwise we won't
1559+
* be able to get rid of PCP prios on Port 2.
1560+
*/
1561+
if (ksz_is_ksz88x3(dev))
1562+
queues = 1;
1563+
else
1564+
queues = dev->info->num_tx_queues;
15251565

1526-
/* disable DiffServ priority */
1527-
ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_DIFFSERV_ENABLE, false);
1566+
ksz8_port_queue_split(dev, port, queues);
15281567

15291568
/* replace priority */
15301569
ksz_port_cfg(dev, port, P_802_1P_CTRL,
15311570
masks[PORT_802_1P_REMAPPING], false);
15321571

1533-
/* enable 802.1p priority */
1534-
ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_ENABLE, true);
1535-
15361572
if (cpu_port)
15371573
member = dsa_user_ports(ds);
15381574
else

drivers/net/dsa/microchip/ksz8795_reg.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@
124124
#define PORT_BASED_PRIO_3 3
125125
#define PORT_INSERT_TAG BIT(2)
126126
#define PORT_REMOVE_TAG BIT(1)
127-
#define PORT_QUEUE_SPLIT_L BIT(0)
127+
#define KSZ8795_PORT_2QUEUE_SPLIT_EN BIT(0)
128+
#define KSZ8873_PORT_4QUEUE_SPLIT_EN BIT(0)
128129

129130
#define REG_PORT_1_CTRL_1 0x11
130131
#define REG_PORT_2_CTRL_1 0x21
@@ -143,6 +144,7 @@
143144
#define REG_PORT_4_CTRL_2 0x42
144145
#define REG_PORT_5_CTRL_2 0x52
145146

147+
#define KSZ8873_PORT_2QUEUE_SPLIT_EN BIT(7)
146148
#define PORT_INGRESS_FILTER BIT(6)
147149
#define PORT_DISCARD_NON_VID BIT(5)
148150
#define PORT_FORCE_FLOW_CTRL BIT(4)
@@ -463,10 +465,7 @@
463465
#define REG_PORT_4_CTRL_13 0xE1
464466
#define REG_PORT_5_CTRL_13 0xF1
465467

466-
#define PORT_QUEUE_SPLIT_H BIT(1)
467-
#define PORT_QUEUE_SPLIT_1 0
468-
#define PORT_QUEUE_SPLIT_2 1
469-
#define PORT_QUEUE_SPLIT_4 2
468+
#define KSZ8795_PORT_4QUEUE_SPLIT_EN BIT(1)
470469
#define PORT_DROP_TAG BIT(0)
471470

472471
#define REG_PORT_1_CTRL_14 0xB2

drivers/net/dsa/microchip/ksz9477.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,18 +1158,12 @@ void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
11581158
/* enable broadcast storm limit */
11591159
ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true);
11601160

1161-
/* disable DiffServ priority */
1162-
ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_DIFFSERV_PRIO_ENABLE, false);
1163-
11641161
/* replace priority */
11651162
ksz_port_cfg(dev, port, REG_PORT_MRI_MAC_CTRL, PORT_USER_PRIO_CEILING,
11661163
false);
11671164
ksz9477_port_cfg32(dev, port, REG_PORT_MTI_QUEUE_CTRL_0__4,
11681165
MTI_PVID_REPLACE, false);
11691166

1170-
/* enable 802.1p priority */
1171-
ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_PRIO_ENABLE, true);
1172-
11731167
/* force flow control for non-PHY ports only */
11741168
ksz_port_cfg(dev, port, REG_PORT_CTRL_0,
11751169
PORT_FORCE_TX_FLOW_CTRL | PORT_FORCE_RX_FLOW_CTRL,

0 commit comments

Comments
 (0)