net: microchip: sparx5: add support for offloading mqprio qdisc
authorDaniel Machon <daniel.machon@microchip.com>
Tue, 20 Sep 2022 10:14:29 +0000 (12:14 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 23 Sep 2022 08:53:10 +0000 (09:53 +0100)
Add support for offloading mqprio qdisc to sparx5 switch.

The offloaded mqprio qdisc currently does nothing by itself, but serves
as an attachment point for other qdiscs (tbf, ets etc.)

Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/microchip/sparx5/Makefile
drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
drivers/net/ethernet/microchip/sparx5/sparx5_qos.c [new file with mode: 0644]
drivers/net/ethernet/microchip/sparx5/sparx5_qos.h [new file with mode: 0644]
drivers/net/ethernet/microchip/sparx5/sparx5_tc.c

index 1d21d8ef891ac6346277416c27115f3ba934b9e2..d1c6ad96674789b21ac2bbb388f2294bbc532508 100644 (file)
@@ -8,4 +8,4 @@ obj-$(CONFIG_SPARX5_SWITCH) += sparx5-switch.o
 sparx5-switch-objs  := sparx5_main.o sparx5_packet.o \
  sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o \
  sparx5_switchdev.o sparx5_calendar.o sparx5_ethtool.o sparx5_fdma.o \
- sparx5_ptp.o sparx5_pgid.o sparx5_tc.o
+ sparx5_ptp.o sparx5_pgid.o sparx5_tc.o sparx5_qos.o
index c1a357f45a066df86018b75b98ce4f1d42939f58..19516ccad5338c511c8e2ea132cb55681034a468 100644 (file)
@@ -242,10 +242,14 @@ struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno)
        struct sparx5_port *spx5_port;
        struct net_device *ndev;
 
-       ndev = devm_alloc_etherdev(sparx5->dev, sizeof(struct sparx5_port));
+       ndev = devm_alloc_etherdev_mqs(sparx5->dev, sizeof(struct sparx5_port),
+                                      SPX5_PRIOS, 1);
        if (!ndev)
                return ERR_PTR(-ENOMEM);
 
+       ndev->hw_features |= NETIF_F_HW_TC;
+       ndev->features |= NETIF_F_HW_TC;
+
        SET_NETDEV_DEV(ndev, sparx5->dev);
        spx5_port = netdev_priv(ndev);
        spx5_port->ndev = ndev;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c
new file mode 100644 (file)
index 0000000..3c6d672
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Microchip Sparx5 Switch driver
+ *
+ * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
+ */
+
+#include "sparx5_main.h"
+#include "sparx5_qos.h"
+
+int sparx5_tc_mqprio_add(struct net_device *ndev, u8 num_tc)
+{
+       int i;
+
+       if (num_tc != SPX5_PRIOS) {
+               netdev_err(ndev, "Only %d traffic classes supported\n",
+                          SPX5_PRIOS);
+               return -EINVAL;
+       }
+
+       netdev_set_num_tc(ndev, num_tc);
+
+       for (i = 0; i < num_tc; i++)
+               netdev_set_tc_queue(ndev, i, 1, i);
+
+       netdev_dbg(ndev, "dev->num_tc %u dev->real_num_tx_queues %u\n",
+                  ndev->num_tc, ndev->real_num_tx_queues);
+
+       return 0;
+}
+
+int sparx5_tc_mqprio_del(struct net_device *ndev)
+{
+       netdev_reset_tc(ndev);
+
+       netdev_dbg(ndev, "dev->num_tc %u dev->real_num_tx_queues %u\n",
+                  ndev->num_tc, ndev->real_num_tx_queues);
+
+       return 0;
+}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
new file mode 100644 (file)
index 0000000..0572fb4
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Microchip Sparx5 Switch driver
+ *
+ * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
+ */
+
+#ifndef __SPARX5_QOS_H__
+#define __SPARX5_QOS_H__
+
+#include <linux/netdevice.h>
+
+/* Multi-Queue Priority */
+int sparx5_tc_mqprio_add(struct net_device *ndev, u8 num_tc);
+int sparx5_tc_mqprio_del(struct net_device *ndev);
+
+#endif /* __SPARX5_QOS_H__ */
index 1bafca0be7951702716031b775e472e6b717bb55..6e01a7c7c8214b2500cd5d516c0e68cd0ebc9b41 100644 (file)
@@ -4,13 +4,29 @@
  * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
  */
 
+#include <net/pkt_cls.h>
+
 #include "sparx5_tc.h"
 #include "sparx5_main.h"
+#include "sparx5_qos.h"
+
+static int sparx5_tc_setup_qdisc_mqprio(struct net_device *ndev,
+                                       struct tc_mqprio_qopt_offload *m)
+{
+       m->qopt.hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+       if (m->qopt.num_tc == 0)
+               return sparx5_tc_mqprio_del(ndev);
+       else
+               return sparx5_tc_mqprio_add(ndev, m->qopt.num_tc);
+}
 
 int sparx5_port_setup_tc(struct net_device *ndev, enum tc_setup_type type,
                         void *type_data)
 {
        switch (type) {
+       case TC_SETUP_QDISC_MQPRIO:
+               return sparx5_tc_setup_qdisc_mqprio(ndev, type_data);
        default:
                return -EOPNOTSUPP;
        }