Skip to content

Commit

Permalink
Merge branch 'ksz-dcb-dscp'
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
davem330 committed May 8, 2024
2 parents 09ca994 + cbc7aff commit 9f481ce
Show file tree
Hide file tree
Showing 18 changed files with 2,133 additions and 86 deletions.
2 changes: 2 additions & 0 deletions drivers/net/dsa/microchip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ menuconfig NET_DSA_MICROCHIP_KSZ_COMMON
depends on NET_DSA
select NET_DSA_TAG_KSZ
select NET_DSA_TAG_NONE
select NET_IEEE8021Q_HELPERS
select DCB
help
This driver adds support for Microchip KSZ9477 series switch and
KSZ8795/KSZ88x3 switch chips.
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/dsa/microchip/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON) += ksz_switch.o
ksz_switch-objs := ksz_common.o
ksz_switch-objs := ksz_common.o ksz_dcb.o
ksz_switch-objs += ksz9477.o ksz9477_acl.o ksz9477_tc_flower.o
ksz_switch-objs += ksz8795.o
ksz_switch-objs += lan937x_main.o
Expand Down
1 change: 1 addition & 0 deletions drivers/net/dsa/microchip/ksz8.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ void ksz8_phylink_mac_link_up(struct phylink_config *config,
struct phy_device *phydev, unsigned int mode,
phy_interface_t interface, int speed, int duplex,
bool tx_pause, bool rx_pause);
int ksz8_all_queues_split(struct ksz_device *dev, int queues);

#endif
106 changes: 71 additions & 35 deletions drivers/net/dsa/microchip/ksz8795.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,37 +127,71 @@ int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu)
return -EOPNOTSUPP;
}

static void ksz8795_set_prio_queue(struct ksz_device *dev, int port, int queue)
static int ksz8_port_queue_split(struct ksz_device *dev, int port, int queues)
{
u8 hi, lo;
u8 mask_4q, mask_2q;
u8 reg_4q, reg_2q;
u8 data_4q = 0;
u8 data_2q = 0;
int ret;

/* Number of queues can only be 1, 2, or 4. */
switch (queue) {
case 4:
case 3:
queue = PORT_QUEUE_SPLIT_4;
break;
case 2:
queue = PORT_QUEUE_SPLIT_2;
break;
default:
queue = PORT_QUEUE_SPLIT_1;
if (ksz_is_ksz88x3(dev)) {
mask_4q = KSZ8873_PORT_4QUEUE_SPLIT_EN;
mask_2q = KSZ8873_PORT_2QUEUE_SPLIT_EN;
reg_4q = REG_PORT_CTRL_0;
reg_2q = REG_PORT_CTRL_2;

/* KSZ8795 family switches have Weighted Fair Queueing (WFQ)
* enabled by default. Enable it for KSZ8873 family switches
* too. Default value for KSZ8873 family is strict priority,
* which should be enabled by using TC_SETUP_QDISC_ETS, not
* by default.
*/
ret = ksz_rmw8(dev, REG_SW_CTRL_3, WEIGHTED_FAIR_QUEUE_ENABLE,
WEIGHTED_FAIR_QUEUE_ENABLE);
if (ret)
return ret;
} else {
mask_4q = KSZ8795_PORT_4QUEUE_SPLIT_EN;
mask_2q = KSZ8795_PORT_2QUEUE_SPLIT_EN;
reg_4q = REG_PORT_CTRL_13;
reg_2q = REG_PORT_CTRL_0;

/* TODO: this is legacy from initial KSZ8795 driver, should be
* moved to appropriate place in the future.
*/
ret = ksz_rmw8(dev, REG_SW_CTRL_19,
SW_OUT_RATE_LIMIT_QUEUE_BASED,
SW_OUT_RATE_LIMIT_QUEUE_BASED);
if (ret)
return ret;
}

if (queues == 4)
data_4q = mask_4q;
else if (queues == 2)
data_2q = mask_2q;

ret = ksz_prmw8(dev, port, reg_4q, mask_4q, data_4q);
if (ret)
return ret;

return ksz_prmw8(dev, port, reg_2q, mask_2q, data_2q);
}

int ksz8_all_queues_split(struct ksz_device *dev, int queues)
{
struct dsa_switch *ds = dev->ds;
const struct dsa_port *dp;

dsa_switch_for_each_port(dp, ds) {
int ret = ksz8_port_queue_split(dev, dp->index, queues);

if (ret)
return ret;
}
ksz_pread8(dev, port, REG_PORT_CTRL_0, &lo);
ksz_pread8(dev, port, P_DROP_TAG_CTRL, &hi);
lo &= ~PORT_QUEUE_SPLIT_L;
if (queue & PORT_QUEUE_SPLIT_2)
lo |= PORT_QUEUE_SPLIT_L;
hi &= ~PORT_QUEUE_SPLIT_H;
if (queue & PORT_QUEUE_SPLIT_4)
hi |= PORT_QUEUE_SPLIT_H;
ksz_pwrite8(dev, port, REG_PORT_CTRL_0, lo);
ksz_pwrite8(dev, port, P_DROP_TAG_CTRL, hi);

/* Default is port based for egress rate limit. */
if (queue != PORT_QUEUE_SPLIT_1)
ksz_cfg(dev, REG_SW_CTRL_19, SW_OUT_RATE_LIMIT_QUEUE_BASED,
true);

return 0;
}

void ksz8_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt)
Expand Down Expand Up @@ -1513,26 +1547,28 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
{
struct dsa_switch *ds = dev->ds;
const u32 *masks;
int queues;
u8 member;

masks = dev->info->masks;

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

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

/* disable DiffServ priority */
ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_DIFFSERV_ENABLE, false);
ksz8_port_queue_split(dev, port, queues);

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

/* enable 802.1p priority */
ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_ENABLE, true);

if (cpu_port)
member = dsa_user_ports(ds);
else
Expand Down
9 changes: 4 additions & 5 deletions drivers/net/dsa/microchip/ksz8795_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@
#define PORT_BASED_PRIO_3 3
#define PORT_INSERT_TAG BIT(2)
#define PORT_REMOVE_TAG BIT(1)
#define PORT_QUEUE_SPLIT_L BIT(0)
#define KSZ8795_PORT_2QUEUE_SPLIT_EN BIT(0)
#define KSZ8873_PORT_4QUEUE_SPLIT_EN BIT(0)

#define REG_PORT_1_CTRL_1 0x11
#define REG_PORT_2_CTRL_1 0x21
Expand All @@ -143,6 +144,7 @@
#define REG_PORT_4_CTRL_2 0x42
#define REG_PORT_5_CTRL_2 0x52

#define KSZ8873_PORT_2QUEUE_SPLIT_EN BIT(7)
#define PORT_INGRESS_FILTER BIT(6)
#define PORT_DISCARD_NON_VID BIT(5)
#define PORT_FORCE_FLOW_CTRL BIT(4)
Expand Down Expand Up @@ -463,10 +465,7 @@
#define REG_PORT_4_CTRL_13 0xE1
#define REG_PORT_5_CTRL_13 0xF1

#define PORT_QUEUE_SPLIT_H BIT(1)
#define PORT_QUEUE_SPLIT_1 0
#define PORT_QUEUE_SPLIT_2 1
#define PORT_QUEUE_SPLIT_4 2
#define KSZ8795_PORT_4QUEUE_SPLIT_EN BIT(1)
#define PORT_DROP_TAG BIT(0)

#define REG_PORT_1_CTRL_14 0xB2
Expand Down
6 changes: 0 additions & 6 deletions drivers/net/dsa/microchip/ksz9477.c
Original file line number Diff line number Diff line change
Expand Up @@ -1158,18 +1158,12 @@ void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
/* enable broadcast storm limit */
ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true);

/* disable DiffServ priority */
ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_DIFFSERV_PRIO_ENABLE, false);

/* replace priority */
ksz_port_cfg(dev, port, REG_PORT_MRI_MAC_CTRL, PORT_USER_PRIO_CEILING,
false);
ksz9477_port_cfg32(dev, port, REG_PORT_MTI_QUEUE_CTRL_0__4,
MTI_PVID_REPLACE, false);

/* enable 802.1p priority */
ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_PRIO_ENABLE, true);

/* force flow control for non-PHY ports only */
ksz_port_cfg(dev, port, REG_PORT_CTRL_0,
PORT_FORCE_TX_FLOW_CTRL | PORT_FORCE_RX_FLOW_CTRL,
Expand Down
Loading

0 comments on commit 9f481ce

Please sign in to comment.