1
2
3
4
5
6
7
8
9
10
11#include <linux/bitops.h>
12#include <linux/phy.h>
13#include <linux/module.h>
14#include <linux/delay.h>
15
16#define RTL821x_PHYSR 0x11
17#define RTL821x_PHYSR_DUPLEX BIT(13)
18#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
19
20#define RTL821x_INER 0x12
21#define RTL8211B_INER_INIT 0x6400
22#define RTL8211E_INER_LINK_STATUS BIT(10)
23#define RTL8211F_INER_LINK_STATUS BIT(4)
24
25#define RTL821x_INSR 0x13
26
27#define RTL821x_EXT_PAGE_SELECT 0x1e
28#define RTL821x_PAGE_SELECT 0x1f
29
30#define RTL8211F_INSR 0x1d
31
32#define RTL8211F_TX_DELAY BIT(8)
33#define RTL8211F_RX_DELAY BIT(3)
34
35#define RTL8211E_TX_DELAY BIT(1)
36#define RTL8211E_RX_DELAY BIT(2)
37#define RTL8211E_MODE_MII_GMII BIT(3)
38
39#define RTL8201F_ISR 0x1e
40#define RTL8201F_IER 0x13
41
42#define RTL8366RB_POWER_SAVE 0x15
43#define RTL8366RB_POWER_SAVE_ON BIT(12)
44
45#define RTL_SUPPORTS_5000FULL BIT(14)
46#define RTL_SUPPORTS_2500FULL BIT(13)
47#define RTL_SUPPORTS_10000FULL BIT(0)
48#define RTL_ADV_2500FULL BIT(7)
49#define RTL_LPADV_10000FULL BIT(11)
50#define RTL_LPADV_5000FULL BIT(6)
51#define RTL_LPADV_2500FULL BIT(5)
52
53#define RTLGEN_SPEED_MASK 0x0630
54
55#define RTL_GENERIC_PHYID 0x001cc800
56
57MODULE_DESCRIPTION("Realtek PHY driver");
58MODULE_AUTHOR("Johnson Leung");
59MODULE_LICENSE("GPL");
60
61static int rtl821x_read_page(struct phy_device *phydev)
62{
63 return __phy_read(phydev, RTL821x_PAGE_SELECT);
64}
65
66static int rtl821x_write_page(struct phy_device *phydev, int page)
67{
68 return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
69}
70
71static int rtl8201_ack_interrupt(struct phy_device *phydev)
72{
73 int err;
74
75 err = phy_read(phydev, RTL8201F_ISR);
76
77 return (err < 0) ? err : 0;
78}
79
80static int rtl821x_ack_interrupt(struct phy_device *phydev)
81{
82 int err;
83
84 err = phy_read(phydev, RTL821x_INSR);
85
86 return (err < 0) ? err : 0;
87}
88
89static int rtl8211f_ack_interrupt(struct phy_device *phydev)
90{
91 int err;
92
93 err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
94
95 return (err < 0) ? err : 0;
96}
97
98static int rtl8201_config_intr(struct phy_device *phydev)
99{
100 u16 val;
101
102 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
103 val = BIT(13) | BIT(12) | BIT(11);
104 else
105 val = 0;
106
107 return phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
108}
109
110static int rtl8211b_config_intr(struct phy_device *phydev)
111{
112 int err;
113
114 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
115 err = phy_write(phydev, RTL821x_INER,
116 RTL8211B_INER_INIT);
117 else
118 err = phy_write(phydev, RTL821x_INER, 0);
119
120 return err;
121}
122
123static int rtl8211e_config_intr(struct phy_device *phydev)
124{
125 int err;
126
127 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
128 err = phy_write(phydev, RTL821x_INER,
129 RTL8211E_INER_LINK_STATUS);
130 else
131 err = phy_write(phydev, RTL821x_INER, 0);
132
133 return err;
134}
135
136static int rtl8211f_config_intr(struct phy_device *phydev)
137{
138 u16 val;
139
140 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
141 val = RTL8211F_INER_LINK_STATUS;
142 else
143 val = 0;
144
145 return phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
146}
147
148static int rtl8211_config_aneg(struct phy_device *phydev)
149{
150 int ret;
151
152 ret = genphy_config_aneg(phydev);
153 if (ret < 0)
154 return ret;
155
156
157
158
159 if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) {
160 phy_write(phydev, 0x17, 0x2138);
161 phy_write(phydev, 0x0e, 0x0260);
162 } else {
163 phy_write(phydev, 0x17, 0x2108);
164 phy_write(phydev, 0x0e, 0x0000);
165 }
166
167 return 0;
168}
169
170static int rtl8211c_config_init(struct phy_device *phydev)
171{
172
173 return phy_set_bits(phydev, MII_CTRL1000,
174 CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
175}
176
177static int rtl8211f_config_init(struct phy_device *phydev)
178{
179 struct device *dev = &phydev->mdio.dev;
180 u16 val_txdly, val_rxdly;
181 int ret;
182
183 switch (phydev->interface) {
184 case PHY_INTERFACE_MODE_RGMII:
185 val_txdly = 0;
186 val_rxdly = 0;
187 break;
188
189 case PHY_INTERFACE_MODE_RGMII_RXID:
190 val_txdly = 0;
191 val_rxdly = RTL8211F_RX_DELAY;
192 break;
193
194 case PHY_INTERFACE_MODE_RGMII_TXID:
195 val_txdly = RTL8211F_TX_DELAY;
196 val_rxdly = 0;
197 break;
198
199 case PHY_INTERFACE_MODE_RGMII_ID:
200 val_txdly = RTL8211F_TX_DELAY;
201 val_rxdly = RTL8211F_RX_DELAY;
202 break;
203
204 default:
205 return 0;
206 }
207
208 ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
209 val_txdly);
210 if (ret < 0) {
211 dev_err(dev, "Failed to update the TX delay register\n");
212 return ret;
213 } else if (ret) {
214 dev_dbg(dev,
215 "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
216 val_txdly ? "Enabling" : "Disabling");
217 } else {
218 dev_dbg(dev,
219 "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
220 val_txdly ? "enabled" : "disabled");
221 }
222
223 ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY,
224 val_rxdly);
225 if (ret < 0) {
226 dev_err(dev, "Failed to update the RX delay register\n");
227 return ret;
228 } else if (ret) {
229 dev_dbg(dev,
230 "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
231 val_rxdly ? "Enabling" : "Disabling");
232 } else {
233 dev_dbg(dev,
234 "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
235 val_rxdly ? "enabled" : "disabled");
236 }
237
238 return 0;
239}
240
241static int rtl8211e_config_init(struct phy_device *phydev)
242{
243 int ret = 0, oldpage;
244 u16 val;
245
246
247 switch (phydev->interface) {
248 case PHY_INTERFACE_MODE_RGMII:
249 val = 0;
250 break;
251 case PHY_INTERFACE_MODE_RGMII_ID:
252 val = RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
253 break;
254 case PHY_INTERFACE_MODE_RGMII_RXID:
255 val = RTL8211E_RX_DELAY;
256 break;
257 case PHY_INTERFACE_MODE_RGMII_TXID:
258 val = RTL8211E_TX_DELAY;
259 break;
260 default:
261 return 0;
262 }
263
264
265
266
267
268
269
270
271
272 oldpage = phy_select_page(phydev, 0x7);
273 if (oldpage < 0)
274 goto err_restore_page;
275
276 ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4);
277 if (ret)
278 goto err_restore_page;
279
280 ret = __phy_modify(phydev, 0x1c, RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
281 val);
282
283err_restore_page:
284 return phy_restore_page(phydev, oldpage, ret);
285}
286
287static int rtl8211b_suspend(struct phy_device *phydev)
288{
289 phy_write(phydev, MII_MMD_DATA, BIT(9));
290
291 return genphy_suspend(phydev);
292}
293
294static int rtl8211b_resume(struct phy_device *phydev)
295{
296 phy_write(phydev, MII_MMD_DATA, 0);
297
298 return genphy_resume(phydev);
299}
300
301static int rtl8366rb_config_init(struct phy_device *phydev)
302{
303 int ret;
304
305 ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
306 RTL8366RB_POWER_SAVE_ON);
307 if (ret) {
308 dev_err(&phydev->mdio.dev,
309 "error enabling power management\n");
310 }
311
312 return ret;
313}
314
315
316static int rtlgen_get_speed(struct phy_device *phydev)
317{
318 int val;
319
320 if (!phydev->link)
321 return 0;
322
323 val = phy_read_paged(phydev, 0xa43, 0x12);
324 if (val < 0)
325 return val;
326
327 switch (val & RTLGEN_SPEED_MASK) {
328 case 0x0000:
329 phydev->speed = SPEED_10;
330 break;
331 case 0x0010:
332 phydev->speed = SPEED_100;
333 break;
334 case 0x0020:
335 phydev->speed = SPEED_1000;
336 break;
337 case 0x0200:
338 phydev->speed = SPEED_10000;
339 break;
340 case 0x0210:
341 phydev->speed = SPEED_2500;
342 break;
343 case 0x0220:
344 phydev->speed = SPEED_5000;
345 break;
346 default:
347 break;
348 }
349
350 return 0;
351}
352
353static int rtlgen_read_status(struct phy_device *phydev)
354{
355 int ret;
356
357 ret = genphy_read_status(phydev);
358 if (ret < 0)
359 return ret;
360
361 return rtlgen_get_speed(phydev);
362}
363
364static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
365{
366 int ret;
367
368 if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
369 rtl821x_write_page(phydev, 0xa5c);
370 ret = __phy_read(phydev, 0x12);
371 rtl821x_write_page(phydev, 0);
372 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
373 rtl821x_write_page(phydev, 0xa5d);
374 ret = __phy_read(phydev, 0x10);
375 rtl821x_write_page(phydev, 0);
376 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) {
377 rtl821x_write_page(phydev, 0xa5d);
378 ret = __phy_read(phydev, 0x11);
379 rtl821x_write_page(phydev, 0);
380 } else {
381 ret = -EOPNOTSUPP;
382 }
383
384 return ret;
385}
386
387static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
388 u16 val)
389{
390 int ret;
391
392 if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
393 rtl821x_write_page(phydev, 0xa5d);
394 ret = __phy_write(phydev, 0x10, val);
395 rtl821x_write_page(phydev, 0);
396 } else {
397 ret = -EOPNOTSUPP;
398 }
399
400 return ret;
401}
402
403static int rtl8125_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
404{
405 int ret = rtlgen_read_mmd(phydev, devnum, regnum);
406
407 if (ret != -EOPNOTSUPP)
408 return ret;
409
410 if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) {
411 rtl821x_write_page(phydev, 0xa6e);
412 ret = __phy_read(phydev, 0x16);
413 rtl821x_write_page(phydev, 0);
414 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
415 rtl821x_write_page(phydev, 0xa6d);
416 ret = __phy_read(phydev, 0x12);
417 rtl821x_write_page(phydev, 0);
418 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) {
419 rtl821x_write_page(phydev, 0xa6d);
420 ret = __phy_read(phydev, 0x10);
421 rtl821x_write_page(phydev, 0);
422 }
423
424 return ret;
425}
426
427static int rtl8125_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
428 u16 val)
429{
430 int ret = rtlgen_write_mmd(phydev, devnum, regnum, val);
431
432 if (ret != -EOPNOTSUPP)
433 return ret;
434
435 if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
436 rtl821x_write_page(phydev, 0xa6d);
437 ret = __phy_write(phydev, 0x12, val);
438 rtl821x_write_page(phydev, 0);
439 }
440
441 return ret;
442}
443
444static int rtl8125_get_features(struct phy_device *phydev)
445{
446 int val;
447
448 val = phy_read_paged(phydev, 0xa61, 0x13);
449 if (val < 0)
450 return val;
451
452 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
453 phydev->supported, val & RTL_SUPPORTS_2500FULL);
454 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
455 phydev->supported, val & RTL_SUPPORTS_5000FULL);
456 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
457 phydev->supported, val & RTL_SUPPORTS_10000FULL);
458
459 return genphy_read_abilities(phydev);
460}
461
462static int rtl8125_config_aneg(struct phy_device *phydev)
463{
464 int ret = 0;
465
466 if (phydev->autoneg == AUTONEG_ENABLE) {
467 u16 adv2500 = 0;
468
469 if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
470 phydev->advertising))
471 adv2500 = RTL_ADV_2500FULL;
472
473 ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
474 RTL_ADV_2500FULL, adv2500);
475 if (ret < 0)
476 return ret;
477 }
478
479 return __genphy_config_aneg(phydev, ret);
480}
481
482static int rtl8125_read_status(struct phy_device *phydev)
483{
484 int ret;
485
486 if (phydev->autoneg == AUTONEG_ENABLE) {
487 int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
488
489 if (lpadv < 0)
490 return lpadv;
491
492 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
493 phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
494 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
495 phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
496 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
497 phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
498 }
499
500 ret = genphy_read_status(phydev);
501 if (ret < 0)
502 return ret;
503
504 return rtlgen_get_speed(phydev);
505}
506
507static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
508{
509 int val;
510
511 phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
512 val = phy_read(phydev, 0x13);
513 phy_write(phydev, RTL821x_PAGE_SELECT, 0);
514
515 return val >= 0 && val & RTL_SUPPORTS_2500FULL;
516}
517
518static int rtlgen_match_phy_device(struct phy_device *phydev)
519{
520 return phydev->phy_id == RTL_GENERIC_PHYID &&
521 !rtlgen_supports_2_5gbps(phydev);
522}
523
524static int rtl8125_match_phy_device(struct phy_device *phydev)
525{
526 return phydev->phy_id == RTL_GENERIC_PHYID &&
527 rtlgen_supports_2_5gbps(phydev);
528}
529
530static int rtlgen_resume(struct phy_device *phydev)
531{
532 int ret = genphy_resume(phydev);
533
534
535 msleep(20);
536
537 return ret;
538}
539
540static struct phy_driver realtek_drvs[] = {
541 {
542 PHY_ID_MATCH_EXACT(0x00008201),
543 .name = "RTL8201CP Ethernet",
544 }, {
545 PHY_ID_MATCH_EXACT(0x001cc816),
546 .name = "RTL8201F Fast Ethernet",
547 .ack_interrupt = &rtl8201_ack_interrupt,
548 .config_intr = &rtl8201_config_intr,
549 .suspend = genphy_suspend,
550 .resume = genphy_resume,
551 .read_page = rtl821x_read_page,
552 .write_page = rtl821x_write_page,
553 }, {
554 PHY_ID_MATCH_MODEL(0x001cc880),
555 .name = "RTL8208 Fast Ethernet",
556 .read_mmd = genphy_read_mmd_unsupported,
557 .write_mmd = genphy_write_mmd_unsupported,
558 .suspend = genphy_suspend,
559 .resume = genphy_resume,
560 .read_page = rtl821x_read_page,
561 .write_page = rtl821x_write_page,
562 }, {
563 PHY_ID_MATCH_EXACT(0x001cc910),
564 .name = "RTL8211 Gigabit Ethernet",
565 .config_aneg = rtl8211_config_aneg,
566 .read_mmd = &genphy_read_mmd_unsupported,
567 .write_mmd = &genphy_write_mmd_unsupported,
568 .read_page = rtl821x_read_page,
569 .write_page = rtl821x_write_page,
570 }, {
571 PHY_ID_MATCH_EXACT(0x001cc912),
572 .name = "RTL8211B Gigabit Ethernet",
573 .ack_interrupt = &rtl821x_ack_interrupt,
574 .config_intr = &rtl8211b_config_intr,
575 .read_mmd = &genphy_read_mmd_unsupported,
576 .write_mmd = &genphy_write_mmd_unsupported,
577 .suspend = rtl8211b_suspend,
578 .resume = rtl8211b_resume,
579 .read_page = rtl821x_read_page,
580 .write_page = rtl821x_write_page,
581 }, {
582 PHY_ID_MATCH_EXACT(0x001cc913),
583 .name = "RTL8211C Gigabit Ethernet",
584 .config_init = rtl8211c_config_init,
585 .read_mmd = &genphy_read_mmd_unsupported,
586 .write_mmd = &genphy_write_mmd_unsupported,
587 .read_page = rtl821x_read_page,
588 .write_page = rtl821x_write_page,
589 }, {
590 PHY_ID_MATCH_EXACT(0x001cc914),
591 .name = "RTL8211DN Gigabit Ethernet",
592 .ack_interrupt = rtl821x_ack_interrupt,
593 .config_intr = rtl8211e_config_intr,
594 .suspend = genphy_suspend,
595 .resume = genphy_resume,
596 .read_page = rtl821x_read_page,
597 .write_page = rtl821x_write_page,
598 }, {
599 PHY_ID_MATCH_EXACT(0x001cc915),
600 .name = "RTL8211E Gigabit Ethernet",
601 .config_init = &rtl8211e_config_init,
602 .ack_interrupt = &rtl821x_ack_interrupt,
603 .config_intr = &rtl8211e_config_intr,
604 .suspend = genphy_suspend,
605 .resume = genphy_resume,
606 .read_page = rtl821x_read_page,
607 .write_page = rtl821x_write_page,
608 }, {
609 PHY_ID_MATCH_EXACT(0x001cc916),
610 .name = "RTL8211F Gigabit Ethernet",
611 .config_init = &rtl8211f_config_init,
612 .ack_interrupt = &rtl8211f_ack_interrupt,
613 .config_intr = &rtl8211f_config_intr,
614 .suspend = genphy_suspend,
615 .resume = genphy_resume,
616 .read_page = rtl821x_read_page,
617 .write_page = rtl821x_write_page,
618 }, {
619 .name = "Generic FE-GE Realtek PHY",
620 .match_phy_device = rtlgen_match_phy_device,
621 .read_status = rtlgen_read_status,
622 .suspend = genphy_suspend,
623 .resume = rtlgen_resume,
624 .read_page = rtl821x_read_page,
625 .write_page = rtl821x_write_page,
626 .read_mmd = rtlgen_read_mmd,
627 .write_mmd = rtlgen_write_mmd,
628 }, {
629 .name = "RTL8125 2.5Gbps internal",
630 .match_phy_device = rtl8125_match_phy_device,
631 .get_features = rtl8125_get_features,
632 .config_aneg = rtl8125_config_aneg,
633 .read_status = rtl8125_read_status,
634 .suspend = genphy_suspend,
635 .resume = rtlgen_resume,
636 .read_page = rtl821x_read_page,
637 .write_page = rtl821x_write_page,
638 .read_mmd = rtl8125_read_mmd,
639 .write_mmd = rtl8125_write_mmd,
640 }, {
641 PHY_ID_MATCH_EXACT(0x001cc961),
642 .name = "RTL8366RB Gigabit Ethernet",
643 .config_init = &rtl8366rb_config_init,
644
645
646
647
648
649 .ack_interrupt = genphy_no_ack_interrupt,
650 .config_intr = genphy_no_config_intr,
651 .suspend = genphy_suspend,
652 .resume = genphy_resume,
653 },
654};
655
656module_phy_driver(realtek_drvs);
657
658static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
659 { PHY_ID_MATCH_VENDOR(0x001cc800) },
660 { }
661};
662
663MODULE_DEVICE_TABLE(mdio, realtek_tbl);
664