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(&reg_stats->ifInUcastPkts);
+		stats->ifInMulticastPkts = readl(&reg_stats->ifInMulticastPkts);
+		stats->ifInBroadcastPkts = readl(&reg_stats->ifInBroadcastPkts);
+		stats->etherStatsPkts = readl(&reg_stats->etherStatsPkts);
+		stats->ifOutUcastPkts = readl(&reg_stats->ifOutUcastPkts);
+		stats->ifOutMulticastPkts = readl(&reg_stats->ifOutMulticastPkts);
+		stats->ifOutBroadcastPkts = readl(&reg_stats->ifOutBroadcastPkts);
+		stats->ifInErrors = readl(&reg_stats->ifInErrors);
+		stats->ifOutErrors = readl(&reg_stats->ifOutErrors);
+		stats->aFramesReceivedOK = readl(&reg_stats->aFramesReceivedOK);
+		stats->aFramesTransmittedOK = readl(&reg_stats->aFramesTransmittedOK);
+		stats->aOctetsReceivedOK = readl(&reg_stats->aOctetsReceivedOK);
+		stats->aOctetsTransmittedOK = readl(&reg_stats->aOctetsTransmittedOK);
+		stats->etherStatsUndersizePkts = readl(&reg_stats->etherStatsUndersizePkts);
+		stats->etherStatsFragments = readl(&reg_stats->etherStatsFragments);
+		stats->etherStatsJabbers = readl(&reg_stats->etherStatsJabbers);
+		stats->etherStatsOversizePkts = readl(&reg_stats->etherStatsOversizePkts);
+		stats->aFrameCheckSequenceErrors =
+			readl(&reg_stats->aFrameCheckSequenceErrors);
+		stats->aAlignmentErrors = readl(&reg_stats->aAlignmentErrors);
+		stats->etherStatsDropEvents = readl(&reg_stats->etherStatsDropEvents);
+		stats->aPAUSEMACCtrlFramesTransmitted =
+			readl(&reg_stats->aPAUSEMACCtrlFramesTransmitted);
+		stats->aPAUSEMACCtrlFramesReceived =
+			readl(&reg_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(&reg_stats->etherStatsOctets);
+		stats->etherStatsPkts64Octets = readl(&reg_stats->etherStatsPkts64Octets);
+		stats->etherStatsPkts65to127Octets =
+			readl(&reg_stats->etherStatsPkts65to127Octets);
+		stats->etherStatsPkts128to255Octets =
+			readl(&reg_stats->etherStatsPkts128to255Octets);
+		stats->etherStatsPkts256to511Octets =
+			readl(&reg_stats->etherStatsPkts256to511Octets);
+		stats->etherStatsPkts512to1023Octets =
+			readl(&reg_stats->etherStatsPkts512to1023Octets);
+		stats->etherStatsPkts1024to1518Octets =
+			readl(&reg_stats->etherStatsPkts1024to1518Octets);
+		stats->etherStatsPkts1519toX = readl(&reg_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(&reg_stats->ifInUcastPkts);
+			stats->ifInMulticastPkts = readl(&reg_stats->ifInMulticastPkts);
+			stats->ifInBroadcastPkts = readl(&reg_stats->ifInBroadcastPkts);
+			stats->etherStatsPkts = readl(&reg_stats->etherStatsPkts);
+			stats->ifOutUcastPkts = readl(&reg_stats->ifOutUcastPkts);
+			stats->ifOutMulticastPkts = readl(&reg_stats->ifOutMulticastPkts);
+			stats->ifOutBroadcastPkts = readl(&reg_stats->ifOutBroadcastPkts);
+			stats->ifInErrors = readl(&reg_stats->ifInErrors);
+			stats->ifOutErrors = readl(&reg_stats->ifOutErrors);
+			stats->aFramesReceivedOK = readl(&reg_stats->aFramesReceivedOK);
+			stats->aFramesTransmittedOK = readl(&reg_stats->aFramesTransmittedOK);
+
+			/* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */
+			octets = readl(&reg_stats->ifInOctetsL);
+			octets |= (u64)(readl(&reg_stats->ifInOctetsH)) << 32;
+			octets -= 18 * stats->aFramesReceivedOK;
+			octets -= 4 * readl(&reg_stats->VLANReceivedOK);
+			stats->aOctetsReceivedOK = octets;
+
+			/* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */
+			octets = readl(&reg_stats->ifOutOctetsL);
+			octets |= (u64)(readl(&reg_stats->ifOutOctetsH)) << 32;
+			octets -= 18 * stats->aFramesTransmittedOK;
+			octets -= 4 * readl(&reg_stats->VLANTransmittedOK);
+			stats->aOctetsTransmittedOK = octets;
+
+			stats->etherStatsUndersizePkts = readl(&reg_stats->etherStatsUndersizePkts);
+			stats->etherStatsFragments = readl(&reg_stats->etherStatsFragments);
+			stats->etherStatsJabbers = readl(&reg_stats->etherStatsJabbers);
+			stats->etherStatsOversizePkts = readl(&reg_stats->etherStatsOversizePkts);
+			stats->aFrameCheckSequenceErrors = readl(&reg_stats->aFrameCheckSequenceErrors);
+			stats->aAlignmentErrors = readl(&reg_stats->aAlignmentErrors);
+			stats->etherStatsDropEvents = readl(&reg_stats->etherStatsDropEvents);
+			stats->aPAUSEMACCtrlFramesTransmitted = readl(&reg_stats->aPAUSEMACCtrlFramesTransmitted);
+			stats->aPAUSEMACCtrlFramesReceived = readl(&reg_stats->aPAUSEMACCtrlFramesReceived);
+			stats->aFrameTooLongErrors = readl(&reg_stats->aFrameTooLongErrors);
+			stats->aInRangeLengthErrors = readl(&reg_stats->aInRangeLengthErrors);
+			stats->VLANTransmittedOK = readl(&reg_stats->VLANTransmittedOK);
+			stats->VLANReceivedOK = readl(&reg_stats->VLANReceivedOK);
+			stats->etherStatsOctets = readl(&reg_stats->etherStatsOctets);
+			stats->etherStatsPkts64Octets = readl(&reg_stats->etherStatsPkts64Octets);
+			stats->etherStatsPkts65to127Octets = readl(&reg_stats->etherStatsPkts65to127Octets);
+			stats->etherStatsPkts128to255Octets = readl(&reg_stats->etherStatsPkts128to255Octets);
+			stats->etherStatsPkts256to511Octets = readl(&reg_stats->etherStatsPkts256to511Octets);
+			stats->etherStatsPkts512to1023Octets = readl(&reg_stats->etherStatsPkts512to1023Octets);
+			stats->etherStatsPkts1024to1518Octets = readl(&reg_stats->etherStatsPkts1024to1518Octets);
+			stats->etherStatsPkts1519toX = readl(&reg_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(&reg_rx_stats->ifInUcastPkts);
+			stats->ifInMulticastPkts = readl(&reg_rx_stats->ifInMulticastPkts);
+			stats->ifInBroadcastPkts = readl(&reg_rx_stats->ifInBroadcastPkts);
+			stats->etherStatsPkts = readl(&reg_rx_stats->etherStatsPkts);
+			stats->ifOutUcastPkts = readl(&reg_tx_stats->ifUcastPkts);
+			stats->ifOutMulticastPkts = readl(&reg_tx_stats->ifMulticastPkts);
+			stats->ifOutBroadcastPkts = readl(&reg_tx_stats->ifBroadcastPkts);
+			stats->ifInErrors = readl(&reg_rx_stats->ifInErrors);
+			stats->ifOutErrors = readl(&reg_tx_stats->ifOutErrors);
+			stats->aFramesReceivedOK = readl(&reg_rx_stats->FramesOK);
+			stats->aFramesTransmittedOK = readl(&reg_tx_stats->FramesOK);
+
+			/* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */
+			octets = readl(&reg_rx_stats->ifOctetsL);
+			octets |= (u64)(readl(&reg_rx_stats->ifOctetsH)) << 32;
+			octets -= 18 * stats->aFramesReceivedOK;
+			octets -= 4 * readl(&reg_rx_stats->VLANOK);
+			stats->aOctetsReceivedOK = octets;
+
+			/* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */
+			octets = readl(&reg_tx_stats->ifOctetsL);
+			octets |= (u64)(readl(&reg_tx_stats->ifOctetsH)) << 32;
+			octets -= 18 * stats->aFramesTransmittedOK;
+			octets -= 4 * readl(&reg_tx_stats->VLANOK);
+			stats->aOctetsTransmittedOK = octets;
+
+			stats->etherStatsUndersizePkts = readl(&reg_rx_stats->etherStatsUndersizePkts);
+			stats->etherStatsFragments = readl(&reg_rx_stats->etherStatsFragments);
+			stats->etherStatsJabbers = readl(&reg_rx_stats->etherStatsJabbers);
+			stats->etherStatsOversizePkts = readl(&reg_rx_stats->etherStatsOversizePkts);
+			stats->aFrameCheckSequenceErrors = readl(&reg_rx_stats->CRCErrors);
+			stats->aAlignmentErrors = readl(&reg_rx_stats->aAlignmentErrors);
+			stats->etherStatsDropEvents = readl(&reg_rx_stats->etherStatsDropEvents);
+			stats->aPAUSEMACCtrlFramesTransmitted = readl(&reg_tx_stats->aPAUSEMACCtrlFrames);
+			stats->aPAUSEMACCtrlFramesReceived = readl(&reg_rx_stats->aPAUSEMACCtrlFrames);
+			stats->aFrameTooLongErrors = readl(&reg_rx_stats->aFrameTooLong);
+			stats->aInRangeLengthErrors = readl(&reg_rx_stats->aInRangeLengthErrors);
+			stats->VLANTransmittedOK = readl(&reg_tx_stats->VLANOK);
+			stats->VLANReceivedOK = readl(&reg_rx_stats->VLANOK);
+			stats->etherStatsOctets = readl(&reg_rx_stats->etherStatsOctets);
+			stats->etherStatsPkts64Octets = readl(&reg_rx_stats->etherStatsPkts64Octets);
+			stats->etherStatsPkts65to127Octets = readl(&reg_rx_stats->etherStatsPkts65to127Octets);
+			stats->etherStatsPkts128to255Octets = readl(&reg_rx_stats->etherStatsPkts128to255Octets);
+			stats->etherStatsPkts256to511Octets = readl(&reg_rx_stats->etherStatsPkts256to511Octets);
+			stats->etherStatsPkts512to1023Octets = readl(&reg_rx_stats->etherStatsPkts512to1023Octets);
+			stats->etherStatsPkts1024to1518Octets = readl(&reg_rx_stats->etherStatsPkts1024to1518Octets);
+			stats->etherStatsPkts1519toX = readl(&reg_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(&reg_rx_stats->ifInUcastPkts);
+		stats->ifInMulticastPkts = _40g_mac_reg_read32(&reg_rx_stats->ifInMulticastPkts);
+		stats->ifInBroadcastPkts = _40g_mac_reg_read32(&reg_rx_stats->ifInBroadcastPkts);
+		stats->etherStatsPkts = _40g_mac_reg_read32(&reg_rx_stats->etherStatsPkts);
+		stats->ifOutUcastPkts = _40g_mac_reg_read32(&reg_tx_stats->ifUcastPkts);
+		stats->ifOutMulticastPkts = _40g_mac_reg_read32(&reg_tx_stats->ifMulticastPkts);
+		stats->ifOutBroadcastPkts = _40g_mac_reg_read32(&reg_tx_stats->ifBroadcastPkts);
+		stats->ifInErrors = _40g_mac_reg_read32(&reg_rx_stats->ifInErrors);
+		stats->ifOutErrors = _40g_mac_reg_read32(&reg_tx_stats->ifOutErrors);
+		stats->aFramesReceivedOK = _40g_mac_reg_read32(&reg_rx_stats->FramesOK);
+		stats->aFramesTransmittedOK = _40g_mac_reg_read32(&reg_tx_stats->FramesOK);
+
+		/* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */
+		octets = _40g_mac_reg_read32(&reg_rx_stats->ifOctetsL);
+		octets |= (u64)(_40g_mac_reg_read32(&reg_rx_stats->ifOctetsH)) << 32;
+		octets -= 18 * stats->aFramesReceivedOK;
+		octets -= 4 * _40g_mac_reg_read32(&reg_rx_stats->VLANOK);
+		stats->aOctetsReceivedOK = octets;
+
+		/* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */
+		octets = _40g_mac_reg_read32(&reg_tx_stats->ifOctetsL);
+		octets |= (u64)(_40g_mac_reg_read32(&reg_tx_stats->ifOctetsH)) << 32;
+		octets -= 18 * stats->aFramesTransmittedOK;
+		octets -= 4 * _40g_mac_reg_read32(&reg_tx_stats->VLANOK);
+		stats->aOctetsTransmittedOK = octets;
+
+		stats->etherStatsUndersizePkts = _40g_mac_reg_read32(&reg_rx_stats->etherStatsUndersizePkts);
+		stats->etherStatsFragments = _40g_mac_reg_read32(&reg_rx_stats->etherStatsFragments);
+		stats->etherStatsJabbers = _40g_mac_reg_read32(&reg_rx_stats->etherStatsJabbers);
+		stats->etherStatsOversizePkts = _40g_mac_reg_read32(&reg_rx_stats->etherStatsOversizePkts);
+		stats->aFrameCheckSequenceErrors = _40g_mac_reg_read32(&reg_rx_stats->CRCErrors);
+		stats->aAlignmentErrors = _40g_mac_reg_read32(&reg_rx_stats->aAlignmentErrors);
+		stats->etherStatsDropEvents = _40g_mac_reg_read32(&reg_rx_stats->etherStatsDropEvents);
+		stats->aPAUSEMACCtrlFramesTransmitted = _40g_mac_reg_read32(&reg_tx_stats->aPAUSEMACCtrlFrames);
+		stats->aPAUSEMACCtrlFramesReceived = _40g_mac_reg_read32(&reg_rx_stats->aPAUSEMACCtrlFrames);
+		stats->aFrameTooLongErrors = _40g_mac_reg_read32(&reg_rx_stats->aFrameTooLong);
+		stats->aInRangeLengthErrors = _40g_mac_reg_read32(&reg_rx_stats->aInRangeLengthErrors);
+		stats->VLANTransmittedOK = _40g_mac_reg_read32(&reg_tx_stats->VLANOK);
+		stats->VLANReceivedOK = _40g_mac_reg_read32(&reg_rx_stats->VLANOK);
+		stats->etherStatsOctets = _40g_mac_reg_read32(&reg_rx_stats->etherStatsOctets);
+		stats->etherStatsPkts64Octets = _40g_mac_reg_read32(&reg_rx_stats->etherStatsPkts64Octets);
+		stats->etherStatsPkts65to127Octets = _40g_mac_reg_read32(&reg_rx_stats->etherStatsPkts65to127Octets);
+		stats->etherStatsPkts128to255Octets = _40g_mac_reg_read32(&reg_rx_stats->etherStatsPkts128to255Octets);
+		stats->etherStatsPkts256to511Octets = _40g_mac_reg_read32(&reg_rx_stats->etherStatsPkts256to511Octets);
+		stats->etherStatsPkts512to1023Octets = _40g_mac_reg_read32(&reg_rx_stats->etherStatsPkts512to1023Octets);
+		stats->etherStatsPkts1024to1518Octets = _40g_mac_reg_read32(&reg_rx_stats->etherStatsPkts1024to1518Octets);
+		stats->etherStatsPkts1519toX = _40g_mac_reg_read32(&reg_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),
