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 bcm54xx_phy_probe(struct phy_device *phydev) 770 { 771 struct bcm54xx_phy_priv *priv; 772 773 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 774 if (!priv) 775 return -ENOMEM; 776 777 phydev->priv = priv; 778 779 priv->stats = devm_kcalloc(&phydev->mdio.dev, 780 bcm_phy_get_sset_count(phydev), sizeof(u64), 781 GFP_KERNEL); 782 if (!priv->stats) 783 return -ENOMEM; 784 785 priv->ptp = bcm_ptp_probe(phydev); 786 if (IS_ERR(priv->ptp)) 787 return PTR_ERR(priv->ptp); 788 789 return 0; 790 } 791 792 static void bcm54xx_get_stats(struct phy_device *phydev, 793 struct ethtool_stats *stats, u64 *data) 794 { 795 struct bcm54xx_phy_priv *priv = phydev->priv; 796 797 bcm_phy_get_stats(phydev, priv->stats, stats, data); 798 } 799 800 static void bcm54xx_link_change_notify(struct phy_device *phydev) 801 { 802 u16 mask = MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE | 803 MII_BCM54XX_EXP_EXP08_FORCE_DAC_WAKE; 804 int ret; 805 806 if (phydev->state != PHY_RUNNING) 807 return; 808 809 /* Don't change the DAC wake settings if auto power down 810 * is not requested. 811 */ 812 if (!(phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) 813 return; 814 815 ret = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP08); 816 if (ret < 0) 817 return; 818 819 /* Enable/disable 10BaseT auto and forced early DAC wake depending 820 * on the negotiated speed, those settings should only be done 821 * for 10Mbits/sec. 822 */ 823 if (phydev->speed == SPEED_10) 824 ret |= mask; 825 else 826 ret &= ~mask; 827 bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08, ret); 828 } 829 830 static struct phy_driver broadcom_drivers[] = { 831 { 832 .phy_id = PHY_ID_BCM5411, 833 .phy_id_mask = 0xfffffff0, 834 .name = "Broadcom BCM5411", 835 /* PHY_GBIT_FEATURES */ 836 .get_sset_count = bcm_phy_get_sset_count, 837 .get_strings = bcm_phy_get_strings, 838 .get_stats = bcm54xx_get_stats, 839 .probe = bcm54xx_phy_probe, 840 .config_init = bcm54xx_config_init, 841 .config_intr = bcm_phy_config_intr, 842 .handle_interrupt = bcm_phy_handle_interrupt, 843 .link_change_notify = bcm54xx_link_change_notify, 844 }, { 845 .phy_id = PHY_ID_BCM5421, 846 .phy_id_mask = 0xfffffff0, 847 .name = "Broadcom BCM5421", 848 /* PHY_GBIT_FEATURES */ 849 .get_sset_count = bcm_phy_get_sset_count, 850 .get_strings = bcm_phy_get_strings, 851 .get_stats = bcm54xx_get_stats, 852 .probe = bcm54xx_phy_probe, 853 .config_init = bcm54xx_config_init, 854 .config_intr = bcm_phy_config_intr, 855 .handle_interrupt = bcm_phy_handle_interrupt, 856 .link_change_notify = bcm54xx_link_change_notify, 857 }, { 858 .phy_id = PHY_ID_BCM54210E, 859 .phy_id_mask = 0xfffffff0, 860 .name = "Broadcom BCM54210E", 861 /* PHY_GBIT_FEATURES */ 862 .get_sset_count = bcm_phy_get_sset_count, 863 .get_strings = bcm_phy_get_strings, 864 .get_stats = bcm54xx_get_stats, 865 .probe = bcm54xx_phy_probe, 866 .config_init = bcm54xx_config_init, 867 .config_intr = bcm_phy_config_intr, 868 .handle_interrupt = bcm_phy_handle_interrupt, 869 .link_change_notify = bcm54xx_link_change_notify, 870 .suspend = bcm54xx_suspend, 871 .resume = bcm54xx_resume, 872 }, { 873 .phy_id = PHY_ID_BCM5461, 874 .phy_id_mask = 0xfffffff0, 875 .name = "Broadcom BCM5461", 876 /* PHY_GBIT_FEATURES */ 877 .get_sset_count = bcm_phy_get_sset_count, 878 .get_strings = bcm_phy_get_strings, 879 .get_stats = bcm54xx_get_stats, 880 .probe = bcm54xx_phy_probe, 881 .config_init = bcm54xx_config_init, 882 .config_intr = bcm_phy_config_intr, 883 .handle_interrupt = bcm_phy_handle_interrupt, 884 .link_change_notify = bcm54xx_link_change_notify, 885 }, { 886 .phy_id = PHY_ID_BCM54612E, 887 .phy_id_mask = 0xfffffff0, 888 .name = "Broadcom BCM54612E", 889 /* PHY_GBIT_FEATURES */ 890 .get_sset_count = bcm_phy_get_sset_count, 891 .get_strings = bcm_phy_get_strings, 892 .get_stats = bcm54xx_get_stats, 893 .probe = bcm54xx_phy_probe, 894 .config_init = bcm54xx_config_init, 895 .config_intr = bcm_phy_config_intr, 896 .handle_interrupt = bcm_phy_handle_interrupt, 897 .link_change_notify = bcm54xx_link_change_notify, 898 }, { 899 .phy_id = PHY_ID_BCM54616S, 900 .phy_id_mask = 0xfffffff0, 901 .name = "Broadcom BCM54616S", 902 /* PHY_GBIT_FEATURES */ 903 .soft_reset = genphy_soft_reset, 904 .config_init = bcm54xx_config_init, 905 .config_aneg = bcm54616s_config_aneg, 906 .config_intr = bcm_phy_config_intr, 907 .handle_interrupt = bcm_phy_handle_interrupt, 908 .read_status = bcm54616s_read_status, 909 .probe = bcm54616s_probe, 910 .link_change_notify = bcm54xx_link_change_notify, 911 }, { 912 .phy_id = PHY_ID_BCM5464, 913 .phy_id_mask = 0xfffffff0, 914 .name = "Broadcom BCM5464", 915 /* PHY_GBIT_FEATURES */ 916 .get_sset_count = bcm_phy_get_sset_count, 917 .get_strings = bcm_phy_get_strings, 918 .get_stats = bcm54xx_get_stats, 919 .probe = bcm54xx_phy_probe, 920 .config_init = bcm54xx_config_init, 921 .config_intr = bcm_phy_config_intr, 922 .handle_interrupt = bcm_phy_handle_interrupt, 923 .suspend = genphy_suspend, 924 .resume = genphy_resume, 925 .link_change_notify = bcm54xx_link_change_notify, 926 }, { 927 .phy_id = PHY_ID_BCM5481, 928 .phy_id_mask = 0xfffffff0, 929 .name = "Broadcom BCM5481", 930 /* PHY_GBIT_FEATURES */ 931 .get_sset_count = bcm_phy_get_sset_count, 932 .get_strings = bcm_phy_get_strings, 933 .get_stats = bcm54xx_get_stats, 934 .probe = bcm54xx_phy_probe, 935 .config_init = bcm54xx_config_init, 936 .config_aneg = bcm5481_config_aneg, 937 .config_intr = bcm_phy_config_intr, 938 .handle_interrupt = bcm_phy_handle_interrupt, 939 .link_change_notify = bcm54xx_link_change_notify, 940 }, { 941 .phy_id = PHY_ID_BCM54810, 942 .phy_id_mask = 0xfffffff0, 943 .name = "Broadcom BCM54810", 944 /* PHY_GBIT_FEATURES */ 945 .get_sset_count = bcm_phy_get_sset_count, 946 .get_strings = bcm_phy_get_strings, 947 .get_stats = bcm54xx_get_stats, 948 .probe = bcm54xx_phy_probe, 949 .config_init = bcm54xx_config_init, 950 .config_aneg = bcm5481_config_aneg, 951 .config_intr = bcm_phy_config_intr, 952 .handle_interrupt = bcm_phy_handle_interrupt, 953 .suspend = bcm54xx_suspend, 954 .resume = bcm54xx_resume, 955 .link_change_notify = bcm54xx_link_change_notify, 956 }, { 957 .phy_id = PHY_ID_BCM54811, 958 .phy_id_mask = 0xfffffff0, 959 .name = "Broadcom BCM54811", 960 /* PHY_GBIT_FEATURES */ 961 .get_sset_count = bcm_phy_get_sset_count, 962 .get_strings = bcm_phy_get_strings, 963 .get_stats = bcm54xx_get_stats, 964 .probe = bcm54xx_phy_probe, 965 .config_init = bcm54811_config_init, 966 .config_aneg = bcm5481_config_aneg, 967 .config_intr = bcm_phy_config_intr, 968 .handle_interrupt = bcm_phy_handle_interrupt, 969 .suspend = bcm54xx_suspend, 970 .resume = bcm54xx_resume, 971 .link_change_notify = bcm54xx_link_change_notify, 972 }, { 973 .phy_id = PHY_ID_BCM5482, 974 .phy_id_mask = 0xfffffff0, 975 .name = "Broadcom BCM5482", 976 /* PHY_GBIT_FEATURES */ 977 .get_sset_count = bcm_phy_get_sset_count, 978 .get_strings = bcm_phy_get_strings, 979 .get_stats = bcm54xx_get_stats, 980 .probe = bcm54xx_phy_probe, 981 .config_init = bcm54xx_config_init, 982 .config_intr = bcm_phy_config_intr, 983 .handle_interrupt = bcm_phy_handle_interrupt, 984 .link_change_notify = bcm54xx_link_change_notify, 985 }, { 986 .phy_id = PHY_ID_BCM50610, 987 .phy_id_mask = 0xfffffff0, 988 .name = "Broadcom BCM50610", 989 /* PHY_GBIT_FEATURES */ 990 .get_sset_count = bcm_phy_get_sset_count, 991 .get_strings = bcm_phy_get_strings, 992 .get_stats = bcm54xx_get_stats, 993 .probe = bcm54xx_phy_probe, 994 .config_init = bcm54xx_config_init, 995 .config_intr = bcm_phy_config_intr, 996 .handle_interrupt = bcm_phy_handle_interrupt, 997 .link_change_notify = bcm54xx_link_change_notify, 998 .suspend = bcm54xx_suspend, 999 .resume = bcm54xx_resume, 1000 }, { 1001 .phy_id = PHY_ID_BCM50610M, 1002 .phy_id_mask = 0xfffffff0, 1003 .name = "Broadcom BCM50610M", 1004 /* PHY_GBIT_FEATURES */ 1005 .get_sset_count = bcm_phy_get_sset_count, 1006 .get_strings = bcm_phy_get_strings, 1007 .get_stats = bcm54xx_get_stats, 1008 .probe = bcm54xx_phy_probe, 1009 .config_init = bcm54xx_config_init, 1010 .config_intr = bcm_phy_config_intr, 1011 .handle_interrupt = bcm_phy_handle_interrupt, 1012 .link_change_notify = bcm54xx_link_change_notify, 1013 .suspend = bcm54xx_suspend, 1014 .resume = bcm54xx_resume, 1015 }, { 1016 .phy_id = PHY_ID_BCM57780, 1017 .phy_id_mask = 0xfffffff0, 1018 .name = "Broadcom BCM57780", 1019 /* PHY_GBIT_FEATURES */ 1020 .get_sset_count = bcm_phy_get_sset_count, 1021 .get_strings = bcm_phy_get_strings, 1022 .get_stats = bcm54xx_get_stats, 1023 .probe = bcm54xx_phy_probe, 1024 .config_init = bcm54xx_config_init, 1025 .config_intr = bcm_phy_config_intr, 1026 .handle_interrupt = bcm_phy_handle_interrupt, 1027 .link_change_notify = bcm54xx_link_change_notify, 1028 }, { 1029 .phy_id = PHY_ID_BCMAC131, 1030 .phy_id_mask = 0xfffffff0, 1031 .name = "Broadcom BCMAC131", 1032 /* PHY_BASIC_FEATURES */ 1033 .config_init = brcm_fet_config_init, 1034 .config_intr = brcm_fet_config_intr, 1035 .handle_interrupt = brcm_fet_handle_interrupt, 1036 }, { 1037 .phy_id = PHY_ID_BCM5241, 1038 .phy_id_mask = 0xfffffff0, 1039 .name = "Broadcom BCM5241", 1040 /* PHY_BASIC_FEATURES */ 1041 .config_init = brcm_fet_config_init, 1042 .config_intr = brcm_fet_config_intr, 1043 .handle_interrupt = brcm_fet_handle_interrupt, 1044 }, { 1045 .phy_id = PHY_ID_BCM5395, 1046 .phy_id_mask = 0xfffffff0, 1047 .name = "Broadcom BCM5395", 1048 .flags = PHY_IS_INTERNAL, 1049 /* PHY_GBIT_FEATURES */ 1050 .get_sset_count = bcm_phy_get_sset_count, 1051 .get_strings = bcm_phy_get_strings, 1052 .get_stats = bcm54xx_get_stats, 1053 .probe = bcm54xx_phy_probe, 1054 .link_change_notify = bcm54xx_link_change_notify, 1055 }, { 1056 .phy_id = PHY_ID_BCM53125, 1057 .phy_id_mask = 0xfffffff0, 1058 .name = "Broadcom BCM53125", 1059 .flags = PHY_IS_INTERNAL, 1060 /* PHY_GBIT_FEATURES */ 1061 .get_sset_count = bcm_phy_get_sset_count, 1062 .get_strings = bcm_phy_get_strings, 1063 .get_stats = bcm54xx_get_stats, 1064 .probe = bcm54xx_phy_probe, 1065 .config_init = bcm54xx_config_init, 1066 .config_intr = bcm_phy_config_intr, 1067 .handle_interrupt = bcm_phy_handle_interrupt, 1068 .link_change_notify = bcm54xx_link_change_notify, 1069 }, { 1070 .phy_id = PHY_ID_BCM53128, 1071 .phy_id_mask = 0xfffffff0, 1072 .name = "Broadcom BCM53128", 1073 .flags = PHY_IS_INTERNAL, 1074 /* PHY_GBIT_FEATURES */ 1075 .get_sset_count = bcm_phy_get_sset_count, 1076 .get_strings = bcm_phy_get_strings, 1077 .get_stats = bcm54xx_get_stats, 1078 .probe = bcm54xx_phy_probe, 1079 .config_init = bcm54xx_config_init, 1080 .config_intr = bcm_phy_config_intr, 1081 .handle_interrupt = bcm_phy_handle_interrupt, 1082 .link_change_notify = bcm54xx_link_change_notify, 1083 }, { 1084 .phy_id = PHY_ID_BCM89610, 1085 .phy_id_mask = 0xfffffff0, 1086 .name = "Broadcom BCM89610", 1087 /* PHY_GBIT_FEATURES */ 1088 .get_sset_count = bcm_phy_get_sset_count, 1089 .get_strings = bcm_phy_get_strings, 1090 .get_stats = bcm54xx_get_stats, 1091 .probe = bcm54xx_phy_probe, 1092 .config_init = bcm54xx_config_init, 1093 .config_intr = bcm_phy_config_intr, 1094 .handle_interrupt = bcm_phy_handle_interrupt, 1095 .link_change_notify = bcm54xx_link_change_notify, 1096 } }; 1097 1098 module_phy_driver(broadcom_drivers); 1099 1100 static struct mdio_device_id __maybe_unused broadcom_tbl[] = { 1101 { PHY_ID_BCM5411, 0xfffffff0 }, 1102 { PHY_ID_BCM5421, 0xfffffff0 }, 1103 { PHY_ID_BCM54210E, 0xfffffff0 }, 1104 { PHY_ID_BCM5461, 0xfffffff0 }, 1105 { PHY_ID_BCM54612E, 0xfffffff0 }, 1106 { PHY_ID_BCM54616S, 0xfffffff0 }, 1107 { PHY_ID_BCM5464, 0xfffffff0 }, 1108 { PHY_ID_BCM5481, 0xfffffff0 }, 1109 { PHY_ID_BCM54810, 0xfffffff0 }, 1110 { PHY_ID_BCM54811, 0xfffffff0 }, 1111 { PHY_ID_BCM5482, 0xfffffff0 }, 1112 { PHY_ID_BCM50610, 0xfffffff0 }, 1113 { PHY_ID_BCM50610M, 0xfffffff0 }, 1114 { PHY_ID_BCM57780, 0xfffffff0 }, 1115 { PHY_ID_BCMAC131, 0xfffffff0 }, 1116 { PHY_ID_BCM5241, 0xfffffff0 }, 1117 { PHY_ID_BCM5395, 0xfffffff0 }, 1118 { PHY_ID_BCM53125, 0xfffffff0 }, 1119 { PHY_ID_BCM53128, 0xfffffff0 }, 1120 { PHY_ID_BCM89610, 0xfffffff0 }, 1121 { } 1122 }; 1123 1124 MODULE_DEVICE_TABLE(mdio, broadcom_tbl); 1125