1 // SPDX-License-Identifier: GPL-2.0 2 /* Driver for the Texas Instruments DP83822, DP83825 and DP83826 PHYs. 3 * 4 * Copyright (C) 2017 Texas Instruments Inc. 5 */ 6 7 #include <linux/ethtool.h> 8 #include <linux/etherdevice.h> 9 #include <linux/kernel.h> 10 #include <linux/mii.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/phy.h> 14 #include <linux/netdevice.h> 15 16 #define DP83822_PHY_ID 0x2000a240 17 #define DP83825S_PHY_ID 0x2000a140 18 #define DP83825I_PHY_ID 0x2000a150 19 #define DP83825CM_PHY_ID 0x2000a160 20 #define DP83825CS_PHY_ID 0x2000a170 21 #define DP83826C_PHY_ID 0x2000a130 22 #define DP83826NC_PHY_ID 0x2000a110 23 24 #define DP83822_DEVADDR 0x1f 25 26 #define MII_DP83822_CTRL_2 0x0a 27 #define MII_DP83822_PHYSTS 0x10 28 #define MII_DP83822_PHYSCR 0x11 29 #define MII_DP83822_MISR1 0x12 30 #define MII_DP83822_MISR2 0x13 31 #define MII_DP83822_FCSCR 0x14 32 #define MII_DP83822_RCSR 0x17 33 #define MII_DP83822_RESET_CTRL 0x1f 34 #define MII_DP83822_GENCFG 0x465 35 #define MII_DP83822_SOR1 0x467 36 37 /* GENCFG */ 38 #define DP83822_SIG_DET_LOW BIT(0) 39 40 /* Control Register 2 bits */ 41 #define DP83822_FX_ENABLE BIT(14) 42 43 #define DP83822_HW_RESET BIT(15) 44 #define DP83822_SW_RESET BIT(14) 45 46 /* PHY STS bits */ 47 #define DP83822_PHYSTS_DUPLEX BIT(2) 48 #define DP83822_PHYSTS_10 BIT(1) 49 #define DP83822_PHYSTS_LINK BIT(0) 50 51 /* PHYSCR Register Fields */ 52 #define DP83822_PHYSCR_INT_OE BIT(0) /* Interrupt Output Enable */ 53 #define DP83822_PHYSCR_INTEN BIT(1) /* Interrupt Enable */ 54 55 /* MISR1 bits */ 56 #define DP83822_RX_ERR_HF_INT_EN BIT(0) 57 #define DP83822_FALSE_CARRIER_HF_INT_EN BIT(1) 58 #define DP83822_ANEG_COMPLETE_INT_EN BIT(2) 59 #define DP83822_DUP_MODE_CHANGE_INT_EN BIT(3) 60 #define DP83822_SPEED_CHANGED_INT_EN BIT(4) 61 #define DP83822_LINK_STAT_INT_EN BIT(5) 62 #define DP83822_ENERGY_DET_INT_EN BIT(6) 63 #define DP83822_LINK_QUAL_INT_EN BIT(7) 64 65 /* MISR2 bits */ 66 #define DP83822_JABBER_DET_INT_EN BIT(0) 67 #define DP83822_WOL_PKT_INT_EN BIT(1) 68 #define DP83822_SLEEP_MODE_INT_EN BIT(2) 69 #define DP83822_MDI_XOVER_INT_EN BIT(3) 70 #define DP83822_LB_FIFO_INT_EN BIT(4) 71 #define DP83822_PAGE_RX_INT_EN BIT(5) 72 #define DP83822_ANEG_ERR_INT_EN BIT(6) 73 #define DP83822_EEE_ERROR_CHANGE_INT_EN BIT(7) 74 75 /* INT_STAT1 bits */ 76 #define DP83822_WOL_INT_EN BIT(4) 77 #define DP83822_WOL_INT_STAT BIT(12) 78 79 #define MII_DP83822_RXSOP1 0x04a5 80 #define MII_DP83822_RXSOP2 0x04a6 81 #define MII_DP83822_RXSOP3 0x04a7 82 83 /* WoL Registers */ 84 #define MII_DP83822_WOL_CFG 0x04a0 85 #define MII_DP83822_WOL_STAT 0x04a1 86 #define MII_DP83822_WOL_DA1 0x04a2 87 #define MII_DP83822_WOL_DA2 0x04a3 88 #define MII_DP83822_WOL_DA3 0x04a4 89 90 /* WoL bits */ 91 #define DP83822_WOL_MAGIC_EN BIT(0) 92 #define DP83822_WOL_SECURE_ON BIT(5) 93 #define DP83822_WOL_EN BIT(7) 94 #define DP83822_WOL_INDICATION_SEL BIT(8) 95 #define DP83822_WOL_CLR_INDICATION BIT(11) 96 97 /* RSCR bits */ 98 #define DP83822_RX_CLK_SHIFT BIT(12) 99 #define DP83822_TX_CLK_SHIFT BIT(11) 100 101 /* SOR1 mode */ 102 #define DP83822_STRAP_MODE1 0 103 #define DP83822_STRAP_MODE2 BIT(0) 104 #define DP83822_STRAP_MODE3 BIT(1) 105 #define DP83822_STRAP_MODE4 GENMASK(1, 0) 106 107 #define DP83822_COL_STRAP_MASK GENMASK(11, 10) 108 #define DP83822_COL_SHIFT 10 109 #define DP83822_RX_ER_STR_MASK GENMASK(9, 8) 110 #define DP83822_RX_ER_SHIFT 8 111 112 #define MII_DP83822_FIBER_ADVERTISE (ADVERTISED_TP | ADVERTISED_MII | \ 113 ADVERTISED_FIBRE | ADVERTISED_BNC | \ 114 ADVERTISED_Pause | ADVERTISED_Asym_Pause | \ 115 ADVERTISED_100baseT_Full) 116 117 struct dp83822_private { 118 bool fx_signal_det_low; 119 int fx_enabled; 120 u16 fx_sd_enable; 121 }; 122 123 static int dp83822_ack_interrupt(struct phy_device *phydev) 124 { 125 int err; 126 127 err = phy_read(phydev, MII_DP83822_MISR1); 128 if (err < 0) 129 return err; 130 131 err = phy_read(phydev, MII_DP83822_MISR2); 132 if (err < 0) 133 return err; 134 135 return 0; 136 } 137 138 static int dp83822_set_wol(struct phy_device *phydev, 139 struct ethtool_wolinfo *wol) 140 { 141 struct net_device *ndev = phydev->attached_dev; 142 u16 value; 143 const u8 *mac; 144 145 if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) { 146 mac = (const u8 *)ndev->dev_addr; 147 148 if (!is_valid_ether_addr(mac)) 149 return -EINVAL; 150 151 /* MAC addresses start with byte 5, but stored in mac[0]. 152 * 822 PHYs store bytes 4|5, 2|3, 0|1 153 */ 154 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA1, 155 (mac[1] << 8) | mac[0]); 156 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA2, 157 (mac[3] << 8) | mac[2]); 158 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA3, 159 (mac[5] << 8) | mac[4]); 160 161 value = phy_read_mmd(phydev, DP83822_DEVADDR, 162 MII_DP83822_WOL_CFG); 163 if (wol->wolopts & WAKE_MAGIC) 164 value |= DP83822_WOL_MAGIC_EN; 165 else 166 value &= ~DP83822_WOL_MAGIC_EN; 167 168 if (wol->wolopts & WAKE_MAGICSECURE) { 169 phy_write_mmd(phydev, DP83822_DEVADDR, 170 MII_DP83822_RXSOP1, 171 (wol->sopass[1] << 8) | wol->sopass[0]); 172 phy_write_mmd(phydev, DP83822_DEVADDR, 173 MII_DP83822_RXSOP2, 174 (wol->sopass[3] << 8) | wol->sopass[2]); 175 phy_write_mmd(phydev, DP83822_DEVADDR, 176 MII_DP83822_RXSOP3, 177 (wol->sopass[5] << 8) | wol->sopass[4]); 178 value |= DP83822_WOL_SECURE_ON; 179 } else { 180 value &= ~DP83822_WOL_SECURE_ON; 181 } 182 183 /* Clear any pending WoL interrupt */ 184 phy_read(phydev, MII_DP83822_MISR2); 185 186 value |= DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL | 187 DP83822_WOL_CLR_INDICATION; 188 189 return phy_write_mmd(phydev, DP83822_DEVADDR, 190 MII_DP83822_WOL_CFG, value); 191 } else { 192 return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, 193 MII_DP83822_WOL_CFG, DP83822_WOL_EN); 194 } 195 } 196 197 static void dp83822_get_wol(struct phy_device *phydev, 198 struct ethtool_wolinfo *wol) 199 { 200 int value; 201 u16 sopass_val; 202 203 wol->supported = (WAKE_MAGIC | WAKE_MAGICSECURE); 204 wol->wolopts = 0; 205 206 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG); 207 208 if (value & DP83822_WOL_MAGIC_EN) 209 wol->wolopts |= WAKE_MAGIC; 210 211 if (value & DP83822_WOL_SECURE_ON) { 212 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR, 213 MII_DP83822_RXSOP1); 214 wol->sopass[0] = (sopass_val & 0xff); 215 wol->sopass[1] = (sopass_val >> 8); 216 217 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR, 218 MII_DP83822_RXSOP2); 219 wol->sopass[2] = (sopass_val & 0xff); 220 wol->sopass[3] = (sopass_val >> 8); 221 222 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR, 223 MII_DP83822_RXSOP3); 224 wol->sopass[4] = (sopass_val & 0xff); 225 wol->sopass[5] = (sopass_val >> 8); 226 227 wol->wolopts |= WAKE_MAGICSECURE; 228 } 229 230 /* WoL is not enabled so set wolopts to 0 */ 231 if (!(value & DP83822_WOL_EN)) 232 wol->wolopts = 0; 233 } 234 235 static int dp83822_config_intr(struct phy_device *phydev) 236 { 237 struct dp83822_private *dp83822 = phydev->priv; 238 int misr_status; 239 int physcr_status; 240 int err; 241 242 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { 243 misr_status = phy_read(phydev, MII_DP83822_MISR1); 244 if (misr_status < 0) 245 return misr_status; 246 247 misr_status |= (DP83822_RX_ERR_HF_INT_EN | 248 DP83822_FALSE_CARRIER_HF_INT_EN | 249 DP83822_LINK_STAT_INT_EN | 250 DP83822_ENERGY_DET_INT_EN | 251 DP83822_LINK_QUAL_INT_EN); 252 253 if (!dp83822->fx_enabled) 254 misr_status |= DP83822_ANEG_COMPLETE_INT_EN | 255 DP83822_DUP_MODE_CHANGE_INT_EN | 256 DP83822_SPEED_CHANGED_INT_EN; 257 258 259 err = phy_write(phydev, MII_DP83822_MISR1, misr_status); 260 if (err < 0) 261 return err; 262 263 misr_status = phy_read(phydev, MII_DP83822_MISR2); 264 if (misr_status < 0) 265 return misr_status; 266 267 misr_status |= (DP83822_JABBER_DET_INT_EN | 268 DP83822_SLEEP_MODE_INT_EN | 269 DP83822_LB_FIFO_INT_EN | 270 DP83822_PAGE_RX_INT_EN | 271 DP83822_EEE_ERROR_CHANGE_INT_EN); 272 273 if (!dp83822->fx_enabled) 274 misr_status |= DP83822_MDI_XOVER_INT_EN | 275 DP83822_ANEG_ERR_INT_EN | 276 DP83822_WOL_PKT_INT_EN; 277 278 err = phy_write(phydev, MII_DP83822_MISR2, misr_status); 279 if (err < 0) 280 return err; 281 282 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR); 283 if (physcr_status < 0) 284 return physcr_status; 285 286 physcr_status |= DP83822_PHYSCR_INT_OE | DP83822_PHYSCR_INTEN; 287 288 } else { 289 err = phy_write(phydev, MII_DP83822_MISR1, 0); 290 if (err < 0) 291 return err; 292 293 err = phy_write(phydev, MII_DP83822_MISR1, 0); 294 if (err < 0) 295 return err; 296 297 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR); 298 if (physcr_status < 0) 299 return physcr_status; 300 301 physcr_status &= ~DP83822_PHYSCR_INTEN; 302 } 303 304 return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status); 305 } 306 307 static int dp8382x_disable_wol(struct phy_device *phydev) 308 { 309 int value = DP83822_WOL_EN | DP83822_WOL_MAGIC_EN | 310 DP83822_WOL_SECURE_ON; 311 312 return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, 313 MII_DP83822_WOL_CFG, value); 314 } 315 316 static int dp83822_read_status(struct phy_device *phydev) 317 { 318 struct dp83822_private *dp83822 = phydev->priv; 319 int status = phy_read(phydev, MII_DP83822_PHYSTS); 320 int ctrl2; 321 int ret; 322 323 if (dp83822->fx_enabled) { 324 if (status & DP83822_PHYSTS_LINK) { 325 phydev->speed = SPEED_UNKNOWN; 326 phydev->duplex = DUPLEX_UNKNOWN; 327 } else { 328 ctrl2 = phy_read(phydev, MII_DP83822_CTRL_2); 329 if (ctrl2 < 0) 330 return ctrl2; 331 332 if (!(ctrl2 & DP83822_FX_ENABLE)) { 333 ret = phy_write(phydev, MII_DP83822_CTRL_2, 334 DP83822_FX_ENABLE | ctrl2); 335 if (ret < 0) 336 return ret; 337 } 338 } 339 } 340 341 ret = genphy_read_status(phydev); 342 if (ret) 343 return ret; 344 345 if (status < 0) 346 return status; 347 348 if (status & DP83822_PHYSTS_DUPLEX) 349 phydev->duplex = DUPLEX_FULL; 350 else 351 phydev->duplex = DUPLEX_HALF; 352 353 if (status & DP83822_PHYSTS_10) 354 phydev->speed = SPEED_10; 355 else 356 phydev->speed = SPEED_100; 357 358 return 0; 359 } 360 361 static int dp83822_config_init(struct phy_device *phydev) 362 { 363 struct dp83822_private *dp83822 = phydev->priv; 364 struct device *dev = &phydev->mdio.dev; 365 int rgmii_delay; 366 s32 rx_int_delay; 367 s32 tx_int_delay; 368 int err = 0; 369 int bmcr; 370 371 if (phy_interface_is_rgmii(phydev)) { 372 rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0, 373 true); 374 375 if (rx_int_delay <= 0) 376 rgmii_delay = 0; 377 else 378 rgmii_delay = DP83822_RX_CLK_SHIFT; 379 380 tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0, 381 false); 382 if (tx_int_delay <= 0) 383 rgmii_delay &= ~DP83822_TX_CLK_SHIFT; 384 else 385 rgmii_delay |= DP83822_TX_CLK_SHIFT; 386 387 if (rgmii_delay) { 388 err = phy_set_bits_mmd(phydev, DP83822_DEVADDR, 389 MII_DP83822_RCSR, rgmii_delay); 390 if (err) 391 return err; 392 } 393 } 394 395 if (dp83822->fx_enabled) { 396 err = phy_modify(phydev, MII_DP83822_CTRL_2, 397 DP83822_FX_ENABLE, 1); 398 if (err < 0) 399 return err; 400 401 /* Only allow advertising what this PHY supports */ 402 linkmode_and(phydev->advertising, phydev->advertising, 403 phydev->supported); 404 405 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 406 phydev->supported); 407 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 408 phydev->advertising); 409 410 /* Auto neg is not supported in fiber mode */ 411 bmcr = phy_read(phydev, MII_BMCR); 412 if (bmcr < 0) 413 return bmcr; 414 415 if (bmcr & BMCR_ANENABLE) { 416 err = phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0); 417 if (err < 0) 418 return err; 419 } 420 phydev->autoneg = AUTONEG_DISABLE; 421 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, 422 phydev->supported); 423 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, 424 phydev->advertising); 425 426 /* Setup fiber advertisement */ 427 err = phy_modify_changed(phydev, MII_ADVERTISE, 428 MII_DP83822_FIBER_ADVERTISE, 429 MII_DP83822_FIBER_ADVERTISE); 430 431 if (err < 0) 432 return err; 433 434 if (dp83822->fx_signal_det_low) { 435 err = phy_set_bits_mmd(phydev, DP83822_DEVADDR, 436 MII_DP83822_GENCFG, 437 DP83822_SIG_DET_LOW); 438 if (err) 439 return err; 440 } 441 } 442 return dp8382x_disable_wol(phydev); 443 } 444 445 static int dp8382x_config_init(struct phy_device *phydev) 446 { 447 return dp8382x_disable_wol(phydev); 448 } 449 450 static int dp83822_phy_reset(struct phy_device *phydev) 451 { 452 int err; 453 454 err = phy_write(phydev, MII_DP83822_RESET_CTRL, DP83822_SW_RESET); 455 if (err < 0) 456 return err; 457 458 return phydev->drv->config_init(phydev); 459 } 460 461 #ifdef CONFIG_OF_MDIO 462 static int dp83822_of_init(struct phy_device *phydev) 463 { 464 struct dp83822_private *dp83822 = phydev->priv; 465 struct device *dev = &phydev->mdio.dev; 466 467 /* Signal detection for the PHY is only enabled if the FX_EN and the 468 * SD_EN pins are strapped. Signal detection can only enabled if FX_EN 469 * is strapped otherwise signal detection is disabled for the PHY. 470 */ 471 if (dp83822->fx_enabled && dp83822->fx_sd_enable) 472 dp83822->fx_signal_det_low = device_property_present(dev, 473 "ti,link-loss-low"); 474 if (!dp83822->fx_enabled) 475 dp83822->fx_enabled = device_property_present(dev, 476 "ti,fiber-mode"); 477 478 return 0; 479 } 480 #else 481 static int dp83822_of_init(struct phy_device *phydev) 482 { 483 return 0; 484 } 485 #endif /* CONFIG_OF_MDIO */ 486 487 static int dp83822_read_straps(struct phy_device *phydev) 488 { 489 struct dp83822_private *dp83822 = phydev->priv; 490 int fx_enabled, fx_sd_enable; 491 int val; 492 493 val = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_SOR1); 494 if (val < 0) 495 return val; 496 497 fx_enabled = (val & DP83822_COL_STRAP_MASK) >> DP83822_COL_SHIFT; 498 if (fx_enabled == DP83822_STRAP_MODE2 || 499 fx_enabled == DP83822_STRAP_MODE3) 500 dp83822->fx_enabled = 1; 501 502 if (dp83822->fx_enabled) { 503 fx_sd_enable = (val & DP83822_RX_ER_STR_MASK) >> DP83822_RX_ER_SHIFT; 504 if (fx_sd_enable == DP83822_STRAP_MODE3 || 505 fx_sd_enable == DP83822_STRAP_MODE4) 506 dp83822->fx_sd_enable = 1; 507 } 508 509 return 0; 510 } 511 512 static int dp83822_probe(struct phy_device *phydev) 513 { 514 struct dp83822_private *dp83822; 515 int ret; 516 517 dp83822 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83822), 518 GFP_KERNEL); 519 if (!dp83822) 520 return -ENOMEM; 521 522 phydev->priv = dp83822; 523 524 ret = dp83822_read_straps(phydev); 525 if (ret) 526 return ret; 527 528 dp83822_of_init(phydev); 529 530 return 0; 531 } 532 533 static int dp83822_suspend(struct phy_device *phydev) 534 { 535 int value; 536 537 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG); 538 539 if (!(value & DP83822_WOL_EN)) 540 genphy_suspend(phydev); 541 542 return 0; 543 } 544 545 static int dp83822_resume(struct phy_device *phydev) 546 { 547 int value; 548 549 genphy_resume(phydev); 550 551 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG); 552 553 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, value | 554 DP83822_WOL_CLR_INDICATION); 555 556 return 0; 557 } 558 559 #define DP83822_PHY_DRIVER(_id, _name) \ 560 { \ 561 PHY_ID_MATCH_MODEL(_id), \ 562 .name = (_name), \ 563 /* PHY_BASIC_FEATURES */ \ 564 .probe = dp83822_probe, \ 565 .soft_reset = dp83822_phy_reset, \ 566 .config_init = dp83822_config_init, \ 567 .read_status = dp83822_read_status, \ 568 .get_wol = dp83822_get_wol, \ 569 .set_wol = dp83822_set_wol, \ 570 .ack_interrupt = dp83822_ack_interrupt, \ 571 .config_intr = dp83822_config_intr, \ 572 .suspend = dp83822_suspend, \ 573 .resume = dp83822_resume, \ 574 } 575 576 #define DP8382X_PHY_DRIVER(_id, _name) \ 577 { \ 578 PHY_ID_MATCH_MODEL(_id), \ 579 .name = (_name), \ 580 /* PHY_BASIC_FEATURES */ \ 581 .soft_reset = dp83822_phy_reset, \ 582 .config_init = dp8382x_config_init, \ 583 .get_wol = dp83822_get_wol, \ 584 .set_wol = dp83822_set_wol, \ 585 .ack_interrupt = dp83822_ack_interrupt, \ 586 .config_intr = dp83822_config_intr, \ 587 .suspend = dp83822_suspend, \ 588 .resume = dp83822_resume, \ 589 } 590 591 static struct phy_driver dp83822_driver[] = { 592 DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"), 593 DP8382X_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"), 594 DP8382X_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"), 595 DP8382X_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"), 596 DP8382X_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"), 597 DP8382X_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"), 598 DP8382X_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"), 599 }; 600 module_phy_driver(dp83822_driver); 601 602 static struct mdio_device_id __maybe_unused dp83822_tbl[] = { 603 { DP83822_PHY_ID, 0xfffffff0 }, 604 { DP83825I_PHY_ID, 0xfffffff0 }, 605 { DP83826C_PHY_ID, 0xfffffff0 }, 606 { DP83826NC_PHY_ID, 0xfffffff0 }, 607 { DP83825S_PHY_ID, 0xfffffff0 }, 608 { DP83825CM_PHY_ID, 0xfffffff0 }, 609 { DP83825CS_PHY_ID, 0xfffffff0 }, 610 { }, 611 }; 612 MODULE_DEVICE_TABLE(mdio, dp83822_tbl); 613 614 MODULE_DESCRIPTION("Texas Instruments DP83822 PHY driver"); 615 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com"); 616 MODULE_LICENSE("GPL v2"); 617