Commit 80fea53d authored by David S. Miller's avatar David S. Miller

Merge branch 'net-mvneta-implement-basic-MQPrio-support'

Maxime Chevallier says:

====================
net: mvneta: implement basic MQPrio support

This is V2 for the MQPrio support in mvneta.

This small series adds basic support for mqprio offloading, by having
the rx queueing mirroring the TCs based on VLAN prio fields.

This was tested on Armada 3700, and proves useful to make sure
high-priority traffic has a better chance not getting dropped when
there's lots of packets incoming.

The first patch of the series deals with the per-cpu interrupts on the
armada 3700. Since they don't work, there were already some patches
applied to keep all queue mappings to CPU0, but there still were some
remaining mappings left to be dealt with.

The second patch implements the MQPrio offloading for the receive path.

Changes in V2 :
 - Add a Fixes tag for the first patch
 - Fix some warnings and the xmas tree in the second patch
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 44c32039 4906887a
......@@ -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)
......@@ -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;
......@@ -3428,7 +3431,9 @@ static int mvneta_txq_sw_init(struct mvneta_port *pp,
return -ENOMEM;
/* Setup XPS mapping */
if (txq_number > 1)
if (pp->neta_armada3700)
cpu = 0;
else if (txq_number > 1)
cpu = txq->id % num_present_cpus();
else
cpu = pp->rxq_def % num_present_cpus();
......@@ -4206,6 +4211,11 @@ static int mvneta_cpu_online(unsigned int cpu, struct hlist_node *node)
node_online);
struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu);
/* Armada 3700's per-cpu interrupt for mvneta is broken, all interrupts
* are routed to CPU 0, so we don't need all the cpu-hotplug support
*/
if (pp->neta_armada3700)
return 0;
spin_lock(&pp->lock);
/*
......@@ -4915,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,
......@@ -4927,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 = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment