From: Jiri Pirko <j...@mellanox.com>

If action is gact goto_chain, offload it to HW by jumping to another
ruleset.

Signed-off-by: Jiri Pirko <j...@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_flower.c  | 23 ++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
index 34872aa..8aace9a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
@@ -45,7 +45,7 @@
 #include "core_acl_flex_keys.h"
 
 static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
-                                        struct net_device *dev,
+                                        struct net_device *dev, bool ingress,
                                         struct mlxsw_sp_acl_rule_info *rulei,
                                         struct tcf_exts *exts)
 {
@@ -71,6 +71,20 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp 
*mlxsw_sp,
                        err = mlxsw_sp_acl_rulei_act_trap(rulei);
                        if (err)
                                return err;
+               } else if (is_tcf_gact_goto_chain(a)) {
+                       u32 chain_index = tcf_gact_goto_chain_index(a);
+                       struct mlxsw_sp_acl_ruleset *ruleset;
+                       u16 group_id;
+
+                       ruleset = mlxsw_sp_acl_ruleset_lookup(mlxsw_sp, dev,
+                                                             ingress,
+                                                             chain_index,
+                                                             
MLXSW_SP_ACL_PROFILE_FLOWER);
+                       if (IS_ERR(ruleset))
+                               return PTR_ERR(ruleset);
+
+                       group_id = mlxsw_sp_acl_ruleset_group_id(ruleset);
+                       mlxsw_sp_acl_rulei_act_jump(rulei, group_id);
                } else if (is_tcf_mirred_egress_redirect(a)) {
                        int ifindex = tcf_mirred_ifindex(a);
                        struct net_device *out_dev;
@@ -246,7 +260,7 @@ static int mlxsw_sp_flower_parse_ip(struct mlxsw_sp 
*mlxsw_sp,
 }
 
 static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
-                                struct net_device *dev,
+                                struct net_device *dev, bool ingress,
                                 struct mlxsw_sp_acl_rule_info *rulei,
                                 struct tc_cls_flower_offload *f)
 {
@@ -364,7 +378,8 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
        if (err)
                return err;
 
-       return mlxsw_sp_flower_parse_actions(mlxsw_sp, dev, rulei, f->exts);
+       return mlxsw_sp_flower_parse_actions(mlxsw_sp, dev, ingress,
+                                            rulei, f->exts);
 }
 
 int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
@@ -390,7 +405,7 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp_port 
*mlxsw_sp_port, bool ingress,
        }
 
        rulei = mlxsw_sp_acl_rule_rulei(rule);
-       err = mlxsw_sp_flower_parse(mlxsw_sp, dev, rulei, f);
+       err = mlxsw_sp_flower_parse(mlxsw_sp, dev, ingress, rulei, f);
        if (err)
                goto err_flower_parse;
 
-- 
2.9.3

Reply via email to