xref: /openbmc/linux/drivers/net/phy/realtek.c (revision 55fd7e02)
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 #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 
57 MODULE_DESCRIPTION("Realtek PHY driver");
58 MODULE_AUTHOR("Johnson Leung");
59 MODULE_LICENSE("GPL");
60 
61 static int rtl821x_read_page(struct phy_device *phydev)
62 {
63 	return __phy_read(phydev, RTL821x_PAGE_SELECT);
64 }
65 
66 static int rtl821x_write_page(struct phy_device *phydev, int page)
67 {
68 	return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
69 }
70 
71 static 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 
80 static 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 
89 static 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 
98 static 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 
110 static 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 
123 static 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 
136 static 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 
148 static 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 	/* Quirk was copied from vendor driver. Unfortunately it includes no
157 	 * description of the magic numbers.
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 
170 static int rtl8211c_config_init(struct phy_device *phydev)
171 {
172 	/* RTL8211C has an issue when operating in Gigabit slave mode */
173 	return phy_set_bits(phydev, MII_CTRL1000,
174 			    CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
175 }
176 
177 static 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: /* the rest of the modes imply leaving delay as is. */
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 
241 static int rtl8211e_config_init(struct phy_device *phydev)
242 {
243 	int ret = 0, oldpage;
244 	u16 val;
245 
246 	/* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
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: /* the rest of the modes imply leaving delays as is. */
261 		return 0;
262 	}
263 
264 	/* According to a sample driver there is a 0x1c config register on the
265 	 * 0xa4 extension page (0x7) layout. It can be used to disable/enable
266 	 * the RX/TX delays otherwise controlled by RXDLY/TXDLY pins. It can
267 	 * also be used to customize the whole configuration register:
268 	 * 8:6 = PHY Address, 5:4 = Auto-Negotiation, 3 = Interface Mode Select,
269 	 * 2 = RX Delay, 1 = TX Delay, 0 = SELRGV (see original PHY datasheet
270 	 * for details).
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 
283 err_restore_page:
284 	return phy_restore_page(phydev, oldpage, ret);
285 }
286 
287 static 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 
294 static int rtl8211b_resume(struct phy_device *phydev)
295 {
296 	phy_write(phydev, MII_MMD_DATA, 0);
297 
298 	return genphy_resume(phydev);
299 }
300 
301 static 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 /* get actual speed to cover the downshift case */
316 static 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 
353 static 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 
364 static 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 
387 static 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 
403 static 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 
427 static 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 
444 static 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 
462 static 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 
482 static 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 
507 static 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 
518 static 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 
524 static 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 
530 static int rtlgen_resume(struct phy_device *phydev)
531 {
532 	int ret = genphy_resume(phydev);
533 
534 	/* Internal PHY's from RTL8168h up may not be instantly ready */
535 	msleep(20);
536 
537 	return ret;
538 }
539 
540 static 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 		/* These interrupts are handled by the irq controller
645 		 * embedded inside the RTL8366RB, they get unmasked when the
646 		 * irq is requested and ACKed by reading the status register,
647 		 * which is done by the irqchip code.
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 
656 module_phy_driver(realtek_drvs);
657 
658 static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
659 	{ PHY_ID_MATCH_VENDOR(0x001cc800) },
660 	{ }
661 };
662 
663 MODULE_DEVICE_TABLE(mdio, realtek_tbl);
664