diff options
author | Nithin Sujir <nsujir@broadcom.com> | 2014-01-03 13:09:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-03 20:59:52 -0500 |
commit | 1743b83c86b5dc525463a1bc9c701b4d9e428c5b (patch) | |
tree | 13e5250827b18e20c0a5cf2e20e626e0f08512f6 /drivers/net/ethernet/broadcom/tg3.c | |
parent | f82995b65c44f353358179f4e2745cf967e00b31 (diff) |
tg3: Poll cpmu link state on APE + ASF enabled devices
On ASF enabled devices where the mgmt firmware runs on the application
processing engine, there is a race between the tg3 driver processing a
link change event and the ASF firmware clearing the link changed bit in
the EMAC status register. This leads to link notifications to the driver
sometimes getting lost.
Poll the CPMU link state as a backup for the normal interrupt path
update if ASF is enabled.
Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 7bc8449af262..8f43c6755911 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -10960,6 +10960,13 @@ static void tg3_timer(unsigned long __opaque) | |||
10960 | } else if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) && | 10960 | } else if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) && |
10961 | tg3_flag(tp, 5780_CLASS)) { | 10961 | tg3_flag(tp, 5780_CLASS)) { |
10962 | tg3_serdes_parallel_detect(tp); | 10962 | tg3_serdes_parallel_detect(tp); |
10963 | } else if (tg3_flag(tp, POLL_CPMU_LINK)) { | ||
10964 | u32 cpmu = tr32(TG3_CPMU_STATUS); | ||
10965 | bool link_up = !((cpmu & TG3_CPMU_STATUS_LINK_MASK) == | ||
10966 | TG3_CPMU_STATUS_LINK_MASK); | ||
10967 | |||
10968 | if (link_up != tp->link_up) | ||
10969 | tg3_setup_phy(tp, false); | ||
10963 | } | 10970 | } |
10964 | 10971 | ||
10965 | tp->timer_counter = tp->timer_multiplier; | 10972 | tp->timer_counter = tp->timer_multiplier; |
@@ -16766,6 +16773,9 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent) | |||
16766 | else | 16773 | else |
16767 | tg3_flag_clear(tp, POLL_SERDES); | 16774 | tg3_flag_clear(tp, POLL_SERDES); |
16768 | 16775 | ||
16776 | if (tg3_flag(tp, ENABLE_APE) && tg3_flag(tp, ENABLE_ASF)) | ||
16777 | tg3_flag_set(tp, POLL_CPMU_LINK); | ||
16778 | |||
16769 | tp->rx_offset = NET_SKB_PAD + NET_IP_ALIGN; | 16779 | tp->rx_offset = NET_SKB_PAD + NET_IP_ALIGN; |
16770 | tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD; | 16780 | tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD; |
16771 | if (tg3_asic_rev(tp) == ASIC_REV_5701 && | 16781 | if (tg3_asic_rev(tp) == ASIC_REV_5701 && |