* [PATCH net-next v3 0/2] net: dsa: yt921x: Add port TBF support
@ 2026-05-08 6:57 David Yang
2026-05-08 6:57 ` [PATCH net-next v3 1/2] net/sched: tbf: add extack to offload params David Yang
2026-05-08 6:57 ` [PATCH net-next v3 2/2] net: dsa: yt921x: Add port TBF support David Yang
0 siblings, 2 replies; 6+ messages in thread
From: David Yang @ 2026-05-08 6:57 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jamal Hadi Salim,
Jiri Pirko, Simon Horman, linux-kernel
v2: https://lore.kernel.org/r/20260504101258.1608004-1-mmyangfl@gmail.com
- drop changes on tc_tbf_qopt_offload_replace_params
- drop excessive checks for tbf setup
- react to TC_TBF_STATS correctly
v1: https://lore.kernel.org/r/20260502215314.917687-1-mmyangfl@gmail.com
- remove queue related register definiations
- add missing extack param during tbf setup
v0: https://lore.kernel.org/r/20260409171209.2575583-1-mmyangfl@gmail.com
- picked from old series
- add extack to the offload struct
- add all params to the offload struct
David Yang (2):
net/sched: tbf: add extack to offload params
net: dsa: yt921x: Add port TBF support
drivers/net/dsa/yt921x.c | 84 ++++++++++++++++++++++++++++++++++++++++
drivers/net/dsa/yt921x.h | 18 +++++++++
include/net/pkt_cls.h | 1 +
net/sched/sch_tbf.c | 9 ++++-
4 files changed, 110 insertions(+), 2 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH net-next v3 1/2] net/sched: tbf: add extack to offload params
2026-05-08 6:57 [PATCH net-next v3 0/2] net: dsa: yt921x: Add port TBF support David Yang
@ 2026-05-08 6:57 ` David Yang
2026-05-12 9:06 ` Simon Horman
2026-05-08 6:57 ` [PATCH net-next v3 2/2] net: dsa: yt921x: Add port TBF support David Yang
1 sibling, 1 reply; 6+ messages in thread
From: David Yang @ 2026-05-08 6:57 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jamal Hadi Salim,
Jiri Pirko, Simon Horman, linux-kernel
Drivers might have error messages to propagate to user space. Propagate
the netlink extack so that they can inform user space in a verbal way of
their limitations.
Signed-off-by: David Yang <mmyangfl@gmail.com>
---
include/net/pkt_cls.h | 1 +
net/sched/sch_tbf.c | 9 +++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 99ac747b7906..3bd08d7f39c1 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -1046,6 +1046,7 @@ struct tc_tbf_qopt_offload_replace_params {
};
struct tc_tbf_qopt_offload {
+ struct netlink_ext_ack *extack;
enum tc_tbf_command command;
u32 handle;
u32 parent;
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index f2340164f579..4576111fe075 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -139,7 +139,8 @@ static u64 psched_ns_t2l(const struct psched_ratecfg *r,
return len;
}
-static void tbf_offload_change(struct Qdisc *sch)
+static void tbf_offload_change(struct Qdisc *sch,
+ struct netlink_ext_ack *extack)
{
struct tbf_sched_data *q = qdisc_priv(sch);
struct net_device *dev = qdisc_dev(sch);
@@ -148,6 +149,7 @@ static void tbf_offload_change(struct Qdisc *sch)
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
return;
+ qopt.extack = extack;
qopt.command = TC_TBF_REPLACE;
qopt.handle = sch->handle;
qopt.parent = sch->parent;
@@ -166,6 +168,7 @@ static void tbf_offload_destroy(struct Qdisc *sch)
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
return;
+ qopt.extack = NULL;
qopt.command = TC_TBF_DESTROY;
qopt.handle = sch->handle;
qopt.parent = sch->parent;
@@ -176,6 +179,7 @@ static int tbf_offload_dump(struct Qdisc *sch)
{
struct tc_tbf_qopt_offload qopt;
+ qopt.extack = NULL;
qopt.command = TC_TBF_STATS;
qopt.handle = sch->handle;
qopt.parent = sch->parent;
@@ -193,6 +197,7 @@ static void tbf_offload_graft(struct Qdisc *sch, struct Qdisc *new,
.parent = sch->parent,
.child_handle = new->handle,
.command = TC_TBF_GRAFT,
+ .extack = extack,
};
qdisc_offload_graft_helper(qdisc_dev(sch), sch, new, old,
@@ -477,7 +482,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
qdisc_put(old);
err = 0;
- tbf_offload_change(sch);
+ tbf_offload_change(sch, extack);
done:
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH net-next v3 2/2] net: dsa: yt921x: Add port TBF support
2026-05-08 6:57 [PATCH net-next v3 0/2] net: dsa: yt921x: Add port TBF support David Yang
2026-05-08 6:57 ` [PATCH net-next v3 1/2] net/sched: tbf: add extack to offload params David Yang
@ 2026-05-08 6:57 ` David Yang
2026-05-12 8:56 ` Paolo Abeni
2026-05-12 9:10 ` Simon Horman
1 sibling, 2 replies; 6+ messages in thread
From: David Yang @ 2026-05-08 6:57 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jamal Hadi Salim,
Jiri Pirko, Simon Horman, linux-kernel
React to TC_SETUP_QDISC_TBF and configure the egress shaper as
appropriate with the maximum rate and burst size requested by the user.
Per queue shaper is possible, though not touched in this commit.
Signed-off-by: David Yang <mmyangfl@gmail.com>
---
drivers/net/dsa/yt921x.c | 84 ++++++++++++++++++++++++++++++++++++++++
drivers/net/dsa/yt921x.h | 18 +++++++++
2 files changed, 102 insertions(+)
diff --git a/drivers/net/dsa/yt921x.c b/drivers/net/dsa/yt921x.c
index fd1fdcd5f9a3..e5f547629bfd 100644
--- a/drivers/net/dsa/yt921x.c
+++ b/drivers/net/dsa/yt921x.c
@@ -24,6 +24,7 @@
#include <net/dsa.h>
#include <net/dscp.h>
#include <net/ieee8021q.h>
+#include <net/pkt_cls.h>
#include "yt921x.h"
@@ -1272,6 +1273,17 @@ yt921x_marker_tfm_police(struct yt921x_marker *marker,
priv, port, extack);
}
+static int
+yt921x_marker_tfm_shape(struct yt921x_marker *marker, u64 rate, u64 burst,
+ unsigned int flags, struct yt921x_priv *priv, int port,
+ struct netlink_ext_ack *extack)
+{
+ return yt921x_marker_tfm(marker, rate, burst, flags,
+ priv->port_shape_slot_ns, YT921X_SHAPE_CIR_MAX,
+ YT921X_SHAPE_CBS_MAX, YT921X_SHAPE_UNIT_MAX,
+ priv, port, extack);
+}
+
static int
yt921x_police_validate(const struct flow_action_police *police,
const struct flow_action *action,
@@ -1378,6 +1390,70 @@ yt921x_dsa_port_policer_add(struct dsa_switch *ds, int port,
return res;
}
+static int
+yt921x_dsa_port_setup_tc_tbf_port(struct dsa_switch *ds, int port,
+ const struct tc_tbf_qopt_offload *qopt)
+{
+ struct yt921x_priv *priv = to_yt921x_priv(ds);
+ struct netlink_ext_ack *extack = qopt->extack;
+ u32 ctrls[2];
+ int res;
+
+ if (qopt->parent != TC_H_ROOT)
+ return -EOPNOTSUPP;
+
+ switch (qopt->command) {
+ case TC_TBF_STATS:
+ return 0;
+ case TC_TBF_DESTROY:
+ ctrls[0] = 0;
+ ctrls[1] = 0;
+ break;
+ case TC_TBF_REPLACE: {
+ const struct tc_tbf_qopt_offload_replace_params *p;
+ struct yt921x_marker marker;
+
+ p = &qopt->replace_params;
+
+ res = yt921x_marker_tfm_shape(&marker, p->rate.rate_bytes_ps,
+ p->max_size,
+ YT921X_MARKER_SINGLE_BUCKET,
+ priv, port, extack);
+ if (res)
+ return res;
+
+ ctrls[0] = YT921X_PORT_SHAPE_CTRLa_CIR(marker.cir) |
+ YT921X_PORT_SHAPE_CTRLa_CBS(marker.cbs);
+ ctrls[1] = YT921X_PORT_SHAPE_CTRLb_UNIT(marker.unit) |
+ YT921X_PORT_SHAPE_CTRLb_EN;
+ break;
+ }
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ mutex_lock(&priv->reg_lock);
+ res = yt921x_reg64_write(priv, YT921X_PORTn_SHAPE_CTRL(port), ctrls);
+ mutex_unlock(&priv->reg_lock);
+
+ return res;
+}
+
+static int
+yt921x_dsa_port_setup_tc(struct dsa_switch *ds, int port,
+ enum tc_setup_type type, void *type_data)
+{
+ switch (type) {
+ case TC_SETUP_QDISC_TBF: {
+ const struct tc_tbf_qopt_offload *qopt = type_data;
+
+ return yt921x_dsa_port_setup_tc_tbf_port(ds, port, qopt);
+ }
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static int
yt921x_mirror_del(struct yt921x_priv *priv, int port, bool ingress)
{
@@ -3524,6 +3600,13 @@ static int yt921x_chip_setup_tc(struct yt921x_priv *priv)
return res;
priv->meter_slot_ns = ctrl * op_ns;
+ ctrl = max(priv->port_shape_slot_ns / op_ns,
+ YT921X_PORT_SHAPE_SLOT_MIN);
+ res = yt921x_reg_write(priv, YT921X_PORT_SHAPE_SLOT, ctrl);
+ if (res)
+ return res;
+ priv->port_shape_slot_ns = ctrl * op_ns;
+
return 0;
}
@@ -3680,6 +3763,7 @@ static const struct dsa_switch_ops yt921x_dsa_switch_ops = {
/* rate */
.port_policer_del = yt921x_dsa_port_policer_del,
.port_policer_add = yt921x_dsa_port_policer_add,
+ .port_setup_tc = yt921x_dsa_port_setup_tc,
/* hsr */
.port_hsr_leave = dsa_port_simple_hsr_leave,
.port_hsr_join = dsa_port_simple_hsr_join,
diff --git a/drivers/net/dsa/yt921x.h b/drivers/net/dsa/yt921x.h
index 546b12a8994a..70fa780c337f 100644
--- a/drivers/net/dsa/yt921x.h
+++ b/drivers/net/dsa/yt921x.h
@@ -531,6 +531,19 @@ enum yt921x_app_selector {
#define YT921X_MIRROR_PORT_M GENMASK(3, 0)
#define YT921X_MIRROR_PORT(x) FIELD_PREP(YT921X_MIRROR_PORT_M, (x))
+#define YT921X_PORT_SHAPE_SLOT 0x34000c
+#define YT921X_PORT_SHAPE_SLOT_SLOT_M GENMASK(11, 0)
+#define YT921X_PORTn_SHAPE_CTRL(port) (0x354000 + 8 * (port))
+#define YT921X_PORT_SHAPE_CTRLb_EN BIT(4)
+#define YT921X_PORT_SHAPE_CTRLb_PKT_MODE BIT(3) /* 0: byte rate mode */
+#define YT921X_PORT_SHAPE_CTRLb_UNIT_M GENMASK(2, 0)
+#define YT921X_PORT_SHAPE_CTRLb_UNIT(x) FIELD_PREP(YT921X_PORT_SHAPE_CTRLb_UNIT_M, (x))
+#define YT921X_PORT_SHAPE_CTRLa_CBS_M GENMASK(31, 18)
+#define YT921X_PORT_SHAPE_CTRLa_CBS(x) FIELD_PREP(YT921X_PORT_SHAPE_CTRLa_CBS_M, (x))
+#define YT921X_PORT_SHAPE_CTRLa_CIR_M GENMASK(17, 0)
+#define YT921X_PORT_SHAPE_CTRLa_CIR(x) FIELD_PREP(YT921X_PORT_SHAPE_CTRLa_CIR_M, (x))
+#define YT921X_PORTn_SHAPE_STAT(port) (0x356000 + 4 * (port))
+
#define YT921X_EDATA_EXTMODE 0xfb
#define YT921X_EDATA_LEN 0x100
@@ -556,6 +569,10 @@ enum yt921x_fdb_entry_status {
#define YT921X_METER_UNIT_MAX ((1 << 3) - 1)
#define YT921X_METER_CIR_MAX ((1 << 18) - 1)
#define YT921X_METER_CBS_MAX ((1 << 16) - 1)
+#define YT921X_PORT_SHAPE_SLOT_MIN 80
+#define YT921X_SHAPE_UNIT_MAX ((1 << 3) - 1)
+#define YT921X_SHAPE_CIR_MAX ((1 << 18) - 1)
+#define YT921X_SHAPE_CBS_MAX ((1 << 14) - 1)
#define YT921X_LAG_NUM 2
#define YT921X_LAG_PORT_NUM 4
@@ -652,6 +669,7 @@ struct yt921x_priv {
const struct yt921x_info *info;
unsigned int meter_slot_ns;
+ unsigned int port_shape_slot_ns;
/* cache of dsa_cpu_ports(ds) */
u16 cpu_ports_mask;
unsigned char cycle_ns;
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net-next v3 2/2] net: dsa: yt921x: Add port TBF support
2026-05-08 6:57 ` [PATCH net-next v3 2/2] net: dsa: yt921x: Add port TBF support David Yang
@ 2026-05-12 8:56 ` Paolo Abeni
2026-05-12 9:10 ` Simon Horman
1 sibling, 0 replies; 6+ messages in thread
From: Paolo Abeni @ 2026-05-12 8:56 UTC (permalink / raw)
To: David Yang, netdev
Cc: Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Jamal Hadi Salim, Jiri Pirko, Simon Horman,
linux-kernel
On 5/8/26 8:57 AM, David Yang wrote:
> @@ -1378,6 +1390,70 @@ yt921x_dsa_port_policer_add(struct dsa_switch *ds, int port,
> return res;
> }
>
> +static int
> +yt921x_dsa_port_setup_tc_tbf_port(struct dsa_switch *ds, int port,
> + const struct tc_tbf_qopt_offload *qopt)
> +{
> + struct yt921x_priv *priv = to_yt921x_priv(ds);
> + struct netlink_ext_ack *extack = qopt->extack;
> + u32 ctrls[2];
> + int res;
> +
> + if (qopt->parent != TC_H_ROOT)
> + return -EOPNOTSUPP;
> +
> + switch (qopt->command) {
> + case TC_TBF_STATS:
> + return 0;
The above makes the stats actually not supported; it should return
-NOPNOTSUPP.
/P
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next v3 1/2] net/sched: tbf: add extack to offload params
2026-05-08 6:57 ` [PATCH net-next v3 1/2] net/sched: tbf: add extack to offload params David Yang
@ 2026-05-12 9:06 ` Simon Horman
0 siblings, 0 replies; 6+ messages in thread
From: Simon Horman @ 2026-05-12 9:06 UTC (permalink / raw)
To: mmyangfl
Cc: 'Simon Horman', netdev, andrew, olteanv, davem, edumazet,
kuba, pabeni, jhs, jiri, linux-kernel
From: 'Simon Horman' <horms@kernel.org>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev
---
net/sched: tbf: add extack to offload params
Drivers might have error messages to propagate to user space. Propagate
the netlink extack so that they can inform user space in a verbal way of
their limitations.
> diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
> index f2340164f579a..4576111fe0758 100644
> --- a/net/sched/sch_tbf.c
> +++ b/net/sched/sch_tbf.c
[ ... ]
> @@ -193,6 +197,7 @@ static void tbf_offload_graft(struct Qdisc *sch, struct Qdisc *new,
> .parent = sch->parent,
> .child_handle = new->handle,
> .command = TC_TBF_GRAFT,
> + .extack = extack,
> };
>
> qdisc_offload_graft_helper(qdisc_dev(sch), sch, new, old,
Will the driver's extack message be overwritten here?
Looking at qdisc_offload_graft_helper() in net/sched/sch_api.c, if the
driver returns an error and any qdisc is offloaded, it calls
NL_SET_ERR_MSG:
net/sched/sch_api.c:qdisc_offload_graft_helper() {
err = dev->netdev_ops->ndo_setup_tc(dev, type, type_data);
...
if (any_qdisc_is_offloaded)
NL_SET_ERR_MSG(extack, "Offloading graft operation failed.");
}
Does this unconditionally overwrite the specific error message just set
by the driver, defeating the patch's goal for graft operations?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next v3 2/2] net: dsa: yt921x: Add port TBF support
2026-05-08 6:57 ` [PATCH net-next v3 2/2] net: dsa: yt921x: Add port TBF support David Yang
2026-05-12 8:56 ` Paolo Abeni
@ 2026-05-12 9:10 ` Simon Horman
1 sibling, 0 replies; 6+ messages in thread
From: Simon Horman @ 2026-05-12 9:10 UTC (permalink / raw)
To: mmyangfl
Cc: 'Simon Horman', netdev, andrew, olteanv, davem, edumazet,
kuba, pabeni, jhs, jiri, linux-kernel
From: 'Simon Horman' <horms@kernel.org>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev
---
net: dsa: yt921x: Add port TBF support
This commit adds support for configuring the egress shaper via the
TC_SETUP_QDISC_TBF offload in the yt921x driver.
> diff --git a/drivers/net/dsa/yt921x.c b/drivers/net/dsa/yt921x.c
> index 42dca9617fb17..c5af64ea0c326 100644
> --- a/drivers/net/dsa/yt921x.c
> +++ b/drivers/net/dsa/yt921x.c
[ ... ]
> +static int
> +yt921x_dsa_port_setup_tc_tbf_port(struct dsa_switch *ds, int port,
> + const struct tc_tbf_qopt_offload *qopt)
> +{
> + struct yt921x_priv *priv = to_yt921x_priv(ds);
> + struct netlink_ext_ack *extack = qopt->extack;
> + u32 ctrls[2];
> + int res;
> +
> + if (qopt->parent != TC_H_ROOT)
> + return -EOPNOTSUPP;
> +
> + switch (qopt->command) {
> + case TC_TBF_STATS:
> + return 0;
Is it intended to return 0 here without populating the hardware statistics?
When the driver handles this command by returning 0 without modifying
qopt->stats, it incorrectly signals to the TC core that hardware statistics
were successfully fetched. As a result, the subsystem will report
unmodified (typically zeroed) statistics, which hides any packets shaped
or dropped by the hardware.
Should this read the hardware statistic registers (like the newly defined
YT921X_PORTn_SHAPE_STAT) to update qopt->stats, or alternatively return
-EOPNOTSUPP to indicate a lack of support?
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-05-12 9:12 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-08 6:57 [PATCH net-next v3 0/2] net: dsa: yt921x: Add port TBF support David Yang
2026-05-08 6:57 ` [PATCH net-next v3 1/2] net/sched: tbf: add extack to offload params David Yang
2026-05-12 9:06 ` Simon Horman
2026-05-08 6:57 ` [PATCH net-next v3 2/2] net: dsa: yt921x: Add port TBF support David Yang
2026-05-12 8:56 ` Paolo Abeni
2026-05-12 9:10 ` Simon Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox