Skip to content

Commit

Permalink
net: mvneta: Implement mqprio support
Browse files Browse the repository at this point in the history
Implement a basic MQPrio support, inserting rules in RX that translate
the TC to prio mapping into vlan prio to queues.

The TX logic stays the same as when we don't offload the qdisc.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Maxime Chevallier authored and David S. Miller committed Feb 16, 2021
1 parent cf9bf87 commit 4906887
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions drivers/net/ethernet/marvell/mvneta.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@
#define MVNETA_TX_NO_DATA_SWAP BIT(5)
#define MVNETA_DESC_SWAP BIT(6)
#define MVNETA_TX_BRST_SZ_MASK(burst) ((burst) << 22)
#define MVNETA_VLAN_PRIO_TO_RXQ 0x2440
#define MVNETA_VLAN_PRIO_RXQ_MAP(prio, rxq) ((rxq) << ((prio) * 3))
#define MVNETA_PORT_STATUS 0x2444
#define MVNETA_TX_IN_PRGRS BIT(1)
#define MVNETA_TX_FIFO_EMPTY BIT(8)
Expand Down Expand Up @@ -490,6 +492,7 @@ 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;
Expand Down Expand Up @@ -4922,6 +4925,63 @@ static int mvneta_ethtool_set_eee(struct net_device *dev,
return phylink_ethtool_set_eee(pp->phylink, eee);
}

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)
{
u32 val = 0;
int i;

for (i = 0; i < rxq_number; i++)
val |= MVNETA_VLAN_PRIO_RXQ_MAP(i, pp->prio_tc_map[i]);

mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, val);
}

static int mvneta_setup_mqprio(struct net_device *dev,
struct tc_mqprio_qopt *qopt)
{
struct mvneta_port *pp = netdev_priv(dev);
u8 num_tc;
int i;

qopt->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
num_tc = qopt->num_tc;

if (num_tc > rxq_number)
return -EINVAL;

if (!num_tc) {
mvneta_clear_rx_prio_map(pp);
netdev_reset_tc(dev);
return 0;
}

memcpy(pp->prio_tc_map, qopt->prio_tc_map, sizeof(pp->prio_tc_map));

mvneta_setup_rx_prio_map(pp);

netdev_set_num_tc(dev, qopt->num_tc);
for (i = 0; i < qopt->num_tc; i++)
netdev_set_tc_queue(dev, i, qopt->count[i], qopt->offset[i]);

return 0;
}

static int mvneta_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
switch (type) {
case TC_SETUP_QDISC_MQPRIO:
return mvneta_setup_mqprio(dev, type_data);
default:
return -EOPNOTSUPP;
}
}

static const struct net_device_ops mvneta_netdev_ops = {
.ndo_open = mvneta_open,
.ndo_stop = mvneta_stop,
Expand All @@ -4934,6 +4994,7 @@ static const struct net_device_ops mvneta_netdev_ops = {
.ndo_do_ioctl = mvneta_ioctl,
.ndo_bpf = mvneta_xdp,
.ndo_xdp_xmit = mvneta_xdp_xmit,
.ndo_setup_tc = mvneta_setup_tc,
};

static const struct ethtool_ops mvneta_eth_tool_ops = {
Expand Down

0 comments on commit 4906887

Please sign in to comment.