forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
....@@ -7,6 +7,8 @@
77 #include <linux/gfp.h>
88 #include <linux/refcount.h>
99 #include <linux/rhashtable.h>
10
+#define CREATE_TRACE_POINTS
11
+#include <trace/events/mlxsw.h>
1012
1113 #include "reg.h"
1214 #include "core.h"
....@@ -14,8 +16,8 @@
1416 #include "spectrum_acl_tcam.h"
1517 #include "core_acl_flex_keys.h"
1618
17
-#define MLXSW_SP_ACL_ATCAM_LKEY_ID_BLOCK_START 6
18
-#define MLXSW_SP_ACL_ATCAM_LKEY_ID_BLOCK_END 11
19
+#define MLXSW_SP_ACL_ATCAM_LKEY_ID_BLOCK_CLEAR_START 0
20
+#define MLXSW_SP_ACL_ATCAM_LKEY_ID_BLOCK_CLEAR_END 5
1921
2022 struct mlxsw_sp_acl_atcam_lkey_id_ht_key {
2123 char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* MSB blocks */
....@@ -34,7 +36,7 @@
3436 void (*fini)(struct mlxsw_sp_acl_atcam_region *aregion);
3537 struct mlxsw_sp_acl_atcam_lkey_id *
3638 (*lkey_id_get)(struct mlxsw_sp_acl_atcam_region *aregion,
37
- struct mlxsw_sp_acl_rule_info *rulei, u8 erp_id);
39
+ char *enc_key, u8 erp_id);
3840 void (*lkey_id_put)(struct mlxsw_sp_acl_atcam_region *aregion,
3941 struct mlxsw_sp_acl_atcam_lkey_id *lkey_id);
4042 };
....@@ -64,7 +66,7 @@
6466 static bool
6567 mlxsw_sp_acl_atcam_is_centry(const struct mlxsw_sp_acl_atcam_entry *aentry)
6668 {
67
- return mlxsw_sp_acl_erp_is_ctcam_erp(aentry->erp);
69
+ return mlxsw_sp_acl_erp_mask_is_ctcam(aentry->erp_mask);
6870 }
6971
7072 static int
....@@ -90,8 +92,7 @@
9092
9193 static struct mlxsw_sp_acl_atcam_lkey_id *
9294 mlxsw_sp_acl_atcam_generic_lkey_id_get(struct mlxsw_sp_acl_atcam_region *aregion,
93
- struct mlxsw_sp_acl_rule_info *rulei,
94
- u8 erp_id)
95
+ char *enc_key, u8 erp_id)
9596 {
9697 struct mlxsw_sp_acl_atcam_region_generic *region_generic;
9798
....@@ -220,8 +221,7 @@
220221
221222 static struct mlxsw_sp_acl_atcam_lkey_id *
222223 mlxsw_sp_acl_atcam_12kb_lkey_id_get(struct mlxsw_sp_acl_atcam_region *aregion,
223
- struct mlxsw_sp_acl_rule_info *rulei,
224
- u8 erp_id)
224
+ char *enc_key, u8 erp_id)
225225 {
226226 struct mlxsw_sp_acl_atcam_region_12kb *region_12kb = aregion->priv;
227227 struct mlxsw_sp_acl_tcam_region *region = aregion->region;
....@@ -230,9 +230,10 @@
230230 struct mlxsw_afk *afk = mlxsw_sp_acl_afk(mlxsw_sp->acl);
231231 struct mlxsw_sp_acl_atcam_lkey_id *lkey_id;
232232
233
- mlxsw_afk_encode(afk, region->key_info, &rulei->values, ht_key.enc_key,
234
- NULL, MLXSW_SP_ACL_ATCAM_LKEY_ID_BLOCK_START,
235
- MLXSW_SP_ACL_ATCAM_LKEY_ID_BLOCK_END);
233
+ memcpy(ht_key.enc_key, enc_key, sizeof(ht_key.enc_key));
234
+ mlxsw_afk_clear(afk, ht_key.enc_key,
235
+ MLXSW_SP_ACL_ATCAM_LKEY_ID_BLOCK_CLEAR_START,
236
+ MLXSW_SP_ACL_ATCAM_LKEY_ID_BLOCK_CLEAR_END);
236237 ht_key.erp_id = erp_id;
237238 lkey_id = rhashtable_lookup_fast(&region_12kb->lkey_ht, &ht_key,
238239 mlxsw_sp_acl_atcam_lkey_id_ht_params);
....@@ -317,6 +318,7 @@
317318 struct mlxsw_sp_acl_atcam *atcam,
318319 struct mlxsw_sp_acl_atcam_region *aregion,
319320 struct mlxsw_sp_acl_tcam_region *region,
321
+ void *hints_priv,
320322 const struct mlxsw_sp_acl_ctcam_region_ops *ops)
321323 {
322324 int err;
....@@ -324,6 +326,7 @@
324326 aregion->region = region;
325327 aregion->atcam = atcam;
326328 mlxsw_sp_acl_atcam_region_type_init(aregion);
329
+ INIT_LIST_HEAD(&aregion->entries_list);
327330
328331 err = rhashtable_init(&aregion->entries_ht,
329332 &mlxsw_sp_acl_atcam_entries_ht_params);
....@@ -332,7 +335,7 @@
332335 err = aregion->ops->init(aregion);
333336 if (err)
334337 goto err_ops_init;
335
- err = mlxsw_sp_acl_erp_region_init(aregion);
338
+ err = mlxsw_sp_acl_erp_region_init(aregion, hints_priv);
336339 if (err)
337340 goto err_erp_region_init;
338341 err = mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &aregion->cregion,
....@@ -357,6 +360,7 @@
357360 mlxsw_sp_acl_erp_region_fini(aregion);
358361 aregion->ops->fini(aregion);
359362 rhashtable_destroy(&aregion->entries_ht);
363
+ WARN_ON(!list_empty(&aregion->entries_list));
360364 }
361365
362366 void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion,
....@@ -379,7 +383,7 @@
379383 struct mlxsw_sp_acl_rule_info *rulei)
380384 {
381385 struct mlxsw_sp_acl_tcam_region *region = aregion->region;
382
- u8 erp_id = mlxsw_sp_acl_erp_id(aentry->erp);
386
+ u8 erp_id = mlxsw_sp_acl_erp_mask_erp_id(aentry->erp_mask);
383387 struct mlxsw_sp_acl_atcam_lkey_id *lkey_id;
384388 char ptce3_pl[MLXSW_REG_PTCE3_LEN];
385389 u32 kvdl_index, priority;
....@@ -389,7 +393,7 @@
389393 if (err)
390394 return err;
391395
392
- lkey_id = aregion->ops->lkey_id_get(aregion, rulei, erp_id);
396
+ lkey_id = aregion->ops->lkey_id_get(aregion, aentry->enc_key, erp_id);
393397 if (IS_ERR(lkey_id))
394398 return PTR_ERR(lkey_id);
395399 aentry->lkey_id = lkey_id;
....@@ -397,7 +401,10 @@
397401 kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block);
398402 mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_WRITE,
399403 priority, region->tcam_region_info,
400
- aentry->ht_key.enc_key, erp_id,
404
+ aentry->enc_key, erp_id,
405
+ aentry->delta_info.start,
406
+ aentry->delta_info.mask,
407
+ aentry->delta_info.value,
401408 refcount_read(&lkey_id->refcnt) != 1, lkey_id->id,
402409 kvdl_index);
403410 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce3), ptce3_pl);
....@@ -418,15 +425,47 @@
418425 {
419426 struct mlxsw_sp_acl_atcam_lkey_id *lkey_id = aentry->lkey_id;
420427 struct mlxsw_sp_acl_tcam_region *region = aregion->region;
421
- u8 erp_id = mlxsw_sp_acl_erp_id(aentry->erp);
428
+ u8 erp_id = mlxsw_sp_acl_erp_mask_erp_id(aentry->erp_mask);
422429 char ptce3_pl[MLXSW_REG_PTCE3_LEN];
423430
424431 mlxsw_reg_ptce3_pack(ptce3_pl, false, MLXSW_REG_PTCE3_OP_WRITE_WRITE, 0,
425
- region->tcam_region_info, aentry->ht_key.enc_key,
426
- erp_id, refcount_read(&lkey_id->refcnt) != 1,
432
+ region->tcam_region_info,
433
+ aentry->enc_key, erp_id,
434
+ aentry->delta_info.start,
435
+ aentry->delta_info.mask,
436
+ aentry->delta_info.value,
437
+ refcount_read(&lkey_id->refcnt) != 1,
427438 lkey_id->id, 0);
428439 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce3), ptce3_pl);
429440 aregion->ops->lkey_id_put(aregion, lkey_id);
441
+}
442
+
443
+static int
444
+mlxsw_sp_acl_atcam_region_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
445
+ struct mlxsw_sp_acl_atcam_region *aregion,
446
+ struct mlxsw_sp_acl_atcam_entry *aentry,
447
+ struct mlxsw_sp_acl_rule_info *rulei)
448
+{
449
+ struct mlxsw_sp_acl_atcam_lkey_id *lkey_id = aentry->lkey_id;
450
+ u8 erp_id = mlxsw_sp_acl_erp_mask_erp_id(aentry->erp_mask);
451
+ struct mlxsw_sp_acl_tcam_region *region = aregion->region;
452
+ char ptce3_pl[MLXSW_REG_PTCE3_LEN];
453
+ u32 kvdl_index, priority;
454
+ int err;
455
+
456
+ err = mlxsw_sp_acl_tcam_priority_get(mlxsw_sp, rulei, &priority, true);
457
+ if (err)
458
+ return err;
459
+ kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block);
460
+ mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_UPDATE,
461
+ priority, region->tcam_region_info,
462
+ aentry->enc_key, erp_id,
463
+ aentry->delta_info.start,
464
+ aentry->delta_info.mask,
465
+ aentry->delta_info.value,
466
+ refcount_read(&lkey_id->refcnt) != 1, lkey_id->id,
467
+ kvdl_index);
468
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce3), ptce3_pl);
430469 }
431470
432471 static int
....@@ -438,19 +477,37 @@
438477 struct mlxsw_sp_acl_tcam_region *region = aregion->region;
439478 char mask[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN] = { 0 };
440479 struct mlxsw_afk *afk = mlxsw_sp_acl_afk(mlxsw_sp->acl);
441
- struct mlxsw_sp_acl_erp *erp;
442
- unsigned int blocks_count;
480
+ const struct mlxsw_sp_acl_erp_delta *delta;
481
+ struct mlxsw_sp_acl_erp_mask *erp_mask;
443482 int err;
444483
445
- blocks_count = mlxsw_afk_key_info_blocks_count_get(region->key_info);
446484 mlxsw_afk_encode(afk, region->key_info, &rulei->values,
447
- aentry->ht_key.enc_key, mask, 0, blocks_count - 1);
485
+ aentry->ht_key.full_enc_key, mask);
448486
449
- erp = mlxsw_sp_acl_erp_get(aregion, mask, false);
450
- if (IS_ERR(erp))
451
- return PTR_ERR(erp);
452
- aentry->erp = erp;
453
- aentry->ht_key.erp_id = mlxsw_sp_acl_erp_id(erp);
487
+ erp_mask = mlxsw_sp_acl_erp_mask_get(aregion, mask, false);
488
+ if (IS_ERR(erp_mask))
489
+ return PTR_ERR(erp_mask);
490
+ aentry->erp_mask = erp_mask;
491
+ aentry->ht_key.erp_id = mlxsw_sp_acl_erp_mask_erp_id(erp_mask);
492
+ memcpy(aentry->enc_key, aentry->ht_key.full_enc_key,
493
+ sizeof(aentry->enc_key));
494
+
495
+ /* Compute all needed delta information and clear the delta bits
496
+ * from the encrypted key.
497
+ */
498
+ delta = mlxsw_sp_acl_erp_delta(aentry->erp_mask);
499
+ aentry->delta_info.start = mlxsw_sp_acl_erp_delta_start(delta);
500
+ aentry->delta_info.mask = mlxsw_sp_acl_erp_delta_mask(delta);
501
+ aentry->delta_info.value =
502
+ mlxsw_sp_acl_erp_delta_value(delta,
503
+ aentry->ht_key.full_enc_key);
504
+ mlxsw_sp_acl_erp_delta_clear(delta, aentry->enc_key);
505
+
506
+ /* Add rule to the list of A-TCAM rules, assuming this
507
+ * rule is intended to A-TCAM. In case this rule does
508
+ * not fit into A-TCAM it will be removed from the list.
509
+ */
510
+ list_add(&aentry->list, &aregion->entries_list);
454511
455512 /* We can't insert identical rules into the A-TCAM, so fail and
456513 * let the rule spill into C-TCAM
....@@ -461,6 +518,13 @@
461518 if (err)
462519 goto err_rhashtable_insert;
463520
521
+ /* Bloom filter must be updated here, before inserting the rule into
522
+ * the A-TCAM.
523
+ */
524
+ err = mlxsw_sp_acl_erp_bf_insert(mlxsw_sp, aregion, erp_mask, aentry);
525
+ if (err)
526
+ goto err_bf_insert;
527
+
464528 err = mlxsw_sp_acl_atcam_region_entry_insert(mlxsw_sp, aregion, aentry,
465529 rulei);
466530 if (err)
....@@ -469,10 +533,13 @@
469533 return 0;
470534
471535 err_rule_insert:
536
+ mlxsw_sp_acl_erp_bf_remove(mlxsw_sp, aregion, erp_mask, aentry);
537
+err_bf_insert:
472538 rhashtable_remove_fast(&aregion->entries_ht, &aentry->ht_node,
473539 mlxsw_sp_acl_atcam_entries_ht_params);
474540 err_rhashtable_insert:
475
- mlxsw_sp_acl_erp_put(aregion, erp);
541
+ list_del(&aentry->list);
542
+ mlxsw_sp_acl_erp_mask_put(aregion, erp_mask);
476543 return err;
477544 }
478545
....@@ -482,9 +549,21 @@
482549 struct mlxsw_sp_acl_atcam_entry *aentry)
483550 {
484551 mlxsw_sp_acl_atcam_region_entry_remove(mlxsw_sp, aregion, aentry);
552
+ mlxsw_sp_acl_erp_bf_remove(mlxsw_sp, aregion, aentry->erp_mask, aentry);
485553 rhashtable_remove_fast(&aregion->entries_ht, &aentry->ht_node,
486554 mlxsw_sp_acl_atcam_entries_ht_params);
487
- mlxsw_sp_acl_erp_put(aregion, aentry->erp);
555
+ list_del(&aentry->list);
556
+ mlxsw_sp_acl_erp_mask_put(aregion, aentry->erp_mask);
557
+}
558
+
559
+static int
560
+__mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
561
+ struct mlxsw_sp_acl_atcam_region *aregion,
562
+ struct mlxsw_sp_acl_atcam_entry *aentry,
563
+ struct mlxsw_sp_acl_rule_info *rulei)
564
+{
565
+ return mlxsw_sp_acl_atcam_region_entry_action_replace(mlxsw_sp, aregion,
566
+ aentry, rulei);
488567 }
489568
490569 int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
....@@ -502,6 +581,7 @@
502581 /* It is possible we failed to add the rule to the A-TCAM due to
503582 * exceeded number of masks. Try to spill into C-TCAM.
504583 */
584
+ trace_mlxsw_sp_acl_atcam_entry_add_ctcam_spill(mlxsw_sp, aregion);
505585 err = mlxsw_sp_acl_ctcam_entry_add(mlxsw_sp, &aregion->cregion,
506586 &achunk->cchunk, &aentry->centry,
507587 rulei, true);
....@@ -523,6 +603,27 @@
523603 __mlxsw_sp_acl_atcam_entry_del(mlxsw_sp, aregion, aentry);
524604 }
525605
606
+int
607
+mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
608
+ struct mlxsw_sp_acl_atcam_region *aregion,
609
+ struct mlxsw_sp_acl_atcam_entry *aentry,
610
+ struct mlxsw_sp_acl_rule_info *rulei)
611
+{
612
+ int err;
613
+
614
+ if (mlxsw_sp_acl_atcam_is_centry(aentry))
615
+ err = mlxsw_sp_acl_ctcam_entry_action_replace(mlxsw_sp,
616
+ &aregion->cregion,
617
+ &aentry->centry,
618
+ rulei);
619
+ else
620
+ err = __mlxsw_sp_acl_atcam_entry_action_replace(mlxsw_sp,
621
+ aregion, aentry,
622
+ rulei);
623
+
624
+ return err;
625
+}
626
+
526627 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
527628 struct mlxsw_sp_acl_atcam *atcam)
528629 {
....@@ -534,3 +635,14 @@
534635 {
535636 mlxsw_sp_acl_erps_fini(mlxsw_sp, atcam);
536637 }
638
+
639
+void *
640
+mlxsw_sp_acl_atcam_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion)
641
+{
642
+ return mlxsw_sp_acl_erp_rehash_hints_get(aregion);
643
+}
644
+
645
+void mlxsw_sp_acl_atcam_rehash_hints_put(void *hints_priv)
646
+{
647
+ mlxsw_sp_acl_erp_rehash_hints_put(hints_priv);
648
+}