Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/iwn/if_iwn.c
Show First 20 Lines • Show All 338 Lines • ▼ Show 20 Lines | |||||
static void iwn_init(struct iwn_softc *); | static void iwn_init(struct iwn_softc *); | ||||
static void iwn_stop_locked(struct iwn_softc *); | static void iwn_stop_locked(struct iwn_softc *); | ||||
static void iwn_stop(struct iwn_softc *); | static void iwn_stop(struct iwn_softc *); | ||||
static void iwn_scan_start(struct ieee80211com *); | static void iwn_scan_start(struct ieee80211com *); | ||||
static void iwn_scan_end(struct ieee80211com *); | static void iwn_scan_end(struct ieee80211com *); | ||||
static void iwn_set_channel(struct ieee80211com *); | static void iwn_set_channel(struct ieee80211com *); | ||||
static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long); | static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long); | ||||
static void iwn_scan_mindwell(struct ieee80211_scan_state *); | static void iwn_scan_mindwell(struct ieee80211_scan_state *); | ||||
static void iwn_hw_reset(void *, int); | |||||
#ifdef IWN_DEBUG | #ifdef IWN_DEBUG | ||||
static char *iwn_get_csr_string(int); | static char *iwn_get_csr_string(int); | ||||
static void iwn_debug_register(struct iwn_softc *); | static void iwn_debug_register(struct iwn_softc *); | ||||
#endif | #endif | ||||
static device_method_t iwn_methods[] = { | static device_method_t iwn_methods[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
DEVMETHOD(device_probe, iwn_probe), | DEVMETHOD(device_probe, iwn_probe), | ||||
▲ Show 20 Lines • Show All 316 Lines • ▼ Show 20 Lines | #endif | ||||
ic->ic_scan_mindwell = iwn_scan_mindwell; | ic->ic_scan_mindwell = iwn_scan_mindwell; | ||||
ic->ic_getradiocaps = iwn_getradiocaps; | ic->ic_getradiocaps = iwn_getradiocaps; | ||||
ic->ic_setregdomain = iwn_setregdomain; | ic->ic_setregdomain = iwn_setregdomain; | ||||
iwn_radiotap_attach(sc); | iwn_radiotap_attach(sc); | ||||
callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0); | callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0); | ||||
callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0); | callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0); | ||||
TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc); | |||||
TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc); | TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc); | ||||
TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc); | TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc); | ||||
TASK_INIT(&sc->sc_panic_task, 0, iwn_panicked, sc); | TASK_INIT(&sc->sc_panic_task, 0, iwn_panicked, sc); | ||||
TASK_INIT(&sc->sc_xmit_task, 0, iwn_xmit_task, sc); | TASK_INIT(&sc->sc_xmit_task, 0, iwn_xmit_task, sc); | ||||
mbufq_init(&sc->sc_xmit_queue, 1024); | mbufq_init(&sc->sc_xmit_queue, 1024); | ||||
sc->sc_tq = taskqueue_create("iwn_taskq", M_WAITOK, | |||||
taskqueue_thread_enqueue, &sc->sc_tq); | |||||
error = taskqueue_start_threads(&sc->sc_tq, 1, 0, "iwn_taskq"); | |||||
if (error != 0) { | |||||
device_printf(dev, "can't start threads, error %d\n", error); | |||||
goto fail; | |||||
} | |||||
iwn_sysctlattach(sc); | iwn_sysctlattach(sc); | ||||
/* | /* | ||||
* Hook our interrupt after all initialization is complete. | * Hook our interrupt after all initialization is complete. | ||||
*/ | */ | ||||
error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, | error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, | ||||
NULL, iwn_intr, sc, &sc->sc_ih); | NULL, iwn_intr, sc, &sc->sc_ih); | ||||
if (error != 0) { | if (error != 0) { | ||||
▲ Show 20 Lines • Show All 681 Lines • ▼ Show 20 Lines | iwn_xmit_queue_enqueue(struct iwn_softc *sc, struct mbuf *m) | ||||
IWN_LOCK_ASSERT(sc); | IWN_LOCK_ASSERT(sc); | ||||
return (mbufq_enqueue(&sc->sc_xmit_queue, m)); | return (mbufq_enqueue(&sc->sc_xmit_queue, m)); | ||||
} | } | ||||
static int | static int | ||||
iwn_detach(device_t dev) | iwn_detach(device_t dev) | ||||
{ | { | ||||
struct iwn_softc *sc = device_get_softc(dev); | struct iwn_softc *sc = device_get_softc(dev); | ||||
struct ieee80211com *ic = &sc->sc_ic; | |||||
int qid; | int qid; | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); | ||||
if (sc->sc_ic.ic_softc != NULL) { | if (ic->ic_softc != NULL) { | ||||
/* Free the mbuf queue and node references */ | /* Free the mbuf queue and node references */ | ||||
IWN_LOCK(sc); | IWN_LOCK(sc); | ||||
iwn_xmit_queue_drain(sc); | iwn_xmit_queue_drain(sc); | ||||
IWN_UNLOCK(sc); | IWN_UNLOCK(sc); | ||||
ieee80211_draintask(&sc->sc_ic, &sc->sc_reinit_task); | ieee80211_draintask(ic, &sc->sc_radioon_task); | ||||
ieee80211_draintask(&sc->sc_ic, &sc->sc_radioon_task); | ieee80211_draintask(ic, &sc->sc_radiooff_task); | ||||
ieee80211_draintask(&sc->sc_ic, &sc->sc_radiooff_task); | ieee80211_draintask(ic, &sc->sc_xmit_task); | ||||
iwn_stop(sc); | iwn_stop(sc); | ||||
taskqueue_drain_all(sc->sc_tq); | taskqueue_drain(taskqueue_thread, &sc->sc_panic_task); | ||||
taskqueue_free(sc->sc_tq); | |||||
callout_drain(&sc->watchdog_to); | callout_drain(&sc->watchdog_to); | ||||
callout_drain(&sc->calib_to); | callout_drain(&sc->calib_to); | ||||
ieee80211_ifdetach(&sc->sc_ic); | ieee80211_ifdetach(ic); | ||||
} | } | ||||
/* Uninstall interrupt handler. */ | /* Uninstall interrupt handler. */ | ||||
if (sc->irq != NULL) { | if (sc->irq != NULL) { | ||||
bus_teardown_intr(dev, sc->irq, sc->sc_ih); | bus_teardown_intr(dev, sc->irq, sc->sc_ih); | ||||
bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq), | bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq), | ||||
sc->irq); | sc->irq); | ||||
pci_release_msi(dev); | pci_release_msi(dev); | ||||
▲ Show 20 Lines • Show All 1,722 Lines • ▼ Show 20 Lines | if (sc->sc_beacon_wait) { | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, | DPRINTF(sc, IWN_DEBUG_TRACE, | ||||
"%s: beacon_wait, type=%d, subtype=%d\n", | "%s: beacon_wait, type=%d, subtype=%d\n", | ||||
__func__, type, subtype); | __func__, type, subtype); | ||||
if (type == IEEE80211_FC0_TYPE_MGT && | if (type == IEEE80211_FC0_TYPE_MGT && | ||||
subtype == IEEE80211_FC0_SUBTYPE_BEACON) { | subtype == IEEE80211_FC0_SUBTYPE_BEACON) { | ||||
DPRINTF(sc, IWN_DEBUG_TRACE | IWN_DEBUG_XMIT, | DPRINTF(sc, IWN_DEBUG_TRACE | IWN_DEBUG_XMIT, | ||||
"%s: waking things up\n", __func__); | "%s: waking things up\n", __func__); | ||||
/* queue taskqueue to transmit! */ | /* queue taskqueue to transmit! */ | ||||
taskqueue_enqueue(sc->sc_tq, &sc->sc_xmit_task); | ieee80211_runtask(ic, &sc->sc_xmit_task); | ||||
} | } | ||||
} | } | ||||
IWN_UNLOCK(sc); | IWN_UNLOCK(sc); | ||||
/* Send the frame to the 802.11 layer. */ | /* Send the frame to the 802.11 layer. */ | ||||
if (ni != NULL) { | if (ni != NULL) { | ||||
if (ni->ni_flags & IEEE80211_NODE_HT) | if (ni->ni_flags & IEEE80211_NODE_HT) | ||||
▲ Show 20 Lines • Show All 987 Lines • ▼ Show 20 Lines | if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) { | ||||
device_printf(sc->sc_dev, "%s: fatal firmware error\n", | device_printf(sc->sc_dev, "%s: fatal firmware error\n", | ||||
__func__); | __func__); | ||||
#ifdef IWN_DEBUG | #ifdef IWN_DEBUG | ||||
iwn_debug_register(sc); | iwn_debug_register(sc); | ||||
#endif | #endif | ||||
/* Dump firmware error log and stop. */ | /* Dump firmware error log and stop. */ | ||||
iwn_fatal_intr(sc); | iwn_fatal_intr(sc); | ||||
taskqueue_enqueue(sc->sc_tq, &sc->sc_panic_task); | taskqueue_enqueue(taskqueue_thread, &sc->sc_panic_task); | ||||
goto done; | goto done; | ||||
} | } | ||||
if ((r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX | IWN_INT_RX_PERIODIC)) || | if ((r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX | IWN_INT_RX_PERIODIC)) || | ||||
(r2 & IWN_FH_INT_RX)) { | (r2 & IWN_FH_INT_RX)) { | ||||
if (sc->sc_flags & IWN_FLAG_USE_ICT) { | if (sc->sc_flags & IWN_FLAG_USE_ICT) { | ||||
if (r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX)) | if (r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX)) | ||||
IWN_WRITE(sc, IWN_FH_INT, IWN_FH_INT_RX); | IWN_WRITE(sc, IWN_FH_INT, IWN_FH_INT_RX); | ||||
IWN_WRITE_1(sc, IWN_INT_PERIODIC, | IWN_WRITE_1(sc, IWN_INT_PERIODIC, | ||||
▲ Show 20 Lines • Show All 831 Lines • ▼ Show 20 Lines | iwn_watchdog(void *arg) | ||||
KASSERT(sc->sc_flags & IWN_FLAG_RUNNING, ("not running")); | KASSERT(sc->sc_flags & IWN_FLAG_RUNNING, ("not running")); | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | ||||
if (sc->sc_tx_timer > 0) { | if (sc->sc_tx_timer > 0) { | ||||
if (--sc->sc_tx_timer == 0) { | if (--sc->sc_tx_timer == 0) { | ||||
ic_printf(ic, "device timeout\n"); | ic_printf(ic, "device timeout\n"); | ||||
ieee80211_runtask(ic, &sc->sc_reinit_task); | ieee80211_restart_all(ic); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc); | callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc); | ||||
} | } | ||||
static int | static int | ||||
iwn_cdev_open(struct cdev *dev, int flags, int type, struct thread *td) | iwn_cdev_open(struct cdev *dev, int flags, int type, struct thread *td) | ||||
▲ Show 20 Lines • Show All 3,904 Lines • ▼ Show 20 Lines | |||||
* Callback from net80211 to handle the minimum dwell time being met. | * Callback from net80211 to handle the minimum dwell time being met. | ||||
* The intent is to terminate the scan but we just let the firmware | * The intent is to terminate the scan but we just let the firmware | ||||
* notify us when it's finished as we have no safe way to abort it. | * notify us when it's finished as we have no safe way to abort it. | ||||
*/ | */ | ||||
static void | static void | ||||
iwn_scan_mindwell(struct ieee80211_scan_state *ss) | iwn_scan_mindwell(struct ieee80211_scan_state *ss) | ||||
{ | { | ||||
/* NB: don't try to abort scan; wait for firmware to finish */ | /* NB: don't try to abort scan; wait for firmware to finish */ | ||||
} | |||||
static void | |||||
iwn_hw_reset(void *arg0, int pending) | |||||
{ | |||||
struct iwn_softc *sc = arg0; | |||||
struct ieee80211com *ic = &sc->sc_ic; | |||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | |||||
iwn_stop(sc); | |||||
iwn_init(sc); | |||||
ieee80211_notify_radio(ic, 1); | |||||
} | } | ||||
#ifdef IWN_DEBUG | #ifdef IWN_DEBUG | ||||
#define IWN_DESC(x) case x: return #x | #define IWN_DESC(x) case x: return #x | ||||
/* | /* | ||||
* Translate CSR code to string | * Translate CSR code to string | ||||
*/ | */ | ||||
static char *iwn_get_csr_string(int csr) | static char *iwn_get_csr_string(int csr) | ||||
▲ Show 20 Lines • Show All 76 Lines • Show Last 20 Lines |