[PATCH net-next v2 10/10] net: dsa: realtek: rtl8365mb: report the DCB DSCP-to-priority map

From: Oleksij Rempel

Date: Thu Nov 12 2026 - 03:51:24 EST


Report the DSCP-to-priority map through dcbnl, so that "dcb app show"
lists, on every port, the priority a DSCP value gets once the port
trusts DSCP.

The switch has one DSCP-to-priority table for all its ports, with
exactly one priority per DSCP value. dcbnl, in contrast, configures DSCP
priorities per port and allows several priorities for one DSCP value.
DSA could mirror a change to every port (dscp_prio_mapping_is_global),
but a request on one port would still change the classification of all
ports. Keep the map read-only. The QoS baseline seeds it with the
default mapping from ietf_dscp_to_ieee8021q_tt(). Requests to change a
DSCP entry fail with -EOPNOTSUPP.

Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx>
---
Q: The v1 review (Linus) suggested DSCP get, add and delete callbacks
in the common code, and setting ds->dscp_prio_mapping_is_global when
registering DSCP offload. Why are add, delete and the flag gone in v2?
A: The DSCP get moved into the shared code as asked. Add and del were
dropped because the table is chip-wide, as the commit message explains.
Without add and del, nothing would use the flag, so it is not set.

Changes in v2:
- make the DSCP map read-only, as the table is shared by all ports of
the chip and per-port remapping would change every port
- drop the DSCP add/del ops, whose delete path could leave the hardware
out of step with the remaining APP entries (sashiko)
- do not set ds->dscp_prio_mapping_is_global; without DSCP add/del
nothing needs its global set/del path (sashiko)
- retitled (was "offload DCB DSCP-to-priority")
- move the DSCP get handling into rtl83xx-qos.c behind a new
qos_get_dscp_prio callback (Linus)
- DSCP table seeding moved to the baseline patch
- read the table entry through rtl8365mb_qos_regmap_read_field(), which
uses field_get() (Luiz)
---
drivers/net/dsa/realtek/realtek.h | 1 +
drivers/net/dsa/realtek/rtl8365mb_main.c | 2 ++
drivers/net/dsa/realtek/rtl8365mb_qos.c | 7 +++++++
drivers/net/dsa/realtek/rtl8365mb_qos.h | 1 +
drivers/net/dsa/realtek/rtl83xx-qos.c | 19 +++++++++++++++++++
drivers/net/dsa/realtek/rtl83xx-qos.h | 1 +
6 files changed, 31 insertions(+)

diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
index 0008ba9681cccb521d85d9bfc97425ad1b777aa6..6f2bdeab703a7758e01f983b8907c9421c89fa52 100644
--- a/drivers/net/dsa/realtek/realtek.h
+++ b/drivers/net/dsa/realtek/realtek.h
@@ -181,6 +181,7 @@ struct realtek_ops {
int (*qos_set_port_prio)(struct realtek_priv *priv, int port,
u8 iprio, u8 untag_pcp);
int (*qos_set_pcp_prio)(struct realtek_priv *priv, u8 pcp, u8 iprio);
+ int (*qos_get_dscp_prio)(struct realtek_priv *priv, u8 dscp);
int (*qos_set_dscp_prio)(struct realtek_priv *priv, u8 dscp,
u8 iprio);
/* @trust is indexed by enum rtl83xx_apptrust_slot and has @n entries.
diff --git a/drivers/net/dsa/realtek/rtl8365mb_main.c b/drivers/net/dsa/realtek/rtl8365mb_main.c
index d16e7c99217bdc01d1bdf7dbbcb8e7ed1441e6a8..9377bdbae36c487cf11dc48e77f23ca9f78565dc 100644
--- a/drivers/net/dsa/realtek/rtl8365mb_main.c
+++ b/drivers/net/dsa/realtek/rtl8365mb_main.c
@@ -3483,6 +3483,7 @@ static const struct dsa_switch_ops rtl8365mb_switch_ops = {
.port_set_default_prio = rtl83xx_port_set_default_prio,
.port_get_apptrust = rtl83xx_port_get_apptrust,
.port_set_apptrust = rtl83xx_port_set_apptrust,
+ .port_get_dscp_prio = rtl83xx_port_get_dscp_prio,
.port_stp_state_set = rtl8365mb_port_stp_state_set,
.port_fast_age = rtl83xx_port_fast_age,
.port_fdb_add = rtl83xx_port_fdb_add,
@@ -3528,6 +3529,7 @@ static const struct realtek_ops rtl8365mb_ops = {
.qos_get_port_prio = rtl8365mb_qos_get_port_prio,
.qos_set_port_prio = rtl8365mb_qos_set_port_prio,
.qos_set_pcp_prio = rtl8365mb_qos_set_pcp_prio,
+ .qos_get_dscp_prio = rtl8365mb_qos_get_dscp_prio,
.qos_set_dscp_prio = rtl8365mb_qos_set_dscp_prio,
.qos_set_apptrust = rtl8365mb_qos_set_apptrust,
.qos_get_apptrust = rtl8365mb_qos_get_apptrust,
diff --git a/drivers/net/dsa/realtek/rtl8365mb_qos.c b/drivers/net/dsa/realtek/rtl8365mb_qos.c
index c465d639ee5e527a604498fb064d6757aac1fda4..095f4a77bd1c666528b5fa9f57aa427114ebefb3 100644
--- a/drivers/net/dsa/realtek/rtl8365mb_qos.c
+++ b/drivers/net/dsa/realtek/rtl8365mb_qos.c
@@ -255,6 +255,13 @@ int rtl8365mb_qos_set_pcp_prio(struct realtek_priv *priv, u8 pcp, u8 iprio)
iprio);
}

+int rtl8365mb_qos_get_dscp_prio(struct realtek_priv *priv, u8 dscp)
+{
+ return rtl8365mb_qos_regmap_read_field(priv,
+ RTL8365MB_QOS_DSCP_PRI_REG(dscp),
+ rtl8365mb_qos_sel_mask(dscp));
+}
+
int rtl8365mb_qos_set_dscp_prio(struct realtek_priv *priv, u8 dscp, u8 iprio)
{
return rtl8365mb_qos_regmap_update_field(priv,
diff --git a/drivers/net/dsa/realtek/rtl8365mb_qos.h b/drivers/net/dsa/realtek/rtl8365mb_qos.h
index eed5ea5fa7f345ce6989e3e890d7cd755da9d0fc..9602807f7db5b9c5bf0202612e4cd77b85079cb7 100644
--- a/drivers/net/dsa/realtek/rtl8365mb_qos.h
+++ b/drivers/net/dsa/realtek/rtl8365mb_qos.h
@@ -23,6 +23,7 @@ int rtl8365mb_qos_get_port_prio(struct realtek_priv *priv, int port);
int rtl8365mb_qos_set_port_prio(struct realtek_priv *priv, int port, u8 iprio,
u8 untag_pcp);
int rtl8365mb_qos_set_pcp_prio(struct realtek_priv *priv, u8 pcp, u8 iprio);
+int rtl8365mb_qos_get_dscp_prio(struct realtek_priv *priv, u8 dscp);
int rtl8365mb_qos_set_dscp_prio(struct realtek_priv *priv, u8 dscp, u8 iprio);
int rtl8365mb_qos_set_apptrust(struct realtek_priv *priv, int port,
const bool *trust, unsigned int n);
diff --git a/drivers/net/dsa/realtek/rtl83xx-qos.c b/drivers/net/dsa/realtek/rtl83xx-qos.c
index b25a9dfb9138b5c2c176dbe68974cdd65e1643bb..f4b7866c7f70ba5ea74f5d8631a9b66afcf50728 100644
--- a/drivers/net/dsa/realtek/rtl83xx-qos.c
+++ b/drivers/net/dsa/realtek/rtl83xx-qos.c
@@ -134,6 +134,25 @@ int rtl83xx_port_set_default_prio(struct dsa_switch *ds, int port, u8 prio)
}
EXPORT_SYMBOL_NS_GPL(rtl83xx_port_set_default_prio, "REALTEK_DSA");

+int rtl83xx_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp)
+{
+ struct realtek_priv *priv = ds->priv;
+ int tt;
+
+ if (!priv->ops->qos_get_dscp_prio)
+ return -EOPNOTSUPP;
+
+ if (dscp >= DSCP_MAX)
+ return -EINVAL;
+
+ tt = priv->ops->qos_get_dscp_prio(priv, dscp);
+ if (tt < 0)
+ return tt;
+
+ return ieee8021q_tt_to_pcp(tt);
+}
+EXPORT_SYMBOL_NS_GPL(rtl83xx_port_get_dscp_prio, "REALTEK_DSA");
+
int rtl83xx_port_get_apptrust(struct dsa_switch *ds, int port, u8 *sel,
int *nsel)
{
diff --git a/drivers/net/dsa/realtek/rtl83xx-qos.h b/drivers/net/dsa/realtek/rtl83xx-qos.h
index fbddc7b7d9dd37918423afc5373b684596637a05..06dbfd24b1af5cced870f463f15b1b39eceb56ee 100644
--- a/drivers/net/dsa/realtek/rtl83xx-qos.h
+++ b/drivers/net/dsa/realtek/rtl83xx-qos.h
@@ -15,5 +15,6 @@ int rtl83xx_port_get_apptrust(struct dsa_switch *ds, int port, u8 *sel,
int *nsel);
int rtl83xx_port_set_apptrust(struct dsa_switch *ds, int port, const u8 *sel,
int nsel);
+int rtl83xx_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp);

#endif /* _RTL83XX_QOS_H */

--
2.47.3