realtek: update the tree to the latest refactored version
[openwrt/staging/hauke.git] / target / linux / realtek / files-5.4 / drivers / net / phy / rtl83xx-phy.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Realtek RTL838X Ethernet MDIO interface driver
3 *
4 * Copyright (C) 2020 B. Koblitz
5 */
6
7 #include <linux/module.h>
8 #include <linux/delay.h>
9 #include <linux/phy.h>
10 #include <linux/netdevice.h>
11 #include <linux/firmware.h>
12 #include <linux/crc32.h>
13
14 #include <asm/mach-rtl838x/mach-rtl83xx.h>
15 #include "rtl83xx-phy.h"
16
17
18 extern struct rtl83xx_soc_info soc_info;
19 extern struct mutex smi_lock;
20
21 static const struct firmware rtl838x_8380_fw;
22 static const struct firmware rtl838x_8214fc_fw;
23 static const struct firmware rtl838x_8218b_fw;
24
25
26 static int read_phy(u32 port, u32 page, u32 reg, u32 *val)
27 {
28 if (soc_info.family == RTL8390_FAMILY_ID)
29 return rtl839x_read_phy(port, page, reg, val);
30 else
31 return rtl838x_read_phy(port, page, reg, val);
32 }
33
34 static int write_phy(u32 port, u32 page, u32 reg, u32 val)
35 {
36 if (soc_info.family == RTL8390_FAMILY_ID)
37 return rtl839x_write_phy(port, page, reg, val);
38 else
39 return rtl838x_write_phy(port, page, reg, val);
40 }
41
42 static void int_phy_on_off(int mac, bool on)
43 {
44 u32 val;
45
46 read_phy(mac, 0, 0, &val);
47 if (on)
48 write_phy(mac, 0, 0, val & ~(1 << 11));
49 else
50 write_phy(mac, 0, 0, val | (1 << 11));
51 }
52
53 static void rtl8214fc_on_off(int mac, bool on)
54 {
55 u32 val;
56
57 /* fiber ports */
58 write_phy(mac, 4095, 30, 3);
59 read_phy(mac, 0, 16, &val);
60 if (on)
61 write_phy(mac, 0, 16, val & ~(1 << 11));
62 else
63 write_phy(mac, 0, 16, val | (1 << 11));
64
65 /* copper ports */
66 write_phy(mac, 4095, 30, 1);
67 read_phy(mac, 0, 16, &val);
68 if (on)
69 write_phy(mac, 0xa40, 16, val & ~(1 << 11));
70 else
71 write_phy(mac, 0xa40, 16, val | (1 << 11));
72 }
73
74 static void phy_reset(int mac)
75 {
76 u32 val;
77
78 read_phy(mac, 0, 0, &val);
79 write_phy(mac, 0, 0, val | (0x1 << 15));
80 }
81
82 /* Read the link and speed status of the 2 internal SGMII/1000Base-X
83 * ports of the RTL838x SoCs
84 */
85 static int rtl8380_read_status(struct phy_device *phydev)
86 {
87 int err;
88
89 err = genphy_read_status(phydev);
90
91 if (phydev->link) {
92 phydev->speed = SPEED_1000;
93 phydev->duplex = DUPLEX_FULL;
94 }
95
96 return err;
97 }
98
99 /* Read the link and speed status of the 2 internal SGMII/1000Base-X
100 * ports of the RTL8393 SoC
101 */
102 static int rtl8393_read_status(struct phy_device *phydev)
103 {
104 int offset = 0;
105 int err;
106 int phy_addr = phydev->mdio.addr;
107 u32 v;
108
109 err = genphy_read_status(phydev);
110 if (phy_addr == 49)
111 offset = 0x100;
112
113 if (phydev->link) {
114 phydev->speed = SPEED_100;
115 /* Read SPD_RD_00 (bit 13) and SPD_RD_01 (bit 6) out of the internal
116 * PHY registers
117 */
118 v = sw_r32(RTL839X_SDS12_13_XSG0 + offset + 0x80);
119 if (!(v & (1 << 13)) && (v & (1 << 6)))
120 phydev->speed = SPEED_1000;
121 phydev->duplex = DUPLEX_FULL;
122 }
123
124 return err;
125 }
126
127 static struct fw_header *rtl838x_request_fw(struct phy_device *phydev,
128 const struct firmware *fw,
129 const char *name)
130 {
131 struct device *dev = &phydev->mdio.dev;
132 int err;
133 struct fw_header *h;
134 uint32_t checksum, my_checksum;
135
136 err = request_firmware(&fw, name, dev);
137 if (err < 0)
138 goto out;
139
140 if (fw->size < sizeof(struct fw_header)) {
141 pr_err("Firmware size too small.\n");
142 err = -EINVAL;
143 goto out;
144 }
145
146 h = (struct fw_header *) fw->data;
147 pr_info("Firmware loaded. Size %d, magic: %08x\n", fw->size, h->magic);
148
149 if (h->magic != 0x83808380) {
150 pr_err("Wrong firmware file: MAGIC mismatch.\n");
151 goto out;
152 }
153
154 checksum = h->checksum;
155 h->checksum = 0;
156 my_checksum = ~crc32(0xFFFFFFFFU, fw->data, fw->size);
157 if (checksum != my_checksum) {
158 pr_err("Firmware checksum mismatch.\n");
159 err = -EINVAL;
160 goto out;
161 }
162 h->checksum = checksum;
163
164 return h;
165 out:
166 dev_err(dev, "Unable to load firmware %s (%d)\n", name, err);
167 return NULL;
168 }
169
170 static int rtl8390_configure_generic(struct phy_device *phydev)
171 {
172 u32 val, phy_id;
173 int mac = phydev->mdio.addr;
174
175 read_phy(mac, 0, 2, &val);
176 phy_id = val << 16;
177 read_phy(mac, 0, 3, &val);
178 phy_id |= val;
179 pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
180
181 /* Read internal PHY ID */
182 write_phy(mac, 31, 27, 0x0002);
183 read_phy(mac, 31, 28, &val);
184
185 /* Internal RTL8218B, version 2 */
186 phydev_info(phydev, "Detected unknown %x\n", val);
187 return 0;
188 }
189
190 static int rtl8380_configure_int_rtl8218b(struct phy_device *phydev)
191 {
192 u32 val, phy_id;
193 int i, p, ipd_flag;
194 int mac = phydev->mdio.addr;
195 struct fw_header *h;
196 u32 *rtl838x_6275B_intPhy_perport;
197 u32 *rtl8218b_6276B_hwEsd_perport;
198
199
200 read_phy(mac, 0, 2, &val);
201 phy_id = val << 16;
202 read_phy(mac, 0, 3, &val);
203 phy_id |= val;
204 pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
205
206 /* Read internal PHY ID */
207 write_phy(mac, 31, 27, 0x0002);
208 read_phy(mac, 31, 28, &val);
209 if (val != 0x6275) {
210 phydev_err(phydev, "Expected internal RTL8218B, found PHY-ID %x\n", val);
211 return -1;
212 }
213
214 /* Internal RTL8218B, version 2 */
215 phydev_info(phydev, "Detected internal RTL8218B\n");
216
217 h = rtl838x_request_fw(phydev, &rtl838x_8380_fw, FIRMWARE_838X_8380_1);
218 if (!h)
219 return -1;
220
221 if (h->phy != 0x83800000) {
222 phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n");
223 return -1;
224 }
225
226 rtl838x_6275B_intPhy_perport = (void *)h + sizeof(struct fw_header)
227 + h->parts[8].start;
228
229 rtl8218b_6276B_hwEsd_perport = (void *)h + sizeof(struct fw_header)
230 + h->parts[9].start;
231
232 if (sw_r32(RTL838X_DMY_REG31) == 0x1)
233 ipd_flag = 1;
234
235 read_phy(mac, 0, 0, &val);
236 if (val & (1 << 11))
237 int_phy_on_off(mac, true);
238 else
239 phy_reset(mac);
240 msleep(100);
241
242 /* Ready PHY for patch */
243 for (p = 0; p < 8; p++) {
244 write_phy(mac + p, 0xfff, 0x1f, 0x0b82);
245 write_phy(mac + p, 0xfff, 0x10, 0x0010);
246 }
247 msleep(500);
248 for (p = 0; p < 8; p++) {
249 for (i = 0; i < 100 ; i++) {
250 read_phy(mac + p, 0x0b80, 0x10, &val);
251 if (val & 0x40)
252 break;
253 }
254 if (i >= 100) {
255 phydev_err(phydev,
256 "ERROR: Port %d not ready for patch.\n",
257 mac + p);
258 return -1;
259 }
260 }
261 for (p = 0; p < 8; p++) {
262 i = 0;
263 while (rtl838x_6275B_intPhy_perport[i * 2]) {
264 write_phy(mac + p, 0xfff,
265 rtl838x_6275B_intPhy_perport[i * 2],
266 rtl838x_6275B_intPhy_perport[i * 2 + 1]);
267 i++;
268 }
269 i = 0;
270 while (rtl8218b_6276B_hwEsd_perport[i * 2]) {
271 write_phy(mac + p, 0xfff,
272 rtl8218b_6276B_hwEsd_perport[i * 2],
273 rtl8218b_6276B_hwEsd_perport[i * 2 + 1]);
274 i++;
275 }
276 }
277 return 0;
278 }
279
280 static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev)
281 {
282 u32 val, ipd, phy_id;
283 int i, l;
284 int mac = phydev->mdio.addr;
285 struct fw_header *h;
286 u32 *rtl8380_rtl8218b_perchip;
287 u32 *rtl8218B_6276B_rtl8380_perport;
288 u32 *rtl8380_rtl8218b_perport;
289
290 if (soc_info.family == RTL8380_FAMILY_ID && mac != 0 && mac != 16) {
291 phydev_err(phydev, "External RTL8218B must have PHY-IDs 0 or 16!\n");
292 return -1;
293 }
294 read_phy(mac, 0, 2, &val);
295 phy_id = val << 16;
296 read_phy(mac, 0, 3, &val);
297 phy_id |= val;
298 pr_info("Phy on MAC %d: %x\n", mac, phy_id);
299
300 /* Read internal PHY ID */
301 write_phy(mac, 31, 27, 0x0002);
302 read_phy(mac, 31, 28, &val);
303 if (val != 0x6276) {
304 phydev_err(phydev, "Expected external RTL8218B, found PHY-ID %x\n", val);
305 return -1;
306 }
307 phydev_info(phydev, "Detected external RTL8218B\n");
308
309 h = rtl838x_request_fw(phydev, &rtl838x_8218b_fw, FIRMWARE_838X_8218b_1);
310 if (!h)
311 return -1;
312
313 if (h->phy != 0x8218b000) {
314 phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n");
315 return -1;
316 }
317
318 rtl8380_rtl8218b_perchip = (void *)h + sizeof(struct fw_header)
319 + h->parts[0].start;
320
321 rtl8218B_6276B_rtl8380_perport = (void *)h + sizeof(struct fw_header)
322 + h->parts[1].start;
323
324 rtl8380_rtl8218b_perport = (void *)h + sizeof(struct fw_header)
325 + h->parts[2].start;
326
327 read_phy(mac, 0, 0, &val);
328 if (val & (1 << 11))
329 int_phy_on_off(mac, true);
330 else
331 phy_reset(mac);
332 msleep(100);
333
334 /* Get Chip revision */
335 write_phy(mac, 0xfff, 0x1f, 0x0);
336 write_phy(mac, 0xfff, 0x1b, 0x4);
337 read_phy(mac, 0xfff, 0x1c, &val);
338
339 i = 0;
340 while (rtl8380_rtl8218b_perchip[i * 3]
341 && rtl8380_rtl8218b_perchip[i * 3 + 1]) {
342 write_phy(mac + rtl8380_rtl8218b_perchip[i * 3],
343 0xfff, rtl8380_rtl8218b_perchip[i * 3 + 1],
344 rtl8380_rtl8218b_perchip[i * 3 + 2]);
345 i++;
346 }
347
348 /* Enable PHY */
349 for (i = 0; i < 8; i++) {
350 write_phy(mac + i, 0xfff, 0x1f, 0x0000);
351 write_phy(mac + i, 0xfff, 0x00, 0x1140);
352 }
353 mdelay(100);
354
355 /* Request patch */
356 for (i = 0; i < 8; i++) {
357 write_phy(mac + i, 0xfff, 0x1f, 0x0b82);
358 write_phy(mac + i, 0xfff, 0x10, 0x0010);
359 }
360 mdelay(300);
361
362 /* Verify patch readiness */
363 for (i = 0; i < 8; i++) {
364 for (l = 0; l < 100; l++) {
365 read_phy(mac + i, 0xb80, 0x10, &val);
366 if (val & 0x40)
367 break;
368 }
369 if (l >= 100) {
370 phydev_err(phydev, "Could not patch PHY\n");
371 return -1;
372 }
373 }
374
375 /* Use Broadcast ID method for patching */
376 write_phy(mac, 0xfff, 0x1f, 0x0000);
377 write_phy(mac, 0xfff, 0x1d, 0x0008);
378 write_phy(mac, 0xfff, 0x1f, 0x0266);
379 write_phy(mac, 0xfff, 0x16, 0xff00 + mac);
380 write_phy(mac, 0xfff, 0x1f, 0x0000);
381 write_phy(mac, 0xfff, 0x1d, 0x0000);
382 mdelay(1);
383
384 write_phy(mac, 0xfff, 30, 8);
385 write_phy(mac, 0x26e, 17, 0xb);
386 write_phy(mac, 0x26e, 16, 0x2);
387 mdelay(1);
388 read_phy(mac, 0x26e, 19, &ipd);
389 write_phy(mac, 0, 30, 0);
390 ipd = (ipd >> 4) & 0xf;
391
392 i = 0;
393 while (rtl8218B_6276B_rtl8380_perport[i * 2]) {
394 write_phy(mac, 0xfff, rtl8218B_6276B_rtl8380_perport[i * 2],
395 rtl8218B_6276B_rtl8380_perport[i * 2 + 1]);
396 i++;
397 }
398
399 /*Disable broadcast ID*/
400 write_phy(mac, 0xfff, 0x1f, 0x0000);
401 write_phy(mac, 0xfff, 0x1d, 0x0008);
402 write_phy(mac, 0xfff, 0x1f, 0x0266);
403 write_phy(mac, 0xfff, 0x16, 0x00 + mac);
404 write_phy(mac, 0xfff, 0x1f, 0x0000);
405 write_phy(mac, 0xfff, 0x1d, 0x0000);
406 mdelay(1);
407
408 return 0;
409 }
410
411 static int rtl8218b_ext_match_phy_device(struct phy_device *phydev)
412 {
413 int addr = phydev->mdio.addr;
414
415 /* Both the RTL8214FC and the external RTL8218B have the same
416 * PHY ID. On the RTL838x, the RTL8218B can only be attached_dev
417 * at PHY IDs 0-7, while the RTL8214FC must be attached via
418 * the pair of SGMII/1000Base-X with higher PHY-IDs
419 */
420 if (soc_info.family == RTL8380_FAMILY_ID)
421 return phydev->phy_id == PHY_ID_RTL8218B_E && addr < 8;
422 else
423 return phydev->phy_id == PHY_ID_RTL8218B_E;
424 }
425
426 /*
427 * Read an mmd register of the PHY
428 */
429 static int rtl83xx_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val)
430 {
431 u32 v;
432
433 mutex_lock(&smi_lock);
434
435 if (rtl838x_smi_wait_op(10000))
436 goto timeout;
437
438 sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
439 mdelay(10);
440
441 sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
442
443 v = addr << 16 | reg;
444 sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_3);
445
446 /* mmd-access | read | cmd-start */
447 v = 1 << 1 | 0 << 2 | 1;
448 sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
449
450 if (rtl838x_smi_wait_op(10000))
451 goto timeout;
452
453 *val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
454
455 mutex_unlock(&smi_lock);
456 return 0;
457
458 timeout:
459 mutex_unlock(&smi_lock);
460 return -ETIMEDOUT;
461 }
462
463 /*
464 * Write to an mmd register of the PHY
465 */
466 static int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val)
467 {
468 u32 v;
469
470 pr_debug("MMD write: port %d, dev %d, reg %d, val %x\n", port, addr, reg, val);
471 val &= 0xffff;
472 mutex_lock(&smi_lock);
473
474 if (rtl838x_smi_wait_op(10000))
475 goto timeout;
476
477 sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
478 mdelay(10);
479
480 sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
481
482 sw_w32_mask(0x1f << 16, addr << 16, RTL838X_SMI_ACCESS_PHY_CTRL_3);
483 sw_w32_mask(0xffff, reg, RTL838X_SMI_ACCESS_PHY_CTRL_3);
484 /* mmd-access | write | cmd-start */
485 v = 1 << 1 | 1 << 2 | 1;
486 sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
487
488 if (rtl838x_smi_wait_op(10000))
489 goto timeout;
490
491 mutex_unlock(&smi_lock);
492 return 0;
493
494 timeout:
495 mutex_unlock(&smi_lock);
496 return -ETIMEDOUT;
497 }
498
499 static int rtl8218b_read_mmd(struct phy_device *phydev,
500 int devnum, u16 regnum)
501 {
502 int ret;
503 u32 val;
504 int addr = phydev->mdio.addr;
505
506 ret = rtl83xx_read_mmd_phy(addr, devnum, regnum, &val);
507 if (ret)
508 return ret;
509 return val;
510 }
511
512 static int rtl8218b_write_mmd(struct phy_device *phydev,
513 int devnum, u16 regnum, u16 val)
514 {
515 int addr = phydev->mdio.addr;
516
517 return rtl838x_write_mmd_phy(addr, devnum, regnum, val);
518 }
519
520 static void rtl8380_rtl8214fc_media_set(int mac, bool set_fibre)
521 {
522 int base = mac - (mac % 4);
523 static int reg[] = {16, 19, 20, 21};
524 int val, media, power;
525
526 pr_info("%s: port %d, set_fibre: %d\n", __func__, mac, set_fibre);
527 write_phy(base, 0xfff, 29, 8);
528 read_phy(base, 0x266, reg[mac % 4], &val);
529
530 media = (val >> 10) & 0x3;
531 pr_info("Current media %x\n", media);
532 if (media & 0x2) {
533 pr_info("Powering off COPPER\n");
534 write_phy(base, 0xfff, 29, 1);
535 /* Ensure power is off */
536 read_phy(base, 0xa40, 16, &power);
537 if (!(power & (1 << 11)))
538 write_phy(base, 0xa40, 16, power | (1 << 11));
539 } else {
540 pr_info("Powering off FIBRE");
541 write_phy(base, 0xfff, 29, 3);
542 /* Ensure power is off */
543 read_phy(base, 0xa40, 16, &power);
544 if (!(power & (1 << 11)))
545 write_phy(base, 0xa40, 16, power | (1 << 11));
546 }
547
548 if (set_fibre) {
549 val |= 1 << 10;
550 val &= ~(1 << 11);
551 } else {
552 val |= 1 << 10;
553 val |= 1 << 11;
554 }
555 write_phy(base, 0xfff, 29, 8);
556 write_phy(base, 0x266, reg[mac % 4], val);
557 write_phy(base, 0xfff, 29, 0);
558
559 if (set_fibre) {
560 pr_info("Powering on FIBRE");
561 write_phy(base, 0xfff, 29, 3);
562 /* Ensure power is off */
563 read_phy(base, 0xa40, 16, &power);
564 if (power & (1 << 11))
565 write_phy(base, 0xa40, 16, power & ~(1 << 11));
566 } else {
567 pr_info("Powering on COPPER\n");
568 write_phy(base, 0xfff, 29, 1);
569 /* Ensure power is off */
570 read_phy(base, 0xa40, 16, &power);
571 if (power & (1 << 11))
572 write_phy(base, 0xa40, 16, power & ~(1 << 11));
573 }
574
575 write_phy(base, 0xfff, 29, 0);
576 }
577
578 static bool rtl8380_rtl8214fc_media_is_fibre(int mac)
579 {
580 int base = mac - (mac % 4);
581 static int reg[] = {16, 19, 20, 21};
582 u32 val;
583
584 write_phy(base, 0xfff, 29, 8);
585 read_phy(base, 0x266, reg[mac % 4], &val);
586 write_phy(base, 0xfff, 29, 0);
587 if (val & (1 << 11))
588 return false;
589 return true;
590 }
591
592 static int rtl8214fc_set_port(struct phy_device *phydev, int port)
593 {
594 bool is_fibre = (port == PORT_FIBRE ? true : false);
595 int addr = phydev->mdio.addr;
596
597 pr_debug("%s port %d to %d\n", __func__, addr, port);
598
599 rtl8380_rtl8214fc_media_set(addr, is_fibre);
600 return 0;
601 }
602
603 static int rtl8214fc_get_port(struct phy_device *phydev)
604 {
605 int addr = phydev->mdio.addr;
606
607 pr_debug("%s: port %d\n", __func__, addr);
608 if (rtl8380_rtl8214fc_media_is_fibre(addr))
609 return PORT_FIBRE;
610 return PORT_MII;
611 }
612
613 static void rtl8218b_eee_set_u_boot(int port, bool enable)
614 {
615 u32 val;
616 bool an_enabled;
617
618 /* Set GPHY page to copper */
619 write_phy(port, 0, 30, 0x0001);
620 read_phy(port, 0, 0, &val);
621 an_enabled = val & (1 << 12);
622
623 if (enable) {
624 /* 100/1000M EEE Capability */
625 write_phy(port, 0, 13, 0x0007);
626 write_phy(port, 0, 14, 0x003C);
627 write_phy(port, 0, 13, 0x4007);
628 write_phy(port, 0, 14, 0x0006);
629
630 read_phy(port, 0x0A43, 25, &val);
631 val |= 1 << 4;
632 write_phy(port, 0x0A43, 25, val);
633 } else {
634 /* 100/1000M EEE Capability */
635 write_phy(port, 0, 13, 0x0007);
636 write_phy(port, 0, 14, 0x003C);
637 write_phy(port, 0, 13, 0x0007);
638 write_phy(port, 0, 14, 0x0000);
639
640 read_phy(port, 0x0A43, 25, &val);
641 val &= ~(1 << 4);
642 write_phy(port, 0x0A43, 25, val);
643 }
644
645 /* Restart AN if enabled */
646 if (an_enabled) {
647 read_phy(port, 0, 0, &val);
648 val |= (1 << 12) | (1 << 9);
649 write_phy(port, 0, 0, val);
650 }
651
652 /* GPHY page back to auto*/
653 write_phy(port, 0xa42, 29, 0);
654 }
655
656 // TODO: unused
657 static void rtl8380_rtl8218b_eee_set(int port, bool enable)
658 {
659 u32 val;
660 bool an_enabled;
661
662 pr_debug("In %s %d, enable %d\n", __func__, port, enable);
663 /* Set GPHY page to copper */
664 write_phy(port, 0xa42, 29, 0x0001);
665
666 read_phy(port, 0, 0, &val);
667 an_enabled = val & (1 << 12);
668
669 /* MAC based EEE */
670 read_phy(port, 0xa43, 25, &val);
671 val &= ~(1 << 5);
672 write_phy(port, 0xa43, 25, val);
673
674 /* 100M / 1000M EEE */
675 if (enable)
676 rtl838x_write_mmd_phy(port, 7, 60, 0x6);
677 else
678 rtl838x_write_mmd_phy(port, 7, 60, 0);
679
680 /* 500M EEE ability */
681 read_phy(port, 0xa42, 20, &val);
682 if (enable)
683 val |= 1 << 7;
684 else
685 val &= ~(1 << 7);
686 write_phy(port, 0xa42, 20, val);
687
688 /* Restart AN if enabled */
689 if (an_enabled) {
690 read_phy(port, 0, 0, &val);
691 val |= (1 << 12) | (1 << 9);
692 write_phy(port, 0, 0, val);
693 }
694
695 /* GPHY page back to auto*/
696 write_phy(port, 0xa42, 29, 0);
697 }
698
699 static int rtl8218b_get_eee(struct phy_device *phydev,
700 struct ethtool_eee *e)
701 {
702 u32 val;
703 int addr = phydev->mdio.addr;
704
705 pr_debug("In %s, port %d\n", __func__, addr);
706
707 /* Set GPHY page to copper */
708 write_phy(addr, 0xa42, 29, 0x0001);
709
710 rtl83xx_read_mmd_phy(addr, 7, 60, &val);
711 if (e->eee_enabled && (!!(val & (1 << 7))))
712 e->eee_enabled = !!(val & (1 << 7));
713 else
714 e->eee_enabled = 0;
715
716 /* GPHY page to auto */
717 write_phy(addr, 0xa42, 29, 0x0000);
718
719 return 0;
720 }
721
722 // TODO: unused
723 static void rtl8380_rtl8218b_green_set(int mac, bool enable)
724 {
725 u32 val;
726
727 /* Set GPHY page to copper */
728 write_phy(mac, 0xa42, 29, 0x0001);
729
730 write_phy(mac, 0, 27, 0x8011);
731 read_phy(mac, 0, 28, &val);
732 if (enable) {
733 val |= 1 << 9;
734 write_phy(mac, 0, 27, 0x8011);
735 write_phy(mac, 0, 28, val);
736 } else {
737 val &= ~(1 << 9);
738 write_phy(mac, 0, 27, 0x8011);
739 write_phy(mac, 0, 28, val);
740 }
741
742 /* GPHY page to auto */
743 write_phy(mac, 0xa42, 29, 0x0000);
744 }
745
746 // TODO: unused
747 static int rtl8380_rtl8214fc_get_green(struct phy_device *phydev, struct ethtool_eee *e)
748 {
749 u32 val;
750 int addr = phydev->mdio.addr;
751
752 pr_debug("In %s %d\n", __func__, addr);
753 /* Set GPHY page to copper */
754 write_phy(addr, 0xa42, 29, 0x0001);
755
756 write_phy(addr, 0, 27, 0x8011);
757 read_phy(addr, 0, 28, &val);
758 if (e->eee_enabled && (!!(val & (1 << 9))))
759 e->eee_enabled = !!(val & (1 << 9));
760 else
761 e->eee_enabled = 0;
762
763 /* GPHY page to auto */
764 write_phy(addr, 0xa42, 29, 0x0000);
765
766 return 0;
767 }
768
769 static int rtl8214fc_set_eee(struct phy_device *phydev,
770 struct ethtool_eee *e)
771 {
772 u32 pollMask;
773 int addr = phydev->mdio.addr;
774
775 pr_debug("In %s port %d, enabled %d\n", __func__, addr, e->eee_enabled);
776
777 if (rtl8380_rtl8214fc_media_is_fibre(addr)) {
778 netdev_err(phydev->attached_dev, "Port %d configured for FIBRE", addr);
779 return -ENOTSUPP;
780 }
781
782 pollMask = sw_r32(RTL838X_SMI_POLL_CTRL);
783 sw_w32(0, RTL838X_SMI_POLL_CTRL);
784 rtl8218b_eee_set_u_boot(addr, (bool) e->eee_enabled);
785 sw_w32(pollMask, RTL838X_SMI_POLL_CTRL);
786 return 0;
787 }
788
789 static int rtl8214fc_get_eee(struct phy_device *phydev,
790 struct ethtool_eee *e)
791 {
792 int addr = phydev->mdio.addr;
793
794 pr_debug("In %s port %d, enabled %d\n", __func__, addr, e->eee_enabled);
795 if (rtl8380_rtl8214fc_media_is_fibre(addr)) {
796 netdev_err(phydev->attached_dev, "Port %d configured for FIBRE", addr);
797 return -ENOTSUPP;
798 }
799
800 return rtl8218b_get_eee(phydev, e);
801 }
802
803 static int rtl8218b_set_eee(struct phy_device *phydev,
804 struct ethtool_eee *e)
805 {
806 u32 pollMask;
807 int addr = phydev->mdio.addr;
808
809 pr_debug("In %s, port %d, enabled %d\n", __func__, addr, e->eee_enabled);
810
811 pollMask = sw_r32(RTL838X_SMI_POLL_CTRL);
812 sw_w32(0, RTL838X_SMI_POLL_CTRL);
813 rtl8218b_eee_set_u_boot(addr, (bool) e->eee_enabled);
814 sw_w32(pollMask, RTL838X_SMI_POLL_CTRL);
815
816 return 0;
817 }
818
819 static int rtl8214c_match_phy_device(struct phy_device *phydev)
820 {
821 return phydev->phy_id == PHY_ID_RTL8214C;
822 }
823
824 static int rtl8380_configure_rtl8214c(struct phy_device *phydev)
825 {
826 u32 phy_id, val;
827 int mac = phydev->mdio.addr;
828
829 read_phy(mac, 0, 2, &val);
830 phy_id = val << 16;
831 read_phy(mac, 0, 3, &val);
832 phy_id |= val;
833 pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
834
835 phydev_info(phydev, "Detected external RTL8214C\n");
836
837 /* GPHY auto conf */
838 write_phy(mac, 0xa42, 29, 0);
839 return 0;
840 }
841
842 static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
843 {
844 u32 phy_id, val, page = 0;
845 int i, l;
846 int mac = phydev->mdio.addr;
847 struct fw_header *h;
848 u32 *rtl8380_rtl8214fc_perchip;
849 u32 *rtl8380_rtl8214fc_perport;
850
851 read_phy(mac, 0, 2, &val);
852 phy_id = val << 16;
853 read_phy(mac, 0, 3, &val);
854 phy_id |= val;
855 pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
856
857 /* Read internal PHY id */
858 write_phy(mac, 0, 30, 0x0001);
859 write_phy(mac, 0, 31, 0x0a42);
860 write_phy(mac, 31, 27, 0x0002);
861 read_phy(mac, 31, 28, &val);
862 if (val != 0x6276) {
863 phydev_err(phydev, "Expected external RTL8214FC, found PHY-ID %x\n", val);
864 return -1;
865 }
866 phydev_info(phydev, "Detected external RTL8214FC\n");
867
868 h = rtl838x_request_fw(phydev, &rtl838x_8214fc_fw, FIRMWARE_838X_8214FC_1);
869 if (!h)
870 return -1;
871
872 if (h->phy != 0x8214fc00) {
873 phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n");
874 return -1;
875 }
876
877 rtl8380_rtl8214fc_perchip = (void *)h + sizeof(struct fw_header)
878 + h->parts[0].start;
879
880 rtl8380_rtl8214fc_perport = (void *)h + sizeof(struct fw_header)
881 + h->parts[1].start;
882
883 /* detect phy version */
884 write_phy(mac, 0xfff, 27, 0x0004);
885 read_phy(mac, 0xfff, 28, &val);
886
887 read_phy(mac, 0, 16, &val);
888 if (val & (1 << 11))
889 rtl8214fc_on_off(mac, true);
890 else
891 phy_reset(mac);
892
893 msleep(100);
894 write_phy(mac, 0, 30, 0x0001);
895
896 i = 0;
897 while (rtl8380_rtl8214fc_perchip[i * 3]
898 && rtl8380_rtl8214fc_perchip[i * 3 + 1]) {
899 if (rtl8380_rtl8214fc_perchip[i * 3 + 1] == 0x1f)
900 page = rtl8380_rtl8214fc_perchip[i * 3 + 2];
901 if (rtl8380_rtl8214fc_perchip[i * 3 + 1] == 0x13 && page == 0x260) {
902 read_phy(mac + rtl8380_rtl8214fc_perchip[i * 3], 0x260, 13, &val);
903 val = (val & 0x1f00) | (rtl8380_rtl8214fc_perchip[i * 3 + 2]
904 & 0xe0ff);
905 write_phy(mac + rtl8380_rtl8214fc_perchip[i * 3],
906 0xfff, rtl8380_rtl8214fc_perchip[i * 3 + 1], val);
907 } else {
908 write_phy(mac + rtl8380_rtl8214fc_perchip[i * 3],
909 0xfff, rtl8380_rtl8214fc_perchip[i * 3 + 1],
910 rtl8380_rtl8214fc_perchip[i * 3 + 2]);
911 }
912 i++;
913 }
914
915 /* Force copper medium */
916 for (i = 0; i < 4; i++) {
917 write_phy(mac + i, 0xfff, 0x1f, 0x0000);
918 write_phy(mac + i, 0xfff, 0x1e, 0x0001);
919 }
920
921 /* Enable PHY */
922 for (i = 0; i < 4; i++) {
923 write_phy(mac + i, 0xfff, 0x1f, 0x0000);
924 write_phy(mac + i, 0xfff, 0x00, 0x1140);
925 }
926 mdelay(100);
927
928 /* Disable Autosensing */
929 for (i = 0; i < 4; i++) {
930 for (l = 0; l < 100; l++) {
931 read_phy(mac + i, 0x0a42, 0x10, &val);
932 if ((val & 0x7) >= 3)
933 break;
934 }
935 if (l >= 100) {
936 phydev_err(phydev, "Could not disable autosensing\n");
937 return -1;
938 }
939 }
940
941 /* Request patch */
942 for (i = 0; i < 4; i++) {
943 write_phy(mac + i, 0xfff, 0x1f, 0x0b82);
944 write_phy(mac + i, 0xfff, 0x10, 0x0010);
945 }
946 mdelay(300);
947
948 /* Verify patch readiness */
949 for (i = 0; i < 4; i++) {
950 for (l = 0; l < 100; l++) {
951 read_phy(mac + i, 0xb80, 0x10, &val);
952 if (val & 0x40)
953 break;
954 }
955 if (l >= 100) {
956 phydev_err(phydev, "Could not patch PHY\n");
957 return -1;
958 }
959 }
960
961 /* Use Broadcast ID method for patching */
962 write_phy(mac, 0xfff, 0x1f, 0x0000);
963 write_phy(mac, 0xfff, 0x1d, 0x0008);
964 write_phy(mac, 0xfff, 0x1f, 0x0266);
965 write_phy(mac, 0xfff, 0x16, 0xff00 + mac);
966 write_phy(mac, 0xfff, 0x1f, 0x0000);
967 write_phy(mac, 0xfff, 0x1d, 0x0000);
968 mdelay(1);
969
970 i = 0;
971 while (rtl8380_rtl8214fc_perport[i * 2]) {
972 write_phy(mac, 0xfff, rtl8380_rtl8214fc_perport[i * 2],
973 rtl8380_rtl8214fc_perport[i * 2 + 1]);
974 i++;
975 }
976
977 /*Disable broadcast ID*/
978 write_phy(mac, 0xfff, 0x1f, 0x0000);
979 write_phy(mac, 0xfff, 0x1d, 0x0008);
980 write_phy(mac, 0xfff, 0x1f, 0x0266);
981 write_phy(mac, 0xfff, 0x16, 0x00 + mac);
982 write_phy(mac, 0xfff, 0x1f, 0x0000);
983 write_phy(mac, 0xfff, 0x1d, 0x0000);
984 mdelay(1);
985
986 /* Auto medium selection */
987 for (i = 0; i < 4; i++) {
988 write_phy(mac + i, 0xfff, 0x1f, 0x0000);
989 write_phy(mac + i, 0xfff, 0x1e, 0x0000);
990 }
991
992 return 0;
993 }
994
995 static int rtl8214fc_match_phy_device(struct phy_device *phydev)
996 {
997 int addr = phydev->mdio.addr;
998
999 return phydev->phy_id == PHY_ID_RTL8214FC && addr >= 24;
1000 }
1001
1002 static int rtl8380_configure_serdes(struct phy_device *phydev)
1003 {
1004 u32 v;
1005 u32 sds_conf_value;
1006 int i;
1007 struct fw_header *h;
1008 u32 *rtl8380_sds_take_reset;
1009 u32 *rtl8380_sds_common;
1010 u32 *rtl8380_sds01_qsgmii_6275b;
1011 u32 *rtl8380_sds23_qsgmii_6275b;
1012 u32 *rtl8380_sds4_fiber_6275b;
1013 u32 *rtl8380_sds5_fiber_6275b;
1014 u32 *rtl8380_sds_reset;
1015 u32 *rtl8380_sds_release_reset;
1016
1017 phydev_info(phydev, "Detected internal RTL8380 SERDES\n");
1018
1019 h = rtl838x_request_fw(phydev, &rtl838x_8218b_fw, FIRMWARE_838X_8380_1);
1020 if (!h)
1021 return -1;
1022
1023 if (h->magic != 0x83808380) {
1024 phydev_err(phydev, "Wrong firmware file: magic number mismatch.\n");
1025 return -1;
1026 }
1027
1028 rtl8380_sds_take_reset = (void *)h + sizeof(struct fw_header)
1029 + h->parts[0].start;
1030
1031 rtl8380_sds_common = (void *)h + sizeof(struct fw_header)
1032 + h->parts[1].start;
1033
1034 rtl8380_sds01_qsgmii_6275b = (void *)h + sizeof(struct fw_header)
1035 + h->parts[2].start;
1036
1037 rtl8380_sds23_qsgmii_6275b = (void *)h + sizeof(struct fw_header)
1038 + h->parts[3].start;
1039
1040 rtl8380_sds4_fiber_6275b = (void *)h + sizeof(struct fw_header)
1041 + h->parts[4].start;
1042
1043 rtl8380_sds5_fiber_6275b = (void *)h + sizeof(struct fw_header)
1044 + h->parts[5].start;
1045
1046 rtl8380_sds_reset = (void *)h + sizeof(struct fw_header)
1047 + h->parts[6].start;
1048
1049 rtl8380_sds_release_reset = (void *)h + sizeof(struct fw_header)
1050 + h->parts[7].start;
1051
1052 /* Back up serdes power off value */
1053 sds_conf_value = sw_r32(RTL838X_SDS_CFG_REG);
1054 pr_info("SDS power down value: %x\n", sds_conf_value);
1055
1056 /* take serdes into reset */
1057 i = 0;
1058 while (rtl8380_sds_take_reset[2 * i]) {
1059 sw_w32(rtl8380_sds_take_reset[2 * i + 1], rtl8380_sds_take_reset[2 * i]);
1060 i++;
1061 udelay(1000);
1062 }
1063
1064 /* apply common serdes patch */
1065 i = 0;
1066 while (rtl8380_sds_common[2 * i]) {
1067 sw_w32(rtl8380_sds_common[2 * i + 1], rtl8380_sds_common[2 * i]);
1068 i++;
1069 udelay(1000);
1070 }
1071
1072 /* internal R/W enable */
1073 sw_w32(3, RTL838X_INT_RW_CTRL);
1074
1075 /* SerDes ports 4 and 5 are FIBRE ports */
1076 sw_w32_mask(0x7 | 0x38, 1 | (1 << 3), RTL838X_INT_MODE_CTRL);
1077
1078 /* SerDes module settings, SerDes 0-3 are QSGMII */
1079 v = 0x6 << 25 | 0x6 << 20 | 0x6 << 15 | 0x6 << 10;
1080 /* SerDes 4 and 5 are 1000BX FIBRE */
1081 v |= 0x4 << 5 | 0x4;
1082 sw_w32(v, RTL838X_SDS_MODE_SEL);
1083
1084 pr_info("PLL control register: %x\n", sw_r32(RTL838X_PLL_CML_CTRL));
1085 sw_w32_mask(0xfffffff0, 0xaaaaaaaf & 0xf, RTL838X_PLL_CML_CTRL);
1086 i = 0;
1087 while (rtl8380_sds01_qsgmii_6275b[2 * i]) {
1088 sw_w32(rtl8380_sds01_qsgmii_6275b[2 * i + 1],
1089 rtl8380_sds01_qsgmii_6275b[2 * i]);
1090 i++;
1091 }
1092
1093 i = 0;
1094 while (rtl8380_sds23_qsgmii_6275b[2 * i]) {
1095 sw_w32(rtl8380_sds23_qsgmii_6275b[2 * i + 1], rtl8380_sds23_qsgmii_6275b[2 * i]);
1096 i++;
1097 }
1098
1099 i = 0;
1100 while (rtl8380_sds4_fiber_6275b[2 * i]) {
1101 sw_w32(rtl8380_sds4_fiber_6275b[2 * i + 1], rtl8380_sds4_fiber_6275b[2 * i]);
1102 i++;
1103 }
1104
1105 i = 0;
1106 while (rtl8380_sds5_fiber_6275b[2 * i]) {
1107 sw_w32(rtl8380_sds5_fiber_6275b[2 * i + 1], rtl8380_sds5_fiber_6275b[2 * i]);
1108 i++;
1109 }
1110
1111 i = 0;
1112 while (rtl8380_sds_reset[2 * i]) {
1113 sw_w32(rtl8380_sds_reset[2 * i + 1], rtl8380_sds_reset[2 * i]);
1114 i++;
1115 }
1116
1117 i = 0;
1118 while (rtl8380_sds_release_reset[2 * i]) {
1119 sw_w32(rtl8380_sds_release_reset[2 * i + 1], rtl8380_sds_release_reset[2 * i]);
1120 i++;
1121 }
1122
1123 pr_info("SDS power down value now: %x\n", sw_r32(RTL838X_SDS_CFG_REG));
1124 sw_w32(sds_conf_value, RTL838X_SDS_CFG_REG);
1125
1126 pr_info("Configuration of SERDES done\n");
1127 return 0;
1128 }
1129
1130 static int rtl8390_configure_serdes(struct phy_device *phydev)
1131 {
1132 phydev_info(phydev, "Detected internal RTL8390 SERDES\n");
1133
1134 /* In autoneg state, force link, set SR4_CFG_EN_LINK_FIB1G */
1135 sw_w32_mask(0, 1 << 18, RTL839X_SDS12_13_XSG0 + 0x0a);
1136
1137 /* Disable EEE: Clear FRE16_EEE_RSG_FIB1G, FRE16_EEE_STD_FIB1G,
1138 * FRE16_C1_PWRSAV_EN_FIB1G, FRE16_C2_PWRSAV_EN_FIB1G
1139 * and FRE16_EEE_QUIET_FIB1G
1140 */
1141 sw_w32_mask(0x1f << 10, 0, RTL839X_SDS12_13_XSG0 + 0xe0);
1142
1143 return 0;
1144 }
1145
1146 static int rtl8214fc_phy_probe(struct phy_device *phydev)
1147 {
1148 struct device *dev = &phydev->mdio.dev;
1149 struct rtl838x_phy_priv *priv;
1150 int addr = phydev->mdio.addr;
1151
1152 /* 839x has internal SerDes */
1153 if (soc_info.id == 0x8393)
1154 return -ENODEV;
1155
1156 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1157 if (!priv)
1158 return -ENOMEM;
1159
1160 priv->name = "RTL8214FC";
1161
1162 /* All base addresses of the PHYs start at multiples of 8 */
1163 if (!(addr % 8)) {
1164 /* Configuration must be done whil patching still possible */
1165 return rtl8380_configure_rtl8214fc(phydev);
1166 }
1167 return 0;
1168 }
1169
1170 static int rtl8214c_phy_probe(struct phy_device *phydev)
1171 {
1172 struct device *dev = &phydev->mdio.dev;
1173 struct rtl838x_phy_priv *priv;
1174 int addr = phydev->mdio.addr;
1175
1176 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1177 if (!priv)
1178 return -ENOMEM;
1179
1180 priv->name = "RTL8214C";
1181
1182 /* All base addresses of the PHYs start at multiples of 8 */
1183 if (!(addr % 8)) {
1184 /* Configuration must be done whil patching still possible */
1185 return rtl8380_configure_rtl8214c(phydev);
1186 }
1187 return 0;
1188 }
1189
1190 static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
1191 {
1192 struct device *dev = &phydev->mdio.dev;
1193 struct rtl838x_phy_priv *priv;
1194 int addr = phydev->mdio.addr;
1195
1196 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1197 if (!priv)
1198 return -ENOMEM;
1199
1200 priv->name = "RTL8218B (external)";
1201
1202 /* All base addresses of the PHYs start at multiples of 8 */
1203 if (!(addr % 8) && soc_info.family == RTL8380_FAMILY_ID) {
1204 /* Configuration must be done while patching still possible */
1205 return rtl8380_configure_ext_rtl8218b(phydev);
1206 }
1207 return 0;
1208 }
1209
1210 static int rtl8218b_int_phy_probe(struct phy_device *phydev)
1211 {
1212 struct device *dev = &phydev->mdio.dev;
1213 struct rtl838x_phy_priv *priv;
1214 int addr = phydev->mdio.addr;
1215
1216 if (soc_info.family != RTL8380_FAMILY_ID)
1217 return -ENODEV;
1218 if (addr >= 24)
1219 return -ENODEV;
1220
1221 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1222 if (!priv)
1223 return -ENOMEM;
1224
1225 priv->name = "RTL8218B (internal)";
1226
1227 /* All base addresses of the PHYs start at multiples of 8 */
1228 if (!(addr % 8)) {
1229 /* Configuration must be done while patching still possible */
1230 return rtl8380_configure_int_rtl8218b(phydev);
1231 }
1232 return 0;
1233 }
1234
1235 static int rtl838x_serdes_probe(struct phy_device *phydev)
1236 {
1237 struct device *dev = &phydev->mdio.dev;
1238 struct rtl838x_phy_priv *priv;
1239 int addr = phydev->mdio.addr;
1240
1241 if (soc_info.family != RTL8380_FAMILY_ID)
1242 return -ENODEV;
1243 if (addr < 24)
1244 return -ENODEV;
1245
1246 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1247 if (!priv)
1248 return -ENOMEM;
1249
1250 priv->name = "RTL8380 Serdes";
1251
1252 /* On the RTL8380M, PHYs 24-27 connect to the internal SerDes */
1253 if (soc_info.id == 0x8380) {
1254 if (addr == 24)
1255 return rtl8380_configure_serdes(phydev);
1256 return 0;
1257 }
1258 return -ENODEV;
1259 }
1260
1261 static int rtl8393_serdes_probe(struct phy_device *phydev)
1262 {
1263 struct device *dev = &phydev->mdio.dev;
1264 struct rtl838x_phy_priv *priv;
1265 int addr = phydev->mdio.addr;
1266
1267 pr_info("%s: id: %d\n", __func__, addr);
1268 if (soc_info.family != RTL8390_FAMILY_ID)
1269 return -ENODEV;
1270
1271 if (addr < 24)
1272 return -ENODEV;
1273
1274 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1275 if (!priv)
1276 return -ENOMEM;
1277
1278 priv->name = "RTL8393 Serdes";
1279 return rtl8390_configure_serdes(phydev);
1280 }
1281
1282 static int rtl8390_serdes_probe(struct phy_device *phydev)
1283 {
1284 struct device *dev = &phydev->mdio.dev;
1285 struct rtl838x_phy_priv *priv;
1286 int addr = phydev->mdio.addr;
1287
1288 if (soc_info.family != RTL8390_FAMILY_ID)
1289 return -ENODEV;
1290
1291 if (addr < 24)
1292 return -ENODEV;
1293
1294 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1295 if (!priv)
1296 return -ENOMEM;
1297
1298 priv->name = "RTL8390 Serdes";
1299 return rtl8390_configure_generic(phydev);
1300 }
1301
1302 static struct phy_driver rtl83xx_phy_driver[] = {
1303 {
1304 PHY_ID_MATCH_MODEL(PHY_ID_RTL8214C),
1305 .name = "Realtek RTL8214C",
1306 .features = PHY_GBIT_FEATURES,
1307 .match_phy_device = rtl8214c_match_phy_device,
1308 .probe = rtl8214c_phy_probe,
1309 .suspend = genphy_suspend,
1310 .resume = genphy_resume,
1311 .set_loopback = genphy_loopback,
1312 },
1313 {
1314 PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC),
1315 .name = "Realtek RTL8214FC",
1316 .features = PHY_GBIT_FIBRE_FEATURES,
1317 .match_phy_device = rtl8214fc_match_phy_device,
1318 .probe = rtl8214fc_phy_probe,
1319 .suspend = genphy_suspend,
1320 .resume = genphy_resume,
1321 .set_loopback = genphy_loopback,
1322 .read_mmd = rtl8218b_read_mmd,
1323 .write_mmd = rtl8218b_write_mmd,
1324 .set_port = rtl8214fc_set_port,
1325 .get_port = rtl8214fc_get_port,
1326 .set_eee = rtl8214fc_set_eee,
1327 .get_eee = rtl8214fc_get_eee,
1328 },
1329 {
1330 PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_E),
1331 .name = "Realtek RTL8218B (external)",
1332 .features = PHY_GBIT_FEATURES,
1333 .match_phy_device = rtl8218b_ext_match_phy_device,
1334 .probe = rtl8218b_ext_phy_probe,
1335 .suspend = genphy_suspend,
1336 .resume = genphy_resume,
1337 .set_loopback = genphy_loopback,
1338 .read_mmd = rtl8218b_read_mmd,
1339 .write_mmd = rtl8218b_write_mmd,
1340 .set_eee = rtl8218b_set_eee,
1341 .get_eee = rtl8218b_get_eee,
1342 },
1343 {
1344 PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I),
1345 .name = "Realtek RTL8218B (internal)",
1346 .features = PHY_GBIT_FEATURES,
1347 .probe = rtl8218b_int_phy_probe,
1348 .suspend = genphy_suspend,
1349 .resume = genphy_resume,
1350 .set_loopback = genphy_loopback,
1351 .read_mmd = rtl8218b_read_mmd,
1352 .write_mmd = rtl8218b_write_mmd,
1353 .set_eee = rtl8218b_set_eee,
1354 .get_eee = rtl8218b_get_eee,
1355 },
1356 {
1357 PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I),
1358 .name = "Realtek RTL8380 SERDES",
1359 .features = PHY_GBIT_FIBRE_FEATURES,
1360 .probe = rtl838x_serdes_probe,
1361 .suspend = genphy_suspend,
1362 .resume = genphy_resume,
1363 .set_loopback = genphy_loopback,
1364 .read_mmd = rtl8218b_read_mmd,
1365 .write_mmd = rtl8218b_write_mmd,
1366 .read_status = rtl8380_read_status,
1367 },
1368 {
1369 PHY_ID_MATCH_MODEL(PHY_ID_RTL8393_I),
1370 .name = "Realtek RTL8393 SERDES",
1371 .features = PHY_GBIT_FIBRE_FEATURES,
1372 .probe = rtl8393_serdes_probe,
1373 .suspend = genphy_suspend,
1374 .resume = genphy_resume,
1375 .set_loopback = genphy_loopback,
1376 .read_status = rtl8393_read_status,
1377 },
1378 {
1379 PHY_ID_MATCH_MODEL(PHY_ID_RTL8390_GENERIC),
1380 .name = "Realtek RTL8390 Generic",
1381 .features = PHY_GBIT_FIBRE_FEATURES,
1382 .probe = rtl8390_serdes_probe,
1383 .suspend = genphy_suspend,
1384 .resume = genphy_resume,
1385 .set_loopback = genphy_loopback,
1386 }
1387 };
1388
1389 module_phy_driver(rtl83xx_phy_driver);
1390
1391 static struct mdio_device_id __maybe_unused rtl83xx_tbl[] = {
1392 { PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC) },
1393 { }
1394 };
1395
1396 MODULE_DEVICE_TABLE(mdio, rtl83xx_tbl);
1397
1398 MODULE_AUTHOR("B. Koblitz");
1399 MODULE_DESCRIPTION("RTL83xx PHY driver");
1400 MODULE_LICENSE("GPL");