Add per-queue TX/RX packet and byte counters to the VF ethtool stats table. The stats length is now dynamically determined based on whether the device is a VF or PF via wx_stats_len(). Signed-off-by: Mengyuan Lou --- .../net/ethernet/wangxun/libwx/wx_ethtool.c | 48 +++++++++++++++---- drivers/net/ethernet/wangxun/libwx/wx_hw.c | 4 ++ .../net/ethernet/wangxun/libwx/wx_vf_common.c | 2 + 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c index 30c6ef6103ac..86f6ac63acf7 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c @@ -48,6 +48,10 @@ static const struct wx_stats wx_gstrings_stats[] = { WX_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared), }; +static const struct wx_stats wx_gstrings_stats_vf[] = { + WX_STAT("non_eop_descs", non_eop_descs), +}; + static const struct wx_stats wx_gstrings_fdir_stats[] = { WX_STAT("fdir_match", stats.fdirmatch), WX_STAT("fdir_miss", stats.fdirmiss), @@ -69,15 +73,26 @@ static const struct wx_stats wx_gstrings_rsc_stats[] = { #define WX_QUEUE_STATS_LEN ( \ (WX_NUM_TX_QUEUES + WX_NUM_RX_QUEUES) * \ (sizeof(struct wx_queue_stats) / sizeof(u64))) -#define WX_GLOBAL_STATS_LEN ARRAY_SIZE(wx_gstrings_stats) #define WX_FDIR_STATS_LEN ARRAY_SIZE(wx_gstrings_fdir_stats) #define WX_RSC_STATS_LEN ARRAY_SIZE(wx_gstrings_rsc_stats) -#define WX_STATS_LEN (WX_GLOBAL_STATS_LEN + WX_QUEUE_STATS_LEN) + +static inline unsigned int wx_global_stats_len(const struct wx *wx) +{ + return wx->pdev->is_virtfn ? + ARRAY_SIZE(wx_gstrings_stats_vf) : ARRAY_SIZE(wx_gstrings_stats); +} + +static inline unsigned int wx_stats_len(const struct wx *wx) +{ + struct net_device *netdev = wx->netdev; + + return wx_global_stats_len(wx) + WX_QUEUE_STATS_LEN; +} int wx_get_sset_count(struct net_device *netdev, int sset) { struct wx *wx = netdev_priv(netdev); - int len = WX_STATS_LEN; + int len = wx_stats_len(wx); switch (sset) { case ETH_SS_STATS: @@ -100,8 +115,11 @@ void wx_get_strings(struct net_device *netdev, u32 stringset, u8 *data) switch (stringset) { case ETH_SS_STATS: - for (i = 0; i < WX_GLOBAL_STATS_LEN; i++) - ethtool_puts(&p, wx_gstrings_stats[i].stat_string); + for (i = 0; i < wx_global_stats_len(wx); i++) + if (wx->pdev->is_virtfn) + ethtool_puts(&p, wx_gstrings_stats_vf[i].stat_string); + else + ethtool_puts(&p, wx_gstrings_stats[i].stat_string); if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) { for (i = 0; i < WX_FDIR_STATS_LEN; i++) ethtool_puts(&p, wx_gstrings_fdir_stats[i].stat_string); @@ -134,10 +152,16 @@ void wx_get_ethtool_stats(struct net_device *netdev, wx_update_stats(wx); - for (i = 0; i < WX_GLOBAL_STATS_LEN; i++) { - p = (char *)wx + wx_gstrings_stats[i].stat_offset; - data[i] = (wx_gstrings_stats[i].sizeof_stat == - sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + for (i = 0; i < wx_global_stats_len(wx); i++) { + if (wx->pdev->is_virtfn) { + p = (char *)wx + wx_gstrings_stats_vf[i].stat_offset; + data[i] = (wx_gstrings_stats_vf[i].sizeof_stat == + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + } else { + p = (char *)wx + wx_gstrings_stats[i].stat_offset; + data[i] = (wx_gstrings_stats[i].sizeof_stat == + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + } } if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) { @@ -219,9 +243,10 @@ EXPORT_SYMBOL(wx_get_pause_stats); void wx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info) { - unsigned int stats_len = WX_STATS_LEN; struct wx *wx = netdev_priv(netdev); + unsigned int stats_len; + stats_len = wx_stats_len(wx); if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) stats_len += WX_FDIR_STATS_LEN; @@ -851,6 +876,9 @@ static const struct ethtool_ops wx_ethtool_ops_vf = { .set_coalesce = wx_set_coalesce, .get_ts_info = ethtool_op_get_ts_info, .get_link_ksettings = wx_get_link_ksettings_vf, + .get_sset_count = wx_get_sset_count, + .get_strings = wx_get_strings, + .get_ethtool_stats = wx_get_ethtool_stats, }; void wx_set_ethtool_ops_vf(struct net_device *netdev) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c index 260e14d5d541..ce172b6deb80 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c @@ -2917,6 +2917,9 @@ void wx_update_stats(struct wx *wx) wx->restart_queue = restart_queue; wx->tx_busy = tx_busy; + if (wx->pdev->is_virtfn) + goto skip_hw_stats; + wx_update_xoff_rx_lfc(wx); hwstats->gprc += rd32(wx, WX_RDM_PKT_CNT); @@ -2956,6 +2959,7 @@ void wx_update_stats(struct wx *wx) hwstats->qmprc += rd32_wrap(wx, WX_PX_MPRC(i), &wx->last_stats.qmprc[i]); +skip_hw_stats: spin_unlock(&wx->hw_stats_lock); } EXPORT_SYMBOL(wx_update_stats); diff --git a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c index 26de78e9a69e..1d84fe35d7d9 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c @@ -5,6 +5,7 @@ #include #include "wx_type.h" +#include "wx_hw.h" #include "wx_mbx.h" #include "wx_lib.h" #include "wx_vf.h" @@ -409,6 +410,7 @@ static void wxvf_service_task(struct work_struct *work) wxvf_link_config_subtask(wx); wxvf_reset_subtask(wx); + wx_update_stats(wx); wx_service_event_complete(wx); } -- 2.30.1