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_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 [ # # ]: 0 : } else if ((hw->mcfg >= CFG_METHOD_48 && hw->mcfg <= CFG_METHOD_58) ||
562 [ # # ]: 0 : (hw->mcfg >= CFG_METHOD_69 && hw->mcfg <= CFG_METHOD_71) ||
563 : : hw->mcfg == CFG_METHOD_91) {
564 : 0 : RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) & ~BIT_6);
565 : : }
566 : : }
567 : :
568 : : void
569 : 0 : rtl_hw_ephy_config(struct rtl_hw *hw)
570 : : {
571 : 0 : hw->hw_ops.hw_ephy_config(hw);
572 : 0 : }
573 : :
574 : : static int
575 : 0 : rtl_wait_phy_reset_complete(struct rtl_hw *hw)
576 : : {
577 : : int i, val;
578 : :
579 [ # # ]: 0 : for (i = 0; i < 2500; i++) {
580 : 0 : val = rtl_mdio_read(hw, MII_BMCR) & BMCR_RESET;
581 [ # # ]: 0 : if (!val)
582 : : return 0;
583 : :
584 : : rte_delay_ms(1);
585 : : }
586 : :
587 : : return -1;
588 : : }
589 : :
590 : : static void
591 : 0 : rtl_xmii_reset_enable(struct rtl_hw *hw)
592 : : {
593 : : u32 val;
594 : :
595 [ # # ]: 0 : if (rtl_is_in_phy_disable_mode(hw))
596 : : return;
597 : :
598 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
599 : :
600 : 0 : val = rtl_mdio_read(hw, MII_ADVERTISE);
601 : 0 : val &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF |
602 : : ADVERTISE_100FULL);
603 : 0 : rtl_mdio_write(hw, MII_ADVERTISE, val);
604 : :
605 : 0 : val = rtl_mdio_read(hw, MII_CTRL1000);
606 : 0 : val &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
607 : 0 : rtl_mdio_write(hw, MII_CTRL1000, val);
608 : :
609 [ # # ]: 0 : if (rtl_is_8125(hw)) {
610 : 0 : val = rtl_mdio_direct_read_phy_ocp(hw, 0xA5D4);
611 : 0 : val &= ~(RTK_ADVERTISE_2500FULL | RTK_ADVERTISE_5000FULL |
612 : : RTK_ADVERTISE_10000FULL);
613 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xA5D4, val);
614 : : }
615 : :
616 : 0 : rtl_mdio_write(hw, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
617 : :
618 [ # # ]: 0 : if (rtl_wait_phy_reset_complete(hw))
619 : 0 : PMD_INIT_LOG(NOTICE, "PHY reset failed.");
620 : : }
621 : :
622 : : static void
623 : 0 : rtl8125_set_hw_phy_before_init_phy_mcu(struct rtl_hw *hw)
624 : : {
625 : : u16 val;
626 : :
627 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_50) {
628 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xBF86, 0x9000);
629 : :
630 : 0 : rtl_set_eth_phy_ocp_bit(hw, 0xC402, BIT_10);
631 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xC402, BIT_10);
632 : :
633 : 0 : val = rtl_mdio_direct_read_phy_ocp(hw, 0xBF86);
634 : 0 : val &= (BIT_1 | BIT_0);
635 [ # # ]: 0 : if (val != 0)
636 : 0 : PMD_INIT_LOG(NOTICE, "PHY watch dog not clear, value = 0x%x",
637 : : val);
638 : :
639 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xBD86, 0x1010);
640 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xBD88, 0x1010);
641 : :
642 : 0 : rtl_clear_and_set_eth_phy_ocp_bit(hw, 0xBD4E, (BIT_11 | BIT_10), BIT_11);
643 : 0 : rtl_clear_and_set_eth_phy_ocp_bit(hw, 0xBF46, (BIT_11 | BIT_10 | BIT_9 | BIT_8),
644 : : (BIT_10 | BIT_9 | BIT_8));
645 : : }
646 : 0 : }
647 : :
648 : : static u16
649 : 0 : rtl_get_hw_phy_mcu_code_ver(struct rtl_hw *hw)
650 : : {
651 : : u16 hw_ram_code_ver = ~0;
652 : :
653 [ # # ]: 0 : if (rtl_is_8125(hw)) {
654 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xA436, 0x801E);
655 : 0 : hw_ram_code_ver = rtl_mdio_direct_read_phy_ocp(hw, 0xA438);
656 : : } else {
657 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A43);
658 : 0 : rtl_mdio_write(hw, 0x13, 0x801E);
659 : 0 : hw_ram_code_ver = rtl_mdio_read(hw, 0x14);
660 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
661 : : }
662 : :
663 : 0 : return hw_ram_code_ver;
664 : : }
665 : :
666 : : static int
667 : : rtl_check_hw_phy_mcu_code_ver(struct rtl_hw *hw)
668 : : {
669 : : int ram_code_ver_match = 0;
670 : :
671 : 0 : hw->hw_ram_code_ver = rtl_get_hw_phy_mcu_code_ver(hw);
672 : :
673 [ # # ]: 0 : if (hw->hw_ram_code_ver == hw->sw_ram_code_ver) {
674 : : ram_code_ver_match = 1;
675 : 0 : hw->HwHasWrRamCodeToMicroP = TRUE;
676 : : } else {
677 : 0 : hw->HwHasWrRamCodeToMicroP = FALSE;
678 : : }
679 : :
680 : : return ram_code_ver_match;
681 : : }
682 : :
683 : : static void
684 : 0 : rtl_write_hw_phy_mcu_code_ver(struct rtl_hw *hw)
685 : : {
686 [ # # ]: 0 : if (rtl_is_8125(hw)) {
687 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xA436, 0x801E);
688 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xA438, hw->sw_ram_code_ver);
689 : 0 : hw->hw_ram_code_ver = hw->sw_ram_code_ver;
690 : : } else {
691 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A43);
692 : 0 : rtl_mdio_write(hw, 0x13, 0x801E);
693 : 0 : rtl_mdio_write(hw, 0x14, hw->sw_ram_code_ver);
694 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
695 : 0 : hw->hw_ram_code_ver = hw->sw_ram_code_ver;
696 : : }
697 : 0 : }
698 : :
699 : : static void
700 : 0 : rtl_enable_phy_disable_mode(struct rtl_hw *hw)
701 : : {
702 [ # # # ]: 0 : switch (hw->HwSuppCheckPhyDisableModeVer) {
703 : 0 : case 1:
704 : 0 : rtl_mac_ocp_write(hw, 0xDC20, rtl_mac_ocp_read(hw, 0xDC20) |
705 : : BIT_1);
706 : 0 : break;
707 : 0 : case 2:
708 : : case 3:
709 : 0 : RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) | BIT_5);
710 : : break;
711 : : }
712 : 0 : }
713 : :
714 : : static void
715 : 0 : rtl_disable_phy_disable_mode(struct rtl_hw *hw)
716 : : {
717 [ # # # ]: 0 : switch (hw->HwSuppCheckPhyDisableModeVer) {
718 : 0 : case 1:
719 : 0 : rtl_mac_ocp_write(hw, 0xDC20, rtl_mac_ocp_read(hw, 0xDC20) &
720 : : ~BIT_1);
721 : 0 : break;
722 : 0 : case 2:
723 : : case 3:
724 : 0 : RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) & ~BIT_5);
725 : : break;
726 : : }
727 : :
728 : : rte_delay_ms(1);
729 : 0 : }
730 : :
731 : : static int
732 : 0 : rtl8168_phy_ram_code_check(struct rtl_hw *hw)
733 : : {
734 : : u16 val;
735 : : int retval = TRUE;
736 : :
737 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_21) {
738 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A40);
739 : 0 : val = rtl_mdio_read(hw, 0x10);
740 : 0 : val &= ~BIT_11;
741 : 0 : rtl_mdio_write(hw, 0x10, val);
742 : :
743 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A00);
744 : 0 : val = rtl_mdio_read(hw, 0x10);
745 : 0 : val &= ~(BIT_12 | BIT_13 | BIT_14 | BIT_15);
746 : 0 : rtl_mdio_write(hw, 0x10, val);
747 : :
748 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A43);
749 : 0 : rtl_mdio_write(hw, 0x13, 0x8010);
750 : 0 : val = rtl_mdio_read(hw, 0x14);
751 : 0 : val &= ~BIT_11;
752 : 0 : rtl_mdio_write(hw, 0x14, val);
753 : :
754 : 0 : retval = rtl_set_phy_mcu_patch_request(hw);
755 : :
756 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A40);
757 : 0 : rtl_mdio_write(hw, 0x10, 0x0140);
758 : :
759 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A4A);
760 : 0 : val = rtl_mdio_read(hw, 0x13);
761 : 0 : val &= ~BIT_6;
762 : 0 : val |= BIT_7;
763 : 0 : rtl_mdio_write(hw, 0x13, val);
764 : :
765 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A44);
766 : 0 : val = rtl_mdio_read(hw, 0x14);
767 : 0 : val |= BIT_2;
768 : 0 : rtl_mdio_write(hw, 0x14, val);
769 : :
770 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A50);
771 : 0 : val = rtl_mdio_read(hw, 0x11);
772 : 0 : val |= (BIT_11 | BIT_12);
773 : 0 : rtl_mdio_write(hw, 0x11, val);
774 : :
775 : 0 : retval = rtl_clear_phy_mcu_patch_request(hw);
776 : :
777 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A40);
778 : 0 : rtl_mdio_write(hw, 0x10, 0x1040);
779 : :
780 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A4A);
781 : 0 : val = rtl_mdio_read(hw, 0x13);
782 : 0 : val &= ~(BIT_6 | BIT_7);
783 : 0 : rtl_mdio_write(hw, 0x13, val);
784 : :
785 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A44);
786 : 0 : val = rtl_mdio_read(hw, 0x14);
787 : 0 : val &= ~BIT_2;
788 : 0 : rtl_mdio_write(hw, 0x14, val);
789 : :
790 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A50);
791 : 0 : val = rtl_mdio_read(hw, 0x11);
792 : 0 : val &= ~(BIT_11 | BIT_12);
793 : 0 : rtl_mdio_write(hw, 0x11, val);
794 : :
795 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A43);
796 : 0 : rtl_mdio_write(hw, 0x13, 0x8010);
797 : 0 : val = rtl_mdio_read(hw, 0x14);
798 : 0 : val |= BIT_11;
799 : 0 : rtl_mdio_write(hw, 0x14, val);
800 : :
801 : 0 : retval = rtl_set_phy_mcu_patch_request(hw);
802 : :
803 : 0 : rtl_mdio_write(hw, 0x1f, 0x0A20);
804 : 0 : val = rtl_mdio_read(hw, 0x13);
805 [ # # ]: 0 : if (val & BIT_11) {
806 [ # # ]: 0 : if (val & BIT_10)
807 : : retval = FALSE;
808 : : }
809 : :
810 : 0 : rtl_clear_phy_mcu_patch_request(hw);
811 : :
812 : : rte_delay_ms(2);
813 : : }
814 : :
815 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
816 : :
817 : 0 : return retval;
818 : : }
819 : :
820 : : static void
821 : 0 : rtl8168_set_phy_ram_code_check_fail_flag(struct rtl_hw *hw)
822 : : {
823 : : u16 tmp_ushort;
824 : :
825 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_21) {
826 : 0 : tmp_ushort = rtl_mac_ocp_read(hw, 0xD3C0);
827 : 0 : tmp_ushort |= BIT_0;
828 : 0 : rtl_mac_ocp_write(hw, 0xD3C0, tmp_ushort);
829 : : }
830 : 0 : }
831 : :
832 : : static void
833 : 0 : rtl_init_hw_phy_mcu(struct rtl_hw *hw)
834 : : {
835 : : u8 require_disable_phy_disable_mode = FALSE;
836 : :
837 [ # # ]: 0 : if (hw->NotWrRamCodeToMicroP)
838 : : return;
839 : :
840 : : if (rtl_check_hw_phy_mcu_code_ver(hw))
841 : 0 : return;
842 : :
843 [ # # # # ]: 0 : if (!rtl_is_8125(hw) && !rtl8168_phy_ram_code_check(hw)) {
844 : 0 : rtl8168_set_phy_ram_code_check_fail_flag(hw);
845 : 0 : return;
846 : : }
847 : :
848 [ # # # # ]: 0 : if (HW_SUPPORT_CHECK_PHY_DISABLE_MODE(hw) && rtl_is_in_phy_disable_mode(hw))
849 : : require_disable_phy_disable_mode = TRUE;
850 : :
851 : : if (require_disable_phy_disable_mode)
852 : 0 : rtl_disable_phy_disable_mode(hw);
853 : :
854 : 0 : hw->hw_ops.hw_phy_mcu_config(hw);
855 : :
856 [ # # ]: 0 : if (require_disable_phy_disable_mode)
857 : 0 : rtl_enable_phy_disable_mode(hw);
858 : :
859 : 0 : rtl_write_hw_phy_mcu_code_ver(hw);
860 : :
861 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
862 : :
863 : 0 : hw->HwHasWrRamCodeToMicroP = TRUE;
864 : : }
865 : :
866 : : static void
867 : 0 : rtl_disable_aldps(struct rtl_hw *hw)
868 : : {
869 : : u16 tmp_ushort;
870 : : u32 timeout = 0;
871 : : u32 wait_cnt = 200;
872 : :
873 [ # # ]: 0 : if (rtl_is_8125(hw)) {
874 : 0 : tmp_ushort = rtl_mdio_real_direct_read_phy_ocp(hw, 0xA430);
875 [ # # ]: 0 : if (tmp_ushort & BIT_2) {
876 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA430, BIT_2);
877 : :
878 : : do {
879 : 0 : rte_delay_us(100);
880 : 0 : tmp_ushort = rtl_mac_ocp_read(hw, 0xE908);
881 : 0 : timeout++;
882 [ # # # # ]: 0 : } while (!(tmp_ushort & BIT_7) && timeout < wait_cnt);
883 : : }
884 : : } else {
885 : 0 : tmp_ushort = rtl_mdio_real_direct_read_phy_ocp(hw, 0xA430);
886 [ # # ]: 0 : if (tmp_ushort & BIT_2)
887 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA430, BIT_2);
888 : : }
889 : 0 : }
890 : :
891 : : static bool
892 : 0 : rtl_is_adv_eee_enabled(struct rtl_hw *hw)
893 : : {
894 : : bool enabled = false;
895 : :
896 [ # # ]: 0 : if (hw->mcfg >= CFG_METHOD_25 && hw->mcfg <= CFG_METHOD_36) {
897 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A43);
898 [ # # ]: 0 : if (rtl_mdio_read(hw, 0x10) & BIT_15)
899 : : enabled = true;
900 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
901 [ # # ]: 0 : } else if ((hw->mcfg >= CFG_METHOD_48 && hw->mcfg <= CFG_METHOD_55) ||
902 : : hw->mcfg == CFG_METHOD_58 || hw->mcfg == CFG_METHOD_69 ||
903 : : hw->mcfg == CFG_METHOD_70 || hw->mcfg == CFG_METHOD_71 ||
904 : : hw->mcfg == CFG_METHOD_91){
905 [ # # ]: 0 : if (rtl_mdio_direct_read_phy_ocp(hw, 0xA430) & BIT_15)
906 : : enabled = true;
907 : : }
908 : :
909 : 0 : return enabled;
910 : : }
911 : :
912 : : static void
913 : 0 : _rtl_disable_adv_eee(struct rtl_hw *hw)
914 : : {
915 : : bool lock;
916 : : u16 data;
917 : :
918 [ # # ]: 0 : if (rtl_is_adv_eee_enabled(hw))
919 : : lock = true;
920 : : else
921 : : lock = false;
922 : :
923 : : if (lock)
924 : 0 : rtl_set_phy_mcu_patch_request(hw);
925 : :
926 [ # # # # : 0 : switch (hw->mcfg) {
# # ]
927 : 0 : case CFG_METHOD_25:
928 : 0 : rtl_eri_write(hw, 0x1EA, 1, 0x00, ERIAR_ExGMAC);
929 : :
930 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A42);
931 : 0 : data = rtl_mdio_read(hw, 0x16);
932 : 0 : data &= ~BIT_1;
933 : 0 : rtl_mdio_write(hw, 0x16, data);
934 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
935 : 0 : break;
936 : 0 : case CFG_METHOD_26:
937 : 0 : data = rtl_mac_ocp_read(hw, 0xE052);
938 : 0 : data &= ~BIT_0;
939 : 0 : rtl_mac_ocp_write(hw, 0xE052, data);
940 : :
941 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A42);
942 : 0 : data = rtl_mdio_read(hw, 0x16);
943 : 0 : data &= ~BIT_1;
944 : 0 : rtl_mdio_write(hw, 0x16, data);
945 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
946 : 0 : break;
947 : 0 : case CFG_METHOD_27:
948 : : case CFG_METHOD_28:
949 : 0 : data = rtl_mac_ocp_read(hw, 0xE052);
950 : 0 : data &= ~BIT_0;
951 : 0 : rtl_mac_ocp_write(hw, 0xE052, data);
952 : 0 : break;
953 : 0 : case CFG_METHOD_29:
954 : : case CFG_METHOD_30:
955 : : case CFG_METHOD_31:
956 : : case CFG_METHOD_32:
957 : : case CFG_METHOD_33:
958 : : case CFG_METHOD_34:
959 : : case CFG_METHOD_35:
960 : : case CFG_METHOD_36:
961 : 0 : data = rtl_mac_ocp_read(hw, 0xE052);
962 : 0 : data &= ~BIT_0;
963 : 0 : rtl_mac_ocp_write(hw, 0xE052, data);
964 : :
965 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A43);
966 : 0 : data = rtl_mdio_read(hw, 0x10) & ~(BIT_15);
967 : 0 : rtl_mdio_write(hw, 0x10, data);
968 : :
969 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A44);
970 : 0 : data = rtl_mdio_read(hw, 0x11) & ~(BIT_12 | BIT_13 | BIT_14);
971 : 0 : rtl_mdio_write(hw, 0x11, data);
972 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
973 : 0 : break;
974 : 0 : case CFG_METHOD_48:
975 : : case CFG_METHOD_49:
976 : : case CFG_METHOD_50:
977 : : case CFG_METHOD_51:
978 : : case CFG_METHOD_52:
979 : : case CFG_METHOD_53:
980 : : case CFG_METHOD_54:
981 : : case CFG_METHOD_55:
982 : : case CFG_METHOD_56:
983 : : case CFG_METHOD_57:
984 : : case CFG_METHOD_58:
985 : : case CFG_METHOD_69:
986 : : case CFG_METHOD_70:
987 : : case CFG_METHOD_71:
988 : : case CFG_METHOD_91:
989 : 0 : rtl_clear_mac_ocp_bit(hw, 0xE052, BIT_0);
990 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA442, (BIT_12 | BIT_13));
991 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA430, BIT_15);
992 : 0 : break;
993 : : }
994 : :
995 [ # # ]: 0 : if (lock)
996 : 0 : rtl_clear_phy_mcu_patch_request(hw);
997 : 0 : }
998 : :
999 : : static void
1000 : 0 : rtl_disable_adv_eee(struct rtl_hw *hw)
1001 : : {
1002 [ # # ]: 0 : if (hw->mcfg < CFG_METHOD_25 || hw->mcfg == CFG_METHOD_37)
1003 : : return;
1004 : :
1005 : 0 : rtl_oob_mutex_lock(hw);
1006 : :
1007 : 0 : _rtl_disable_adv_eee(hw);
1008 : :
1009 : 0 : rtl_oob_mutex_unlock(hw);
1010 : : }
1011 : :
1012 : : static void
1013 : 0 : rtl_disable_eee(struct rtl_hw *hw)
1014 : : {
1015 : : u16 data;
1016 : : u16 mask;
1017 : : u32 csi_tmp;
1018 : :
1019 [ # # # # : 0 : switch (hw->mcfg) {
# ]
1020 : 0 : case CFG_METHOD_21:
1021 : : case CFG_METHOD_22:
1022 : : case CFG_METHOD_23:
1023 : : case CFG_METHOD_24:
1024 : : case CFG_METHOD_25:
1025 : : case CFG_METHOD_26:
1026 : : case CFG_METHOD_27:
1027 : : case CFG_METHOD_28:
1028 : : case CFG_METHOD_29:
1029 : : case CFG_METHOD_30:
1030 : : case CFG_METHOD_31:
1031 : : case CFG_METHOD_32:
1032 : : case CFG_METHOD_33:
1033 : : case CFG_METHOD_34:
1034 : : case CFG_METHOD_35:
1035 : : case CFG_METHOD_36:
1036 : 0 : csi_tmp = rtl_eri_read(hw, 0x1B0, 4, ERIAR_ExGMAC);
1037 : 0 : csi_tmp &= ~(BIT_1 | BIT_0);
1038 : 0 : rtl_eri_write(hw, 0x1B0, 4, csi_tmp, ERIAR_ExGMAC);
1039 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A43);
1040 : 0 : data = rtl_mdio_read(hw, 0x11);
1041 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_36)
1042 : 0 : rtl_mdio_write(hw, 0x11, data | BIT_4);
1043 : : else
1044 : 0 : rtl_mdio_write(hw, 0x11, data & ~BIT_4);
1045 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A5D);
1046 : 0 : rtl_mdio_write(hw, 0x10, 0x0000);
1047 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1048 : 0 : break;
1049 : 0 : case CFG_METHOD_48:
1050 : : case CFG_METHOD_49:
1051 : : case CFG_METHOD_52:
1052 : 0 : rtl_clear_mac_ocp_bit(hw, 0xE040, (BIT_1 | BIT_0));
1053 : 0 : rtl_clear_mac_ocp_bit(hw, 0xEB62, (BIT_2 | BIT_1));
1054 : :
1055 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA432, BIT_4);
1056 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA5D0, (BIT_2 | BIT_1));
1057 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D4, BIT_0);
1058 : :
1059 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D8, BIT_4);
1060 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_7);
1061 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA4A2, BIT_9);
1062 : 0 : break;
1063 : 0 : case CFG_METHOD_50:
1064 : : case CFG_METHOD_51:
1065 : : case CFG_METHOD_53:
1066 : : case CFG_METHOD_54:
1067 : : case CFG_METHOD_55:
1068 : : case CFG_METHOD_56:
1069 : : case CFG_METHOD_57:
1070 : : case CFG_METHOD_58:
1071 : 0 : rtl_clear_mac_ocp_bit(hw, 0xE040, (BIT_1 | BIT_0));
1072 : :
1073 : 0 : rtl_set_eth_phy_ocp_bit(hw, 0xA432, BIT_4);
1074 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA5D0, (BIT_2 | BIT_1));
1075 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D4, BIT_0);
1076 : :
1077 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D8, BIT_4);
1078 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_7);
1079 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA4A2, BIT_9);
1080 : 0 : break;
1081 : 0 : case CFG_METHOD_69:
1082 : : case CFG_METHOD_70:
1083 : : case CFG_METHOD_71:
1084 : : case CFG_METHOD_91:
1085 : 0 : rtl_clear_mac_ocp_bit(hw, 0xE040, (BIT_1 | BIT_0));
1086 : :
1087 [ # # ]: 0 : if (HW_SUPP_PHY_LINK_SPEED_10000M(hw))
1088 : : mask = MDIO_EEE_100TX | MDIO_EEE_1000T | MDIO_EEE_10GT;
1089 : : else
1090 : : mask = MDIO_EEE_100TX | MDIO_EEE_1000T;
1091 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA5D0, mask);
1092 : :
1093 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D4, MDIO_EEE_2_5GT | MDIO_EEE_5GT);
1094 : :
1095 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA6D8, BIT_4);
1096 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_7);
1097 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA4A2, BIT_9);
1098 : 0 : break;
1099 : : default:
1100 : : /* Not support EEE */
1101 : : break;
1102 : : }
1103 : :
1104 [ # # ]: 0 : switch (hw->mcfg) {
1105 : 0 : case CFG_METHOD_29:
1106 : : case CFG_METHOD_30:
1107 : : case CFG_METHOD_35:
1108 : : case CFG_METHOD_36:
1109 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A42);
1110 : 0 : rtl_clear_eth_phy_bit(hw, 0x14, BIT_7);
1111 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A4A);
1112 : 0 : rtl_clear_eth_phy_bit(hw, 0x11, BIT_9);
1113 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1114 : 0 : break;
1115 : : }
1116 : :
1117 : : /* Advanced EEE */
1118 : 0 : rtl_disable_adv_eee(hw);
1119 : 0 : }
1120 : :
1121 : : void
1122 : 0 : rtl_hw_phy_config(struct rtl_hw *hw)
1123 : : {
1124 : 0 : rtl_xmii_reset_enable(hw);
1125 : :
1126 [ # # # # ]: 0 : if (HW_DASH_SUPPORT_TYPE_3(hw) && hw->HwPkgDet == 0x06)
1127 : : return;
1128 : :
1129 : 0 : rtl8125_set_hw_phy_before_init_phy_mcu(hw);
1130 : :
1131 : 0 : rtl_init_hw_phy_mcu(hw);
1132 : :
1133 : 0 : hw->hw_ops.hw_phy_config(hw);
1134 : :
1135 : 0 : rtl_disable_aldps(hw);
1136 : :
1137 : : /* Legacy force mode (chap 22) */
1138 [ # # ]: 0 : if (rtl_is_8125(hw))
1139 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA5B4, BIT_15);
1140 : :
1141 [ # # ]: 0 : if (HW_FIBER_MODE_ENABLED(hw))
1142 : 0 : rtl8127_hw_fiber_phy_config(hw);
1143 : :
1144 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1145 : :
1146 [ # # ]: 0 : if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(hw))
1147 : 0 : rtl_disable_eee(hw);
1148 : : }
1149 : :
1150 : : static void
1151 : 0 : rtl_phy_restart_nway(struct rtl_hw *hw)
1152 : : {
1153 [ # # ]: 0 : if (rtl_is_in_phy_disable_mode(hw))
1154 : : return;
1155 : :
1156 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1157 [ # # ]: 0 : if (rtl_is_8125(hw))
1158 : 0 : rtl_mdio_write(hw, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
1159 : : else
1160 : 0 : rtl_mdio_write(hw, MII_BMCR, BMCR_RESET | BMCR_ANENABLE |
1161 : : BMCR_ANRESTART);
1162 : : }
1163 : :
1164 : : static void
1165 : 0 : rtl_phy_setup_force_mode(struct rtl_hw *hw, u32 speed, u8 duplex)
1166 : : {
1167 : : u16 bmcr_true_force = 0;
1168 : :
1169 [ # # ]: 0 : if (rtl_is_in_phy_disable_mode(hw))
1170 : : return;
1171 : :
1172 [ # # ]: 0 : if (speed == SPEED_10 && duplex == DUPLEX_HALF)
1173 : : bmcr_true_force = BMCR_SPEED10;
1174 [ # # ]: 0 : else if (speed == SPEED_10 && duplex == DUPLEX_FULL)
1175 : : bmcr_true_force = BMCR_SPEED10 | BMCR_FULLDPLX;
1176 [ # # ]: 0 : else if (speed == SPEED_100 && duplex == DUPLEX_HALF)
1177 : : bmcr_true_force = BMCR_SPEED100;
1178 [ # # ]: 0 : else if (speed == SPEED_100 && duplex == DUPLEX_FULL)
1179 : : bmcr_true_force = BMCR_SPEED100 | BMCR_FULLDPLX;
1180 : : else
1181 : : return;
1182 : :
1183 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1184 : 0 : rtl_mdio_write(hw, MII_BMCR, bmcr_true_force);
1185 : : }
1186 : :
1187 : : static int
1188 : 0 : rtl_set_speed_xmii(struct rtl_hw *hw, u8 autoneg, u32 speed, u8 duplex, u64 adv)
1189 : : {
1190 : : u16 mask = 0;
1191 : : int auto_nego = 0;
1192 : : int giga_ctrl = 0;
1193 : : int ctrl_2500 = 0;
1194 : : int rc = -EINVAL;
1195 : :
1196 : : /* Disable giga lite */
1197 [ # # # # : 0 : switch (hw->mcfg) {
# # ]
1198 : 0 : case CFG_METHOD_29:
1199 : : case CFG_METHOD_30:
1200 : : case CFG_METHOD_35:
1201 : : case CFG_METHOD_36:
1202 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A42);
1203 : 0 : rtl_clear_eth_phy_bit(hw, 0x14, BIT_9);
1204 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A40);
1205 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1206 : 0 : break;
1207 : 0 : case CFG_METHOD_31:
1208 : : case CFG_METHOD_32:
1209 : : case CFG_METHOD_33:
1210 : : case CFG_METHOD_34:
1211 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A42);
1212 : 0 : rtl_clear_eth_phy_bit(hw, 0x14, BIT_9 | BIT_7);
1213 : 0 : rtl_mdio_write(hw, 0x1F, 0x0A40);
1214 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
1215 : 0 : break;
1216 : 0 : case CFG_METHOD_91:
1217 : : mask |= BIT_2;
1218 : : /* Fall through */
1219 : 0 : case CFG_METHOD_69:
1220 : : case CFG_METHOD_70:
1221 : : case CFG_METHOD_71:
1222 : 0 : mask |= BIT_1;
1223 : : /* Fall through */
1224 : 0 : case CFG_METHOD_48:
1225 : : case CFG_METHOD_49:
1226 : : case CFG_METHOD_50:
1227 : : case CFG_METHOD_51:
1228 : : case CFG_METHOD_52:
1229 : : case CFG_METHOD_53:
1230 : : case CFG_METHOD_54:
1231 : : case CFG_METHOD_55:
1232 : : case CFG_METHOD_56:
1233 : : case CFG_METHOD_57:
1234 : : case CFG_METHOD_58:
1235 : 0 : mask |= BIT_0;
1236 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_9);
1237 : 0 : rtl_clear_eth_phy_ocp_bit(hw, 0xA5EA, mask);
1238 : 0 : break;
1239 : : }
1240 : :
1241 [ # # ]: 0 : if (!rtl_is_speed_mode_valid(hw, speed)) {
1242 : 0 : speed = hw->HwSuppMaxPhyLinkSpeed;
1243 : : duplex = DUPLEX_FULL;
1244 : 0 : adv |= hw->advertising;
1245 : : }
1246 : :
1247 [ # # ]: 0 : if (HW_FIBER_MODE_ENABLED(hw))
1248 : 0 : goto set_speed;
1249 : :
1250 : 0 : giga_ctrl = rtl_mdio_read(hw, MII_CTRL1000);
1251 : 0 : giga_ctrl &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
1252 [ # # ]: 0 : if (rtl_is_8125(hw)) {
1253 : 0 : ctrl_2500 = rtl_mdio_direct_read_phy_ocp(hw, 0xA5D4);
1254 : 0 : ctrl_2500 &= ~(RTK_ADVERTISE_2500FULL | RTK_ADVERTISE_5000FULL |
1255 : : RTK_ADVERTISE_10000FULL);
1256 : : }
1257 : :
1258 [ # # ]: 0 : if (autoneg == AUTONEG_ENABLE) {
1259 : : /* N-way force */
1260 : 0 : auto_nego = rtl_mdio_read(hw, MII_ADVERTISE);
1261 : 0 : auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
1262 : : ADVERTISE_100HALF | ADVERTISE_100FULL |
1263 : : ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
1264 : :
1265 [ # # ]: 0 : if (adv & ADVERTISE_10_HALF)
1266 : 0 : auto_nego |= ADVERTISE_10HALF;
1267 [ # # ]: 0 : if (adv & ADVERTISE_10_FULL)
1268 : 0 : auto_nego |= ADVERTISE_10FULL;
1269 [ # # ]: 0 : if (adv & ADVERTISE_100_HALF)
1270 : 0 : auto_nego |= ADVERTISE_100HALF;
1271 [ # # ]: 0 : if (adv & ADVERTISE_100_FULL)
1272 : 0 : auto_nego |= ADVERTISE_100FULL;
1273 [ # # ]: 0 : if (adv & ADVERTISE_1000_HALF)
1274 : 0 : giga_ctrl |= ADVERTISE_1000HALF;
1275 [ # # ]: 0 : if (adv & ADVERTISE_1000_FULL)
1276 : 0 : giga_ctrl |= ADVERTISE_1000FULL;
1277 [ # # ]: 0 : if (adv & ADVERTISE_2500_FULL)
1278 : 0 : ctrl_2500 |= RTK_ADVERTISE_2500FULL;
1279 [ # # ]: 0 : if (adv & ADVERTISE_5000_FULL)
1280 : 0 : ctrl_2500 |= RTK_ADVERTISE_5000FULL;
1281 [ # # ]: 0 : if (adv & ADVERTISE_10000_FULL)
1282 : 0 : ctrl_2500 |= RTK_ADVERTISE_10000FULL;
1283 : :
1284 : : /* Flow control */
1285 [ # # ]: 0 : if (hw->fcpause == rtl_fc_full)
1286 : 0 : auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
1287 : :
1288 : 0 : rtl_mdio_write(hw, 0x1f, 0x0000);
1289 : 0 : rtl_mdio_write(hw, MII_ADVERTISE, auto_nego);
1290 : 0 : rtl_mdio_write(hw, MII_CTRL1000, giga_ctrl);
1291 [ # # ]: 0 : if (rtl_is_8125(hw))
1292 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xA5D4, ctrl_2500);
1293 : 0 : rtl_phy_restart_nway(hw);
1294 : : rte_delay_ms(20);
1295 : : } else {
1296 : : /* True force */
1297 [ # # ]: 0 : if (speed == SPEED_10 || speed == SPEED_100)
1298 : 0 : rtl_phy_setup_force_mode(hw, speed, duplex);
1299 : : else
1300 : 0 : goto out;
1301 : : }
1302 : :
1303 : 0 : set_speed:
1304 : 0 : hw->autoneg = autoneg;
1305 : 0 : hw->speed = speed;
1306 : 0 : hw->duplex = duplex;
1307 : 0 : hw->advertising = adv;
1308 : :
1309 [ # # ]: 0 : if (HW_FIBER_MODE_ENABLED(hw))
1310 : 0 : rtl8127_hw_fiber_phy_config(hw);
1311 : :
1312 : : rc = 0;
1313 : 0 : out:
1314 : 0 : return rc;
1315 : : }
1316 : :
1317 : : int
1318 : 0 : rtl_set_speed(struct rtl_hw *hw)
1319 : : {
1320 : : int ret;
1321 : :
1322 : 0 : ret = rtl_set_speed_xmii(hw, hw->autoneg, hw->speed, hw->duplex,
1323 : : hw->advertising);
1324 : :
1325 : 0 : return ret;
1326 : : }
1327 : :
1328 : : void
1329 : 0 : rtl_clear_and_set_eth_phy_bit(struct rtl_hw *hw, u8 addr, u16 clearmask,
1330 : : u16 setmask)
1331 : : {
1332 : : u16 val;
1333 : :
1334 : 0 : val = rtl_mdio_read(hw, addr);
1335 : 0 : val &= ~clearmask;
1336 : 0 : val |= setmask;
1337 : 0 : rtl_mdio_write(hw, addr, val);
1338 : 0 : }
1339 : :
1340 : : void
1341 : 0 : rtl_clear_eth_phy_bit(struct rtl_hw *hw, u8 addr, u16 mask)
1342 : : {
1343 : 0 : rtl_clear_and_set_eth_phy_bit(hw, addr, mask, 0);
1344 : 0 : }
1345 : :
1346 : : void
1347 : 0 : rtl_set_eth_phy_bit(struct rtl_hw *hw, u8 addr, u16 mask)
1348 : : {
1349 : 0 : rtl_clear_and_set_eth_phy_bit(hw, addr, 0, mask);
1350 : 0 : }
1351 : :
1352 : : void
1353 : 0 : rtl8127_clear_ephy_ext_addr(struct rtl_hw *hw)
1354 : : {
1355 : : rtl8127_set_ephy_ext_addr(hw, 0x0000);
1356 : 0 : }
|