diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
index 6a001d9..c2a6fbb 100644
--- a/doc/guides/nics/cnxk.rst
+++ b/doc/guides/nics/cnxk.rst
@@ -25,6 +25,7 @@ Features of the CNXK Ethdev PMD are:
 - Receiver Side Scaling (RSS)
 - MAC filtering
 - Inner and Outer Checksum offload
+- Port hardware statistics
 - Link state information
 - Link flow control
 - MTU update
diff --git a/doc/guides/nics/features/cnxk.ini b/doc/guides/nics/features/cnxk.ini
index e5669f5..40952a9 100644
--- a/doc/guides/nics/features/cnxk.ini
+++ b/doc/guides/nics/features/cnxk.ini
@@ -32,6 +32,8 @@ L4 checksum offload  = Y
 Inner L3 checksum    = Y
 Inner L4 checksum    = Y
 Packet type parsing  = Y
+Basic stats          = Y
+Stats per queue      = Y
 Module EEPROM dump   = Y
 Linux                = Y
 ARMv8                = Y
diff --git a/doc/guides/nics/features/cnxk_vec.ini b/doc/guides/nics/features/cnxk_vec.ini
index dff0c9b..32035bb 100644
--- a/doc/guides/nics/features/cnxk_vec.ini
+++ b/doc/guides/nics/features/cnxk_vec.ini
@@ -30,6 +30,8 @@ L4 checksum offload  = Y
 Inner L3 checksum    = Y
 Inner L4 checksum    = Y
 Packet type parsing  = Y
+Basic stats          = Y
+Stats per queue      = Y
 Module EEPROM dump   = Y
 Linux                = Y
 ARMv8                = Y
diff --git a/doc/guides/nics/features/cnxk_vf.ini b/doc/guides/nics/features/cnxk_vf.ini
index b950d2f..8060a68 100644
--- a/doc/guides/nics/features/cnxk_vf.ini
+++ b/doc/guides/nics/features/cnxk_vf.ini
@@ -27,6 +27,8 @@ L4 checksum offload  = Y
 Inner L3 checksum    = Y
 Inner L4 checksum    = Y
 Packet type parsing  = Y
+Basic stats          = Y
+Stats per queue      = Y
 Module EEPROM dump   = Y
 Linux                = Y
 ARMv8                = Y
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 57c30c4..f6eb9c9 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1167,6 +1167,9 @@ struct eth_dev_ops cnxk_eth_dev_ops = {
 	.rx_queue_intr_enable = cnxk_nix_rx_queue_intr_enable,
 	.rx_queue_intr_disable = cnxk_nix_rx_queue_intr_disable,
 	.pool_ops_supported = cnxk_nix_pool_ops_supported,
+	.queue_stats_mapping_set = cnxk_nix_queue_stats_mapping,
+	.stats_get = cnxk_nix_stats_get,
+	.stats_reset = cnxk_nix_stats_reset,
 };
 
 static int
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index 0b501f6..5075e7c 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -188,6 +188,10 @@ struct cnxk_eth_dev {
 
 	/* Default mac address */
 	uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
+
+	/* Per queue statistics counters */
+	uint32_t txq_stat_map[RTE_ETHDEV_QUEUE_STAT_CNTRS];
+	uint32_t rxq_stat_map[RTE_ETHDEV_QUEUE_STAT_CNTRS];
 };
 
 struct cnxk_eth_rxq_sp {
@@ -271,6 +275,10 @@ void cnxk_nix_toggle_flag_link_cfg(struct cnxk_eth_dev *dev, bool set);
 void cnxk_eth_dev_link_status_cb(struct roc_nix *nix,
 				 struct roc_nix_link_info *link);
 int cnxk_nix_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete);
+int cnxk_nix_queue_stats_mapping(struct rte_eth_dev *dev, uint16_t queue_id,
+				 uint8_t stat_idx, uint8_t is_rx);
+int cnxk_nix_stats_reset(struct rte_eth_dev *dev);
+int cnxk_nix_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
 
 /* Lookup configuration */
 const uint32_t *cnxk_nix_supported_ptypes_get(struct rte_eth_dev *eth_dev);
diff --git a/drivers/net/cnxk/cnxk_stats.c b/drivers/net/cnxk/cnxk_stats.c
new file mode 100644
index 0000000..24bff0b
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_stats.c
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#include "cnxk_ethdev.h"
+
+int
+cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix *nix = &dev->nix;
+	struct roc_nix_stats nix_stats;
+	int rc = 0, i;
+
+	rc = roc_nix_stats_get(nix, &nix_stats);
+	if (rc)
+		goto exit;
+
+	stats->opackets = nix_stats.tx_ucast;
+	stats->opackets += nix_stats.tx_mcast;
+	stats->opackets += nix_stats.tx_bcast;
+	stats->oerrors = nix_stats.tx_drop;
+	stats->obytes = nix_stats.tx_octs;
+
+	stats->ipackets = nix_stats.rx_ucast;
+	stats->ipackets += nix_stats.rx_mcast;
+	stats->ipackets += nix_stats.rx_bcast;
+	stats->imissed = nix_stats.rx_drop;
+	stats->ibytes = nix_stats.rx_octs;
+	stats->ierrors = nix_stats.rx_err;
+
+	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
+		struct roc_nix_stats_queue qstats;
+		uint16_t qidx;
+
+		if (dev->txq_stat_map[i] & (1U << 31)) {
+			qidx = dev->txq_stat_map[i] & 0xFFFF;
+			rc = roc_nix_stats_queue_get(nix, qidx, 0, &qstats);
+			if (rc)
+				goto exit;
+			stats->q_opackets[i] = qstats.tx_pkts;
+			stats->q_obytes[i] = qstats.tx_octs;
+			stats->q_errors[i] = qstats.tx_drop_pkts;
+		}
+
+		if (dev->rxq_stat_map[i] & (1U << 31)) {
+			qidx = dev->rxq_stat_map[i] & 0xFFFF;
+			rc = roc_nix_stats_queue_get(nix, qidx, 1, &qstats);
+			if (rc)
+				goto exit;
+			stats->q_ipackets[i] = qstats.rx_pkts;
+			stats->q_ibytes[i] = qstats.rx_octs;
+			stats->q_errors[i] += qstats.rx_drop_pkts;
+		}
+	}
+exit:
+	return rc;
+}
+
+int
+cnxk_nix_stats_reset(struct rte_eth_dev *eth_dev)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+
+	return roc_nix_stats_reset(&dev->nix);
+}
+
+int
+cnxk_nix_queue_stats_mapping(struct rte_eth_dev *eth_dev, uint16_t queue_id,
+			     uint8_t stat_idx, uint8_t is_rx)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+
+	if (is_rx) {
+		if (queue_id >= dev->nb_rxq)
+			return -EINVAL;
+		dev->rxq_stat_map[stat_idx] = ((1U << 31) | queue_id);
+	} else {
+		if (queue_id >= dev->nb_txq)
+			return -EINVAL;
+		dev->txq_stat_map[stat_idx] = ((1U << 31) | queue_id);
+	}
+
+	return 0;
+}
diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build
index 748a49a..e0ab9d6 100644
--- a/drivers/net/cnxk/meson.build
+++ b/drivers/net/cnxk/meson.build
@@ -12,7 +12,8 @@ sources = files('cnxk_ethdev.c',
 		'cnxk_ethdev_ops.c',
 		'cnxk_ethdev_devargs.c',
 		'cnxk_link.c',
-		'cnxk_lookup.c')
+		'cnxk_lookup.c',
+		'cnxk_stats.c')
 
 # CN9K
 sources += files('cn9k_ethdev.c',
