Merge "[qca-ssdk]: fix kw issue"
diff --git a/config b/config
index dcd2659..814df35 100755
--- a/config
+++ b/config
@@ -222,7 +222,9 @@
 IN_MALIBU_PHY=TRUE
 ifeq (ALL_CHIP, $(CHIP_TYPE))
 IN_AQUANTIA_PHY=TRUE
+IN_QCA803X_PHY=TRUE
 else
+IN_QCA803X_PHY=FALSE
 IN_AQUANTIA_PHY=FALSE
 endif
 ifeq ($(SFE_FEATURE), enable)
diff --git a/include/common/sw_config.h b/include/common/sw_config.h
index 60e2a8f..d1c4f69 100755
--- a/include/common/sw_config.h
+++ b/include/common/sw_config.h
@@ -22,7 +22,7 @@
 #endif /* __cplusplus */
 
 #define SW_MAX_NR_DEV      3
-#define SW_MAX_NR_PORT     32
+#define SW_MAX_NR_PORT     16
 
 #ifdef HSL_STANDALONG
 #define HSL_LOCAL
diff --git a/include/hsl/isis/isis_api.h b/include/hsl/isis/isis_api.h
index f241327..7fbc03f 100755
--- a/include/hsl/isis/isis_api.h
+++ b/include/hsl/isis/isis_api.h
@@ -61,7 +61,9 @@
     SW_API_DEF(SW_API_PT_LINK_MODE_GET, isis_port_link_forcemode_get), \
     SW_API_DEF(SW_API_PT_LINK_STATUS_GET, isis_port_link_status_get), \
     SW_API_DEF(SW_API_PT_MAC_LOOPBACK_SET, isis_port_mac_loopback_set), \
-    SW_API_DEF(SW_API_PT_MAC_LOOPBACK_GET, isis_port_mac_loopback_get),
+    SW_API_DEF(SW_API_PT_MAC_LOOPBACK_GET, isis_port_mac_loopback_get), \
+    SW_API_DEF(SW_API_PT_8023AZ_SET, isis_port_8023az_set), \
+    SW_API_DEF(SW_API_PT_8023AZ_GET, isis_port_8023az_get),
 
 #define PORTCONTROL_API_PARAM \
     SW_API_DESC(SW_API_PT_DUPLEX_GET) \
@@ -102,7 +104,9 @@
     SW_API_DESC(SW_API_PT_LINK_MODE_GET) \
     SW_API_DESC(SW_API_PT_LINK_STATUS_GET) \
     SW_API_DESC(SW_API_PT_MAC_LOOPBACK_SET) \
-    SW_API_DESC(SW_API_PT_MAC_LOOPBACK_GET)
+    SW_API_DESC(SW_API_PT_MAC_LOOPBACK_GET) \
+    SW_API_DESC(SW_API_PT_8023AZ_SET) \
+    SW_API_DESC(SW_API_PT_8023AZ_GET)
 #else
 #define PORTCONTROL_API
 #define PORTCONTROL_API_PARAM
diff --git a/include/hsl/isis/isis_port_ctrl.h b/include/hsl/isis/isis_port_ctrl.h
index da567e7..dd136d6 100755
--- a/include/hsl/isis/isis_port_ctrl.h
+++ b/include/hsl/isis/isis_port_ctrl.h
@@ -208,6 +208,13 @@
     HSL_LOCAL sw_error_t
     isis_port_mac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable);
 
+    HSL_LOCAL sw_error_t
+    isis_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable);
+
+    HSL_LOCAL sw_error_t
+    isis_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable);
+
+
 #endif
 
 #ifdef __cplusplus
diff --git a/include/hsl/isisc/isisc_api.h b/include/hsl/isisc/isisc_api.h
index ec1ddc8..4e9d753 100755
--- a/include/hsl/isisc/isisc_api.h
+++ b/include/hsl/isisc/isisc_api.h
@@ -61,7 +61,9 @@
     SW_API_DEF(SW_API_PT_LINK_MODE_GET, isisc_port_link_forcemode_get), \
     SW_API_DEF(SW_API_PT_LINK_STATUS_GET, isisc_port_link_status_get), \
     SW_API_DEF(SW_API_PT_MAC_LOOPBACK_SET, isisc_port_mac_loopback_set), \
-    SW_API_DEF(SW_API_PT_MAC_LOOPBACK_GET, isisc_port_mac_loopback_get),
+    SW_API_DEF(SW_API_PT_MAC_LOOPBACK_GET, isisc_port_mac_loopback_get), \
+    SW_API_DEF(SW_API_PT_8023AZ_SET, isisc_port_8023az_set), \
+    SW_API_DEF(SW_API_PT_8023AZ_GET, isisc_port_8023az_get),
 
 #define PORTCONTROL_API_PARAM \
     SW_API_DESC(SW_API_PT_DUPLEX_GET) \
@@ -102,7 +104,9 @@
     SW_API_DESC(SW_API_PT_LINK_MODE_GET) \
     SW_API_DESC(SW_API_PT_LINK_STATUS_GET) \
     SW_API_DESC(SW_API_PT_MAC_LOOPBACK_SET) \
-    SW_API_DESC(SW_API_PT_MAC_LOOPBACK_GET)
+    SW_API_DESC(SW_API_PT_MAC_LOOPBACK_GET) \
+    SW_API_DESC(SW_API_PT_8023AZ_SET) \
+    SW_API_DESC(SW_API_PT_8023AZ_GET)
 #else
 #define PORTCONTROL_API
 #define PORTCONTROL_API_PARAM
diff --git a/include/hsl/isisc/isisc_port_ctrl.h b/include/hsl/isisc/isisc_port_ctrl.h
index 7378e9d..19fc087 100755
--- a/include/hsl/isisc/isisc_port_ctrl.h
+++ b/include/hsl/isisc/isisc_port_ctrl.h
@@ -210,6 +210,13 @@
 
     HSL_LOCAL sw_error_t
     isisc_port_mac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable);
+
+    HSL_LOCAL sw_error_t
+    isisc_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable);
+
+    HSL_LOCAL sw_error_t
+    isisc_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable);
+
 #endif
 
 #ifdef __cplusplus
diff --git a/include/hsl/phy/aquantia_phy.h b/include/hsl/phy/aquantia_phy.h
index 3f4240d..e5121c3 100755
--- a/include/hsl/phy/aquantia_phy.h
+++ b/include/hsl/phy/aquantia_phy.h
@@ -77,6 +77,7 @@
 #define AQUANTIA_2500M_LOOPBACK  0x0004
 #define AQUANTIA_5000M_LOOPBACK  0x0005
 #define AQUANTIA_POWER_SAVE  0x0800
+#define AQUANTIA_POWER_DOWN  0x0800
 #define AQUANTIA_STATUS_LINK 0x0004
 #define AQUANTIA_PHY_USX_AUTONEG_ENABLE	0x8
   /* FDX =1, half duplex =0 */
diff --git a/include/hsl/phy/f1_phy.h b/include/hsl/phy/f1_phy.h
index f93d5b0..b5a4f02 100755
--- a/include/hsl/phy/f1_phy.h
+++ b/include/hsl/phy/f1_phy.h
@@ -44,7 +44,9 @@
 #define F1_PHY_CDT_STATUS                   28
 #define F1_DEBUG_PORT_ADDRESS               29
 #define F1_DEBUG_PORT_DATA                  30
-
+#define F1_PHY_8023AZ_EEE_CTRL	0x3c
+#define F1_PHY_MMD7_NUM	7
+#define F1_PHY_AZ_ENABLE	0x6
 
     /*debug port*/
 #define F1_DEBUG_PORT_RGMII_MODE            18
@@ -454,7 +456,14 @@
     f1_phy_intr_status_get(a_uint32_t dev_id, a_uint32_t phy_id,
                            a_uint32_t * intr_status_flag);
 
-	int f1_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp);
+    sw_error_t
+    f1_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable);
+
+    sw_error_t
+    f1_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable);
+
+    int
+    f1_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp);
 
 #ifdef __cplusplus
 }
diff --git a/include/hsl/phy/hsl_phy.h b/include/hsl/phy/hsl_phy.h
index f0ffba9..63d0c0f 100755
--- a/include/hsl/phy/hsl_phy.h
+++ b/include/hsl/phy/hsl_phy.h
@@ -285,6 +285,7 @@
 	F2_PHY_CHIP,
 	MALIBU_PHY_CHIP,
 	AQUANTIA_PHY_CHIP,
+	QCA803X_PHY_CHIP,
 	MAX_PHY_CHIP,
 } phy_type_t;
 
@@ -296,6 +297,7 @@
 
 #define MALIBU5PORT_PHY 0x004DD0B1
 #define MALIBU2PORT_PHY 0x004DD0B2
+#define QCA8033_PHY 0x004DD074
 #define F1V1_PHY 0x004DD033
 #define F1V2_PHY 0x004DD034
 #define F1V3_PHY 0x004DD035
@@ -304,6 +306,7 @@
 #define AQUANTIA_PHY_107 0x03a1b4e2
 #define AQUANTIA_PHY_109 0x03a1b502
 #define AQUANTIA_PHY_111 0x03a1b610
+#define AQUANTIA_PHY_112 0x03a1b660
 #define PHY_805XV2 0x004DD082
 #define PHY_805XV1 0x004DD081
 
diff --git a/include/hsl/phy/qca803x_phy.h b/include/hsl/phy/qca803x_phy.h
new file mode 100755
index 0000000..d1630e9
--- /dev/null
+++ b/include/hsl/phy/qca803x_phy.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * 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.
+ */
+
+#ifndef _QCA803X_PHY_H_
+#define _QCA803X_PHY_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif				/* __cplusplus */
+
+#define QCA803X_COMMON_CTRL  0x1040
+#define QCA803X_10M_LOOPBACK  0x4100
+#define QCA803X_100M_LOOPBACK  0x6100
+#define QCA803X_1000M_LOOPBACK  0x4140
+
+  /* PHY Registers */
+#define QCA803X_PHY_CONTROL                      0
+#define QCA803X_PHY_STATUS                       1
+#define QCA803X_PHY_SPEC_STATUS                  17
+
+#define QCA803X_PHY_ID1                          2
+#define QCA803X_PHY_ID2                          3
+#define QCA803X_AUTONEG_ADVERT                   4
+#define QCA803X_1000BASET_CONTROL                9
+#define QCA803X_1000BASET_STATUS                 10
+#define QCA803X_MMD_CTRL_REG                     13
+#define QCA803X_MMD_DATA_REG                     14
+#define QCA803X_PHY_INTR_MASK                    18
+#define QCA803X_PHY_INTR_STATUS                  19
+#define QCA803X_PHY_CDT_CONTROL                  22
+#define QCA803X_PHY_CDT_STATUS                   28
+#define QCA803X_DEBUG_PORT_ADDRESS               29
+#define QCA803X_DEBUG_PORT_DATA                  30
+
+#define QCA803X_DEBUG_PHY_HIBERNATION_CTRL  0xb
+#define QCA803X_DEBUG_PHY_POWER_SAVING_CTRL  0x29
+#define QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL       0x3c
+#define QCA803X_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL       0x805a
+#define QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL1   0x804a
+#define QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL2   0x804b
+#define QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL3   0x804c
+#define QCA803X_PHY_MMD3_WOL_CTRL  0x8012
+#define QCA803X_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL       0x804e
+#define QCA803X_PHY_MMD3_ADDR_8023AZ_CLD_CTRL       0x8007
+
+  /* PHY Registers Field */
+#define QCA803X_STATUS_LINK_PASS                 0x0400
+
+  /* Control Register fields  offset:0 */
+  /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define QCA803X_CTRL_SPEED_MSB                   0x0040
+
+  /* Collision test enable */
+#define QCA803X_CTRL_COLL_TEST_ENABLE            0x0080
+
+  /* FDX =1, half duplex =0 */
+#define QCA803X_CTRL_FULL_DUPLEX                 0x0100
+
+  /* Restart auto negotiation */
+#define QCA803X_CTRL_RESTART_AUTONEGOTIATION     0x0200
+
+  /* Power down */
+#define QCA803X_CTRL_POWER_DOWN                  0x0800
+
+  /* Auto Neg Enable */
+#define QCA803X_CTRL_AUTONEGOTIATION_ENABLE      0x1000
+
+  /* Local Loopback Enable */
+#define QCA803X_LOCAL_LOOPBACK_ENABLE      0x4000
+
+  /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define QCA803X_CTRL_SPEED_LSB                   0x2000
+
+  /* 0 = normal, 1 = loopback */
+#define QCA803X_CTRL_LOOPBACK                    0x4000
+#define QCA803X_CTRL_SOFTWARE_RESET              0x8000
+
+#define QCA803X_CTRL_SPEED_MASK                  0x2040
+#define QCA803X_CTRL_SPEED_1000                  0x0040
+#define QCA803X_CTRL_SPEED_100                   0x2000
+#define QCA803X_CTRL_SPEED_10                    0x0000
+
+#define QCA803X_RESET_DONE(phy_control)                   \
+    (((phy_control) & (QCA803X_CTRL_SOFTWARE_RESET)) == 0)
+
+  /* Auto-Negotiation Advertisement register. offset:4 */
+#define QCA803X_ADVERTISE_SELECTOR_FIELD         0x0001
+
+  /* 10T   Half Duplex Capable */
+#define QCA803X_ADVERTISE_10HALF                 0x0020
+
+  /* 10T   Full Duplex Capable */
+#define QCA803X_ADVERTISE_10FULL                 0x0040
+
+  /* 100TX Half Duplex Capable */
+#define QCA803X_ADVERTISE_100HALF                0x0080
+
+  /* 100TX Full Duplex Capable */
+#define QCA803X_ADVERTISE_100FULL                0x0100
+
+  /* 100T4 Capable */
+#define QCA803X_ADVERTISE_100T4                  0x0200
+
+  /* Pause operation desired */
+#define QCA803X_ADVERTISE_PAUSE                  0x0400
+
+  /* Asymmetric Pause Direction bit */
+#define QCA803X_ADVERTISE_ASYM_PAUSE             0x0800
+
+  /* Remote Fault detected */
+#define QCA803X_ADVERTISE_REMOTE_FAULT           0x2000
+
+  /* 100TX Half Duplex Capable */
+#define QCA803X_ADVERTISE_1000HALF                0x0100
+
+  /* 100TX Full Duplex Capable */
+#define QCA803X_ADVERTISE_1000FULL                0x0200
+
+#define QCA803X_ADVERTISE_ALL \
+    (QCA803X_ADVERTISE_10HALF | QCA803X_ADVERTISE_10FULL | \
+     QCA803X_ADVERTISE_100HALF | QCA803X_ADVERTISE_100FULL | \
+     QCA803X_ADVERTISE_1000FULL)
+
+#define QCA803X_ADVERTISE_MEGA_ALL \
+    (QCA803X_ADVERTISE_10HALF | QCA803X_ADVERTISE_10FULL | \
+     QCA803X_ADVERTISE_100HALF | QCA803X_ADVERTISE_100FULL)
+
+#define QCA803X_BX_ADVERTISE_1000FULL                0x0020
+#define QCA803X_BX_ADVERTISE_1000HALF                0x0040
+#define QCA803X_BX_ADVERTISE_PAUSE                      0x0080
+#define QCA803X_BX_ADVERTISE_ASYM_PAUSE           0x0100
+
+#define QCA803X_BX_ADVERTISE_ALL \
+    (QCA803X_BX_ADVERTISE_ASYM_PAUSE | QCA803X_BX_ADVERTISE_PAUSE | \
+     QCA803X_BX_ADVERTISE_1000HALF | QCA803X_BX_ADVERTISE_1000FULL)
+
+  /* 1=Duplex 0=Half Duplex */
+#define QCA803X_STATUS_FULL_DUPLEX               0x2000
+
+  /* Speed, bits 14:15 */
+#define QCA803X_STATUS_SPEED                    0xC000
+#define QCA803X_STATUS_SPEED_MASK               0xC000
+
+  /* 00=10Mbs */
+#define QCA803X_STATUS_SPEED_10MBS              0x0000
+
+  /* 01=100Mbs */
+#define QCA803X_STATUS_SPEED_100MBS             0x4000
+
+  /* 10=1000Mbs */
+#define QCA803X_STATUS_SPEED_1000MBS            0x8000
+
+  /*QCA803X interrupt flag */
+#define QCA803X_INTR_SPEED_CHANGE              0x4000
+#define QCA803X_INTR_DUPLEX_CHANGE             0x2000
+#define QCA803X_INTR_STATUS_UP_CHANGE          0x0400
+#define QCA803X_INTR_STATUS_DOWN_CHANGE        0x0800
+#define QCA803X_INTR_BX_FX_STATUS_DOWN_CHANGE        0x0100
+#define QCA803X_INTR_BX_FX_STATUS_UP_CHANGE        0x0080
+#define QCA803X_INTR_MEDIA_STATUS_CHANGE             0x1000
+
+sw_error_t
+qca803x_phy_set_duplex (a_uint32_t dev_id, a_uint32_t phy_id,
+		   fal_port_duplex_t duplex);
+
+sw_error_t
+qca803x_phy_get_duplex (a_uint32_t dev_id, a_uint32_t phy_id,
+		   fal_port_duplex_t * duplex);
+
+sw_error_t
+qca803x_phy_set_speed (a_uint32_t dev_id, a_uint32_t phy_id,
+		  fal_port_speed_t speed);
+
+sw_error_t
+qca803x_phy_get_speed (a_uint32_t dev_id, a_uint32_t phy_id,
+		  fal_port_speed_t * speed);
+
+sw_error_t
+qca803x_phy_restart_autoneg (a_uint32_t dev_id, a_uint32_t phy_id);
+
+sw_error_t
+qca803x_phy_enable_autoneg (a_uint32_t dev_id, a_uint32_t phy_id);
+
+a_bool_t
+qca803x_phy_get_link_status (a_uint32_t dev_id, a_uint32_t phy_id);
+
+sw_error_t
+qca803x_phy_set_autoneg_adv (a_uint32_t dev_id, a_uint32_t phy_id,
+			a_uint32_t autoneg);
+
+sw_error_t
+qca803x_phy_get_autoneg_adv (a_uint32_t dev_id, a_uint32_t phy_id,
+			a_uint32_t * autoneg);
+
+a_bool_t qca803x_phy_autoneg_status (a_uint32_t dev_id, a_uint32_t phy_id);
+
+sw_error_t
+qca803x_phy_intr_mask_set (a_uint32_t dev_id, a_uint32_t phy_id,
+		      a_uint32_t intr_mask_flag);
+
+sw_error_t
+qca803x_phy_intr_mask_get (a_uint32_t dev_id, a_uint32_t phy_id,
+		      a_uint32_t * intr_mask_flag);
+
+sw_error_t
+qca803x_phy_intr_status_get (a_uint32_t dev_id, a_uint32_t phy_id,
+			a_uint32_t * intr_status_flag);
+
+sw_error_t
+qca803x_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id,
+		a_uint16_t * org_id, a_uint16_t * rev_id);
+
+int qca803x_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp);
+
+#ifdef __cplusplus
+}
+#endif				/* __cplusplus */
+#endif				/* _qca803x_PHY_H_ */
diff --git a/include/init/ssdk_init.h b/include/init/ssdk_init.h
index d329de4..169646e 100755
--- a/include/init/ssdk_init.h
+++ b/include/init/ssdk_init.h
@@ -32,6 +32,7 @@
 #define SSDK_L0SCHEDULER_UCASTQ_CFG_MAX	256
 #define SSDK_L1SCHEDULER_CFG_MAX	64
 #define SSDK_SP_MAX_PRIORITY		8
+#define SSDK_MAX_FRAME_SIZE	16383
 
 #define PORT_GMAC_TYPE	1
 #define PORT_XGMAC_TYPE	2
diff --git a/include/init/ssdk_plat.h b/include/init/ssdk_plat.h
old mode 100644
new mode 100755
index fc38c27..46e0ff1
--- a/include/init/ssdk_plat.h
+++ b/include/init/ssdk_plat.h
@@ -257,15 +257,15 @@
 	struct delayed_work mib_dwork;
 	/*qm_err_check*/
 	struct mutex 	qm_lock;
-	a_uint32_t port_link_down[AR8327_NUM_PORTS];
-	a_uint32_t port_link_up[AR8327_NUM_PORTS];
-	a_uint32_t port_old_link[AR8327_NUM_PORTS];
-	a_uint32_t port_old_speed[AR8327_NUM_PORTS];
-	a_uint32_t port_old_duplex[AR8327_NUM_PORTS];
-	a_uint32_t port_old_phy_status[AR8327_NUM_PORTS];
-	a_uint32_t port_qm_buf[AR8327_NUM_PORTS];
-	a_uint32_t port_old_tx_flowctrl[AR8327_NUM_PORTS];
-	a_uint32_t port_old_rx_flowctrl[AR8327_NUM_PORTS];
+	a_uint32_t port_link_down[SW_MAX_NR_PORT];
+	a_uint32_t port_link_up[SW_MAX_NR_PORT];
+	a_uint32_t port_old_link[SW_MAX_NR_PORT];
+	a_uint32_t port_old_speed[SW_MAX_NR_PORT];
+	a_uint32_t port_old_duplex[SW_MAX_NR_PORT];
+	a_uint32_t port_old_phy_status[SW_MAX_NR_PORT];
+	a_uint32_t port_qm_buf[SW_MAX_NR_PORT];
+	a_uint32_t port_old_tx_flowctrl[SW_MAX_NR_PORT];
+	a_uint32_t port_old_rx_flowctrl[SW_MAX_NR_PORT];
 	struct delayed_work qm_dwork_polling;
 	struct work_struct	 intr_workqueue;
 	/*qm_err_check end*/
diff --git a/make/linux_opt.mk b/make/linux_opt.mk
index 3a28661..323af72 100755
--- a/make/linux_opt.mk
+++ b/make/linux_opt.mk
@@ -160,6 +160,10 @@
   MODULE_CFLAG += -DIN_AQUANTIA_PHY
 endif
 
+ifeq (TRUE, $(IN_QCA803X_PHY))
+  MODULE_CFLAG += -DIN_QCA803X_PHY
+endif
+
 ifeq (TRUE, $(IN_VSI))
   MODULE_CFLAG += -DIN_VSI
 endif
diff --git a/src/hsl/dess/dess_interface_ctrl.c b/src/hsl/dess/dess_interface_ctrl.c
index d9aac95..f6396f9 100755
--- a/src/hsl/dess/dess_interface_ctrl.c
+++ b/src/hsl/dess/dess_interface_ctrl.c
@@ -28,6 +28,7 @@
 #define DESS_PHY_MODE_PHY_ID  4
 #define DESS_LPI_PORT1_OFFSET 4
 #define DESS_LPI_BIT_STEP     2
+#define DESS_LPI_ENABLE     3
 
 #define DESS_MAC4  4
 #define DESS_MAC5  5
@@ -36,7 +37,7 @@
 _dess_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable)
 {
     sw_error_t rv = SW_OK;
-    a_uint32_t reg = 0, field, offset, device_id, rev_id, reverse = 0;
+    a_uint32_t reg = 0, field, offset, device_id;
 
     HSL_REG_ENTRY_GET(rv, dev_id, MASK_CTL, 0,
                       (a_uint8_t *) (&reg), sizeof (a_uint32_t));
@@ -48,25 +49,6 @@
         return SW_NOT_SUPPORTED;
     }
 
-    SW_GET_FIELD_BY_REG(MASK_CTL, REV_ID, rev_id, reg);
-    if (DESS_DEVICE_ID == rev_id)
-    {
-        reverse = 0;
-    }
-    else
-    {
-        reverse = 1;
-    }
-
-    if (rev_id == 0)
-    {
-        reverse = 1;
-    }
-    else
-    {
-        reverse = 0;
-    }
-
     if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
     {
         return SW_BAD_PARAM;
@@ -78,7 +60,7 @@
 
     if (A_TRUE == enable)
     {
-        field  = 1;
+        field  = DESS_LPI_ENABLE;
     }
     else if (A_FALSE == enable)
     {
@@ -89,13 +71,8 @@
         return SW_BAD_PARAM;
     }
 
-    if (reverse)
-    {
-        field = (~field) & 0x1UL;
-    }
-
     offset = (port_id - 1) * DESS_LPI_BIT_STEP + DESS_LPI_PORT1_OFFSET;
-    reg &= (~(0x1UL << offset));
+    reg &= (~(DESS_LPI_ENABLE << offset));
     reg |= (field << offset);
 
     HSL_REG_ENTRY_SET(rv, dev_id, EEE_CTL, 0,
@@ -107,7 +84,7 @@
 _dess_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable)
 {
     sw_error_t rv = SW_OK;
-    a_uint32_t reg = 0, field, offset, device_id, rev_id, reverse = 0;
+    a_uint32_t reg = 0, field, offset, device_id;
 
     HSL_REG_ENTRY_GET(rv, dev_id, MASK_CTL, 0,
                       (a_uint8_t *) (&reg), sizeof (a_uint32_t));
@@ -119,25 +96,6 @@
         return SW_NOT_SUPPORTED;
     }
 
-    SW_GET_FIELD_BY_REG(MASK_CTL, REV_ID, rev_id, reg);
-    if (DESS_DEVICE_ID == rev_id)
-    {
-        reverse = 0;
-    }
-    else
-    {
-        reverse = 1;
-    }
-
-    if (rev_id == 0)
-    {
-        reverse = 1;
-    }
-    else
-    {
-        reverse = 0;
-    }
-
     if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
     {
         return SW_BAD_PARAM;
@@ -148,14 +106,9 @@
     SW_RTN_ON_ERROR(rv);
 
     offset = (port_id - 1) * DESS_LPI_BIT_STEP + DESS_LPI_PORT1_OFFSET;
-    field = (reg >> offset) & 0x1;
+    field = (reg >> offset) & 0x3;
 
-    if (reverse)
-    {
-        field = (~field) & 0x1UL;
-    }
-
-    if (field)
+    if (field == DESS_LPI_ENABLE)
     {
         *enable = A_TRUE;
     }
diff --git a/src/hsl/isis/isis_port_ctrl.c b/src/hsl/isis/isis_port_ctrl.c
index 6e2b781..00531cc 100755
--- a/src/hsl/isis/isis_port_ctrl.c
+++ b/src/hsl/isis/isis_port_ctrl.c
@@ -705,6 +705,57 @@
 
     return rv;
 }
+static sw_error_t
+_isis_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable)
+{
+    sw_error_t rv;
+    a_uint32_t phy_id = 0;
+    hsl_phy_ops_t *phy_drv;
+
+    HSL_DEV_ID_CHECK (dev_id);
+    if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY))
+    {
+        return SW_BAD_PARAM;
+    }
+
+    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id));
+    if (NULL == phy_drv->phy_8023az_set)
+        return SW_NOT_SUPPORTED;
+
+    rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id);
+    SW_RTN_ON_ERROR (rv);
+
+    rv = phy_drv->phy_8023az_set (dev_id, phy_id, enable);
+
+    return rv;
+}
+
+static sw_error_t
+_isis_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id,
+		       a_bool_t * enable)
+{
+    sw_error_t rv;
+    a_uint32_t phy_id = 0;
+    hsl_phy_ops_t *phy_drv;
+
+    HSL_DEV_ID_CHECK (dev_id);
+
+    if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY))
+    {
+        return SW_BAD_PARAM;
+    }
+
+    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id));
+    if (NULL == phy_drv->phy_8023az_get)
+        return SW_NOT_SUPPORTED;
+
+    rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id);
+    SW_RTN_ON_ERROR (rv);
+
+    rv = phy_drv->phy_8023az_get (dev_id, phy_id, enable);
+
+    return rv;
+}
 
 static sw_error_t
 _isis_port_rxhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id,
@@ -1830,6 +1881,42 @@
     HSL_API_UNLOCK;
     return rv;
 }
+/**
+ * @brief Set 802.3az status on a particular port.
+ * @param[in] dev_id device id
+ * @param[in] port_id port id
+ * @param[out] enable A_TRUE or A_FALSE
+ * @return SW_OK or error code
+ */
+HSL_LOCAL sw_error_t
+isis_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable)
+{
+    sw_error_t rv;
+
+    HSL_API_LOCK;
+    rv = _isis_port_8023az_set (dev_id, port_id, enable);
+    HSL_API_UNLOCK;
+    return rv;
+}
+
+/**
+ * @brief Get 8023az status on a particular port.
+ * @param[in] dev_id device id
+ * @param[in] port_id port id
+ * @param[out] enable A_TRUE or A_FALSE
+ * @return SW_OK or error code
+ */
+HSL_LOCAL sw_error_t
+isis_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id,
+		      a_bool_t * enable)
+{
+    sw_error_t rv;
+
+    HSL_API_LOCK;
+    rv = _isis_port_8023az_get (dev_id, port_id, enable);
+    HSL_API_UNLOCK;
+    return rv;
+}
 
 /**
  * @brief Set status of Atheros header packets parsed on a particular port.
@@ -2255,6 +2342,8 @@
         p_api->port_link_status_get = isis_port_link_status_get;
         p_api->port_mac_loopback_set = isis_port_mac_loopback_set;
         p_api->port_mac_loopback_get = isis_port_mac_loopback_get;
+        p_api->port_8023az_set = isis_port_8023az_set;
+        p_api->port_8023az_get = isis_port_8023az_get;
     }
 #endif
 
diff --git a/src/hsl/isisc/isisc_port_ctrl.c b/src/hsl/isisc/isisc_port_ctrl.c
index e260cd5..dc7316e 100755
--- a/src/hsl/isisc/isisc_port_ctrl.c
+++ b/src/hsl/isisc/isisc_port_ctrl.c
@@ -751,6 +751,59 @@
 
     return rv;
 }
+
+static sw_error_t
+_isisc_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable)
+{
+    sw_error_t rv;
+    a_uint32_t phy_id = 0;
+    hsl_phy_ops_t *phy_drv;
+
+    HSL_DEV_ID_CHECK (dev_id);
+    if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY))
+    {
+        return SW_BAD_PARAM;
+    }
+
+    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id));
+    if (NULL == phy_drv->phy_8023az_set)
+        return SW_NOT_SUPPORTED;
+
+    rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id);
+    SW_RTN_ON_ERROR (rv);
+
+    rv = phy_drv->phy_8023az_set (dev_id, phy_id, enable);
+
+    return rv;
+}
+
+static sw_error_t
+_isisc_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id,
+		       a_bool_t * enable)
+{
+    sw_error_t rv;
+    a_uint32_t phy_id = 0;
+    hsl_phy_ops_t *phy_drv;
+
+    HSL_DEV_ID_CHECK (dev_id);
+
+    if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY))
+    {
+        return SW_BAD_PARAM;
+    }
+
+    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id));
+    if (NULL == phy_drv->phy_8023az_get)
+        return SW_NOT_SUPPORTED;
+
+    rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id);
+    SW_RTN_ON_ERROR (rv);
+
+    rv = phy_drv->phy_8023az_get (dev_id, phy_id, enable);
+
+    return rv;
+}
+
 #endif
 static sw_error_t
 _isisc_port_rxhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id,
@@ -1954,6 +2007,44 @@
     HSL_API_UNLOCK;
     return rv;
 }
+
+/**
+ * @brief Set 802.3az status on a particular port.
+ * @param[in] dev_id device id
+ * @param[in] port_id port id
+ * @param[out] enable A_TRUE or A_FALSE
+ * @return SW_OK or error code
+ */
+HSL_LOCAL sw_error_t
+isisc_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable)
+{
+    sw_error_t rv;
+
+    HSL_API_LOCK;
+    rv = _isisc_port_8023az_set (dev_id, port_id, enable);
+    HSL_API_UNLOCK;
+    return rv;
+}
+
+/**
+ * @brief Get 8023az status on a particular port.
+ * @param[in] dev_id device id
+ * @param[in] port_id port id
+ * @param[out] enable A_TRUE or A_FALSE
+ * @return SW_OK or error code
+ */
+HSL_LOCAL sw_error_t
+isisc_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id,
+		      a_bool_t * enable)
+{
+    sw_error_t rv;
+
+    HSL_API_LOCK;
+    rv = _isisc_port_8023az_get (dev_id, port_id, enable);
+    HSL_API_UNLOCK;
+    return rv;
+}
+
 #endif
 
 /**
@@ -2431,13 +2522,13 @@
 
         p_api->port_duplex_set = isisc_port_duplex_set;
         p_api->port_speed_set = isisc_port_speed_set;
-	p_api->port_flowctrl_set = isisc_port_flowctrl_set;
-	p_api->port_flowctrl_forcemode_set = isisc_port_flowctrl_forcemode_set;
-	p_api->port_duplex_get = isisc_port_duplex_get;
-	p_api->port_speed_get = isisc_port_speed_get;
-	p_api->port_autoneg_enable = isisc_port_autoneg_enable;
-	p_api->port_autoneg_restart = isisc_port_autoneg_restart;
-	p_api->port_autoneg_adv_set = isisc_port_autoneg_adv_set;
+        p_api->port_flowctrl_set = isisc_port_flowctrl_set;
+        p_api->port_flowctrl_forcemode_set = isisc_port_flowctrl_forcemode_set;
+        p_api->port_duplex_get = isisc_port_duplex_get;
+        p_api->port_speed_get = isisc_port_speed_get;
+        p_api->port_autoneg_enable = isisc_port_autoneg_enable;
+        p_api->port_autoneg_restart = isisc_port_autoneg_restart;
+        p_api->port_autoneg_adv_set = isisc_port_autoneg_adv_set;
         p_api->port_autoneg_status_get = isisc_port_autoneg_status_get;
         p_api->port_autoneg_adv_get = isisc_port_autoneg_adv_get;
 #ifndef IN_PORTCONTROL_MINI
@@ -2448,27 +2539,28 @@
         p_api->port_hibernate_set = isisc_port_hibernate_set;
         p_api->port_hibernate_get = isisc_port_hibernate_get;
         p_api->port_cdt = isisc_port_cdt;
-	p_api->port_rxhdr_mode_get = isisc_port_rxhdr_mode_get;
-	p_api->port_txhdr_mode_get = isisc_port_txhdr_mode_get;
-	p_api->header_type_get = isisc_header_type_get;
-	p_api->port_txmac_status_get = isisc_port_txmac_status_get;
-	p_api->port_rxmac_status_get = isisc_port_rxmac_status_get;
-
+        p_api->port_rxhdr_mode_get = isisc_port_rxhdr_mode_get;
+        p_api->port_txhdr_mode_get = isisc_port_txhdr_mode_get;
+        p_api->header_type_get = isisc_header_type_get;
+        p_api->port_txmac_status_get = isisc_port_txmac_status_get;
+        p_api->port_rxmac_status_get = isisc_port_rxmac_status_get;
+        p_api->port_8023az_set = isisc_port_8023az_set;
+        p_api->port_8023az_get = isisc_port_8023az_get;
 #endif
-	p_api->port_txfc_status_get = isisc_port_txfc_status_get;
-	p_api->port_rxhdr_mode_set = isisc_port_rxhdr_mode_set;
-	p_api->port_txhdr_mode_set = isisc_port_txhdr_mode_set;
-	p_api->header_type_set = isisc_header_type_set;
-	p_api->port_txmac_status_set = isisc_port_txmac_status_set;
-	p_api->port_rxmac_status_set = isisc_port_rxmac_status_set;
-	p_api->port_txfc_status_set = isisc_port_txfc_status_set;
-	p_api->port_rxfc_status_set = isisc_port_rxfc_status_set;
-	p_api->port_link_status_get = isisc_port_link_status_get;
-	p_api->port_rxfc_status_get = isisc_port_rxfc_status_get;
-	p_api->port_power_off = isisc_port_power_off;
-	p_api->port_power_on = isisc_port_power_on;
-	p_api->port_link_forcemode_set = isisc_port_link_forcemode_set;
-	p_api->port_link_forcemode_get = isisc_port_link_forcemode_get;
+        p_api->port_txfc_status_get = isisc_port_txfc_status_get;
+        p_api->port_rxhdr_mode_set = isisc_port_rxhdr_mode_set;
+        p_api->port_txhdr_mode_set = isisc_port_txhdr_mode_set;
+        p_api->header_type_set = isisc_header_type_set;
+        p_api->port_txmac_status_set = isisc_port_txmac_status_set;
+        p_api->port_rxmac_status_set = isisc_port_rxmac_status_set;
+        p_api->port_txfc_status_set = isisc_port_txfc_status_set;
+        p_api->port_rxfc_status_set = isisc_port_rxfc_status_set;
+        p_api->port_link_status_get = isisc_port_link_status_get;
+        p_api->port_rxfc_status_get = isisc_port_rxfc_status_get;
+        p_api->port_power_off = isisc_port_power_off;
+        p_api->port_power_on = isisc_port_power_on;
+        p_api->port_link_forcemode_set = isisc_port_link_forcemode_set;
+        p_api->port_link_forcemode_get = isisc_port_link_forcemode_get;
 #ifndef IN_PORTCONTROL_MINI
         p_api->port_bp_status_set = isisc_port_bp_status_set;
         p_api->port_bp_status_get = isisc_port_bp_status_get;
diff --git a/src/hsl/phy/Makefile b/src/hsl/phy/Makefile
index 4130fc9..2e7608d 100755
--- a/src/hsl/phy/Makefile
+++ b/src/hsl/phy/Makefile
@@ -42,6 +42,10 @@
 ifeq (TRUE, $(IN_AQUANTIA_PHY))
     SRC_LIST += aquantia_phy.c
 endif
+
+ifeq (TRUE, $(IN_QCA803X_PHY))
+    SRC_LIST += qca803x_phy.c
+endif
 SRC_LIST += hsl_phy.c
 
 ifeq (linux, $(OS))
diff --git a/src/hsl/phy/aquantia_phy.c b/src/hsl/phy/aquantia_phy.c
index e6b5eca..fcb06f2 100755
--- a/src/hsl/phy/aquantia_phy.c
+++ b/src/hsl/phy/aquantia_phy.c
@@ -963,6 +963,45 @@
 	return SW_OK;
 }
 
+/******************************************************************************
+*
+* aquantia_phy_off - power off the phy
+*
+* Power off the phy
+*/
+sw_error_t aquantia_phy_poweroff(a_uint32_t dev_id, a_uint32_t phy_id)
+{
+	a_uint16_t phy_data;
+	sw_error_t rv;
+
+	phy_data = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOABLE_REGISTERS,
+		AQUANTIA_GLOABLE_STANDARD_CONTROL1);
+	phy_data |= AQUANTIA_POWER_DOWN;
+	rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GLOABLE_REGISTERS,
+		AQUANTIA_GLOABLE_STANDARD_CONTROL1,phy_data);
+
+	return rv;
+}
+
+/******************************************************************************
+*
+* aquantia_phy_on - power on the phy
+*
+* Power on the phy
+*/
+sw_error_t aquantia_phy_poweron(a_uint32_t dev_id, a_uint32_t phy_id)
+{
+	a_uint16_t phy_data;
+	sw_error_t rv;
+
+	phy_data = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOABLE_REGISTERS,
+		AQUANTIA_GLOABLE_STANDARD_CONTROL1);
+	phy_data &= ~AQUANTIA_POWER_DOWN;
+	rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GLOABLE_REGISTERS,
+		AQUANTIA_GLOABLE_STANDARD_CONTROL1,phy_data);
+
+	return rv;
+}
 
 /******************************************************************************
 *
@@ -1043,6 +1082,8 @@
 	aquantia_phy_api_ops->phy_autoneg_adv_get = aquantia_phy_get_autoneg_adv;
 	aquantia_phy_api_ops->phy_powersave_set = aquantia_phy_set_powersave;
 	aquantia_phy_api_ops->phy_powersave_get = aquantia_phy_get_powersave;
+	aquantia_phy_api_ops->phy_power_on = aquantia_phy_poweron;
+	aquantia_phy_api_ops->phy_power_off = aquantia_phy_poweroff;
 	aquantia_phy_api_ops->phy_cdt = aquantia_phy_cdt;
 	aquantia_phy_api_ops->phy_link_status_get = aquantia_phy_get_link_status;
 	aquantia_phy_api_ops->phy_mdix_set = aquantia_phy_set_mdix;
diff --git a/src/hsl/phy/f1_phy.c b/src/hsl/phy/f1_phy.c
index 52fd170..07eb7bf 100755
--- a/src/hsl/phy/f1_phy.c
+++ b/src/hsl/phy/f1_phy.c
@@ -1296,6 +1296,59 @@
 
     return SW_OK;
 }
+/******************************************************************************
+*
+*f1_phy_set_8023az status
+*
+* get 8023az status
+*/
+
+sw_error_t
+f1_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable)
+{
+	a_uint16_t phy_data;
+
+	phy_data = f1_phy_mmd_read(dev_id, phy_id, F1_PHY_MMD7_NUM,
+				       F1_PHY_8023AZ_EEE_CTRL);
+	if (enable == A_TRUE) {
+		phy_data |= F1_PHY_AZ_ENABLE;
+
+		f1_phy_mmd_write(dev_id, phy_id, F1_PHY_MMD7_NUM,
+			     F1_PHY_8023AZ_EEE_CTRL, phy_data);
+	} else {
+		phy_data &= ~F1_PHY_AZ_ENABLE;
+
+		f1_phy_mmd_write(dev_id, phy_id, F1_PHY_MMD7_NUM,
+			     F1_PHY_8023AZ_EEE_CTRL, phy_data);
+	}
+
+	f1_phy_restart_autoneg(dev_id, phy_id);
+
+	return SW_OK;
+}
+
+/******************************************************************************
+*
+*f1_phy_get_8023az status
+*
+* get 8023az status
+*/
+sw_error_t
+f1_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable)
+{
+	a_uint16_t phy_data;
+
+	*enable = A_FALSE;
+
+	phy_data = f1_phy_mmd_read(dev_id, phy_id, F1_PHY_MMD7_NUM,
+				       F1_PHY_8023AZ_EEE_CTRL);
+
+	if ((phy_data & 0x6) == F1_PHY_AZ_ENABLE)
+		*enable = A_TRUE;
+
+	return SW_OK;
+}
+
 static int f1_phy_api_ops_init(void)
 {
 	int ret;
@@ -1337,6 +1390,8 @@
 	f1_phy_api_ops->phy_intr_mask_set = f1_phy_intr_mask_set;
 	f1_phy_api_ops->phy_intr_mask_get = f1_phy_intr_mask_get;
 	f1_phy_api_ops->phy_intr_status_get = f1_phy_intr_status_get;
+	f1_phy_api_ops->phy_8023az_set = f1_phy_set_8023az;
+	f1_phy_api_ops->phy_8023az_get = f1_phy_get_8023az;
 
 	ret = hsl_phy_api_ops_register(F1_PHY_CHIP, f1_phy_api_ops);
 
diff --git a/src/hsl/phy/hsl_phy.c b/src/hsl/phy/hsl_phy.c
index 75a3cde..7120f11 100755
--- a/src/hsl/phy/hsl_phy.c
+++ b/src/hsl/phy/hsl_phy.c
@@ -26,7 +26,11 @@
 #ifdef IN_AQUANTIA_PHY
 #include <aquantia_phy.h>
 #endif
+#ifdef IN_QCA803X_PHY
+#include <qca803x_phy.h>
+#endif
 
+#include "sw.h"
 #include "ssdk_plat.h"
 
 phy_info_t *phy_info[SW_MAX_NR_DEV] = {0};
@@ -55,6 +59,11 @@
 	#else
 	{AQUANTIA_PHY_CHIP, {0}, NULL, NULL},
 	#endif
+	#ifdef IN_QCA803X_PHY
+	{QCA803X_PHY_CHIP, {0}, NULL, qca803x_phy_init},
+	#else
+	{QCA803X_PHY_CHIP, {0}, NULL, NULL},
+	#endif
 	{MAX_PHY_CHIP, {0}, NULL, NULL}
 };
 sw_error_t hsl_phy_api_ops_register(phy_type_t phy_type, hsl_phy_ops_t * phy_api_ops)
@@ -140,8 +149,11 @@
 			else if ((phy_id == MALIBU2PORT_PHY) || (phy_id == MALIBU5PORT_PHY))
 				phytype = MALIBU_PHY_CHIP;
 			else if ((phy_id == AQUANTIA_PHY_107) || (phy_id == AQUANTIA_PHY_109) ||
-						(phy_id == AQUANTIA_PHY_111))
+				(phy_id == AQUANTIA_PHY_111) ||
+				(phy_id == AQUANTIA_PHY_112))
 				phytype = AQUANTIA_PHY_CHIP;
+			else if (phy_id == QCA8033_PHY)
+				phytype = QCA803X_PHY_CHIP;
 			else
 			{
 				SSDK_INFO("dev_id = %d, phy_adress = %d, phy_id = 0x%x phy type doesn't match\n",
@@ -255,7 +267,7 @@
 	{
 		if (phy_info[dev_id]->phy_type[i] == MALIBU_PHY_CHIP)
 		{
-			phy_drv = hsl_phy_api_ops_get (dev_id, i);
+			SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get (dev_id, i));
 			if (NULL == phy_drv->phy_serdes_reset)
 				return SW_NOT_SUPPORTED;
 			rv = phy_drv->phy_serdes_reset(dev_id);
@@ -276,7 +288,7 @@
 	{
 		if (phy_info[dev_id]->phy_type[i] == MALIBU_PHY_CHIP)
 		{
-			phy_drv = hsl_phy_api_ops_get (dev_id, i);
+			SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get (dev_id, i));
 			if (NULL == phy_drv->phy_interface_mode_set)
 				return SW_NOT_SUPPORTED;
 
diff --git a/src/hsl/phy/qca803x_phy.c b/src/hsl/phy/qca803x_phy.c
new file mode 100755
index 0000000..1578608
--- /dev/null
+++ b/src/hsl/phy/qca803x_phy.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * 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 "fal_port_ctrl.h"
+#include "hsl_api.h"
+#include "hsl.h"
+#include "qca803x_phy.h"
+#include "hsl_phy.h"
+#include <linux/kconfig.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
+#include <linux/switch.h>
+#else
+#include <net/switch.h>
+#endif
+#include "ssdk_plat.h"
+
+/******************************************************************************
+*
+* qca803x_phy_mii_read - mii register read
+*
+* mii register read
+*/
+a_uint16_t
+qca803x_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id)
+{
+	sw_error_t rv = SW_OK;
+	a_uint16_t phy_data = 0;
+
+	HSL_PHY_GET(rv, dev_id, phy_id, reg_id, &phy_data);
+	if (SW_OK != rv) {
+		return rv;
+	}
+
+	return phy_data;
+}
+
+/******************************************************************************
+*
+* qca803x_phy_mii_write - mii register write
+*
+* mii register write
+*/
+sw_error_t
+qca803x_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id,
+		       a_uint16_t reg_val)
+{
+	sw_error_t rv;
+
+	HSL_PHY_SET(rv, dev_id, phy_id, reg_id, reg_val);
+
+	return rv;
+
+}
+/******************************************************************************
+*
+* qca803x_phy_get_speed - Determines the speed of phy ports associated with the
+* specified device.
+*/
+
+sw_error_t
+qca803x_phy_get_speed(a_uint32_t dev_id, a_uint32_t phy_id,
+		     fal_port_speed_t * speed)
+{
+	a_uint16_t phy_data;
+	sw_error_t rv = SW_OK;
+
+	phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_STATUS);
+
+	switch (phy_data & QCA803X_STATUS_SPEED_MASK)
+	{
+		case QCA803X_STATUS_SPEED_1000MBS:
+			*speed = FAL_SPEED_1000;
+			break;
+		case QCA803X_STATUS_SPEED_100MBS:
+			*speed = FAL_SPEED_100;
+			break;
+		case QCA803X_STATUS_SPEED_10MBS:
+			*speed = FAL_SPEED_10;
+			break;
+		default:
+			return SW_READ_ERROR;
+	}
+
+	return rv;
+}
+
+/******************************************************************************
+*
+* qca803x_phy_get_duplex - Determines the speed of phy ports associated with the
+* specified device.
+*/
+sw_error_t
+qca803x_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id,
+		      fal_port_duplex_t * duplex)
+{
+	a_uint16_t phy_data;
+	sw_error_t rv = SW_OK;
+
+	phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_STATUS);
+
+	//read duplex
+	if (phy_data & QCA803X_STATUS_FULL_DUPLEX)
+		*duplex = FAL_FULL_DUPLEX;
+	else
+		*duplex = FAL_HALF_DUPLEX;
+
+	return rv;
+}
+
+/******************************************************************************
+*
+* qca803x_phy_reset - reset the phy
+*
+* reset the phy
+*/
+sw_error_t qca803x_phy_reset(a_uint32_t dev_id, a_uint32_t phy_id)
+{
+	a_uint16_t phy_data;
+	sw_error_t rv = SW_OK;
+
+	phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL);
+	rv = qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL,
+			     phy_data | QCA803X_CTRL_SOFTWARE_RESET);
+
+	return rv;
+}
+/******************************************************************************
+*
+* qca803x_phy_status - test to see if the specified phy link is alive
+*
+* RETURNS:
+*    A_TRUE  --> link is alive
+*    A_FALSE --> link is down
+*/
+a_bool_t qca803x_phy_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id)
+{
+	a_uint16_t phy_data;
+	a_bool_t rv = A_TRUE;
+	phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_STATUS);
+
+	if (phy_data & QCA803X_STATUS_LINK_PASS) {
+		rv = A_TRUE;
+	} else {
+		rv = A_FALSE;
+	}
+	return rv;
+}
+/******************************************************************************
+*
+* qca803x_restart_autoneg - restart the phy autoneg
+*
+*/
+sw_error_t qca803x_phy_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id)
+{
+	a_uint16_t phy_data = 0;
+	sw_error_t rv = SW_OK;
+
+	phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL);
+	phy_data |= QCA803X_CTRL_AUTONEGOTIATION_ENABLE;
+	rv = qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL,
+			     phy_data | QCA803X_CTRL_RESTART_AUTONEGOTIATION);
+
+	return rv;
+}
+/******************************************************************************
+*
+* qca803x_phy_enable_autonego
+*
+*/
+sw_error_t qca803x_phy_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id)
+{
+	a_uint16_t phy_data = 0;
+	sw_error_t rv = SW_OK;
+
+	phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL);
+	rv = qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL,
+			     phy_data | QCA803X_CTRL_AUTONEGOTIATION_ENABLE);
+
+	return rv;
+}
+
+/******************************************************************************
+*
+* qca803x_phy_set_speed - Determines the speed of phy ports associated with the
+* specified device.
+*/
+sw_error_t
+qca803x_phy_set_speed(a_uint32_t dev_id, a_uint32_t phy_id,
+		     fal_port_speed_t speed)
+{
+	a_uint16_t phy_data = 0;
+	fal_port_duplex_t old_duplex;
+	sw_error_t rv = SW_OK;
+
+	phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL);
+	rv = qca803x_phy_get_duplex(dev_id, phy_id, &old_duplex);
+	if(rv != SW_OK) {
+		return rv;
+	}
+
+	if (old_duplex == FAL_FULL_DUPLEX) {
+		phy_data |= QCA803X_CTRL_FULL_DUPLEX;
+		switch(speed)
+		{
+			case FAL_SPEED_1000:
+				phy_data |= QCA803X_CTRL_SPEED_1000;
+				phy_data &= ~QCA803X_CTRL_SPEED_100;
+				phy_data |= QCA803X_CTRL_AUTONEGOTIATION_ENABLE;
+				break;
+			case FAL_SPEED_100:
+			case FAL_SPEED_10:
+				phy_data &= ~QCA803X_CTRL_SPEED_1000;
+				phy_data &= ~QCA803X_CTRL_AUTONEGOTIATION_ENABLE;
+				if (FAL_SPEED_100 == speed) {
+					phy_data |= QCA803X_CTRL_SPEED_100;
+				} else {
+					phy_data &= ~QCA803X_CTRL_SPEED_100;
+				}
+				break;
+			default:
+				return SW_BAD_PARAM;
+		}
+	} else if (old_duplex == FAL_HALF_DUPLEX) {
+		phy_data &= ~QCA803X_CTRL_FULL_DUPLEX;
+		switch(speed)
+		{
+			case FAL_SPEED_100:
+			case FAL_SPEED_10:
+				phy_data &= ~QCA803X_CTRL_SPEED_1000;
+				phy_data &= ~QCA803X_CTRL_AUTONEGOTIATION_ENABLE;
+				if (FAL_SPEED_100 == speed) {
+					phy_data |= QCA803X_CTRL_SPEED_100;
+				} else {
+					phy_data &= ~QCA803X_CTRL_SPEED_100;
+				}
+				break;
+			case FAL_SPEED_1000:
+				phy_data |= QCA803X_CTRL_FULL_DUPLEX;
+				phy_data |= QCA803X_CTRL_SPEED_1000;
+				phy_data &= ~QCA803X_CTRL_SPEED_100;
+				phy_data |= QCA803X_CTRL_AUTONEGOTIATION_ENABLE;
+				break;
+			default:
+				return SW_BAD_PARAM;
+		}
+	} else {
+		return SW_FAIL;
+	}
+	rv = qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL, phy_data);
+
+	return rv;
+}
+
+/******************************************************************************
+*
+* qca803x_phy_set_duplex - Determines the speed of phy ports associated with the
+* specified device.
+*/
+sw_error_t
+qca803x_phy_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id,
+		      fal_port_duplex_t duplex)
+{
+	a_uint16_t phy_data = 0;
+	fal_port_speed_t old_speed;
+	sw_error_t rv = SW_OK;
+
+	phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL);
+	qca803x_phy_get_speed(dev_id, phy_id, &old_speed);
+	switch(old_speed)
+	{
+		case FAL_SPEED_1000:
+			phy_data |= QCA803X_CTRL_SPEED_1000;
+			phy_data &= ~QCA803X_CTRL_SPEED_100;
+			phy_data |= QCA803X_CTRL_AUTONEGOTIATION_ENABLE;
+			if (duplex == FAL_FULL_DUPLEX) {
+				phy_data |= QCA803X_CTRL_FULL_DUPLEX;
+			} else {
+				return SW_NOT_SUPPORTED;
+			}
+			break;
+		case FAL_SPEED_100:
+		case FAL_SPEED_10:
+			if(old_speed == FAL_SPEED_100) {
+				phy_data |= QCA803X_CTRL_SPEED_100;
+			} else {
+				phy_data &= ~QCA803X_CTRL_SPEED_100;
+			}
+			phy_data &= ~QCA803X_CTRL_SPEED_1000;
+			phy_data &= ~QCA803X_CTRL_AUTONEGOTIATION_ENABLE;
+			if (duplex == FAL_FULL_DUPLEX) {
+				phy_data |= QCA803X_CTRL_FULL_DUPLEX;
+			} else {
+				phy_data &= ~QCA803X_CTRL_FULL_DUPLEX;
+			}
+			break;
+		default:
+			return SW_FAIL;
+	}
+	rv = qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL, phy_data);
+
+	return rv;
+}
+
+/******************************************************************************
+*
+* qca803x_phy_get_phy_id - get the phy id
+*
+*/
+sw_error_t
+qca803x_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id,
+		      a_uint16_t * org_id, a_uint16_t * rev_id)
+{
+	*org_id = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_ID1);
+	*rev_id = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_ID2);
+
+	return SW_OK;
+}
+
+static sw_error_t qca803x_phy_api_ops_init(void)
+{
+	sw_error_t  ret = SW_OK;
+	hsl_phy_ops_t *qca803x_phy_api_ops = NULL;
+
+	qca803x_phy_api_ops = kzalloc(sizeof(hsl_phy_ops_t), GFP_KERNEL);
+	if (qca803x_phy_api_ops == NULL) {
+		SSDK_ERROR("qca803x phy ops kzalloc failed!\n");
+		return -ENOMEM;
+	}
+
+	phy_api_ops_init(QCA803X_PHY_CHIP);
+
+	qca803x_phy_api_ops->phy_speed_get = qca803x_phy_get_speed;
+	qca803x_phy_api_ops->phy_speed_set = qca803x_phy_set_speed;
+	qca803x_phy_api_ops->phy_duplex_get = qca803x_phy_get_duplex;
+	qca803x_phy_api_ops->phy_duplex_set = qca803x_phy_set_duplex;
+	qca803x_phy_api_ops->phy_autoneg_enable_set = qca803x_phy_enable_autoneg;
+	qca803x_phy_api_ops->phy_restart_autoneg = qca803x_phy_restart_autoneg;
+	qca803x_phy_api_ops->phy_link_status_get = qca803x_phy_get_link_status;
+	qca803x_phy_api_ops->phy_reset = qca803x_phy_reset;
+	qca803x_phy_api_ops->phy_reg_write = qca803x_phy_reg_write;
+	qca803x_phy_api_ops->phy_reg_read = qca803x_phy_reg_read;
+
+	ret = hsl_phy_api_ops_register(QCA803X_PHY_CHIP, qca803x_phy_api_ops);
+
+	if (ret == SW_OK)
+		SSDK_INFO("qca probe qca803x phy driver succeeded!\n");
+	else
+		SSDK_ERROR("qca probe qca803x phy driver failed! (code: %d)\n", ret);
+
+	return ret;
+}
+
+/******************************************************************************
+*
+* qca803x_phy_init -
+*
+*/
+int qca803x_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp)
+{
+	static a_uint32_t phy_ops_flag = 0;
+
+	SSDK_INFO("start to init qca803x phy!\n");
+	if(phy_ops_flag == 0) {
+		qca803x_phy_api_ops_init();
+		phy_ops_flag = 1;
+	}
+
+	return 0;
+}
+
diff --git a/src/init/ssdk_init.c b/src/init/ssdk_init.c
old mode 100644
new mode 100755
index c0aeecd..63e2c88
--- a/src/init/ssdk_init.c
+++ b/src/init/ssdk_init.c
@@ -1370,7 +1370,7 @@
 {
 	a_uint32_t port_id;
 
-	for (port_id = 1; port_id < AR8327_NUM_PORTS; port_id ++) {
+	for (port_id = 1; port_id < SW_MAX_NR_PORT; port_id ++) {
 
 		qca_phy_priv_global[dev_id]->port_old_link[port_id - 1] = 0;
 		qca_phy_priv_global[dev_id]->port_old_speed[port_id - 1] = FAL_SPEED_BUTT;
@@ -3353,7 +3353,7 @@
 		fal_port_rxmac_status_set (dev_id, i, A_FALSE);
 		fal_port_rxfc_status_set(dev_id, i, A_TRUE);
 		fal_port_txfc_status_set(dev_id, i, A_TRUE);
-		fal_port_max_frame_size_set(dev_id, i, 1518);
+		fal_port_max_frame_size_set(dev_id, i, SSDK_MAX_FRAME_SIZE);
 	}
 
 	for(i = 5; i < 7; i++) {
@@ -3362,7 +3362,7 @@
 		fal_port_rxmac_status_set (dev_id, i, A_FALSE);
 		fal_port_rxfc_status_set(dev_id, i, A_TRUE);
 		fal_port_txfc_status_set(dev_id, i, A_TRUE);
-		fal_port_max_frame_size_set(dev_id, i, 1518);
+		fal_port_max_frame_size_set(dev_id, i, SSDK_MAX_FRAME_SIZE);
 	}
 
 	for(i = 1; i < 7; i++) {