root/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mlxsw_sp_act_kvdl_set_add
  2. mlxsw_sp1_act_kvdl_set_add
  3. mlxsw_sp2_act_kvdl_set_add
  4. mlxsw_sp_act_kvdl_set_del
  5. mlxsw_sp1_act_kvdl_set_activity_get
  6. mlxsw_sp2_act_kvdl_set_activity_get
  7. mlxsw_sp_act_kvdl_fwd_entry_add
  8. mlxsw_sp_act_kvdl_fwd_entry_del
  9. mlxsw_sp_act_counter_index_get
  10. mlxsw_sp_act_counter_index_put
  11. mlxsw_sp_act_mirror_add
  12. mlxsw_sp_act_mirror_del
  13. mlxsw_sp_afa_init
  14. mlxsw_sp_afa_fini

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
   3 
   4 #include "spectrum_acl_flex_actions.h"
   5 #include "core_acl_flex_actions.h"
   6 #include "spectrum_span.h"
   7 
   8 static int mlxsw_sp_act_kvdl_set_add(void *priv, u32 *p_kvdl_index,
   9                                      char *enc_actions, bool is_first, bool ca)
  10 {
  11         struct mlxsw_sp *mlxsw_sp = priv;
  12         char pefa_pl[MLXSW_REG_PEFA_LEN];
  13         u32 kvdl_index;
  14         int err;
  15 
  16         /* The first action set of a TCAM entry is stored directly in TCAM,
  17          * not KVD linear area.
  18          */
  19         if (is_first)
  20                 return 0;
  21 
  22         err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ACTSET,
  23                                   1, &kvdl_index);
  24         if (err)
  25                 return err;
  26         mlxsw_reg_pefa_pack(pefa_pl, kvdl_index, ca, enc_actions);
  27         err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pefa), pefa_pl);
  28         if (err)
  29                 goto err_pefa_write;
  30         *p_kvdl_index = kvdl_index;
  31         return 0;
  32 
  33 err_pefa_write:
  34         mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ACTSET,
  35                            1, kvdl_index);
  36         return err;
  37 }
  38 
  39 static int mlxsw_sp1_act_kvdl_set_add(void *priv, u32 *p_kvdl_index,
  40                                       char *enc_actions, bool is_first)
  41 {
  42         return mlxsw_sp_act_kvdl_set_add(priv, p_kvdl_index, enc_actions,
  43                                          is_first, false);
  44 }
  45 
  46 static int mlxsw_sp2_act_kvdl_set_add(void *priv, u32 *p_kvdl_index,
  47                                       char *enc_actions, bool is_first)
  48 {
  49         return mlxsw_sp_act_kvdl_set_add(priv, p_kvdl_index, enc_actions,
  50                                          is_first, true);
  51 }
  52 
  53 static void mlxsw_sp_act_kvdl_set_del(void *priv, u32 kvdl_index,
  54                                       bool is_first)
  55 {
  56         struct mlxsw_sp *mlxsw_sp = priv;
  57 
  58         if (is_first)
  59                 return;
  60         mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ACTSET,
  61                            1, kvdl_index);
  62 }
  63 
  64 static int mlxsw_sp1_act_kvdl_set_activity_get(void *priv, u32 kvdl_index,
  65                                                bool *activity)
  66 {
  67         return -EOPNOTSUPP;
  68 }
  69 
  70 static int mlxsw_sp2_act_kvdl_set_activity_get(void *priv, u32 kvdl_index,
  71                                                bool *activity)
  72 {
  73         struct mlxsw_sp *mlxsw_sp = priv;
  74         char pefa_pl[MLXSW_REG_PEFA_LEN];
  75         int err;
  76 
  77         mlxsw_reg_pefa_pack(pefa_pl, kvdl_index, true, NULL);
  78         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pefa), pefa_pl);
  79         if (err)
  80                 return err;
  81         mlxsw_reg_pefa_unpack(pefa_pl, activity);
  82         return 0;
  83 }
  84 
  85 static int mlxsw_sp_act_kvdl_fwd_entry_add(void *priv, u32 *p_kvdl_index,
  86                                            u8 local_port)
  87 {
  88         struct mlxsw_sp *mlxsw_sp = priv;
  89         char ppbs_pl[MLXSW_REG_PPBS_LEN];
  90         u32 kvdl_index;
  91         int err;
  92 
  93         err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_PBS,
  94                                   1, &kvdl_index);
  95         if (err)
  96                 return err;
  97         mlxsw_reg_ppbs_pack(ppbs_pl, kvdl_index, local_port);
  98         err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ppbs), ppbs_pl);
  99         if (err)
 100                 goto err_ppbs_write;
 101         *p_kvdl_index = kvdl_index;
 102         return 0;
 103 
 104 err_ppbs_write:
 105         mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_PBS,
 106                            1, kvdl_index);
 107         return err;
 108 }
 109 
 110 static void mlxsw_sp_act_kvdl_fwd_entry_del(void *priv, u32 kvdl_index)
 111 {
 112         struct mlxsw_sp *mlxsw_sp = priv;
 113 
 114         mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_PBS,
 115                            1, kvdl_index);
 116 }
 117 
 118 static int
 119 mlxsw_sp_act_counter_index_get(void *priv, unsigned int *p_counter_index)
 120 {
 121         struct mlxsw_sp *mlxsw_sp = priv;
 122 
 123         return mlxsw_sp_flow_counter_alloc(mlxsw_sp, p_counter_index);
 124 }
 125 
 126 static void
 127 mlxsw_sp_act_counter_index_put(void *priv, unsigned int counter_index)
 128 {
 129         struct mlxsw_sp *mlxsw_sp = priv;
 130 
 131         mlxsw_sp_flow_counter_free(mlxsw_sp, counter_index);
 132 }
 133 
 134 static int
 135 mlxsw_sp_act_mirror_add(void *priv, u8 local_in_port,
 136                         const struct net_device *out_dev,
 137                         bool ingress, int *p_span_id)
 138 {
 139         struct mlxsw_sp_port *in_port;
 140         struct mlxsw_sp *mlxsw_sp = priv;
 141         enum mlxsw_sp_span_type type;
 142 
 143         type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
 144         in_port = mlxsw_sp->ports[local_in_port];
 145 
 146         return mlxsw_sp_span_mirror_add(in_port, out_dev, type,
 147                                         false, p_span_id);
 148 }
 149 
 150 static void
 151 mlxsw_sp_act_mirror_del(void *priv, u8 local_in_port, int span_id, bool ingress)
 152 {
 153         struct mlxsw_sp *mlxsw_sp = priv;
 154         struct mlxsw_sp_port *in_port;
 155         enum mlxsw_sp_span_type type;
 156 
 157         type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
 158         in_port = mlxsw_sp->ports[local_in_port];
 159 
 160         mlxsw_sp_span_mirror_del(in_port, span_id, type, false);
 161 }
 162 
 163 const struct mlxsw_afa_ops mlxsw_sp1_act_afa_ops = {
 164         .kvdl_set_add           = mlxsw_sp1_act_kvdl_set_add,
 165         .kvdl_set_del           = mlxsw_sp_act_kvdl_set_del,
 166         .kvdl_set_activity_get  = mlxsw_sp1_act_kvdl_set_activity_get,
 167         .kvdl_fwd_entry_add     = mlxsw_sp_act_kvdl_fwd_entry_add,
 168         .kvdl_fwd_entry_del     = mlxsw_sp_act_kvdl_fwd_entry_del,
 169         .counter_index_get      = mlxsw_sp_act_counter_index_get,
 170         .counter_index_put      = mlxsw_sp_act_counter_index_put,
 171         .mirror_add             = mlxsw_sp_act_mirror_add,
 172         .mirror_del             = mlxsw_sp_act_mirror_del,
 173 };
 174 
 175 const struct mlxsw_afa_ops mlxsw_sp2_act_afa_ops = {
 176         .kvdl_set_add           = mlxsw_sp2_act_kvdl_set_add,
 177         .kvdl_set_del           = mlxsw_sp_act_kvdl_set_del,
 178         .kvdl_set_activity_get  = mlxsw_sp2_act_kvdl_set_activity_get,
 179         .kvdl_fwd_entry_add     = mlxsw_sp_act_kvdl_fwd_entry_add,
 180         .kvdl_fwd_entry_del     = mlxsw_sp_act_kvdl_fwd_entry_del,
 181         .counter_index_get      = mlxsw_sp_act_counter_index_get,
 182         .counter_index_put      = mlxsw_sp_act_counter_index_put,
 183         .mirror_add             = mlxsw_sp_act_mirror_add,
 184         .mirror_del             = mlxsw_sp_act_mirror_del,
 185         .dummy_first_set        = true,
 186 };
 187 
 188 int mlxsw_sp_afa_init(struct mlxsw_sp *mlxsw_sp)
 189 {
 190         mlxsw_sp->afa = mlxsw_afa_create(MLXSW_CORE_RES_GET(mlxsw_sp->core,
 191                                                             ACL_ACTIONS_PER_SET),
 192                                          mlxsw_sp->afa_ops, mlxsw_sp);
 193         return PTR_ERR_OR_ZERO(mlxsw_sp->afa);
 194 }
 195 
 196 void mlxsw_sp_afa_fini(struct mlxsw_sp *mlxsw_sp)
 197 {
 198         mlxsw_afa_destroy(mlxsw_sp->afa);
 199 }

/* [<][>][^][v][top][bottom][index][help] */