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_enable_jumbo(phydev); 185 if (ret) 186 return ret; 187 188 ret = bcm_phy_downshift_get(phydev, &count); 189 if (ret) 190 return ret; 191 192 /* Only enable EEE if Wirespeed/downshift is disabled */ 193 ret = bcm_phy_set_eee(phydev, count == DOWNSHIFT_DEV_DISABLE); 194 if (ret) 195 return ret; 196 197 return bcm_phy_enable_apd(phydev, true); 198 } 199 200 static int bcm7xxx_28nm_resume(struct phy_device *phydev) 201 { 202 int ret; 203 204 /* Re-apply workarounds coming out suspend/resume */ 205 ret = bcm7xxx_28nm_config_init(phydev); 206 if (ret) 207 return ret; 208 209 /* 28nm Gigabit PHYs come out of reset without any half-duplex 210 * or "hub" compliant advertised mode, fix that. This does not 211 * cause any problems with the PHY library since genphy_config_aneg() 212 * gracefully handles auto-negotiated and forced modes. 213 */ 214 return genphy_config_aneg(phydev); 215 } 216 217 static int phy_set_clr_bits(struct phy_device *dev, int location, 218 int set_mask, int clr_mask) 219 { 220 int v, ret; 221 222 v = phy_read(dev, location); 223 if (v < 0) 224 return v; 225 226 v &= ~clr_mask; 227 v |= set_mask; 228 229 ret = phy_write(dev, location, v); 230 if (ret < 0) 231 return ret; 232 233 return v; 234 } 235 236 static int bcm7xxx_28nm_ephy_01_afe_config_init(struct phy_device *phydev) 237 { 238 int ret; 239 240 /* set shadow mode 2 */ 241 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 242 MII_BCM7XXX_SHD_MODE_2, 0); 243 if (ret < 0) 244 return ret; 245 246 /* Set current trim values INT_trim = -1, Ext_trim =0 */ 247 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_BIAS_TRIM, 0x3BE0); 248 if (ret < 0) 249 goto reset_shadow_mode; 250 251 /* Cal reset */ 252 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 253 MII_BCM7XXX_SHD_3_TL4); 254 if (ret < 0) 255 goto reset_shadow_mode; 256 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 257 MII_BCM7XXX_TL4_RST_MSK, 0); 258 if (ret < 0) 259 goto reset_shadow_mode; 260 261 /* Cal reset disable */ 262 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 263 MII_BCM7XXX_SHD_3_TL4); 264 if (ret < 0) 265 goto reset_shadow_mode; 266 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 267 0, MII_BCM7XXX_TL4_RST_MSK); 268 if (ret < 0) 269 goto reset_shadow_mode; 270 271 reset_shadow_mode: 272 /* reset shadow mode 2 */ 273 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, 274 MII_BCM7XXX_SHD_MODE_2); 275 if (ret < 0) 276 return ret; 277 278 return 0; 279 } 280 281 /* The 28nm EPHY does not support Clause 45 (MMD) used by bcm-phy-lib */ 282 static int bcm7xxx_28nm_ephy_apd_enable(struct phy_device *phydev) 283 { 284 int ret; 285 286 /* set shadow mode 1 */ 287 ret = phy_set_clr_bits(phydev, MII_BRCM_FET_BRCMTEST, 288 MII_BRCM_FET_BT_SRE, 0); 289 if (ret < 0) 290 return ret; 291 292 /* Enable auto-power down */ 293 ret = phy_set_clr_bits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2, 294 MII_BRCM_FET_SHDW_AS2_APDE, 0); 295 if (ret < 0) 296 return ret; 297 298 /* reset shadow mode 1 */ 299 ret = phy_set_clr_bits(phydev, MII_BRCM_FET_BRCMTEST, 0, 300 MII_BRCM_FET_BT_SRE); 301 if (ret < 0) 302 return ret; 303 304 return 0; 305 } 306 307 static int bcm7xxx_28nm_ephy_eee_enable(struct phy_device *phydev) 308 { 309 int ret; 310 311 /* set shadow mode 2 */ 312 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 313 MII_BCM7XXX_SHD_MODE_2, 0); 314 if (ret < 0) 315 return ret; 316 317 /* Advertise supported modes */ 318 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 319 MII_BCM7XXX_SHD_3_AN_EEE_ADV); 320 if (ret < 0) 321 goto reset_shadow_mode; 322 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 323 MDIO_EEE_100TX); 324 if (ret < 0) 325 goto reset_shadow_mode; 326 327 /* Restore Defaults */ 328 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 329 MII_BCM7XXX_SHD_3_PCS_CTRL_2); 330 if (ret < 0) 331 goto reset_shadow_mode; 332 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 333 MII_BCM7XXX_PCS_CTRL_2_DEF); 334 if (ret < 0) 335 goto reset_shadow_mode; 336 337 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 338 MII_BCM7XXX_SHD_3_EEE_THRESH); 339 if (ret < 0) 340 goto reset_shadow_mode; 341 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 342 MII_BCM7XXX_EEE_THRESH_DEF); 343 if (ret < 0) 344 goto reset_shadow_mode; 345 346 /* Enable EEE autonegotiation */ 347 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, 348 MII_BCM7XXX_SHD_3_AN_STAT); 349 if (ret < 0) 350 goto reset_shadow_mode; 351 ret = phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, 352 (MII_BCM7XXX_AN_NULL_MSG_EN | MII_BCM7XXX_AN_EEE_EN)); 353 if (ret < 0) 354 goto reset_shadow_mode; 355 356 reset_shadow_mode: 357 /* reset shadow mode 2 */ 358 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, 359 MII_BCM7XXX_SHD_MODE_2); 360 if (ret < 0) 361 return ret; 362 363 /* Restart autoneg */ 364 phy_write(phydev, MII_BMCR, 365 (BMCR_SPEED100 | BMCR_ANENABLE | BMCR_ANRESTART)); 366 367 return 0; 368 } 369 370 static int bcm7xxx_28nm_ephy_config_init(struct phy_device *phydev) 371 { 372 u8 rev = phydev->phy_id & ~phydev->drv->phy_id_mask; 373 int ret = 0; 374 375 pr_info_once("%s: %s PHY revision: 0x%02x\n", 376 phydev_name(phydev), phydev->drv->name, rev); 377 378 /* Dummy read to a register to workaround a possible issue upon reset 379 * where the internal inverter may not allow the first MDIO transaction 380 * to pass the MDIO management controller and make us return 0xffff for 381 * such reads. 382 */ 383 phy_read(phydev, MII_BMSR); 384 385 /* Apply AFE software work-around if necessary */ 386 if (rev == 0x01) { 387 ret = bcm7xxx_28nm_ephy_01_afe_config_init(phydev); 388 if (ret) 389 return ret; 390 } 391 392 ret = bcm7xxx_28nm_ephy_eee_enable(phydev); 393 if (ret) 394 return ret; 395 396 return bcm7xxx_28nm_ephy_apd_enable(phydev); 397 } 398 399 static int bcm7xxx_28nm_ephy_resume(struct phy_device *phydev) 400 { 401 int ret; 402 403 /* Re-apply workarounds coming out suspend/resume */ 404 ret = bcm7xxx_28nm_ephy_config_init(phydev); 405 if (ret) 406 return ret; 407 408 return genphy_config_aneg(phydev); 409 } 410 411 static int bcm7xxx_config_init(struct phy_device *phydev) 412 { 413 int ret; 414 415 /* Enable 64 clock MDIO */ 416 phy_write(phydev, MII_BCM7XXX_AUX_MODE, MII_BCM7XXX_64CLK_MDIO); 417 phy_read(phydev, MII_BCM7XXX_AUX_MODE); 418 419 /* set shadow mode 2 */ 420 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 421 MII_BCM7XXX_SHD_MODE_2, MII_BCM7XXX_SHD_MODE_2); 422 if (ret < 0) 423 return ret; 424 425 /* set iddq_clkbias */ 426 phy_write(phydev, MII_BCM7XXX_100TX_DISC, 0x0F00); 427 udelay(10); 428 429 /* reset iddq_clkbias */ 430 phy_write(phydev, MII_BCM7XXX_100TX_DISC, 0x0C00); 431 432 phy_write(phydev, MII_BCM7XXX_100TX_FALSE_CAR, 0x7555); 433 434 /* reset shadow mode 2 */ 435 ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, MII_BCM7XXX_SHD_MODE_2); 436 if (ret < 0) 437 return ret; 438 439 return 0; 440 } 441 442 /* Workaround for putting the PHY in IDDQ mode, required 443 * for all BCM7XXX 40nm and 65nm PHYs 444 */ 445 static int bcm7xxx_suspend(struct phy_device *phydev) 446 { 447 int ret; 448 static const struct bcm7xxx_regs { 449 int reg; 450 u16 value; 451 } bcm7xxx_suspend_cfg[] = { 452 { MII_BCM7XXX_TEST, 0x008b }, 453 { MII_BCM7XXX_100TX_AUX_CTL, 0x01c0 }, 454 { MII_BCM7XXX_100TX_DISC, 0x7000 }, 455 { MII_BCM7XXX_TEST, 0x000f }, 456 { MII_BCM7XXX_100TX_AUX_CTL, 0x20d0 }, 457 { MII_BCM7XXX_TEST, 0x000b }, 458 }; 459 unsigned int i; 460 461 for (i = 0; i < ARRAY_SIZE(bcm7xxx_suspend_cfg); i++) { 462 ret = phy_write(phydev, 463 bcm7xxx_suspend_cfg[i].reg, 464 bcm7xxx_suspend_cfg[i].value); 465 if (ret) 466 return ret; 467 } 468 469 return 0; 470 } 471 472 static int bcm7xxx_28nm_get_tunable(struct phy_device *phydev, 473 struct ethtool_tunable *tuna, 474 void *data) 475 { 476 switch (tuna->id) { 477 case ETHTOOL_PHY_DOWNSHIFT: 478 return bcm_phy_downshift_get(phydev, (u8 *)data); 479 default: 480 return -EOPNOTSUPP; 481 } 482 } 483 484 static int bcm7xxx_28nm_set_tunable(struct phy_device *phydev, 485 struct ethtool_tunable *tuna, 486 const void *data) 487 { 488 u8 count = *(u8 *)data; 489 int ret; 490 491 switch (tuna->id) { 492 case ETHTOOL_PHY_DOWNSHIFT: 493 ret = bcm_phy_downshift_set(phydev, count); 494 break; 495 default: 496 return -EOPNOTSUPP; 497 } 498 499 if (ret) 500 return ret; 501 502 /* Disable EEE advertisement since this prevents the PHY 503 * from successfully linking up, trigger auto-negotiation restart 504 * to let the MAC decide what to do. 505 */ 506 ret = bcm_phy_set_eee(phydev, count == DOWNSHIFT_DEV_DISABLE); 507 if (ret) 508 return ret; 509 510 return genphy_restart_aneg(phydev); 511 } 512 513 static void bcm7xxx_28nm_get_phy_stats(struct phy_device *phydev, 514 struct ethtool_stats *stats, u64 *data) 515 { 516 struct bcm7xxx_phy_priv *priv = phydev->priv; 517 518 bcm_phy_get_stats(phydev, priv->stats, stats, data); 519 } 520 521 static int bcm7xxx_28nm_probe(struct phy_device *phydev) 522 { 523 struct bcm7xxx_phy_priv *priv; 524 525 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 526 if (!priv) 527 return -ENOMEM; 528 529 phydev->priv = priv; 530 531 priv->stats = devm_kcalloc(&phydev->mdio.dev, 532 bcm_phy_get_sset_count(phydev), sizeof(u64), 533 GFP_KERNEL); 534 if (!priv->stats) 535 return -ENOMEM; 536 537 return 0; 538 } 539 540 #define BCM7XXX_28NM_GPHY(_oui, _name) \ 541 { \ 542 .phy_id = (_oui), \ 543 .phy_id_mask = 0xfffffff0, \ 544 .name = _name, \ 545 /* PHY_GBIT_FEATURES */ \ 546 .flags = PHY_IS_INTERNAL, \ 547 .config_init = bcm7xxx_28nm_config_init, \ 548 .resume = bcm7xxx_28nm_resume, \ 549 .get_tunable = bcm7xxx_28nm_get_tunable, \ 550 .set_tunable = bcm7xxx_28nm_set_tunable, \ 551 .get_sset_count = bcm_phy_get_sset_count, \ 552 .get_strings = bcm_phy_get_strings, \ 553 .get_stats = bcm7xxx_28nm_get_phy_stats, \ 554 .probe = bcm7xxx_28nm_probe, \ 555 } 556 557 #define BCM7XXX_28NM_EPHY(_oui, _name) \ 558 { \ 559 .phy_id = (_oui), \ 560 .phy_id_mask = 0xfffffff0, \ 561 .name = _name, \ 562 /* PHY_BASIC_FEATURES */ \ 563 .flags = PHY_IS_INTERNAL, \ 564 .config_init = bcm7xxx_28nm_ephy_config_init, \ 565 .resume = bcm7xxx_28nm_ephy_resume, \ 566 .get_sset_count = bcm_phy_get_sset_count, \ 567 .get_strings = bcm_phy_get_strings, \ 568 .get_stats = bcm7xxx_28nm_get_phy_stats, \ 569 .probe = bcm7xxx_28nm_probe, \ 570 } 571 572 #define BCM7XXX_40NM_EPHY(_oui, _name) \ 573 { \ 574 .phy_id = (_oui), \ 575 .phy_id_mask = 0xfffffff0, \ 576 .name = _name, \ 577 /* PHY_BASIC_FEATURES */ \ 578 .flags = PHY_IS_INTERNAL, \ 579 .soft_reset = genphy_soft_reset, \ 580 .config_init = bcm7xxx_config_init, \ 581 .suspend = bcm7xxx_suspend, \ 582 .resume = bcm7xxx_config_init, \ 583 } 584 585 static struct phy_driver bcm7xxx_driver[] = { 586 BCM7XXX_28NM_GPHY(PHY_ID_BCM7250, "Broadcom BCM7250"), 587 BCM7XXX_28NM_EPHY(PHY_ID_BCM7255, "Broadcom BCM7255"), 588 BCM7XXX_28NM_EPHY(PHY_ID_BCM7260, "Broadcom BCM7260"), 589 BCM7XXX_28NM_EPHY(PHY_ID_BCM7268, "Broadcom BCM7268"), 590 BCM7XXX_28NM_EPHY(PHY_ID_BCM7271, "Broadcom BCM7271"), 591 BCM7XXX_28NM_GPHY(PHY_ID_BCM7278, "Broadcom BCM7278"), 592 BCM7XXX_28NM_GPHY(PHY_ID_BCM7364, "Broadcom BCM7364"), 593 BCM7XXX_28NM_GPHY(PHY_ID_BCM7366, "Broadcom BCM7366"), 594 BCM7XXX_28NM_GPHY(PHY_ID_BCM74371, "Broadcom BCM74371"), 595 BCM7XXX_28NM_GPHY(PHY_ID_BCM7439, "Broadcom BCM7439"), 596 BCM7XXX_28NM_GPHY(PHY_ID_BCM7439_2, "Broadcom BCM7439 (2)"), 597 BCM7XXX_28NM_GPHY(PHY_ID_BCM7445, "Broadcom BCM7445"), 598 BCM7XXX_40NM_EPHY(PHY_ID_BCM7346, "Broadcom BCM7346"), 599 BCM7XXX_40NM_EPHY(PHY_ID_BCM7362, "Broadcom BCM7362"), 600 BCM7XXX_40NM_EPHY(PHY_ID_BCM7425, "Broadcom BCM7425"), 601 BCM7XXX_40NM_EPHY(PHY_ID_BCM7429, "Broadcom BCM7429"), 602 BCM7XXX_40NM_EPHY(PHY_ID_BCM7435, "Broadcom BCM7435"), 603 }; 604 605 static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = { 606 { PHY_ID_BCM7250, 0xfffffff0, }, 607 { PHY_ID_BCM7255, 0xfffffff0, }, 608 { PHY_ID_BCM7260, 0xfffffff0, }, 609 { PHY_ID_BCM7268, 0xfffffff0, }, 610 { PHY_ID_BCM7271, 0xfffffff0, }, 611 { PHY_ID_BCM7278, 0xfffffff0, }, 612 { PHY_ID_BCM7364, 0xfffffff0, }, 613 { PHY_ID_BCM7366, 0xfffffff0, }, 614 { PHY_ID_BCM7346, 0xfffffff0, }, 615 { PHY_ID_BCM7362, 0xfffffff0, }, 616 { PHY_ID_BCM7425, 0xfffffff0, }, 617 { PHY_ID_BCM7429, 0xfffffff0, }, 618 { PHY_ID_BCM74371, 0xfffffff0, }, 619 { PHY_ID_BCM7439, 0xfffffff0, }, 620 { PHY_ID_BCM7435, 0xfffffff0, }, 621 { PHY_ID_BCM7445, 0xfffffff0, }, 622 { } 623 }; 624 625 module_phy_driver(bcm7xxx_driver); 626 627 MODULE_DEVICE_TABLE(mdio, bcm7xxx_tbl); 628 629 MODULE_DESCRIPTION("Broadcom BCM7xxx internal PHY driver"); 630 MODULE_LICENSE("GPL"); 631 MODULE_AUTHOR("Broadcom Corporation"); 632