Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * r8169_phy_config.c: RealTek 8169/8168/8101 ethernet driver.
4 : : *
5 : : * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
6 : : * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
7 : : * Copyright (c) a lot of people too. Please respect their work.
8 : : *
9 : : * See MAINTAINERS file for support contact information.
10 : : */
11 : :
12 : : #include <linux/delay.h>
13 : : #include <linux/phy.h>
14 : :
15 : : #include "r8169.h"
16 : :
17 : : typedef void (*rtl_phy_cfg_fct)(struct rtl8169_private *tp,
18 : : struct phy_device *phydev);
19 : :
20 : 0 : static void r8168d_modify_extpage(struct phy_device *phydev, int extpage,
21 : : int reg, u16 mask, u16 val)
22 : : {
23 : 0 : int oldpage = phy_select_page(phydev, 0x0007);
24 : :
25 : 0 : __phy_write(phydev, 0x1e, extpage);
26 : 0 : __phy_modify(phydev, reg, mask, val);
27 : :
28 : 0 : phy_restore_page(phydev, oldpage, 0);
29 : 0 : }
30 : :
31 : 0 : static void r8168d_phy_param(struct phy_device *phydev, u16 parm,
32 : : u16 mask, u16 val)
33 : : {
34 : 0 : int oldpage = phy_select_page(phydev, 0x0005);
35 : :
36 : 0 : __phy_write(phydev, 0x05, parm);
37 : 0 : __phy_modify(phydev, 0x06, mask, val);
38 : :
39 : 0 : phy_restore_page(phydev, oldpage, 0);
40 : 0 : }
41 : :
42 : 0 : static void r8168g_phy_param(struct phy_device *phydev, u16 parm,
43 : : u16 mask, u16 val)
44 : : {
45 : 0 : int oldpage = phy_select_page(phydev, 0x0a43);
46 : :
47 : 0 : __phy_write(phydev, 0x13, parm);
48 : 0 : __phy_modify(phydev, 0x14, mask, val);
49 : :
50 : 0 : phy_restore_page(phydev, oldpage, 0);
51 : 0 : }
52 : :
53 : : struct phy_reg {
54 : : u16 reg;
55 : : u16 val;
56 : : };
57 : :
58 : 0 : static void __rtl_writephy_batch(struct phy_device *phydev,
59 : : const struct phy_reg *regs, int len)
60 : : {
61 : 0 : phy_lock_mdio_bus(phydev);
62 : :
63 [ # # ]: 0 : while (len-- > 0) {
64 : 0 : __phy_write(phydev, regs->reg, regs->val);
65 : 0 : regs++;
66 : : }
67 : :
68 : 0 : phy_unlock_mdio_bus(phydev);
69 : 0 : }
70 : :
71 : : #define rtl_writephy_batch(p, a) __rtl_writephy_batch(p, a, ARRAY_SIZE(a))
72 : :
73 : 0 : static void rtl8168f_config_eee_phy(struct phy_device *phydev)
74 : : {
75 : 0 : r8168d_modify_extpage(phydev, 0x0020, 0x15, 0, BIT(8));
76 : 0 : r8168d_phy_param(phydev, 0x8b85, 0, BIT(13));
77 : 0 : }
78 : :
79 : 0 : static void rtl8168g_config_eee_phy(struct phy_device *phydev)
80 : : {
81 : 0 : phy_modify_paged(phydev, 0x0a43, 0x11, 0, BIT(4));
82 : : }
83 : :
84 : 0 : static void rtl8168h_config_eee_phy(struct phy_device *phydev)
85 : : {
86 : 0 : rtl8168g_config_eee_phy(phydev);
87 : :
88 : 0 : phy_modify_paged(phydev, 0xa4a, 0x11, 0x0000, 0x0200);
89 : 0 : phy_modify_paged(phydev, 0xa42, 0x14, 0x0000, 0x0080);
90 : 0 : }
91 : :
92 : 0 : static void rtl8125_config_eee_phy(struct phy_device *phydev)
93 : : {
94 : 0 : rtl8168h_config_eee_phy(phydev);
95 : :
96 : 0 : phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000);
97 : 0 : phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
98 : 0 : }
99 : :
100 : 0 : static void rtl8169s_hw_phy_config(struct rtl8169_private *tp,
101 : : struct phy_device *phydev)
102 : : {
103 : 0 : static const struct phy_reg phy_reg_init[] = {
104 : : { 0x1f, 0x0001 },
105 : : { 0x06, 0x006e },
106 : : { 0x08, 0x0708 },
107 : : { 0x15, 0x4000 },
108 : : { 0x18, 0x65c7 },
109 : :
110 : : { 0x1f, 0x0001 },
111 : : { 0x03, 0x00a1 },
112 : : { 0x02, 0x0008 },
113 : : { 0x01, 0x0120 },
114 : : { 0x00, 0x1000 },
115 : : { 0x04, 0x0800 },
116 : : { 0x04, 0x0000 },
117 : :
118 : : { 0x03, 0xff41 },
119 : : { 0x02, 0xdf60 },
120 : : { 0x01, 0x0140 },
121 : : { 0x00, 0x0077 },
122 : : { 0x04, 0x7800 },
123 : : { 0x04, 0x7000 },
124 : :
125 : : { 0x03, 0x802f },
126 : : { 0x02, 0x4f02 },
127 : : { 0x01, 0x0409 },
128 : : { 0x00, 0xf0f9 },
129 : : { 0x04, 0x9800 },
130 : : { 0x04, 0x9000 },
131 : :
132 : : { 0x03, 0xdf01 },
133 : : { 0x02, 0xdf20 },
134 : : { 0x01, 0xff95 },
135 : : { 0x00, 0xba00 },
136 : : { 0x04, 0xa800 },
137 : : { 0x04, 0xa000 },
138 : :
139 : : { 0x03, 0xff41 },
140 : : { 0x02, 0xdf20 },
141 : : { 0x01, 0x0140 },
142 : : { 0x00, 0x00bb },
143 : : { 0x04, 0xb800 },
144 : : { 0x04, 0xb000 },
145 : :
146 : : { 0x03, 0xdf41 },
147 : : { 0x02, 0xdc60 },
148 : : { 0x01, 0x6340 },
149 : : { 0x00, 0x007d },
150 : : { 0x04, 0xd800 },
151 : : { 0x04, 0xd000 },
152 : :
153 : : { 0x03, 0xdf01 },
154 : : { 0x02, 0xdf20 },
155 : : { 0x01, 0x100a },
156 : : { 0x00, 0xa0ff },
157 : : { 0x04, 0xf800 },
158 : : { 0x04, 0xf000 },
159 : :
160 : : { 0x1f, 0x0000 },
161 : : { 0x0b, 0x0000 },
162 : : { 0x00, 0x9200 }
163 : : };
164 : :
165 : 0 : rtl_writephy_batch(phydev, phy_reg_init);
166 : 0 : }
167 : :
168 : 0 : static void rtl8169sb_hw_phy_config(struct rtl8169_private *tp,
169 : : struct phy_device *phydev)
170 : : {
171 : 0 : phy_write_paged(phydev, 0x0002, 0x01, 0x90d0);
172 : 0 : }
173 : :
174 : 0 : static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp,
175 : : struct phy_device *phydev)
176 : : {
177 : 0 : static const struct phy_reg phy_reg_init[] = {
178 : : { 0x1f, 0x0001 },
179 : : { 0x04, 0x0000 },
180 : : { 0x03, 0x00a1 },
181 : : { 0x02, 0x0008 },
182 : : { 0x01, 0x0120 },
183 : : { 0x00, 0x1000 },
184 : : { 0x04, 0x0800 },
185 : : { 0x04, 0x9000 },
186 : : { 0x03, 0x802f },
187 : : { 0x02, 0x4f02 },
188 : : { 0x01, 0x0409 },
189 : : { 0x00, 0xf099 },
190 : : { 0x04, 0x9800 },
191 : : { 0x04, 0xa000 },
192 : : { 0x03, 0xdf01 },
193 : : { 0x02, 0xdf20 },
194 : : { 0x01, 0xff95 },
195 : : { 0x00, 0xba00 },
196 : : { 0x04, 0xa800 },
197 : : { 0x04, 0xf000 },
198 : : { 0x03, 0xdf01 },
199 : : { 0x02, 0xdf20 },
200 : : { 0x01, 0x101a },
201 : : { 0x00, 0xa0ff },
202 : : { 0x04, 0xf800 },
203 : : { 0x04, 0x0000 },
204 : : { 0x1f, 0x0000 },
205 : :
206 : : { 0x1f, 0x0001 },
207 : : { 0x10, 0xf41b },
208 : : { 0x14, 0xfb54 },
209 : : { 0x18, 0xf5c7 },
210 : : { 0x1f, 0x0000 },
211 : :
212 : : { 0x1f, 0x0001 },
213 : : { 0x17, 0x0cc0 },
214 : : { 0x1f, 0x0000 }
215 : : };
216 : :
217 : 0 : rtl_writephy_batch(phydev, phy_reg_init);
218 : 0 : }
219 : :
220 : 0 : static void rtl8169sce_hw_phy_config(struct rtl8169_private *tp,
221 : : struct phy_device *phydev)
222 : : {
223 : 0 : static const struct phy_reg phy_reg_init[] = {
224 : : { 0x1f, 0x0001 },
225 : : { 0x04, 0x0000 },
226 : : { 0x03, 0x00a1 },
227 : : { 0x02, 0x0008 },
228 : : { 0x01, 0x0120 },
229 : : { 0x00, 0x1000 },
230 : : { 0x04, 0x0800 },
231 : : { 0x04, 0x9000 },
232 : : { 0x03, 0x802f },
233 : : { 0x02, 0x4f02 },
234 : : { 0x01, 0x0409 },
235 : : { 0x00, 0xf099 },
236 : : { 0x04, 0x9800 },
237 : : { 0x04, 0xa000 },
238 : : { 0x03, 0xdf01 },
239 : : { 0x02, 0xdf20 },
240 : : { 0x01, 0xff95 },
241 : : { 0x00, 0xba00 },
242 : : { 0x04, 0xa800 },
243 : : { 0x04, 0xf000 },
244 : : { 0x03, 0xdf01 },
245 : : { 0x02, 0xdf20 },
246 : : { 0x01, 0x101a },
247 : : { 0x00, 0xa0ff },
248 : : { 0x04, 0xf800 },
249 : : { 0x04, 0x0000 },
250 : : { 0x1f, 0x0000 },
251 : :
252 : : { 0x1f, 0x0001 },
253 : : { 0x0b, 0x8480 },
254 : : { 0x1f, 0x0000 },
255 : :
256 : : { 0x1f, 0x0001 },
257 : : { 0x18, 0x67c7 },
258 : : { 0x04, 0x2000 },
259 : : { 0x03, 0x002f },
260 : : { 0x02, 0x4360 },
261 : : { 0x01, 0x0109 },
262 : : { 0x00, 0x3022 },
263 : : { 0x04, 0x2800 },
264 : : { 0x1f, 0x0000 },
265 : :
266 : : { 0x1f, 0x0001 },
267 : : { 0x17, 0x0cc0 },
268 : : { 0x1f, 0x0000 }
269 : : };
270 : :
271 : 0 : rtl_writephy_batch(phydev, phy_reg_init);
272 : 0 : }
273 : :
274 : 0 : static void rtl8168bb_hw_phy_config(struct rtl8169_private *tp,
275 : : struct phy_device *phydev)
276 : : {
277 : 0 : phy_write(phydev, 0x1f, 0x0001);
278 : 0 : phy_set_bits(phydev, 0x16, BIT(0));
279 : 0 : phy_write(phydev, 0x10, 0xf41b);
280 : 0 : phy_write(phydev, 0x1f, 0x0000);
281 : 0 : }
282 : :
283 : 0 : static void rtl8168bef_hw_phy_config(struct rtl8169_private *tp,
284 : : struct phy_device *phydev)
285 : : {
286 : 0 : phy_write_paged(phydev, 0x0001, 0x10, 0xf41b);
287 : 0 : }
288 : :
289 : 0 : static void rtl8168cp_1_hw_phy_config(struct rtl8169_private *tp,
290 : : struct phy_device *phydev)
291 : : {
292 : 0 : phy_write(phydev, 0x1d, 0x0f00);
293 : 0 : phy_write_paged(phydev, 0x0002, 0x0c, 0x1ec8);
294 : 0 : }
295 : :
296 : 0 : static void rtl8168cp_2_hw_phy_config(struct rtl8169_private *tp,
297 : : struct phy_device *phydev)
298 : : {
299 : 0 : phy_set_bits(phydev, 0x14, BIT(5));
300 : 0 : phy_set_bits(phydev, 0x0d, BIT(5));
301 : 0 : phy_write_paged(phydev, 0x0001, 0x1d, 0x3d98);
302 : 0 : }
303 : :
304 : 0 : static void rtl8168c_1_hw_phy_config(struct rtl8169_private *tp,
305 : : struct phy_device *phydev)
306 : : {
307 : 0 : static const struct phy_reg phy_reg_init[] = {
308 : : { 0x1f, 0x0001 },
309 : : { 0x12, 0x2300 },
310 : : { 0x1f, 0x0002 },
311 : : { 0x00, 0x88d4 },
312 : : { 0x01, 0x82b1 },
313 : : { 0x03, 0x7002 },
314 : : { 0x08, 0x9e30 },
315 : : { 0x09, 0x01f0 },
316 : : { 0x0a, 0x5500 },
317 : : { 0x0c, 0x00c8 },
318 : : { 0x1f, 0x0003 },
319 : : { 0x12, 0xc096 },
320 : : { 0x16, 0x000a },
321 : : { 0x1f, 0x0000 },
322 : : { 0x1f, 0x0000 },
323 : : { 0x09, 0x2000 },
324 : : { 0x09, 0x0000 }
325 : : };
326 : :
327 : 0 : rtl_writephy_batch(phydev, phy_reg_init);
328 : :
329 : 0 : phy_set_bits(phydev, 0x14, BIT(5));
330 : 0 : phy_set_bits(phydev, 0x0d, BIT(5));
331 : 0 : }
332 : :
333 : 0 : static void rtl8168c_2_hw_phy_config(struct rtl8169_private *tp,
334 : : struct phy_device *phydev)
335 : : {
336 : 0 : static const struct phy_reg phy_reg_init[] = {
337 : : { 0x1f, 0x0001 },
338 : : { 0x12, 0x2300 },
339 : : { 0x03, 0x802f },
340 : : { 0x02, 0x4f02 },
341 : : { 0x01, 0x0409 },
342 : : { 0x00, 0xf099 },
343 : : { 0x04, 0x9800 },
344 : : { 0x04, 0x9000 },
345 : : { 0x1d, 0x3d98 },
346 : : { 0x1f, 0x0002 },
347 : : { 0x0c, 0x7eb8 },
348 : : { 0x06, 0x0761 },
349 : : { 0x1f, 0x0003 },
350 : : { 0x16, 0x0f0a },
351 : : { 0x1f, 0x0000 }
352 : : };
353 : :
354 : 0 : rtl_writephy_batch(phydev, phy_reg_init);
355 : :
356 : 0 : phy_set_bits(phydev, 0x16, BIT(0));
357 : 0 : phy_set_bits(phydev, 0x14, BIT(5));
358 : 0 : phy_set_bits(phydev, 0x0d, BIT(5));
359 : 0 : }
360 : :
361 : 0 : static void rtl8168c_3_hw_phy_config(struct rtl8169_private *tp,
362 : : struct phy_device *phydev)
363 : : {
364 : 0 : static const struct phy_reg phy_reg_init[] = {
365 : : { 0x1f, 0x0001 },
366 : : { 0x12, 0x2300 },
367 : : { 0x1d, 0x3d98 },
368 : : { 0x1f, 0x0002 },
369 : : { 0x0c, 0x7eb8 },
370 : : { 0x06, 0x5461 },
371 : : { 0x1f, 0x0003 },
372 : : { 0x16, 0x0f0a },
373 : : { 0x1f, 0x0000 }
374 : : };
375 : :
376 : 0 : rtl_writephy_batch(phydev, phy_reg_init);
377 : :
378 : 0 : phy_set_bits(phydev, 0x16, BIT(0));
379 : 0 : phy_set_bits(phydev, 0x14, BIT(5));
380 : 0 : phy_set_bits(phydev, 0x0d, BIT(5));
381 : 0 : }
382 : :
383 : : static const struct phy_reg rtl8168d_1_phy_reg_init_0[] = {
384 : : /* Channel Estimation */
385 : : { 0x1f, 0x0001 },
386 : : { 0x06, 0x4064 },
387 : : { 0x07, 0x2863 },
388 : : { 0x08, 0x059c },
389 : : { 0x09, 0x26b4 },
390 : : { 0x0a, 0x6a19 },
391 : : { 0x0b, 0xdcc8 },
392 : : { 0x10, 0xf06d },
393 : : { 0x14, 0x7f68 },
394 : : { 0x18, 0x7fd9 },
395 : : { 0x1c, 0xf0ff },
396 : : { 0x1d, 0x3d9c },
397 : : { 0x1f, 0x0003 },
398 : : { 0x12, 0xf49f },
399 : : { 0x13, 0x070b },
400 : : { 0x1a, 0x05ad },
401 : : { 0x14, 0x94c0 },
402 : :
403 : : /*
404 : : * Tx Error Issue
405 : : * Enhance line driver power
406 : : */
407 : : { 0x1f, 0x0002 },
408 : : { 0x06, 0x5561 },
409 : : { 0x1f, 0x0005 },
410 : : { 0x05, 0x8332 },
411 : : { 0x06, 0x5561 },
412 : :
413 : : /*
414 : : * Can not link to 1Gbps with bad cable
415 : : * Decrease SNR threshold form 21.07dB to 19.04dB
416 : : */
417 : : { 0x1f, 0x0001 },
418 : : { 0x17, 0x0cc0 },
419 : :
420 : : { 0x1f, 0x0000 },
421 : : { 0x0d, 0xf880 }
422 : : };
423 : :
424 : : static const struct phy_reg rtl8168d_1_phy_reg_init_1[] = {
425 : : { 0x1f, 0x0002 },
426 : : { 0x05, 0x669a },
427 : : { 0x1f, 0x0005 },
428 : : { 0x05, 0x8330 },
429 : : { 0x06, 0x669a },
430 : : { 0x1f, 0x0002 }
431 : : };
432 : :
433 : 0 : static void rtl8168d_apply_firmware_cond(struct rtl8169_private *tp,
434 : : struct phy_device *phydev,
435 : : u16 val)
436 : : {
437 : 0 : u16 reg_val;
438 : :
439 : 0 : phy_write(phydev, 0x1f, 0x0005);
440 : 0 : phy_write(phydev, 0x05, 0x001b);
441 : 0 : reg_val = phy_read(phydev, 0x06);
442 : 0 : phy_write(phydev, 0x1f, 0x0000);
443 : :
444 [ # # ]: 0 : if (reg_val != val)
445 : 0 : phydev_warn(phydev, "chipset not ready for firmware\n");
446 : : else
447 : 0 : r8169_apply_firmware(tp);
448 : 0 : }
449 : :
450 : 0 : static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp,
451 : : struct phy_device *phydev)
452 : : {
453 : 0 : rtl_writephy_batch(phydev, rtl8168d_1_phy_reg_init_0);
454 : :
455 : : /*
456 : : * Rx Error Issue
457 : : * Fine Tune Switching regulator parameter
458 : : */
459 : 0 : phy_write(phydev, 0x1f, 0x0002);
460 : 0 : phy_modify(phydev, 0x0b, 0x00ef, 0x0010);
461 : 0 : phy_modify(phydev, 0x0c, 0x5d00, 0xa200);
462 : :
463 [ # # ]: 0 : if (rtl8168d_efuse_read(tp, 0x01) == 0xb1) {
464 : 0 : int val;
465 : :
466 : 0 : rtl_writephy_batch(phydev, rtl8168d_1_phy_reg_init_1);
467 : :
468 : 0 : val = phy_read(phydev, 0x0d);
469 : :
470 [ # # ]: 0 : if ((val & 0x00ff) != 0x006c) {
471 : 0 : static const u32 set[] = {
472 : : 0x0065, 0x0066, 0x0067, 0x0068,
473 : : 0x0069, 0x006a, 0x006b, 0x006c
474 : : };
475 : 0 : int i;
476 : :
477 : 0 : phy_write(phydev, 0x1f, 0x0002);
478 : :
479 : 0 : val &= 0xff00;
480 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(set); i++)
481 : 0 : phy_write(phydev, 0x0d, val | set[i]);
482 : : }
483 : : } else {
484 : 0 : phy_write_paged(phydev, 0x0002, 0x05, 0x6662);
485 : 0 : r8168d_phy_param(phydev, 0x8330, 0xffff, 0x6662);
486 : : }
487 : :
488 : : /* RSET couple improve */
489 : 0 : phy_write(phydev, 0x1f, 0x0002);
490 : 0 : phy_set_bits(phydev, 0x0d, 0x0300);
491 : 0 : phy_set_bits(phydev, 0x0f, 0x0010);
492 : :
493 : : /* Fine tune PLL performance */
494 : 0 : phy_write(phydev, 0x1f, 0x0002);
495 : 0 : phy_modify(phydev, 0x02, 0x0600, 0x0100);
496 : 0 : phy_clear_bits(phydev, 0x03, 0xe000);
497 : 0 : phy_write(phydev, 0x1f, 0x0000);
498 : :
499 : 0 : rtl8168d_apply_firmware_cond(tp, phydev, 0xbf00);
500 : 0 : }
501 : :
502 : 0 : static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp,
503 : : struct phy_device *phydev)
504 : : {
505 : 0 : rtl_writephy_batch(phydev, rtl8168d_1_phy_reg_init_0);
506 : :
507 [ # # ]: 0 : if (rtl8168d_efuse_read(tp, 0x01) == 0xb1) {
508 : 0 : int val;
509 : :
510 : 0 : rtl_writephy_batch(phydev, rtl8168d_1_phy_reg_init_1);
511 : :
512 : 0 : val = phy_read(phydev, 0x0d);
513 [ # # ]: 0 : if ((val & 0x00ff) != 0x006c) {
514 : 0 : static const u32 set[] = {
515 : : 0x0065, 0x0066, 0x0067, 0x0068,
516 : : 0x0069, 0x006a, 0x006b, 0x006c
517 : : };
518 : 0 : int i;
519 : :
520 : 0 : phy_write(phydev, 0x1f, 0x0002);
521 : :
522 : 0 : val &= 0xff00;
523 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(set); i++)
524 : 0 : phy_write(phydev, 0x0d, val | set[i]);
525 : : }
526 : : } else {
527 : 0 : phy_write_paged(phydev, 0x0002, 0x05, 0x2642);
528 : 0 : r8168d_phy_param(phydev, 0x8330, 0xffff, 0x2642);
529 : : }
530 : :
531 : : /* Fine tune PLL performance */
532 : 0 : phy_write(phydev, 0x1f, 0x0002);
533 : 0 : phy_modify(phydev, 0x02, 0x0600, 0x0100);
534 : 0 : phy_clear_bits(phydev, 0x03, 0xe000);
535 : 0 : phy_write(phydev, 0x1f, 0x0000);
536 : :
537 : : /* Switching regulator Slew rate */
538 : 0 : phy_modify_paged(phydev, 0x0002, 0x0f, 0x0000, 0x0017);
539 : :
540 : 0 : rtl8168d_apply_firmware_cond(tp, phydev, 0xb300);
541 : 0 : }
542 : :
543 : 0 : static void rtl8168d_3_hw_phy_config(struct rtl8169_private *tp,
544 : : struct phy_device *phydev)
545 : : {
546 : 0 : static const struct phy_reg phy_reg_init[] = {
547 : : { 0x1f, 0x0002 },
548 : : { 0x10, 0x0008 },
549 : : { 0x0d, 0x006c },
550 : :
551 : : { 0x1f, 0x0000 },
552 : : { 0x0d, 0xf880 },
553 : :
554 : : { 0x1f, 0x0001 },
555 : : { 0x17, 0x0cc0 },
556 : :
557 : : { 0x1f, 0x0001 },
558 : : { 0x0b, 0xa4d8 },
559 : : { 0x09, 0x281c },
560 : : { 0x07, 0x2883 },
561 : : { 0x0a, 0x6b35 },
562 : : { 0x1d, 0x3da4 },
563 : : { 0x1c, 0xeffd },
564 : : { 0x14, 0x7f52 },
565 : : { 0x18, 0x7fc6 },
566 : : { 0x08, 0x0601 },
567 : : { 0x06, 0x4063 },
568 : : { 0x10, 0xf074 },
569 : : { 0x1f, 0x0003 },
570 : : { 0x13, 0x0789 },
571 : : { 0x12, 0xf4bd },
572 : : { 0x1a, 0x04fd },
573 : : { 0x14, 0x84b0 },
574 : : { 0x1f, 0x0000 },
575 : : { 0x00, 0x9200 },
576 : :
577 : : { 0x1f, 0x0005 },
578 : : { 0x01, 0x0340 },
579 : : { 0x1f, 0x0001 },
580 : : { 0x04, 0x4000 },
581 : : { 0x03, 0x1d21 },
582 : : { 0x02, 0x0c32 },
583 : : { 0x01, 0x0200 },
584 : : { 0x00, 0x5554 },
585 : : { 0x04, 0x4800 },
586 : : { 0x04, 0x4000 },
587 : : { 0x04, 0xf000 },
588 : : { 0x03, 0xdf01 },
589 : : { 0x02, 0xdf20 },
590 : : { 0x01, 0x101a },
591 : : { 0x00, 0xa0ff },
592 : : { 0x04, 0xf800 },
593 : : { 0x04, 0xf000 },
594 : : { 0x1f, 0x0000 },
595 : : };
596 : :
597 : 0 : rtl_writephy_batch(phydev, phy_reg_init);
598 : 0 : r8168d_modify_extpage(phydev, 0x0023, 0x16, 0xffff, 0x0000);
599 : 0 : }
600 : :
601 : 0 : static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp,
602 : : struct phy_device *phydev)
603 : : {
604 : 0 : phy_write_paged(phydev, 0x0001, 0x17, 0x0cc0);
605 : 0 : r8168d_modify_extpage(phydev, 0x002d, 0x18, 0xffff, 0x0040);
606 : 0 : phy_set_bits(phydev, 0x0d, BIT(5));
607 : 0 : }
608 : :
609 : 0 : static void rtl8168e_1_hw_phy_config(struct rtl8169_private *tp,
610 : : struct phy_device *phydev)
611 : : {
612 : 0 : static const struct phy_reg phy_reg_init[] = {
613 : : /* Channel estimation fine tune */
614 : : { 0x1f, 0x0001 },
615 : : { 0x0b, 0x6c20 },
616 : : { 0x07, 0x2872 },
617 : : { 0x1c, 0xefff },
618 : : { 0x1f, 0x0003 },
619 : : { 0x14, 0x6420 },
620 : : { 0x1f, 0x0000 },
621 : : };
622 : :
623 : 0 : r8169_apply_firmware(tp);
624 : :
625 : : /* Enable Delay cap */
626 : 0 : r8168d_phy_param(phydev, 0x8b80, 0xffff, 0xc896);
627 : :
628 : 0 : rtl_writephy_batch(phydev, phy_reg_init);
629 : :
630 : : /* Update PFM & 10M TX idle timer */
631 : 0 : r8168d_modify_extpage(phydev, 0x002f, 0x15, 0xffff, 0x1919);
632 : :
633 : 0 : r8168d_modify_extpage(phydev, 0x00ac, 0x18, 0xffff, 0x0006);
634 : :
635 : : /* DCO enable for 10M IDLE Power */
636 : 0 : r8168d_modify_extpage(phydev, 0x0023, 0x17, 0x0000, 0x0006);
637 : :
638 : : /* For impedance matching */
639 : 0 : phy_modify_paged(phydev, 0x0002, 0x08, 0x7f00, 0x8000);
640 : :
641 : : /* PHY auto speed down */
642 : 0 : r8168d_modify_extpage(phydev, 0x002d, 0x18, 0x0000, 0x0050);
643 : 0 : phy_set_bits(phydev, 0x14, BIT(15));
644 : :
645 : 0 : r8168d_phy_param(phydev, 0x8b86, 0x0000, 0x0001);
646 : 0 : r8168d_phy_param(phydev, 0x8b85, 0x2000, 0x0000);
647 : :
648 : 0 : r8168d_modify_extpage(phydev, 0x0020, 0x15, 0x1100, 0x0000);
649 : 0 : phy_write_paged(phydev, 0x0006, 0x00, 0x5a00);
650 : :
651 : 0 : phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0000);
652 : 0 : }
653 : :
654 : 0 : static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp,
655 : : struct phy_device *phydev)
656 : : {
657 : 0 : r8169_apply_firmware(tp);
658 : :
659 : : /* Enable Delay cap */
660 : 0 : r8168d_modify_extpage(phydev, 0x00ac, 0x18, 0xffff, 0x0006);
661 : :
662 : : /* Channel estimation fine tune */
663 : 0 : phy_write_paged(phydev, 0x0003, 0x09, 0xa20f);
664 : :
665 : : /* Green Setting */
666 : 0 : r8168d_phy_param(phydev, 0x8b5b, 0xffff, 0x9222);
667 : 0 : r8168d_phy_param(phydev, 0x8b6d, 0xffff, 0x8000);
668 : 0 : r8168d_phy_param(phydev, 0x8b76, 0xffff, 0x8000);
669 : :
670 : : /* For 4-corner performance improve */
671 : 0 : phy_write(phydev, 0x1f, 0x0005);
672 : 0 : phy_write(phydev, 0x05, 0x8b80);
673 : 0 : phy_set_bits(phydev, 0x17, 0x0006);
674 : 0 : phy_write(phydev, 0x1f, 0x0000);
675 : :
676 : : /* PHY auto speed down */
677 : 0 : r8168d_modify_extpage(phydev, 0x002d, 0x18, 0x0000, 0x0010);
678 : 0 : phy_set_bits(phydev, 0x14, BIT(15));
679 : :
680 : : /* improve 10M EEE waveform */
681 : 0 : r8168d_phy_param(phydev, 0x8b86, 0x0000, 0x0001);
682 : :
683 : : /* Improve 2-pair detection performance */
684 : 0 : r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x4000);
685 : :
686 : 0 : rtl8168f_config_eee_phy(phydev);
687 : :
688 : : /* Green feature */
689 : 0 : phy_write(phydev, 0x1f, 0x0003);
690 : 0 : phy_set_bits(phydev, 0x19, BIT(0));
691 : 0 : phy_set_bits(phydev, 0x10, BIT(10));
692 : 0 : phy_write(phydev, 0x1f, 0x0000);
693 : 0 : phy_modify_paged(phydev, 0x0005, 0x01, 0, BIT(8));
694 : 0 : }
695 : :
696 : : static void rtl8168f_hw_phy_config(struct rtl8169_private *tp,
697 : : struct phy_device *phydev)
698 : : {
699 : : /* For 4-corner performance improve */
700 : : r8168d_phy_param(phydev, 0x8b80, 0x0000, 0x0006);
701 : :
702 : : /* PHY auto speed down */
703 : : r8168d_modify_extpage(phydev, 0x002d, 0x18, 0x0000, 0x0010);
704 : : phy_set_bits(phydev, 0x14, BIT(15));
705 : :
706 : : /* Improve 10M EEE waveform */
707 : : r8168d_phy_param(phydev, 0x8b86, 0x0000, 0x0001);
708 : :
709 : : rtl8168f_config_eee_phy(phydev);
710 : : }
711 : :
712 : 0 : static void rtl8168f_1_hw_phy_config(struct rtl8169_private *tp,
713 : : struct phy_device *phydev)
714 : : {
715 : 0 : r8169_apply_firmware(tp);
716 : :
717 : : /* Channel estimation fine tune */
718 : 0 : phy_write_paged(phydev, 0x0003, 0x09, 0xa20f);
719 : :
720 : : /* Modify green table for giga & fnet */
721 : 0 : r8168d_phy_param(phydev, 0x8b55, 0xffff, 0x0000);
722 : 0 : r8168d_phy_param(phydev, 0x8b5e, 0xffff, 0x0000);
723 : 0 : r8168d_phy_param(phydev, 0x8b67, 0xffff, 0x0000);
724 : 0 : r8168d_phy_param(phydev, 0x8b70, 0xffff, 0x0000);
725 : 0 : r8168d_modify_extpage(phydev, 0x0078, 0x17, 0xffff, 0x0000);
726 : 0 : r8168d_modify_extpage(phydev, 0x0078, 0x19, 0xffff, 0x00fb);
727 : :
728 : : /* Modify green table for 10M */
729 : 0 : r8168d_phy_param(phydev, 0x8b79, 0xffff, 0xaa00);
730 : :
731 : : /* Disable hiimpedance detection (RTCT) */
732 : 0 : phy_write_paged(phydev, 0x0003, 0x01, 0x328a);
733 : :
734 : 0 : rtl8168f_hw_phy_config(tp, phydev);
735 : :
736 : : /* Improve 2-pair detection performance */
737 : 0 : r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x4000);
738 : 0 : }
739 : :
740 : 0 : static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp,
741 : : struct phy_device *phydev)
742 : : {
743 : 0 : r8169_apply_firmware(tp);
744 : :
745 : 0 : rtl8168f_hw_phy_config(tp, phydev);
746 : 0 : }
747 : :
748 : 0 : static void rtl8411_hw_phy_config(struct rtl8169_private *tp,
749 : : struct phy_device *phydev)
750 : : {
751 : 0 : r8169_apply_firmware(tp);
752 : :
753 : 0 : rtl8168f_hw_phy_config(tp, phydev);
754 : :
755 : : /* Improve 2-pair detection performance */
756 : 0 : r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x4000);
757 : :
758 : : /* Channel estimation fine tune */
759 : 0 : phy_write_paged(phydev, 0x0003, 0x09, 0xa20f);
760 : :
761 : : /* Modify green table for giga & fnet */
762 : 0 : r8168d_phy_param(phydev, 0x8b55, 0xffff, 0x0000);
763 : 0 : r8168d_phy_param(phydev, 0x8b5e, 0xffff, 0x0000);
764 : 0 : r8168d_phy_param(phydev, 0x8b67, 0xffff, 0x0000);
765 : 0 : r8168d_phy_param(phydev, 0x8b70, 0xffff, 0x0000);
766 : 0 : r8168d_modify_extpage(phydev, 0x0078, 0x17, 0xffff, 0x0000);
767 : 0 : r8168d_modify_extpage(phydev, 0x0078, 0x19, 0xffff, 0x00aa);
768 : :
769 : : /* Modify green table for 10M */
770 : 0 : r8168d_phy_param(phydev, 0x8b79, 0xffff, 0xaa00);
771 : :
772 : : /* Disable hiimpedance detection (RTCT) */
773 : 0 : phy_write_paged(phydev, 0x0003, 0x01, 0x328a);
774 : :
775 : : /* Modify green table for giga */
776 : 0 : r8168d_phy_param(phydev, 0x8b54, 0x0800, 0x0000);
777 : 0 : r8168d_phy_param(phydev, 0x8b5d, 0x0800, 0x0000);
778 : 0 : r8168d_phy_param(phydev, 0x8a7c, 0x0100, 0x0000);
779 : 0 : r8168d_phy_param(phydev, 0x8a7f, 0x0000, 0x0100);
780 : 0 : r8168d_phy_param(phydev, 0x8a82, 0x0100, 0x0000);
781 : 0 : r8168d_phy_param(phydev, 0x8a85, 0x0100, 0x0000);
782 : 0 : r8168d_phy_param(phydev, 0x8a88, 0x0100, 0x0000);
783 : :
784 : : /* uc same-seed solution */
785 : 0 : r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x8000);
786 : :
787 : : /* Green feature */
788 : 0 : phy_write(phydev, 0x1f, 0x0003);
789 : 0 : phy_clear_bits(phydev, 0x19, BIT(0));
790 : 0 : phy_clear_bits(phydev, 0x10, BIT(10));
791 : 0 : phy_write(phydev, 0x1f, 0x0000);
792 : 0 : }
793 : :
794 : 0 : static void rtl8168g_disable_aldps(struct phy_device *phydev)
795 : : {
796 : 0 : phy_modify_paged(phydev, 0x0a43, 0x10, BIT(2), 0);
797 : : }
798 : :
799 : 0 : static void rtl8168g_phy_adjust_10m_aldps(struct phy_device *phydev)
800 : : {
801 : 0 : phy_modify_paged(phydev, 0x0bcc, 0x14, BIT(8), 0);
802 : 0 : phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(7) | BIT(6));
803 : 0 : r8168g_phy_param(phydev, 0x8084, 0x6000, 0x0000);
804 : 0 : phy_modify_paged(phydev, 0x0a43, 0x10, 0x0000, 0x1003);
805 : 0 : }
806 : :
807 : 0 : static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp,
808 : : struct phy_device *phydev)
809 : : {
810 : 0 : int ret;
811 : :
812 : 0 : r8169_apply_firmware(tp);
813 : :
814 : 0 : ret = phy_read_paged(phydev, 0x0a46, 0x10);
815 [ # # ]: 0 : if (ret & BIT(8))
816 : 0 : phy_modify_paged(phydev, 0x0bcc, 0x12, BIT(15), 0);
817 : : else
818 : 0 : phy_modify_paged(phydev, 0x0bcc, 0x12, 0, BIT(15));
819 : :
820 : 0 : ret = phy_read_paged(phydev, 0x0a46, 0x13);
821 [ # # ]: 0 : if (ret & BIT(8))
822 : 0 : phy_modify_paged(phydev, 0x0c41, 0x15, 0, BIT(1));
823 : : else
824 : 0 : phy_modify_paged(phydev, 0x0c41, 0x15, BIT(1), 0);
825 : :
826 : : /* Enable PHY auto speed down */
827 : 0 : phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(3) | BIT(2));
828 : :
829 : 0 : rtl8168g_phy_adjust_10m_aldps(phydev);
830 : :
831 : : /* EEE auto-fallback function */
832 : 0 : phy_modify_paged(phydev, 0x0a4b, 0x11, 0, BIT(2));
833 : :
834 : : /* Enable UC LPF tune function */
835 : 0 : r8168g_phy_param(phydev, 0x8012, 0x0000, 0x8000);
836 : :
837 : 0 : phy_modify_paged(phydev, 0x0c42, 0x11, BIT(13), BIT(14));
838 : :
839 : : /* Improve SWR Efficiency */
840 : 0 : phy_write(phydev, 0x1f, 0x0bcd);
841 : 0 : phy_write(phydev, 0x14, 0x5065);
842 : 0 : phy_write(phydev, 0x14, 0xd065);
843 : 0 : phy_write(phydev, 0x1f, 0x0bc8);
844 : 0 : phy_write(phydev, 0x11, 0x5655);
845 : 0 : phy_write(phydev, 0x1f, 0x0bcd);
846 : 0 : phy_write(phydev, 0x14, 0x1065);
847 : 0 : phy_write(phydev, 0x14, 0x9065);
848 : 0 : phy_write(phydev, 0x14, 0x1065);
849 : 0 : phy_write(phydev, 0x1f, 0x0000);
850 : :
851 : 0 : rtl8168g_disable_aldps(phydev);
852 : 0 : rtl8168g_config_eee_phy(phydev);
853 : 0 : }
854 : :
855 : 0 : static void rtl8168g_2_hw_phy_config(struct rtl8169_private *tp,
856 : : struct phy_device *phydev)
857 : : {
858 : 0 : r8169_apply_firmware(tp);
859 : 0 : rtl8168g_config_eee_phy(phydev);
860 : 0 : }
861 : :
862 : 0 : static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp,
863 : : struct phy_device *phydev)
864 : : {
865 : 0 : u16 dout_tapbin;
866 : 0 : u32 data;
867 : :
868 : 0 : r8169_apply_firmware(tp);
869 : :
870 : : /* CHN EST parameters adjust - giga master */
871 : 0 : r8168g_phy_param(phydev, 0x809b, 0xf800, 0x8000);
872 : 0 : r8168g_phy_param(phydev, 0x80a2, 0xff00, 0x8000);
873 : 0 : r8168g_phy_param(phydev, 0x80a4, 0xff00, 0x8500);
874 : 0 : r8168g_phy_param(phydev, 0x809c, 0xff00, 0xbd00);
875 : :
876 : : /* CHN EST parameters adjust - giga slave */
877 : 0 : r8168g_phy_param(phydev, 0x80ad, 0xf800, 0x7000);
878 : 0 : r8168g_phy_param(phydev, 0x80b4, 0xff00, 0x5000);
879 : 0 : r8168g_phy_param(phydev, 0x80ac, 0xff00, 0x4000);
880 : :
881 : : /* CHN EST parameters adjust - fnet */
882 : 0 : r8168g_phy_param(phydev, 0x808e, 0xff00, 0x1200);
883 : 0 : r8168g_phy_param(phydev, 0x8090, 0xff00, 0xe500);
884 : 0 : r8168g_phy_param(phydev, 0x8092, 0xff00, 0x9f00);
885 : :
886 : : /* enable R-tune & PGA-retune function */
887 : 0 : dout_tapbin = 0;
888 : 0 : data = phy_read_paged(phydev, 0x0a46, 0x13);
889 : 0 : data &= 3;
890 : 0 : data <<= 2;
891 : 0 : dout_tapbin |= data;
892 : 0 : data = phy_read_paged(phydev, 0x0a46, 0x12);
893 : 0 : data &= 0xc000;
894 : 0 : data >>= 14;
895 : 0 : dout_tapbin |= data;
896 : 0 : dout_tapbin = ~(dout_tapbin ^ 0x08);
897 : 0 : dout_tapbin <<= 12;
898 : 0 : dout_tapbin &= 0xf000;
899 : :
900 : 0 : r8168g_phy_param(phydev, 0x827a, 0xf000, dout_tapbin);
901 : 0 : r8168g_phy_param(phydev, 0x827b, 0xf000, dout_tapbin);
902 : 0 : r8168g_phy_param(phydev, 0x827c, 0xf000, dout_tapbin);
903 : 0 : r8168g_phy_param(phydev, 0x827d, 0xf000, dout_tapbin);
904 : 0 : r8168g_phy_param(phydev, 0x0811, 0x0000, 0x0800);
905 : 0 : phy_modify_paged(phydev, 0x0a42, 0x16, 0x0000, 0x0002);
906 : :
907 : : /* enable GPHY 10M */
908 : 0 : phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(11));
909 : :
910 : : /* SAR ADC performance */
911 : 0 : phy_modify_paged(phydev, 0x0bca, 0x17, BIT(12) | BIT(13), BIT(14));
912 : :
913 : 0 : r8168g_phy_param(phydev, 0x803f, 0x3000, 0x0000);
914 : 0 : r8168g_phy_param(phydev, 0x8047, 0x3000, 0x0000);
915 : 0 : r8168g_phy_param(phydev, 0x804f, 0x3000, 0x0000);
916 : 0 : r8168g_phy_param(phydev, 0x8057, 0x3000, 0x0000);
917 : 0 : r8168g_phy_param(phydev, 0x805f, 0x3000, 0x0000);
918 : 0 : r8168g_phy_param(phydev, 0x8067, 0x3000, 0x0000);
919 : 0 : r8168g_phy_param(phydev, 0x806f, 0x3000, 0x0000);
920 : :
921 : : /* disable phy pfm mode */
922 : 0 : phy_modify_paged(phydev, 0x0a44, 0x11, BIT(7), 0);
923 : :
924 : 0 : rtl8168g_disable_aldps(phydev);
925 : 0 : rtl8168h_config_eee_phy(phydev);
926 : 0 : }
927 : :
928 : 0 : static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp,
929 : : struct phy_device *phydev)
930 : : {
931 : 0 : u16 ioffset, rlen;
932 : 0 : u32 data;
933 : :
934 : 0 : r8169_apply_firmware(tp);
935 : :
936 : : /* CHIN EST parameter update */
937 : 0 : r8168g_phy_param(phydev, 0x808a, 0x003f, 0x000a);
938 : :
939 : : /* enable R-tune & PGA-retune function */
940 : 0 : r8168g_phy_param(phydev, 0x0811, 0x0000, 0x0800);
941 : 0 : phy_modify_paged(phydev, 0x0a42, 0x16, 0x0000, 0x0002);
942 : :
943 : : /* enable GPHY 10M */
944 : 0 : phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(11));
945 : :
946 : 0 : ioffset = rtl8168h_2_get_adc_bias_ioffset(tp);
947 [ # # ]: 0 : if (ioffset != 0xffff)
948 : 0 : phy_write_paged(phydev, 0x0bcf, 0x16, ioffset);
949 : :
950 : : /* Modify rlen (TX LPF corner frequency) level */
951 : 0 : data = phy_read_paged(phydev, 0x0bcd, 0x16);
952 : 0 : data &= 0x000f;
953 : 0 : rlen = 0;
954 [ # # ]: 0 : if (data > 3)
955 : 0 : rlen = data - 3;
956 : 0 : data = rlen | (rlen << 4) | (rlen << 8) | (rlen << 12);
957 : 0 : phy_write_paged(phydev, 0x0bcd, 0x17, data);
958 : :
959 : : /* disable phy pfm mode */
960 : 0 : phy_modify_paged(phydev, 0x0a44, 0x11, BIT(7), 0);
961 : :
962 : 0 : rtl8168g_disable_aldps(phydev);
963 : 0 : rtl8168g_config_eee_phy(phydev);
964 : 0 : }
965 : :
966 : 0 : static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp,
967 : : struct phy_device *phydev)
968 : : {
969 : : /* Enable PHY auto speed down */
970 : 0 : phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(3) | BIT(2));
971 : :
972 : 0 : rtl8168g_phy_adjust_10m_aldps(phydev);
973 : :
974 : : /* Enable EEE auto-fallback function */
975 : 0 : phy_modify_paged(phydev, 0x0a4b, 0x11, 0, BIT(2));
976 : :
977 : : /* Enable UC LPF tune function */
978 : 0 : r8168g_phy_param(phydev, 0x8012, 0x0000, 0x8000);
979 : :
980 : : /* set rg_sel_sdm_rate */
981 : 0 : phy_modify_paged(phydev, 0x0c42, 0x11, BIT(13), BIT(14));
982 : :
983 : 0 : rtl8168g_disable_aldps(phydev);
984 : 0 : rtl8168g_config_eee_phy(phydev);
985 : 0 : }
986 : :
987 : 0 : static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp,
988 : : struct phy_device *phydev)
989 : : {
990 : 0 : rtl8168g_phy_adjust_10m_aldps(phydev);
991 : :
992 : : /* Enable UC LPF tune function */
993 : 0 : r8168g_phy_param(phydev, 0x8012, 0x0000, 0x8000);
994 : :
995 : : /* Set rg_sel_sdm_rate */
996 : 0 : phy_modify_paged(phydev, 0x0c42, 0x11, BIT(13), BIT(14));
997 : :
998 : : /* Channel estimation parameters */
999 : 0 : r8168g_phy_param(phydev, 0x80f3, 0xff00, 0x8b00);
1000 : 0 : r8168g_phy_param(phydev, 0x80f0, 0xff00, 0x3a00);
1001 : 0 : r8168g_phy_param(phydev, 0x80ef, 0xff00, 0x0500);
1002 : 0 : r8168g_phy_param(phydev, 0x80f6, 0xff00, 0x6e00);
1003 : 0 : r8168g_phy_param(phydev, 0x80ec, 0xff00, 0x6800);
1004 : 0 : r8168g_phy_param(phydev, 0x80ed, 0xff00, 0x7c00);
1005 : 0 : r8168g_phy_param(phydev, 0x80f2, 0xff00, 0xf400);
1006 : 0 : r8168g_phy_param(phydev, 0x80f4, 0xff00, 0x8500);
1007 : 0 : r8168g_phy_param(phydev, 0x8110, 0xff00, 0xa800);
1008 : 0 : r8168g_phy_param(phydev, 0x810f, 0xff00, 0x1d00);
1009 : 0 : r8168g_phy_param(phydev, 0x8111, 0xff00, 0xf500);
1010 : 0 : r8168g_phy_param(phydev, 0x8113, 0xff00, 0x6100);
1011 : 0 : r8168g_phy_param(phydev, 0x8115, 0xff00, 0x9200);
1012 : 0 : r8168g_phy_param(phydev, 0x810e, 0xff00, 0x0400);
1013 : 0 : r8168g_phy_param(phydev, 0x810c, 0xff00, 0x7c00);
1014 : 0 : r8168g_phy_param(phydev, 0x810b, 0xff00, 0x5a00);
1015 : 0 : r8168g_phy_param(phydev, 0x80d1, 0xff00, 0xff00);
1016 : 0 : r8168g_phy_param(phydev, 0x80cd, 0xff00, 0x9e00);
1017 : 0 : r8168g_phy_param(phydev, 0x80d3, 0xff00, 0x0e00);
1018 : 0 : r8168g_phy_param(phydev, 0x80d5, 0xff00, 0xca00);
1019 : 0 : r8168g_phy_param(phydev, 0x80d7, 0xff00, 0x8400);
1020 : :
1021 : : /* Force PWM-mode */
1022 : 0 : phy_write(phydev, 0x1f, 0x0bcd);
1023 : 0 : phy_write(phydev, 0x14, 0x5065);
1024 : 0 : phy_write(phydev, 0x14, 0xd065);
1025 : 0 : phy_write(phydev, 0x1f, 0x0bc8);
1026 : 0 : phy_write(phydev, 0x12, 0x00ed);
1027 : 0 : phy_write(phydev, 0x1f, 0x0bcd);
1028 : 0 : phy_write(phydev, 0x14, 0x1065);
1029 : 0 : phy_write(phydev, 0x14, 0x9065);
1030 : 0 : phy_write(phydev, 0x14, 0x1065);
1031 : 0 : phy_write(phydev, 0x1f, 0x0000);
1032 : :
1033 : 0 : rtl8168g_disable_aldps(phydev);
1034 : 0 : rtl8168g_config_eee_phy(phydev);
1035 : 0 : }
1036 : :
1037 : 0 : static void rtl8117_hw_phy_config(struct rtl8169_private *tp,
1038 : : struct phy_device *phydev)
1039 : : {
1040 : : /* CHN EST parameters adjust - fnet */
1041 : 0 : r8168g_phy_param(phydev, 0x808e, 0xff00, 0x4800);
1042 : 0 : r8168g_phy_param(phydev, 0x8090, 0xff00, 0xcc00);
1043 : 0 : r8168g_phy_param(phydev, 0x8092, 0xff00, 0xb000);
1044 : :
1045 : 0 : r8168g_phy_param(phydev, 0x8088, 0xff00, 0x6000);
1046 : 0 : r8168g_phy_param(phydev, 0x808b, 0x3f00, 0x0b00);
1047 : 0 : r8168g_phy_param(phydev, 0x808d, 0x1f00, 0x0600);
1048 : 0 : r8168g_phy_param(phydev, 0x808c, 0xff00, 0xb000);
1049 : 0 : r8168g_phy_param(phydev, 0x80a0, 0xff00, 0x2800);
1050 : 0 : r8168g_phy_param(phydev, 0x80a2, 0xff00, 0x5000);
1051 : 0 : r8168g_phy_param(phydev, 0x809b, 0xf800, 0xb000);
1052 : 0 : r8168g_phy_param(phydev, 0x809a, 0xff00, 0x4b00);
1053 : 0 : r8168g_phy_param(phydev, 0x809d, 0x3f00, 0x0800);
1054 : 0 : r8168g_phy_param(phydev, 0x80a1, 0xff00, 0x7000);
1055 : 0 : r8168g_phy_param(phydev, 0x809f, 0x1f00, 0x0300);
1056 : 0 : r8168g_phy_param(phydev, 0x809e, 0xff00, 0x8800);
1057 : 0 : r8168g_phy_param(phydev, 0x80b2, 0xff00, 0x2200);
1058 : 0 : r8168g_phy_param(phydev, 0x80ad, 0xf800, 0x9800);
1059 : 0 : r8168g_phy_param(phydev, 0x80af, 0x3f00, 0x0800);
1060 : 0 : r8168g_phy_param(phydev, 0x80b3, 0xff00, 0x6f00);
1061 : 0 : r8168g_phy_param(phydev, 0x80b1, 0x1f00, 0x0300);
1062 : 0 : r8168g_phy_param(phydev, 0x80b0, 0xff00, 0x9300);
1063 : :
1064 : 0 : r8168g_phy_param(phydev, 0x8011, 0x0000, 0x0800);
1065 : :
1066 : : /* enable GPHY 10M */
1067 : 0 : phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(11));
1068 : :
1069 : 0 : r8168g_phy_param(phydev, 0x8016, 0x0000, 0x0400);
1070 : :
1071 : 0 : rtl8168g_disable_aldps(phydev);
1072 : 0 : rtl8168h_config_eee_phy(phydev);
1073 : 0 : }
1074 : :
1075 : 0 : static void rtl8102e_hw_phy_config(struct rtl8169_private *tp,
1076 : : struct phy_device *phydev)
1077 : : {
1078 : 0 : static const struct phy_reg phy_reg_init[] = {
1079 : : { 0x1f, 0x0003 },
1080 : : { 0x08, 0x441d },
1081 : : { 0x01, 0x9100 },
1082 : : { 0x1f, 0x0000 }
1083 : : };
1084 : :
1085 : 0 : phy_set_bits(phydev, 0x11, BIT(12));
1086 : 0 : phy_set_bits(phydev, 0x19, BIT(13));
1087 : 0 : phy_set_bits(phydev, 0x10, BIT(15));
1088 : :
1089 : 0 : rtl_writephy_batch(phydev, phy_reg_init);
1090 : 0 : }
1091 : :
1092 : 0 : static void rtl8105e_hw_phy_config(struct rtl8169_private *tp,
1093 : : struct phy_device *phydev)
1094 : : {
1095 : : /* Disable ALDPS before ram code */
1096 : 0 : phy_write(phydev, 0x18, 0x0310);
1097 : 0 : msleep(100);
1098 : :
1099 : 0 : r8169_apply_firmware(tp);
1100 : :
1101 : 0 : phy_write_paged(phydev, 0x0005, 0x1a, 0x0000);
1102 : 0 : phy_write_paged(phydev, 0x0004, 0x1c, 0x0000);
1103 : 0 : phy_write_paged(phydev, 0x0001, 0x15, 0x7701);
1104 : 0 : }
1105 : :
1106 : 0 : static void rtl8402_hw_phy_config(struct rtl8169_private *tp,
1107 : : struct phy_device *phydev)
1108 : : {
1109 : : /* Disable ALDPS before setting firmware */
1110 : 0 : phy_write(phydev, 0x18, 0x0310);
1111 : 0 : msleep(20);
1112 : :
1113 : 0 : r8169_apply_firmware(tp);
1114 : :
1115 : : /* EEE setting */
1116 : 0 : phy_write(phydev, 0x1f, 0x0004);
1117 : 0 : phy_write(phydev, 0x10, 0x401f);
1118 : 0 : phy_write(phydev, 0x19, 0x7030);
1119 : 0 : phy_write(phydev, 0x1f, 0x0000);
1120 : 0 : }
1121 : :
1122 : 0 : static void rtl8106e_hw_phy_config(struct rtl8169_private *tp,
1123 : : struct phy_device *phydev)
1124 : : {
1125 : 0 : static const struct phy_reg phy_reg_init[] = {
1126 : : { 0x1f, 0x0004 },
1127 : : { 0x10, 0xc07f },
1128 : : { 0x19, 0x7030 },
1129 : : { 0x1f, 0x0000 }
1130 : : };
1131 : :
1132 : : /* Disable ALDPS before ram code */
1133 : 0 : phy_write(phydev, 0x18, 0x0310);
1134 : 0 : msleep(100);
1135 : :
1136 : 0 : r8169_apply_firmware(tp);
1137 : :
1138 : 0 : rtl_writephy_batch(phydev, phy_reg_init);
1139 : 0 : }
1140 : :
1141 : 0 : static void rtl8125_1_hw_phy_config(struct rtl8169_private *tp,
1142 : : struct phy_device *phydev)
1143 : : {
1144 : 0 : phy_modify_paged(phydev, 0xad4, 0x10, 0x03ff, 0x0084);
1145 : 0 : phy_modify_paged(phydev, 0xad4, 0x17, 0x0000, 0x0010);
1146 : 0 : phy_modify_paged(phydev, 0xad1, 0x13, 0x03ff, 0x0006);
1147 : 0 : phy_modify_paged(phydev, 0xad3, 0x11, 0x003f, 0x0006);
1148 : 0 : phy_modify_paged(phydev, 0xac0, 0x14, 0x0000, 0x1100);
1149 : 0 : phy_modify_paged(phydev, 0xac8, 0x15, 0xf000, 0x7000);
1150 : 0 : phy_modify_paged(phydev, 0xad1, 0x14, 0x0000, 0x0400);
1151 : 0 : phy_modify_paged(phydev, 0xad1, 0x15, 0x0000, 0x03ff);
1152 : 0 : phy_modify_paged(phydev, 0xad1, 0x16, 0x0000, 0x03ff);
1153 : :
1154 : 0 : r8168g_phy_param(phydev, 0x80ea, 0xff00, 0xc400);
1155 : 0 : r8168g_phy_param(phydev, 0x80eb, 0x0700, 0x0300);
1156 : 0 : r8168g_phy_param(phydev, 0x80f8, 0xff00, 0x1c00);
1157 : 0 : r8168g_phy_param(phydev, 0x80f1, 0xff00, 0x3000);
1158 : 0 : r8168g_phy_param(phydev, 0x80fe, 0xff00, 0xa500);
1159 : 0 : r8168g_phy_param(phydev, 0x8102, 0xff00, 0x5000);
1160 : 0 : r8168g_phy_param(phydev, 0x8105, 0xff00, 0x3300);
1161 : 0 : r8168g_phy_param(phydev, 0x8100, 0xff00, 0x7000);
1162 : 0 : r8168g_phy_param(phydev, 0x8104, 0xff00, 0xf000);
1163 : 0 : r8168g_phy_param(phydev, 0x8106, 0xff00, 0x6500);
1164 : 0 : r8168g_phy_param(phydev, 0x80dc, 0xff00, 0xed00);
1165 : 0 : r8168g_phy_param(phydev, 0x80df, 0x0000, 0x0100);
1166 : 0 : r8168g_phy_param(phydev, 0x80e1, 0x0100, 0x0000);
1167 : :
1168 : 0 : phy_modify_paged(phydev, 0xbf0, 0x13, 0x003f, 0x0038);
1169 : 0 : r8168g_phy_param(phydev, 0x819f, 0xffff, 0xd0b6);
1170 : :
1171 : 0 : phy_write_paged(phydev, 0xbc3, 0x12, 0x5555);
1172 : 0 : phy_modify_paged(phydev, 0xbf0, 0x15, 0x0e00, 0x0a00);
1173 : 0 : phy_modify_paged(phydev, 0xa5c, 0x10, 0x0400, 0x0000);
1174 : 0 : phy_modify_paged(phydev, 0xa44, 0x11, 0x0000, 0x0800);
1175 : :
1176 : 0 : rtl8125_config_eee_phy(phydev);
1177 : 0 : }
1178 : :
1179 : 0 : static void rtl8125_2_hw_phy_config(struct rtl8169_private *tp,
1180 : : struct phy_device *phydev)
1181 : : {
1182 : 0 : int i;
1183 : :
1184 : 0 : phy_modify_paged(phydev, 0xad4, 0x17, 0x0000, 0x0010);
1185 : 0 : phy_modify_paged(phydev, 0xad1, 0x13, 0x03ff, 0x03ff);
1186 : 0 : phy_modify_paged(phydev, 0xad3, 0x11, 0x003f, 0x0006);
1187 : 0 : phy_modify_paged(phydev, 0xac0, 0x14, 0x1100, 0x0000);
1188 : 0 : phy_modify_paged(phydev, 0xacc, 0x10, 0x0003, 0x0002);
1189 : 0 : phy_modify_paged(phydev, 0xad4, 0x10, 0x00e7, 0x0044);
1190 : 0 : phy_modify_paged(phydev, 0xac1, 0x12, 0x0080, 0x0000);
1191 : 0 : phy_modify_paged(phydev, 0xac8, 0x10, 0x0300, 0x0000);
1192 : 0 : phy_modify_paged(phydev, 0xac5, 0x17, 0x0007, 0x0002);
1193 : 0 : phy_write_paged(phydev, 0xad4, 0x16, 0x00a8);
1194 : 0 : phy_write_paged(phydev, 0xac5, 0x16, 0x01ff);
1195 : 0 : phy_modify_paged(phydev, 0xac8, 0x15, 0x00f0, 0x0030);
1196 : :
1197 : 0 : phy_write(phydev, 0x1f, 0x0b87);
1198 : 0 : phy_write(phydev, 0x16, 0x80a2);
1199 : 0 : phy_write(phydev, 0x17, 0x0153);
1200 : 0 : phy_write(phydev, 0x16, 0x809c);
1201 : 0 : phy_write(phydev, 0x17, 0x0153);
1202 : 0 : phy_write(phydev, 0x1f, 0x0000);
1203 : :
1204 : 0 : phy_write(phydev, 0x1f, 0x0a43);
1205 : 0 : phy_write(phydev, 0x13, 0x81B3);
1206 : 0 : phy_write(phydev, 0x14, 0x0043);
1207 : 0 : phy_write(phydev, 0x14, 0x00A7);
1208 : 0 : phy_write(phydev, 0x14, 0x00D6);
1209 : 0 : phy_write(phydev, 0x14, 0x00EC);
1210 : 0 : phy_write(phydev, 0x14, 0x00F6);
1211 : 0 : phy_write(phydev, 0x14, 0x00FB);
1212 : 0 : phy_write(phydev, 0x14, 0x00FD);
1213 : 0 : phy_write(phydev, 0x14, 0x00FF);
1214 : 0 : phy_write(phydev, 0x14, 0x00BB);
1215 : 0 : phy_write(phydev, 0x14, 0x0058);
1216 : 0 : phy_write(phydev, 0x14, 0x0029);
1217 : 0 : phy_write(phydev, 0x14, 0x0013);
1218 : 0 : phy_write(phydev, 0x14, 0x0009);
1219 : 0 : phy_write(phydev, 0x14, 0x0004);
1220 : 0 : phy_write(phydev, 0x14, 0x0002);
1221 [ # # ]: 0 : for (i = 0; i < 25; i++)
1222 : 0 : phy_write(phydev, 0x14, 0x0000);
1223 : 0 : phy_write(phydev, 0x1f, 0x0000);
1224 : :
1225 : 0 : r8168g_phy_param(phydev, 0x8257, 0xffff, 0x020F);
1226 : 0 : r8168g_phy_param(phydev, 0x80ea, 0xffff, 0x7843);
1227 : :
1228 : 0 : r8169_apply_firmware(tp);
1229 : :
1230 : 0 : phy_modify_paged(phydev, 0xd06, 0x14, 0x0000, 0x2000);
1231 : :
1232 : 0 : r8168g_phy_param(phydev, 0x81a2, 0x0000, 0x0100);
1233 : :
1234 : 0 : phy_modify_paged(phydev, 0xb54, 0x16, 0xff00, 0xdb00);
1235 : 0 : phy_modify_paged(phydev, 0xa45, 0x12, 0x0001, 0x0000);
1236 : 0 : phy_modify_paged(phydev, 0xa5d, 0x12, 0x0000, 0x0020);
1237 : 0 : phy_modify_paged(phydev, 0xad4, 0x17, 0x0010, 0x0000);
1238 : 0 : phy_modify_paged(phydev, 0xa86, 0x15, 0x0001, 0x0000);
1239 : 0 : phy_modify_paged(phydev, 0xa44, 0x11, 0x0000, 0x0800);
1240 : :
1241 : 0 : rtl8125_config_eee_phy(phydev);
1242 : 0 : }
1243 : :
1244 : 0 : void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
1245 : : enum mac_version ver)
1246 : : {
1247 : 0 : static const rtl_phy_cfg_fct phy_configs[] = {
1248 : : /* PCI devices. */
1249 : : [RTL_GIGA_MAC_VER_02] = rtl8169s_hw_phy_config,
1250 : : [RTL_GIGA_MAC_VER_03] = rtl8169s_hw_phy_config,
1251 : : [RTL_GIGA_MAC_VER_04] = rtl8169sb_hw_phy_config,
1252 : : [RTL_GIGA_MAC_VER_05] = rtl8169scd_hw_phy_config,
1253 : : [RTL_GIGA_MAC_VER_06] = rtl8169sce_hw_phy_config,
1254 : : /* PCI-E devices. */
1255 : : [RTL_GIGA_MAC_VER_07] = rtl8102e_hw_phy_config,
1256 : : [RTL_GIGA_MAC_VER_08] = rtl8102e_hw_phy_config,
1257 : : [RTL_GIGA_MAC_VER_09] = rtl8102e_hw_phy_config,
1258 : : [RTL_GIGA_MAC_VER_10] = NULL,
1259 : : [RTL_GIGA_MAC_VER_11] = rtl8168bb_hw_phy_config,
1260 : : [RTL_GIGA_MAC_VER_12] = rtl8168bef_hw_phy_config,
1261 : : [RTL_GIGA_MAC_VER_13] = NULL,
1262 : : [RTL_GIGA_MAC_VER_14] = NULL,
1263 : : [RTL_GIGA_MAC_VER_15] = NULL,
1264 : : [RTL_GIGA_MAC_VER_16] = NULL,
1265 : : [RTL_GIGA_MAC_VER_17] = rtl8168bef_hw_phy_config,
1266 : : [RTL_GIGA_MAC_VER_18] = rtl8168cp_1_hw_phy_config,
1267 : : [RTL_GIGA_MAC_VER_19] = rtl8168c_1_hw_phy_config,
1268 : : [RTL_GIGA_MAC_VER_20] = rtl8168c_2_hw_phy_config,
1269 : : [RTL_GIGA_MAC_VER_21] = rtl8168c_3_hw_phy_config,
1270 : : [RTL_GIGA_MAC_VER_22] = rtl8168c_3_hw_phy_config,
1271 : : [RTL_GIGA_MAC_VER_23] = rtl8168cp_2_hw_phy_config,
1272 : : [RTL_GIGA_MAC_VER_24] = rtl8168cp_2_hw_phy_config,
1273 : : [RTL_GIGA_MAC_VER_25] = rtl8168d_1_hw_phy_config,
1274 : : [RTL_GIGA_MAC_VER_26] = rtl8168d_2_hw_phy_config,
1275 : : [RTL_GIGA_MAC_VER_27] = rtl8168d_3_hw_phy_config,
1276 : : [RTL_GIGA_MAC_VER_28] = rtl8168d_4_hw_phy_config,
1277 : : [RTL_GIGA_MAC_VER_29] = rtl8105e_hw_phy_config,
1278 : : [RTL_GIGA_MAC_VER_30] = rtl8105e_hw_phy_config,
1279 : : [RTL_GIGA_MAC_VER_31] = NULL,
1280 : : [RTL_GIGA_MAC_VER_32] = rtl8168e_1_hw_phy_config,
1281 : : [RTL_GIGA_MAC_VER_33] = rtl8168e_1_hw_phy_config,
1282 : : [RTL_GIGA_MAC_VER_34] = rtl8168e_2_hw_phy_config,
1283 : : [RTL_GIGA_MAC_VER_35] = rtl8168f_1_hw_phy_config,
1284 : : [RTL_GIGA_MAC_VER_36] = rtl8168f_2_hw_phy_config,
1285 : : [RTL_GIGA_MAC_VER_37] = rtl8402_hw_phy_config,
1286 : : [RTL_GIGA_MAC_VER_38] = rtl8411_hw_phy_config,
1287 : : [RTL_GIGA_MAC_VER_39] = rtl8106e_hw_phy_config,
1288 : : [RTL_GIGA_MAC_VER_40] = rtl8168g_1_hw_phy_config,
1289 : : [RTL_GIGA_MAC_VER_41] = NULL,
1290 : : [RTL_GIGA_MAC_VER_42] = rtl8168g_2_hw_phy_config,
1291 : : [RTL_GIGA_MAC_VER_43] = rtl8168g_2_hw_phy_config,
1292 : : [RTL_GIGA_MAC_VER_44] = rtl8168g_2_hw_phy_config,
1293 : : [RTL_GIGA_MAC_VER_45] = rtl8168h_1_hw_phy_config,
1294 : : [RTL_GIGA_MAC_VER_46] = rtl8168h_2_hw_phy_config,
1295 : : [RTL_GIGA_MAC_VER_47] = rtl8168h_1_hw_phy_config,
1296 : : [RTL_GIGA_MAC_VER_48] = rtl8168h_2_hw_phy_config,
1297 : : [RTL_GIGA_MAC_VER_49] = rtl8168ep_1_hw_phy_config,
1298 : : [RTL_GIGA_MAC_VER_50] = rtl8168ep_2_hw_phy_config,
1299 : : [RTL_GIGA_MAC_VER_51] = rtl8168ep_2_hw_phy_config,
1300 : : [RTL_GIGA_MAC_VER_52] = rtl8117_hw_phy_config,
1301 : : [RTL_GIGA_MAC_VER_60] = rtl8125_1_hw_phy_config,
1302 : : [RTL_GIGA_MAC_VER_61] = rtl8125_2_hw_phy_config,
1303 : : };
1304 : :
1305 [ # # ]: 0 : if (phy_configs[ver])
1306 : 0 : phy_configs[ver](tp, phydev);
1307 : 0 : }
|