Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 Realtek Corporation. All rights reserved
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <errno.h>
7 : : #include <stdint.h>
8 : :
9 : : #include <rte_ether.h>
10 : : #include <ethdev_pci.h>
11 : :
12 : : #include "r8169_ethdev.h"
13 : : #include "r8169_hw.h"
14 : : #include "r8169_phy.h"
15 : : #include "r8169_logs.h"
16 : : #include "r8169_dash.h"
17 : : #include "r8169_fiber.h"
18 : :
19 : : static u16
20 : : rtl_map_phy_ocp_addr(u16 PageNum, u8 RegNum)
21 : : {
22 : : u8 ocp_reg_num = 0;
23 : : u16 ocp_page_num = 0;
24 : : u16 ocp_phy_address = 0;
25 : :
26 : 0 : if (PageNum == 0) {
27 : 0 : ocp_page_num = OCP_STD_PHY_BASE_PAGE + (RegNum / 8);
28 : 0 : ocp_reg_num = 0x10 + (RegNum % 8);
29 : : } else {
30 : : ocp_page_num = PageNum;
31 : : ocp_reg_num = RegNum;
32 : : }
33 : :
34 : 0 : ocp_page_num <<= 4;
35 : :
36 [ # # # # ]: 0 : if (ocp_reg_num < 16) {
37 : : ocp_phy_address = 0;
38 : : } else {
39 : 0 : ocp_reg_num -= 16;
40 : 0 : ocp_reg_num <<= 1;
41 : :
42 : 0 : ocp_phy_address = ocp_page_num + ocp_reg_num;
43 : : }
44 : :
45 : : return ocp_phy_address;
46 : : }
47 : :
48 : : static u32
49 : 0 : rtl_mdio_real_direct_read_phy_ocp(struct rtl_hw *hw, u32 RegAddr)
50 : : {
51 : : u32 data32;
52 : : int i, value = 0;
53 : :
54 : 0 : data32 = RegAddr / 2;
55 : 0 : data32 <<= OCPR_Addr_Reg_shift;
56 : :
57 : 0 : RTL_W32(hw, PHYOCP, data32);
58 [ # # ]: 0 : for (i = 0; i < RTL_CHANNEL_WAIT_COUNT; i++) {
59 : 0 : rte_delay_us(RTL_CHANNEL_WAIT_TIME);
60 : :
61 [ # # ]: 0 : if (RTL_R32(hw, PHYOCP) & OCPR_Flag)
62 : : break;
63 : : }
64 : 0 : value = RTL_R32(hw, PHYOCP) & OCPDR_Data_Mask;
65 : :
66 : 0 : return value;
67 : : }
68 : :
69 : : u32
70 : 0 : rtl_mdio_direct_read_phy_ocp(struct rtl_hw *hw, u32 RegAddr)
71 : : {
72 : 0 : return rtl_mdio_real_direct_read_phy_ocp(hw, RegAddr);
73 : : }
74 : :
75 : : u32
76 : 0 : rtl_mdio_real_read_phy_ocp(struct rtl_hw *hw, u16 PageNum, u32 RegAddr)
77 : : {
78 : : u16 ocp_addr;
79 : :
80 [ # # ]: 0 : ocp_addr = rtl_map_phy_ocp_addr(PageNum, RegAddr);
81 : :
82 : 0 : return rtl_mdio_real_direct_read_phy_ocp(hw, ocp_addr);
83 : : }
84 : :
85 : : static u32
86 : : rtl_mdio_real_read(struct rtl_hw *hw, u32 RegAddr)
87 : : {
88 : 0 : return rtl_mdio_real_read_phy_ocp(hw, hw->cur_page, RegAddr);
89 : : }
90 : :
91 : : u32
92 : 0 : rtl_mdio_read(struct rtl_hw *hw, u32 RegAddr)
93 : : {
94 : 0 : return rtl_mdio_real_read(hw, RegAddr);
95 : : }
96 : :
97 : : static void
98 : 0 : rtl_mdio_real_direct_write_phy_ocp(struct rtl_hw *hw, u32 RegAddr, u32 value)
99 : : {
100 : : u32 data32;
101 : : int i;
102 : :
103 : 0 : data32 = RegAddr / 2;
104 : 0 : data32 <<= OCPR_Addr_Reg_shift;
105 : 0 : data32 |= OCPR_Write | value;
106 : :
107 : 0 : RTL_W32(hw, PHYOCP, data32);
108 [ # # ]: 0 : for (i = 0; i < RTL_CHANNEL_WAIT_COUNT; i++) {
109 : 0 : rte_delay_us(RTL_CHANNEL_WAIT_TIME);
110 : :
111 [ # # ]: 0 : if (!(RTL_R32(hw, PHYOCP) & OCPR_Flag))
112 : : break;
113 : : }
114 : 0 : }
115 : :
116 : : void
117 : 0 : rtl_mdio_direct_write_phy_ocp(struct rtl_hw *hw, u32 RegAddr, u32 value)
118 : : {
119 : 0 : rtl_mdio_real_direct_write_phy_ocp(hw, RegAddr, value);
120 : 0 : }
121 : :
122 : : void
123 : 0 : rtl_mdio_real_write_phy_ocp(struct rtl_hw *hw, u16 PageNum, u32 RegAddr, u32 value)
124 : : {
125 : : u16 ocp_addr;
126 : :
127 [ # # ]: 0 : ocp_addr = rtl_map_phy_ocp_addr(PageNum, RegAddr);
128 : :
129 : 0 : rtl_mdio_direct_write_phy_ocp(hw, ocp_addr, value);
130 : 0 : }
131 : :
132 : : static void
133 : : rtl_mdio_real_write(struct rtl_hw *hw, u32 RegAddr, u32 value)
134 : : {
135 : 0 : if (RegAddr == 0x1F) {
136 : 0 : hw->cur_page = value;
137 : 0 : return;
138 : : }
139 : 0 : rtl_mdio_real_write_phy_ocp(hw, hw->cur_page, RegAddr, value);
140 : : }
141 : :
142 : : void
143 [ # # ]: 0 : rtl_mdio_write(struct rtl_hw *hw, u32 RegAddr, u32 value)
144 : : {
145 : : rtl_mdio_real_write(hw, RegAddr, value);
146 : 0 : }
147 : :
148 : : void
149 : 0 : rtl_clear_and_set_eth_phy_ocp_bit(struct rtl_hw *hw, u16 addr, u16 clearmask,
150 : : u16 setmask)
151 : : {
152 : : u16 val;
153 : :
154 : 0 : val = rtl_mdio_direct_read_phy_ocp(hw, addr);
155 : 0 : val &= ~clearmask;
156 : 0 : val |= setmask;
157 : 0 : rtl_mdio_direct_write_phy_ocp(hw, addr, val);
158 : 0 : }
159 : :
160 : : void
161 : 0 : rtl_clear_eth_phy_ocp_bit(struct rtl_hw *hw, u16 addr, u16 mask)
162 : : {
163 : 0 : rtl_clear_and_set_eth_phy_ocp_bit(hw, addr, mask, 0);
164 : 0 : }
165 : :
166 : : void
167 : 0 : rtl_set_eth_phy_ocp_bit(struct rtl_hw *hw, u16 addr, u16 mask)
168 : : {
169 : 0 : rtl_clear_and_set_eth_phy_ocp_bit(hw, addr, 0, mask);
170 : 0 : }
171 : :
172 : : static u8
173 : 0 : rtl8168_check_ephy_addr(struct rtl_hw *hw, int addr)
174 : : {
175 [ # # ]: 0 : if (hw->mcfg != CFG_METHOD_35 && hw->mcfg != CFG_METHOD_36)
176 : 0 : goto exit;
177 : :
178 [ # # ]: 0 : if (addr & (BIT_6 | BIT_5))
179 : 0 : rtl8168_clear_and_set_mcu_ocp_bit(hw, 0xDE28, (BIT_1 | BIT_0),
180 : 0 : (addr >> 5) & (BIT_1 | BIT_0));
181 : :
182 : 0 : addr &= 0x1F;
183 : :
184 : 0 : exit:
185 : 0 : return addr;
186 : : }
187 : :
188 : : static void
189 : 0 : _rtl_ephy_write(struct rtl_hw *hw, int addr, int value, unsigned int mask)
190 : : {
191 : : int i;
192 : :
193 : 0 : RTL_W32(hw, EPHYAR, EPHYAR_Write | (addr & mask) << EPHYAR_Reg_shift |
194 : : (value & EPHYAR_Data_Mask));
195 : :
196 [ # # ]: 0 : for (i = 0; i < RTL_CHANNEL_WAIT_COUNT; i++) {
197 : 0 : rte_delay_us(RTL_CHANNEL_WAIT_TIME);
198 : :
199 : : /* Check if the NIC has completed EPHY write */
200 [ # # ]: 0 : if (!(RTL_R32(hw, EPHYAR) & EPHYAR_Flag))
201 : : break;
202 : : }
203 : :
204 : 0 : rte_delay_us(RTL_CHANNEL_EXIT_DELAY_TIME);
205 : 0 : }
206 : :
207 : : static void
208 : : rtl8127_set_ephy_ext_addr(struct rtl_hw *hw, int addr)
209 : : {
210 : 0 : _rtl_ephy_write(hw, EPHYAR_EXT_ADDR, addr, EPHYAR_Reg_Mask_v2);
211 : : }
212 : :
213 : : static int
214 : : rtl8127_check_ephy_ext_addr(struct rtl_hw *hw, int addr)
215 : : {
216 : : int data;
217 : :
218 : 0 : data = ((u16)addr >> 12);
219 : :
220 : : rtl8127_set_ephy_ext_addr(hw, data);
221 : :
222 : 0 : return (addr & 0xfff);
223 : : }
224 : :
225 : : void
226 : 0 : rtl_ephy_write(struct rtl_hw *hw, int addr, int value)
227 : : {
228 : : unsigned int mask;
229 : :
230 [ # # ]: 0 : if (!rtl_is_8125(hw)) {
231 : : mask = EPHYAR_Reg_Mask;
232 : 0 : addr = rtl8168_check_ephy_addr(hw, addr);
233 [ # # ]: 0 : } else if (hw->mcfg >= CFG_METHOD_91) {
234 : : mask = EPHYAR_Reg_Mask_v2;
235 : : addr = rtl8127_check_ephy_ext_addr(hw, addr);
236 : : } else {
237 : : mask = EPHYAR_Reg_Mask_v2;
238 : : }
239 : :
240 : 0 : _rtl_ephy_write(hw, addr, value, mask);
241 : 0 : }
242 : :
243 : : static u16
244 : 0 : _rtl_ephy_read(struct rtl_hw *hw, int addr, unsigned int mask)
245 : : {
246 : : int i;
247 : : u16 value = 0xffff;
248 : :
249 : 0 : RTL_W32(hw, EPHYAR, EPHYAR_Read | (addr & mask) << EPHYAR_Reg_shift);
250 : :
251 [ # # ]: 0 : for (i = 0; i < RTL_CHANNEL_WAIT_COUNT; i++) {
252 : 0 : rte_delay_us(RTL_CHANNEL_WAIT_TIME);
253 : :
254 : : /* Check if the NIC has completed EPHY read */
255 [ # # ]: 0 : if (RTL_R32(hw, EPHYAR) & EPHYAR_Flag) {
256 : 0 : value = (u16)(RTL_R32(hw, EPHYAR) & EPHYAR_Data_Mask);
257 : 0 : break;
258 : : }
259 : : }
260 : :
261 : 0 : rte_delay_us(RTL_CHANNEL_EXIT_DELAY_TIME);
262 : :
263 : 0 : return value;
264 : : }
265 : :
266 : : u16
267 : 0 : rtl_ephy_read(struct rtl_hw *hw, int addr)
268 : : {
269 : : unsigned int mask;
270 : :
271 [ # # ]: 0 : if (!rtl_is_8125(hw)) {
272 : : mask = EPHYAR_Reg_Mask;
273 : 0 : addr = rtl8168_check_ephy_addr(hw, addr);
274 [ # # ]: 0 : } else if (hw->mcfg >= CFG_METHOD_91) {
275 : : mask = EPHYAR_Reg_Mask_v2;
276 : : addr = rtl8127_check_ephy_ext_addr(hw, addr);
277 : : } else {
278 : : mask = EPHYAR_Reg_Mask_v2;
279 : : }
280 : :
281 : 0 : return _rtl_ephy_read(hw, addr, mask);
282 : : }
283 : :
284 : : void
285 : 0 : rtl_clear_and_set_pcie_phy_bit(struct rtl_hw *hw, u8 addr, u16 clearmask,
286 : : u16 setmask)
287 : : {
288 : : u16 ephy_value;
289 : :
290 : 0 : ephy_value = rtl_ephy_read(hw, addr);
291 : 0 : ephy_value &= ~clearmask;
292 : 0 : ephy_value |= setmask;
293 : 0 : rtl_ephy_write(hw, addr, ephy_value);
294 : 0 : }
295 : :
296 : : void
297 : 0 : rtl_clear_pcie_phy_bit(struct rtl_hw *hw, u8 addr, u16 mask)
298 : : {
299 : 0 : rtl_clear_and_set_pcie_phy_bit(hw, addr, mask, 0);
300 : 0 : }
301 : :
302 : : void
303 : 0 : rtl_set_pcie_phy_bit(struct rtl_hw *hw, u8 addr, u16 mask)
304 : : {
305 : 0 : rtl_clear_and_set_pcie_phy_bit(hw, addr, 0, mask);
306 : 0 : }
307 : :
308 : : bool
309 : 0 : rtl_set_phy_mcu_patch_request(struct rtl_hw *hw)
310 : : {
311 : : u16 gphy_val;
312 : : u16 wait_cnt;
313 : : bool bool_success = TRUE;
314 : :
315 [ # # ]: 0 : if (rtl_is_8125(hw)) {
316 : 0 : rtl_set_eth_phy_ocp_bit(hw, 0xB820, BIT_4);
317 : :
318 : : wait_cnt = 0;
319 : : do {
320 : 0 : gphy_val = rtl_mdio_direct_read_phy_ocp(hw, 0xB800);
321 : 0 : rte_delay_us(100);
322 : 0 : wait_cnt++;
323 [ # # # # ]: 0 : } while (!(gphy_val & BIT_6) && (wait_cnt < 1000));
324 : :
325 [ # # # # ]: 0 : if (!(gphy_val & BIT_6) && wait_cnt == 1000)
326 : : bool_success = FALSE;
327 : : } else {
328 : 0 : rtl_mdio_write(hw, 0x1f, 0x0B82);
329 : 0 : rtl_set_eth_phy_bit(hw, 0x10, BIT_4);
330 : :
331 : 0 : rtl_mdio_write(hw, 0x1f, 0x0B80);
332 : : wait_cnt = 0;
333 : : do {
334 : 0 : gphy_val = rtl_mdio_read(hw, 0x10);
335 : 0 : rte_delay_us(100);
336 : 0 : wait_cnt++;
337 [ # # # # ]: 0 : } while (!(gphy_val & BIT_6) && (wait_cnt < 1000));
338 : :
339 [ # # # # ]: 0 : if (!(gphy_val & BIT_6) && wait_cnt == 1000)
340 : : bool_success = FALSE;
341 : :
342 : 0 : rtl_mdio_write(hw, 0x1f, 0x0000);
343 : : }
344 : :
345 [ # # ]: 0 : if (!bool_success)
346 : 0 : PMD_INIT_LOG(NOTICE, "%s fail.", __func__);
347 : :
348 : 0 : return bool_success;
349 : : }
350 : :
351 : : bool
352 : 0 : rtl_clear_phy_mcu_patch_request(struct rtl_hw *hw)
353 : : {
354 : : u16 gphy_val;
355 : : u16 wait_cnt;
356 : : bool bool_success = TRUE;
357 : :
358 [ # # ]: 0 : if (rtl_is_8125(hw)) {
359 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xB820, BIT_4);
360 : :
361 : : wait_cnt = 0;
362 : : do {
363 : 0 : gphy_val = rtl_mdio_direct_read_phy_ocp(hw, 0xB800);
364 : 0 : rte_delay_us(100);
365 : 0 : wait_cnt++;
366 [ # # # # ]: 0 : } while ((gphy_val & BIT_6) && (wait_cnt < 1000));
367 : :
368 [ # # # # ]: 0 : if ((gphy_val & BIT_6) && wait_cnt == 1000)
369 : : bool_success = FALSE;
370 : : } else {
371 : 0 : rtl_mdio_write(hw, 0x1f, 0x0B82);
372 : 0 : rtl_clear_eth_phy_bit(hw, 0x10, BIT_4);
373 : :
374 : 0 : rtl_mdio_write(hw, 0x1f, 0x0B80);
375 : : wait_cnt = 0;
376 : : do {
377 : 0 : gphy_val = rtl_mdio_read(hw, 0x10);
378 : 0 : rte_delay_us(100);
379 : 0 : wait_cnt++;
380 [ # # # # ]: 0 : } while ((gphy_val & BIT_6) && (wait_cnt < 1000));
381 : :
382 [ # # # # ]: 0 : if ((gphy_val & BIT_6) && wait_cnt == 1000)
383 : : bool_success = FALSE;
384 : :
385 : 0 : rtl_mdio_write(hw, 0x1f, 0x0000);
386 : : }
387 : :
388 [ # # ]: 0 : if (!bool_success)
389 : 0 : PMD_INIT_LOG(NOTICE, "%s fail.", __func__);
390 : :
391 : 0 : return bool_success;
392 : : }
393 : :
394 : : void
395 : 0 : rtl_set_phy_mcu_ram_code(struct rtl_hw *hw, const u16 *ramcode, u16 codesize)
396 : : {
397 : : u16 i;
398 : : u16 addr;
399 : : u16 val;
400 : :
401 [ # # # # ]: 0 : if (ramcode == NULL || codesize % 2)
402 : 0 : goto out;
403 : :
404 [ # # ]: 0 : for (i = 0; i < codesize; i += 2) {
405 : 0 : addr = ramcode[i];
406 : 0 : val = ramcode[i + 1];
407 [ # # ]: 0 : if (addr == 0xFFFF && val == 0xFFFF)
408 : : break;
409 : 0 : rtl_mdio_direct_write_phy_ocp(hw, addr, val);
410 : : }
411 : :
412 : 0 : out:
413 : 0 : return;
414 : : }
415 : :
416 : : static u8
417 : 0 : rtl_is_phy_disable_mode_enabled(struct rtl_hw *hw)
418 : : {
419 : : u8 phy_disable_mode_enabled = FALSE;
420 : :
421 [ # # # ]: 0 : switch (hw->HwSuppCheckPhyDisableModeVer) {
422 : 0 : case 1:
423 [ # # ]: 0 : if (rtl_mac_ocp_read(hw, 0xDC20) & BIT_1)
424 : : phy_disable_mode_enabled = TRUE;
425 : : break;
426 : 0 : case 2:
427 : : case 3:
428 [ # # ]: 0 : if (RTL_R8(hw, 0xF2) & BIT_5)
429 : : phy_disable_mode_enabled = TRUE;
430 : : break;
431 : : }
432 : :
433 : 0 : return phy_disable_mode_enabled;
434 : : }
435 : :
436 : : static u8
437 : 0 : rtl_is_gpio_low(struct rtl_hw *hw)
438 : : {
439 : : u8 gpio_low = FALSE;
440 : :
441 [ # # # ]: 0 : switch (hw->HwSuppCheckPhyDisableModeVer) {
442 : 0 : case 1:
443 : : case 2:
444 [ # # ]: 0 : if (!(rtl_mac_ocp_read(hw, 0xDC04) & BIT_9))
445 : : gpio_low = TRUE;
446 : : break;
447 : 0 : case 3:
448 [ # # ]: 0 : if (!(rtl_mac_ocp_read(hw, 0xDC04) & BIT_13))
449 : : gpio_low = TRUE;
450 : : break;
451 : : }
452 : :
453 : 0 : return gpio_low;
454 : : }
455 : :
456 : : static u8
457 : 0 : rtl_is_in_phy_disable_mode(struct rtl_hw *hw)
458 : : {
459 : : u8 in_phy_disable_mode = FALSE;
460 : :
461 [ # # # # ]: 0 : if (rtl_is_phy_disable_mode_enabled(hw) && rtl_is_gpio_low(hw))
462 : : in_phy_disable_mode = TRUE;
463 : :
464 : 0 : return in_phy_disable_mode;
465 : : }
466 : :
467 : : static void
468 : 0 : rtl_wait_phy_ups_resume(struct rtl_hw *hw, u16 PhyState)
469 : : {
470 : : u16 tmp_phy_state;
471 : : int i = 0;
472 : :
473 [ # # ]: 0 : if (hw->mcfg >= CFG_METHOD_29 && hw->mcfg <= CFG_METHOD_36) {
474 : : do {
475 : 0 : tmp_phy_state = rtl_mdio_real_read_phy_ocp(hw, 0x0A42, 0x10);
476 : 0 : tmp_phy_state &= 0x7;
477 : : rte_delay_ms(1);
478 : 0 : i++;
479 [ # # ]: 0 : } while ((i < 100) && (tmp_phy_state != PhyState));
480 [ # # ]: 0 : } else if (rtl_is_8125(hw)) {
481 : : do {
482 : 0 : tmp_phy_state = rtl_mdio_direct_read_phy_ocp(hw, 0xA420);
483 : 0 : tmp_phy_state &= 0x7;
484 : : rte_delay_ms(1);
485 : 0 : i++;
486 [ # # ]: 0 : } while ((i < 100) && (tmp_phy_state != PhyState));
487 : : }
488 : 0 : }
489 : :
490 : : static void
491 : 0 : rtl_phy_power_up(struct rtl_hw *hw)
492 : : {
493 [ # # ]: 0 : if (rtl_is_in_phy_disable_mode(hw))
494 : : return;
495 : :
496 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
497 : :
498 : 0 : rtl_mdio_write(hw, MII_BMCR, BMCR_ANENABLE);
499 : :
500 : : /* Wait mdc/mdio ready */
501 [ # # # # ]: 0 : if (hw->mcfg == CFG_METHOD_23 || hw->mcfg == CFG_METHOD_27 ||
502 : : hw->mcfg == CFG_METHOD_28)
503 : : rte_delay_ms(10);
504 : :
505 : : /* Wait ups resume (phy state 3) */
506 : 0 : rtl_wait_phy_ups_resume(hw, 3);
507 : : }
508 : :
509 : : void
510 : 0 : rtl_powerup_pll(struct rtl_hw *hw)
511 : : {
512 [ # # ]: 0 : if (!(hw->mcfg == CFG_METHOD_23 || hw->mcfg == CFG_METHOD_37))
513 : 0 : RTL_W8(hw, PMCH, RTL_R8(hw, PMCH) | BIT_7 | BIT_6);
514 : :
515 : 0 : rtl_phy_power_up(hw);
516 : 0 : }
517 : :
518 : : static void
519 : 0 : rtl_phy_power_down(struct rtl_hw *hw)
520 : : {
521 : : u32 csi_tmp;
522 : :
523 : : /* MCU PME intr masks */
524 [ # # ]: 0 : if (hw->mcfg >= CFG_METHOD_21 && hw->mcfg <= CFG_METHOD_24) {
525 : 0 : csi_tmp = rtl_eri_read(hw, 0x1AB, 1, ERIAR_ExGMAC);
526 : 0 : csi_tmp &= ~(BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6 | BIT_7);
527 : 0 : rtl_eri_write(hw, 0x1AB, 1, csi_tmp, ERIAR_ExGMAC);
528 [ # # ]: 0 : } else if (hw->mcfg == CFG_METHOD_25 ||
529 : : (hw->mcfg >= CFG_METHOD_27 && hw->mcfg <= CFG_METHOD_37)) {
530 : 0 : csi_tmp = rtl_eri_read(hw, 0x1AB, 1, ERIAR_ExGMAC);
531 : 0 : csi_tmp &= ~(BIT_3 | BIT_6);
532 : 0 : rtl_eri_write(hw, 0x1AB, 1, csi_tmp, ERIAR_ExGMAC);
533 : : }
534 : :
535 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
536 : :
537 [ # # ]: 0 : if ((hw->mcfg >= CFG_METHOD_25 && hw->mcfg <= CFG_METHOD_28) ||
538 : : (hw->mcfg >= CFG_METHOD_31 && hw->mcfg <= CFG_METHOD_34))
539 : 0 : rtl_mdio_write(hw, MII_BMCR, BMCR_PDOWN);
540 : : else
541 : 0 : rtl_mdio_write(hw, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN);
542 : 0 : }
543 : :
544 : : void
545 : 0 : rtl_powerdown_pll(struct rtl_hw *hw)
546 : : {
547 [ # # ]: 0 : if (hw->DASH)
548 : : return;
549 : :
550 : 0 : rtl_phy_power_down(hw);
551 : :
552 [ # # ]: 0 : if (!hw->HwIcVerUnknown) {
553 [ # # # # : 0 : if (!(hw->mcfg == CFG_METHOD_23 || hw->mcfg == CFG_METHOD_37 ||
# # ]
554 : : hw->mcfg == CFG_METHOD_60 || hw->mcfg == CFG_METHOD_91))
555 : 0 : RTL_W8(hw, PMCH, RTL_R8(hw, PMCH) & ~BIT_7);
556 : : }
557 : :
558 [ # # ]: 0 : if (hw->mcfg >= CFG_METHOD_21 && hw->mcfg <= CFG_METHOD_36) {
559 : 0 : RTL_W8(hw, 0xD0, RTL_R8(hw, 0xD0) & ~BIT_6);
560 : 0 : RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) & ~BIT_6);
561 : : }
562 : : }
563 : :
564 : : void
565 : 0 : rtl_hw_ephy_config(struct rtl_hw *hw)
566 : : {
567 : 0 : hw->hw_ops.hw_ephy_config(hw);
568 : 0 : }
569 : :
570 : : static int
571 : 0 : rtl_wait_phy_reset_complete(struct rtl_hw *hw)
572 : : {
573 : : int i, val;
574 : :
575 [ # # ]: 0 : for (i = 0; i < 2500; i++) {
576 : 0 : val = rtl_mdio_read(hw, MII_BMCR) & BMCR_RESET;
577 [ # # ]: 0 : if (!val)
578 : : return 0;
579 : :
580 : : rte_delay_ms(1);
581 : : }
582 : :
583 : : return -1;
584 : : }
585 : :
586 : : static void
587 : 0 : rtl_xmii_reset_enable(struct rtl_hw *hw)
588 : : {
589 : : u32 val;
590 : :
591 [ # # ]: 0 : if (rtl_is_in_phy_disable_mode(hw))
592 : : return;
593 : :
594 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
595 : :
596 : 0 : val = rtl_mdio_read(hw, MII_ADVERTISE);
597 : 0 : val &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF |
598 : : ADVERTISE_100FULL);
599 : 0 : rtl_mdio_write(hw, MII_ADVERTISE, val);
600 : :
601 : 0 : val = rtl_mdio_read(hw, MII_CTRL1000);
602 : 0 : val &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
603 : 0 : rtl_mdio_write(hw, MII_CTRL1000, val);
604 : :
605 [ # # ]: 0 : if (rtl_is_8125(hw)) {
606 : 0 : val = rtl_mdio_direct_read_phy_ocp(hw, 0xA5D4);
607 : 0 : val &= ~(RTK_ADVERTISE_2500FULL | RTK_ADVERTISE_5000FULL |
608 : : RTK_ADVERTISE_10000FULL);
609 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xA5D4, val);
610 : : }
611 : :
612 : 0 : rtl_mdio_write(hw, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
613 : :
614 [ # # ]: 0 : if (rtl_wait_phy_reset_complete(hw))
615 : 0 : PMD_INIT_LOG(NOTICE, "PHY reset failed.");
616 : : }
617 : :
618 : : static void
619 : 0 : rtl8125_set_hw_phy_before_init_phy_mcu(struct rtl_hw *hw)
620 : : {
621 : : u16 val;
622 : :
623 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_50) {
624 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xBF86, 0x9000);
625 : :
626 : 0 : rtl_set_eth_phy_ocp_bit(hw, 0xC402, BIT_10);
627 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xC402, BIT_10);
628 : :
629 : 0 : val = rtl_mdio_direct_read_phy_ocp(hw, 0xBF86);
630 : 0 : val &= (BIT_1 | BIT_0);
631 [ # # ]: 0 : if (val != 0)
632 : 0 : PMD_INIT_LOG(NOTICE, "PHY watch dog not clear, value = 0x%x",
633 : : val);
634 : :
635 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xBD86, 0x1010);
636 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xBD88, 0x1010);
637 : :
638 : 0 : rtl_clear_and_set_eth_phy_ocp_bit(hw, 0xBD4E, (BIT_11 | BIT_10), BIT_11);
639 : 0 : rtl_clear_and_set_eth_phy_ocp_bit(hw, 0xBF46, (BIT_11 | BIT_10 | BIT_9 | BIT_8),
640 : : (BIT_10 | BIT_9 | BIT_8));
641 : : }
642 : 0 : }
643 : :
644 : : static u16
645 : 0 : rtl_get_hw_phy_mcu_code_ver(struct rtl_hw *hw)
646 : : {
647 : : u16 hw_ram_code_ver = ~0;
648 : :
649 [ # # ]: 0 : if (rtl_is_8125(hw)) {
650 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xA436, 0x801E);
651 : 0 : hw_ram_code_ver = rtl_mdio_direct_read_phy_ocp(hw, 0xA438);
652 : : } else {
653 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A43);
654 : 0 : rtl_mdio_write(hw, 0x13, 0x801E);
655 : 0 : hw_ram_code_ver = rtl_mdio_read(hw, 0x14);
656 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
657 : : }
658 : :
659 : 0 : return hw_ram_code_ver;
660 : : }
661 : :
662 : : static int
663 : : rtl_check_hw_phy_mcu_code_ver(struct rtl_hw *hw)
664 : : {
665 : : int ram_code_ver_match = 0;
666 : :
667 : 0 : hw->hw_ram_code_ver = rtl_get_hw_phy_mcu_code_ver(hw);
668 : :
669 [ # # ]: 0 : if (hw->hw_ram_code_ver == hw->sw_ram_code_ver) {
670 : : ram_code_ver_match = 1;
671 : 0 : hw->HwHasWrRamCodeToMicroP = TRUE;
672 : : } else {
673 : 0 : hw->HwHasWrRamCodeToMicroP = FALSE;
674 : : }
675 : :
676 : : return ram_code_ver_match;
677 : : }
678 : :
679 : : static void
680 : 0 : rtl_write_hw_phy_mcu_code_ver(struct rtl_hw *hw)
681 : : {
682 [ # # ]: 0 : if (rtl_is_8125(hw)) {
683 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xA436, 0x801E);
684 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xA438, hw->sw_ram_code_ver);
685 : 0 : hw->hw_ram_code_ver = hw->sw_ram_code_ver;
686 : : } else {
687 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A43);
688 : 0 : rtl_mdio_write(hw, 0x13, 0x801E);
689 : 0 : rtl_mdio_write(hw, 0x14, hw->sw_ram_code_ver);
690 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
691 : 0 : hw->hw_ram_code_ver = hw->sw_ram_code_ver;
692 : : }
693 : 0 : }
694 : :
695 : : static void
696 : 0 : rtl_enable_phy_disable_mode(struct rtl_hw *hw)
697 : : {
698 [ # # # ]: 0 : switch (hw->HwSuppCheckPhyDisableModeVer) {
699 : 0 : case 1:
700 : 0 : rtl_mac_ocp_write(hw, 0xDC20, rtl_mac_ocp_read(hw, 0xDC20) |
701 : : BIT_1);
702 : 0 : break;
703 : 0 : case 2:
704 : : case 3:
705 : 0 : RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) | BIT_5);
706 : : break;
707 : : }
708 : 0 : }
709 : :
710 : : static void
711 : 0 : rtl_disable_phy_disable_mode(struct rtl_hw *hw)
712 : : {
713 [ # # # ]: 0 : switch (hw->HwSuppCheckPhyDisableModeVer) {
714 : 0 : case 1:
715 : 0 : rtl_mac_ocp_write(hw, 0xDC20, rtl_mac_ocp_read(hw, 0xDC20) &
716 : : ~BIT_1);
717 : 0 : break;
718 : 0 : case 2:
719 : : case 3:
720 : 0 : RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) & ~BIT_5);
721 : : break;
722 : : }
723 : :
724 : : rte_delay_ms(1);
725 : 0 : }
726 : :
727 : : static int
728 : 0 : rtl8168_phy_ram_code_check(struct rtl_hw *hw)
729 : : {
730 : : u16 val;
731 : : int retval = TRUE;
732 : :
733 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_21) {
734 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A40);
735 : 0 : val = rtl_mdio_read(hw, 0x10);
736 : 0 : val &= ~BIT_11;
737 : 0 : rtl_mdio_write(hw, 0x10, val);
738 : :
739 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A00);
740 : 0 : val = rtl_mdio_read(hw, 0x10);
741 : 0 : val &= ~(BIT_12 | BIT_13 | BIT_14 | BIT_15);
742 : 0 : rtl_mdio_write(hw, 0x10, val);
743 : :
744 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A43);
745 : 0 : rtl_mdio_write(hw, 0x13, 0x8010);
746 : 0 : val = rtl_mdio_read(hw, 0x14);
747 : 0 : val &= ~BIT_11;
748 : 0 : rtl_mdio_write(hw, 0x14, val);
749 : :
750 : 0 : retval = rtl_set_phy_mcu_patch_request(hw);
751 : :
752 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A40);
753 : 0 : rtl_mdio_write(hw, 0x10, 0x0140);
754 : :
755 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A4A);
756 : 0 : val = rtl_mdio_read(hw, 0x13);
757 : 0 : val &= ~BIT_6;
758 : 0 : val |= BIT_7;
759 : 0 : rtl_mdio_write(hw, 0x13, val);
760 : :
761 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A44);
762 : 0 : val = rtl_mdio_read(hw, 0x14);
763 : 0 : val |= BIT_2;
764 : 0 : rtl_mdio_write(hw, 0x14, val);
765 : :
766 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A50);
767 : 0 : val = rtl_mdio_read(hw, 0x11);
768 : 0 : val |= (BIT_11 | BIT_12);
769 : 0 : rtl_mdio_write(hw, 0x11, val);
770 : :
771 : 0 : retval = rtl_clear_phy_mcu_patch_request(hw);
772 : :
773 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A40);
774 : 0 : rtl_mdio_write(hw, 0x10, 0x1040);
775 : :
776 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A4A);
777 : 0 : val = rtl_mdio_read(hw, 0x13);
778 : 0 : val &= ~(BIT_6 | BIT_7);
779 : 0 : rtl_mdio_write(hw, 0x13, val);
780 : :
781 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A44);
782 : 0 : val = rtl_mdio_read(hw, 0x14);
783 : 0 : val &= ~BIT_2;
784 : 0 : rtl_mdio_write(hw, 0x14, val);
785 : :
786 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A50);
787 : 0 : val = rtl_mdio_read(hw, 0x11);
788 : 0 : val &= ~(BIT_11 | BIT_12);
789 : 0 : rtl_mdio_write(hw, 0x11, val);
790 : :
791 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A43);
792 : 0 : rtl_mdio_write(hw, 0x13, 0x8010);
793 : 0 : val = rtl_mdio_read(hw, 0x14);
794 : 0 : val |= BIT_11;
795 : 0 : rtl_mdio_write(hw, 0x14, val);
796 : :
797 : 0 : retval = rtl_set_phy_mcu_patch_request(hw);
798 : :
799 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A20);
800 : 0 : val = rtl_mdio_read(hw, 0x13);
801 [ # # ]: 0 : if (val & BIT_11) {
802 [ # # ]: 0 : if (val & BIT_10)
803 : : retval = FALSE;
804 : : }
805 : :
806 : 0 : rtl_clear_phy_mcu_patch_request(hw);
807 : :
808 : : rte_delay_ms(2);
809 : : }
810 : :
811 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
812 : :
813 : 0 : return retval;
814 : : }
815 : :
816 : : static void
817 : 0 : rtl8168_set_phy_ram_code_check_fail_flag(struct rtl_hw *hw)
818 : : {
819 : : u16 tmp_ushort;
820 : :
821 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_21) {
822 : 0 : tmp_ushort = rtl_mac_ocp_read(hw, 0xD3C0);
823 : 0 : tmp_ushort |= BIT_0;
824 : 0 : rtl_mac_ocp_write(hw, 0xD3C0, tmp_ushort);
825 : : }
826 : 0 : }
827 : :
828 : : static void
829 : 0 : rtl_init_hw_phy_mcu(struct rtl_hw *hw)
830 : : {
831 : : u8 require_disable_phy_disable_mode = FALSE;
832 : :
833 [ # # ]: 0 : if (hw->NotWrRamCodeToMicroP)
834 : : return;
835 : :
836 : : if (rtl_check_hw_phy_mcu_code_ver(hw))
837 : 0 : return;
838 : :
839 [ # # # # ]: 0 : if (!rtl_is_8125(hw) && !rtl8168_phy_ram_code_check(hw)) {
840 : 0 : rtl8168_set_phy_ram_code_check_fail_flag(hw);
841 : 0 : return;
842 : : }
843 : :
844 [ # # # # ]: 0 : if (HW_SUPPORT_CHECK_PHY_DISABLE_MODE(hw) && rtl_is_in_phy_disable_mode(hw))
845 : : require_disable_phy_disable_mode = TRUE;
846 : :
847 : : if (require_disable_phy_disable_mode)
848 : 0 : rtl_disable_phy_disable_mode(hw);
849 : :
850 : 0 : hw->hw_ops.hw_phy_mcu_config(hw);
851 : :
852 [ # # ]: 0 : if (require_disable_phy_disable_mode)
853 : 0 : rtl_enable_phy_disable_mode(hw);
854 : :
855 : 0 : rtl_write_hw_phy_mcu_code_ver(hw);
856 : :
857 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
858 : :
859 : 0 : hw->HwHasWrRamCodeToMicroP = TRUE;
860 : : }
861 : :
862 : : static void
863 : 0 : rtl_disable_aldps(struct rtl_hw *hw)
864 : : {
865 : : u16 tmp_ushort;
866 : : u32 timeout = 0;
867 : : u32 wait_cnt = 200;
868 : :
869 [ # # ]: 0 : if (rtl_is_8125(hw)) {
870 : 0 : tmp_ushort = rtl_mdio_real_direct_read_phy_ocp(hw, 0xA430);
871 [ # # ]: 0 : if (tmp_ushort & BIT_2) {
872 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA430, BIT_2);
873 : :
874 : : do {
875 : 0 : rte_delay_us(100);
876 : 0 : tmp_ushort = rtl_mac_ocp_read(hw, 0xE908);
877 : 0 : timeout++;
878 [ # # # # ]: 0 : } while (!(tmp_ushort & BIT_7) && timeout < wait_cnt);
879 : : }
880 : : } else {
881 : 0 : tmp_ushort = rtl_mdio_real_direct_read_phy_ocp(hw, 0xA430);
882 [ # # ]: 0 : if (tmp_ushort & BIT_2)
883 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA430, BIT_2);
884 : : }
885 : 0 : }
886 : :
887 : : static bool
888 : 0 : rtl_is_adv_eee_enabled(struct rtl_hw *hw)
889 : : {
890 : : bool enabled = false;
891 : :
892 [ # # ]: 0 : if (rtl_is_8125(hw)) {
893 [ # # ]: 0 : if (rtl_mdio_direct_read_phy_ocp(hw, 0xA430) & BIT_15)
894 : : enabled = true;
895 [ # # ]: 0 : } else if (hw->mcfg >= CFG_METHOD_25 && hw->mcfg <= CFG_METHOD_36) {
896 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A43);
897 [ # # ]: 0 : if (rtl_mdio_read(hw, 0x10) & BIT_15)
898 : : enabled = true;
899 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
900 : : }
901 : :
902 : 0 : return enabled;
903 : : }
904 : :
905 : : static void
906 : 0 : _rtl_disable_adv_eee(struct rtl_hw *hw)
907 : : {
908 : : bool lock;
909 : : u16 data;
910 : :
911 [ # # ]: 0 : if (rtl_is_adv_eee_enabled(hw))
912 : : lock = true;
913 : : else
914 : : lock = false;
915 : :
916 : : if (lock)
917 : 0 : rtl_set_phy_mcu_patch_request(hw);
918 : :
919 [ # # # # : 0 : switch (hw->mcfg) {
# ]
920 : 0 : case CFG_METHOD_25:
921 : 0 : rtl_eri_write(hw, 0x1EA, 1, 0x00, ERIAR_ExGMAC);
922 : :
923 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A42);
924 : 0 : data = rtl_mdio_read(hw, 0x16);
925 : 0 : data &= ~BIT_1;
926 : 0 : rtl_mdio_write(hw, 0x16, data);
927 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
928 : 0 : break;
929 : 0 : case CFG_METHOD_26:
930 : 0 : data = rtl_mac_ocp_read(hw, 0xE052);
931 : 0 : data &= ~BIT_0;
932 : 0 : rtl_mac_ocp_write(hw, 0xE052, data);
933 : :
934 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A42);
935 : 0 : data = rtl_mdio_read(hw, 0x16);
936 : 0 : data &= ~BIT_1;
937 : 0 : rtl_mdio_write(hw, 0x16, data);
938 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
939 : 0 : break;
940 : 0 : case CFG_METHOD_27:
941 : : case CFG_METHOD_28:
942 : 0 : data = rtl_mac_ocp_read(hw, 0xE052);
943 : 0 : data &= ~BIT_0;
944 : 0 : rtl_mac_ocp_write(hw, 0xE052, data);
945 : 0 : break;
946 : 0 : case CFG_METHOD_29:
947 : : case CFG_METHOD_30:
948 : : case CFG_METHOD_31:
949 : : case CFG_METHOD_32:
950 : : case CFG_METHOD_33:
951 : : case CFG_METHOD_34:
952 : : case CFG_METHOD_35:
953 : : case CFG_METHOD_36:
954 : 0 : data = rtl_mac_ocp_read(hw, 0xE052);
955 : 0 : data &= ~BIT_0;
956 : 0 : rtl_mac_ocp_write(hw, 0xE052, data);
957 : :
958 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A43);
959 : 0 : data = rtl_mdio_read(hw, 0x10) & ~(BIT_15);
960 : 0 : rtl_mdio_write(hw, 0x10, data);
961 : :
962 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A44);
963 : 0 : data = rtl_mdio_read(hw, 0x11) & ~(BIT_12 | BIT_13 | BIT_14);
964 : 0 : rtl_mdio_write(hw, 0x11, data);
965 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
966 : 0 : break;
967 : 0 : default:
968 [ # # ]: 0 : if (!rtl_is_8125(hw))
969 : : break;
970 : 0 : rtl_clear_mac_ocp_bit(hw, 0xE052, BIT_0);
971 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA442, (BIT_12 | BIT_13));
972 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA430, BIT_15);
973 : 0 : break;
974 : : }
975 : :
976 [ # # ]: 0 : if (lock)
977 : 0 : rtl_clear_phy_mcu_patch_request(hw);
978 : 0 : }
979 : :
980 : : static void
981 : 0 : rtl_disable_adv_eee(struct rtl_hw *hw)
982 : : {
983 [ # # ]: 0 : if (hw->mcfg < CFG_METHOD_25 || hw->mcfg == CFG_METHOD_37)
984 : : return;
985 : :
986 : 0 : rtl_oob_mutex_lock(hw);
987 : :
988 : 0 : _rtl_disable_adv_eee(hw);
989 : :
990 : 0 : rtl_oob_mutex_unlock(hw);
991 : : }
992 : :
993 : : static void
994 : 0 : rtl_disable_eee(struct rtl_hw *hw)
995 : : {
996 : : u16 data;
997 : : u16 mask;
998 : : u32 csi_tmp;
999 : :
1000 [ # # # # : 0 : switch (hw->mcfg) {
# ]
1001 : 0 : case CFG_METHOD_21:
1002 : : case CFG_METHOD_22:
1003 : : case CFG_METHOD_23:
1004 : : case CFG_METHOD_24:
1005 : : case CFG_METHOD_25:
1006 : : case CFG_METHOD_26:
1007 : : case CFG_METHOD_27:
1008 : : case CFG_METHOD_28:
1009 : : case CFG_METHOD_29:
1010 : : case CFG_METHOD_30:
1011 : : case CFG_METHOD_31:
1012 : : case CFG_METHOD_32:
1013 : : case CFG_METHOD_33:
1014 : : case CFG_METHOD_34:
1015 : : case CFG_METHOD_35:
1016 : : case CFG_METHOD_36:
1017 : 0 : csi_tmp = rtl_eri_read(hw, 0x1B0, 4, ERIAR_ExGMAC);
1018 : 0 : csi_tmp &= ~(BIT_1 | BIT_0);
1019 : 0 : rtl_eri_write(hw, 0x1B0, 4, csi_tmp, ERIAR_ExGMAC);
1020 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A43);
1021 : 0 : data = rtl_mdio_read(hw, 0x11);
1022 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_36)
1023 : 0 : rtl_mdio_write(hw, 0x11, data | BIT_4);
1024 : : else
1025 : 0 : rtl_mdio_write(hw, 0x11, data & ~BIT_4);
1026 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A5D);
1027 : 0 : rtl_mdio_write(hw, 0x10, 0x0000);
1028 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1029 : 0 : break;
1030 : 0 : case CFG_METHOD_48:
1031 : : case CFG_METHOD_49:
1032 : : case CFG_METHOD_52:
1033 : 0 : rtl_clear_mac_ocp_bit(hw, 0xE040, (BIT_1 | BIT_0));
1034 : 0 : rtl_clear_mac_ocp_bit(hw, 0xEB62, (BIT_2 | BIT_1));
1035 : :
1036 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA432, BIT_4);
1037 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA5D0, (BIT_2 | BIT_1));
1038 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D4, BIT_0);
1039 : :
1040 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D8, BIT_4);
1041 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_7);
1042 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA4A2, BIT_9);
1043 : 0 : break;
1044 : 0 : case CFG_METHOD_50:
1045 : : case CFG_METHOD_51:
1046 : : case CFG_METHOD_53:
1047 : : case CFG_METHOD_54:
1048 : : case CFG_METHOD_55:
1049 : : case CFG_METHOD_56:
1050 : : case CFG_METHOD_57:
1051 : : case CFG_METHOD_58:
1052 : : case CFG_METHOD_59:
1053 : : case CFG_METHOD_60:
1054 : : case CFG_METHOD_61:
1055 : 0 : rtl_clear_mac_ocp_bit(hw, 0xE040, (BIT_1 | BIT_0));
1056 : :
1057 : 0 : rtl_set_eth_phy_ocp_bit(hw, 0xA432, BIT_4);
1058 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA5D0, (BIT_2 | BIT_1));
1059 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D4, BIT_0);
1060 : :
1061 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D8, BIT_4);
1062 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_7);
1063 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA4A2, BIT_9);
1064 : 0 : break;
1065 : 0 : case CFG_METHOD_70:
1066 : : case CFG_METHOD_71:
1067 : : case CFG_METHOD_91:
1068 : 0 : rtl_clear_mac_ocp_bit(hw, 0xE040, (BIT_1 | BIT_0));
1069 : :
1070 [ # # ]: 0 : if (HW_SUPP_PHY_LINK_SPEED_10000M(hw))
1071 : : mask = MDIO_EEE_100TX | MDIO_EEE_1000T | MDIO_EEE_10GT;
1072 : : else
1073 : : mask = MDIO_EEE_100TX | MDIO_EEE_1000T;
1074 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA5D0, mask);
1075 : :
1076 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D4, MDIO_EEE_2_5GT | MDIO_EEE_5GT);
1077 : :
1078 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D8, BIT_4);
1079 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_7);
1080 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA4A2, BIT_9);
1081 : 0 : break;
1082 : : default:
1083 : : /* Not support EEE */
1084 : : break;
1085 : : }
1086 : :
1087 [ # # ]: 0 : switch (hw->mcfg) {
1088 : 0 : case CFG_METHOD_29:
1089 : : case CFG_METHOD_30:
1090 : : case CFG_METHOD_35:
1091 : : case CFG_METHOD_36:
1092 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A42);
1093 : 0 : rtl_clear_eth_phy_bit(hw, 0x14, BIT_7);
1094 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A4A);
1095 : 0 : rtl_clear_eth_phy_bit(hw, 0x11, BIT_9);
1096 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1097 : 0 : break;
1098 : : }
1099 : :
1100 : : /* Advanced EEE */
1101 : 0 : rtl_disable_adv_eee(hw);
1102 : 0 : }
1103 : :
1104 : : void
1105 : 0 : rtl_hw_phy_config(struct rtl_hw *hw)
1106 : : {
1107 : 0 : rtl_xmii_reset_enable(hw);
1108 : :
1109 [ # # # # ]: 0 : if (HW_DASH_SUPPORT_TYPE_3(hw) && hw->HwPkgDet == 0x06)
1110 : : return;
1111 : :
1112 : 0 : rtl8125_set_hw_phy_before_init_phy_mcu(hw);
1113 : :
1114 : 0 : rtl_init_hw_phy_mcu(hw);
1115 : :
1116 : 0 : hw->hw_ops.hw_phy_config(hw);
1117 : :
1118 : 0 : rtl_disable_aldps(hw);
1119 : :
1120 : : /* Legacy force mode (chap 22) */
1121 [ # # ]: 0 : if (rtl_is_8125(hw))
1122 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA5B4, BIT_15);
1123 : :
1124 [ # # ]: 0 : if (HW_FIBER_MODE_ENABLED(hw))
1125 : 0 : rtl8127_hw_fiber_phy_config(hw);
1126 : :
1127 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1128 : :
1129 [ # # ]: 0 : if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(hw))
1130 : 0 : rtl_disable_eee(hw);
1131 : : }
1132 : :
1133 : : static void
1134 : 0 : rtl_phy_restart_nway(struct rtl_hw *hw)
1135 : : {
1136 [ # # ]: 0 : if (rtl_is_in_phy_disable_mode(hw))
1137 : : return;
1138 : :
1139 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1140 [ # # ]: 0 : if (rtl_is_8125(hw))
1141 : 0 : rtl_mdio_write(hw, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
1142 : : else
1143 : 0 : rtl_mdio_write(hw, MII_BMCR, BMCR_RESET | BMCR_ANENABLE |
1144 : : BMCR_ANRESTART);
1145 : : }
1146 : :
1147 : : static void
1148 : 0 : rtl_phy_setup_force_mode(struct rtl_hw *hw, u32 speed, u8 duplex)
1149 : : {
1150 : : u16 bmcr_true_force = 0;
1151 : :
1152 [ # # ]: 0 : if (rtl_is_in_phy_disable_mode(hw))
1153 : : return;
1154 : :
1155 [ # # ]: 0 : if (speed == SPEED_10 && duplex == DUPLEX_HALF)
1156 : : bmcr_true_force = BMCR_SPEED10;
1157 [ # # ]: 0 : else if (speed == SPEED_10 && duplex == DUPLEX_FULL)
1158 : : bmcr_true_force = BMCR_SPEED10 | BMCR_FULLDPLX;
1159 [ # # ]: 0 : else if (speed == SPEED_100 && duplex == DUPLEX_HALF)
1160 : : bmcr_true_force = BMCR_SPEED100;
1161 [ # # ]: 0 : else if (speed == SPEED_100 && duplex == DUPLEX_FULL)
1162 : : bmcr_true_force = BMCR_SPEED100 | BMCR_FULLDPLX;
1163 : : else
1164 : : return;
1165 : :
1166 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1167 : 0 : rtl_mdio_write(hw, MII_BMCR, bmcr_true_force);
1168 : : }
1169 : :
1170 : : static int
1171 : 0 : rtl_set_speed_xmii(struct rtl_hw *hw, u8 autoneg, u32 speed, u8 duplex, u64 adv)
1172 : : {
1173 : : u16 mask = 0;
1174 : : int auto_nego = 0;
1175 : : int giga_ctrl = 0;
1176 : : int ctrl_2500 = 0;
1177 : : int rc = -EINVAL;
1178 : :
1179 : : /* Disable giga lite */
1180 [ # # # # : 0 : switch (hw->mcfg) {
# ]
1181 : 0 : case CFG_METHOD_29:
1182 : : case CFG_METHOD_30:
1183 : : case CFG_METHOD_35:
1184 : : case CFG_METHOD_36:
1185 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A42);
1186 : 0 : rtl_clear_eth_phy_bit(hw, 0x14, BIT_9);
1187 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A40);
1188 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1189 : 0 : break;
1190 : 0 : case CFG_METHOD_31:
1191 : : case CFG_METHOD_32:
1192 : : case CFG_METHOD_33:
1193 : : case CFG_METHOD_34:
1194 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A42);
1195 : 0 : rtl_clear_eth_phy_bit(hw, 0x14, BIT_9 | BIT_7);
1196 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A40);
1197 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1198 : 0 : break;
1199 : 0 : case CFG_METHOD_91:
1200 : : mask |= BIT_2;
1201 : : /* Fall through */
1202 : 0 : case CFG_METHOD_70:
1203 : : case CFG_METHOD_71:
1204 : 0 : mask |= BIT_1;
1205 : : /* Fall through */
1206 : 0 : default:
1207 [ # # ]: 0 : if (!rtl_is_8125(hw))
1208 : : break;
1209 : 0 : mask |= BIT_0;
1210 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_9);
1211 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA5EA, mask);
1212 : 0 : break;
1213 : : }
1214 : :
1215 [ # # ]: 0 : if (!rtl_is_speed_mode_valid(hw, speed)) {
1216 : 0 : speed = hw->HwSuppMaxPhyLinkSpeed;
1217 : : duplex = DUPLEX_FULL;
1218 : 0 : adv |= hw->advertising;
1219 : : }
1220 : :
1221 [ # # ]: 0 : if (HW_FIBER_MODE_ENABLED(hw))
1222 : 0 : goto set_speed;
1223 : :
1224 : 0 : giga_ctrl = rtl_mdio_read(hw, MII_CTRL1000);
1225 : 0 : giga_ctrl &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
1226 [ # # ]: 0 : if (rtl_is_8125(hw)) {
1227 : 0 : ctrl_2500 = rtl_mdio_direct_read_phy_ocp(hw, 0xA5D4);
1228 : 0 : ctrl_2500 &= ~(RTK_ADVERTISE_2500FULL | RTK_ADVERTISE_5000FULL |
1229 : : RTK_ADVERTISE_10000FULL);
1230 : : }
1231 : :
1232 [ # # ]: 0 : if (autoneg == AUTONEG_ENABLE) {
1233 : : /* N-way force */
1234 : 0 : auto_nego = rtl_mdio_read(hw, MII_ADVERTISE);
1235 : 0 : auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
1236 : : ADVERTISE_100HALF | ADVERTISE_100FULL |
1237 : : ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
1238 : :
1239 [ # # ]: 0 : if (adv & ADVERTISE_10_HALF)
1240 : 0 : auto_nego |= ADVERTISE_10HALF;
1241 [ # # ]: 0 : if (adv & ADVERTISE_10_FULL)
1242 : 0 : auto_nego |= ADVERTISE_10FULL;
1243 [ # # ]: 0 : if (adv & ADVERTISE_100_HALF)
1244 : 0 : auto_nego |= ADVERTISE_100HALF;
1245 [ # # ]: 0 : if (adv & ADVERTISE_100_FULL)
1246 : 0 : auto_nego |= ADVERTISE_100FULL;
1247 [ # # ]: 0 : if (adv & ADVERTISE_1000_HALF)
1248 : 0 : giga_ctrl |= ADVERTISE_1000HALF;
1249 [ # # ]: 0 : if (adv & ADVERTISE_1000_FULL)
1250 : 0 : giga_ctrl |= ADVERTISE_1000FULL;
1251 [ # # ]: 0 : if (adv & ADVERTISE_2500_FULL)
1252 : 0 : ctrl_2500 |= RTK_ADVERTISE_2500FULL;
1253 [ # # ]: 0 : if (adv & ADVERTISE_5000_FULL)
1254 : 0 : ctrl_2500 |= RTK_ADVERTISE_5000FULL;
1255 [ # # ]: 0 : if (adv & ADVERTISE_10000_FULL)
1256 : 0 : ctrl_2500 |= RTK_ADVERTISE_10000FULL;
1257 : :
1258 : : /* Flow control */
1259 [ # # ]: 0 : if (hw->fcpause == rtl_fc_full)
1260 : 0 : auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
1261 : :
1262 : 0 : rtl_mdio_write(hw, 0x1f, 0x0000);
1263 : 0 : rtl_mdio_write(hw, MII_ADVERTISE, auto_nego);
1264 : 0 : rtl_mdio_write(hw, MII_CTRL1000, giga_ctrl);
1265 [ # # ]: 0 : if (rtl_is_8125(hw))
1266 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xA5D4, ctrl_2500);
1267 : 0 : rtl_phy_restart_nway(hw);
1268 : : rte_delay_ms(20);
1269 : : } else {
1270 : : /* True force */
1271 [ # # ]: 0 : if (speed == SPEED_10 || speed == SPEED_100)
1272 : 0 : rtl_phy_setup_force_mode(hw, speed, duplex);
1273 : : else
1274 : 0 : goto out;
1275 : : }
1276 : :
1277 : 0 : set_speed:
1278 : 0 : hw->autoneg = autoneg;
1279 : 0 : hw->speed = speed;
1280 : 0 : hw->duplex = duplex;
1281 : 0 : hw->advertising = adv;
1282 : :
1283 [ # # ]: 0 : if (HW_FIBER_MODE_ENABLED(hw))
1284 : 0 : rtl8127_hw_fiber_phy_config(hw);
1285 : :
1286 : : rc = 0;
1287 : 0 : out:
1288 : 0 : return rc;
1289 : : }
1290 : :
1291 : : int
1292 : 0 : rtl_set_speed(struct rtl_hw *hw)
1293 : : {
1294 : : int ret;
1295 : :
1296 : 0 : ret = rtl_set_speed_xmii(hw, hw->autoneg, hw->speed, hw->duplex,
1297 : : hw->advertising);
1298 : :
1299 : 0 : return ret;
1300 : : }
1301 : :
1302 : : void
1303 : 0 : rtl_clear_and_set_eth_phy_bit(struct rtl_hw *hw, u8 addr, u16 clearmask,
1304 : : u16 setmask)
1305 : : {
1306 : : u16 val;
1307 : :
1308 : 0 : val = rtl_mdio_read(hw, addr);
1309 : 0 : val &= ~clearmask;
1310 : 0 : val |= setmask;
1311 : 0 : rtl_mdio_write(hw, addr, val);
1312 : 0 : }
1313 : :
1314 : : void
1315 : 0 : rtl_clear_eth_phy_bit(struct rtl_hw *hw, u8 addr, u16 mask)
1316 : : {
1317 : 0 : rtl_clear_and_set_eth_phy_bit(hw, addr, mask, 0);
1318 : 0 : }
1319 : :
1320 : : void
1321 : 0 : rtl_set_eth_phy_bit(struct rtl_hw *hw, u8 addr, u16 mask)
1322 : : {
1323 : 0 : rtl_clear_and_set_eth_phy_bit(hw, addr, 0, mask);
1324 : 0 : }
1325 : :
1326 : : void
1327 : 0 : rtl8127_clear_ephy_ext_addr(struct rtl_hw *hw)
1328 : : {
1329 : : rtl8127_set_ephy_ext_addr(hw, 0x0000);
1330 : 0 : }
|