diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h index 69cb73ca8bca..e2fffe1597e9 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h @@ -844,6 +844,10 @@ enum { #define FBNIC_CSR_END_SIG 0x1184e /* CSR section delimiter */ #define FBNIC_CSR_START_MAC_STAT 0x11a00 +#define FBNIC_MAC_STAT_RX_XOFF_STB_L 0x11a00 /* 0x46800 */ +#define FBNIC_MAC_STAT_RX_XOFF_STB_H 0x11a01 /* 0x46804 */ +#define FBNIC_MAC_STAT_TX_XOFF_STB_L 0x11a04 /* 0x46810 */ +#define FBNIC_MAC_STAT_TX_XOFF_STB_H 0x11a05 /* 0x46814 */ #define FBNIC_MAC_STAT_RX_BYTE_COUNT_L 0x11a08 /* 0x46820 */ #define FBNIC_MAC_STAT_RX_BYTE_COUNT_H 0x11a09 /* 0x46824 */ #define FBNIC_MAC_STAT_RX_ALIGN_ERROR_L 0x11a0a /* 0x46828 */ diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c index 4194b30f1074..b4ff98ee2051 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c @@ -1641,6 +1641,22 @@ static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter) *stat = counter->value; } +static void +fbnic_get_pause_stats(struct net_device *netdev, + struct ethtool_pause_stats *pause_stats) +{ + struct fbnic_net *fbn = netdev_priv(netdev); + struct fbnic_mac_stats *mac_stats; + struct fbnic_dev *fbd = fbn->fbd; + + mac_stats = &fbd->hw_stats.mac; + + fbd->mac->get_pause_stats(fbd, false, &mac_stats->pause); + + pause_stats->tx_pause_frames = mac_stats->pause.tx_pause_frames.value; + pause_stats->rx_pause_frames = mac_stats->pause.rx_pause_frames.value; +} + static void fbnic_get_fec_stats(struct net_device *netdev, struct ethtool_fec_stats *fec_stats) @@ -1801,6 +1817,7 @@ static const struct ethtool_ops fbnic_ethtool_ops = { .set_coalesce = fbnic_set_coalesce, .get_ringparam = fbnic_get_ringparam, .set_ringparam = fbnic_set_ringparam, + .get_pause_stats = fbnic_get_pause_stats, .get_pauseparam = fbnic_phylink_get_pauseparam, .set_pauseparam = fbnic_phylink_set_pauseparam, .get_strings = fbnic_get_strings, diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c index 9e7becba7386..8b9b2076beec 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c @@ -536,6 +536,7 @@ static void fbnic_reset_hw_mac_stats(struct fbnic_dev *fbd, const struct fbnic_mac *mac = fbd->mac; mac->get_eth_mac_stats(fbd, true, &mac_stats->eth_mac); + mac->get_pause_stats(fbd, true, &mac_stats->pause); mac->get_eth_ctrl_stats(fbd, true, &mac_stats->eth_ctrl); mac->get_rmon_stats(fbd, true, &mac_stats->rmon); } diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h index baffae1868a6..aa3f429a9aed 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h @@ -50,6 +50,12 @@ struct fbnic_rmon_stats { struct fbnic_stat_counter hist_tx[ETHTOOL_RMON_HIST_MAX]; }; +/* Note: not updated by fbnic_get_hw_stats() */ +struct fbnic_pause_stats { + struct fbnic_stat_counter tx_pause_frames; + struct fbnic_stat_counter rx_pause_frames; +}; + struct fbnic_eth_mac_stats { struct fbnic_stat_counter FramesTransmittedOK; struct fbnic_stat_counter FramesReceivedOK; @@ -73,6 +79,7 @@ struct fbnic_phy_stats { struct fbnic_mac_stats { struct fbnic_eth_mac_stats eth_mac; + struct fbnic_pause_stats pause; struct fbnic_eth_ctrl_stats eth_ctrl; struct fbnic_rmon_stats rmon; }; diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c index ffdaebd4002a..8f998d26b9a3 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c @@ -709,6 +709,16 @@ fbnic_mac_get_eth_mac_stats(struct fbnic_dev *fbd, bool reset, MAC_STAT_TX_BROADCAST); } +static void +fbnic_mac_get_pause_stats(struct fbnic_dev *fbd, bool reset, + struct fbnic_pause_stats *pause_stats) +{ + fbnic_mac_stat_rd64(fbd, reset, pause_stats->tx_pause_frames, + MAC_STAT_TX_XOFF_STB); + fbnic_mac_stat_rd64(fbd, reset, pause_stats->rx_pause_frames, + MAC_STAT_RX_XOFF_STB); +} + static void fbnic_mac_get_eth_ctrl_stats(struct fbnic_dev *fbd, bool reset, struct fbnic_eth_ctrl_stats *ctrl_stats) @@ -856,6 +866,7 @@ static const struct fbnic_mac fbnic_mac_asic = { .get_fec_stats = fbnic_mac_get_fec_stats, .get_pcs_stats = fbnic_mac_get_pcs_stats, .get_eth_mac_stats = fbnic_mac_get_eth_mac_stats, + .get_pause_stats = fbnic_mac_get_pause_stats, .get_eth_ctrl_stats = fbnic_mac_get_eth_ctrl_stats, .get_rmon_stats = fbnic_mac_get_rmon_stats, .link_down = fbnic_mac_link_down_asic, diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.h b/drivers/net/ethernet/meta/fbnic/fbnic_mac.h index 92dd6efb920a..ede5ff0dae22 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.h @@ -85,6 +85,8 @@ struct fbnic_mac { struct fbnic_pcs_stats *pcs_stats); void (*get_eth_mac_stats)(struct fbnic_dev *fbd, bool reset, struct fbnic_eth_mac_stats *mac_stats); + void (*get_pause_stats)(struct fbnic_dev *fbd, bool reset, + struct fbnic_pause_stats *pause_stats); void (*get_eth_ctrl_stats)(struct fbnic_dev *fbd, bool reset, struct fbnic_eth_ctrl_stats *ctrl_stats); void (*get_rmon_stats)(struct fbnic_dev *fbd, bool reset,