summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/microchip/sparx5
diff options
context:
space:
mode:
authorSteen Hegelund <steen.hegelund@microchip.com>2022-11-11 14:05:18 +0100
committerDavid S. Miller <davem@davemloft.net>2022-11-14 11:24:17 +0000
commit40e7fe18abab3880e54e86521307c40ea92676d1 (patch)
treeff4e651ff64e89813a0fd489bd811e08b607d332 /drivers/net/ethernet/microchip/sparx5
parentf13230a474774f2b38dab61eb22b3e494d9f5dc7 (diff)
downloadlinux-40e7fe18abab3880e54e86521307c40ea92676d1.tar.bz2
net: microchip: sparx5: Add support for TC flower filter statistics
This provides flower filter packet statistics (bytes are not supported) via the dedicated IS2 counter feature. All rules having the same TC cookie will contribute to the packet statistics for the filter as they are considered to be part of the same TC flower filter. Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/microchip/sparx5')
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
index b76b8fc567bb..a48baeacc1d2 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
@@ -21,6 +21,11 @@ struct sparx5_tc_flower_parse_usage {
unsigned int used_keys;
};
+struct sparx5_tc_rule_pkt_cnt {
+ u64 cookie;
+ u32 pkts;
+};
+
/* These protocols have dedicated keysets in IS2 and a TC dissector
* ETH_P_ARP does not have a TC dissector
*/
@@ -605,6 +610,20 @@ static int sparx5_tc_flower_action_check(struct vcap_control *vctrl,
return 0;
}
+/* Add a rule counter action - only IS2 is considered for now */
+static int sparx5_tc_add_rule_counter(struct vcap_admin *admin,
+ struct vcap_rule *vrule)
+{
+ int err;
+
+ err = vcap_rule_add_action_u32(vrule, VCAP_AF_CNT_ID, vrule->id);
+ if (err)
+ return err;
+
+ vcap_rule_set_counter_id(vrule, vrule->id);
+ return err;
+}
+
static int sparx5_tc_flower_replace(struct net_device *ndev,
struct flow_cls_offload *fco,
struct vcap_admin *admin)
@@ -630,6 +649,11 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
vrule->cookie = fco->cookie;
sparx5_tc_use_dissectors(fco, admin, vrule, &l3_proto);
+
+ err = sparx5_tc_add_rule_counter(admin, vrule);
+ if (err)
+ goto out;
+
frule = flow_cls_offload_flow_rule(fco);
flow_action_for_each(idx, act, &frule->action) {
switch (act->id) {
@@ -708,6 +732,48 @@ static int sparx5_tc_flower_destroy(struct net_device *ndev,
return err;
}
+/* Collect packet counts from all rules with the same cookie */
+static int sparx5_tc_rule_counter_cb(void *arg, struct vcap_rule *rule)
+{
+ struct sparx5_tc_rule_pkt_cnt *rinfo = arg;
+ struct vcap_counter counter;
+ int err = 0;
+
+ if (rule->cookie == rinfo->cookie) {
+ err = vcap_rule_get_counter(rule, &counter);
+ if (err)
+ return err;
+ rinfo->pkts += counter.value;
+ /* Reset the rule counter */
+ counter.value = 0;
+ vcap_rule_set_counter(rule, &counter);
+ }
+ return err;
+}
+
+static int sparx5_tc_flower_stats(struct net_device *ndev,
+ struct flow_cls_offload *fco,
+ struct vcap_admin *admin)
+{
+ struct sparx5_port *port = netdev_priv(ndev);
+ struct sparx5_tc_rule_pkt_cnt rinfo = {};
+ struct vcap_control *vctrl;
+ ulong lastused = 0;
+ u64 drops = 0;
+ u32 pkts = 0;
+ int err;
+
+ rinfo.cookie = fco->cookie;
+ vctrl = port->sparx5->vcap_ctrl;
+ err = vcap_rule_iter(vctrl, sparx5_tc_rule_counter_cb, &rinfo);
+ if (err)
+ return err;
+ pkts = rinfo.pkts;
+ flow_stats_update(&fco->stats, 0x0, pkts, drops, lastused,
+ FLOW_ACTION_HW_STATS_IMMEDIATE);
+ return err;
+}
+
int sparx5_tc_flower(struct net_device *ndev, struct flow_cls_offload *fco,
bool ingress)
{
@@ -729,6 +795,8 @@ int sparx5_tc_flower(struct net_device *ndev, struct flow_cls_offload *fco,
return sparx5_tc_flower_replace(ndev, fco, admin);
case FLOW_CLS_DESTROY:
return sparx5_tc_flower_destroy(ndev, fco, admin);
+ case FLOW_CLS_STATS:
+ return sparx5_tc_flower_stats(ndev, fco, admin);
default:
return -EOPNOTSUPP;
}