diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/tg3.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 3caead4c2702..cdade05bdd07 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -1695,7 +1695,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv | |||
1695 | u32 old_tx_mode = tp->tx_mode; | 1695 | u32 old_tx_mode = tp->tx_mode; |
1696 | 1696 | ||
1697 | if (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) { | 1697 | if (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) { |
1698 | if (tp->tg3_flags2 & (TG3_FLG2_MII_SERDES|TG3_FLG2_HW_AUTONEG)) | 1698 | if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) |
1699 | new_tg3_flags = tg3_resolve_flowctrl_1000X(local_adv, | 1699 | new_tg3_flags = tg3_resolve_flowctrl_1000X(local_adv, |
1700 | remote_adv); | 1700 | remote_adv); |
1701 | else | 1701 | else |
@@ -2317,6 +2317,7 @@ struct tg3_fiber_aneginfo { | |||
2317 | static int tg3_fiber_aneg_smachine(struct tg3 *tp, | 2317 | static int tg3_fiber_aneg_smachine(struct tg3 *tp, |
2318 | struct tg3_fiber_aneginfo *ap) | 2318 | struct tg3_fiber_aneginfo *ap) |
2319 | { | 2319 | { |
2320 | u16 flowctrl; | ||
2320 | unsigned long delta; | 2321 | unsigned long delta; |
2321 | u32 rx_cfg_reg; | 2322 | u32 rx_cfg_reg; |
2322 | int ret; | 2323 | int ret; |
@@ -2416,7 +2417,12 @@ static int tg3_fiber_aneg_smachine(struct tg3 *tp, | |||
2416 | 2417 | ||
2417 | case ANEG_STATE_ABILITY_DETECT_INIT: | 2418 | case ANEG_STATE_ABILITY_DETECT_INIT: |
2418 | ap->flags &= ~(MR_TOGGLE_TX); | 2419 | ap->flags &= ~(MR_TOGGLE_TX); |
2419 | ap->txconfig = (ANEG_CFG_FD | ANEG_CFG_PS1); | 2420 | ap->txconfig = ANEG_CFG_FD; |
2421 | flowctrl = tg3_advert_flowctrl_1000X(tp->link_config.flowctrl); | ||
2422 | if (flowctrl & ADVERTISE_1000XPAUSE) | ||
2423 | ap->txconfig |= ANEG_CFG_PS1; | ||
2424 | if (flowctrl & ADVERTISE_1000XPSE_ASYM) | ||
2425 | ap->txconfig |= ANEG_CFG_PS2; | ||
2420 | tw32(MAC_TX_AUTO_NEG, ap->txconfig); | 2426 | tw32(MAC_TX_AUTO_NEG, ap->txconfig); |
2421 | tp->mac_mode |= MAC_MODE_SEND_CONFIGS; | 2427 | tp->mac_mode |= MAC_MODE_SEND_CONFIGS; |
2422 | tw32_f(MAC_MODE, tp->mac_mode); | 2428 | tw32_f(MAC_MODE, tp->mac_mode); |
@@ -2562,7 +2568,7 @@ static int tg3_fiber_aneg_smachine(struct tg3 *tp, | |||
2562 | return ret; | 2568 | return ret; |
2563 | } | 2569 | } |
2564 | 2570 | ||
2565 | static int fiber_autoneg(struct tg3 *tp, u32 *flags) | 2571 | static int fiber_autoneg(struct tg3 *tp, u32 *txflags, u32 *rxflags) |
2566 | { | 2572 | { |
2567 | int res = 0; | 2573 | int res = 0; |
2568 | struct tg3_fiber_aneginfo aninfo; | 2574 | struct tg3_fiber_aneginfo aninfo; |
@@ -2596,7 +2602,8 @@ static int fiber_autoneg(struct tg3 *tp, u32 *flags) | |||
2596 | tw32_f(MAC_MODE, tp->mac_mode); | 2602 | tw32_f(MAC_MODE, tp->mac_mode); |
2597 | udelay(40); | 2603 | udelay(40); |
2598 | 2604 | ||
2599 | *flags = aninfo.flags; | 2605 | *txflags = aninfo.txconfig; |
2606 | *rxflags = aninfo.flags; | ||
2600 | 2607 | ||
2601 | if (status == ANEG_DONE && | 2608 | if (status == ANEG_DONE && |
2602 | (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK | | 2609 | (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK | |
@@ -2806,18 +2813,21 @@ static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status) | |||
2806 | goto out; | 2813 | goto out; |
2807 | 2814 | ||
2808 | if (tp->link_config.autoneg == AUTONEG_ENABLE) { | 2815 | if (tp->link_config.autoneg == AUTONEG_ENABLE) { |
2809 | u32 flags; | 2816 | u32 txflags, rxflags; |
2810 | int i; | 2817 | int i; |
2811 | 2818 | ||
2812 | if (fiber_autoneg(tp, &flags)) { | 2819 | if (fiber_autoneg(tp, &txflags, &rxflags)) { |
2813 | u32 local_adv, remote_adv; | 2820 | u32 local_adv = 0, remote_adv = 0; |
2814 | 2821 | ||
2815 | local_adv = ADVERTISE_PAUSE_CAP; | 2822 | if (txflags & ANEG_CFG_PS1) |
2816 | remote_adv = 0; | 2823 | local_adv |= ADVERTISE_1000XPAUSE; |
2817 | if (flags & MR_LP_ADV_SYM_PAUSE) | 2824 | if (txflags & ANEG_CFG_PS2) |
2818 | remote_adv |= LPA_PAUSE_CAP; | 2825 | local_adv |= ADVERTISE_1000XPSE_ASYM; |
2819 | if (flags & MR_LP_ADV_ASYM_PAUSE) | 2826 | |
2820 | remote_adv |= LPA_PAUSE_ASYM; | 2827 | if (rxflags & MR_LP_ADV_SYM_PAUSE) |
2828 | remote_adv |= LPA_1000XPAUSE; | ||
2829 | if (rxflags & MR_LP_ADV_ASYM_PAUSE) | ||
2830 | remote_adv |= LPA_1000XPAUSE_ASYM; | ||
2821 | 2831 | ||
2822 | tg3_setup_flow_control(tp, local_adv, remote_adv); | 2832 | tg3_setup_flow_control(tp, local_adv, remote_adv); |
2823 | 2833 | ||
@@ -2841,6 +2851,8 @@ static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status) | |||
2841 | !(mac_status & MAC_STATUS_RCVD_CFG)) | 2851 | !(mac_status & MAC_STATUS_RCVD_CFG)) |
2842 | current_link_up = 1; | 2852 | current_link_up = 1; |
2843 | } else { | 2853 | } else { |
2854 | tg3_setup_flow_control(tp, 0, 0); | ||
2855 | |||
2844 | /* Forcing 1000FD link up. */ | 2856 | /* Forcing 1000FD link up. */ |
2845 | current_link_up = 1; | 2857 | current_link_up = 1; |
2846 | 2858 | ||