mlxsw: spectrum: Move ACL flexible actions instance to spectrum
authorYotam Gigi <yotamg@mellanox.com>
Tue, 19 Sep 2017 08:00:09 +0000 (10:00 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 19 Sep 2017 21:21:40 +0000 (14:21 -0700)
A flexible action instance allows, given a set of ops, creating, committing
and sharing a set of ACL action blocks. The flexible action instance in
question is using the spectrum KVD linear space to store the flexible
action sets.

Move this flexible action instance to the common spectrum struct to allow
other users (such as multicast router) to get that functionality.

Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/Makefile
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c [new file with mode: 0644]
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.h [new file with mode: 0644]

index 891ff418bb5edcf79996365e37a2d6757be52c46..4b88158173f3932ec91d2a8a30cb46c64651f846 100644 (file)
@@ -17,7 +17,7 @@ mlxsw_spectrum-objs           := spectrum.o spectrum_buffers.o \
                                   spectrum_kvdl.o spectrum_acl_tcam.o \
                                   spectrum_acl.o spectrum_flower.o \
                                   spectrum_cnt.o spectrum_fid.o \
-                                  spectrum_ipip.o
+                                  spectrum_ipip.o spectrum_acl_flex_actions.o
 mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB)    += spectrum_dcb.o
 mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o
 obj-$(CONFIG_MLXSW_MINIMAL)    += mlxsw_minimal.o
index 97284161ea3595b105fd300bd7f52ed238fadcaf..6ba6ff276b175f8c96e979bc28e50789c7dae487 100644 (file)
@@ -69,6 +69,7 @@
 #include "txheader.h"
 #include "spectrum_cnt.h"
 #include "spectrum_dpipe.h"
+#include "spectrum_acl_flex_actions.h"
 #include "../mlxfw/mlxfw.h"
 
 #define MLXSW_FWREV_MAJOR 13
@@ -3699,6 +3700,12 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
                goto err_counter_pool_init;
        }
 
+       err = mlxsw_sp_afa_init(mlxsw_sp);
+       if (err) {
+               dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize ACL actions\n");
+               goto err_afa_init;
+       }
+
        err = mlxsw_sp_router_init(mlxsw_sp);
        if (err) {
                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n");
@@ -3740,6 +3747,8 @@ err_acl_init:
 err_span_init:
        mlxsw_sp_router_fini(mlxsw_sp);
 err_router_init:
+       mlxsw_sp_afa_fini(mlxsw_sp);
+err_afa_init:
        mlxsw_sp_counter_pool_fini(mlxsw_sp);
 err_counter_pool_init:
        mlxsw_sp_switchdev_fini(mlxsw_sp);
@@ -3763,6 +3772,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
        mlxsw_sp_acl_fini(mlxsw_sp);
        mlxsw_sp_span_fini(mlxsw_sp);
        mlxsw_sp_router_fini(mlxsw_sp);
+       mlxsw_sp_afa_fini(mlxsw_sp);
        mlxsw_sp_counter_pool_fini(mlxsw_sp);
        mlxsw_sp_switchdev_fini(mlxsw_sp);
        mlxsw_sp_lag_fini(mlxsw_sp);
index 84ce83acdc199bf4c311c325edc5f7ccba1af375..7180d8f3de7526426792116a113b6b49078556fd 100644 (file)
@@ -152,6 +152,7 @@ struct mlxsw_sp {
        struct mlxsw_sp_sb *sb;
        struct mlxsw_sp_bridge *bridge;
        struct mlxsw_sp_router *router;
+       struct mlxsw_afa *afa;
        struct mlxsw_sp_acl *acl;
        struct mlxsw_sp_fid_core *fid_core;
        struct {
index 4b2455e3e0797cd1f15ac74190ea732392de3e4b..2523785f19047107d9eade23619656d1c90407ca 100644 (file)
@@ -52,7 +52,6 @@
 struct mlxsw_sp_acl {
        struct mlxsw_sp *mlxsw_sp;
        struct mlxsw_afk *afk;
-       struct mlxsw_afa *afa;
        struct mlxsw_sp_fid *dummy_fid;
        const struct mlxsw_sp_acl_ops *ops;
        struct rhashtable ruleset_ht;
@@ -333,7 +332,7 @@ mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl)
        rulei = kzalloc(sizeof(*rulei), GFP_KERNEL);
        if (!rulei)
                return NULL;
-       rulei->act_block = mlxsw_afa_block_create(acl->afa);
+       rulei->act_block = mlxsw_afa_block_create(acl->mlxsw_sp->afa);
        if (IS_ERR(rulei->act_block)) {
                err = PTR_ERR(rulei->act_block);
                goto err_afa_block_create;
@@ -653,85 +652,6 @@ int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp,
        return 0;
 }
 
-#define MLXSW_SP_KDVL_ACT_EXT_SIZE 1
-
-static int mlxsw_sp_act_kvdl_set_add(void *priv, u32 *p_kvdl_index,
-                                    char *enc_actions, bool is_first)
-{
-       struct mlxsw_sp *mlxsw_sp = priv;
-       char pefa_pl[MLXSW_REG_PEFA_LEN];
-       u32 kvdl_index;
-       int err;
-
-       /* The first action set of a TCAM entry is stored directly in TCAM,
-        * not KVD linear area.
-        */
-       if (is_first)
-               return 0;
-
-       err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KDVL_ACT_EXT_SIZE,
-                                 &kvdl_index);
-       if (err)
-               return err;
-       mlxsw_reg_pefa_pack(pefa_pl, kvdl_index, enc_actions);
-       err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pefa), pefa_pl);
-       if (err)
-               goto err_pefa_write;
-       *p_kvdl_index = kvdl_index;
-       return 0;
-
-err_pefa_write:
-       mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
-       return err;
-}
-
-static void mlxsw_sp_act_kvdl_set_del(void *priv, u32 kvdl_index,
-                                     bool is_first)
-{
-       struct mlxsw_sp *mlxsw_sp = priv;
-
-       if (is_first)
-               return;
-       mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
-}
-
-static int mlxsw_sp_act_kvdl_fwd_entry_add(void *priv, u32 *p_kvdl_index,
-                                          u8 local_port)
-{
-       struct mlxsw_sp *mlxsw_sp = priv;
-       char ppbs_pl[MLXSW_REG_PPBS_LEN];
-       u32 kvdl_index;
-       int err;
-
-       err = mlxsw_sp_kvdl_alloc(mlxsw_sp, 1, &kvdl_index);
-       if (err)
-               return err;
-       mlxsw_reg_ppbs_pack(ppbs_pl, kvdl_index, local_port);
-       err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ppbs), ppbs_pl);
-       if (err)
-               goto err_ppbs_write;
-       *p_kvdl_index = kvdl_index;
-       return 0;
-
-err_ppbs_write:
-       mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
-       return err;
-}
-
-static void mlxsw_sp_act_kvdl_fwd_entry_del(void *priv, u32 kvdl_index)
-{
-       struct mlxsw_sp *mlxsw_sp = priv;
-
-       mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
-}
-
-static const struct mlxsw_afa_ops mlxsw_sp_act_afa_ops = {
-       .kvdl_set_add           = mlxsw_sp_act_kvdl_set_add,
-       .kvdl_set_del           = mlxsw_sp_act_kvdl_set_del,
-       .kvdl_fwd_entry_add     = mlxsw_sp_act_kvdl_fwd_entry_add,
-       .kvdl_fwd_entry_del     = mlxsw_sp_act_kvdl_fwd_entry_del,
-};
-
 int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp)
 {
        const struct mlxsw_sp_acl_ops *acl_ops = &mlxsw_sp_acl_tcam_ops;
@@ -753,14 +673,6 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp)
                goto err_afk_create;
        }
 
-       acl->afa = mlxsw_afa_create(MLXSW_CORE_RES_GET(mlxsw_sp->core,
-                                                      ACL_ACTIONS_PER_SET),
-                                   &mlxsw_sp_act_afa_ops, mlxsw_sp);
-       if (IS_ERR(acl->afa)) {
-               err = PTR_ERR(acl->afa);
-               goto err_afa_create;
-       }
-
        err = rhashtable_init(&acl->ruleset_ht,
                              &mlxsw_sp_acl_ruleset_ht_params);
        if (err)
@@ -792,8 +704,6 @@ err_acl_ops_init:
 err_fid_get:
        rhashtable_destroy(&acl->ruleset_ht);
 err_rhashtable_init:
-       mlxsw_afa_destroy(acl->afa);
-err_afa_create:
        mlxsw_afk_destroy(acl->afk);
 err_afk_create:
        kfree(acl);
@@ -810,7 +720,6 @@ void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp)
        WARN_ON(!list_empty(&acl->rules));
        mlxsw_sp_fid_put(acl->dummy_fid);
        rhashtable_destroy(&acl->ruleset_ht);
-       mlxsw_afa_destroy(acl->afa);
        mlxsw_afk_destroy(acl->afk);
        kfree(acl);
 }
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
new file mode 100644 (file)
index 0000000..4d3340e
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
+ * Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "spectrum_acl_flex_actions.h"
+#include "core_acl_flex_actions.h"
+
+#define MLXSW_SP_KVDL_ACT_EXT_SIZE 1
+
+static int mlxsw_sp_act_kvdl_set_add(void *priv, u32 *p_kvdl_index,
+                                    char *enc_actions, bool is_first)
+{
+       struct mlxsw_sp *mlxsw_sp = priv;
+       char pefa_pl[MLXSW_REG_PEFA_LEN];
+       u32 kvdl_index;
+       int err;
+
+       /* The first action set of a TCAM entry is stored directly in TCAM,
+        * not KVD linear area.
+        */
+       if (is_first)
+               return 0;
+
+       err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ACT_EXT_SIZE,
+                                 &kvdl_index);
+       if (err)
+               return err;
+       mlxsw_reg_pefa_pack(pefa_pl, kvdl_index, enc_actions);
+       err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pefa), pefa_pl);
+       if (err)
+               goto err_pefa_write;
+       *p_kvdl_index = kvdl_index;
+       return 0;
+
+err_pefa_write:
+       mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
+       return err;
+}
+
+static void mlxsw_sp_act_kvdl_set_del(void *priv, u32 kvdl_index,
+                                     bool is_first)
+{
+       struct mlxsw_sp *mlxsw_sp = priv;
+
+       if (is_first)
+               return;
+       mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
+}
+
+static int mlxsw_sp_act_kvdl_fwd_entry_add(void *priv, u32 *p_kvdl_index,
+                                          u8 local_port)
+{
+       struct mlxsw_sp *mlxsw_sp = priv;
+       char ppbs_pl[MLXSW_REG_PPBS_LEN];
+       u32 kvdl_index;
+       int err;
+
+       err = mlxsw_sp_kvdl_alloc(mlxsw_sp, 1, &kvdl_index);
+       if (err)
+               return err;
+       mlxsw_reg_ppbs_pack(ppbs_pl, kvdl_index, local_port);
+       err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ppbs), ppbs_pl);
+       if (err)
+               goto err_ppbs_write;
+       *p_kvdl_index = kvdl_index;
+       return 0;
+
+err_ppbs_write:
+       mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
+       return err;
+}
+
+static void mlxsw_sp_act_kvdl_fwd_entry_del(void *priv, u32 kvdl_index)
+{
+       struct mlxsw_sp *mlxsw_sp = priv;
+
+       mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
+}
+
+static const struct mlxsw_afa_ops mlxsw_sp_act_afa_ops = {
+       .kvdl_set_add           = mlxsw_sp_act_kvdl_set_add,
+       .kvdl_set_del           = mlxsw_sp_act_kvdl_set_del,
+       .kvdl_fwd_entry_add     = mlxsw_sp_act_kvdl_fwd_entry_add,
+       .kvdl_fwd_entry_del     = mlxsw_sp_act_kvdl_fwd_entry_del,
+};
+
+int mlxsw_sp_afa_init(struct mlxsw_sp *mlxsw_sp)
+{
+       mlxsw_sp->afa = mlxsw_afa_create(MLXSW_CORE_RES_GET(mlxsw_sp->core,
+                                                           ACL_ACTIONS_PER_SET),
+                                        &mlxsw_sp_act_afa_ops, mlxsw_sp);
+       return PTR_ERR_OR_ZERO(mlxsw_sp->afa);
+}
+
+void mlxsw_sp_afa_fini(struct mlxsw_sp *mlxsw_sp)
+{
+       mlxsw_afa_destroy(mlxsw_sp->afa);
+}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.h
new file mode 100644 (file)
index 0000000..2726192
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.h
+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
+ * Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MLXSW_SPECTRUM_ACL_FLEX_KEYS_H
+#define _MLXSW_SPECTRUM_ACL_FLEX_KEYS_H
+
+#include "spectrum.h"
+
+int mlxsw_sp_afa_init(struct mlxsw_sp *mlxsw_sp);
+void mlxsw_sp_afa_fini(struct mlxsw_sp *mlxsw_sp);
+
+#endif