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
6 Implement a basic MQPrio support, inserting rules in RX that translate
7 the TC to prio mapping into vlan prio to queues.
9 The TX logic stays the same as when we don't offload the qdisc.
11 Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
12 Signed-off-by: David S. Miller <davem@davemloft.net>
14 drivers/net/ethernet/marvell/mvneta.c | 61 +++++++++++++++++++++++++++++++++++
15 1 file changed, 61 insertions(+)
17 (limited to 'drivers/net/ethernet/marvell/mvneta.c')
19 --- a/drivers/net/ethernet/marvell/mvneta.c
20 +++ b/drivers/net/ethernet/marvell/mvneta.c
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 {
36 phy_interface_t phy_interface;
37 struct device_node *dn;
38 @@ -4913,6 +4916,63 @@ static u16 mvneta_select_queue(struct ne
42 +static void mvneta_clear_rx_prio_map(struct mvneta_port *pp)
44 + mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, 0);
47 +static void mvneta_setup_rx_prio_map(struct mvneta_port *pp)
52 + for (i = 0; i < rxq_number; i++)
53 + val |= MVNETA_VLAN_PRIO_RXQ_MAP(i, pp->prio_tc_map[i]);
55 + mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, val);
58 +static int mvneta_setup_mqprio(struct net_device *dev,
59 + struct tc_mqprio_qopt *qopt)
61 + struct mvneta_port *pp = netdev_priv(dev);
65 + qopt->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
66 + num_tc = qopt->num_tc;
68 + if (num_tc > rxq_number)
72 + mvneta_clear_rx_prio_map(pp);
73 + netdev_reset_tc(dev);
77 + memcpy(pp->prio_tc_map, qopt->prio_tc_map, sizeof(pp->prio_tc_map));
79 + mvneta_setup_rx_prio_map(pp);
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]);
88 +static int mvneta_setup_tc(struct net_device *dev, enum tc_setup_type type,
92 + case TC_SETUP_QDISC_MQPRIO:
93 + return mvneta_setup_mqprio(dev, type_data);
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
104 .ndo_bpf = mvneta_xdp,
105 .ndo_xdp_xmit = mvneta_xdp_xmit,
106 + .ndo_setup_tc = mvneta_setup_tc,
109 static const struct ethtool_ops mvneta_eth_tool_ops = {