Commit 5af946f4 authored by Daniel Machon's avatar Daniel Machon Committed by David S. Miller

net: sparx5: add support for matchall mirror stats

Add support for tc matchall mirror stats. When a new matchall mirror
rule is added, the baseline stats for that port is saved.
Signed-off-by: default avatarDaniel Machon <daniel.machon@microchip.com>
Reviewed-by: default avatarSteen Hegelund <Steen.Hegelund@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2ac99ed9
...@@ -174,6 +174,7 @@ struct sparx5_port { ...@@ -174,6 +174,7 @@ struct sparx5_port {
struct phylink_config phylink_config; struct phylink_config phylink_config;
struct phylink *phylink; struct phylink *phylink;
struct phylink_pcs phylink_pcs; struct phylink_pcs phylink_pcs;
struct flow_stats mirror_stats;
u16 portno; u16 portno;
/* Ingress default VLAN (pvid) */ /* Ingress default VLAN (pvid) */
u16 pvid; u16 pvid;
...@@ -562,6 +563,8 @@ void sparx5_new_base_time(struct sparx5 *sparx5, const u32 cycle_time, ...@@ -562,6 +563,8 @@ void sparx5_new_base_time(struct sparx5 *sparx5, const u32 cycle_time,
/* sparx5_mirror.c */ /* sparx5_mirror.c */
int sparx5_mirror_add(struct sparx5_mall_entry *entry); int sparx5_mirror_add(struct sparx5_mall_entry *entry);
void sparx5_mirror_del(struct sparx5_mall_entry *entry); void sparx5_mirror_del(struct sparx5_mall_entry *entry);
void sparx5_mirror_stats(struct sparx5_mall_entry *entry,
struct flow_stats *fstats);
/* Clock period in picoseconds */ /* Clock period in picoseconds */
static inline u32 sparx5_clk_period(enum sparx5_core_clockfreq cclock) static inline u32 sparx5_clk_period(enum sparx5_core_clockfreq cclock)
......
...@@ -196,3 +196,40 @@ void sparx5_mirror_del(struct sparx5_mall_entry *entry) ...@@ -196,3 +196,40 @@ void sparx5_mirror_del(struct sparx5_mall_entry *entry)
mirror_idx, mirror_idx,
SPX5_MIRROR_MONITOR_PORT_DEFAULT); SPX5_MIRROR_MONITOR_PORT_DEFAULT);
} }
void sparx5_mirror_stats(struct sparx5_mall_entry *entry,
struct flow_stats *fstats)
{
struct sparx5_port *port = entry->port;
struct rtnl_link_stats64 new_stats;
struct flow_stats *old_stats;
old_stats = &entry->port->mirror_stats;
sparx5_get_stats64(port->ndev, &new_stats);
if (entry->ingress) {
flow_stats_update(fstats,
new_stats.rx_bytes - old_stats->bytes,
new_stats.rx_packets - old_stats->pkts,
new_stats.rx_dropped - old_stats->drops,
old_stats->lastused,
FLOW_ACTION_HW_STATS_IMMEDIATE);
old_stats->bytes = new_stats.rx_bytes;
old_stats->pkts = new_stats.rx_packets;
old_stats->drops = new_stats.rx_dropped;
old_stats->lastused = jiffies;
} else {
flow_stats_update(fstats,
new_stats.tx_bytes - old_stats->bytes,
new_stats.tx_packets - old_stats->pkts,
new_stats.tx_dropped - old_stats->drops,
old_stats->lastused,
FLOW_ACTION_HW_STATS_IMMEDIATE);
old_stats->bytes = new_stats.tx_bytes;
old_stats->pkts = new_stats.tx_packets;
old_stats->drops = new_stats.tx_dropped;
old_stats->lastused = jiffies;
}
}
...@@ -96,6 +96,8 @@ static int sparx5_tc_matchall_replace(struct net_device *ndev, ...@@ -96,6 +96,8 @@ static int sparx5_tc_matchall_replace(struct net_device *ndev,
} }
return err; return err;
} }
/* Get baseline stats for this port */
sparx5_mirror_stats(mall_entry, &tmo->stats);
break; break;
case FLOW_ACTION_GOTO: case FLOW_ACTION_GOTO:
err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev, err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev,
...@@ -162,6 +164,29 @@ static int sparx5_tc_matchall_destroy(struct net_device *ndev, ...@@ -162,6 +164,29 @@ static int sparx5_tc_matchall_destroy(struct net_device *ndev,
return err; return err;
} }
static int sparx5_tc_matchall_stats(struct net_device *ndev,
struct tc_cls_matchall_offload *tmo,
bool ingress)
{
struct sparx5_port *port = netdev_priv(ndev);
struct sparx5 *sparx5 = port->sparx5;
struct sparx5_mall_entry *entry;
entry = sparx5_tc_matchall_entry_find(&sparx5->mall_entries,
tmo->cookie);
if (!entry)
return -ENOENT;
if (entry->type == FLOW_ACTION_MIRRED) {
sparx5_mirror_stats(entry, &tmo->stats);
} else {
NL_SET_ERR_MSG_MOD(tmo->common.extack, "Unsupported action");
return -EOPNOTSUPP;
}
return 0;
}
int sparx5_tc_matchall(struct net_device *ndev, int sparx5_tc_matchall(struct net_device *ndev,
struct tc_cls_matchall_offload *tmo, struct tc_cls_matchall_offload *tmo,
bool ingress) bool ingress)
...@@ -171,6 +196,8 @@ int sparx5_tc_matchall(struct net_device *ndev, ...@@ -171,6 +196,8 @@ int sparx5_tc_matchall(struct net_device *ndev,
return sparx5_tc_matchall_replace(ndev, tmo, ingress); return sparx5_tc_matchall_replace(ndev, tmo, ingress);
case TC_CLSMATCHALL_DESTROY: case TC_CLSMATCHALL_DESTROY:
return sparx5_tc_matchall_destroy(ndev, tmo, ingress); return sparx5_tc_matchall_destroy(ndev, tmo, ingress);
case TC_CLSMATCHALL_STATS:
return sparx5_tc_matchall_stats(ndev, tmo, ingress);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment