ath25: switch default kernel to 5.15
[openwrt/openwrt.git] / target / linux / mvebu / patches-5.10 / 701-v5.14-net-ethernet-marvell-mvnetaMQPrio.patch
1 From 4906887a8ae5f1296f8079bcf4565a6092a8e402 Mon Sep 17 00:00:00 2001
2 From: Maxime Chevallier <maxime.chevallier@bootlin.com>
3 Date: Tue, 16 Feb 2021 10:25:36 +0100
4 Subject: net: mvneta: Implement mqprio support
5
6 Implement a basic MQPrio support, inserting rules in RX that translate
7 the TC to prio mapping into vlan prio to queues.
8
9 The TX logic stays the same as when we don't offload the qdisc.
10
11 Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
12 Signed-off-by: David S. Miller <davem@davemloft.net>
13 ---
14 drivers/net/ethernet/marvell/mvneta.c | 61 +++++++++++++++++++++++++++++++++++
15 1 file changed, 61 insertions(+)
16
17 (limited to 'drivers/net/ethernet/marvell/mvneta.c')
18
19 --- a/drivers/net/ethernet/marvell/mvneta.c
20 +++ b/drivers/net/ethernet/marvell/mvneta.c
21 @@ -102,6 +102,8 @@
22 #define MVNETA_TX_NO_DATA_SWAP BIT(5)
23 #define MVNETA_DESC_SWAP BIT(6)
24 #define MVNETA_TX_BRST_SZ_MASK(burst) ((burst) << 22)
25 +#define MVNETA_VLAN_PRIO_TO_RXQ 0x2440
26 +#define MVNETA_VLAN_PRIO_RXQ_MAP(prio, rxq) ((rxq) << ((prio) * 3))
27 #define MVNETA_PORT_STATUS 0x2444
28 #define MVNETA_TX_IN_PRGRS BIT(0)
29 #define MVNETA_TX_FIFO_EMPTY BIT(8)
30 @@ -490,6 +492,7 @@ struct mvneta_port {
31 u8 mcast_count[256];
32 u16 tx_ring_size;
33 u16 rx_ring_size;
34 + u8 prio_tc_map[8];
35
36 phy_interface_t phy_interface;
37 struct device_node *dn;
38 @@ -4913,6 +4916,63 @@ static u16 mvneta_select_queue(struct ne
39 }
40 #endif
41
42 +static void mvneta_clear_rx_prio_map(struct mvneta_port *pp)
43 +{
44 + mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, 0);
45 +}
46 +
47 +static void mvneta_setup_rx_prio_map(struct mvneta_port *pp)
48 +{
49 + u32 val = 0;
50 + int i;
51 +
52 + for (i = 0; i < rxq_number; i++)
53 + val |= MVNETA_VLAN_PRIO_RXQ_MAP(i, pp->prio_tc_map[i]);
54 +
55 + mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, val);
56 +}
57 +
58 +static int mvneta_setup_mqprio(struct net_device *dev,
59 + struct tc_mqprio_qopt *qopt)
60 +{
61 + struct mvneta_port *pp = netdev_priv(dev);
62 + u8 num_tc;
63 + int i;
64 +
65 + qopt->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
66 + num_tc = qopt->num_tc;
67 +
68 + if (num_tc > rxq_number)
69 + return -EINVAL;
70 +
71 + if (!num_tc) {
72 + mvneta_clear_rx_prio_map(pp);
73 + netdev_reset_tc(dev);
74 + return 0;
75 + }
76 +
77 + memcpy(pp->prio_tc_map, qopt->prio_tc_map, sizeof(pp->prio_tc_map));
78 +
79 + mvneta_setup_rx_prio_map(pp);
80 +
81 + netdev_set_num_tc(dev, qopt->num_tc);
82 + for (i = 0; i < qopt->num_tc; i++)
83 + netdev_set_tc_queue(dev, i, qopt->count[i], qopt->offset[i]);
84 +
85 + return 0;
86 +}
87 +
88 +static int mvneta_setup_tc(struct net_device *dev, enum tc_setup_type type,
89 + void *type_data)
90 +{
91 + switch (type) {
92 + case TC_SETUP_QDISC_MQPRIO:
93 + return mvneta_setup_mqprio(dev, type_data);
94 + default:
95 + return -EOPNOTSUPP;
96 + }
97 +}
98 +
99 static const struct net_device_ops mvneta_netdev_ops = {
100 .ndo_open = mvneta_open,
101 .ndo_stop = mvneta_stop,
102 @@ -4928,6 +4988,7 @@ static const struct net_device_ops mvnet
103 #endif
104 .ndo_bpf = mvneta_xdp,
105 .ndo_xdp_xmit = mvneta_xdp_xmit,
106 + .ndo_setup_tc = mvneta_setup_tc,
107 };
108
109 static const struct ethtool_ops mvneta_eth_tool_ops = {