1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Broadcom BCM7xxx internal transceivers support. 4 * 5 * Copyright (C) 2014-2017 Broadcom 6 */ 7 8 #include <linux/module.h> 9 #include <linux/phy.h> 10 #include <linux/delay.h> 11 #include "bcm-phy-lib.h" 12 #include <linux/bitops.h> 13 #include <linux/brcmphy.h> 14 #include <linux/mdio.h> 15 16 /* Broadcom BCM7xxx internal PHY registers */ 17 18 /* EPHY only register definitions */ 19 #define MII_BCM7XXX_100TX_AUX_CTL 0x10 20 #define MII_BCM7XXX_100TX_FALSE_CAR 0x13 21 #define MII_BCM7XXX_100TX_DISC 0x14 22 #define MII_BCM7XXX_AUX_MODE 0x1d 23 #define MII_BCM7XXX_64CLK_MDIO BIT(12) 24 #define MII_BCM7XXX_TEST 0x1f 25 #define MII_BCM7XXX_SHD_MODE_2 BIT(2) 26 #define MII_BCM7XXX_SHD_2_ADDR_CTRL 0xe 27 #define MII_BCM7XXX_SHD_2_CTRL_STAT 0xf 28 #define MII_BCM7XXX_SHD_2_BIAS_TRIM 0x1a 29 #define MII_BCM7XXX_SHD_3_AN_EEE_ADV 0x3 30 #define MII_BCM7XXX_SHD_3_PCS_CTRL_2 0x6 31 #define MII_BCM7XXX_PCS_CTRL_2_DEF 0x4400 32 #define MII_BCM7XXX_SHD_3_AN_STAT 0xb 33 #define MII_BCM7XXX_AN_NULL_MSG_EN BIT(0) 34 #define MII_BCM7XXX_AN_EEE_EN BIT(1) 35 #define MII_BCM7XXX_SHD_3_EEE_THRESH 0xe 36 #define MII_BCM7XXX_EEE_THRESH_DEF 0x50 37 #define MII_BCM7XXX_SHD_3_TL4 0x23 38 #define MII_BCM7XXX_TL4_RST_MSK (BIT(2) | BIT(1)) 39 40 struct bcm7xxx_phy_priv { 41 u64 *stats; 42 }; 43 44 static int bcm7xxx_28nm_d0_afe_config_init(struct phy_device *phydev) 45 { 46 /* AFE_RXCONFIG_0 */ 47 bcm_phy_write_misc(phydev, AFE_RXCONFIG_0, 0xeb15); 48 49 /* AFE_RXCONFIG_1 */ 50 bcm_phy_write_misc(phydev, AFE_RXCONFIG_1, 0x9b2f); 51 52 /* AFE_RXCONFIG_2, set rCal offset for HT=0 code and LT=-2 code */ 53 bcm_phy_write_misc(phydev, AFE_RXCONFIG_2, 0x2003); 54 55 /* AFE_RX_LP_COUNTER, set RX bandwidth to maximum */ 56 bcm_phy_write_misc(phydev, AFE_RX_LP_COUNTER, 0x7fc0); 57 58 /* AFE_TX_CONFIG, set 100BT Cfeed=011 to improve rise/fall time */ 59 bcm_phy_write_misc(phydev, AFE_TX_CONFIG, 0x431); 60 61 /* AFE_VDCA_ICTRL_0, set Iq=1101 instead of 0111 for AB symmetry */ 62 bcm_phy_write_misc(phydev, AFE_VDCA_ICTRL_0, 0xa7da); 63 64 /* AFE_VDAC_OTHERS_0, set 1000BT Cidac=010 for all ports */ 65 bcm_phy_write_misc(phydev, AFE_VDAC_OTHERS_0, 0xa020); 66 67 /* AFE_HPF_TRIM_OTHERS, set 100Tx/10BT to -4.5% swing and set rCal 68 * offset for HT=0 code 69 */ 70 bcm_phy_write_misc(phydev, AFE_HPF_TRIM_OTHERS, 0x00e3); 71 72 /* CORE_BASE1E, force trim to overwrite and set I_ext trim to 0000 */ 73 phy_write(phydev, MII_BRCM_CORE_BASE1E, 0x0010); 74 75 /* DSP_TAP10, adjust bias current trim (+0% swing, +0 tick) */ 76 bcm_phy_write_misc(phydev, DSP_TAP10, 0x011b); 77 78 /* Reset R_CAL/RC_CAL engine */ 79 bcm_phy_r_rc_cal_reset(phydev); 80 81 return 0; 82 } 83 84 static int bcm7xxx_28nm_e0_plus_afe_config_init(struct phy_device *phydev) 85 { 86 /* AFE_RXCONFIG_1, provide more margin for INL/DNL measurement */ 87 bcm_phy_write_misc(phydev, AFE_RXCONFIG_1, 0x9b2f); 88 89 /* AFE_TX_CONFIG, set 100BT Cfeed=011 to improve rise/fall time */ 90 bcm_phy_write_misc(phydev, AFE_TX_CONFIG, 0x431); 91 92 /* AFE_VDCA_ICTRL_0, set Iq=1101 instead of 0111 for AB symmetry */ 93 bcm_phy_write_misc(phydev, AFE_VDCA_ICTRL_0, 0xa7da); 94 95 /* AFE_HPF_TRIM_OTHERS, set 100Tx/10BT to -4.5% swing and set rCal 96 * offset for HT=0 code 97 */ 98 bcm_phy_write_misc(phydev, AFE_HPF_TRIM_OTHERS, 0x00e3); 99 100 /* CORE_BASE1E, force trim to overwrite and set I_ext trim to 0000 */ 101 phy_write(phydev, MII_BRCM_CORE_BASE1E, 0x0010); 102 103 /* DSP_TAP10, adjust bias current trim (+0% swing, +0 tick) */ 104 bcm_phy_write_misc(phydev, DSP_TAP10, 0x011b); 105 106 /* Reset R_CAL/RC_CAL engine */ 107 bcm_phy_r_rc_cal_reset(phydev); 108 109 return 0; 110 } 111 112 static int bcm7xxx_28nm_a0_patch_afe_config_init(struct phy_device *phydev) 113 { 114 /* +1 RC_CAL codes for RL centering for both LT and HT conditions */ 115 bcm_phy_write_misc(phydev, AFE_RXCONFIG_2, 0xd003); 116 117 /* Cut master bias current by 2% to compensate for RC_CAL offset */ 118 bcm_phy_write_misc(phydev, DSP_TAP10, 0x791b); 119 120 /* Improve hybrid leakage */ 121 bcm_phy_write_misc(phydev, AFE_HPF_TRIM_OTHERS, 0x10e3); 122 123 /* Change rx_on_tune 8 to 0xf */ 124 bcm_phy_write_misc(phydev, 0x21, 0x2, 0x87f6); 125 126 /* Change 100Tx EEE bandwidth */ 127 bcm_phy_write_misc(phydev, 0x22, 0x2, 0x017d); 128 129 /* Enable ffe zero detection for Vitesse interoperability */ 130 bcm_phy_write_misc(phydev, 0x26, 0x2, 0x0015); 131 132 bcm_phy_r_rc_cal_reset(phydev); 133 134 return 0; 135 } 136 137 static int bcm7xxx_28nm_config_init(struct phy_device *phydev) 138 { 139 u8 rev = PHY_BRCM_7XXX_REV(phydev->dev_flags); 140 u8 patch = PHY_BRCM_7XXX_PATCH(phydev->dev_flags); 141 u8 count; 142 int ret = 0; 143 144 /* Newer devices have moved the revision information back into a 145 * standard location in MII_PHYS_ID[23] 146 */ 147 if (rev == 0) 148 rev = phydev->phy_id & ~phydev->drv->phy_id_mask; 149 150 pr_info_once("%s: %s PHY revision: 0x%02x, patch: %d\n", 151 phydev_name(phydev), phydev->drv->name, rev, patch); 152 153 /* Dummy read to a register to workaround an issue upon reset where the 154 * internal inverter may not allow the first MDIO transaction to pass 155 * the MDIO management controller and make us return 0xffff for such 156 * reads. 157 */ 158 phy_read(phydev, MII_BMSR); 159 160 switch (rev) { 161 case 0xa0: 162 case 0xb0: 163 ret = bcm_phy_28nm_a0b0_afe_config_init(phydev); 164 break; 165 case 0xd0: 166 ret = bcm7xxx_28nm_d0_afe_config_init(phydev); 167 break; 168 case 0xe0: 169 case 0xf0: 170 /* Rev G0 introduces a roll over */ 171 case 0x10: 172 ret = bcm7xxx_28nm_e0_plus_afe_config_init(phydev); 173 break; 174 case 0x01: 175 ret = bcm7xxx_28nm_a0_patch_afe_config_init(phydev); 176 break; 177 default: 178 break; 179 } 180 181 if (ret) 182 return ret; 183 184 ret = bcm_phy_downshift_get(phydev, &count); 185 if (ret) 186 return ret; 187 188 /* Only enable EEE if Wirespeed/downshift is disabled */ 189 ret = bcm_phy_set_eee(phydev, count == DOWNSHIFT_DEV_DISABLE); 190 if (ret) 191 return ret; 192 193 return bcm_phy_enable_apd(phydev, true); 194 } 195 196 static int bcm7xxx_28nm_resume(struct phy_device *phydev) 197 { 198 int ret; 199 200 /* Re-apply workarounds coming out suspend/resume */ 201 ret = bcm7xxx_28nm_config_init(phydev); 202 if (ret) 203 return ret; 204 205 /* 28nm Gigabit PHYs come out of reset without any half-duplex 206 * or "hub" compliant advertised mode, fix that. This does not 207 * cause any problems with the PHY library since genphy_config_aneg() 208 * gracefully handles auto-negotiated and forced modes. 209 */ 210 return genphy_config_aneg(phydev); 211 } 212 213 static int phy_set_clr_bits(struct phy_device *dev, int location, 214 int set_mask, int clr_mask) 215 { 216 int v, ret; 217 218 v = phy_read(dev, location); 219 if (v < 0) 220 return v; 221 222 v &= ~clr_mask; 223 v |= set_mask; 224 225 ret = phy_write(dev, location, v); 226 if (ret < 0) 227 return ret; 228 229 return v; 230 } 231 232 static int bcm7xxx_28nm_ephy_01_afe_config_init(struct phy_device *phydev) 233 { 234 int ret; 235 236 /* set shadow mode 2 */ 237 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 238 MII_BCM7XXX_SHD_MODE_2, 0); 239 if (ret < 0) 240 return ret; 241 242 /* Set current trim values INT_trim = -1, Ext_trim =0 */ 243 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_BIAS_TRIM, 0x3BE0); 244 if (ret < 0) 245 goto reset_shadow_mode; 246 247 /* Cal reset */ 248 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 249 MII_BCM7XXX_SHD_3_TL4); 250 if (ret < 0) 251 goto reset_shadow_mode; 252 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 253 MII_BCM7XXX_TL4_RST_MSK, 0); 254 if (ret < 0) 255 goto reset_shadow_mode; 256 257 /* Cal reset disable */ 258 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 259 MII_BCM7XXX_SHD_3_TL4); 260 if (ret < 0) 261 goto reset_shadow_mode; 262 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 263 0, MII_BCM7XXX_TL4_RST_MSK); 264 if (ret < 0) 265 goto reset_shadow_mode; 266 267 reset_shadow_mode: 268 /* reset shadow mode 2 */ 269 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, 270 MII_BCM7XXX_SHD_MODE_2); 271 if (ret < 0) 272 return ret; 273 274 return 0; 275 } 276 277 /* The 28nm EPHY does not support Clause 45 (MMD) used by bcm-phy-lib */ 278 static int bcm7xxx_28nm_ephy_apd_enable(struct phy_device *phydev) 279 { 280 int ret; 281 282 /* set shadow mode 1 */ 283 ret = phy_set_clr_bits(phydev, MII_BRCM_FET_BRCMTEST, 284 MII_BRCM_FET_BT_SRE, 0); 285 if (ret < 0) 286 return ret; 287 288 /* Enable auto-power down */ 289 ret = phy_set_clr_bits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2, 290 MII_BRCM_FET_SHDW_AS2_APDE, 0); 291 if (ret < 0) 292 return ret; 293 294 /* reset shadow mode 1 */ 295 ret = phy_set_clr_bits(phydev, MII_BRCM_FET_BRCMTEST, 0, 296 MII_BRCM_FET_BT_SRE); 297 if (ret < 0) 298 return ret; 299 300 return 0; 301 } 302 303 static int bcm7xxx_28nm_ephy_eee_enable(struct phy_device *phydev) 304 { 305 int ret; 306 307 /* set shadow mode 2 */ 308 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 309 MII_BCM7XXX_SHD_MODE_2, 0); 310 if (ret < 0) 311 return ret; 312 313 /* Advertise supported modes */ 314 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 315 MII_BCM7XXX_SHD_3_AN_EEE_ADV); 316 if (ret < 0) 317 goto reset_shadow_mode; 318 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 319 MDIO_EEE_100TX); 320 if (ret < 0) 321 goto reset_shadow_mode; 322 323 /* Restore Defaults */ 324 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 325 MII_BCM7XXX_SHD_3_PCS_CTRL_2); 326 if (ret < 0) 327 goto reset_shadow_mode; 328 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 329 MII_BCM7XXX_PCS_CTRL_2_DEF); 330 if (ret < 0) 331 goto reset_shadow_mode; 332 333 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 334 MII_BCM7XXX_SHD_3_EEE_THRESH); 335 if (ret < 0) 336 goto reset_shadow_mode; 337 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 338 MII_BCM7XXX_EEE_THRESH_DEF); 339 if (ret < 0) 340 goto reset_shadow_mode; 341 342 /* Enable EEE autonegotiation */ 343 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 344 MII_BCM7XXX_SHD_3_AN_STAT); 345 if (ret < 0) 346 goto reset_shadow_mode; 347 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 348 (MII_BCM7XXX_AN_NULL_MSG_EN | MII_BCM7XXX_AN_EEE_EN)); 349 if (ret < 0) 350 goto reset_shadow_mode; 351 352 reset_shadow_mode: 353 /* reset shadow mode 2 */ 354 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, 355 MII_BCM7XXX_SHD_MODE_2); 356 if (ret < 0) 357 return ret; 358 359 /* Restart autoneg */ 360 phy_write(phydev, MII_BMCR, 361 (BMCR_SPEED100 | BMCR_ANENABLE | BMCR_ANRESTART)); 362 363 return 0; 364 } 365 366 static int bcm7xxx_28nm_ephy_config_init(struct phy_device *phydev) 367 { 368 u8 rev = phydev->phy_id & ~phydev->drv->phy_id_mask; 369 int ret = 0; 370 371 pr_info_once("%s: %s PHY revision: 0x%02x\n", 372 phydev_name(phydev), phydev->drv->name, rev); 373 374 /* Dummy read to a register to workaround a possible issue upon reset 375 * where the internal inverter may not allow the first MDIO transaction 376 * to pass the MDIO management controller and make us return 0xffff for 377 * such reads. 378 */ 379 phy_read(phydev, MII_BMSR); 380 381 /* Apply AFE software work-around if necessary */ 382 if (rev == 0x01) { 383 ret = bcm7xxx_28nm_ephy_01_afe_config_init(phydev); 384 if (ret) 385 return ret; 386 } 387 388 ret = bcm7xxx_28nm_ephy_eee_enable(phydev); 389 if (ret) 390 return ret; 391 392 return bcm7xxx_28nm_ephy_apd_enable(phydev); 393 } 394 395 static int bcm7xxx_28nm_ephy_resume(struct phy_device *phydev) 396 { 397 int ret; 398 399 /* Re-apply workarounds coming out suspend/resume */ 400 ret = bcm7xxx_28nm_ephy_config_init(phydev); 401 if (ret) 402 return ret; 403 404 return genphy_config_aneg(phydev); 405 } 406 407 static int bcm7xxx_config_init(struct phy_device *phydev) 408 { 409 int ret; 410 411 /* Enable 64 clock MDIO */ 412 phy_write(phydev, MII_BCM7XXX_AUX_MODE, MII_BCM7XXX_64CLK_MDIO); 413 phy_read(phydev, MII_BCM7XXX_AUX_MODE); 414 415 /* set shadow mode 2 */ 416 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 417 MII_BCM7XXX_SHD_MODE_2, MII_BCM7XXX_SHD_MODE_2); 418 if (ret < 0) 419 return ret; 420 421 /* set iddq_clkbias */ 422 phy_write(phydev, MII_BCM7XXX_100TX_DISC, 0x0F00); 423 udelay(10); 424 425 /* reset iddq_clkbias */ 426 phy_write(phydev, MII_BCM7XXX_100TX_DISC, 0x0C00); 427 428 phy_write(phydev, MII_BCM7XXX_100TX_FALSE_CAR, 0x7555); 429 430 /* reset shadow mode 2 */ 431 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, MII_BCM7XXX_SHD_MODE_2); 432 if (ret < 0) 433 return ret; 434 435 return 0; 436 } 437 438 /* Workaround for putting the PHY in IDDQ mode, required 439 * for all BCM7XXX 40nm and 65nm PHYs 440 */ 441 static int bcm7xxx_suspend(struct phy_device *phydev) 442 { 443 int ret; 444 static const struct bcm7xxx_regs { 445 int reg; 446 u16 value; 447 } bcm7xxx_suspend_cfg[] = { 448 { MII_BCM7XXX_TEST, 0x008b }, 449 { MII_BCM7XXX_100TX_AUX_CTL, 0x01c0 }, 450 { MII_BCM7XXX_100TX_DISC, 0x7000 }, 451 { MII_BCM7XXX_TEST, 0x000f }, 452 { MII_BCM7XXX_100TX_AUX_CTL, 0x20d0 }, 453 { MII_BCM7XXX_TEST, 0x000b }, 454 }; 455 unsigned int i; 456 457 for (i = 0; i < ARRAY_SIZE(bcm7xxx_suspend_cfg); i++) { 458 ret = phy_write(phydev, 459 bcm7xxx_suspend_cfg[i].reg, 460 bcm7xxx_suspend_cfg[i].value); 461 if (ret) 462 return ret; 463 } 464 465 return 0; 466 } 467 468 static int bcm7xxx_28nm_get_tunable(struct phy_device *phydev, 469 struct ethtool_tunable *tuna, 470 void *data) 471 { 472 switch (tuna->id) { 473 case ETHTOOL_PHY_DOWNSHIFT: 474 return bcm_phy_downshift_get(phydev, (u8 *)data); 475 default: 476 return -EOPNOTSUPP; 477 } 478 } 479 480 static int bcm7xxx_28nm_set_tunable(struct phy_device *phydev, 481 struct ethtool_tunable *tuna, 482 const void *data) 483 { 484 u8 count = *(u8 *)data; 485 int ret; 486 487 switch (tuna->id) { 488 case ETHTOOL_PHY_DOWNSHIFT: 489 ret = bcm_phy_downshift_set(phydev, count); 490 break; 491 default: 492 return -EOPNOTSUPP; 493 } 494 495 if (ret) 496 return ret; 497 498 /* Disable EEE advertisement since this prevents the PHY 499 * from successfully linking up, trigger auto-negotiation restart 500 * to let the MAC decide what to do. 501 */ 502 ret = bcm_phy_set_eee(phydev, count == DOWNSHIFT_DEV_DISABLE); 503 if (ret) 504 return ret; 505 506 return genphy_restart_aneg(phydev); 507 } 508 509 static void bcm7xxx_28nm_get_phy_stats(struct phy_device *phydev, 510 struct ethtool_stats *stats, u64 *data) 511 { 512 struct bcm7xxx_phy_priv *priv = phydev->priv; 513 514 bcm_phy_get_stats(phydev, priv->stats, stats, data); 515 } 516 517 static int bcm7xxx_28nm_probe(struct phy_device *phydev) 518 { 519 struct bcm7xxx_phy_priv *priv; 520 521 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 522 if (!priv) 523 return -ENOMEM; 524 525 phydev->priv = priv; 526 527 priv->stats = devm_kcalloc(&phydev->mdio.dev, 528 bcm_phy_get_sset_count(phydev), sizeof(u64), 529 GFP_KERNEL); 530 if (!priv->stats) 531 return -ENOMEM; 532 533 return 0; 534 } 535 536 #define BCM7XXX_28NM_GPHY(_oui, _name) \ 537 { \ 538 .phy_id = (_oui), \ 539 .phy_id_mask = 0xfffffff0, \ 540 .name = _name, \ 541 /* PHY_GBIT_FEATURES */ \ 542 .flags = PHY_IS_INTERNAL, \ 543 .config_init = bcm7xxx_28nm_config_init, \ 544 .resume = bcm7xxx_28nm_resume, \ 545 .get_tunable = bcm7xxx_28nm_get_tunable, \ 546 .set_tunable = bcm7xxx_28nm_set_tunable, \ 547 .get_sset_count = bcm_phy_get_sset_count, \ 548 .get_strings = bcm_phy_get_strings, \ 549 .get_stats = bcm7xxx_28nm_get_phy_stats, \ 550 .probe = bcm7xxx_28nm_probe, \ 551 } 552 553 #define BCM7XXX_28NM_EPHY(_oui, _name) \ 554 { \ 555 .phy_id = (_oui), \ 556 .phy_id_mask = 0xfffffff0, \ 557 .name = _name, \ 558 /* PHY_BASIC_FEATURES */ \ 559 .flags = PHY_IS_INTERNAL, \ 560 .config_init = bcm7xxx_28nm_ephy_config_init, \ 561 .resume = bcm7xxx_28nm_ephy_resume, \ 562 .get_sset_count = bcm_phy_get_sset_count, \ 563 .get_strings = bcm_phy_get_strings, \ 564 .get_stats = bcm7xxx_28nm_get_phy_stats, \ 565 .probe = bcm7xxx_28nm_probe, \ 566 } 567 568 #define BCM7XXX_40NM_EPHY(_oui, _name) \ 569 { \ 570 .phy_id = (_oui), \ 571 .phy_id_mask = 0xfffffff0, \ 572 .name = _name, \ 573 /* PHY_BASIC_FEATURES */ \ 574 .flags = PHY_IS_INTERNAL, \ 575 .config_init = bcm7xxx_config_init, \ 576 .suspend = bcm7xxx_suspend, \ 577 .resume = bcm7xxx_config_init, \ 578 } 579 580 static struct phy_driver bcm7xxx_driver[] = { 581 BCM7XXX_28NM_GPHY(PHY_ID_BCM7250, "Broadcom BCM7250"), 582 BCM7XXX_28NM_EPHY(PHY_ID_BCM7255, "Broadcom BCM7255"), 583 BCM7XXX_28NM_EPHY(PHY_ID_BCM7260, "Broadcom BCM7260"), 584 BCM7XXX_28NM_EPHY(PHY_ID_BCM7268, "Broadcom BCM7268"), 585 BCM7XXX_28NM_EPHY(PHY_ID_BCM7271, "Broadcom BCM7271"), 586 BCM7XXX_28NM_GPHY(PHY_ID_BCM7278, "Broadcom BCM7278"), 587 BCM7XXX_28NM_GPHY(PHY_ID_BCM7364, "Broadcom BCM7364"), 588 BCM7XXX_28NM_GPHY(PHY_ID_BCM7366, "Broadcom BCM7366"), 589 BCM7XXX_28NM_GPHY(PHY_ID_BCM74371, "Broadcom BCM74371"), 590 BCM7XXX_28NM_GPHY(PHY_ID_BCM7439, "Broadcom BCM7439"), 591 BCM7XXX_28NM_GPHY(PHY_ID_BCM7439_2, "Broadcom BCM7439 (2)"), 592 BCM7XXX_28NM_GPHY(PHY_ID_BCM7445, "Broadcom BCM7445"), 593 BCM7XXX_40NM_EPHY(PHY_ID_BCM7346, "Broadcom BCM7346"), 594 BCM7XXX_40NM_EPHY(PHY_ID_BCM7362, "Broadcom BCM7362"), 595 BCM7XXX_40NM_EPHY(PHY_ID_BCM7425, "Broadcom BCM7425"), 596 BCM7XXX_40NM_EPHY(PHY_ID_BCM7429, "Broadcom BCM7429"), 597 BCM7XXX_40NM_EPHY(PHY_ID_BCM7435, "Broadcom BCM7435"), 598 }; 599 600 static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = { 601 { PHY_ID_BCM7250, 0xfffffff0, }, 602 { PHY_ID_BCM7255, 0xfffffff0, }, 603 { PHY_ID_BCM7260, 0xfffffff0, }, 604 { PHY_ID_BCM7268, 0xfffffff0, }, 605 { PHY_ID_BCM7271, 0xfffffff0, }, 606 { PHY_ID_BCM7278, 0xfffffff0, }, 607 { PHY_ID_BCM7364, 0xfffffff0, }, 608 { PHY_ID_BCM7366, 0xfffffff0, }, 609 { PHY_ID_BCM7346, 0xfffffff0, }, 610 { PHY_ID_BCM7362, 0xfffffff0, }, 611 { PHY_ID_BCM7425, 0xfffffff0, }, 612 { PHY_ID_BCM7429, 0xfffffff0, }, 613 { PHY_ID_BCM74371, 0xfffffff0, }, 614 { PHY_ID_BCM7439, 0xfffffff0, }, 615 { PHY_ID_BCM7435, 0xfffffff0, }, 616 { PHY_ID_BCM7445, 0xfffffff0, }, 617 { } 618 }; 619 620 module_phy_driver(bcm7xxx_driver); 621 622 MODULE_DEVICE_TABLE(mdio, bcm7xxx_tbl); 623 624 MODULE_DESCRIPTION("Broadcom BCM7xxx internal PHY driver"); 625 MODULE_LICENSE("GPL"); 626 MODULE_AUTHOR("Broadcom Corporation"); 627