1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * drivers/net/phy/smsc.c 4 * 5 * Driver for SMSC PHYs 6 * 7 * Author: Herbert Valerio Riedel 8 * 9 * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org> 10 * 11 * Support added for SMSC LAN8187 and LAN8700 by steve.glendinning@shawell.net 12 * 13 */ 14 15 #include <linux/clk.h> 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/mii.h> 19 #include <linux/ethtool.h> 20 #include <linux/of.h> 21 #include <linux/phy.h> 22 #include <linux/netdevice.h> 23 #include <linux/smscphy.h> 24 25 /* Vendor-specific PHY Definitions */ 26 /* EDPD NLP / crossover time configuration */ 27 #define PHY_EDPD_CONFIG 16 28 #define PHY_EDPD_CONFIG_EXT_CROSSOVER_ 0x0001 29 30 /* Control/Status Indication Register */ 31 #define SPECIAL_CTRL_STS 27 32 #define SPECIAL_CTRL_STS_OVRRD_AMDIX_ 0x8000 33 #define SPECIAL_CTRL_STS_AMDIX_ENABLE_ 0x4000 34 #define SPECIAL_CTRL_STS_AMDIX_STATE_ 0x2000 35 36 struct smsc_hw_stat { 37 const char *string; 38 u8 reg; 39 u8 bits; 40 }; 41 42 static struct smsc_hw_stat smsc_hw_stats[] = { 43 { "phy_symbol_errors", 26, 16}, 44 }; 45 46 struct smsc_phy_priv { 47 u16 intmask; 48 bool energy_enable; 49 }; 50 51 static int smsc_phy_ack_interrupt(struct phy_device *phydev) 52 { 53 int rc = phy_read(phydev, MII_LAN83C185_ISF); 54 55 return rc < 0 ? rc : 0; 56 } 57 58 static int smsc_phy_config_intr(struct phy_device *phydev) 59 { 60 struct smsc_phy_priv *priv = phydev->priv; 61 int rc; 62 63 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { 64 rc = smsc_phy_ack_interrupt(phydev); 65 if (rc) 66 return rc; 67 68 priv->intmask = MII_LAN83C185_ISF_INT4 | MII_LAN83C185_ISF_INT6; 69 if (priv->energy_enable) 70 priv->intmask |= MII_LAN83C185_ISF_INT7; 71 72 rc = phy_write(phydev, MII_LAN83C185_IM, priv->intmask); 73 } else { 74 priv->intmask = 0; 75 76 rc = phy_write(phydev, MII_LAN83C185_IM, 0); 77 if (rc) 78 return rc; 79 80 rc = smsc_phy_ack_interrupt(phydev); 81 } 82 83 return rc < 0 ? rc : 0; 84 } 85 86 static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev) 87 { 88 struct smsc_phy_priv *priv = phydev->priv; 89 int irq_status; 90 91 irq_status = phy_read(phydev, MII_LAN83C185_ISF); 92 if (irq_status < 0) { 93 if (irq_status != -ENODEV) 94 phy_error(phydev); 95 96 return IRQ_NONE; 97 } 98 99 if (!(irq_status & priv->intmask)) 100 return IRQ_NONE; 101 102 phy_trigger_machine(phydev); 103 104 return IRQ_HANDLED; 105 } 106 107 static int smsc_phy_config_init(struct phy_device *phydev) 108 { 109 struct smsc_phy_priv *priv = phydev->priv; 110 int rc; 111 112 if (!priv->energy_enable || phydev->irq != PHY_POLL) 113 return 0; 114 115 rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); 116 117 if (rc < 0) 118 return rc; 119 120 /* Enable energy detect mode for this SMSC Transceivers */ 121 rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, 122 rc | MII_LAN83C185_EDPWRDOWN); 123 return rc; 124 } 125 126 static int smsc_phy_reset(struct phy_device *phydev) 127 { 128 int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES); 129 if (rc < 0) 130 return rc; 131 132 /* If the SMSC PHY is in power down mode, then set it 133 * in all capable mode before using it. 134 */ 135 if ((rc & MII_LAN83C185_MODE_MASK) == MII_LAN83C185_MODE_POWERDOWN) { 136 /* set "all capable" mode */ 137 rc |= MII_LAN83C185_MODE_ALL; 138 phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc); 139 } 140 141 /* reset the phy */ 142 return genphy_soft_reset(phydev); 143 } 144 145 static int lan87xx_config_aneg(struct phy_device *phydev) 146 { 147 int rc; 148 int val; 149 150 switch (phydev->mdix_ctrl) { 151 case ETH_TP_MDI: 152 val = SPECIAL_CTRL_STS_OVRRD_AMDIX_; 153 break; 154 case ETH_TP_MDI_X: 155 val = SPECIAL_CTRL_STS_OVRRD_AMDIX_ | 156 SPECIAL_CTRL_STS_AMDIX_STATE_; 157 break; 158 case ETH_TP_MDI_AUTO: 159 val = SPECIAL_CTRL_STS_AMDIX_ENABLE_; 160 break; 161 default: 162 return genphy_config_aneg(phydev); 163 } 164 165 rc = phy_read(phydev, SPECIAL_CTRL_STS); 166 if (rc < 0) 167 return rc; 168 169 rc &= ~(SPECIAL_CTRL_STS_OVRRD_AMDIX_ | 170 SPECIAL_CTRL_STS_AMDIX_ENABLE_ | 171 SPECIAL_CTRL_STS_AMDIX_STATE_); 172 rc |= val; 173 phy_write(phydev, SPECIAL_CTRL_STS, rc); 174 175 phydev->mdix = phydev->mdix_ctrl; 176 return genphy_config_aneg(phydev); 177 } 178 179 static int lan95xx_config_aneg_ext(struct phy_device *phydev) 180 { 181 int rc; 182 183 if (phydev->phy_id != 0x0007c0f0) /* not (LAN9500A or LAN9505A) */ 184 return lan87xx_config_aneg(phydev); 185 186 /* Extend Manual AutoMDIX timer */ 187 rc = phy_read(phydev, PHY_EDPD_CONFIG); 188 if (rc < 0) 189 return rc; 190 191 rc |= PHY_EDPD_CONFIG_EXT_CROSSOVER_; 192 phy_write(phydev, PHY_EDPD_CONFIG, rc); 193 return lan87xx_config_aneg(phydev); 194 } 195 196 /* 197 * The LAN87xx suffers from rare absence of the ENERGYON-bit when Ethernet cable 198 * plugs in while LAN87xx is in Energy Detect Power-Down mode. This leads to 199 * unstable detection of plugging in Ethernet cable. 200 * This workaround disables Energy Detect Power-Down mode and waiting for 201 * response on link pulses to detect presence of plugged Ethernet cable. 202 * The Energy Detect Power-Down mode is enabled again in the end of procedure to 203 * save approximately 220 mW of power if cable is unplugged. 204 * The workaround is only applicable to poll mode. Energy Detect Power-Down may 205 * not be used in interrupt mode lest link change detection becomes unreliable. 206 */ 207 static int lan87xx_read_status(struct phy_device *phydev) 208 { 209 struct smsc_phy_priv *priv = phydev->priv; 210 211 int err = genphy_read_status(phydev); 212 213 if (!phydev->link && priv->energy_enable && phydev->irq == PHY_POLL) { 214 /* Disable EDPD to wake up PHY */ 215 int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); 216 if (rc < 0) 217 return rc; 218 219 rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, 220 rc & ~MII_LAN83C185_EDPWRDOWN); 221 if (rc < 0) 222 return rc; 223 224 /* Wait max 640 ms to detect energy and the timeout is not 225 * an actual error. 226 */ 227 read_poll_timeout(phy_read, rc, 228 rc & MII_LAN83C185_ENERGYON || rc < 0, 229 10000, 640000, true, phydev, 230 MII_LAN83C185_CTRL_STATUS); 231 if (rc < 0) 232 return rc; 233 234 /* Re-enable EDPD */ 235 rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); 236 if (rc < 0) 237 return rc; 238 239 rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, 240 rc | MII_LAN83C185_EDPWRDOWN); 241 if (rc < 0) 242 return rc; 243 } 244 245 return err; 246 } 247 248 static int smsc_get_sset_count(struct phy_device *phydev) 249 { 250 return ARRAY_SIZE(smsc_hw_stats); 251 } 252 253 static void smsc_get_strings(struct phy_device *phydev, u8 *data) 254 { 255 int i; 256 257 for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++) { 258 strncpy(data + i * ETH_GSTRING_LEN, 259 smsc_hw_stats[i].string, ETH_GSTRING_LEN); 260 } 261 } 262 263 static u64 smsc_get_stat(struct phy_device *phydev, int i) 264 { 265 struct smsc_hw_stat stat = smsc_hw_stats[i]; 266 int val; 267 u64 ret; 268 269 val = phy_read(phydev, stat.reg); 270 if (val < 0) 271 ret = U64_MAX; 272 else 273 ret = val; 274 275 return ret; 276 } 277 278 static void smsc_get_stats(struct phy_device *phydev, 279 struct ethtool_stats *stats, u64 *data) 280 { 281 int i; 282 283 for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++) 284 data[i] = smsc_get_stat(phydev, i); 285 } 286 287 static int smsc_phy_probe(struct phy_device *phydev) 288 { 289 struct device *dev = &phydev->mdio.dev; 290 struct device_node *of_node = dev->of_node; 291 struct smsc_phy_priv *priv; 292 struct clk *refclk; 293 294 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 295 if (!priv) 296 return -ENOMEM; 297 298 priv->energy_enable = true; 299 300 if (of_property_read_bool(of_node, "smsc,disable-energy-detect")) 301 priv->energy_enable = false; 302 303 phydev->priv = priv; 304 305 /* Make clk optional to keep DTB backward compatibility. */ 306 refclk = devm_clk_get_optional_enabled(dev, NULL); 307 if (IS_ERR(refclk)) 308 return dev_err_probe(dev, PTR_ERR(refclk), 309 "Failed to request clock\n"); 310 311 return clk_set_rate(refclk, 50 * 1000 * 1000); 312 } 313 314 static struct phy_driver smsc_phy_driver[] = { 315 { 316 .phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */ 317 .phy_id_mask = 0xfffffff0, 318 .name = "SMSC LAN83C185", 319 320 /* PHY_BASIC_FEATURES */ 321 322 .probe = smsc_phy_probe, 323 324 /* basic functions */ 325 .config_init = smsc_phy_config_init, 326 .soft_reset = smsc_phy_reset, 327 328 /* IRQ related */ 329 .config_intr = smsc_phy_config_intr, 330 .handle_interrupt = smsc_phy_handle_interrupt, 331 332 .suspend = genphy_suspend, 333 .resume = genphy_resume, 334 }, { 335 .phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */ 336 .phy_id_mask = 0xfffffff0, 337 .name = "SMSC LAN8187", 338 339 /* PHY_BASIC_FEATURES */ 340 341 .probe = smsc_phy_probe, 342 343 /* basic functions */ 344 .config_init = smsc_phy_config_init, 345 .soft_reset = smsc_phy_reset, 346 347 /* IRQ related */ 348 .config_intr = smsc_phy_config_intr, 349 .handle_interrupt = smsc_phy_handle_interrupt, 350 351 /* Statistics */ 352 .get_sset_count = smsc_get_sset_count, 353 .get_strings = smsc_get_strings, 354 .get_stats = smsc_get_stats, 355 356 .suspend = genphy_suspend, 357 .resume = genphy_resume, 358 }, { 359 /* This covers internal PHY (phy_id: 0x0007C0C3) for 360 * LAN9500 (PID: 0x9500), LAN9514 (PID: 0xec00), LAN9505 (PID: 0x9505) 361 */ 362 .phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */ 363 .phy_id_mask = 0xfffffff0, 364 .name = "SMSC LAN8700", 365 366 /* PHY_BASIC_FEATURES */ 367 368 .probe = smsc_phy_probe, 369 370 /* basic functions */ 371 .read_status = lan87xx_read_status, 372 .config_init = smsc_phy_config_init, 373 .soft_reset = smsc_phy_reset, 374 .config_aneg = lan87xx_config_aneg, 375 376 /* IRQ related */ 377 .config_intr = smsc_phy_config_intr, 378 .handle_interrupt = smsc_phy_handle_interrupt, 379 380 /* Statistics */ 381 .get_sset_count = smsc_get_sset_count, 382 .get_strings = smsc_get_strings, 383 .get_stats = smsc_get_stats, 384 385 .suspend = genphy_suspend, 386 .resume = genphy_resume, 387 }, { 388 .phy_id = 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */ 389 .phy_id_mask = 0xfffffff0, 390 .name = "SMSC LAN911x Internal PHY", 391 392 /* PHY_BASIC_FEATURES */ 393 394 .probe = smsc_phy_probe, 395 396 /* IRQ related */ 397 .config_intr = smsc_phy_config_intr, 398 .handle_interrupt = smsc_phy_handle_interrupt, 399 400 .suspend = genphy_suspend, 401 .resume = genphy_resume, 402 }, { 403 /* This covers internal PHY (phy_id: 0x0007C0F0) for 404 * LAN9500A (PID: 0x9E00), LAN9505A (PID: 0x9E01) 405 */ 406 .phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */ 407 .phy_id_mask = 0xfffffff0, 408 .name = "SMSC LAN8710/LAN8720", 409 410 /* PHY_BASIC_FEATURES */ 411 412 .probe = smsc_phy_probe, 413 414 /* basic functions */ 415 .read_status = lan87xx_read_status, 416 .config_init = smsc_phy_config_init, 417 .soft_reset = smsc_phy_reset, 418 .config_aneg = lan95xx_config_aneg_ext, 419 420 /* IRQ related */ 421 .config_intr = smsc_phy_config_intr, 422 .handle_interrupt = smsc_phy_handle_interrupt, 423 424 /* Statistics */ 425 .get_sset_count = smsc_get_sset_count, 426 .get_strings = smsc_get_strings, 427 .get_stats = smsc_get_stats, 428 429 .suspend = genphy_suspend, 430 .resume = genphy_resume, 431 }, { 432 .phy_id = 0x0007c110, 433 .phy_id_mask = 0xfffffff0, 434 .name = "SMSC LAN8740", 435 436 /* PHY_BASIC_FEATURES */ 437 .flags = PHY_RST_AFTER_CLK_EN, 438 439 .probe = smsc_phy_probe, 440 441 /* basic functions */ 442 .read_status = lan87xx_read_status, 443 .config_init = smsc_phy_config_init, 444 .soft_reset = smsc_phy_reset, 445 446 /* IRQ related */ 447 .config_intr = smsc_phy_config_intr, 448 .handle_interrupt = smsc_phy_handle_interrupt, 449 450 /* Statistics */ 451 .get_sset_count = smsc_get_sset_count, 452 .get_strings = smsc_get_strings, 453 .get_stats = smsc_get_stats, 454 455 .suspend = genphy_suspend, 456 .resume = genphy_resume, 457 }, { 458 .phy_id = 0x0007c130, /* 0x0007c130 and 0x0007c131 */ 459 /* This mask (0xfffffff2) is to differentiate from 460 * LAN88xx (phy_id 0x0007c132) 461 * and allows future phy_id revisions. 462 */ 463 .phy_id_mask = 0xfffffff2, 464 .name = "Microchip LAN8742", 465 466 /* PHY_BASIC_FEATURES */ 467 .flags = PHY_RST_AFTER_CLK_EN, 468 469 .probe = smsc_phy_probe, 470 471 /* basic functions */ 472 .read_status = lan87xx_read_status, 473 .config_init = smsc_phy_config_init, 474 .soft_reset = smsc_phy_reset, 475 476 /* IRQ related */ 477 .config_intr = smsc_phy_config_intr, 478 .handle_interrupt = smsc_phy_handle_interrupt, 479 480 /* Statistics */ 481 .get_sset_count = smsc_get_sset_count, 482 .get_strings = smsc_get_strings, 483 .get_stats = smsc_get_stats, 484 485 .suspend = genphy_suspend, 486 .resume = genphy_resume, 487 } }; 488 489 module_phy_driver(smsc_phy_driver); 490 491 MODULE_DESCRIPTION("SMSC PHY driver"); 492 MODULE_AUTHOR("Herbert Valerio Riedel"); 493 MODULE_LICENSE("GPL"); 494 495 static struct mdio_device_id __maybe_unused smsc_tbl[] = { 496 { 0x0007c0a0, 0xfffffff0 }, 497 { 0x0007c0b0, 0xfffffff0 }, 498 { 0x0007c0c0, 0xfffffff0 }, 499 { 0x0007c0d0, 0xfffffff0 }, 500 { 0x0007c0f0, 0xfffffff0 }, 501 { 0x0007c110, 0xfffffff0 }, 502 { 0x0007c130, 0xfffffff2 }, 503 { } 504 }; 505 506 MODULE_DEVICE_TABLE(mdio, smsc_tbl); 507