diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2011-05-19 08:12:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-19 18:00:00 -0400 |
commit | 42b64a450b81ec9e8cdd5b3fb13613ab9bb25048 (patch) | |
tree | f7e12d489f81d6acf0d4b1e0ac693abcb5643fdf /drivers/net/tg3.c | |
parent | b0c5943f1ca4df6c1c451ef6be5287a161d29a9d (diff) |
tg3: Consolidate autoneg advertisement setup code
Autonegotiation setup has gotten a little more complicated since the tg3
driver was created. This patch consolidates autoneg setup into one
routine and modifies the call sites accordingly.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 217 |
1 files changed, 99 insertions, 118 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 695dab274d1e..7675231d9a9d 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -2929,102 +2929,54 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 | |||
2929 | } | 2929 | } |
2930 | } | 2930 | } |
2931 | 2931 | ||
2932 | static void tg3_phy_copper_begin(struct tg3 *tp) | 2932 | static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) |
2933 | { | 2933 | { |
2934 | u32 new_adv; | 2934 | int err = 0; |
2935 | int i; | 2935 | u32 val, new_adv; |
2936 | |||
2937 | if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) { | ||
2938 | /* Entering low power mode. Disable gigabit and | ||
2939 | * 100baseT advertisements. | ||
2940 | */ | ||
2941 | tg3_writephy(tp, MII_TG3_CTRL, 0); | ||
2942 | 2936 | ||
2943 | new_adv = (ADVERTISE_10HALF | ADVERTISE_10FULL | | 2937 | new_adv = ADVERTISE_CSMA; |
2944 | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); | 2938 | if (advertise & ADVERTISED_10baseT_Half) |
2945 | if (tg3_flag(tp, WOL_SPEED_100MB)) | 2939 | new_adv |= ADVERTISE_10HALF; |
2946 | new_adv |= (ADVERTISE_100HALF | ADVERTISE_100FULL); | 2940 | if (advertise & ADVERTISED_10baseT_Full) |
2941 | new_adv |= ADVERTISE_10FULL; | ||
2942 | if (advertise & ADVERTISED_100baseT_Half) | ||
2943 | new_adv |= ADVERTISE_100HALF; | ||
2944 | if (advertise & ADVERTISED_100baseT_Full) | ||
2945 | new_adv |= ADVERTISE_100FULL; | ||
2947 | 2946 | ||
2948 | tg3_writephy(tp, MII_ADVERTISE, new_adv); | 2947 | new_adv |= tg3_advert_flowctrl_1000T(flowctrl); |
2949 | } else if (tp->link_config.speed == SPEED_INVALID) { | ||
2950 | if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) | ||
2951 | tp->link_config.advertising &= | ||
2952 | ~(ADVERTISED_1000baseT_Half | | ||
2953 | ADVERTISED_1000baseT_Full); | ||
2954 | 2948 | ||
2955 | new_adv = ADVERTISE_CSMA; | 2949 | err = tg3_writephy(tp, MII_ADVERTISE, new_adv); |
2956 | if (tp->link_config.advertising & ADVERTISED_10baseT_Half) | 2950 | if (err) |
2957 | new_adv |= ADVERTISE_10HALF; | 2951 | goto done; |
2958 | if (tp->link_config.advertising & ADVERTISED_10baseT_Full) | ||
2959 | new_adv |= ADVERTISE_10FULL; | ||
2960 | if (tp->link_config.advertising & ADVERTISED_100baseT_Half) | ||
2961 | new_adv |= ADVERTISE_100HALF; | ||
2962 | if (tp->link_config.advertising & ADVERTISED_100baseT_Full) | ||
2963 | new_adv |= ADVERTISE_100FULL; | ||
2964 | |||
2965 | new_adv |= tg3_advert_flowctrl_1000T(tp->link_config.flowctrl); | ||
2966 | |||
2967 | tg3_writephy(tp, MII_ADVERTISE, new_adv); | ||
2968 | |||
2969 | if (tp->link_config.advertising & | ||
2970 | (ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full)) { | ||
2971 | new_adv = 0; | ||
2972 | if (tp->link_config.advertising & ADVERTISED_1000baseT_Half) | ||
2973 | new_adv |= MII_TG3_CTRL_ADV_1000_HALF; | ||
2974 | if (tp->link_config.advertising & ADVERTISED_1000baseT_Full) | ||
2975 | new_adv |= MII_TG3_CTRL_ADV_1000_FULL; | ||
2976 | if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY) && | ||
2977 | (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || | ||
2978 | tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)) | ||
2979 | new_adv |= (MII_TG3_CTRL_AS_MASTER | | ||
2980 | MII_TG3_CTRL_ENABLE_AS_MASTER); | ||
2981 | tg3_writephy(tp, MII_TG3_CTRL, new_adv); | ||
2982 | } else { | ||
2983 | tg3_writephy(tp, MII_TG3_CTRL, 0); | ||
2984 | } | ||
2985 | } else { | ||
2986 | new_adv = tg3_advert_flowctrl_1000T(tp->link_config.flowctrl); | ||
2987 | new_adv |= ADVERTISE_CSMA; | ||
2988 | 2952 | ||
2989 | /* Asking for a specific link mode. */ | 2953 | if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) |
2990 | if (tp->link_config.speed == SPEED_1000) { | 2954 | goto done; |
2991 | tg3_writephy(tp, MII_ADVERTISE, new_adv); | ||
2992 | 2955 | ||
2993 | if (tp->link_config.duplex == DUPLEX_FULL) | 2956 | new_adv = 0; |
2994 | new_adv = MII_TG3_CTRL_ADV_1000_FULL; | 2957 | if (advertise & ADVERTISED_1000baseT_Half) |
2995 | else | 2958 | new_adv |= MII_TG3_CTRL_ADV_1000_HALF; |
2996 | new_adv = MII_TG3_CTRL_ADV_1000_HALF; | 2959 | if (advertise & ADVERTISED_1000baseT_Full) |
2997 | if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || | 2960 | new_adv |= MII_TG3_CTRL_ADV_1000_FULL; |
2998 | tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) | ||
2999 | new_adv |= (MII_TG3_CTRL_AS_MASTER | | ||
3000 | MII_TG3_CTRL_ENABLE_AS_MASTER); | ||
3001 | } else { | ||
3002 | if (tp->link_config.speed == SPEED_100) { | ||
3003 | if (tp->link_config.duplex == DUPLEX_FULL) | ||
3004 | new_adv |= ADVERTISE_100FULL; | ||
3005 | else | ||
3006 | new_adv |= ADVERTISE_100HALF; | ||
3007 | } else { | ||
3008 | if (tp->link_config.duplex == DUPLEX_FULL) | ||
3009 | new_adv |= ADVERTISE_10FULL; | ||
3010 | else | ||
3011 | new_adv |= ADVERTISE_10HALF; | ||
3012 | } | ||
3013 | tg3_writephy(tp, MII_ADVERTISE, new_adv); | ||
3014 | 2961 | ||
3015 | new_adv = 0; | 2962 | if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || |
3016 | } | 2963 | tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) |
2964 | new_adv |= (MII_TG3_CTRL_AS_MASTER | | ||
2965 | MII_TG3_CTRL_ENABLE_AS_MASTER); | ||
3017 | 2966 | ||
3018 | tg3_writephy(tp, MII_TG3_CTRL, new_adv); | 2967 | err = tg3_writephy(tp, MII_TG3_CTRL, new_adv); |
3019 | } | 2968 | if (err) |
2969 | goto done; | ||
3020 | 2970 | ||
3021 | if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) { | 2971 | if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) |
3022 | u32 val; | 2972 | goto done; |
3023 | 2973 | ||
3024 | tw32(TG3_CPMU_EEE_MODE, | 2974 | tw32(TG3_CPMU_EEE_MODE, |
3025 | tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); | 2975 | tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); |
3026 | 2976 | ||
3027 | TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); | 2977 | err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); |
2978 | if (!err) { | ||
2979 | u32 err2; | ||
3028 | 2980 | ||
3029 | switch (GET_ASIC_REV(tp->pci_chip_rev_id)) { | 2981 | switch (GET_ASIC_REV(tp->pci_chip_rev_id)) { |
3030 | case ASIC_REV_5717: | 2982 | case ASIC_REV_5717: |
@@ -3041,19 +2993,66 @@ static void tg3_phy_copper_begin(struct tg3 *tp) | |||
3041 | } | 2993 | } |
3042 | 2994 | ||
3043 | val = 0; | 2995 | val = 0; |
3044 | if (tp->link_config.autoneg == AUTONEG_ENABLE) { | 2996 | /* Advertise 100-BaseTX EEE ability */ |
3045 | /* Advertise 100-BaseTX EEE ability */ | 2997 | if (advertise & ADVERTISED_100baseT_Full) |
3046 | if (tp->link_config.advertising & | 2998 | val |= MDIO_AN_EEE_ADV_100TX; |
3047 | ADVERTISED_100baseT_Full) | 2999 | /* Advertise 1000-BaseT EEE ability */ |
3048 | val |= MDIO_AN_EEE_ADV_100TX; | 3000 | if (advertise & ADVERTISED_1000baseT_Full) |
3049 | /* Advertise 1000-BaseT EEE ability */ | 3001 | val |= MDIO_AN_EEE_ADV_1000T; |
3050 | if (tp->link_config.advertising & | 3002 | err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); |
3051 | ADVERTISED_1000baseT_Full) | 3003 | |
3052 | val |= MDIO_AN_EEE_ADV_1000T; | 3004 | err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); |
3005 | if (!err) | ||
3006 | err = err2; | ||
3007 | } | ||
3008 | |||
3009 | done: | ||
3010 | return err; | ||
3011 | } | ||
3012 | |||
3013 | static void tg3_phy_copper_begin(struct tg3 *tp) | ||
3014 | { | ||
3015 | u32 new_adv; | ||
3016 | int i; | ||
3017 | |||
3018 | if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) { | ||
3019 | new_adv = ADVERTISED_10baseT_Half | | ||
3020 | ADVERTISED_10baseT_Full; | ||
3021 | if (tg3_flag(tp, WOL_SPEED_100MB)) | ||
3022 | new_adv |= ADVERTISED_100baseT_Half | | ||
3023 | ADVERTISED_100baseT_Full; | ||
3024 | |||
3025 | tg3_phy_autoneg_cfg(tp, new_adv, | ||
3026 | FLOW_CTRL_TX | FLOW_CTRL_RX); | ||
3027 | } else if (tp->link_config.speed == SPEED_INVALID) { | ||
3028 | if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) | ||
3029 | tp->link_config.advertising &= | ||
3030 | ~(ADVERTISED_1000baseT_Half | | ||
3031 | ADVERTISED_1000baseT_Full); | ||
3032 | |||
3033 | tg3_phy_autoneg_cfg(tp, tp->link_config.advertising, | ||
3034 | tp->link_config.flowctrl); | ||
3035 | } else { | ||
3036 | /* Asking for a specific link mode. */ | ||
3037 | if (tp->link_config.speed == SPEED_1000) { | ||
3038 | if (tp->link_config.duplex == DUPLEX_FULL) | ||
3039 | new_adv = ADVERTISED_1000baseT_Full; | ||
3040 | else | ||
3041 | new_adv = ADVERTISED_1000baseT_Half; | ||
3042 | } else if (tp->link_config.speed == SPEED_100) { | ||
3043 | if (tp->link_config.duplex == DUPLEX_FULL) | ||
3044 | new_adv = ADVERTISED_100baseT_Full; | ||
3045 | else | ||
3046 | new_adv = ADVERTISED_100baseT_Half; | ||
3047 | } else { | ||
3048 | if (tp->link_config.duplex == DUPLEX_FULL) | ||
3049 | new_adv = ADVERTISED_10baseT_Full; | ||
3050 | else | ||
3051 | new_adv = ADVERTISED_10baseT_Half; | ||
3053 | } | 3052 | } |
3054 | tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); | ||
3055 | 3053 | ||
3056 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 3054 | tg3_phy_autoneg_cfg(tp, new_adv, |
3055 | tp->link_config.flowctrl); | ||
3057 | } | 3056 | } |
3058 | 3057 | ||
3059 | if (tp->link_config.autoneg == AUTONEG_DISABLE && | 3058 | if (tp->link_config.autoneg == AUTONEG_DISABLE && |
@@ -12953,7 +12952,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) | |||
12953 | if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && | 12952 | if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && |
12954 | !tg3_flag(tp, ENABLE_APE) && | 12953 | !tg3_flag(tp, ENABLE_APE) && |
12955 | !tg3_flag(tp, ENABLE_ASF)) { | 12954 | !tg3_flag(tp, ENABLE_ASF)) { |
12956 | u32 bmsr, adv_reg, tg3_ctrl, mask; | 12955 | u32 bmsr, mask; |
12957 | 12956 | ||
12958 | tg3_readphy(tp, MII_BMSR, &bmsr); | 12957 | tg3_readphy(tp, MII_BMSR, &bmsr); |
12959 | if (!tg3_readphy(tp, MII_BMSR, &bmsr) && | 12958 | if (!tg3_readphy(tp, MII_BMSR, &bmsr) && |
@@ -12964,36 +12963,18 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) | |||
12964 | if (err) | 12963 | if (err) |
12965 | return err; | 12964 | return err; |
12966 | 12965 | ||
12967 | adv_reg = (ADVERTISE_10HALF | ADVERTISE_10FULL | | 12966 | tg3_phy_set_wirespeed(tp); |
12968 | ADVERTISE_100HALF | ADVERTISE_100FULL | | ||
12969 | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); | ||
12970 | tg3_ctrl = 0; | ||
12971 | if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { | ||
12972 | tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF | | ||
12973 | MII_TG3_CTRL_ADV_1000_FULL); | ||
12974 | if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || | ||
12975 | tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) | ||
12976 | tg3_ctrl |= (MII_TG3_CTRL_AS_MASTER | | ||
12977 | MII_TG3_CTRL_ENABLE_AS_MASTER); | ||
12978 | } | ||
12979 | 12967 | ||
12980 | mask = (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | | 12968 | mask = (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | |
12981 | ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | | 12969 | ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | |
12982 | ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); | 12970 | ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); |
12983 | if (!tg3_copper_is_advertising_all(tp, mask)) { | 12971 | if (!tg3_copper_is_advertising_all(tp, mask)) { |
12984 | tg3_writephy(tp, MII_ADVERTISE, adv_reg); | 12972 | tg3_phy_autoneg_cfg(tp, tp->link_config.advertising, |
12985 | 12973 | tp->link_config.flowctrl); | |
12986 | if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) | ||
12987 | tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl); | ||
12988 | 12974 | ||
12989 | tg3_writephy(tp, MII_BMCR, | 12975 | tg3_writephy(tp, MII_BMCR, |
12990 | BMCR_ANENABLE | BMCR_ANRESTART); | 12976 | BMCR_ANENABLE | BMCR_ANRESTART); |
12991 | } | 12977 | } |
12992 | tg3_phy_set_wirespeed(tp); | ||
12993 | |||
12994 | tg3_writephy(tp, MII_ADVERTISE, adv_reg); | ||
12995 | if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) | ||
12996 | tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl); | ||
12997 | } | 12978 | } |
12998 | 12979 | ||
12999 | skip_phy_reset: | 12980 | skip_phy_reset: |