Add Traffic Control offload infrastructure with command routing for
TAPRIO qdisc operations:
- macb_setup_taprio(): TAPRIO command dispatcher
- macb_setup_tc(): TC_SETUP_QDISC_TAPRIO entry point
- Support for REPLACE/DESTROY command mapping
Provides standardized TC interface for time-gated scheduling control.
Signed-off-by: Vineeth Karumanchi <vineeth.karumanchi@amd.com>
---
drivers/net/ethernet/cadence/macb_main.c | 33 ++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 6b3eff28a842..cc33491930e3 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4267,6 +4267,38 @@ static void macb_taprio_destroy(struct net_device *ndev)
spin_unlock_irqrestore(&bp->lock, flags);
}
+static int macb_setup_taprio(struct net_device *ndev,
+ struct tc_taprio_qopt_offload *taprio)
+{
+ int err = 0;
+
+ switch (taprio->cmd) {
+ case TAPRIO_CMD_REPLACE:
+ err = macb_taprio_setup_replace(ndev, taprio);
+ break;
+ case TAPRIO_CMD_DESTROY:
+ macb_taprio_destroy(ndev);
+ break;
+ default:
+ err = -EOPNOTSUPP;
+ }
+
+ return err;
+}
+
+static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
+{
+ if (!dev || !type_data)
+ return -EINVAL;
+
+ switch (type) {
+ case TC_SETUP_QDISC_TAPRIO:
+ return macb_setup_taprio(dev, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static const struct net_device_ops macb_netdev_ops = {
.ndo_open = macb_open,
.ndo_stop = macb_close,
@@ -4284,6 +4316,7 @@ static const struct net_device_ops macb_netdev_ops = {
.ndo_features_check = macb_features_check,
.ndo_hwtstamp_set = macb_hwtstamp_set,
.ndo_hwtstamp_get = macb_hwtstamp_get,
+ .ndo_setup_tc = macb_setup_tc,
};
/* Configure peripheral capabilities according to device tree
--
2.34.1
Hi Vineeth, kernel test robot noticed the following build errors: [auto build test ERROR on net-next/main] url: https://github.com/intel-lab-lkp/linux/commits/Vineeth-Karumanchi/net-macb-Define-ENST-hardware-registers-for-time-aware-scheduling/20250722-234618 base: net-next/main patch link: https://lore.kernel.org/r/20250722154111.1871292-6-vineeth.karumanchi%40amd.com patch subject: [PATCH net-next 5/6] net: macb: Implement TAPRIO TC offload command interface config: i386-randconfig-005-20250728 (https://download.01.org/0day-ci/archive/20250729/202507290045.ckQlBy8r-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250729/202507290045.ckQlBy8r-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202507290045.ckQlBy8r-lkp@intel.com/ All errors (new ones prefixed by >>, old ones prefixed by <<): >> ERROR: modpost: "__umoddi3" [drivers/net/ethernet/cadence/macb.ko] undefined! >> ERROR: modpost: "__udivdi3" [drivers/net/ethernet/cadence/macb.ko] undefined! -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
On 7/22/25 18:41, Vineeth Karumanchi wrote: > Add Traffic Control offload infrastructure with command routing for > TAPRIO qdisc operations: > > - macb_setup_taprio(): TAPRIO command dispatcher > - macb_setup_tc(): TC_SETUP_QDISC_TAPRIO entry point > - Support for REPLACE/DESTROY command mapping > > Provides standardized TC interface for time-gated scheduling control. > > Signed-off-by: Vineeth Karumanchi <vineeth.karumanchi@amd.com> > --- > drivers/net/ethernet/cadence/macb_main.c | 33 ++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) > > diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c > index 6b3eff28a842..cc33491930e3 100644 > --- a/drivers/net/ethernet/cadence/macb_main.c > +++ b/drivers/net/ethernet/cadence/macb_main.c > @@ -4267,6 +4267,38 @@ static void macb_taprio_destroy(struct net_device *ndev) > spin_unlock_irqrestore(&bp->lock, flags); > } > > +static int macb_setup_taprio(struct net_device *ndev, > + struct tc_taprio_qopt_offload *taprio) > +{ > + int err = 0; > + > + switch (taprio->cmd) { > + case TAPRIO_CMD_REPLACE: > + err = macb_taprio_setup_replace(ndev, taprio); > + break; > + case TAPRIO_CMD_DESTROY: > + macb_taprio_destroy(ndev); macb_taprio_setup_replace() along with macb_taprio_destroy() touch HW registers. Could macb_setup_taprio() be called when the interface is runtime suspended? > + break; > + default: > + err = -EOPNOTSUPP; > + } > + > + return err; > +} > + > +static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) > +{ > + if (!dev || !type_data) > + return -EINVAL; > + > + switch (type) { > + case TC_SETUP_QDISC_TAPRIO: > + return macb_setup_taprio(dev, type_data); Same here. > + default: > + return -EOPNOTSUPP; > + } > +} > + > static const struct net_device_ops macb_netdev_ops = { > .ndo_open = macb_open, > .ndo_stop = macb_close, > @@ -4284,6 +4316,7 @@ static const struct net_device_ops macb_netdev_ops = { > .ndo_features_check = macb_features_check, > .ndo_hwtstamp_set = macb_hwtstamp_set, > .ndo_hwtstamp_get = macb_hwtstamp_get, > + .ndo_setup_tc = macb_setup_tc, This patch (or parts of it) should be merged with the previous ones. Otherwise you introduce patches with code that is unused. Thank you, Claudiu > }; > > /* Configure peripheral capabilities according to device tree
Hi Claudiu, On 7/26/2025 5:59 PM, claudiu beznea (tuxon) wrote: <...> >> + int err = 0; >> + >> + switch (taprio->cmd) { >> + case TAPRIO_CMD_REPLACE: >> + err = macb_taprio_setup_replace(ndev, taprio); >> + break; >> + case TAPRIO_CMD_DESTROY: >> + macb_taprio_destroy(ndev); > > macb_taprio_setup_replace() along with macb_taprio_destroy() touch HW > registers. Could macb_setup_taprio() be called when the interface is > runtime suspended? > > Nice catch! I will leverage pm_runtime_suspended(&pdev->dev) check before configuring. >> + break; >> + default: >> + err = -EOPNOTSUPP; >> + } >> + >> + return err; >> +} >> + >> +static int macb_setup_tc(struct net_device *dev, enum tc_setup_type >> type, void *type_data) >> +{ >> + if (!dev || !type_data) >> + return -EINVAL; >> + >> + switch (type) { >> + case TC_SETUP_QDISC_TAPRIO: >> + return macb_setup_taprio(dev, type_data); > > Same here. > >> + default: >> + return -EOPNOTSUPP; >> + } >> +} >> + >> static const struct net_device_ops macb_netdev_ops = { >> .ndo_open = macb_open, >> .ndo_stop = macb_close, >> @@ -4284,6 +4316,7 @@ static const struct net_device_ops >> macb_netdev_ops = { >> .ndo_features_check = macb_features_check, >> .ndo_hwtstamp_set = macb_hwtstamp_set, >> .ndo_hwtstamp_get = macb_hwtstamp_get, >> + .ndo_setup_tc = macb_setup_tc, > > This patch (or parts of it) should be merged with the previous ones. > Otherwise you introduce patches with code that is unused. > Clubbing all comments on patch organization: I see that patch series gets merged into 2 set only. 1/6 + 2/6 + 3/6 + 4/6 + 5/6 ==> 1/2 6/6 ==> 2/2 Please let me know your thoughts or suggestions. Thanks -- 🙏 vineeth
On 29.07.2025 12:38, Karumanchi, Vineeth wrote: > Hi Claudiu, > > > On 7/26/2025 5:59 PM, claudiu beznea (tuxon) wrote: > <...> >>> + int err = 0; >>> + >>> + switch (taprio->cmd) { >>> + case TAPRIO_CMD_REPLACE: >>> + err = macb_taprio_setup_replace(ndev, taprio); >>> + break; >>> + case TAPRIO_CMD_DESTROY: >>> + macb_taprio_destroy(ndev); >> >> macb_taprio_setup_replace() along with macb_taprio_destroy() touch HW >> registers. Could macb_setup_taprio() be called when the interface is >> runtime suspended? >> >> > > Nice catch! > > I will leverage pm_runtime_suspended(&pdev->dev) check before configuring. > >>> + break; >>> + default: >>> + err = -EOPNOTSUPP; >>> + } >>> + >>> + return err; >>> +} >>> + >>> +static int macb_setup_tc(struct net_device *dev, enum tc_setup_type >>> type, void *type_data) >>> +{ >>> + if (!dev || !type_data) >>> + return -EINVAL; >>> + >>> + switch (type) { >>> + case TC_SETUP_QDISC_TAPRIO: >>> + return macb_setup_taprio(dev, type_data); >> >> Same here. >> >>> + default: >>> + return -EOPNOTSUPP; >>> + } >>> +} >>> + >>> static const struct net_device_ops macb_netdev_ops = { >>> .ndo_open = macb_open, >>> .ndo_stop = macb_close, >>> @@ -4284,6 +4316,7 @@ static const struct net_device_ops macb_netdev_ops >>> = { >>> .ndo_features_check = macb_features_check, >>> .ndo_hwtstamp_set = macb_hwtstamp_set, >>> .ndo_hwtstamp_get = macb_hwtstamp_get, >>> + .ndo_setup_tc = macb_setup_tc, >> >> This patch (or parts of it) should be merged with the previous ones. >> Otherwise you introduce patches with code that is unused. >> > > Clubbing all comments on patch organization: > I see that patch series gets merged into 2 set only. > > 1/6 + 2/6 + 3/6 + 4/6 + 5/6 ==> 1/2 > 6/6 ==> 2/2 That should be good. Thank you, Claudiu > > Please let me know your thoughts or suggestions. > > > Thanks
© 2016 - 2025 Red Hat, Inc.