mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-12 06:57:57 +04:00
realtek: dsa: consolidate statistics handling in stats.c
Move hardware statistics helpers and packet counter allocation, read and clear functions into stats.c. Standardize function names on the otto_stats_ prefix, followed by the chip identifier where applicable, and remove redundant stats suffixes. Update declarations, includes, callers and operation tables accordingly. No functional changes intended. Assisted-by: ChatGPT (OpenAI GPT-6 Astra) Link: https://github.com/openwrt/openwrt/pull/25802 Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
This commit is contained in:
1 parent
74521f894e
commit
c8fbe693c3
11 files changed
+468
-452
No files matched your search
@@ -6,7 +6,6 @@
|
||||
#include <net/nexthop.h>
|
||||
#include <net/neighbour.h>
|
||||
#include <net/netevent.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/inetdevice.h>
|
||||
@@ -221,95 +220,6 @@ static int rtldsa_ports_probe(struct rtl838x_switch_priv *priv)
|
||||
// return idx;
|
||||
// }
|
||||
|
||||
/*
|
||||
* Packet counters share hardware memory with octet counters (2 packet counters
|
||||
* per 1 octet block). Allocation relies on two complementary bitmaps:
|
||||
*
|
||||
* octet_cntr_use_bm: 0 = free block, 1 = used (or split into packet counters)
|
||||
* packet_cntr_use_bm: 1 = free standalone counter, 0 = unavailable
|
||||
*
|
||||
* Allocation strategy:
|
||||
* 1. Look for a free standalone counter from an already split block (bit = 1).
|
||||
* 2. If none are free, claim a new octet block 'j', use counter index (2 * j),
|
||||
* and mark counter (2 * j + 1) as available for future allocations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* rtldsa_packet_cntr_alloc - Allocate a hardware packet counter.
|
||||
* @priv: Switch driver private structure.
|
||||
*
|
||||
* Return: Counter index (>= 0) on success, or -1 if full.
|
||||
*/
|
||||
int rtldsa_packet_cntr_alloc(struct rtl838x_switch_priv *priv)
|
||||
{
|
||||
int idx, j, base = 0;
|
||||
|
||||
/* On SoCs where a PIE rule implicitly logs into the LOG table entry
|
||||
* with its own rule ID (RTL930x), the tc cls_flower offload consumes
|
||||
* one LOG counter per PIE rule and does not pass through this
|
||||
* allocator. Keep that range reserved so a route counter handed out
|
||||
* here cannot alias a flow's LOG entry.
|
||||
*
|
||||
* The offload is ingress-only, so PIE rule IDs currently populate
|
||||
* only the lower half of that range, and a route counter's LOG entry
|
||||
* (idx / 2) never dips below the upper half either. If egress PIE
|
||||
* rules are ever wired up, this reservation needs to grow so their
|
||||
* LOG entries stay clear of route counters too.
|
||||
*/
|
||||
if (priv->r->pie_rule_id_is_log_counter)
|
||||
base = priv->r->n_pie_blocks * PIE_BLOCK_SIZE;
|
||||
|
||||
scoped_guard(mutex, &priv->reg_mutex) {
|
||||
idx = find_next_bit(priv->packet_cntr_use_bm, priv->r->n_counters * 2, base);
|
||||
if (idx >= priv->r->n_counters * 2) {
|
||||
j = find_next_zero_bit(priv->octet_cntr_use_bm, priv->r->n_counters,
|
||||
base / 2);
|
||||
if (j >= priv->r->n_counters)
|
||||
return -1;
|
||||
|
||||
__set_bit(j, priv->octet_cntr_use_bm);
|
||||
idx = j * 2;
|
||||
__set_bit(j * 2 + 1, priv->packet_cntr_use_bm);
|
||||
} else {
|
||||
__clear_bit(idx, priv->packet_cntr_use_bm);
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* rtldsa_packet_cntr_free - Release a packet counter from rtldsa_packet_cntr_alloc().
|
||||
* @priv: Switch driver private structure.
|
||||
* @idx: Packet counter index to free; a negative id is ignored.
|
||||
*
|
||||
* Marks the counter free again and, once both halves of its octet block are
|
||||
* free, returns the whole block to the octet counter pool.
|
||||
*/
|
||||
void rtldsa_packet_cntr_free(struct rtl838x_switch_priv *priv, int idx)
|
||||
{
|
||||
int j;
|
||||
|
||||
if (idx < 0 || idx >= priv->r->n_counters * 2)
|
||||
return;
|
||||
|
||||
scoped_guard(mutex, &priv->reg_mutex) {
|
||||
/* already free - guard against a double release */
|
||||
if (test_bit(idx, priv->packet_cntr_use_bm))
|
||||
return;
|
||||
|
||||
__set_bit(idx, priv->packet_cntr_use_bm);
|
||||
|
||||
j = idx / 2;
|
||||
if (test_bit(j, priv->octet_cntr_use_bm) &&
|
||||
test_bit(idx ^ 1, priv->packet_cntr_use_bm)) {
|
||||
__clear_bit(idx, priv->packet_cntr_use_bm);
|
||||
__clear_bit(idx ^ 1, priv->packet_cntr_use_bm);
|
||||
__clear_bit(j, priv->octet_cntr_use_bm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int rtl83xx_port_is_under(const struct net_device *dev, struct rtl838x_switch_priv *priv)
|
||||
{
|
||||
/* Is the lower network device a DSA user network device of our RTL930X-switch?
|
||||
|
||||
@@ -156,8 +156,8 @@ static int rtldsa_83xx_setup(struct dsa_switch *ds)
|
||||
}
|
||||
|
||||
priv->r->print_matrix();
|
||||
rtldsa_stats_init(priv);
|
||||
rtldsa_stats_init_counters(priv);
|
||||
otto_stats_init(priv);
|
||||
otto_stats_init_counters(priv);
|
||||
|
||||
rtldsa_83xx_mc_pmasks_setup(priv);
|
||||
otto_vlan_setup(priv);
|
||||
@@ -206,8 +206,8 @@ static int rtldsa_93xx_setup(struct dsa_switch *ds)
|
||||
priv->r->traffic_set(priv->r->cpu_port, BIT_ULL(priv->r->cpu_port));
|
||||
priv->r->print_matrix();
|
||||
|
||||
rtldsa_stats_init(priv);
|
||||
rtldsa_stats_init_counters(priv);
|
||||
otto_stats_init(priv);
|
||||
otto_stats_init_counters(priv);
|
||||
|
||||
otto_vlan_setup(priv);
|
||||
|
||||
@@ -1249,15 +1249,15 @@ const struct dsa_switch_ops rtldsa_83xx_switch_ops = {
|
||||
|
||||
.phylink_get_caps = rtldsa_phylink_get_caps,
|
||||
|
||||
.get_strings = rtldsa_get_strings,
|
||||
.get_ethtool_stats = rtldsa_get_ethtool_stats,
|
||||
.get_sset_count = rtldsa_get_sset_count,
|
||||
.get_eth_phy_stats = rtldsa_get_eth_phy_stats,
|
||||
.get_eth_mac_stats = rtldsa_get_eth_mac_stats,
|
||||
.get_eth_ctrl_stats = rtldsa_get_eth_ctrl_stats,
|
||||
.get_rmon_stats = rtldsa_get_rmon_stats,
|
||||
.get_stats64 = rtldsa_get_stats64,
|
||||
.get_pause_stats = rtldsa_get_pause_stats,
|
||||
.get_strings = otto_stats_get_strings,
|
||||
.get_ethtool_stats = otto_stats_get_ethtool,
|
||||
.get_sset_count = otto_stats_get_sset_count,
|
||||
.get_eth_phy_stats = otto_stats_get_eth_phy,
|
||||
.get_eth_mac_stats = otto_stats_get_eth_mac,
|
||||
.get_eth_ctrl_stats = otto_stats_get_eth_ctrl,
|
||||
.get_rmon_stats = otto_stats_get_rmon,
|
||||
.get_stats64 = otto_stats_get64,
|
||||
.get_pause_stats = otto_stats_get_pause,
|
||||
|
||||
.port_enable = rtldsa_port_enable,
|
||||
.port_disable = rtldsa_port_disable,
|
||||
@@ -1311,15 +1311,15 @@ const struct dsa_switch_ops rtldsa_93xx_switch_ops = {
|
||||
|
||||
.phylink_get_caps = rtldsa_phylink_get_caps,
|
||||
|
||||
.get_strings = rtldsa_get_strings,
|
||||
.get_ethtool_stats = rtldsa_get_ethtool_stats,
|
||||
.get_sset_count = rtldsa_get_sset_count,
|
||||
.get_eth_phy_stats = rtldsa_get_eth_phy_stats,
|
||||
.get_eth_mac_stats = rtldsa_get_eth_mac_stats,
|
||||
.get_eth_ctrl_stats = rtldsa_get_eth_ctrl_stats,
|
||||
.get_rmon_stats = rtldsa_get_rmon_stats,
|
||||
.get_stats64 = rtldsa_get_stats64,
|
||||
.get_pause_stats = rtldsa_get_pause_stats,
|
||||
.get_strings = otto_stats_get_strings,
|
||||
.get_ethtool_stats = otto_stats_get_ethtool,
|
||||
.get_sset_count = otto_stats_get_sset_count,
|
||||
.get_eth_phy_stats = otto_stats_get_eth_phy,
|
||||
.get_eth_mac_stats = otto_stats_get_eth_mac,
|
||||
.get_eth_ctrl_stats = otto_stats_get_eth_ctrl,
|
||||
.get_rmon_stats = otto_stats_get_rmon,
|
||||
.get_stats64 = otto_stats_get64,
|
||||
.get_pause_stats = otto_stats_get_pause,
|
||||
|
||||
.port_enable = rtldsa_port_enable,
|
||||
.port_disable = rtldsa_port_disable,
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
#include "l3.h"
|
||||
#include "pie.h"
|
||||
#include "rtl-otto.h"
|
||||
#include "stats.h"
|
||||
|
||||
/* Route entry types */
|
||||
#define ROUTE_TYPE_IP4UC 0
|
||||
@@ -1745,7 +1746,7 @@ static void otto_l3_route_update_hw(struct otto_l3_ctrl *ctrl, struct otto_l3_ro
|
||||
return;
|
||||
|
||||
if (r->pr.id < 0) {
|
||||
r->pr.packet_cntr = rtldsa_packet_cntr_alloc(priv);
|
||||
r->pr.packet_cntr = otto_stats_packet_cntr_alloc(priv);
|
||||
if (r->pr.packet_cntr >= 0) {
|
||||
dev_info(ctrl->dev, "Using packet counter %d\n",
|
||||
r->pr.packet_cntr);
|
||||
@@ -2174,7 +2175,7 @@ static void otto_l3_route_teardown(struct otto_l3_ctrl *ctrl, struct otto_l3_rou
|
||||
otto_l2_nexthop_del(priv, &r->nh);
|
||||
|
||||
dev_dbg(ctrl->dev, "releasing packet counter %d\n", r->pr.packet_cntr);
|
||||
rtldsa_packet_cntr_free(priv, r->pr.packet_cntr);
|
||||
otto_stats_packet_cntr_free(priv, r->pr.packet_cntr);
|
||||
|
||||
/* Once the rows are not where the list says, after a failed move or a
|
||||
* lookup that timed out, the row of a prefix route may still be in
|
||||
|
||||
@@ -337,7 +337,7 @@ struct rtldsa_config {
|
||||
* code.
|
||||
*
|
||||
* Any SoC family which requires stat_port_table_read must use the table
|
||||
* rtldsa_counters_(un)lock_table helpers. They are using a mutex for locking. The counters
|
||||
* otto_stats_counters_(un)lock_table helpers. They are using a mutex for locking. The counters
|
||||
* update is therefore not atomic.
|
||||
*/
|
||||
void (*stat_update_counters_atomically)(struct rtl838x_switch_priv *priv, int port);
|
||||
@@ -554,8 +554,6 @@ struct fdb_update_work {
|
||||
};
|
||||
|
||||
void rtldsa_port_fast_age(struct dsa_switch *ds, int port);
|
||||
int rtldsa_packet_cntr_alloc(struct rtl838x_switch_priv *priv);
|
||||
void rtldsa_packet_cntr_free(struct rtl838x_switch_priv *priv, int idx);
|
||||
int rtl83xx_port_is_under(const struct net_device *dev, struct rtl838x_switch_priv *priv);
|
||||
/* Port register accessor functions for the RTL839x and RTL931X SoCs */
|
||||
void rtl839x_mask_port_reg_be(u64 clear, u64 set, int reg);
|
||||
|
||||
@@ -157,46 +157,6 @@ static void rtl838x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
|
||||
priv->eee_enabled = enable;
|
||||
}
|
||||
|
||||
static u32 rtl838x_packet_cntr_read(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
u32 buf[2];
|
||||
u32 v;
|
||||
|
||||
dev_dbg(priv->dev, "reading LOG packet counter %d\n", counter);
|
||||
otto_table_read(RTL8380_TBL_LOG, counter / 2, &buf);
|
||||
|
||||
dev_dbg(priv->dev, "LOG entry: %08x %08x\n", buf[0], buf[1]);
|
||||
if (counter % 2)
|
||||
v = buf[0];
|
||||
else
|
||||
v = buf[1];
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static void rtl838x_packet_cntr_clear(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
int tbl = otto_table_acquire(RTL8380_TBL_LOG);
|
||||
u32 buf[2];
|
||||
|
||||
dev_dbg(priv->dev, "clearing LOG packet counter %d\n", counter);
|
||||
|
||||
/*
|
||||
* Two counters share one LOG table entry. Read the current entry
|
||||
* first so clearing one half preserves the adjacent counter.
|
||||
*/
|
||||
__otto_table_read(tbl, counter / 2, &buf);
|
||||
|
||||
if (counter % 2)
|
||||
buf[0] = 0;
|
||||
else
|
||||
buf[1] = 0;
|
||||
|
||||
__otto_table_write(tbl, counter / 2, &buf);
|
||||
|
||||
otto_table_release(tbl);
|
||||
}
|
||||
|
||||
static void rtl838x_set_igr_filter(int port, enum igr_filter state)
|
||||
{
|
||||
sw_w32_mask(0x3 << ((port & 0xf) << 1), state << ((port & 0xf) << 1),
|
||||
@@ -229,12 +189,6 @@ static void rtl838x_set_receive_management_action(int port, rma_ctrl_t type, act
|
||||
}
|
||||
}
|
||||
|
||||
static void rtldsa_838x_stat_init(struct rtl838x_switch_priv *priv)
|
||||
{
|
||||
/* Enable statistics module: all counters plus debug */
|
||||
sw_w32_mask(0, 3, RTL838X_STAT_CTRL);
|
||||
}
|
||||
|
||||
const struct rtldsa_config rtldsa_838x_cfg = {
|
||||
.switch_ops = &rtldsa_83xx_switch_ops,
|
||||
.phylink_mac_ops = &rtldsa_83xx_phylink_mac_ops,
|
||||
@@ -254,12 +208,12 @@ const struct rtldsa_config rtldsa_838x_cfg = {
|
||||
.get_port_reg_le = rtl838x_get_port_reg,
|
||||
.stat_port_rst = RTL838X_STAT_PORT_RST,
|
||||
.stat_rst = RTL838X_STAT_RST,
|
||||
.stat_init = rtldsa_838x_stat_init,
|
||||
.stat_init = otto_stats_838x_init,
|
||||
.stat_port_std_mib = RTL838X_STAT_PORT_STD_MIB,
|
||||
.mib_desc = &rtldsa_838x_mib_desc,
|
||||
.stat_counters_lock = rtldsa_counters_lock_register,
|
||||
.stat_counters_unlock = rtldsa_counters_unlock_register,
|
||||
.stat_update_counters_atomically = rtldsa_update_counters_atomically,
|
||||
.stat_counters_lock = otto_stats_counters_lock_register,
|
||||
.stat_counters_unlock = otto_stats_counters_unlock_register,
|
||||
.stat_update_counters_atomically = otto_stats_update_counters_atomically,
|
||||
.stat_counter_poll_interval = RTLDSA_COUNTERS_POLL_INTERVAL,
|
||||
.port_iso_ctrl = rtl838x_port_iso_ctrl,
|
||||
.traffic_enable = rtl838x_traffic_enable,
|
||||
@@ -330,8 +284,8 @@ const struct rtldsa_config rtldsa_838x_cfg = {
|
||||
.pie_rule_add = rtl838x_pie_rule_add,
|
||||
.pie_rule_rm = rtl838x_pie_rule_rm,
|
||||
.l2_learning_setup = otto_l2_838x_learning_setup,
|
||||
.packet_cntr_read = rtl838x_packet_cntr_read,
|
||||
.packet_cntr_clear = rtl838x_packet_cntr_clear,
|
||||
.packet_cntr_read = otto_stats_838x_packet_cntr_read,
|
||||
.packet_cntr_clear = otto_stats_838x_packet_cntr_clear,
|
||||
.set_receive_management_action = rtl838x_set_receive_management_action,
|
||||
.get_egress_rate = rtldsa_838x_get_egress_rate,
|
||||
.set_egress_rate = rtldsa_838x_set_egress_rate,
|
||||
|
||||
@@ -157,45 +157,6 @@ static void rtl839x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
|
||||
priv->eee_enabled = enable;
|
||||
}
|
||||
|
||||
static u32 rtl839x_packet_cntr_read(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
u32 buf[2];
|
||||
u32 v;
|
||||
|
||||
dev_dbg(priv->dev, "reading LOG packet counter %d\n", counter);
|
||||
otto_table_read(RTL8390_TBL_LOG, counter / 2, &buf);
|
||||
|
||||
if (counter % 2)
|
||||
v = buf[0];
|
||||
else
|
||||
v = buf[1];
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static void rtl839x_packet_cntr_clear(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
int tbl = otto_table_acquire(RTL8390_TBL_LOG);
|
||||
u32 buf[2];
|
||||
|
||||
dev_dbg(priv->dev, "clearing LOG packet counter %d\n", counter);
|
||||
|
||||
/*
|
||||
* Two counters share one LOG table entry. Read the current entry
|
||||
* first so clearing one half preserves the adjacent counter.
|
||||
*/
|
||||
__otto_table_read(tbl, counter / 2, &buf);
|
||||
|
||||
if (counter % 2)
|
||||
buf[0] = 0;
|
||||
else
|
||||
buf[1] = 0;
|
||||
|
||||
__otto_table_write(tbl, counter / 2, &buf);
|
||||
|
||||
otto_table_release(tbl);
|
||||
}
|
||||
|
||||
static void rtl839x_set_igr_filter(int port, enum igr_filter state)
|
||||
{
|
||||
sw_w32_mask(0x3 << ((port & 0xf) << 1), state << ((port & 0xf) << 1),
|
||||
@@ -249,9 +210,9 @@ const struct rtldsa_config rtldsa_839x_cfg = {
|
||||
.stat_rst = RTL839X_STAT_RST,
|
||||
.stat_port_std_mib = RTL839X_STAT_PORT_STD_MIB,
|
||||
.mib_desc = &rtldsa_839x_mib_desc,
|
||||
.stat_counters_lock = rtldsa_counters_lock_register,
|
||||
.stat_counters_unlock = rtldsa_counters_unlock_register,
|
||||
.stat_update_counters_atomically = rtldsa_update_counters_atomically,
|
||||
.stat_counters_lock = otto_stats_counters_lock_register,
|
||||
.stat_counters_unlock = otto_stats_counters_unlock_register,
|
||||
.stat_update_counters_atomically = otto_stats_update_counters_atomically,
|
||||
.stat_counter_poll_interval = RTLDSA_COUNTERS_POLL_INTERVAL,
|
||||
.traffic_enable = rtl839x_traffic_enable,
|
||||
.traffic_disable = rtl839x_traffic_disable,
|
||||
@@ -320,8 +281,8 @@ const struct rtldsa_config rtldsa_839x_cfg = {
|
||||
.pie_rule_add = rtl839x_pie_rule_add,
|
||||
.pie_rule_rm = rtl839x_pie_rule_rm,
|
||||
.l2_learning_setup = otto_l2_839x_learning_setup,
|
||||
.packet_cntr_read = rtl839x_packet_cntr_read,
|
||||
.packet_cntr_clear = rtl839x_packet_cntr_clear,
|
||||
.packet_cntr_read = otto_stats_839x_packet_cntr_read,
|
||||
.packet_cntr_clear = otto_stats_839x_packet_cntr_clear,
|
||||
.set_receive_management_action = rtl839x_set_receive_management_action,
|
||||
.get_egress_rate = rtldsa_839x_get_egress_rate,
|
||||
.set_egress_rate = rtldsa_839x_set_egress_rate,
|
||||
|
||||
@@ -383,61 +383,6 @@ static void rtl930x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
|
||||
// return mtu_id;
|
||||
// }
|
||||
|
||||
/* A PIE rule logs its matched packets into the LOG table entry that carries
|
||||
* its own rule ID, in data word 1 - one entry per rule. Counters handed out
|
||||
* by rtldsa_packet_cntr_alloc() for L3 route statistics start above the PIE
|
||||
* rule ID range and pack two 32-bit counters into one 64-bit LOG entry.
|
||||
*/
|
||||
#define RTL930X_PIE_RULE_IDS (rtldsa_930x_cfg.n_pie_blocks * PIE_BLOCK_SIZE)
|
||||
|
||||
static u32 rtl930x_packet_cntr_read(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
u32 buf[2];
|
||||
u32 v;
|
||||
|
||||
dev_dbg(priv->dev, "reading LOG packet counter %d\n", counter);
|
||||
|
||||
if (counter < RTL930X_PIE_RULE_IDS) {
|
||||
otto_table_read(RTL9300_TBL_LOG, counter, &buf);
|
||||
v = buf[1];
|
||||
} else {
|
||||
/* Two counters share one entry, so the parity of counter picks
|
||||
* which half of it to return.
|
||||
*/
|
||||
otto_table_read(RTL9300_TBL_LOG, counter / 2, &buf);
|
||||
v = counter % 2 ? buf[0] : buf[1];
|
||||
}
|
||||
|
||||
dev_dbg(priv->dev, "LOG entry: %08x %08x\n", buf[0], buf[1]);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static void rtl930x_packet_cntr_clear(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
int tbl = otto_table_acquire(RTL9300_TBL_LOG);
|
||||
|
||||
u32 v[2];
|
||||
|
||||
dev_dbg(priv->dev, "clearing LOG packet counter %d\n", counter);
|
||||
|
||||
/* Read-modify-write: for a route counter the other 32-bit counter in
|
||||
* the same 64-bit entry must be preserved; for a PIE rule ID the entry
|
||||
* is ours alone but the RMW is harmless.
|
||||
*/
|
||||
if (counter < RTL930X_PIE_RULE_IDS) {
|
||||
__otto_table_read(tbl, counter, &v);
|
||||
v[1] = 0;
|
||||
__otto_table_write(tbl, counter, &v);
|
||||
} else {
|
||||
__otto_table_read(tbl, counter / 2, &v);
|
||||
v[counter % 2 ? 0 : 1] = 0;
|
||||
__otto_table_write(tbl, counter / 2, &v);
|
||||
}
|
||||
|
||||
otto_table_release(tbl);
|
||||
}
|
||||
|
||||
static void rtl930x_set_igr_filter(int port, enum igr_filter state)
|
||||
{
|
||||
sw_w32_mask(0x3 << ((port & 0xf) << 1), state << ((port & 0xf) << 1),
|
||||
@@ -620,9 +565,9 @@ const struct rtldsa_config rtldsa_930x_cfg = {
|
||||
.stat_port_std_mib = RTL930X_STAT_PORT_MIB_CNTR,
|
||||
.stat_port_prv_mib = RTL930X_STAT_PORT_PRVTE_CNTR,
|
||||
.mib_desc = &rtldsa_930x_mib_desc,
|
||||
.stat_counters_lock = rtldsa_counters_lock_register,
|
||||
.stat_counters_unlock = rtldsa_counters_unlock_register,
|
||||
.stat_update_counters_atomically = rtldsa_update_counters_atomically,
|
||||
.stat_counters_lock = otto_stats_counters_lock_register,
|
||||
.stat_counters_unlock = otto_stats_counters_unlock_register,
|
||||
.stat_update_counters_atomically = otto_stats_update_counters_atomically,
|
||||
.stat_counter_poll_interval = RTLDSA_COUNTERS_POLL_INTERVAL,
|
||||
.traffic_enable = rtl930x_traffic_enable,
|
||||
.traffic_disable = rtl930x_traffic_disable,
|
||||
@@ -686,8 +631,8 @@ const struct rtldsa_config rtldsa_930x_cfg = {
|
||||
.pie_rule_add = rtl930x_pie_rule_add,
|
||||
.pie_rule_rm = rtl930x_pie_rule_rm,
|
||||
.l2_learning_setup = otto_l2_930x_learning_setup,
|
||||
.packet_cntr_read = rtl930x_packet_cntr_read,
|
||||
.packet_cntr_clear = rtl930x_packet_cntr_clear,
|
||||
.packet_cntr_read = otto_stats_930x_packet_cntr_read,
|
||||
.packet_cntr_clear = otto_stats_930x_packet_cntr_clear,
|
||||
.led_init = rtl930x_led_init,
|
||||
.enable_learning = otto_l2_930x_enable_learning,
|
||||
.enable_l2_new_sa_fwd = otto_l2_930x_set_port_new_sa_fwd,
|
||||
|
||||
@@ -385,36 +385,6 @@ static void rtldsa_931x_led_init(struct rtl838x_switch_priv *priv)
|
||||
dev_dbg(dev, "%08x: %08x\n", 0xbb000600 + i * 4, sw_r32(0x0600 + i * 4));
|
||||
}
|
||||
|
||||
static u64 rtldsa_931x_stat_port_table_read(int port, unsigned int mib_size,
|
||||
unsigned int mib_offset, bool is_pvt)
|
||||
{
|
||||
enum otto_table_id id;
|
||||
int field_offset;
|
||||
u32 val[2];
|
||||
|
||||
if (is_pvt) {
|
||||
id = RTL9310_TBL_STAT_PORT_PRVTE_CNTR;
|
||||
field_offset = 27;
|
||||
} else {
|
||||
id = RTL9310_TBL_STAT_PORT_MIB_CNTR;
|
||||
field_offset = 52;
|
||||
}
|
||||
|
||||
/* Counter fields are numbered down from the last data word of the
|
||||
* entry, so the high half of a 64 bit counter sits at the lower word
|
||||
* index.
|
||||
*/
|
||||
if (mib_size == 2) {
|
||||
otto_table_offset_read(id, port, &val, field_offset - (mib_offset + 1));
|
||||
|
||||
return (u64)val[0] << 32 | val[1];
|
||||
}
|
||||
|
||||
otto_table_offset_read(id, port, &val[0], field_offset - mib_offset);
|
||||
|
||||
return val[0];
|
||||
}
|
||||
|
||||
const struct rtldsa_config rtldsa_931x_cfg = {
|
||||
.switch_ops = &rtldsa_93xx_switch_ops,
|
||||
.phylink_mac_ops = &rtldsa_93xx_phylink_mac_ops,
|
||||
@@ -436,9 +406,9 @@ const struct rtldsa_config rtldsa_931x_cfg = {
|
||||
.stat_rst = RTL931X_STAT_RST,
|
||||
.stat_port_std_mib = 0, /* Not defined */
|
||||
.mib_desc = &rtldsa_931x_mib_desc,
|
||||
.stat_port_table_read = rtldsa_931x_stat_port_table_read,
|
||||
.stat_counters_lock = rtldsa_counters_lock_table,
|
||||
.stat_counters_unlock = rtldsa_counters_unlock_table,
|
||||
.stat_port_table_read = otto_stats_931x_port_table_read,
|
||||
.stat_counters_lock = otto_stats_counters_lock_table,
|
||||
.stat_counters_unlock = otto_stats_counters_unlock_table,
|
||||
.stat_counter_poll_interval = RTLDSA_COUNTERS_FAST_POLL_INTERVAL,
|
||||
.traffic_enable = rtl931x_traffic_enable,
|
||||
.traffic_disable = rtl931x_traffic_disable,
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/soc/realtek/otto_table.h>
|
||||
#include <linux/string.h>
|
||||
#include <net/dsa.h>
|
||||
|
||||
#include "pie.h"
|
||||
#include "rtl-otto.h"
|
||||
#include "stats.h"
|
||||
|
||||
@@ -368,7 +374,43 @@ const struct rtldsa_mib_desc rtldsa_931x_mib_desc = {
|
||||
.list = rtldsa_931x_mib_list
|
||||
};
|
||||
|
||||
void rtldsa_stats_init(struct rtl838x_switch_priv *priv)
|
||||
void otto_stats_838x_init(struct rtl838x_switch_priv *priv)
|
||||
{
|
||||
/* Enable statistics module: all counters plus debug */
|
||||
sw_w32_mask(0, 3, RTL838X_STAT_CTRL);
|
||||
}
|
||||
|
||||
u64 otto_stats_931x_port_table_read(int port, unsigned int mib_size,
|
||||
unsigned int mib_offset, bool is_pvt)
|
||||
{
|
||||
enum otto_table_id id;
|
||||
int field_offset;
|
||||
u32 val[2];
|
||||
|
||||
if (is_pvt) {
|
||||
id = RTL9310_TBL_STAT_PORT_PRVTE_CNTR;
|
||||
field_offset = 27;
|
||||
} else {
|
||||
id = RTL9310_TBL_STAT_PORT_MIB_CNTR;
|
||||
field_offset = 52;
|
||||
}
|
||||
|
||||
/* Counter fields are numbered down from the last data word of the
|
||||
* entry, so the high half of a 64 bit counter sits at the lower word
|
||||
* index.
|
||||
*/
|
||||
if (mib_size == 2) {
|
||||
otto_table_offset_read(id, port, &val, field_offset - (mib_offset + 1));
|
||||
|
||||
return (u64)val[0] << 32 | val[1];
|
||||
}
|
||||
|
||||
otto_table_offset_read(id, port, &val[0], field_offset - mib_offset);
|
||||
|
||||
return val[0];
|
||||
}
|
||||
|
||||
void otto_stats_init(struct rtl838x_switch_priv *priv)
|
||||
{
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
|
||||
@@ -381,9 +423,9 @@ void rtldsa_stats_init(struct rtl838x_switch_priv *priv)
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
}
|
||||
|
||||
static bool rtldsa_read_mib_item(struct rtl838x_switch_priv *priv, int port,
|
||||
const struct rtldsa_mib_item *mib_item,
|
||||
u64 *data)
|
||||
static bool otto_stats_read_mib_item(struct rtl838x_switch_priv *priv, int port,
|
||||
const struct rtldsa_mib_item *mib_item,
|
||||
u64 *data)
|
||||
{
|
||||
u32 high1, high2;
|
||||
int reg, reg_offset, addr_low;
|
||||
@@ -428,14 +470,14 @@ static bool rtldsa_read_mib_item(struct rtl838x_switch_priv *priv, int port,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rtldsa_update_counter(struct rtl838x_switch_priv *priv, int port,
|
||||
struct rtldsa_counter *counter,
|
||||
const struct rtldsa_mib_item *mib_item)
|
||||
static void otto_stats_update_counter(struct rtl838x_switch_priv *priv, int port,
|
||||
struct rtldsa_counter *counter,
|
||||
const struct rtldsa_mib_item *mib_item)
|
||||
{
|
||||
u64 val;
|
||||
u32 val32, diff;
|
||||
|
||||
if (!rtldsa_read_mib_item(priv, port, mib_item, &val))
|
||||
if (!otto_stats_read_mib_item(priv, port, mib_item, &val))
|
||||
return;
|
||||
|
||||
if (mib_item->size == 2) {
|
||||
@@ -448,8 +490,8 @@ static void rtldsa_update_counter(struct rtl838x_switch_priv *priv, int port,
|
||||
}
|
||||
}
|
||||
|
||||
static void rtldsa_update_link_stat(struct rtnl_link_stats64 *s,
|
||||
const struct rtldsa_counter_state *counters)
|
||||
static void otto_stats_update_link(struct rtnl_link_stats64 *s,
|
||||
const struct rtldsa_counter_state *counters)
|
||||
{
|
||||
s->rx_packets = counters->if_in_ucast_pkts.val +
|
||||
counters->if_in_mcast_pkts.val +
|
||||
@@ -483,7 +525,7 @@ static void rtldsa_update_link_stat(struct rtnl_link_stats64 *s,
|
||||
s->tx_errors = s->tx_aborted_errors + s->tx_window_errors;
|
||||
}
|
||||
|
||||
static void rtldsa_update_port_counters(struct rtl838x_switch_priv *priv, int port)
|
||||
static void otto_stats_update_port_counters(struct rtl838x_switch_priv *priv, int port)
|
||||
{
|
||||
struct rtldsa_counter_state *counters = &priv->ports[port].counters;
|
||||
const struct rtldsa_mib_desc *mib_desc;
|
||||
@@ -500,120 +542,120 @@ static void rtldsa_update_port_counters(struct rtl838x_switch_priv *priv, int po
|
||||
return;
|
||||
counters->last_update = now;
|
||||
|
||||
rtldsa_update_counter(priv, port, &counters->symbol_errors,
|
||||
&mib_desc->symbol_errors);
|
||||
otto_stats_update_counter(priv, port, &counters->symbol_errors,
|
||||
&mib_desc->symbol_errors);
|
||||
|
||||
rtldsa_update_counter(priv, port, &counters->if_in_octets,
|
||||
&mib_desc->if_in_octets);
|
||||
rtldsa_update_counter(priv, port, &counters->if_out_octets,
|
||||
&mib_desc->if_out_octets);
|
||||
rtldsa_update_counter(priv, port, &counters->if_in_ucast_pkts,
|
||||
&mib_desc->if_in_ucast_pkts);
|
||||
rtldsa_update_counter(priv, port, &counters->if_in_mcast_pkts,
|
||||
&mib_desc->if_in_mcast_pkts);
|
||||
rtldsa_update_counter(priv, port, &counters->if_in_bcast_pkts,
|
||||
&mib_desc->if_in_bcast_pkts);
|
||||
rtldsa_update_counter(priv, port, &counters->if_out_ucast_pkts,
|
||||
&mib_desc->if_out_ucast_pkts);
|
||||
rtldsa_update_counter(priv, port, &counters->if_out_mcast_pkts,
|
||||
&mib_desc->if_out_mcast_pkts);
|
||||
rtldsa_update_counter(priv, port, &counters->if_out_bcast_pkts,
|
||||
&mib_desc->if_out_bcast_pkts);
|
||||
rtldsa_update_counter(priv, port, &counters->if_out_discards,
|
||||
&mib_desc->if_out_discards);
|
||||
rtldsa_update_counter(priv, port, &counters->single_collisions,
|
||||
&mib_desc->single_collisions);
|
||||
rtldsa_update_counter(priv, port, &counters->multiple_collisions,
|
||||
&mib_desc->multiple_collisions);
|
||||
rtldsa_update_counter(priv, port, &counters->deferred_transmissions,
|
||||
&mib_desc->deferred_transmissions);
|
||||
rtldsa_update_counter(priv, port, &counters->late_collisions,
|
||||
&mib_desc->late_collisions);
|
||||
rtldsa_update_counter(priv, port, &counters->excessive_collisions,
|
||||
&mib_desc->excessive_collisions);
|
||||
rtldsa_update_counter(priv, port, &counters->crc_align_errors,
|
||||
&mib_desc->crc_align_errors);
|
||||
rtldsa_update_counter(priv, port, &counters->rx_pkts_over_max_octets,
|
||||
&mib_desc->rx_pkts_over_max_octets);
|
||||
otto_stats_update_counter(priv, port, &counters->if_in_octets,
|
||||
&mib_desc->if_in_octets);
|
||||
otto_stats_update_counter(priv, port, &counters->if_out_octets,
|
||||
&mib_desc->if_out_octets);
|
||||
otto_stats_update_counter(priv, port, &counters->if_in_ucast_pkts,
|
||||
&mib_desc->if_in_ucast_pkts);
|
||||
otto_stats_update_counter(priv, port, &counters->if_in_mcast_pkts,
|
||||
&mib_desc->if_in_mcast_pkts);
|
||||
otto_stats_update_counter(priv, port, &counters->if_in_bcast_pkts,
|
||||
&mib_desc->if_in_bcast_pkts);
|
||||
otto_stats_update_counter(priv, port, &counters->if_out_ucast_pkts,
|
||||
&mib_desc->if_out_ucast_pkts);
|
||||
otto_stats_update_counter(priv, port, &counters->if_out_mcast_pkts,
|
||||
&mib_desc->if_out_mcast_pkts);
|
||||
otto_stats_update_counter(priv, port, &counters->if_out_bcast_pkts,
|
||||
&mib_desc->if_out_bcast_pkts);
|
||||
otto_stats_update_counter(priv, port, &counters->if_out_discards,
|
||||
&mib_desc->if_out_discards);
|
||||
otto_stats_update_counter(priv, port, &counters->single_collisions,
|
||||
&mib_desc->single_collisions);
|
||||
otto_stats_update_counter(priv, port, &counters->multiple_collisions,
|
||||
&mib_desc->multiple_collisions);
|
||||
otto_stats_update_counter(priv, port, &counters->deferred_transmissions,
|
||||
&mib_desc->deferred_transmissions);
|
||||
otto_stats_update_counter(priv, port, &counters->late_collisions,
|
||||
&mib_desc->late_collisions);
|
||||
otto_stats_update_counter(priv, port, &counters->excessive_collisions,
|
||||
&mib_desc->excessive_collisions);
|
||||
otto_stats_update_counter(priv, port, &counters->crc_align_errors,
|
||||
&mib_desc->crc_align_errors);
|
||||
otto_stats_update_counter(priv, port, &counters->rx_pkts_over_max_octets,
|
||||
&mib_desc->rx_pkts_over_max_octets);
|
||||
|
||||
rtldsa_update_counter(priv, port, &counters->unsupported_opcodes,
|
||||
&mib_desc->unsupported_opcodes);
|
||||
otto_stats_update_counter(priv, port, &counters->unsupported_opcodes,
|
||||
&mib_desc->unsupported_opcodes);
|
||||
|
||||
rtldsa_update_counter(priv, port, &counters->rx_undersize_pkts,
|
||||
&mib_desc->rx_undersize_pkts);
|
||||
rtldsa_update_counter(priv, port, &counters->rx_oversize_pkts,
|
||||
&mib_desc->rx_oversize_pkts);
|
||||
rtldsa_update_counter(priv, port, &counters->rx_fragments,
|
||||
&mib_desc->rx_fragments);
|
||||
rtldsa_update_counter(priv, port, &counters->rx_jabbers,
|
||||
&mib_desc->rx_jabbers);
|
||||
otto_stats_update_counter(priv, port, &counters->rx_undersize_pkts,
|
||||
&mib_desc->rx_undersize_pkts);
|
||||
otto_stats_update_counter(priv, port, &counters->rx_oversize_pkts,
|
||||
&mib_desc->rx_oversize_pkts);
|
||||
otto_stats_update_counter(priv, port, &counters->rx_fragments,
|
||||
&mib_desc->rx_fragments);
|
||||
otto_stats_update_counter(priv, port, &counters->rx_jabbers,
|
||||
&mib_desc->rx_jabbers);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(mib_desc->tx_pkts); i++) {
|
||||
if (mib_desc->tx_pkts[i].reg == MIB_REG_INVALID)
|
||||
break;
|
||||
|
||||
rtldsa_update_counter(priv, port, &counters->tx_pkts[i],
|
||||
&mib_desc->tx_pkts[i]);
|
||||
otto_stats_update_counter(priv, port, &counters->tx_pkts[i],
|
||||
&mib_desc->tx_pkts[i]);
|
||||
}
|
||||
for (int i = 0; i < ARRAY_SIZE(mib_desc->rx_pkts); i++) {
|
||||
if (mib_desc->rx_pkts[i].reg == MIB_REG_INVALID)
|
||||
break;
|
||||
|
||||
rtldsa_update_counter(priv, port, &counters->rx_pkts[i],
|
||||
&mib_desc->rx_pkts[i]);
|
||||
otto_stats_update_counter(priv, port, &counters->rx_pkts[i],
|
||||
&mib_desc->rx_pkts[i]);
|
||||
}
|
||||
|
||||
rtldsa_update_counter(priv, port, &counters->drop_events,
|
||||
&mib_desc->drop_events);
|
||||
rtldsa_update_counter(priv, port, &counters->collisions,
|
||||
&mib_desc->collisions);
|
||||
otto_stats_update_counter(priv, port, &counters->drop_events,
|
||||
&mib_desc->drop_events);
|
||||
otto_stats_update_counter(priv, port, &counters->collisions,
|
||||
&mib_desc->collisions);
|
||||
|
||||
rtldsa_update_counter(priv, port, &counters->rx_pause_frames,
|
||||
&mib_desc->rx_pause_frames);
|
||||
rtldsa_update_counter(priv, port, &counters->tx_pause_frames,
|
||||
&mib_desc->tx_pause_frames);
|
||||
otto_stats_update_counter(priv, port, &counters->rx_pause_frames,
|
||||
&mib_desc->rx_pause_frames);
|
||||
otto_stats_update_counter(priv, port, &counters->tx_pause_frames,
|
||||
&mib_desc->tx_pause_frames);
|
||||
|
||||
/* prepare get_stats64 reply without requiring caller waiting for mutex */
|
||||
spin_lock(&counters->link_stat_lock);
|
||||
rtldsa_update_link_stat(&counters->link_stat, counters);
|
||||
otto_stats_update_link(&counters->link_stat, counters);
|
||||
spin_unlock(&counters->link_stat_lock);
|
||||
}
|
||||
|
||||
void rtldsa_counters_lock_register(struct rtl838x_switch_priv *priv, int port)
|
||||
void otto_stats_counters_lock_register(struct rtl838x_switch_priv *priv, int port)
|
||||
__acquires(&priv->ports[port].counters.lock)
|
||||
{
|
||||
spin_lock(&priv->ports[port].counters.lock);
|
||||
}
|
||||
|
||||
void rtldsa_counters_unlock_register(struct rtl838x_switch_priv *priv, int port)
|
||||
void otto_stats_counters_unlock_register(struct rtl838x_switch_priv *priv, int port)
|
||||
__releases(&priv->ports[port].counters.lock)
|
||||
{
|
||||
spin_unlock(&priv->ports[port].counters.lock);
|
||||
}
|
||||
|
||||
void rtldsa_counters_lock_table(struct rtl838x_switch_priv *priv, int port __maybe_unused)
|
||||
void otto_stats_counters_lock_table(struct rtl838x_switch_priv *priv, int port __maybe_unused)
|
||||
__acquires(&priv->counters_lock)
|
||||
{
|
||||
mutex_lock(&priv->counters_lock);
|
||||
}
|
||||
|
||||
void rtldsa_counters_unlock_table(struct rtl838x_switch_priv *priv, int port __maybe_unused)
|
||||
void otto_stats_counters_unlock_table(struct rtl838x_switch_priv *priv, int port __maybe_unused)
|
||||
__releases(&priv->ports[port].counters.lock)
|
||||
{
|
||||
mutex_unlock(&priv->counters_lock);
|
||||
}
|
||||
|
||||
static void rtldsa_counters_lock(struct rtl838x_switch_priv *priv, int port)
|
||||
static void otto_stats_counters_lock(struct rtl838x_switch_priv *priv, int port)
|
||||
{
|
||||
priv->r->stat_counters_lock(priv, port);
|
||||
}
|
||||
|
||||
static void rtldsa_counters_unlock(struct rtl838x_switch_priv *priv, int port)
|
||||
static void otto_stats_counters_unlock(struct rtl838x_switch_priv *priv, int port)
|
||||
{
|
||||
priv->r->stat_counters_unlock(priv, port);
|
||||
}
|
||||
|
||||
static void rtldsa_poll_counters(struct work_struct *work)
|
||||
static void otto_stats_poll_counters(struct work_struct *work)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv = container_of(to_delayed_work(work),
|
||||
struct rtl838x_switch_priv,
|
||||
@@ -623,16 +665,16 @@ static void rtldsa_poll_counters(struct work_struct *work)
|
||||
if (!priv->ports[port].phy && !priv->ports[port].has_pcs)
|
||||
continue;
|
||||
|
||||
rtldsa_counters_lock(priv, port);
|
||||
rtldsa_update_port_counters(priv, port);
|
||||
rtldsa_counters_unlock(priv, port);
|
||||
otto_stats_counters_lock(priv, port);
|
||||
otto_stats_update_port_counters(priv, port);
|
||||
otto_stats_counters_unlock(priv, port);
|
||||
}
|
||||
|
||||
queue_delayed_work(priv->wq, &priv->counters_work,
|
||||
priv->r->stat_counter_poll_interval);
|
||||
}
|
||||
|
||||
void rtldsa_stats_init_counters(struct rtl838x_switch_priv *priv)
|
||||
void otto_stats_init_counters(struct rtl838x_switch_priv *priv)
|
||||
{
|
||||
struct rtldsa_counter_state *counters;
|
||||
|
||||
@@ -647,12 +689,12 @@ void rtldsa_stats_init_counters(struct rtl838x_switch_priv *priv)
|
||||
spin_lock_init(&counters->link_stat_lock);
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&priv->counters_work, rtldsa_poll_counters);
|
||||
INIT_DELAYED_WORK(&priv->counters_work, otto_stats_poll_counters);
|
||||
queue_delayed_work(priv->wq, &priv->counters_work,
|
||||
priv->r->stat_counter_poll_interval);
|
||||
}
|
||||
|
||||
void rtldsa_get_strings(struct dsa_switch *ds, int port, u32 stringset, u8 *data)
|
||||
void otto_stats_get_strings(struct dsa_switch *ds, int port, u32 stringset, u8 *data)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv = ds->priv;
|
||||
const struct rtldsa_mib_desc *mib_desc;
|
||||
@@ -669,8 +711,8 @@ void rtldsa_get_strings(struct dsa_switch *ds, int port, u32 stringset, u8 *data
|
||||
ethtool_puts(&data, mib_desc->list[i].name);
|
||||
}
|
||||
|
||||
void rtldsa_get_ethtool_stats(struct dsa_switch *ds, int port,
|
||||
u64 *data)
|
||||
void otto_stats_get_ethtool(struct dsa_switch *ds, int port,
|
||||
u64 *data)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv = ds->priv;
|
||||
const struct rtldsa_mib_desc *mib_desc;
|
||||
@@ -682,11 +724,11 @@ void rtldsa_get_ethtool_stats(struct dsa_switch *ds, int port,
|
||||
mib_desc = priv->r->mib_desc;
|
||||
for (int i = 0; i < mib_desc->list_count; i++) {
|
||||
mib_item = &mib_desc->list[i].item;
|
||||
rtldsa_read_mib_item(priv, port, mib_item, &data[i]);
|
||||
otto_stats_read_mib_item(priv, port, mib_item, &data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int rtldsa_get_sset_count(struct dsa_switch *ds, int port, int sset)
|
||||
int otto_stats_get_sset_count(struct dsa_switch *ds, int port, int sset)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv = ds->priv;
|
||||
|
||||
@@ -699,8 +741,8 @@ int rtldsa_get_sset_count(struct dsa_switch *ds, int port, int sset)
|
||||
return priv->r->mib_desc->list_count;
|
||||
}
|
||||
|
||||
void rtldsa_get_eth_phy_stats(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_phy_stats *phy_stats)
|
||||
void otto_stats_get_eth_phy(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_phy_stats *phy_stats)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv = ds->priv;
|
||||
struct rtldsa_counter_state *counters = &priv->ports[port].counters;
|
||||
@@ -708,17 +750,17 @@ void rtldsa_get_eth_phy_stats(struct dsa_switch *ds, int port,
|
||||
if (port < 0 || port >= priv->r->cpu_port)
|
||||
return;
|
||||
|
||||
rtldsa_counters_lock(priv, port);
|
||||
otto_stats_counters_lock(priv, port);
|
||||
|
||||
rtldsa_update_port_counters(priv, port);
|
||||
otto_stats_update_port_counters(priv, port);
|
||||
|
||||
phy_stats->SymbolErrorDuringCarrier = counters->symbol_errors.val;
|
||||
|
||||
rtldsa_counters_unlock(priv, port);
|
||||
otto_stats_counters_unlock(priv, port);
|
||||
}
|
||||
|
||||
void rtldsa_get_eth_mac_stats(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_mac_stats *mac_stats)
|
||||
void otto_stats_get_eth_mac(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_mac_stats *mac_stats)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv = ds->priv;
|
||||
struct rtldsa_counter_state *counters = &priv->ports[port].counters;
|
||||
@@ -726,9 +768,9 @@ void rtldsa_get_eth_mac_stats(struct dsa_switch *ds, int port,
|
||||
if (port < 0 || port >= priv->r->cpu_port)
|
||||
return;
|
||||
|
||||
rtldsa_counters_lock(priv, port);
|
||||
otto_stats_counters_lock(priv, port);
|
||||
|
||||
rtldsa_update_port_counters(priv, port);
|
||||
otto_stats_update_port_counters(priv, port);
|
||||
|
||||
/* Frame and octet counters are calculated based on RFC3635, while also
|
||||
* taking into account that the behaviour of the hardware counters differs
|
||||
@@ -765,11 +807,11 @@ void rtldsa_get_eth_mac_stats(struct dsa_switch *ds, int port,
|
||||
|
||||
mac_stats->FrameCheckSequenceErrors = counters->crc_align_errors.val;
|
||||
|
||||
rtldsa_counters_unlock(priv, port);
|
||||
otto_stats_counters_unlock(priv, port);
|
||||
}
|
||||
|
||||
void rtldsa_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_ctrl_stats *ctrl_stats)
|
||||
void otto_stats_get_eth_ctrl(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_ctrl_stats *ctrl_stats)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv = ds->priv;
|
||||
struct rtldsa_counter_state *counters = &priv->ports[port].counters;
|
||||
@@ -777,18 +819,18 @@ void rtldsa_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
|
||||
if (port < 0 || port >= priv->r->cpu_port)
|
||||
return;
|
||||
|
||||
rtldsa_counters_lock(priv, port);
|
||||
otto_stats_counters_lock(priv, port);
|
||||
|
||||
rtldsa_update_port_counters(priv, port);
|
||||
otto_stats_update_port_counters(priv, port);
|
||||
|
||||
ctrl_stats->UnsupportedOpcodesReceived = counters->unsupported_opcodes.val;
|
||||
|
||||
rtldsa_counters_unlock(priv, port);
|
||||
otto_stats_counters_unlock(priv, port);
|
||||
}
|
||||
|
||||
void rtldsa_get_rmon_stats(struct dsa_switch *ds, int port,
|
||||
struct ethtool_rmon_stats *rmon_stats,
|
||||
const struct ethtool_rmon_hist_range **ranges)
|
||||
void otto_stats_get_rmon(struct dsa_switch *ds, int port,
|
||||
struct ethtool_rmon_stats *rmon_stats,
|
||||
const struct ethtool_rmon_hist_range **ranges)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv = ds->priv;
|
||||
const struct rtldsa_mib_desc *mib_desc;
|
||||
@@ -799,9 +841,9 @@ void rtldsa_get_rmon_stats(struct dsa_switch *ds, int port,
|
||||
|
||||
mib_desc = priv->r->mib_desc;
|
||||
|
||||
rtldsa_counters_lock(priv, port);
|
||||
otto_stats_counters_lock(priv, port);
|
||||
|
||||
rtldsa_update_port_counters(priv, port);
|
||||
otto_stats_update_port_counters(priv, port);
|
||||
|
||||
rmon_stats->undersize_pkts = counters->rx_undersize_pkts.val;
|
||||
rmon_stats->oversize_pkts = counters->rx_oversize_pkts.val;
|
||||
@@ -824,18 +866,18 @@ void rtldsa_get_rmon_stats(struct dsa_switch *ds, int port,
|
||||
|
||||
*ranges = mib_desc->rmon_ranges;
|
||||
|
||||
rtldsa_counters_unlock(priv, port);
|
||||
otto_stats_counters_unlock(priv, port);
|
||||
}
|
||||
|
||||
void rtldsa_update_counters_atomically(struct rtl838x_switch_priv *priv, int port)
|
||||
void otto_stats_update_counters_atomically(struct rtl838x_switch_priv *priv, int port)
|
||||
{
|
||||
rtldsa_counters_lock(priv, port);
|
||||
rtldsa_update_port_counters(priv, port);
|
||||
rtldsa_counters_unlock(priv, port);
|
||||
otto_stats_counters_lock(priv, port);
|
||||
otto_stats_update_port_counters(priv, port);
|
||||
otto_stats_counters_unlock(priv, port);
|
||||
}
|
||||
|
||||
void rtldsa_get_stats64(struct dsa_switch *ds, int port,
|
||||
struct rtnl_link_stats64 *s)
|
||||
void otto_stats_get64(struct dsa_switch *ds, int port,
|
||||
struct rtnl_link_stats64 *s)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv = ds->priv;
|
||||
struct rtldsa_counter_state *counters = &priv->ports[port].counters;
|
||||
@@ -852,8 +894,8 @@ void rtldsa_get_stats64(struct dsa_switch *ds, int port,
|
||||
spin_unlock(&counters->link_stat_lock);
|
||||
}
|
||||
|
||||
void rtldsa_get_pause_stats(struct dsa_switch *ds, int port,
|
||||
struct ethtool_pause_stats *pause_stats)
|
||||
void otto_stats_get_pause(struct dsa_switch *ds, int port,
|
||||
struct ethtool_pause_stats *pause_stats)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv = ds->priv;
|
||||
struct rtldsa_counter_state *counters = &priv->ports[port].counters;
|
||||
@@ -861,12 +903,235 @@ void rtldsa_get_pause_stats(struct dsa_switch *ds, int port,
|
||||
if (port < 0 || port >= priv->r->cpu_port)
|
||||
return;
|
||||
|
||||
rtldsa_counters_lock(priv, port);
|
||||
otto_stats_counters_lock(priv, port);
|
||||
|
||||
rtldsa_update_port_counters(priv, port);
|
||||
otto_stats_update_port_counters(priv, port);
|
||||
|
||||
pause_stats->tx_pause_frames = counters->tx_pause_frames.val;
|
||||
pause_stats->rx_pause_frames = counters->rx_pause_frames.val;
|
||||
|
||||
rtldsa_counters_unlock(priv, port);
|
||||
otto_stats_counters_unlock(priv, port);
|
||||
}
|
||||
|
||||
/*
|
||||
* Packet counters share hardware memory with octet counters (2 packet counters
|
||||
* per 1 octet block). Allocation relies on two complementary bitmaps:
|
||||
*
|
||||
* octet_cntr_use_bm: 0 = free block, 1 = used (or split into packet counters)
|
||||
* packet_cntr_use_bm: 1 = free standalone counter, 0 = unavailable
|
||||
*
|
||||
* Allocation strategy:
|
||||
* 1. Look for a free standalone counter from an already split block (bit = 1).
|
||||
* 2. If none are free, claim a new octet block 'j', use counter index (2 * j),
|
||||
* and mark counter (2 * j + 1) as available for future allocations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* otto_stats_packet_cntr_alloc - Allocate a hardware packet counter.
|
||||
* @priv: Switch driver private structure.
|
||||
*
|
||||
* Return: Counter index (>= 0) on success, or -1 if full.
|
||||
*/
|
||||
int otto_stats_packet_cntr_alloc(struct rtl838x_switch_priv *priv)
|
||||
{
|
||||
int idx, j, base = 0;
|
||||
|
||||
/* On SoCs where a PIE rule implicitly logs into the LOG table entry
|
||||
* with its own rule ID (RTL930x), the tc cls_flower offload consumes
|
||||
* one LOG counter per PIE rule and does not pass through this
|
||||
* allocator. Keep that range reserved so a route counter handed out
|
||||
* here cannot alias a flow's LOG entry.
|
||||
*
|
||||
* The offload is ingress-only, so PIE rule IDs currently populate
|
||||
* only the lower half of that range, and a route counter's LOG entry
|
||||
* (idx / 2) never dips below the upper half either. If egress PIE
|
||||
* rules are ever wired up, this reservation needs to grow so their
|
||||
* LOG entries stay clear of route counters too.
|
||||
*/
|
||||
if (priv->r->pie_rule_id_is_log_counter)
|
||||
base = priv->r->n_pie_blocks * PIE_BLOCK_SIZE;
|
||||
|
||||
scoped_guard(mutex, &priv->reg_mutex) {
|
||||
idx = find_next_bit(priv->packet_cntr_use_bm, priv->r->n_counters * 2, base);
|
||||
if (idx >= priv->r->n_counters * 2) {
|
||||
j = find_next_zero_bit(priv->octet_cntr_use_bm, priv->r->n_counters,
|
||||
base / 2);
|
||||
if (j >= priv->r->n_counters)
|
||||
return -1;
|
||||
|
||||
__set_bit(j, priv->octet_cntr_use_bm);
|
||||
idx = j * 2;
|
||||
__set_bit(j * 2 + 1, priv->packet_cntr_use_bm);
|
||||
} else {
|
||||
__clear_bit(idx, priv->packet_cntr_use_bm);
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* otto_stats_packet_cntr_free - Release a packet counter from otto_stats_packet_cntr_alloc().
|
||||
* @priv: Switch driver private structure.
|
||||
* @idx: Packet counter index to free; a negative id is ignored.
|
||||
*
|
||||
* Marks the counter free again and, once both halves of its octet block are
|
||||
* free, returns the whole block to the octet counter pool.
|
||||
*/
|
||||
void otto_stats_packet_cntr_free(struct rtl838x_switch_priv *priv, int idx)
|
||||
{
|
||||
int j;
|
||||
|
||||
if (idx < 0 || idx >= priv->r->n_counters * 2)
|
||||
return;
|
||||
|
||||
scoped_guard(mutex, &priv->reg_mutex) {
|
||||
/* already free - guard against a double release */
|
||||
if (test_bit(idx, priv->packet_cntr_use_bm))
|
||||
return;
|
||||
|
||||
__set_bit(idx, priv->packet_cntr_use_bm);
|
||||
|
||||
j = idx / 2;
|
||||
if (test_bit(j, priv->octet_cntr_use_bm) &&
|
||||
test_bit(idx ^ 1, priv->packet_cntr_use_bm)) {
|
||||
__clear_bit(idx, priv->packet_cntr_use_bm);
|
||||
__clear_bit(idx ^ 1, priv->packet_cntr_use_bm);
|
||||
__clear_bit(j, priv->octet_cntr_use_bm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 otto_stats_838x_packet_cntr_read(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
u32 buf[2];
|
||||
u32 v;
|
||||
|
||||
dev_dbg(priv->dev, "reading LOG packet counter %d\n", counter);
|
||||
otto_table_read(RTL8380_TBL_LOG, counter / 2, &buf);
|
||||
|
||||
dev_dbg(priv->dev, "LOG entry: %08x %08x\n", buf[0], buf[1]);
|
||||
if (counter % 2)
|
||||
v = buf[0];
|
||||
else
|
||||
v = buf[1];
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void otto_stats_838x_packet_cntr_clear(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
int tbl = otto_table_acquire(RTL8380_TBL_LOG);
|
||||
u32 buf[2];
|
||||
|
||||
dev_dbg(priv->dev, "clearing LOG packet counter %d\n", counter);
|
||||
|
||||
/*
|
||||
* Two counters share one LOG table entry. Read the current entry
|
||||
* first so clearing one half preserves the adjacent counter.
|
||||
*/
|
||||
__otto_table_read(tbl, counter / 2, &buf);
|
||||
|
||||
if (counter % 2)
|
||||
buf[0] = 0;
|
||||
else
|
||||
buf[1] = 0;
|
||||
|
||||
__otto_table_write(tbl, counter / 2, &buf);
|
||||
|
||||
otto_table_release(tbl);
|
||||
}
|
||||
|
||||
u32 otto_stats_839x_packet_cntr_read(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
u32 buf[2];
|
||||
u32 v;
|
||||
|
||||
dev_dbg(priv->dev, "reading LOG packet counter %d\n", counter);
|
||||
otto_table_read(RTL8390_TBL_LOG, counter / 2, &buf);
|
||||
|
||||
if (counter % 2)
|
||||
v = buf[0];
|
||||
else
|
||||
v = buf[1];
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void otto_stats_839x_packet_cntr_clear(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
int tbl = otto_table_acquire(RTL8390_TBL_LOG);
|
||||
u32 buf[2];
|
||||
|
||||
dev_dbg(priv->dev, "clearing LOG packet counter %d\n", counter);
|
||||
|
||||
/*
|
||||
* Two counters share one LOG table entry. Read the current entry
|
||||
* first so clearing one half preserves the adjacent counter.
|
||||
*/
|
||||
__otto_table_read(tbl, counter / 2, &buf);
|
||||
|
||||
if (counter % 2)
|
||||
buf[0] = 0;
|
||||
else
|
||||
buf[1] = 0;
|
||||
|
||||
__otto_table_write(tbl, counter / 2, &buf);
|
||||
|
||||
otto_table_release(tbl);
|
||||
}
|
||||
|
||||
/* A PIE rule logs its matched packets into the LOG table entry that carries
|
||||
* its own rule ID, in data word 1 - one entry per rule. Counters handed out
|
||||
* by otto_stats_packet_cntr_alloc() for L3 route statistics start above the PIE
|
||||
* rule ID range and pack two 32-bit counters into one 64-bit LOG entry.
|
||||
*/
|
||||
#define RTL930X_PIE_RULE_IDS (rtldsa_930x_cfg.n_pie_blocks * PIE_BLOCK_SIZE)
|
||||
|
||||
u32 otto_stats_930x_packet_cntr_read(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
u32 buf[2];
|
||||
u32 v;
|
||||
|
||||
dev_dbg(priv->dev, "reading LOG packet counter %d\n", counter);
|
||||
|
||||
if (counter < RTL930X_PIE_RULE_IDS) {
|
||||
otto_table_read(RTL9300_TBL_LOG, counter, &buf);
|
||||
v = buf[1];
|
||||
} else {
|
||||
/* Two counters share one entry, so the parity of counter picks
|
||||
* which half of it to return.
|
||||
*/
|
||||
otto_table_read(RTL9300_TBL_LOG, counter / 2, &buf);
|
||||
v = counter % 2 ? buf[0] : buf[1];
|
||||
}
|
||||
|
||||
dev_dbg(priv->dev, "LOG entry: %08x %08x\n", buf[0], buf[1]);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void otto_stats_930x_packet_cntr_clear(struct rtl838x_switch_priv *priv, int counter)
|
||||
{
|
||||
int tbl = otto_table_acquire(RTL9300_TBL_LOG);
|
||||
|
||||
u32 v[2];
|
||||
|
||||
dev_dbg(priv->dev, "clearing LOG packet counter %d\n", counter);
|
||||
|
||||
/* Read-modify-write: for a route counter the other 32-bit counter in
|
||||
* the same 64-bit entry must be preserved; for a PIE rule ID the entry
|
||||
* is ours alone but the RMW is harmless.
|
||||
*/
|
||||
if (counter < RTL930X_PIE_RULE_IDS) {
|
||||
__otto_table_read(tbl, counter, &v);
|
||||
v[1] = 0;
|
||||
__otto_table_write(tbl, counter, &v);
|
||||
} else {
|
||||
__otto_table_read(tbl, counter / 2, &v);
|
||||
v[counter % 2 ? 0 : 1] = 0;
|
||||
__otto_table_write(tbl, counter / 2, &v);
|
||||
}
|
||||
|
||||
otto_table_release(tbl);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __RTL_OTTO_STATS_H
|
||||
#define __RTL_OTTO_STATS_H
|
||||
#ifndef _OTTO_STATS_H
|
||||
#define _OTTO_STATS_H
|
||||
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/jiffies.h>
|
||||
@@ -177,36 +177,48 @@ struct ethtool_rmon_stats;
|
||||
struct rtl838x_switch_priv;
|
||||
struct rtnl_link_stats64;
|
||||
|
||||
void rtldsa_stats_init(struct rtl838x_switch_priv *priv);
|
||||
void rtldsa_stats_init_counters(struct rtl838x_switch_priv *priv);
|
||||
void otto_stats_init(struct rtl838x_switch_priv *priv);
|
||||
void otto_stats_init_counters(struct rtl838x_switch_priv *priv);
|
||||
void otto_stats_838x_init(struct rtl838x_switch_priv *priv);
|
||||
u64 otto_stats_931x_port_table_read(int port, unsigned int mib_size,
|
||||
unsigned int mib_offset, bool is_pvt);
|
||||
|
||||
void rtldsa_get_strings(struct dsa_switch *ds, int port, u32 stringset,
|
||||
u8 *data);
|
||||
void rtldsa_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data);
|
||||
int rtldsa_get_sset_count(struct dsa_switch *ds, int port, int sset);
|
||||
void rtldsa_get_eth_phy_stats(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_phy_stats *phy_stats);
|
||||
void rtldsa_get_eth_mac_stats(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_mac_stats *mac_stats);
|
||||
void rtldsa_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_ctrl_stats *ctrl_stats);
|
||||
void rtldsa_get_rmon_stats(struct dsa_switch *ds, int port,
|
||||
struct ethtool_rmon_stats *rmon_stats,
|
||||
const struct ethtool_rmon_hist_range **ranges);
|
||||
void rtldsa_get_stats64(struct dsa_switch *ds, int port,
|
||||
struct rtnl_link_stats64 *s);
|
||||
void rtldsa_get_pause_stats(struct dsa_switch *ds, int port,
|
||||
struct ethtool_pause_stats *pause_stats);
|
||||
int otto_stats_packet_cntr_alloc(struct rtl838x_switch_priv *priv);
|
||||
void otto_stats_packet_cntr_free(struct rtl838x_switch_priv *priv, int idx);
|
||||
u32 otto_stats_838x_packet_cntr_read(struct rtl838x_switch_priv *priv, int counter);
|
||||
void otto_stats_838x_packet_cntr_clear(struct rtl838x_switch_priv *priv, int counter);
|
||||
u32 otto_stats_839x_packet_cntr_read(struct rtl838x_switch_priv *priv, int counter);
|
||||
void otto_stats_839x_packet_cntr_clear(struct rtl838x_switch_priv *priv, int counter);
|
||||
u32 otto_stats_930x_packet_cntr_read(struct rtl838x_switch_priv *priv, int counter);
|
||||
void otto_stats_930x_packet_cntr_clear(struct rtl838x_switch_priv *priv, int counter);
|
||||
|
||||
void rtldsa_counters_lock_register(struct rtl838x_switch_priv *priv, int port)
|
||||
void otto_stats_get_strings(struct dsa_switch *ds, int port, u32 stringset,
|
||||
u8 *data);
|
||||
void otto_stats_get_ethtool(struct dsa_switch *ds, int port, u64 *data);
|
||||
int otto_stats_get_sset_count(struct dsa_switch *ds, int port, int sset);
|
||||
void otto_stats_get_eth_phy(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_phy_stats *phy_stats);
|
||||
void otto_stats_get_eth_mac(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_mac_stats *mac_stats);
|
||||
void otto_stats_get_eth_ctrl(struct dsa_switch *ds, int port,
|
||||
struct ethtool_eth_ctrl_stats *ctrl_stats);
|
||||
void otto_stats_get_rmon(struct dsa_switch *ds, int port,
|
||||
struct ethtool_rmon_stats *rmon_stats,
|
||||
const struct ethtool_rmon_hist_range **ranges);
|
||||
void otto_stats_get64(struct dsa_switch *ds, int port,
|
||||
struct rtnl_link_stats64 *s);
|
||||
void otto_stats_get_pause(struct dsa_switch *ds, int port,
|
||||
struct ethtool_pause_stats *pause_stats);
|
||||
|
||||
void otto_stats_counters_lock_register(struct rtl838x_switch_priv *priv, int port)
|
||||
__acquires(&priv->ports[port].counters.lock);
|
||||
void rtldsa_counters_unlock_register(struct rtl838x_switch_priv *priv, int port)
|
||||
void otto_stats_counters_unlock_register(struct rtl838x_switch_priv *priv, int port)
|
||||
__releases(&priv->ports[port].counters.lock);
|
||||
void rtldsa_counters_lock_table(struct rtl838x_switch_priv *priv, int port)
|
||||
void otto_stats_counters_lock_table(struct rtl838x_switch_priv *priv, int port)
|
||||
__acquires(&priv->counters_lock);
|
||||
void rtldsa_counters_unlock_table(struct rtl838x_switch_priv *priv, int port)
|
||||
void otto_stats_counters_unlock_table(struct rtl838x_switch_priv *priv, int port)
|
||||
__releases(&priv->ports[port].counters.lock);
|
||||
void rtldsa_update_counters_atomically(struct rtl838x_switch_priv *priv,
|
||||
int port);
|
||||
void otto_stats_update_counters_atomically(struct rtl838x_switch_priv *priv,
|
||||
int port);
|
||||
|
||||
#endif /* __RTL_OTTO_STATS_H */
|
||||
#endif /* _OTTO_STATS_H */
|
||||
@@ -481,7 +481,7 @@ static int otto_tc_configure_flower(struct rtl838x_switch_priv *priv,
|
||||
/* The only caller, otto_tc_pie_cls_flower_add(), is RTL930x-only, where
|
||||
* the PIE rule ID is also the LOG table counter ID: the counter is
|
||||
* implied by the rule and only known once pie_rule_add() has assigned
|
||||
* the ID. That range is kept out of rtldsa_packet_cntr_alloc(), so the
|
||||
* the ID. That range is kept out of otto_stats_packet_cntr_alloc(), so the
|
||||
* implied LOG entry cannot alias an L3 route PIE rule's counter.
|
||||
*/
|
||||
flow->rule.log_sel = true;
|
||||
|
||||
Reference in new issue
Block a user