Commit f203fd85 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

eth: mvpp2: implement new RSS context API

Implement the separate create/modify/delete ops for RSS.

No problems with IDs - even tho RSS tables are per device
the driver already seems to allocate IDs linearly per port.
There's a translation table from per-port context ID
to device context ID.

mvpp2 doesn't have a key for the hash, it defaults to
an empty/previous indir table.

Note that there is no key at all, so we don't have to be
concerned with reporting the wrong one (which is addressed
by a patch later in the series).

Compile-tested only.
Reviewed-by: default avatarEdward Cree <ecree.xilinx@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 10fbe8c0
...@@ -1522,29 +1522,19 @@ static int mvpp22_rss_context_create(struct mvpp2_port *port, u32 *rss_ctx) ...@@ -1522,29 +1522,19 @@ static int mvpp22_rss_context_create(struct mvpp2_port *port, u32 *rss_ctx)
return 0; return 0;
} }
int mvpp22_port_rss_ctx_create(struct mvpp2_port *port, u32 *port_ctx) int mvpp22_port_rss_ctx_create(struct mvpp2_port *port, u32 port_ctx)
{ {
u32 rss_ctx; u32 rss_ctx;
int ret, i; int ret;
ret = mvpp22_rss_context_create(port, &rss_ctx); ret = mvpp22_rss_context_create(port, &rss_ctx);
if (ret) if (ret)
return ret; return ret;
/* Find the first available context number in the port, starting from 1. if (WARN_ON_ONCE(port->rss_ctx[port_ctx] >= 0))
* Context 0 on each port is reserved for the default context.
*/
for (i = 1; i < MVPP22_N_RSS_TABLES; i++) {
if (port->rss_ctx[i] < 0)
break;
}
if (i == MVPP22_N_RSS_TABLES)
return -EINVAL; return -EINVAL;
port->rss_ctx[i] = rss_ctx; port->rss_ctx[port_ctx] = rss_ctx;
*port_ctx = i;
return 0; return 0;
} }
......
...@@ -264,7 +264,7 @@ int mvpp22_port_rss_init(struct mvpp2_port *port); ...@@ -264,7 +264,7 @@ int mvpp22_port_rss_init(struct mvpp2_port *port);
int mvpp22_port_rss_enable(struct mvpp2_port *port); int mvpp22_port_rss_enable(struct mvpp2_port *port);
int mvpp22_port_rss_disable(struct mvpp2_port *port); int mvpp22_port_rss_disable(struct mvpp2_port *port);
int mvpp22_port_rss_ctx_create(struct mvpp2_port *port, u32 *rss_ctx); int mvpp22_port_rss_ctx_create(struct mvpp2_port *port, u32 rss_ctx);
int mvpp22_port_rss_ctx_delete(struct mvpp2_port *port, u32 rss_ctx); int mvpp22_port_rss_ctx_delete(struct mvpp2_port *port, u32 rss_ctx);
int mvpp22_port_rss_ctx_indir_set(struct mvpp2_port *port, u32 rss_ctx, int mvpp22_port_rss_ctx_indir_set(struct mvpp2_port *port, u32 rss_ctx,
......
...@@ -5696,40 +5696,82 @@ static int mvpp2_ethtool_get_rxfh(struct net_device *dev, ...@@ -5696,40 +5696,82 @@ static int mvpp2_ethtool_get_rxfh(struct net_device *dev,
return ret; return ret;
} }
static int mvpp2_ethtool_set_rxfh(struct net_device *dev, static bool mvpp2_ethtool_rxfh_okay(struct mvpp2_port *port,
struct ethtool_rxfh_param *rxfh, const struct ethtool_rxfh_param *rxfh)
struct netlink_ext_ack *extack)
{ {
struct mvpp2_port *port = netdev_priv(dev);
u32 *rss_context = &rxfh->rss_context;
int ret = 0;
if (!mvpp22_rss_is_supported(port)) if (!mvpp22_rss_is_supported(port))
return -EOPNOTSUPP; return false;
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
rxfh->hfunc != ETH_RSS_HASH_CRC32) rxfh->hfunc != ETH_RSS_HASH_CRC32)
return -EOPNOTSUPP; return false;
if (rxfh->key) if (rxfh->key)
return false;
return true;
}
static int mvpp2_create_rxfh_context(struct net_device *dev,
struct ethtool_rxfh_context *ctx,
const struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
struct mvpp2_port *port = netdev_priv(dev);
int ret = 0;
if (!mvpp2_ethtool_rxfh_okay(port, rxfh))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (*rss_context && rxfh->rss_delete) ctx->hfunc = ETH_RSS_HASH_CRC32;
return mvpp22_port_rss_ctx_delete(port, *rss_context);
if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) { ret = mvpp22_port_rss_ctx_create(port, rxfh->rss_context);
ret = mvpp22_port_rss_ctx_create(port, rss_context); if (ret)
if (ret) return ret;
return ret;
}
if (rxfh->indir) if (!rxfh->indir)
ret = mvpp22_port_rss_ctx_indir_set(port, *rss_context, ret = mvpp22_port_rss_ctx_indir_get(port, rxfh->rss_context,
ethtool_rxfh_context_indir(ctx));
else
ret = mvpp22_port_rss_ctx_indir_set(port, rxfh->rss_context,
rxfh->indir); rxfh->indir);
return ret;
}
static int mvpp2_modify_rxfh_context(struct net_device *dev,
struct ethtool_rxfh_context *ctx,
const struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
struct mvpp2_port *port = netdev_priv(dev);
int ret = 0;
if (!mvpp2_ethtool_rxfh_okay(port, rxfh))
return -EOPNOTSUPP;
if (rxfh->indir)
ret = mvpp22_port_rss_ctx_indir_set(port, rxfh->rss_context,
rxfh->indir);
return ret; return ret;
} }
static int mvpp2_remove_rxfh_context(struct net_device *dev,
struct ethtool_rxfh_context *ctx,
u32 rss_context,
struct netlink_ext_ack *extack)
{
struct mvpp2_port *port = netdev_priv(dev);
return mvpp22_port_rss_ctx_delete(port, rss_context);
}
static int mvpp2_ethtool_set_rxfh(struct net_device *dev,
struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
return mvpp2_modify_rxfh_context(dev, NULL, rxfh, extack);
}
/* Device ops */ /* Device ops */
static const struct net_device_ops mvpp2_netdev_ops = { static const struct net_device_ops mvpp2_netdev_ops = {
...@@ -5750,6 +5792,7 @@ static const struct net_device_ops mvpp2_netdev_ops = { ...@@ -5750,6 +5792,7 @@ static const struct net_device_ops mvpp2_netdev_ops = {
static const struct ethtool_ops mvpp2_eth_tool_ops = { static const struct ethtool_ops mvpp2_eth_tool_ops = {
.cap_rss_ctx_supported = true, .cap_rss_ctx_supported = true,
.rxfh_max_num_contexts = MVPP22_N_RSS_TABLES,
.supported_coalesce_params = ETHTOOL_COALESCE_USECS | .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_MAX_FRAMES, ETHTOOL_COALESCE_MAX_FRAMES,
.nway_reset = mvpp2_ethtool_nway_reset, .nway_reset = mvpp2_ethtool_nway_reset,
...@@ -5772,6 +5815,9 @@ static const struct ethtool_ops mvpp2_eth_tool_ops = { ...@@ -5772,6 +5815,9 @@ static const struct ethtool_ops mvpp2_eth_tool_ops = {
.get_rxfh_indir_size = mvpp2_ethtool_get_rxfh_indir_size, .get_rxfh_indir_size = mvpp2_ethtool_get_rxfh_indir_size,
.get_rxfh = mvpp2_ethtool_get_rxfh, .get_rxfh = mvpp2_ethtool_get_rxfh,
.set_rxfh = mvpp2_ethtool_set_rxfh, .set_rxfh = mvpp2_ethtool_set_rxfh,
.create_rxfh_context = mvpp2_create_rxfh_context,
.modify_rxfh_context = mvpp2_modify_rxfh_context,
.remove_rxfh_context = mvpp2_remove_rxfh_context,
}; };
/* Used for PPv2.1, or PPv2.2 with the old Device Tree binding that /* Used for PPv2.1, or PPv2.2 with the old Device Tree binding that
......
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