mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
net: ti: icssg-prueth: Add ICSSG FW Stats
The ICSSG firmware maintains set of stats called PA_STATS. Currently the driver only dumps 4 stats. Add support for dumping more stats. The offset for different stats are defined as MACROs in icssg_switch_map.h file. All the offsets are for Slice0. Slice1 offsets are slice0 + 4. The offset calculation is taken care while reading the stats in emac_update_hardware_stats(). The statistics are documented in Documentation/networking/device_drivers/icssg_prueth.rst Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: MD Danish Anwar <danishanwar@ti.com> Link: https://patch.msgid.link/20250424095316.2643573-1-danishanwar@ti.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
a427e7f99b
commit
0d15a26b24
|
|
@ -55,6 +55,7 @@ Contents:
|
||||||
ti/cpsw_switchdev
|
ti/cpsw_switchdev
|
||||||
ti/am65_nuss_cpsw_switchdev
|
ti/am65_nuss_cpsw_switchdev
|
||||||
ti/tlan
|
ti/tlan
|
||||||
|
ti/icssg_prueth
|
||||||
wangxun/txgbe
|
wangxun/txgbe
|
||||||
wangxun/ngbe
|
wangxun/ngbe
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
==============================================
|
||||||
|
Texas Instruments ICSSG PRUETH ethernet driver
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
:Version: 1.0
|
||||||
|
|
||||||
|
ICSSG Firmware
|
||||||
|
==============
|
||||||
|
|
||||||
|
Every ICSSG core has two Programmable Real-Time Unit(PRUs), two auxiliary
|
||||||
|
Real-Time Transfer Unit (RTUs), and two Transmit Real-Time Transfer Units
|
||||||
|
(TX_PRUs). Each one of these runs its own firmware. The firmwares combnined are
|
||||||
|
referred as ICSSG Firmware.
|
||||||
|
|
||||||
|
Firmware Statistics
|
||||||
|
===================
|
||||||
|
|
||||||
|
The ICSSG firmware maintains certain statistics which are dumped by the driver
|
||||||
|
via ``ethtool -S <interface>``
|
||||||
|
|
||||||
|
These statistics are as follows,
|
||||||
|
|
||||||
|
- ``FW_RTU_PKT_DROP``: Diagnostic error counter which increments when RTU drops a locally injected packet due to port being disabled or rule violation.
|
||||||
|
- ``FW_Q0_OVERFLOW``: TX overflow counter for queue0
|
||||||
|
- ``FW_Q1_OVERFLOW``: TX overflow counter for queue1
|
||||||
|
- ``FW_Q2_OVERFLOW``: TX overflow counter for queue2
|
||||||
|
- ``FW_Q3_OVERFLOW``: TX overflow counter for queue3
|
||||||
|
- ``FW_Q4_OVERFLOW``: TX overflow counter for queue4
|
||||||
|
- ``FW_Q5_OVERFLOW``: TX overflow counter for queue5
|
||||||
|
- ``FW_Q6_OVERFLOW``: TX overflow counter for queue6
|
||||||
|
- ``FW_Q7_OVERFLOW``: TX overflow counter for queue7
|
||||||
|
- ``FW_DROPPED_PKT``: This counter is incremented when a packet is dropped at PRU because of rule violation.
|
||||||
|
- ``FW_RX_ERROR``: Incremented if there was a CRC error or Min/Max frame error at PRU
|
||||||
|
- ``FW_RX_DS_INVALID``: Incremented when RTU detects Data Status invalid condition
|
||||||
|
- ``FW_TX_DROPPED_PACKET``: Counter for packets dropped via TX Port
|
||||||
|
- ``FW_TX_TS_DROPPED_PACKET``: Counter for packets with TS flag dropped via TX Port
|
||||||
|
- ``FW_INF_PORT_DISABLED``: Incremented when RX frame is dropped due to port being disabled
|
||||||
|
- ``FW_INF_SAV``: Incremented when RX frame is dropped due to Source Address violation
|
||||||
|
- ``FW_INF_SA_DL``: Incremented when RX frame is dropped due to Source Address being in the denylist
|
||||||
|
- ``FW_INF_PORT_BLOCKED``: Incremented when RX frame is dropped due to port being blocked and frame being a special frame
|
||||||
|
- ``FW_INF_DROP_TAGGED`` : Incremented when RX frame is dropped for being tagged
|
||||||
|
- ``FW_INF_DROP_PRIOTAGGED``: Incremented when RX frame is dropped for being priority tagged
|
||||||
|
- ``FW_INF_DROP_NOTAG``: Incremented when RX frame is dropped for being untagged
|
||||||
|
- ``FW_INF_DROP_NOTMEMBER``: Incremented when RX frame is dropped for port not being member of VLAN
|
||||||
|
- ``FW_RX_EOF_SHORT_FRMERR``: Incremented if End Of Frame (EOF) task is scheduled without seeing RX_B1
|
||||||
|
- ``FW_RX_B0_DROP_EARLY_EOF``: Incremented when frame is dropped due to Early EOF
|
||||||
|
- ``FW_TX_JUMBO_FRM_CUTOFF``: Incremented when frame is cut off to prevent packet size > 2000 Bytes
|
||||||
|
- ``FW_RX_EXP_FRAG_Q_DROP``: Incremented when express frame is received in the same queue as the previous fragment
|
||||||
|
- ``FW_RX_FIFO_OVERRUN``: RX fifo overrun counter
|
||||||
|
- ``FW_CUT_THR_PKT``: Incremented when a packet is forwarded using Cut-Through forwarding method
|
||||||
|
- ``FW_HOST_RX_PKT_CNT``: Number of valid packets sent by Rx PRU to Host on PSI
|
||||||
|
- ``FW_HOST_TX_PKT_CNT``: Number of valid packets copied by RTU0 to Tx queues
|
||||||
|
- ``FW_HOST_EGRESS_Q_PRE_OVERFLOW``: Host Egress Q (Pre-emptible) Overflow Counter
|
||||||
|
- ``FW_HOST_EGRESS_Q_EXP_OVERFLOW``: Host Egress Q (Pre-emptible) Overflow Counter
|
||||||
|
|
@ -1318,10 +1318,28 @@ void icssg_ndo_get_stats64(struct net_device *ndev,
|
||||||
stats->rx_over_errors = emac_get_stat_by_name(emac, "rx_over_errors");
|
stats->rx_over_errors = emac_get_stat_by_name(emac, "rx_over_errors");
|
||||||
stats->multicast = emac_get_stat_by_name(emac, "rx_multicast_frames");
|
stats->multicast = emac_get_stat_by_name(emac, "rx_multicast_frames");
|
||||||
|
|
||||||
stats->rx_errors = ndev->stats.rx_errors;
|
stats->rx_errors = ndev->stats.rx_errors +
|
||||||
stats->rx_dropped = ndev->stats.rx_dropped;
|
emac_get_stat_by_name(emac, "FW_RX_ERROR") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_RX_EOF_SHORT_FRMERR") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_RX_B0_DROP_EARLY_EOF") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_RX_EXP_FRAG_Q_DROP") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_RX_FIFO_OVERRUN");
|
||||||
|
stats->rx_dropped = ndev->stats.rx_dropped +
|
||||||
|
emac_get_stat_by_name(emac, "FW_DROPPED_PKT") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_INF_PORT_DISABLED") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_INF_SAV") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_INF_SA_DL") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_INF_PORT_BLOCKED") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_INF_DROP_TAGGED") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_INF_DROP_PRIOTAGGED") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_INF_DROP_NOTAG") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_INF_DROP_NOTMEMBER");
|
||||||
stats->tx_errors = ndev->stats.tx_errors;
|
stats->tx_errors = ndev->stats.tx_errors;
|
||||||
stats->tx_dropped = ndev->stats.tx_dropped;
|
stats->tx_dropped = ndev->stats.tx_dropped +
|
||||||
|
emac_get_stat_by_name(emac, "FW_RTU_PKT_DROP") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_TX_DROPPED_PACKET") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_TX_TS_DROPPED_PACKET") +
|
||||||
|
emac_get_stat_by_name(emac, "FW_TX_JUMBO_FRM_CUTOFF");
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(icssg_ndo_get_stats64);
|
EXPORT_SYMBOL_GPL(icssg_ndo_get_stats64);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
#define ICSSG_MAX_RFLOWS 8 /* per slice */
|
#define ICSSG_MAX_RFLOWS 8 /* per slice */
|
||||||
|
|
||||||
#define ICSSG_NUM_PA_STATS 4
|
#define ICSSG_NUM_PA_STATS 32
|
||||||
#define ICSSG_NUM_MIIG_STATS 60
|
#define ICSSG_NUM_MIIG_STATS 60
|
||||||
/* Number of ICSSG related stats */
|
/* Number of ICSSG related stats */
|
||||||
#define ICSSG_NUM_STATS (ICSSG_NUM_MIIG_STATS + ICSSG_NUM_PA_STATS)
|
#define ICSSG_NUM_STATS (ICSSG_NUM_MIIG_STATS + ICSSG_NUM_PA_STATS)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#define ICSSG_TX_PACKET_OFFSET 0xA0
|
#define ICSSG_TX_PACKET_OFFSET 0xA0
|
||||||
#define ICSSG_TX_BYTE_OFFSET 0xEC
|
#define ICSSG_TX_BYTE_OFFSET 0xEC
|
||||||
#define ICSSG_FW_STATS_BASE 0x0248
|
|
||||||
|
|
||||||
static u32 stats_base[] = { 0x54c, /* Slice 0 stats start */
|
static u32 stats_base[] = { 0x54c, /* Slice 0 stats start */
|
||||||
0xb18, /* Slice 1 stats start */
|
0xb18, /* Slice 1 stats start */
|
||||||
|
|
@ -46,9 +45,8 @@ void emac_update_hardware_stats(struct prueth_emac *emac)
|
||||||
|
|
||||||
if (prueth->pa_stats) {
|
if (prueth->pa_stats) {
|
||||||
for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++) {
|
for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++) {
|
||||||
reg = ICSSG_FW_STATS_BASE +
|
reg = icssg_all_pa_stats[i].offset +
|
||||||
icssg_all_pa_stats[i].offset *
|
slice * sizeof(u32);
|
||||||
PRUETH_NUM_MACS + slice * sizeof(u32);
|
|
||||||
regmap_read(prueth->pa_stats, reg, &val);
|
regmap_read(prueth->pa_stats, reg, &val);
|
||||||
emac->pa_stats[i] += val;
|
emac->pa_stats[i] += val;
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +78,7 @@ int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name)
|
||||||
if (emac->prueth->pa_stats) {
|
if (emac->prueth->pa_stats) {
|
||||||
for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++) {
|
for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++) {
|
||||||
if (!strcmp(icssg_all_pa_stats[i].name, stat_name))
|
if (!strcmp(icssg_all_pa_stats[i].name, stat_name))
|
||||||
return emac->pa_stats[icssg_all_pa_stats[i].offset / sizeof(u32)];
|
return emac->pa_stats[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -155,24 +155,10 @@ static const struct icssg_miig_stats icssg_all_miig_stats[] = {
|
||||||
ICSSG_MIIG_STATS(tx_bytes, true),
|
ICSSG_MIIG_STATS(tx_bytes, true),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
#define ICSSG_PA_STATS(field) \
|
||||||
* struct pa_stats_regs - ICSSG Firmware maintained PA Stats register
|
{ \
|
||||||
* @fw_rx_cnt: Number of valid packets sent by Rx PRU to Host on PSI
|
#field, \
|
||||||
* @fw_tx_cnt: Number of valid packets copied by RTU0 to Tx queues
|
field, \
|
||||||
* @fw_tx_pre_overflow: Host Egress Q (Pre-emptible) Overflow Counter
|
|
||||||
* @fw_tx_exp_overflow: Host Egress Q (Express) Overflow Counter
|
|
||||||
*/
|
|
||||||
struct pa_stats_regs {
|
|
||||||
u32 fw_rx_cnt;
|
|
||||||
u32 fw_tx_cnt;
|
|
||||||
u32 fw_tx_pre_overflow;
|
|
||||||
u32 fw_tx_exp_overflow;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ICSSG_PA_STATS(field) \
|
|
||||||
{ \
|
|
||||||
#field, \
|
|
||||||
offsetof(struct pa_stats_regs, field), \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct icssg_pa_stats {
|
struct icssg_pa_stats {
|
||||||
|
|
@ -181,10 +167,38 @@ struct icssg_pa_stats {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct icssg_pa_stats icssg_all_pa_stats[] = {
|
static const struct icssg_pa_stats icssg_all_pa_stats[] = {
|
||||||
ICSSG_PA_STATS(fw_rx_cnt),
|
ICSSG_PA_STATS(FW_RTU_PKT_DROP),
|
||||||
ICSSG_PA_STATS(fw_tx_cnt),
|
ICSSG_PA_STATS(FW_Q0_OVERFLOW),
|
||||||
ICSSG_PA_STATS(fw_tx_pre_overflow),
|
ICSSG_PA_STATS(FW_Q1_OVERFLOW),
|
||||||
ICSSG_PA_STATS(fw_tx_exp_overflow),
|
ICSSG_PA_STATS(FW_Q2_OVERFLOW),
|
||||||
|
ICSSG_PA_STATS(FW_Q3_OVERFLOW),
|
||||||
|
ICSSG_PA_STATS(FW_Q4_OVERFLOW),
|
||||||
|
ICSSG_PA_STATS(FW_Q5_OVERFLOW),
|
||||||
|
ICSSG_PA_STATS(FW_Q6_OVERFLOW),
|
||||||
|
ICSSG_PA_STATS(FW_Q7_OVERFLOW),
|
||||||
|
ICSSG_PA_STATS(FW_DROPPED_PKT),
|
||||||
|
ICSSG_PA_STATS(FW_RX_ERROR),
|
||||||
|
ICSSG_PA_STATS(FW_RX_DS_INVALID),
|
||||||
|
ICSSG_PA_STATS(FW_TX_DROPPED_PACKET),
|
||||||
|
ICSSG_PA_STATS(FW_TX_TS_DROPPED_PACKET),
|
||||||
|
ICSSG_PA_STATS(FW_INF_PORT_DISABLED),
|
||||||
|
ICSSG_PA_STATS(FW_INF_SAV),
|
||||||
|
ICSSG_PA_STATS(FW_INF_SA_DL),
|
||||||
|
ICSSG_PA_STATS(FW_INF_PORT_BLOCKED),
|
||||||
|
ICSSG_PA_STATS(FW_INF_DROP_TAGGED),
|
||||||
|
ICSSG_PA_STATS(FW_INF_DROP_PRIOTAGGED),
|
||||||
|
ICSSG_PA_STATS(FW_INF_DROP_NOTAG),
|
||||||
|
ICSSG_PA_STATS(FW_INF_DROP_NOTMEMBER),
|
||||||
|
ICSSG_PA_STATS(FW_RX_EOF_SHORT_FRMERR),
|
||||||
|
ICSSG_PA_STATS(FW_RX_B0_DROP_EARLY_EOF),
|
||||||
|
ICSSG_PA_STATS(FW_TX_JUMBO_FRM_CUTOFF),
|
||||||
|
ICSSG_PA_STATS(FW_RX_EXP_FRAG_Q_DROP),
|
||||||
|
ICSSG_PA_STATS(FW_RX_FIFO_OVERRUN),
|
||||||
|
ICSSG_PA_STATS(FW_CUT_THR_PKT),
|
||||||
|
ICSSG_PA_STATS(FW_HOST_RX_PKT_CNT),
|
||||||
|
ICSSG_PA_STATS(FW_HOST_TX_PKT_CNT),
|
||||||
|
ICSSG_PA_STATS(FW_HOST_EGRESS_Q_PRE_OVERFLOW),
|
||||||
|
ICSSG_PA_STATS(FW_HOST_EGRESS_Q_EXP_OVERFLOW),
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __NET_TI_ICSSG_STATS_H */
|
#endif /* __NET_TI_ICSSG_STATS_H */
|
||||||
|
|
|
||||||
|
|
@ -231,4 +231,37 @@
|
||||||
/* Start of 32 bits PA_STAT counters */
|
/* Start of 32 bits PA_STAT counters */
|
||||||
#define PA_STAT_32b_START_OFFSET 0x0080
|
#define PA_STAT_32b_START_OFFSET 0x0080
|
||||||
|
|
||||||
|
#define FW_RTU_PKT_DROP 0x0088
|
||||||
|
#define FW_Q0_OVERFLOW 0x0090
|
||||||
|
#define FW_Q1_OVERFLOW 0x0098
|
||||||
|
#define FW_Q2_OVERFLOW 0x00A0
|
||||||
|
#define FW_Q3_OVERFLOW 0x00A8
|
||||||
|
#define FW_Q4_OVERFLOW 0x00B0
|
||||||
|
#define FW_Q5_OVERFLOW 0x00B8
|
||||||
|
#define FW_Q6_OVERFLOW 0x00C0
|
||||||
|
#define FW_Q7_OVERFLOW 0x00C8
|
||||||
|
#define FW_DROPPED_PKT 0x00F8
|
||||||
|
#define FW_RX_ERROR 0x0100
|
||||||
|
#define FW_RX_DS_INVALID 0x0108
|
||||||
|
#define FW_TX_DROPPED_PACKET 0x0110
|
||||||
|
#define FW_TX_TS_DROPPED_PACKET 0x0118
|
||||||
|
#define FW_INF_PORT_DISABLED 0x0120
|
||||||
|
#define FW_INF_SAV 0x0128
|
||||||
|
#define FW_INF_SA_DL 0x0130
|
||||||
|
#define FW_INF_PORT_BLOCKED 0x0138
|
||||||
|
#define FW_INF_DROP_TAGGED 0x0140
|
||||||
|
#define FW_INF_DROP_PRIOTAGGED 0x0148
|
||||||
|
#define FW_INF_DROP_NOTAG 0x0150
|
||||||
|
#define FW_INF_DROP_NOTMEMBER 0x0158
|
||||||
|
#define FW_RX_EOF_SHORT_FRMERR 0x0188
|
||||||
|
#define FW_RX_B0_DROP_EARLY_EOF 0x0190
|
||||||
|
#define FW_TX_JUMBO_FRM_CUTOFF 0x0198
|
||||||
|
#define FW_RX_EXP_FRAG_Q_DROP 0x01A0
|
||||||
|
#define FW_RX_FIFO_OVERRUN 0x01A8
|
||||||
|
#define FW_CUT_THR_PKT 0x01B0
|
||||||
|
#define FW_HOST_RX_PKT_CNT 0x0248
|
||||||
|
#define FW_HOST_TX_PKT_CNT 0x0250
|
||||||
|
#define FW_HOST_EGRESS_Q_PRE_OVERFLOW 0x0258
|
||||||
|
#define FW_HOST_EGRESS_Q_EXP_OVERFLOW 0x0260
|
||||||
|
|
||||||
#endif /* __NET_TI_ICSSG_SWITCH_MAP_H */
|
#endif /* __NET_TI_ICSSG_SWITCH_MAP_H */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user