mvebu: next backport mvnet MQPrio offload
[openwrt/openwrt.git] / target / linux / mvebu / patches-5.10 / 704-net-next-ethernet-marvell-mvnetaMQPrioQueue.patch
diff --git a/target/linux/mvebu/patches-5.10/704-net-next-ethernet-marvell-mvnetaMQPrioQueue.patch b/target/linux/mvebu/patches-5.10/704-net-next-ethernet-marvell-mvnetaMQPrioQueue.patch
new file mode 100644 (file)
index 0000000..ac5fdc3
--- /dev/null
@@ -0,0 +1,102 @@
+From e9f7099d0730341b24c057acbf545dd019581db6 Mon Sep 17 00:00:00 2001
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Date: Fri, 26 Nov 2021 12:20:55 +0100
+Subject: net: mvneta: Allow having more than one queue per TC
+
+The current mqprio implementation assumed that we are only using one
+queue per TC. Use the offset and count parameters to allow using
+multiple queues per TC. In that case, the controller will use a standard
+round-robin algorithm to pick queues assigned to the same TC, with the
+same priority.
+
+This only applies to VLAN priorities in ingress traffic, each TC
+corresponding to a vlan priority.
+
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/marvell/mvneta.c | 35 ++++++++++++++++++++---------------
+ 1 file changed, 20 insertions(+), 15 deletions(-)
+
+(limited to 'drivers/net/ethernet/marvell/mvneta.c')
+
+diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
+index d3ce87e69d2a8..aba452e8abfe6 100644
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -493,7 +493,6 @@ struct mvneta_port {
+       u8 mcast_count[256];
+       u16 tx_ring_size;
+       u16 rx_ring_size;
+-      u8 prio_tc_map[8];
+       phy_interface_t phy_interface;
+       struct device_node *dn;
+@@ -4897,13 +4896,12 @@ static void mvneta_clear_rx_prio_map(struct mvneta_port *pp)
+       mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, 0);
+ }
+-static void mvneta_setup_rx_prio_map(struct mvneta_port *pp)
++static void mvneta_map_vlan_prio_to_rxq(struct mvneta_port *pp, u8 pri, u8 rxq)
+ {
+-      u32 val = 0;
+-      int i;
++      u32 val = mvreg_read(pp, MVNETA_VLAN_PRIO_TO_RXQ);
+-      for (i = 0; i < rxq_number; i++)
+-              val |= MVNETA_VLAN_PRIO_RXQ_MAP(i, pp->prio_tc_map[i]);
++      val &= ~MVNETA_VLAN_PRIO_RXQ_MAP(pri, 0x7);
++      val |= MVNETA_VLAN_PRIO_RXQ_MAP(pri, rxq);
+       mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, val);
+ }
+@@ -4912,8 +4910,8 @@ static int mvneta_setup_mqprio(struct net_device *dev,
+                              struct tc_mqprio_qopt_offload *mqprio)
+ {
+       struct mvneta_port *pp = netdev_priv(dev);
++      int rxq, tc;
+       u8 num_tc;
+-      int i;
+       if (mqprio->qopt.hw != TC_MQPRIO_HW_OFFLOAD_TCS)
+               return 0;
+@@ -4923,21 +4921,28 @@ static int mvneta_setup_mqprio(struct net_device *dev,
+       if (num_tc > rxq_number)
+               return -EINVAL;
++      mvneta_clear_rx_prio_map(pp);
++
+       if (!num_tc) {
+-              mvneta_clear_rx_prio_map(pp);
+               netdev_reset_tc(dev);
+               return 0;
+       }
+-      memcpy(pp->prio_tc_map, mqprio->qopt.prio_tc_map,
+-             sizeof(pp->prio_tc_map));
++      netdev_set_num_tc(dev, mqprio->qopt.num_tc);
++
++      for (tc = 0; tc < mqprio->qopt.num_tc; tc++) {
++              netdev_set_tc_queue(dev, tc, mqprio->qopt.count[tc],
++                                  mqprio->qopt.offset[tc]);
+-      mvneta_setup_rx_prio_map(pp);
++              for (rxq = mqprio->qopt.offset[tc];
++                   rxq < mqprio->qopt.count[tc] + mqprio->qopt.offset[tc];
++                   rxq++) {
++                      if (rxq >= rxq_number)
++                              return -EINVAL;
+-      netdev_set_num_tc(dev, mqprio->qopt.num_tc);
+-      for (i = 0; i < mqprio->qopt.num_tc; i++)
+-              netdev_set_tc_queue(dev, i, mqprio->qopt.count[i],
+-                                  mqprio->qopt.offset[i]);
++                      mvneta_map_vlan_prio_to_rxq(pp, tc, rxq);
++              }
++      }
+       return 0;
+ }
+-- 
+cgit 1.2.3-1.el7
+