Blame view

drivers/net/phy/realtek.c 4.9 KB
097c2aa89   Johnson Leung   phylib: Add Realt...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  /*
   * drivers/net/phy/realtek.c
   *
   * Driver for Realtek PHYs
   *
   * Author: Johnson Leung <r58129@freescale.com>
   *
   * Copyright (c) 2004 Freescale Semiconductor, Inc.
   *
   * This program is free software; you can redistribute  it and/or modify it
   * under  the terms of  the GNU General  Public License as published by the
   * Free Software Foundation;  either version 2 of the  License, or (at your
   * option) any later version.
   *
   */
  #include <linux/phy.h>
9d9779e72   Paul Gortmaker   drivers/net: Add ...
17
  #include <linux/module.h>
097c2aa89   Johnson Leung   phylib: Add Realt...
18
19
20
21
22
23
24
  
  #define RTL821x_PHYSR		0x11
  #define RTL821x_PHYSR_DUPLEX	0x2000
  #define RTL821x_PHYSR_SPEED	0xc000
  #define RTL821x_INER		0x12
  #define RTL821x_INER_INIT	0x6400
  #define RTL821x_INSR		0x13
3447cf2e9   Shengzhou Liu   net/phy: Add supp...
25
  #define RTL8211E_INER_LINK_STATUS 0x400
097c2aa89   Johnson Leung   phylib: Add Realt...
26

3447cf2e9   Shengzhou Liu   net/phy: Add supp...
27
28
29
30
  #define RTL8211F_INER_LINK_STATUS 0x0010
  #define RTL8211F_INSR		0x1d
  #define RTL8211F_PAGE_SELECT	0x1f
  #define RTL8211F_TX_DELAY	0x100
ef3d90491   Giuseppe CAVALLARO   net: phy: realtek...
31

097c2aa89   Johnson Leung   phylib: Add Realt...
32
33
34
35
36
37
38
39
40
41
42
43
  MODULE_DESCRIPTION("Realtek PHY driver");
  MODULE_AUTHOR("Johnson Leung");
  MODULE_LICENSE("GPL");
  
  static int rtl821x_ack_interrupt(struct phy_device *phydev)
  {
  	int err;
  
  	err = phy_read(phydev, RTL821x_INSR);
  
  	return (err < 0) ? err : 0;
  }
3447cf2e9   Shengzhou Liu   net/phy: Add supp...
44
45
46
47
48
49
50
51
52
53
54
  static int rtl8211f_ack_interrupt(struct phy_device *phydev)
  {
  	int err;
  
  	phy_write(phydev, RTL8211F_PAGE_SELECT, 0xa43);
  	err = phy_read(phydev, RTL8211F_INSR);
  	/* restore to default page 0 */
  	phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
  
  	return (err < 0) ? err : 0;
  }
ef3d90491   Giuseppe CAVALLARO   net: phy: realtek...
55
  static int rtl8211b_config_intr(struct phy_device *phydev)
097c2aa89   Johnson Leung   phylib: Add Realt...
56
57
58
59
60
61
62
63
64
65
66
  {
  	int err;
  
  	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  		err = phy_write(phydev, RTL821x_INER,
  				RTL821x_INER_INIT);
  	else
  		err = phy_write(phydev, RTL821x_INER, 0);
  
  	return err;
  }
ef3d90491   Giuseppe CAVALLARO   net: phy: realtek...
67
68
69
70
71
72
  static int rtl8211e_config_intr(struct phy_device *phydev)
  {
  	int err;
  
  	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  		err = phy_write(phydev, RTL821x_INER,
8b64fd614   Giuseppe CAVALLARO   net: phy: rtl8211...
73
  				RTL8211E_INER_LINK_STATUS);
ef3d90491   Giuseppe CAVALLARO   net: phy: realtek...
74
75
76
77
78
  	else
  		err = phy_write(phydev, RTL821x_INER, 0);
  
  	return err;
  }
3447cf2e9   Shengzhou Liu   net/phy: Add supp...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  static int rtl8211f_config_intr(struct phy_device *phydev)
  {
  	int err;
  
  	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  		err = phy_write(phydev, RTL821x_INER,
  				RTL8211F_INER_LINK_STATUS);
  	else
  		err = phy_write(phydev, RTL821x_INER, 0);
  
  	return err;
  }
  
  static int rtl8211f_config_init(struct phy_device *phydev)
  {
  	int ret;
  	u16 reg;
  
  	ret = genphy_config_init(phydev);
  	if (ret < 0)
  		return ret;
f87f42a63   Eric Lee   Make changes to h...
100
101
102
103
  	/* Set green LED for Link, yellow LED for Active */
  	phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd04);
  	phy_write(phydev, 0x10, 0x617f);
  	phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
e3230494b   Martin Blumenstingl   net: phy: realtek...
104
105
106
107
108
109
  	phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
  	reg = phy_read(phydev, 0x11);
  
  	/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
  	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
  	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
3447cf2e9   Shengzhou Liu   net/phy: Add supp...
110
  		reg |= RTL8211F_TX_DELAY;
e3230494b   Martin Blumenstingl   net: phy: realtek...
111
112
113
114
115
116
  	else
  		reg &= ~RTL8211F_TX_DELAY;
  
  	phy_write(phydev, 0x11, reg);
  	/* restore to default page 0 */
  	phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
3447cf2e9   Shengzhou Liu   net/phy: Add supp...
117
118
119
  
  	return 0;
  }
71b9c4a83   Jongsung Kim   net: phy: realtek...
120
121
122
123
124
125
126
127
128
  static struct phy_driver realtek_drvs[] = {
  	{
  		.phy_id         = 0x00008201,
  		.name           = "RTL8201CP Ethernet",
  		.phy_id_mask    = 0x0000ffff,
  		.features       = PHY_BASIC_FEATURES,
  		.flags          = PHY_HAS_INTERRUPT,
  		.config_aneg    = &genphy_config_aneg,
  		.read_status    = &genphy_read_status,
71b9c4a83   Jongsung Kim   net: phy: realtek...
129
130
131
132
133
134
135
136
137
138
  	}, {
  		.phy_id		= 0x001cc912,
  		.name		= "RTL8211B Gigabit Ethernet",
  		.phy_id_mask	= 0x001fffff,
  		.features	= PHY_GBIT_FEATURES,
  		.flags		= PHY_HAS_INTERRUPT,
  		.config_aneg	= &genphy_config_aneg,
  		.read_status	= &genphy_read_status,
  		.ack_interrupt	= &rtl821x_ack_interrupt,
  		.config_intr	= &rtl8211b_config_intr,
71b9c4a83   Jongsung Kim   net: phy: realtek...
139
  	}, {
0024f8920   Shaohui Xie   net: phy: add Rea...
140
141
142
143
144
145
146
147
148
149
150
  		.phy_id		= 0x001cc914,
  		.name		= "RTL8211DN Gigabit Ethernet",
  		.phy_id_mask	= 0x001fffff,
  		.features	= PHY_GBIT_FEATURES,
  		.flags		= PHY_HAS_INTERRUPT,
  		.config_aneg	= genphy_config_aneg,
  		.read_status	= genphy_read_status,
  		.ack_interrupt	= rtl821x_ack_interrupt,
  		.config_intr	= rtl8211e_config_intr,
  		.suspend	= genphy_suspend,
  		.resume		= genphy_resume,
0024f8920   Shaohui Xie   net: phy: add Rea...
151
  	}, {
71b9c4a83   Jongsung Kim   net: phy: realtek...
152
153
154
155
156
157
158
159
160
161
162
  		.phy_id		= 0x001cc915,
  		.name		= "RTL8211E Gigabit Ethernet",
  		.phy_id_mask	= 0x001fffff,
  		.features	= PHY_GBIT_FEATURES,
  		.flags		= PHY_HAS_INTERRUPT,
  		.config_aneg	= &genphy_config_aneg,
  		.read_status	= &genphy_read_status,
  		.ack_interrupt	= &rtl821x_ack_interrupt,
  		.config_intr	= &rtl8211e_config_intr,
  		.suspend	= genphy_suspend,
  		.resume		= genphy_resume,
3447cf2e9   Shengzhou Liu   net/phy: Add supp...
163
164
165
166
167
168
169
170
171
172
173
174
175
  	}, {
  		.phy_id		= 0x001cc916,
  		.name		= "RTL8211F Gigabit Ethernet",
  		.phy_id_mask	= 0x001fffff,
  		.features	= PHY_GBIT_FEATURES,
  		.flags		= PHY_HAS_INTERRUPT,
  		.config_aneg	= &genphy_config_aneg,
  		.config_init	= &rtl8211f_config_init,
  		.read_status	= &genphy_read_status,
  		.ack_interrupt	= &rtl8211f_ack_interrupt,
  		.config_intr	= &rtl8211f_config_intr,
  		.suspend	= genphy_suspend,
  		.resume		= genphy_resume,
71b9c4a83   Jongsung Kim   net: phy: realtek...
176
  	},
097c2aa89   Johnson Leung   phylib: Add Realt...
177
  };
50fd71507   Johan Hovold   net: phy: replace...
178
  module_phy_driver(realtek_drvs);
4e4f10f64   David Woodhouse   phylib: Add modul...
179

cf93c9458   Uwe Kleine-König   net/phy: fix many...
180
  static struct mdio_device_id __maybe_unused realtek_tbl[] = {
4e4f10f64   David Woodhouse   phylib: Add modul...
181
  	{ 0x001cc912, 0x001fffff },
0024f8920   Shaohui Xie   net: phy: add Rea...
182
  	{ 0x001cc914, 0x001fffff },
ef3d90491   Giuseppe CAVALLARO   net: phy: realtek...
183
  	{ 0x001cc915, 0x001fffff },
3447cf2e9   Shengzhou Liu   net/phy: Add supp...
184
  	{ 0x001cc916, 0x001fffff },
4e4f10f64   David Woodhouse   phylib: Add modul...
185
186
187
188
  	{ }
  };
  
  MODULE_DEVICE_TABLE(mdio, realtek_tbl);