1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * drivers/net/phy/broadcom.c 4 * 5 * Broadcom BCM5411, BCM5421 and BCM5461 Gigabit Ethernet 6 * transceivers. 7 * 8 * Copyright (c) 2006 Maciej W. Rozycki 9 * 10 * Inspired by code written by Amy Fong. 11 */ 12 13 #include "bcm-phy-lib.h" 14 #include <linux/delay.h> 15 #include <linux/module.h> 16 #include <linux/phy.h> 17 #include <linux/brcmphy.h> 18 #include <linux/of.h> 19 20 #define BRCM_PHY_MODEL(phydev) \ 21 ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask) 22 23 #define BRCM_PHY_REV(phydev) \ 24 ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask)) 25 26 MODULE_DESCRIPTION("Broadcom PHY driver"); 27 MODULE_AUTHOR("Maciej W. Rozycki"); 28 MODULE_LICENSE("GPL"); 29 30 struct bcm54xx_phy_priv { 31 u64 *stats; 32 struct bcm_ptp_private *ptp; 33 }; 34 35 static int bcm54xx_config_clock_delay(struct phy_device *phydev) 36 { 37 int rc, val; 38 39 /* handling PHY's internal RX clock delay */ 40 val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); 41 val |= MII_BCM54XX_AUXCTL_MISC_WREN; 42 if (phydev->interface == PHY_INTERFACE_MODE_RGMII || 43 phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { 44 /* Disable RGMII RXC-RXD skew */ 45 val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; 46 } 47 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || 48 phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { 49 /* Enable RGMII RXC-RXD skew */ 50 val |= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; 51 } 52 rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, 53 val); 54 if (rc < 0) 55 return rc; 56 57 /* handling PHY's internal TX clock delay */ 58 val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL); 59 if (phydev->interface == PHY_INTERFACE_MODE_RGMII || 60 phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { 61 /* Disable internal TX clock delay */ 62 val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; 63 } 64 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || 65 phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { 66 /* Enable internal TX clock delay */ 67 val |= BCM54810_SHD_CLK_CTL_GTXCLK_EN; 68 } 69 rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); 70 if (rc < 0) 71 return rc; 72 73 return 0; 74 } 75 76 static int bcm54210e_config_init(struct phy_device *phydev) 77 { 78 int val; 79 80 bcm54xx_config_clock_delay(phydev); 81 82 if (phydev->dev_flags & PHY_BRCM_EN_MASTER_MODE) { 83 val = phy_read(phydev, MII_CTRL1000); 84 val |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER; 85 phy_write(phydev, MII_CTRL1000, val); 86 } 87 88 return 0; 89 } 90 91 static int bcm54612e_config_init(struct phy_device *phydev) 92 { 93 int reg; 94 95 bcm54xx_config_clock_delay(phydev); 96 97 /* Enable CLK125 MUX on LED4 if ref clock is enabled. */ 98 if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) { 99 int err; 100 101 reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0); 102 err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0, 103 BCM54612E_LED4_CLK125OUT_EN | reg); 104 105 if (err < 0) 106 return err; 107 } 108 109 return 0; 110 } 111 112 static int bcm54616s_config_init(struct phy_device *phydev) 113 { 114 int rc, val; 115 116 if (phydev->interface != PHY_INTERFACE_MODE_SGMII && 117 phydev->interface != PHY_INTERFACE_MODE_1000BASEX) 118 return 0; 119 120 /* Ensure proper interface mode is selected. */ 121 /* Disable RGMII mode */ 122 val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); 123 if (val < 0) 124 return val; 125 val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_EN; 126 val |= MII_BCM54XX_AUXCTL_MISC_WREN; 127 rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, 128 val); 129 if (rc < 0) 130 return rc; 131 132 /* Select 1000BASE-X register set (primary SerDes) */ 133 val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE); 134 if (val < 0) 135 return val; 136 val |= BCM54XX_SHD_MODE_1000BX; 137 rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val); 138 if (rc < 0) 139 return rc; 140 141 /* Power down SerDes interface */ 142 rc = phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN); 143 if (rc < 0) 144 return rc; 145 146 /* Select proper interface mode */ 147 val &= ~BCM54XX_SHD_INTF_SEL_MASK; 148 val |= phydev->interface == PHY_INTERFACE_MODE_SGMII ? 149 BCM54XX_SHD_INTF_SEL_SGMII : 150 BCM54XX_SHD_INTF_SEL_GBIC; 151 rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val); 152 if (rc < 0) 153 return rc; 154 155 /* Power up SerDes interface */ 156 rc = phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN); 157 if (rc < 0) 158 return rc; 159 160 /* Select copper register set */ 161 val &= ~BCM54XX_SHD_MODE_1000BX; 162 rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val); 163 if (rc < 0) 164 return rc; 165 166 /* Power up copper interface */ 167 return phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN); 168 } 169 170 /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */ 171 static int bcm50610_a0_workaround(struct phy_device *phydev) 172 { 173 int err; 174 175 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH0, 176 MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN | 177 MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF); 178 if (err < 0) 179 return err; 180 181 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH3, 182 MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ); 183 if (err < 0) 184 return err; 185 186 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP75, 187 MII_BCM54XX_EXP_EXP75_VDACCTRL); 188 if (err < 0) 189 return err; 190 191 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP96, 192 MII_BCM54XX_EXP_EXP96_MYST); 193 if (err < 0) 194 return err; 195 196 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP97, 197 MII_BCM54XX_EXP_EXP97_MYST); 198 199 return err; 200 } 201 202 static int bcm54xx_phydsp_config(struct phy_device *phydev) 203 { 204 int err, err2; 205 206 /* Enable the SMDSP clock */ 207 err = bcm54xx_auxctl_write(phydev, 208 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL, 209 MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA | 210 MII_BCM54XX_AUXCTL_ACTL_TX_6DB); 211 if (err < 0) 212 return err; 213 214 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || 215 BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) { 216 /* Clear bit 9 to fix a phy interop issue. */ 217 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08, 218 MII_BCM54XX_EXP_EXP08_RJCT_2MHZ); 219 if (err < 0) 220 goto error; 221 222 if (phydev->drv->phy_id == PHY_ID_BCM50610) { 223 err = bcm50610_a0_workaround(phydev); 224 if (err < 0) 225 goto error; 226 } 227 } 228 229 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) { 230 int val; 231 232 val = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP75); 233 if (val < 0) 234 goto error; 235 236 val |= MII_BCM54XX_EXP_EXP75_CM_OSC; 237 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP75, val); 238 } 239 240 error: 241 /* Disable the SMDSP clock */ 242 err2 = bcm54xx_auxctl_write(phydev, 243 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL, 244 MII_BCM54XX_AUXCTL_ACTL_TX_6DB); 245 246 /* Return the first error reported. */ 247 return err ? err : err2; 248 } 249 250 static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) 251 { 252 u32 orig; 253 int val; 254 bool clk125en = true; 255 256 /* Abort if we are using an untested phy. */ 257 if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 && 258 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 && 259 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M && 260 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54210E && 261 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54810 && 262 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54811) 263 return; 264 265 val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3); 266 if (val < 0) 267 return; 268 269 orig = val; 270 271 if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || 272 BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) && 273 BRCM_PHY_REV(phydev) >= 0x3) { 274 /* 275 * Here, bit 0 _disables_ CLK125 when set. 276 * This bit is set by default. 277 */ 278 clk125en = false; 279 } else { 280 if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) { 281 if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54811) { 282 /* Here, bit 0 _enables_ CLK125 when set */ 283 val &= ~BCM54XX_SHD_SCR3_DEF_CLK125; 284 } 285 clk125en = false; 286 } 287 } 288 289 if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) 290 val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS; 291 else 292 val |= BCM54XX_SHD_SCR3_DLLAPD_DIS; 293 294 if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) { 295 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E || 296 BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810 || 297 BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54811) 298 val |= BCM54XX_SHD_SCR3_RXCTXC_DIS; 299 else 300 val |= BCM54XX_SHD_SCR3_TRDDAPD; 301 } 302 303 if (orig != val) 304 bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, val); 305 306 val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_APD); 307 if (val < 0) 308 return; 309 310 orig = val; 311 312 if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) 313 val |= BCM54XX_SHD_APD_EN; 314 else 315 val &= ~BCM54XX_SHD_APD_EN; 316 317 if (orig != val) 318 bcm_phy_write_shadow(phydev, BCM54XX_SHD_APD, val); 319 } 320 321 static void bcm54xx_ptp_stop(struct phy_device *phydev) 322 { 323 struct bcm54xx_phy_priv *priv = phydev->priv; 324 325 if (priv->ptp) 326 bcm_ptp_stop(priv->ptp); 327 } 328 329 static void bcm54xx_ptp_config_init(struct phy_device *phydev) 330 { 331 struct bcm54xx_phy_priv *priv = phydev->priv; 332 333 if (priv->ptp) 334 bcm_ptp_config_init(phydev); 335 } 336 337 static int bcm54xx_config_init(struct phy_device *phydev) 338 { 339 int reg, err, val; 340 341 reg = phy_read(phydev, MII_BCM54XX_ECR); 342 if (reg < 0) 343 return reg; 344 345 /* Mask interrupts globally. */ 346 reg |= MII_BCM54XX_ECR_IM; 347 err = phy_write(phydev, MII_BCM54XX_ECR, reg); 348 if (err < 0) 349 return err; 350 351 /* Unmask events we are interested in. */ 352 reg = ~(MII_BCM54XX_INT_DUPLEX | 353 MII_BCM54XX_INT_SPEED | 354 MII_BCM54XX_INT_LINK); 355 err = phy_write(phydev, MII_BCM54XX_IMR, reg); 356 if (err < 0) 357 return err; 358 359 if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || 360 BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) && 361 (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE)) 362 bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0); 363 364 bcm54xx_adjust_rxrefclk(phydev); 365 366 switch (BRCM_PHY_MODEL(phydev)) { 367 case PHY_ID_BCM50610: 368 case PHY_ID_BCM50610M: 369 err = bcm54xx_config_clock_delay(phydev); 370 break; 371 case PHY_ID_BCM54210E: 372 err = bcm54210e_config_init(phydev); 373 break; 374 case PHY_ID_BCM54612E: 375 err = bcm54612e_config_init(phydev); 376 break; 377 case PHY_ID_BCM54616S: 378 err = bcm54616s_config_init(phydev); 379 break; 380 case PHY_ID_BCM54810: 381 /* For BCM54810, we need to disable BroadR-Reach function */ 382 val = bcm_phy_read_exp(phydev, 383 BCM54810_EXP_BROADREACH_LRE_MISC_CTL); 384 val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN; 385 err = bcm_phy_write_exp(phydev, 386 BCM54810_EXP_BROADREACH_LRE_MISC_CTL, 387 val); 388 break; 389 } 390 if (err) 391 return err; 392 393 bcm54xx_phydsp_config(phydev); 394 395 /* For non-SFP setups, encode link speed into LED1 and LED3 pair 396 * (green/amber). 397 * Also flash these two LEDs on activity. This means configuring 398 * them for MULTICOLOR and encoding link/activity into them. 399 * Don't do this for devices on an SFP module, since some of these 400 * use the LED outputs to control the SFP LOS signal, and changing 401 * these settings will cause LOS to malfunction. 402 */ 403 if (!phy_on_sfp(phydev)) { 404 val = BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_MULTICOLOR1) | 405 BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1); 406 bcm_phy_write_shadow(phydev, BCM5482_SHD_LEDS1, val); 407 408 val = BCM_LED_MULTICOLOR_IN_PHASE | 409 BCM5482_SHD_LEDS1_LED1(BCM_LED_MULTICOLOR_LINK_ACT) | 410 BCM5482_SHD_LEDS1_LED3(BCM_LED_MULTICOLOR_LINK_ACT); 411 bcm_phy_write_exp(phydev, BCM_EXP_MULTICOLOR, val); 412 } 413 414 bcm54xx_ptp_config_init(phydev); 415 416 return 0; 417 } 418 419 static int bcm54xx_iddq_set(struct phy_device *phydev, bool enable) 420 { 421 int ret = 0; 422 423 if (!(phydev->dev_flags & PHY_BRCM_IDDQ_SUSPEND)) 424 return ret; 425 426 ret = bcm_phy_read_exp(phydev, BCM54XX_TOP_MISC_IDDQ_CTRL); 427 if (ret < 0) 428 goto out; 429 430 if (enable) 431 ret |= BCM54XX_TOP_MISC_IDDQ_SR | BCM54XX_TOP_MISC_IDDQ_LP; 432 else 433 ret &= ~(BCM54XX_TOP_MISC_IDDQ_SR | BCM54XX_TOP_MISC_IDDQ_LP); 434 435 ret = bcm_phy_write_exp(phydev, BCM54XX_TOP_MISC_IDDQ_CTRL, ret); 436 out: 437 return ret; 438 } 439 440 static int bcm54xx_suspend(struct phy_device *phydev) 441 { 442 int ret; 443 444 bcm54xx_ptp_stop(phydev); 445 446 /* We cannot use a read/modify/write here otherwise the PHY gets into 447 * a bad state where its LEDs keep flashing, thus defeating the purpose 448 * of low power mode. 449 */ 450 ret = phy_write(phydev, MII_BMCR, BMCR_PDOWN); 451 if (ret < 0) 452 return ret; 453 454 return bcm54xx_iddq_set(phydev, true); 455 } 456 457 static int bcm54xx_resume(struct phy_device *phydev) 458 { 459 int ret; 460 461 ret = bcm54xx_iddq_set(phydev, false); 462 if (ret < 0) 463 return ret; 464 465 /* Writes to register other than BMCR would be ignored 466 * unless we clear the PDOWN bit first 467 */ 468 ret = genphy_resume(phydev); 469 if (ret < 0) 470 return ret; 471 472 /* Upon exiting power down, the PHY remains in an internal reset state 473 * for 40us 474 */ 475 fsleep(40); 476 477 /* Issue a soft reset after clearing the power down bit 478 * and before doing any other configuration. 479 */ 480 if (phydev->dev_flags & PHY_BRCM_IDDQ_SUSPEND) { 481 ret = genphy_soft_reset(phydev); 482 if (ret < 0) 483 return ret; 484 } 485 486 return bcm54xx_config_init(phydev); 487 } 488 489 static int bcm54811_config_init(struct phy_device *phydev) 490 { 491 int err, reg; 492 493 /* Disable BroadR-Reach function. */ 494 reg = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL); 495 reg &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN; 496 err = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL, 497 reg); 498 if (err < 0) 499 return err; 500 501 err = bcm54xx_config_init(phydev); 502 503 /* Enable CLK125 MUX on LED4 if ref clock is enabled. */ 504 if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) { 505 reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0); 506 err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0, 507 BCM54612E_LED4_CLK125OUT_EN | reg); 508 if (err < 0) 509 return err; 510 } 511 512 return err; 513 } 514 515 static int bcm5481_config_aneg(struct phy_device *phydev) 516 { 517 struct device_node *np = phydev->mdio.dev.of_node; 518 int ret; 519 520 /* Aneg firstly. */ 521 ret = genphy_config_aneg(phydev); 522 523 /* Then we can set up the delay. */ 524 bcm54xx_config_clock_delay(phydev); 525 526 if (of_property_read_bool(np, "enet-phy-lane-swap")) { 527 /* Lane Swap - Undocumented register...magic! */ 528 ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9, 529 0x11B); 530 if (ret < 0) 531 return ret; 532 } 533 534 return ret; 535 } 536 537 struct bcm54616s_phy_priv { 538 bool mode_1000bx_en; 539 }; 540 541 static int bcm54616s_probe(struct phy_device *phydev) 542 { 543 struct bcm54616s_phy_priv *priv; 544 int val; 545 546 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 547 if (!priv) 548 return -ENOMEM; 549 550 phydev->priv = priv; 551 552 val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE); 553 if (val < 0) 554 return val; 555 556 /* The PHY is strapped in RGMII-fiber mode when INTERF_SEL[1:0] 557 * is 01b, and the link between PHY and its link partner can be 558 * either 1000Base-X or 100Base-FX. 559 * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX 560 * support is still missing as of now. 561 */ 562 if ((val & BCM54XX_SHD_INTF_SEL_MASK) == BCM54XX_SHD_INTF_SEL_RGMII) { 563 val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL); 564 if (val < 0) 565 return val; 566 567 /* Bit 0 of the SerDes 100-FX Control register, when set 568 * to 1, sets the MII/RGMII -> 100BASE-FX configuration. 569 * When this bit is set to 0, it sets the GMII/RGMII -> 570 * 1000BASE-X configuration. 571 */ 572 if (!(val & BCM54616S_100FX_MODE)) 573 priv->mode_1000bx_en = true; 574 575 phydev->port = PORT_FIBRE; 576 } 577 578 return 0; 579 } 580 581 static int bcm54616s_config_aneg(struct phy_device *phydev) 582 { 583 struct bcm54616s_phy_priv *priv = phydev->priv; 584 int ret; 585 586 /* Aneg firstly. */ 587 if (priv->mode_1000bx_en) 588 ret = genphy_c37_config_aneg(phydev); 589 else 590 ret = genphy_config_aneg(phydev); 591 592 /* Then we can set up the delay. */ 593 bcm54xx_config_clock_delay(phydev); 594 595 return ret; 596 } 597 598 static int bcm54616s_read_status(struct phy_device *phydev) 599 { 600 struct bcm54616s_phy_priv *priv = phydev->priv; 601 int err; 602 603 if (priv->mode_1000bx_en) 604 err = genphy_c37_read_status(phydev); 605 else 606 err = genphy_read_status(phydev); 607 608 return err; 609 } 610 611 static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set) 612 { 613 int val; 614 615 val = phy_read(phydev, reg); 616 if (val < 0) 617 return val; 618 619 return phy_write(phydev, reg, val | set); 620 } 621 622 static int brcm_fet_config_init(struct phy_device *phydev) 623 { 624 int reg, err, err2, brcmtest; 625 626 /* Reset the PHY to bring it to a known state. */ 627 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 628 if (err < 0) 629 return err; 630 631 /* The datasheet indicates the PHY needs up to 1us to complete a reset, 632 * build some slack here. 633 */ 634 usleep_range(1000, 2000); 635 636 /* The PHY requires 65 MDC clock cycles to complete a write operation 637 * and turnaround the line properly. 638 * 639 * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac) 640 * may flag the lack of turn-around as a read failure. This is 641 * particularly true with this combination since the MDIO controller 642 * only used 64 MDC cycles. This is not a critical failure in this 643 * specific case and it has no functional impact otherwise, so we let 644 * that one go through. If there is a genuine bus error, the next read 645 * of MII_BRCM_FET_INTREG will error out. 646 */ 647 err = phy_read(phydev, MII_BMCR); 648 if (err < 0 && err != -EIO) 649 return err; 650 651 reg = phy_read(phydev, MII_BRCM_FET_INTREG); 652 if (reg < 0) 653 return reg; 654 655 /* Unmask events we are interested in and mask interrupts globally. */ 656 reg = MII_BRCM_FET_IR_DUPLEX_EN | 657 MII_BRCM_FET_IR_SPEED_EN | 658 MII_BRCM_FET_IR_LINK_EN | 659 MII_BRCM_FET_IR_ENABLE | 660 MII_BRCM_FET_IR_MASK; 661 662 err = phy_write(phydev, MII_BRCM_FET_INTREG, reg); 663 if (err < 0) 664 return err; 665 666 /* Enable shadow register access */ 667 brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST); 668 if (brcmtest < 0) 669 return brcmtest; 670 671 reg = brcmtest | MII_BRCM_FET_BT_SRE; 672 673 err = phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg); 674 if (err < 0) 675 return err; 676 677 /* Set the LED mode */ 678 reg = phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4); 679 if (reg < 0) { 680 err = reg; 681 goto done; 682 } 683 684 reg &= ~MII_BRCM_FET_SHDW_AM4_LED_MASK; 685 reg |= MII_BRCM_FET_SHDW_AM4_LED_MODE1; 686 687 err = phy_write(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg); 688 if (err < 0) 689 goto done; 690 691 /* Enable auto MDIX */ 692 err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_MISCCTRL, 693 MII_BRCM_FET_SHDW_MC_FAME); 694 if (err < 0) 695 goto done; 696 697 if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) { 698 /* Enable auto power down */ 699 err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2, 700 MII_BRCM_FET_SHDW_AS2_APDE); 701 } 702 703 done: 704 /* Disable shadow register access */ 705 err2 = phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest); 706 if (!err) 707 err = err2; 708 709 return err; 710 } 711 712 static int brcm_fet_ack_interrupt(struct phy_device *phydev) 713 { 714 int reg; 715 716 /* Clear pending interrupts. */ 717 reg = phy_read(phydev, MII_BRCM_FET_INTREG); 718 if (reg < 0) 719 return reg; 720 721 return 0; 722 } 723 724 static int brcm_fet_config_intr(struct phy_device *phydev) 725 { 726 int reg, err; 727 728 reg = phy_read(phydev, MII_BRCM_FET_INTREG); 729 if (reg < 0) 730 return reg; 731 732 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { 733 err = brcm_fet_ack_interrupt(phydev); 734 if (err) 735 return err; 736 737 reg &= ~MII_BRCM_FET_IR_MASK; 738 err = phy_write(phydev, MII_BRCM_FET_INTREG, reg); 739 } else { 740 reg |= MII_BRCM_FET_IR_MASK; 741 err = phy_write(phydev, MII_BRCM_FET_INTREG, reg); 742 if (err) 743 return err; 744 745 err = brcm_fet_ack_interrupt(phydev); 746 } 747 748 return err; 749 } 750 751 static irqreturn_t brcm_fet_handle_interrupt(struct phy_device *phydev) 752 { 753 int irq_status; 754 755 irq_status = phy_read(phydev, MII_BRCM_FET_INTREG); 756 if (irq_status < 0) { 757 phy_error(phydev); 758 return IRQ_NONE; 759 } 760 761 if (irq_status == 0) 762 return IRQ_NONE; 763 764 phy_trigger_machine(phydev); 765 766 return IRQ_HANDLED; 767 } 768 769 static int brcm_fet_suspend(struct phy_device *phydev) 770 { 771 int reg, err, err2, brcmtest; 772 773 /* We cannot use a read/modify/write here otherwise the PHY continues 774 * to drive LEDs which defeats the purpose of low power mode. 775 */ 776 err = phy_write(phydev, MII_BMCR, BMCR_PDOWN); 777 if (err < 0) 778 return err; 779 780 /* Enable shadow register access */ 781 brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST); 782 if (brcmtest < 0) 783 return brcmtest; 784 785 reg = brcmtest | MII_BRCM_FET_BT_SRE; 786 787 err = phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg); 788 if (err < 0) 789 return err; 790 791 /* Set standby mode */ 792 err = phy_modify(phydev, MII_BRCM_FET_SHDW_AUXMODE4, 793 MII_BRCM_FET_SHDW_AM4_STANDBY, 794 MII_BRCM_FET_SHDW_AM4_STANDBY); 795 796 /* Disable shadow register access */ 797 err2 = phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest); 798 if (!err) 799 err = err2; 800 801 return err; 802 } 803 804 static int bcm54xx_phy_probe(struct phy_device *phydev) 805 { 806 struct bcm54xx_phy_priv *priv; 807 808 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 809 if (!priv) 810 return -ENOMEM; 811 812 phydev->priv = priv; 813 814 priv->stats = devm_kcalloc(&phydev->mdio.dev, 815 bcm_phy_get_sset_count(phydev), sizeof(u64), 816 GFP_KERNEL); 817 if (!priv->stats) 818 return -ENOMEM; 819 820 priv->ptp = bcm_ptp_probe(phydev); 821 if (IS_ERR(priv->ptp)) 822 return PTR_ERR(priv->ptp); 823 824 return 0; 825 } 826 827 static void bcm54xx_get_stats(struct phy_device *phydev, 828 struct ethtool_stats *stats, u64 *data) 829 { 830 struct bcm54xx_phy_priv *priv = phydev->priv; 831 832 bcm_phy_get_stats(phydev, priv->stats, stats, data); 833 } 834 835 static void bcm54xx_link_change_notify(struct phy_device *phydev) 836 { 837 u16 mask = MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE | 838 MII_BCM54XX_EXP_EXP08_FORCE_DAC_WAKE; 839 int ret; 840 841 if (phydev->state != PHY_RUNNING) 842 return; 843 844 /* Don't change the DAC wake settings if auto power down 845 * is not requested. 846 */ 847 if (!(phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) 848 return; 849 850 ret = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP08); 851 if (ret < 0) 852 return; 853 854 /* Enable/disable 10BaseT auto and forced early DAC wake depending 855 * on the negotiated speed, those settings should only be done 856 * for 10Mbits/sec. 857 */ 858 if (phydev->speed == SPEED_10) 859 ret |= mask; 860 else 861 ret &= ~mask; 862 bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08, ret); 863 } 864 865 static struct phy_driver broadcom_drivers[] = { 866 { 867 .phy_id = PHY_ID_BCM5411, 868 .phy_id_mask = 0xfffffff0, 869 .name = "Broadcom BCM5411", 870 /* PHY_GBIT_FEATURES */ 871 .get_sset_count = bcm_phy_get_sset_count, 872 .get_strings = bcm_phy_get_strings, 873 .get_stats = bcm54xx_get_stats, 874 .probe = bcm54xx_phy_probe, 875 .config_init = bcm54xx_config_init, 876 .config_intr = bcm_phy_config_intr, 877 .handle_interrupt = bcm_phy_handle_interrupt, 878 .link_change_notify = bcm54xx_link_change_notify, 879 }, { 880 .phy_id = PHY_ID_BCM5421, 881 .phy_id_mask = 0xfffffff0, 882 .name = "Broadcom BCM5421", 883 /* PHY_GBIT_FEATURES */ 884 .get_sset_count = bcm_phy_get_sset_count, 885 .get_strings = bcm_phy_get_strings, 886 .get_stats = bcm54xx_get_stats, 887 .probe = bcm54xx_phy_probe, 888 .config_init = bcm54xx_config_init, 889 .config_intr = bcm_phy_config_intr, 890 .handle_interrupt = bcm_phy_handle_interrupt, 891 .link_change_notify = bcm54xx_link_change_notify, 892 }, { 893 .phy_id = PHY_ID_BCM54210E, 894 .phy_id_mask = 0xfffffff0, 895 .name = "Broadcom BCM54210E", 896 /* PHY_GBIT_FEATURES */ 897 .get_sset_count = bcm_phy_get_sset_count, 898 .get_strings = bcm_phy_get_strings, 899 .get_stats = bcm54xx_get_stats, 900 .probe = bcm54xx_phy_probe, 901 .config_init = bcm54xx_config_init, 902 .config_intr = bcm_phy_config_intr, 903 .handle_interrupt = bcm_phy_handle_interrupt, 904 .link_change_notify = bcm54xx_link_change_notify, 905 .suspend = bcm54xx_suspend, 906 .resume = bcm54xx_resume, 907 }, { 908 .phy_id = PHY_ID_BCM5461, 909 .phy_id_mask = 0xfffffff0, 910 .name = "Broadcom BCM5461", 911 /* PHY_GBIT_FEATURES */ 912 .get_sset_count = bcm_phy_get_sset_count, 913 .get_strings = bcm_phy_get_strings, 914 .get_stats = bcm54xx_get_stats, 915 .probe = bcm54xx_phy_probe, 916 .config_init = bcm54xx_config_init, 917 .config_intr = bcm_phy_config_intr, 918 .handle_interrupt = bcm_phy_handle_interrupt, 919 .link_change_notify = bcm54xx_link_change_notify, 920 }, { 921 .phy_id = PHY_ID_BCM54612E, 922 .phy_id_mask = 0xfffffff0, 923 .name = "Broadcom BCM54612E", 924 /* PHY_GBIT_FEATURES */ 925 .get_sset_count = bcm_phy_get_sset_count, 926 .get_strings = bcm_phy_get_strings, 927 .get_stats = bcm54xx_get_stats, 928 .probe = bcm54xx_phy_probe, 929 .config_init = bcm54xx_config_init, 930 .config_intr = bcm_phy_config_intr, 931 .handle_interrupt = bcm_phy_handle_interrupt, 932 .link_change_notify = bcm54xx_link_change_notify, 933 }, { 934 .phy_id = PHY_ID_BCM54616S, 935 .phy_id_mask = 0xfffffff0, 936 .name = "Broadcom BCM54616S", 937 /* PHY_GBIT_FEATURES */ 938 .soft_reset = genphy_soft_reset, 939 .config_init = bcm54xx_config_init, 940 .config_aneg = bcm54616s_config_aneg, 941 .config_intr = bcm_phy_config_intr, 942 .handle_interrupt = bcm_phy_handle_interrupt, 943 .read_status = bcm54616s_read_status, 944 .probe = bcm54616s_probe, 945 .link_change_notify = bcm54xx_link_change_notify, 946 }, { 947 .phy_id = PHY_ID_BCM5464, 948 .phy_id_mask = 0xfffffff0, 949 .name = "Broadcom BCM5464", 950 /* PHY_GBIT_FEATURES */ 951 .get_sset_count = bcm_phy_get_sset_count, 952 .get_strings = bcm_phy_get_strings, 953 .get_stats = bcm54xx_get_stats, 954 .probe = bcm54xx_phy_probe, 955 .config_init = bcm54xx_config_init, 956 .config_intr = bcm_phy_config_intr, 957 .handle_interrupt = bcm_phy_handle_interrupt, 958 .suspend = genphy_suspend, 959 .resume = genphy_resume, 960 .link_change_notify = bcm54xx_link_change_notify, 961 }, { 962 .phy_id = PHY_ID_BCM5481, 963 .phy_id_mask = 0xfffffff0, 964 .name = "Broadcom BCM5481", 965 /* PHY_GBIT_FEATURES */ 966 .get_sset_count = bcm_phy_get_sset_count, 967 .get_strings = bcm_phy_get_strings, 968 .get_stats = bcm54xx_get_stats, 969 .probe = bcm54xx_phy_probe, 970 .config_init = bcm54xx_config_init, 971 .config_aneg = bcm5481_config_aneg, 972 .config_intr = bcm_phy_config_intr, 973 .handle_interrupt = bcm_phy_handle_interrupt, 974 .link_change_notify = bcm54xx_link_change_notify, 975 }, { 976 .phy_id = PHY_ID_BCM54810, 977 .phy_id_mask = 0xfffffff0, 978 .name = "Broadcom BCM54810", 979 /* PHY_GBIT_FEATURES */ 980 .get_sset_count = bcm_phy_get_sset_count, 981 .get_strings = bcm_phy_get_strings, 982 .get_stats = bcm54xx_get_stats, 983 .probe = bcm54xx_phy_probe, 984 .config_init = bcm54xx_config_init, 985 .config_aneg = bcm5481_config_aneg, 986 .config_intr = bcm_phy_config_intr, 987 .handle_interrupt = bcm_phy_handle_interrupt, 988 .suspend = bcm54xx_suspend, 989 .resume = bcm54xx_resume, 990 .link_change_notify = bcm54xx_link_change_notify, 991 }, { 992 .phy_id = PHY_ID_BCM54811, 993 .phy_id_mask = 0xfffffff0, 994 .name = "Broadcom BCM54811", 995 /* PHY_GBIT_FEATURES */ 996 .get_sset_count = bcm_phy_get_sset_count, 997 .get_strings = bcm_phy_get_strings, 998 .get_stats = bcm54xx_get_stats, 999 .probe = bcm54xx_phy_probe, 1000 .config_init = bcm54811_config_init, 1001 .config_aneg = bcm5481_config_aneg, 1002 .config_intr = bcm_phy_config_intr, 1003 .handle_interrupt = bcm_phy_handle_interrupt, 1004 .suspend = bcm54xx_suspend, 1005 .resume = bcm54xx_resume, 1006 .link_change_notify = bcm54xx_link_change_notify, 1007 }, { 1008 .phy_id = PHY_ID_BCM5482, 1009 .phy_id_mask = 0xfffffff0, 1010 .name = "Broadcom BCM5482", 1011 /* PHY_GBIT_FEATURES */ 1012 .get_sset_count = bcm_phy_get_sset_count, 1013 .get_strings = bcm_phy_get_strings, 1014 .get_stats = bcm54xx_get_stats, 1015 .probe = bcm54xx_phy_probe, 1016 .config_init = bcm54xx_config_init, 1017 .config_intr = bcm_phy_config_intr, 1018 .handle_interrupt = bcm_phy_handle_interrupt, 1019 .link_change_notify = bcm54xx_link_change_notify, 1020 }, { 1021 .phy_id = PHY_ID_BCM50610, 1022 .phy_id_mask = 0xfffffff0, 1023 .name = "Broadcom BCM50610", 1024 /* PHY_GBIT_FEATURES */ 1025 .get_sset_count = bcm_phy_get_sset_count, 1026 .get_strings = bcm_phy_get_strings, 1027 .get_stats = bcm54xx_get_stats, 1028 .probe = bcm54xx_phy_probe, 1029 .config_init = bcm54xx_config_init, 1030 .config_intr = bcm_phy_config_intr, 1031 .handle_interrupt = bcm_phy_handle_interrupt, 1032 .link_change_notify = bcm54xx_link_change_notify, 1033 .suspend = bcm54xx_suspend, 1034 .resume = bcm54xx_resume, 1035 }, { 1036 .phy_id = PHY_ID_BCM50610M, 1037 .phy_id_mask = 0xfffffff0, 1038 .name = "Broadcom BCM50610M", 1039 /* PHY_GBIT_FEATURES */ 1040 .get_sset_count = bcm_phy_get_sset_count, 1041 .get_strings = bcm_phy_get_strings, 1042 .get_stats = bcm54xx_get_stats, 1043 .probe = bcm54xx_phy_probe, 1044 .config_init = bcm54xx_config_init, 1045 .config_intr = bcm_phy_config_intr, 1046 .handle_interrupt = bcm_phy_handle_interrupt, 1047 .link_change_notify = bcm54xx_link_change_notify, 1048 .suspend = bcm54xx_suspend, 1049 .resume = bcm54xx_resume, 1050 }, { 1051 .phy_id = PHY_ID_BCM57780, 1052 .phy_id_mask = 0xfffffff0, 1053 .name = "Broadcom BCM57780", 1054 /* PHY_GBIT_FEATURES */ 1055 .get_sset_count = bcm_phy_get_sset_count, 1056 .get_strings = bcm_phy_get_strings, 1057 .get_stats = bcm54xx_get_stats, 1058 .probe = bcm54xx_phy_probe, 1059 .config_init = bcm54xx_config_init, 1060 .config_intr = bcm_phy_config_intr, 1061 .handle_interrupt = bcm_phy_handle_interrupt, 1062 .link_change_notify = bcm54xx_link_change_notify, 1063 }, { 1064 .phy_id = PHY_ID_BCMAC131, 1065 .phy_id_mask = 0xfffffff0, 1066 .name = "Broadcom BCMAC131", 1067 /* PHY_BASIC_FEATURES */ 1068 .config_init = brcm_fet_config_init, 1069 .config_intr = brcm_fet_config_intr, 1070 .handle_interrupt = brcm_fet_handle_interrupt, 1071 .suspend = brcm_fet_suspend, 1072 .resume = brcm_fet_config_init, 1073 }, { 1074 .phy_id = PHY_ID_BCM5241, 1075 .phy_id_mask = 0xfffffff0, 1076 .name = "Broadcom BCM5241", 1077 /* PHY_BASIC_FEATURES */ 1078 .config_init = brcm_fet_config_init, 1079 .config_intr = brcm_fet_config_intr, 1080 .handle_interrupt = brcm_fet_handle_interrupt, 1081 .suspend = brcm_fet_suspend, 1082 .resume = brcm_fet_config_init, 1083 }, { 1084 .phy_id = PHY_ID_BCM5395, 1085 .phy_id_mask = 0xfffffff0, 1086 .name = "Broadcom BCM5395", 1087 .flags = PHY_IS_INTERNAL, 1088 /* PHY_GBIT_FEATURES */ 1089 .get_sset_count = bcm_phy_get_sset_count, 1090 .get_strings = bcm_phy_get_strings, 1091 .get_stats = bcm54xx_get_stats, 1092 .probe = bcm54xx_phy_probe, 1093 .link_change_notify = bcm54xx_link_change_notify, 1094 }, { 1095 .phy_id = PHY_ID_BCM53125, 1096 .phy_id_mask = 0xfffffff0, 1097 .name = "Broadcom BCM53125", 1098 .flags = PHY_IS_INTERNAL, 1099 /* PHY_GBIT_FEATURES */ 1100 .get_sset_count = bcm_phy_get_sset_count, 1101 .get_strings = bcm_phy_get_strings, 1102 .get_stats = bcm54xx_get_stats, 1103 .probe = bcm54xx_phy_probe, 1104 .config_init = bcm54xx_config_init, 1105 .config_intr = bcm_phy_config_intr, 1106 .handle_interrupt = bcm_phy_handle_interrupt, 1107 .link_change_notify = bcm54xx_link_change_notify, 1108 }, { 1109 .phy_id = PHY_ID_BCM53128, 1110 .phy_id_mask = 0xfffffff0, 1111 .name = "Broadcom BCM53128", 1112 .flags = PHY_IS_INTERNAL, 1113 /* PHY_GBIT_FEATURES */ 1114 .get_sset_count = bcm_phy_get_sset_count, 1115 .get_strings = bcm_phy_get_strings, 1116 .get_stats = bcm54xx_get_stats, 1117 .probe = bcm54xx_phy_probe, 1118 .config_init = bcm54xx_config_init, 1119 .config_intr = bcm_phy_config_intr, 1120 .handle_interrupt = bcm_phy_handle_interrupt, 1121 .link_change_notify = bcm54xx_link_change_notify, 1122 }, { 1123 .phy_id = PHY_ID_BCM89610, 1124 .phy_id_mask = 0xfffffff0, 1125 .name = "Broadcom BCM89610", 1126 /* PHY_GBIT_FEATURES */ 1127 .get_sset_count = bcm_phy_get_sset_count, 1128 .get_strings = bcm_phy_get_strings, 1129 .get_stats = bcm54xx_get_stats, 1130 .probe = bcm54xx_phy_probe, 1131 .config_init = bcm54xx_config_init, 1132 .config_intr = bcm_phy_config_intr, 1133 .handle_interrupt = bcm_phy_handle_interrupt, 1134 .link_change_notify = bcm54xx_link_change_notify, 1135 } }; 1136 1137 module_phy_driver(broadcom_drivers); 1138 1139 static struct mdio_device_id __maybe_unused broadcom_tbl[] = { 1140 { PHY_ID_BCM5411, 0xfffffff0 }, 1141 { PHY_ID_BCM5421, 0xfffffff0 }, 1142 { PHY_ID_BCM54210E, 0xfffffff0 }, 1143 { PHY_ID_BCM5461, 0xfffffff0 }, 1144 { PHY_ID_BCM54612E, 0xfffffff0 }, 1145 { PHY_ID_BCM54616S, 0xfffffff0 }, 1146 { PHY_ID_BCM5464, 0xfffffff0 }, 1147 { PHY_ID_BCM5481, 0xfffffff0 }, 1148 { PHY_ID_BCM54810, 0xfffffff0 }, 1149 { PHY_ID_BCM54811, 0xfffffff0 }, 1150 { PHY_ID_BCM5482, 0xfffffff0 }, 1151 { PHY_ID_BCM50610, 0xfffffff0 }, 1152 { PHY_ID_BCM50610M, 0xfffffff0 }, 1153 { PHY_ID_BCM57780, 0xfffffff0 }, 1154 { PHY_ID_BCMAC131, 0xfffffff0 }, 1155 { PHY_ID_BCM5241, 0xfffffff0 }, 1156 { PHY_ID_BCM5395, 0xfffffff0 }, 1157 { PHY_ID_BCM53125, 0xfffffff0 }, 1158 { PHY_ID_BCM53128, 0xfffffff0 }, 1159 { PHY_ID_BCM89610, 0xfffffff0 }, 1160 { } 1161 }; 1162 1163 MODULE_DEVICE_TABLE(mdio, broadcom_tbl); 1164