aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@mellanox.com>2018-03-19 03:51:02 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-20 12:11:02 -0400
commit808be37ae323ed5585a3e6257ccb5b435bd1a4b9 (patch)
treee592512f7bc8e8232c8680cde1c0521d178cc8a7
parent7e8c711661ce21ceba5be861b1b3d30f325a4db1 (diff)
mlxsw: spectrum_acl: Adapt ACL configuration to new firmware versions
The driver currently creates empty ACL groups, binds them to the requested port and then fills them with actual ACLs that point to TCAM regions. However, empty ACL groups are considered invalid and upcoming firmware versions are going to forbid their binding. Work around this limitation by only performing the binding after the first ACL was added to the group. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
index 21ed27ae51e3..1c1601a43978 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
@@ -160,6 +160,13 @@ bool mlxsw_sp_acl_block_disabled(struct mlxsw_sp_acl_block *block)
160 return block->disable_count; 160 return block->disable_count;
161} 161}
162 162
163static bool
164mlxsw_sp_acl_ruleset_is_singular(const struct mlxsw_sp_acl_ruleset *ruleset)
165{
166 /* We hold a reference on ruleset ourselves */
167 return ruleset->ref_count == 2;
168}
169
163static int 170static int
164mlxsw_sp_acl_ruleset_bind(struct mlxsw_sp *mlxsw_sp, 171mlxsw_sp_acl_ruleset_bind(struct mlxsw_sp *mlxsw_sp,
165 struct mlxsw_sp_acl_block *block, 172 struct mlxsw_sp_acl_block *block,
@@ -341,21 +348,8 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp,
341 if (err) 348 if (err)
342 goto err_ht_insert; 349 goto err_ht_insert;
343 350
344 if (!chain_index) {
345 /* We only need ruleset with chain index 0, the implicit one,
346 * to be directly bound to device. The rest of the rulesets
347 * are bound by "Goto action set".
348 */
349 err = mlxsw_sp_acl_ruleset_block_bind(mlxsw_sp, ruleset, block);
350 if (err)
351 goto err_ruleset_bind;
352 }
353
354 return ruleset; 351 return ruleset;
355 352
356err_ruleset_bind:
357 rhashtable_remove_fast(&acl->ruleset_ht, &ruleset->ht_node,
358 mlxsw_sp_acl_ruleset_ht_params);
359err_ht_insert: 353err_ht_insert:
360 ops->ruleset_del(mlxsw_sp, ruleset->priv); 354 ops->ruleset_del(mlxsw_sp, ruleset->priv);
361err_ops_ruleset_add: 355err_ops_ruleset_add:
@@ -369,12 +363,8 @@ static void mlxsw_sp_acl_ruleset_destroy(struct mlxsw_sp *mlxsw_sp,
369 struct mlxsw_sp_acl_ruleset *ruleset) 363 struct mlxsw_sp_acl_ruleset *ruleset)
370{ 364{
371 const struct mlxsw_sp_acl_profile_ops *ops = ruleset->ht_key.ops; 365 const struct mlxsw_sp_acl_profile_ops *ops = ruleset->ht_key.ops;
372 struct mlxsw_sp_acl_block *block = ruleset->ht_key.block;
373 u32 chain_index = ruleset->ht_key.chain_index;
374 struct mlxsw_sp_acl *acl = mlxsw_sp->acl; 366 struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
375 367
376 if (!chain_index)
377 mlxsw_sp_acl_ruleset_block_unbind(mlxsw_sp, ruleset, block);
378 rhashtable_remove_fast(&acl->ruleset_ht, &ruleset->ht_node, 368 rhashtable_remove_fast(&acl->ruleset_ht, &ruleset->ht_node,
379 mlxsw_sp_acl_ruleset_ht_params); 369 mlxsw_sp_acl_ruleset_ht_params);
380 ops->ruleset_del(mlxsw_sp, ruleset->priv); 370 ops->ruleset_del(mlxsw_sp, ruleset->priv);
@@ -688,10 +678,25 @@ int mlxsw_sp_acl_rule_add(struct mlxsw_sp *mlxsw_sp,
688 if (err) 678 if (err)
689 goto err_rhashtable_insert; 679 goto err_rhashtable_insert;
690 680
681 if (!ruleset->ht_key.chain_index &&
682 mlxsw_sp_acl_ruleset_is_singular(ruleset)) {
683 /* We only need ruleset with chain index 0, the implicit
684 * one, to be directly bound to device. The rest of the
685 * rulesets are bound by "Goto action set".
686 */
687 err = mlxsw_sp_acl_ruleset_block_bind(mlxsw_sp, ruleset,
688 ruleset->ht_key.block);
689 if (err)
690 goto err_ruleset_block_bind;
691 }
692
691 list_add_tail(&rule->list, &mlxsw_sp->acl->rules); 693 list_add_tail(&rule->list, &mlxsw_sp->acl->rules);
692 ruleset->ht_key.block->rule_count++; 694 ruleset->ht_key.block->rule_count++;
693 return 0; 695 return 0;
694 696
697err_ruleset_block_bind:
698 rhashtable_remove_fast(&ruleset->rule_ht, &rule->ht_node,
699 mlxsw_sp_acl_rule_ht_params);
695err_rhashtable_insert: 700err_rhashtable_insert:
696 ops->rule_del(mlxsw_sp, rule->priv); 701 ops->rule_del(mlxsw_sp, rule->priv);
697 return err; 702 return err;
@@ -705,6 +710,10 @@ void mlxsw_sp_acl_rule_del(struct mlxsw_sp *mlxsw_sp,
705 710
706 ruleset->ht_key.block->rule_count--; 711 ruleset->ht_key.block->rule_count--;
707 list_del(&rule->list); 712 list_del(&rule->list);
713 if (!ruleset->ht_key.chain_index &&
714 mlxsw_sp_acl_ruleset_is_singular(ruleset))
715 mlxsw_sp_acl_ruleset_block_unbind(mlxsw_sp, ruleset,
716 ruleset->ht_key.block);
708 rhashtable_remove_fast(&ruleset->rule_ht, &rule->ht_node, 717 rhashtable_remove_fast(&ruleset->rule_ht, &rule->ht_node,
709 mlxsw_sp_acl_rule_ht_params); 718 mlxsw_sp_acl_rule_ht_params);
710 ops->rule_del(mlxsw_sp, rule->priv); 719 ops->rule_del(mlxsw_sp, rule->priv);