tg3: Integrate flowctrl check into AN adv check
This patch integrates tg3_adv_1000T_flowctrl_ok() into tg3_copper_is_advertising_all() and renames the function tg3_phy_copper_an_config_ok(). Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Reviewed-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
92feeabf3f
commit
e2bf73e75a
1 changed files with 25 additions and 56 deletions
|
@ -3768,65 +3768,39 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask)
|
static bool tg3_phy_copper_an_config_ok(struct tg3 *tp, u32 *lcladv)
|
||||||
{
|
{
|
||||||
u32 adv_reg, all_mask = 0;
|
u32 advmsk, tgtadv, advertising;
|
||||||
|
|
||||||
all_mask = ethtool_adv_to_mii_adv_t(mask) & ADVERTISE_ALL;
|
advertising = tp->link_config.advertising;
|
||||||
|
tgtadv = ethtool_adv_to_mii_adv_t(advertising) & ADVERTISE_ALL;
|
||||||
|
|
||||||
if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg))
|
advmsk = ADVERTISE_ALL;
|
||||||
return 0;
|
if (tp->link_config.active_duplex == DUPLEX_FULL) {
|
||||||
|
tgtadv |= tg3_advert_flowctrl_1000T(tp->link_config.flowctrl);
|
||||||
|
advmsk |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
|
||||||
|
}
|
||||||
|
|
||||||
if ((adv_reg & ADVERTISE_ALL) != all_mask)
|
if (tg3_readphy(tp, MII_ADVERTISE, lcladv))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
|
if ((*lcladv & advmsk) != tgtadv)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
|
if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
|
||||||
u32 tg3_ctrl;
|
u32 tg3_ctrl;
|
||||||
|
|
||||||
all_mask = ethtool_adv_to_mii_ctrl1000_t(mask);
|
tgtadv = ethtool_adv_to_mii_ctrl1000_t(advertising);
|
||||||
|
|
||||||
if (tg3_readphy(tp, MII_CTRL1000, &tg3_ctrl))
|
if (tg3_readphy(tp, MII_CTRL1000, &tg3_ctrl))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
tg3_ctrl &= (ADVERTISE_1000HALF | ADVERTISE_1000FULL);
|
tg3_ctrl &= (ADVERTISE_1000HALF | ADVERTISE_1000FULL);
|
||||||
if (tg3_ctrl != all_mask)
|
if (tg3_ctrl != tgtadv)
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
static int tg3_adv_1000T_flowctrl_ok(struct tg3 *tp, u32 *lcladv, u32 *rmtadv)
|
|
||||||
{
|
|
||||||
u32 curadv, reqadv;
|
|
||||||
|
|
||||||
if (tg3_readphy(tp, MII_ADVERTISE, lcladv))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
curadv = *lcladv & (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
|
|
||||||
reqadv = tg3_advert_flowctrl_1000T(tp->link_config.flowctrl);
|
|
||||||
|
|
||||||
if (tp->link_config.active_duplex == DUPLEX_FULL) {
|
|
||||||
if (curadv != reqadv)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (tg3_flag(tp, PAUSE_AUTONEG))
|
|
||||||
tg3_readphy(tp, MII_LPA, rmtadv);
|
|
||||||
} else {
|
|
||||||
/* Reprogram the advertisement register, even if it
|
|
||||||
* does not affect the current link. If the link
|
|
||||||
* gets renegotiated in the future, we can save an
|
|
||||||
* additional renegotiation cycle by advertising
|
|
||||||
* it correctly in the first place.
|
|
||||||
*/
|
|
||||||
if (curadv != reqadv) {
|
|
||||||
*lcladv &= ~(ADVERTISE_PAUSE_CAP |
|
|
||||||
ADVERTISE_PAUSE_ASYM);
|
|
||||||
tg3_writephy(tp, MII_ADVERTISE, *lcladv | reqadv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
|
static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
|
||||||
|
@ -3988,12 +3962,10 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
|
||||||
|
|
||||||
if (tp->link_config.autoneg == AUTONEG_ENABLE) {
|
if (tp->link_config.autoneg == AUTONEG_ENABLE) {
|
||||||
if ((bmcr & BMCR_ANENABLE) &&
|
if ((bmcr & BMCR_ANENABLE) &&
|
||||||
tg3_copper_is_advertising_all(tp,
|
tg3_phy_copper_an_config_ok(tp, &lcl_adv) &&
|
||||||
tp->link_config.advertising)) {
|
(tg3_flag(tp, PAUSE_AUTONEG) &&
|
||||||
if (tg3_adv_1000T_flowctrl_ok(tp, &lcl_adv,
|
!tg3_readphy(tp, MII_LPA, &rmt_adv)))
|
||||||
&rmt_adv))
|
current_link_up = 1;
|
||||||
current_link_up = 1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!(bmcr & BMCR_ANENABLE) &&
|
if (!(bmcr & BMCR_ANENABLE) &&
|
||||||
tp->link_config.speed == current_speed &&
|
tp->link_config.speed == current_speed &&
|
||||||
|
@ -13323,7 +13295,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
|
||||||
if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
|
if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
|
||||||
!tg3_flag(tp, ENABLE_APE) &&
|
!tg3_flag(tp, ENABLE_APE) &&
|
||||||
!tg3_flag(tp, ENABLE_ASF)) {
|
!tg3_flag(tp, ENABLE_ASF)) {
|
||||||
u32 bmsr, mask;
|
u32 bmsr, dummy;
|
||||||
|
|
||||||
tg3_readphy(tp, MII_BMSR, &bmsr);
|
tg3_readphy(tp, MII_BMSR, &bmsr);
|
||||||
if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
|
if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
|
||||||
|
@ -13336,10 +13308,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
|
||||||
|
|
||||||
tg3_phy_set_wirespeed(tp);
|
tg3_phy_set_wirespeed(tp);
|
||||||
|
|
||||||
mask = (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
|
if (!tg3_phy_copper_an_config_ok(tp, &dummy)) {
|
||||||
ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
|
|
||||||
ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full);
|
|
||||||
if (!tg3_copper_is_advertising_all(tp, mask)) {
|
|
||||||
tg3_phy_autoneg_cfg(tp, tp->link_config.advertising,
|
tg3_phy_autoneg_cfg(tp, tp->link_config.advertising,
|
||||||
tp->link_config.flowctrl);
|
tp->link_config.flowctrl);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue