Blame view
drivers/net/phy/realtek.c
7.78 KB
097c2aa89 phylib: Add Realt... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* * 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. * */ |
8cc5baefb net: phy: realtek... |
16 |
#include <linux/bitops.h> |
097c2aa89 phylib: Add Realt... |
17 |
#include <linux/phy.h> |
9d9779e72 drivers/net: Add ... |
18 |
#include <linux/module.h> |
097c2aa89 phylib: Add Realt... |
19 |
|
f609ab0ed net: phy: realtek... |
20 21 22 |
#define RTL821x_PHYSR 0x11 #define RTL821x_PHYSR_DUPLEX BIT(13) #define RTL821x_PHYSR_SPEED GENMASK(15, 14) |
a82f266d2 net: phy: realtek... |
23 |
|
f609ab0ed net: phy: realtek... |
24 25 26 27 |
#define RTL821x_INER 0x12 #define RTL8211B_INER_INIT 0x6400 #define RTL8211E_INER_LINK_STATUS BIT(10) #define RTL8211F_INER_LINK_STATUS BIT(4) |
a82f266d2 net: phy: realtek... |
28 |
|
f609ab0ed net: phy: realtek... |
29 |
#define RTL821x_INSR 0x13 |
a82f266d2 net: phy: realtek... |
30 |
|
f609ab0ed net: phy: realtek... |
31 |
#define RTL821x_PAGE_SELECT 0x1f |
097c2aa89 phylib: Add Realt... |
32 |
|
f609ab0ed net: phy: realtek... |
33 |
#define RTL8211F_INSR 0x1d |
ef3d90491 net: phy: realtek... |
34 |
|
f609ab0ed net: phy: realtek... |
35 36 37 38 |
#define RTL8211F_TX_DELAY BIT(8) #define RTL8201F_ISR 0x1e #define RTL8201F_IER 0x13 |
513588dd4 net: phy: realtek... |
39 |
|
d85458256 net: phy: realtek... |
40 41 |
#define RTL8366RB_POWER_SAVE 0x15 #define RTL8366RB_POWER_SAVE_ON BIT(12) |
097c2aa89 phylib: Add Realt... |
42 43 44 |
MODULE_DESCRIPTION("Realtek PHY driver"); MODULE_AUTHOR("Johnson Leung"); MODULE_LICENSE("GPL"); |
d98c8ccde phy: realtek: use... |
45 |
static int rtl821x_read_page(struct phy_device *phydev) |
136819a6e net: phy: realtek... |
46 |
{ |
d98c8ccde phy: realtek: use... |
47 |
return __phy_read(phydev, RTL821x_PAGE_SELECT); |
136819a6e net: phy: realtek... |
48 |
} |
d98c8ccde phy: realtek: use... |
49 |
static int rtl821x_write_page(struct phy_device *phydev, int page) |
136819a6e net: phy: realtek... |
50 |
{ |
d98c8ccde phy: realtek: use... |
51 |
return __phy_write(phydev, RTL821x_PAGE_SELECT, page); |
136819a6e net: phy: realtek... |
52 |
} |
513588dd4 net: phy: realtek... |
53 54 55 56 57 58 59 60 |
static int rtl8201_ack_interrupt(struct phy_device *phydev) { int err; err = phy_read(phydev, RTL8201F_ISR); return (err < 0) ? err : 0; } |
097c2aa89 phylib: Add Realt... |
61 62 63 64 65 66 67 68 |
static int rtl821x_ack_interrupt(struct phy_device *phydev) { int err; err = phy_read(phydev, RTL821x_INSR); return (err < 0) ? err : 0; } |
3447cf2e9 net/phy: Add supp... |
69 70 71 |
static int rtl8211f_ack_interrupt(struct phy_device *phydev) { int err; |
d98c8ccde phy: realtek: use... |
72 |
err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR); |
3447cf2e9 net/phy: Add supp... |
73 74 75 |
return (err < 0) ? err : 0; } |
513588dd4 net: phy: realtek... |
76 77 |
static int rtl8201_config_intr(struct phy_device *phydev) { |
136819a6e net: phy: realtek... |
78 |
u16 val; |
513588dd4 net: phy: realtek... |
79 80 |
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) |
136819a6e net: phy: realtek... |
81 |
val = BIT(13) | BIT(12) | BIT(11); |
513588dd4 net: phy: realtek... |
82 |
else |
136819a6e net: phy: realtek... |
83 |
val = 0; |
513588dd4 net: phy: realtek... |
84 |
|
d98c8ccde phy: realtek: use... |
85 |
return phy_write_paged(phydev, 0x7, RTL8201F_IER, val); |
513588dd4 net: phy: realtek... |
86 |
} |
ef3d90491 net: phy: realtek... |
87 |
static int rtl8211b_config_intr(struct phy_device *phydev) |
097c2aa89 phylib: Add Realt... |
88 89 90 91 92 |
{ int err; if (phydev->interrupts == PHY_INTERRUPT_ENABLED) err = phy_write(phydev, RTL821x_INER, |
69021e32e net: phy: realtek... |
93 |
RTL8211B_INER_INIT); |
097c2aa89 phylib: Add Realt... |
94 95 96 97 98 |
else err = phy_write(phydev, RTL821x_INER, 0); return err; } |
ef3d90491 net: phy: realtek... |
99 100 101 102 103 104 |
static int rtl8211e_config_intr(struct phy_device *phydev) { int err; if (phydev->interrupts == PHY_INTERRUPT_ENABLED) err = phy_write(phydev, RTL821x_INER, |
8b64fd614 net: phy: rtl8211... |
105 |
RTL8211E_INER_LINK_STATUS); |
ef3d90491 net: phy: realtek... |
106 107 108 109 110 |
else err = phy_write(phydev, RTL821x_INER, 0); return err; } |
3447cf2e9 net/phy: Add supp... |
111 112 |
static int rtl8211f_config_intr(struct phy_device *phydev) { |
136819a6e net: phy: realtek... |
113 |
u16 val; |
3447cf2e9 net/phy: Add supp... |
114 115 |
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) |
136819a6e net: phy: realtek... |
116 |
val = RTL8211F_INER_LINK_STATUS; |
3447cf2e9 net/phy: Add supp... |
117 |
else |
136819a6e net: phy: realtek... |
118 |
val = 0; |
3447cf2e9 net/phy: Add supp... |
119 |
|
d98c8ccde phy: realtek: use... |
120 |
return phy_write_paged(phydev, 0xa42, RTL821x_INER, val); |
3447cf2e9 net/phy: Add supp... |
121 |
} |
d241d4aac net: phy: realtek... |
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
static int rtl8211_config_aneg(struct phy_device *phydev) { int ret; ret = genphy_config_aneg(phydev); if (ret < 0) return ret; /* Quirk was copied from vendor driver. Unfortunately it includes no * description of the magic numbers. */ if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) { phy_write(phydev, 0x17, 0x2138); phy_write(phydev, 0x0e, 0x0260); } else { phy_write(phydev, 0x17, 0x2108); phy_write(phydev, 0x0e, 0x0000); } return 0; } |
cf87915cb net: phy: realtek... |
143 144 145 146 147 148 149 150 |
static int rtl8211c_config_init(struct phy_device *phydev) { /* RTL8211C has an issue when operating in Gigabit slave mode */ phy_set_bits(phydev, MII_CTRL1000, CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER); return genphy_config_init(phydev); } |
3447cf2e9 net/phy: Add supp... |
151 152 153 |
static int rtl8211f_config_init(struct phy_device *phydev) { int ret; |
d98c8ccde phy: realtek: use... |
154 |
u16 val = 0; |
3447cf2e9 net/phy: Add supp... |
155 156 157 158 |
ret = genphy_config_init(phydev); if (ret < 0) return ret; |
a24d67573 Make changes to h... |
159 160 161 162 |
/* Set green LED for Link, yellow LED for Active */ phy_write(phydev, RTL821x_PAGE_SELECT, 0xd04); phy_write(phydev, 0x10, 0x617f); phy_write(phydev, RTL821x_PAGE_SELECT, 0x0); |
e3230494b net: phy: realtek... |
163 164 165 |
/* 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) |
d98c8ccde phy: realtek: use... |
166 |
val = RTL8211F_TX_DELAY; |
3447cf2e9 net/phy: Add supp... |
167 |
|
d98c8ccde phy: realtek: use... |
168 |
return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val); |
3447cf2e9 net/phy: Add supp... |
169 |
} |
049ff57a2 net: phy: realtek... |
170 171 172 173 174 175 176 177 178 179 180 181 182 |
static int rtl8211b_suspend(struct phy_device *phydev) { phy_write(phydev, MII_MMD_DATA, BIT(9)); return genphy_suspend(phydev); } static int rtl8211b_resume(struct phy_device *phydev) { phy_write(phydev, MII_MMD_DATA, 0); return genphy_resume(phydev); } |
d85458256 net: phy: realtek... |
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
static int rtl8366rb_config_init(struct phy_device *phydev) { int ret; ret = genphy_config_init(phydev); if (ret < 0) return ret; ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE, RTL8366RB_POWER_SAVE_ON); if (ret) { dev_err(&phydev->mdio.dev, "error enabling power management "); } return ret; } |
71b9c4a83 net: phy: realtek... |
201 202 203 204 205 206 207 |
static struct phy_driver realtek_drvs[] = { { .phy_id = 0x00008201, .name = "RTL8201CP Ethernet", .phy_id_mask = 0x0000ffff, .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT, |
71b9c4a83 net: phy: realtek... |
208 |
}, { |
513588dd4 net: phy: realtek... |
209 |
.phy_id = 0x001cc816, |
c87de8694 net: phy: realtek... |
210 |
.name = "RTL8201F Fast Ethernet", |
513588dd4 net: phy: realtek... |
211 212 213 |
.phy_id_mask = 0x001fffff, .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT, |
513588dd4 net: phy: realtek... |
214 215 216 217 |
.ack_interrupt = &rtl8201_ack_interrupt, .config_intr = &rtl8201_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, |
d98c8ccde phy: realtek: use... |
218 219 |
.read_page = rtl821x_read_page, .write_page = rtl821x_write_page, |
513588dd4 net: phy: realtek... |
220 |
}, { |
d241d4aac net: phy: realtek... |
221 222 223 224 225 226 227 228 |
.phy_id = 0x001cc910, .name = "RTL8211 Gigabit Ethernet", .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .config_aneg = rtl8211_config_aneg, .read_mmd = &genphy_read_mmd_unsupported, .write_mmd = &genphy_write_mmd_unsupported, }, { |
71b9c4a83 net: phy: realtek... |
229 230 231 232 233 |
.phy_id = 0x001cc912, .name = "RTL8211B Gigabit Ethernet", .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, |
71b9c4a83 net: phy: realtek... |
234 235 |
.ack_interrupt = &rtl821x_ack_interrupt, .config_intr = &rtl8211b_config_intr, |
0231b1a07 net: phy: realtek... |
236 237 |
.read_mmd = &genphy_read_mmd_unsupported, .write_mmd = &genphy_write_mmd_unsupported, |
049ff57a2 net: phy: realtek... |
238 239 |
.suspend = rtl8211b_suspend, .resume = rtl8211b_resume, |
71b9c4a83 net: phy: realtek... |
240 |
}, { |
cf87915cb net: phy: realtek... |
241 242 243 244 245 246 247 248 |
.phy_id = 0x001cc913, .name = "RTL8211C Gigabit Ethernet", .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .config_init = rtl8211c_config_init, .read_mmd = &genphy_read_mmd_unsupported, .write_mmd = &genphy_write_mmd_unsupported, }, { |
0024f8920 net: phy: add Rea... |
249 250 251 252 253 |
.phy_id = 0x001cc914, .name = "RTL8211DN Gigabit Ethernet", .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, |
0024f8920 net: phy: add Rea... |
254 255 256 257 |
.ack_interrupt = rtl821x_ack_interrupt, .config_intr = rtl8211e_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, |
0024f8920 net: phy: add Rea... |
258 |
}, { |
71b9c4a83 net: phy: realtek... |
259 260 261 262 263 |
.phy_id = 0x001cc915, .name = "RTL8211E Gigabit Ethernet", .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, |
71b9c4a83 net: phy: realtek... |
264 265 266 267 |
.ack_interrupt = &rtl821x_ack_interrupt, .config_intr = &rtl8211e_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, |
3447cf2e9 net/phy: Add supp... |
268 269 270 271 272 273 |
}, { .phy_id = 0x001cc916, .name = "RTL8211F Gigabit Ethernet", .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, |
3447cf2e9 net/phy: Add supp... |
274 |
.config_init = &rtl8211f_config_init, |
3447cf2e9 net/phy: Add supp... |
275 276 277 278 |
.ack_interrupt = &rtl8211f_ack_interrupt, .config_intr = &rtl8211f_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, |
d98c8ccde phy: realtek: use... |
279 280 |
.read_page = rtl821x_read_page, .write_page = rtl821x_write_page, |
d85458256 net: phy: realtek... |
281 282 283 284 285 286 287 288 289 |
}, { .phy_id = 0x001cc961, .name = "RTL8366RB Gigabit Ethernet", .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, .config_init = &rtl8366rb_config_init, .suspend = genphy_suspend, .resume = genphy_resume, |
71b9c4a83 net: phy: realtek... |
290 |
}, |
097c2aa89 phylib: Add Realt... |
291 |
}; |
50fd71507 net: phy: replace... |
292 |
module_phy_driver(realtek_drvs); |
4e4f10f64 phylib: Add modul... |
293 |
|
cf93c9458 net/phy: fix many... |
294 |
static struct mdio_device_id __maybe_unused realtek_tbl[] = { |
513588dd4 net: phy: realtek... |
295 |
{ 0x001cc816, 0x001fffff }, |
100ec4bf0 net: phy: realtek... |
296 |
{ 0x001cc910, 0x001fffff }, |
4e4f10f64 phylib: Add modul... |
297 |
{ 0x001cc912, 0x001fffff }, |
04ecac8c1 net: phy: realtek... |
298 |
{ 0x001cc913, 0x001fffff }, |
0024f8920 net: phy: add Rea... |
299 |
{ 0x001cc914, 0x001fffff }, |
ef3d90491 net: phy: realtek... |
300 |
{ 0x001cc915, 0x001fffff }, |
3447cf2e9 net/phy: Add supp... |
301 |
{ 0x001cc916, 0x001fffff }, |
d85458256 net: phy: realtek... |
302 |
{ 0x001cc961, 0x001fffff }, |
4e4f10f64 phylib: Add modul... |
303 304 305 306 |
{ } }; MODULE_DEVICE_TABLE(mdio, realtek_tbl); |