aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2011-05-19 08:12:49 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-19 18:00:00 -0400
commit42b64a450b81ec9e8cdd5b3fb13613ab9bb25048 (patch)
treef7e12d489f81d6acf0d4b1e0ac693abcb5643fdf /drivers/net
parentb0c5943f1ca4df6c1c451ef6be5287a161d29a9d (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')
-rw-r--r--drivers/net/tg3.c217
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
2932static void tg3_phy_copper_begin(struct tg3 *tp) 2932static 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
3009done:
3010 return err;
3011}
3012
3013static 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
12999skip_phy_reset: 12980skip_phy_reset: