diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index face04f905f1..2bd22139d2fe 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -4491,6 +4491,32 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp) | |||
4491 | return err; | 4491 | return err; |
4492 | } | 4492 | } |
4493 | 4493 | ||
4494 | static bool tg3_phy_eee_config_ok(struct tg3 *tp) | ||
4495 | { | ||
4496 | u32 val; | ||
4497 | u32 tgtadv = 0; | ||
4498 | u32 advertising = tp->link_config.advertising; | ||
4499 | |||
4500 | if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) | ||
4501 | return true; | ||
4502 | |||
4503 | if (tg3_phy_cl45_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, &val)) | ||
4504 | return false; | ||
4505 | |||
4506 | val &= (MDIO_AN_EEE_ADV_100TX | MDIO_AN_EEE_ADV_1000T); | ||
4507 | |||
4508 | |||
4509 | if (advertising & ADVERTISED_100baseT_Full) | ||
4510 | tgtadv |= MDIO_AN_EEE_ADV_100TX; | ||
4511 | if (advertising & ADVERTISED_1000baseT_Full) | ||
4512 | tgtadv |= MDIO_AN_EEE_ADV_1000T; | ||
4513 | |||
4514 | if (val != tgtadv) | ||
4515 | return false; | ||
4516 | |||
4517 | return true; | ||
4518 | } | ||
4519 | |||
4494 | static bool tg3_phy_copper_an_config_ok(struct tg3 *tp, u32 *lcladv) | 4520 | static bool tg3_phy_copper_an_config_ok(struct tg3 *tp, u32 *lcladv) |
4495 | { | 4521 | { |
4496 | u32 advmsk, tgtadv, advertising; | 4522 | u32 advmsk, tgtadv, advertising; |
@@ -4739,10 +4765,22 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) | |||
4739 | tp->link_config.active_duplex = current_duplex; | 4765 | tp->link_config.active_duplex = current_duplex; |
4740 | 4766 | ||
4741 | if (tp->link_config.autoneg == AUTONEG_ENABLE) { | 4767 | if (tp->link_config.autoneg == AUTONEG_ENABLE) { |
4768 | bool eee_config_ok = tg3_phy_eee_config_ok(tp); | ||
4769 | |||
4742 | if ((bmcr & BMCR_ANENABLE) && | 4770 | if ((bmcr & BMCR_ANENABLE) && |
4771 | eee_config_ok && | ||
4743 | tg3_phy_copper_an_config_ok(tp, &lcl_adv) && | 4772 | tg3_phy_copper_an_config_ok(tp, &lcl_adv) && |
4744 | tg3_phy_copper_fetch_rmtadv(tp, &rmt_adv)) | 4773 | tg3_phy_copper_fetch_rmtadv(tp, &rmt_adv)) |
4745 | current_link_up = 1; | 4774 | current_link_up = 1; |
4775 | |||
4776 | /* EEE settings changes take effect only after a phy | ||
4777 | * reset. If we have skipped a reset due to Link Flap | ||
4778 | * Avoidance being enabled, do it now. | ||
4779 | */ | ||
4780 | if (!eee_config_ok && | ||
4781 | (tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN) && | ||
4782 | !force_reset) | ||
4783 | tg3_phy_reset(tp); | ||
4746 | } else { | 4784 | } else { |
4747 | if (!(bmcr & BMCR_ANENABLE) && | 4785 | if (!(bmcr & BMCR_ANENABLE) && |
4748 | tp->link_config.speed == current_speed && | 4786 | tp->link_config.speed == current_speed && |