realtek: dsa: move egress rate handling to SoC config

The RTL838x and RTL839x families use different mechanisms for reading
and configuring the port egress rate.

Add get_egress_rate and set_egress_rate callbacks to rtldsa_config and
use them from debugfs instead of selecting the implementation based on
priv->family_id.

Rename the existing functions to use the rtldsa_838x and rtldsa_839x
prefixes consistently with the other SoC-specific callbacks.

This removes another family_id dependency from the common debugfs
code and keeps the SoC-specific implementation selected through
rtldsa_config.

While we are here do some minor type cleanups:

- Change the value used by port_egress_rate_read() from int to u32
  and remove the negative value check. Both get_egress_rate callbacks
  return u32, so value can never be negative and the check could not
  report an error. The callbacks return 0 for an invalid port instead.
- Change the res size_t variable type to ssize_t. This fixes the dead
  comparison "res < 0".
- Remove the uninitialized read in rtldsa_839x_get_egress_rate()

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24918
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
This commit is contained in:
Markus Stockhausen committed 2026-08-29 09:04:29 +02:00
1 parent 08966754f1
commit ccde424785
5 files changed
+23 -25

No files matched your search

@@ -632,17 +632,11 @@ static ssize_t port_egress_rate_read(struct file *filp, char __user *buffer, siz
struct rtldsa_port *p = filp->private_data;
struct dsa_switch *ds = p->dp->ds;
struct rtl838x_switch_priv *priv = ds->priv;
int value;
u32 value;
if (priv->family_id == RTL8380_FAMILY_ID)
value = rtl838x_get_egress_rate(priv, p->dp->index);
else
value = rtl839x_get_egress_rate(priv, p->dp->index);
value = priv->r->get_egress_rate(priv, p->dp->index);
if (value < 0)
return -EINVAL;
return rtl838x_common_read(buffer, count, ppos, (u32)value);
return rtl838x_common_read(buffer, count, ppos, value);
}
static ssize_t port_egress_rate_write(struct file *filp, const char __user *buffer,
@@ -652,15 +646,13 @@ static ssize_t port_egress_rate_write(struct file *filp, const char __user *buff
struct dsa_switch *ds = p->dp->ds;
struct rtl838x_switch_priv *priv = ds->priv;
u32 value;
size_t res = rtl838x_common_write(buffer, count, ppos, &value);
ssize_t res;
res = rtl838x_common_write(buffer, count, ppos, &value);
if (res < 0)
return res;
if (priv->family_id == RTL8380_FAMILY_ID)
rtl838x_set_egress_rate(priv, p->dp->index, value);
else
rtl839x_set_egress_rate(priv, p->dp->index, value);
priv->r->set_egress_rate(priv, p->dp->index, value);
return res;
}
@@ -42,7 +42,7 @@ static void rtl839x_read_out_q_table(int port)
rtl839x_exec_tbl2_cmd(cmd);
}
u32 rtl838x_get_egress_rate(struct rtl838x_switch_priv *priv, int port)
u32 rtldsa_838x_get_egress_rate(struct rtl838x_switch_priv *priv, int port)
{
if (port > priv->r->cpu_port)
return 0;
@@ -51,7 +51,7 @@ u32 rtl838x_get_egress_rate(struct rtl838x_switch_priv *priv, int port)
}
/* Sets the rate limit, 10MBit/s is equal to a rate value of 625 */
int rtl838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate)
int rtldsa_838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate)
{
u32 old_rate;
@@ -65,11 +65,10 @@ int rtl838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate
}
/* Sets the rate limit, 10MBit/s is equal to a rate value of 625 */
u32 rtl839x_get_egress_rate(struct rtl838x_switch_priv *priv, int port)
u32 rtldsa_839x_get_egress_rate(struct rtl838x_switch_priv *priv, int port)
{
u32 rate;
pr_debug("%s: Getting egress rate on port %d to %d\n", __func__, port, rate);
if (port >= priv->r->cpu_port)
return 0;
@@ -82,12 +81,13 @@ u32 rtl839x_get_egress_rate(struct rtl838x_switch_priv *priv, int port)
rate |= sw_r32(RTL839X_TBL_ACCESS_DATA_2(8)) >> 20;
mutex_unlock(&priv->reg_mutex);
pr_debug("%s: Getting egress rate on port %d is %d\n", __func__, port, rate);
return rate;
}
/* Sets the rate limit, 10MBit/s is equal to a rate value of 625, returns previous rate */
int rtl839x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate)
int rtldsa_839x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate)
{
u32 old_rate;
@@ -212,7 +212,7 @@ static void rtl839x_set_scheduling_algorithm(struct rtl838x_switch_priv *priv, i
sw_w32(0x2, RTL839X_OAM_PORT_ACT_CTRL(port));
/* Set port egress rate to unlimited */
egress_rate = rtl839x_set_egress_rate(priv, port, 0xFFFFF);
egress_rate = rtldsa_839x_set_egress_rate(priv, port, 0xFFFFF);
/* Wait until the egress used page count of that port is 0 */
i = 0;
@@ -238,7 +238,7 @@ static void rtl839x_set_scheduling_algorithm(struct rtl838x_switch_priv *priv, i
sw_w32(oam_port_state, RTL839X_OAM_PORT_ACT_CTRL(port));
/* Restore port egress rate */
rtl839x_set_egress_rate(priv, port, egress_rate);
rtldsa_839x_set_egress_rate(priv, port, egress_rate);
}
mutex_unlock(&priv->reg_mutex);
@@ -1415,6 +1415,8 @@ struct rtldsa_config {
void (*packet_cntr_clear)(int counter);
void (*set_receive_management_action)(int port, rma_ctrl_t type, action_type_t action);
void (*led_init)(struct rtl838x_switch_priv *priv);
u32 (*get_egress_rate)(struct rtl838x_switch_priv *priv, int port);
int (*set_egress_rate)(struct rtl838x_switch_priv *priv, int port, u32 rate);
void (*qos_init)(struct rtl838x_switch_priv *priv);
int (*trk_mbr_ctr)(int group);
void (*lag_switch_init)(struct rtl838x_switch_priv *priv);
@@ -1628,20 +1630,20 @@ int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type
/* Port register accessor functions for the RTL839x and RTL931X SoCs */
void rtl839x_mask_port_reg_be(u64 clear, u64 set, int reg);
u32 rtl839x_get_egress_rate(struct rtl838x_switch_priv *priv, int port);
u32 rtldsa_839x_get_egress_rate(struct rtl838x_switch_priv *priv, int port);
u64 rtl839x_get_port_reg_be(int reg);
void rtl839x_set_port_reg_be(u64 set, int reg);
void rtl839x_mask_port_reg_le(u64 clear, u64 set, int reg);
int rtl839x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate);
int rtldsa_839x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate);
void rtl839x_set_port_reg_le(u64 set, int reg);
u64 rtl839x_get_port_reg_le(int reg);
/* Port register accessor functions for the RTL838x and RTL930X SoCs */
void rtl838x_mask_port_reg(u64 clear, u64 set, int reg);
void rtl838x_set_port_reg(u64 set, int reg);
u32 rtl838x_get_egress_rate(struct rtl838x_switch_priv *priv, int port);
u32 rtldsa_838x_get_egress_rate(struct rtl838x_switch_priv *priv, int port);
u64 rtl838x_get_port_reg(int reg);
int rtl838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate);
int rtldsa_838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate);
/* RTL838x-specific */
u32 rtl838x_hash(struct rtl838x_switch_priv *priv, u64 seed);
@@ -1851,6 +1851,8 @@ const struct rtldsa_config rtldsa_838x_cfg = {
.packet_cntr_read = rtl838x_packet_cntr_read,
.packet_cntr_clear = rtl838x_packet_cntr_clear,
.set_receive_management_action = rtl838x_set_receive_management_action,
.get_egress_rate = rtldsa_838x_get_egress_rate,
.set_egress_rate = rtldsa_838x_set_egress_rate,
.qos_init = rtldsa_838x_qos_init,
.lag_set_distribution_algorithm = rtldsa_838x_set_distribution_algorithm,
.lag_set_port_members = rtldsa_838x_lag_set_port_members,
@@ -1734,6 +1734,8 @@ const struct rtldsa_config rtldsa_839x_cfg = {
.packet_cntr_read = rtl839x_packet_cntr_read,
.packet_cntr_clear = rtl839x_packet_cntr_clear,
.set_receive_management_action = rtl839x_set_receive_management_action,
.get_egress_rate = rtldsa_839x_get_egress_rate,
.set_egress_rate = rtldsa_839x_set_egress_rate,
.qos_init = rtldsa_839x_qos_init,
.lag_set_distribution_algorithm = rtldsa_839x_set_distribution_algorithm,
.lag_set_port_members = rtldsa_839x_lag_set_port_members,