mlxsw: spectrum: Allow fetch-and-clear of flow counters
authorPetr Machata <petrm@nvidia.com>
Fri, 8 Mar 2024 12:59:49 +0000 (13:59 +0100)
committerJakub Kicinski <kuba@kernel.org>
Mon, 11 Mar 2024 21:14:08 +0000 (14:14 -0700)
For the report_delta-like interface like a previous patch has added for
collection of NH group statistics, it's easiest to read the counter and
have the HW clear it right away. Thus, change mlxsw_sp_flow_counter_get()
to take a bool indicating whether this should be done.

Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/r/6a096ede8ee92d5041e3832242c3bbc137198aba.1709901020.git.petrm@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

index ecde2086c703a438da5185556e1479c69adc6c8e..bb642e9bb6cf8be5e532b2664e06f037c459d8ec 100644 (file)
@@ -176,13 +176,15 @@ MLXSW_ITEM32(tx, hdr, fid, 0x08, 16, 16);
 MLXSW_ITEM32(tx, hdr, type, 0x0C, 0, 4);
 
 int mlxsw_sp_flow_counter_get(struct mlxsw_sp *mlxsw_sp,
-                             unsigned int counter_index, u64 *packets,
-                             u64 *bytes)
+                             unsigned int counter_index, bool clear,
+                             u64 *packets, u64 *bytes)
 {
+       enum mlxsw_reg_mgpc_opcode op = clear ? MLXSW_REG_MGPC_OPCODE_CLEAR :
+                                               MLXSW_REG_MGPC_OPCODE_NOP;
        char mgpc_pl[MLXSW_REG_MGPC_LEN];
        int err;
 
-       mlxsw_reg_mgpc_pack(mgpc_pl, counter_index, MLXSW_REG_MGPC_OPCODE_NOP,
+       mlxsw_reg_mgpc_pack(mgpc_pl, counter_index, op,
                            MLXSW_REG_FLOW_COUNTER_SET_TYPE_PACKETS_BYTES);
        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mgpc), mgpc_pl);
        if (err)
index 898d24232935db384eadddf34a53cdc8d901f1df..3beb5d0847ab7ee672a9664d133e316f091b80e9 100644 (file)
@@ -706,8 +706,8 @@ int mlxsw_sp_port_kill_vid(struct net_device *dev,
 int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin,
                           u16 vid_end, bool is_member, bool untagged);
 int mlxsw_sp_flow_counter_get(struct mlxsw_sp *mlxsw_sp,
-                             unsigned int counter_index, u64 *packets,
-                             u64 *bytes);
+                             unsigned int counter_index, bool clear,
+                             u64 *packets, u64 *bytes);
 int mlxsw_sp_flow_counter_alloc(struct mlxsw_sp *mlxsw_sp,
                                unsigned int *p_counter_index);
 void mlxsw_sp_flow_counter_free(struct mlxsw_sp *mlxsw_sp,
index b01b000bc71c145da7fe1b183d551708d92505b2..3e70cee4d2f3e6687d2ca8671842165f43895370 100644 (file)
@@ -1024,7 +1024,7 @@ int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp,
        rulei = mlxsw_sp_acl_rule_rulei(rule);
        if (rulei->counter_valid) {
                err = mlxsw_sp_flow_counter_get(mlxsw_sp, rulei->counter_index,
-                                               &current_packets,
+                                               false, &current_packets,
                                                &current_bytes);
                if (err)
                        return err;
index 221aa6a474eb104ce5be1591e91d134dc4aeb68b..01d81ae3662a117ffb4b125a5794a7614a8143e0 100644 (file)
@@ -361,7 +361,7 @@ static int mlxsw_sp_mr_tcam_route_stats(struct mlxsw_sp *mlxsw_sp,
        struct mlxsw_sp_mr_tcam_route *route = route_priv;
 
        return mlxsw_sp_flow_counter_get(mlxsw_sp, route->counter_index,
-                                        packets, bytes);
+                                        false, packets, bytes);
 }
 
 static int
index 23b54a4040af02369a0e620d06d31ca04b201b92..2df95b5a444fba9a413e4869477fedc0cb5dc8fc 100644 (file)
@@ -2251,7 +2251,7 @@ int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp,
                return -EINVAL;
 
        return mlxsw_sp_flow_counter_get(mlxsw_sp, neigh_entry->counter_index,
-                                        p_counter, NULL);
+                                        false, p_counter, NULL);
 }
 
 static struct mlxsw_sp_neigh_entry *
@@ -3186,7 +3186,7 @@ int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp,
                return -EINVAL;
 
        return mlxsw_sp_flow_counter_get(mlxsw_sp, nh->counter_index,
-                                        p_counter, NULL);
+                                        false, p_counter, NULL);
 }
 
 struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router,