summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/pensando/ionic/ionic_ethtool.c')
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_ethtool.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index 78a802eb159f..c4ab4b5caa0a 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -115,9 +115,32 @@ static void ionic_get_link_ext_stats(struct net_device *netdev,
struct ethtool_link_ext_stats *stats)
{
struct ionic_lif *lif = netdev_priv(netdev);
+ struct ionic *ionic = lif->ionic;
+ u64 link_down_count_total;
+ u16 link_down_count_fw;
+
+ if (ionic->pdev->is_virtfn)
+ return;
+
+ if (!ionic->idev.port_info) {
+ netdev_err_once(netdev, "port_info not initialized\n");
+ return;
+ }
+
+ link_down_count_fw =
+ le16_to_cpu(ionic->idev.port_info->status.link_down_count);
+ link_down_count_total = ionic->idev.link_down_count_total +
+ link_down_count_fw -
+ ionic->idev.link_down_count_last;
+
+ /* The firmware counter is only 16 bits and can wraparound */
+ if (link_down_count_fw < ionic->idev.link_down_count_last)
+ link_down_count_total += BIT(16);
+
+ ionic->idev.link_down_count_last = link_down_count_fw;
+ ionic->idev.link_down_count_total = link_down_count_total;
- if (lif->ionic->pdev->is_physfn)
- stats->link_down_events = lif->link_down_count;
+ stats->link_down_events = link_down_count_total;
}
static int ionic_get_link_ksettings(struct net_device *netdev,