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 - 2026 Red Hat, Inc.