Skip to content

Commit f4e2987

Browse files
net: mana: Expose additional hardware counters for drop and TC via ethtool.
jira LE-3915 commit-author Dipayaan Roy <dipayanroy@linux.microsoft.com> commit c09ef59 Add support for reporting additional hardware counters for drop and TC using the ethtool -S interface. These counters include: - Aggregate Rx/Tx drop counters - Per-TC Rx/Tx packet counters - Per-TC Rx/Tx byte counters - Per-TC Rx/Tx pause frame counters The counters are exposed using ethtool_ops->get_ethtool_stats and ethtool_ops->get_strings. This feature/counters are not available to all versions of hardware. Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com> Reviewed-by: Subbaraya Sundeep <sbhatta@marvell.com> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com> Link: https://patch.msgid.link/20250609100103.GA7102@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit c09ef59) Signed-off-by: Shreeya Patel <spatel@ciq.com> Signed-off-by: Jonathan Maple <jmaple@ciq.com> Signed-off-by: Shreeya Patel <spatel@ciq.com>
1 parent af2dc26 commit f4e2987

File tree

4 files changed

+292
-8
lines changed

4 files changed

+292
-8
lines changed

drivers/net/ethernet/microsoft/mana/hw_channel.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/* Copyright (c) 2021, Microsoft Corporation. */
33

44
#include <net/mana/gdma.h>
5+
#include <net/mana/mana.h>
56
#include <net/mana/hw_channel.h>
67

78
static int mana_hwc_get_msg_index(struct hw_channel_context *hwc, u16 *msg_id)
@@ -870,8 +871,9 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,
870871
}
871872

872873
if (ctx->status_code && ctx->status_code != GDMA_STATUS_MORE_ENTRIES) {
873-
dev_err(hwc->dev, "HWC: Failed hw_channel req: 0x%x\n",
874-
ctx->status_code);
874+
if (req_msg->req.msg_type != MANA_QUERY_PHY_STAT)
875+
dev_err(hwc->dev, "HWC: Failed hw_channel req: 0x%x\n",
876+
ctx->status_code);
875877
err = -EPROTO;
876878
goto out;
877879
}

drivers/net/ethernet/microsoft/mana/mana_en.c

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -768,8 +768,9 @@ static int mana_send_request(struct mana_context *ac, void *in_buf,
768768
err = mana_gd_send_request(gc, in_len, in_buf, out_len,
769769
out_buf);
770770
if (err || resp->status) {
771-
dev_err(dev, "Failed to send mana message: %d, 0x%x\n",
772-
err, resp->status);
771+
if (req->req.msg_type != MANA_QUERY_PHY_STAT)
772+
dev_err(dev, "Failed to send mana message: %d, 0x%x\n",
773+
err, resp->status);
773774
return err ? err : -EPROTO;
774775
}
775776

@@ -2595,6 +2596,88 @@ void mana_query_gf_stats(struct mana_port_context *apc)
25952596
apc->eth_stats.hc_tx_err_gdma = resp.tx_err_gdma;
25962597
}
25972598

2599+
void mana_query_phy_stats(struct mana_port_context *apc)
2600+
{
2601+
struct mana_query_phy_stat_resp resp = {};
2602+
struct mana_query_phy_stat_req req = {};
2603+
struct net_device *ndev = apc->ndev;
2604+
int err;
2605+
2606+
mana_gd_init_req_hdr(&req.hdr, MANA_QUERY_PHY_STAT,
2607+
sizeof(req), sizeof(resp));
2608+
err = mana_send_request(apc->ac, &req, sizeof(req), &resp,
2609+
sizeof(resp));
2610+
if (err)
2611+
return;
2612+
2613+
err = mana_verify_resp_hdr(&resp.hdr, MANA_QUERY_PHY_STAT,
2614+
sizeof(resp));
2615+
if (err || resp.hdr.status) {
2616+
netdev_err(ndev,
2617+
"Failed to query PHY stats: %d, resp:0x%x\n",
2618+
err, resp.hdr.status);
2619+
return;
2620+
}
2621+
2622+
/* Aggregate drop counters */
2623+
apc->phy_stats.rx_pkt_drop_phy = resp.rx_pkt_drop_phy;
2624+
apc->phy_stats.tx_pkt_drop_phy = resp.tx_pkt_drop_phy;
2625+
2626+
/* Per TC traffic Counters */
2627+
apc->phy_stats.rx_pkt_tc0_phy = resp.rx_pkt_tc0_phy;
2628+
apc->phy_stats.tx_pkt_tc0_phy = resp.tx_pkt_tc0_phy;
2629+
apc->phy_stats.rx_pkt_tc1_phy = resp.rx_pkt_tc1_phy;
2630+
apc->phy_stats.tx_pkt_tc1_phy = resp.tx_pkt_tc1_phy;
2631+
apc->phy_stats.rx_pkt_tc2_phy = resp.rx_pkt_tc2_phy;
2632+
apc->phy_stats.tx_pkt_tc2_phy = resp.tx_pkt_tc2_phy;
2633+
apc->phy_stats.rx_pkt_tc3_phy = resp.rx_pkt_tc3_phy;
2634+
apc->phy_stats.tx_pkt_tc3_phy = resp.tx_pkt_tc3_phy;
2635+
apc->phy_stats.rx_pkt_tc4_phy = resp.rx_pkt_tc4_phy;
2636+
apc->phy_stats.tx_pkt_tc4_phy = resp.tx_pkt_tc4_phy;
2637+
apc->phy_stats.rx_pkt_tc5_phy = resp.rx_pkt_tc5_phy;
2638+
apc->phy_stats.tx_pkt_tc5_phy = resp.tx_pkt_tc5_phy;
2639+
apc->phy_stats.rx_pkt_tc6_phy = resp.rx_pkt_tc6_phy;
2640+
apc->phy_stats.tx_pkt_tc6_phy = resp.tx_pkt_tc6_phy;
2641+
apc->phy_stats.rx_pkt_tc7_phy = resp.rx_pkt_tc7_phy;
2642+
apc->phy_stats.tx_pkt_tc7_phy = resp.tx_pkt_tc7_phy;
2643+
2644+
/* Per TC byte Counters */
2645+
apc->phy_stats.rx_byte_tc0_phy = resp.rx_byte_tc0_phy;
2646+
apc->phy_stats.tx_byte_tc0_phy = resp.tx_byte_tc0_phy;
2647+
apc->phy_stats.rx_byte_tc1_phy = resp.rx_byte_tc1_phy;
2648+
apc->phy_stats.tx_byte_tc1_phy = resp.tx_byte_tc1_phy;
2649+
apc->phy_stats.rx_byte_tc2_phy = resp.rx_byte_tc2_phy;
2650+
apc->phy_stats.tx_byte_tc2_phy = resp.tx_byte_tc2_phy;
2651+
apc->phy_stats.rx_byte_tc3_phy = resp.rx_byte_tc3_phy;
2652+
apc->phy_stats.tx_byte_tc3_phy = resp.tx_byte_tc3_phy;
2653+
apc->phy_stats.rx_byte_tc4_phy = resp.rx_byte_tc4_phy;
2654+
apc->phy_stats.tx_byte_tc4_phy = resp.tx_byte_tc4_phy;
2655+
apc->phy_stats.rx_byte_tc5_phy = resp.rx_byte_tc5_phy;
2656+
apc->phy_stats.tx_byte_tc5_phy = resp.tx_byte_tc5_phy;
2657+
apc->phy_stats.rx_byte_tc6_phy = resp.rx_byte_tc6_phy;
2658+
apc->phy_stats.tx_byte_tc6_phy = resp.tx_byte_tc6_phy;
2659+
apc->phy_stats.rx_byte_tc7_phy = resp.rx_byte_tc7_phy;
2660+
apc->phy_stats.tx_byte_tc7_phy = resp.tx_byte_tc7_phy;
2661+
2662+
/* Per TC pause Counters */
2663+
apc->phy_stats.rx_pause_tc0_phy = resp.rx_pause_tc0_phy;
2664+
apc->phy_stats.tx_pause_tc0_phy = resp.tx_pause_tc0_phy;
2665+
apc->phy_stats.rx_pause_tc1_phy = resp.rx_pause_tc1_phy;
2666+
apc->phy_stats.tx_pause_tc1_phy = resp.tx_pause_tc1_phy;
2667+
apc->phy_stats.rx_pause_tc2_phy = resp.rx_pause_tc2_phy;
2668+
apc->phy_stats.tx_pause_tc2_phy = resp.tx_pause_tc2_phy;
2669+
apc->phy_stats.rx_pause_tc3_phy = resp.rx_pause_tc3_phy;
2670+
apc->phy_stats.tx_pause_tc3_phy = resp.tx_pause_tc3_phy;
2671+
apc->phy_stats.rx_pause_tc4_phy = resp.rx_pause_tc4_phy;
2672+
apc->phy_stats.tx_pause_tc4_phy = resp.tx_pause_tc4_phy;
2673+
apc->phy_stats.rx_pause_tc5_phy = resp.rx_pause_tc5_phy;
2674+
apc->phy_stats.tx_pause_tc5_phy = resp.tx_pause_tc5_phy;
2675+
apc->phy_stats.rx_pause_tc6_phy = resp.rx_pause_tc6_phy;
2676+
apc->phy_stats.tx_pause_tc6_phy = resp.tx_pause_tc6_phy;
2677+
apc->phy_stats.rx_pause_tc7_phy = resp.rx_pause_tc7_phy;
2678+
apc->phy_stats.tx_pause_tc7_phy = resp.tx_pause_tc7_phy;
2679+
}
2680+
25982681
static int mana_init_port(struct net_device *ndev)
25992682
{
26002683
struct mana_port_context *apc = netdev_priv(ndev);

drivers/net/ethernet/microsoft/mana/mana_ethtool.c

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77

88
#include <net/mana/mana.h>
99

10-
static const struct {
10+
struct mana_stats_desc {
1111
char name[ETH_GSTRING_LEN];
1212
u16 offset;
13-
} mana_eth_stats[] = {
13+
};
14+
15+
static const struct mana_stats_desc mana_eth_stats[] = {
1416
{"stop_queue", offsetof(struct mana_ethtool_stats, stop_queue)},
1517
{"wake_queue", offsetof(struct mana_ethtool_stats, wake_queue)},
1618
{"hc_rx_discards_no_wqe", offsetof(struct mana_ethtool_stats,
@@ -75,6 +77,59 @@ static const struct {
7577
rx_cqe_unknown_type)},
7678
};
7779

80+
static const struct mana_stats_desc mana_phy_stats[] = {
81+
{ "hc_rx_pkt_drop_phy", offsetof(struct mana_ethtool_phy_stats, rx_pkt_drop_phy) },
82+
{ "hc_tx_pkt_drop_phy", offsetof(struct mana_ethtool_phy_stats, tx_pkt_drop_phy) },
83+
{ "hc_tc0_rx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, rx_pkt_tc0_phy) },
84+
{ "hc_tc0_rx_byte_phy", offsetof(struct mana_ethtool_phy_stats, rx_byte_tc0_phy) },
85+
{ "hc_tc0_tx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, tx_pkt_tc0_phy) },
86+
{ "hc_tc0_tx_byte_phy", offsetof(struct mana_ethtool_phy_stats, tx_byte_tc0_phy) },
87+
{ "hc_tc1_rx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, rx_pkt_tc1_phy) },
88+
{ "hc_tc1_rx_byte_phy", offsetof(struct mana_ethtool_phy_stats, rx_byte_tc1_phy) },
89+
{ "hc_tc1_tx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, tx_pkt_tc1_phy) },
90+
{ "hc_tc1_tx_byte_phy", offsetof(struct mana_ethtool_phy_stats, tx_byte_tc1_phy) },
91+
{ "hc_tc2_rx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, rx_pkt_tc2_phy) },
92+
{ "hc_tc2_rx_byte_phy", offsetof(struct mana_ethtool_phy_stats, rx_byte_tc2_phy) },
93+
{ "hc_tc2_tx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, tx_pkt_tc2_phy) },
94+
{ "hc_tc2_tx_byte_phy", offsetof(struct mana_ethtool_phy_stats, tx_byte_tc2_phy) },
95+
{ "hc_tc3_rx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, rx_pkt_tc3_phy) },
96+
{ "hc_tc3_rx_byte_phy", offsetof(struct mana_ethtool_phy_stats, rx_byte_tc3_phy) },
97+
{ "hc_tc3_tx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, tx_pkt_tc3_phy) },
98+
{ "hc_tc3_tx_byte_phy", offsetof(struct mana_ethtool_phy_stats, tx_byte_tc3_phy) },
99+
{ "hc_tc4_rx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, rx_pkt_tc4_phy) },
100+
{ "hc_tc4_rx_byte_phy", offsetof(struct mana_ethtool_phy_stats, rx_byte_tc4_phy) },
101+
{ "hc_tc4_tx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, tx_pkt_tc4_phy) },
102+
{ "hc_tc4_tx_byte_phy", offsetof(struct mana_ethtool_phy_stats, tx_byte_tc4_phy) },
103+
{ "hc_tc5_rx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, rx_pkt_tc5_phy) },
104+
{ "hc_tc5_rx_byte_phy", offsetof(struct mana_ethtool_phy_stats, rx_byte_tc5_phy) },
105+
{ "hc_tc5_tx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, tx_pkt_tc5_phy) },
106+
{ "hc_tc5_tx_byte_phy", offsetof(struct mana_ethtool_phy_stats, tx_byte_tc5_phy) },
107+
{ "hc_tc6_rx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, rx_pkt_tc6_phy) },
108+
{ "hc_tc6_rx_byte_phy", offsetof(struct mana_ethtool_phy_stats, rx_byte_tc6_phy) },
109+
{ "hc_tc6_tx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, tx_pkt_tc6_phy) },
110+
{ "hc_tc6_tx_byte_phy", offsetof(struct mana_ethtool_phy_stats, tx_byte_tc6_phy) },
111+
{ "hc_tc7_rx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, rx_pkt_tc7_phy) },
112+
{ "hc_tc7_rx_byte_phy", offsetof(struct mana_ethtool_phy_stats, rx_byte_tc7_phy) },
113+
{ "hc_tc7_tx_pkt_phy", offsetof(struct mana_ethtool_phy_stats, tx_pkt_tc7_phy) },
114+
{ "hc_tc7_tx_byte_phy", offsetof(struct mana_ethtool_phy_stats, tx_byte_tc7_phy) },
115+
{ "hc_tc0_rx_pause_phy", offsetof(struct mana_ethtool_phy_stats, rx_pause_tc0_phy) },
116+
{ "hc_tc0_tx_pause_phy", offsetof(struct mana_ethtool_phy_stats, tx_pause_tc0_phy) },
117+
{ "hc_tc1_rx_pause_phy", offsetof(struct mana_ethtool_phy_stats, rx_pause_tc1_phy) },
118+
{ "hc_tc1_tx_pause_phy", offsetof(struct mana_ethtool_phy_stats, tx_pause_tc1_phy) },
119+
{ "hc_tc2_rx_pause_phy", offsetof(struct mana_ethtool_phy_stats, rx_pause_tc2_phy) },
120+
{ "hc_tc2_tx_pause_phy", offsetof(struct mana_ethtool_phy_stats, tx_pause_tc2_phy) },
121+
{ "hc_tc3_rx_pause_phy", offsetof(struct mana_ethtool_phy_stats, rx_pause_tc3_phy) },
122+
{ "hc_tc3_tx_pause_phy", offsetof(struct mana_ethtool_phy_stats, tx_pause_tc3_phy) },
123+
{ "hc_tc4_rx_pause_phy", offsetof(struct mana_ethtool_phy_stats, rx_pause_tc4_phy) },
124+
{ "hc_tc4_tx_pause_phy", offsetof(struct mana_ethtool_phy_stats, tx_pause_tc4_phy) },
125+
{ "hc_tc5_rx_pause_phy", offsetof(struct mana_ethtool_phy_stats, rx_pause_tc5_phy) },
126+
{ "hc_tc5_tx_pause_phy", offsetof(struct mana_ethtool_phy_stats, tx_pause_tc5_phy) },
127+
{ "hc_tc6_rx_pause_phy", offsetof(struct mana_ethtool_phy_stats, rx_pause_tc6_phy) },
128+
{ "hc_tc6_tx_pause_phy", offsetof(struct mana_ethtool_phy_stats, tx_pause_tc6_phy) },
129+
{ "hc_tc7_rx_pause_phy", offsetof(struct mana_ethtool_phy_stats, rx_pause_tc7_phy) },
130+
{ "hc_tc7_tx_pause_phy", offsetof(struct mana_ethtool_phy_stats, tx_pause_tc7_phy) },
131+
};
132+
78133
static int mana_get_sset_count(struct net_device *ndev, int stringset)
79134
{
80135
struct mana_port_context *apc = netdev_priv(ndev);
@@ -83,8 +138,8 @@ static int mana_get_sset_count(struct net_device *ndev, int stringset)
83138
if (stringset != ETH_SS_STATS)
84139
return -EINVAL;
85140

86-
return ARRAY_SIZE(mana_eth_stats) + num_queues *
87-
(MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT);
141+
return ARRAY_SIZE(mana_eth_stats) + ARRAY_SIZE(mana_phy_stats) +
142+
num_queues * (MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT);
88143
}
89144

90145
static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
@@ -99,6 +154,9 @@ static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
99154
for (i = 0; i < ARRAY_SIZE(mana_eth_stats); i++)
100155
ethtool_puts(&data, mana_eth_stats[i].name);
101156

157+
for (i = 0; i < ARRAY_SIZE(mana_phy_stats); i++)
158+
ethtool_puts(&data, mana_phy_stats[i].name);
159+
102160
for (i = 0; i < num_queues; i++) {
103161
ethtool_sprintf(&data, "rx_%d_packets", i);
104162
ethtool_sprintf(&data, "rx_%d_bytes", i);
@@ -128,6 +186,7 @@ static void mana_get_ethtool_stats(struct net_device *ndev,
128186
struct mana_port_context *apc = netdev_priv(ndev);
129187
unsigned int num_queues = apc->num_queues;
130188
void *eth_stats = &apc->eth_stats;
189+
void *phy_stats = &apc->phy_stats;
131190
struct mana_stats_rx *rx_stats;
132191
struct mana_stats_tx *tx_stats;
133192
unsigned int start;
@@ -151,9 +210,18 @@ static void mana_get_ethtool_stats(struct net_device *ndev,
151210
/* we call mana function to update stats from GDMA */
152211
mana_query_gf_stats(apc);
153212

213+
/* We call this mana function to get the phy stats from GDMA and includes
214+
* aggregate tx/rx drop counters, Per-TC(Traffic Channel) tx/rx and pause
215+
* counters.
216+
*/
217+
mana_query_phy_stats(apc);
218+
154219
for (q = 0; q < ARRAY_SIZE(mana_eth_stats); q++)
155220
data[i++] = *(u64 *)(eth_stats + mana_eth_stats[q].offset);
156221

222+
for (q = 0; q < ARRAY_SIZE(mana_phy_stats); q++)
223+
data[i++] = *(u64 *)(phy_stats + mana_phy_stats[q].offset);
224+
157225
for (q = 0; q < num_queues; q++) {
158226
rx_stats = &apc->rxqs[q]->stats;
159227

0 commit comments

Comments
 (0)