Message ID | 20240814092033.2984734-3-danishanwar@ti.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Add support for ICSSG PA_STATS | expand |
On Wed, Aug 14, 2024 at 02:50:33PM +0530, MD Danish Anwar wrote: > Add support for dumping PA stats registers via ethtool. > Firmware maintained stats are stored at PA Stats registers. > Also modify emac_get_strings() API to use ethtool_puts(). > > Signed-off-by: MD Danish Anwar <danishanwar@ti.com> > --- > drivers/net/ethernet/ti/icssg/icssg_ethtool.c | 17 +++++----- > drivers/net/ethernet/ti/icssg/icssg_prueth.c | 6 ++++ > drivers/net/ethernet/ti/icssg/icssg_prueth.h | 5 ++- > drivers/net/ethernet/ti/icssg/icssg_stats.c | 19 +++++++++-- > drivers/net/ethernet/ti/icssg/icssg_stats.h | 32 +++++++++++++++++++ > 5 files changed, 67 insertions(+), 12 deletions(-) > > diff --git a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c > index 5688f054cec5..51bb509d37c7 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c > +++ b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c > @@ -83,13 +83,11 @@ static void emac_get_strings(struct net_device *ndev, u32 stringset, u8 *data) > > switch (stringset) { > case ETH_SS_STATS: > - for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) { > - if (!icssg_all_stats[i].standard_stats) { > - memcpy(p, icssg_all_stats[i].name, > - ETH_GSTRING_LEN); > - p += ETH_GSTRING_LEN; > - } > - } > + for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) > + if (!icssg_all_stats[i].standard_stats) > + ethtool_puts(&p, icssg_all_stats[i].name); > + for (i = 0; i < ICSSG_NUM_PA_STATS; i++) It would probably be better to use ARRAY_SIZE(icssg_all_pa_stats) so that it's consistent with the loop right before. > + ethtool_puts(&p, icssg_all_pa_stats[i].name); > break; > default: > break; > @@ -100,13 +98,16 @@ static void emac_get_ethtool_stats(struct net_device *ndev, > struct ethtool_stats *stats, u64 *data) > { > struct prueth_emac *emac = netdev_priv(ndev); > - int i; > + int i, j; > > emac_update_hardware_stats(emac); > > for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) > if (!icssg_all_stats[i].standard_stats) > *(data++) = emac->stats[i]; > + > + for (j = 0; j < ICSSG_NUM_PA_STATS; j++) > + *(data++) = emac->stats[i + j]; Here i is not an iterator. It's a stand in for ARRAY_SIZE(icssg_all_stats). It would be more readable to do that directly. for (i = 0; i < ICSSG_NUM_PA_STATS; i++) *(data++) = emac->stats[ARRAY_SIZE(icssg_all_stats) + i]; To be honest, putting the pa_stats at the end of ->stats would have made sense if we could have looped over the whole array, but since they have to be treated differently we should probably just put them into their own ->pa_stats array. I haven't tested this so maybe I've missed something obvious. The "all" in "icssg_all_stats" doesn't really make sense anymore btw... Sorry for being so nit picky on a v5 patch. :( regards, dan carpenter
On Wed, Aug 14, 2024 at 02:50:33PM +0530, MD Danish Anwar wrote: ... > diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h > index f678d656a3ed..ac2291d22c42 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h > +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h > @@ -50,8 +50,10 @@ > > #define ICSSG_MAX_RFLOWS 8 /* per slice */ > > +#define ICSSG_NUM_PA_STATS 4 > +#define ICSSG_NUM_MII_G_RT_STATS 60 > /* Number of ICSSG related stats */ > -#define ICSSG_NUM_STATS 60 > +#define ICSSG_NUM_STATS (ICSSG_NUM_MII_G_RT_STATS + ICSSG_NUM_PA_STATS) > #define ICSSG_NUM_STANDARD_STATS 31 > #define ICSSG_NUM_ETHTOOL_STATS (ICSSG_NUM_STATS - ICSSG_NUM_STANDARD_STATS) > > @@ -263,6 +265,7 @@ struct prueth { > struct net_device *registered_netdevs[PRUETH_NUM_MACS]; > struct regmap *miig_rt; > struct regmap *mii_rt; > + struct regmap *pa_stats; Please add an entry for pa_stats to the Kernel doc for this structure. > > enum pruss_pru_id pru_id[PRUSS_NUM_PRUS]; > struct platform_device *pdev; ... > diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.h b/drivers/net/ethernet/ti/icssg/icssg_stats.h > index 999a4a91276c..e834316092c9 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_stats.h > +++ b/drivers/net/ethernet/ti/icssg/icssg_stats.h > @@ -77,6 +77,20 @@ struct miig_stats_regs { > u32 tx_bytes; > }; > > +/** > + * struct pa_stats_regs - ICSSG Firmware maintained PA Stats register > + * @u32 fw_rx_cnt: Number of valid packets sent by Rx PRU to Host on PSI > + * @u32 fw_tx_cnt: Number of valid packets copied by RTU0 to Tx queues > + * @u32 fw_tx_pre_overflow: Host Egress Q (Pre-emptible) Overflow Counter > + * @u32 fw_tx_exp_overflow: Host Egress Q (Express) Overflow Counter > + */ ./scripts/kernel-doc -none doesn't seem to like the syntax above. Perhaps s/u32 // ? > +struct pa_stats_regs { > + u32 fw_rx_cnt; > + u32 fw_tx_cnt; > + u32 fw_tx_pre_overflow; > + u32 fw_tx_exp_overflow; > +}; > + > #define ICSSG_STATS(field, stats_type) \ > { \ > #field, \ ...
On 8/15/2024 9:31 PM, Simon Horman wrote: > On Wed, Aug 14, 2024 at 02:50:33PM +0530, MD Danish Anwar wrote: > > ... > >> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h >> index f678d656a3ed..ac2291d22c42 100644 >> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h >> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h >> @@ -50,8 +50,10 @@ >> >> #define ICSSG_MAX_RFLOWS 8 /* per slice */ >> >> +#define ICSSG_NUM_PA_STATS 4 >> +#define ICSSG_NUM_MII_G_RT_STATS 60 >> /* Number of ICSSG related stats */ >> -#define ICSSG_NUM_STATS 60 >> +#define ICSSG_NUM_STATS (ICSSG_NUM_MII_G_RT_STATS + ICSSG_NUM_PA_STATS) >> #define ICSSG_NUM_STANDARD_STATS 31 >> #define ICSSG_NUM_ETHTOOL_STATS (ICSSG_NUM_STATS - ICSSG_NUM_STANDARD_STATS) >> >> @@ -263,6 +265,7 @@ struct prueth { >> struct net_device *registered_netdevs[PRUETH_NUM_MACS]; >> struct regmap *miig_rt; >> struct regmap *mii_rt; >> + struct regmap *pa_stats; > > Please add an entry for pa_stats to the Kernel doc for this structure. > >> >> enum pruss_pru_id pru_id[PRUSS_NUM_PRUS]; >> struct platform_device *pdev; > > ... > >> diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.h b/drivers/net/ethernet/ti/icssg/icssg_stats.h >> index 999a4a91276c..e834316092c9 100644 >> --- a/drivers/net/ethernet/ti/icssg/icssg_stats.h >> +++ b/drivers/net/ethernet/ti/icssg/icssg_stats.h >> @@ -77,6 +77,20 @@ struct miig_stats_regs { >> u32 tx_bytes; >> }; >> >> +/** >> + * struct pa_stats_regs - ICSSG Firmware maintained PA Stats register >> + * @u32 fw_rx_cnt: Number of valid packets sent by Rx PRU to Host on PSI >> + * @u32 fw_tx_cnt: Number of valid packets copied by RTU0 to Tx queues >> + * @u32 fw_tx_pre_overflow: Host Egress Q (Pre-emptible) Overflow Counter >> + * @u32 fw_tx_exp_overflow: Host Egress Q (Express) Overflow Counter >> + */ > > ./scripts/kernel-doc -none doesn't seem to like the syntax above. > Perhaps s/u32 // ? Sure, I will drop u32 from comment. > >> +struct pa_stats_regs { >> + u32 fw_rx_cnt; >> + u32 fw_tx_cnt; >> + u32 fw_tx_pre_overflow; >> + u32 fw_tx_exp_overflow; >> +}; >> + >> #define ICSSG_STATS(field, stats_type) \ >> { \ >> #field, \ > > ...
On 8/15/2024 4:58 PM, Dan Carpenter wrote: > On Wed, Aug 14, 2024 at 02:50:33PM +0530, MD Danish Anwar wrote: >> Add support for dumping PA stats registers via ethtool. >> Firmware maintained stats are stored at PA Stats registers. >> Also modify emac_get_strings() API to use ethtool_puts(). >> >> Signed-off-by: MD Danish Anwar <danishanwar@ti.com> >> --- >> drivers/net/ethernet/ti/icssg/icssg_ethtool.c | 17 +++++----- >> drivers/net/ethernet/ti/icssg/icssg_prueth.c | 6 ++++ >> drivers/net/ethernet/ti/icssg/icssg_prueth.h | 5 ++- >> drivers/net/ethernet/ti/icssg/icssg_stats.c | 19 +++++++++-- >> drivers/net/ethernet/ti/icssg/icssg_stats.h | 32 +++++++++++++++++++ >> 5 files changed, 67 insertions(+), 12 deletions(-) >> >> diff --git a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c >> index 5688f054cec5..51bb509d37c7 100644 >> --- a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c >> +++ b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c >> @@ -83,13 +83,11 @@ static void emac_get_strings(struct net_device *ndev, u32 stringset, u8 *data) >> >> switch (stringset) { >> case ETH_SS_STATS: >> - for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) { >> - if (!icssg_all_stats[i].standard_stats) { >> - memcpy(p, icssg_all_stats[i].name, >> - ETH_GSTRING_LEN); >> - p += ETH_GSTRING_LEN; >> - } >> - } >> + for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) >> + if (!icssg_all_stats[i].standard_stats) >> + ethtool_puts(&p, icssg_all_stats[i].name); >> + for (i = 0; i < ICSSG_NUM_PA_STATS; i++) > > It would probably be better to use ARRAY_SIZE(icssg_all_pa_stats) so that it's > consistent with the loop right before. Sure Dan. > >> + ethtool_puts(&p, icssg_all_pa_stats[i].name); >> break; >> default: >> break; >> @@ -100,13 +98,16 @@ static void emac_get_ethtool_stats(struct net_device *ndev, >> struct ethtool_stats *stats, u64 *data) >> { >> struct prueth_emac *emac = netdev_priv(ndev); >> - int i; >> + int i, j; >> >> emac_update_hardware_stats(emac); >> >> for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) >> if (!icssg_all_stats[i].standard_stats) >> *(data++) = emac->stats[i]; >> + >> + for (j = 0; j < ICSSG_NUM_PA_STATS; j++) >> + *(data++) = emac->stats[i + j]; > > Here i is not an iterator. It's a stand in for ARRAY_SIZE(icssg_all_stats). > It would be more readable to do that directly. > > for (i = 0; i < ICSSG_NUM_PA_STATS; i++) > *(data++) = emac->stats[ARRAY_SIZE(icssg_all_stats) + i]; > > To be honest, putting the pa_stats at the end of ->stats would have made sense > if we could have looped over the whole array, but since they have to be treated > differently we should probably just put them into their own ->pa_stats array. > Sure Dan. It will make more sense to have different array for pa_stats. I will do this change and update. > I haven't tested this so maybe I've missed something obvious. > > The "all" in "icssg_all_stats" doesn't really make sense anymore btw... > Correct, the "icssg_all_stats" should be renamed to "icssg_mii_g_rt_stats". > Sorry for being so nit picky on a v5 patch. :( > It's okay. Thanks for the review. I will address all these comments and send out a v6. > regards, > dan carpenter >
diff --git a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c index 5688f054cec5..51bb509d37c7 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c +++ b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c @@ -83,13 +83,11 @@ static void emac_get_strings(struct net_device *ndev, u32 stringset, u8 *data) switch (stringset) { case ETH_SS_STATS: - for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) { - if (!icssg_all_stats[i].standard_stats) { - memcpy(p, icssg_all_stats[i].name, - ETH_GSTRING_LEN); - p += ETH_GSTRING_LEN; - } - } + for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) + if (!icssg_all_stats[i].standard_stats) + ethtool_puts(&p, icssg_all_stats[i].name); + for (i = 0; i < ICSSG_NUM_PA_STATS; i++) + ethtool_puts(&p, icssg_all_pa_stats[i].name); break; default: break; @@ -100,13 +98,16 @@ static void emac_get_ethtool_stats(struct net_device *ndev, struct ethtool_stats *stats, u64 *data) { struct prueth_emac *emac = netdev_priv(ndev); - int i; + int i, j; emac_update_hardware_stats(emac); for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) if (!icssg_all_stats[i].standard_stats) *(data++) = emac->stats[i]; + + for (j = 0; j < ICSSG_NUM_PA_STATS; j++) + *(data++) = emac->stats[i + j]; } static int emac_get_ts_info(struct net_device *ndev, diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c index 53a3e44b99a2..f623a0f603fc 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -1182,6 +1182,12 @@ static int prueth_probe(struct platform_device *pdev) return -ENODEV; } + prueth->pa_stats = syscon_regmap_lookup_by_phandle(np, "ti,pa-stats"); + if (IS_ERR(prueth->pa_stats)) { + dev_err(dev, "couldn't get ti,pa-stats syscon regmap\n"); + return -ENODEV; + } + if (eth0_node) { ret = prueth_get_cores(prueth, ICSS_SLICE0, false); if (ret) diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h index f678d656a3ed..ac2291d22c42 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h @@ -50,8 +50,10 @@ #define ICSSG_MAX_RFLOWS 8 /* per slice */ +#define ICSSG_NUM_PA_STATS 4 +#define ICSSG_NUM_MII_G_RT_STATS 60 /* Number of ICSSG related stats */ -#define ICSSG_NUM_STATS 60 +#define ICSSG_NUM_STATS (ICSSG_NUM_MII_G_RT_STATS + ICSSG_NUM_PA_STATS) #define ICSSG_NUM_STANDARD_STATS 31 #define ICSSG_NUM_ETHTOOL_STATS (ICSSG_NUM_STATS - ICSSG_NUM_STANDARD_STATS) @@ -263,6 +265,7 @@ struct prueth { struct net_device *registered_netdevs[PRUETH_NUM_MACS]; struct regmap *miig_rt; struct regmap *mii_rt; + struct regmap *pa_stats; enum pruss_pru_id pru_id[PRUSS_NUM_PRUS]; struct platform_device *pdev; diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.c b/drivers/net/ethernet/ti/icssg/icssg_stats.c index 2fb150c13078..ce6606e4a369 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_stats.c +++ b/drivers/net/ethernet/ti/icssg/icssg_stats.c @@ -11,6 +11,7 @@ #define ICSSG_TX_PACKET_OFFSET 0xA0 #define ICSSG_TX_BYTE_OFFSET 0xEC +#define ICSSG_FW_STATS_BASE 0x0248 static u32 stats_base[] = { 0x54c, /* Slice 0 stats start */ 0xb18, /* Slice 1 stats start */ @@ -22,8 +23,8 @@ void emac_update_hardware_stats(struct prueth_emac *emac) int slice = prueth_emac_slice(emac); u32 base = stats_base[slice]; u32 tx_pkt_cnt = 0; - u32 val; - int i; + u32 val, reg; + int i, j; for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) { regmap_read(prueth->miig_rt, @@ -40,6 +41,13 @@ void emac_update_hardware_stats(struct prueth_emac *emac) if (icssg_all_stats[i].offset == ICSSG_TX_BYTE_OFFSET) emac->stats[i] -= tx_pkt_cnt * 8; } + + for (j = 0; j < ICSSG_NUM_PA_STATS; j++) { + reg = ICSSG_FW_STATS_BASE + icssg_all_pa_stats[j].offset * + PRUETH_NUM_MACS + slice * sizeof(u32); + regmap_read(prueth->pa_stats, reg, &val); + emac->stats[i + j] += val; + } } void icssg_stats_work_handler(struct work_struct *work) @@ -55,13 +63,18 @@ EXPORT_SYMBOL_GPL(icssg_stats_work_handler); int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name) { - int i; + int i, j; for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) { if (!strcmp(icssg_all_stats[i].name, stat_name)) return emac->stats[icssg_all_stats[i].offset / sizeof(u32)]; } + for (j = 0; j < ICSSG_NUM_PA_STATS; j++) { + if (!strcmp(icssg_all_pa_stats[j].name, stat_name)) + return emac->stats[i + icssg_all_pa_stats[j].offset / sizeof(u32)]; + } + netdev_err(emac->ndev, "Invalid stats %s\n", stat_name); return -EINVAL; } diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.h b/drivers/net/ethernet/ti/icssg/icssg_stats.h index 999a4a91276c..e834316092c9 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_stats.h +++ b/drivers/net/ethernet/ti/icssg/icssg_stats.h @@ -77,6 +77,20 @@ struct miig_stats_regs { u32 tx_bytes; }; +/** + * struct pa_stats_regs - ICSSG Firmware maintained PA Stats register + * @u32 fw_rx_cnt: Number of valid packets sent by Rx PRU to Host on PSI + * @u32 fw_tx_cnt: Number of valid packets copied by RTU0 to Tx queues + * @u32 fw_tx_pre_overflow: Host Egress Q (Pre-emptible) Overflow Counter + * @u32 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_STATS(field, stats_type) \ { \ #field, \ @@ -84,12 +98,23 @@ struct miig_stats_regs { stats_type \ } +#define ICSSG_PA_STATS(field) \ +{ \ + #field, \ + offsetof(struct pa_stats_regs, field), \ +} + struct icssg_stats { char name[ETH_GSTRING_LEN]; u32 offset; bool standard_stats; }; +struct icssg_pa_stats { + char name[ETH_GSTRING_LEN]; + u32 offset; +}; + static const struct icssg_stats icssg_all_stats[] = { /* Rx */ ICSSG_STATS(rx_packets, true), @@ -155,4 +180,11 @@ static const struct icssg_stats icssg_all_stats[] = { ICSSG_STATS(tx_bytes, true), }; +static const struct icssg_pa_stats icssg_all_pa_stats[] = { + ICSSG_PA_STATS(fw_rx_cnt), + ICSSG_PA_STATS(fw_tx_cnt), + ICSSG_PA_STATS(fw_tx_pre_overflow), + ICSSG_PA_STATS(fw_tx_exp_overflow), +}; + #endif /* __NET_TI_ICSSG_STATS_H */
Add support for dumping PA stats registers via ethtool. Firmware maintained stats are stored at PA Stats registers. Also modify emac_get_strings() API to use ethtool_puts(). Signed-off-by: MD Danish Anwar <danishanwar@ti.com> --- drivers/net/ethernet/ti/icssg/icssg_ethtool.c | 17 +++++----- drivers/net/ethernet/ti/icssg/icssg_prueth.c | 6 ++++ drivers/net/ethernet/ti/icssg/icssg_prueth.h | 5 ++- drivers/net/ethernet/ti/icssg/icssg_stats.c | 19 +++++++++-- drivers/net/ethernet/ti/icssg/icssg_stats.h | 32 +++++++++++++++++++ 5 files changed, 67 insertions(+), 12 deletions(-)