@@ -33,6 +33,10 @@ struct prestera_acl_rule_entry {
33
33
struct {
34
34
u8 valid :1 ;
35
35
} accept , drop , trap ;
36
+ struct {
37
+ u32 id ;
38
+ struct prestera_counter_block * block ;
39
+ } counter ;
36
40
};
37
41
};
38
42
@@ -335,6 +339,10 @@ int prestera_acl_rule_add(struct prestera_switch *sw,
335
339
rule -> re_arg .vtcam_id = ruleset -> vtcam_id ;
336
340
rule -> re_key .prio = rule -> priority ;
337
341
342
+ /* setup counter */
343
+ rule -> re_arg .count .valid = true;
344
+ rule -> re_arg .count .client = PRESTERA_HW_COUNTER_CLIENT_LOOKUP_0 ;
345
+
338
346
rule -> re = prestera_acl_rule_entry_find (sw -> acl , & rule -> re_key );
339
347
err = WARN_ON (rule -> re ) ? - EEXIST : 0 ;
340
348
if (err )
@@ -389,9 +397,20 @@ int prestera_acl_rule_get_stats(struct prestera_acl *acl,
389
397
struct prestera_acl_rule * rule ,
390
398
u64 * packets , u64 * bytes , u64 * last_use )
391
399
{
400
+ u64 current_packets ;
401
+ u64 current_bytes ;
402
+ int err ;
403
+
404
+ err = prestera_counter_stats_get (acl -> sw -> counter ,
405
+ rule -> re -> counter .block ,
406
+ rule -> re -> counter .id ,
407
+ & current_packets , & current_bytes );
408
+ if (err )
409
+ return err ;
410
+
411
+ * packets = current_packets ;
412
+ * bytes = current_bytes ;
392
413
* last_use = jiffies ;
393
- * packets = 0 ;
394
- * bytes = 0 ;
395
414
396
415
return 0 ;
397
416
}
@@ -437,6 +456,12 @@ static int __prestera_acl_rule_entry2hw_add(struct prestera_switch *sw,
437
456
act_hw [act_num ].id = PRESTERA_ACL_RULE_ACTION_TRAP ;
438
457
act_num ++ ;
439
458
}
459
+ /* counter */
460
+ if (e -> counter .block ) {
461
+ act_hw [act_num ].id = PRESTERA_ACL_RULE_ACTION_COUNT ;
462
+ act_hw [act_num ].count .id = e -> counter .id ;
463
+ act_num ++ ;
464
+ }
440
465
441
466
return prestera_hw_vtcam_rule_add (sw , e -> vtcam_id , e -> key .prio ,
442
467
e -> key .match .key , e -> key .match .mask ,
@@ -447,7 +472,8 @@ static void
447
472
__prestera_acl_rule_entry_act_destruct (struct prestera_switch * sw ,
448
473
struct prestera_acl_rule_entry * e )
449
474
{
450
- /* destroy action entry */
475
+ /* counter */
476
+ prestera_counter_put (sw -> counter , e -> counter .block , e -> counter .id );
451
477
}
452
478
453
479
void prestera_acl_rule_entry_destroy (struct prestera_acl * acl ,
@@ -476,8 +502,22 @@ __prestera_acl_rule_entry_act_construct(struct prestera_switch *sw,
476
502
e -> drop .valid = arg -> drop .valid ;
477
503
/* trap */
478
504
e -> trap .valid = arg -> trap .valid ;
505
+ /* counter */
506
+ if (arg -> count .valid ) {
507
+ int err ;
508
+
509
+ err = prestera_counter_get (sw -> counter , arg -> count .client ,
510
+ & e -> counter .block ,
511
+ & e -> counter .id );
512
+ if (err )
513
+ goto err_out ;
514
+ }
479
515
480
516
return 0 ;
517
+
518
+ err_out :
519
+ __prestera_acl_rule_entry_act_destruct (sw , e );
520
+ return - EINVAL ;
481
521
}
482
522
483
523
struct prestera_acl_rule_entry *
0 commit comments