Module Name:    src
Committed By:   msaitoh
Date:           Fri May  1 03:42:15 UTC 2015

Modified Files:
        src/sys/dev/pci: if_bge.c

Log Message:
 Add some workaround code for BGE_ASICREV_BCM5784 from Linux.


To generate a diff of this commit:
cvs rdiff -u -r1.286 -r1.287 src/sys/dev/pci/if_bge.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_bge.c
diff -u src/sys/dev/pci/if_bge.c:1.286 src/sys/dev/pci/if_bge.c:1.287
--- src/sys/dev/pci/if_bge.c:1.286	Fri May  1 03:26:43 2015
+++ src/sys/dev/pci/if_bge.c	Fri May  1 03:42:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_bge.c,v 1.286 2015/05/01 03:26:43 msaitoh Exp $	*/
+/*	$NetBSD: if_bge.c,v 1.287 2015/05/01 03:42:15 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 2001 Wind River Systems
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.286 2015/05/01 03:26:43 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.287 2015/05/01 03:42:15 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -5378,6 +5378,29 @@ bge_init(struct ifnet *ifp)
 	bge_sig_pre_reset(sc, BGE_RESET_START);
 	bge_reset(sc);
 	bge_sig_legacy(sc, BGE_RESET_START);
+
+	if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5784_AX) {
+		reg = CSR_READ_4(sc, BGE_CPMU_CTRL);
+		reg &= ~(BGE_CPMU_CTRL_LINK_AWARE_MODE |
+		    BGE_CPMU_CTRL_LINK_IDLE_MODE);
+		CSR_WRITE_4(sc, BGE_CPMU_CTRL, reg);
+
+		reg = CSR_READ_4(sc, BGE_CPMU_LSPD_10MB_CLK);
+		reg &= ~BGE_CPMU_LSPD_10MB_CLK;
+		reg |= BGE_CPMU_LSPD_10MB_MACCLK_6_25;
+		CSR_WRITE_4(sc, BGE_CPMU_LSPD_10MB_CLK, reg);
+
+		reg = CSR_READ_4(sc, BGE_CPMU_LNK_AWARE_PWRMD);
+		reg &= ~BGE_CPMU_LNK_AWARE_MACCLK_MASK;
+		reg |= BGE_CPMU_LNK_AWARE_MACCLK_6_25;
+		CSR_WRITE_4(sc, BGE_CPMU_LNK_AWARE_PWRMD, reg);
+
+		reg = CSR_READ_4(sc, BGE_CPMU_HST_ACC);
+		reg &= ~BGE_CPMU_HST_ACC_MACCLK_MASK;
+		reg |= BGE_CPMU_HST_ACC_MACCLK_6_25;
+		CSR_WRITE_4(sc, BGE_CPMU_HST_ACC, reg);
+	}
+
 	bge_sig_post_reset(sc, BGE_RESET_START);
 
 	bge_chipinit(sc);
@@ -5563,10 +5586,33 @@ bge_ifmedia_upd(struct ifnet *ifp)
 		return 0;
 	}
 
+	if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784) &&
+	    (BGE_CHIPREV(sc->bge_chipid) != BGE_CHIPREV_5784_AX)) {
+		uint32_t reg;
+
+		reg = CSR_READ_4(sc, BGE_CPMU_CTRL);
+		if ((reg & BGE_CPMU_CTRL_GPHY_10MB_RXONLY) != 0) {
+			reg &= ~BGE_CPMU_CTRL_GPHY_10MB_RXONLY;
+			CSR_WRITE_4(sc, BGE_CPMU_CTRL, reg);
+		}
+	}
+
 	BGE_STS_SETBIT(sc, BGE_STS_LINK_EVT);
 	if ((rc = mii_mediachg(mii)) == ENXIO)
 		return 0;
 
+	if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5784_AX) {
+		uint32_t reg;
+
+		reg = CSR_READ_4(sc, BGE_CPMU_LSPD_1000MB_CLK);
+		if ((reg & BGE_CPMU_LSPD_1000MB_MACCLK_MASK)
+		    == (BGE_CPMU_LSPD_1000MB_MACCLK_12_5)) {
+			reg &= ~BGE_CPMU_LSPD_1000MB_MACCLK_MASK;
+			delay(40);
+			CSR_WRITE_4(sc, BGE_CPMU_LSPD_1000MB_CLK, reg);
+		}
+	}
+
 	/*
 	 * Force an interrupt so that we will call bge_link_upd
 	 * if needed and clear any pending link state attention.
@@ -5937,6 +5983,23 @@ bge_link_upd(struct bge_softc *sc)
 		mii_pollstat(mii);
 	}
 
+	if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5784_AX) {
+		uint32_t reg, scale;
+
+		reg = CSR_READ_4(sc, BGE_CPMU_CLCK_STAT) &
+		    BGE_CPMU_CLCK_STAT_MAC_CLCK_MASK;
+		if (reg == BGE_CPMU_CLCK_STAT_MAC_CLCK_62_5)
+			scale = 65;
+		else if (reg == BGE_CPMU_CLCK_STAT_MAC_CLCK_6_25)
+			scale = 6;
+		else
+			scale = 12;
+
+		reg = CSR_READ_4(sc, BGE_MISC_CFG) &
+		    ~BGE_MISCCFG_TIMER_PRESCALER;
+		reg |= scale << 1;
+		CSR_WRITE_4(sc, BGE_MISC_CFG, reg);
+	}
 	/* Clear the attention */
 	CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
 	    BGE_MACSTAT_CFG_CHANGED|BGE_MACSTAT_MI_COMPLETE|

Reply via email to