summaryrefslogtreecommitdiffstats
path: root/sys/dev/bge
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2007-04-30 21:55:27 +0000
committermarius <marius@FreeBSD.org>2007-04-30 21:55:27 +0000
commitf18c6c03395fa5c067d494cb5cef42d8855707e0 (patch)
tree6fee858fcee2fb1b2da2b1e692e2dba4b42b5e3f /sys/dev/bge
parent4c8790bcb470e9daa8fd9298949e28ff3454d8b1 (diff)
downloadFreeBSD-src-f18c6c03395fa5c067d494cb5cef42d8855707e0.zip
FreeBSD-src-f18c6c03395fa5c067d494cb5cef42d8855707e0.tar.gz
- Add support/quirks for the on-board BGEs found in Sun Blade 1500
Blade 2500, Fire V210 and probably some other sparc64 machines. These chips are typically not fitted with an EEPROM which means that we have to obtain the MAC address via OFW and that some chip tests will just always fail. These changes are based on the respective code found in OpenBSD with some additional info obtained from OpenSolaris and some style suggestions by jkim@. They also have the desired side-effect of respecting the 'local-mac-address?' system configuration variable for the affected BGEs. - In bge_attach() factor out calling bge_release_resources() before going to the fail label into the fail label as well as replace a magic 6 with ETHER_ADDR_LEN. Reviewed by: yongari (before style changes), jkim
Diffstat (limited to 'sys/dev/bge')
-rw-r--r--sys/dev/bge/if_bge.c126
-rw-r--r--sys/dev/bge/if_bgereg.h6
2 files changed, 98 insertions, 34 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index c6c0ea0..18f9a80 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -106,6 +106,13 @@ __FBSDID("$FreeBSD$");
#include "miidevs.h"
#include <dev/mii/brgphyreg.h>
+#ifdef __sparc64__
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
+#include <machine/ofw_machdep.h>
+#include <machine/ver.h>
+#endif
+
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
@@ -348,6 +355,7 @@ static int bge_init_tx_ring(struct bge_softc *);
static int bge_chipinit(struct bge_softc *);
static int bge_blockinit(struct bge_softc *);
+static int bge_has_eeprom(struct bge_softc *);
static uint32_t bge_readmem_ind(struct bge_softc *, int);
static void bge_writemem_ind(struct bge_softc *, int, int);
#ifdef notdef
@@ -428,6 +436,50 @@ SYSCTL_INT(_hw_bge, OID_AUTO, fake_autoneg, CTLFLAG_RD, &bge_fake_autoneg, 0,
SYSCTL_INT(_hw_bge, OID_AUTO, allow_asf, CTLFLAG_RD, &bge_allow_asf, 0,
"Allow ASF mode if available");
+#define SPARC64_BLADE_1500_MODEL "SUNW,Sun-Blade-1500"
+#define SPARC64_BLADE_1500_PATH_BGE "/pci@1f,700000/network@2"
+#define SPARC64_BLADE_2500_MODEL "SUNW,Sun-Blade-2500"
+#define SPARC64_BLADE_2500_PATH_BGE "/pci@1c,600000/network@3"
+#define SPARC64_OFW_SUBVENDOR "subsystem-vendor-id"
+
+static int
+bge_has_eeprom(struct bge_softc *sc)
+{
+#ifdef __sparc64__
+ char buf[sizeof(SPARC64_BLADE_1500_PATH_BGE)];
+ device_t dev;
+ uint32_t subvendor;
+
+ dev = sc->bge_dev;
+
+ /*
+ * The on-board BGEs found in sun4u machines aren't fitted with
+ * an EEPROM which means that we have to obtain the MAC address
+ * via OFW and that some tests will always fail. We distinguish
+ * such BGEs by the subvendor ID, which also has to be obtained
+ * from OFW instead of the PCI configuration space as the latter
+ * indicates Broadcom as the subvendor of the netboot interface.
+ * For early Blade 1500 and 2500 we even have to check the OFW
+ * device path as the subvendor ID always defaults to Broadcom
+ * there.
+ */
+ if (OF_getprop(ofw_bus_get_node(dev), SPARC64_OFW_SUBVENDOR,
+ &subvendor, sizeof(subvendor)) == sizeof(subvendor) &&
+ subvendor == SUN_VENDORID)
+ return (0);
+ memset(buf, 0, sizeof(buf));
+ if (OF_package_to_path(ofw_bus_get_node(dev), buf, sizeof(buf)) > 0) {
+ if (strcmp(sparc64_model, SPARC64_BLADE_1500_MODEL) == 0 &&
+ strcmp(buf, SPARC64_BLADE_1500_PATH_BGE) == 0)
+ return (0);
+ if (strcmp(sparc64_model, SPARC64_BLADE_2500_MODEL) == 0 &&
+ strcmp(buf, SPARC64_BLADE_2500_PATH_BGE) == 0)
+ return (0);
+ }
+#endif
+ return (1);
+}
+
static uint32_t
bge_readmem_ind(struct bge_softc *sc, int off)
{
@@ -1100,9 +1152,12 @@ bge_chipinit(struct bge_softc *sc)
/*
* Check the 'ROM failed' bit on the RX CPU to see if
- * self-tests passed.
+ * self-tests passed. Skip this check when there's no
+ * EEPROM fitted, since in that case it will always
+ * fail.
*/
- if (CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL) {
+ if ((sc->bge_flags & BGE_FLAG_EEPROM) &&
+ CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL) {
device_printf(sc->bge_dev, "RX CPU self-diagnostics failed!\n");
return (ENODEV);
}
@@ -2171,8 +2226,8 @@ bge_attach(device_t dev)
struct bge_softc *sc;
uint32_t hwcfg = 0;
uint32_t mac_tmp = 0;
- u_char eaddr[6];
- int error = 0, rid, trys, reg;
+ u_char eaddr[ETHER_ADDR_LEN];
+ int error, reg, rid, trys;
sc = device_get_softc(dev);
sc->bge_dev = dev;
@@ -2203,6 +2258,9 @@ bge_attach(device_t dev)
sc->bge_asicrev = BGE_ASICREV(sc->bge_chipid);
sc->bge_chiprev = BGE_CHIPREV(sc->bge_chipid);
+ if (bge_has_eeprom(sc))
+ sc->bge_flags |= BGE_FLAG_EEPROM;
+
/* Save chipset family. */
switch (sc->bge_asicrev) {
case BGE_ASICREV_BCM5700:
@@ -2316,7 +2374,6 @@ bge_attach(device_t dev)
/* Try to reset the chip. */
if (bge_reset(sc)) {
device_printf(sc->bge_dev, "chip reset failed\n");
- bge_release_resources(sc);
error = ENXIO;
goto fail;
}
@@ -2339,7 +2396,6 @@ bge_attach(device_t dev)
bge_sig_pre_reset(sc, BGE_RESET_STOP);
if (bge_reset(sc)) {
device_printf(sc->bge_dev, "chip reset failed\n");
- bge_release_resources(sc);
error = ENXIO;
goto fail;
}
@@ -2349,29 +2405,32 @@ bge_attach(device_t dev)
if (bge_chipinit(sc)) {
device_printf(sc->bge_dev, "chip initialization failed\n");
- bge_release_resources(sc);
error = ENXIO;
goto fail;
}
- /*
- * Get station address from the EEPROM.
- */
- mac_tmp = bge_readmem_ind(sc, 0x0C14);
- if ((mac_tmp >> 16) == 0x484B) {
- eaddr[0] = (u_char)(mac_tmp >> 8);
- eaddr[1] = (u_char)mac_tmp;
- mac_tmp = bge_readmem_ind(sc, 0x0C18);
- eaddr[2] = (u_char)(mac_tmp >> 24);
- eaddr[3] = (u_char)(mac_tmp >> 16);
- eaddr[4] = (u_char)(mac_tmp >> 8);
- eaddr[5] = (u_char)mac_tmp;
- } else if (bge_read_eeprom(sc, eaddr,
- BGE_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
- device_printf(sc->bge_dev, "failed to read station address\n");
- bge_release_resources(sc);
- error = ENXIO;
- goto fail;
+#ifdef __sparc64__
+ if ((sc->bge_flags & BGE_FLAG_EEPROM) == 0)
+ OF_getetheraddr(dev, eaddr);
+ else
+#endif
+ {
+ mac_tmp = bge_readmem_ind(sc, 0x0C14);
+ if ((mac_tmp >> 16) == 0x484B) {
+ eaddr[0] = (u_char)(mac_tmp >> 8);
+ eaddr[1] = (u_char)mac_tmp;
+ mac_tmp = bge_readmem_ind(sc, 0x0C18);
+ eaddr[2] = (u_char)(mac_tmp >> 24);
+ eaddr[3] = (u_char)(mac_tmp >> 16);
+ eaddr[4] = (u_char)(mac_tmp >> 8);
+ eaddr[5] = (u_char)mac_tmp;
+ } else if (bge_read_eeprom(sc, eaddr,
+ BGE_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
+ device_printf(sc->bge_dev,
+ "failed to read station address\n");
+ error = ENXIO;
+ goto fail;
+ }
}
/* 5705 limits RX return ring to 512 entries. */
@@ -2383,7 +2442,6 @@ bge_attach(device_t dev)
if (bge_dma_alloc(dev)) {
device_printf(sc->bge_dev,
"failed to allocate DMA resources\n");
- bge_release_resources(sc);
error = ENXIO;
goto fail;
}
@@ -2399,7 +2457,6 @@ bge_attach(device_t dev)
ifp = sc->bge_ifp = if_alloc(IFT_ETHER);
if (ifp == NULL) {
device_printf(sc->bge_dev, "failed to if_alloc()\n");
- bge_release_resources(sc);
error = ENXIO;
goto fail;
}
@@ -2445,11 +2502,10 @@ bge_attach(device_t dev)
*/
if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) == BGE_MAGIC_NUMBER)
hwcfg = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG);
- else {
+ else if (sc->bge_flags & BGE_FLAG_EEPROM) {
if (bge_read_eeprom(sc, (caddr_t)&hwcfg, BGE_EE_HWCFG_OFFSET,
sizeof(hwcfg))) {
device_printf(sc->bge_dev, "failed to read EEPROM\n");
- bge_release_resources(sc);
error = ENXIO;
goto fail;
}
@@ -2495,7 +2551,6 @@ again:
}
device_printf(sc->bge_dev, "MII without any PHY!\n");
- bge_release_resources(sc);
error = ENXIO;
goto fail;
}
@@ -2543,7 +2598,11 @@ again:
bge_add_sysctls(sc);
+ return (0);
+
fail:
+ bge_release_resources(sc);
+
return (error);
}
@@ -2726,8 +2785,8 @@ bge_reset(struct bge_softc *sc)
/*
* Poll until we see the 1's complement of the magic number.
- * This indicates that the firmware initialization
- * is complete.
+ * This indicates that the firmware initialization is complete.
+ * We expect this to fail if no EEPROM is fitted though.
*/
for (i = 0; i < BGE_TIMEOUT; i++) {
val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
@@ -2736,10 +2795,9 @@ bge_reset(struct bge_softc *sc)
DELAY(10);
}
- if (i == BGE_TIMEOUT) {
+ if ((sc->bge_flags & BGE_FLAG_EEPROM) && i == BGE_TIMEOUT)
device_printf(sc->bge_dev, "firmware handshake timed out, "
"found 0x%08x\n", val);
- }
/*
* XXX Wait for the value of the PCISTATE register to
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index 769cbdf..5698793 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -2080,6 +2080,11 @@ struct bge_status_block {
#define APPLE_DEVICE_BCM5701 0x1645
/*
+ * Sun PCI vendor ID
+ */
+#define SUN_VENDORID 0x108e
+
+/*
* Offset of MAC address inside EEPROM.
*/
#define BGE_EE_MAC_OFFSET 0x7C
@@ -2454,6 +2459,7 @@ struct bge_softc {
uint32_t bge_flags;
#define BGE_FLAG_TBI 0x00000001
#define BGE_FLAG_JUMBO 0x00000002
+#define BGE_FLAG_EEPROM 0x00000004
#define BGE_FLAG_MSI 0x00000100
#define BGE_FLAG_PCIX 0x00000200
#define BGE_FLAG_PCIE 0x00000400
OpenPOWER on IntegriCloud