diff options
author | Michael Chan <mchan@broadcom.com> | 2012-07-29 15:15:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-30 02:18:31 -0400 |
commit | 091f0ea30074bc43f9250961b3247af713024bc6 (patch) | |
tree | 6811dce54854469457b3c5e20d150f160de0c4ba /drivers | |
parent | 10ce95d6ef36c65df7dcd3b8fcf86913f8b298bd (diff) |
tg3: Add New 5719 Read DMA workaround
After Power-on-reset, the 5719's TX DMA length registers may contain
uninitialized values and cause TX DMA to stall. Check for invalid
values and set a register bit to flush the TX channels. The bit
needs to be turned off after the DMA channels have been flushed.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.h | 7 |
2 files changed, 29 insertions, 1 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index f0434dfbda9c..50045ed1e8c0 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -9276,6 +9276,19 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
9276 | tw32_f(RDMAC_MODE, rdmac_mode); | 9276 | tw32_f(RDMAC_MODE, rdmac_mode); |
9277 | udelay(40); | 9277 | udelay(40); |
9278 | 9278 | ||
9279 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { | ||
9280 | for (i = 0; i < TG3_NUM_RDMA_CHANNELS; i++) { | ||
9281 | if (tr32(TG3_RDMA_LENGTH + (i << 2)) > TG3_MAX_MTU(tp)) | ||
9282 | break; | ||
9283 | } | ||
9284 | if (i < TG3_NUM_RDMA_CHANNELS) { | ||
9285 | val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); | ||
9286 | val |= TG3_LSO_RD_DMA_TX_LENGTH_WA; | ||
9287 | tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val); | ||
9288 | tg3_flag_set(tp, 5719_RDMA_BUG); | ||
9289 | } | ||
9290 | } | ||
9291 | |||
9279 | tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE); | 9292 | tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE); |
9280 | if (!tg3_flag(tp, 5705_PLUS)) | 9293 | if (!tg3_flag(tp, 5705_PLUS)) |
9281 | tw32(MBFREE_MODE, MBFREE_MODE_ENABLE); | 9294 | tw32(MBFREE_MODE, MBFREE_MODE_ENABLE); |
@@ -9635,6 +9648,16 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp) | |||
9635 | TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST); | 9648 | TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST); |
9636 | TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST); | 9649 | TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST); |
9637 | TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST); | 9650 | TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST); |
9651 | if (unlikely(tg3_flag(tp, 5719_RDMA_BUG) && | ||
9652 | (sp->tx_ucast_packets.low + sp->tx_mcast_packets.low + | ||
9653 | sp->tx_bcast_packets.low) > TG3_NUM_RDMA_CHANNELS)) { | ||
9654 | u32 val; | ||
9655 | |||
9656 | val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); | ||
9657 | val &= ~TG3_LSO_RD_DMA_TX_LENGTH_WA; | ||
9658 | tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val); | ||
9659 | tg3_flag_clear(tp, 5719_RDMA_BUG); | ||
9660 | } | ||
9638 | 9661 | ||
9639 | TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS); | 9662 | TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS); |
9640 | TG3_STAT_ADD32(&sp->rx_fragments, MAC_RX_STATS_FRAGMENTS); | 9663 | TG3_STAT_ADD32(&sp->rx_fragments, MAC_RX_STATS_FRAGMENTS); |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 6fb45a500032..6d52cb286826 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
@@ -1376,7 +1376,11 @@ | |||
1376 | #define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910 | 1376 | #define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910 |
1377 | #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K 0x00030000 | 1377 | #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K 0x00030000 |
1378 | #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K 0x000c0000 | 1378 | #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K 0x000c0000 |
1379 | /* 0x4914 --> 0x4c00 unused */ | 1379 | #define TG3_LSO_RD_DMA_TX_LENGTH_WA 0x02000000 |
1380 | /* 0x4914 --> 0x4be0 unused */ | ||
1381 | |||
1382 | #define TG3_NUM_RDMA_CHANNELS 4 | ||
1383 | #define TG3_RDMA_LENGTH 0x00004be0 | ||
1380 | 1384 | ||
1381 | /* Write DMA control registers */ | 1385 | /* Write DMA control registers */ |
1382 | #define WDMAC_MODE 0x00004c00 | 1386 | #define WDMAC_MODE 0x00004c00 |
@@ -2959,6 +2963,7 @@ enum TG3_FLAGS { | |||
2959 | TG3_FLAG_L1PLLPD_EN, | 2963 | TG3_FLAG_L1PLLPD_EN, |
2960 | TG3_FLAG_APE_HAS_NCSI, | 2964 | TG3_FLAG_APE_HAS_NCSI, |
2961 | TG3_FLAG_4K_FIFO_LIMIT, | 2965 | TG3_FLAG_4K_FIFO_LIMIT, |
2966 | TG3_FLAG_5719_RDMA_BUG, | ||
2962 | TG3_FLAG_RESET_TASK_PENDING, | 2967 | TG3_FLAG_RESET_TASK_PENDING, |
2963 | TG3_FLAG_5705_PLUS, | 2968 | TG3_FLAG_5705_PLUS, |
2964 | TG3_FLAG_IS_5788, | 2969 | TG3_FLAG_IS_5788, |