summaryrefslogtreecommitdiffstats
path: root/sys/dev/bce
diff options
context:
space:
mode:
authorambrisko <ambrisko@FreeBSD.org>2010-10-06 18:36:50 +0000
committerambrisko <ambrisko@FreeBSD.org>2010-10-06 18:36:50 +0000
commit81421f8fc287fbb1fc113cd84cab418e9c373270 (patch)
treea4d3e56f16adea3c40a46a6008c8ebf8a02cc705 /sys/dev/bce
parent526f3b44831a9e2ca2e896f3f88bc955b35dccf6 (diff)
downloadFreeBSD-src-81421f8fc287fbb1fc113cd84cab418e9c373270.zip
FreeBSD-src-81421f8fc287fbb1fc113cd84cab418e9c373270.tar.gz
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
Diffstat (limited to 'sys/dev/bce')
-rw-r--r--sys/dev/bce/if_bce.c67
-rw-r--r--sys/dev/bce/if_bcereg.h1
2 files changed, 68 insertions, 0 deletions
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index 8671142..5cc8157 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -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 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 */
@@ -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. */
/* */
@@ -8566,6 +8623,16 @@ bce_add_sysctls(struct bce_softc *sc)
"interrupts_tx",
CTLFLAG_RD, &sc->interrupts_tx,
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
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h
index 2bb589f..cedb6b1 100644
--- a/sys/dev/bce/if_bcereg.h
+++ b/sys/dev/bce/if_bcereg.h
@@ -6790,6 +6790,7 @@ struct bce_softc
/* Number of VLAN tagged frames stripped. */
u32 vlan_tagged_frames_stripped;
#endif
+ uint8_t *nvram_buf;
};
#endif /* __BCEREG_H_DEFINED */
OpenPOWER on IntegriCloud