Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: dsa: microchip: add ETS scheduler support for KSZ88x3 switches

Implement Enhanced Transmission Selection scheduler (ETS) support for
KSZ88x3 devices, which support two fixed egress scheduling modes:
Strict Priority and Weighted Fair Queuing (WFQ).

Since the switch does not allow remapping priorities to queues or
adjusting weights, this implementation only supports enabling
strict priority mode. If strict mode is not explicitly requested,
the switch falls back to its default WFQ mode.

This patch introduces KSZ88x3-specific handlers for ETS add and
delete operations and uses TXQ Split Control registers to toggle
the WFQ enable bit per queue. Corresponding macros are also added
for register access.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Link: https://patch.msgid.link/20250410124249.2728568-1-o.rempel@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Oleksij Rempel and committed by
Jakub Kicinski
4129a75a b8ebc893

+113 -3
+94 -3
drivers/net/dsa/microchip/ksz_common.c
··· 3999 3999 return p->bands - 1 - band; 4000 4000 } 4001 4001 4002 + /** 4003 + * ksz88x3_tc_ets_add - Configure ETS (Enhanced Transmission Selection) 4004 + * for a port on KSZ88x3 switch 4005 + * @dev: Pointer to the KSZ switch device structure 4006 + * @port: Port number to configure 4007 + * @p: Pointer to offload replace parameters describing ETS bands and mapping 4008 + * 4009 + * The KSZ88x3 supports two scheduling modes: Strict Priority and 4010 + * Weighted Fair Queuing (WFQ). Both modes have fixed behavior: 4011 + * - No configurable queue-to-priority mapping 4012 + * - No weight adjustment in WFQ mode 4013 + * 4014 + * This function configures the switch to use strict priority mode by 4015 + * clearing the WFQ enable bit for all queues associated with ETS bands. 4016 + * If strict priority is not explicitly requested, the switch will default 4017 + * to WFQ mode. 4018 + * 4019 + * Return: 0 on success, or a negative error code on failure 4020 + */ 4021 + static int ksz88x3_tc_ets_add(struct ksz_device *dev, int port, 4022 + struct tc_ets_qopt_offload_replace_params *p) 4023 + { 4024 + int ret, band; 4025 + 4026 + /* Only strict priority mode is supported for now. 4027 + * WFQ is implicitly enabled when strict mode is disabled. 4028 + */ 4029 + for (band = 0; band < p->bands; band++) { 4030 + int queue = ksz_ets_band_to_queue(p, band); 4031 + u8 reg; 4032 + 4033 + /* Calculate TXQ Split Control register address for this 4034 + * port/queue 4035 + */ 4036 + reg = KSZ8873_TXQ_SPLIT_CTRL_REG(port, queue); 4037 + 4038 + /* Clear WFQ enable bit to select strict priority scheduling */ 4039 + ret = ksz_rmw8(dev, reg, KSZ8873_TXQ_WFQ_ENABLE, 0); 4040 + if (ret) 4041 + return ret; 4042 + } 4043 + 4044 + return 0; 4045 + } 4046 + 4047 + /** 4048 + * ksz88x3_tc_ets_del - Reset ETS (Enhanced Transmission Selection) config 4049 + * for a port on KSZ88x3 switch 4050 + * @dev: Pointer to the KSZ switch device structure 4051 + * @port: Port number to reset 4052 + * 4053 + * The KSZ88x3 supports only fixed scheduling modes: Strict Priority or 4054 + * Weighted Fair Queuing (WFQ), with no reconfiguration of weights or 4055 + * queue mapping. This function resets the port’s scheduling mode to 4056 + * the default, which is WFQ, by enabling the WFQ bit for all queues. 4057 + * 4058 + * Return: 0 on success, or a negative error code on failure 4059 + */ 4060 + static int ksz88x3_tc_ets_del(struct ksz_device *dev, int port) 4061 + { 4062 + int ret, queue; 4063 + 4064 + /* Iterate over all transmit queues for this port */ 4065 + for (queue = 0; queue < dev->info->num_tx_queues; queue++) { 4066 + u8 reg; 4067 + 4068 + /* Calculate TXQ Split Control register address for this 4069 + * port/queue 4070 + */ 4071 + reg = KSZ8873_TXQ_SPLIT_CTRL_REG(port, queue); 4072 + 4073 + /* Set WFQ enable bit to revert back to default scheduling 4074 + * mode 4075 + */ 4076 + ret = ksz_rmw8(dev, reg, KSZ8873_TXQ_WFQ_ENABLE, 4077 + KSZ8873_TXQ_WFQ_ENABLE); 4078 + if (ret) 4079 + return ret; 4080 + } 4081 + 4082 + return 0; 4083 + } 4084 + 4002 4085 static int ksz_queue_set_strict(struct ksz_device *dev, int port, int queue) 4003 4086 { 4004 4087 int ret; ··· 4163 4080 for (queue = 0; queue < dev->info->num_tx_queues; queue++) { 4164 4081 ret = ksz_queue_set_wrr(dev, port, queue, 4165 4082 KSZ9477_DEFAULT_WRR_WEIGHT); 4083 + 4166 4084 if (ret) 4167 4085 return ret; 4168 4086 } ··· 4216 4132 struct ksz_device *dev = ds->priv; 4217 4133 int ret; 4218 4134 4219 - if (is_ksz8(dev)) 4135 + if (is_ksz8(dev) && !ksz_is_ksz88x3(dev)) 4220 4136 return -EOPNOTSUPP; 4221 4137 4222 4138 if (qopt->parent != TC_H_ROOT) { ··· 4230 4146 if (ret) 4231 4147 return ret; 4232 4148 4233 - return ksz_tc_ets_add(dev, port, &qopt->replace_params); 4149 + if (ksz_is_ksz88x3(dev)) 4150 + return ksz88x3_tc_ets_add(dev, port, 4151 + &qopt->replace_params); 4152 + else 4153 + return ksz_tc_ets_add(dev, port, &qopt->replace_params); 4234 4154 case TC_ETS_DESTROY: 4235 - return ksz_tc_ets_del(dev, port); 4155 + if (ksz_is_ksz88x3(dev)) 4156 + return ksz88x3_tc_ets_del(dev, port); 4157 + else 4158 + return ksz_tc_ets_del(dev, port); 4236 4159 case TC_ETS_STATS: 4237 4160 case TC_ETS_GRAFT: 4238 4161 return -EOPNOTSUPP;
+19
drivers/net/dsa/microchip/ksz_common.h
··· 836 836 #define SW_HI_SPEED_DRIVE_STRENGTH_S 4 837 837 #define SW_LO_SPEED_DRIVE_STRENGTH_S 0 838 838 839 + /* TXQ Split Control Register for per-port, per-queue configuration. 840 + * Register 0xAF is TXQ Split for Q3 on Port 1. 841 + * Register offset formula: 0xAF + (port * 4) + (3 - queue) 842 + * where: port = 0..2, queue = 0..3 843 + */ 844 + #define KSZ8873_TXQ_SPLIT_CTRL_REG(port, queue) \ 845 + (0xAF + ((port) * 4) + (3 - (queue))) 846 + 847 + /* Bit 7 selects between: 848 + * 0 = Strict priority mode (highest-priority queue first) 849 + * 1 = Weighted Fair Queuing (WFQ) mode: 850 + * Queue weights: Q3:Q2:Q1:Q0 = 8:4:2:1 851 + * If any queues are empty, weight is redistributed. 852 + * 853 + * Note: This is referred to as "Weighted Fair Queuing" (WFQ) in KSZ8863/8873 854 + * documentation, and as "Weighted Round Robin" (WRR) in KSZ9477 family docs. 855 + */ 856 + #define KSZ8873_TXQ_WFQ_ENABLE BIT(7) 857 + 839 858 #define KSZ9477_REG_PORT_OUT_RATE_0 0x0420 840 859 #define KSZ9477_OUT_RATE_NO_LIMIT 0 841 860