diff --git a/src/add-ons/kernel/drivers/network/wlan/marv88w8363/Jamfile b/src/add-ons/kernel/drivers/network/wlan/marv88w8363/Jamfile index 560f062e9e..d2eec68a0e 100644 --- a/src/add-ons/kernel/drivers/network/wlan/marv88w8363/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/marv88w8363/Jamfile @@ -21,6 +21,7 @@ KernelAddon marv88w8363 : if_mwl.c if_mwl_pci.c mwlhal.c + glue.c : libfreebsd_wlan.a libfreebsd_network.a diff --git a/src/add-ons/kernel/drivers/network/wlan/marv88w8363/dev/mwl/if_mwl.c b/src/add-ons/kernel/drivers/network/wlan/marv88w8363/dev/mwl/if_mwl.c index c320cdb49c..7a249ee6d1 100644 --- a/src/add-ons/kernel/drivers/network/wlan/marv88w8363/dev/mwl/if_mwl.c +++ b/src/add-ons/kernel/drivers/network/wlan/marv88w8363/dev/mwl/if_mwl.c @@ -821,21 +821,11 @@ mwl_intr(void *arg) struct mwl_softc *sc = arg; struct mwl_hal *mh = sc->sc_mh; uint32_t status; + HAIKU_INTR_REGISTER_STATE; - if (sc->sc_invalid) { - /* - * The hardware is not ready/present, don't touch anything. - * Note this can happen early on if the IRQ is shared. - */ - DPRINTF(sc, MWL_DEBUG_ANY, "%s: invalid; ignored\n", __func__); - return; - } - /* - * Figure out the reason(s) for the interrupt. - */ - mwl_hal_getisr(mh, &status); /* NB: clears ISR too */ - if (status == 0) /* must be a shared irq */ - return; + HAIKU_INTR_REGISTER_ENTER(); + status = sc->sc_lastisr; + HAIKU_INTR_REGISTER_LEAVE(); DPRINTF(sc, MWL_DEBUG_INTR, "%s: status 0x%x imask 0x%x\n", __func__, status, sc->sc_imask); diff --git a/src/add-ons/kernel/drivers/network/wlan/marv88w8363/dev/mwl/if_mwlvar.h b/src/add-ons/kernel/drivers/network/wlan/marv88w8363/dev/mwl/if_mwlvar.h index d69285d17d..3062ab75e8 100644 --- a/src/add-ons/kernel/drivers/network/wlan/marv88w8363/dev/mwl/if_mwlvar.h +++ b/src/add-ons/kernel/drivers/network/wlan/marv88w8363/dev/mwl/if_mwlvar.h @@ -331,6 +331,8 @@ struct mwl_softc { struct mwl_tx_radiotap_header sc_tx_th; struct mwl_rx_radiotap_header sc_rx_th; + + uint32_t sc_lastisr; }; #define MWL_LOCK_INIT(_sc) \ diff --git a/src/add-ons/kernel/drivers/network/wlan/marv88w8363/glue.c b/src/add-ons/kernel/drivers/network/wlan/marv88w8363/glue.c new file mode 100644 index 0000000000..b10b4747dc --- /dev/null +++ b/src/add-ons/kernel/drivers/network/wlan/marv88w8363/glue.c @@ -0,0 +1,77 @@ +/* + * Copyright 2009, Colin Günther, coling@gmx.de. + * All Rights Reserved. Distributed under the terms of the MIT License. + */ + + +#include +#include + +#include +#include + +#include + +#include + +#include + + +HAIKU_FBSD_WLAN_DRIVER_GLUE(marv88w8363, mwl, pci) +NO_HAIKU_FBSD_MII_DRIVER(); +HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES|FBSD_WLAN); +HAIKU_FIRMWARE_VERSION(0); + + +int +HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) +{ + struct mwl_softc* sc = (struct mwl_softc*)device_get_softc(dev); + struct mwl_hal* mh = sc->sc_mh; + HAIKU_INTR_REGISTER_STATE; + + if (sc->sc_invalid) { + /* + * The hardware is not ready/present, don't touch anything. + * Note this can happen early on if the IRQ is shared. + */ + return 0; + } + + HAIKU_INTR_REGISTER_ENTER(); + + /* + * We have to save the isr status right now. + * Some devices don't like having the interrupt disabled + * before accessing the isr status. + * + * Those devices return status 0, when status access + * occurs after disabling the interrupts with mwl_hal_intrset. + * + * Note: This glue.c is based on the one for the atheros wlan driver. + * So the comment above isn't based on tests on real marvell hardware. + * But due to the similarities in both drivers I just go the safe + * route here. It doesn't do any harm, but may prevent hard to spot + * bugs. + */ + mwl_hal_getisr(mh, &sc->sc_lastisr); /* NB: clears ISR too */ + if (sc->sc_lastisr == 0) { /* must be a shared irq */ + HAIKU_INTR_REGISTER_LEAVE(); + return 0; + } + + mwl_hal_intrset(mh, 0); // disable further intr's + + HAIKU_INTR_REGISTER_LEAVE(); + return 1; +} + + +void +HAIKU_REENABLE_INTERRUPTS(device_t dev) +{ + struct mwl_softc* sc = (struct mwl_softc*)device_get_softc(dev); + struct mwl_hal* mh = sc->sc_mh; + + mwl_hal_intrset(mh, sc->sc_imask); +}