summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2005-11-27 00:26:37 +0000
committerBrad Smith <brad@cvs.openbsd.org>2005-11-27 00:26:37 +0000
commita559439036a57ea18b33c6cb61928c75da44cc29 (patch)
treeb6cc9115c8bf77c3d3f8cb5ce7faa56cfb07ced6 /sys
parent6b9295a162808f286198d5965c38511d717b8190 (diff)
add initial support for ASF.
this should allow IPMI BMC pass-through to work once the OS is running. From Doug Ambrisko on the FreeBSD net list. Based on the Linux tg3 driver.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_bge.c116
-rw-r--r--sys/dev/pci/if_bgereg.h11
2 files changed, 117 insertions, 10 deletions
diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c
index 9d806b3e648..516b26c0dbe 100644
--- a/sys/dev/pci/if_bge.c
+++ b/sys/dev/pci/if_bge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bge.c,v 1.103 2005/11/25 03:42:35 brad Exp $ */
+/* $OpenBSD: if_bge.c,v 1.104 2005/11/27 00:26:36 brad Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@@ -176,6 +176,12 @@ int bge_miibus_readreg(struct device *, int, int);
void bge_miibus_writereg(struct device *, int, int, int);
void bge_miibus_statchg(struct device *);
+#define BGE_RESET_START 1
+#define BGE_RESET_STOP 2
+void bge_sig_pre_reset(struct bge_softc *, int);
+void bge_sig_post_reset(struct bge_softc *, int);
+void bge_sig_legacy(struct bge_softc *, int);
+void bge_stop_fw(struct bge_softc *);
void bge_reset(struct bge_softc *);
#define BGE_DEBUG
@@ -1264,6 +1270,7 @@ bge_chipinit(struct bge_softc *sc)
CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS|
BGE_MODECTL_MAC_ATTN_INTR|BGE_MODECTL_HOST_SEND_BDS);
#endif
+ BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
/*
* Disable memory write invalidate. Apparently it is not supported
@@ -1815,9 +1822,26 @@ bge_attach(struct device *parent, struct device *self, void *aux)
}
}
+ sc->bge_asf_mode = 0;
+ if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) == BGE_MAGIC_NUMBER) {
+ if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG)
+ & BGE_HWCFG_ASF) {
+ sc->bge_asf_mode |= ASF_ENABLE;
+
+ if (CSR_READ_4(sc, BGE_MODE_CTL)
+ & BGE_MODECTL_STACKUP)
+ sc->bge_asf_mode |= ASF_STACKUP;
+ if (BGE_IS_575X_PLUS(sc))
+ sc->bge_asf_mode |= ASF_NEW_HANDSHAKE;
+ }
+ }
+
/* Try to reset the chip. */
- DPRINTFN(5, ("bge_reset\n"));
+ bge_stop_fw(sc);
+ bge_sig_pre_reset(sc, BGE_RESET_STOP);
bge_reset(sc);
+ bge_sig_legacy(sc, BGE_RESET_STOP);
+ bge_sig_post_reset(sc, BGE_RESET_STOP);
if (bge_chipinit(sc)) {
printf(": chip initialization failed\n");
@@ -2026,6 +2050,70 @@ fail_1:
}
void
+bge_sig_pre_reset(struct bge_softc *sc, int type)
+{
+ bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
+
+ if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
+ switch (type) {
+ case BGE_RESET_START:
+ bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */
+ break;
+ case BGE_RESET_STOP:
+ bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */
+ break;
+ }
+ }
+}
+
+void
+bge_sig_post_reset(struct bge_softc *sc, int type)
+{
+ if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
+ switch (type) {
+ case BGE_RESET_START:
+ bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001);
+ /* START DONE */
+ break;
+ case BGE_RESET_STOP:
+ bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002);
+ break;
+ }
+ }
+}
+
+void
+bge_sig_legacy(struct bge_softc *sc, int type)
+{
+ if (sc->bge_asf_mode) {
+ switch (type) {
+ case BGE_RESET_START:
+ bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */
+ break;
+ case BGE_RESET_STOP:
+ bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */
+ break;
+ }
+ }
+}
+
+void
+bge_stop_fw(struct bge_softc *sc)
+{
+ int i;
+
+ if (sc->bge_asf_mode) {
+ bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE);
+
+ for (i = 0; i < 100; i++ ) {
+ if (!(CSR_READ_4(sc, BGE_CPU_EVENT) & (1 << 14)))
+ break;
+ DELAY(10);
+ }
+ }
+}
+
+void
bge_reset(struct bge_softc *sc)
{
struct pci_attach_args *pa = &sc->bge_pa;
@@ -2086,12 +2174,6 @@ bge_reset(struct bge_softc *sc)
CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
/*
- * Prevent PXE restart: write a magic number to the
- * general communications memory at 0xB50.
- */
- bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
-
- /*
* Poll the value location we just wrote until
* we see the 1's complement of the magic number.
* This indicates that the firmware initialization
@@ -2134,6 +2216,8 @@ bge_reset(struct bge_softc *sc)
/* Fix up byte swapping */
CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS);
+ if (sc->bge_asf_mode & ASF_STACKUP)
+ BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
@@ -2916,7 +3000,13 @@ bge_init(void *xsc)
/* Cancel pending I/O and flush buffers. */
bge_stop(sc);
+
+ bge_stop_fw(sc);
+ bge_sig_pre_reset(sc, BGE_RESET_START);
bge_reset(sc);
+ bge_sig_legacy(sc, BGE_RESET_START);
+ bge_sig_post_reset(sc, BGE_RESET_START);
+
bge_chipinit(sc);
/*
@@ -3301,7 +3391,15 @@ bge_stop(struct bge_softc *sc)
/*
* Tell firmware we're shutting down.
*/
- BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+ bge_stop_fw(sc);
+ bge_sig_pre_reset(sc, BGE_RESET_STOP);
+ bge_reset(sc);
+ bge_sig_legacy(sc, BGE_RESET_STOP);
+ bge_sig_post_reset(sc, BGE_RESET_STOP);
+ if (sc->bge_asf_mode & ASF_STACKUP)
+ BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+ else
+ BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
/* Free the RX lists. */
bge_free_rx_ring_std(sc);
diff --git a/sys/dev/pci/if_bgereg.h b/sys/dev/pci/if_bgereg.h
index a5588017b0e..e5d29ffbf0d 100644
--- a/sys/dev/pci/if_bgereg.h
+++ b/sys/dev/pci/if_bgereg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bgereg.h,v 1.32 2005/11/24 12:25:07 fgsch Exp $ */
+/* $OpenBSD: if_bgereg.h,v 1.33 2005/11/27 00:26:36 brad Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@@ -76,6 +76,8 @@
#define BGE_SOFTWARE_GENCOMM 0x00000B50
#define BGE_SOFTWARE_GENCOMM_SIG 0x00000B54
#define BGE_SOFTWARE_GENCOMM_NICCFG 0x00000B58
+#define BGE_SOFTWARE_GENCOMM_FW 0x00000B78
+#define BGE_FW_PAUSE 0x00000002
#define BGE_SOFTWARE_GENCOMM_END 0x00000FFF
#define BGE_UNMAPPED 0x00001000
#define BGE_UNMAPPED_END 0x00001FFF
@@ -1649,6 +1651,7 @@
#define BGE_MODE_CTL 0x6800
#define BGE_MISC_CFG 0x6804
#define BGE_MISC_LOCAL_CTL 0x6808
+#define BGE_CPU_EVENT 0x6810
#define BGE_EE_ADDR 0x6838
#define BGE_EE_DATA 0x683C
#define BGE_EE_CTL 0x6840
@@ -1930,6 +1933,7 @@ struct bge_status_block {
#define BGE_HWCFG_VOLTAGE 0x00000003
#define BGE_HWCFG_PHYLED_MODE 0x0000000C
#define BGE_HWCFG_MEDIA 0x00000030
+#define BGE_HWCFG_ASF 0x00000080
#define BGE_VOLTAGE_1POINT3 0x00000000
#define BGE_VOLTAGE_1POINT8 0x00000001
@@ -2303,6 +2307,10 @@ struct txdmamap_pool_entry {
#define BGE_RXRING_VALID 0x0002
#define BGE_JUMBO_RXRING_VALID 0x0004
+#define ASF_ENABLE 1
+#define ASF_NEW_HANDSHAKE 2
+#define ASF_STACKUP 4
+
struct bge_softc {
struct device bge_dev;
struct arpcom arpcom; /* interface info */
@@ -2319,6 +2327,7 @@ struct bge_softc {
u_int32_t bge_chipid;
u_int32_t bge_quirks;
u_int8_t bge_no_3_led;
+ u_int8_t bge_asf_mode;
u_int8_t bge_pcie;
struct bge_ring_data *bge_rdata; /* rings */
struct bge_chain_data bge_cdata; /* mbufs */