diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index fa504dd22bf6..ce3b118bcf19 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -802,6 +802,15 @@ struct ethtool_ops {
 	void	(*get_rmon_stats)(struct net_device *dev,
 				  struct ethtool_rmon_stats *rmon_stats,
 				  const struct ethtool_rmon_hist_range **ranges);
+	void	(*get_eth_pmac_phy_stats)(struct net_device *dev,
+					  struct ethtool_eth_phy_stats *phy_stats);
+	void	(*get_eth_pmac_mac_stats)(struct net_device *dev,
+					  struct ethtool_eth_mac_stats *mac_stats);
+	void	(*get_eth_pmac_ctrl_stats)(struct net_device *dev,
+					   struct ethtool_eth_ctrl_stats *ctrl_stats);
+	void	(*get_pmac_rmon_stats)(struct net_device *dev,
+				       struct ethtool_rmon_stats *rmon_stats,
+				       const struct ethtool_rmon_hist_range **ranges);
 	int	(*get_module_power_mode)(struct net_device *dev,
 					 struct ethtool_module_power_mode_params *params,
 					 struct netlink_ext_ack *extack);
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 658810274c49..a2743ffb6c63 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -742,6 +742,10 @@ enum {
 	ETHTOOL_STATS_ETH_MAC,
 	ETHTOOL_STATS_ETH_CTRL,
 	ETHTOOL_STATS_RMON,
+	ETHTOOL_STATS_ETH_PMAC_PHY,
+	ETHTOOL_STATS_ETH_PMAC_MAC,
+	ETHTOOL_STATS_ETH_PMAC_CTRL,
+	ETHTOOL_STATS_PMAC_RMON,
 
 	/* add new constants above here */
 	__ETHTOOL_STATS_CNT
diff --git a/net/ethtool/stats.c b/net/ethtool/stats.c
index 8d4d3c70c0a4..50e858b540c2 100644
--- a/net/ethtool/stats.c
+++ b/net/ethtool/stats.c
@@ -24,8 +24,13 @@ struct stats_reply_data {
 		struct ethtool_eth_mac_stats	mac_stats;
 		struct ethtool_eth_ctrl_stats	ctrl_stats;
 		struct ethtool_rmon_stats	rmon_stats;
+		struct ethtool_eth_phy_stats	pmac_phy_stats;
+		struct ethtool_eth_mac_stats	pmac_mac_stats;
+		struct ethtool_eth_ctrl_stats	pmac_ctrl_stats;
+		struct ethtool_rmon_stats	pmac_rmon_stats;
 	);
 	const struct ethtool_rmon_hist_range	*rmon_ranges;
+	const struct ethtool_rmon_hist_range	*pmac_rmon_ranges;
 };
 
 #define STATS_REPDATA(__reply_base) \
@@ -36,6 +41,10 @@ const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN] = {
 	[ETHTOOL_STATS_ETH_MAC]			= "eth-mac",
 	[ETHTOOL_STATS_ETH_CTRL]		= "eth-ctrl",
 	[ETHTOOL_STATS_RMON]			= "rmon",
+	[ETHTOOL_STATS_ETH_PMAC_PHY]		= "eth-pmac-phy",
+	[ETHTOOL_STATS_ETH_PMAC_MAC]		= "eth-pmac-mac",
+	[ETHTOOL_STATS_ETH_PMAC_CTRL]		= "eth-pmac-ctrl",
+	[ETHTOOL_STATS_PMAC_RMON]		= "pmac-rmon",
 };
 
 const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN] = {
@@ -143,6 +152,20 @@ static int stats_prepare_data(const struct ethnl_req_info *req_base,
 		ops->get_rmon_stats(dev, &data->rmon_stats,
 				    &data->rmon_ranges);
 
+	if (test_bit(ETHTOOL_STATS_ETH_PMAC_PHY, req_info->stat_mask) &&
+	    ops->get_eth_pmac_phy_stats)
+		ops->get_eth_pmac_phy_stats(dev, &data->pmac_phy_stats);
+	if (test_bit(ETHTOOL_STATS_ETH_PMAC_MAC, req_info->stat_mask) &&
+	    ops->get_eth_pmac_mac_stats)
+		ops->get_eth_pmac_mac_stats(dev, &data->pmac_mac_stats);
+	if (test_bit(ETHTOOL_STATS_ETH_PMAC_CTRL, req_info->stat_mask) &&
+	    ops->get_eth_pmac_ctrl_stats)
+		ops->get_eth_pmac_ctrl_stats(dev, &data->pmac_ctrl_stats);
+	if (test_bit(ETHTOOL_STATS_PMAC_RMON, req_info->stat_mask) &&
+	    ops->get_pmac_rmon_stats)
+		ops->get_pmac_rmon_stats(dev, &data->pmac_rmon_stats,
+					 &data->pmac_rmon_ranges);
+
 	ethnl_ops_complete(dev);
 	return 0;
 }
@@ -176,6 +199,28 @@ static int stats_reply_size(const struct ethnl_req_info *req_base,
 			nla_total_size(4)) *	/* _A_STATS_GRP_HIST_BKT_HI */
 			ETHTOOL_RMON_HIST_MAX * 2;
 	}
+	if (test_bit(ETHTOOL_STATS_ETH_PMAC_PHY, req_info->stat_mask)) {
+		n_stats += sizeof(struct ethtool_eth_mac_stats) / sizeof(u64);
+		n_grps++;
+	}
+	if (test_bit(ETHTOOL_STATS_ETH_PMAC_MAC, req_info->stat_mask)) {
+		n_stats += sizeof(struct ethtool_eth_mac_stats) / sizeof(u64);
+		n_grps++;
+	}
+	if (test_bit(ETHTOOL_STATS_ETH_PMAC_CTRL, req_info->stat_mask)) {
+		n_stats += sizeof(struct ethtool_eth_ctrl_stats) / sizeof(u64);
+		n_grps++;
+	}
+	if (test_bit(ETHTOOL_STATS_PMAC_RMON, req_info->stat_mask)) {
+		n_stats += sizeof(struct ethtool_rmon_stats) / sizeof(u64);
+		n_grps++;
+		/* Above includes the space for _A_STATS_GRP_HIST_VALs */
+
+		len += (nla_total_size(0) +	/* _A_STATS_GRP_HIST */
+			nla_total_size(4) +	/* _A_STATS_GRP_HIST_BKT_LOW */
+			nla_total_size(4)) *	/* _A_STATS_GRP_HIST_BKT_HI */
+			ETHTOOL_RMON_HIST_MAX * 2;
+	}
 
 	len += n_grps * (nla_total_size(0) + /* _A_STATS_GRP */
 			 nla_total_size(4) + /* _A_STATS_GRP_ID */
@@ -419,6 +464,31 @@ static int stats_fill_reply(struct sk_buff *skb,
 				      ETH_SS_STATS_RMON, stats_put_rmon_stats);
 	}
 
+	if (!ret && test_bit(ETHTOOL_STATS_ETH_PMAC_PHY, req_info->stat_mask))
+		ret = stats_put_stats(skb, &data->pmac_phy_stats,
+				      ETHTOOL_STATS_ETH_PMAC_PHY,
+				      ETH_SS_STATS_ETH_PHY,
+				      stats_put_phy_stats);
+	if (!ret && test_bit(ETHTOOL_STATS_ETH_PMAC_MAC, req_info->stat_mask))
+		ret = stats_put_stats(skb, &data->pmac_mac_stats,
+				      ETHTOOL_STATS_ETH_PMAC_MAC,
+				      ETH_SS_STATS_ETH_MAC,
+				      stats_put_mac_stats);
+	if (!ret && test_bit(ETHTOOL_STATS_ETH_PMAC_CTRL, req_info->stat_mask))
+		ret = stats_put_stats(skb, &data->pmac_ctrl_stats,
+				      ETHTOOL_STATS_ETH_PMAC_CTRL,
+				      ETH_SS_STATS_ETH_CTRL,
+				      stats_put_ctrl_stats);
+	if (!ret && test_bit(ETHTOOL_STATS_PMAC_RMON, req_info->stat_mask)) {
+		struct rmon_stats_put_ctx ctx = {
+			.rmon_stats = &data->pmac_rmon_stats,
+			.rmon_ranges = data->pmac_rmon_ranges,
+		};
+
+		ret = stats_put_stats(skb, &ctx, ETHTOOL_STATS_PMAC_RMON,
+				      ETH_SS_STATS_RMON, stats_put_rmon_stats);
+	}
+
 	return ret;
 }
 
