]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/net/phy/realtek.c
761ce3b1e7bdba4687ef62d8c33151a99e78f5ac
[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 MODULE_DESCRIPTION("Realtek PHY driver");
43 MODULE_AUTHOR("Johnson Leung");
44 MODULE_LICENSE("GPL");
45
46 static int rtl821x_read_page(struct phy_device *phydev)
47 {
48         return __phy_read(phydev, RTL821x_PAGE_SELECT);
49 }
50
51 static int rtl821x_write_page(struct phy_device *phydev, int page)
52 {
53         return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
54 }
55
56 static int rtl8201_ack_interrupt(struct phy_device *phydev)
57 {
58         int err;
59
60         err = phy_read(phydev, RTL8201F_ISR);
61
62         return (err < 0) ? err : 0;
63 }
64
65 static int rtl821x_ack_interrupt(struct phy_device *phydev)
66 {
67         int err;
68
69         err = phy_read(phydev, RTL821x_INSR);
70
71         return (err < 0) ? err : 0;
72 }
73
74 static int rtl8211f_ack_interrupt(struct phy_device *phydev)
75 {
76         int err;
77
78         err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
79
80         return (err < 0) ? err : 0;
81 }
82
83 static int rtl8201_config_intr(struct phy_device *phydev)
84 {
85         u16 val;
86
87         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
88                 val = BIT(13) | BIT(12) | BIT(11);
89         else
90                 val = 0;
91
92         return phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
93 }
94
95 static int rtl8211b_config_intr(struct phy_device *phydev)
96 {
97         int err;
98
99         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
100                 err = phy_write(phydev, RTL821x_INER,
101                                 RTL8211B_INER_INIT);
102         else
103                 err = phy_write(phydev, RTL821x_INER, 0);
104
105         return err;
106 }
107
108 static int rtl8211e_config_intr(struct phy_device *phydev)
109 {
110         int err;
111
112         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
113                 err = phy_write(phydev, RTL821x_INER,
114                                 RTL8211E_INER_LINK_STATUS);
115         else
116                 err = phy_write(phydev, RTL821x_INER, 0);
117
118         return err;
119 }
120
121 static int rtl8211f_config_intr(struct phy_device *phydev)
122 {
123         u16 val;
124
125         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
126                 val = RTL8211F_INER_LINK_STATUS;
127         else
128                 val = 0;
129
130         return phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
131 }
132
133 static int rtl8211_config_aneg(struct phy_device *phydev)
134 {
135         int ret;
136
137         ret = genphy_config_aneg(phydev);
138         if (ret < 0)
139                 return ret;
140
141         /* Quirk was copied from vendor driver. Unfortunately it includes no
142          * description of the magic numbers.
143          */
144         if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) {
145                 phy_write(phydev, 0x17, 0x2138);
146                 phy_write(phydev, 0x0e, 0x0260);
147         } else {
148                 phy_write(phydev, 0x17, 0x2108);
149                 phy_write(phydev, 0x0e, 0x0000);
150         }
151
152         return 0;
153 }
154
155 static int rtl8211c_config_init(struct phy_device *phydev)
156 {
157         /* RTL8211C has an issue when operating in Gigabit slave mode */
158         return phy_set_bits(phydev, MII_CTRL1000,
159                             CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
160 }
161
162 static int rtl8211f_config_init(struct phy_device *phydev)
163 {
164         u16 val;
165
166         /* enable TX-delay for rgmii-{id,txid}, and disable it for rgmii and
167          * rgmii-rxid. The RX-delay can be enabled by the external RXDLY pin.
168          */
169         switch (phydev->interface) {
170         case PHY_INTERFACE_MODE_RGMII:
171         case PHY_INTERFACE_MODE_RGMII_RXID:
172                 val = 0;
173                 break;
174         case PHY_INTERFACE_MODE_RGMII_ID:
175         case PHY_INTERFACE_MODE_RGMII_TXID:
176                 val = RTL8211F_TX_DELAY;
177                 break;
178         default: /* the rest of the modes imply leaving delay as is. */
179                 return 0;
180         }
181
182         return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val);
183 }
184
185 static int rtl8211e_config_init(struct phy_device *phydev)
186 {
187         int ret = 0, oldpage;
188         u16 val;
189
190         /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
191         switch (phydev->interface) {
192         case PHY_INTERFACE_MODE_RGMII:
193                 val = 0;
194                 break;
195         case PHY_INTERFACE_MODE_RGMII_ID:
196                 val = RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
197                 break;
198         case PHY_INTERFACE_MODE_RGMII_RXID:
199                 val = RTL8211E_RX_DELAY;
200                 break;
201         case PHY_INTERFACE_MODE_RGMII_TXID:
202                 val = RTL8211E_TX_DELAY;
203                 break;
204         default: /* the rest of the modes imply leaving delays as is. */
205                 return 0;
206         }
207
208         /* According to a sample driver there is a 0x1c config register on the
209          * 0xa4 extension page (0x7) layout. It can be used to disable/enable
210          * the RX/TX delays otherwise controlled by RXDLY/TXDLY pins. It can
211          * also be used to customize the whole configuration register:
212          * 8:6 = PHY Address, 5:4 = Auto-Negotiation, 3 = Interface Mode Select,
213          * 2 = RX Delay, 1 = TX Delay, 0 = SELRGV (see original PHY datasheet
214          * for details).
215          */
216         oldpage = phy_select_page(phydev, 0x7);
217         if (oldpage < 0)
218                 goto err_restore_page;
219
220         ret = phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4);
221         if (ret)
222                 goto err_restore_page;
223
224         ret = phy_modify(phydev, 0x1c, RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
225                          val);
226
227 err_restore_page:
228         return phy_restore_page(phydev, oldpage, ret);
229 }
230
231 static int rtl8211b_suspend(struct phy_device *phydev)
232 {
233         phy_write(phydev, MII_MMD_DATA, BIT(9));
234
235         return genphy_suspend(phydev);
236 }
237
238 static int rtl8211b_resume(struct phy_device *phydev)
239 {
240         phy_write(phydev, MII_MMD_DATA, 0);
241
242         return genphy_resume(phydev);
243 }
244
245 static int rtl8366rb_config_init(struct phy_device *phydev)
246 {
247         int ret;
248
249         ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
250                            RTL8366RB_POWER_SAVE_ON);
251         if (ret) {
252                 dev_err(&phydev->mdio.dev,
253                         "error enabling power management\n");
254         }
255
256         return ret;
257 }
258
259 static struct phy_driver realtek_drvs[] = {
260         {
261                 PHY_ID_MATCH_EXACT(0x00008201),
262                 .name           = "RTL8201CP Ethernet",
263         }, {
264                 PHY_ID_MATCH_EXACT(0x001cc816),
265                 .name           = "RTL8201F Fast Ethernet",
266                 .ack_interrupt  = &rtl8201_ack_interrupt,
267                 .config_intr    = &rtl8201_config_intr,
268                 .suspend        = genphy_suspend,
269                 .resume         = genphy_resume,
270                 .read_page      = rtl821x_read_page,
271                 .write_page     = rtl821x_write_page,
272         }, {
273                 PHY_ID_MATCH_EXACT(0x001cc910),
274                 .name           = "RTL8211 Gigabit Ethernet",
275                 .config_aneg    = rtl8211_config_aneg,
276                 .read_mmd       = &genphy_read_mmd_unsupported,
277                 .write_mmd      = &genphy_write_mmd_unsupported,
278         }, {
279                 PHY_ID_MATCH_EXACT(0x001cc912),
280                 .name           = "RTL8211B Gigabit Ethernet",
281                 .ack_interrupt  = &rtl821x_ack_interrupt,
282                 .config_intr    = &rtl8211b_config_intr,
283                 .read_mmd       = &genphy_read_mmd_unsupported,
284                 .write_mmd      = &genphy_write_mmd_unsupported,
285                 .suspend        = rtl8211b_suspend,
286                 .resume         = rtl8211b_resume,
287         }, {
288                 PHY_ID_MATCH_EXACT(0x001cc913),
289                 .name           = "RTL8211C Gigabit Ethernet",
290                 .config_init    = rtl8211c_config_init,
291                 .read_mmd       = &genphy_read_mmd_unsupported,
292                 .write_mmd      = &genphy_write_mmd_unsupported,
293         }, {
294                 PHY_ID_MATCH_EXACT(0x001cc914),
295                 .name           = "RTL8211DN Gigabit Ethernet",
296                 .ack_interrupt  = rtl821x_ack_interrupt,
297                 .config_intr    = rtl8211e_config_intr,
298                 .suspend        = genphy_suspend,
299                 .resume         = genphy_resume,
300         }, {
301                 PHY_ID_MATCH_EXACT(0x001cc915),
302                 .name           = "RTL8211E Gigabit Ethernet",
303                 .config_init    = &rtl8211e_config_init,
304                 .ack_interrupt  = &rtl821x_ack_interrupt,
305                 .config_intr    = &rtl8211e_config_intr,
306                 .suspend        = genphy_suspend,
307                 .resume         = genphy_resume,
308         }, {
309                 PHY_ID_MATCH_EXACT(0x001cc916),
310                 .name           = "RTL8211F Gigabit Ethernet",
311                 .config_init    = &rtl8211f_config_init,
312                 .ack_interrupt  = &rtl8211f_ack_interrupt,
313                 .config_intr    = &rtl8211f_config_intr,
314                 .suspend        = genphy_suspend,
315                 .resume         = genphy_resume,
316                 .read_page      = rtl821x_read_page,
317                 .write_page     = rtl821x_write_page,
318         }, {
319                 PHY_ID_MATCH_EXACT(0x001cc800),
320                 .name           = "Generic Realtek PHY",
321                 .suspend        = genphy_suspend,
322                 .resume         = genphy_resume,
323                 .read_page      = rtl821x_read_page,
324                 .write_page     = rtl821x_write_page,
325         }, {
326                 PHY_ID_MATCH_EXACT(0x001cc961),
327                 .name           = "RTL8366RB Gigabit Ethernet",
328                 .config_init    = &rtl8366rb_config_init,
329                 /* These interrupts are handled by the irq controller
330                  * embedded inside the RTL8366RB, they get unmasked when the
331                  * irq is requested and ACKed by reading the status register,
332                  * which is done by the irqchip code.
333                  */
334                 .ack_interrupt  = genphy_no_ack_interrupt,
335                 .config_intr    = genphy_no_config_intr,
336                 .suspend        = genphy_suspend,
337                 .resume         = genphy_resume,
338         },
339 };
340
341 module_phy_driver(realtek_drvs);
342
343 static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
344         { PHY_ID_MATCH_VENDOR(0x001cc800) },
345         { }
346 };
347
348 MODULE_DEVICE_TABLE(mdio, realtek_tbl);