Add the capability to read the complete contents of the NVRAM via sysctl

dev.bce.<unit>.nvram_dump
Add the capability to write the complete contents of the NVRAM via sysctl
	dev.bce.<unit>.nvram_write
These are only available if the kernel option BCE_DEBUG is enabled.
The nvram_write sysctl also requires the kernel option
BCE_NVRAM_WRITE_SUPPORT to be enabled.  These are to be used at your
own caution.  Since the MAC addresses are stored in the NVRAM, if you
dump one NIC and restore it on another NIC the destination NIC's
MAC addresses will not be preserved.  A tool can be made using these
sysctl's to manage the on-chip firmware.

Reviewed by:	davidch, yongari
This commit is contained in:
Doug Ambrisko 2010-10-06 18:36:50 +00:00
parent 86a04a0cc7
commit 584d21f69e
3 changed files with 69 additions and 0 deletions

View File

@ -696,6 +696,7 @@ ED_SIC opt_ed.h
# bce driver # bce driver
BCE_DEBUG opt_bce.h BCE_DEBUG opt_bce.h
BCE_NVRAM_WRITE_SUPPORT opt_bce.h
SOCKBUF_DEBUG opt_global.h SOCKBUF_DEBUG opt_global.h

View File

@ -343,6 +343,12 @@ static int bce_miibus_read_reg (device_t, int, int);
static int bce_miibus_write_reg (device_t, int, int, int); static int bce_miibus_write_reg (device_t, int, int, int);
static void bce_miibus_statchg (device_t); static void bce_miibus_statchg (device_t);
#ifdef BCE_DEBUG
static int sysctl_nvram_dump(SYSCTL_HANDLER_ARGS);
#ifdef BCE_NVRAM_WRITE_SUPPORT
static int sysctl_nvram_write(SYSCTL_HANDLER_ARGS);
#endif
#endif
/****************************************************************************/ /****************************************************************************/
/* BCE NVRAM Access Routines */ /* BCE NVRAM Access Routines */
@ -8342,6 +8348,57 @@ bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
} }
static int
sysctl_nvram_dump(SYSCTL_HANDLER_ARGS)
{
struct bce_softc *sc = (struct bce_softc *)arg1;
int error, i;
if (sc->nvram_buf == NULL) {
sc->nvram_buf = malloc(sc->bce_flash_size,
M_TEMP, M_ZERO | M_WAITOK);
}
if (sc->nvram_buf == NULL) {
return(ENOMEM);
}
if (req->oldlen == sc->bce_flash_size) {
for (i = 0; i < sc->bce_flash_size; i++) {
bce_nvram_read(sc, i, &sc->nvram_buf[i], 1);
}
}
error = SYSCTL_OUT(req, sc->nvram_buf, sc->bce_flash_size);
return error;
}
#ifdef BCE_NVRAM_WRITE_SUPPORT
static int
sysctl_nvram_write(SYSCTL_HANDLER_ARGS)
{
struct bce_softc *sc = (struct bce_softc *)arg1;
int error;
if (sc->nvram_buf == NULL) {
sc->nvram_buf = malloc(sc->bce_flash_size,
M_TEMP, M_ZERO | M_WAITOK);
}
if (sc->nvram_buf == NULL) {
return(ENOMEM);
}
bzero(sc->nvram_buf, sc->bce_flash_size);
error = SYSCTL_IN(req, sc->nvram_buf, sc->bce_flash_size);
if (req->newlen == sc->bce_flash_size) {
bce_nvram_write(sc, 0, sc->nvram_buf , sc->bce_flash_size);
}
return error;
}
#endif
/****************************************************************************/ /****************************************************************************/
/* Provides a sysctl interface to allow reading a CID. */ /* Provides a sysctl interface to allow reading a CID. */
/* */ /* */
@ -8566,6 +8623,16 @@ bce_add_sysctls(struct bce_softc *sc)
"interrupts_tx", "interrupts_tx",
CTLFLAG_RD, &sc->interrupts_tx, CTLFLAG_RD, &sc->interrupts_tx,
0, "Number of TX interrupts"); 0, "Number of TX interrupts");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
"nvram_dump", CTLTYPE_OPAQUE | CTLFLAG_RD,
(void *)sc, 0,
sysctl_nvram_dump, "S", "");
#ifdef BCE_NVRAM_WRITE_SUPPORT
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
"nvram_write", CTLTYPE_OPAQUE | CTLFLAG_WR,
(void *)sc, 0,
sysctl_nvram_write, "S", "");
#endif
#endif #endif
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,

View File

@ -6790,6 +6790,7 @@ struct bce_softc
/* Number of VLAN tagged frames stripped. */ /* Number of VLAN tagged frames stripped. */
u32 vlan_tagged_frames_stripped; u32 vlan_tagged_frames_stripped;
#endif #endif
uint8_t *nvram_buf;
}; };
#endif /* __BCEREG_H_DEFINED */ #endif /* __BCEREG_H_DEFINED */