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_driver.h>
11 : :
12 : : #include "r8169_fiber.h"
13 : :
14 : : static bool
15 : : rtl8127_wait_8127_sds_cmd_done(struct rtl_hw *hw)
16 : : {
17 : : u32 timeout = 0;
18 : : u32 waitcount = 100;
19 : :
20 : : do {
21 [ # # # # ]: 0 : if (RTL_R16(hw, R8127_SDS_8127_CMD) & R8127_SDS_8127_CMD_IN)
22 : 0 : rte_delay_us(1);
23 : : else
24 : : return true;
25 [ # # # # ]: 0 : } while (++timeout < waitcount);
26 : :
27 : : return false;
28 : : }
29 : :
30 : : static u16
31 : 0 : rtl8127_sds_phy_read_8127(struct rtl_hw *hw, u16 index, u16 page, u16 reg)
32 : : {
33 : 0 : RTL_W16(hw, R8127_SDS_8127_ADDR,
34 : : R8127_MAKE_SDS_8127_ADDR(index, page, reg));
35 : 0 : RTL_W16(hw, R8127_SDS_8127_CMD, R8127_SDS_8127_CMD_IN);
36 : :
37 [ # # ]: 0 : if (rtl8127_wait_8127_sds_cmd_done(hw))
38 : 0 : return RTL_R16(hw, R8127_SDS_8127_DATA_OUT);
39 : : else
40 : : return 0xffff;
41 : : }
42 : :
43 : : static void
44 : 0 : rtl8127_sds_phy_write_8127(struct rtl_hw *hw, u16 index, u16 page, u16 reg,
45 : : u16 val)
46 : : {
47 : 0 : RTL_W16(hw, R8127_SDS_8127_DATA_IN, val);
48 : 0 : RTL_W16(hw, R8127_SDS_8127_ADDR,
49 : : R8127_MAKE_SDS_8127_ADDR(index, page, reg));
50 : 0 : RTL_W16(hw, R8127_SDS_8127_CMD,
51 : : R8127_SDS_8127_CMD_IN | R8127_SDS_8127_WE_IN);
52 : :
53 : : rtl8127_wait_8127_sds_cmd_done(hw);
54 : 0 : }
55 : :
56 : : static void
57 : 0 : rtl8127_clear_and_set_sds_phy_bit(struct rtl_hw *hw, u16 index, u16 page,
58 : : u16 addr, u16 clearmask, u16 setmask)
59 : : {
60 : : u16 val;
61 : :
62 : 0 : val = rtl8127_sds_phy_read_8127(hw, index, page, addr);
63 : 0 : val &= ~clearmask;
64 : 0 : val |= setmask;
65 : 0 : rtl8127_sds_phy_write_8127(hw, index, page, addr, val);
66 : 0 : }
67 : :
68 : : static void
69 : : rtl8127_clear_sds_phy_bit(struct rtl_hw *hw, u16 index, u16 page,
70 : : u16 addr, u16 mask)
71 : : {
72 : 0 : rtl8127_clear_and_set_sds_phy_bit(hw, index, page, addr, mask, 0);
73 : : }
74 : :
75 : : static void
76 : : rtl8127_set_sds_phy_bit(struct rtl_hw *hw, u16 index, u16 page, u16 addr,
77 : : u16 mask)
78 : : {
79 : 0 : rtl8127_clear_and_set_sds_phy_bit(hw, index, page, addr, 0, mask);
80 : : }
81 : :
82 : : static void
83 : 0 : rtl8127_sds_phy_reset_8127(struct rtl_hw *hw)
84 : : {
85 : 0 : RTL_W8(hw, 0x2350, RTL_R8(hw, 0x2350) & ~BIT_0);
86 : 0 : rte_delay_us(1);
87 : :
88 : 0 : RTL_W16(hw, 0x233A, 0x801F);
89 : 0 : RTL_W8(hw, 0x2350, RTL_R8(hw, 0x2350) | BIT_0);
90 : 0 : rte_delay_us(10);
91 : 0 : }
92 : :
93 : : static void
94 : : rtl8127_sds_phy_reset(struct rtl_hw *hw)
95 : : {
96 [ # # ]: 0 : switch (hw->HwFiberModeVer) {
97 : 0 : case FIBER_MODE_RTL8127ATF:
98 : 0 : rtl8127_sds_phy_reset_8127(hw);
99 : 0 : break;
100 : : default:
101 : : break;
102 : : }
103 : : }
104 : :
105 : : static void
106 : 0 : rtl8127_set_sds_phy_caps_1g_8127(struct rtl_hw *hw)
107 : : {
108 : : u16 val;
109 : :
110 : : rtl8127_set_sds_phy_bit(hw, 0, 1, 31, BIT_3);
111 : 0 : rtl8127_clear_and_set_sds_phy_bit(hw, 0, 2, 0, BIT_13 | BIT_12 | BIT_6,
112 : : BIT_12 | BIT_6);
113 : 0 : RTL_W16(hw, 0x233A, 0x8004);
114 : :
115 : 0 : val = RTL_R16(hw, 0x233E);
116 : 0 : val &= (BIT_13 | BIT_12 | BIT_1 | BIT_0);
117 : 0 : val |= BIT_1;
118 : 0 : RTL_W16(hw, 0x233E, val);
119 : :
120 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xC40A, 0x0);
121 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xC466, 0x0);
122 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xC808, 0x0);
123 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xC80A, 0x0);
124 : 0 : rtl_clear_and_set_eth_phy_ocp_bit(hw, 0xC804, 0x000F, 0x000C);
125 : 0 : }
126 : :
127 : : static void
128 : 0 : rtl8127_sds_phy_exit_1g_8127(struct rtl_hw *hw)
129 : : {
130 : : rtl8127_clear_sds_phy_bit(hw, 0, 1, 31, BIT_3);
131 : 0 : rtl8127_clear_and_set_sds_phy_bit(hw, 0, 2, 0, BIT_13 | BIT_12 | BIT_6,
132 : : BIT_6);
133 : :
134 : : rtl8127_sds_phy_reset(hw);
135 : 0 : }
136 : :
137 : : static void
138 : 0 : rtl8127_set_sds_phy_caps_10g_8127(struct rtl_hw *hw)
139 : : {
140 : : u16 val;
141 : :
142 : 0 : RTL_W16(hw, 0x233A, 0x801A);
143 : :
144 : 0 : val = RTL_R16(hw, 0x233E);
145 : 0 : val &= (BIT_13 | BIT_12 | BIT_1 | BIT_0);
146 : 0 : val |= BIT_12;
147 : 0 : RTL_W16(hw, 0x233E, val);
148 : :
149 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xC40A, 0x0);
150 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xC466, 0x3);
151 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xC808, 0x0);
152 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xC80A, 0x0);
153 : 0 : rtl_clear_and_set_eth_phy_ocp_bit(hw, 0xC804, 0x000F, 0x000C);
154 : 0 : }
155 : :
156 : : static void
157 : 0 : rtl8127_set_sds_phy_caps_8127(struct rtl_hw *hw)
158 : : {
159 : 0 : rtl8127_sds_phy_exit_1g_8127(hw);
160 : :
161 [ # # # ]: 0 : switch (hw->speed) {
162 : 0 : case SPEED_10000:
163 : 0 : rtl8127_set_sds_phy_caps_10g_8127(hw);
164 : 0 : break;
165 : 0 : case SPEED_1000:
166 : 0 : rtl8127_set_sds_phy_caps_1g_8127(hw);
167 : 0 : break;
168 : : default:
169 : : break;
170 : : }
171 : 0 : }
172 : :
173 : : static void
174 : : rtl8127_set_sds_phy_caps(struct rtl_hw *hw)
175 : : {
176 : : switch (hw->HwFiberModeVer) {
177 : 0 : case FIBER_MODE_RTL8127ATF:
178 : 0 : rtl8127_set_sds_phy_caps_8127(hw);
179 : : break;
180 : : default:
181 : : break;
182 : : }
183 : : }
184 : :
185 : : static void
186 : : rtl8127_hw_sds_phy_config(struct rtl_hw *hw)
187 : : {
188 : : rtl8127_set_sds_phy_caps(hw);
189 : 0 : }
190 : :
191 : : void
192 : 0 : rtl8127_hw_fiber_phy_config(struct rtl_hw *hw)
193 : : {
194 [ # # ]: 0 : switch (hw->HwFiberModeVer) {
195 : : case FIBER_MODE_RTL8127ATF:
196 : : rtl8127_hw_sds_phy_config(hw);
197 : : break;
198 : : default:
199 : : break;
200 : : }
201 : 0 : }
|