From 05c72d73d6528c71e4da94554f47cf7af6a2dc25 Mon Sep 17 00:00:00 2001
From: Markus Gothe <markus.gothe@genexis.eu>
Date: Wed, 22 Jan 2025 20:16:02 +0100
Subject: [PATCH] econet: Add PON support.

---
 econet/ecnt_prvt.c | 30 ++++++++++++++++++++++++++++--
 econet/ecnt_prvt.h |  1 +
 econet/econet.c    | 13 ++++++++++++-
 ethernet.c         |  2 ++
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/econet/ecnt_prvt.c b/econet/ecnt_prvt.c
index 2c42a03..844b4a4 100644
--- a/econet/ecnt_prvt.c
+++ b/econet/ecnt_prvt.c
@@ -55,6 +55,7 @@
 #define IFNAME_ETH0             "eth0."
 #define IFNAME_NAS              "nas"
 #define IFNAME_AE_WAN           "ae_wan"
+#define IFNAME_PON              "pon"
 #define DRIVER_NAME "hsgmii_lan"
 #define DRIVER_NAME_LEN 20
 
@@ -267,7 +268,9 @@ int ae_wan_prvt_get_port_statistics(struct eth_stats *stats, struct eth_rmon_sta
 	memset(&rx_stats, 0, sizeof(ECNT_FEMGR_GDMA2_RX_STATISTICS));
 
 	chrCmd(cmdbuf, sizeof(cmdbuf), "cat /proc/tc3162/ae_wan_switch_hsgmii_lan");
-	if (cmdbuf[0] != '\0' && strcmp(cmdbuf, "pon") != 0) {
+	if (cmdbuf[0] == '\0')  {
+		return -1;
+	} else if (strcmp(cmdbuf, "pon") != 0) {
 		int i = 0, hsgmii_index = -1;
 		for (; i < ARRAY_SIZE(hsgmii_lookup_tbl); i++) {
 			if (!strcmp(cmdbuf, hsgmii_lookup_tbl[i].iftype)) {
@@ -308,6 +311,28 @@ int ae_wan_prvt_get_port_statistics(struct eth_stats *stats, struct eth_rmon_sta
 	return 0;
 }
 
+int pon_prvt_get_port_statistics(struct eth_stats *stats, struct eth_rmon_stats *rstats) {
+	ECNT_FEMGR_GDMA2_TX_STATISTICS tx_stats;
+	ECNT_FEMGR_GDMA2_RX_STATISTICS rx_stats;
+	char driver_name[DRIVER_NAME_LEN] = {0};
+
+	if (get_drv_info_by_ifname(IFNAME_PON, driver_name))
+		return -1;
+
+	memset(&tx_stats, 0, sizeof(ECNT_FEMGR_GDMA2_TX_STATISTICS));
+	memset(&rx_stats, 0, sizeof(ECNT_FEMGR_GDMA2_RX_STATISTICS));
+
+	if (!fe_lib_get_gdma2_tx_statistics(&tx_stats)) {
+		fill_stats_tx_from_gdma(stats, rstats, &tx_stats);
+	}
+
+	if (!fe_lib_get_gdma2_rx_statistics(&rx_stats)) {
+		fill_stats_rx_from_gdma(stats, rstats, &rx_stats);
+	}
+
+	return 0;
+}
+
 int ecnt_prvt_get_port_statistics(uint32_t port,
 								  struct eth_stats *stats,
 								  struct eth_rmon_stats *rstats)
@@ -479,7 +504,8 @@ uint32_t ecnt_prvt_get_port_num(const char *ifname)
 			return ECNT_PRVT_PORT_NUM_INVALID;
 		}
 	} else if (strncmp(ifname, IFNAME_NAS, strlen(IFNAME_NAS)) == 0 ||
-			   strncmp(ifname, IFNAME_AE_WAN, strlen(IFNAME_AE_WAN)) == 0) {
+			   strncmp(ifname, IFNAME_AE_WAN, strlen(IFNAME_AE_WAN)) == 0 ||
+			   strncmp(ifname, IFNAME_PON, strlen(IFNAME_PON)) == 0) {
 		is_wan = true;
 	} else {
 		return ECNT_PRVT_PORT_NUM_INVALID;
diff --git a/econet/ecnt_prvt.h b/econet/ecnt_prvt.h
index 24f4af9..cc211c9 100644
--- a/econet/ecnt_prvt.h
+++ b/econet/ecnt_prvt.h
@@ -113,6 +113,7 @@ int ecnt_prvt_set_port_state(uint32_t port_num, bool state);
 
 int hsgmii_lan_prvt_get_port_statistics(char *ifname, struct eth_stats *stats, struct eth_rmon_stats *rstats);
 int ae_wan_prvt_get_port_statistics(struct eth_stats *stats, struct eth_rmon_stats *rstats);
+int pon_prvt_get_port_statistics(struct eth_stats *stats, struct eth_rmon_stats *rstats);
 
 #ifdef __cplusplus
 }
diff --git a/econet/econet.c b/econet/econet.c
index 72c4f36..31f7fe8 100644
--- a/econet/econet.c
+++ b/econet/econet.c
@@ -68,10 +68,15 @@ int econet_eth_get_stats(const char *ifname, struct eth_stats *stats)
 		if (!hsgmii_lan_prvt_get_port_statistics(ifname, stats, NULL)) {
 			return 0;
 		} else if (!strcmp(ifname, "ae_wan")) {
-			/* Check and fetch rstats if the Interface belongs to ae_wan driver */
+			/* Check and fetch stats if the Interface belongs to ae_wan driver */
 			if (!ae_wan_prvt_get_port_statistics(stats, NULL)) {
 				return 0;
 			}
+		} else if (!strcmp(ifname, "pon")) {
+			/* Check and fetch stats if the Interface belongs to PON driver */
+			if (!pon_prvt_get_port_statistics(stats, NULL)) {
+				return 0;
+			}
 		}
 
 		libethernet_err("error reading stats for interface %s\n", ifname);
@@ -101,6 +106,11 @@ int econet_eth_get_rmon_stats(const char *ifname, struct eth_rmon_stats *rstats)
 			if (!ae_wan_prvt_get_port_statistics(NULL, rstats)) {
 				return 0;
 			}
+		} else if (!strcmp(ifname, "pon")) {
+			/* Check and fetch rstats if the Interface belongs to PON driver */
+			if (!pon_prvt_get_port_statistics(NULL, rstats)) {
+				return 0;
+			}
 		}
 
 		libethernet_err("error reading rmon stats for interface %s\n", ifname);
@@ -187,5 +197,6 @@ const struct eth_ops __name = {                         \
 ECNT_ETH_OPS(econet_gen_eth_ops, "eth");
 ECNT_ETH_OPS(econet_nas_wan_eth_ops, "nas");
 ECNT_ETH_OPS(econet_ae_wan_eth_ops, "ae_wan");
+ECNT_ETH_OPS(econet_pon_ops, "pon");
 
 #undef ECNT_ETH_OPS
diff --git a/ethernet.c b/ethernet.c
index aea13ef..d16371e 100644
--- a/ethernet.c
+++ b/ethernet.c
@@ -47,6 +47,7 @@ extern const struct eth_ops test_eth_ops;
 extern const struct eth_ops econet_gen_eth_ops;
 extern const struct eth_ops econet_nas_wan_eth_ops;
 extern const struct eth_ops econet_ae_wan_eth_ops;
+extern const struct eth_ops econet_pon_ops;
 #elif defined(IOPSYS_MEDIATEK)
 extern const struct eth_ops mtk_eth_ops;
 #elif defined(IOPSYS_LINUX)
@@ -64,6 +65,7 @@ const struct eth_ops *eth_ops[] = {
 	&econet_gen_eth_ops,
 	&econet_nas_wan_eth_ops,
 	&econet_ae_wan_eth_ops,
+	&econet_pon_ops,
 #elif defined(IOPSYS_MEDIATEK)
 	&mtk_eth_ops
 #elif defined(IOPSYS_LINUX)
-- 
GitLab