static int bcm7xxx_28nm_set_tunable(struct phy_device *phydev, struct ethtool_tunable *tuna, const void *data) { u8 count = *(u8 *)data; int ret; switch (tuna->id) { case ETHTOOL_PHY_DOWNSHIFT: ret = bcm_phy_downshift_set(phydev, count); break; default: return -EOPNOTSUPP; } if (ret) return ret; /* Disable EEE advertisment since this prevents the PHY * from successfully linking up, trigger auto-negotiation restart * to let the MAC decide what to do. */ ret = bcm_phy_set_eee(phydev, count == DOWNSHIFT_DEV_DISABLE); if (ret) return ret; return genphy_restart_aneg(phydev); }
static int bcm_cygnus_config_init(struct phy_device *phydev) { int reg, rc; reg = phy_read(phydev, MII_BCM54XX_ECR); if (reg < 0) return reg; /* Mask interrupts globally. */ reg |= MII_BCM54XX_ECR_IM; rc = phy_write(phydev, MII_BCM54XX_ECR, reg); if (rc) return rc; /* Unmask events of interest */ reg = ~(MII_BCM54XX_INT_DUPLEX | MII_BCM54XX_INT_SPEED | MII_BCM54XX_INT_LINK); rc = phy_write(phydev, MII_BCM54XX_IMR, reg); if (rc) return rc; /* Apply AFE settings for the PHY */ rc = bcm_cygnus_afe_config(phydev); if (rc) return rc; /* Advertise EEE */ rc = bcm_phy_set_eee(phydev, true); if (rc) return rc; /* Enable APD */ return bcm_phy_enable_apd(phydev, false); }
static int bcm7xxx_28nm_config_init(struct phy_device *phydev) { u8 rev = PHY_BRCM_7XXX_REV(phydev->dev_flags); u8 patch = PHY_BRCM_7XXX_PATCH(phydev->dev_flags); u8 count; int ret = 0; /* Newer devices have moved the revision information back into a * standard location in MII_PHYS_ID[23] */ if (rev == 0) rev = phydev->phy_id & ~phydev->drv->phy_id_mask; pr_info_once("%s: %s PHY revision: 0x%02x, patch: %d\n", phydev_name(phydev), phydev->drv->name, rev, patch); /* Dummy read to a register to workaround an issue upon reset where the * internal inverter may not allow the first MDIO transaction to pass * the MDIO management controller and make us return 0xffff for such * reads. */ phy_read(phydev, MII_BMSR); switch (rev) { case 0xb0: ret = bcm7xxx_28nm_b0_afe_config_init(phydev); break; case 0xd0: ret = bcm7xxx_28nm_d0_afe_config_init(phydev); break; case 0xe0: case 0xf0: /* Rev G0 introduces a roll over */ case 0x10: ret = bcm7xxx_28nm_e0_plus_afe_config_init(phydev); break; case 0x01: ret = bcm7xxx_28nm_a0_patch_afe_config_init(phydev); break; default: break; } if (ret) return ret; ret = bcm_phy_downshift_get(phydev, &count); if (ret) return ret; /* Only enable EEE if Wirespeed/downshift is disabled */ ret = bcm_phy_set_eee(phydev, count == DOWNSHIFT_DEV_DISABLE); if (ret) return ret; return bcm_phy_enable_apd(phydev, true); }