Merge "[rdk-b][common][bsp][Refactor and sync kernel/wifi from Openwrt]"
diff --git a/recipes-devtools/mii-mgr/files/fix-rdkb-wan-get-status-fail.patch b/recipes-devtools/mii-mgr/files/fix-rdkb-wan-get-status-fail.patch
new file mode 100644
index 0000000..b1725c5
--- /dev/null
+++ b/recipes-devtools/mii-mgr/files/fix-rdkb-wan-get-status-fail.patch
@@ -0,0 +1,11 @@
+--- ../mii_mgr.c.bak	2022-11-03 15:21:40.446210000 +0800
++++ ../mii_mgr.c	2022-11-03 15:23:20.435803359 +0800
+@@ -118,7 +118,7 @@
+ 				is_priv = 0;
+ 				break;
+ 			case 'i':
+-				strncpy(ifname, optarg, 5);
++				strncpy(ifname, optarg, IFNAMSIZ);
+ 				ifname[IFNAMSIZ - 1] = '\0';
+ 				break;	
+ 			case 'p':
diff --git a/recipes-devtools/mii-mgr/files/src/Makefile b/recipes-devtools/mii-mgr/files/src/Makefile
new file mode 100644
index 0000000..55d6a6f
--- /dev/null
+++ b/recipes-devtools/mii-mgr/files/src/Makefile
@@ -0,0 +1,16 @@
+EXEC = mii_mgr
+
+CFLAGS += -Wall -Werror
+
+all: $(EXEC)
+
+mii_mgr: mii_mgr.o
+
+	$(CC) $(LDFLAGS) -o $@ $^
+
+romfs:
+	$(ROMFSINST) /bin/mii_mgr
+
+clean:
+	-rm -f $(EXEC) *.elf *.gdb *.o
+
diff --git a/recipes-devtools/mii-mgr/files/mii_mgr.c b/recipes-devtools/mii-mgr/files/src/mii_mgr.c
similarity index 92%
rename from recipes-devtools/mii-mgr/files/mii_mgr.c
rename to recipes-devtools/mii-mgr/files/src/mii_mgr.c
index f968807..a22c3e8 100644
--- a/recipes-devtools/mii-mgr/files/mii_mgr.c
+++ b/recipes-devtools/mii-mgr/files/src/mii_mgr.c
@@ -118,22 +118,30 @@
 				is_priv = 0;
 				break;
 			case 'i':
-				strncpy(ifname, optarg, IFNAMSIZ);
+				strncpy(ifname, optarg, 5);
 				ifname[IFNAMSIZ - 1] = '\0';
 				break;	
 			case 'p':
 				port = strtoul(optarg, NULL, 16);
+				if (port > INT_MAX)
+					return -EINVAL;
 				break;
-			case 'd':
-				dev = strtoul(optarg, NULL, 16);
+                        case 'd':				
+                                dev = strtoul(optarg, NULL, 16);
+				if (dev > INT_MAX)
+					return -EINVAL;
 				is_cl45 = 1;
 				break;
 			case 'r':
 				reg_num = strtoul(optarg, NULL, 16);
+				if (reg_num > INT_MAX)
+					return -EINVAL;
 				break;
 
 			case 'v':
 				val = strtoul(optarg, NULL, 16);
+				if (val > INT_MAX)
+					return -EINVAL;
 				break;
 			case '?':
 				show_usage();
diff --git a/recipes-devtools/mii-mgr/files/mii_mgr.h b/recipes-devtools/mii-mgr/files/src/mii_mgr.h
similarity index 100%
rename from recipes-devtools/mii-mgr/files/mii_mgr.h
rename to recipes-devtools/mii-mgr/files/src/mii_mgr.h
diff --git a/recipes-devtools/mii-mgr/mii-mgr_1.0.bb b/recipes-devtools/mii-mgr/mii-mgr_1.0.bb
index 9a16340..c233ebe 100644
--- a/recipes-devtools/mii-mgr/mii-mgr_1.0.bb
+++ b/recipes-devtools/mii-mgr/mii-mgr_1.0.bb
@@ -3,20 +3,20 @@
 LICENSE = "GPLv2"
 LIC_FILES_CHKSUM = "file://COPYING;md5=c188eeeb69c0a05d0545816f1458a0c9"
 
-S = "${WORKDIR}"
-
 SRC_URI = " \
-    file://COPYING \
-    file://mii_mgr.c \
-    file://mii_mgr.h \
+    file://COPYING;subdir=git/src \
+    file://src;subdir=git \
+    file://fix-rdkb-wan-get-status-fail.patch \
     "
 
+S = "${WORKDIR}/git/src"
+
 do_compile() {
     ${CC} ${LDFLAGS} mii_mgr.c -o mii_mgr
 }
 
 do_install() {
     install -d ${D}${sbindir}
-    install -m 0755 ${WORKDIR}/mii_mgr ${D}${sbindir}
-    install -m 0755 ${WORKDIR}/mii_mgr ${D}${sbindir}/mii_mgr_cl45
+    install -m 0755 ${S}/mii_mgr ${D}${sbindir}
+    install -m 0755 ${S}/mii_mgr ${D}${sbindir}/mii_mgr_cl45
 }
diff --git a/recipes-devtools/mtk-factory-rw/files/fix-rdkb-get-board-name-issue.patch b/recipes-devtools/mtk-factory-rw/files/fix-rdkb-get-board-name-issue.patch
new file mode 100644
index 0000000..010ecdc
--- /dev/null
+++ b/recipes-devtools/mtk-factory-rw/files/fix-rdkb-get-board-name-issue.patch
@@ -0,0 +1,20 @@
+--- ../mtk_factory_rw.sh.bak	2022-11-03 17:09:43.001641800 +0800
++++ ../mtk_factory_rw.sh	2022-11-03 17:26:01.636647400 +0800
+@@ -27,7 +27,7 @@
+ lan_mac_offset=0x2A
+ wan_mac_offset=0x24
+ 
+-case `cat /tmp/sysinfo/board_name` in
++case `cat /proc/device-tree/model` in
+ 	*7621*ax*)
+ 		# 256k - 12 byte
+ 		lan_mac_offset=0x3FFF4
+@@ -65,7 +65,7 @@
+ 	local length=$1
+ 	local offset=$2
+ 
+-	hexdump -v -n ${length} -s ${offset} -e ''`expr ${length} - 1`'/1 "%02x-" "%02x "' ${factory_mtd}
++	hexdump -v -n ${length} -s ${offset} -e ''`expr ${length} - 1`'/1 "%02x:" "%02x "' ${factory_mtd}
+ }
+ 
+ overwrite_data=
diff --git a/recipes-devtools/mtk-factory-rw/files/mtk_factory_rw.sh b/recipes-devtools/mtk-factory-rw/files/mtk_factory_rw.sh
index 4b4a03f..3124088 100644
--- a/recipes-devtools/mtk-factory-rw/files/mtk_factory_rw.sh
+++ b/recipes-devtools/mtk-factory-rw/files/mtk_factory_rw.sh
@@ -27,7 +27,7 @@
 lan_mac_offset=0x2A
 wan_mac_offset=0x24
 
-case `cat /proc/device-tree/model` in
+case `cat /tmp/sysinfo/board_name` in
 	*7621*ax*)
 		# 256k - 12 byte
 		lan_mac_offset=0x3FFF4
@@ -46,6 +46,12 @@
 		lan_mac_offset=0x1F800
 		wan_mac_offset=0x1F806
 		;;
+	*7988*)
+		#1024k - 18 byte
+		lan2_mac_offset=0xFFFEE
+		lan_mac_offset=0xFFFF4
+		wan_mac_offset=0xFFFFA
+		;;
 	*)
 		lan_mac_offset=0x2A
 		wan_mac_offset=0x24
@@ -59,7 +65,7 @@
 	local length=$1
 	local offset=$2
 
-	hexdump -v -n ${length} -s ${offset} -e ''`expr ${length} - 1`'/1 "%02x:" "%02x "' ${factory_mtd}
+	hexdump -v -n ${length} -s ${offset} -e ''`expr ${length} - 1`'/1 "%02x-" "%02x "' ${factory_mtd}
 }
 
 overwrite_data=
@@ -99,6 +105,9 @@
 	if [ "$1" == "lan" ]; then
 		#read lan mac
 		Get_offset_data 6 ${lan_mac_offset}
+	elif [ "$1" == "lan2" ]; then
+		#read lan2 mac
+		Get_offset_data 6 ${lan2_mac_offset}
 	elif [ "$1" == "wan" ]; then
 		#read wan mac
 		Get_offset_data 6 ${wan_mac_offset}
@@ -121,6 +130,10 @@
 		#write lan mac
 		Set_offset_data 6 ${lan_mac_offset} $@
 
+	elif [ "$1" == "lan2" ]; then
+		#write lan2 mac
+		Set_offset_data 6 ${lan2_mac_offset} $@
+
 	elif [ "$1" == "wan" ]; then
 		#write wan mac
 		Set_offset_data 6 ${wan_mac_offset} $@
@@ -135,7 +148,7 @@
 # 2. Set/Get the offset data: mtk_factory -r/-w length offset /data
 # 3. Overwrite from offset1 to offset2 by length byte : mtk_factory -o length from to
 if [ "$1" == "-r" ]; then
-	if [ "$2" == "lan" -o "$2" == "wan" ]; then
+	if [ "$2" == "lan" -o "$2" == "lan2" -o "$2" == "wan" ]; then
 		GetMac $2
 	elif [ "$2" -eq "$2" ]; then
 		Get_offset_data $2 $3
@@ -145,7 +158,7 @@
 		exit 1
 	fi
 elif [ "$1" == "-w" ]; then
-	if [ "$2" == "lan" -o "$2" == "wan" ]; then
+	if [ "$2" == "lan"  -o "$2" == "lan2" -o "$2" == "wan" ]; then
 		SetMac $2 $@
 	else
 		Set_offset_data $2 $3 $@
diff --git a/recipes-devtools/mtk-factory-rw/mtk-factory-rw.bb b/recipes-devtools/mtk-factory-rw/mtk-factory-rw.bb
index 0d86d6c..66eacd7 100644
--- a/recipes-devtools/mtk-factory-rw/mtk-factory-rw.bb
+++ b/recipes-devtools/mtk-factory-rw/mtk-factory-rw.bb
@@ -11,6 +11,7 @@
     file://mtk_factory_rw.sh \
     file://init-MacAddr.sh \
     file://init-MacAddr.service \
+    file://fix-rdkb-get-board-name-issue.patch \
     "
 
 SYSTEMD_PACKAGES = "${PN}"
diff --git a/recipes-devtools/regs/files/src/Makefile b/recipes-devtools/regs/files/src/Makefile
new file mode 100644
index 0000000..bc3a12f
--- /dev/null
+++ b/recipes-devtools/regs/files/src/Makefile
@@ -0,0 +1,13 @@
+EXEC = regs
+
+all: $(EXEC)
+
+$(EXEC): $(EXEC).c
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c $(LDLIBS)
+
+romfs:
+	$(ROMFSINST) /bin/$(EXEC)
+
+clean:
+	-rm -f $(EXEC) *.elf *.gdb *.o
+
diff --git a/recipes-devtools/regs/files/regs.c b/recipes-devtools/regs/files/src/regs.c
similarity index 76%
rename from recipes-devtools/regs/files/regs.c
rename to recipes-devtools/regs/files/src/regs.c
index 93a3532..09e088c 100644
--- a/recipes-devtools/regs/files/regs.c
+++ b/recipes-devtools/regs/files/src/regs.c
@@ -15,7 +15,7 @@
  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
@@ -44,8 +44,8 @@
 #define MAP_SIZE 4096UL
 #define MAP_MASK (MAP_SIZE - 1)
 
-void dump_page(uint32_t *vaddr, uint32_t *vbase, uint32_t *pbase){
-	
+void dump_page(uint32_t *vaddr, uint32_t *vbase, uint32_t *pbase)
+{
 	int i =0;
 	uint32_t *end = vaddr + (MAP_SIZE >> 6);
 	uint32_t *start = vaddr;
@@ -63,15 +63,27 @@
     int value;
     int i;
 
+	if ((start_bit < 0) || (start_bit > 31) ||
+	    (data_len < 1) || (data_len > 32) ||
+	    (start_bit + data_len > 32)) {
+		fprintf(stderr, "Startbit range[0~31], and DataLen range[1~32], and Startbit + DataLen <= 32\n");
+		return;
+	}
+
-    for (i = 0; i < data_len; i++) {
-        mask |= 1 << (start_bit + i);
-    }
+	for (i = 0; i < data_len; i++) {
+		if (start_bit + i > 31)
+			break;
+
+		mask |= 1 << (start_bit + i);
+	}
+
+	value = *((volatile uint32_t *) virt_addr);
+	value &= ~mask;
+	value |= (data << start_bit) & mask;;
 
-    value = *((volatile uint32_t *) virt_addr);
-    value &= ~mask;
-    value |= (data << start_bit) & mask;;
+	*((uint32_t *) virt_addr) = value;
 
-    *((uint32_t *) virt_addr) = value;
+	printf("Modify 0x%X[%d:%d]; ", data, start_bit + data_len - 1, start_bit);
 }
 
 void usage(void)
@@ -80,8 +92,8 @@
 			"\tType    : access operation type : [m]odify, [w]wite, [d]ump\n"
 			"\tOffset  : offset into memory region to act upon\n"
 			"\tData    : data to be written\n"
-			"\tStartbit: Startbit of Addr that want to be modified\n"
-			"\tDataLen : Data length of Data\n\n"
+			"\tStartbit: Startbit of Addr that want to be modified. Range[0~31]\n"
+			"\tDataLen : Data length of Data. Range[1~32], and Startbit + DataLen <= 32\n\n"
 			"Example:\tRead/Write/Modify register \n"
 			"\tRead    : regs d 0x1b100000           //dump 0x1b100000~0x1b1000f0 \n"
 			"\tWrite   : regs w 0x1b100000 0x1234    //write 0x1b100000=0x1234\n"
@@ -100,30 +112,31 @@
 	off_t offset = 0;
 	int access_type = 0;
 
-	if(argc < 2) {
+	if(argc < 3) {
 		usage();
 		exit(1);
 	}
 
 	access_type = tolower(argv[1][0]);
-	if((access_type == 'd' && argc < 3) || (access_type == 'w' && argc < 4) || (access_type == 'm' && argc < 6)) {
+	if ((access_type == 'w' && argc < 4) || (access_type == 'm' && argc < 6)) {
 		usage();
 		exit(1);
 	}
 
 	filename = "/dev/mem";
-	if((fd = open(filename, O_RDWR | O_SYNC)) == -1) 
+	if((fd = open(filename, O_RDWR | O_SYNC)) == -1)
 		PRINT_ERROR;
 
 	/* Map one page */
 	offset = strtoul(argv[2], NULL, 16);
 	map_base = mmap(0, 2*MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset & ~MAP_MASK);
-	if(map_base == (void *) -1) 
+	if(map_base == (void *) -1)
 		PRINT_ERROR;
 
 	virt_addr = map_base + (offset & MAP_MASK);
 	read_result = *((volatile uint32_t *) virt_addr);
-	printf("Value at 0x%X (%p): 0x%X\n", offset, virt_addr, read_result);
+	printf("Value at 0x%llX (%p): 0x%X\n",
+	       (unsigned long long)offset, virt_addr, read_result);
 
 	switch(access_type) {
 		case 'm':
@@ -135,19 +148,21 @@
 		case 'w':
 			writeval = strtoul(argv[3], 0, 16);
 			*((uint32_t *) virt_addr) = writeval;
+			printf("Written 0x%X; ", writeval);
 			break;
 		case 'd':
 			dump_page(virt_addr, map_base, (uint32_t *)(offset & ~MAP_MASK));
-			return;
+			goto out;
 		default:
 			fprintf(stderr, "Illegal data type '%c'.\n", access_type);
-			exit(2);
+			goto out;
 	}
 
 	read_result = *((volatile uint32_t *) virt_addr);
-	printf("Written 0x%X; Readback 0x%X\n", writeval, read_result);
+	printf("Readback 0x%X\n", read_result);
 
-	if(munmap(map_base, MAP_SIZE) == -1) 
+out:
+	if(munmap(map_base, MAP_SIZE) == -1)
 		PRINT_ERROR;
 
 	close(fd);
diff --git a/recipes-devtools/regs/regs_1.0.bb b/recipes-devtools/regs/regs_1.0.bb
index 80666fa..7761918 100644
--- a/recipes-devtools/regs/regs_1.0.bb
+++ b/recipes-devtools/regs/regs_1.0.bb
@@ -3,18 +3,18 @@
 LICENSE = "GPLv2"
 LIC_FILES_CHKSUM = "file://COPYING;md5=c188eeeb69c0a05d0545816f1458a0c9"
 
-S = "${WORKDIR}"
-
 SRC_URI = " \
-    file://COPYING \
-    file://regs.c \
+    file://COPYING;subdir=git/src \
+    file://src;subdir=git \
     "
 
+S = "${WORKDIR}/git/src"
+
 do_compile() {
     ${CC} ${CFLAGS} ${LDFLAGS} regs.c -o regs
 }
 
 do_install() {
     install -d ${D}${base_bindir}
-    install -m 0755 ${WORKDIR}/regs ${D}${base_bindir}
+    install -m 0755 ${S}/regs ${D}${base_bindir}
 }
diff --git a/recipes-devtools/switch/files/rdkb-change-bridge-name.patch b/recipes-devtools/switch/files/rdkb-change-bridge-name.patch
new file mode 100644
index 0000000..e443661
--- /dev/null
+++ b/recipes-devtools/switch/files/rdkb-change-bridge-name.patch
@@ -0,0 +1,51 @@
+--- ../switch_ioctl.h.bak	2022-11-02 19:27:43.197665700 +0800
++++ ../switch_ioctl.h	2022-11-02 19:30:58.210080614 +0800
+@@ -5,8 +5,8 @@
+ #ifndef SWITCH_IOCTL_H
+ #define SWITCH_IOCTL_H
+ 
+-#define ETH_DEVNAME "eth0"
+-#define BR_DEVNAME "br-lan"
++#define ETH_DEVNAME "eth1"
++#define BR_DEVNAME "brlan0"
+ 
+ #define RAETH_MII_READ                  0x89F3
+ #define RAETH_MII_WRITE                 0x89F4
+
+
+--- ../switch_fun.c.bak	2022-10-11 16:07:00.560664900 +0800
++++ ../switch_fun.c	2022-11-03 09:44:01.559470656 +0800
+@@ -1334,6 +1334,23 @@
+ 				printf("%03x:   ", (value >> 16) & 0xfff);
+ 				reg_read(REG_ATRD_ADDR, &value2);
+ 				j = (value2 >> 4) & 0xff; //r_port_map
++				if(j & 0x01)
++					printf("0");
++				else if (j & 0x02)
++					printf("1"); 
++				else if (j & 0x04)
++					printf("2"); 
++				else if (j & 0x08)
++					printf("3");
++				else if (j & 0x10)
++					printf("4");
++				else if (j & 0x20)
++					printf("5");
++				else if (j & 0x40)
++					printf("6");
++				else if (j & 0x80)
++					printf("7");
++				/*	 	 	 	
+ 				printf("%c", (j & 0x01) ? '1' : '-');
+ 				printf("%c", (j & 0x02) ? '1' : '-');
+ 				printf("%c", (j & 0x04) ? '1' : '-');
+@@ -1342,7 +1359,8 @@
+ 				printf("%c", (j & 0x20) ? '1' : '-');
+ 				printf("%c", (j & 0x40) ? '1' : '-');
+ 				printf("%c", (j & 0x80) ? '1' : '-');
+-
++				*/
++				printf("       ");
+ 				reg_read(REG_TSRA2_ADDR, &mac2);
+ 
+ 				printf("   %2d", (mac2 >> 12) & 0x7); //FID
diff --git a/recipes-devtools/switch/files/Makefile b/recipes-devtools/switch/files/src/Makefile
similarity index 100%
rename from recipes-devtools/switch/files/Makefile
rename to recipes-devtools/switch/files/src/Makefile
diff --git a/recipes-devtools/switch/files/src/NOTICE b/recipes-devtools/switch/files/src/NOTICE
new file mode 100644
index 0000000..c031eed
--- /dev/null
+++ b/recipes-devtools/switch/files/src/NOTICE
@@ -0,0 +1,202 @@
+MediaTek (C) 2011
+
+The GNU General Public License (GPL)
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU
+General Public License is intended to guarantee your freedom to share and change free software--to make sure the
+software is free for all its users. This General Public License applies to most of the Free Software Foundation's
+software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is
+covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make
+sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you
+receive source code or can get it if you want it, that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to
+surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all
+the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them
+these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty
+for this free software. If the software is modified by someone else and passed on, we want its recipients to know that
+what they have is not the original, so that any problems introduced by others will not reflect on the original authors'
+reputations.
+
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors
+of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this,
+we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it
+may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or
+work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to
+say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into
+another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is
+addressed as "you".
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its
+scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made by running the Program). Whether that is true
+depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided
+that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of
+warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other
+recipients of the Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection
+in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and
+copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of
+these conditions:
+
+a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any
+change.
+
+b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the
+Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this
+License.
+
+c) If the modified program normally reads commands interactively when run, you must cause it, when started running for
+such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright
+notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may
+redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if
+the Program itself is interactive but does not normally print such an announcement, your work based on the Program is
+not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the
+Program, and can be reasonably considered independent and separate works in themselves, then this License, and its
+terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same
+sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part
+regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you;
+rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the
+Program.
+
+In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the
+Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you also do one of the following:
+
+a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms
+of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+
+b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than
+your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source
+code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange;
+or,
+
+c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This
+alternative is allowed only for noncommercial distribution and only if you received the program in object code or
+executable form with such an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for making modifications to it. For an executable work,
+complete source code means all the source code for all modules it contains, plus any associated interface definition
+files, plus the scripts used to control compilation and installation of the executable. However, as a special exception,
+the source code distributed need not include anything that is normally distributed (in either source or binary form)
+with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless
+that component itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy from a designated place, then offering
+equivalent access to copy the source code from the same place counts as distribution of the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your
+rights under this License. However, parties who have received copies, or rights, from you under this License will not
+have their licenses terminated so long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it. However, nothing else grants you
+permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do
+not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you
+indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or
+modifying the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a
+license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You
+may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not
+responsible for enforcing compliance by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to
+patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the
+conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as
+to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence
+you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution
+of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy
+both it and this License would be to refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the
+section is intended to apply and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest
+validity of any such claims; this section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices. Many people have made generous contributions to
+the wide range of software distributed through that system in reliance on consistent application of that system; it is
+up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee
+cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted
+interfaces, the original copyright holder who places the Program under this License may add an explicit geographical
+distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time.
+Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or
+concerns.
+
+Each version is given a distinguishing version number. If the Program specifies a version number of this License which
+applies to it and "any later version", you have the option of following the terms and conditions either of that version
+or of any later version published by the Free Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are
+different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two
+goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of
+software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM
+"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY
+WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
+SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT
+LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
+THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+
diff --git a/recipes-devtools/switch/files/switch_753x.c b/recipes-devtools/switch/files/src/switch_753x.c
similarity index 91%
rename from recipes-devtools/switch/files/switch_753x.c
rename to recipes-devtools/switch/files/src/switch_753x.c
index 54d1fe6..9c7c921 100644
--- a/recipes-devtools/switch/files/switch_753x.c
+++ b/recipes-devtools/switch/files/src/switch_753x.c
@@ -113,8 +113,10 @@
 
 	/* 8. vlan table operations */
 	printf("8) mt753x switch sip table operations====================================================================================================================>>>>\n");
-	printf(" 8.1) %s vlan dump						- dump switch vlan table\n", cmd);
-	printf(" 8.2) %s vlan set [vlan idx] [vid] [portmap]			- set vlan id and associated member at switch vlan table\n", cmd);
+	printf(" 8.1) %s vlan dump (egtag)					- dump switch vlan table (with per port eg_tag setting)\n", cmd);
+	printf(" 8.2) %s vlan set [fid:0~7] [vid] [portmap]			- set vlan id and associated member at switch vlan table\n", cmd);
+	printf("			([stag:0~4095] [eg_con:0|1] [egtagPortMap 0:untagged 2:tagged]) \n");
+	printf("			Full Example: %s vlan set 0 3 10000100 0 0 20000200\n", cmd);
 	printf(" 8.3) %s vlan vid [vlan idx] [active:0|1] [vid] [portMap] 	- set switch vlan vid elements  \n", cmd);
 	printf("			[egtagPortMap] [ivl_en] [fid] [stag]							 \n");
 	printf(" 8.4) %s vlan pvid [port] [pvid]				- set switch vlan pvid  \n", cmd);
@@ -192,13 +194,20 @@
 	printf(" 15.3) %s pfc tx_counter [port]					- get port n pfc 8 up rx counter \n", cmd);
 	printf("																			\n");
 
+	/*15. pfc(priority flow control) operations*/
+	printf("16) mt753x EEE(802.3az) operations==============================================================================================================>>>>\n");
+	printf(" 16.1) %s eee enable [enable 0|1] ([portMap])			- enable or disable EEE (by portMap)\n", cmd);
+	printf(" 16.2) %s eee dump ([port])					- dump EEE capability (by port)\n", cmd);
+	printf("																			\n");
+
 	exit_free();
 	exit(0);
 }
 
 static void parse_reg_cmd(int argc, char *argv[], int len)
 {
-	int off, val = -1;
+	unsigned int val;
+	unsigned int off;
 	int i, j;
 
 	if (!strncmp(argv[len - 3], "reg", 4)) {
@@ -232,6 +241,9 @@
 static int get_chip_name()
 {
 	int temp;
+	FILE *fp = NULL;
+	char buff[255];
+
 	/*judge 7530*/
 	reg_read((0x7ffc), &temp);
 	temp = temp >> 16;
@@ -242,14 +254,29 @@
 	temp = temp >> 16;
 	if (temp == 0x7531)
 		return temp;
+
+	/*judge jaguar embedded switch*/
+	fp = fopen("/proc/device-tree/compatible", "r");
+	if (fp != NULL) {
+		temp = -1;
+		if (fgets(buff, 255, (FILE *)fp) && strstr(buff, "mt7988"))
+			temp = 0x7988;
+
+		fclose(fp);
+		return temp;
+	}
+
 	return -1;
 }
 
 static int phy_operate(int argc, char *argv[])
 {
+	unsigned int port_num;
+	unsigned int dev_num;
+	unsigned int value, cl_value;
+	unsigned int reg;
+	int ret = 0, cl_ret = 0;
 	char op;
-	int ret = 0;
-	int port_num, dev_num, reg, value=-1;
 
 	if (strncmp(argv[2], "cl22", 4) && strncmp(argv[2], "cl45", 4))
 		usage(argv[0]);
@@ -262,7 +289,7 @@
 			if (argc == 6) {
 				port_num = strtoul(argv[argc-2], NULL, 0);
 				ret = mii_mgr_read(port_num, reg, &value);
-				if (value == -1)
+				if (ret < 0)
 					printf(" Phy read reg fail\n");
 				else
 					printf(" Phy read reg=0x%x, value=0x%x\n", reg, value);
@@ -270,7 +297,7 @@
 				dev_num = strtoul(argv[argc-2], NULL, 0);
 				port_num = strtoul(argv[argc-3], NULL, 0);
 				ret = mii_mgr_c45_read(port_num, dev_num, reg, &value);
-				if (value == -1)
+				if (ret < 0)
 					printf(" Phy read reg fail\n");
 				else
 					printf(" Phy read reg=0x%x, value=0x%x\n", reg, value);
@@ -283,11 +310,21 @@
 			if (argc == 7) {
 				port_num = strtoul(argv[argc-3], NULL, 0);
 				ret = mii_mgr_write(port_num, reg, value);
+				cl_ret = mii_mgr_read(port_num, reg, &cl_value);
+				if (cl_ret < 0)
+					printf(" Phy read reg fail\n");
+				else
+					printf(" Phy read reg=0x%x, value=0x%x\n", reg, cl_value);
 			}
 			else if (argc == 8) {
 				dev_num = strtoul(argv[argc-3], NULL, 0);
 				port_num = strtoul(argv[argc-4], NULL, 0);
 				ret = mii_mgr_c45_write(port_num, dev_num, reg, value);
+				cl_ret = mii_mgr_c45_read(port_num, dev_num, reg, &cl_value);
+				if (cl_ret < 0)
+					printf(" Phy read reg fail\n");
+				else
+					printf(" Phy read reg=0x%x, value=0x%x\n", reg, cl_value);
 			}
 			else
 				usage(argv[0]);
@@ -302,7 +339,6 @@
 
 int main(int argc, char *argv[])
 {
-	int i, j;
 	int err;
 
 	attres = (struct mt753x_attr *)malloc(sizeof(struct mt753x_attr));
@@ -311,16 +347,28 @@
 	attres->phy_dev = -1;
 	nl_init_flag = true;
 
-	switch_ioctl_init();
-	err = mt753x_netlink_init();
-	if (err < 0)
-		nl_init_flag = false;
+	/* dsa netlink family might not be enabled. Try gsw netlink family. */
+	err = mt753x_netlink_init(MT753X_DSA_GENL_NAME);
+	if (!err)
+		chip_name = get_chip_name();
 
-	chip_name = get_chip_name();
-	if (chip_name < 0) {
-		printf("no chip unsupport or chip id is invalid!\n");
-		exit_free();
-		exit(0);
+	if (err < 0) {
+		err = mt753x_netlink_init(MT753X_GENL_NAME);
+		if (!err)
+			chip_name = get_chip_name();
+	}
+	
+	if (err < 0) {
+		err = switch_ioctl_init();
+		if (!err) {
+			nl_init_flag = false;
+			chip_name = get_chip_name();
+			if (chip_name < 0) {
+				printf("no chip unsupport or chip id is invalid!\n");
+				exit_free();
+				exit(0);
+			}
+		}
 	}
 
 	if (argc < 2)
@@ -536,7 +584,7 @@
 		if (argc < 3)
 			usage(argv[0]);
 		if (!strncmp(argv[2], "dump", 5))
-			vlan_dump();
+			vlan_dump(argc, argv);
 		else if (!strncmp(argv[2], "set", 4))
 			vlan_set(argc, argv);
 		else if (!strncmp(argv[2], "clear", 6))
@@ -642,6 +690,16 @@
 			usage(argv[0]);
 		else
 			phy_crossover(argc, argv);
+	} else if (!strncmp(argv[1], "eee", 4)) {
+		if (argc < 3)
+			usage(argv[0]);
+		if (!strncmp(argv[2], "enable", 7) ||
+			 !strncmp(argv[2], "disable", 8))
+			eee_enable(argc, argv);
+		else if (!strncmp(argv[2], "dump", 5))
+			eee_dump(argc, argv);
+		else
+			usage(argv[0]);
 	} else
 		usage(argv[0]);
 
diff --git a/recipes-devtools/switch/files/switch_extend.h b/recipes-devtools/switch/files/src/switch_extend.h
similarity index 99%
rename from recipes-devtools/switch/files/switch_extend.h
rename to recipes-devtools/switch/files/src/switch_extend.h
index 8522424..c352767 100644
--- a/recipes-devtools/switch/files/switch_extend.h
+++ b/recipes-devtools/switch/files/src/switch_extend.h
@@ -337,5 +337,6 @@
 						 "         2: Learning\n" \
 						 "         3: Forwarding\n"
 #define HELP_COLLISION_POOL_EN	"collision-pool enable [enable 0|1] \n"
+#define HELP_EEE_EN		"eee [enable|disable] ([port|portMap]) \n"
 
 //#endif //SQA_VERIFY
diff --git a/recipes-devtools/switch/files/switch_fun.c b/recipes-devtools/switch/files/src/switch_fun.c
similarity index 85%
rename from recipes-devtools/switch/files/switch_fun.c
rename to recipes-devtools/switch/files/src/switch_fun.c
index b37b850..ce9d2bb 100644
--- a/recipes-devtools/switch/files/switch_fun.c
+++ b/recipes-devtools/switch/files/src/switch_fun.c
@@ -28,10 +28,8 @@
 		return -1;
 
 	c = strchr(src, separator);
-	if (c == NULL) {
-		strcpy(dest, src);
+	if (c == NULL)
 		return -1;
-	}
 
 	len = c - src;
 	strncpy(dest, src, len);
@@ -61,7 +59,7 @@
 /*convert IP address from number to string */
 static void ip_to_str(char *str, unsigned int ip)
 {
-	unsigned char *ptr = (char *)&ip;
+	unsigned char *ptr = (unsigned char *)&ip;
 	unsigned char c[4];
 
 	c[0] = *(ptr);
@@ -72,7 +70,7 @@
 	sprintf(str, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]);
 }
 
-int reg_read(int offset, int *value)
+int reg_read(unsigned int offset, unsigned int *value)
 {
 	int ret = -1;
 
@@ -84,14 +82,14 @@
 	}
 	if (ret < 0) {
 		printf("Read fail\n");
-		exit_free();
-		exit(0);
+		*value = 0;
+		return ret;
 	}
 
 	return 0;
 }
 
-int reg_write(int offset, int value)
+int reg_write(unsigned int offset, unsigned int value)
 {
 	int ret = -1;
 
@@ -109,11 +107,11 @@
 	return 0;
 }
 
-int mii_mgr_read(unsigned int port_num, unsigned int reg, int *value)
+int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value)
 {
-	int ret = -1;
+	int ret;
 
-	if (port_num > 31 || port_num < 0) {
+	if (port_num > 31) {
 		printf("Invalid Port or PHY addr \n");
 		return -1;
 	}
@@ -124,7 +122,7 @@
 		ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
 
 	if (ret < 0) {
-		printf("Phy read fail\n");
+		printf("Phy cl22 read fail\n");
 		exit_free();
 		exit(0);
 	}
@@ -134,9 +132,9 @@
 
 int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value)
 {
-	int ret = -1;
+	int ret;
 
-	if (port_num > 31 || port_num < 0) {
+	if (port_num > 31) {
 		printf("Invalid Port or PHY addr \n");
 		return -1;
 	}
@@ -147,7 +145,7 @@
 		ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
 
 	if (ret < 0) {
-		printf("Phy write fail\n");
+		printf("Phy cl22 write fail\n");
 		exit_free();
 		exit(0);
 	}
@@ -155,11 +153,11 @@
 	return 0;
 }
 
-int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg, int *value)
+int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int *value)
 {
-	int ret = -1;
+	int ret;
 
-	if (port_num > 31 || port_num < 0) {
+	if (port_num > 31) {
 		printf("Invalid Port or PHY addr \n");
 		return -1;
 	}
@@ -170,7 +168,7 @@
 		ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
 
 	if (ret < 0) {
-		printf("Phy read fail\n");
+		printf("Phy cl45 read fail\n");
 		exit_free();
 		exit(0);
 	}
@@ -180,9 +178,9 @@
 
 int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int value)
 {
-	int ret = -1;
+	int ret;
 
-	if (port_num > 31 || port_num < 0) {
+	if (port_num > 31) {
 		printf("Invalid Port or PHY addr \n");
 		return -1;
 	}
@@ -193,17 +191,18 @@
 		ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
 
 	if (ret < 0) {
-		printf("Phy write fail\n");
+		printf("Phy cl45 write fail\n");
 		exit_free();
 		exit(0);
 	}
+
 	return 0;
 }
 
 
 int phy_dump(int phy_addr)
 {
-	int ret = -1;
+	int ret;
 
 	if (nl_init_flag == true)
 		ret = phy_dump_netlink(attres, phy_addr);
@@ -221,12 +220,11 @@
 
 void phy_crossover(int argc, char *argv[])
 {
-	int port_num = strtoul(argv[2], NULL, 10);
-	int value;
-	int ret = -1;
+	unsigned int port_num = strtoul(argv[2], NULL, 10);
+	unsigned int value;
+	int ret;
 
-	if ((port_num < 0) || (port_num > 4))
-	{
+	if (port_num > 4) {
 		printf("invaild value, port_name:0~4\n");
 		return;
 	}
@@ -272,8 +270,11 @@
 
 int rw_phy_token_ring(int argc, char *argv[])
 {
-	int port_num, ch_addr, node_addr, data_addr,val_l=0;
-	int Tr_reg_control, val_h = 0;
+	int ch_addr, node_addr, data_addr;
+	unsigned int tr_reg_control;
+	unsigned int val_l = 0;
+	unsigned int val_h = 0;
+	unsigned int port_num;
 
 	if (argc < 4)
 		return -1;
@@ -283,7 +284,7 @@
 			return -1;
 		mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
 		port_num = strtoul(argv[3], NULL, 0);
-		if (port_num < 0 || port_num > MAX_PORT) {
+		if (port_num > MAX_PORT) {
 			printf("Illegal port index and port:0~6\n");
 			return -1;
 		}
@@ -291,17 +292,17 @@
 		node_addr = strtoul(argv[5], NULL, 0);
 		data_addr = strtoul(argv[6], NULL, 0);
 		printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n", port_num, ch_addr, node_addr, data_addr);
-		Tr_reg_control = (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1);
-		mii_mgr_write(port_num, 16, Tr_reg_control); // r16 = Tr_reg_control
+		tr_reg_control = (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1);
+		mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
 		mii_mgr_read(port_num, 17, &val_l);
 		mii_mgr_read(port_num, 18, &val_h);
-		printf("switch trreg read Tr_reg_control=%x, value_H=%x, value_L=%x\n", Tr_reg_control, val_h, val_l);
+		printf("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n", tr_reg_control, val_h, val_l);
 	} else if (argv[2][0] == 'w') {
 		if (argc != 9)
 			return -1;
 		mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
 		port_num = strtoul(argv[3], NULL, 0);
-		if (port_num < 0 || port_num > MAX_PORT) {
+		if (port_num > MAX_PORT) {
 			printf("\n**Illegal port index and port:0~6\n");
 			return -1;
 		}
@@ -311,11 +312,11 @@
 		val_h = strtoul(argv[7], NULL, 0);
 		val_l = strtoul(argv[8], NULL, 0);
 		printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n", port_num, ch_addr, node_addr, data_addr);
-		Tr_reg_control = (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1);
+		tr_reg_control = (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1);
 		mii_mgr_write(port_num, 17, val_l);
 		mii_mgr_write(port_num, 18, val_h);
-		mii_mgr_write(port_num, 16, Tr_reg_control); // r16 = Tr_reg_control
-		printf("switch trreg Write Tr_reg_control=%x, value_H=%x, value_L=%x\n", Tr_reg_control, val_h, val_l);
+		mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
+		printf("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n", tr_reg_control, val_h, val_l);
 	} else
 		return -1;
 	return 0;
@@ -326,7 +327,7 @@
 	unsigned int value, reg;
 	unsigned int max_index;
 
-	if (chip_name == 0x7531)
+	if (chip_name == 0x7531 || chip_name == 0x7988)
 		max_index = 256;
 	else
 		max_index = 64;
@@ -379,7 +380,7 @@
 	unsigned int value, reg;
 	unsigned int max_index;
 
-	if (chip_name == 0x7531)
+	if (chip_name == 0x7531 || chip_name == 0x7988)
 		max_index = 128;
 	else
 		max_index = 32;
@@ -429,7 +430,7 @@
 	unsigned int value, reg;
 	unsigned int max_index;
 
-	if (chip_name == 0x7531)
+	if (chip_name == 0x7531 || chip_name == 0x7988)
 		max_index = 128;
 	else
 		max_index = 32;
@@ -563,7 +564,7 @@
 int acl_parameters_pre_del(int len1, int len2, int argc, char *argv[], int *port)
 {
 	int i;
-	int ret = 0;
+
 	*port = 0;
 	if (argc < len1) {
 		printf("insufficient arguments!\n");
@@ -590,6 +591,7 @@
 		}
 		*port += (argv[5][i] - '0') * (1 << i);
 	}
+	return 0;
 }
 
 void acl_compare_pattern(int ports, int comparion, int base, int word, unsigned char table_index)
@@ -608,7 +610,7 @@
 
 void acl_mac_add(int argc, char *argv[])
 {
-	unsigned int i, value, mac;
+	unsigned int value;
 	int ports;
 	char tmpstr[5];
 	int ret;
@@ -645,13 +647,11 @@
 
 void acl_dip_meter(int argc, char *argv[])
 {
-	unsigned int i, value, ip_value, meter;
-	unsigned int idx, vid;
-	int stag = 0;
+	unsigned int value, ip_value, meter;
 	int ports;
-	char tmpstr[16];
 	int ret;
 
+	ip_value = 0;
 	ret = acl_parameters_pre_del(7, -1, argc, argv, &ports);
 	if (ret < 0)
 		return;
@@ -670,12 +670,13 @@
 
 	//set action
 	meter = strtoul(argv[6], NULL, 0);
-	if (meter < 0 || ((chip_name == 0x7530) && (meter > 1000000)) ||
-		((chip_name == 0x7531) && (meter > 2500000))) {
-		printf("\n**Illegal meter input, and 7530: 0~1000000Kpbs, 7531: 0~2500000Kpbs**\n");
+	if (((chip_name == 0x7530) && (meter > 1000000)) ||
+		((chip_name == 0x7531) && (meter > 2500000)) ||
+		((chip_name == 0x7988) && (meter > 4000000))) {
+		printf("\n**Illegal meter input, and 7530: 0~1000000Kpbs, 7531: 0~2500000Kpbs, 7988: 0~4000000Kpbs**\n");
 		return;
 	}
-	if (((chip_name == 0x7531) && (meter > 1000000))) {
+	if (((chip_name == 0x7531 || chip_name == 0x7988) && (meter > 1000000))) {
 		reg_read(0xc,&value);
 		value |= 0x1 << 30;
 		reg_write(0xC,value);
@@ -695,14 +696,12 @@
 
 void acl_dip_trtcm(int argc, char *argv[])
 {
-	unsigned int i, value, value2, ip_value;
-	unsigned int idx, vid;
+	unsigned int value, value2, ip_value;
 	unsigned int CIR, CBS, PIR, PBS;
-	int stag = 0;
 	int ports;
-	char tmpstr[16];
 	int ret;
 
+	ip_value = 0;
 	ret = acl_parameters_pre_del(10, -1, argc, argv, &ports);
 	if (ret < 0)
 		return;
@@ -722,8 +721,7 @@
 	PIR = strtoul(argv[8], NULL, 0);
 	PBS = strtoul(argv[9], NULL, 0);
 
-	if (CIR < 0 || CBS < 0 || PIR < 0 || PBS < 0 ||
-	CIR > 65535*64 || CBS > 65535 || PIR > 65535*64  || PBS > 65535) {
+	if (CIR > 65535*64 || CBS > 65535 || PIR > 65535*64  || PBS > 65535) {
 		printf("\n**Illegal input parameters**\n");
 		return;
 	}
@@ -751,11 +749,8 @@
 
 void acl_ethertype(int argc, char *argv[])
 {
-	unsigned int i, value, ethertype;
-	unsigned int idx, vid;
-	int stag = 0;
+	unsigned int value, ethertype;
 	int ports;
-	char tmpstr[16];
 	int ret;
 
 	ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
@@ -780,14 +775,12 @@
 
 void acl_dip_modify(int argc, char *argv[])
 {
-	unsigned int i, value, ip_value;
-	unsigned int idx, vid;
-	int stag = 0;
+	unsigned int value, ip_value;
 	int ports;
 	int priority;
-	char tmpstr[16];
 	int ret;
 
+	ip_value = 0;
 	priority = strtoul(argv[6], NULL, 16);
 	if (priority < 0 || priority > 7) {
 		printf("\n**Illegal priority value!**\n");
@@ -820,13 +813,11 @@
 
 void acl_dip_pppoe(int argc, char *argv[])
 {
-	unsigned int i, value, ip_value;
-	unsigned int idx, vid;
-	int stag = 0;
+	unsigned int value, ip_value;
 	int ports;
-	char tmpstr[16];
 	int ret;
 
+	ip_value = 0;
 	ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
 	if (ret < 0)
 		return;
@@ -855,13 +846,11 @@
 
 void acl_dip_add(int argc, char *argv[])
 {
-	unsigned int i, value, ip_value;
-	unsigned int idx, vid;
+	unsigned int value, ip_value;
 	int ports;
-	int stag = 0;
-	char tmpstr[16];
 	int ret;
 
+	ip_value = 0;
 	ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
 	if (ret < 0)
 		return;
@@ -889,11 +878,8 @@
 
 void acl_l4_add(int argc, char *argv[])
 {
-	unsigned int i, value;
-	unsigned int idx, vid;
+	unsigned int value;
 	int ports;
-	int stag = 0;
-	char tmpstr[16];
 	int ret;
 
 	ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
@@ -914,11 +900,8 @@
 
 void acl_sp_add(int argc, char *argv[])
 {
-	unsigned int i, value;
-	unsigned int idx, vid;
+	unsigned int value;
 	int ports;
-	int stag = 0;
-	char tmpstr[16];
 	int ret;
 
 	ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
@@ -964,19 +947,12 @@
 
 static void dip_dump_internal(int type)
 {
-	int i, j, value, mac, mac2, value2;
-	int vid[16];
+	unsigned int i, j, value, mac, mac2, value2;
 	char tmpstr[16];
 	int table_size = 0;
 	int hit_value1 = 0;
 	int hit_value2 = 0;
 
-	for (i = 0; i < 8; i++) {
-		reg_read(REG_VLAN_ID_BASE + 4 * i, &value);
-		vid[2 * i] = value & 0xfff;
-		vid[2 * i + 1] = (value & 0xfff000) >> 12;
-	}
-
 	if(type == GENERAL_TABLE) {
 		table_size = 0x800;
 		reg_write(REG_ATC_ADDR, 0x8104); //dip search command
@@ -1052,15 +1028,16 @@
 
 void dip_add(int argc, char *argv[])
 {
-	unsigned int i, j, value;
-	char tmpstr[9];
+	unsigned int value = 0;
+	unsigned int i, j;
+
+	value = 0;
 
 	str_to_ip(&value, argv[3]);
 
 	reg_write(REG_ATA1_ADDR, value);
 	printf("REG_ATA1_ADDR is 0x%x\n\r", value);
 
-	value = 0;
 #if 0
 	reg_write(REG_ATA2_ADDR, value);
 	printf("REG_ATA2_ADDR is 0x%x\n\r", value);
@@ -1105,9 +1082,9 @@
 
 void dip_del(int argc, char *argv[])
 {
-	unsigned int i, j, value;
-	char tmpstr[9];
+	unsigned int i, value;
 
+	value = 0;
 	str_to_ip(&value, argv[3]);
 
 	reg_write(REG_ATA1_ADDR, value);
@@ -1137,7 +1114,8 @@
 void dip_clear(void)
 {
 
-	int value;
+	unsigned int value;
+
 	reg_write(REG_ATC_ADDR, 0x8102); //clear all dip
 	usleep(5000);
 	reg_read(REG_ATC_ADDR, &value);
@@ -1146,19 +1124,11 @@
 
 static void sip_dump_internal(int type)
 {
-	int i, j, value, mac, mac2, value2;
-	int vid[16];
-	char tmpstr[16];
-
+	unsigned int i, j, value, mac, mac2, value2;
 	int table_size = 0;
 	int hit_value1 = 0;
 	int hit_value2 = 0;
-
-	for (i = 0; i < 8; i++) {
-		reg_read(REG_VLAN_ID_BASE + 4 * i, &value);
-		vid[2 * i] = value & 0xfff;
-		vid[2 * i + 1] = (value & 0xfff000) >> 12;
-	}
+	char tmpstr[16];
 
 	if (type == GENERAL_TABLE) {
 		table_size = 0x800;
@@ -1237,8 +1207,8 @@
 void sip_add(int argc, char *argv[])
 {
 	unsigned int i, j, value;
-	char tmpstr[9];
 
+	value = 0;
 	str_to_ip(&value, argv[3]); //SIP
 
 	reg_write(REG_ATA2_ADDR, value);
@@ -1290,9 +1260,9 @@
 
 void sip_del(int argc, char *argv[])
 {
-	unsigned int i, j, value;
-	char tmpstr[9];
+	unsigned int i, value;
 
+	value = 0;
 	str_to_ip(&value, argv[3]);
 
 	reg_write(REG_ATA2_ADDR, value); //SIP
@@ -1321,7 +1291,7 @@
 
 void sip_clear(void)
 {
-	int value;
+	unsigned int value;
 
 	reg_write(REG_ATC_ADDR, 0x8202); //clear all sip
 	usleep(5000);
@@ -1331,18 +1301,12 @@
 
 static void table_dump_internal(int type)
 {
-	int i, j, value, mac, mac2, value2;
-	int vid[16];
+	unsigned int i, j, value, mac, mac2, value2;
 	int table_size = 0;
 	int table_end = 0;
 	int hit_value1 = 0;
 	int hit_value2 = 0;
 
-	for (i = 0; i < 8; i++) {
-		reg_read(REG_VLAN_ID_BASE + 4 * i, &value);
-		vid[2 * i] = value & 0xfff;
-		vid[2 * i + 1] = (value & 0xfff000) >> 12;
-	}
 	if (type == GENERAL_TABLE){
 		table_size = 0x800;
 		table_end = 0x7FF;
@@ -1370,23 +1334,6 @@
 				printf("%03x:   ", (value >> 16) & 0xfff);
 				reg_read(REG_ATRD_ADDR, &value2);
 				j = (value2 >> 4) & 0xff; //r_port_map
-				if(j & 0x01)
-					printf("0");
-				else if (j & 0x02)
-					printf("1"); 
-				else if (j & 0x04)
-					printf("2"); 
-				else if (j & 0x08)
-					printf("3");
-				else if (j & 0x10)
-					printf("4");
-				else if (j & 0x20)
-					printf("5");
-				else if (j & 0x40)
-					printf("6");
-				else if (j & 0x80)
-					printf("7");
-				/*	 	 	 	
 				printf("%c", (j & 0x01) ? '1' : '-');
 				printf("%c", (j & 0x02) ? '1' : '-');
 				printf("%c", (j & 0x04) ? '1' : '-');
@@ -1395,8 +1342,7 @@
 				printf("%c", (j & 0x20) ? '1' : '-');
 				printf("%c", (j & 0x40) ? '1' : '-');
 				printf("%c", (j & 0x80) ? '1' : '-');
-				*/
-				printf("       ");
+
 				reg_read(REG_TSRA2_ADDR, &mac2);
 
 				printf("   %2d", (mac2 >> 12) & 0x7); //FID
@@ -1708,7 +1654,7 @@
 
 void table_del_fid(int argc, char *argv[])
 {
-	int i, j, value;
+	unsigned int i, j, value;
 	char tmpstr[9];
 
 	if (!argv[3] || strlen(argv[3]) != 12) {
@@ -1726,7 +1672,7 @@
 
 	if (argc > 5) {
 		j = strtoul(argv[5], NULL, 0);
-		if (j < 0 || 7 < j) {
+		if (j > 7) {
 			printf("wrong fid range, should be within 0~7\n");
 			return;
 		}
@@ -1756,7 +1702,7 @@
 
 void table_del_vid(int argc, char *argv[])
 {
-	int i, j, value;
+	unsigned int i, j, value;
 	char tmpstr[9];
 
 	if (!argv[3] || strlen(argv[3]) != 12) {
@@ -1774,7 +1720,7 @@
 	value = (value << 16);
 
 	j = strtoul(argv[5], NULL, 0);
-	if (j < 0 || 4095 < j) {
+	if (j > 4095) {
 		printf("wrong fid range, should be within 0~4095\n");
 		return;
 	}
@@ -1803,7 +1749,7 @@
 
 void table_clear(void)
 {
-	int i, value, mac;
+	unsigned int value;
 	reg_write(REG_ATC_ADDR, 0x8002);
 	usleep(5000);
 	reg_read(REG_ATC_ADDR, &value);
@@ -1867,14 +1813,22 @@
 	reg_write(offset, value);
 }
 
-void vlan_dump(void)
+void vlan_dump(int argc, char *argv[])
 {
-	int i, j, vid, value, value2;
+	unsigned int i, j, value, value2;
+	int eg_tag = 0;
 
-	printf("  vid  fid  portmap    s-tag\n");
+	if (argc == 4) {
+		if (!strncmp(argv[3], "egtag", 6))
+			eg_tag = 1;
+	}
+
+	if (eg_tag)
+		printf("  vid  fid  portmap    s-tag\teg_tag(0:untagged 2:tagged)\n");
+	else
+		printf("  vid  fid  portmap    s-tag\n");
+
 	for (i = 1; i < 4095; i++) {
-		//reg_read(REG_VLAN_ID_BASE + 4*i, &vid);
-		//value = (0x80000000 + 2*i);  //r_vid_cmd
 		value = (0x80000000 + i); //r_vid_cmd
 		reg_write(REG_VTCR_ADDR, value);
 
@@ -1904,7 +1858,28 @@
 			printf("%c", (value & 0x00200000) ? '1' : '-');
 			printf("%c", (value & 0x00400000) ? '1' : '-');
 			printf("%c", (value & 0x00800000) ? '1' : '-');
-			printf("    %4d\n", ((value & 0xfff0) >> 4));
+			printf("    %4d", ((value & 0xfff0) >> 4));
+			if (eg_tag) {
+				printf("\t");
+				if ((value & (0x3 << 28)) == (0x3 << 28)) {
+					/* VTAG_EN=1 and EG_CON=1 */
+					printf("CONSISTENT");
+				} else if (value & (0x1 << 28)) {
+					/* VTAG_EN=1 */
+					printf("%d", (value2 & 0x0003) >> 0);
+					printf("%d", (value2 & 0x000c) >> 2);
+					printf("%d", (value2 & 0x0030) >> 4);
+					printf("%d", (value2 & 0x00c0) >> 6);
+					printf("%d", (value2 & 0x0300) >> 8);
+					printf("%d", (value2 & 0x0c00) >> 10);
+					printf("%d", (value2 & 0x3000) >> 12);
+					printf("%d", (value2 & 0xc000) >> 14);
+				} else {
+					/* VTAG_EN=0 */
+					printf("DISABLED");
+				}
+			}
+			printf("\n");
 		} else {
 			/*print 16 vid for reference information*/
 			if (i <= 16) {
@@ -1940,8 +1915,8 @@
 
 void vlan_clear(int argc, char *argv[])
 {
-	unsigned int i, j, value, value2;
-	int idx, vid;
+	unsigned int value;
+	int vid;
 	unsigned long duration_us = 0;
 	struct timespec start, end;
 
@@ -1967,86 +1942,104 @@
 
 void vlan_set(int argc, char *argv[])
 {
-	unsigned int i, j, value, value2;
-	int idx, vid;
+	unsigned int vlan_mem = 0;
+	unsigned int value = 0;
+	unsigned int value2 = 0;
+	int i, vid, fid;
 	int stag = 0;
-	unsigned char eg_con = 0;
-	unsigned char eg_tag = 0;
+	unsigned long eg_con = 0;
+	unsigned int eg_tag = 0;
 
 	if (argc < 5) {
 		printf("insufficient arguments!\n");
 		return;
 	}
+
+	fid = strtoul(argv[3], NULL, 0);
+	if (fid < 0 || fid > 7) {
+		printf("wrong filtering db id range, should be within 0~7\n");
+		return;
+	}
+	value |= (fid << 1);
+
 	vid = strtoul(argv[4], NULL, 0);
 	if (vid < 0 || 0xfff < vid) {
 		printf("wrong vlan id range, should be within 0~4095\n");
 		return;
 	}
+
 	if (strlen(argv[5]) != 8) {
 		printf("portmap format error, should be of length 7\n");
 		return;
 	}
-	j = 0;
+
+	vlan_mem = 0;
 	for (i = 0; i < 8; i++) {
 		if (argv[5][i] != '0' && argv[5][i] != '1') {
 			printf("portmap format error, should be of combination of 0 or 1\n");
 			return;
 		}
-		j += (argv[5][i] - '0') * (1 << i);
-	}
-	//set vlan identifier
-	/*
-	reg_read(REG_VLAN_ID_BASE + 4*(idx/2), &value);
-	if (idx % 2 == 0) {
-	value &= 0xfff000;
-	value |= vid;
-	}
-	else {
-	value &= 0xfff;
-	value |= (vid << 12);
+		vlan_mem += (argv[5][i] - '0') * (1 << i);
 	}
-	reg_write(REG_VLAN_ID_BASE + 4*(idx/2), value);
-	*/
 
-	/*port stag*/
+	/* VLAN stag */
 	if (argc > 6) {
 		stag = strtoul(argv[6], NULL, 16);
-		printf("STAG index is 0x%x\n", stag);
+		if (stag < 0 || 0xfff < stag) {
+			printf("wrong stag id range, should be within 0~4095\n");
+			return;
+		}
+		//printf("STAG is 0x%x\n", stag);
 	}
 
-	//set vlan member
-	value = (j << 16);
-	//value |= (idx << 1);//fid
+	/* set vlan member */
+	value |= (vlan_mem << 16);
 	value |= (1 << 30);		//IVL=1
 	value |= ((stag & 0xfff) << 4); //stag
 	value |= 1;			//valid
 
 	if (argc > 7) {
+		eg_con = strtoul(argv[7], NULL, 2);
+		eg_con = !!eg_con;
 		value |= (eg_con << 29); //eg_con
 		value |= (1 << 28);      //eg tag control enable
 	}
 
+	if (argc > 8 && !eg_con) {
+		if (strlen(argv[8]) != 8) {
+			printf("egtag portmap format error, should be of length 7\n");
+			return;
+		}
+
-	if (argc > 8) {
+		for (i = 0; i < 8; i++) {
+			if (argv[8][i] < '0' || argv[8][i] > '3') {
+				printf("egtag portmap format error, should be of combination of 0 or 3\n");
+				return;
+			}
+			//eg_tag += (argv[8][i] - '0') * (1 << i * 2);
+			eg_tag |= (argv[8][i] - '0') << (i * 2);
+		}
+
 		value |= (1 << 28);    //eg tag control enable
-		value2 = eg_tag;       //port 0
-		value2 |= eg_tag << 2; //port  1
-		value2 |= eg_tag << 4; //port 2
-		reg_write(REG_VAWD2_ADDR, value2);
+		value2 &= ~(0xffff);
+		value2 |= eg_tag;
 	}
 	reg_write(REG_VAWD1_ADDR, value);
+	reg_write(REG_VAWD2_ADDR, value2);
+	//printf("VAWD1=0x%08x VAWD2=0x%08x ", value, value2);
 
-	//value = (0x80001000 + idx);  //w_vid_cmd
 	value = (0x80001000 + vid); //w_vid_cmd
 	reg_write(REG_VTCR_ADDR, value);
+	//printf("VTCR=0x%08x\n", value);
 
-	for (j = 0; j < 300; j++) {
+	for (i = 0; i < 300; i++) {
 		usleep(1000);
 		reg_read(REG_VTCR_ADDR, &value);
 		if ((value & 0x80000000) == 0) //table busy
 			break;
 	}
 
-	if (j == 300)
+	if (i == 300)
 		printf("config vlan timeout.\n");
 }
 
@@ -2056,6 +2049,7 @@
 	unsigned int wan_num = 4;
 	unsigned int port, offset, value;
 	char cmd[80];
+	int ret;
 
 	if (argc > 3)
 		leaky_en = strtoul(argv[3], NULL, 10);
@@ -2166,8 +2160,11 @@
 	reg_write(0x90, 0x8000b003);
 
 	/*Force eth2 to receive all igmp packets*/
-	sprintf(cmd,"echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router",BR_DEVNAME,ETH_DEVNAME);
-	system(cmd);
+	snprintf(cmd, sizeof(cmd), "echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router", BR_DEVNAME, ETH_DEVNAME);
+	ret = system(cmd);
+	if (ret)
+		printf("Failed to set /sys/devices/virtual/net/%s/brif/%s/multicast_router\n",
+		       BR_DEVNAME, ETH_DEVNAME);
 }
 
 void igmp_disable(int argc, char *argv[])
@@ -2232,8 +2229,11 @@
 	printf("config igmpsnoop off.\n");
 }
 
-void switch_reset(int argc, char *argv[])
+int switch_reset(int argc, char *argv[])
 {
+	if (chip_name == 0x7988)
+		return -1;
+
 	unsigned int value = 0;
 	/*Software Register Reset  and Software System Reset */
 	reg_write(0x7000, 0x3);
@@ -2245,6 +2245,7 @@
 		printf("GPIO Mode (0x7c0c) select value =0x%x  \n", value);
 	}
 	printf("Switch Software Reset !!! \n");
+	return 0;
 }
 
 int phy_set_fc(int argc, char *argv[])
@@ -2256,8 +2257,7 @@
 	pause_capable = atoi(argv[4]);
 
 	/*Check the input parameters is right or not.*/
-	if (port < 0 || port > MAX_PORT-2 || pause_capable < 0
-		|| pause_capable > 1) {
+	if (port > MAX_PORT - 2 || pause_capable > 1) {
 		printf("Illegal parameter (port:0~4, full_duplex_pause_capable:0|1)\n");
 		return -1;
 	}
@@ -2284,8 +2284,7 @@
 	auto_negotiation_en = atoi(argv[4]);
 
 	/*Check the input parameters is right or not.*/
-	if (port < 0 || port > MAX_PORT-2 || auto_negotiation_en < 0
-		|| auto_negotiation_en > 1) {
+	if (port > MAX_PORT - 2 || auto_negotiation_en > 1) {
 		printf("Illegal parameter (port:0~4, auto_negotiation_en:0|1)\n");
 		return -1;
 	}
@@ -2302,7 +2301,7 @@
 int set_mac_pfc(int argc, char *argv[])
 {
 	unsigned int value;
-	unsigned char port, enable = 0;
+	int port, enable = 0;
 
 	port = atoi(argv[3]);
 	enable = atoi(argv[4]);
@@ -2311,7 +2310,7 @@
 		printf("Illegal parameter (port:0~6, enable|diable:0|1) \n");
 		return -1;
 	}
-	if (chip_name == 0x7531) {
+	if (chip_name == 0x7531 || chip_name == 0x7988) {
 		reg_read(REG_PFC_CTRL_ADDR, &value);
 		value &= ~(1 << port);
 		value |= (enable << port);
@@ -2351,7 +2350,8 @@
 
 int qos_sch_select(int argc, char *argv[])
 {
-	unsigned char type = 0, port, queue;
+	unsigned char port, queue;
+	unsigned char type = 0;
 	unsigned int value, reg;
 
 	if (argc < 7)
@@ -2361,10 +2361,11 @@
 	queue = atoi(argv[4]);
 	type = atoi(argv[6]);
 
-	if (port < 0 || port > 6 || queue < 0 || queue > 7) {
+	if (port > 6 || queue > 7) {
 		printf("\n Illegal input parameters\n");
 		return -1;
 	}
+
 	if ((type != 0 && type != 1 && type != 2)) {
 		printf(HELP_QOS_TYPE);
 		return -1;
@@ -2378,13 +2379,13 @@
 			/*min sharper-->round roubin, disable min sharper rate limit*/
 			reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
 			reg_read(reg, &value);
-			value &= (0x0);
+			value = 0x0;
 			reg_write(reg, value);
 		} else if (type == 1) {
 			/*min sharper-->sp, disable min sharper rate limit*/
 			reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
 			reg_read(reg, &value);
-			value &= (0x0);
+			value = 0x0;
 			value |= (1 << 31);
 			reg_write(reg, value);
 		} else {
@@ -2396,14 +2397,14 @@
 			/*max sharper-->sp, disable max sharper rate limit*/
 			reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
 			reg_read(reg, &value);
-			value &= (0x0);
+			value = 0x0;
 			value |= (1 << 31);
 			reg_write(reg, value);
 		} else if (type == 2) {
 			/*max sharper-->wfq, disable max sharper rate limit*/
 			reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
 			reg_read(reg, &value);
-			value &= (0x0);
+			value = 0x0;
 			reg_write(reg, value);
 		} else {
 			printf("max sharper only support: wfq or sp\n");
@@ -2418,7 +2419,7 @@
 	return 0;
 }
 
-void get_upw(int *value, unsigned char base)
+void get_upw(unsigned int *value, unsigned char base)
 {
 	*value &= (~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
 		     (0x7 << 16) | (0x7 << 20)));
@@ -2455,7 +2456,8 @@
 
 void qos_set_base(int argc, char *argv[])
 {
-	unsigned char base = 0, port;
+	unsigned char base = 0;
+	unsigned char port;
 	unsigned int value;
 
 	if (argc < 5)
@@ -2464,12 +2466,12 @@
 	port = atoi(argv[3]);
 	base = atoi(argv[4]);
 
-	if ((base < 0 || base > 6)) {
+	if (base > 6) {
 		printf(HELP_QOS_BASE);
 		return;
 	}
 
-	if ((port < 0 || port > 6)) {
+	if (port > 6) {
 		printf("Illegal port index:%d\n",port);
 		return;
 	}
@@ -2484,7 +2486,7 @@
 		reg_write(0x44, value);
 		printf("reg: 0x44, value: 0x%x\n", value);
 
-	} else if (chip_name == 0x7531) {
+	} else if (chip_name == 0x7531 || chip_name == 0x7988) {
 
 		reg_read(GSW_UPW(port), &value);
 		get_upw(&value, base);
@@ -2499,7 +2501,8 @@
 
 void qos_wfq_set_weight(int argc, char *argv[])
 {
-	unsigned char port, queue, weight[8], i;
+	int port, weight[8], i;
+	unsigned char queue;
 	unsigned int reg, value;
 
 	port = atoi(argv[3]);
@@ -2543,7 +2546,7 @@
 	port = atoi(argv[3]);
 	prio = atoi(argv[4]);
 
-	if ((port < 0 || port >= 7) || (prio < 0 || prio > 7)) {
+	if (port >= 7 || prio > 7) {
 		printf(HELP_QOS_PORT_PRIO);
 		return;
 	}
@@ -2563,7 +2566,7 @@
 	dscp = atoi(argv[3]);
 	prio = atoi(argv[4]);
 
-	if ((dscp < 0 || dscp > 63) || (prio < 0 || prio > 7)) {
+	if (dscp > 63 || prio > 7) {
 		printf(HELP_QOS_DSCP_PRIO);
 		return;
 	}
@@ -2590,7 +2593,7 @@
 	prio = atoi(argv[4]);
 	queue = atoi(argv[5]);
 
-	if ((prio < 0 || prio > 7) || (queue < 0 || queue > 7)) {
+	if (prio > 7 || queue > 7) {
 		printf(HELP_QOS_PRIO_QMAP);
 		return;
 	}
@@ -2607,7 +2610,7 @@
 		}
 		reg_write(reg, value);
 		printf("write reg: %x, value: %x\n", reg, value);
-	} else if (chip_name == 0x7531) {
+	} else if (chip_name == 0x7531 || chip_name == 0x7988) {
 		pem_n = prio / 2;
 		reg = GSW_PEM(pem_n) + 0x100 * port;
 		reg_read(reg, &value);
@@ -2633,7 +2636,7 @@
 {
 	unsigned int value = 0;
 	unsigned int value2 = 0;
-	int reg = 0;
+	unsigned int reg;
 	int i;
 
 	printf("index: %x, active: %x, vid: %x, portMap: %x, \
@@ -2683,10 +2686,9 @@
 	return 0;
 
 } /*end macMT753xVlanSetVid*/
-
+/*
 static int macMT753xVlanGetVtbl(unsigned short index)
 {
-	unsigned short vid = 0;
 	unsigned int reg, value, vawd1, vawd2;
 
 	reg = 0x90; // VTCR
@@ -2714,7 +2716,7 @@
 			(vawd1 & 0xff0000) >> 16, vawd2, (vawd1 & 0xfff0) >> 0x4, (vawd1 >> 30) & 0x1);
 	}
 	return 0;
-} /*end macMT753xVlanGetVtbl*/
+} */ /*end macMT753xVlanGetVtbl*/
 
 static int macMT753xVlanSetPvid(unsigned char port, unsigned short pvid)
 {
@@ -2740,20 +2742,19 @@
 	printf("SetPVID: port:%d pvid:%d\r\n", port, pvid);
 	return 0;
 }
-
+/*
 static int macMT753xVlanGetPvid(unsigned char port)
 {
 	unsigned int value;
 	unsigned int reg;
 
-	/*Parameters is error*/
 	if (port > 6)
 		return -1;
 	reg = 0x2014 + (port * 0x100);
 	reg_read(reg, &value);
 	return (value & 0xfff);
-}
-
+} */
+/*
 static int macMT753xVlanDisp(void)
 {
 	unsigned int i = 0;
@@ -2771,7 +2772,8 @@
 	for (i = 0; i < MAX_VID_VALUE; i++)
 		macMT753xVlanGetVtbl(i);
 
-} /*end macMT753xVlanDisp*/
+	return 0;
+}*/ /*end macMT753xVlanDisp*/
 
 void doVlanSetPvid(int argc, char *argv[])
 {
@@ -2872,7 +2874,7 @@
 	printf("port: %x, attr: %x\n", port, attr);
 
 	/*Check the input parameters is right or not.*/
-	if ((port < 0 || port > SWITCH_MAX_PORT) || (attr < 0 || attr > 3)) {
+	if (port > SWITCH_MAX_PORT || attr > 3) {
 		printf(HELP_VLAN_PORT_ATTR);
 		return;
 	}
@@ -2897,7 +2899,7 @@
 	printf("port: %x, mode: %x\n", port, mode);
 
 	/*Check the input parameters is right or not.*/
-	if ((port < 0 || port > SWITCH_MAX_PORT) || (mode < 0 || mode > 3)) {
+	if (port > SWITCH_MAX_PORT || mode > 3) {
 		printf(HELP_VLAN_PORT_MODE);
 		return;
 	}
@@ -3100,7 +3102,7 @@
 	reg_write(reg, value);
 }
 
-int ingress_rate_set(int on_off, int port, int bw)
+int ingress_rate_set(int on_off, unsigned int port, unsigned int bw)
 {
 	unsigned int reg, value;
 
@@ -3109,21 +3111,27 @@
 	/*token-bucket*/
 	if (on_off == 1) {
 		if (chip_name == 0x7530) {
-			if (bw < 0 || bw > 1000000) {
+			if (bw > 1000000) {
 				printf("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",bw);
 				return -1;
 			}
 			value = ((bw / 32) << 16) + (1 << 15) + (7 << 8) + (1 << 7) + 0x0f;
-		} else if (chip_name == 0x7531) {
-			if (bw < 0 || bw > 2500000) {
+		} else if (chip_name == 0x7531 || chip_name == 0x7988) {
+			if ((chip_name == 0x7531) && (bw > 2500000)) {
 				printf("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",bw);
 				return -1;
 			}
-		        if (bw/32 >= 65536) //supoort 2.5G case
-                                value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) + (7 << 8) + 0xf;
-                        else
-                                value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf;
+
+			if ((chip_name == 0x7988) && (bw > 4000000)) {
+				printf("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",bw);
+				return -1;
 			}
+
+			if (bw/32 >= 65536) //supoort 2.5G case
+				value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) + (7 << 8) + 0xf;
+			else
+				value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf;
+		}
 		else
 			printf("unknow chip\n");
 	}
@@ -3175,15 +3183,20 @@
 				return -1;
 			}
 			value = ((bw / 32) << 16) + (1 << 15) + (7 << 8) + (1 << 7) + 0xf;
-		} else if (chip_name == 0x7531) {
-			if (bw < 0 || bw > 2500000) {
+		} else if (chip_name == 0x7531 || chip_name == 0x7988) {
+			if ((chip_name == 0x7531) && (bw < 0 || bw > 2500000)) {
 				printf("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",bw);
 				return -1;
 			}
+			if ((chip_name == 0x7988) && (bw < 0 || bw > 4000000)) {
+				printf("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",bw);
+				return -1;
+			}
-		        if (bw/32 >= 65536)	//support 2.5G cases
-                                value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) + (7 << 8) + 0xf;
-                        else
-                                value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf;
+
+			if (bw/32 >= 65536)	//support 2.5G cases
+				value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) + (7 << 8) + 0xf;
+			else
+				value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf;
 		}
 		else
 			printf("unknow chip\n");
@@ -3207,7 +3220,7 @@
 	port = atoi(argv[3]);
 	rate = atoi(argv[4]);
 
-	if (rate < 0)
+	if (port > 6)
 		return;
 
 	if (dir == 1) //ingress
@@ -3230,12 +3243,12 @@
 	printf("collision pool enable: %d \n", enable);
 
 	/*Check the input parameters is right or not.*/
-	if ((enable > 1) || (enable < 0)) {
+	if (enable > 1) {
 		printf(HELP_COLLISION_POOL_EN);
 		return -1;
 	}
 
-	if (chip_name == 0x7531) {
+	if (chip_name == 0x7531 || chip_name == 0x7988) {
 		reg = REG_CPGC_ADDR;
 		if(enable == 1) {
 			/* active reset */
@@ -3301,7 +3314,7 @@
 {
 	unsigned int value, reg;
 
-	if (chip_name == 0x7531) {
+	if (chip_name == 0x7531 || chip_name == 0x7988) {
 		reg = REG_CPGC_ADDR;
 		reg_read(reg, &value);
 		if(value & REG_CPCG_COL_EN_MASK)
@@ -3317,7 +3330,7 @@
 {
 	unsigned int value, reg;
 
-	if (chip_name == 0x7531) {
+	if (chip_name == 0x7531 || chip_name == 0x7988) {
 		reg = REG_CPGC_ADDR;
 		reg_read(reg, &value);
 		if(value & REG_CPCG_COL_EN_MASK)
@@ -3335,7 +3348,7 @@
 {
 	unsigned int value, reg;
 
-	if (chip_name == 0x7531) {
+	if (chip_name == 0x7531 ||  chip_name == 0x7988) {
 		reg = REG_CPGC_ADDR;
 		reg_read(reg, &value);
 		if(value & REG_CPCG_COL_EN_MASK)
@@ -3361,7 +3374,7 @@
 		return;
 	}
 
-	if (chip_name == 0x7531) {
+	if (chip_name == 0x7531 ||  chip_name == 0x7988) {
 		reg= PFC_RX_COUNTER_L(port);
 		reg_read(reg, &value);
 		user_pri = value & 0xff;
@@ -3405,7 +3418,7 @@
 		return;
 	}
 
-	if (chip_name == 0x7531) {
+	if (chip_name == 0x7531 || chip_name == 0x7988) {
 		reg= PFC_TX_COUNTER_L(port);
 		reg_read(reg, &value);
 		user_pri = value & 0xff;
@@ -3438,104 +3451,103 @@
 
 void read_output_queue_counters()
 {
+	unsigned int port=0;
+	unsigned int value, output_queue;
+	unsigned int base=0x220;
 
-unsigned int port=0;
-unsigned int value, output_queue;
-unsigned int base=0x220;
+	for (port = 0; port < 7; port++) {
+		reg_write(0x7038, base + (port *4));
+		reg_read(0x7034, &value);
+		output_queue = value & 0xff;
+		printf("\n port %d  output queue 0 counter is %d.\n", port,output_queue);
+		output_queue = (value & 0xff00) >> 8;
+		printf("\n port %d  output queue 1 counter is %d.\n", port,output_queue);
 
-for (port = 0; port < 7; port++) {
-	reg_write(0x7038, base + (port *4));
-	reg_read(0x7034, &value);
-	output_queue = value & 0xff;
-	printf("\n port %d  output queue 0 counter is %d.\n", port,output_queue);
-	output_queue = (value & 0xff00) >> 8;
-	printf("\n port %d  output queue 1 counter is %d.\n", port,output_queue);
+		reg_write(0x7038, base + (port *4) + 1);
+		reg_read(0x7034, &value);
+		output_queue = value & 0xff;
+		printf("\n port %d  output queue 2 counter is %d.\n", port,output_queue);
+		output_queue = (value & 0xff00) >> 8;
+		printf("\n port %d  output queue 3 counter is %d.\n", port,output_queue);
 
-	reg_write(0x7038, base + (port *4) + 1);
-	reg_read(0x7034, &value);
-	output_queue = value & 0xff;
-	printf("\n port %d  output queue 2 counter is %d.\n", port,output_queue);
-	output_queue = (value & 0xff00) >> 8;
-	printf("\n port %d  output queue 3 counter is %d.\n", port,output_queue);
+		reg_write(0x7038, base + (port *4) + 2);
+		reg_read(0x7034, &value);
+		output_queue = value & 0xff;
+		printf("\n port %d  output queue 4 counter is %d.\n", port,output_queue);
+		output_queue = (value & 0xff00) >> 8;
+		printf("\n port %d  output queue 5 counter is %d.\n", port,output_queue);
 
-	reg_write(0x7038, base + (port *4) + 2);
-	reg_read(0x7034, &value);
-	output_queue = value & 0xff;
-	printf("\n port %d  output queue 4 counter is %d.\n", port,output_queue);
-	output_queue = (value & 0xff00) >> 8;
-	printf("\n port %d  output queue 5 counter is %d.\n", port,output_queue);
-
-	reg_write(0x7038, base + (port *4) + 3);
-	reg_read(0x7034, &value);
-	output_queue = value & 0xff;
-	printf("\n port %d  output queue 6 counter is %d.\n", port,output_queue);
-	output_queue = (value & 0xff00) >> 8;
-	printf("\n port %d  output queue 7 counter is %d.\n", port,output_queue);
+		reg_write(0x7038, base + (port *4) + 3);
+		reg_read(0x7034, &value);
+		output_queue = value & 0xff;
+		printf("\n port %d  output queue 6 counter is %d.\n", port,output_queue);
+		output_queue = (value & 0xff00) >> 8;
+		printf("\n port %d  output queue 7 counter is %d.\n", port,output_queue);
 	}
 }
 
 void read_free_page_counters()
 {
-unsigned int value;
-unsigned int free_page,free_page_last_read;
-unsigned int fc_free_blk_lothd,fc_free_blk_hithd;
-unsigned int fc_port_blk_thd,fc_port_blk_hi_thd;
-unsigned int queue[8]={0};
+	unsigned int value;
+	unsigned int free_page,free_page_last_read;
+	unsigned int fc_free_blk_lothd,fc_free_blk_hithd;
+	unsigned int fc_port_blk_thd,fc_port_blk_hi_thd;
+	unsigned int queue[8]={0};
 
-if (chip_name == 0x7531) {
-	/* get system free page link counter*/
-	reg_read(0x1fc0, &value);
-	free_page = value & 0xFFF;
-	free_page_last_read = (value & 0xFFF0000) >> 16;
+	if (chip_name == 0x7531 || chip_name == 0x7988) {
+		/* get system free page link counter*/
+		reg_read(0x1fc0, &value);
+		free_page = value & 0xFFF;
+		free_page_last_read = (value & 0xFFF0000) >> 16;
 
-	/* get system flow control waterwark */
-	reg_read(0x1fe0, &value);
-	fc_free_blk_lothd = value & 0x3FF;
-	fc_free_blk_hithd = (value & 0x3FF0000) >> 16;
+		/* get system flow control waterwark */
+		reg_read(0x1fe0, &value);
+		fc_free_blk_lothd = value & 0x3FF;
+		fc_free_blk_hithd = (value & 0x3FF0000) >> 16;
 
-	/* get port flow control waterwark */
-	reg_read(0x1fe4, &value);
-	fc_port_blk_thd = value & 0x3FF;
-	fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16;
+		/* get port flow control waterwark */
+		reg_read(0x1fe4, &value);
+		fc_port_blk_thd = value & 0x3FF;
+		fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16;
 
-	/* get queue flow control waterwark */
-	reg_read(0x1fe8, &value);
-	queue[0]= value & 0x3F;
-	queue[1]= (value & 0x3F00) >> 8;
-	queue[2]= (value & 0x3F0000) >> 16;
-	queue[3]= (value & 0x3F000000) >> 24;
-	reg_read(0x1fec, &value);
-	queue[4]= value & 0x3F;
-	queue[5]= (value & 0x3F00) >> 8;
-	queue[6]= (value & 0x3F0000) >> 16;
-	queue[7]= (value & 0x3F000000) >> 24;
-	}else{
-	/* get system free page link counter*/
-	reg_read(0x1fc0, &value);
-	free_page = value & 0x3FF;
-	free_page_last_read = (value & 0x3FF0000) >> 16;
+		/* get queue flow control waterwark */
+		reg_read(0x1fe8, &value);
+		queue[0]= value & 0x3F;
+		queue[1]= (value & 0x3F00) >> 8;
+		queue[2]= (value & 0x3F0000) >> 16;
+		queue[3]= (value & 0x3F000000) >> 24;
+		reg_read(0x1fec, &value);
+		queue[4]= value & 0x3F;
+		queue[5]= (value & 0x3F00) >> 8;
+		queue[6]= (value & 0x3F0000) >> 16;
+		queue[7]= (value & 0x3F000000) >> 24;
+	} else {
+		/* get system free page link counter*/
+		reg_read(0x1fc0, &value);
+		free_page = value & 0x3FF;
+		free_page_last_read = (value & 0x3FF0000) >> 16;
 
-	/* get system flow control waterwark */
-	reg_read(0x1fe0, &value);
-	fc_free_blk_lothd = value & 0xFF;
-	fc_free_blk_hithd = (value & 0xFF00) >> 8;
+		/* get system flow control waterwark */
+		reg_read(0x1fe0, &value);
+		fc_free_blk_lothd = value & 0xFF;
+		fc_free_blk_hithd = (value & 0xFF00) >> 8;
 
-	/* get port flow control waterwark */
-	reg_read(0x1fe0, &value);
-	fc_port_blk_thd = (value & 0xFF0000) >> 16;
-	reg_read(0x1ff4, &value);
-	fc_port_blk_hi_thd = (value & 0xFF00) >> 8;
+		/* get port flow control waterwark */
+		reg_read(0x1fe0, &value);
+		fc_port_blk_thd = (value & 0xFF0000) >> 16;
+		reg_read(0x1ff4, &value);
+		fc_port_blk_hi_thd = (value & 0xFF00) >> 8;
 
-	/* get queue flow control waterwark */
-	reg_read(0x1fe4, &value);
-	queue[0]= value & 0xF;
-	queue[1]= (value & 0xF0) >> 4;
-	queue[2]= (value & 0xF00) >> 8;
-	queue[3]= (value & 0xF000) >>12;
-	queue[4]= (value & 0xF0000) >>16;
-	queue[5]= (value & 0xF00000) >> 20;
-	queue[6]= (value & 0xF000000) >> 24;
-	queue[7]= (value & 0xF0000000) >> 28;
+		/* get queue flow control waterwark */
+		reg_read(0x1fe4, &value);
+		queue[0]= value & 0xF;
+		queue[1]= (value & 0xF0) >> 4;
+		queue[2]= (value & 0xF00) >> 8;
+		queue[3]= (value & 0xF000) >>12;
+		queue[4]= (value & 0xF0000) >>16;
+		queue[5]= (value & 0xF00000) >> 20;
+		queue[6]= (value & 0xF000000) >> 24;
+		queue[7]= (value & 0xF0000000) >> 28;
 	}
 
 	printf("<===Free Page=======Current=======Last Read access=====> \n ");
@@ -3558,7 +3570,133 @@
 	printf("=========================================================\n ");
 }
 
+void eee_enable(int argc, char *argv[])
+{
+	unsigned long enable;
+	unsigned int value;
+	unsigned int eee_cap;
+	unsigned int eee_en_bitmap = 0;
+	unsigned long port_map;
+	long port_num = -1;
+	int p;
+
+	if (argc < 3)
+		goto error;
+
+	/*Check the input parameters is right or not.*/
+	if (!strncmp(argv[2], "enable", 7))
+		enable = 1;
+	else if (!strncmp(argv[2], "disable", 8))
+		enable = 0;
+	else
+		goto error;
+
+	if (argc > 3) {
+		if (strlen(argv[3]) == 1) {
+			port_num = strtol(argv[3], (char **)NULL, 10);
+			if (port_num < 0 || port_num > MAX_PHY_PORT - 1) {
+				printf("Illegal port index and port:0~4\n");
+				goto error;
+			}
+			port_map = 1 << port_num;
+		} else if (strlen(argv[3]) == 5) {
+			port_map = 0;
+			for (p = 0; p < MAX_PHY_PORT; p++) {
+				if (argv[3][p] != '0' && argv[3][p] != '1') {
+					printf("portmap format error, should be combination of 0 or 1\n");
+					goto error;
+				}
+				port_map |= ((argv[3][p] - '0') << p);
+			}
+		} else {
+			printf("port_no or portmap format error, should be length of 1 or 5\n");
+			goto error;
+		}
+	} else {
+		port_map = 0x1f;
+	}
+
+	eee_cap = (enable)? 6: 0;
+	for (p = 0; p < MAX_PHY_PORT; p++) {
+		/* port_map describe p0p1p2p3p4 from left to rignt */
+		if(!!(port_map & (1 << p)))
+			mii_mgr_c45_write(p, 0x7, 0x3c, eee_cap);
+
+		mii_mgr_c45_read(p, 0x7, 0x3c, &value);
+		/* mt7531: Always readback eee_cap = 0 when global EEE switch
+		 * is turned off.
+		 */
+		if (value | eee_cap)
+			eee_en_bitmap |= (1 << (MAX_PHY_PORT - 1 - p));
+	}
+
+	/* Turn on/off global EEE switch */
+	if (chip_name == 0x7531 || chip_name == 0x7988) {
+		mii_mgr_c45_read(0, 0x1f, 0x403, &value);
+		if (eee_en_bitmap)
+			value |= (1 << 6);
+		else
+			value &= ~(1 << 6);
+		mii_mgr_c45_write(0, 0x1f, 0x403, value);
+	} else {
+		printf("\nCommand not support by this chip.\n");
+	}
+
+	printf("EEE(802.3az) %s", (enable)? "enable": "disable");
+	if (argc == 4) {
+		if (port_num >= 0)
+			printf(" port%ld", port_num);
+		else
+			printf(" port_map: %s", argv[3]);
+	} else {
+		printf(" all ports");
+	}
+	printf("\n");
+
+	return;
+error:
+	printf(HELP_EEE_EN);
+	return;
+}
+
+void eee_dump(int argc, char *argv[])
+{
+	unsigned int cap, lp_cap;
+	long port = -1;
+	int p;
+
+	if (argc > 3) {
+		if (strlen(argv[3]) > 1) {
+			printf("port# format error, should be of length 1\n");
+			return;
+		}
+
+		port = strtol(argv[3], (char **)NULL, 0);
+		if (port < 0 || port > MAX_PHY_PORT) {
+			printf("port# format error, should be 0 to %d\n",
+				       MAX_PHY_PORT);
+			return;
+		}
+	}
+
+	for (p = 0; p < MAX_PHY_PORT; p++) {
+		if (port >= 0 && p != port)
+			continue;
+
+		mii_mgr_c45_read(p, 0x7, 0x3c, &cap);
+		mii_mgr_c45_read(p, 0x7, 0x3d, &lp_cap);
+		printf("port%d EEE cap=0x%02x, link partner EEE cap=0x%02x",
+		       p, cap, lp_cap);
+
+		if (port >= 0 && p == port) {
+			mii_mgr_c45_read(p, 0x3, 0x1, &cap);
+			printf(", st=0x%03x", cap);
+		}
+		printf("\n");
+	}
+}
+
-void dump_each_port(int base)
+void dump_each_port(unsigned int base)
 {
 	unsigned int pkt_cnt = 0;
 	int i = 0;
diff --git a/recipes-devtools/switch/files/switch_fun.h b/recipes-devtools/switch/files/src/switch_fun.h
similarity index 88%
rename from recipes-devtools/switch/files/switch_fun.h
rename to recipes-devtools/switch/files/src/switch_fun.h
index 57a2345..70e4d18 100644
--- a/recipes-devtools/switch/files/switch_fun.h
+++ b/recipes-devtools/switch/files/src/switch_fun.h
@@ -9,6 +9,7 @@
 #define MT7530_T10_TEST_CONTROL 0x145
 
 #define MAX_PORT 6
+#define MAX_PHY_PORT 5
 #define CONFIG_MTK_7531_DVT 1
 
 extern int chip_name;
@@ -16,11 +17,11 @@
 extern bool nl_init_flag;
 
 /*basic operation*/
-int reg_read(int offset, int *value);
-int reg_write(int offset, int value);
-int mii_mgr_read(unsigned int port_num, unsigned int reg, int *value);
+int reg_read(unsigned int offset, unsigned int *value);
+int reg_write(unsigned int offset, unsigned int value);
+int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value);
 int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value);
-int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg, int *value);
+int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int *value);
 int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int value);
 
 /*phy setting*/
@@ -73,7 +74,7 @@
 void table_clear(void);
 
 /*vlan table*/
-void vlan_dump(void);
+void vlan_dump(int argc, char *argv[]);
 void vlan_clear(int argc, char *argv[]);
 void vlan_set(int argc, char *argv[]);
 
@@ -99,7 +100,7 @@
 
 /*rate control*/
 void rate_control(int argc, char *argv[]);
-int ingress_rate_set(int on_off, int port, int bw);
+int ingress_rate_set(int on_off, unsigned int port, unsigned int bw);
 int egress_rate_set(int on_off, int port, int bw);
 
 /*QoS*/
@@ -127,7 +128,11 @@
 void pfc_get_tx_counter(int argc, char *argv[]);
 
 /*switch reset*/
-void switch_reset(int argc, char *argv[]);
+int switch_reset(int argc, char *argv[]);
+
+/* EEE(802.3az) function  */
+void eee_enable(int argc, char *argv[]);
+void eee_dump(int argc, char *argv[]);
 
 void read_mib_counters();
 void clear_mib_counters();
@@ -136,4 +141,4 @@
 
 void phy_crossover(int argc, char *argv[]);
 void exit_free();
-#endif
\ No newline at end of file
+#endif
diff --git a/recipes-devtools/switch/files/src/switch_ioctl.c b/recipes-devtools/switch/files/src/switch_ioctl.c
new file mode 100644
index 0000000..f6b97d4
--- /dev/null
+++ b/recipes-devtools/switch/files/src/switch_ioctl.c
@@ -0,0 +1,478 @@
+/*
+ * switch_ioctl.c: switch(ioctl) set API
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/if.h>
+
+#include "switch_fun.h"
+#include "switch_ioctl.h"
+
+static int esw_fd;
+
+int switch_ioctl_init(void)
+{
+	esw_fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (esw_fd < 0) {
+		perror("socket");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void switch_ioctl_fini(void)
+{
+	close(esw_fd);
+}
+
+int reg_read_ioctl(unsigned int offset, unsigned int *value)
+{
+	struct ifreq ifr;
+	struct ra_mii_ioctl_data mii;
+
+	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+	ifr.ifr_data = &mii;
+
+	mii.phy_id = 0x1f;
+	mii.reg_num = offset;
+
+	if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
+		perror("ioctl");
+		close(esw_fd);
+		exit(0);
+	}
+	*value = mii.val_out;
+	return 0;
+}
+
+int reg_read_tr(int offset, int *value)
+{
+	struct ifreq ifr;
+	struct ra_mii_ioctl_data mii;
+
+	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+	ifr.ifr_data = &mii;
+
+	mii.phy_id = 0;
+	mii.reg_num = offset;
+
+	if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
+		perror("ioctl");
+		close(esw_fd);
+		exit(0);
+	}
+	*value = mii.val_out;
+	return 0;
+}
+
+int reg_write_ioctl(unsigned int offset, unsigned int value)
+{
+	struct ifreq ifr;
+	struct ra_mii_ioctl_data mii;
+
+	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+	ifr.ifr_data = &mii;
+
+	mii.phy_id = 0x1f;
+	mii.reg_num = offset;
+	mii.val_in = value;
+
+	if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
+		perror("ioctl");
+		close(esw_fd);
+		exit(0);
+	}
+	return 0;
+}
+
+int reg_write_tr(int offset, int value)
+{
+	struct ifreq ifr;
+	struct ra_mii_ioctl_data mii;
+
+	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+	ifr.ifr_data = &mii;
+
+	mii.phy_id = 0;
+	mii.reg_num = offset;
+	mii.val_in = value;
+
+	if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
+		perror("ioctl");
+		close(esw_fd);
+		exit(0);
+	}
+	return 0;
+}
+
+int phy_dump_ioctl(unsigned int phy_addr)
+{
+	struct ifreq ifr;
+	struct esw_reg reg;
+
+	reg.val = phy_addr;
+	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+	ifr.ifr_data = &reg;
+	if (-1 == ioctl(esw_fd, RAETH_ESW_PHY_DUMP, &ifr)) {
+		perror("ioctl");
+		close(esw_fd);
+		exit(0);
+	}
+	return 0;
+}
+
+int mii_mgr_cl22_read_ioctl(unsigned int port_num, unsigned int reg, unsigned int *value)
+{
+	unsigned int reg_value;
+	int loop_cnt;
+	int op_busy;
+
+	loop_cnt = 0;
+
+	/*Change to indirect access mode*/
+	/*if you need to use direct access mode, please change back manually by reset bit5*/
+	if (chip_name == 0x7530) {
+		reg_read(0x7804, &reg_value);
+		if (((reg_value >> 5) & 0x1) == 0) {
+			reg_value |= 1 << 5;
+			reg_write(0x7804, reg_value);
+			printf("Change to indirect access mode:0x%x\n",
+			       reg_value);
+		}
+	}
+	reg_value = 0x80090000 | (port_num << 20) | (reg << 25);
+	reg_write(0x701c, reg_value);
+	while (1)
+	{
+		reg_read(0x701c, &reg_value);
+		op_busy = reg_value & (1 << 31);
+		if (!op_busy) {
+			reg_value = reg_value & 0xFFFF;
+			break;
+		} else if (loop_cnt < 10)
+			loop_cnt++;
+		else {
+			printf("MDIO read opeartion timeout\n");
+			reg_value = 0;
+			break;
+		}
+	}
+	//printf(" PHY Indirect Access Control(0x701c) register read value =0x%x  \n", reg_value);
+	*value = reg_value;
+
+	return 0;
+}
+
+int mii_mgr_cl22_write_ioctl(unsigned int port_num, unsigned int reg, unsigned int value)
+{
+	unsigned int reg_value;
+	int loop_cnt;
+	int op_busy;
+
+	loop_cnt = 0;
+	/*Change to indirect access mode*/
+	/*if you need to use direct access mode, please change back manually by reset bit5*/
+	if (chip_name == 0x7530) {
+		reg_read(0x7804, &reg_value);
+		if (((reg_value >> 5) & 0x1) == 0) {
+			reg_value |= 1 << 5;
+			reg_write(0x7804, reg_value);
+			printf("Change to indirect access mode:0x%x\n",
+			       reg_value);
+		}
+	}
+
+	reg_value = 0x80050000 | (port_num << 20) | (reg << 25) | value;
+	reg_write(0x701c, reg_value);
+	while (1)
+	{
+		reg_read(0x701c, &reg_value);
+		op_busy = reg_value & (1 << 31);
+		if (!op_busy)
+			break;
+		else if (loop_cnt < 10)
+			loop_cnt++;
+		else {
+			printf("MDIO write opeartion timeout\n");
+			break;
+		}
+	}
+
+	//printf(" PHY Indirect Access Control(0x701c) register write value =0x%x  \n", reg_value);
+
+	return 0;
+}
+
+int mii_mgr_cl45_read_indirect(unsigned int port_num, unsigned int dev,
+			       unsigned int reg, unsigned int *value)
+{
+	int sk, method, ret;
+	struct ifreq ifr;
+	struct ra_mii_ioctl_data mii;
+
+	if (!value)
+		return -1;
+
+	sk = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sk < 0) {
+		printf("Open socket failed\n");
+
+		return -1;
+	}
+
+	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+	ifr.ifr_data = &mii;
+
+	method = RAETH_MII_WRITE;
+	mii.phy_id = port_num;
+	mii.reg_num = 13;
+	mii.val_in = dev;
+	ret = ioctl(sk, method, &ifr);
+
+	method = RAETH_MII_WRITE;
+	mii.phy_id = port_num;
+	mii.reg_num = 14;
+	mii.val_in = reg;
+	ret = ioctl(sk, method, &ifr);
+
+	method = RAETH_MII_WRITE;
+	mii.phy_id = port_num;
+	mii.reg_num = 13;
+	mii.val_in = (0x6000 | dev);
+	ret = ioctl(sk, method, &ifr);
+
+	usleep(1000);
+
+	method = RAETH_MII_READ;
+	mii.phy_id = port_num;
+	mii.reg_num = 14;
+	ret = ioctl(sk, method, &ifr);
+
+	close(sk);
+	*value = mii.val_out;
+
+	return ret;
+}
+
+int mii_mgr_cl45_write_indirect(unsigned int port_num, unsigned int dev,
+				unsigned int reg, unsigned int value)
+{
+	int sk, method, ret;
+	struct ifreq ifr;
+	struct ra_mii_ioctl_data mii;
+
+	sk = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sk < 0) {
+		printf("Open socket failed\n");
+
+		return -1;
+	}
+
+	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+	ifr.ifr_data = &mii;
+
+	method = RAETH_MII_WRITE;
+	mii.phy_id = port_num;
+	mii.reg_num = 13;
+	mii.val_in = dev;
+	ret = ioctl(sk, method, &ifr);
+
+	method = RAETH_MII_WRITE;
+	mii.phy_id = port_num;
+	mii.reg_num = 14;
+	mii.val_in = reg;
+	ret = ioctl(sk, method, &ifr);
+
+	method = RAETH_MII_WRITE;
+	mii.phy_id = port_num;
+	mii.reg_num = 13;
+	mii.val_in = (0x6000 | dev);
+	ret = ioctl(sk, method, &ifr);
+
+	usleep(1000);
+
+	method = RAETH_MII_WRITE;
+	mii.phy_id = port_num;
+	mii.reg_num = 14;
+	mii.val_in = value;
+	ret = ioctl(sk, method, &ifr);
+
+	close(sk);
+
+	return ret;
+}
+
+int mii_mgr_cl45_read(unsigned int port_num, unsigned int dev,
+		      unsigned int reg, unsigned int *value)
+{
+	unsigned int reg_value;
+	int loop_cnt;
+	int op_busy;
+	int ret = 0;
+
+	loop_cnt = 0;
+
+	reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg;
+	reg_write(0x701c, reg_value);
+	while (1)
+	{
+		reg_read(0x701c, &reg_value);
+		op_busy = reg_value & (1 << 31);
+		if (!op_busy) {
+			break;
+		} else if (loop_cnt < 10) {
+			loop_cnt++;
+		} else {
+			printf("MDIO cl45 set dev opeartion timeout\n");
+			reg_value = 0;
+			ret = -1; 
+			goto out;
+		}
+	}
+
+	reg_value = 0x800c0000 | (port_num << 20) | (dev << 25);
+	reg_write(0x701c, reg_value);
+	while (1)
+	{
+		reg_read(0x701c, &reg_value);
+		op_busy = reg_value & (1 << 31);
+		if (!op_busy) {
+			reg_value = reg_value & 0xFFFF;
+			break;
+		} else if (loop_cnt < 10) {
+			loop_cnt++;
+		} else {
+			printf("MDIO cl45 read reg opeartion timeout\n");
+			reg_value = 0;
+			ret = -1; 
+			break;
+		}
+	}
+out:
+	//printf(" PHY Indirect Access Control(0x701c) register read value =0x%x  \n", reg_value);
+	*value = reg_value;
+
+	return ret;
+}
+
+int mii_mgr_cl45_write(unsigned int port_num, unsigned int dev,
+		       unsigned int reg, unsigned int value)
+{
+	unsigned int reg_value;
+	int loop_cnt;
+	int op_busy;
+	int ret = 0;
+
+	loop_cnt = 0;
+
+	reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg;
+	reg_write(0x701c, reg_value);
+	while (1)
+	{
+		reg_read(0x701c, &reg_value);
+		op_busy = reg_value & (1 << 31);
+		if (!op_busy)
+			break;
+		else if (loop_cnt < 10)
+			loop_cnt++;
+		else {
+			printf("MDIO cl45 set dev opeartion timeout\n");
+			ret = -1; 
+			goto out;
+		}
+	}
+
+	reg_value = 0x80040000 | (port_num << 20) | (dev << 25) | value;
+	reg_write(0x701c, reg_value);
+	while (1)
+	{
+		reg_read(0x701c, &reg_value);
+		op_busy = reg_value & (1 << 31);
+		if (!op_busy)
+			break;
+		else if (loop_cnt < 10)
+			loop_cnt++;
+		else {
+			printf("MDIO cl45 write reg opeartion timeout\n");
+			ret = -1; 
+			break;
+		}
+	}
+out:
+	//printf(" PHY Indirect Access Control(0x701c) register write value =0x%x  \n", reg_value);
+	return ret;
+}
+
+int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev,
+			    unsigned int reg, unsigned int *value)
+{
+	if (chip_name == 0x7531 || chip_name == 0x7988)
+		return mii_mgr_cl45_read(port_num, dev, reg, value);
+	else if (chip_name == 0x7530)
+		return mii_mgr_cl45_read_indirect(port_num, dev, reg, value);
+	else
+		return -1;
+}
+
+int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev,
+			     unsigned int reg, unsigned int value)
+{
+	if (chip_name == 0x7531 || chip_name == 0x7988)
+		return mii_mgr_cl45_write(port_num, dev, reg, value);
+	else if (chip_name == 0x7530)
+		return mii_mgr_cl45_write_indirect(port_num, dev, reg, value);
+	else
+		return -1;
+}
+
+int dump_gphy(void)
+{
+	int cl22_reg[6] = {0x00, 0x01, 0x04, 0x05, 0x09, 0x0A};
+	int cl45_start_reg = 0x9B;
+	int cl45_end_reg = 0xA2;
+	unsigned int value;
+	int port_num = 5;
+	int i, j, ret;
+
+	int sk, method;
+	struct ifreq ifr;
+	struct ra_mii_ioctl_data mii;
+
+	sk = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sk < 0) {
+		printf("Open socket failed\n");
+		return -1;
+	}
+
+	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+	ifr.ifr_data = &mii;
+	/* dump CL45 reg first*/
+	for (i = 0; i < port_num; i++) {
+		printf("== Port %d ==\n", i);
+		for (j = cl45_start_reg; j < (cl45_end_reg + 1); j++) {
+			ret = mii_mgr_cl45_read_ioctl(i, 0x1E, j, &value);
+			if (ret)
+				continue;
+			printf("dev1Eh_reg%xh = 0x%x\n", j, value);
+		}
+	}
+	printf("== Global ==\n");
+	for (i = 0; i < sizeof(cl22_reg) / sizeof(cl22_reg[0]); i++) {
+		method = RAETH_MII_READ;
+		mii.phy_id = 0;
+		mii.reg_num = cl22_reg[i];
+		ret = ioctl(sk, method, &ifr);
+		printf("Reg%xh = 0x%x\n", cl22_reg[i], mii.val_out);
+	}
+
+	close(sk);
+
+	return ret;
+}
diff --git a/recipes-devtools/switch/files/switch_ioctl.h b/recipes-devtools/switch/files/src/switch_ioctl.h
similarity index 68%
rename from recipes-devtools/switch/files/switch_ioctl.h
rename to recipes-devtools/switch/files/src/switch_ioctl.h
index c12e8d8..dffe9c7 100644
--- a/recipes-devtools/switch/files/switch_ioctl.h
+++ b/recipes-devtools/switch/files/src/switch_ioctl.h
@@ -5,8 +5,8 @@
 #ifndef SWITCH_IOCTL_H
 #define SWITCH_IOCTL_H
 
-#define ETH_DEVNAME "eth1"
-#define BR_DEVNAME "brlan0"
+#define ETH_DEVNAME "eth0"
+#define BR_DEVNAME "br-lan"
 
 #define RAETH_MII_READ                  0x89F3
 #define RAETH_MII_WRITE                 0x89F4
@@ -18,13 +18,15 @@
 };
 
 struct ra_mii_ioctl_data {
-        __u32 phy_id;
-        __u32 reg_num;
+        __u16 phy_id;
+        __u16 reg_num;
         __u32 val_in;
         __u32 val_out;
+/*
         __u32 port_num;
         __u32 dev_addr;
         __u32 reg_addr;
+*/
 };
 
 struct ra_switch_ioctl_data {
@@ -52,14 +54,17 @@
 
 extern int chip_name;
 
-void switch_ioctl_init(void);
+int switch_ioctl_init(void);
 void switch_ioctl_fini(void);
-int reg_read_ioctl(int offset, int *value);
-int reg_write_ioctl(int offset, int value);
-int phy_dump_ioctl(int phy_addr);
-int mii_mgr_cl22_read_ioctl(unsigned int port_num, unsigned int reg, int *value);
+int reg_read_ioctl(unsigned int offset, unsigned int *value);
+int reg_write_ioctl(unsigned int offset, unsigned int value);
+int phy_dump_ioctl(unsigned int phy_addr);
+int mii_mgr_cl22_read_ioctl(unsigned int port_num, unsigned int reg,
+			    unsigned int *value);
 int mii_mgr_cl22_write_ioctl(unsigned int port_num, unsigned int reg,
-			unsigned int value);
-int mii_mgr_cl45_read_ioctl(int port_num, int dev, int reg, int *value);
-int mii_mgr_cl45_write_ioctl(int port_num, int dev, int reg, int value);
+			     unsigned int value);
+int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev,
+			    unsigned int reg, unsigned int *value);
+int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev,
+			     unsigned int reg, unsigned int value);
 #endif
diff --git a/recipes-devtools/switch/files/switch_netlink.c b/recipes-devtools/switch/files/src/switch_netlink.c
similarity index 90%
rename from recipes-devtools/switch/files/switch_netlink.c
rename to recipes-devtools/switch/files/src/switch_netlink.c
index c89ddb6..90a4a19 100644
--- a/recipes-devtools/switch/files/switch_netlink.c
+++ b/recipes-devtools/switch/files/src/switch_netlink.c
@@ -91,7 +91,6 @@
 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
 	struct mt753x_attr *val = arg;
 	char *str;
-	int data;
 
 	if (nla_parse(attrs, MT753X_ATTR_TYPE_MAX, genlmsg_attrdata(gnlh, 0),
 		      genlmsg_attrlen(gnlh, 0), NULL) < 0)
@@ -148,7 +147,8 @@
 
 	/*Fill attaribute of netlink message by construct function*/
 	if (construct) {
-		if (construct(msg, arg) < 0) {
+		err = construct(msg, arg);
+		if (err < 0) {
 			fprintf(stderr, "attributes error\n");
 			goto nal_put_failure;
 		}
@@ -208,7 +208,7 @@
 	family = NULL;
 }
 
-int mt753x_netlink_init(void)
+int mt753x_netlink_init(const char *name)
 {
 	int ret;
 
@@ -234,8 +234,11 @@
 		goto err;
 	}
 
+	if (name == NULL)
+		return -EINVAL;
+
 	/*Look up generic netlik family by "mt753x" in the provided cache*/
-	family = genl_ctrl_search_by_name(cache, MT753X_GENL_NAME);
+	family = genl_ctrl_search_by_name(cache, name);
 	if (!family) {
 		//fprintf(stderr,"switch(mt753x) API not be prepared\n");
 		goto err;
@@ -267,10 +270,11 @@
 	return 0;
 }
 
-static int phy_operate_netlink(char op, struct mt753x_attr *arg, int port_num,
-					int phy_dev, int offset, int *value)
+static int phy_operate_netlink(char op, struct mt753x_attr *arg,
+			       unsigned int port_num, unsigned int phy_dev,
+			       unsigned int offset, unsigned int *value)
 {
-	int ret;
+	int ret = 0;
 	struct mt753x_attr *attr = arg;
 
 	attr->port_num = port_num;
@@ -298,7 +302,8 @@
 	return ret;
 }
 
-int reg_read_netlink(struct mt753x_attr *arg, int offset, int *value)
+int reg_read_netlink(struct mt753x_attr *arg, unsigned int offset,
+		     unsigned int *value)
 {
 	int ret;
 
@@ -306,7 +311,8 @@
 	return ret;
 }
 
-int reg_write_netlink(struct mt753x_attr *arg, int offset, int value)
+int reg_write_netlink(struct mt753x_attr *arg, unsigned int offset,
+		      unsigned int value)
 {
 	int ret;
 
@@ -314,7 +320,8 @@
 	return ret;
 }
 
-int phy_cl22_read_netlink(struct mt753x_attr *arg, int port_num, int phy_addr, int *value)
+int phy_cl22_read_netlink(struct mt753x_attr *arg, unsigned int port_num,
+			  unsigned int phy_addr, unsigned int *value)
 {
 	int ret;
 
@@ -322,7 +329,8 @@
 	return ret;
 }
 
-int phy_cl22_write_netlink(struct mt753x_attr *arg, int port_num, int phy_addr, int value)
+int phy_cl22_write_netlink(struct mt753x_attr *arg, unsigned int port_num,
+			   unsigned int phy_addr, unsigned int value)
 {
 	int ret;
 
@@ -330,8 +338,9 @@
 	return ret;
 }
 
-int phy_cl45_read_netlink(struct mt753x_attr *arg, int port_num, int phy_dev,
-			 int phy_addr, int *value)
+int phy_cl45_read_netlink(struct mt753x_attr *arg, unsigned int port_num,
+			  unsigned int phy_dev, unsigned int phy_addr,
+			  unsigned int *value)
 {
 	int ret;
 
@@ -339,8 +348,9 @@
 	return ret;
 }
 
-int phy_cl45_write_netlink(struct mt753x_attr *arg, int port_num, int phy_dev,
-			  int phy_addr, int value)
+int phy_cl45_write_netlink(struct mt753x_attr *arg, unsigned int port_num,
+			   unsigned int phy_dev, unsigned int phy_addr,
+			   unsigned int value)
 {
 	int ret;
 
@@ -351,10 +361,9 @@
 void dump_extend_phy_reg(struct mt753x_attr *arg, int port_no, int from,
 			int to, int is_local, int page_no)
 {
-	int ret;
-        int i = 0;
-        int temp = 0;
+        unsigned int temp = 0;
         int r31 = 0;
+        int i = 0;
 
         if (is_local == 0) {
             printf("\n\nGlobal Register Page %d\n",page_no);
diff --git a/recipes-devtools/switch/files/src/switch_netlink.h b/recipes-devtools/switch/files/src/switch_netlink.h
new file mode 100644
index 0000000..b3f946e
--- /dev/null
+++ b/recipes-devtools/switch/files/src/switch_netlink.h
@@ -0,0 +1,70 @@
+/*
+ * switch_netlink.h: switch(netlink) set API
+ * 
+ * Author: Sirui Zhao <Sirui.Zhao@mediatek.com>
+ */
+#ifndef MT753X_NETLINK_H
+#define MT753X_NETLINK_H
+
+#define MT753X_GENL_NAME "mt753x"
+#define MT753X_DSA_GENL_NAME "mt753x_dsa"
+#define MT753X_GENL_VERSION 0X1
+
+/*add your cmd to here*/
+enum {
+	MT753X_CMD_UNSPEC = 0, /*Reserved*/
+	MT753X_CMD_REQUEST,    /*user->kernelrequest/get-response*/
+	MT753X_CMD_REPLY,      /*kernel->user event*/
+	MT753X_CMD_READ,
+	MT753X_CMD_WRITE,
+	__MT753X_CMD_MAX,
+};
+#define MT753X_CMD_MAX (__MT753X_CMD_MAX - 1)
+
+/*define attar types */
+enum
+{
+	MT753X_ATTR_TYPE_UNSPEC = 0,
+	MT753X_ATTR_TYPE_MESG, /*MT753X message*/
+	MT753X_ATTR_TYPE_PHY,
+	MT753X_ATTR_TYPE_PHY_DEV,
+	MT753X_ATTR_TYPE_REG,
+	MT753X_ATTR_TYPE_VAL,
+	MT753X_ATTR_TYPE_DEV_NAME,
+	MT753X_ATTR_TYPE_DEV_ID,
+	__MT753X_ATTR_TYPE_MAX,
+};
+#define MT753X_ATTR_TYPE_MAX (__MT753X_ATTR_TYPE_MAX - 1)
+
+struct mt753x_attr {
+	int port_num;
+	int phy_dev;
+	int reg;
+	int value;
+	int type;
+	char op;
+	char *dev_info;
+	int dev_name;
+	int dev_id;
+};
+
+int mt753x_netlink_init(const char *name);
+void mt753x_netlink_free(void);
+void mt753x_list_swdev(struct mt753x_attr *arg, int cmd);
+int reg_read_netlink(struct mt753x_attr *arg, unsigned int offset,
+		     unsigned int *value);
+int reg_write_netlink(struct mt753x_attr *arg, unsigned int offset,
+		      unsigned int value);
+int phy_cl22_read_netlink(struct mt753x_attr *arg, unsigned int port_num,
+			  unsigned int phy_addr, unsigned int *value);
+int phy_cl22_write_netlink(struct mt753x_attr *arg, unsigned int port_num,
+			   unsigned int phy_addr, unsigned int value);
+int phy_cl45_read_netlink(struct mt753x_attr *arg, unsigned int port_num,
+			  unsigned int phy_dev, unsigned int phy_addr,
+			  unsigned int *value);
+int phy_cl45_write_netlink(struct mt753x_attr *arg, unsigned int port_num,
+			   unsigned int phy_dev, unsigned int phy_addr,
+			   unsigned int value);
+int phy_dump_netlink(struct mt753x_attr *arg, int phy_addr);
+
+#endif
diff --git a/recipes-devtools/switch/files/switch_ioctl.c b/recipes-devtools/switch/files/switch_ioctl.c
deleted file mode 100644
index ca3f15b..0000000
--- a/recipes-devtools/switch/files/switch_ioctl.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * switch_ioctl.c: switch(ioctl) set API
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <linux/if.h>
-
-#include "switch_fun.h"
-#include "switch_ioctl.h"
-
-static int esw_fd;
-
-void switch_ioctl_init(void)
-{
-	esw_fd = socket(AF_INET, SOCK_DGRAM, 0);
-	if (esw_fd < 0) {
-		perror("socket");
-		exit(0);
-	}
-}
-
-void switch_ioctl_fini(void)
-{
-	close(esw_fd);
-}
-
-int reg_read_ioctl(int offset, int *value)
-{
-	struct ifreq ifr;
-	struct esw_reg reg;
-
-	struct ra_mii_ioctl_data mii;
-	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
-	ifr.ifr_data = &mii;
-
-	mii.phy_id = 0x1f;
-	mii.reg_num = offset;
-
-	if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
-		perror("ioctl");
-		close(esw_fd);
-		exit(0);
-	}
-	*value = mii.val_out;
-	return 0;
-}
-
-int reg_read_tr(int offset, int *value)
-{
-	struct ifreq ifr;
-	struct esw_reg reg;
-	struct ra_mii_ioctl_data mii;
-
-	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
-	ifr.ifr_data = &mii;
-
-	mii.phy_id = 0;
-	mii.reg_num = offset;
-
-	if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
-		perror("ioctl");
-		close(esw_fd);
-		exit(0);
-	}
-	*value = mii.val_out;
-	return 0;
-}
-
-int reg_write_ioctl(int offset, int value)
-{
-	struct ifreq ifr;
-	struct esw_reg reg;
-	struct ra_mii_ioctl_data mii;
-
-	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
-	ifr.ifr_data = &mii;
-
-	mii.phy_id = 0x1f;
-	mii.reg_num = offset;
-	mii.val_in = value;
-
-	if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
-		perror("ioctl");
-		close(esw_fd);
-		exit(0);
-	}
-	return 0;
-}
-
-int reg_write_tr(int offset, int value)
-{
-	struct ifreq ifr;
-	struct esw_reg reg;
-	struct ra_mii_ioctl_data mii;
-
-	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
-	ifr.ifr_data = &mii;
-
-	mii.phy_id = 0;
-	mii.reg_num = offset;
-	mii.val_in = value;
-
-	if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
-		perror("ioctl");
-		close(esw_fd);
-		exit(0);
-	}
-	return 0;
-}
-
-int phy_dump_ioctl(int phy_addr)
-{
-	struct ifreq ifr;
-	struct esw_reg reg;
-
-	reg.val = phy_addr;
-	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
-	ifr.ifr_data = &reg;
-	if (-1 == ioctl(esw_fd, RAETH_ESW_PHY_DUMP, &ifr)) {
-		perror("ioctl");
-		close(esw_fd);
-		exit(0);
-	}
-	return 0;
-}
-
-int mii_mgr_cl22_read_ioctl(unsigned int port_num, unsigned int reg, int *value)
-{
-	int reg_value;
-	int loop_cnt;
-	int op_busy;
-
-	loop_cnt = 0;
-
-	/*Change to indirect access mode*/
-	/*if you need to use direct access mode, please change back manually by reset bit5*/
-	reg_read(0x7804, &reg_value);
-	if (((reg_value >> 5) & 0x1) == 0) {
-		reg_value |= 1 << 5;
-		reg_write(0x7804, reg_value);
-		printf("Change to indirect access mode:0x%x\n",reg_value);
-	}
-	reg_value = 0x80090000 | (port_num << 20) | (reg << 25);
-	reg_write(0x701c, reg_value);
-	while (1)
-	{
-		reg_read(0x701c, &reg_value);
-		op_busy = reg_value & (1 << 31);
-		if (!op_busy) {
-			reg_value = reg_value & 0xFFFF;
-			break;
-		} else if (loop_cnt < 10)
-			loop_cnt++;
-		else {
-			printf("MDIO read opeartion timeout\n");
-			reg_value = 0;
-			break;
-		}
-	}
-	printf(" PHY Indirect Access Control(0x701c) register read value =0x%x  \n", reg_value);
-	*value = reg_value;
-	return 0;
-}
-
-int mii_mgr_cl22_write_ioctl(unsigned int port_num, unsigned int reg, unsigned int value)
-{
-	int reg_value;
-	int loop_cnt;
-	int op_busy;
-
-	loop_cnt = 0;
-	/*Change to indirect access mode*/
-	/*if you need to use direct access mode, please change back manually by reset bit5*/
-	reg_read(0x7804, &reg_value);
-	if (((reg_value >> 5) & 0x1) == 0) {
-		reg_value |= 1 << 5;
-		reg_write(0x7804, reg_value);
-		printf("Change to indirect access mode:0x%x\n",reg_value);
-	}
-
-	reg_value = 0x80050000 | (port_num << 20) | (reg << 25) | value;
-	reg_write(0x701c, reg_value);
-	while (1)
-	{
-		reg_read(0x701c, &reg_value);
-		op_busy = reg_value & (1 << 31);
-		if (!op_busy)
-			break;
-		else if (loop_cnt < 10)
-			loop_cnt++;
-		else {
-			printf("MDIO write opeartion timeout\n");
-			break;
-		}
-	}
-
-	printf(" PHY Indirect Access Control(0x701c) register write value =0x%x  \n", reg_value);
-	return 0;
-}
-
-int mii_mgr_cl45_read_ioctl(int port_num, int dev, int reg, int *value)
-{
-	int sk, method, ret, i;
-	struct ifreq ifr;
-	struct ra_mii_ioctl_data mii;
-
-	sk = socket(AF_INET, SOCK_DGRAM, 0);
-	if (sk < 0)
-		printf("Open socket failed\n");
-
-	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
-	ifr.ifr_data = &mii;
-
-	method = RAETH_MII_WRITE;
-	mii.phy_id = port_num;
-	mii.reg_num = 13;
-	mii.val_in = dev;
-	ret = ioctl(sk, method, &ifr);
-
-	method = RAETH_MII_WRITE;
-	mii.phy_id = port_num;
-	mii.reg_num = 14;
-	mii.val_in = reg;
-	ret = ioctl(sk, method, &ifr);
-
-	method = RAETH_MII_WRITE;
-	mii.phy_id = port_num;
-	mii.reg_num = 13;
-	mii.val_in = (0x6000 | dev);
-	ret = ioctl(sk, method, &ifr);
-
-	usleep(1000);
-
-	method = RAETH_MII_READ;
-	mii.phy_id = port_num;
-	mii.reg_num = 14;
-	ret = ioctl(sk, method, &ifr);
-
-	close(sk);
-	*value = mii.val_out;
-	return 0;
-}
-
-int mii_mgr_cl45_write_ioctl(int port_num, int dev, int reg, int value)
-{
-	int sk, method, ret, i;
-	struct ifreq ifr;
-	struct ra_mii_ioctl_data mii;
-
-	sk = socket(AF_INET, SOCK_DGRAM, 0);
-	if (sk < 0)
-		printf("Open socket failed\n");
-
-	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
-	ifr.ifr_data = &mii;
-
-	method = RAETH_MII_WRITE;
-	mii.phy_id = port_num;
-	mii.reg_num = 13;
-	mii.val_in = dev;
-	ret = ioctl(sk, method, &ifr);
-
-	method = RAETH_MII_WRITE;
-	mii.phy_id = port_num;
-	mii.reg_num = 14;
-	mii.val_in = reg;
-	ret = ioctl(sk, method, &ifr);
-
-	method = RAETH_MII_WRITE;
-	mii.phy_id = port_num;
-	mii.reg_num = 13;
-	mii.val_in = (0x6000 | dev);
-	ret = ioctl(sk, method, &ifr);
-
-	usleep(1000);
-
-	method = RAETH_MII_WRITE;
-	mii.phy_id = port_num;
-	mii.reg_num = 14;
-	mii.val_in = value;
-	ret = ioctl(sk, method, &ifr);
-
-	close(sk);
-
-	return ret;
-}
-
-int dump_gphy(void)
-{
-	int port_num = 5;
-	int cl45_start_reg = 0x9B;
-	int cl45_end_reg = 0xA2;
-	int cl22_reg[6] = {0x00, 0x01, 0x04, 0x05, 0x09, 0x0A};
-	int i, j, ret;
-	int *value;
-
-	int sk, method;
-	struct ifreq ifr;
-	struct ra_mii_ioctl_data mii;
-
-	sk = socket(AF_INET, SOCK_DGRAM, 0);
-	if (sk < 0)
-		printf("Open socket failed\n");
-
-	strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
-	ifr.ifr_data = &mii;
-	/* dump CL45 reg first*/
-	for (i = 0; i < 5; i++) {
-		printf("== Port %d ==\n", i);
-		for (j = cl45_start_reg; j < (cl45_end_reg + 1); j++) {
-			mii_mgr_cl45_read_ioctl(i, 0x1E, j, value);
-			printf("dev1Eh_reg%xh = 0x%x\n", j, *value);
-		}
-	}
-	printf("== Global ==\n");
-	for (i = 0; i < 6; i++) {
-		method = RAETH_MII_READ;
-		mii.phy_id = 0;
-		mii.reg_num = cl22_reg[i];
-		ret = ioctl(sk, method, &ifr);
-		printf("Reg%xh = 0x%x\n", cl22_reg[i], mii.val_out);
-	}
-
-	close(sk);
-	return 0;
-}
diff --git a/recipes-devtools/switch/files/switch_netlink.h b/recipes-devtools/switch/files/switch_netlink.h
deleted file mode 100644
index de7d36b..0000000
--- a/recipes-devtools/switch/files/switch_netlink.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * switch_netlink.h: switch(netlink) set API
- * 
- * Author: Sirui Zhao <Sirui.Zhao@mediatek.com>
- */
-#ifndef MT753X_NETLINK_H
-#define MT753X_NETLINK_H
-
-#define MT753X_GENL_NAME "mt753x"
-#define MT753X_GENL_VERSION 0X1
-
-/*add your cmd to here*/
-enum {
-	MT753X_CMD_UNSPEC = 0, /*Reserved*/
-	MT753X_CMD_REQUEST,    /*user->kernelrequest/get-response*/
-	MT753X_CMD_REPLY,      /*kernel->user event*/
-	MT753X_CMD_READ,
-	MT753X_CMD_WRITE,
-	__MT753X_CMD_MAX,
-};
-#define MT753X_CMD_MAX (__MT753X_CMD_MAX - 1)
-
-/*define attar types */
-enum
-{
-	MT753X_ATTR_TYPE_UNSPEC = 0,
-	MT753X_ATTR_TYPE_MESG, /*MT753X message*/
-	MT753X_ATTR_TYPE_PHY,
-	MT753X_ATTR_TYPE_PHY_DEV,
-	MT753X_ATTR_TYPE_REG,
-	MT753X_ATTR_TYPE_VAL,
-	MT753X_ATTR_TYPE_DEV_NAME,
-	MT753X_ATTR_TYPE_DEV_ID,
-	__MT753X_ATTR_TYPE_MAX,
-};
-#define MT753X_ATTR_TYPE_MAX (__MT753X_ATTR_TYPE_MAX - 1)
-
-struct mt753x_attr {
-	int port_num;
-	int phy_dev;
-	int reg;
-	int value;
-	int type;
-	char op;
-	char *dev_info;
-	int dev_name;
-	int dev_id;
-};
-
-int mt753x_netlink_init(void);
-void mt753x_netlink_free(void);
-void mt753x_list_swdev(struct mt753x_attr *arg, int cmd);
-int reg_read_netlink(struct mt753x_attr *arg, int offset, int *value);
-int reg_write_netlink(struct mt753x_attr *arg, int offset, int value);
-int phy_cl22_read_netlink(struct mt753x_attr *arg, int port_num, int phy_addr, int *value);
-int phy_cl22_write_netlink(struct mt753x_attr *arg, int port_num, int phy_addr, int value);
-int phy_cl45_read_netlink(struct mt753x_attr *arg, int port_num, int phy_dev,
-			 int phy_addr, int *value);
-int phy_cl45_write_netlink(struct mt753x_attr *arg, int port_num, int phy_dev,
-			  int phy_addr, int value);
-int phy_dump_netlink(struct mt753x_attr *arg, int phy_addr);
-
-#endif
diff --git a/recipes-devtools/switch/switch_1.0.bb b/recipes-devtools/switch/switch_1.0.bb
index 5c95e6e..133b669 100644
--- a/recipes-devtools/switch/switch_1.0.bb
+++ b/recipes-devtools/switch/switch_1.0.bb
@@ -3,23 +3,17 @@
 LICENSE = "GPLv2"
 LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
 
-S = "${WORKDIR}"
 
 DEPENDS = "libnl"
 
 SRC_URI = " \
-    file://COPYING \
-    file://Makefile \
-    file://switch_753x.c \
-    file://switch_extend.h \
-    file://switch_fun.c \
-    file://switch_fun.h \
-    file://switch_ioctl.c \
-    file://switch_ioctl.h \
-    file://switch_netlink.c \
-    file://switch_netlink.h \
+    file://COPYING;subdir=git/src \
+    file://src;subdir=git \
+    file://rdkb-change-bridge-name.patch \
     "
 
+S = "${WORKDIR}/git/src"
+
 CFLAGS_prepend = " \
     -D_GNU_SOURCE \
     -I${STAGING_INCDIR}/libnl3 \
@@ -33,5 +27,5 @@
 do_install() {
     install -d ${D}/usr/sbin
     install -d ${D}/lib/network
-    install -m 0755 ${WORKDIR}/switch ${D}/usr/sbin
+    install -m 0755 ${S}/switch ${D}/usr/sbin
 }