-/* $OpenBSD: rt2560.c,v 1.48 2010/05/19 15:27:35 oga Exp $ */
+/* $OpenBSD: rt2560.c,v 1.49 2010/08/04 19:48:33 damien Exp $ */
/*-
* Copyright (c) 2005, 2006
return 0;
}
+void
+rt2560_suspend(void *xsc)
+{
+ struct rt2560_softc *sc = xsc;
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+ if (ifp->if_flags & IFF_RUNNING)
+ rt2560_stop(ifp, 0);
+}
+
+void
+rt2560_resume(void *xsc)
+{
+ struct rt2560_softc *sc = xsc;
+
+ rt2560_power(PWR_RESUME, sc);
+}
+
int
rt2560_alloc_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring,
int count)
struct ifnet *ifp = &sc->sc_ic.ic_if;
int s;
- DPRINTF(("%s: rt2560_power(%d)\n", sc->sc_dev.dv_xname, why));
-
s = splnet();
switch (why) {
case PWR_SUSPEND:
case PWR_STANDBY:
- rt2560_stop(ifp, 1);
+ rt2560_stop(ifp, 0);
if (sc->sc_power != NULL)
(*sc->sc_power)(sc, why);
break;
rt2560_init(ifp);
if (sc->sc_power != NULL)
(*sc->sc_power)(sc, why);
- if (ifp->if_flags & IFF_RUNNING)
- rt2560_start(ifp);
}
break;
}
-/* $OpenBSD: rt2560var.h,v 1.6 2009/08/10 17:47:23 damien Exp $ */
+/* $OpenBSD: rt2560var.h,v 1.7 2010/08/04 19:48:33 damien Exp $ */
/*-
* Copyright (c) 2005, 2006
int rt2560_attach(void *, int);
int rt2560_detach(void *);
+void rt2560_suspend(void *);
+void rt2560_resume(void *);
int rt2560_intr(void *);
-/* $OpenBSD: rt2661.c,v 1.54 2010/05/19 15:27:35 oga Exp $ */
+/* $OpenBSD: rt2661.c,v 1.55 2010/08/04 19:48:33 damien Exp $ */
/*-
* Copyright (c) 2006
#define DPRINTFN(n, x)
#endif
+void rt2661_attachhook(void *);
int rt2661_alloc_tx_ring(struct rt2661_softc *,
struct rt2661_tx_ring *, int);
void rt2661_reset_tx_ring(struct rt2661_softc *,
int rt2661_bbp_init(struct rt2661_softc *);
int rt2661_init(struct ifnet *);
void rt2661_stop(struct ifnet *, int);
-int rt2661_load_microcode(struct rt2661_softc *, const uint8_t *,
- int);
+int rt2661_load_microcode(struct rt2661_softc *);
void rt2661_rx_tune(struct rt2661_softc *);
#ifdef notyet
void rt2661_radar_start(struct rt2661_softc *);
{
struct rt2661_softc *sc = xsc;
struct ieee80211com *ic = &sc->sc_ic;
- struct ifnet *ifp = &ic->ic_if;
uint32_t val;
- int error, ac, i, ntries;
+ int error, ac, ntries;
sc->sc_id = id;
goto fail2;
}
+ if (rootvp == NULL)
+ mountroothook_establish(rt2661_attachhook, sc);
+ else
+ rt2661_attachhook(sc);
+
+ sc->sc_powerhook = powerhook_establish(rt2661_power, sc);
+ if (sc->sc_powerhook == NULL) {
+ printf("%s: WARNING: unable to establish power hook\n",
+ sc->sc_dev.dv_xname);
+ }
+
+ return 0;
+
+fail2: rt2661_free_tx_ring(sc, &sc->mgtq);
+fail1: while (--ac >= 0)
+ rt2661_free_tx_ring(sc, &sc->txq[ac]);
+ return ENXIO;
+}
+
+void
+rt2661_attachhook(void *xsc)
+{
+ struct rt2661_softc *sc = xsc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+ const char *name = NULL; /* make lint happy */
+ int i, error;
+
+ 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 ((error = loadfirmware(name, &sc->ucode, &sc->ucsize)) != 0) {
+ printf("%s: error %d, could not read firmware %s\n",
+ sc->sc_dev.dv_xname, error, name);
+ return;
+ }
+
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
ic->ic_state = IEEE80211_S_INIT;
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
sc->sc_txtap.wt_ihdr.it_present = htole32(RT2661_TX_RADIOTAP_PRESENT);
#endif
-
- sc->sc_powerhook = powerhook_establish(rt2661_power, sc);
- if (sc->sc_powerhook == NULL) {
- printf("%s: WARNING: unable to establish power hook\n",
- sc->sc_dev.dv_xname);
- }
-
- return 0;
-
-fail2: rt2661_free_tx_ring(sc, &sc->mgtq);
-fail1: while (--ac >= 0)
- rt2661_free_tx_ring(sc, &sc->txq[ac]);
- return ENXIO;
}
int
rt2661_free_tx_ring(sc, &sc->mgtq);
rt2661_free_rx_ring(sc, &sc->rxq);
+ if (sc->ucode != NULL)
+ free(sc->ucode, M_DEVBUF);
+
return 0;
}
+void
+rt2661_suspend(void *xsc)
+{
+ struct rt2661_softc *sc = xsc;
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+ if (ifp->if_flags & IFF_RUNNING)
+ rt2661_stop(ifp, 0);
+}
+
+void
+rt2661_resume(void *xsc)
+{
+ struct rt2661_softc *sc = xsc;
+
+ rt2661_power(PWR_RESUME, sc);
+}
+
int
rt2661_alloc_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring,
int count)
{
struct rt2661_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
- const char *name = NULL; /* make lint happy */
- uint8_t *ucode;
- size_t size;
uint32_t tmp, sta[3];
- int i, ntries, error;
+ int i, ntries;
/* for CardBus, power on the socket */
if (!(sc->sc_flags & RT2661_ENABLED)) {
rt2661_stop(ifp, 0);
- 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 ((error = loadfirmware(name, &ucode, &size)) != 0) {
- printf("%s: error %d, could not read firmware %s\n",
- sc->sc_dev.dv_xname, error, 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;
- }
-
- free(ucode, M_DEVBUF);
- sc->sc_flags |= RT2661_FWLOADED;
+ if (rt2661_load_microcode(sc) != 0) {
+ printf("%s: could not load 8051 microcode\n",
+ sc->sc_dev.dv_xname);
+ rt2661_stop(ifp, 1);
+ return EIO;
}
/* initialize Tx rings */
if (disable && sc->sc_disable != NULL) {
if (sc->sc_flags & RT2661_ENABLED) {
(*sc->sc_disable)(sc);
- sc->sc_flags &= ~(RT2661_ENABLED | RT2661_FWLOADED);
+ sc->sc_flags &= ~RT2661_ENABLED;
}
}
}
int
-rt2661_load_microcode(struct rt2661_softc *sc, const uint8_t *ucode, int size)
+rt2661_load_microcode(struct rt2661_softc *sc)
{
int ntries;
/* write 8051's microcode */
RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET | RT2661_MCU_SEL);
- RAL_WRITE_REGION_1(sc, RT2661_MCU_CODE_BASE, ucode, size);
+ RAL_WRITE_REGION_1(sc, RT2661_MCU_CODE_BASE, sc->ucode, sc->ucsize);
RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
/* kick 8051's ass */
struct ifnet *ifp = &sc->sc_ic.ic_if;
int s;
- DPRINTF(("%s: rt2661_power(%d)\n", sc->sc_dev.dv_xname, why));
-
s = splnet();
switch (why) {
case PWR_SUSPEND:
case PWR_STANDBY:
- rt2661_stop(ifp, 1);
- sc->sc_flags &= ~RT2661_FWLOADED;
+ rt2661_stop(ifp, 0);
if (sc->sc_power != NULL)
(*sc->sc_power)(sc, why);
break;
rt2661_init(ifp);
if (sc->sc_power != NULL)
(*sc->sc_power)(sc, why);
- if (ifp->if_flags & IFF_RUNNING)
- rt2661_start(ifp);
}
break;
}
-/* $OpenBSD: rt2661var.h,v 1.10 2009/08/10 17:47:23 damien Exp $ */
+/* $OpenBSD: rt2661var.h,v 1.11 2010/08/04 19:48:33 damien Exp $ */
/*-
* Copyright (c) 2006
int sc_id;
int sc_flags;
#define RT2661_ENABLED (1 << 0)
-#define RT2661_FWLOADED (1 << 1)
-#define RT2661_UPDATE_SLOT (1 << 2)
-#define RT2661_SET_SLOTTIME (1 << 3)
+#define RT2661_UPDATE_SLOT (1 << 1)
+#define RT2661_SET_SLOTTIME (1 << 2)
int sc_tx_timer;
struct ieee80211_channel *sc_curchan;
+ u_char *ucode;
+ size_t ucsize;
+
uint8_t rf_rev;
uint8_t rfprog;
int rt2661_attach(void *, int);
int rt2661_detach(void *);
+void rt2661_suspend(void *);
+void rt2661_resume(void *);
int rt2661_intr(void *);
-/* $OpenBSD: rt2860.c,v 1.56 2010/07/19 19:47:52 damien Exp $ */
+/* $OpenBSD: rt2860.c,v 1.57 2010/08/04 19:48:33 damien Exp $ */
/*-
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
#define DPRINTFN(n, x)
#endif
+void rt2860_attachhook(void *);
int rt2860_alloc_tx_ring(struct rt2860_softc *,
struct rt2860_tx_ring *);
void rt2860_reset_tx_ring(struct rt2860_softc *,
{
struct rt2860_softc *sc = xsc;
struct ieee80211com *ic = &sc->sc_ic;
- struct ifnet *ifp = &ic->ic_if;
- int i, qid, ntries, error;
+ int qid, ntries, error;
uint32_t tmp;
sc->amrr.amrr_min_success_threshold = 1;
sc->mgtqid = (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) ?
EDCA_AC_VO : 5;
+ if (rootvp == NULL)
+ mountroothook_establish(rt2860_attachhook, sc);
+ else
+ rt2860_attachhook(sc);
+
+ sc->sc_powerhook = powerhook_establish(rt2860_power, sc);
+ if (sc->sc_powerhook == NULL) {
+ printf("%s: WARNING: unable to establish power hook\n",
+ sc->sc_dev.dv_xname);
+ }
+
+ return 0;
+
+fail2: rt2860_free_rx_ring(sc, &sc->rxq);
+fail1: while (--qid >= 0)
+ rt2860_free_tx_ring(sc, &sc->txq[qid]);
+ return error;
+}
+
+void
+rt2860_attachhook(void *xsc)
+{
+ struct rt2860_softc *sc = xsc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+ int i, error;
+
+ error = loadfirmware("ral-rt2860", &sc->ucode, &sc->ucsize);
+ if (error != 0) {
+ printf("%s: error %d, could not read firmware file %s\n",
+ sc->sc_dev.dv_xname, error, "ral-rt2860");
+ return;
+ }
+
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
ic->ic_state = IEEE80211_S_INIT;
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
sc->sc_txtap.wt_ihdr.it_present = htole32(RT2860_TX_RADIOTAP_PRESENT);
#endif
-
- sc->sc_powerhook = powerhook_establish(rt2860_power, sc);
- if (sc->sc_powerhook == NULL) {
- printf("%s: WARNING: unable to establish power hook\n",
- sc->sc_dev.dv_xname);
- }
-
- return 0;
-
-fail2: rt2860_free_rx_ring(sc, &sc->rxq);
-fail1: while (--qid >= 0)
- rt2860_free_tx_ring(sc, &sc->txq[qid]);
- return error;
}
int
rt2860_free_rx_ring(sc, &sc->rxq);
rt2860_free_tx_pool(sc);
+ if (sc->ucode != NULL)
+ free(sc->ucode, M_DEVBUF);
+
return 0;
}
+void
+rt2860_suspend(void *xsc)
+{
+ struct rt2860_softc *sc = xsc;
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+ if (ifp->if_flags & IFF_RUNNING)
+ rt2860_stop(ifp, 0);
+}
+
+void
+rt2860_resume(void *xsc)
+{
+ struct rt2860_softc *sc = xsc;
+
+ rt2860_power(PWR_RESUME, sc);
+}
+
int
rt2860_alloc_tx_ring(struct rt2860_softc *sc, struct rt2860_tx_ring *ring)
{
RAL_BARRIER_WRITE(sc);
RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe00);
- if (!(sc->sc_flags & RT2860_FWLOADED)) {
- if ((error = rt2860_load_microcode(sc)) != 0) {
- printf("%s: could not load 8051 microcode\n",
- sc->sc_dev.dv_xname);
- rt2860_stop(ifp, 1);
- return error;
- }
- sc->sc_flags |= RT2860_FWLOADED;
+ if ((error = rt2860_load_microcode(sc)) != 0) {
+ printf("%s: could not load 8051 microcode\n",
+ sc->sc_dev.dv_xname);
+ rt2860_stop(ifp, 1);
+ return error;
}
IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
if (disable && sc->sc_disable != NULL) {
if (sc->sc_flags & RT2860_ENABLED) {
(*sc->sc_disable)(sc);
- sc->sc_flags &= ~(RT2860_ENABLED | RT2860_FWLOADED);
+ sc->sc_flags &= ~RT2860_ENABLED;
}
}
}
int
rt2860_load_microcode(struct rt2860_softc *sc)
{
- u_char *ucode;
- size_t size;
- int error, ntries;
-
- if ((error = loadfirmware("ral-rt2860", &ucode, &size)) != 0) {
- printf("%s: error %d, could not read firmware file %s\n",
- sc->sc_dev.dv_xname, error, "ral-rt2860");
- return error;
- }
+ int ntries;
/* set "host program ram write selection" bit */
RAL_WRITE(sc, RT2860_SYS_CTRL, RT2860_HST_PM_SEL);
/* write microcode image */
- RAL_WRITE_REGION_1(sc, RT2860_FW_BASE, ucode, size);
+ RAL_WRITE_REGION_1(sc, RT2860_FW_BASE, sc->ucode, sc->ucsize);
/* kick microcontroller unit */
RAL_WRITE(sc, RT2860_SYS_CTRL, 0);
RAL_BARRIER_WRITE(sc);
RAL_WRITE(sc, RT2860_H2M_BBPAGENT, 0);
RAL_WRITE(sc, RT2860_H2M_MAILBOX, 0);
- free(ucode, M_DEVBUF);
-
/* wait until microcontroller is ready */
RAL_BARRIER_READ_WRITE(sc);
for (ntries = 0; ntries < 1000; ntries++) {
switch (why) {
case PWR_SUSPEND:
case PWR_STANDBY:
- rt2860_stop(ifp, 1);
- sc->sc_flags &= ~RT2860_FWLOADED;
+ rt2860_stop(ifp, 0);
if (sc->sc_power != NULL)
(*sc->sc_power)(sc, why);
break;
rt2860_init(ifp);
if (sc->sc_power != NULL)
(*sc->sc_power)(sc, why);
- if (ifp->if_flags & IFF_RUNNING)
- rt2860_start(ifp);
}
break;
}
-/* $OpenBSD: rt2860var.h,v 1.17 2010/07/19 19:47:52 damien Exp $ */
+/* $OpenBSD: rt2860var.h,v 1.18 2010/08/04 19:48:33 damien Exp $ */
/*-
* Copyright (c) 2007
int sc_flags;
#define RT2860_ENABLED (1 << 0)
-#define RT2860_FWLOADED (1 << 1)
-#define RT2860_ADVANCED_PS (1 << 2)
-#define RT2860_PCIE (1 << 3)
+#define RT2860_ADVANCED_PS (1 << 1)
+#define RT2860_PCIE (1 << 2)
uint32_t sc_ic_flags;
int fixed_ridx;
+ u_char *ucode;
+ size_t ucsize;
+
struct rt2860_tx_ring txq[6];
struct rt2860_rx_ring rxq;
int rt2860_attach(void *, int);
int rt2860_detach(void *);
+void rt2860_suspend(void *);
+void rt2860_resume(void *);
int rt2860_intr(void *);
-/* $OpenBSD: if_ral_pci.c,v 1.19 2010/04/05 14:14:02 damien Exp $ */
+/* $OpenBSD: if_ral_pci.c,v 1.20 2010/08/04 19:48:33 damien Exp $ */
/*-
* Copyright (c) 2005-2010 Damien Bergamini <damien.bergamini@free.fr>
#include <sys/malloc.h>
#include <sys/timeout.h>
#include <sys/device.h>
+#include <sys/workq.h>
#include <machine/bus.h>
#include <machine/intr.h>
static struct ral_opns {
int (*attach)(void *, int);
int (*detach)(void *);
+ void (*suspend)(void *);
+ void (*resume)(void *);
int (*intr)(void *);
} ral_rt2560_opns = {
rt2560_attach,
rt2560_detach,
+ rt2560_suspend,
+ rt2560_resume,
rt2560_intr
}, ral_rt2661_opns = {
rt2661_attach,
rt2661_detach,
+ rt2661_suspend,
+ rt2661_resume,
rt2661_intr
}, ral_rt2860_opns = {
rt2860_attach,
rt2860_detach,
+ rt2860_suspend,
+ rt2860_resume,
rt2860_intr
};
pci_chipset_tag_t sc_pc;
void *sc_ih;
bus_size_t sc_mapsize;
+ struct workq_task sc_resume_wqt;
};
/* Base Address Register */
int ral_pci_match(struct device *, void *, void *);
void ral_pci_attach(struct device *, struct device *, void *);
int ral_pci_detach(struct device *, int);
+int ral_pci_activate(struct device *, int);
+void ral_pci_resume(void *, void *);
struct cfattach ral_pci_ca = {
sizeof (struct ral_pci_softc), ral_pci_match, ral_pci_attach,
- ral_pci_detach
+ ral_pci_detach, ral_pci_activate
};
const struct pci_matchid ral_pci_devices[] = {
return 0;
}
+
+int
+ral_pci_activate(struct device *self, int act)
+{
+ struct ral_pci_softc *psc = (struct ral_pci_softc *)self;
+ struct rt2560_softc *sc = &psc->sc_sc;
+
+ switch (act) {
+ case DVACT_SUSPEND:
+ (*psc->sc_opns->suspend)(sc);
+ break;
+ case DVACT_RESUME:
+ workq_queue_task(NULL, &psc->sc_resume_wqt, 0,
+ ral_pci_resume, psc, NULL);
+ break;
+ }
+
+ return 0;
+}
+
+void
+ral_pci_resume(void *arg1, void *arg2)
+{
+ struct ral_pci_softc *psc = arg1;
+ struct rt2560_softc *sc = &psc->sc_sc;
+ int s;
+
+ s = splnet();
+ (*psc->sc_opns->resume)(sc);
+ splx(s);
+}