1
2
3
4
5
6
7
8
9
10#include <linux/bitops.h>
11#include <linux/phy.h>
12#include <linux/module.h>
13#include <linux/delay.h>
14
15#define RTL821x_PHYSR 0x11
16#define RTL821x_PHYSR_DUPLEX BIT(13)
17#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
18
19#define RTL821x_INER 0x12
20#define RTL8211B_INER_INIT 0x6400
21#define RTL8211E_INER_LINK_STATUS BIT(10)
22#define RTL8211F_INER_LINK_STATUS BIT(4)
23
24#define RTL821x_INSR 0x13
25
26#define RTL821x_EXT_PAGE_SELECT 0x1e
27#define RTL821x_PAGE_SELECT 0x1f
28
29#define RTL8211F_PHYCR1 0x18
30#define RTL8211F_INSR 0x1d
31
32#define RTL8211F_TX_DELAY BIT(8)
33#define RTL8211F_RX_DELAY BIT(3)
34
35#define RTL8211F_ALDPS_PLL_OFF BIT(1)
36#define RTL8211F_ALDPS_ENABLE BIT(2)
37#define RTL8211F_ALDPS_XTAL_OFF BIT(12)
38
39#define RTL8211E_CTRL_DELAY BIT(13)
40#define RTL8211E_TX_DELAY BIT(12)
41#define RTL8211E_RX_DELAY BIT(11)
42
43#define RTL8201F_ISR 0x1e
44#define RTL8201F_ISR_ANERR BIT(15)
45#define RTL8201F_ISR_DUPLEX BIT(13)
46#define RTL8201F_ISR_LINK BIT(11)
47#define RTL8201F_ISR_MASK (RTL8201F_ISR_ANERR | \
48 RTL8201F_ISR_DUPLEX | \
49 RTL8201F_ISR_LINK)
50#define RTL8201F_IER 0x13
51
52#define RTL8366RB_POWER_SAVE 0x15
53#define RTL8366RB_POWER_SAVE_ON BIT(12)
54
55#define RTL_SUPPORTS_5000FULL BIT(14)
56#define RTL_SUPPORTS_2500FULL BIT(13)
57#define RTL_SUPPORTS_10000FULL BIT(0)
58#define RTL_ADV_2500FULL BIT(7)
59#define RTL_LPADV_10000FULL BIT(11)
60#define RTL_LPADV_5000FULL BIT(6)
61#define RTL_LPADV_2500FULL BIT(5)
62
63#define RTL9000A_GINMR 0x14
64#define RTL9000A_GINMR_LINK_STATUS BIT(4)
65
66#define RTLGEN_SPEED_MASK 0x0630
67
68#define RTL_GENERIC_PHYID 0x001cc800
69
70MODULE_DESCRIPTION("Realtek PHY driver");
71MODULE_AUTHOR("Johnson Leung");
72MODULE_LICENSE("GPL");
73
74static int rtl821x_read_page(struct phy_device *phydev)
75{
76 return __phy_read(phydev, RTL821x_PAGE_SELECT);
77}
78
79static int rtl821x_write_page(struct phy_device *phydev, int page)
80{
81 return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
82}
83
84static int rtl8201_ack_interrupt(struct phy_device *phydev)
85{
86 int err;
87
88 err = phy_read(phydev, RTL8201F_ISR);
89
90 return (err < 0) ? err : 0;
91}
92
93static int rtl821x_ack_interrupt(struct phy_device *phydev)
94{
95 int err;
96
97 err = phy_read(phydev, RTL821x_INSR);
98
99 return (err < 0) ? err : 0;
100}
101
102static int rtl8211f_ack_interrupt(struct phy_device *phydev)
103{
104 int err;
105
106 err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
107
108 return (err < 0) ? err : 0;
109}
110
111static int rtl8201_config_intr(struct phy_device *phydev)
112{
113 u16 val;
114 int err;
115
116 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
117 err = rtl8201_ack_interrupt(phydev);
118 if (err)
119 return err;
120
121 val = BIT(13) | BIT(12) | BIT(11);
122 err = phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
123 } else {
124 val = 0;
125 err = phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
126 if (err)
127 return err;
128
129 err = rtl8201_ack_interrupt(phydev);
130 }
131
132 return err;
133}
134
135static int rtl8211b_config_intr(struct phy_device *phydev)
136{
137 int err;
138
139 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
140 err = rtl821x_ack_interrupt(phydev);
141 if (err)
142 return err;
143
144 err = phy_write(phydev, RTL821x_INER,
145 RTL8211B_INER_INIT);
146 } else {
147 err = phy_write(phydev, RTL821x_INER, 0);
148 if (err)
149 return err;
150
151 err = rtl821x_ack_interrupt(phydev);
152 }
153
154 return err;
155}
156
157static int rtl8211e_config_intr(struct phy_device *phydev)
158{
159 int err;
160
161 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
162 err = rtl821x_ack_interrupt(phydev);
163 if (err)
164 return err;
165
166 err = phy_write(phydev, RTL821x_INER,
167 RTL8211E_INER_LINK_STATUS);
168 } else {
169 err = phy_write(phydev, RTL821x_INER, 0);
170 if (err)
171 return err;
172
173 err = rtl821x_ack_interrupt(phydev);
174 }
175
176 return err;
177}
178
179static int rtl8211f_config_intr(struct phy_device *phydev)
180{
181 u16 val;
182 int err;
183
184 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
185 err = rtl8211f_ack_interrupt(phydev);
186 if (err)
187 return err;
188
189 val = RTL8211F_INER_LINK_STATUS;
190 err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
191 } else {
192 val = 0;
193 err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
194 if (err)
195 return err;
196
197 err = rtl8211f_ack_interrupt(phydev);
198 }
199
200 return err;
201}
202
203static irqreturn_t rtl8201_handle_interrupt(struct phy_device *phydev)
204{
205 int irq_status;
206
207 irq_status = phy_read(phydev, RTL8201F_ISR);
208 if (irq_status < 0) {
209 phy_error(phydev);
210 return IRQ_NONE;
211 }
212
213 if (!(irq_status & RTL8201F_ISR_MASK))
214 return IRQ_NONE;
215
216 phy_trigger_machine(phydev);
217
218 return IRQ_HANDLED;
219}
220
221static irqreturn_t rtl821x_handle_interrupt(struct phy_device *phydev)
222{
223 int irq_status, irq_enabled;
224
225 irq_status = phy_read(phydev, RTL821x_INSR);
226 if (irq_status < 0) {
227 phy_error(phydev);
228 return IRQ_NONE;
229 }
230
231 irq_enabled = phy_read(phydev, RTL821x_INER);
232 if (irq_enabled < 0) {
233 phy_error(phydev);
234 return IRQ_NONE;
235 }
236
237 if (!(irq_status & irq_enabled))
238 return IRQ_NONE;
239
240 phy_trigger_machine(phydev);
241
242 return IRQ_HANDLED;
243}
244
245static irqreturn_t rtl8211f_handle_interrupt(struct phy_device *phydev)
246{
247 int irq_status;
248
249 irq_status = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
250 if (irq_status < 0) {
251 phy_error(phydev);
252 return IRQ_NONE;
253 }
254
255 if (!(irq_status & RTL8211F_INER_LINK_STATUS))
256 return IRQ_NONE;
257
258 phy_trigger_machine(phydev);
259
260 return IRQ_HANDLED;
261}
262
263static int rtl8211_config_aneg(struct phy_device *phydev)
264{
265 int ret;
266
267 ret = genphy_config_aneg(phydev);
268 if (ret < 0)
269 return ret;
270
271
272
273
274 if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) {
275 phy_write(phydev, 0x17, 0x2138);
276 phy_write(phydev, 0x0e, 0x0260);
277 } else {
278 phy_write(phydev, 0x17, 0x2108);
279 phy_write(phydev, 0x0e, 0x0000);
280 }
281
282 return 0;
283}
284
285static int rtl8211c_config_init(struct phy_device *phydev)
286{
287
288 return phy_set_bits(phydev, MII_CTRL1000,
289 CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
290}
291
292static int rtl8211f_config_init(struct phy_device *phydev)
293{
294 struct device *dev = &phydev->mdio.dev;
295 u16 val_txdly, val_rxdly;
296 u16 val;
297 int ret;
298
299 val = RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_XTAL_OFF;
300 phy_modify_paged_changed(phydev, 0xa43, RTL8211F_PHYCR1, val, val);
301
302 switch (phydev->interface) {
303 case PHY_INTERFACE_MODE_RGMII:
304 val_txdly = 0;
305 val_rxdly = 0;
306 break;
307
308 case PHY_INTERFACE_MODE_RGMII_RXID:
309 val_txdly = 0;
310 val_rxdly = RTL8211F_RX_DELAY;
311 break;
312
313 case PHY_INTERFACE_MODE_RGMII_TXID:
314 val_txdly = RTL8211F_TX_DELAY;
315 val_rxdly = 0;
316 break;
317
318 case PHY_INTERFACE_MODE_RGMII_ID:
319 val_txdly = RTL8211F_TX_DELAY;
320 val_rxdly = RTL8211F_RX_DELAY;
321 break;
322
323 default:
324 return 0;
325 }
326
327 ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
328 val_txdly);
329 if (ret < 0) {
330 dev_err(dev, "Failed to update the TX delay register\n");
331 return ret;
332 } else if (ret) {
333 dev_dbg(dev,
334 "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
335 val_txdly ? "Enabling" : "Disabling");
336 } else {
337 dev_dbg(dev,
338 "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
339 val_txdly ? "enabled" : "disabled");
340 }
341
342 ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY,
343 val_rxdly);
344 if (ret < 0) {
345 dev_err(dev, "Failed to update the RX delay register\n");
346 return ret;
347 } else if (ret) {
348 dev_dbg(dev,
349 "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
350 val_rxdly ? "Enabling" : "Disabling");
351 } else {
352 dev_dbg(dev,
353 "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
354 val_rxdly ? "enabled" : "disabled");
355 }
356
357 return 0;
358}
359
360static int rtl8211e_config_init(struct phy_device *phydev)
361{
362 int ret = 0, oldpage;
363 u16 val;
364
365
366 switch (phydev->interface) {
367 case PHY_INTERFACE_MODE_RGMII:
368 val = RTL8211E_CTRL_DELAY | 0;
369 break;
370 case PHY_INTERFACE_MODE_RGMII_ID:
371 val = RTL8211E_CTRL_DELAY | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
372 break;
373 case PHY_INTERFACE_MODE_RGMII_RXID:
374 val = RTL8211E_CTRL_DELAY | RTL8211E_RX_DELAY;
375 break;
376 case PHY_INTERFACE_MODE_RGMII_TXID:
377 val = RTL8211E_CTRL_DELAY | RTL8211E_TX_DELAY;
378 break;
379 default:
380 return 0;
381 }
382
383
384
385
386
387
388
389
390
391
392 oldpage = phy_select_page(phydev, 0x7);
393 if (oldpage < 0)
394 goto err_restore_page;
395
396 ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4);
397 if (ret)
398 goto err_restore_page;
399
400 ret = __phy_modify(phydev, 0x1c, RTL8211E_CTRL_DELAY
401 | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
402 val);
403
404err_restore_page:
405 return phy_restore_page(phydev, oldpage, ret);
406}
407
408static int rtl8211b_suspend(struct phy_device *phydev)
409{
410 phy_write(phydev, MII_MMD_DATA, BIT(9));
411
412 return genphy_suspend(phydev);
413}
414
415static int rtl8211b_resume(struct phy_device *phydev)
416{
417 phy_write(phydev, MII_MMD_DATA, 0);
418
419 return genphy_resume(phydev);
420}
421
422static int rtl8366rb_config_init(struct phy_device *phydev)
423{
424 int ret;
425
426 ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
427 RTL8366RB_POWER_SAVE_ON);
428 if (ret) {
429 dev_err(&phydev->mdio.dev,
430 "error enabling power management\n");
431 }
432
433 return ret;
434}
435
436
437static int rtlgen_get_speed(struct phy_device *phydev)
438{
439 int val;
440
441 if (!phydev->link)
442 return 0;
443
444 val = phy_read_paged(phydev, 0xa43, 0x12);
445 if (val < 0)
446 return val;
447
448 switch (val & RTLGEN_SPEED_MASK) {
449 case 0x0000:
450 phydev->speed = SPEED_10;
451 break;
452 case 0x0010:
453 phydev->speed = SPEED_100;
454 break;
455 case 0x0020:
456 phydev->speed = SPEED_1000;
457 break;
458 case 0x0200:
459 phydev->speed = SPEED_10000;
460 break;
461 case 0x0210:
462 phydev->speed = SPEED_2500;
463 break;
464 case 0x0220:
465 phydev->speed = SPEED_5000;
466 break;
467 default:
468 break;
469 }
470
471 return 0;
472}
473
474static int rtlgen_read_status(struct phy_device *phydev)
475{
476 int ret;
477
478 ret = genphy_read_status(phydev);
479 if (ret < 0)
480 return ret;
481
482 return rtlgen_get_speed(phydev);
483}
484
485static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
486{
487 int ret;
488
489 if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
490 rtl821x_write_page(phydev, 0xa5c);
491 ret = __phy_read(phydev, 0x12);
492 rtl821x_write_page(phydev, 0);
493 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
494 rtl821x_write_page(phydev, 0xa5d);
495 ret = __phy_read(phydev, 0x10);
496 rtl821x_write_page(phydev, 0);
497 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) {
498 rtl821x_write_page(phydev, 0xa5d);
499 ret = __phy_read(phydev, 0x11);
500 rtl821x_write_page(phydev, 0);
501 } else {
502 ret = -EOPNOTSUPP;
503 }
504
505 return ret;
506}
507
508static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
509 u16 val)
510{
511 int ret;
512
513 if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
514 rtl821x_write_page(phydev, 0xa5d);
515 ret = __phy_write(phydev, 0x10, val);
516 rtl821x_write_page(phydev, 0);
517 } else {
518 ret = -EOPNOTSUPP;
519 }
520
521 return ret;
522}
523
524static int rtl822x_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
525{
526 int ret = rtlgen_read_mmd(phydev, devnum, regnum);
527
528 if (ret != -EOPNOTSUPP)
529 return ret;
530
531 if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) {
532 rtl821x_write_page(phydev, 0xa6e);
533 ret = __phy_read(phydev, 0x16);
534 rtl821x_write_page(phydev, 0);
535 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
536 rtl821x_write_page(phydev, 0xa6d);
537 ret = __phy_read(phydev, 0x12);
538 rtl821x_write_page(phydev, 0);
539 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) {
540 rtl821x_write_page(phydev, 0xa6d);
541 ret = __phy_read(phydev, 0x10);
542 rtl821x_write_page(phydev, 0);
543 }
544
545 return ret;
546}
547
548static int rtl822x_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
549 u16 val)
550{
551 int ret = rtlgen_write_mmd(phydev, devnum, regnum, val);
552
553 if (ret != -EOPNOTSUPP)
554 return ret;
555
556 if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
557 rtl821x_write_page(phydev, 0xa6d);
558 ret = __phy_write(phydev, 0x12, val);
559 rtl821x_write_page(phydev, 0);
560 }
561
562 return ret;
563}
564
565static int rtl822x_get_features(struct phy_device *phydev)
566{
567 int val;
568
569 val = phy_read_paged(phydev, 0xa61, 0x13);
570 if (val < 0)
571 return val;
572
573 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
574 phydev->supported, val & RTL_SUPPORTS_2500FULL);
575 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
576 phydev->supported, val & RTL_SUPPORTS_5000FULL);
577 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
578 phydev->supported, val & RTL_SUPPORTS_10000FULL);
579
580 return genphy_read_abilities(phydev);
581}
582
583static int rtl822x_config_aneg(struct phy_device *phydev)
584{
585 int ret = 0;
586
587 if (phydev->autoneg == AUTONEG_ENABLE) {
588 u16 adv2500 = 0;
589
590 if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
591 phydev->advertising))
592 adv2500 = RTL_ADV_2500FULL;
593
594 ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
595 RTL_ADV_2500FULL, adv2500);
596 if (ret < 0)
597 return ret;
598 }
599
600 return __genphy_config_aneg(phydev, ret);
601}
602
603static int rtl822x_read_status(struct phy_device *phydev)
604{
605 int ret;
606
607 if (phydev->autoneg == AUTONEG_ENABLE) {
608 int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
609
610 if (lpadv < 0)
611 return lpadv;
612
613 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
614 phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
615 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
616 phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
617 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
618 phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
619 }
620
621 ret = genphy_read_status(phydev);
622 if (ret < 0)
623 return ret;
624
625 return rtlgen_get_speed(phydev);
626}
627
628static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
629{
630 int val;
631
632 phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
633 val = phy_read(phydev, 0x13);
634 phy_write(phydev, RTL821x_PAGE_SELECT, 0);
635
636 return val >= 0 && val & RTL_SUPPORTS_2500FULL;
637}
638
639static int rtlgen_match_phy_device(struct phy_device *phydev)
640{
641 return phydev->phy_id == RTL_GENERIC_PHYID &&
642 !rtlgen_supports_2_5gbps(phydev);
643}
644
645static int rtl8226_match_phy_device(struct phy_device *phydev)
646{
647 return phydev->phy_id == RTL_GENERIC_PHYID &&
648 rtlgen_supports_2_5gbps(phydev);
649}
650
651static int rtlgen_resume(struct phy_device *phydev)
652{
653 int ret = genphy_resume(phydev);
654
655
656 msleep(20);
657
658 return ret;
659}
660
661static int rtl9000a_config_init(struct phy_device *phydev)
662{
663 phydev->autoneg = AUTONEG_DISABLE;
664 phydev->speed = SPEED_100;
665 phydev->duplex = DUPLEX_FULL;
666
667 return 0;
668}
669
670static int rtl9000a_config_aneg(struct phy_device *phydev)
671{
672 int ret;
673 u16 ctl = 0;
674
675 switch (phydev->master_slave_set) {
676 case MASTER_SLAVE_CFG_MASTER_FORCE:
677 ctl |= CTL1000_AS_MASTER;
678 break;
679 case MASTER_SLAVE_CFG_SLAVE_FORCE:
680 break;
681 case MASTER_SLAVE_CFG_UNKNOWN:
682 case MASTER_SLAVE_CFG_UNSUPPORTED:
683 return 0;
684 default:
685 phydev_warn(phydev, "Unsupported Master/Slave mode\n");
686 return -EOPNOTSUPP;
687 }
688
689 ret = phy_modify_changed(phydev, MII_CTRL1000, CTL1000_AS_MASTER, ctl);
690 if (ret == 1)
691 ret = genphy_soft_reset(phydev);
692
693 return ret;
694}
695
696static int rtl9000a_read_status(struct phy_device *phydev)
697{
698 int ret;
699
700 phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
701 phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
702
703 ret = genphy_update_link(phydev);
704 if (ret)
705 return ret;
706
707 ret = phy_read(phydev, MII_CTRL1000);
708 if (ret < 0)
709 return ret;
710 if (ret & CTL1000_AS_MASTER)
711 phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE;
712 else
713 phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE;
714
715 ret = phy_read(phydev, MII_STAT1000);
716 if (ret < 0)
717 return ret;
718 if (ret & LPA_1000MSRES)
719 phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
720 else
721 phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
722
723 return 0;
724}
725
726static int rtl9000a_ack_interrupt(struct phy_device *phydev)
727{
728 int err;
729
730 err = phy_read(phydev, RTL8211F_INSR);
731
732 return (err < 0) ? err : 0;
733}
734
735static int rtl9000a_config_intr(struct phy_device *phydev)
736{
737 u16 val;
738 int err;
739
740 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
741 err = rtl9000a_ack_interrupt(phydev);
742 if (err)
743 return err;
744
745 val = (u16)~RTL9000A_GINMR_LINK_STATUS;
746 err = phy_write_paged(phydev, 0xa42, RTL9000A_GINMR, val);
747 } else {
748 val = ~0;
749 err = phy_write_paged(phydev, 0xa42, RTL9000A_GINMR, val);
750 if (err)
751 return err;
752
753 err = rtl9000a_ack_interrupt(phydev);
754 }
755
756 return phy_write_paged(phydev, 0xa42, RTL9000A_GINMR, val);
757}
758
759static irqreturn_t rtl9000a_handle_interrupt(struct phy_device *phydev)
760{
761 int irq_status;
762
763 irq_status = phy_read(phydev, RTL8211F_INSR);
764 if (irq_status < 0) {
765 phy_error(phydev);
766 return IRQ_NONE;
767 }
768
769 if (!(irq_status & RTL8211F_INER_LINK_STATUS))
770 return IRQ_NONE;
771
772 phy_trigger_machine(phydev);
773
774 return IRQ_HANDLED;
775}
776
777static struct phy_driver realtek_drvs[] = {
778 {
779 PHY_ID_MATCH_EXACT(0x00008201),
780 .name = "RTL8201CP Ethernet",
781 .read_page = rtl821x_read_page,
782 .write_page = rtl821x_write_page,
783 }, {
784 PHY_ID_MATCH_EXACT(0x001cc816),
785 .name = "RTL8201F Fast Ethernet",
786 .config_intr = &rtl8201_config_intr,
787 .handle_interrupt = rtl8201_handle_interrupt,
788 .suspend = genphy_suspend,
789 .resume = genphy_resume,
790 .read_page = rtl821x_read_page,
791 .write_page = rtl821x_write_page,
792 }, {
793 PHY_ID_MATCH_MODEL(0x001cc880),
794 .name = "RTL8208 Fast Ethernet",
795 .read_mmd = genphy_read_mmd_unsupported,
796 .write_mmd = genphy_write_mmd_unsupported,
797 .suspend = genphy_suspend,
798 .resume = genphy_resume,
799 .read_page = rtl821x_read_page,
800 .write_page = rtl821x_write_page,
801 }, {
802 PHY_ID_MATCH_EXACT(0x001cc910),
803 .name = "RTL8211 Gigabit Ethernet",
804 .config_aneg = rtl8211_config_aneg,
805 .read_mmd = &genphy_read_mmd_unsupported,
806 .write_mmd = &genphy_write_mmd_unsupported,
807 .read_page = rtl821x_read_page,
808 .write_page = rtl821x_write_page,
809 }, {
810 PHY_ID_MATCH_EXACT(0x001cc912),
811 .name = "RTL8211B Gigabit Ethernet",
812 .config_intr = &rtl8211b_config_intr,
813 .handle_interrupt = rtl821x_handle_interrupt,
814 .read_mmd = &genphy_read_mmd_unsupported,
815 .write_mmd = &genphy_write_mmd_unsupported,
816 .suspend = rtl8211b_suspend,
817 .resume = rtl8211b_resume,
818 .read_page = rtl821x_read_page,
819 .write_page = rtl821x_write_page,
820 }, {
821 PHY_ID_MATCH_EXACT(0x001cc913),
822 .name = "RTL8211C Gigabit Ethernet",
823 .config_init = rtl8211c_config_init,
824 .read_mmd = &genphy_read_mmd_unsupported,
825 .write_mmd = &genphy_write_mmd_unsupported,
826 .read_page = rtl821x_read_page,
827 .write_page = rtl821x_write_page,
828 }, {
829 PHY_ID_MATCH_EXACT(0x001cc914),
830 .name = "RTL8211DN Gigabit Ethernet",
831 .config_intr = rtl8211e_config_intr,
832 .handle_interrupt = rtl821x_handle_interrupt,
833 .suspend = genphy_suspend,
834 .resume = genphy_resume,
835 .read_page = rtl821x_read_page,
836 .write_page = rtl821x_write_page,
837 }, {
838 PHY_ID_MATCH_EXACT(0x001cc915),
839 .name = "RTL8211E Gigabit Ethernet",
840 .config_init = &rtl8211e_config_init,
841 .config_intr = &rtl8211e_config_intr,
842 .handle_interrupt = rtl821x_handle_interrupt,
843 .suspend = genphy_suspend,
844 .resume = genphy_resume,
845 .read_page = rtl821x_read_page,
846 .write_page = rtl821x_write_page,
847 }, {
848 PHY_ID_MATCH_EXACT(0x001cc916),
849 .name = "RTL8211F Gigabit Ethernet",
850 .config_init = &rtl8211f_config_init,
851 .read_status = rtlgen_read_status,
852 .config_intr = &rtl8211f_config_intr,
853 .handle_interrupt = rtl8211f_handle_interrupt,
854 .suspend = genphy_suspend,
855 .resume = genphy_resume,
856 .read_page = rtl821x_read_page,
857 .write_page = rtl821x_write_page,
858 }, {
859 .name = "Generic FE-GE Realtek PHY",
860 .match_phy_device = rtlgen_match_phy_device,
861 .read_status = rtlgen_read_status,
862 .suspend = genphy_suspend,
863 .resume = rtlgen_resume,
864 .read_page = rtl821x_read_page,
865 .write_page = rtl821x_write_page,
866 .read_mmd = rtlgen_read_mmd,
867 .write_mmd = rtlgen_write_mmd,
868 }, {
869 .name = "RTL8226 2.5Gbps PHY",
870 .match_phy_device = rtl8226_match_phy_device,
871 .get_features = rtl822x_get_features,
872 .config_aneg = rtl822x_config_aneg,
873 .read_status = rtl822x_read_status,
874 .suspend = genphy_suspend,
875 .resume = rtlgen_resume,
876 .read_page = rtl821x_read_page,
877 .write_page = rtl821x_write_page,
878 .read_mmd = rtl822x_read_mmd,
879 .write_mmd = rtl822x_write_mmd,
880 }, {
881 PHY_ID_MATCH_EXACT(0x001cc840),
882 .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
883 .get_features = rtl822x_get_features,
884 .config_aneg = rtl822x_config_aneg,
885 .read_status = rtl822x_read_status,
886 .suspend = genphy_suspend,
887 .resume = rtlgen_resume,
888 .read_page = rtl821x_read_page,
889 .write_page = rtl821x_write_page,
890 .read_mmd = rtl822x_read_mmd,
891 .write_mmd = rtl822x_write_mmd,
892 }, {
893 PHY_ID_MATCH_EXACT(0x001cc838),
894 .name = "RTL8226-CG 2.5Gbps PHY",
895 .get_features = rtl822x_get_features,
896 .config_aneg = rtl822x_config_aneg,
897 .read_status = rtl822x_read_status,
898 .suspend = genphy_suspend,
899 .resume = rtlgen_resume,
900 .read_page = rtl821x_read_page,
901 .write_page = rtl821x_write_page,
902 }, {
903 PHY_ID_MATCH_EXACT(0x001cc848),
904 .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
905 .get_features = rtl822x_get_features,
906 .config_aneg = rtl822x_config_aneg,
907 .read_status = rtl822x_read_status,
908 .suspend = genphy_suspend,
909 .resume = rtlgen_resume,
910 .read_page = rtl821x_read_page,
911 .write_page = rtl821x_write_page,
912 }, {
913 PHY_ID_MATCH_EXACT(0x001cc849),
914 .name = "RTL8221B-VB-CG 2.5Gbps PHY",
915 .get_features = rtl822x_get_features,
916 .config_aneg = rtl822x_config_aneg,
917 .read_status = rtl822x_read_status,
918 .suspend = genphy_suspend,
919 .resume = rtlgen_resume,
920 .read_page = rtl821x_read_page,
921 .write_page = rtl821x_write_page,
922 }, {
923 PHY_ID_MATCH_EXACT(0x001cc84a),
924 .name = "RTL8221B-VM-CG 2.5Gbps PHY",
925 .get_features = rtl822x_get_features,
926 .config_aneg = rtl822x_config_aneg,
927 .read_status = rtl822x_read_status,
928 .suspend = genphy_suspend,
929 .resume = rtlgen_resume,
930 .read_page = rtl821x_read_page,
931 .write_page = rtl821x_write_page,
932 }, {
933 PHY_ID_MATCH_EXACT(0x001cc961),
934 .name = "RTL8366RB Gigabit Ethernet",
935 .config_init = &rtl8366rb_config_init,
936
937
938
939
940
941 .config_intr = genphy_no_config_intr,
942 .handle_interrupt = genphy_handle_interrupt_no_ack,
943 .suspend = genphy_suspend,
944 .resume = genphy_resume,
945 }, {
946 PHY_ID_MATCH_EXACT(0x001ccb00),
947 .name = "RTL9000AA_RTL9000AN Ethernet",
948 .features = PHY_BASIC_T1_FEATURES,
949 .config_init = rtl9000a_config_init,
950 .config_aneg = rtl9000a_config_aneg,
951 .read_status = rtl9000a_read_status,
952 .config_intr = rtl9000a_config_intr,
953 .handle_interrupt = rtl9000a_handle_interrupt,
954 .suspend = genphy_suspend,
955 .resume = genphy_resume,
956 .read_page = rtl821x_read_page,
957 .write_page = rtl821x_write_page,
958 },
959};
960
961module_phy_driver(realtek_drvs);
962
963static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
964 { PHY_ID_MATCH_VENDOR(0x001cc800) },
965 { }
966};
967
968MODULE_DEVICE_TABLE(mdio, realtek_tbl);
969