2022-09-06 04:00:10 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
* Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ngbe_phy_yt.h"
|
|
|
|
|
|
|
|
#define YT_PHY_RST_WAIT_PERIOD 5
|
|
|
|
|
|
|
|
s32 ngbe_read_phy_reg_yt(struct ngbe_hw *hw,
|
|
|
|
u32 reg_addr, u32 device_type, u16 *phy_data)
|
|
|
|
{
|
|
|
|
mdi_reg_t reg;
|
|
|
|
mdi_reg_22_t reg22;
|
|
|
|
|
|
|
|
reg.device_type = device_type;
|
|
|
|
reg.addr = reg_addr;
|
|
|
|
|
|
|
|
ngbe_mdi_map_register(®, ®22);
|
|
|
|
|
|
|
|
/* Read MII reg according to media type */
|
|
|
|
if (hw->phy.media_type == ngbe_media_type_fiber) {
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
|
|
|
|
reg22.device_type, YT_SMI_PHY_SDS);
|
|
|
|
ngbe_read_phy_reg_mdi(hw, reg22.addr,
|
|
|
|
reg22.device_type, phy_data);
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
|
|
|
|
reg22.device_type, 0);
|
|
|
|
} else {
|
|
|
|
ngbe_read_phy_reg_mdi(hw, reg22.addr,
|
|
|
|
reg22.device_type, phy_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_write_phy_reg_yt(struct ngbe_hw *hw,
|
|
|
|
u32 reg_addr, u32 device_type, u16 phy_data)
|
|
|
|
{
|
|
|
|
mdi_reg_t reg;
|
|
|
|
mdi_reg_22_t reg22;
|
|
|
|
|
|
|
|
reg.device_type = device_type;
|
|
|
|
reg.addr = reg_addr;
|
|
|
|
|
|
|
|
ngbe_mdi_map_register(®, ®22);
|
|
|
|
|
|
|
|
/* Write MII reg according to media type */
|
|
|
|
if (hw->phy.media_type == ngbe_media_type_fiber) {
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
|
|
|
|
reg22.device_type, YT_SMI_PHY_SDS);
|
|
|
|
ngbe_write_phy_reg_mdi(hw, reg22.addr,
|
|
|
|
reg22.device_type, phy_data);
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
|
|
|
|
reg22.device_type, 0);
|
|
|
|
} else {
|
|
|
|
ngbe_write_phy_reg_mdi(hw, reg22.addr,
|
|
|
|
reg22.device_type, phy_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw,
|
|
|
|
u32 reg_addr, u32 device_type, u16 *phy_data)
|
|
|
|
{
|
|
|
|
ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
|
|
|
|
ngbe_read_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw,
|
|
|
|
u32 reg_addr, u32 device_type, u16 phy_data)
|
|
|
|
{
|
|
|
|
ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
|
|
|
|
ngbe_write_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_read_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
|
|
|
|
u32 reg_addr, u32 device_type, u16 *phy_data)
|
|
|
|
{
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS);
|
|
|
|
ngbe_read_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data);
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
|
|
|
|
u32 reg_addr, u32 device_type, u16 phy_data)
|
|
|
|
{
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS);
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data);
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_init_phy_yt(struct ngbe_hw *hw)
|
|
|
|
{
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_init(&hw->phy_lock);
|
|
|
|
|
|
|
|
if (hw->lsc) {
|
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
|
|
|
/* close sds area register */
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
|
|
|
|
/* enable interrupts */
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_INTR, 0,
|
|
|
|
YT_INTR_ENA_MASK | YT_SDS_INTR_ENA_MASK);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
}
|
2022-09-06 04:00:10 +00:00
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
hw->phy.set_phy_power(hw, false);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
|
|
|
|
bool autoneg_wait_to_complete)
|
|
|
|
{
|
|
|
|
u16 value_r4 = 0;
|
|
|
|
u16 value_r9 = 0;
|
|
|
|
u16 value;
|
|
|
|
|
|
|
|
UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
|
|
|
|
|
|
|
|
hw->phy.autoneg_advertised = 0;
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
/* check chip_mode first */
|
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
|
|
|
ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(0)) {
|
|
|
|
/* UTP to rgmii */
|
|
|
|
if (!hw->mac.autoneg) {
|
|
|
|
switch (speed) {
|
|
|
|
case NGBE_LINK_SPEED_1GB_FULL:
|
|
|
|
value = YT_BCR_SPEED_SELECT1;
|
|
|
|
break;
|
|
|
|
case NGBE_LINK_SPEED_100M_FULL:
|
|
|
|
value = YT_BCR_SPEED_SELECT0;
|
|
|
|
break;
|
|
|
|
case NGBE_LINK_SPEED_10M_FULL:
|
|
|
|
value = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
value = YT_BCR_SPEED_SELECT0 |
|
|
|
|
YT_BCR_SPEED_SELECT1;
|
|
|
|
DEBUGOUT("unknown speed = 0x%x.",
|
|
|
|
speed);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* duplex full */
|
|
|
|
value |= YT_BCR_DUPLEX | YT_BCR_RESET;
|
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
|
|
|
|
goto skip_an;
|
|
|
|
}
|
|
|
|
|
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
/*disable 100/10base-T Self-negotiation ability*/
|
2023-09-13 12:21:49 +00:00
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value);
|
|
|
|
value &= ~(YT_ANA_100BASET_FULL | YT_ANA_100BASET_HALF |
|
|
|
|
YT_ANA_10BASET_FULL | YT_ANA_10BASET_HALF);
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_ANA, 0, value);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
/*disable 1000base-T Self-negotiation ability*/
|
2023-09-13 12:21:49 +00:00
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_MS_CTRL, 0, &value);
|
|
|
|
value &= ~(YT_MS_1000BASET_FULL | YT_MS_1000BASET_HALF);
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_MS_CTRL, 0, value);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
if (speed & NGBE_LINK_SPEED_1GB_FULL) {
|
|
|
|
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
|
|
|
|
value_r9 |= YT_MS_1000BASET_FULL;
|
|
|
|
}
|
|
|
|
if (speed & NGBE_LINK_SPEED_100M_FULL) {
|
|
|
|
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL;
|
|
|
|
value_r4 |= YT_ANA_100BASET_FULL;
|
|
|
|
}
|
|
|
|
if (speed & NGBE_LINK_SPEED_10M_FULL) {
|
|
|
|
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL;
|
|
|
|
value_r4 |= YT_ANA_10BASET_FULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* enable 1000base-T Self-negotiation ability */
|
2023-09-13 12:21:49 +00:00
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_MS_CTRL, 0, &value);
|
2022-09-06 04:00:10 +00:00
|
|
|
value |= value_r9;
|
2023-09-13 12:21:49 +00:00
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_MS_CTRL, 0, value);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
/* enable 100/10base-T Self-negotiation ability */
|
2023-09-13 12:21:49 +00:00
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value);
|
2022-09-06 04:00:10 +00:00
|
|
|
value |= value_r4;
|
2023-09-13 12:21:49 +00:00
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_ANA, 0, value);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
/* software reset to make the above configuration take effect*/
|
2023-09-13 12:21:49 +00:00
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
|
|
|
|
value |= YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN;
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
skip_an:
|
|
|
|
hw->phy.set_phy_power(hw, true);
|
|
|
|
} else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(1)) {
|
|
|
|
/* fiber to rgmii */
|
2022-09-06 04:00:10 +00:00
|
|
|
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
|
|
|
|
|
|
|
|
/* RGMII_Config1 : Config rx and tx training delay */
|
|
|
|
value = YT_RGMII_CONF1_RXDELAY |
|
|
|
|
YT_RGMII_CONF1_TXDELAY_FE |
|
|
|
|
YT_RGMII_CONF1_TXDELAY;
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value);
|
|
|
|
value = YT_CHIP_MODE_SEL(1) |
|
|
|
|
YT_CHIP_SW_LDO_EN |
|
|
|
|
YT_CHIP_SW_RST;
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
ngbe_read_phy_reg_sds_ext_yt(hw, YT_AUTO, 0, &value);
|
|
|
|
value &= ~YT_AUTO_SENSING;
|
|
|
|
ngbe_write_phy_reg_sds_ext_yt(hw, YT_AUTO, 0, value);
|
|
|
|
|
|
|
|
ngbe_read_phy_reg_ext_yt(hw, YT_MISC, 0, &value);
|
|
|
|
value |= YT_MISC_RESV;
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_MISC, 0, value);
|
|
|
|
|
|
|
|
ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
|
|
|
|
value &= ~YT_CHIP_SW_RST;
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
|
|
|
|
|
2022-09-06 04:00:10 +00:00
|
|
|
/* software reset */
|
2023-09-13 12:21:49 +00:00
|
|
|
if (hw->mac.autoneg)
|
|
|
|
value = YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN |
|
|
|
|
YT_BCR_DUPLEX | YT_BCR_SPEED_SELECT1;
|
|
|
|
else
|
|
|
|
value = YT_BCR_RESET | YT_BCR_DUPLEX |
|
|
|
|
YT_BCR_SPEED_SELECT1;
|
|
|
|
hw->phy.write_reg(hw, YT_BCR, 0, value);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
hw->phy.set_phy_power(hw, true);
|
|
|
|
} else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(2)) {
|
|
|
|
hw->phy.set_phy_power(hw, true);
|
|
|
|
|
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
|
|
|
hw->phy.read_reg(hw, YT_SPST, 0, &value);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
if (value & YT_SPST_LINK) {
|
|
|
|
/* fiber up */
|
|
|
|
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
|
|
|
|
} else {
|
|
|
|
/* utp up */
|
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
|
|
|
/*disable 100/10base-T Self-negotiation ability*/
|
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value);
|
|
|
|
value &= ~(YT_ANA_100BASET_FULL | YT_ANA_100BASET_HALF |
|
|
|
|
YT_ANA_10BASET_FULL | YT_ANA_10BASET_HALF);
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_ANA, 0, value);
|
|
|
|
|
|
|
|
/*disable 1000base-T Self-negotiation ability*/
|
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_MS_CTRL, 0, &value);
|
|
|
|
value &= ~(YT_MS_1000BASET_FULL | YT_MS_1000BASET_HALF);
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_MS_CTRL, 0, value);
|
|
|
|
|
|
|
|
if (speed & NGBE_LINK_SPEED_1GB_FULL) {
|
|
|
|
hw->phy.autoneg_advertised |=
|
|
|
|
NGBE_LINK_SPEED_1GB_FULL;
|
|
|
|
value_r9 |= YT_MS_1000BASET_FULL;
|
|
|
|
}
|
|
|
|
if (speed & NGBE_LINK_SPEED_100M_FULL) {
|
|
|
|
hw->phy.autoneg_advertised |=
|
|
|
|
NGBE_LINK_SPEED_100M_FULL;
|
|
|
|
value_r4 |= YT_ANA_100BASET_FULL;
|
|
|
|
}
|
|
|
|
if (speed & NGBE_LINK_SPEED_10M_FULL) {
|
|
|
|
hw->phy.autoneg_advertised |=
|
|
|
|
NGBE_LINK_SPEED_10M_FULL;
|
|
|
|
value_r4 |= YT_ANA_10BASET_FULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* enable 1000base-T Self-negotiation ability */
|
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_MS_CTRL, 0, &value);
|
|
|
|
value |= value_r9;
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_MS_CTRL, 0, value);
|
|
|
|
|
|
|
|
/* enable 100/10base-T Self-negotiation ability */
|
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value);
|
|
|
|
value |= value_r4;
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_ANA, 0, value);
|
|
|
|
|
2024-10-17 10:26:34 +00:00
|
|
|
/* config for yt8531sh-ca */
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SPEC_CONF, 0,
|
|
|
|
YT_SPEC_CONF_8531SH_CA);
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
/* software reset to make the above configuration
|
|
|
|
* take effect
|
|
|
|
*/
|
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
|
|
|
|
value |= YT_BCR_RESET;
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
}
|
|
|
|
} else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(4)) {
|
|
|
|
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
|
|
|
|
|
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
|
|
|
ngbe_read_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, &value);
|
|
|
|
value |= YT_RGMII_CONF1_MODE;
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value);
|
|
|
|
|
|
|
|
ngbe_read_phy_reg_ext_yt(hw, YT_RGMII_CONF2, 0, &value);
|
|
|
|
value &= ~(YT_RGMII_CONF2_SPEED_MASK | YT_RGMII_CONF2_DUPLEX |
|
|
|
|
YT_RGMII_CONF2_LINKUP);
|
|
|
|
value |= YT_RGMII_CONF2_SPEED(2) | YT_RGMII_CONF2_DUPLEX |
|
|
|
|
YT_RGMII_CONF2_LINKUP;
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF2, 0, value);
|
|
|
|
|
|
|
|
ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
|
|
|
|
value &= ~YT_SMI_PHY_SW_RST;
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
|
|
|
|
hw->phy.set_phy_power(hw, true);
|
|
|
|
} else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(5)) {
|
|
|
|
/* sgmii_to_rgmii */
|
|
|
|
if (!hw->mac.autoneg) {
|
|
|
|
switch (speed) {
|
|
|
|
case NGBE_LINK_SPEED_1GB_FULL:
|
|
|
|
value = YT_BCR_SPEED_SELECT1;
|
|
|
|
break;
|
|
|
|
case NGBE_LINK_SPEED_100M_FULL:
|
|
|
|
value = YT_BCR_SPEED_SELECT0;
|
|
|
|
break;
|
|
|
|
case NGBE_LINK_SPEED_10M_FULL:
|
|
|
|
value = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
value = YT_BCR_SPEED_SELECT0 |
|
|
|
|
YT_BCR_SPEED_SELECT1;
|
|
|
|
DEBUGOUT("unknown speed = 0x%x", speed);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* duplex full */
|
|
|
|
value |= YT_BCR_DUPLEX | YT_BCR_RESET;
|
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
|
|
|
hw->phy.write_reg(hw, YT_BCR, 0, value);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
|
|
|
|
goto skip_an_sr;
|
|
|
|
}
|
|
|
|
|
|
|
|
value = 0;
|
|
|
|
if (speed & NGBE_LINK_SPEED_1GB_FULL) {
|
|
|
|
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
|
|
|
|
value |= YT_BCR_SPEED_SELECT1;
|
|
|
|
}
|
|
|
|
if (speed & NGBE_LINK_SPEED_100M_FULL) {
|
|
|
|
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL;
|
|
|
|
value |= YT_BCR_SPEED_SELECT0;
|
|
|
|
}
|
|
|
|
if (speed & NGBE_LINK_SPEED_10M_FULL)
|
|
|
|
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL;
|
|
|
|
|
|
|
|
/* duplex full */
|
|
|
|
value |= YT_BCR_DUPLEX | YT_BCR_RESET;
|
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
hw->phy.write_reg(hw, YT_BCR, 0, value);
|
2023-09-13 12:21:49 +00:00
|
|
|
|
|
|
|
/* software reset to make the above configuration take effect */
|
|
|
|
hw->phy.read_reg(hw, YT_BCR, 0, &value);
|
|
|
|
value |= YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN;
|
|
|
|
hw->phy.write_reg(hw, 0x0, 0, value);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
|
|
|
|
skip_an_sr:
|
|
|
|
hw->phy.set_phy_power(hw, true);
|
2022-09-06 04:00:10 +00:00
|
|
|
}
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
|
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &value);
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
|
|
|
|
{
|
|
|
|
u32 i;
|
|
|
|
u16 ctrl = 0;
|
|
|
|
s32 status = 0;
|
|
|
|
|
|
|
|
if (hw->phy.type != ngbe_phy_yt8521s &&
|
|
|
|
hw->phy.type != ngbe_phy_yt8521s_sfi)
|
|
|
|
return NGBE_ERR_PHY_TYPE;
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
|
|
|
/* check chip_mode first */
|
|
|
|
ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &ctrl);
|
|
|
|
if (ctrl & YT_CHIP_MODE_MASK) {
|
|
|
|
/* fiber to rgmii */
|
2022-09-06 04:00:10 +00:00
|
|
|
status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
|
2023-09-13 12:21:49 +00:00
|
|
|
/* sds software reset */
|
|
|
|
ctrl |= YT_BCR_RESET;
|
|
|
|
status = hw->phy.write_reg(hw, YT_BCR, 0, ctrl);
|
|
|
|
|
|
|
|
for (i = 0; i < YT_PHY_RST_WAIT_PERIOD; i++) {
|
|
|
|
status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
|
|
|
|
if (!(ctrl & YT_BCR_RESET))
|
|
|
|
break;
|
|
|
|
msleep(1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* UTP to rgmii */
|
|
|
|
status = ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &ctrl);
|
|
|
|
/* sds software reset */
|
|
|
|
ctrl |= YT_BCR_RESET;
|
|
|
|
status = ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, ctrl);
|
|
|
|
|
|
|
|
for (i = 0; i < YT_PHY_RST_WAIT_PERIOD; i++) {
|
|
|
|
status = ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &ctrl);
|
|
|
|
if (!(ctrl & YT_BCR_RESET))
|
|
|
|
break;
|
|
|
|
msleep(1);
|
|
|
|
}
|
2022-09-06 04:00:10 +00:00
|
|
|
}
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
if (i == YT_PHY_RST_WAIT_PERIOD) {
|
|
|
|
DEBUGOUT("PHY reset polling failed to complete.");
|
|
|
|
return NGBE_ERR_RESET_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_get_phy_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit)
|
|
|
|
{
|
|
|
|
u16 value;
|
|
|
|
s32 status = 0;
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
status = hw->phy.read_reg(hw, YT_ANA, 0, &value);
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
value &= YT_FANA_PAUSE_MASK;
|
|
|
|
*pause_bit = (u8)(value >> 7);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_get_phy_lp_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit)
|
|
|
|
{
|
|
|
|
u16 value;
|
|
|
|
s32 status = 0;
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
status = hw->phy.read_reg(hw, YT_LPAR, 0, &value);
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
value &= YT_FLPAR_PAUSE_MASK;
|
|
|
|
*pause_bit = (u8)(value >> 7);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_set_phy_pause_adv_yt(struct ngbe_hw *hw, u16 pause_bit)
|
|
|
|
{
|
|
|
|
u16 value;
|
|
|
|
s32 status = 0;
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
status = hw->phy.read_reg(hw, YT_ANA, 0, &value);
|
|
|
|
value &= ~YT_FANA_PAUSE_MASK;
|
|
|
|
value |= pause_bit;
|
|
|
|
status = hw->phy.write_reg(hw, YT_ANA, 0, value);
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw,
|
|
|
|
u32 *speed, bool *link_up)
|
|
|
|
{
|
|
|
|
s32 status = 0;
|
|
|
|
u16 phy_link = 0;
|
|
|
|
u16 phy_speed = 0;
|
|
|
|
u16 phy_data = 0;
|
|
|
|
u16 insr = 0;
|
|
|
|
|
|
|
|
/* Initialize speed and link to default case */
|
|
|
|
*link_up = false;
|
|
|
|
*speed = NGBE_LINK_SPEED_UNKNOWN;
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
|
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &insr);
|
|
|
|
|
|
|
|
status = hw->phy.read_reg(hw, YT_SPST, 0, &phy_data);
|
|
|
|
phy_link = phy_data & YT_SPST_LINK;
|
|
|
|
phy_speed = phy_data & YT_SPST_SPEED_MASK;
|
|
|
|
|
|
|
|
if (phy_link) {
|
|
|
|
*link_up = true;
|
2023-09-13 12:21:49 +00:00
|
|
|
} else {
|
|
|
|
status = ngbe_read_phy_reg_mdi(hw, YT_SPST, 0, &phy_data);
|
|
|
|
phy_link = phy_data & YT_SPST_LINK;
|
|
|
|
phy_speed = phy_data & YT_SPST_SPEED_MASK;
|
|
|
|
|
|
|
|
if (phy_link)
|
|
|
|
*link_up = true;
|
|
|
|
}
|
2022-09-06 04:00:10 +00:00
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
if (*link_up) {
|
2022-09-06 04:00:10 +00:00
|
|
|
if (phy_speed == YT_SPST_SPEED_1000M)
|
|
|
|
*speed = NGBE_LINK_SPEED_1GB_FULL;
|
|
|
|
else if (phy_speed == YT_SPST_SPEED_100M)
|
|
|
|
*speed = NGBE_LINK_SPEED_100M_FULL;
|
|
|
|
else if (phy_speed == YT_SPST_SPEED_10M)
|
|
|
|
*speed = NGBE_LINK_SPEED_10M_FULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
s32 ngbe_set_phy_power_yt(struct ngbe_hw *hw, bool on)
|
|
|
|
{
|
|
|
|
u16 value = 0;
|
|
|
|
|
|
|
|
rte_spinlock_lock(&hw->phy_lock);
|
|
|
|
/* power down/up in fiber mode */
|
|
|
|
hw->phy.read_reg(hw, YT_BCR, 0, &value);
|
|
|
|
if (on)
|
|
|
|
value &= ~YT_BCR_PWDN;
|
|
|
|
else
|
|
|
|
value |= YT_BCR_PWDN;
|
|
|
|
hw->phy.write_reg(hw, YT_BCR, 0, value);
|
|
|
|
|
|
|
|
value = 0;
|
|
|
|
/* power down/up in UTP mode */
|
|
|
|
ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
|
|
|
|
if (on)
|
|
|
|
value &= ~YT_BCR_PWDN;
|
|
|
|
else
|
|
|
|
value |= YT_BCR_PWDN;
|
|
|
|
ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
|
|
|
|
rte_spinlock_unlock(&hw->phy_lock);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|