[qca-ssdk] merge recent changes

1. Add mib feature for swconfig when disable ar8216
2. Fix remove issue and after stop thread, free memory.
3. Add support for nat_helper building if IN_NAT_HELPER is enabled in config
4. Fix issue: default configuration vlan1 and vlan2 does not forword packet
5. Remove fdb buffer full message
6. Fix ref-fdb show issue
7. Remove temp files after building

Signed-off-by: Yue Lun <luny@codeaurora.org>
diff --git a/Makefile b/Makefile
old mode 100644
new mode 100755
index acf59b5..1e669be
--- a/Makefile
+++ b/Makefile
@@ -14,9 +14,9 @@
 
 all: $(BIN_DIR) kslib uslib shell
 	mkdir -p ./temp/;cd ./temp;cp ../build/bin/ssdk_ks_km.a ./;ar -x ssdk_ks_km.a; cp ../ko_Makefile ./Makefile;
-	make -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=arm-openwrt-linux-uclibcgnueabi- modules
-	cp temp/*.ko build/bin;pwd; ls;
-	#rm -Rf ./temp .tmp_versions *.symvers *.order *.mod.c *.o;
+	make -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules
+	cp temp/*.ko build/bin;
+	rm -Rf ./temp
 	@echo "---Build [SSDK-$(VERSION)] at $(BUILD_DATE) finished."
 
 kslib:kslib_o
diff --git a/app/nathelper/linux/host_helper.c b/app/nathelper/linux/host_helper.c
index ef5ef10..733338e 100755
--- a/app/nathelper/linux/host_helper.c
+++ b/app/nathelper/linux/host_helper.c
@@ -16,6 +16,7 @@
 

 

 #ifdef KVER32

+#include <linux/kconfig.h> 

 #include <generated/autoconf.h>

 #else

 #include <linux/autoconf.h>

@@ -38,7 +39,7 @@
 #include <linux/if_vlan.h>

 #endif

 #if defined (CONFIG_BRIDGE)

-#include <net/bridge/br_private.h>

+#include <../net/bridge/br_private.h>

 #endif

 #include <linux/ppp_defs.h>

 #include <linux/filter.h>

@@ -669,6 +670,7 @@
 #ifdef ISISC

         if (0 == is_wan) /* Not WAN -> LAN */

         {

+#if NAT_TODO   

             /* Setup private and netmask as soon as possible */

             if (NULL != nat_dev->br_port) /* under bridge interface. */

             {

@@ -677,6 +679,18 @@
 #else

                 in_device_lan = (struct in_device *) nat_dev->br_port->br->dev->ip_ptr;

 #endif

+#else

+#ifdef KVER32

+            if (NULL != br_port_get_rcu(nat_dev)) /* under bridge interface. */

+            {

+                in_device_lan = (struct in_device *) (br_port_get_rcu(nat_dev)->br->dev->ip_ptr);

+#else

+            /* Setup private and netmask as soon as possible */

+            if (NULL != nat_dev->br_port) /* under bridge interface. */

+            {

+                in_device_lan = (struct in_device *) nat_dev->br_port->br->dev->ip_ptr;

+#endif

+#endif

             }

             else

             {

@@ -689,7 +703,9 @@
             }

             nat_hw_prv_mask_set((a_uint32_t)(in_device_lan->ifa_list->ifa_mask));

             nat_hw_prv_base_set((a_uint32_t)(in_device_lan->ifa_list->ifa_address));

+#ifndef KVER32

             printk("Set private base 0x%08x for %s\n", (a_uint32_t)(in_device_lan->ifa_list->ifa_address), nat_dev->br_port->br->dev->name);

+#endif

             memcpy(&lanip, (void *)&(in_device_lan->ifa_list->ifa_address), 4); /* copy Lan port IP. */

 #ifndef ISISC

             redirect_internal_ip_packets_to_cpu_on_wan_add_acl_rules((a_uint32_t)(in_device_lan->ifa_list->ifa_address),

@@ -731,7 +747,9 @@
     {

         for (i=0; i<7; i++) /* For AR8327/AR8337, only 7 port */

         {

+#if NAT_TODO /* need to implement here */

             PORTVLAN_ROUTE_DEFV_SET(0, i);

+#endif

         }

         setup_default_vid = 1;

     }

@@ -1523,9 +1541,17 @@
                 arp_hw_add(sport, vid, sip, sa, 1);

             }

 

+#if NAT_TODO /* should be ok */

             if ((NULL != in->ip6_ptr) && (NULL != ((struct inet6_dev *)in->ip6_ptr)->addr_list))

+#else

+            if (NULL != in->ip6_ptr)

+#endif

             {

-                in_device_addr = ((struct inet6_dev *)in->ip6_ptr)->addr_list;

+#if NAT_TODO  /* MUST be double check */

+                in_device_addr = ((struct inet6_dev *)(in->ip6_ptr))->addr_list;

+#else

+                list_for_each_entry(in_device_addr, &(in->ip6_ptr)->addr_list, if_list);

+#endif                

                 if (0 == dev_is_lan)

                 {

                     /* WAN ipv6 address*/

diff --git a/app/nathelper/linux/lib/nat_helper_dt.c b/app/nathelper/linux/lib/nat_helper_dt.c
index 33ef9c1..19b1c84 100755
--- a/app/nathelper/linux/lib/nat_helper_dt.c
+++ b/app/nathelper/linux/lib/nat_helper_dt.c
@@ -16,6 +16,7 @@
 

 

 #ifdef KVER32

+#include <linux/kconfig.h>

 #include <generated/autoconf.h>

 #else

 #include <linux/autoconf.h>

@@ -637,7 +638,9 @@
                 {

                     NAPT_CT_AGING_DISABLE(ct_addr);

                     napt_ct_buf_in_hw_set(napt_ct, hw_index);

+#if NAT_TODO

                     ct->in_hnat = 1; /* contrack in HNAT now. */

+#endif

                 }

             }

         }

diff --git a/app/nathelper/linux/lib/nat_helper_hsl.c b/app/nathelper/linux/lib/nat_helper_hsl.c
index 543a34e..dd92fcf 100755
--- a/app/nathelper/linux/lib/nat_helper_hsl.c
+++ b/app/nathelper/linux/lib/nat_helper_hsl.c
@@ -16,6 +16,7 @@
 

 

 #ifdef KVER32

+#include <linux/kconfig.h> 

 #include <generated/autoconf.h>

 #else

 #include <linux/autoconf.h>

diff --git a/app/nathelper/linux/lib/nat_helper_hsl.h b/app/nathelper/linux/lib/nat_helper_hsl.h
index 1f4970b..7bfe1e7 100755
--- a/app/nathelper/linux/lib/nat_helper_hsl.h
+++ b/app/nathelper/linux/lib/nat_helper_hsl.h
@@ -18,6 +18,13 @@
 #ifndef _NAT_HELPER_HSL_H

 #define _NAT_HELPER_HSL_H

 

+#ifdef KVER32

+#include <linux/kconfig.h> 

+#include <generated/autoconf.h>

+#else

+#include <linux/autoconf.h>

+#endif

+

 #include <linux/if_ether.h>

 

 #define NAT_HW_NUM 32

diff --git a/app/nathelper/linux/napt_acl.c b/app/nathelper/linux/napt_acl.c
index 41280e0..801032e 100755
--- a/app/nathelper/linux/napt_acl.c
+++ b/app/nathelper/linux/napt_acl.c
@@ -16,6 +16,7 @@
 

 

 #ifdef KVER32

+#include <linux/kconfig.h> 

 #include <generated/autoconf.h>

 #else

 #include <linux/autoconf.h>

diff --git a/app/nathelper/linux/napt_helper.c b/app/nathelper/linux/napt_helper.c
index 4dbc4fc..53b5822 100755
--- a/app/nathelper/linux/napt_helper.c
+++ b/app/nathelper/linux/napt_helper.c
@@ -16,6 +16,7 @@
 

 

 #ifdef KVER32

+#include <linux/kconfig.h>  

 #include <generated/autoconf.h>

 #else

 #include <linux/autoconf.h>

@@ -100,9 +101,9 @@
             ct->timeout.expires = jiffies+(5*24*60*60*HZ);

         }

     }

-

+#if NAT_TODO

     ct->in_hnat = 0; /* once timmer is enabled, contrack not in HNAT anymore. */

-

+#endif

     HNAT_PRINTK("<aging> ct:[%x] add timeout again\n",  ct_addr);

     add_timer(&ct->timeout);

 }

@@ -172,8 +173,8 @@
 

     if(cct)

     {

-        return (cct[IP_CT_DIR_ORIGINAL].packets +

-                cct[IP_CT_DIR_REPLY].packets);

+        return (atomic64_read(&cct[IP_CT_DIR_ORIGINAL].packets) +

+                atomic64_read(&cct[IP_CT_DIR_REPLY].packets));

     }

     else

     {

diff --git a/app/nathelper/linux/nat_helper.c b/app/nathelper/linux/nat_helper.c
index e3b129d..5fd1c16 100755
--- a/app/nathelper/linux/nat_helper.c
+++ b/app/nathelper/linux/nat_helper.c
@@ -14,6 +14,12 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

  */

 

+#ifdef KVER32

+#include <linux/kconfig.h> 

+#include <generated/autoconf.h>

+#else

+#include <linux/autoconf.h>

+#endif

 

 #include "nat_helper.h"

 

diff --git a/include/init/ssdk_plat.h b/include/init/ssdk_plat.h
index 90116e7..ef421e8 100755
--- a/include/init/ssdk_plat.h
+++ b/include/init/ssdk_plat.h
@@ -104,7 +104,9 @@
 #define   AR8327_PAD_MAC_PWR_RGMII1_1_8V		BIT(18)

 

 #define AR8327_NUM_PHYS		5

+#define AR8327_PORT_CPU     0

 #define AR8327_NUM_PORTS	7

+#define AR8327_MAX_VLANS  128

 

 enum {

     AR8327_PORT_SPEED_10M = 0,

@@ -121,31 +123,56 @@
 	QCA_VER_AR8337 = 0x13

 };

 

+/*poll mib per 2secs*/

+#define QCA_PHY_MIB_WORK_DELAY	2000

+#define QCA_MIB_ITEM_NUMBER	41

+

 struct qca_phy_priv {

 	struct phy_device *phy;

+	struct switch_dev sw_dev;

     a_uint8_t version;

-	a_uint8_t revision;    

+	a_uint8_t revision;

 	a_uint32_t (*mii_read)(a_uint32_t reg);

 	void (*mii_write)(a_uint32_t reg, a_uint32_t val);

     void (*phy_dbg_write)(a_uint32_t dev_id, a_uint32_t phy_addr,

                         a_uint16_t dbg_addr, a_uint16_t dbg_data);

-    void (*phy_mmd_write)(a_uint32_t dev_id, a_uint32_t phy_addr, 

+    void (*phy_mmd_write)(a_uint32_t dev_id, a_uint32_t phy_addr,

                           a_uint16_t addr, a_uint16_t data);

-    void (*phy_write)(a_uint32_t dev_id, a_uint32_t phy_addr, 

+    void (*phy_write)(a_uint32_t dev_id, a_uint32_t phy_addr,

                             a_uint32_t reg, a_uint16_t data);

+

+	bool init;

+	struct mutex reg_mutex;

+	struct mutex mib_lock;

+	struct delayed_work mib_dwork;

+	u64 *mib_counters;

+	/* dump buf */

+	a_uint8_t  buf[2048];

+

+    /* VLAN database */

+    bool       vlan;  /* True: 1q vlan mode, False: port vlan mode */

+    a_uint16_t vlan_id[AR8327_MAX_VLANS];

+    a_uint8_t  vlan_table[AR8327_MAX_VLANS];

+    a_uint8_t  vlan_tagged;

+    a_uint16_t pvid[AR8327_NUM_PORTS];

+

 };

 

-static int 

+

+#define qca_phy_priv_get(_dev) \

+		container_of(_dev, struct qca_phy_priv, sw_dev)

+

+static int

 miibus_get(void);

-uint32_t 

+uint32_t

 qca_ar8216_mii_read(int reg);

-void 

+void

 qca_ar8216_mii_write(int reg, uint32_t val);

-static sw_error_t 

-qca_ar8327_phy_write(a_uint32_t dev_id, a_uint32_t phy_addr, 

+static sw_error_t

+qca_ar8327_phy_write(a_uint32_t dev_id, a_uint32_t phy_addr,

                             a_uint32_t reg, a_uint16_t data);

 static void

-qca_ar8327_mmd_write(a_uint32_t dev_id, a_uint32_t phy_addr, 

+qca_ar8327_mmd_write(a_uint32_t dev_id, a_uint32_t phy_addr,

                               a_uint16_t addr, a_uint16_t data);

 static void

 qca_ar8327_phy_dbg_write(a_uint32_t dev_id, a_uint32_t phy_addr,

diff --git a/include/ref/ref_fdb.h b/include/ref/ref_fdb.h
new file mode 100755
index 0000000..c245df8
--- /dev/null
+++ b/include/ref/ref_fdb.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ * All rights reserved.
+ * Qualcomm Atheros Confidential and Proprietary.
+ *
+ */
+
+#ifndef _REF_FDB_H_
+#define _REF_FDB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif                          /* __cplusplus */
+
+
+int
+qca_ar8327_sw_atu_flush(struct qca_phy_priv *priv);
+
+int
+qca_ar8327_sw_atu_dump(struct switch_dev *dev,
+		       		const struct switch_attr *attr,
+		       		struct switch_val *val);
+
+
+#ifdef __cplusplus
+}
+#endif                          /* __cplusplus */
+#endif                          /* _REF_FDB_H_ */
+
diff --git a/include/ref/ref_mib.h b/include/ref/ref_mib.h
new file mode 100755
index 0000000..2a80d2e
--- /dev/null
+++ b/include/ref/ref_mib.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ * All rights reserved.
+ * Qualcomm Atheros Confidential and Proprietary.
+ *
+ */
+
+#ifndef _REF_MIB_H_
+#define _REF_MIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif                          /* __cplusplus */
+
+int
+qca_ar8327_sw_set_reset_mibs(struct switch_dev *dev,
+			 						const struct switch_attr *attr,
+			 						struct switch_val *val);
+
+int
+qca_ar8327_sw_set_port_reset_mib(struct switch_dev *dev,
+			     					const struct switch_attr *attr,
+			     					struct switch_val *val);
+
+
+int
+qca_ar8327_sw_get_port_mib(struct switch_dev *dev,
+		       						const struct switch_attr *attr,
+		       						struct switch_val *val);
+
+void
+qca_ar8327_sw_mib_task(struct switch_dev *dev);
+
+#ifdef __cplusplus
+}
+#endif                          /* __cplusplus */
+#endif                          /* _REF_MIB_H_ */
+
diff --git a/include/ref/ref_misc.h b/include/ref/ref_misc.h
new file mode 100755
index 0000000..59dc9c4
--- /dev/null
+++ b/include/ref/ref_misc.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ * All rights reserved.
+ * Qualcomm Atheros Confidential and Proprietary.
+ *
+ */
+
+#ifndef _REF_MISC_H_
+#define _REF_MISC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif                          /* __cplusplus */
+
+int
+qca_ar8327_sw_set_max_frame_size(struct switch_dev *dev,
+										const struct switch_attr *attr,
+		   								struct switch_val *val);
+
+int
+qca_ar8327_sw_get_max_frame_size(struct switch_dev *dev,
+										const struct switch_attr *attr,
+		   								struct switch_val *val);
+
+#ifdef __cplusplus
+}
+#endif                          /* __cplusplus */
+#endif                          /* _REF_MISC_H_ */
+
diff --git a/include/ref/ref_port_ctrl.h b/include/ref/ref_port_ctrl.h
new file mode 100755
index 0000000..fdf0a67
--- /dev/null
+++ b/include/ref/ref_port_ctrl.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ * All rights reserved.
+ * Qualcomm Atheros Confidential and Proprietary.
+ *
+ */
+
+#ifndef _REF_PORT_CTRL_H_
+#define _REF_PORT_CTRL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif                          /* __cplusplus */
+
+int
+qca_ar8327_sw_get_port_link(struct switch_dev *dev, int port,
+			                        struct switch_port_link *link);
+
+#ifdef __cplusplus
+}
+#endif                          /* __cplusplus */
+#endif                          /* _REF_PORT_CTRL_H_ */
+
diff --git a/include/ref/ref_vlan.h b/include/ref/ref_vlan.h
new file mode 100755
index 0000000..69bd2b6
--- /dev/null
+++ b/include/ref/ref_vlan.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ * All rights reserved.
+ * Qualcomm Atheros Confidential and Proprietary.
+ *
+ */
+
+#ifndef _REF_VLAN_H_
+#define _REF_VLAN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif                          /* __cplusplus */
+
+int
+qca_ar8327_sw_set_vlan(struct switch_dev *dev,
+                       const struct switch_attr *attr,
+                       struct switch_val *val);
+
+int
+qca_ar8327_sw_get_vlan(struct switch_dev *dev,
+                       const struct switch_attr *attr,
+                       struct switch_val *val);
+
+int
+qca_ar8327_sw_set_vid(struct switch_dev *dev,
+                      const struct switch_attr *attr,
+                      struct switch_val *val);
+
+int
+qca_ar8327_sw_get_vid(struct switch_dev *dev,
+                      const struct switch_attr *attr,
+                      struct switch_val *val);
+
+int
+qca_ar8327_sw_get_pvid(struct switch_dev *dev, int port, int *vlan);
+
+int
+qca_ar8327_sw_set_pvid(struct switch_dev *dev, int port, int vlan);
+
+int
+qca_ar8327_sw_get_ports(struct switch_dev *dev, struct switch_val *val);
+
+int
+qca_ar8327_sw_set_ports(struct switch_dev *dev, struct switch_val *val);
+
+int
+qca_ar8327_sw_hw_apply(struct switch_dev *dev);
+
+int
+qca_ar8327_sw_reset_switch(struct switch_dev *dev);
+
+#ifdef __cplusplus
+}
+#endif                          /* __cplusplus */
+#endif                          /* _REF_VLAN_H_ */
+
diff --git a/include/sal/os/linux/aos_types_pvt.h b/include/sal/os/linux/aos_types_pvt.h
index e2336e0..74d3e64 100755
--- a/include/sal/os/linux/aos_types_pvt.h
+++ b/include/sal/os/linux/aos_types_pvt.h
@@ -17,13 +17,11 @@
 #ifndef _AOS_PVTTYPES_H

 #define _AOS_PVTTYPES_H

 

-#ifdef GCCV4

 #ifdef KVER32

 #include <generated/autoconf.h>

 #else

 #include <linux/autoconf.h>

 #endif

-#endif

 #include <asm/types.h>

 #include <linux/compiler.h>

 /*

diff --git a/include/sal/os/linux_user/aos_types_pvt.h b/include/sal/os/linux_user/aos_types_pvt.h
index c67bd79..9facc0f 100755
--- a/include/sal/os/linux_user/aos_types_pvt.h
+++ b/include/sal/os/linux_user/aos_types_pvt.h
@@ -18,9 +18,6 @@
 #define _AOS_PVTTYPES_H

 

 #include <asm/types.h>

-#ifndef GCCV4

-#include <linux/compiler.h>

-#endif

 #include <stdio.h>

 /*

  * Private definitions of general data types

diff --git a/ko_Makefile b/ko_Makefile
index dfaf50d..a2d1501 100755
--- a/ko_Makefile
+++ b/ko_Makefile
@@ -1,3 +1,3 @@
 obj-m :=  qca-ssdk.o
 OBJ_LIST:=$(wildcard ./*.o)
-qca-ssdk-objs := api_access.o hsl_port_prop.o isisc_igmp.o isisc_led.o isisc_sec.o  isisc_nat.o isisc_reg_access.o sd.o f1_phy.o isisc_acl.o isisc_init.o isisc_mib.o isisc_port_ctrl.o isisc_stp.o ssdk_init.o hsl_acl.o isisc_acl_parse.o isisc_interface_ctrl.o isisc_mirror.o isisc_portvlan.o isisc_trunk.o hsl_api.o isisc_cosmap.o isisc_ip.o isisc_misc.o isisc_qos.o isisc_vlan.o sw_api_ks_ioctl.o hsl_dev.o isisc_fdb.o isisc_leaky.o isisc_multicast_acl.o isisc_rate.o util.o fal_acl.o fal_interface_ctrl.o fal_mirror.o fal_qos.o fal_trunk.o fal_cosmap.o fal_ip.o fal_misc.o fal_rate.o fal_vlan.o fal_fdb.o fal_leaky.o fal_nat.o fal_reg_access.o fal_igmp.o fal_led.o fal_port_ctrl.o fal_sec.o fal_init.o fal_mib.o fal_portvlan.o fal_stp.o
+qca-ssdk-objs := api_access.o hsl_port_prop.o isisc_igmp.o isisc_led.o isisc_sec.o  isisc_nat.o isisc_reg_access.o sd.o f1_phy.o isisc_acl.o isisc_init.o isisc_mib.o isisc_port_ctrl.o isisc_stp.o ssdk_init.o hsl_acl.o isisc_acl_parse.o isisc_interface_ctrl.o isisc_mirror.o isisc_portvlan.o isisc_trunk.o hsl_api.o isisc_cosmap.o isisc_ip.o isisc_misc.o isisc_qos.o isisc_vlan.o sw_api_ks_ioctl.o hsl_dev.o isisc_fdb.o isisc_leaky.o isisc_multicast_acl.o isisc_rate.o util.o fal_acl.o fal_interface_ctrl.o fal_mirror.o fal_qos.o fal_trunk.o fal_cosmap.o fal_ip.o fal_misc.o fal_rate.o fal_vlan.o fal_fdb.o fal_leaky.o fal_nat.o fal_reg_access.o fal_igmp.o fal_led.o fal_port_ctrl.o fal_sec.o fal_init.o fal_mib.o fal_portvlan.o fal_stp.o ref_vlan.o ref_fdb.o ref_mib.o ref_port_ctrl.o ref_misc.o
diff --git a/make/components.mk b/make/components.mk
old mode 100644
new mode 100755
index bd162be..1c0dfba
--- a/make/components.mk
+++ b/make/components.mk
@@ -2,12 +2,12 @@
 ifeq (linux, $(OS))
   ifeq (KSLIB, $(MODULE_TYPE))
     ifeq (TRUE, $(KERNEL_MODE))
-      COMPONENTS = HSL SAL INIT UTIL
+      COMPONENTS = HSL SAL INIT UTIL REF
       ifeq (TRUE, $(FAL))
         COMPONENTS += FAL
       endif
     else
-      COMPONENTS = HSL SAL INIT
+      COMPONENTS = HSL SAL INIT REF
     endif
 
     ifeq (TRUE, $(UK_IF))
@@ -17,7 +17,7 @@
   
   ifeq (USLIB, $(MODULE_TYPE))
     ifneq (TRUE, $(KERNEL_MODE))
-      COMPONENTS = HSL SAL INIT UTIL
+      COMPONENTS = HSL SAL INIT UTIL REF
       ifeq (TRUE, $(FAL))
         COMPONENTS += FAL
       endif
diff --git a/make/linux_opt.mk b/make/linux_opt.mk
old mode 100644
new mode 100755
index df65d8b..1cbee42
--- a/make/linux_opt.mk
+++ b/make/linux_opt.mk
@@ -115,7 +115,7 @@
 endif
 
 ifeq (TRUE, $(DEBUG_ON))
-  MODULE_CFLAG += -g 
+  MODULE_CFLAG += -g
 endif
 
 MODULE_CFLAG += $(OPT_FLAG) -Wall -DVERSION=\"$(VERSION)\" -DBUILD_DATE=\"$(BUILD_DATE)\" -DCPU=\"$(CPU)\" -DOS=\"$(OS)\"
@@ -124,6 +124,7 @@
                    -I$(PRJ_PATH)/include/common \
                    -I$(PRJ_PATH)/include/api \
                    -I$(PRJ_PATH)/include/fal \
+                   -I$(PRJ_PATH)/include/ref \
                    -I$(PRJ_PATH)/include/hsl \
                    -I$(PRJ_PATH)/include/hsl/phy \
                    -I$(PRJ_PATH)/include/sal/os \
@@ -213,10 +214,10 @@
 	      -I$(SYS_PATH)/include/generated \
 	      -I$(SYS_PATH)/usr/include
         endif
-	  
-	  
+
+
   endif
-  
+
   ifeq (2_6, $(OS_VER))
         MODULE_CFLAG += -DKVER26
         MODULE_CFLAG += -DLNX26_22
@@ -243,13 +244,13 @@
 	      -I$(SYS_PATH)/include/generated \
 	      -I$(SYS_PATH)/usr/include
         endif
-	  
-	  
+
+
   endif
 
   MODULE_CFLAG += -D__KERNEL__ -DKERNEL_MODULE $(CPU_CFLAG)
 
-  
+
 endif
 
 ifeq (SHELL, $(MODULE_TYPE))
@@ -260,7 +261,7 @@
     else
    	  MODULE_CFLAG += -DKVER24
     endif
-  
+
     ifeq (TRUE, $(KERNEL_MODE))
       MODULE_CFLAG += -static
     else
diff --git a/src/hsl/isis/isis_ip.c b/src/hsl/isis/isis_ip.c
index 8ffb941..79210a4 100755
--- a/src/hsl/isis/isis_ip.c
+++ b/src/hsl/isis/isis_ip.c
@@ -1370,7 +1370,7 @@
 _isis_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable)

 {

     sw_error_t rv;

-    a_uint32_t data;

+    a_uint32_t route_en = 0, l3_en = 0;

 

     HSL_DEV_ID_CHECK(dev_id);

 

@@ -1378,10 +1378,14 @@
     SW_RTN_ON_ERROR(rv);

 

     HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ROUTER_EN,

-                      (a_uint8_t *) (&data), sizeof (a_uint32_t));

+                      (a_uint8_t *) (&route_en), sizeof (a_uint32_t));

     SW_RTN_ON_ERROR(rv);

 

-    if (data)

+    HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, L3_EN,

+                      (a_uint8_t *) (&l3_en), sizeof (a_uint32_t))

+    SW_RTN_ON_ERROR(rv);

+

+    if (route_en && l3_en)

     {

         *enable = A_TRUE;

     }

diff --git a/src/hsl/isisc/isisc_ip.c b/src/hsl/isisc/isisc_ip.c
index 23c2d24..992917d 100755
--- a/src/hsl/isisc/isisc_ip.c
+++ b/src/hsl/isisc/isisc_ip.c
@@ -1412,7 +1412,7 @@
 _isisc_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable)

 {

     sw_error_t rv;

-    a_uint32_t data;

+    a_uint32_t route_en = 0, l3_en = 0;

 

     HSL_DEV_ID_CHECK(dev_id);

 

@@ -1420,10 +1420,14 @@
     SW_RTN_ON_ERROR(rv);

 

     HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ROUTER_EN,

-                      (a_uint8_t *) (&data), sizeof (a_uint32_t));

+                      (a_uint8_t *) (&route_en), sizeof (a_uint32_t));

     SW_RTN_ON_ERROR(rv);

 

-    if (data)

+    HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, L3_EN,

+                      (a_uint8_t *) (&l3_en), sizeof (a_uint32_t))

+    SW_RTN_ON_ERROR(rv);

+

+    if (route_en && l3_en)

     {

         *enable = A_TRUE;

     }

diff --git a/src/init/ssdk_init.c b/src/init/ssdk_init.c
index e2d9592..a7f6092 100755
--- a/src/init/ssdk_init.c
+++ b/src/init/ssdk_init.c
@@ -44,6 +44,11 @@
 #include <linux/netdevice.h>

 #include <linux/ar8216_platform.h>

 #include "ssdk_plat.h"

+#include "ref_vlan.h"

+#include "ref_fdb.h"

+#include "ref_mib.h"

+#include "ref_port_ctrl.h"

+#include "ref_misc.h"

 

 static void

 qca_phy_read_port_link(struct qca_phy_priv *priv, int port,

@@ -249,7 +254,7 @@
 }

 

 static void

-ar8327_port_init(struct qca_phy_priv *priv, a_uint32_t port)

+qca_ar8327_port_init(struct qca_phy_priv *priv, a_uint32_t port)

 {

 	struct ar8327_platform_data *plat_data;

 	struct ar8327_port_cfg *port_cfg;

@@ -376,13 +381,158 @@
 	msleep(1000);

 

 	for (i = 0; i < AR8327_NUM_PORTS; i++) {

-		ar8327_port_init(priv, i);

+		qca_ar8327_port_init(priv, i);

     }

 

 	return 0;

 }

 

 static int

+qca_ar8327_sw_get_reg_val(struct switch_dev *dev,

+                                    int reg, int *val)

+{

+	return 0;

+}

+

+static int

+qca_ar8327_sw_set_reg_val(struct switch_dev *dev,

+                                    int reg, int val)

+{

+	return 0;

+}

+

+static struct switch_attr qca_ar8327_globals[] = {

+	{

+		.name = "enable_vlan",

+		.description = "Enable 8021q VLAN",

+		.type = SWITCH_TYPE_INT,

+		.set = qca_ar8327_sw_set_vlan,

+		.get = qca_ar8327_sw_get_vlan,

+		.max = 1

+	},{

+		.name = "max_frame_size",

+		.description = "Set Max frame Size Of Mac",

+		.type = SWITCH_TYPE_INT,

+		.set = qca_ar8327_sw_set_max_frame_size,

+		.get = qca_ar8327_sw_get_max_frame_size,

+		.max = 9018

+	},

+	{

+		.name = "reset_mibs",

+		.description = "Reset All MIB Counters",

+		.type = SWITCH_TYPE_NOVAL,

+		.set = qca_ar8327_sw_set_reset_mibs,

+	},

+	{

+		.name = "flush_arl",

+		.description = "Flush All ARL table",

+		.type = SWITCH_TYPE_NOVAL,

+		.set = qca_ar8327_sw_atu_flush,

+	},

+	{

+		.name = "dump_arl",

+		.description = "Dump All ARL table",

+		.type = SWITCH_TYPE_STRING,

+		.get = qca_ar8327_sw_atu_dump,

+	},

+};

+

+static struct switch_attr qca_ar8327_port[] = {

+	{

+		.name = "reset_mib",

+		.description = "Reset Mib Counters",

+		.type = SWITCH_TYPE_NOVAL,

+		.set = qca_ar8327_sw_set_port_reset_mib,

+	},

+	{

+		.name = "mib",

+		.description = "Get Mib Counters",

+		.type = SWITCH_TYPE_STRING,

+		.set = NULL,

+		.get = qca_ar8327_sw_get_port_mib,

+	},

+};

+

+static struct switch_attr qca_ar8327_vlan[] = {

+	{

+		.name = "vid",

+		.description = "Configure Vlan Id",

+		.type = SWITCH_TYPE_INT,

+		.set = qca_ar8327_sw_set_vid,

+		.get = qca_ar8327_sw_get_vid,

+		.max = 4094,

+	},

+};

+

+static const struct switch_dev_ops qca_ar8327_sw_ops = {

+	.attr_global = {

+		.attr = qca_ar8327_globals,

+		.n_attr = ARRAY_SIZE(qca_ar8327_globals),

+	},

+	.attr_port = {

+		.attr = qca_ar8327_port,

+		.n_attr = ARRAY_SIZE(qca_ar8327_port),

+	},

+	.attr_vlan = {

+		.attr = qca_ar8327_vlan,

+		.n_attr = ARRAY_SIZE(qca_ar8327_vlan),

+	},

+	.get_port_pvid = qca_ar8327_sw_get_pvid,

+	.set_port_pvid = qca_ar8327_sw_set_pvid,

+	.get_vlan_ports = qca_ar8327_sw_get_ports,

+	.set_vlan_ports = qca_ar8327_sw_set_ports,

+	.apply_config = qca_ar8327_sw_hw_apply,

+	.reset_switch = qca_ar8327_sw_reset_switch,

+	.get_port_link = qca_ar8327_sw_get_port_link,

+	.get_reg_val = qca_ar8327_sw_get_reg_val,

+	.set_reg_val = qca_ar8327_sw_set_reg_val,

+};

+

+static int

+qca_phy_mib_task(struct qca_phy_priv *priv)

+{

+	qca_ar8327_sw_mib_task(&priv->sw_dev);

+}

+

+static void

+qca_phy_mib_work_task(struct work_struct *work)

+{

+	struct qca_phy_priv *priv = container_of(work, struct qca_phy_priv,

+                                            mib_dwork.work);

+

+	mutex_lock(&priv->mib_lock);

+

+    qca_phy_mib_task(priv);

+

+	mutex_unlock(&priv->mib_lock);

+	schedule_delayed_work(&priv->mib_dwork,

+			      msecs_to_jiffies(QCA_PHY_MIB_WORK_DELAY));

+}

+

+static int

+qca_phy_mib_work_start(struct qca_phy_priv *priv)

+{

+	mutex_init(&priv->mib_lock);

+	priv->mib_counters = kzalloc(priv->sw_dev.ports * QCA_MIB_ITEM_NUMBER *

+	      sizeof(*priv->mib_counters), GFP_KERNEL);

+	if (!priv->mib_counters)

+		return -ENOMEM;

+

+	INIT_DELAYED_WORK(&priv->mib_dwork, qca_phy_mib_work_task);

+

+	schedule_delayed_work(&priv->mib_dwork,

+			               msecs_to_jiffies(QCA_PHY_MIB_WORK_DELAY));

+

+	return 0;

+}

+

+static void

+qca_phy_mib_work_stop(struct qca_phy_priv *priv)

+{

+	cancel_delayed_work_sync(&priv->mib_dwork);

+}

+

+static int

 qca_phy_id_chip(struct qca_phy_priv *priv)

 {

 	a_uint32_t value, version;

@@ -408,6 +558,7 @@
 qca_phy_config_init(struct phy_device *pdev)

 {

 	struct qca_phy_priv *priv = pdev->priv;

+	struct switch_dev *sw_dev;

 	int ret;

 

 	if (pdev->addr != 0) {

@@ -440,12 +591,27 @@
 	pdev->supported |= SUPPORTED_1000baseT_Full;

 	pdev->advertising |= ADVERTISED_1000baseT_Full;

 

+	sw_dev = &priv->sw_dev;

+	sw_dev->ops = &qca_ar8327_sw_ops;

+	sw_dev->name = "QCA AR8327 AR8337";

+	sw_dev->vlans = AR8327_MAX_VLANS;

+	sw_dev->ports = AR8327_NUM_PORTS;

+

+	ret = register_switch(&priv->sw_dev, pdev->attached_dev);

+	if (ret != 0) {

+		kfree(priv);

+        return ret;

+    }

+

 	ret = qca_ar8327_hw_init(priv);

 	if (ret != 0) {

 		kfree(priv);

         return ret;

     }

 

+    qca_phy_mib_work_start(priv);

+    mutex_init(&priv->reg_mutex);

+

 	return ret;

 }

 

@@ -524,15 +690,21 @@
 {

 	struct qca_phy_priv *priv = pdev->priv;

 

+	if ((pdev->addr == 0) && priv) {

+        qca_phy_mib_work_stop(priv);

+		kfree(priv->mib_counters);

+		unregister_switch(&priv->sw_dev);

+	}

+

 	if (priv) {

 		kfree(priv);

     }

 }

 

 static struct phy_driver qca_phy_driver = {

-    .name		= "QCA AR8327 AR8337",

+    .name		= "QCA AR8216 AR8236 AR8316 AR8327 AR8337",

 	.phy_id		= 0x004d0000,

-	.phy_id_mask= 0xffff0000,

+    .phy_id_mask= 0xffff0000,

 	.probe		= qca_phy_probe,

 	.remove		= qca_phy_remove,

 	.config_init= &qca_phy_config_init,

@@ -549,6 +721,12 @@
 

     miibus_get();

 

+    if(driver_find(qca_phy_driver.name, &mdio_bus_type)){

+        printk("QCA PHY driver had been Registered\n");

+        return 0;

+    }

+

+    printk("Register QCA PHY driver\n");

 	return phy_driver_register(&qca_phy_driver);

 }

 

@@ -569,7 +747,6 @@
 sw_error_t

 ssdk_switch_init(a_uint32_t dev_id)

 {

-    sw_error_t rv;

     a_uint32_t nr = 0;

     a_uint32_t i;

     hsl_dev_t *p_dev = NULL;

@@ -656,7 +833,7 @@
             fal_qos_queue_tx_buf_nr_set(dev_id, i, 0, &nr);

         }

     }

-

+    return SW_OK;

 }

 

 

diff --git a/src/ref/Makefile b/src/ref/Makefile
new file mode 100755
index 0000000..570e75b
--- /dev/null
+++ b/src/ref/Makefile
@@ -0,0 +1,13 @@
+LOC_DIR=src/ref
+LIB=REF
+
+include $(PRJ_PATH)/make/config.mk
+
+SRC_LIST=$(wildcard *.c)
+
+include $(PRJ_PATH)/make/components.mk
+include $(PRJ_PATH)/make/defs.mk
+include $(PRJ_PATH)/make/target.mk
+
+all: dep obj
+
diff --git a/src/ref/ref_fdb.c b/src/ref/ref_fdb.c
new file mode 100755
index 0000000..af5ac10
--- /dev/null
+++ b/src/ref/ref_fdb.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "sw.h"
+#include "ssdk_init.h"
+#include "fal_init.h"
+#include "fal_misc.h"
+#include "fal_mib.h"
+#include "fal_port_ctrl.h"
+#include "fal_portvlan.h"
+#include "fal_fdb.h"
+#include "fal_stp.h"
+#include "fal_igmp.h"
+#include "fal_qos.h"
+#include "hsl.h"
+#include "hsl_dev.h"
+#include "ssdk_init.h"
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <asm/mach-types.h>
+#include <linux/kconfig.h>
+#include <generated/autoconf.h>
+#include <net/switch.h>
+#include <linux/delay.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+#include <linux/ar8216_platform.h>
+#include "ssdk_plat.h"
+#include "ref_vlan.h"
+
+
+int
+qca_ar8327_sw_atu_flush(struct qca_phy_priv *priv)
+{
+	/* 0: dynamic 1:dynamic, static */
+	fal_fdb_del_all(0, 1);
+
+	return 0;
+}
+
+int
+qca_ar8327_sw_atu_dump(struct switch_dev *dev,
+		       		const struct switch_attr *attr,
+		       		struct switch_val *val)
+{
+	struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+	a_uint32_t rv;
+	char *buf;
+	a_uint32_t len = 0;
+	int i;
+	fal_fdb_op_t option;
+	fal_fdb_entry_t entry;
+
+	buf = (char*) priv->buf;
+	memset(buf, 0, 2048);
+	memset(&option, 0, sizeof(fal_fdb_op_t));
+	memset(&entry, 0, sizeof(fal_fdb_entry_t));
+
+	rv = fal_fdb_extend_first(0, &option, &entry);
+	while (!rv)
+    {
+		len += snprintf(buf+len, 2048-len, "MAC: %02x:%02x:%02x:%02x:%02x:%02x PORTMAP: 0x%02x VID: 0x%x STATUS: 0x%x\n",
+			entry.addr.uc[0],entry.addr.uc[1],entry.addr.uc[2],entry.addr.uc[3],entry.addr.uc[4],entry.addr.uc[5],
+			entry.port.map,
+			entry.fid,
+			entry.static_en);
+
+		if (2048-len < 74){
+//			snprintf(buf+len, 2048-len, "Buffer not enough!\n");
+			break;
+		}
+
+		rv = fal_fdb_extend_next(0, &option, &entry);
+    }
+
+	val->value.s = priv->buf;
+	val->len = len;
+
+	return 0;
+}
+
diff --git a/src/ref/ref_mib.c b/src/ref/ref_mib.c
new file mode 100755
index 0000000..293d792
--- /dev/null
+++ b/src/ref/ref_mib.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "sw.h"
+#include "ssdk_init.h"
+#include "fal_init.h"
+#include "fal_misc.h"
+#include "fal_mib.h"
+#include "fal_port_ctrl.h"
+#include "fal_portvlan.h"
+#include "fal_fdb.h"
+#include "fal_stp.h"
+#include "fal_igmp.h"
+#include "fal_qos.h"
+#include "hsl.h"
+#include "hsl_dev.h"
+#include "ssdk_init.h"
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <asm/mach-types.h>
+#include <linux/kconfig.h>
+#include <generated/autoconf.h>
+#include <net/switch.h>
+#include <linux/delay.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+#include <linux/ar8216_platform.h>
+#include "ssdk_plat.h"
+#include "ref_vlan.h"
+
+int
+_qca_ar8327_sw_capture_port_counter(struct switch_dev *dev, int port)
+{
+    int pos = 0;
+    fal_mib_info_t  mib_Info;
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+
+    fal_get_mib_info(0, port, &mib_Info);
+    pos = port * QCA_MIB_ITEM_NUMBER;
+    priv->mib_counters[pos++] += mib_Info.RxBroad;
+    priv->mib_counters[pos++] += mib_Info.RxPause;
+    priv->mib_counters[pos++] += mib_Info.RxMulti;
+    priv->mib_counters[pos++] += mib_Info.RxFcsErr;
+    priv->mib_counters[pos++] += mib_Info.RxAllignErr;
+    priv->mib_counters[pos++] += mib_Info.RxRunt;
+    priv->mib_counters[pos++] += mib_Info.RxFragment;
+    priv->mib_counters[pos++] += mib_Info.Rx64Byte;
+    priv->mib_counters[pos++] += mib_Info.Rx128Byte;
+    priv->mib_counters[pos++] += mib_Info.Rx256Byte;
+    priv->mib_counters[pos++] += mib_Info.Rx512Byte;
+    priv->mib_counters[pos++] += mib_Info.Rx1024Byte;
+    priv->mib_counters[pos++] += mib_Info.Rx1518Byte;
+    priv->mib_counters[pos++] += mib_Info.RxMaxByte;
+    priv->mib_counters[pos++] += mib_Info.RxTooLong;
+    priv->mib_counters[pos] += mib_Info.RxGoodByte_lo;
+    priv->mib_counters[pos++] |= (mib_Info.RxGoodByte_hi << 32);
+    priv->mib_counters[pos] += mib_Info.RxBadByte_lo;
+    priv->mib_counters[pos++] |= (mib_Info.RxBadByte_hi << 32);
+    priv->mib_counters[pos++] += mib_Info.RxOverFlow;
+    priv->mib_counters[pos++] += mib_Info.Filtered;
+    priv->mib_counters[pos++] += mib_Info.TxBroad;
+    priv->mib_counters[pos++] += mib_Info.TxPause;
+    priv->mib_counters[pos++] += mib_Info.TxMulti;
+    priv->mib_counters[pos++] += mib_Info.TxUnderRun;
+    priv->mib_counters[pos++] += mib_Info.Tx64Byte;
+    priv->mib_counters[pos++] += mib_Info.Tx128Byte;
+    priv->mib_counters[pos++] += mib_Info.Tx256Byte;
+    priv->mib_counters[pos++] += mib_Info.Tx512Byte;
+    priv->mib_counters[pos++] += mib_Info.Tx1024Byte;
+    priv->mib_counters[pos++] += mib_Info.Tx1518Byte;
+    priv->mib_counters[pos++] += mib_Info.TxMaxByte;
+    priv->mib_counters[pos++] += mib_Info.TxOverSize;
+    priv->mib_counters[pos] += mib_Info.TxByte_lo;
+    priv->mib_counters[pos++] |= (mib_Info.TxByte_hi << 32);
+    priv->mib_counters[pos++] += mib_Info.TxCollision;
+    priv->mib_counters[pos++] += mib_Info.TxAbortCol;
+    priv->mib_counters[pos++] += mib_Info.TxMultiCol;
+    priv->mib_counters[pos++] += mib_Info.TxSingalCol;
+    priv->mib_counters[pos++] += mib_Info.TxExcDefer;
+    priv->mib_counters[pos++] += mib_Info.TxDefer;
+    priv->mib_counters[pos++] += mib_Info.TxLateCol;
+    priv->mib_counters[pos++] += mib_Info.RxUniCast;
+    priv->mib_counters[pos++] += mib_Info.TxUniCast;
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_set_reset_mibs(struct switch_dev *dev,
+			 						const struct switch_attr *attr,
+			 						struct switch_val *val)
+{
+    int i = 0;
+    int len = 0;
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+    len = dev->ports * QCA_MIB_ITEM_NUMBER *
+	      sizeof(*priv->mib_counters);
+
+    mutex_lock(&priv->mib_lock);
+    memset(priv->mib_counters, '\0', len);
+    for (i = 0; i < dev->ports; i++)
+    {
+        fal_mib_port_flush_counters(0, i);
+    }
+    mutex_unlock(&priv->mib_lock);
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_set_port_reset_mib(struct switch_dev *dev,
+			     					const struct switch_attr *attr,
+			     					struct switch_val *val)
+{
+    int len = 0;
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+    len = QCA_MIB_ITEM_NUMBER * sizeof(*priv->mib_counters);
+
+    mutex_lock(&priv->mib_lock);
+
+    memset(priv->mib_counters + (val->port_vlan * QCA_MIB_ITEM_NUMBER), '\0', len);
+
+    fal_mib_port_flush_counters(0, val->port_vlan);
+    mutex_unlock(&priv->mib_lock);
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_get_port_mib(struct switch_dev *dev,
+		       						const struct switch_attr *attr,
+		       						struct switch_val *val)
+{
+    int port = 0;
+    int len = 0;
+    int pos = 0;
+
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+    char *buf = priv->buf;
+
+    port = val->port_vlan;
+    if (port >= dev->ports)
+        return -EINVAL;
+
+    mutex_lock(&priv->mib_lock);
+    _qca_ar8327_sw_capture_port_counter(dev, port);
+    pos = port * QCA_MIB_ITEM_NUMBER;
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "Port %d MIB counters\n",
+                            port);
+
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxBroad",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxPause",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxMulti",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxFcsErr",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxAllignErr",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxRunt",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxFragment",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Rx64Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Rx128Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Rx256Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Rx512Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Rx1024Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Rx1518Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxMaxByte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxTooLong",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxGoodByte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxBadByte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxOverFlow",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Filtered",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxBroad",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxPause",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxMulti",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxUnderRun",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Tx64Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Tx128Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Tx256Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Tx512Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Tx1024Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "Tx1518Byte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxMaxByte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxOverSize",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxByte",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxCollision",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxAbortCol",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxMultiCol",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxSingalCol",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxExcDefer",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxDefer",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxLateCol",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "RxUniCast",
+                            priv->mib_counters[pos++]);
+    len += snprintf(buf + len, sizeof(priv->buf) - len,
+                            "%-12s: %llu\n",
+                            "TxUniCast",
+                            priv->mib_counters[pos++]);
+    mutex_unlock(&priv->mib_lock);
+
+    val->value.s = buf;
+    val->len = len;
+
+    return 0;
+}
+
+void
+qca_ar8327_sw_mib_task(struct switch_dev *dev)
+{
+    int i = 0;
+
+    for (i = 0; i < dev->ports; i++)
+    {
+        _qca_ar8327_sw_capture_port_counter(dev, i);
+    }
+
+    return;
+}
+
+
diff --git a/src/ref/ref_misc.c b/src/ref/ref_misc.c
new file mode 100755
index 0000000..0bf98de
--- /dev/null
+++ b/src/ref/ref_misc.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "sw.h"
+#include "ssdk_init.h"
+#include "fal_init.h"
+#include "fal_misc.h"
+#include "fal_mib.h"
+#include "fal_port_ctrl.h"
+#include "fal_portvlan.h"
+#include "fal_fdb.h"
+#include "fal_stp.h"
+#include "fal_igmp.h"
+#include "fal_qos.h"
+#include "hsl.h"
+#include "hsl_dev.h"
+#include "ssdk_init.h"
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <asm/mach-types.h>
+#include <linux/kconfig.h>
+#include <generated/autoconf.h>
+#include <net/switch.h>
+#include <linux/delay.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+#include <linux/ar8216_platform.h>
+#include "ssdk_plat.h"
+#include "ref_vlan.h"
+
+int
+qca_ar8327_sw_set_max_frame_size(struct switch_dev *dev,
+										const struct switch_attr *attr,
+		   								struct switch_val *val)
+{
+	a_uint32_t size = val->value.i;
+	a_uint32_t ret;
+
+	ret = fal_frame_max_size_set(0, size);
+	if (ret){
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+qca_ar8327_sw_get_max_frame_size(struct switch_dev *dev,
+										const struct switch_attr *attr,
+		   								struct switch_val *val)
+{
+	a_uint32_t size = 0;
+	a_uint32_t ret;
+
+	ret = fal_frame_max_size_get(0, &size);
+	if (ret){
+		return -1;
+	}
+
+	val->value.i = size;
+
+	return 0;
+}
+
diff --git a/src/ref/ref_port_ctrl.c b/src/ref/ref_port_ctrl.c
new file mode 100755
index 0000000..1383d9e
--- /dev/null
+++ b/src/ref/ref_port_ctrl.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "sw.h"
+#include "ssdk_init.h"
+#include "fal_init.h"
+#include "fal_misc.h"
+#include "fal_mib.h"
+#include "fal_port_ctrl.h"
+#include "fal_portvlan.h"
+#include "fal_fdb.h"
+#include "fal_stp.h"
+#include "fal_igmp.h"
+#include "fal_qos.h"
+#include "hsl.h"
+#include "hsl_dev.h"
+#include "ssdk_init.h"
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <asm/mach-types.h>
+#include <linux/kconfig.h>
+#include <generated/autoconf.h>
+#include <net/switch.h>
+#include <linux/delay.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+#include <linux/ar8216_platform.h>
+#include "ssdk_plat.h"
+#include "ref_vlan.h"
+
+int
+qca_ar8327_sw_get_port_link(struct switch_dev *dev, int port,
+			                        struct switch_port_link *link)
+{
+	struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+
+	fal_port_speed_t speed;
+	fal_port_duplex_t duplex;
+	a_bool_t status;
+	a_bool_t tx_fc;
+	a_bool_t rx_fc;
+	a_uint32_t ret;
+
+	ret = fal_port_link_status_get(0, port, &status);
+	if (ret){
+		return -1;
+	}
+
+	ret = fal_port_speed_get(0, port, &speed);
+	if (ret){
+		return -1;
+	}
+
+	ret = fal_port_duplex_get(0, port, &duplex);
+	if (ret){
+		return -1;
+	}
+
+	ret = fal_port_rxfc_status_get(0, port, &rx_fc);
+	if (ret){
+		return -1;
+	}
+
+	ret = fal_port_txfc_status_get(0, port, &tx_fc);
+	if (ret){
+		return -1;
+	}
+
+	link->link = status;
+	if (speed == FAL_SPEED_10){
+		link->speed = SWITCH_PORT_SPEED_10;
+	} else if (speed == FAL_SPEED_100){
+		link->speed = SWITCH_PORT_SPEED_100;
+	} else if (speed == FAL_SPEED_1000){
+		link->speed = SWITCH_PORT_SPEED_1000;
+	} else {
+		link->speed = SWITCH_PORT_SPEED_UNKNOWN;
+	}
+
+	if (duplex == FAL_HALF_DUPLEX){
+		link->duplex = 0; /* HALF */
+	} else if (duplex == FAL_FULL_DUPLEX){
+		link->duplex = 1; /* FULL */
+	}
+
+	link->rx_flow = rx_fc;
+	link->tx_flow = tx_fc;
+
+	return 0;
+}
+
diff --git a/src/ref/ref_vlan.c b/src/ref/ref_vlan.c
new file mode 100755
index 0000000..78ea02c
--- /dev/null
+++ b/src/ref/ref_vlan.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "sw.h"
+#include "ssdk_init.h"
+#include "fal_init.h"
+#include "fal_misc.h"
+#include "fal_mib.h"
+#include "fal_port_ctrl.h"
+#include "fal_portvlan.h"
+#include "fal_fdb.h"
+#include "fal_stp.h"
+#include "fal_igmp.h"
+#include "fal_qos.h"
+#include "hsl.h"
+#include "hsl_dev.h"
+#include "ssdk_init.h"
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <asm/mach-types.h>
+#include <linux/kconfig.h>
+#include <generated/autoconf.h>
+#include <net/switch.h>
+#include <linux/delay.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+#include <linux/ar8216_platform.h>
+#include "ssdk_plat.h"
+#include "ref_vlan.h"
+
+int
+qca_ar8327_sw_set_vlan(struct switch_dev *dev,
+                       const struct switch_attr *attr,
+                       struct switch_val *val)
+{
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+
+    priv->vlan = !!val->value.i;
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_get_vlan(struct switch_dev *dev,
+                       const struct switch_attr *attr,
+                       struct switch_val *val)
+{
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+
+    val->value.i = priv->vlan;
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_set_vid(struct switch_dev *dev,
+                      const struct switch_attr *attr,
+                      struct switch_val *val)
+{
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+
+    priv->vlan_id[val->port_vlan] = val->value.i;
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_get_vid(struct switch_dev *dev,
+                      const struct switch_attr *attr,
+                      struct switch_val *val)
+{
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+
+    val->value.i = priv->vlan_id[val->port_vlan];
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_get_pvid(struct switch_dev *dev, int port, int *vlan)
+{
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+
+    *vlan = priv->pvid[port];
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_set_pvid(struct switch_dev *dev, int port, int vlan)
+{
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+
+    /* make sure no invalid PVIDs get set */
+    if (vlan >= dev->vlans)
+        return -1;
+
+    priv->pvid[port] = vlan;
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_get_ports(struct switch_dev *dev, struct switch_val *val)
+{
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+    a_uint8_t ports = priv->vlan_table[val->port_vlan];
+    int i;
+
+    val->len = 0;
+    for (i = 0; i < dev->ports; i++) {
+        struct switch_port *p;
+
+        if (!(ports & (1 << i)))
+            continue;
+
+        p = &val->value.ports[val->len++];
+        p->id = i;
+        if (priv->vlan_tagged & (1 << i))
+            p->flags = (1 << SWITCH_PORT_FLAG_TAGGED);
+        else
+            p->flags = 0;
+    }
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_set_ports(struct switch_dev *dev, struct switch_val *val)
+{
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+    a_uint8_t *vt = &priv->vlan_table[val->port_vlan];
+    int i, j;
+
+    *vt = 0;
+    for (i = 0; i < val->len; i++) {
+        struct switch_port *p = &val->value.ports[i];
+
+        if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) {
+            priv->vlan_tagged |= (1 << p->id);
+        } else {
+            priv->vlan_tagged &= ~(1 << p->id);
+            priv->pvid[p->id] = val->port_vlan;
+
+            /* make sure that an untagged port does not
+             * appear in other vlans */
+            for (j = 0; j < AR8327_MAX_VLANS; j++) {
+                if (j == val->port_vlan)
+                    continue;
+                priv->vlan_table[j] &= ~(1 << p->id);
+            }
+        }
+
+        *vt |= 1 << p->id;
+    }
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_hw_apply(struct switch_dev *dev)
+{
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+    fal_pbmp_t portmask[AR8327_NUM_PORTS];
+    int i, j;
+
+    mutex_lock(&priv->reg_mutex);
+
+    /* flush all vlan translation unit entries */
+    fal_vlan_flush(0);
+
+    memset(portmask, 0, sizeof(portmask));
+    if (!priv->init) {
+        /* calculate the port destination masks and load vlans
+         * into the vlan translation unit */
+        for (j = 0; j < AR8327_MAX_VLANS; j++) {
+            u8 vp = priv->vlan_table[j];
+
+            if (!vp)
+            continue;
+
+            fal_vlan_create(0, priv->vlan_id[j]);
+
+            for (i = 0; i < dev->ports; i++) {
+                u8 mask = (1 << i);
+                if (vp & mask) {
+                    fal_vlan_member_add(0, priv->vlan_id[j], i,
+                           (mask & priv->vlan_tagged)? FAL_EG_TAGGED : FAL_EG_UNTAGGED);
+                    portmask[i] |= vp & ~mask;
+                }
+            }
+
+        }
+    } else {
+        /* vlan disabled:
+         * isolate all ports, but connect them to the cpu port */
+        for (i = 0; i < dev->ports; i++) {
+            if (i == AR8327_PORT_CPU)
+                continue;
+
+            portmask[i] = 1 << AR8327_PORT_CPU;
+            portmask[AR8327_PORT_CPU] |= (1 << i);
+        }
+    }
+
+    /* update the port destination mask registers and tag settings */
+    for (i = 0; i < dev->ports; i++) {
+        /*
+        int egress, ingress;
+        */
+        int pvid;
+        fal_pt_1qmode_t ingressMode;
+        fal_pt_1q_egmode_t egressMode;
+
+        if (priv->vlan) {
+            pvid = priv->vlan_id[priv->pvid[i]];
+            if (priv->vlan_tagged & (1 << i)) {
+                /*
+                egress = AR8216_OUT_ADD_VLAN;
+                */
+                egressMode = FAL_EG_TAGGED;
+            } else {
+                /*
+                egress = AR8216_OUT_STRIP_VLAN;
+                */
+                egressMode = FAL_EG_UNTAGGED;
+            }
+
+            /*
+            ingress = AR8216_IN_SECURE;
+            */
+            ingressMode = FAL_1Q_SECURE;
+        } else {
+            pvid = i;
+            /*
+            egress = AR8216_OUT_KEEP;
+            ingress = AR8216_IN_PORT_ONLY;
+            */
+            egressMode = FAL_EG_UNMODIFIED;
+            ingressMode = FAL_1Q_DISABLE;
+        }
+        /*
+        priv->chip->setup_port(priv, i, egress, ingress, portmask[i], pvid);
+        */
+        fal_port_1qmode_set(0, i, ingressMode);
+        fal_port_egvlanmode_set(0, i, egressMode);
+        fal_port_default_cvid_set(0, i, pvid);
+        fal_portvlan_member_update(0, i, portmask[i]);
+    }
+
+    mutex_unlock(&priv->reg_mutex);
+
+    return 0;
+}
+
+int
+qca_ar8327_sw_reset_switch(struct switch_dev *dev)
+{
+    struct qca_phy_priv *priv = qca_phy_priv_get(dev);
+    int i;
+
+    mutex_lock(&priv->reg_mutex);
+
+    priv->vlan = 0;
+    memset(priv->vlan_table, 0, sizeof(a_uint8_t) * AR8327_MAX_VLANS);
+    priv->vlan_tagged = 0;
+    memset(priv->pvid, 0, sizeof(a_uint16_t) * AR8327_NUM_PORTS);
+
+    for (i = 0; i < AR8327_MAX_VLANS; i++)
+        priv->vlan_id[i] = i;
+
+	/* Configure all ports
+	for (i = 0; i < dev->ports; i++)
+		priv->chip->init_port(priv, i);
+
+	priv->chip->init_globals(priv); */
+
+    mutex_unlock(&priv->reg_mutex);
+
+    return qca_ar8327_sw_hw_apply(dev);
+}
+
+
diff --git a/src/shell/shell_config.c b/src/shell/shell_config.c
index f63345b..9e3f52b 100755
--- a/src/shell/shell_config.c
+++ b/src/shell/shell_config.c
@@ -433,8 +433,8 @@
     {

         "stp", "config STP",

         {

-            {"portState", "set", "set STP state of a port", "st_id <port_id> <disable|block|listen|learn|forward>", SW_API_STP_PT_STATE_SET, NULL},

-            {"portState", "get", "get STP state of a port", "st_id <port_id>", SW_API_STP_PT_STATE_GET, NULL},

+            {"portState", "set", "set STP state of a port", "<st_id> <port_id> <disable|block|listen|learn|forward>", SW_API_STP_PT_STATE_SET, NULL},

+            {"portState", "get", "get STP state of a port", "<st_id> <port_id>", SW_API_STP_PT_STATE_GET, NULL},

             {NULL, NULL, NULL, NULL, (int)NULL, NULL}/*end of desc*/

         },

     },

diff --git a/src/shell/shell_io.c b/src/shell/shell_io.c
index 6c23472..a4e9242 100755
--- a/src/shell/shell_io.c
+++ b/src/shell/shell_io.c
@@ -6745,6 +6745,7 @@
     do

     {

         cmd = get_sub_cmd("vid low", NULL);

+        SW_RTN_ON_NULL_PARAM(cmd);

 

         if (!strncasecmp(cmd, "quit", 4))

         {

@@ -6768,6 +6769,7 @@
     do

     {

         cmd = get_sub_cmd("vid high", NULL);

+        SW_RTN_ON_NULL_PARAM(cmd);

 

         if (!strncasecmp(cmd, "quit", 4))

         {