diff --git a/Makefile b/Makefile
index a0582e8176adc5a40c726caa1e3510dbde5ac748..66e7f0d33ca88a4679bd8bd5318abd31e9c9ad31 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,15 @@
 CC = gcc
 CFLAGS = -O2 -Wall -g
 
+LIBETH_CFLAGS += -I. -I../libeasy
+LIBETH_LDFLAGS += -L../libeasy
+LIBS += -lnl-3 -lnl-route-3 -lnl-genl-3
+LIBS += -leasy
+
 objs_lib = ethernet.o
 
 ifeq ($(PLATFORM),BROADCOM)
-objs_lib += bcm.o
+objs_lib += bcm/bcm.o
 else ifeq ($(PLATFORM),MEDIATEK)
 objs_lib += ethsw.o
 XXFLAGS += -Wl,-whole-archive -lsw -Wl,-no-whole-archive
@@ -13,10 +18,12 @@ endif
 all: libethernet.so
 
 %.o: %.c
-	$(CC) $(CFLAGS) -fPIC -c -o $@ $<
+	$(CC) $(CFLAGS) $(LIBETH_CFLAGS) -fPIC -c -o $@ $<
 
 libethernet.so: $(objs_lib)
-	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(LDFLAGS) -shared -o $@ $^ $(XXFLAGS)
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(LDFLAGS) $(LIBETH_LDFLAGS) \
+		-shared -o $@ $^ $(XXFLAGS) $(LIBS)
 
 clean:
+	rm -f bcm/*.o
 	rm -f *.o *.so
diff --git a/bcm.c b/bcm.c
deleted file mode 100644
index 4812a92fb3c391f327768874e03b0bd2c6248928..0000000000000000000000000000000000000000
--- a/bcm.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * bcm.c - implements for Broadcom eth switch
- *
- * Copyright (C) 2018 iopsys Software Solutions AB. All rights reserved.
- *
- * Author: anjan.chanda@iopsys.eu
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <net/if.h>
-#include <stdbool.h>
-#include <linux/mii.h>
-
-#include "ethernet.h"
-#include "bcmswapitypes.h"
-#include "bcmnet.h"
-
-#define UNUSED(var)	(void)(var)
-
-#define PHYID_2_MII_IOCTL(phy_id, mii_ioctl_data) \
-                    {mii_ioctl_data->val_out = (phy_id >> 24 ) & 0xff; \
-                    mii_ioctl_data->phy_id = phy_id & 0x1f;}
-
-int bcm_eth_get_link_settings(char *name, struct eth_link *link)
-{
-	int port = ETH_PORT_UNDEFINED;
-	int portmap = 0;
-	int ret;
-	int num_ports = 0;
-	int pos = 0;
-	int phy_id = 0;
-	struct ethswctl_data data;
-
-	ret = eth_ioctl(name, SIOCGQUERYNUMPORTS,
-				&portmap, sizeof(portmap));
-	if (ret < 0)
-		return -1;
-
-	while (portmap && pos < sizeof(portmap) * 8) {
-		if ((portmap & (1 << pos++)))
-			num_ports++;
-	}
-
-	if (link && link->portid != ETH_PORT_UNDEFINED)
-		port = link->portid;
-
-	if (!num_ports) {
-		if (port >= 0)
-			return -ETH_EINVAL;
-	}
-	else {
-		if (port == ETH_PORT_UNDEFINED) {
-			if (num_ports > 1) {
-				return -ETH_EINVAL;
-			} else {
-				for (port = 0; port < 32; port++)
-					if ((portmap & (1 << port)))
-						break;
-			}
-		}
-
-		if ((portmap & (1 << port)) == 0)
-			return -ETH_EINVAL;
-	}
-
-	eth_get_phy_id(name, port, &phy_id);
-
-	memset(&data, 0, sizeof(struct ethswctl_data));
-	data.op = ETHSWPHYMODE;
-	data.type = TYPE_GET;
-	data.addressing_flag = ETHSW_ADDRESSING_DEV;
-	if (port != ETH_PORT_UNDEFINED) {
-		data.sub_unit = -1;
-		data.sub_port = port;
-		data.addressing_flag |= ETHSW_ADDRESSING_SUBPORT;
-	}
-
-	if (eth_ioctl(name, SIOCETHSWCTLOPS, &data,
-				sizeof(struct ethswctl_data)) < 0)
-		return -1;
-
-	link->autoneg = !!(data.phycfg & PHY_CFG_AUTO_NEGO);
-	link->fullduplex = !!(data.phycfg & (PHY_CFG_10000FD |
-						PHY_CFG_5000FD |
-						PHY_CFG_2500FD |
-						PHY_CFG_1000FD |
-						PHY_CFG_100FD  |
-						PHY_CFG_10FD));
-	link->speed = data.speed;
-	link->down = data.speed == 0 ? 1 : 0;
-
-	if (data.phycfg & PHY_CFG_1000FD)
-		link->capability |= ETH_1000_Full;
-
-	if (data.phycfg & PHY_CFG_1000HD)
-		link->capability |= ETH_1000_Half;
-
-	if (data.phycfg & PHY_CFG_100FD)
-		link->capability |= ETH_100_Full;
-
-	if (data.phycfg & PHY_CFG_100HD)
-		link->capability |= ETH_100_Half;
-
-	if (data.phycfg & PHY_CFG_10FD)
-		link->capability |= ETH_10_Full;
-
-	if (data.phycfg & PHY_CFG_10HD)
-		link->capability |= ETH_10_Half;
-
-	if (data.phycfg & PHY_CFG_5000FD)
-		link->capability |= ETH_5000_Full;
-
-	if (data.phycfg & PHY_CFG_10000FD)
-		link->capability |= ETH_10000_Full;
-
-	return 0;
-}
-
-int bcm_eth_set_link_settings(char *name, struct eth_link link)
-{
-	fprintf(stderr, "%s(): name = %s\n", __func__, name);
-	return 0;
-}
-
-int bcm_eth_poweron_phy(char *name, struct eth_phy p)
-{
-	struct ethctl_data data;
-
-	memset(&data, 0, sizeof(struct ethctl_data));
-	data.op = ETHSETSPOWERUP;
-
-	if (eth_ioctl(name, SIOCETHSWCTLOPS, &data,
-				sizeof(struct ethswctl_data)) < 0)
-		return -1;
-
-	return 0;
-}
-
-int bcm_eth_poweroff_phy(char *name, struct eth_phy p)
-{
-	struct ethctl_data data;
-
-	memset(&data, 0, sizeof(struct ethctl_data));
-	data.op = ETHSETSPOWERDOWN;
-
-	if (eth_ioctl(name, SIOCETHSWCTLOPS, &data,
-				sizeof(struct ethswctl_data)) < 0)
-		return -1;
-
-	return 0;
-}
-
-int bcm_eth_reset_phy(char *name, int phy_id)
-{
-	return eth_mii_reset_phy(name, phy_id & 0x1f);
-}
-
-const struct eth_ops bcm_eth_ops = {
-	.name = "eth",
-	//.up = bcm_eth_up,
-	//.down = bcm_eth_down,
-	.set_link_settings = bcm_eth_set_link_settings,
-	.get_link_settings = bcm_eth_get_link_settings,
-	//.get_stats = bcm_eth_get_stats,
-	.poweron_phy = bcm_eth_poweron_phy,
-	.poweroff_phy = bcm_eth_poweroff_phy,
-	.reset_phy = bcm_eth_reset_phy,
-};
diff --git a/bcm/bcm.c b/bcm/bcm.c
new file mode 100644
index 0000000000000000000000000000000000000000..643e6f85c649cbac669a5f9dbffe9c79bd27f890
--- /dev/null
+++ b/bcm/bcm.c
@@ -0,0 +1,287 @@
+/*
+ * bcm.c - implements for Broadcom eth switch
+ *
+ * Copyright (C) 2018 iopsys Software Solutions AB. All rights reserved.
+ *
+ * Author: anjan.chanda@iopsys.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <net/if.h>
+#include <stdbool.h>
+#include <linux/mii.h>
+
+#include "easy.h"
+#include "ethernet.h"
+#include "bcmswapitypes.h"
+#include "bcmnet.h"
+
+#define PHYID_2_MII_IOCTL(phy_id, mii_ioctl_data) \
+                    {mii_ioctl_data->val_out = (phy_id >> 24 ) & 0xff; \
+                    mii_ioctl_data->phy_id = phy_id & 0x1f;}
+
+static int bcm_eth_get_unit_port(const char *ifname, int *unit, int *port)
+{
+	struct ethswctl_data data;
+	int ret;
+	int i;
+
+	memset(&data, 0, sizeof(struct ethswctl_data));
+
+	data.op = ETHSWUNITPORT;
+	data.type = TYPE_GET;
+	strncpy(data.ifname, ifname, 16);
+
+	ret = eth_ioctl(ifname, SIOCETHSWCTLOPS, &data,
+						sizeof(struct ethswctl_data));
+	if (ret != 0) {
+		fprintf(stderr, "ioctl failed! ret = %d\n", ret);
+		return -1;
+	}
+
+	*unit = data.unit;
+	*port = data.port;
+
+	if (!data.port && data.port_map) {
+		unsigned int portmap = data.port_map;
+
+		for (i = 0; i < sizeof(portmap); i++) {
+			if (!!(portmap & (1 << i))) {
+				*port = i;
+				break;
+			}
+		}
+	}
+
+	/* fprintf(stderr, "[%s] unit = %d port = %d portmap = 0x%x "
+			"phyportmap = 0x%x\n",
+			ifname, *unit, *port, data.port_map,
+			data.phy_portmap); */
+
+	return 0;
+}
+
+int bcm_eth_get_link_settings(const char *ifname, struct eth_link *link)
+{
+	struct ethswctl_data data;
+	int unit = -1;
+	int port = -1;
+	int ret;
+
+	memset(&data, 0, sizeof(struct ethswctl_data));
+	ret = bcm_eth_get_unit_port(ifname, &unit, &port);
+	if (ret)
+		return -1;
+
+	data.op = ETHSWPHYMODE;
+	data.port = port;
+	data.unit = unit;
+	data.type = TYPE_GET;
+
+	ret = eth_ioctl(ifname, SIOCETHSWCTLOPS, &data,
+						sizeof(struct ethswctl_data));
+	if (ret != 0) {
+		fprintf(stderr, "ioctl failed!\n");
+		return -1;
+	}
+
+	link->portid = port;
+	link->speed = data.speed;
+	link->fullduplex = data.duplex == 1 ? false : true;
+
+	/* fprintf(stderr, "port: %d  speed = %d  fullduplex = %d\n",
+			link->portid, link->speed, link->fullduplex); */
+
+	if (!!(data.phycfg & PHY_CFG_1000FD))
+		link->capability |= ETH_1000_Full;
+
+	if (!!(data.phycfg & PHY_CFG_1000HD))
+		link->capability |= ETH_1000_Half;
+
+	if (!!(data.phycfg & PHY_CFG_100FD))
+		link->capability |= ETH_100_Full;
+
+	if (!!(data.phycfg & PHY_CFG_100HD))
+		link->capability |= ETH_100_Half;
+
+	if (!!(data.phycfg & PHY_CFG_10FD))
+		link->capability |= ETH_10_Full;
+
+	if (!!(data.phycfg & PHY_CFG_10HD))
+		link->capability |= ETH_10_Half;
+
+	if (!!(data.phycfg & PHY_CFG_5000FD))
+		link->capability |= ETH_5000_Full;
+
+	if (!!(data.phycfg & PHY_CFG_10000FD))
+		link->capability |= ETH_10000_Full;
+
+
+	memset(&data, 0, sizeof(struct ethswctl_data));
+	data.op = ETHSWPHYAUTONEG;
+	data.port = port;
+	data.unit = unit;
+	data.type = TYPE_GET;
+
+	ret = eth_ioctl(ifname, SIOCETHSWCTLOPS, &data,
+						sizeof(struct ethswctl_data));
+	if (ret != 0) {
+		fprintf(stderr, "ioctl failed! ret = %d\n", ret);
+		return -1;
+	}
+
+	link->autoneg = data.autoneg_info == 0 ? false : true;
+	/* fprintf(stderr, "autoneg = %d\n", link->autoneg); */
+
+	memset(&data, 0, sizeof(struct ethswctl_data));
+	data.op = ETHSWLINKSTATUS;
+	data.port = port;
+	data.unit = unit;
+	data.type = TYPE_GET;
+
+	ret = eth_ioctl(ifname, SIOCETHSWCTLOPS, &data,
+						sizeof(struct ethswctl_data));
+	if (ret != 0) {
+		fprintf(stderr, "ioctl failed!\n");
+		return -1;
+	}
+
+	link->down = data.status == 0 ? true : false;
+
+	return 0;
+}
+
+int bcm_eth_set_link_settings(const char *name, struct eth_link link)
+{
+	fprintf(stderr, "%s(): TODO\n", __func__);
+	return 0;
+}
+
+int bcm_eth_poweron_phy(const char *name, struct eth_phy p)
+{
+	struct ethctl_data data;
+
+	memset(&data, 0, sizeof(struct ethctl_data));
+	data.op = ETHSETSPOWERUP;
+
+	if (eth_ioctl(name, SIOCETHSWCTLOPS, &data,
+				sizeof(struct ethswctl_data)) < 0)
+		return -1;
+
+	return 0;
+}
+
+int bcm_eth_poweroff_phy(const char *name, struct eth_phy p)
+{
+	struct ethctl_data data;
+
+	memset(&data, 0, sizeof(struct ethctl_data));
+	data.op = ETHSETSPOWERDOWN;
+
+	if (eth_ioctl(name, SIOCETHSWCTLOPS, &data,
+				sizeof(struct ethswctl_data)) < 0)
+		return -1;
+
+	return 0;
+}
+
+int bcm_eth_reset_phy(const char *name, int phy_id)
+{
+	return eth_mii_reset_phy(name, phy_id & 0x1f);
+}
+
+
+int bcm_eth_get_rmon_stats(const char *ifname, struct eth_rmon_stats *tx,
+						struct eth_rmon_stats *rx)
+{
+	struct ethswctl_data data;
+	int ret;
+	int unit = -1;
+	int port = -1;
+
+	memset(&data, 0, sizeof(struct ethswctl_data));
+	ret = bcm_eth_get_unit_port(ifname, &unit, &port);
+	if (ret)
+		return -1;
+
+	//data.op = ETHSWDUMPMIB;
+	data.op = ETHSWEMACGET;
+	data.port = port;
+	data.unit = unit;
+	data.queue = -1;	/* prio_q = -1 */
+
+	ret = eth_ioctl(ifname, SIOCETHSWCTLOPS, &data,
+						sizeof(struct ethswctl_data));
+	if (ret != 0) {
+		fprintf(stderr, "ioctl failed! ret = %d\n", ret);
+		return -1;
+	}
+
+	tx->all_q = true;
+	tx->bytes = data.emac_stats_s.tx_byte;
+	tx->packets = data.emac_stats_s.tx_packet;
+	tx->bcast_packets = data.emac_stats_s.tx_broadcast_packet;
+	tx->mcast_packets = data.emac_stats_s.tx_multicast_packet;
+	tx->crc_err_packets = data.emac_stats_s.tx_fcs_error;
+	tx->under_sz_packets = data.emac_stats_s.tx_undersize_frame;
+	tx->over_sz_packets = data.emac_stats_s.tx_oversize_frame;
+	tx->packets_64bytes = data.emac_stats_s.tx_frame_64;
+	tx->packets_65to127bytes = data.emac_stats_s.tx_frame_65_127;
+	tx->packets_128to255bytes = data.emac_stats_s.tx_frame_128_255;
+	tx->packets_256to511bytes = data.emac_stats_s.tx_frame_256_511;
+	tx->packets_512to1023bytes = data.emac_stats_s.tx_frame_512_1023;
+	tx->packets_1024to1518bytes = data.emac_stats_s.tx_frame_1024_1518;
+
+
+	rx->all_q = true;
+	rx->bytes = data.emac_stats_s.rx_byte;
+	rx->packets = data.emac_stats_s.rx_packet;
+	rx->bcast_packets = data.emac_stats_s.rx_broadcast_packet;
+	rx->mcast_packets = data.emac_stats_s.rx_multicast_packet;
+	rx->crc_err_packets = data.emac_stats_s.rx_fcs_error;
+	rx->under_sz_packets = data.emac_stats_s.rx_undersize_packet;
+	rx->over_sz_packets = data.emac_stats_s.rx_oversize_packet;
+	rx->packets_64bytes = data.emac_stats_s.rx_frame_64;
+	rx->packets_65to127bytes = data.emac_stats_s.rx_frame_65_127;
+	rx->packets_128to255bytes = data.emac_stats_s.rx_frame_128_255;
+	rx->packets_256to511bytes = data.emac_stats_s.rx_frame_256_511;
+	rx->packets_512to1023bytes = data.emac_stats_s.rx_frame_512_1023;
+	rx->packets_1024to1518bytes = data.emac_stats_s.rx_frame_1024_1518;
+
+	return 0;
+}
+
+const struct eth_ops bcm_eth_ops = {
+	.ifname = "eth",
+	//.up = bcm_eth_up,
+	//.down = bcm_eth_down,
+	.set_link_settings = bcm_eth_set_link_settings,
+	.get_link_settings = bcm_eth_get_link_settings,
+	//.get_stats = bcm_eth_get_stats,
+	.get_rmon_stats = bcm_eth_get_rmon_stats,
+	.poweron_phy = bcm_eth_poweron_phy,
+	.poweroff_phy = bcm_eth_poweroff_phy,
+	.reset_phy = bcm_eth_reset_phy,
+};
diff --git a/bcmnet.h b/bcm/bcmnet.h
similarity index 100%
rename from bcmnet.h
rename to bcm/bcmnet.h
diff --git a/bcmswapitypes.h b/bcm/bcmswapitypes.h
similarity index 93%
rename from bcmswapitypes.h
rename to bcm/bcmswapitypes.h
index 99e0fe9c01950534ffee7e2c4a14c844355f304d..bd5c9444aa2e17ea035d26938d43645707acc056 100644
--- a/bcmswapitypes.h
+++ b/bcm/bcmswapitypes.h
@@ -32,6 +32,7 @@
 #define __BCM_SWAPI_TYPES_H__
 
 #include "bcmtypes.h"
+#include "net_port.h"
 
 /*
  * BCM API error codes.
@@ -158,13 +159,16 @@ enum {
     ETHSWPHYAPD,
     ETHSWPHYEEE,
     ETHSWDEEPGREENMODE, /* 80 */
-    ETHSWSTATPORTGET,
     ETHSWPHYAUTONEGCAPADV,
     ETHSWQUEMON,
     ETHSWQUEMAP,
     ETHSWPORTSTORMCTRL,
     ETHSWOAMIDXMAPPING,
     ETHSWCFP,
+    ETHSWSWITCHFLAG,
+    ETHSWAUTOMDIX,
+    ETHSWIFSTP,
+    ETHSWMACLMT, /* 90 */
 };
 
 typedef struct cfpArg_s {
@@ -306,6 +310,7 @@ enum {
 #define OPT_UDF_MASK = (CFP_ARG_DA_M | CFP_ARG_SA_M)
 
 #define BMCR_SPEED2500      0x0080  /* Command Parameter definition */
+#define BMCR_SPEED10000     0x0020  /* Command Parameter definition */
 
 /*************************************************
  *  Flow Control Diagnosis Definitions           *
@@ -329,8 +334,22 @@ enum {
     QUE_MON_MAX_TYPES,
 };
 
+enum {
+    PORT_LIMIT_EN,
+    PORT_LIMIT,
+    PORT_ACTION,
+    PORT_LEARNED_COUNT,
+    PORT_OVER_LIMIT_PKT_COUNT,
+	PORT_RST_OVER_LIMIT_PKT_COUNT,
+    GLOBAL_LIMIT,
+    GLOBAL_LEARNED_COUNT,
+	GLOBAL_RST_OVER_LIMIT_PKT_COUNT,
+
+    MACLMT_MAX_TYPES,
+};
     
-#if defined(CONFIG_BCM963138) || defined(CONFIG_BCM963148) || defined(CONFIG_BCM94908) || defined(CHIP_63138) || defined(CHIP_63148) || defined(CHIP_4908)
+#if defined(CONFIG_BCM963138) || defined(CONFIG_BCM963148) || defined(CONFIG_BCM94908) || defined(CONFIG_BCM963158) || defined(CONFIG_BCM963178) || defined(CONFIG_BCM947622) || \
+    defined(CHIP_63138) || defined(CHIP_63148) || defined(CHIP_4908) || defined(CHIP_63158) || defined(CHIP_63178)  || defined(CHIP_47622)
 #define BCM_COS_COUNT  8
 #else
 #define BCM_COS_COUNT  4
@@ -428,7 +447,10 @@ struct ethswctl_data
             int ret_val;
             int val;
             int max_pkts_per_iter;
+            int rx_queues;
             int weights[BCM_COS_COUNT];
+#define MAX_WRR_WEIGHTS 16
+            int weight_pkts[BCM_COS_COUNT];
             unsigned char qos_egrq_sched_cap[BCM_COS_COUNT];
             int priority;
             int sw_port_type;
@@ -460,6 +482,9 @@ struct ethswctl_data
             int duplex;
             unsigned int port_map;
             unsigned int phy_portmap;
+            int cfgSpeed;
+            int cfgDuplex;
+            int phyCap;
             int phycfg;
             int epon_port;
             char ifname[IFNAMSIZ];
@@ -472,6 +497,7 @@ struct ethswctl_data
         };
         struct dos_ctrl_params
         {
+            unsigned char da_eq_sa_drop_en;
             unsigned char ip_lan_drop_en;   
             unsigned char tcp_blat_drop_en; 
             unsigned char udp_blat_drop_en; 
@@ -596,28 +622,6 @@ struct ethswctl_data
         {
            unsigned int link_change;
         }mdk_kernel_poll;
-        /** Port statistics */
-       struct rdpa_port_stats
-       {
-           uint64 rx_valid_pkt;               /**< Valid Received packets */
-           uint64 rx_crc_error_pkt;           /**< Received packets with CRC error */
-           uint64 rx_discard_1;               /**< RX discard 1 */
-           uint64 rx_discard_2;               /**< RX discard 2  */    
-           uint64 bbh_drop_1;                 /**< BBH drop 1  */    
-           uint64 bbh_drop_2;                 /**< BBH drop 2 */    
-           uint64 bbh_drop_3;                 /**< BBH drop 3 */    
-           uint64 rx_discard_max_length;      /**< Packets discarded due to size bigger than MTU  */    
-           uint64 rx_discard_min_length;      /**< Packets discarded due to size smaller than 64  */    
-           uint64 tx_valid_pkt;               /**< Valid transmitted packets */    
-           uint64 tx_discard;                 /**< TX discarded packets (TX FIFO full) */
-           uint64 discard_pkt;                /**< Dropped filtered Packets */
-           uint64 rx_valid_bytes;
-           uint64 tx_valid_bytes;
-           uint64 rx_broadcast_pkt;
-           uint64 tx_broadcast_pkt;
-           uint64 rx_multicast_pkt;
-           uint64 tx_multicast_pkt;
-        } rdpa_port_stats_s;
         struct oam_idx_str
         {
             #define OAM_MAP_SUB_TYPE_TO_UNIT_PORT 0
@@ -630,6 +634,12 @@ struct ethswctl_data
             };
 
         }oam_idx_str;
+        struct
+        {
+            int pfc_ret;
+            int pfc_timer[8];
+        };
+        net_port_t net_port;
     };  /* Union */
 };
 
@@ -679,6 +689,8 @@ typedef enum bcm_switch_control_e {
   bcmSwitchLinkUpLanPorts,          /* COnfigure TxQ Configuration Mode */
   bcmSwitchLinkUpWanPorts,      /* COnfigure TxQ Configuration Mode */
   bcmSwitchMaxStreams,          /* Configure Queue Max Streams */
+  bcmSwitchCurStreams,          /* Current streams used to compute threshold */
+  bcmSwitchActQuePerPort,       /* Active Queue per poert */
   bcmSwitch__Count,
 } bcm_switch_control_t;
 
@@ -773,7 +785,8 @@ typedef struct {
 #define BCM_COSQ_COMBO   2
 #define BCM_COSQ_SP      0
 
-#if defined(CONFIG_BCM963138) || defined(CONFIG_BCM963148) || defined(CONFIG_BCM94908) || defined(CHIP_63138) || defined(CHIP_63148) || defined(CHIP_4908)
+#if defined(CONFIG_BCM963138) || defined(CONFIG_BCM963148) || defined(CONFIG_BCM94908) || defined(CONFIG_BCM963158) || defined(CONFIG_BCM963178) \
+    || defined(CHIP_63138) || defined(CHIP_63148) || defined(CHIP_4908) || defined(CHIP_63158) || defined(CHIP_63178)
 #define NUM_EGRESS_QUEUES  8
 #else
 #define NUM_EGRESS_QUEUES  4
@@ -791,8 +804,11 @@ typedef struct {
 #define PAUSE_FLOW_CTRL_BOTH 2
 #define PAUSE_FLOW_CTRL_TX   3
 #define PAUSE_FLOW_CTRL_RX   4
-#define PAUSE_FLOW_CTRL_BCMSWITCH_OFF  5
-#define PAUSE_FLOW_CTRL_BCMSWITCH_ON   6
+#define PAUSE_FLOW_PFC_BOTH  5
+#define PAUSE_FLOW_PFC_TX    6
+#define PAUSE_FLOW_PFC_RX    7
+#define PAUSE_FLOW_CTRL_BCMSWITCH_OFF  8
+#define PAUSE_FLOW_CTRL_BCMSWITCH_ON   9
 #define SWITCH_PORTS_ALL_PHYS  255
 
 /* For ETHSWCOSTXQSEL */
@@ -811,6 +827,7 @@ typedef struct {
 #define IMP_PORT_ID   8
 #define P4_PORT_ID    4
 #define P5_PORT_ID    5
+#define P7_PORT_ID    7
 #define TC_ZERO_QOS   4
 #define SWAP_TYPE_MASK  (0xff<<24)
 #define PORT_RXDISABLE 0x1
@@ -830,6 +847,16 @@ typedef struct {
 /* Link Handling */
 #define ETHSW_LINK_MIGHT_CHANGED    (1<<0)
 #define ETHSW_LINK_FORCE_CHECK      (1<<1)
+#define ETHSW_LINK_CHANGED          (1<<2)
+
+/* Spanning Tree states */
+enum {
+    STP_DISABLED,
+    STP_LISTENING,
+    STP_LEARNING,
+    STP_FORWARDING,
+    STP_BLOCKING,
+};
 
 /* DMA Dump */
 #define ETHSW_DMA_RX    1
diff --git a/bcmtypes.h b/bcm/bcmtypes.h
similarity index 100%
rename from bcmtypes.h
rename to bcm/bcmtypes.h
diff --git a/bcm/net_port.h b/bcm/net_port.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe9d26fe3c7a6e2ccae71ed51ecfe212f210ea60
--- /dev/null
+++ b/bcm/net_port.h
@@ -0,0 +1,101 @@
+/*
+    Copyright 2007-2015 Broadcom Corporation
+
+    <:label-BRCM:2015:DUAL/GPL:standard
+    
+    Unless you and Broadcom execute a separate written software license
+    agreement governing use of this software, this software is licensed
+    to you under the terms of the GNU General Public License version 2
+    (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+    with the following added to such license:
+    
+       As a special exception, the copyright holders of this software give
+       you permission to link this software with independent modules, and
+       to copy and distribute the resulting executable under terms of your
+       choice, provided that you also meet, for each linked independent
+       module, the terms and conditions of the license of that module.
+       An independent module is a module which is not derived from this
+       software.  The special exception does not apply to any modifications
+       of the software.
+    
+    Not withstanding the above, under no circumstances may you combine
+    this software in any way with any other Broadcom software provided
+    under a license other than the GPL, without Broadcom's express prior
+    written consent.
+    
+    :>
+*/
+
+/***********************************************************************/
+/*                                                                     */
+/*   MODULE:  net_port.h                                               */
+/*   PURPOSE: Generic port name interface.                             */
+/*                                                                     */
+/***********************************************************************/
+#ifndef _NET_PORT_H
+#define _NET_PORT_H
+
+typedef struct net_port_t
+{
+    int port;
+    int sub_type;
+    int is_wan;
+    int speed;
+    char ifname[32];
+} net_port_t;
+
+#define _FOREACH_NET_PORT_TYPE(TYPE, TYPE0) \
+    TYPE0(NET_PORT_LAN_0) \
+    TYPE(NET_PORT_LAN_1) \
+    TYPE(NET_PORT_LAN_2) \
+    TYPE(NET_PORT_LAN_3) \
+    TYPE(NET_PORT_LAN_4) \
+    TYPE(NET_PORT_LAN_5) \
+    TYPE(NET_PORT_LAN_6) \
+    TYPE(NET_PORT_LAN_7) \
+    TYPE(NET_PORT_EPON_AE) \
+    TYPE(NET_PORT_EPON) \
+    TYPE(NET_PORT_GPON) \
+    TYPE(NET_PORT_LAST) \
+    TYPE(NET_PORT_NONE)
+
+#define _FOREACH_NET_PORT_SUBTYPE_TYPE(TYPE, TYPE0) \
+    TYPE0(NET_PORT_SUBTYPE_GPON) \
+    TYPE(NET_PORT_SUBTYPE_XGPON) \
+    TYPE(NET_PORT_SUBTYPE_XGS) \
+    TYPE(NET_PORT_SUBTYPE_NGPON) \
+    TYPE(NET_PORT_SUBTYPE_LAST) \
+    TYPE(NET_PORT_SUBTYPE_NONE)
+    
+#define _FOREACH_NET_PORT_SPEED_TYPE(TYPE, TYPE0) \
+    TYPE0(NET_PORT_SPEED_0101) \
+    TYPE(NET_PORT_SPEED_0201) \
+    TYPE(NET_PORT_SPEED_0202) \
+    TYPE(NET_PORT_SPEED_2501) \
+    TYPE(NET_PORT_SPEED_1001) \
+    TYPE(NET_PORT_SPEED_1025) \
+    TYPE(NET_PORT_SPEED_1010) \
+    TYPE(NET_PORT_SPEED_LAST) \
+    TYPE(NET_PORT_SPEED_NONE)
+
+#define FOREACH_NET_PORT_ENUM \
+    _FOREACH_NET_PORT_TYPE(GENERATE_ENUM, GENERATE_ENUM0) \
+    _FOREACH_NET_PORT_SUBTYPE_TYPE(GENERATE_ENUM, GENERATE_ENUM0) \
+    _FOREACH_NET_PORT_SPEED_TYPE(GENERATE_ENUM, GENERATE_ENUM0)
+
+#define FOREACH_NET_PORT_STRING \
+    _FOREACH_NET_PORT_TYPE(GENERATE_STRING, GENERATE_STRING) \
+    _FOREACH_NET_PORT_SUBTYPE_TYPE(GENERATE_STRING, GENERATE_STRING) \
+    _FOREACH_NET_PORT_SPEED_TYPE(GENERATE_STRING, GENERATE_STRING)
+
+#define GENERATE_ENUM(ENUM) ENUM,
+#define GENERATE_ENUM0(ENUM) ENUM = 0,
+#define GENERATE_STRING(STRING) #STRING,
+
+enum
+{
+    FOREACH_NET_PORT_ENUM
+};
+
+#endif
+
diff --git a/ethernet.c b/ethernet.c
index 9cbc6231d5d69efe6deca27626ae86a6ec5dc925..7e4ddcb6f554c01af3fa3cf202af235a5cd6f543 100644
--- a/ethernet.c
+++ b/ethernet.c
@@ -1,7 +1,7 @@
 /*
  * ethernet.c - file implements library APIs
  *
- * Copyright (C) 2018 iopsys Software Solutions AB. All rights reserved.
+ * Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
  *
  * Author: anjan.chanda@iopsys.eu
  *
@@ -34,6 +34,7 @@
 #include <linux/sockios.h>
 #include <linux/mii.h>
 
+#include "easy.h"
 #include "ethernet.h"
 
 #ifdef IOPSYS_BROADCOM
@@ -46,139 +47,140 @@ const struct eth_ops *eth_ops[] = {
 #ifdef IOPSYS_BROADCOM
 	&bcm_eth_ops,
 #else
-	&ethsw_ops,
+	&ethsw_ops,   /* FIXME */
 #endif
 };
 
-const struct eth_ops *get_eth_driver(char *name)
+const struct eth_ops *get_eth_driver(const char *ifname)
 {
 	int i;
 
 	for (i = 0; i < sizeof(eth_ops)/sizeof(eth_ops[0]); i++)
-		if (!strncmp(eth_ops[i]->name, name,
-					strlen(eth_ops[i]->name)))
+		if (!strncmp(eth_ops[i]->ifname, ifname,
+					strlen(eth_ops[i]->ifname)))
 			return eth_ops[i];
 
 	return NULL;
 }
 
-int eth_up(char *name)
+int eth_up(const char *ifname)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
+	const struct eth_ops *eth = get_eth_driver(ifname);
 
 	if (eth && eth->up)
-		return eth->up(name);
+		return eth->up(ifname);
 
 	return -1;
 }
 
-int eth_down(char *name)
+int eth_down(const char *ifname)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
+	const struct eth_ops *eth = get_eth_driver(ifname);
 
 	if (eth && eth->down)
-		return eth->down(name);
+		return eth->down(ifname);
 
 	return -1;
 }
 
-int eth_get_link_settings(char *name, struct eth_link *link)
+int eth_get_link_settings(const char *ifname, struct eth_link *link)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
+	const struct eth_ops *eth = get_eth_driver(ifname);
 
 	if (eth && eth->get_link_settings)
-		return eth->get_link_settings(name, link);
+		return eth->get_link_settings(ifname, link);
 
 	return -1;
 }
 
-int eth_set_link_settings(char *name, struct eth_link link)
+int eth_set_link_settings(const char *ifname, struct eth_link link)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
+	const struct eth_ops *eth = get_eth_driver(ifname);
 
 	if (eth && eth->set_link_settings)
-		return eth->set_link_settings(name, link);
+		return eth->set_link_settings(ifname, link);
 
 	return -1;
 }
 
-int eth_get_operstate(char *name, enum eth_operstate *op)
+int eth_get_operstate(const char *ifname, ifopstatus_t *s)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
-
-	if (eth && eth->get_operstate)
-		return eth->get_operstate(name, op);
+	return get_ifoperstatus(ifname, s);
+}
 
+int eth_set_operstate(const char *ifname, ifopstatus_t s)
+{
+	/* return set_ifoperstatus(ifname, s); */	//TODO
 	return -1;
 }
 
-int eth_set_operstate(char *name, enum eth_operstate op)
+int eth_get_stats(const char *ifname, struct eth_stats *s)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
+	const struct eth_ops *eth = get_eth_driver(ifname);
 
-	if (eth && eth->set_operstate)
-		return eth->set_operstate(name, op);
+	if (eth && eth->get_stats)
+		return eth->get_stats(ifname, s);
 
 	return -1;
 }
 
-int eth_get_stats(char *name, struct eth_counters *c)
+int eth_get_rmon_stats(const char *ifname, struct eth_rmon_stats *tx,
+						struct eth_rmon_stats *rx)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
+	const struct eth_ops *eth = get_eth_driver(ifname);
 
-	if (eth && eth->get_stats)
-		return eth->get_stats(name, c);
+	if (eth && eth->get_rmon_stats)
+		return eth->get_rmon_stats(ifname, tx, rx);
 
 	return -1;
 }
 
-int eth_poweron_phy(char *name, struct eth_phy p)
+int eth_poweron_phy(const char *ifname, struct eth_phy p)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
+	const struct eth_ops *eth = get_eth_driver(ifname);
 
 	if (eth && eth->poweron_phy)
-		return eth->poweron_phy(name, p);
+		return eth->poweron_phy(ifname, p);
 
 	return -1;
 }
 
-int eth_poweroff_phy(char *name, struct eth_phy p)
+int eth_poweroff_phy(const char *ifname, struct eth_phy p)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
+	const struct eth_ops *eth = get_eth_driver(ifname);
 
 	if (eth && eth->poweroff_phy)
-		return eth->poweroff_phy(name, p);
+		return eth->poweroff_phy(ifname, p);
 
 	return -1;
 }
 
-
-int eth_reset_phy(char *name, int phy_id)
+int eth_reset_phy(const char *ifname, int phy_id)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
+	const struct eth_ops *eth = get_eth_driver(ifname);
 
 	if (eth && eth->reset_phy)
-		return eth->reset_phy(name, phy_id);
+		return eth->reset_phy(ifname, phy_id);
 	else
-		return eth_mii_reset_phy(name, phy_id);
+		return eth_mii_reset_phy(ifname, phy_id);
 }
 
-int eth_get_phy_id(char *name, int port, int *phy_id)
+int eth_get_phy_id(const char *ifname, int port, int *phy_id)
 {
-	const struct eth_ops *eth = get_eth_driver(name);
+	const struct eth_ops *eth = get_eth_driver(ifname);
 
 	if (eth && eth->get_phy_id)
-		return eth->get_phy_id(name, port, phy_id);
+		return eth->get_phy_id(ifname, port, phy_id);
 	else
-		return eth_mii_get_phy_id(name, port, phy_id);
+		return eth_mii_get_phy_id(ifname, port, phy_id);
 }
 
-int eth_ioctl(char *name, int cmd, void *in, int len)
+int eth_ioctl(const char *ifname, int cmd, void *in, int len)
 {
 	struct ifreq ifr;
 	int s;
 
-	strncpy(ifr.ifr_name, name, IFNAMSIZ);
+	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
 	s = socket(AF_INET, SOCK_DGRAM, 0);
 	if (s < 0)
 		return -1;
@@ -201,7 +203,7 @@ int eth_ioctl(char *name, int cmd, void *in, int len)
 	return 0;
 }
 
-int eth_mii_get_phy_id(char *ifname, int port, int *phy_id)
+int eth_mii_get_phy_id(const char *ifname, int port, int *phy_id)
 {
 	struct mii_ioctl_data *mii;
 	struct ifreq ifr;
@@ -237,7 +239,7 @@ int eth_mii_get_phy_id(char *ifname, int port, int *phy_id)
 	return 0;
 }
 
-static int eth_mii_ioctl(char *name, int cmd, int phy_id, int reg,
+static int eth_mii_ioctl(const char *ifname, int cmd, int phy_id, int reg,
 						int in, int *out)
 {
 	struct mii_ioctl_data *mii;
@@ -249,7 +251,7 @@ static int eth_mii_ioctl(char *name, int cmd, int phy_id, int reg,
 		return -1;
 
 	memset(&ifr, 0, sizeof(struct ifreq));
-	strncpy(ifr.ifr_name, name, IFNAMSIZ);
+	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
 	if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
 		fprintf(stderr, "SIOCGIFINDEX failed!\n");
 		close(s);
@@ -277,18 +279,18 @@ static int eth_mii_ioctl(char *name, int cmd, int phy_id, int reg,
 	return 0;
 }
 
-int eth_mii_read(char *name, int phy_id, int reg, int *out)
+int eth_mii_read(const char *ifname, int phy_id, int reg, int *out)
 {
-	return eth_mii_ioctl(name, SIOCGMIIREG, phy_id, reg, 0, out);
+	return eth_mii_ioctl(ifname, SIOCGMIIREG, phy_id, reg, 0, out);
 }
 
-int eth_mii_write(char *name, int phy_id, int reg, int in)
+int eth_mii_write(const char *ifname, int phy_id, int reg, int in)
 {
-	return eth_mii_ioctl(name, SIOCGMIIREG, phy_id, reg, in, NULL);
+	return eth_mii_ioctl(ifname, SIOCGMIIREG, phy_id, reg, in, NULL);
 }
 
-int eth_mii_reset_phy(char *name, int phy_id)
+int eth_mii_reset_phy(const char *ifname, int phy_id)
 {
-	return eth_mii_ioctl(name, SIOCSMIIREG, phy_id,
+	return eth_mii_ioctl(ifname, SIOCSMIIREG, phy_id,
 				MII_BMCR, BMCR_RESET, NULL);
 }
diff --git a/ethernet.h b/ethernet.h
index d51d3646b01794e185c8e73db17442f8de6c5ff1..3cf3cf3f93a24c55448f8dc565b3a96c26885b6c 100644
--- a/ethernet.h
+++ b/ethernet.h
@@ -1,7 +1,7 @@
 /*
- * ethernet.h - library header file
+ * ethernet.h - libethernet header file
  *
- * Copyright (C) 2018 iopsys Software Solutions AB. All rights reserved.
+ * Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
  *
  * Author: anjan.chanda@iopsys.eu
  *
@@ -24,37 +24,49 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <linux/types.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/** enum eth_operstate -  maps to operational state of interface */
-enum eth_operstate {
-	IF_UP,
-	IF_DOWN,
-	IF_UKNOWN,
-	IF_DORMANT,
-	IF_NOTPRESENT,
-	IF_LLDOWN,
-	IF_ERROR,
+/* enum eth_duplex - duplex modes */
+enum eth_duplex {
+	AUTO_DUPLEX,
+	HALF_DUPLEX,
+	FULL_DUPLEX,
 };
 
-struct eth_counters {
-	unsigned long tx_bytes;
-	unsigned long rx_bytes;
-	unsigned long tx_packets;
-	unsigned long rx_packets;
-
-	/** packets dropped due to errors */
-	unsigned long tx_error_packets;
-	unsigned long rx_error_packets;
+/* enum eth_rmon_status - rmon status */
+enum rmon_status {
+	RMON_STATUS_DISABLED,
+	RMON_STATUS_ENABLED,
+	RMON_STATUS_ERR_MISCONF,
+	RMON_STATUS_ERR,
+};
 
-	/** no-error packets dropped due to other factors */
-	unsigned long tx_dropped_packets;
-	unsigned long rx_dropped_pcakets;
+/* struct eth_rmon_stats - ethernet rmon counters */
+struct eth_rmon_stats {
+	enum rmon_status status;
+	uint16_t vlanid;                /* 0..4094 */
+	bool all_q;
+	uint32_t drop_events;
+	unsigned long bytes;
+	unsigned long packets;
+	unsigned long bcast_packets;
+	unsigned long mcast_packets;
+	uint32_t crc_err_packets;
+	uint32_t under_sz_packets;
+	uint32_t over_sz_packets;
+	unsigned long packets_64bytes;
+	unsigned long packets_65to127bytes;
+	unsigned long packets_128to255bytes;
+	unsigned long packets_256to511bytes;
+	unsigned long packets_512to1023bytes;
+	unsigned long packets_1024to1518bytes;
 };
 
+
 #define ETH_PORT_UNDEFINED	-1
 
 enum eth_speed {
@@ -75,15 +87,6 @@ struct eth_phy {
 	int portidx;
 };
 
-struct eth_link {
-	int portid;
-	uint32_t capability;
-	bool autoneg;
-	uint32_t speed;
-	bool fullduplex;
-	bool down;
-};
-
 struct eth_info {
 	int phy_portmap;
 	int phy_numports;
@@ -97,6 +100,74 @@ enum eth_callstatus {
 	ETH_EUNKNOWN
 };
 
+struct eth_stats {
+	unsigned long tx_bytes;
+	unsigned long rx_bytes;
+	unsigned long tx_packets;
+	unsigned long rx_packets;
+	uint32_t tx_errors;                 /* error packets */
+	uint32_t rx_errors;
+	unsigned long tx_ucast_packets;     /* unicast packets */
+	unsigned long rx_ucast_packets;
+	unsigned long tx_mcast_packets;     /* multicast packets */
+	unsigned long rx_mcast_packets;
+	unsigned long tx_bcast_packets;     /* broadcast packets */
+	unsigned long rx_bcast_packets;
+	uint32_t tx_discard_packets;        /* no error packets dropped */
+	uint32_t rx_discard_packets;        /* no error packets dropped */
+	uint32_t rx_unknown_packets;        /* unknown protocol packets */
+};
+
+/* struct eth_vlan - vlan over eth_link */
+struct eth_vlan {
+	ifopstatus_t status;
+	uint16_t id;                       /* vlan id [1..4094] */
+	uint16_t tpid;                     /* tag protocol id, t.x. 0x8100 */
+	struct eth_stats stats;
+};
+
+//TODO: revisit
+/* struct eth_link - logical link per ethernet port */
+struct eth_link {
+	int portid;
+	uint32_t capability;
+	bool autoneg;
+	uint32_t speed;
+	bool fullduplex;
+	bool down;
+	bool prio_tagged;
+	struct eth_stats stats;
+};
+
+/* struct eth_iface - ethernet interface */
+struct eth_iface {
+	ifopstatus_t status;
+	uint32_t lastchange;              /* in secs */
+	bool is_upstream;
+	uint8_t macaddr[6];
+	uint32_t max_bitrate;             /* in Mbps */
+	uint32_t curr_bitrate;            /* in Mbps */
+	enum eth_duplex duplex;
+	bool eee_supported;
+	bool eee_enabled;
+	struct eth_stats stats;
+};
+
+/* struct eth_device - ethernet device */
+struct eth_device {
+	bool wol_supported;
+	uint32_t num_ifaces;
+	uint32_t num_links;
+	uint32_t num_vlans;
+	struct eth_rmon_stats tx,
+			      rx;
+	struct eth_iface *ifs;
+	struct eth_link *links;
+	struct eth_vlan *vlans;
+};
+
+
+
 #ifndef if_mii
 static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
 {
@@ -105,50 +176,56 @@ static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
 #endif
 
 
+/* TODO: eth_device/sw_ops, eth_iface_ops, eth_link_ops */
+
 struct eth_ops {
 	/** interface name/prefix to match */
-	const char *name;
+	const char *ifname;
 
-	int (*up)(char *name);
-	int (*down)(char *name);
+	int (*up)(const char *ifname);
+	int (*down)(const char *ifname);
 
-	int (*get_link_settings)(char *name, struct eth_link *link);
-	int (*set_link_settings)(char *name, struct eth_link link);
+	int (*get_link_settings)(const char *ifname, struct eth_link *link);
+	int (*set_link_settings)(const char *ifname, struct eth_link link);
 
-	int (*get_operstate)(char *name, enum eth_operstate *s);
-	int (*set_operstate)(char *name, enum eth_operstate s);
+	int (*get_operstate)(const char *ifname, ifopstatus_t *s);
+	int (*set_operstate)(const char *ifname, ifopstatus_t s);
 
-	int (*reset_phy)(char *name, int phy_id);
-	int (*poweroff_phy)(char *name, struct eth_phy p);
-	int (*poweron_phy)(char *name, struct eth_phy p);
-	int (*get_phy_id)(char *name, int port, int *phy_id);
+	int (*reset_phy)(const char *ifname, int phy_id);
+	int (*poweroff_phy)(const char *ifname, struct eth_phy p);
+	int (*poweron_phy)(const char *ifname, struct eth_phy p);
+	int (*get_phy_id)(const char *ifname, int port, int *phy_id);
 
-	int (*get_stats)(char *name, struct eth_counters *s);
-	int (*get_info)(char *name, struct eth_info *info);
+	int (*get_stats)(const char *ifname, struct eth_stats *s);
+	int (*get_info)(const char *ifname, struct eth_info *info);
+	int (*get_rmon_stats)(const char *ifname, struct eth_rmon_stats *tx,
+						struct eth_rmon_stats *rx);
 };
 
 
 /* API list */
-int eth_up(char *name);
-int eth_down(char *name);
-int eth_get_link_settings(char *name, struct eth_link *link);
-int eth_set_link_settings(char *name, struct eth_link link);
-int eth_get_operstate(char *name, enum eth_operstate *s);
-int eth_set_operstate(char *name, enum eth_operstate s);
-int eth_get_stats(char *name, struct eth_counters *c);
-int eth_get_info(char *name, struct eth_info *info);
-
-int eth_reset_phy(char *name, int phy_id);
-int eth_poweroff_phy(char *name, struct eth_phy p);
-int eth_poweron_phy(char *name, struct eth_phy p);
-
-int eth_get_phy_id(char *name, int port, int *phy_id);
-
-int eth_ioctl(char *name, int cmd, void *in, int len);
-int eth_mii_read(char *name, int phy_id, int reg, int *out);
-int eth_mii_write(char *name, int phy_id, int reg, int in);
-int eth_mii_get_phy_id(char *ifname, int port, int *phy_id);
-int eth_mii_reset_phy(char *name, int phy_id);
+int eth_up(const char *ifname);
+int eth_down(const char *ifname);
+int eth_get_link_settings(const char *ifname, struct eth_link *link);
+int eth_set_link_settings(const char *ifname, struct eth_link link);
+int eth_get_operstate(const char *ifname, ifopstatus_t *s);
+int eth_set_operstate(const char *ifname, ifopstatus_t s);
+int eth_get_stats(const char *ifname, struct eth_stats *c);
+int eth_get_info(const char *ifname, struct eth_info *info);
+int eth_get_rmon_stats(const char *ifname, struct eth_rmon_stats *tx,
+					struct eth_rmon_stats *rx);
+
+int eth_reset_phy(const char *ifname, int phy_id);
+int eth_poweroff_phy(const char *ifname, struct eth_phy p);
+int eth_poweron_phy(const char *ifname, struct eth_phy p);
+
+int eth_get_phy_id(const char *ifname, int port, int *phy_id);
+
+int eth_ioctl(const char *ifname, int cmd, void *in, int len);
+int eth_mii_read(const char *ifname, int phy_id, int reg, int *out);
+int eth_mii_write(const char *ifname, int phy_id, int reg, int in);
+int eth_mii_get_phy_id(const char *ifname, int port, int *phy_id);
+int eth_mii_reset_phy(const char *ifname, int phy_id);
 
 #ifdef __cplusplus
 }