diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2006-02-25 12:56:48 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2006-02-25 12:56:48 +0000 |
commit | 43b0628d6f729fd5b051e187f66bed4f81c07e5f (patch) | |
tree | 7ff8638c412aef96c8e1bcd473bcb17f5cc70986 /sys | |
parent | e974547218ce56dc68df161543697e398d97c51f (diff) |
load the firmware only when necessary (first call to rt2661_init or if the
cardbus socket has been powered off). restore the call to rt2661_init() in
the watchdog since the firmware is not reloaded in this case.
fixes "timeout waiting for BBP" errors seen on some PCI adapters.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/rt2661.c | 62 | ||||
-rw-r--r-- | sys/dev/ic/rt2661var.h | 3 |
2 files changed, 34 insertions, 31 deletions
diff --git a/sys/dev/ic/rt2661.c b/sys/dev/ic/rt2661.c index 24779315ae8..6c7ec42e265 100644 --- a/sys/dev/ic/rt2661.c +++ b/sys/dev/ic/rt2661.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2661.c,v 1.10 2006/02/18 09:41:41 damien Exp $ */ +/* $OpenBSD: rt2661.c,v 1.11 2006/02/25 12:56:47 damien Exp $ */ /*- * Copyright (c) 2006 @@ -1968,8 +1968,7 @@ rt2661_watchdog(struct ifnet *ifp) if (sc->sc_tx_timer > 0) { if (--sc->sc_tx_timer == 0) { printf("%s: device timeout\n", sc->sc_dev.dv_xname); - ifp->if_flags &= ~IFF_UP; - rt2661_stop(ifp, 1); + rt2661_init(ifp); ifp->if_oerrors++; return; } @@ -2550,35 +2549,38 @@ rt2661_init(struct ifnet *ifp) rt2661_stop(ifp, 0); - switch (sc->sc_id) { - case PCI_PRODUCT_RALINK_RT2561: - name = "ral-rt2561"; - break; - case PCI_PRODUCT_RALINK_RT2561S: - name = "ral-rt2561s"; - break; - case PCI_PRODUCT_RALINK_RT2661: - name = "ral-rt2661"; - break; - } + if (!(sc->sc_flags & RT2661_FWLOADED)) { + switch (sc->sc_id) { + case PCI_PRODUCT_RALINK_RT2561: + name = "ral-rt2561"; + break; + case PCI_PRODUCT_RALINK_RT2561S: + name = "ral-rt2561s"; + break; + case PCI_PRODUCT_RALINK_RT2661: + name = "ral-rt2661"; + break; + } - if (loadfirmware(name, &ucode, &size) != 0) { - printf("%s: could not read microcode %s\n", - sc->sc_dev.dv_xname, name); - rt2661_stop(ifp, 1); - return EIO; - } + if (loadfirmware(name, &ucode, &size) != 0) { + printf("%s: could not read microcode %s\n", + sc->sc_dev.dv_xname, name); + rt2661_stop(ifp, 1); + return EIO; + } + + if (rt2661_load_microcode(sc, ucode, size) != 0) { + printf("%s: could not load 8051 microcode\n", + sc->sc_dev.dv_xname); + free(ucode, M_DEVBUF); + rt2661_stop(ifp, 1); + return EIO; + } - if (rt2661_load_microcode(sc, ucode, size) != 0) { - printf("%s: could not load 8051 microcode\n", - sc->sc_dev.dv_xname); free(ucode, M_DEVBUF); - rt2661_stop(ifp, 1); - return EIO; + sc->sc_flags |= RT2661_FWLOADED; } - free(ucode, M_DEVBUF); - /* initialize Tx rings */ RAL_WRITE(sc, RT2661_AC1_BASE_CSR, sc->txq[1].physaddr); RAL_WRITE(sc, RT2661_AC0_BASE_CSR, sc->txq[0].physaddr); @@ -2702,12 +2704,12 @@ rt2661_stop(struct ifnet *ifp, int disable) struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); /* free all nodes */ - sc->sc_tx_timer = 0; ifp->if_timer = 0; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + ieee80211_new_state(ic, IEEE80211_S_INIT, -1); /* free all nodes */ + /* abort Tx (for all 5 Tx rings) */ RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16); @@ -2735,7 +2737,7 @@ rt2661_stop(struct ifnet *ifp, int disable) if (disable && sc->sc_disable != NULL) { if (sc->sc_flags & RT2661_ENABLED) { (*sc->sc_disable)(sc); - sc->sc_flags &= ~RT2661_ENABLED; + sc->sc_flags &= ~(RT2661_ENABLED | RT2661_FWLOADED); } } } diff --git a/sys/dev/ic/rt2661var.h b/sys/dev/ic/rt2661var.h index e7bae7400de..a41bb2d082f 100644 --- a/sys/dev/ic/rt2661var.h +++ b/sys/dev/ic/rt2661var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2661var.h,v 1.3 2006/01/14 12:43:27 damien Exp $ */ +/* $OpenBSD: rt2661var.h,v 1.4 2006/02/25 12:56:47 damien Exp $ */ /*- * Copyright (c) 2006 @@ -109,6 +109,7 @@ struct rt2661_softc { int sc_id; int sc_flags; #define RT2661_ENABLED (1 << 0) +#define RT2661_FWLOADED (1 << 1) int sc_tx_timer; |