* [PATCH net-next 0/4] net: macb: Add TSN MQPRIO and CBS traffic-class offload
@ 2026-08-07 9:50 Vineeth Karumanchi
2026-08-07 9:50 ` [PATCH net-next 1/4] net: macb: Rename MACB_CAPS_QBV to MACB_CAPS_TC Vineeth Karumanchi
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Vineeth Karumanchi @ 2026-08-07 9:50 UTC (permalink / raw)
To: theo.lebrun, conor.dooley, andrew+netdev, davem, edumazet, kuba,
pabeni
Cc: vineeth.karumanchi, git, netdev, linux-kernel
This series adds TSN traffic-class hardware offload support to the
Cadence macb/GEM driver, building on the existing TAPRIO/Qbv
infrastructure.
GEM IP versions that implement Qbv (e.g. Versal GEM) also support
additional TSN clauses. The series first generalises the existing Qbv
capability flag into a traffic-class offload flag and centralises the
common ndo_setup_tc() preconditions, then adds two new offloads:
- MQPRIO: traffic-class to hardware-queue mapping, delegating queue
count and overlap validation to the mqprio core.
- CBS (Credit-Based Shaper, IEEE 802.1Qav): per-queue idleslope
programming on the two highest-priority queues, with the idleslope
register value derived from the current link speed (full 32-bit
range for high-speed GEM, port-rate factor for standard GEM).
Patches 1 and 2 are preparatory refactors with no functional change.
Patches 3 and 4 add the MQPRIO and CBS offloads respectively.
Vineeth Karumanchi (4):
net: macb: Rename MACB_CAPS_QBV to MACB_CAPS_TC
net: macb: Move TC capability and PM checks to macb_setup_tc()
net: macb: Add MQPRIO qdisc hardware offload support
net: macb: Add TSN CBS TC offload support
drivers/net/ethernet/cadence/macb.h | 11 +-
drivers/net/ethernet/cadence/macb_main.c | 209 +++++++++++++++++++++--
2 files changed, 206 insertions(+), 14 deletions(-)
--
2.44.4
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net-next 1/4] net: macb: Rename MACB_CAPS_QBV to MACB_CAPS_TC
2026-08-07 9:50 [PATCH net-next 0/4] net: macb: Add TSN MQPRIO and CBS traffic-class offload Vineeth Karumanchi
@ 2026-08-07 9:50 ` Vineeth Karumanchi
2026-08-07 17:09 ` Conor Dooley
2026-08-07 9:50 ` [PATCH net-next 2/4] net: macb: Move TC capability and PM checks to macb_setup_tc() Vineeth Karumanchi
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Vineeth Karumanchi @ 2026-08-07 9:50 UTC (permalink / raw)
To: theo.lebrun, conor.dooley, andrew+netdev, davem, edumazet, kuba,
pabeni
Cc: vineeth.karumanchi, git, netdev, linux-kernel
The MACB_CAPS_QBV capability flag was originally introduced to
gate TAPRIO/QBV support. However, GEM IP versions that support
QBV also implement multiple TSN clauses.
Replace this with a generic capability flag that can be reused
by other TSN features. Rename MACB_CAPS_QBV to MACB_CAPS_TC to
better reflect its role as a general traffic-class offload capability.
The supported TSN clauses are handled through macb_setup_tc().
Signed-off-by: Vineeth Karumanchi <vineeth.karumanchi@amd.com>
---
drivers/net/ethernet/cadence/macb.h | 2 +-
drivers/net/ethernet/cadence/macb_main.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index a11052565436..f24df25923d7 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -768,7 +768,7 @@
#define MACB_CAPS_MIIONRGMII BIT(9)
#define MACB_CAPS_NEED_TSUCLK BIT(10)
#define MACB_CAPS_QUEUE_DISABLE BIT(11)
-#define MACB_CAPS_QBV BIT(12)
+#define MACB_CAPS_TC BIT(12)
#define MACB_CAPS_PCS BIT(13)
#define MACB_CAPS_HIGH_SPEED BIT(14)
#define MACB_CAPS_CLK_HW_CHG BIT(15)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index d394f1f43b68..29c93df1444c 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4846,8 +4846,8 @@ static int macb_init_dflt(struct platform_device *pdev)
dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
if (bp->caps & MACB_CAPS_SG_DISABLED)
dev->hw_features &= ~NETIF_F_SG;
- /* Enable HW_TC if hardware supports QBV */
- if (bp->caps & MACB_CAPS_QBV)
+ /* Enable TC offload for TSN-capable hardware */
+ if (bp->caps & MACB_CAPS_TC)
dev->hw_features |= NETIF_F_HW_TC;
dev->features = dev->hw_features;
@@ -5678,7 +5678,7 @@ static const struct macb_config versal_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO |
MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_BD_RD_PREFETCH |
MACB_CAPS_NEED_TSUCLK | MACB_CAPS_QUEUE_DISABLE |
- MACB_CAPS_QBV |
+ MACB_CAPS_TC |
MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
.init = init_reset_optional,
--
2.44.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next 2/4] net: macb: Move TC capability and PM checks to macb_setup_tc()
2026-08-07 9:50 [PATCH net-next 0/4] net: macb: Add TSN MQPRIO and CBS traffic-class offload Vineeth Karumanchi
2026-08-07 9:50 ` [PATCH net-next 1/4] net: macb: Rename MACB_CAPS_QBV to MACB_CAPS_TC Vineeth Karumanchi
@ 2026-08-07 9:50 ` Vineeth Karumanchi
2026-08-07 9:50 ` [PATCH net-next 3/4] net: macb: Add MQPRIO qdisc hardware offload support Vineeth Karumanchi
2026-08-07 9:50 ` [PATCH net-next 4/4] net: macb: Add TSN CBS TC " Vineeth Karumanchi
3 siblings, 0 replies; 8+ messages in thread
From: Vineeth Karumanchi @ 2026-08-07 9:50 UTC (permalink / raw)
To: theo.lebrun, conor.dooley, andrew+netdev, davem, edumazet, kuba,
pabeni
Cc: vineeth.karumanchi, git, netdev, linux-kernel
Move the NETIF_F_HW_TC capability check and the runtime PM suspend
guard from macb_setup_taprio() into the common macb_setup_tc()
entry point.
These preconditions apply to all hardware TC offload paths routed
through ndo_setup_tc(), not just TAPRIO. Centralizing them avoids
duplicating the same checks as new TC qdisc types are added.
Signed-off-by: Vineeth Karumanchi <vineeth.karumanchi@amd.com>
---
drivers/net/ethernet/cadence/macb_main.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 29c93df1444c..508d952e2ae7 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4499,18 +4499,8 @@ static void macb_taprio_destroy(struct net_device *ndev)
static int macb_setup_taprio(struct net_device *ndev,
struct tc_taprio_qopt_offload *taprio)
{
- struct macb *bp = netdev_priv(ndev);
int err = 0;
- if (unlikely(!(ndev->hw_features & NETIF_F_HW_TC)))
- return -EOPNOTSUPP;
-
- /* Check if Device is in runtime suspend */
- if (unlikely(pm_runtime_suspended(&bp->pdev->dev))) {
- netdev_err(ndev, "Device is in runtime suspend\n");
- return -EOPNOTSUPP;
- }
-
switch (taprio->cmd) {
case TAPRIO_CMD_REPLACE:
err = macb_taprio_setup_replace(ndev, taprio);
@@ -4528,9 +4518,22 @@ static int macb_setup_taprio(struct net_device *ndev,
static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
+ struct macb *bp;
+
if (!dev || !type_data)
return -EINVAL;
+ bp = netdev_priv(dev);
+
+ if (unlikely(!(dev->hw_features & NETIF_F_HW_TC)))
+ return -EOPNOTSUPP;
+
+ /* Check if Device is in runtime suspend */
+ if (unlikely(pm_runtime_suspended(&bp->pdev->dev))) {
+ netdev_err(dev, "Device is in runtime suspend\n");
+ return -EOPNOTSUPP;
+ }
+
switch (type) {
case TC_SETUP_QDISC_TAPRIO:
return macb_setup_taprio(dev, type_data);
--
2.44.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next 3/4] net: macb: Add MQPRIO qdisc hardware offload support
2026-08-07 9:50 [PATCH net-next 0/4] net: macb: Add TSN MQPRIO and CBS traffic-class offload Vineeth Karumanchi
2026-08-07 9:50 ` [PATCH net-next 1/4] net: macb: Rename MACB_CAPS_QBV to MACB_CAPS_TC Vineeth Karumanchi
2026-08-07 9:50 ` [PATCH net-next 2/4] net: macb: Move TC capability and PM checks to macb_setup_tc() Vineeth Karumanchi
@ 2026-08-07 9:50 ` Vineeth Karumanchi
2026-08-07 9:50 ` [PATCH net-next 4/4] net: macb: Add TSN CBS TC " Vineeth Karumanchi
3 siblings, 0 replies; 8+ messages in thread
From: Vineeth Karumanchi @ 2026-08-07 9:50 UTC (permalink / raw)
To: theo.lebrun, conor.dooley, andrew+netdev, davem, edumazet, kuba,
pabeni
Cc: vineeth.karumanchi, git, netdev, linux-kernel
Add support for TC_SETUP_QDISC_MQPRIO hardware offload, allowing
traffic class to queue mapping via the mqprio qdisc.
Implement macb_setup_mqprio() which configures TC-to-queue mappings
through netdev_set_num_tc() and netdev_set_tc_queue(), and resets
them when num_tc is zero. The driver advertises TC_MQPRIO_HW_OFFLOAD_TCS
offload level.
Add macb_tc_query_caps() to report mqprio capabilities. Setting
validate_queue_counts to true delegates queue count and overlap
validation to the mqprio core via mqprio_validate_queue_counts(),
avoiding redundant checks in the driver.
Signed-off-by: Vineeth Karumanchi <vineeth.karumanchi@amd.com>
---
drivers/net/ethernet/cadence/macb_main.c | 59 ++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 508d952e2ae7..00355cc4b434 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4515,6 +4515,60 @@ static int macb_setup_taprio(struct net_device *ndev,
return err;
}
+static int macb_setup_mqprio(struct net_device *ndev,
+ struct tc_mqprio_qopt_offload *mqprio)
+{
+ struct tc_mqprio_qopt *qopt = &mqprio->qopt;
+ u8 num_tc = qopt->num_tc;
+ int err;
+ u8 i;
+
+ /* Handle reset case early */
+ if (!num_tc) {
+ netdev_reset_tc(ndev);
+ return 0;
+ }
+
+ /* Configure traffic classes */
+ qopt->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+ err = netdev_set_num_tc(ndev, num_tc);
+ if (err)
+ return err;
+
+ for (i = 0; i < num_tc; i++) {
+ err = netdev_set_tc_queue(ndev, i, qopt->count[i],
+ qopt->offset[i]);
+ if (err)
+ goto err_reset_tc;
+
+ netdev_dbg(ndev, "MQPRIO: TC%d -> queue %u (count=%u)\n",
+ i, qopt->offset[i], qopt->count[i]);
+ }
+
+ return 0;
+
+err_reset_tc:
+ netdev_reset_tc(ndev);
+ return err;
+}
+
+static int macb_tc_query_caps(struct net_device *dev,
+ struct tc_query_caps_base *base)
+{
+ switch (base->type) {
+ case TC_SETUP_QDISC_MQPRIO: {
+ struct tc_mqprio_caps *caps = base->caps;
+
+ caps->validate_queue_counts = true;
+
+ return 0;
+ }
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
@@ -4523,6 +4577,9 @@ static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
if (!dev || !type_data)
return -EINVAL;
+ if (type == TC_QUERY_CAPS)
+ return macb_tc_query_caps(dev, type_data);
+
bp = netdev_priv(dev);
if (unlikely(!(dev->hw_features & NETIF_F_HW_TC)))
@@ -4535,6 +4592,8 @@ static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
}
switch (type) {
+ case TC_SETUP_QDISC_MQPRIO:
+ return macb_setup_mqprio(dev, type_data);
case TC_SETUP_QDISC_TAPRIO:
return macb_setup_taprio(dev, type_data);
default:
--
2.44.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next 4/4] net: macb: Add TSN CBS TC offload support
2026-08-07 9:50 [PATCH net-next 0/4] net: macb: Add TSN MQPRIO and CBS traffic-class offload Vineeth Karumanchi
` (2 preceding siblings ...)
2026-08-07 9:50 ` [PATCH net-next 3/4] net: macb: Add MQPRIO qdisc hardware offload support Vineeth Karumanchi
@ 2026-08-07 9:50 ` Vineeth Karumanchi
2026-08-07 17:32 ` Conor Dooley
3 siblings, 1 reply; 8+ messages in thread
From: Vineeth Karumanchi @ 2026-08-07 9:50 UTC (permalink / raw)
To: theo.lebrun, conor.dooley, andrew+netdev, davem, edumazet, kuba,
pabeni
Cc: vineeth.karumanchi, git, netdev, linux-kernel
Add Credit-Based Shaper (CBS/IEEE 802.1Qav) TC offload support for
time-sensitive networking on GEM hardware. CBS is restricted to the
two highest-priority queues: Queue A (num_queues - 1) and Queue B
(num_queues - 2), matching hardware capability.
The idle slope register value is computed differently based on hardware
variant: high-speed GEM scales idleslope linearly to the full 32-bit
register range relative to link speed, while standard GEM multiplies
by a port rate factor derived from the interface width (125 for 1G
GMII, 250 for 10/100M MII).
Validate that idleslope is positive and does not exceed the link
speed, preventing negative values from bypassing the bounds check
due to signed-to-unsigned promotion.
Signed-off-by: Vineeth Karumanchi <vineeth.karumanchi@amd.com>
---
drivers/net/ethernet/cadence/macb.h | 9 ++
drivers/net/ethernet/cadence/macb_main.c | 121 +++++++++++++++++++++++
2 files changed, 130 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index f24df25923d7..d5b28459fd75 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -184,6 +184,9 @@
#define GEM_DCFG8 0x029C /* Design Config 8 */
#define GEM_DCFG10 0x02A4 /* Design Config 10 */
#define GEM_DCFG12 0x02AC /* Design Config 12 */
+#define GEM_CBS_CONTROL 0x04BC /* CBS Control Register */
+#define GEM_CBS_IDLESLOPE_Q_A 0x04C0 /* CBS IdleSlope Queue A */
+#define GEM_CBS_IDLESLOPE_Q_B 0x04C4 /* CBS IdleSlope Queue B */
#define GEM_ENST_CONTROL 0x0880 /* ENST control register */
#define GEM_USX_CONTROL 0x0A80 /* High speed PCS control register */
#define GEM_USX_STATUS 0x0A88 /* High speed PCS status register */
@@ -224,6 +227,12 @@
#define GEM_ENST_ON_TIME(hw_q) (0x0820 + ((hw_q) << 2))
#define GEM_ENST_OFF_TIME(hw_q) (0x0840 + ((hw_q) << 2))
+/* Bitfields in CBS_CONTROL */
+#define GEM_CBS_ENABLE_QUEUE_A_OFFSET 0
+#define GEM_CBS_ENABLE_QUEUE_A_SIZE 1
+#define GEM_CBS_ENABLE_QUEUE_B_OFFSET 1
+#define GEM_CBS_ENABLE_QUEUE_B_SIZE 1
+
/* Bitfields in ENST_CONTROL */
#define GEM_ENST_DISABLE_QUEUE_OFFSET 16
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 00355cc4b434..a0a68490519e 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -99,6 +99,10 @@ struct sifive_fu540_macb_mgmt {
#define MACB_MDIO_TIMEOUT 1000000 /* in usecs */
+/* CBS port transmit rate factors: 1000/interface_width */
+#define MACB_CBS_PORT_RATE_1G 125 /* 1000/8 for GMII (8-bit) */
+#define MACB_CBS_PORT_RATE_10_100M 250 /* 1000/4 for MII (4-bit) */
+
/* DMA buffer descriptor might be different size
* depends on hardware configuration:
*
@@ -4515,6 +4519,121 @@ static int macb_setup_taprio(struct net_device *ndev,
return err;
}
+static int macb_cbs_get_queue_params(struct macb *bp, u8 queue_num,
+ u32 *enable_bit, bool *is_queue_a)
+{
+ /* Queue A is highest priority (num_queues - 1) */
+ if (queue_num == bp->num_queues - 1) {
+ *enable_bit = GEM_BIT(CBS_ENABLE_QUEUE_A);
+ *is_queue_a = true;
+ return 0;
+ }
+
+ /* Queue B is second highest priority (num_queues - 2) */
+ if (queue_num == bp->num_queues - 2) {
+ *enable_bit = GEM_BIT(CBS_ENABLE_QUEUE_B);
+ *is_queue_a = false;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int macb_cbs_add(struct net_device *ndev,
+ struct tc_cbs_qopt_offload *qopt)
+{
+ u32 enable_bit, idleslope, speed_kbps, ctrl;
+ struct macb *bp = netdev_priv(ndev);
+ struct ethtool_link_ksettings kset;
+ bool is_queue_a;
+ int err;
+
+ err = macb_cbs_get_queue_params(bp, qopt->queue, &enable_bit, &is_queue_a);
+ if (err) {
+ netdev_err(ndev, "CBS: Queue %d not eligible (only top 2 queues support CBS)\n",
+ qopt->queue);
+ return -EINVAL;
+ }
+
+ /* idleslope is calibrated for the current link speed; CBS is not
+ * reprogrammed on link-speed changes, so it must be reconfigured
+ * if the link speed changes.
+ */
+ phylink_ethtool_ksettings_get(bp->phylink, &kset);
+
+ if (!kset.base.speed || kset.base.speed == SPEED_UNKNOWN) {
+ netdev_err(ndev, "CBS: Invalid link speed\n");
+ return -EINVAL;
+ }
+
+ speed_kbps = kset.base.speed * 1000;
+
+ if (qopt->idleslope <= 0 || (u32)qopt->idleslope > speed_kbps) {
+ netdev_err(ndev, "CBS: invalid idleslope %d (must be 1..%u kbps)\n",
+ qopt->idleslope, speed_kbps);
+ return -EINVAL;
+ }
+
+ /* Calculate idleslope for hardware register:
+ * - High-speed GEM: scale to full 32-bit register range
+ * - Standard MACB: multiply by port transmit rate factor
+ */
+ if (bp->caps & MACB_CAPS_HIGH_SPEED)
+ idleslope = DIV_ROUND_UP_ULL((u64)qopt->idleslope * U32_MAX, speed_kbps);
+ else
+ idleslope = (u32)qopt->idleslope * (kset.base.speed >= 1000 ?
+ MACB_CBS_PORT_RATE_1G : MACB_CBS_PORT_RATE_10_100M);
+
+ scoped_guard(spinlock_irqsave, &bp->lock) {
+ /* Disable CBS for the queue before updating idleslope */
+ ctrl = gem_readl(bp, CBS_CONTROL) & ~enable_bit;
+ gem_writel(bp, CBS_CONTROL, ctrl);
+ /* Update idleslope for the queue */
+ if (is_queue_a)
+ gem_writel(bp, CBS_IDLESLOPE_Q_A, idleslope);
+ else
+ gem_writel(bp, CBS_IDLESLOPE_Q_B, idleslope);
+
+ /* Re-enable CBS for the queue with new idleslope */
+ gem_writel(bp, CBS_CONTROL, ctrl | enable_bit);
+ }
+
+ netdev_dbg(ndev, "CBS: Configured queue %d with idleslope 0x%x\n",
+ qopt->queue, idleslope);
+
+ return 0;
+}
+
+static void macb_cbs_destroy(struct net_device *ndev, u8 queue_num)
+{
+ struct macb *bp = netdev_priv(ndev);
+ bool is_queue_a;
+ u32 enable_bit;
+
+ if (macb_cbs_get_queue_params(bp, queue_num, &enable_bit, &is_queue_a))
+ return;
+
+ scoped_guard(spinlock_irqsave, &bp->lock) {
+ gem_writel(bp, CBS_CONTROL, gem_readl(bp, CBS_CONTROL) & ~enable_bit);
+ if (is_queue_a)
+ gem_writel(bp, CBS_IDLESLOPE_Q_A, 0);
+ else
+ gem_writel(bp, CBS_IDLESLOPE_Q_B, 0);
+ }
+
+ netdev_dbg(ndev, "CBS: Disabled queue %d\n", queue_num);
+}
+
+static int macb_setup_cbs(struct net_device *ndev,
+ struct tc_cbs_qopt_offload *qopt)
+{
+ if (qopt->enable)
+ return macb_cbs_add(ndev, qopt);
+
+ macb_cbs_destroy(ndev, qopt->queue);
+ return 0;
+}
+
static int macb_setup_mqprio(struct net_device *ndev,
struct tc_mqprio_qopt_offload *mqprio)
{
@@ -4594,6 +4713,8 @@ static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
switch (type) {
case TC_SETUP_QDISC_MQPRIO:
return macb_setup_mqprio(dev, type_data);
+ case TC_SETUP_QDISC_CBS:
+ return macb_setup_cbs(dev, type_data);
case TC_SETUP_QDISC_TAPRIO:
return macb_setup_taprio(dev, type_data);
default:
--
2.44.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 1/4] net: macb: Rename MACB_CAPS_QBV to MACB_CAPS_TC
2026-08-07 9:50 ` [PATCH net-next 1/4] net: macb: Rename MACB_CAPS_QBV to MACB_CAPS_TC Vineeth Karumanchi
@ 2026-08-07 17:09 ` Conor Dooley
2026-08-07 18:26 ` Théo Lebrun
0 siblings, 1 reply; 8+ messages in thread
From: Conor Dooley @ 2026-08-07 17:09 UTC (permalink / raw)
To: Vineeth Karumanchi
Cc: theo.lebrun, conor.dooley, andrew+netdev, davem, edumazet, kuba,
pabeni, git, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2892 bytes --]
On Fri, Aug 07, 2026 at 03:20:09PM +0530, Vineeth Karumanchi wrote:
> The MACB_CAPS_QBV capability flag was originally introduced to
> gate TAPRIO/QBV support. However, GEM IP versions that support
> QBV also implement multiple TSN clauses.
>
> Replace this with a generic capability flag that can be reused
> by other TSN features. Rename MACB_CAPS_QBV to MACB_CAPS_TC to
> better reflect its role as a general traffic-class offload capability.
I'm not convinced that this is broadly correct, whether or not there's
Qav support (which is what you're using the newly renamed flag for)
depends on an IP configuration time define that I think is independent
of whether or not there's Qbv support (gem_exclude_cbs).
That said, the only platform that supports Qbv that I have the exact
documentation for does not disable the CBS bits.
Cheers,
Conor.
>
> The supported TSN clauses are handled through macb_setup_tc().
>
> Signed-off-by: Vineeth Karumanchi <vineeth.karumanchi@amd.com>
> ---
> drivers/net/ethernet/cadence/macb.h | 2 +-
> drivers/net/ethernet/cadence/macb_main.c | 6 +++---
> 2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
> index a11052565436..f24df25923d7 100644
> --- a/drivers/net/ethernet/cadence/macb.h
> +++ b/drivers/net/ethernet/cadence/macb.h
> @@ -768,7 +768,7 @@
> #define MACB_CAPS_MIIONRGMII BIT(9)
> #define MACB_CAPS_NEED_TSUCLK BIT(10)
> #define MACB_CAPS_QUEUE_DISABLE BIT(11)
> -#define MACB_CAPS_QBV BIT(12)
> +#define MACB_CAPS_TC BIT(12)
> #define MACB_CAPS_PCS BIT(13)
> #define MACB_CAPS_HIGH_SPEED BIT(14)
> #define MACB_CAPS_CLK_HW_CHG BIT(15)
> diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> index d394f1f43b68..29c93df1444c 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
> @@ -4846,8 +4846,8 @@ static int macb_init_dflt(struct platform_device *pdev)
> dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
> if (bp->caps & MACB_CAPS_SG_DISABLED)
> dev->hw_features &= ~NETIF_F_SG;
> - /* Enable HW_TC if hardware supports QBV */
> - if (bp->caps & MACB_CAPS_QBV)
> + /* Enable TC offload for TSN-capable hardware */
> + if (bp->caps & MACB_CAPS_TC)
> dev->hw_features |= NETIF_F_HW_TC;
>
> dev->features = dev->hw_features;
> @@ -5678,7 +5678,7 @@ static const struct macb_config versal_config = {
> .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO |
> MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_BD_RD_PREFETCH |
> MACB_CAPS_NEED_TSUCLK | MACB_CAPS_QUEUE_DISABLE |
> - MACB_CAPS_QBV |
> + MACB_CAPS_TC |
> MACB_CAPS_USRIO_HAS_MII,
> .dma_burst_length = 16,
> .init = init_reset_optional,
> --
> 2.44.4
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 4/4] net: macb: Add TSN CBS TC offload support
2026-08-07 9:50 ` [PATCH net-next 4/4] net: macb: Add TSN CBS TC " Vineeth Karumanchi
@ 2026-08-07 17:32 ` Conor Dooley
0 siblings, 0 replies; 8+ messages in thread
From: Conor Dooley @ 2026-08-07 17:32 UTC (permalink / raw)
To: Vineeth Karumanchi
Cc: theo.lebrun, conor.dooley, andrew+netdev, davem, edumazet, kuba,
pabeni, git, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 4622 bytes --]
On Fri, Aug 07, 2026 at 03:20:12PM +0530, Vineeth Karumanchi wrote:
> +static int macb_cbs_get_queue_params(struct macb *bp, u8 queue_num,
> + u32 *enable_bit, bool *is_queue_a)
> +{
> + /* Queue A is highest priority (num_queues - 1) */
> + if (queue_num == bp->num_queues - 1) {
> + *enable_bit = GEM_BIT(CBS_ENABLE_QUEUE_A);
> + *is_queue_a = true;
> + return 0;
> + }
> +
> + /* Queue B is second highest priority (num_queues - 2) */
> + if (queue_num == bp->num_queues - 2) {
> + *enable_bit = GEM_BIT(CBS_ENABLE_QUEUE_B);
What's the point of making enable_bit a parameter if everything you do
using it bounds a conditional section gated on is_queue_a?
> + *is_queue_a = false;
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static int macb_cbs_add(struct net_device *ndev,
> + struct tc_cbs_qopt_offload *qopt)
> +{
> + u32 enable_bit, idleslope, speed_kbps, ctrl;
> + struct macb *bp = netdev_priv(ndev);
> + struct ethtool_link_ksettings kset;
> + bool is_queue_a;
> + int err;
> +
> + err = macb_cbs_get_queue_params(bp, qopt->queue, &enable_bit, &is_queue_a);
> + if (err) {
> + netdev_err(ndev, "CBS: Queue %d not eligible (only top 2 queues support CBS)\n",
> + qopt->queue);
> + return -EINVAL;
> + }
> +
> + /* idleslope is calibrated for the current link speed; CBS is not
> + * reprogrammed on link-speed changes, so it must be reconfigured
> + * if the link speed changes.
> + */
> + phylink_ethtool_ksettings_get(bp->phylink, &kset);
> +
> + if (!kset.base.speed || kset.base.speed == SPEED_UNKNOWN) {
> + netdev_err(ndev, "CBS: Invalid link speed\n");
> + return -EINVAL;
> + }
> +
> + speed_kbps = kset.base.speed * 1000;
> +
> + if (qopt->idleslope <= 0 || (u32)qopt->idleslope > speed_kbps) {
> + netdev_err(ndev, "CBS: invalid idleslope %d (must be 1..%u kbps)\n",
> + qopt->idleslope, speed_kbps);
> + return -EINVAL;
> + }
> +
> + /* Calculate idleslope for hardware register:
> + * - High-speed GEM: scale to full 32-bit register range
> + * - Standard MACB: multiply by port transmit rate factor
I think this comment should probably mention that the register expects
bytes/sec in 1G mode and nibbles/sec in 10/100.
This generally looks sane to my naive eyes otherwise.
Thanks,
Conor.
> + */
> + if (bp->caps & MACB_CAPS_HIGH_SPEED)
> + idleslope = DIV_ROUND_UP_ULL((u64)qopt->idleslope * U32_MAX, speed_kbps);
> + else
> + idleslope = (u32)qopt->idleslope * (kset.base.speed >= 1000 ?
> + MACB_CBS_PORT_RATE_1G : MACB_CBS_PORT_RATE_10_100M);
> +
> + scoped_guard(spinlock_irqsave, &bp->lock) {
> + /* Disable CBS for the queue before updating idleslope */
> + ctrl = gem_readl(bp, CBS_CONTROL) & ~enable_bit;
> + gem_writel(bp, CBS_CONTROL, ctrl);
> + /* Update idleslope for the queue */
> + if (is_queue_a)
> + gem_writel(bp, CBS_IDLESLOPE_Q_A, idleslope);
> + else
> + gem_writel(bp, CBS_IDLESLOPE_Q_B, idleslope);
> +
> + /* Re-enable CBS for the queue with new idleslope */
> + gem_writel(bp, CBS_CONTROL, ctrl | enable_bit);
> + }
> +
> + netdev_dbg(ndev, "CBS: Configured queue %d with idleslope 0x%x\n",
> + qopt->queue, idleslope);
> +
> + return 0;
> +}
> +
> +static void macb_cbs_destroy(struct net_device *ndev, u8 queue_num)
> +{
> + struct macb *bp = netdev_priv(ndev);
> + bool is_queue_a;
> + u32 enable_bit;
> +
> + if (macb_cbs_get_queue_params(bp, queue_num, &enable_bit, &is_queue_a))
> + return;
> +
> + scoped_guard(spinlock_irqsave, &bp->lock) {
> + gem_writel(bp, CBS_CONTROL, gem_readl(bp, CBS_CONTROL) & ~enable_bit);
> + if (is_queue_a)
> + gem_writel(bp, CBS_IDLESLOPE_Q_A, 0);
> + else
> + gem_writel(bp, CBS_IDLESLOPE_Q_B, 0);
> + }
> +
> + netdev_dbg(ndev, "CBS: Disabled queue %d\n", queue_num);
> +}
> +
> +static int macb_setup_cbs(struct net_device *ndev,
> + struct tc_cbs_qopt_offload *qopt)
> +{
> + if (qopt->enable)
> + return macb_cbs_add(ndev, qopt);
> +
> + macb_cbs_destroy(ndev, qopt->queue);
> + return 0;
> +}
> +
> static int macb_setup_mqprio(struct net_device *ndev,
> struct tc_mqprio_qopt_offload *mqprio)
> {
> @@ -4594,6 +4713,8 @@ static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
> switch (type) {
> case TC_SETUP_QDISC_MQPRIO:
> return macb_setup_mqprio(dev, type_data);
> + case TC_SETUP_QDISC_CBS:
> + return macb_setup_cbs(dev, type_data);
> case TC_SETUP_QDISC_TAPRIO:
> return macb_setup_taprio(dev, type_data);
> default:
> --
> 2.44.4
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 1/4] net: macb: Rename MACB_CAPS_QBV to MACB_CAPS_TC
2026-08-07 17:09 ` Conor Dooley
@ 2026-08-07 18:26 ` Théo Lebrun
0 siblings, 0 replies; 8+ messages in thread
From: Théo Lebrun @ 2026-08-07 18:26 UTC (permalink / raw)
To: Conor Dooley, Vineeth Karumanchi
Cc: conor.dooley, andrew+netdev, davem, edumazet, kuba, pabeni, git,
netdev, linux-kernel
Hello Vineeth & Conor,
On Fri Aug 7, 2026 at 7:09 PM CEST, Conor Dooley wrote:
> On Fri, Aug 07, 2026 at 03:20:09PM +0530, Vineeth Karumanchi wrote:
>> The MACB_CAPS_QBV capability flag was originally introduced to
>> gate TAPRIO/QBV support. However, GEM IP versions that support
>> QBV also implement multiple TSN clauses.
>>
>> Replace this with a generic capability flag that can be reused
>> by other TSN features. Rename MACB_CAPS_QBV to MACB_CAPS_TC to
>> better reflect its role as a general traffic-class offload capability.
>
> I'm not convinced that this is broadly correct, whether or not there's
> Qav support (which is what you're using the newly renamed flag for)
> depends on an IP configuration time define that I think is independent
> of whether or not there's Qbv support (gem_exclude_cbs).
>
> That said, the only platform that supports Qbv that I have the exact
> documentation for does not disable the CBS bits.
EyeQ5 instances have both active qbv and cbs as well.
I see two ways forward:
- MACB_CAPS_TC aggregating the two, coming from match data
- split and use runtime-detection, see DCFG1/0x0280 bits 1 and 24
What I like with 1 is that when reading code it's easy to see what
platform can use what features.
What I like with 2 is that it's less churn overall: no modification of
match data once support is merged.
I guess let's go with 2?
(I'll review the rest of the series later on.)
Thanks,
--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-07 18:26 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-07 9:50 [PATCH net-next 0/4] net: macb: Add TSN MQPRIO and CBS traffic-class offload Vineeth Karumanchi
2026-08-07 9:50 ` [PATCH net-next 1/4] net: macb: Rename MACB_CAPS_QBV to MACB_CAPS_TC Vineeth Karumanchi
2026-08-07 17:09 ` Conor Dooley
2026-08-07 18:26 ` Théo Lebrun
2026-08-07 9:50 ` [PATCH net-next 2/4] net: macb: Move TC capability and PM checks to macb_setup_tc() Vineeth Karumanchi
2026-08-07 9:50 ` [PATCH net-next 3/4] net: macb: Add MQPRIO qdisc hardware offload support Vineeth Karumanchi
2026-08-07 9:50 ` [PATCH net-next 4/4] net: macb: Add TSN CBS TC " Vineeth Karumanchi
2026-08-07 17:32 ` Conor Dooley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox