1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
5 #include "ngbe_phy_yt.h"
7 #define YT_PHY_RST_WAIT_PERIOD 5
9 s32 ngbe_read_phy_reg_yt(struct ngbe_hw *hw,
10 u32 reg_addr, u32 device_type, u16 *phy_data)
15 reg.device_type = device_type;
18 ngbe_mdi_map_register(®, ®22);
20 /* Read MII reg according to media type */
21 if (hw->phy.media_type == ngbe_media_type_fiber) {
22 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
23 reg22.device_type, YT_SMI_PHY_SDS);
24 ngbe_read_phy_reg_mdi(hw, reg22.addr,
25 reg22.device_type, phy_data);
26 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
27 reg22.device_type, 0);
29 ngbe_read_phy_reg_mdi(hw, reg22.addr,
30 reg22.device_type, phy_data);
36 s32 ngbe_write_phy_reg_yt(struct ngbe_hw *hw,
37 u32 reg_addr, u32 device_type, u16 phy_data)
42 reg.device_type = device_type;
45 ngbe_mdi_map_register(®, ®22);
47 /* Write MII reg according to media type */
48 if (hw->phy.media_type == ngbe_media_type_fiber) {
49 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
50 reg22.device_type, YT_SMI_PHY_SDS);
51 ngbe_write_phy_reg_mdi(hw, reg22.addr,
52 reg22.device_type, phy_data);
53 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
54 reg22.device_type, 0);
56 ngbe_write_phy_reg_mdi(hw, reg22.addr,
57 reg22.device_type, phy_data);
63 s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw,
64 u32 reg_addr, u32 device_type, u16 *phy_data)
66 ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
67 ngbe_read_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
72 s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw,
73 u32 reg_addr, u32 device_type, u16 phy_data)
75 ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
76 ngbe_write_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
81 s32 ngbe_read_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
82 u32 reg_addr, u32 device_type, u16 *phy_data)
84 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS);
85 ngbe_read_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data);
86 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0);
91 s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
92 u32 reg_addr, u32 device_type, u16 phy_data)
94 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS);
95 ngbe_write_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data);
96 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0);
101 s32 ngbe_init_phy_yt(struct ngbe_hw *hw)
105 DEBUGFUNC("ngbe_init_phy_yt");
107 if (hw->phy.type != ngbe_phy_yt8521s_sfi)
110 /* select sds area register */
111 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
112 /* enable interrupts */
113 ngbe_write_phy_reg_mdi(hw, YT_INTR, 0, YT_INTR_ENA_MASK);
115 /* select fiber_to_rgmii first in multiplex */
116 ngbe_read_phy_reg_ext_yt(hw, YT_MISC, 0, &value);
117 value |= YT_MISC_FIBER_PRIO;
118 ngbe_write_phy_reg_ext_yt(hw, YT_MISC, 0, value);
120 hw->phy.read_reg(hw, YT_BCR, 0, &value);
121 value |= YT_BCR_PWDN;
122 hw->phy.write_reg(hw, YT_BCR, 0, value);
127 s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
128 bool autoneg_wait_to_complete)
134 DEBUGFUNC("ngbe_setup_phy_link_yt");
135 UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
137 hw->phy.autoneg_advertised = 0;
139 if (hw->phy.type == ngbe_phy_yt8521s) {
140 /*disable 100/10base-T Self-negotiation ability*/
141 hw->phy.read_reg(hw, YT_ANA, 0, &value);
142 value &= ~(YT_ANA_100BASET_FULL | YT_ANA_10BASET_FULL);
143 hw->phy.write_reg(hw, YT_ANA, 0, value);
145 /*disable 1000base-T Self-negotiation ability*/
146 hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value);
147 value &= ~YT_MS_1000BASET_FULL;
148 hw->phy.write_reg(hw, YT_MS_CTRL, 0, value);
150 if (speed & NGBE_LINK_SPEED_1GB_FULL) {
151 hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
152 value_r9 |= YT_MS_1000BASET_FULL;
154 if (speed & NGBE_LINK_SPEED_100M_FULL) {
155 hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL;
156 value_r4 |= YT_ANA_100BASET_FULL;
158 if (speed & NGBE_LINK_SPEED_10M_FULL) {
159 hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL;
160 value_r4 |= YT_ANA_10BASET_FULL;
163 /* enable 1000base-T Self-negotiation ability */
164 hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value);
166 hw->phy.write_reg(hw, YT_MS_CTRL, 0, value);
168 /* enable 100/10base-T Self-negotiation ability */
169 hw->phy.read_reg(hw, YT_ANA, 0, &value);
171 hw->phy.write_reg(hw, YT_ANA, 0, value);
173 /* software reset to make the above configuration take effect*/
174 hw->phy.read_reg(hw, YT_BCR, 0, &value);
175 value |= YT_BCR_RESET;
176 hw->phy.write_reg(hw, YT_BCR, 0, value);
178 hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
180 /* RGMII_Config1 : Config rx and tx training delay */
181 value = YT_RGMII_CONF1_RXDELAY |
182 YT_RGMII_CONF1_TXDELAY_FE |
183 YT_RGMII_CONF1_TXDELAY;
184 ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value);
185 value = YT_CHIP_MODE_SEL(1) |
188 ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
191 ngbe_write_phy_reg_sds_ext_yt(hw, 0x0, 0, 0x9140);
194 hw->phy.read_reg(hw, YT_BCR, 0, &value);
195 value &= ~YT_BCR_PWDN;
196 hw->phy.write_reg(hw, YT_BCR, 0, value);
199 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
200 ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &value);
205 s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
211 DEBUGFUNC("ngbe_reset_phy_yt");
213 if (hw->phy.type != ngbe_phy_yt8521s &&
214 hw->phy.type != ngbe_phy_yt8521s_sfi)
215 return NGBE_ERR_PHY_TYPE;
217 status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
218 /* sds software reset */
219 ctrl |= YT_BCR_RESET;
220 status = hw->phy.write_reg(hw, YT_BCR, 0, ctrl);
222 for (i = 0; i < YT_PHY_RST_WAIT_PERIOD; i++) {
223 status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
224 if (!(ctrl & YT_BCR_RESET))
229 if (i == YT_PHY_RST_WAIT_PERIOD) {
230 DEBUGOUT("PHY reset polling failed to complete.\n");
231 return NGBE_ERR_RESET_FAILED;
237 s32 ngbe_get_phy_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit)
242 DEBUGFUNC("ngbe_get_phy_advertised_pause_yt");
244 status = hw->phy.read_reg(hw, YT_ANA, 0, &value);
245 value &= YT_FANA_PAUSE_MASK;
246 *pause_bit = (u8)(value >> 7);
251 s32 ngbe_get_phy_lp_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit)
256 DEBUGFUNC("ngbe_get_phy_lp_advertised_pause_yt");
258 status = hw->phy.read_reg(hw, YT_LPAR, 0, &value);
259 value &= YT_FLPAR_PAUSE_MASK;
260 *pause_bit = (u8)(value >> 7);
265 s32 ngbe_set_phy_pause_adv_yt(struct ngbe_hw *hw, u16 pause_bit)
270 DEBUGFUNC("ngbe_set_phy_pause_adv_yt");
273 status = hw->phy.read_reg(hw, YT_ANA, 0, &value);
274 value &= ~YT_FANA_PAUSE_MASK;
276 status = hw->phy.write_reg(hw, YT_ANA, 0, value);
281 s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw,
282 u32 *speed, bool *link_up)
290 DEBUGFUNC("ngbe_check_phy_link_yt");
292 /* Initialize speed and link to default case */
294 *speed = NGBE_LINK_SPEED_UNKNOWN;
296 ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
297 ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &insr);
299 status = hw->phy.read_reg(hw, YT_SPST, 0, &phy_data);
300 phy_link = phy_data & YT_SPST_LINK;
301 phy_speed = phy_data & YT_SPST_SPEED_MASK;
306 if (phy_speed == YT_SPST_SPEED_1000M)
307 *speed = NGBE_LINK_SPEED_1GB_FULL;
308 else if (phy_speed == YT_SPST_SPEED_100M)
309 *speed = NGBE_LINK_SPEED_100M_FULL;
310 else if (phy_speed == YT_SPST_SPEED_10M)
311 *speed = NGBE_LINK_SPEED_10M_FULL;