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: Edward Cree <ecree.xilinx@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
10fbe8c082
commit
f203fd85e6
@@ -1522,29 +1522,19 @@ static int mvpp22_rss_context_create(struct mvpp2_port *port, u32 *rss_ctx)
|
||||
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;
|
||||
int ret, i;
|
||||
int ret;
|
||||
|
||||
ret = mvpp22_rss_context_create(port, &rss_ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Find the first available context number in the port, starting from 1.
|
||||
* 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)
|
||||
if (WARN_ON_ONCE(port->rss_ctx[port_ctx] >= 0))
|
||||
return -EINVAL;
|
||||
|
||||
port->rss_ctx[i] = rss_ctx;
|
||||
*port_ctx = i;
|
||||
|
||||
port->rss_ctx[port_ctx] = rss_ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_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_indir_set(struct mvpp2_port *port, u32 rss_ctx,
|
||||
|
||||
@@ -5696,38 +5696,80 @@ static int mvpp2_ethtool_get_rxfh(struct net_device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool mvpp2_ethtool_rxfh_okay(struct mvpp2_port *port,
|
||||
const struct ethtool_rxfh_param *rxfh)
|
||||
{
|
||||
if (!mvpp22_rss_is_supported(port))
|
||||
return false;
|
||||
|
||||
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
|
||||
rxfh->hfunc != ETH_RSS_HASH_CRC32)
|
||||
return false;
|
||||
|
||||
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;
|
||||
|
||||
ctx->hfunc = ETH_RSS_HASH_CRC32;
|
||||
|
||||
ret = mvpp22_port_rss_ctx_create(port, rxfh->rss_context);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!rxfh->indir)
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct mvpp2_port *port = netdev_priv(dev);
|
||||
u32 *rss_context = &rxfh->rss_context;
|
||||
int ret = 0;
|
||||
|
||||
if (!mvpp22_rss_is_supported(port))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
|
||||
rxfh->hfunc != ETH_RSS_HASH_CRC32)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (rxfh->key)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (*rss_context && rxfh->rss_delete)
|
||||
return mvpp22_port_rss_ctx_delete(port, *rss_context);
|
||||
|
||||
if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
|
||||
ret = mvpp22_port_rss_ctx_create(port, rss_context);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rxfh->indir)
|
||||
ret = mvpp22_port_rss_ctx_indir_set(port, *rss_context,
|
||||
rxfh->indir);
|
||||
|
||||
return ret;
|
||||
return mvpp2_modify_rxfh_context(dev, NULL, rxfh, extack);
|
||||
}
|
||||
|
||||
/* Device ops */
|
||||
@@ -5750,6 +5792,7 @@ static const struct net_device_ops mvpp2_netdev_ops = {
|
||||
|
||||
static const struct ethtool_ops mvpp2_eth_tool_ops = {
|
||||
.cap_rss_ctx_supported = true,
|
||||
.rxfh_max_num_contexts = MVPP22_N_RSS_TABLES,
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
||||
ETHTOOL_COALESCE_MAX_FRAMES,
|
||||
.nway_reset = mvpp2_ethtool_nway_reset,
|
||||
@@ -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 = mvpp2_ethtool_get_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
|
||||
|
||||
Reference in New Issue
Block a user