From 38c1b17ca1a4f623589c011e6f8173c69245fab4 Mon Sep 17 00:00:00 2001 From: msaitoh Date: Fri, 1 May 2015 03:42:15 +0000 Subject: [PATCH] Add some workaround code for BGE_ASICREV_BCM5784 from Linux. --- sys/dev/pci/if_bge.c | 67 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c index 2c7d0dbd9647..576c5413cfc9 100644 --- a/sys/dev/pci/if_bge.c +++ b/sys/dev/pci/if_bge.c @@ -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 -__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 #include @@ -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|