@@ -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,
@@ -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
@@ -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),