aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNithin Sujir <nsujir@broadcom.com>2014-01-03 13:09:14 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-03 20:59:52 -0500
commit1743b83c86b5dc525463a1bc9c701b4d9e428c5b (patch)
tree13e5250827b18e20c0a5cf2e20e626e0f08512f6 /drivers
parentf82995b65c44f353358179f4e2745cf967e00b31 (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')
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c10
-rw-r--r--drivers/net/ethernet/broadcom/tg3.h2
2 files changed, 12 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 &&
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 9e31eccc250b..ef472385bce4 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -1153,6 +1153,7 @@
1153#define TG3_CPMU_STATUS_FMSK_5717 0x20000000 1153#define TG3_CPMU_STATUS_FMSK_5717 0x20000000
1154#define TG3_CPMU_STATUS_FMSK_5719 0xc0000000 1154#define TG3_CPMU_STATUS_FMSK_5719 0xc0000000
1155#define TG3_CPMU_STATUS_FSHFT_5719 30 1155#define TG3_CPMU_STATUS_FSHFT_5719 30
1156#define TG3_CPMU_STATUS_LINK_MASK 0x180000
1156 1157
1157#define TG3_CPMU_CLCK_STAT 0x00003630 1158#define TG3_CPMU_CLCK_STAT 0x00003630
1158#define CPMU_CLCK_STAT_MAC_CLCK_MASK 0x001f0000 1159#define CPMU_CLCK_STAT_MAC_CLCK_MASK 0x001f0000
@@ -3020,6 +3021,7 @@ enum TG3_FLAGS {
3020 TG3_FLAG_ENABLE_ASF, 3021 TG3_FLAG_ENABLE_ASF,
3021 TG3_FLAG_ASPM_WORKAROUND, 3022 TG3_FLAG_ASPM_WORKAROUND,
3022 TG3_FLAG_POLL_SERDES, 3023 TG3_FLAG_POLL_SERDES,
3024 TG3_FLAG_POLL_CPMU_LINK,
3023 TG3_FLAG_MBOX_WRITE_REORDER, 3025 TG3_FLAG_MBOX_WRITE_REORDER,
3024 TG3_FLAG_PCIX_TARGET_HWBUG, 3026 TG3_FLAG_PCIX_TARGET_HWBUG,
3025 TG3_FLAG_WOL_SPEED_100MB, 3027 TG3_FLAG_WOL_SPEED_100MB,