Skip to content

Commit 2507a64

Browse files
nirdotandavem330
authored andcommitted
mlxsw: spectrum_acl: Add replace rule action operation
Multicast routes actions may be updated after creation. An example for that is an addition of an egress interface to an existing route. So far, as tc flower API dictated, ACL rules were either created or deleted. Since multicast routes in Spectrum-2 are written to ACL as any rule, it is required to allow the update of a rule's action as it may change. Add methods and operations to support updating rule's action. This is supported only for Spectrum-2. Signed-off-by: Nir Dotan <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1a29d29 commit 2507a64

File tree

8 files changed

+194
-0
lines changed

8 files changed

+194
-0
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,9 @@ int mlxsw_sp_acl_rule_add(struct mlxsw_sp *mlxsw_sp,
658658
struct mlxsw_sp_acl_rule *rule);
659659
void mlxsw_sp_acl_rule_del(struct mlxsw_sp *mlxsw_sp,
660660
struct mlxsw_sp_acl_rule *rule);
661+
int mlxsw_sp_acl_rule_action_replace(struct mlxsw_sp *mlxsw_sp,
662+
struct mlxsw_sp_acl_rule *rule,
663+
struct mlxsw_afa_block *afa_block);
661664
struct mlxsw_sp_acl_rule *
662665
mlxsw_sp_acl_rule_lookup(struct mlxsw_sp *mlxsw_sp,
663666
struct mlxsw_sp_acl_ruleset *ruleset,
@@ -702,6 +705,10 @@ struct mlxsw_sp_acl_tcam_ops {
702705
void (*entry_del)(struct mlxsw_sp *mlxsw_sp,
703706
void *region_priv, void *chunk_priv,
704707
void *entry_priv);
708+
int (*entry_action_replace)(struct mlxsw_sp *mlxsw_sp,
709+
void *region_priv, void *chunk_priv,
710+
void *entry_priv,
711+
struct mlxsw_sp_acl_rule_info *rulei);
705712
int (*entry_activity_get)(struct mlxsw_sp *mlxsw_sp,
706713
void *region_priv, void *entry_priv,
707714
bool *activity);

drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,15 @@ static void mlxsw_sp1_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
192192
&chunk->cchunk, &entry->centry);
193193
}
194194

195+
static int
196+
mlxsw_sp1_acl_tcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
197+
void *region_priv, void *chunk_priv,
198+
void *entry_priv,
199+
struct mlxsw_sp_acl_rule_info *rulei)
200+
{
201+
return -EOPNOTSUPP;
202+
}
203+
195204
static int
196205
mlxsw_sp1_acl_tcam_region_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
197206
struct mlxsw_sp_acl_tcam_region *_region,
@@ -240,5 +249,6 @@ const struct mlxsw_sp_acl_tcam_ops mlxsw_sp1_acl_tcam_ops = {
240249
.entry_priv_size = sizeof(struct mlxsw_sp1_acl_tcam_entry),
241250
.entry_add = mlxsw_sp1_acl_tcam_entry_add,
242251
.entry_del = mlxsw_sp1_acl_tcam_entry_del,
252+
.entry_action_replace = mlxsw_sp1_acl_tcam_entry_action_replace,
243253
.entry_activity_get = mlxsw_sp1_acl_tcam_entry_activity_get,
244254
};

drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,23 @@ static void mlxsw_sp2_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
210210
&entry->aentry);
211211
}
212212

213+
static int
214+
mlxsw_sp2_acl_tcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
215+
void *region_priv, void *chunk_priv,
216+
void *entry_priv,
217+
struct mlxsw_sp_acl_rule_info *rulei)
218+
{
219+
struct mlxsw_sp2_acl_tcam_region *region = region_priv;
220+
struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv;
221+
struct mlxsw_sp2_acl_tcam_entry *entry = entry_priv;
222+
223+
entry->act_block = rulei->act_block;
224+
return mlxsw_sp_acl_atcam_entry_action_replace(mlxsw_sp,
225+
&region->aregion,
226+
&chunk->achunk,
227+
&entry->aentry, rulei);
228+
}
229+
213230
static int
214231
mlxsw_sp2_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
215232
void *region_priv, void *entry_priv,
@@ -235,5 +252,6 @@ const struct mlxsw_sp_acl_tcam_ops mlxsw_sp2_acl_tcam_ops = {
235252
.entry_priv_size = sizeof(struct mlxsw_sp2_acl_tcam_entry),
236253
.entry_add = mlxsw_sp2_acl_tcam_entry_add,
237254
.entry_del = mlxsw_sp2_acl_tcam_entry_del,
255+
.entry_action_replace = mlxsw_sp2_acl_tcam_entry_action_replace,
238256
.entry_activity_get = mlxsw_sp2_acl_tcam_entry_activity_get,
239257
};

drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,21 @@ void mlxsw_sp_acl_rule_del(struct mlxsw_sp *mlxsw_sp,
721721
ops->rule_del(mlxsw_sp, rule->priv);
722722
}
723723

724+
int mlxsw_sp_acl_rule_action_replace(struct mlxsw_sp *mlxsw_sp,
725+
struct mlxsw_sp_acl_rule *rule,
726+
struct mlxsw_afa_block *afa_block)
727+
{
728+
struct mlxsw_sp_acl_ruleset *ruleset = rule->ruleset;
729+
const struct mlxsw_sp_acl_profile_ops *ops = ruleset->ht_key.ops;
730+
struct mlxsw_sp_acl_rule_info *rulei;
731+
732+
rulei = mlxsw_sp_acl_rule_rulei(rule);
733+
rulei->act_block = afa_block;
734+
735+
return ops->rule_action_replace(mlxsw_sp, ruleset->priv, rule->priv,
736+
rule->rulei);
737+
}
738+
724739
struct mlxsw_sp_acl_rule *
725740
mlxsw_sp_acl_rule_lookup(struct mlxsw_sp *mlxsw_sp,
726741
struct mlxsw_sp_acl_ruleset *ruleset,

drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,34 @@ mlxsw_sp_acl_atcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp,
437437
aregion->ops->lkey_id_put(aregion, lkey_id);
438438
}
439439

440+
static int
441+
mlxsw_sp_acl_atcam_region_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
442+
struct mlxsw_sp_acl_atcam_region *aregion,
443+
struct mlxsw_sp_acl_atcam_entry *aentry,
444+
struct mlxsw_sp_acl_rule_info *rulei)
445+
{
446+
struct mlxsw_sp_acl_atcam_lkey_id *lkey_id = aentry->lkey_id;
447+
u8 erp_id = mlxsw_sp_acl_erp_mask_erp_id(aentry->erp_mask);
448+
struct mlxsw_sp_acl_tcam_region *region = aregion->region;
449+
char ptce3_pl[MLXSW_REG_PTCE3_LEN];
450+
u32 kvdl_index, priority;
451+
int err;
452+
453+
err = mlxsw_sp_acl_tcam_priority_get(mlxsw_sp, rulei, &priority, true);
454+
if (err)
455+
return err;
456+
kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block);
457+
mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_UPDATE,
458+
priority, region->tcam_region_info,
459+
aentry->ht_key.enc_key, erp_id,
460+
aentry->delta_info.start,
461+
aentry->delta_info.mask,
462+
aentry->delta_info.value,
463+
refcount_read(&lkey_id->refcnt) != 1, lkey_id->id,
464+
kvdl_index);
465+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce3), ptce3_pl);
466+
}
467+
440468
static int
441469
__mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
442470
struct mlxsw_sp_acl_atcam_region *aregion,
@@ -506,6 +534,16 @@ __mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
506534
mlxsw_sp_acl_erp_mask_put(aregion, aentry->erp_mask);
507535
}
508536

537+
static int
538+
__mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
539+
struct mlxsw_sp_acl_atcam_region *aregion,
540+
struct mlxsw_sp_acl_atcam_entry *aentry,
541+
struct mlxsw_sp_acl_rule_info *rulei)
542+
{
543+
return mlxsw_sp_acl_atcam_region_entry_action_replace(mlxsw_sp, aregion,
544+
aentry, rulei);
545+
}
546+
509547
int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
510548
struct mlxsw_sp_acl_atcam_region *aregion,
511549
struct mlxsw_sp_acl_atcam_chunk *achunk,
@@ -542,6 +580,29 @@ void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
542580
__mlxsw_sp_acl_atcam_entry_del(mlxsw_sp, aregion, aentry);
543581
}
544582

583+
int
584+
mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
585+
struct mlxsw_sp_acl_atcam_region *aregion,
586+
struct mlxsw_sp_acl_atcam_chunk *achunk,
587+
struct mlxsw_sp_acl_atcam_entry *aentry,
588+
struct mlxsw_sp_acl_rule_info *rulei)
589+
{
590+
int err;
591+
592+
if (mlxsw_sp_acl_atcam_is_centry(aentry))
593+
err = mlxsw_sp_acl_ctcam_entry_action_replace(mlxsw_sp,
594+
&aregion->cregion,
595+
&achunk->cchunk,
596+
&aentry->centry,
597+
rulei);
598+
else
599+
err = __mlxsw_sp_acl_atcam_entry_action_replace(mlxsw_sp,
600+
aregion, aentry,
601+
rulei);
602+
603+
return err;
604+
}
605+
545606
int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
546607
struct mlxsw_sp_acl_atcam *atcam)
547608
{

drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_ctcam.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,27 @@ mlxsw_sp_acl_ctcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp,
8989
cregion->ops->entry_remove(cregion, centry);
9090
}
9191

92+
static int
93+
mlxsw_sp_acl_ctcam_region_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
94+
struct mlxsw_sp_acl_ctcam_region *cregion,
95+
struct mlxsw_sp_acl_ctcam_entry *centry,
96+
struct mlxsw_afa_block *afa_block,
97+
unsigned int priority)
98+
{
99+
char ptce2_pl[MLXSW_REG_PTCE2_LEN];
100+
char *act_set;
101+
102+
mlxsw_reg_ptce2_pack(ptce2_pl, true, MLXSW_REG_PTCE2_OP_WRITE_UPDATE,
103+
cregion->region->tcam_region_info,
104+
centry->parman_item.index, priority);
105+
106+
act_set = mlxsw_afa_block_first_set(afa_block);
107+
mlxsw_reg_ptce2_flex_action_set_memcpy_to(ptce2_pl, act_set);
108+
109+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce2), ptce2_pl);
110+
}
111+
112+
92113
static int mlxsw_sp_acl_ctcam_region_parman_resize(void *priv,
93114
unsigned long new_count)
94115
{
@@ -191,3 +212,15 @@ void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
191212
parman_item_remove(cregion->parman, &cchunk->parman_prio,
192213
&centry->parman_item);
193214
}
215+
216+
int mlxsw_sp_acl_ctcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
217+
struct mlxsw_sp_acl_ctcam_region *cregion,
218+
struct mlxsw_sp_acl_ctcam_chunk *cchunk,
219+
struct mlxsw_sp_acl_ctcam_entry *centry,
220+
struct mlxsw_sp_acl_rule_info *rulei)
221+
{
222+
return mlxsw_sp_acl_ctcam_region_entry_action_replace(mlxsw_sp, cregion,
223+
centry,
224+
rulei->act_block,
225+
rulei->priority);
226+
}

drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,20 @@ static void mlxsw_sp_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
778778
mlxsw_sp_acl_tcam_chunk_put(mlxsw_sp, chunk);
779779
}
780780

781+
static int
782+
mlxsw_sp_acl_tcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
783+
struct mlxsw_sp_acl_tcam_group *group,
784+
struct mlxsw_sp_acl_tcam_entry *entry,
785+
struct mlxsw_sp_acl_rule_info *rulei)
786+
{
787+
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
788+
struct mlxsw_sp_acl_tcam_chunk *chunk = entry->chunk;
789+
struct mlxsw_sp_acl_tcam_region *region = chunk->region;
790+
791+
return ops->entry_action_replace(mlxsw_sp, region->priv, chunk->priv,
792+
entry->priv, rulei);
793+
}
794+
781795
static int
782796
mlxsw_sp_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
783797
struct mlxsw_sp_acl_tcam_entry *entry,
@@ -938,6 +952,15 @@ mlxsw_sp_acl_tcam_flower_rule_del(struct mlxsw_sp *mlxsw_sp, void *rule_priv)
938952
mlxsw_sp_acl_tcam_entry_del(mlxsw_sp, &rule->entry);
939953
}
940954

955+
static int
956+
mlxsw_sp_acl_tcam_flower_rule_action_replace(struct mlxsw_sp *mlxsw_sp,
957+
void *ruleset_priv,
958+
void *rule_priv,
959+
struct mlxsw_sp_acl_rule_info *rulei)
960+
{
961+
return -EOPNOTSUPP;
962+
}
963+
941964
static int
942965
mlxsw_sp_acl_tcam_flower_rule_activity_get(struct mlxsw_sp *mlxsw_sp,
943966
void *rule_priv, bool *activity)
@@ -958,6 +981,7 @@ static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_flower_ops = {
958981
.rule_priv_size = mlxsw_sp_acl_tcam_flower_rule_priv_size,
959982
.rule_add = mlxsw_sp_acl_tcam_flower_rule_add,
960983
.rule_del = mlxsw_sp_acl_tcam_flower_rule_del,
984+
.rule_action_replace = mlxsw_sp_acl_tcam_flower_rule_action_replace,
961985
.rule_activity_get = mlxsw_sp_acl_tcam_flower_rule_activity_get,
962986
};
963987

@@ -1057,6 +1081,18 @@ mlxsw_sp_acl_tcam_mr_rule_del(struct mlxsw_sp *mlxsw_sp, void *rule_priv)
10571081
mlxsw_sp_acl_tcam_entry_del(mlxsw_sp, &rule->entry);
10581082
}
10591083

1084+
static int
1085+
mlxsw_sp_acl_tcam_mr_rule_action_replace(struct mlxsw_sp *mlxsw_sp,
1086+
void *ruleset_priv, void *rule_priv,
1087+
struct mlxsw_sp_acl_rule_info *rulei)
1088+
{
1089+
struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
1090+
struct mlxsw_sp_acl_tcam_mr_rule *rule = rule_priv;
1091+
1092+
return mlxsw_sp_acl_tcam_entry_action_replace(mlxsw_sp, &ruleset->group,
1093+
&rule->entry, rulei);
1094+
}
1095+
10601096
static int
10611097
mlxsw_sp_acl_tcam_mr_rule_activity_get(struct mlxsw_sp *mlxsw_sp,
10621098
void *rule_priv, bool *activity)
@@ -1077,6 +1113,7 @@ static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_mr_ops = {
10771113
.rule_priv_size = mlxsw_sp_acl_tcam_mr_rule_priv_size,
10781114
.rule_add = mlxsw_sp_acl_tcam_mr_rule_add,
10791115
.rule_del = mlxsw_sp_acl_tcam_mr_rule_del,
1116+
.rule_action_replace = mlxsw_sp_acl_tcam_mr_rule_action_replace,
10801117
.rule_activity_get = mlxsw_sp_acl_tcam_mr_rule_activity_get,
10811118
};
10821119

drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ struct mlxsw_sp_acl_profile_ops {
4848
void *ruleset_priv, void *rule_priv,
4949
struct mlxsw_sp_acl_rule_info *rulei);
5050
void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv);
51+
int (*rule_action_replace)(struct mlxsw_sp *mlxsw_sp,
52+
void *ruleset_priv, void *rule_priv,
53+
struct mlxsw_sp_acl_rule_info *rulei);
5154
int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
5255
bool *activity);
5356
};
@@ -121,6 +124,11 @@ void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
121124
struct mlxsw_sp_acl_ctcam_region *cregion,
122125
struct mlxsw_sp_acl_ctcam_chunk *cchunk,
123126
struct mlxsw_sp_acl_ctcam_entry *centry);
127+
int mlxsw_sp_acl_ctcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
128+
struct mlxsw_sp_acl_ctcam_region *cregion,
129+
struct mlxsw_sp_acl_ctcam_chunk *cchunk,
130+
struct mlxsw_sp_acl_ctcam_entry *centry,
131+
struct mlxsw_sp_acl_rule_info *rulei);
124132
static inline unsigned int
125133
mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
126134
{
@@ -212,6 +220,11 @@ void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
212220
struct mlxsw_sp_acl_atcam_region *aregion,
213221
struct mlxsw_sp_acl_atcam_chunk *achunk,
214222
struct mlxsw_sp_acl_atcam_entry *aentry);
223+
int mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
224+
struct mlxsw_sp_acl_atcam_region *aregion,
225+
struct mlxsw_sp_acl_atcam_chunk *achunk,
226+
struct mlxsw_sp_acl_atcam_entry *aentry,
227+
struct mlxsw_sp_acl_rule_info *rulei);
215228
int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
216229
struct mlxsw_sp_acl_atcam *atcam);
217230
void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,

0 commit comments

Comments
 (0)