]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/net/phy/realtek.c
Merge tag 'firewire-update' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[linux.git] / drivers / net / phy / realtek.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * drivers/net/phy/realtek.c
4  *
5  * Driver for Realtek PHYs
6  *
7  * Author: Johnson Leung <r58129@freescale.com>
8  *
9  * Copyright (c) 2004 Freescale Semiconductor, Inc.
10  */
11 #include <linux/bitops.h>
12 #include <linux/phy.h>
13 #include <linux/module.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_INSR                           0x1d
30
31 #define RTL8211F_TX_DELAY                       BIT(8)
32 #define RTL8211E_TX_DELAY                       BIT(1)
33 #define RTL8211E_RX_DELAY                       BIT(2)
34 #define RTL8211E_MODE_MII_GMII                  BIT(3)
35
36 #define RTL8201F_ISR                            0x1e
37 #define RTL8201F_IER                            0x13
38
39 #define RTL8366RB_POWER_SAVE                    0x15
40 #define RTL8366RB_POWER_SAVE_ON                 BIT(12)
41
42 #define RTL_SUPPORTS_5000FULL                   BIT(14)
43 #define RTL_SUPPORTS_2500FULL                   BIT(13)
44 #define RTL_SUPPORTS_10000FULL                  BIT(0)
45 #define RTL_ADV_2500FULL                        BIT(7)
46 #define RTL_LPADV_10000FULL                     BIT(11)
47 #define RTL_LPADV_5000FULL                      BIT(6)
48 #define RTL_LPADV_2500FULL                      BIT(5)
49
50 #define RTL_GENERIC_PHYID                       0x001cc800
51
52 MODULE_DESCRIPTION("Realtek PHY driver");
53 MODULE_AUTHOR("Johnson Leung");
54 MODULE_LICENSE("GPL");
55
56 static int rtl821x_read_page(struct phy_device *phydev)
57 {
58         return __phy_read(phydev, RTL821x_PAGE_SELECT);
59 }
60
61 static int rtl821x_write_page(struct phy_device *phydev, int page)
62 {
63         return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
64 }
65
66 static int rtl8201_ack_interrupt(struct phy_device *phydev)
67 {
68         int err;
69
70         err = phy_read(phydev, RTL8201F_ISR);
71
72         return (err < 0) ? err : 0;
73 }
74
75 static int rtl821x_ack_interrupt(struct phy_device *phydev)
76 {
77         int err;
78
79         err = phy_read(phydev, RTL821x_INSR);
80
81         return (err < 0) ? err : 0;
82 }
83
84 static int rtl8211f_ack_interrupt(struct phy_device *phydev)
85 {
86         int err;
87
88         err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
89
90         return (err < 0) ? err : 0;
91 }
92
93 static int rtl8201_config_intr(struct phy_device *phydev)
94 {
95         u16 val;
96
97         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
98                 val = BIT(13) | BIT(12) | BIT(11);
99         else
100                 val = 0;
101
102         return phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
103 }
104
105 static int rtl8211b_config_intr(struct phy_device *phydev)
106 {
107         int err;
108
109         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
110                 err = phy_write(phydev, RTL821x_INER,
111                                 RTL8211B_INER_INIT);
112         else
113                 err = phy_write(phydev, RTL821x_INER, 0);
114
115         return err;
116 }
117
118 static int rtl8211e_config_intr(struct phy_device *phydev)
119 {
120         int err;
121
122         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
123                 err = phy_write(phydev, RTL821x_INER,
124                                 RTL8211E_INER_LINK_STATUS);
125         else
126                 err = phy_write(phydev, RTL821x_INER, 0);
127
128         return err;
129 }
130
131 static int rtl8211f_config_intr(struct phy_device *phydev)
132 {
133         u16 val;
134
135         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
136                 val = RTL8211F_INER_LINK_STATUS;
137         else
138                 val = 0;
139
140         return phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
141 }
142
143 static int rtl8211_config_aneg(struct phy_device *phydev)
144 {
145         int ret;
146
147         ret = genphy_config_aneg(phydev);
148         if (ret < 0)
149                 return ret;
150
151         /* Quirk was copied from vendor driver. Unfortunately it includes no
152          * description of the magic numbers.
153          */
154         if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) {
155                 phy_write(phydev, 0x17, 0x2138);
156                 phy_write(phydev, 0x0e, 0x0260);
157         } else {
158                 phy_write(phydev, 0x17, 0x2108);
159                 phy_write(phydev, 0x0e, 0x0000);
160         }
161
162         return 0;
163 }
164
165 static int rtl8211c_config_init(struct phy_device *phydev)
166 {
167         /* RTL8211C has an issue when operating in Gigabit slave mode */
168         return phy_set_bits(phydev, MII_CTRL1000,
169                             CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
170 }
171
172 static int rtl8211f_config_init(struct phy_device *phydev)
173 {
174         u16 val;
175
176         /* enable TX-delay for rgmii-{id,txid}, and disable it for rgmii and
177          * rgmii-rxid. The RX-delay can be enabled by the external RXDLY pin.
178          */
179         switch (phydev->interface) {
180         case PHY_INTERFACE_MODE_RGMII:
181         case PHY_INTERFACE_MODE_RGMII_RXID:
182                 val = 0;
183                 break;
184         case PHY_INTERFACE_MODE_RGMII_ID:
185         case PHY_INTERFACE_MODE_RGMII_TXID:
186                 val = RTL8211F_TX_DELAY;
187                 break;
188         default: /* the rest of the modes imply leaving delay as is. */
189                 return 0;
190         }
191
192         return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val);
193 }
194
195 static int rtl8211e_config_init(struct phy_device *phydev)
196 {
197         int ret = 0, oldpage;
198         u16 val;
199
200         /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
201         switch (phydev->interface) {
202         case PHY_INTERFACE_MODE_RGMII:
203                 val = 0;
204                 break;
205         case PHY_INTERFACE_MODE_RGMII_ID:
206                 val = RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
207                 break;
208         case PHY_INTERFACE_MODE_RGMII_RXID:
209                 val = RTL8211E_RX_DELAY;
210                 break;
211         case PHY_INTERFACE_MODE_RGMII_TXID:
212                 val = RTL8211E_TX_DELAY;
213                 break;
214         default: /* the rest of the modes imply leaving delays as is. */
215                 return 0;
216         }
217
218         /* According to a sample driver there is a 0x1c config register on the
219          * 0xa4 extension page (0x7) layout. It can be used to disable/enable
220          * the RX/TX delays otherwise controlled by RXDLY/TXDLY pins. It can
221          * also be used to customize the whole configuration register:
222          * 8:6 = PHY Address, 5:4 = Auto-Negotiation, 3 = Interface Mode Select,
223          * 2 = RX Delay, 1 = TX Delay, 0 = SELRGV (see original PHY datasheet
224          * for details).
225          */
226         oldpage = phy_select_page(phydev, 0x7);
227         if (oldpage < 0)
228                 goto err_restore_page;
229
230         ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4);
231         if (ret)
232                 goto err_restore_page;
233
234         ret = __phy_modify(phydev, 0x1c, RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
235                            val);
236
237 err_restore_page:
238         return phy_restore_page(phydev, oldpage, ret);
239 }
240
241 static int rtl8211b_suspend(struct phy_device *phydev)
242 {
243         phy_write(phydev, MII_MMD_DATA, BIT(9));
244
245         return genphy_suspend(phydev);
246 }
247
248 static int rtl8211b_resume(struct phy_device *phydev)
249 {
250         phy_write(phydev, MII_MMD_DATA, 0);
251
252         return genphy_resume(phydev);
253 }
254
255 static int rtl8366rb_config_init(struct phy_device *phydev)
256 {
257         int ret;
258
259         ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
260                            RTL8366RB_POWER_SAVE_ON);
261         if (ret) {
262                 dev_err(&phydev->mdio.dev,
263                         "error enabling power management\n");
264         }
265
266         return ret;
267 }
268
269 static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
270 {
271         int ret;
272
273         if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
274                 rtl821x_write_page(phydev, 0xa5c);
275                 ret = __phy_read(phydev, 0x12);
276                 rtl821x_write_page(phydev, 0);
277         } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
278                 rtl821x_write_page(phydev, 0xa5d);
279                 ret = __phy_read(phydev, 0x10);
280                 rtl821x_write_page(phydev, 0);
281         } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) {
282                 rtl821x_write_page(phydev, 0xa5d);
283                 ret = __phy_read(phydev, 0x11);
284                 rtl821x_write_page(phydev, 0);
285         } else {
286                 ret = -EOPNOTSUPP;
287         }
288
289         return ret;
290 }
291
292 static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
293                             u16 val)
294 {
295         int ret;
296
297         if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
298                 rtl821x_write_page(phydev, 0xa5d);
299                 ret = __phy_write(phydev, 0x10, val);
300                 rtl821x_write_page(phydev, 0);
301         } else {
302                 ret = -EOPNOTSUPP;
303         }
304
305         return ret;
306 }
307
308 static int rtl8125_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
309 {
310         int ret = rtlgen_read_mmd(phydev, devnum, regnum);
311
312         if (ret != -EOPNOTSUPP)
313                 return ret;
314
315         if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) {
316                 rtl821x_write_page(phydev, 0xa6e);
317                 ret = __phy_read(phydev, 0x16);
318                 rtl821x_write_page(phydev, 0);
319         } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
320                 rtl821x_write_page(phydev, 0xa6d);
321                 ret = __phy_read(phydev, 0x12);
322                 rtl821x_write_page(phydev, 0);
323         } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) {
324                 rtl821x_write_page(phydev, 0xa6d);
325                 ret = __phy_read(phydev, 0x10);
326                 rtl821x_write_page(phydev, 0);
327         }
328
329         return ret;
330 }
331
332 static int rtl8125_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
333                              u16 val)
334 {
335         int ret = rtlgen_write_mmd(phydev, devnum, regnum, val);
336
337         if (ret != -EOPNOTSUPP)
338                 return ret;
339
340         if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
341                 rtl821x_write_page(phydev, 0xa6d);
342                 ret = __phy_write(phydev, 0x12, val);
343                 rtl821x_write_page(phydev, 0);
344         }
345
346         return ret;
347 }
348
349 static int rtl8125_get_features(struct phy_device *phydev)
350 {
351         int val;
352
353         val = phy_read_paged(phydev, 0xa61, 0x13);
354         if (val < 0)
355                 return val;
356
357         linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
358                          phydev->supported, val & RTL_SUPPORTS_2500FULL);
359         linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
360                          phydev->supported, val & RTL_SUPPORTS_5000FULL);
361         linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
362                          phydev->supported, val & RTL_SUPPORTS_10000FULL);
363
364         return genphy_read_abilities(phydev);
365 }
366
367 static int rtl8125_config_aneg(struct phy_device *phydev)
368 {
369         int ret = 0;
370
371         if (phydev->autoneg == AUTONEG_ENABLE) {
372                 u16 adv2500 = 0;
373
374                 if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
375                                       phydev->advertising))
376                         adv2500 = RTL_ADV_2500FULL;
377
378                 ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
379                                                RTL_ADV_2500FULL, adv2500);
380                 if (ret < 0)
381                         return ret;
382         }
383
384         return __genphy_config_aneg(phydev, ret);
385 }
386
387 static int rtl8125_read_status(struct phy_device *phydev)
388 {
389         if (phydev->autoneg == AUTONEG_ENABLE) {
390                 int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
391
392                 if (lpadv < 0)
393                         return lpadv;
394
395                 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
396                         phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
397                 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
398                         phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
399                 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
400                         phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
401         }
402
403         return genphy_read_status(phydev);
404 }
405
406 static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
407 {
408         int val;
409
410         phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
411         val = phy_read(phydev, 0x13);
412         phy_write(phydev, RTL821x_PAGE_SELECT, 0);
413
414         return val >= 0 && val & RTL_SUPPORTS_2500FULL;
415 }
416
417 static int rtlgen_match_phy_device(struct phy_device *phydev)
418 {
419         return phydev->phy_id == RTL_GENERIC_PHYID &&
420                !rtlgen_supports_2_5gbps(phydev);
421 }
422
423 static int rtl8125_match_phy_device(struct phy_device *phydev)
424 {
425         return phydev->phy_id == RTL_GENERIC_PHYID &&
426                rtlgen_supports_2_5gbps(phydev);
427 }
428
429 static struct phy_driver realtek_drvs[] = {
430         {
431                 PHY_ID_MATCH_EXACT(0x00008201),
432                 .name           = "RTL8201CP Ethernet",
433         }, {
434                 PHY_ID_MATCH_EXACT(0x001cc816),
435                 .name           = "RTL8201F Fast Ethernet",
436                 .ack_interrupt  = &rtl8201_ack_interrupt,
437                 .config_intr    = &rtl8201_config_intr,
438                 .suspend        = genphy_suspend,
439                 .resume         = genphy_resume,
440                 .read_page      = rtl821x_read_page,
441                 .write_page     = rtl821x_write_page,
442         }, {
443                 PHY_ID_MATCH_MODEL(0x001cc880),
444                 .name           = "RTL8208 Fast Ethernet",
445                 .read_mmd       = genphy_read_mmd_unsupported,
446                 .write_mmd      = genphy_write_mmd_unsupported,
447                 .suspend        = genphy_suspend,
448                 .resume         = genphy_resume,
449                 .read_page      = rtl821x_read_page,
450                 .write_page     = rtl821x_write_page,
451         }, {
452                 PHY_ID_MATCH_EXACT(0x001cc910),
453                 .name           = "RTL8211 Gigabit Ethernet",
454                 .config_aneg    = rtl8211_config_aneg,
455                 .read_mmd       = &genphy_read_mmd_unsupported,
456                 .write_mmd      = &genphy_write_mmd_unsupported,
457                 .read_page      = rtl821x_read_page,
458                 .write_page     = rtl821x_write_page,
459         }, {
460                 PHY_ID_MATCH_EXACT(0x001cc912),
461                 .name           = "RTL8211B Gigabit Ethernet",
462                 .ack_interrupt  = &rtl821x_ack_interrupt,
463                 .config_intr    = &rtl8211b_config_intr,
464                 .read_mmd       = &genphy_read_mmd_unsupported,
465                 .write_mmd      = &genphy_write_mmd_unsupported,
466                 .suspend        = rtl8211b_suspend,
467                 .resume         = rtl8211b_resume,
468                 .read_page      = rtl821x_read_page,
469                 .write_page     = rtl821x_write_page,
470         }, {
471                 PHY_ID_MATCH_EXACT(0x001cc913),
472                 .name           = "RTL8211C Gigabit Ethernet",
473                 .config_init    = rtl8211c_config_init,
474                 .read_mmd       = &genphy_read_mmd_unsupported,
475                 .write_mmd      = &genphy_write_mmd_unsupported,
476                 .read_page      = rtl821x_read_page,
477                 .write_page     = rtl821x_write_page,
478         }, {
479                 PHY_ID_MATCH_EXACT(0x001cc914),
480                 .name           = "RTL8211DN Gigabit Ethernet",
481                 .ack_interrupt  = rtl821x_ack_interrupt,
482                 .config_intr    = rtl8211e_config_intr,
483                 .suspend        = genphy_suspend,
484                 .resume         = genphy_resume,
485                 .read_page      = rtl821x_read_page,
486                 .write_page     = rtl821x_write_page,
487         }, {
488                 PHY_ID_MATCH_EXACT(0x001cc915),
489                 .name           = "RTL8211E Gigabit Ethernet",
490                 .config_init    = &rtl8211e_config_init,
491                 .ack_interrupt  = &rtl821x_ack_interrupt,
492                 .config_intr    = &rtl8211e_config_intr,
493                 .suspend        = genphy_suspend,
494                 .resume         = genphy_resume,
495                 .read_page      = rtl821x_read_page,
496                 .write_page     = rtl821x_write_page,
497         }, {
498                 PHY_ID_MATCH_EXACT(0x001cc916),
499                 .name           = "RTL8211F Gigabit Ethernet",
500                 .config_init    = &rtl8211f_config_init,
501                 .ack_interrupt  = &rtl8211f_ack_interrupt,
502                 .config_intr    = &rtl8211f_config_intr,
503                 .suspend        = genphy_suspend,
504                 .resume         = genphy_resume,
505                 .read_page      = rtl821x_read_page,
506                 .write_page     = rtl821x_write_page,
507         }, {
508                 .name           = "Generic FE-GE Realtek PHY",
509                 .match_phy_device = rtlgen_match_phy_device,
510                 .suspend        = genphy_suspend,
511                 .resume         = genphy_resume,
512                 .read_page      = rtl821x_read_page,
513                 .write_page     = rtl821x_write_page,
514                 .read_mmd       = rtlgen_read_mmd,
515                 .write_mmd      = rtlgen_write_mmd,
516         }, {
517                 .name           = "RTL8125 2.5Gbps internal",
518                 .match_phy_device = rtl8125_match_phy_device,
519                 .get_features   = rtl8125_get_features,
520                 .config_aneg    = rtl8125_config_aneg,
521                 .read_status    = rtl8125_read_status,
522                 .suspend        = genphy_suspend,
523                 .resume         = genphy_resume,
524                 .read_page      = rtl821x_read_page,
525                 .write_page     = rtl821x_write_page,
526                 .read_mmd       = rtl8125_read_mmd,
527                 .write_mmd      = rtl8125_write_mmd,
528         }, {
529                 PHY_ID_MATCH_EXACT(0x001cc961),
530                 .name           = "RTL8366RB Gigabit Ethernet",
531                 .config_init    = &rtl8366rb_config_init,
532                 /* These interrupts are handled by the irq controller
533                  * embedded inside the RTL8366RB, they get unmasked when the
534                  * irq is requested and ACKed by reading the status register,
535                  * which is done by the irqchip code.
536                  */
537                 .ack_interrupt  = genphy_no_ack_interrupt,
538                 .config_intr    = genphy_no_config_intr,
539                 .suspend        = genphy_suspend,
540                 .resume         = genphy_resume,
541         },
542 };
543
544 module_phy_driver(realtek_drvs);
545
546 static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
547         { PHY_ID_MATCH_VENDOR(0x001cc800) },
548         { }
549 };
550
551 MODULE_DEVICE_TABLE(mdio, realtek_tbl);