Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8179642b authored by Antoine Tenart's avatar Antoine Tenart Committed by David S. Miller
Browse files

net: mvpp2: RSS indirection table support



This patch adds the RSS indirection table support, allowing to use the
ethtool -x and -X options to dump and set this table.

Signed-off-by: default avatarAntoine Tenart <antoine.tenart@bootlin.com>
[Maxime: Small warning fixes, use one table per port]
Signed-off-by: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a27a254c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -801,6 +801,9 @@ struct mvpp2_port {
	bool has_tx_irqs;

	u32 tx_time_coal;

	/* RSS indirection table */
	u32 indir[MVPP22_RSS_TABLE_ENTRIES];
};

/* The mvpp2_tx_desc and mvpp2_rx_desc structures describe the
+17 −7
Original line number Diff line number Diff line
@@ -107,6 +107,20 @@ void mvpp2_cls_oversize_rxq_set(struct mvpp2_port *port)
	mvpp2_write(port->priv, MVPP2_CLS_SWFWD_PCTRL_REG, val);
}

void mvpp22_rss_fill_table(struct mvpp2_port *port, u32 table)
{
	struct mvpp2 *priv = port->priv;
	int i;

	for (i = 0; i < MVPP22_RSS_TABLE_ENTRIES; i++) {
		u32 sel = MVPP22_RSS_INDEX_TABLE(table) |
			  MVPP22_RSS_INDEX_TABLE_ENTRY(i);
		mvpp2_write(priv, MVPP22_RSS_INDEX, sel);

		mvpp2_write(priv, MVPP22_RSS_TABLE_ENTRY, port->indir[i]);
	}
}

void mvpp22_init_rss(struct mvpp2_port *port)
{
	struct mvpp2 *priv = port->priv;
@@ -129,12 +143,8 @@ void mvpp22_init_rss(struct mvpp2_port *port)
	/* Configure the first table to evenly distribute the packets across
	 * real Rx Queues. The table entries map a hash to a port Rx Queue.
	 */
	for (i = 0; i < MVPP22_RSS_TABLE_ENTRIES; i++) {
		u32 sel = MVPP22_RSS_INDEX_TABLE(port->id) |
			  MVPP22_RSS_INDEX_TABLE_ENTRY(i);
		mvpp2_write(priv, MVPP22_RSS_INDEX, sel);

		mvpp2_write(priv, MVPP22_RSS_TABLE_ENTRY, i % port->nrxqs);
	}
	for (i = 0; i < MVPP22_RSS_TABLE_ENTRIES; i++)
		port->indir[i] = ethtool_rxfh_indir_default(i, port->nrxqs);

	mvpp22_rss_fill_table(port, port->id);
}
+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ struct mvpp2_cls_lookup_entry {
	u32 data;
};

void mvpp22_rss_fill_table(struct mvpp2_port *port, u32 table);

void mvpp22_init_rss(struct mvpp2_port *port);

void mvpp2_cls_init(struct mvpp2 *priv);
+70 −0
Original line number Diff line number Diff line
@@ -3821,6 +3821,71 @@ static int mvpp2_ethtool_set_link_ksettings(struct net_device *dev,
	return phylink_ethtool_ksettings_set(port->phylink, cmd);
}

static int mvpp2_ethtool_get_rxnfc(struct net_device *dev,
				   struct ethtool_rxnfc *info, u32 *rules)
{
	struct mvpp2_port *port = netdev_priv(dev);

	if (!mvpp22_rss_is_supported())
		return -EOPNOTSUPP;

	switch (info->cmd) {
	case ETHTOOL_GRXRINGS:
		info->data = port->nrxqs;
		break;
	default:
		return -ENOTSUPP;
	}

	return 0;
}

static u32 mvpp2_ethtool_get_rxfh_indir_size(struct net_device *dev)
{
	return mvpp22_rss_is_supported() ? MVPP22_RSS_TABLE_ENTRIES : 0;
}

static int mvpp2_ethtool_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
				  u8 *hfunc)
{
	struct mvpp2_port *port = netdev_priv(dev);

	if (!mvpp22_rss_is_supported())
		return -EOPNOTSUPP;

	if (indir)
		memcpy(indir, port->indir,
		       ARRAY_SIZE(port->indir) * sizeof(port->indir[0]));

	if (hfunc)
		*hfunc = ETH_RSS_HASH_CRC32;

	return 0;
}

static int mvpp2_ethtool_set_rxfh(struct net_device *dev, const u32 *indir,
				  const u8 *key, const u8 hfunc)
{
	struct mvpp2_port *port = netdev_priv(dev);

	if (!mvpp22_rss_is_supported())
		return -EOPNOTSUPP;

	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_CRC32)
		return -EOPNOTSUPP;

	if (key)
		return -EOPNOTSUPP;

	if (indir) {
		memcpy(port->indir, indir,
		       ARRAY_SIZE(port->indir) * sizeof(port->indir[0]));
		mvpp22_rss_fill_table(port, port->id);
	}

	return 0;
}

/* Device ops */

static const struct net_device_ops mvpp2_netdev_ops = {
@@ -3852,6 +3917,11 @@ static const struct ethtool_ops mvpp2_eth_tool_ops = {
	.set_pauseparam		= mvpp2_ethtool_set_pause_param,
	.get_link_ksettings	= mvpp2_ethtool_get_link_ksettings,
	.set_link_ksettings	= mvpp2_ethtool_set_link_ksettings,
	.get_rxnfc		= mvpp2_ethtool_get_rxnfc,
	.get_rxfh_indir_size	= mvpp2_ethtool_get_rxfh_indir_size,
	.get_rxfh		= mvpp2_ethtool_get_rxfh,
	.set_rxfh		= mvpp2_ethtool_set_rxfh,

};

/* Used for PPv2.1, or PPv2.2 with the old Device Tree binding that