Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3 : : */
4 : :
5 : : #include "ngbe_phy_yt.h"
6 : :
7 : : #define YT_PHY_RST_WAIT_PERIOD 5
8 : :
9 : 0 : s32 ngbe_read_phy_reg_yt(struct ngbe_hw *hw,
10 : : u32 reg_addr, u32 device_type, u16 *phy_data)
11 : : {
12 : : mdi_reg_t reg;
13 : : mdi_reg_22_t reg22;
14 : :
15 : 0 : reg.device_type = device_type;
16 : 0 : reg.addr = reg_addr;
17 : :
18 : 0 : ngbe_mdi_map_register(®, ®22);
19 : :
20 : : /* Read MII reg according to media type */
21 [ # # ]: 0 : if (hw->phy.media_type == ngbe_media_type_fiber) {
22 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
23 : 0 : reg22.device_type, YT_SMI_PHY_SDS);
24 : 0 : ngbe_read_phy_reg_mdi(hw, reg22.addr,
25 : 0 : reg22.device_type, phy_data);
26 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
27 : 0 : reg22.device_type, 0);
28 : : } else {
29 : 0 : ngbe_read_phy_reg_mdi(hw, reg22.addr,
30 : 0 : reg22.device_type, phy_data);
31 : : }
32 : :
33 : 0 : return 0;
34 : : }
35 : :
36 : 0 : s32 ngbe_write_phy_reg_yt(struct ngbe_hw *hw,
37 : : u32 reg_addr, u32 device_type, u16 phy_data)
38 : : {
39 : : mdi_reg_t reg;
40 : : mdi_reg_22_t reg22;
41 : :
42 : 0 : reg.device_type = device_type;
43 : 0 : reg.addr = reg_addr;
44 : :
45 : 0 : ngbe_mdi_map_register(®, ®22);
46 : :
47 : : /* Write MII reg according to media type */
48 [ # # ]: 0 : if (hw->phy.media_type == ngbe_media_type_fiber) {
49 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
50 : 0 : reg22.device_type, YT_SMI_PHY_SDS);
51 : 0 : ngbe_write_phy_reg_mdi(hw, reg22.addr,
52 : 0 : reg22.device_type, phy_data);
53 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
54 : 0 : reg22.device_type, 0);
55 : : } else {
56 : 0 : ngbe_write_phy_reg_mdi(hw, reg22.addr,
57 : 0 : reg22.device_type, phy_data);
58 : : }
59 : :
60 : 0 : return 0;
61 : : }
62 : :
63 : 0 : s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw,
64 : : u32 reg_addr, u32 device_type, u16 *phy_data)
65 : : {
66 : 0 : ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
67 : 0 : ngbe_read_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
68 : :
69 : 0 : return 0;
70 : : }
71 : :
72 : 0 : s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw,
73 : : u32 reg_addr, u32 device_type, u16 phy_data)
74 : : {
75 : 0 : ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
76 : 0 : ngbe_write_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
77 : :
78 : 0 : return 0;
79 : : }
80 : :
81 : 0 : s32 ngbe_read_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
82 : : u32 reg_addr, u32 device_type, u16 *phy_data)
83 : : {
84 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS);
85 : 0 : ngbe_read_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data);
86 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0);
87 : :
88 : 0 : return 0;
89 : : }
90 : :
91 : 0 : s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
92 : : u32 reg_addr, u32 device_type, u16 phy_data)
93 : : {
94 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS);
95 : 0 : ngbe_write_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data);
96 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0);
97 : :
98 : 0 : return 0;
99 : : }
100 : :
101 [ # # ]: 0 : s32 ngbe_init_phy_yt(struct ngbe_hw *hw)
102 : : {
103 : : rte_spinlock_init(&hw->phy_lock);
104 : :
105 [ # # ]: 0 : if (hw->lsc) {
106 : 0 : rte_spinlock_lock(&hw->phy_lock);
107 : : /* close sds area register */
108 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
109 : : /* enable interrupts */
110 : 0 : ngbe_write_phy_reg_mdi(hw, YT_INTR, 0,
111 : : YT_INTR_ENA_MASK | YT_SDS_INTR_ENA_MASK);
112 : : rte_spinlock_unlock(&hw->phy_lock);
113 : : }
114 : :
115 : 0 : hw->phy.set_phy_power(hw, false);
116 : :
117 : 0 : return 0;
118 : : }
119 : :
120 : 0 : s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
121 : : bool autoneg_wait_to_complete)
122 : : {
123 : : u16 value_r4 = 0;
124 : : u16 value_r9 = 0;
125 : : u16 value;
126 : :
127 : : UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
128 : :
129 : 0 : hw->phy.autoneg_advertised = 0;
130 : :
131 : : /* check chip_mode first */
132 : 0 : rte_spinlock_lock(&hw->phy_lock);
133 : 0 : ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
134 : : rte_spinlock_unlock(&hw->phy_lock);
135 [ # # ]: 0 : if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(0)) {
136 : : /* UTP to rgmii */
137 [ # # ]: 0 : if (!hw->mac.autoneg) {
138 [ # # # # ]: 0 : switch (speed) {
139 : 0 : case NGBE_LINK_SPEED_1GB_FULL:
140 : 0 : value = YT_BCR_SPEED_SELECT1;
141 : 0 : break;
142 : 0 : case NGBE_LINK_SPEED_100M_FULL:
143 : 0 : value = YT_BCR_SPEED_SELECT0;
144 : 0 : break;
145 : 0 : case NGBE_LINK_SPEED_10M_FULL:
146 : 0 : value = 0;
147 : 0 : break;
148 : 0 : default:
149 : 0 : value = YT_BCR_SPEED_SELECT0 |
150 : : YT_BCR_SPEED_SELECT1;
151 : 0 : DEBUGOUT("unknown speed = 0x%x.",
152 : : speed);
153 : 0 : break;
154 : : }
155 : : /* duplex full */
156 : 0 : value |= YT_BCR_DUPLEX | YT_BCR_RESET;
157 : : rte_spinlock_lock(&hw->phy_lock);
158 : 0 : ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
159 : : rte_spinlock_unlock(&hw->phy_lock);
160 : :
161 : 0 : goto skip_an;
162 : : }
163 : :
164 : : rte_spinlock_lock(&hw->phy_lock);
165 : : /*disable 100/10base-T Self-negotiation ability*/
166 : 0 : ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value);
167 : 0 : value &= ~(YT_ANA_100BASET_FULL | YT_ANA_100BASET_HALF |
168 : : YT_ANA_10BASET_FULL | YT_ANA_10BASET_HALF);
169 : 0 : ngbe_write_phy_reg_mdi(hw, YT_ANA, 0, value);
170 : :
171 : : /*disable 1000base-T Self-negotiation ability*/
172 : 0 : ngbe_read_phy_reg_mdi(hw, YT_MS_CTRL, 0, &value);
173 : 0 : value &= ~(YT_MS_1000BASET_FULL | YT_MS_1000BASET_HALF);
174 : 0 : ngbe_write_phy_reg_mdi(hw, YT_MS_CTRL, 0, value);
175 : :
176 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_1GB_FULL) {
177 : 0 : hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
178 : : value_r9 |= YT_MS_1000BASET_FULL;
179 : : }
180 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_100M_FULL) {
181 : 0 : hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL;
182 : : value_r4 |= YT_ANA_100BASET_FULL;
183 : : }
184 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_10M_FULL) {
185 : 0 : hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL;
186 : 0 : value_r4 |= YT_ANA_10BASET_FULL;
187 : : }
188 : :
189 : : /* enable 1000base-T Self-negotiation ability */
190 : 0 : ngbe_read_phy_reg_mdi(hw, YT_MS_CTRL, 0, &value);
191 : 0 : value |= value_r9;
192 : 0 : ngbe_write_phy_reg_mdi(hw, YT_MS_CTRL, 0, value);
193 : :
194 : : /* enable 100/10base-T Self-negotiation ability */
195 : 0 : ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value);
196 : 0 : value |= value_r4;
197 : 0 : ngbe_write_phy_reg_mdi(hw, YT_ANA, 0, value);
198 : :
199 : : /* software reset to make the above configuration take effect*/
200 : 0 : ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
201 : 0 : value |= YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN;
202 : 0 : ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
203 : : rte_spinlock_unlock(&hw->phy_lock);
204 : 0 : skip_an:
205 : 0 : hw->phy.set_phy_power(hw, true);
206 [ # # ]: 0 : } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(1)) {
207 : : /* fiber to rgmii */
208 [ # # ]: 0 : if (!hw->mac.autoneg) {
209 [ # # # ]: 0 : switch (speed) {
210 : 0 : case NGBE_LINK_SPEED_1GB_FULL:
211 : 0 : value = NGBE_LINK_SPEED_1GB_FULL;
212 : 0 : break;
213 : 0 : case NGBE_LINK_SPEED_100M_FULL:
214 : 0 : value = NGBE_LINK_SPEED_100M_FULL;
215 : 0 : break;
216 : 0 : default:
217 : 0 : value = NGBE_LINK_SPEED_1GB_FULL;
218 : 0 : break;
219 : : }
220 : 0 : hw->phy.autoneg_advertised |= value;
221 : 0 : goto skip_an_fiber;
222 : : }
223 : :
224 : 0 : value = 0;
225 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_1GB_FULL)
226 : 0 : hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
227 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_100M_FULL)
228 : 0 : hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL;
229 : :
230 : 0 : skip_an_fiber:
231 : : rte_spinlock_lock(&hw->phy_lock);
232 : 0 : ngbe_read_phy_reg_ext_yt(hw, YT_MISC, 0, &value);
233 [ # # ]: 0 : if (hw->phy.autoneg_advertised & NGBE_LINK_SPEED_1GB_FULL)
234 : 0 : value |= YT_MISC_RESV;
235 [ # # ]: 0 : else if (hw->phy.autoneg_advertised & NGBE_LINK_SPEED_100M_FULL)
236 : 0 : value &= ~YT_MISC_RESV;
237 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_MISC, 0, value);
238 : :
239 : : /* close auto sensing */
240 : 0 : ngbe_read_phy_reg_sds_ext_yt(hw, YT_AUTO, 0, &value);
241 : 0 : value &= ~YT_AUTO_SENSING;
242 : 0 : ngbe_write_phy_reg_sds_ext_yt(hw, YT_AUTO, 0, value);
243 : :
244 : 0 : ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
245 : 0 : value &= ~YT_CHIP_SW_RST;
246 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
247 : :
248 : : /* RGMII_Config1 : Config rx and tx training delay */
249 : 0 : value = YT_RGMII_CONF1_RXDELAY |
250 : : YT_RGMII_CONF1_TXDELAY_FE |
251 : : YT_RGMII_CONF1_TXDELAY;
252 : :
253 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value);
254 : 0 : value = YT_CHIP_MODE_SEL(1) |
255 : : YT_CHIP_SW_LDO_EN |
256 : : YT_CHIP_SW_RST;
257 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
258 : :
259 : : /* software reset */
260 [ # # ]: 0 : if (hw->mac.autoneg) {
261 : 0 : value = YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN |
262 : : YT_BCR_DUPLEX | YT_BCR_SPEED_SELECT1;
263 : : } else {
264 : 0 : value = YT_BCR_RESET | YT_BCR_DUPLEX;
265 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_1GB_FULL)
266 : 0 : value |= YT_BCR_SPEED_SELECT1;
267 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_100M_FULL)
268 : 0 : value |= YT_BCR_SPEED_SELECT0;
269 : : }
270 : 0 : hw->phy.write_reg(hw, YT_BCR, 0, value);
271 : : rte_spinlock_unlock(&hw->phy_lock);
272 : :
273 : 0 : hw->phy.set_phy_power(hw, true);
274 [ # # ]: 0 : } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(2)) {
275 : 0 : hw->phy.set_phy_power(hw, true);
276 : :
277 : : rte_spinlock_lock(&hw->phy_lock);
278 : 0 : hw->phy.read_reg(hw, YT_SPST, 0, &value);
279 : : rte_spinlock_unlock(&hw->phy_lock);
280 [ # # ]: 0 : if (value & YT_SPST_LINK) {
281 : : /* fiber up */
282 : 0 : hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
283 : : } else {
284 : : /* utp up */
285 : : rte_spinlock_lock(&hw->phy_lock);
286 : : /*disable 100/10base-T Self-negotiation ability*/
287 : 0 : ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value);
288 : 0 : value &= ~(YT_ANA_100BASET_FULL | YT_ANA_100BASET_HALF |
289 : : YT_ANA_10BASET_FULL | YT_ANA_10BASET_HALF);
290 : 0 : ngbe_write_phy_reg_mdi(hw, YT_ANA, 0, value);
291 : :
292 : : /*disable 1000base-T Self-negotiation ability*/
293 : 0 : ngbe_read_phy_reg_mdi(hw, YT_MS_CTRL, 0, &value);
294 : 0 : value &= ~(YT_MS_1000BASET_FULL | YT_MS_1000BASET_HALF);
295 : 0 : ngbe_write_phy_reg_mdi(hw, YT_MS_CTRL, 0, value);
296 : :
297 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_1GB_FULL) {
298 : 0 : hw->phy.autoneg_advertised |=
299 : : NGBE_LINK_SPEED_1GB_FULL;
300 : : value_r9 |= YT_MS_1000BASET_FULL;
301 : : }
302 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_100M_FULL) {
303 : 0 : hw->phy.autoneg_advertised |=
304 : : NGBE_LINK_SPEED_100M_FULL;
305 : : value_r4 |= YT_ANA_100BASET_FULL;
306 : : }
307 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_10M_FULL) {
308 : 0 : hw->phy.autoneg_advertised |=
309 : : NGBE_LINK_SPEED_10M_FULL;
310 : 0 : value_r4 |= YT_ANA_10BASET_FULL;
311 : : }
312 : :
313 : : /* enable 1000base-T Self-negotiation ability */
314 : 0 : ngbe_read_phy_reg_mdi(hw, YT_MS_CTRL, 0, &value);
315 : 0 : value |= value_r9;
316 : 0 : ngbe_write_phy_reg_mdi(hw, YT_MS_CTRL, 0, value);
317 : :
318 : : /* enable 100/10base-T Self-negotiation ability */
319 : 0 : ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value);
320 : 0 : value |= value_r4;
321 : 0 : ngbe_write_phy_reg_mdi(hw, YT_ANA, 0, value);
322 : :
323 : : /* software reset to make the above configuration
324 : : * take effect
325 : : */
326 : 0 : ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
327 : 0 : value |= YT_BCR_RESET;
328 : 0 : ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
329 : : rte_spinlock_unlock(&hw->phy_lock);
330 : : }
331 [ # # ]: 0 : } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(4)) {
332 : 0 : hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
333 : :
334 : : rte_spinlock_lock(&hw->phy_lock);
335 : 0 : ngbe_read_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, &value);
336 : 0 : value |= YT_RGMII_CONF1_MODE;
337 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value);
338 : :
339 : 0 : ngbe_read_phy_reg_ext_yt(hw, YT_RGMII_CONF2, 0, &value);
340 : 0 : value &= ~(YT_RGMII_CONF2_SPEED_MASK | YT_RGMII_CONF2_DUPLEX |
341 : : YT_RGMII_CONF2_LINKUP);
342 : 0 : value |= YT_RGMII_CONF2_SPEED(2) | YT_RGMII_CONF2_DUPLEX |
343 : : YT_RGMII_CONF2_LINKUP;
344 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF2, 0, value);
345 : :
346 : 0 : ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
347 : 0 : value &= ~YT_SMI_PHY_SW_RST;
348 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
349 : : rte_spinlock_unlock(&hw->phy_lock);
350 : :
351 : 0 : hw->phy.set_phy_power(hw, true);
352 [ # # ]: 0 : } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(5)) {
353 : : /* sgmii_to_rgmii */
354 [ # # ]: 0 : if (!hw->mac.autoneg) {
355 [ # # # # ]: 0 : switch (speed) {
356 : 0 : case NGBE_LINK_SPEED_1GB_FULL:
357 : 0 : value = YT_BCR_SPEED_SELECT1;
358 : 0 : break;
359 : 0 : case NGBE_LINK_SPEED_100M_FULL:
360 : 0 : value = YT_BCR_SPEED_SELECT0;
361 : 0 : break;
362 : 0 : case NGBE_LINK_SPEED_10M_FULL:
363 : 0 : value = 0;
364 : 0 : break;
365 : 0 : default:
366 : 0 : value = YT_BCR_SPEED_SELECT0 |
367 : : YT_BCR_SPEED_SELECT1;
368 : 0 : DEBUGOUT("unknown speed = 0x%x", speed);
369 : 0 : break;
370 : : }
371 : : /* duplex full */
372 : 0 : value |= YT_BCR_DUPLEX | YT_BCR_RESET;
373 : : rte_spinlock_lock(&hw->phy_lock);
374 : 0 : hw->phy.write_reg(hw, YT_BCR, 0, value);
375 : : rte_spinlock_unlock(&hw->phy_lock);
376 : :
377 : 0 : goto skip_an_sr;
378 : : }
379 : :
380 : 0 : value = 0;
381 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_1GB_FULL) {
382 : 0 : hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
383 : 0 : value |= YT_BCR_SPEED_SELECT1;
384 : : }
385 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_100M_FULL) {
386 : 0 : hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL;
387 : 0 : value |= YT_BCR_SPEED_SELECT0;
388 : : }
389 [ # # ]: 0 : if (speed & NGBE_LINK_SPEED_10M_FULL)
390 : 0 : hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL;
391 : :
392 : : /* duplex full */
393 : 0 : value |= YT_BCR_DUPLEX | YT_BCR_RESET;
394 : : rte_spinlock_lock(&hw->phy_lock);
395 : 0 : hw->phy.write_reg(hw, YT_BCR, 0, value);
396 : :
397 : : /* software reset to make the above configuration take effect */
398 : 0 : hw->phy.read_reg(hw, YT_BCR, 0, &value);
399 : 0 : value |= YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN;
400 : 0 : hw->phy.write_reg(hw, 0x0, 0, value);
401 : : rte_spinlock_unlock(&hw->phy_lock);
402 : :
403 : 0 : skip_an_sr:
404 : 0 : hw->phy.set_phy_power(hw, true);
405 : : }
406 : :
407 : : rte_spinlock_lock(&hw->phy_lock);
408 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
409 : 0 : ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &value);
410 : : rte_spinlock_unlock(&hw->phy_lock);
411 : :
412 : 0 : return 0;
413 : : }
414 : :
415 : 0 : s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
416 : : {
417 : : u32 i;
418 : 0 : u16 ctrl = 0;
419 : : s32 status = 0;
420 : :
421 [ # # ]: 0 : if (hw->phy.type != ngbe_phy_yt8521s &&
422 : : hw->phy.type != ngbe_phy_yt8521s_sfi)
423 : : return NGBE_ERR_PHY_TYPE;
424 : :
425 : 0 : rte_spinlock_lock(&hw->phy_lock);
426 : : /* check chip_mode first */
427 : 0 : ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &ctrl);
428 [ # # ]: 0 : if (ctrl & YT_CHIP_MODE_MASK) {
429 : : /* fiber to rgmii */
430 : 0 : status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
431 : : /* sds software reset */
432 : 0 : ctrl |= YT_BCR_RESET;
433 : 0 : status = hw->phy.write_reg(hw, YT_BCR, 0, ctrl);
434 : :
435 [ # # ]: 0 : for (i = 0; i < YT_PHY_RST_WAIT_PERIOD; i++) {
436 : 0 : status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
437 [ # # ]: 0 : if (!(ctrl & YT_BCR_RESET))
438 : : break;
439 : : msleep(1);
440 : : }
441 : : } else {
442 : : /* UTP to rgmii */
443 : 0 : status = ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &ctrl);
444 : : /* sds software reset */
445 : 0 : ctrl |= YT_BCR_RESET;
446 : 0 : status = ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, ctrl);
447 : :
448 [ # # ]: 0 : for (i = 0; i < YT_PHY_RST_WAIT_PERIOD; i++) {
449 : 0 : status = ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &ctrl);
450 [ # # ]: 0 : if (!(ctrl & YT_BCR_RESET))
451 : : break;
452 : : msleep(1);
453 : : }
454 : : }
455 : : rte_spinlock_unlock(&hw->phy_lock);
456 : :
457 [ # # ]: 0 : if (i == YT_PHY_RST_WAIT_PERIOD) {
458 : 0 : DEBUGOUT("PHY reset polling failed to complete.");
459 : 0 : return NGBE_ERR_RESET_FAILED;
460 : : }
461 : :
462 : : return status;
463 : : }
464 : :
465 : 0 : s32 ngbe_get_phy_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit)
466 : : {
467 : : u16 value;
468 : : s32 status = 0;
469 : :
470 : 0 : rte_spinlock_lock(&hw->phy_lock);
471 : 0 : status = hw->phy.read_reg(hw, YT_ANA, 0, &value);
472 : : rte_spinlock_unlock(&hw->phy_lock);
473 : 0 : value &= YT_FANA_PAUSE_MASK;
474 : 0 : *pause_bit = (u8)(value >> 7);
475 : :
476 : 0 : return status;
477 : : }
478 : :
479 : 0 : s32 ngbe_get_phy_lp_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit)
480 : : {
481 : : u16 value;
482 : : s32 status = 0;
483 : :
484 : 0 : rte_spinlock_lock(&hw->phy_lock);
485 : 0 : status = hw->phy.read_reg(hw, YT_LPAR, 0, &value);
486 : : rte_spinlock_unlock(&hw->phy_lock);
487 : 0 : value &= YT_FLPAR_PAUSE_MASK;
488 : 0 : *pause_bit = (u8)(value >> 7);
489 : :
490 : 0 : return status;
491 : : }
492 : :
493 : 0 : s32 ngbe_set_phy_pause_adv_yt(struct ngbe_hw *hw, u16 pause_bit)
494 : : {
495 : : u16 value;
496 : : s32 status = 0;
497 : :
498 : 0 : rte_spinlock_lock(&hw->phy_lock);
499 : 0 : status = hw->phy.read_reg(hw, YT_ANA, 0, &value);
500 : 0 : value &= ~YT_FANA_PAUSE_MASK;
501 : 0 : value |= pause_bit;
502 : 0 : status = hw->phy.write_reg(hw, YT_ANA, 0, value);
503 : : rte_spinlock_unlock(&hw->phy_lock);
504 : :
505 : 0 : return status;
506 : : }
507 : :
508 : 0 : s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw,
509 : : u32 *speed, bool *link_up)
510 : : {
511 : : s32 status = 0;
512 : : u16 phy_link = 0;
513 : : u16 phy_speed = 0;
514 : 0 : u16 phy_data = 0;
515 : 0 : u16 insr = 0;
516 : :
517 : : /* Initialize speed and link to default case */
518 : 0 : *link_up = false;
519 : 0 : *speed = NGBE_LINK_SPEED_UNKNOWN;
520 : 0 : rte_spinlock_lock(&hw->phy_lock);
521 : :
522 : 0 : ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
523 : 0 : ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &insr);
524 : :
525 : 0 : status = hw->phy.read_reg(hw, YT_SPST, 0, &phy_data);
526 : 0 : phy_link = phy_data & YT_SPST_LINK;
527 : 0 : phy_speed = phy_data & YT_SPST_SPEED_MASK;
528 : :
529 [ # # ]: 0 : if (phy_link) {
530 : 0 : *link_up = true;
531 : : } else {
532 : 0 : status = ngbe_read_phy_reg_mdi(hw, YT_SPST, 0, &phy_data);
533 : 0 : phy_link = phy_data & YT_SPST_LINK;
534 : 0 : phy_speed = phy_data & YT_SPST_SPEED_MASK;
535 : :
536 [ # # ]: 0 : if (phy_link)
537 : 0 : *link_up = true;
538 : : }
539 : :
540 : : rte_spinlock_unlock(&hw->phy_lock);
541 [ # # ]: 0 : if (*link_up) {
542 [ # # ]: 0 : if (phy_speed == YT_SPST_SPEED_1000M)
543 : 0 : *speed = NGBE_LINK_SPEED_1GB_FULL;
544 [ # # ]: 0 : else if (phy_speed == YT_SPST_SPEED_100M)
545 : 0 : *speed = NGBE_LINK_SPEED_100M_FULL;
546 [ # # ]: 0 : else if (phy_speed == YT_SPST_SPEED_10M)
547 : 0 : *speed = NGBE_LINK_SPEED_10M_FULL;
548 : : }
549 : :
550 : 0 : return status;
551 : : }
552 : :
553 : 0 : s32 ngbe_set_phy_power_yt(struct ngbe_hw *hw, bool on)
554 : : {
555 : 0 : u16 value = 0;
556 : :
557 : 0 : rte_spinlock_lock(&hw->phy_lock);
558 : : /* power down/up in fiber mode */
559 : 0 : hw->phy.read_reg(hw, YT_BCR, 0, &value);
560 [ # # ]: 0 : if (on)
561 : 0 : value &= ~YT_BCR_PWDN;
562 : : else
563 : 0 : value |= YT_BCR_PWDN;
564 : 0 : hw->phy.write_reg(hw, YT_BCR, 0, value);
565 : :
566 : 0 : value = 0;
567 : : /* power down/up in UTP mode */
568 : 0 : ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
569 [ # # ]: 0 : if (on)
570 : 0 : value &= ~YT_BCR_PWDN;
571 : : else
572 : 0 : value |= YT_BCR_PWDN;
573 : 0 : ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
574 : : rte_spinlock_unlock(&hw->phy_lock);
575 : :
576 : 0 : return 0;
577 : : }
|