Linux Audio

Check our new training course

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