13
13
* option) any later version.
14
14
*
15
15
*/
16
+ #include <linux/bitops.h>
16
17
#include <linux/phy.h>
17
18
#include <linux/module.h>
18
19
19
- #define RTL821x_PHYSR 0x11
20
- #define RTL821x_PHYSR_DUPLEX 0x2000
21
- #define RTL821x_PHYSR_SPEED 0xc000
22
- #define RTL821x_INER 0x12
23
- #define RTL821x_INER_INIT 0x6400
24
- #define RTL821x_INSR 0x13
25
- #define RTL821x_PAGE_SELECT 0x1f
26
- #define RTL8211E_INER_LINK_STATUS 0x400
20
+ #define RTL821x_PHYSR 0x11
21
+ #define RTL821x_PHYSR_DUPLEX BIT(13)
22
+ #define RTL821x_PHYSR_SPEED GENMASK(15, 14)
27
23
28
- #define RTL8211F_INER_LINK_STATUS 0x0010
29
- #define RTL8211F_INSR 0x1d
30
- #define RTL8211F_TX_DELAY 0x100
24
+ #define RTL821x_INER 0x12
25
+ #define RTL8211B_INER_INIT 0x6400
26
+ #define RTL8211E_INER_LINK_STATUS BIT(10)
27
+ #define RTL8211F_INER_LINK_STATUS BIT(4)
31
28
32
- #define RTL8201F_ISR 0x1e
33
- #define RTL8201F_IER 0x13
29
+ #define RTL821x_INSR 0x13
30
+
31
+ #define RTL821x_PAGE_SELECT 0x1f
32
+
33
+ #define RTL8211F_INSR 0x1d
34
+
35
+ #define RTL8211F_TX_DELAY BIT(8)
36
+
37
+ #define RTL8201F_ISR 0x1e
38
+ #define RTL8201F_IER 0x13
34
39
35
40
MODULE_DESCRIPTION ("Realtek PHY driver" );
36
41
MODULE_AUTHOR ("Johnson Leung" );
37
42
MODULE_LICENSE ("GPL" );
38
43
44
+ static int rtl8211x_page_read (struct phy_device * phydev , u16 page , u16 address )
45
+ {
46
+ int ret ;
47
+
48
+ ret = phy_write (phydev , RTL821x_PAGE_SELECT , page );
49
+ if (ret )
50
+ return ret ;
51
+
52
+ ret = phy_read (phydev , address );
53
+
54
+ /* restore to default page 0 */
55
+ phy_write (phydev , RTL821x_PAGE_SELECT , 0x0 );
56
+
57
+ return ret ;
58
+ }
59
+
60
+ static int rtl8211x_page_write (struct phy_device * phydev , u16 page ,
61
+ u16 address , u16 val )
62
+ {
63
+ int ret ;
64
+
65
+ ret = phy_write (phydev , RTL821x_PAGE_SELECT , page );
66
+ if (ret )
67
+ return ret ;
68
+
69
+ ret = phy_write (phydev , address , val );
70
+
71
+ /* restore to default page 0 */
72
+ phy_write (phydev , RTL821x_PAGE_SELECT , 0x0 );
73
+
74
+ return ret ;
75
+ }
76
+
39
77
static int rtl8201_ack_interrupt (struct phy_device * phydev )
40
78
{
41
79
int err ;
@@ -58,31 +96,21 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
58
96
{
59
97
int err ;
60
98
61
- phy_write (phydev , RTL821x_PAGE_SELECT , 0xa43 );
62
- err = phy_read (phydev , RTL8211F_INSR );
63
- /* restore to default page 0 */
64
- phy_write (phydev , RTL821x_PAGE_SELECT , 0x0 );
99
+ err = rtl8211x_page_read (phydev , 0xa43 , RTL8211F_INSR );
65
100
66
101
return (err < 0 ) ? err : 0 ;
67
102
}
68
103
69
104
static int rtl8201_config_intr (struct phy_device * phydev )
70
105
{
71
- int err ;
72
-
73
- /* switch to page 7 */
74
- phy_write (phydev , RTL821x_PAGE_SELECT , 0x7 );
106
+ u16 val ;
75
107
76
108
if (phydev -> interrupts == PHY_INTERRUPT_ENABLED )
77
- err = phy_write (phydev , RTL8201F_IER ,
78
- BIT (13 ) | BIT (12 ) | BIT (11 ));
109
+ val = BIT (13 ) | BIT (12 ) | BIT (11 );
79
110
else
80
- err = phy_write (phydev , RTL8201F_IER , 0 );
81
-
82
- /* restore to default page 0 */
83
- phy_write (phydev , RTL821x_PAGE_SELECT , 0x0 );
111
+ val = 0 ;
84
112
85
- return err ;
113
+ return rtl8211x_page_write ( phydev , 0x7 , RTL8201F_IER , val ) ;
86
114
}
87
115
88
116
static int rtl8211b_config_intr (struct phy_device * phydev )
@@ -91,7 +119,7 @@ static int rtl8211b_config_intr(struct phy_device *phydev)
91
119
92
120
if (phydev -> interrupts == PHY_INTERRUPT_ENABLED )
93
121
err = phy_write (phydev , RTL821x_INER ,
94
- RTL821x_INER_INIT );
122
+ RTL8211B_INER_INIT );
95
123
else
96
124
err = phy_write (phydev , RTL821x_INER , 0 );
97
125
@@ -113,41 +141,41 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
113
141
114
142
static int rtl8211f_config_intr (struct phy_device * phydev )
115
143
{
116
- int err ;
144
+ u16 val ;
117
145
118
- phy_write (phydev , RTL821x_PAGE_SELECT , 0xa42 );
119
146
if (phydev -> interrupts == PHY_INTERRUPT_ENABLED )
120
- err = phy_write (phydev , RTL821x_INER ,
121
- RTL8211F_INER_LINK_STATUS );
147
+ val = RTL8211F_INER_LINK_STATUS ;
122
148
else
123
- err = phy_write (phydev , RTL821x_INER , 0 );
124
- phy_write (phydev , RTL821x_PAGE_SELECT , 0 );
149
+ val = 0 ;
125
150
126
- return err ;
151
+ return rtl8211x_page_write ( phydev , 0xa42 , RTL821x_INER , val ) ;
127
152
}
128
153
129
154
static int rtl8211f_config_init (struct phy_device * phydev )
130
155
{
131
156
int ret ;
132
- u16 reg ;
157
+ u16 val ;
133
158
134
159
ret = genphy_config_init (phydev );
135
160
if (ret < 0 )
136
161
return ret ;
137
162
138
- phy_write (phydev , RTL821x_PAGE_SELECT , 0xd08 );
139
- reg = phy_read (phydev , 0x11 );
163
+ ret = rtl8211x_page_read (phydev , 0xd08 , 0x11 );
164
+ if (ret < 0 )
165
+ return ret ;
166
+
167
+ val = ret & 0xffff ;
140
168
141
169
/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
142
170
if (phydev -> interface == PHY_INTERFACE_MODE_RGMII_ID ||
143
171
phydev -> interface == PHY_INTERFACE_MODE_RGMII_TXID )
144
- reg |= RTL8211F_TX_DELAY ;
172
+ val |= RTL8211F_TX_DELAY ;
145
173
else
146
- reg &= ~RTL8211F_TX_DELAY ;
174
+ val &= ~RTL8211F_TX_DELAY ;
147
175
148
- phy_write (phydev , 0x11 , reg );
149
- /* restore to default page 0 */
150
- phy_write ( phydev , RTL821x_PAGE_SELECT , 0x0 ) ;
176
+ ret = rtl8211x_page_write (phydev , 0xd08 , 0x11 , val );
177
+ if ( ret )
178
+ return ret ;
151
179
152
180
return 0 ;
153
181
}
0 commit comments