[ipxe-devel] [PATCH 1/3] [tg3] Link detection for BCM5720

Cody Cutler ccutler at cs.utah.edu
Tue Aug 14 17:51:55 UTC 2012


BCM5720 link is not detected without this patch.  Tried to keep it in
harmony with the Linux driver.  Most tg3 cards will use the host status
block for link detection now.

Tested on BCM5720 and BCM5754
---
 src/drivers/net/tg3/tg3_hw.c  |   20 ++++++++++++++++++++
 src/drivers/net/tg3/tg3_phy.c |   29 ++++++++++++++++++++++++-----
 2 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/src/drivers/net/tg3/tg3_hw.c b/src/drivers/net/tg3/tg3_hw.c
index 13d5962..4aa186a 100644
--- a/src/drivers/net/tg3/tg3_hw.c
+++ b/src/drivers/net/tg3/tg3_hw.c
@@ -826,6 +826,26 @@ int tg3_get_invariants(struct tg3 *tp)
 			tp->phy_flags &= ~TG3_PHYFLG_USE_MI_INTERRUPT;
 	}
 
+	/* 5700 {AX,BX} chips have a broken status block link
+	 * change bit implementation, so we must use the
+	 * status register in those cases.
+	 */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
+		tg3_flag_set(tp, USE_LINKCHG_REG);
+	else
+		tg3_flag_clear(tp, USE_LINKCHG_REG);
+
+	/* The led_ctrl is set during tg3_phy_probe, here we might
+	 * have to force the link status polling mechanism based
+	 * upon subsystem IDs.
+	 */
+	if (tp->subsystem_vendor == PCI_VENDOR_ID_DELL &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
+	    !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
+		tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT;
+		tg3_flag_set(tp, USE_LINKCHG_REG);
+	}
+
 	/* For all SERDES we poll the MAC status register. */
 	if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
 		tg3_flag_set(tp, POLL_SERDES);
diff --git a/src/drivers/net/tg3/tg3_phy.c b/src/drivers/net/tg3/tg3_phy.c
index f49c7f0..54ec366 100644
--- a/src/drivers/net/tg3/tg3_phy.c
+++ b/src/drivers/net/tg3/tg3_phy.c
@@ -1008,11 +1008,27 @@ skip_phy_reset:
 void tg3_poll_link(struct tg3 *tp)
 {	DBGP("%s\n", __func__);
 
+	struct tg3_hw_status *sblk = tp->hw_status;
 	u32 mac_stat;
+	int res = 0;
 
-	mac_stat = tr32(MAC_STATUS);
+	if (tg3_flag(tp, USE_LINKCHG_REG)) {
+		mac_stat = tr32(MAC_STATUS);
 
-	if (mac_stat & MAC_STATUS_LNKSTATE_CHANGED)
+		if (mac_stat & MAC_STATUS_LNKSTATE_CHANGED)
+			res = 1;
+
+	} else {
+
+		if (sblk->status & SD_STATUS_LINK_CHG) {
+			sblk->status = SD_STATUS_UPDATED |
+			    (sblk->status & ~SD_STATUS_LINK_CHG);
+
+			res = 1;
+		}
+	}
+
+	if (res)
 		tg3_setup_phy(tp, 0);
 }
 
@@ -1506,9 +1522,12 @@ relink:
 	tw32_f(MAC_MODE, tp->mac_mode);
 	udelay(40);
 
-	/* We always use the link change register */
-	/* NOTE: this freezes for mdc? */
-	tw32_f(MAC_EVENT, 0);
+        if (tg3_flag(tp, USE_LINKCHG_REG))
+		/* NOTE: this freezes for mdc? */
+                tw32_f(MAC_EVENT, 0);
+        else
+                tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
+
 	udelay(40);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 &&
-- 
1.7.6




More information about the ipxe-devel mailing list