Add some workaround code for BGE_ASICREV_BCM5784 from Linux.

This commit is contained in:
msaitoh 2015-05-01 03:42:15 +00:00
parent 988569ba91
commit 38c1b17ca1
1 changed files with 65 additions and 2 deletions

View File

@ -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|