Add the ndo_get_stats64() helper in the Annapurna Labs Alpine Ethernet driver. --- drivers/net/ethernet/annapurna/al_eth.c | 36 ++++ drivers/net/ethernet/annapurna/al_hw_eth.h | 9 + drivers/net/ethernet/annapurna/al_hw_eth_main.c | 225 ++++++++++++++++++++++++ 3 files changed, 270 insertions(+)
diff --git a/drivers/net/ethernet/annapurna/al_eth.c b/drivers/net/ethernet/annapurna/al_eth.c index 779a885de014..8dd84f66b5d1 100644 --- a/drivers/net/ethernet/annapurna/al_eth.c +++ b/drivers/net/ethernet/annapurna/al_eth.c @@ -2388,6 +2388,41 @@ static void al_eth_set_msglevel(struct net_device *netdev, u32 value) adapter->msg_enable = value; } +static void al_eth_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) +{ + struct al_eth_adapter *adapter = netdev_priv(netdev); + struct al_eth_mac_stats *mac_stats = &adapter->mac_stats; + + if (!adapter->up) + return NULL; + + al_eth_mac_stats_get(&adapter->hw_adapter, mac_stats); + + stats->rx_packets = mac_stats->aFramesReceivedOK; /* including pause frames */ + stats->tx_packets = mac_stats->aFramesTransmittedOK; /* including pause frames */ + stats->rx_bytes = mac_stats->aOctetsReceivedOK; + stats->tx_bytes = mac_stats->aOctetsTransmittedOK; + stats->rx_dropped = 0; + stats->multicast = mac_stats->ifInMulticastPkts; + stats->collisions = 0; + + stats->rx_length_errors = (mac_stats->etherStatsUndersizePkts + /* good but short */ + mac_stats->etherStatsFragments + /* short and bad*/ + mac_stats->etherStatsJabbers + /* with crc errors */ + mac_stats->etherStatsOversizePkts); + stats->rx_crc_errors = mac_stats->aFrameCheckSequenceErrors; + stats->rx_frame_errors = mac_stats->aAlignmentErrors; + stats->rx_fifo_errors = mac_stats->etherStatsDropEvents; + stats->rx_missed_errors = 0; + stats->tx_window_errors = 0; + + stats->rx_errors = mac_stats->ifInErrors; + stats->tx_errors = mac_stats->ifOutErrors; + + return stats; +} + static void al_eth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { @@ -2763,6 +2798,7 @@ static const struct net_device_ops al_eth_netdev_ops = { .ndo_stop = al_eth_close, .ndo_start_xmit = al_eth_start_xmit, .ndo_select_queue = al_eth_select_queue, + .ndo_get_stats64 = al_eth_get_stats64, .ndo_do_ioctl = al_eth_ioctl, .ndo_tx_timeout = al_eth_tx_timeout, .ndo_change_mtu = al_eth_change_mtu, diff --git a/drivers/net/ethernet/annapurna/al_hw_eth.h b/drivers/net/ethernet/annapurna/al_hw_eth.h index b2fc58793b3a..a44f3f200838 100644 --- a/drivers/net/ethernet/annapurna/al_hw_eth.h +++ b/drivers/net/ethernet/annapurna/al_hw_eth.h @@ -982,6 +982,15 @@ struct al_eth_mac_stats { }; /* + * get mac statistics + * @param adapter pointer to the private structure. + * @param stats pointer to structure that will be filled with statistics. + * + * @return return 0 on success. otherwise on failure. + */ +int al_eth_mac_stats_get(struct al_hw_eth_adapter *adapter, struct al_eth_mac_stats *stats); + +/* * perform Function Level Reset RMN * * Addressing RMN: 714 diff --git a/drivers/net/ethernet/annapurna/al_hw_eth_main.c b/drivers/net/ethernet/annapurna/al_hw_eth_main.c index abb9ffd09fbf..dac0c1e2a941 100644 --- a/drivers/net/ethernet/annapurna/al_hw_eth_main.c +++ b/drivers/net/ethernet/annapurna/al_hw_eth_main.c @@ -2639,6 +2639,231 @@ int al_eth_flow_control_config(struct al_hw_eth_adapter *adapter, return 0; } +/* get statistics */ +int al_eth_mac_stats_get(struct al_hw_eth_adapter *adapter, struct al_eth_mac_stats *stats) +{ + WARN_ON(!stats); + + memset(stats, 0, sizeof(struct al_eth_mac_stats)); + + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) { + struct al_eth_mac_1g_stats __iomem *reg_stats = + &adapter->mac_regs_base->mac_1g.stats; + + stats->ifInUcastPkts = readl(®_stats->ifInUcastPkts); + stats->ifInMulticastPkts = readl(®_stats->ifInMulticastPkts); + stats->ifInBroadcastPkts = readl(®_stats->ifInBroadcastPkts); + stats->etherStatsPkts = readl(®_stats->etherStatsPkts); + stats->ifOutUcastPkts = readl(®_stats->ifOutUcastPkts); + stats->ifOutMulticastPkts = readl(®_stats->ifOutMulticastPkts); + stats->ifOutBroadcastPkts = readl(®_stats->ifOutBroadcastPkts); + stats->ifInErrors = readl(®_stats->ifInErrors); + stats->ifOutErrors = readl(®_stats->ifOutErrors); + stats->aFramesReceivedOK = readl(®_stats->aFramesReceivedOK); + stats->aFramesTransmittedOK = readl(®_stats->aFramesTransmittedOK); + stats->aOctetsReceivedOK = readl(®_stats->aOctetsReceivedOK); + stats->aOctetsTransmittedOK = readl(®_stats->aOctetsTransmittedOK); + stats->etherStatsUndersizePkts = readl(®_stats->etherStatsUndersizePkts); + stats->etherStatsFragments = readl(®_stats->etherStatsFragments); + stats->etherStatsJabbers = readl(®_stats->etherStatsJabbers); + stats->etherStatsOversizePkts = readl(®_stats->etherStatsOversizePkts); + stats->aFrameCheckSequenceErrors = + readl(®_stats->aFrameCheckSequenceErrors); + stats->aAlignmentErrors = readl(®_stats->aAlignmentErrors); + stats->etherStatsDropEvents = readl(®_stats->etherStatsDropEvents); + stats->aPAUSEMACCtrlFramesTransmitted = + readl(®_stats->aPAUSEMACCtrlFramesTransmitted); + stats->aPAUSEMACCtrlFramesReceived = + readl(®_stats->aPAUSEMACCtrlFramesReceived); + stats->aFrameTooLongErrors = 0; /* N/A */ + stats->aInRangeLengthErrors = 0; /* N/A */ + stats->VLANTransmittedOK = 0; /* N/A */ + stats->VLANReceivedOK = 0; /* N/A */ + stats->etherStatsOctets = readl(®_stats->etherStatsOctets); + stats->etherStatsPkts64Octets = readl(®_stats->etherStatsPkts64Octets); + stats->etherStatsPkts65to127Octets = + readl(®_stats->etherStatsPkts65to127Octets); + stats->etherStatsPkts128to255Octets = + readl(®_stats->etherStatsPkts128to255Octets); + stats->etherStatsPkts256to511Octets = + readl(®_stats->etherStatsPkts256to511Octets); + stats->etherStatsPkts512to1023Octets = + readl(®_stats->etherStatsPkts512to1023Octets); + stats->etherStatsPkts1024to1518Octets = + readl(®_stats->etherStatsPkts1024to1518Octets); + stats->etherStatsPkts1519toX = readl(®_stats->etherStatsPkts1519toX); + } else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { + if (adapter->rev_id < AL_ETH_REV_ID_3) { + struct al_eth_mac_10g_stats_v2 __iomem *reg_stats = + &adapter->mac_regs_base->mac_10g.stats.v2; + u64 octets; + + stats->ifInUcastPkts = readl(®_stats->ifInUcastPkts); + stats->ifInMulticastPkts = readl(®_stats->ifInMulticastPkts); + stats->ifInBroadcastPkts = readl(®_stats->ifInBroadcastPkts); + stats->etherStatsPkts = readl(®_stats->etherStatsPkts); + stats->ifOutUcastPkts = readl(®_stats->ifOutUcastPkts); + stats->ifOutMulticastPkts = readl(®_stats->ifOutMulticastPkts); + stats->ifOutBroadcastPkts = readl(®_stats->ifOutBroadcastPkts); + stats->ifInErrors = readl(®_stats->ifInErrors); + stats->ifOutErrors = readl(®_stats->ifOutErrors); + stats->aFramesReceivedOK = readl(®_stats->aFramesReceivedOK); + stats->aFramesTransmittedOK = readl(®_stats->aFramesTransmittedOK); + + /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */ + octets = readl(®_stats->ifInOctetsL); + octets |= (u64)(readl(®_stats->ifInOctetsH)) << 32; + octets -= 18 * stats->aFramesReceivedOK; + octets -= 4 * readl(®_stats->VLANReceivedOK); + stats->aOctetsReceivedOK = octets; + + /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */ + octets = readl(®_stats->ifOutOctetsL); + octets |= (u64)(readl(®_stats->ifOutOctetsH)) << 32; + octets -= 18 * stats->aFramesTransmittedOK; + octets -= 4 * readl(®_stats->VLANTransmittedOK); + stats->aOctetsTransmittedOK = octets; + + stats->etherStatsUndersizePkts = readl(®_stats->etherStatsUndersizePkts); + stats->etherStatsFragments = readl(®_stats->etherStatsFragments); + stats->etherStatsJabbers = readl(®_stats->etherStatsJabbers); + stats->etherStatsOversizePkts = readl(®_stats->etherStatsOversizePkts); + stats->aFrameCheckSequenceErrors = readl(®_stats->aFrameCheckSequenceErrors); + stats->aAlignmentErrors = readl(®_stats->aAlignmentErrors); + stats->etherStatsDropEvents = readl(®_stats->etherStatsDropEvents); + stats->aPAUSEMACCtrlFramesTransmitted = readl(®_stats->aPAUSEMACCtrlFramesTransmitted); + stats->aPAUSEMACCtrlFramesReceived = readl(®_stats->aPAUSEMACCtrlFramesReceived); + stats->aFrameTooLongErrors = readl(®_stats->aFrameTooLongErrors); + stats->aInRangeLengthErrors = readl(®_stats->aInRangeLengthErrors); + stats->VLANTransmittedOK = readl(®_stats->VLANTransmittedOK); + stats->VLANReceivedOK = readl(®_stats->VLANReceivedOK); + stats->etherStatsOctets = readl(®_stats->etherStatsOctets); + stats->etherStatsPkts64Octets = readl(®_stats->etherStatsPkts64Octets); + stats->etherStatsPkts65to127Octets = readl(®_stats->etherStatsPkts65to127Octets); + stats->etherStatsPkts128to255Octets = readl(®_stats->etherStatsPkts128to255Octets); + stats->etherStatsPkts256to511Octets = readl(®_stats->etherStatsPkts256to511Octets); + stats->etherStatsPkts512to1023Octets = readl(®_stats->etherStatsPkts512to1023Octets); + stats->etherStatsPkts1024to1518Octets = readl(®_stats->etherStatsPkts1024to1518Octets); + stats->etherStatsPkts1519toX = readl(®_stats->etherStatsPkts1519toX); + } else { + struct al_eth_mac_10g_stats_v3_rx __iomem *reg_rx_stats = + &adapter->mac_regs_base->mac_10g.stats.v3.rx; + struct al_eth_mac_10g_stats_v3_tx __iomem *reg_tx_stats = + &adapter->mac_regs_base->mac_10g.stats.v3.tx; + u64 octets; + + stats->ifInUcastPkts = readl(®_rx_stats->ifInUcastPkts); + stats->ifInMulticastPkts = readl(®_rx_stats->ifInMulticastPkts); + stats->ifInBroadcastPkts = readl(®_rx_stats->ifInBroadcastPkts); + stats->etherStatsPkts = readl(®_rx_stats->etherStatsPkts); + stats->ifOutUcastPkts = readl(®_tx_stats->ifUcastPkts); + stats->ifOutMulticastPkts = readl(®_tx_stats->ifMulticastPkts); + stats->ifOutBroadcastPkts = readl(®_tx_stats->ifBroadcastPkts); + stats->ifInErrors = readl(®_rx_stats->ifInErrors); + stats->ifOutErrors = readl(®_tx_stats->ifOutErrors); + stats->aFramesReceivedOK = readl(®_rx_stats->FramesOK); + stats->aFramesTransmittedOK = readl(®_tx_stats->FramesOK); + + /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */ + octets = readl(®_rx_stats->ifOctetsL); + octets |= (u64)(readl(®_rx_stats->ifOctetsH)) << 32; + octets -= 18 * stats->aFramesReceivedOK; + octets -= 4 * readl(®_rx_stats->VLANOK); + stats->aOctetsReceivedOK = octets; + + /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */ + octets = readl(®_tx_stats->ifOctetsL); + octets |= (u64)(readl(®_tx_stats->ifOctetsH)) << 32; + octets -= 18 * stats->aFramesTransmittedOK; + octets -= 4 * readl(®_tx_stats->VLANOK); + stats->aOctetsTransmittedOK = octets; + + stats->etherStatsUndersizePkts = readl(®_rx_stats->etherStatsUndersizePkts); + stats->etherStatsFragments = readl(®_rx_stats->etherStatsFragments); + stats->etherStatsJabbers = readl(®_rx_stats->etherStatsJabbers); + stats->etherStatsOversizePkts = readl(®_rx_stats->etherStatsOversizePkts); + stats->aFrameCheckSequenceErrors = readl(®_rx_stats->CRCErrors); + stats->aAlignmentErrors = readl(®_rx_stats->aAlignmentErrors); + stats->etherStatsDropEvents = readl(®_rx_stats->etherStatsDropEvents); + stats->aPAUSEMACCtrlFramesTransmitted = readl(®_tx_stats->aPAUSEMACCtrlFrames); + stats->aPAUSEMACCtrlFramesReceived = readl(®_rx_stats->aPAUSEMACCtrlFrames); + stats->aFrameTooLongErrors = readl(®_rx_stats->aFrameTooLong); + stats->aInRangeLengthErrors = readl(®_rx_stats->aInRangeLengthErrors); + stats->VLANTransmittedOK = readl(®_tx_stats->VLANOK); + stats->VLANReceivedOK = readl(®_rx_stats->VLANOK); + stats->etherStatsOctets = readl(®_rx_stats->etherStatsOctets); + stats->etherStatsPkts64Octets = readl(®_rx_stats->etherStatsPkts64Octets); + stats->etherStatsPkts65to127Octets = readl(®_rx_stats->etherStatsPkts65to127Octets); + stats->etherStatsPkts128to255Octets = readl(®_rx_stats->etherStatsPkts128to255Octets); + stats->etherStatsPkts256to511Octets = readl(®_rx_stats->etherStatsPkts256to511Octets); + stats->etherStatsPkts512to1023Octets = readl(®_rx_stats->etherStatsPkts512to1023Octets); + stats->etherStatsPkts1024to1518Octets = readl(®_rx_stats->etherStatsPkts1024to1518Octets); + stats->etherStatsPkts1519toX = readl(®_rx_stats->etherStatsPkts1519toMax); + } + } else { + struct al_eth_mac_10g_stats_v3_rx __iomem *reg_rx_stats = + &adapter->mac_regs_base->mac_10g.stats.v3.rx; + struct al_eth_mac_10g_stats_v3_tx __iomem *reg_tx_stats = + &adapter->mac_regs_base->mac_10g.stats.v3.tx; + u64 octets; + + /* 40G MAC statistics registers are the same, only read indirectly */ + #define _40g_mac_reg_read32(field) al_eth_40g_mac_reg_read(adapter, \ + ((u8 *)(field)) - ((u8 *)&adapter->mac_regs_base->mac_10g)) + + stats->ifInUcastPkts = _40g_mac_reg_read32(®_rx_stats->ifInUcastPkts); + stats->ifInMulticastPkts = _40g_mac_reg_read32(®_rx_stats->ifInMulticastPkts); + stats->ifInBroadcastPkts = _40g_mac_reg_read32(®_rx_stats->ifInBroadcastPkts); + stats->etherStatsPkts = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts); + stats->ifOutUcastPkts = _40g_mac_reg_read32(®_tx_stats->ifUcastPkts); + stats->ifOutMulticastPkts = _40g_mac_reg_read32(®_tx_stats->ifMulticastPkts); + stats->ifOutBroadcastPkts = _40g_mac_reg_read32(®_tx_stats->ifBroadcastPkts); + stats->ifInErrors = _40g_mac_reg_read32(®_rx_stats->ifInErrors); + stats->ifOutErrors = _40g_mac_reg_read32(®_tx_stats->ifOutErrors); + stats->aFramesReceivedOK = _40g_mac_reg_read32(®_rx_stats->FramesOK); + stats->aFramesTransmittedOK = _40g_mac_reg_read32(®_tx_stats->FramesOK); + + /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */ + octets = _40g_mac_reg_read32(®_rx_stats->ifOctetsL); + octets |= (u64)(_40g_mac_reg_read32(®_rx_stats->ifOctetsH)) << 32; + octets -= 18 * stats->aFramesReceivedOK; + octets -= 4 * _40g_mac_reg_read32(®_rx_stats->VLANOK); + stats->aOctetsReceivedOK = octets; + + /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */ + octets = _40g_mac_reg_read32(®_tx_stats->ifOctetsL); + octets |= (u64)(_40g_mac_reg_read32(®_tx_stats->ifOctetsH)) << 32; + octets -= 18 * stats->aFramesTransmittedOK; + octets -= 4 * _40g_mac_reg_read32(®_tx_stats->VLANOK); + stats->aOctetsTransmittedOK = octets; + + stats->etherStatsUndersizePkts = _40g_mac_reg_read32(®_rx_stats->etherStatsUndersizePkts); + stats->etherStatsFragments = _40g_mac_reg_read32(®_rx_stats->etherStatsFragments); + stats->etherStatsJabbers = _40g_mac_reg_read32(®_rx_stats->etherStatsJabbers); + stats->etherStatsOversizePkts = _40g_mac_reg_read32(®_rx_stats->etherStatsOversizePkts); + stats->aFrameCheckSequenceErrors = _40g_mac_reg_read32(®_rx_stats->CRCErrors); + stats->aAlignmentErrors = _40g_mac_reg_read32(®_rx_stats->aAlignmentErrors); + stats->etherStatsDropEvents = _40g_mac_reg_read32(®_rx_stats->etherStatsDropEvents); + stats->aPAUSEMACCtrlFramesTransmitted = _40g_mac_reg_read32(®_tx_stats->aPAUSEMACCtrlFrames); + stats->aPAUSEMACCtrlFramesReceived = _40g_mac_reg_read32(®_rx_stats->aPAUSEMACCtrlFrames); + stats->aFrameTooLongErrors = _40g_mac_reg_read32(®_rx_stats->aFrameTooLong); + stats->aInRangeLengthErrors = _40g_mac_reg_read32(®_rx_stats->aInRangeLengthErrors); + stats->VLANTransmittedOK = _40g_mac_reg_read32(®_tx_stats->VLANOK); + stats->VLANReceivedOK = _40g_mac_reg_read32(®_rx_stats->VLANOK); + stats->etherStatsOctets = _40g_mac_reg_read32(®_rx_stats->etherStatsOctets); + stats->etherStatsPkts64Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts64Octets); + stats->etherStatsPkts65to127Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts65to127Octets); + stats->etherStatsPkts128to255Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts128to255Octets); + stats->etherStatsPkts256to511Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts256to511Octets); + stats->etherStatsPkts512to1023Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts512to1023Octets); + stats->etherStatsPkts1024to1518Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts1024to1518Octets); + stats->etherStatsPkts1519toX = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts1519toMax); + } + +/* stats->etherStatsPkts = 1; */ + return 0; +} + /* Traffic control */ int al_eth_flr_rmn(int (*pci_read_config_u32)(void *handle, int where, u32 *val), -- 2.11.0