Re: [PATCH net-next v1 6/8] net: dsa: realtek: rtl8365mb: add QoS baseline and DCB default priority
From: Linus Walleij
Date: Mon Oct 05 2026 - 19:19:28 EST
Hi Oleksij,
thanks for your patch!
As mentioned I think the main logic of this DCB stuff needs to go into
common code.
Whether to use rtl83xx.c or create a new file rtl83xx-dcb.c with just this
QoS DCB stuff is up to you.
Some detailed comments:
On Fri, Oct 2, 2026 at 1:58 PM Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> wrote:
> +#define RTL8365MB_QOS_QMAP_IDX(_nq) ((_nq) & 0x7)
> +
> +/* Internal priority -> queue-id map. Eight tables (one per queue count),
> + * indexed [table][prio]; four priorities per register, 3-bit qid. An N-queue
> + * configuration uses table N-1 (1Q is table 0 at 0x0904, 8Q is table 7).
> + */
> +#define RTL8365MB_QOS_PRI_TO_QID_TABLE(_nq) ((_nq) - 1)
> +#define RTL8365MB_QOS_PRI_TO_QID_REG(_t, _pri) \
> + (0x0904 + ((_t) << 1) + ((_pri) >> 2))
(...)
> +static int rtl8365mb_qos_setup_queues(struct realtek_priv *priv,
> + unsigned int nq)
> +{
> + int table = RTL8365MB_QOS_PRI_TO_QID_TABLE(nq);
Prio to qid table is nq-1
> + struct dsa_switch *ds = &priv->ds;
> + struct dsa_port *dp;
> + int tt, ret;
> +
> + dsa_switch_for_each_port(dp, ds) {
> + u32 reg = RTL8365MB_QOS_PORT_QUEUE_NUMBER_REG(dp->index);
> + int off = RTL8365MB_QOS_PORT_QUEUE_NUMBER_OFFSET(dp->index);
> +
> + ret = rtl8365mb_set_field(priv, reg,
> + rtl8365mb_qos_sel_field_mask(off),
> + RTL8365MB_QOS_QMAP_IDX(nq));
This sets qos port queue number to RTL8365MB_QOS_QMAP_IDX(nq)
which is nq & 7.
> + if (ret)
> + return ret;
> + }
> +
> + for (tt = 0; tt < IEEE8021Q_TT_MAX; tt++) {
> + u32 reg = RTL8365MB_QOS_PRI_TO_QID_REG(table, tt);
This finds the reg for table nq-1
> + int off = RTL8365MB_QOS_PRI_TO_QID_OFFSET(tt);
> + int tc = ieee8021q_tt_to_tc(tt, nq);
> +
> + if (tc < 0)
> + return tc;
> +
> + /* QID field holds the traffic class */
> + ret = rtl8365mb_set_field(priv, reg,
> + rtl8365mb_qos_sel_field_mask(off), tc);
> + if (ret)
> + return ret;
> + }
And sets it.
In a code dump I have for RTL8370 writes the same index into both registers,
so something like:
{
int qmapidx = RTL8365MB_QOS_QMAP_IDX(nq);
ret = rtl8365mb_set_field(priv, reg,
rtl8365mb_qos_sel_field_mask(off),
qmapidx);
(...)
for (tt = 0; tt < IEEE8021Q_TT_MAX; tt++) {
u32 reg = RTL8365MB_QOS_PRI_TO_QID_REG(qmapidx, tt);
int off = RTL8365MB_QOS_PRI_TO_QID_OFFSET(tt);
int tc = ieee8021q_tt_to_tc(tt, nq);
(...)
So we compute index once and use it both for port selection and
table programming.
Can you check this in the RTL8365MB manual, this old RTL8370 code
could be wrong but it's also the way RTL8366RB does things.
Yours,
Linus Walleij