]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
eth: mvpp2: implement new RSS context API
authorJakub Kicinski <kuba@kernel.org>
Sat, 10 Aug 2024 05:37:18 +0000 (22:37 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 12 Aug 2024 13:16:24 +0000 (14:16 +0100)
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>
drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.h
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c

index 40aeaa7bd739fa722ea059968810380a690619ea..1641791a2d5b4ed7303b95a611f19750a73dfa7b 100644 (file)
@@ -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;
 }
 
index 663157dc8062b2db2798f12d11611f0679186b71..85c9c6e8067896a9aef53593eb926193b8f7de8e 100644 (file)
@@ -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,
index 216cc7b860d6d36c114701f1c6558b42e373b5e6..4a7098f5681c15da1457d6693da3e8e961f901af 100644 (file)
@@ -5696,40 +5696,82 @@ static int mvpp2_ethtool_get_rxfh(struct net_device *dev,
        return ret;
 }
 
-static int mvpp2_ethtool_set_rxfh(struct net_device *dev,
-                                 struct ethtool_rxfh_param *rxfh,
-                                 struct netlink_ext_ack *extack)
+static bool mvpp2_ethtool_rxfh_okay(struct mvpp2_port *port,
+                                   const struct ethtool_rxfh_param *rxfh)
 {
-       struct mvpp2_port *port = netdev_priv(dev);
-       u32 *rss_context = &rxfh->rss_context;
-       int ret = 0;
-
        if (!mvpp22_rss_is_supported(port))
-               return -EOPNOTSUPP;
+               return false;
 
        if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
            rxfh->hfunc != ETH_RSS_HASH_CRC32)
-               return -EOPNOTSUPP;
+               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;
 
-       if (*rss_context && rxfh->rss_delete)
-               return mvpp22_port_rss_ctx_delete(port, *rss_context);
+       ctx->hfunc = ETH_RSS_HASH_CRC32;
 
-       if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
-               ret = mvpp22_port_rss_ctx_create(port, rss_context);
-               if (ret)
-                       return ret;
-       }
+       ret = mvpp22_port_rss_ctx_create(port, rxfh->rss_context);
+       if (ret)
+               return ret;
 
-       if (rxfh->indir)
-               ret = mvpp22_port_rss_ctx_indir_set(port, *rss_context,
+       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)
+{
+       return mvpp2_modify_rxfh_context(dev, NULL, rxfh, extack);
+}
+
 /* Device ops */
 
 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 = {
        .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