qualcommax: qca_ppe: count the CPU port's queues in ethtool -S

The CPU port reports the MAC counters of a MAC it does not have, all
zero, and none of its queue counters. Report its unicast and multicast
queue counters instead, as for the user ports.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Julius Bairaktaris authored and Robert Marko committed 2026-10-18 12:50:08 +02:00
1 parent 06a80616a7
commit 3218bba2d2
2 files changed
+24 -18

No files matched your search

@@ -2071,7 +2071,8 @@ static void qca_ppe_get_strings(struct dsa_switch *ds, int port,
if (stringset != ETH_SS_STATS)
return;
for (i = 0; i < ARRAY_SIZE(qca_ppe_mib); i++)
/* The CPU port has no MAC; only its queues count. */
for (i = 0; port && i < ARRAY_SIZE(qca_ppe_mib); i++)
ethtool_puts(&data, qca_ppe_mib[i].name);
ppe_port_qstats(ds_to_priv(ds), port, &data, NULL);
@@ -2083,7 +2084,7 @@ static int qca_ppe_get_sset_count(struct dsa_switch *ds, int port,
if (sset != ETH_SS_STATS)
return 0;
return ARRAY_SIZE(qca_ppe_mib) +
return (port ? ARRAY_SIZE(qca_ppe_mib) : 0) +
ppe_port_qstats(ds_to_priv(ds), port, NULL, NULL);
}
@@ -2091,25 +2092,22 @@ static void qca_ppe_get_ethtool_stats(struct dsa_switch *ds, int port,
uint64_t *data)
{
struct qca_ppe_priv *priv = ds_to_priv(ds);
int off = port ? ARRAY_SIZE(qca_ppe_mib) : 0;
struct qca_ppe_mib_stats *stats, *qstats;
int i, n;
if (port < 1) {
memset(data, 0, sizeof(u64) * ARRAY_SIZE(qca_ppe_mib));
return;
}
stats = ppe_port_mib(priv, port);
qstats = priv->port_qstats + port * PPE_QSTATS_MAX;
spin_lock_bh(&priv->mib_lock);
ppe_mib_fold(priv, port);
if (port) {
stats = ppe_port_mib(priv, port);
ppe_mib_fold(priv, port);
for (i = 0; i < ARRAY_SIZE(qca_ppe_mib); i++)
data[i] = stats[i].total;
}
n = ppe_port_qstats(priv, port, NULL, qstats);
for (i = 0; i < ARRAY_SIZE(qca_ppe_mib); i++)
data[i] = stats[i].total;
for (i = 0; i < n; i++)
data[ARRAY_SIZE(qca_ppe_mib) + i] = qstats[i].total;
data[off + i] = qstats[i].total;
spin_unlock_bh(&priv->mib_lock);
}
@@ -1303,17 +1303,22 @@ u32 ppe_port_queue_drops(struct qca_ppe_priv *priv, int port)
return tx;
}
/* A user port's queue-side counters for ethtool -S: what each of its queues
* sent and dropped by colour, what the buffer manager turned away on ingress,
* and the colours its meter painted. With @names it lists them, with @st it
* folds them; it returns how many there are either way.
/* A port's queue-side counters for ethtool -S: what each of its queues sent
* and dropped by colour and, for a user port, what the buffer manager turned
* away on ingress and the colours its meter painted. With @names it lists
* them, with @st it folds them; it returns how many there are either way.
*/
int ppe_port_qstats(struct qca_ppe_priv *priv, int port, u8 **names,
struct qca_ppe_mib_stats *st)
{
static const struct port_l0_params cpu = {
.ucast_count = PPE_CPU_UCAST_QUEUES,
.mcast_base = 256,
.mcast_count = PPE_MUL_QUEUES_PORT,
};
static const char * const colour[] = { "green", "yellow", "red" };
struct ppe_qstats q = { .priv = priv, .names = names, .st = st };
const struct port_l0_params *p = NULL;
const struct port_l0_params *p = port ? NULL : &cpu;
int bm = PPE_BM_PHY_START + port - 1;
int i, c;
@@ -1351,6 +1356,9 @@ int ppe_port_qstats(struct qca_ppe_priv *priv, int port, u8 **names,
"tx_mcast_queue_%d_drop_%s", i, colour[c]);
}
if (!port)
return q.n;
if (bm <= priv->data->bm_phy_end) {
ppe_qstat(&q, PPE_BM_DROP_STAT(bm), false, "rx_bm_drop");
ppe_qstat(&q, PPE_BM_DROP_STAT(bm + PPE_BM_PORTS), false,