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 *) (®), 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 *) (®), 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++) {