From 3dd76c98e4e83bce3c1c7e8057647b9b6421d151 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Wed, 13 Mar 2013 01:40:01 +0000 Subject: [PATCH] r241438 broke IPMI access on Sun Fire X2200 M2(BCM5715). Fix the IPMI regression by sending BGE_FW_DRV_STATE_UNLOAD to ASF/IPMI firmware in driver attach phase. Sending heartheat to ASF/IPMI is enabled only after upping interface so setting driver state to BGE_FW_DRV_STATE_START in attach phase broke IPMI access. While I'm here, add NVRAM arbitration lock before performing controller reset. ASF/IPMI firmware may be able to access the NVRAM while controller reset is in progress. Without the arbitration lock before resetting the controller, ASF/IPMI may not initialize properly. Special thanks to Miroslav Lachman who provided full remote debugging environments. --- sys/dev/bge/if_bge.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index db86ec2a79e3..cf1a240f03ec 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -3594,15 +3594,15 @@ bge_attach(device_t dev) } bge_stop_fw(sc); - bge_sig_pre_reset(sc, BGE_RESET_START); + bge_sig_pre_reset(sc, BGE_RESET_SHUTDOWN); if (bge_reset(sc)) { device_printf(sc->bge_dev, "chip reset failed\n"); error = ENXIO; goto fail; } - bge_sig_legacy(sc, BGE_RESET_START); - bge_sig_post_reset(sc, BGE_RESET_START); + bge_sig_legacy(sc, BGE_RESET_SHUTDOWN); + bge_sig_post_reset(sc, BGE_RESET_SHUTDOWN); if (bge_chipinit(sc)) { device_printf(sc->bge_dev, "chip initialization failed\n"); @@ -3960,6 +3960,20 @@ bge_reset(struct bge_softc *sc) } else write_op = bge_writereg_ind; + if (sc->bge_asicrev != BGE_ASICREV_BCM5700 && + sc->bge_asicrev != BGE_ASICREV_BCM5701) { + CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_SET1); + for (i = 0; i < 8000; i++) { + if (CSR_READ_4(sc, BGE_NVRAM_SWARB) & + BGE_NVRAMSWARB_GNT1) + break; + DELAY(20); + } + if (i == 8000) { + if (bootverbose) + device_printf(dev, "NVRAM lock timedout!\n"); + } + } /* Take APE lock when performing reset. */ bge_ape_lock(sc, BGE_APE_LOCK_GRC);