aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2005-09-27 15:12:42 -0400
committerDavid S. Miller <davem@davemloft.net>2005-09-27 15:12:42 -0400
commitc94e39418ab6eccf863581f4e0d847da0080b2d3 (patch)
treed7b38279d14d93160ffaed214898973fb2062061 /drivers/net
parent667347f1ca7e099f6833551f194cf2bcc778871b (diff)
[TG3]: 5780 PHY fixes
Fix 5780 PHY related problems: 1. MAC_RX_MODE reset must be done before setting up the MAC_MODE register on 5705_PLUS chips or the chip will stop receiving after a while. The MAC_RX_MODE reset is needed to prevent intermittently losing the first receive packet on serdes chips. 2. Skip MAC loopback test on 5780 because of hardware errata. Normal traffic including PHY loopback is not affected by the errata. 3. PHY loopback fails intermittently on 5708S and this is fixed by putting the PHY in loopback mode first before programming the MAC mode register. A MAC_RX_MODE reset is also added. 4. Return -EINVAL in tg3_nway_reset() if device is in TBI mode. Allow nway_reset if 5780S is in parallel detect mode. 5. Add missing PHY IDs in KNOWN_PHY_ID() macro. Signed-off-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.c37
-rw-r--r--drivers/net/tg3.h1
2 files changed, 32 insertions, 6 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 81f4aedf534c..ef2f1fdd6f64 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -5806,6 +5806,13 @@ static int tg3_reset_hw(struct tg3 *tp)
5806 } 5806 }
5807 memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); 5807 memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
5808 5808
5809 if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
5810 tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
5811 /* reset to prevent losing 1st rx packet intermittently */
5812 tw32_f(MAC_RX_MODE, RX_MODE_RESET);
5813 udelay(10);
5814 }
5815
5809 tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | 5816 tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
5810 MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; 5817 MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
5811 tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR); 5818 tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
@@ -5937,7 +5944,7 @@ static int tg3_reset_hw(struct tg3 *tp)
5937 tw32(MAC_LED_CTRL, tp->led_ctrl); 5944 tw32(MAC_LED_CTRL, tp->led_ctrl);
5938 5945
5939 tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); 5946 tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
5940 if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { 5947 if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
5941 tw32_f(MAC_RX_MODE, RX_MODE_RESET); 5948 tw32_f(MAC_RX_MODE, RX_MODE_RESET);
5942 udelay(10); 5949 udelay(10);
5943 } 5950 }
@@ -7360,12 +7367,17 @@ static int tg3_nway_reset(struct net_device *dev)
7360 if (!netif_running(dev)) 7367 if (!netif_running(dev))
7361 return -EAGAIN; 7368 return -EAGAIN;
7362 7369
7370 if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
7371 return -EINVAL;
7372
7363 spin_lock_bh(&tp->lock); 7373 spin_lock_bh(&tp->lock);
7364 r = -EINVAL; 7374 r = -EINVAL;
7365 tg3_readphy(tp, MII_BMCR, &bmcr); 7375 tg3_readphy(tp, MII_BMCR, &bmcr);
7366 if (!tg3_readphy(tp, MII_BMCR, &bmcr) && 7376 if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
7367 (bmcr & BMCR_ANENABLE)) { 7377 ((bmcr & BMCR_ANENABLE) ||
7368 tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART); 7378 (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
7379 tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
7380 BMCR_ANENABLE);
7369 r = 0; 7381 r = 0;
7370 } 7382 }
7371 spin_unlock_bh(&tp->lock); 7383 spin_unlock_bh(&tp->lock);
@@ -7927,19 +7939,32 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
7927 struct tg3_rx_buffer_desc *desc; 7939 struct tg3_rx_buffer_desc *desc;
7928 7940
7929 if (loopback_mode == TG3_MAC_LOOPBACK) { 7941 if (loopback_mode == TG3_MAC_LOOPBACK) {
7942 /* HW errata - mac loopback fails in some cases on 5780.
7943 * Normal traffic and PHY loopback are not affected by
7944 * errata.
7945 */
7946 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
7947 return 0;
7948
7930 mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | 7949 mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
7931 MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | 7950 MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY |
7932 MAC_MODE_PORT_MODE_GMII; 7951 MAC_MODE_PORT_MODE_GMII;
7933 tw32(MAC_MODE, mac_mode); 7952 tw32(MAC_MODE, mac_mode);
7934 } else if (loopback_mode == TG3_PHY_LOOPBACK) { 7953 } else if (loopback_mode == TG3_PHY_LOOPBACK) {
7954 tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX |
7955 BMCR_SPEED1000);
7956 udelay(40);
7957 /* reset to prevent losing 1st rx packet intermittently */
7958 if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
7959 tw32_f(MAC_RX_MODE, RX_MODE_RESET);
7960 udelay(10);
7961 tw32_f(MAC_RX_MODE, tp->rx_mode);
7962 }
7935 mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | 7963 mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
7936 MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; 7964 MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII;
7937 if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) 7965 if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)
7938 mac_mode &= ~MAC_MODE_LINK_POLARITY; 7966 mac_mode &= ~MAC_MODE_LINK_POLARITY;
7939 tw32(MAC_MODE, mac_mode); 7967 tw32(MAC_MODE, mac_mode);
7940
7941 tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX |
7942 BMCR_SPEED1000);
7943 } 7968 }
7944 else 7969 else
7945 return -EINVAL; 7970 return -EINVAL;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index c184b773e585..2e733c60bfa4 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2246,6 +2246,7 @@ struct tg3 {
2246 (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \ 2246 (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
2247 (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \ 2247 (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
2248 (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \ 2248 (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
2249 (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5780 || \
2249 (X) == PHY_ID_BCM8002) 2250 (X) == PHY_ID_BCM8002)
2250 2251
2251 struct tg3_hw_stats *hw_stats; 2252 struct tg3_hw_stats *hw_stats;