root/drivers/net/phy/bcm7xxx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bcm7xxx_28nm_d0_afe_config_init
  2. bcm7xxx_28nm_e0_plus_afe_config_init
  3. bcm7xxx_28nm_a0_patch_afe_config_init
  4. bcm7xxx_28nm_config_init
  5. bcm7xxx_28nm_resume
  6. phy_set_clr_bits
  7. bcm7xxx_28nm_ephy_01_afe_config_init
  8. bcm7xxx_28nm_ephy_apd_enable
  9. bcm7xxx_28nm_ephy_eee_enable
  10. bcm7xxx_28nm_ephy_config_init
  11. bcm7xxx_28nm_ephy_resume
  12. bcm7xxx_config_init
  13. bcm7xxx_suspend
  14. bcm7xxx_28nm_get_tunable
  15. bcm7xxx_28nm_set_tunable
  16. bcm7xxx_28nm_get_phy_stats
  17. bcm7xxx_28nm_probe

   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         .soft_reset     = genphy_soft_reset,                            \
 576         .config_init    = bcm7xxx_config_init,                          \
 577         .suspend        = bcm7xxx_suspend,                              \
 578         .resume         = bcm7xxx_config_init,                          \
 579 }
 580 
 581 static struct phy_driver bcm7xxx_driver[] = {
 582         BCM7XXX_28NM_GPHY(PHY_ID_BCM7250, "Broadcom BCM7250"),
 583         BCM7XXX_28NM_EPHY(PHY_ID_BCM7255, "Broadcom BCM7255"),
 584         BCM7XXX_28NM_EPHY(PHY_ID_BCM7260, "Broadcom BCM7260"),
 585         BCM7XXX_28NM_EPHY(PHY_ID_BCM7268, "Broadcom BCM7268"),
 586         BCM7XXX_28NM_EPHY(PHY_ID_BCM7271, "Broadcom BCM7271"),
 587         BCM7XXX_28NM_GPHY(PHY_ID_BCM7278, "Broadcom BCM7278"),
 588         BCM7XXX_28NM_GPHY(PHY_ID_BCM7364, "Broadcom BCM7364"),
 589         BCM7XXX_28NM_GPHY(PHY_ID_BCM7366, "Broadcom BCM7366"),
 590         BCM7XXX_28NM_GPHY(PHY_ID_BCM74371, "Broadcom BCM74371"),
 591         BCM7XXX_28NM_GPHY(PHY_ID_BCM7439, "Broadcom BCM7439"),
 592         BCM7XXX_28NM_GPHY(PHY_ID_BCM7439_2, "Broadcom BCM7439 (2)"),
 593         BCM7XXX_28NM_GPHY(PHY_ID_BCM7445, "Broadcom BCM7445"),
 594         BCM7XXX_40NM_EPHY(PHY_ID_BCM7346, "Broadcom BCM7346"),
 595         BCM7XXX_40NM_EPHY(PHY_ID_BCM7362, "Broadcom BCM7362"),
 596         BCM7XXX_40NM_EPHY(PHY_ID_BCM7425, "Broadcom BCM7425"),
 597         BCM7XXX_40NM_EPHY(PHY_ID_BCM7429, "Broadcom BCM7429"),
 598         BCM7XXX_40NM_EPHY(PHY_ID_BCM7435, "Broadcom BCM7435"),
 599 };
 600 
 601 static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
 602         { PHY_ID_BCM7250, 0xfffffff0, },
 603         { PHY_ID_BCM7255, 0xfffffff0, },
 604         { PHY_ID_BCM7260, 0xfffffff0, },
 605         { PHY_ID_BCM7268, 0xfffffff0, },
 606         { PHY_ID_BCM7271, 0xfffffff0, },
 607         { PHY_ID_BCM7278, 0xfffffff0, },
 608         { PHY_ID_BCM7364, 0xfffffff0, },
 609         { PHY_ID_BCM7366, 0xfffffff0, },
 610         { PHY_ID_BCM7346, 0xfffffff0, },
 611         { PHY_ID_BCM7362, 0xfffffff0, },
 612         { PHY_ID_BCM7425, 0xfffffff0, },
 613         { PHY_ID_BCM7429, 0xfffffff0, },
 614         { PHY_ID_BCM74371, 0xfffffff0, },
 615         { PHY_ID_BCM7439, 0xfffffff0, },
 616         { PHY_ID_BCM7435, 0xfffffff0, },
 617         { PHY_ID_BCM7445, 0xfffffff0, },
 618         { }
 619 };
 620 
 621 module_phy_driver(bcm7xxx_driver);
 622 
 623 MODULE_DEVICE_TABLE(mdio, bcm7xxx_tbl);
 624 
 625 MODULE_DESCRIPTION("Broadcom BCM7xxx internal PHY driver");
 626 MODULE_LICENSE("GPL");
 627 MODULE_AUTHOR("Broadcom Corporation");

/* [<][>][^][v][top][bottom][index][help] */