Module Name: src
Committed By: msaitoh
Date: Thu Jan 28 03:09:13 UTC 2010
Modified Files:
src/sys/dev/pci: if_bge.c if_bgereg.h if_bgevar.h
Log Message:
- Introduce IPMI and ASF related code from FreeBSD. It fixes some problems
which occured in netboot on sparc64 and PR#32767
- move the code of disabling host interrput in bge_stop() like linux tg3
driver.
- fix the return value of bge_eeprom_getbyte().
- remove an unused structure.
- KNF
To generate a diff of this commit:
cvs rdiff -u -r1.176 -r1.177 src/sys/dev/pci/if_bge.c
cvs rdiff -u -r1.54 -r1.55 src/sys/dev/pci/if_bgereg.h
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/pci/if_bgevar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/if_bge.c
diff -u src/sys/dev/pci/if_bge.c:1.176 src/sys/dev/pci/if_bge.c:1.177
--- src/sys/dev/pci/if_bge.c:1.176 Mon Jan 25 10:25:30 2010
+++ src/sys/dev/pci/if_bge.c Thu Jan 28 03:09:13 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bge.c,v 1.176 2010/01/25 10:25:30 martin Exp $ */
+/* $NetBSD: if_bge.c,v 1.177 2010/01/28 03:09:13 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@@ -79,7 +79,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.176 2010/01/25 10:25:30 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.177 2010/01/28 03:09:13 msaitoh Exp $");
#include "vlan.h"
#include "rnd.h"
@@ -180,64 +180,87 @@
#define NBGE_RX_THRESH (sizeof(bge_rx_threshes) / sizeof(bge_rx_threshes[0]))
/* XXX patchable; should be sysctl'able */
-static int bge_auto_thresh = 1;
-static int bge_rx_thresh_lvl;
+static int bge_auto_thresh = 1;
+static int bge_rx_thresh_lvl;
-static int bge_rxthresh_nodenum;
+static int bge_rxthresh_nodenum;
typedef int (*bge_eaddr_fcn_t)(struct bge_softc *, uint8_t[]);
-static int bge_probe(device_t, cfdata_t, void *);
-static void bge_attach(device_t, device_t, void *);
-static void bge_release_resources(struct bge_softc *);
-static void bge_txeof(struct bge_softc *);
-static void bge_rxeof(struct bge_softc *);
-
-static int bge_get_eaddr_fw(struct bge_softc *, uint8_t[]);
-static int bge_get_eaddr_mem(struct bge_softc *, uint8_t[]);
-static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]);
-static int bge_get_eaddr_eeprom(struct bge_softc *, uint8_t[]);
-static int bge_get_eaddr(struct bge_softc *, uint8_t[]);
-
-static void bge_tick(void *);
-static void bge_stats_update(struct bge_softc *);
-static void bge_stats_update_regs(struct bge_softc *);
-static int bge_encap(struct bge_softc *, struct mbuf *, uint32_t *);
-
-static int bge_intr(void *);
-static void bge_start(struct ifnet *);
-static int bge_ioctl(struct ifnet *, u_long, void *);
-static int bge_init(struct ifnet *);
-static void bge_stop(struct ifnet *, int);
-static void bge_watchdog(struct ifnet *);
-static int bge_ifmedia_upd(struct ifnet *);
-static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+static int bge_probe(device_t, cfdata_t, void *);
+static void bge_attach(device_t, device_t, void *);
+static void bge_release_resources(struct bge_softc *);
+
+static int bge_get_eaddr_fw(struct bge_softc *, uint8_t[]);
+static int bge_get_eaddr_mem(struct bge_softc *, uint8_t[]);
+static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]);
+static int bge_get_eaddr_eeprom(struct bge_softc *, uint8_t[]);
+static int bge_get_eaddr(struct bge_softc *, uint8_t[]);
+
+static void bge_txeof(struct bge_softc *);
+static void bge_rxeof(struct bge_softc *);
+
+static void bge_asf_driver_up (struct bge_softc *);
+static void bge_tick(void *);
+static void bge_stats_update(struct bge_softc *);
+static void bge_stats_update_regs(struct bge_softc *);
+static int bge_encap(struct bge_softc *, struct mbuf *, uint32_t *);
+
+static int bge_intr(void *);
+static void bge_start(struct ifnet *);
+static int bge_ioctl(struct ifnet *, u_long, void *);
+static int bge_init(struct ifnet *);
+static void bge_stop(struct ifnet *, int);
+static void bge_watchdog(struct ifnet *);
+static int bge_ifmedia_upd(struct ifnet *);
+static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+
+static uint8_t bge_nvram_getbyte(struct bge_softc *, int, uint8_t *);
+static int bge_read_nvram(struct bge_softc *, uint8_t *, int, int);
+
+static uint8_t bge_eeprom_getbyte(struct bge_softc *, int, uint8_t *);
+static int bge_read_eeprom(struct bge_softc *, void *, int, int);
+static void bge_setmulti(struct bge_softc *);
-static void bge_setmulti(struct bge_softc *);
-
-static void bge_handle_events(struct bge_softc *);
-static int bge_alloc_jumbo_mem(struct bge_softc *);
+static void bge_handle_events(struct bge_softc *);
+static int bge_alloc_jumbo_mem(struct bge_softc *);
#if 0 /* XXX */
-static void bge_free_jumbo_mem(struct bge_softc *);
+static void bge_free_jumbo_mem(struct bge_softc *);
#endif
-static void *bge_jalloc(struct bge_softc *);
-static void bge_jfree(struct mbuf *, void *, size_t, void *);
-static int bge_newbuf_std(struct bge_softc *, int, struct mbuf *,
+static void *bge_jalloc(struct bge_softc *);
+static void bge_jfree(struct mbuf *, void *, size_t, void *);
+static int bge_newbuf_std(struct bge_softc *, int, struct mbuf *,
bus_dmamap_t);
-static int bge_newbuf_jumbo(struct bge_softc *, int, struct mbuf *);
-static int bge_init_rx_ring_std(struct bge_softc *);
-static void bge_free_rx_ring_std(struct bge_softc *);
-static int bge_init_rx_ring_jumbo(struct bge_softc *);
-static void bge_free_rx_ring_jumbo(struct bge_softc *);
-static void bge_free_tx_ring(struct bge_softc *);
-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_setpowerstate(struct bge_softc *, int);
-
-static void bge_reset(struct bge_softc *);
-static void bge_link_upd(struct bge_softc *);
+static int bge_newbuf_jumbo(struct bge_softc *, int, struct mbuf *);
+static int bge_init_rx_ring_std(struct bge_softc *);
+static void bge_free_rx_ring_std(struct bge_softc *);
+static int bge_init_rx_ring_jumbo(struct bge_softc *);
+static void bge_free_rx_ring_jumbo(struct bge_softc *);
+static void bge_free_tx_ring(struct bge_softc *);
+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_setpowerstate(struct bge_softc *, int);
+static uint32_t bge_readmem_ind(struct bge_softc *, int);
+static void bge_writemem_ind(struct bge_softc *, int, int);
+static void bge_writembx(struct bge_softc *, int, int);
+static void bge_writemem_direct(struct bge_softc *, int, int);
+static void bge_writereg_ind(struct bge_softc *, int, int);
+static void bge_set_max_readrq(struct bge_softc *);
+
+static int bge_miibus_readreg(device_t, int, int);
+static void bge_miibus_writereg(device_t, int, int, int);
+static void bge_miibus_statchg(device_t);
+
+#define BGE_RESET_START 1
+#define BGE_RESET_STOP 2
+static void bge_sig_post_reset(struct bge_softc *, int);
+static void bge_sig_legacy(struct bge_softc *, int);
+static void bge_sig_pre_reset(struct bge_softc *, int);
+static void bge_stop_fw(struct bge_softc *);
+static int bge_reset(struct bge_softc *);
+static void bge_link_upd(struct bge_softc *);
#ifdef BGE_DEBUG
#define DPRINTF(x) if (bgedebug) printf x
@@ -697,6 +720,8 @@
{ 0, NULL }
};
+static int bge_allow_asf = 1;
+
CFATTACH_DECL_NEW(bge, sizeof(struct bge_softc),
bge_probe, bge_attach, NULL, NULL);
@@ -717,6 +742,31 @@
pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_DATA, val);
}
+/*
+ * PCI Express only
+ */
+static void
+bge_set_max_readrq(struct bge_softc *sc)
+{
+ device_t dev;
+ pcireg_t val;
+
+ dev = sc->bge_dev;
+
+ val = pci_conf_read(sc->sc_pc, sc->sc_pcitag, sc->bge_expcap
+ + PCI_PCIE_DCSR);
+ if ((val & PCI_PCIE_DCSR_MAX_READ_REQ) !=
+ BGE_PCIE_DEVCTL_MAX_READRQ_4096) {
+ printf("adjust device control 0x%04x ",
+ val);
+ val &= ~PCI_PCIE_DCSR_MAX_READ_REQ;
+ val |= BGE_PCIE_DEVCTL_MAX_READRQ_4096;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->bge_expcap
+ + PCI_PCIE_DCSR, val);
+ printf("-> 0x%04x\n", val);
+ }
+}
+
#ifdef notdef
static uint32_t
bge_readreg_ind(struct bge_softc *sc, int off)
@@ -855,7 +905,7 @@
if (i == BGE_TIMEOUT * 10) {
aprint_error_dev(sc->bge_dev, "eeprom read timed out\n");
- return 0;
+ return 1;
}
/* Get result. */
@@ -971,7 +1021,7 @@
}
CSR_WRITE_4(sc, BGE_MI_COMM, BGE_MICMD_WRITE | BGE_MICOMM_BUSY |
- BGE_MIPHY(phy) | BGE_MIREG(reg)|val);
+ BGE_MIPHY(phy) | BGE_MIREG(reg) | val);
for (i = 0; i < BGE_TIMEOUT; i++) {
delay(10);
@@ -1597,36 +1647,82 @@
CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), hashes[i]);
}
-const int bge_swapbits[] = {
- 0,
- BGE_MODECTL_BYTESWAP_DATA,
- BGE_MODECTL_WORDSWAP_DATA,
- BGE_MODECTL_BYTESWAP_NONFRAME,
- BGE_MODECTL_WORDSWAP_NONFRAME,
-
- BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA,
- BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_BYTESWAP_NONFRAME,
- BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_NONFRAME,
-
- BGE_MODECTL_WORDSWAP_DATA|BGE_MODECTL_BYTESWAP_NONFRAME,
- BGE_MODECTL_WORDSWAP_DATA|BGE_MODECTL_WORDSWAP_NONFRAME,
-
- BGE_MODECTL_BYTESWAP_NONFRAME|BGE_MODECTL_WORDSWAP_NONFRAME,
-
- BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA|
- BGE_MODECTL_BYTESWAP_NONFRAME,
- BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA|
- BGE_MODECTL_WORDSWAP_NONFRAME,
- BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_BYTESWAP_NONFRAME|
- BGE_MODECTL_WORDSWAP_NONFRAME,
- BGE_MODECTL_WORDSWAP_DATA|BGE_MODECTL_BYTESWAP_NONFRAME|
- BGE_MODECTL_WORDSWAP_NONFRAME,
+static void
+bge_sig_pre_reset(sc, type)
+ struct bge_softc *sc;
+ int type;
+{
+ /*
+ * Some chips don't like this so only do this if ASF is enabled
+ */
+ if (sc->bge_asf_mode)
+ bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
- BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA|
- BGE_MODECTL_BYTESWAP_NONFRAME|BGE_MODECTL_WORDSWAP_NONFRAME,
-};
+ 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;
+ }
+ }
+}
-int bge_swapindex = 0;
+static void
+bge_sig_post_reset(sc, type)
+ 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;
+ }
+ }
+}
+
+static void
+bge_sig_legacy(sc, type)
+ 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;
+ }
+ }
+}
+
+static void
+bge_stop_fw(sc)
+ struct bge_softc *sc;
+{
+ int i;
+
+ if (sc->bge_asf_mode) {
+ bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE);
+ CSR_WRITE_4(sc, BGE_CPU_EVENT,
+ CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));
+
+ for (i = 0; i < 100; i++ ) {
+ if (!(CSR_READ_4(sc, BGE_CPU_EVENT) & (1 << 14)))
+ break;
+ DELAY(10);
+ }
+ }
+}
/*
* Do endian, PCI and DMA initialization. Also check the on-board ROM
@@ -1726,14 +1822,15 @@
BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA;
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL, dma_rw_ctl);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
+ dma_rw_ctl);
/*
* Set up general mode register.
*/
CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS |
- BGE_MODECTL_MAC_ATTN_INTR | BGE_MODECTL_HOST_SEND_BDS |
- BGE_MODECTL_TX_NO_PHDR_CSUM | BGE_MODECTL_RX_NO_PHDR_CSUM);
+ BGE_MODECTL_MAC_ATTN_INTR | BGE_MODECTL_HOST_SEND_BDS |
+ BGE_MODECTL_TX_NO_PHDR_CSUM | BGE_MODECTL_RX_NO_PHDR_CSUM);
/*
* BCM5701 B5 have a bug causing data corruption when using
@@ -1746,6 +1843,12 @@
BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_FORCE_PCI32);
/*
+ * Tell the firmware the driver is running
+ */
+ if (sc->bge_asf_mode & ASF_STACKUP)
+ BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+
+ /*
* Disable memory write invalidate. Apparently it is not supported
* properly by these devices.
*/
@@ -1780,12 +1883,12 @@
static int
bge_blockinit(struct bge_softc *sc)
{
- volatile struct bge_rcb *rcb;
- bus_size_t rcb_addr;
- int i;
- struct ifnet *ifp = &sc->ethercom.ec_if;
- bge_hostaddr taddr;
- uint32_t val;
+ volatile struct bge_rcb *rcb;
+ bus_size_t rcb_addr;
+ int i;
+ struct ifnet *ifp = &sc->ethercom.ec_if;
+ bge_hostaddr taddr;
+ uint32_t val;
/*
* Initialize the memory window pointer register so that
@@ -2101,16 +2204,15 @@
BGE_MACMODE_FRMHDR_DMA_ENB;
if (sc->bge_flags & BGE_PHY_FIBER_TBI)
- val |= BGE_PORTMODE_TBI;
+ val |= BGE_PORTMODE_TBI;
else if (sc->bge_flags & BGE_PHY_FIBER_MII)
- val |= BGE_PORTMODE_GMII;
+ val |= BGE_PORTMODE_GMII;
else
- val |= BGE_PORTMODE_MII;
+ val |= BGE_PORTMODE_MII;
/* Turn on DMA, clear stats */
CSR_WRITE_4(sc, BGE_MAC_MODE, val);
-
/* Set misc. local control, enable interrupts on attentions */
sc->bge_local_ctrl_reg = BGE_MLC_INTR_ONATTN | BGE_MLC_AUTO_EEPROM;
@@ -2195,9 +2297,8 @@
if (sc->bge_flags & BGE_TSO) {
/* XXX: magic value from Linux driver */
CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE | 0x08);
- } else {
+ } else
CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
- }
/* Turn on send BD initiator state machine */
CSR_WRITE_4(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);
@@ -2469,9 +2570,10 @@
}
if (pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_PCIEXPRESS,
- NULL, NULL) != 0) {
+ &sc->bge_expcap, NULL) != 0) {
/* PCIe */
sc->bge_flags |= BGE_PCIE;
+ bge_set_max_readrq(sc);
} else if ((pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE) &
BGE_PCISTATE_PCI_BUSMODE) == 0) {
/* PCI-X */
@@ -2628,6 +2730,29 @@
DPRINTFN(5, ("bge_reset\n"));
bge_reset(sc);
+ sc->bge_asf_mode = 0;
+ if (bge_allow_asf && (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;
+ sc->bge_asf_mode |= ASF_STACKUP;
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750) {
+ sc->bge_asf_mode |= ASF_NEW_HANDSHAKE;
+ }
+ }
+ }
+
+ /* Try to reset the chip again the nice way. */
+ bge_stop_fw(sc);
+ bge_sig_pre_reset(sc, BGE_RESET_STOP);
+ if (bge_reset(sc)) {
+ aprint_error_dev(sc->bge_dev, "chip reset failed\n");
+ }
+
+ bge_sig_legacy(sc, BGE_RESET_STOP);
+ bge_sig_post_reset(sc, BGE_RESET_STOP);
+
if (bge_chipinit(sc)) {
aprint_error_dev(sc->bge_dev, "chip initialization failed\n");
bge_release_resources(sc);
@@ -2802,17 +2927,24 @@
if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
ifmedia_init(&sc->bge_ifmedia, IFM_IMASK, bge_ifmedia_upd,
bge_ifmedia_sts);
- ifmedia_add(&sc->bge_ifmedia, IFM_ETHER|IFM_1000_SX, 0, NULL);
- ifmedia_add(&sc->bge_ifmedia, IFM_ETHER|IFM_1000_SX|IFM_FDX,
+ ifmedia_add(&sc->bge_ifmedia, IFM_ETHER |IFM_1000_SX, 0, NULL);
+ ifmedia_add(&sc->bge_ifmedia, IFM_ETHER | IFM_1000_SX|IFM_FDX,
0, NULL);
- ifmedia_add(&sc->bge_ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
- ifmedia_set(&sc->bge_ifmedia, IFM_ETHER|IFM_AUTO);
+ ifmedia_add(&sc->bge_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
+ ifmedia_set(&sc->bge_ifmedia, IFM_ETHER | IFM_AUTO);
/* Pretend the user requested this setting */
sc->bge_ifmedia.ifm_media = sc->bge_ifmedia.ifm_cur->ifm_media;
} else {
/*
- * Do transceiver setup.
+ * Do transceiver setup and tell the firmware the
+ * driver is down so we can try to get access the
+ * probe if ASF is running. Retry a couple of times
+ * if we get a conflict with the ASF firmware accessing
+ * the PHY.
*/
+ BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+ bge_asf_driver_up(sc);
+
ifmedia_init(&sc->bge_mii.mii_media, 0, bge_ifmedia_upd,
bge_ifmedia_sts);
mii_attach(sc->bge_dev, &sc->bge_mii, 0xffffffff,
@@ -2828,6 +2960,12 @@
} else
ifmedia_set(&sc->bge_mii.mii_media,
IFM_ETHER|IFM_AUTO);
+
+ /*
+ * Now tell the firmware we are going up after probing the PHY
+ */
+ if (sc->bge_asf_mode & ASF_STACKUP)
+ BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
}
/*
@@ -2883,10 +3021,11 @@
free(sc->bge_vpd_readonly, M_DEVBUF);
}
-static void
+static int
bge_reset(struct bge_softc *sc)
{
uint32_t cachesize, command, pcistate, new_pcistate;
+ pcireg_t devctl;
int i, val;
void (*write_op)(struct bge_softc *, int, int);
@@ -2916,6 +3055,13 @@
BGE_IS_5755_PLUS(sc))
CSR_WRITE_4(sc, BGE_FASTBOOT_PC, 0);
+ /*
+ * Write the magic number to SRAM at offset 0xB50.
+ * When firmware finishes its initialization it will
+ * write ~BGE_MAGIC_NUMBER to the same location.
+ */
+ bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
+
val = BGE_MISCCFG_RESET_CORE_CLOCKS | (65<<1);
/*
* XXX: from FreeBSD/Linux; no documentation
@@ -2970,15 +3116,16 @@
BGE_PCI_UNKNOWN0,
reg | (1 << 15));
}
- /*
- * XXX: Magic Numbers.
- * Sets maximal PCI-e payload and clears any PCI-e errors.
- * Should be replaced with references to PCI config-space
- * capability block for PCI-Express.
- */
+ devctl = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
+ sc->bge_expcap + PCI_PCIE_DCSR);
+ /* Clear enable no snoop and disable relaxed ordering. */
+ devctl &= ~(0x0010 | PCI_PCIE_DCSR_ENA_NO_SNOOP);
+ /* Set PCIE max payload size to 128. */
+ devctl &= ~(0x00e0);
pci_conf_write(sc->sc_pc, sc->sc_pcitag,
- BGE_PCI_CONF_DEV_CTRL, 0xf5000);
-
+ sc->bge_expcap + PCI_PCIE_DCSR, devctl);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag,
+ sc->bge_expcap + PCI_PCIE_DSR, 0);
}
/* Reset some of the PCI state that got zapped by reset */
@@ -2998,12 +3145,6 @@
CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | marbmode);
}
- /*
- * Prevent PXE restart: write a magic number to the
- * general communications memory at 0xB50.
- */
- bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
-
if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
for (i = 0; i < BGE_TIMEOUT; i++) {
val = CSR_READ_4(sc, BGE_VCPU_STATUS);
@@ -3013,7 +3154,7 @@
}
if (i == BGE_TIMEOUT) {
aprint_error_dev(sc->bge_dev, "reset timed out\n");
- return;
+ return 1;
}
} else {
/*
@@ -3029,17 +3170,9 @@
DELAY(10);
}
- if (i >= BGE_TIMEOUT && (!(sc->bge_flags & BGE_NO_EEPROM))) {
+ if (i >= BGE_TIMEOUT && (!(sc->bge_flags & BGE_NO_EEPROM)))
aprint_error_dev(sc->bge_dev,
"firmware handshake timed out, val = %x\n", val);
- /*
- * XXX: occasionally fired on bcm5721, but without
- * apparent harm. For now, keep going if we timeout
- * against PCI-E devices.
- */
- if ((sc->bge_flags & BGE_PCIE) == 0)
- return;
- }
}
/*
@@ -3078,6 +3211,10 @@
/* Fix up byte swapping */
CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS);
+ /* Tell the ASF firmware we are up */
+ if (sc->bge_asf_mode & ASF_STACKUP)
+ BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+
CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
/*
@@ -3106,6 +3243,8 @@
CSR_WRITE_4(sc, 0x7c00, v | (1<<25));
}
DELAY(10000);
+
+ return 0;
}
/*
@@ -3424,6 +3563,25 @@
}
static void
+bge_asf_driver_up(struct bge_softc *sc)
+{
+ if (sc->bge_asf_mode & ASF_STACKUP) {
+ /* Send ASF heartbeat aprox. every 2s */
+ if (sc->bge_asf_count)
+ sc->bge_asf_count --;
+ else {
+ sc->bge_asf_count = 5;
+ bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW,
+ BGE_FW_DRV_ALIVE);
+ bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_LEN, 4);
+ bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_DATA, 3);
+ CSR_WRITE_4(sc, BGE_CPU_EVENT,
+ CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));
+ }
+ }
+}
+
+static void
bge_tick(void *xsc)
{
struct bge_softc *sc = xsc;
@@ -4069,7 +4227,13 @@
/* Cancel pending I/O and flush buffers. */
bge_stop(ifp, 0);
+
+ 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);
/*
@@ -4413,6 +4577,16 @@
callout_stop(&sc->bge_timeout);
/*
+ * Tell firmware we're shutting down.
+ */
+ bge_stop_fw(sc);
+ bge_sig_pre_reset(sc, BGE_RESET_STOP);
+
+ /* Disable host interrupts. */
+ BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
+ bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
+
+ /*
* Disable all of the receiver blocks
*/
bge_stop_block(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
@@ -4453,14 +4627,17 @@
bge_stop_block(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
}
- /* Disable host interrupts. */
- BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
- bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
+ bge_reset(sc);
+ bge_sig_legacy(sc, BGE_RESET_STOP);
+ bge_sig_post_reset(sc, BGE_RESET_STOP);
/*
- * Tell firmware we're shutting down.
+ * Keep the ASF firmware running if up.
*/
- BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+ 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);
@@ -4737,9 +4914,8 @@
{
int mac_offset = BGE_EE_MAC_OFFSET;
- if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
mac_offset = BGE_EE_MAC_OFFSET_5906;
- }
return (bge_read_nvram(sc, ether_addr, mac_offset + 2,
ETHER_ADDR_LEN));
Index: src/sys/dev/pci/if_bgereg.h
diff -u src/sys/dev/pci/if_bgereg.h:1.54 src/sys/dev/pci/if_bgereg.h:1.55
--- src/sys/dev/pci/if_bgereg.h:1.54 Sun Jan 24 16:21:09 2010
+++ src/sys/dev/pci/if_bgereg.h Thu Jan 28 03:09:13 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bgereg.h,v 1.54 2010/01/24 16:21:09 msaitoh Exp $ */
+/* $NetBSD: if_bgereg.h,v 1.55 2010/01/28 03:09:13 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2001
@@ -62,7 +62,6 @@
* Flat mode consumes so much host address space that it is not
* recommended.
*/
-
#define BGE_PAGE_ZERO 0x00000000
#define BGE_PAGE_ZERO_END 0x000000FF
#define BGE_SEND_RING_RCB 0x00000100
@@ -76,6 +75,9 @@
#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_SOFTWARE_GENNCOMM_FW_LEN 0x00000B7C
+#define BGE_SOFTWARE_GENNCOMM_FW_DATA 0x00000B80
#define BGE_SOFTWARE_GENCOMM_END 0x00000FFF
#define BGE_UNMAPPED 0x00001000
#define BGE_UNMAPPED_END 0x00001FFF
@@ -84,6 +86,10 @@
#define BGE_SEND_RING_1_TO_4 0x00004000
#define BGE_SEND_RING_1_TO_4_END 0x00005FFF
+/* Firmware interface */
+#define BGE_FW_DRV_ALIVE 0x00000001
+#define BGE_FW_PAUSE 0x00000002
+
/* Mappings for internal memory configuration */
#define BGE_STD_RX_RINGS 0x00006000
#define BGE_STD_RX_RINGS_END 0x00006FFF
@@ -172,6 +178,26 @@
#define BGE_PCI_MSI_DATA 0x64
/*
+ * PCI Express definitions
+ * According to
+ * PCI Express base specification, REV. 1.0a
+ */
+
+/* PCI Express device control, 16bits */
+#define BGE_PCIE_DEVCTL 0x08
+#define BGE_PCIE_DEVCTL_MAX_READRQ_MASK 0x7000
+#define BGE_PCIE_DEVCTL_MAX_READRQ_128 0x0000
+#define BGE_PCIE_DEVCTL_MAX_READRQ_256 0x1000
+#define BGE_PCIE_DEVCTL_MAX_READRQ_512 0x2000
+#define BGE_PCIE_DEVCTL_MAX_READRQ_1024 0x3000
+#define BGE_PCIE_DEVCTL_MAX_READRQ_2048 0x4000
+#define BGE_PCIE_DEVCTL_MAX_READRQ_4096 0x5000
+
+/* PCI MSI. ??? */
+#define BGE_PCIE_CAPID_REG 0xD0
+#define BGE_PCIE_CAPID 0x10
+
+/*
* PCI registers specific to the BCM570x family.
*/
#define BGE_PCI_MISC_CTL 0x68
@@ -207,7 +233,6 @@
#define BGE_PCI_CONF_DEV_CTRL 0xD8
#define BGE_PCI_CONF_DEV_STUS 0xDA
-
/* PCI Misc. Host control register */
#define BGE_PCIMISCCTL_CLEAR_INTA 0x00000001
#define BGE_PCIMISCCTL_MASK_PCI_INTR 0x00000002
@@ -412,11 +437,6 @@
#define BGE_PCICLOCKCTL_SYSPLL_DISABLE 0x00008000
#define BGE_PCICLOCKCTL_BIST_ENABLE 0x00010000
-
-#ifndef PCIM_CMD_MWIEN
-#define PCIM_CMD_MWIEN 0x0010
-#endif
-
/*
* High priority mailbox registers
* Each mailbox is 64-bits wide, though we only use the
@@ -628,7 +648,6 @@
#define BGE_SGDIG_CFG 0x05B0
#define BGE_SGDIG_STS 0x05B4
#define BGE_MAC_STATS 0x0800
-#define BGE_TX_STATS 0x0880
/* Ethernet MAC Mode register */
#define BGE_MACMODE_RESET 0x00000001
@@ -1718,7 +1737,7 @@
#define BGE_MODE_CTL 0x6800
#define BGE_MISC_CFG 0x6804
#define BGE_MISC_LOCAL_CTL 0x6808
-#define BGE_MISC_TIMER 0x680c
+#define BGE_CPU_EVENT 0x6810
#define BGE_EE_ADDR 0x6838
#define BGE_EE_DATA 0x683C
#define BGE_EE_CTL 0x6840
@@ -1797,8 +1816,6 @@
#define BGE_PHY_PCIE_SCRAM_MODE 0x0020
#define BGE_PHY_PCIE_LTASS_MODE 0x0040
-
-
/* Mode control register */
#define BGE_MODECTL_INT_SNDCOAL_ONLY 0x00000001
#define BGE_MODECTL_BYTESWAP_NONFRAME 0x00000002
@@ -2099,6 +2116,7 @@
#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
Index: src/sys/dev/pci/if_bgevar.h
diff -u src/sys/dev/pci/if_bgevar.h:1.2 src/sys/dev/pci/if_bgevar.h:1.3
--- src/sys/dev/pci/if_bgevar.h:1.2 Sun Jan 24 16:21:09 2010
+++ src/sys/dev/pci/if_bgevar.h Thu Jan 28 03:09:13 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bgevar.h,v 1.2 2010/01/24 16:21:09 msaitoh Exp $ */
+/* $NetBSD: if_bgevar.h,v 1.3 2010/01/28 03:09:13 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2001
@@ -217,6 +217,10 @@
SLIST_ENTRY(txdmamap_pool_entry) link;
};
+#define ASF_ENABLE 1
+#define ASF_NEW_HANDSHAKE 2
+#define ASF_STACKUP 4
+
struct bge_softc {
device_t bge_dev;
struct ethercom ethercom; /* interface info */
@@ -231,8 +235,11 @@
u_int32_t bge_return_ring_cnt;
u_int32_t bge_tx_prodidx;
bus_dma_tag_t bge_dmatag;
+ int bge_expcap;
u_int32_t bge_chipid;
u_int32_t bge_local_ctrl_reg;
+ uint8_t bge_asf_mode;
+ uint8_t bge_asf_count;
struct bge_ring_data *bge_rdata; /* rings */
struct bge_chain_data bge_cdata; /* mbufs */
bus_dmamap_t bge_ring_map;