[iwm] Use iwm_mvm_scan_stop_wait to properly abort scans.
* Add IWM_FLAG_SCAN_RUNNING to sc->sc_flags to track whether the firmware is currently running a scan, in order to decide wheter iwm_scan_end needs to abort a running scan. * In iwm_scan_end, if the scan is still running, we now abort it, in order to keep the firmware scanning state in sync. * Try to make things a bit simpler, by reacting on the IWM_SCAN_OFFLOAD_COMPLETE and IWM_SCAN_COMPLETE_UMAC notifications, instead of IWM_SCAN_ITERATION_COMPLETE and IWM_SCAN_ITERATION_COMPLETE_UMAC. This should be fine since we always only tell the firmware to do a single scan iteration anyway. Obtained from: DragonflyBSD commit 1f249c981c4e89e7cde1836a75b61cac36dc7ac5
This commit is contained in:
parent
28260db250
commit
0fae13e67a
@ -4951,6 +4951,7 @@ iwm_stop(struct iwm_softc *sc)
|
||||
iwm_led_blink_stop(sc);
|
||||
sc->sc_tx_timer = 0;
|
||||
iwm_stop_device(sc);
|
||||
sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -5475,6 +5476,10 @@ iwm_notif_intr(struct iwm_softc *sc)
|
||||
case IWM_SCAN_OFFLOAD_COMPLETE: {
|
||||
struct iwm_periodic_scan_complete *notif;
|
||||
notif = (void *)pkt->data;
|
||||
if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) {
|
||||
sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING;
|
||||
ieee80211_runtask(ic, &sc->sc_es_task);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5492,9 +5497,10 @@ iwm_notif_intr(struct iwm_softc *sc)
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"UMAC scan complete, status=0x%x\n",
|
||||
notif->status);
|
||||
#if 0 /* XXX This would be a duplicate scan end call */
|
||||
taskqueue_enqueue(sc->sc_tq, &sc->sc_es_task);
|
||||
#endif
|
||||
if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) {
|
||||
sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING;
|
||||
ieee80211_runtask(ic, &sc->sc_es_task);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -6254,15 +6260,21 @@ iwm_scan_start(struct ieee80211com *ic)
|
||||
int error;
|
||||
|
||||
IWM_LOCK(sc);
|
||||
if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) {
|
||||
/* This should not be possible */
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: Previous scan not completed yet\n", __func__);
|
||||
}
|
||||
if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
|
||||
error = iwm_mvm_umac_scan(sc);
|
||||
else
|
||||
error = iwm_mvm_lmac_scan(sc);
|
||||
if (error != 0) {
|
||||
device_printf(sc->sc_dev, "could not initiate 2 GHz scan\n");
|
||||
device_printf(sc->sc_dev, "could not initiate scan\n");
|
||||
IWM_UNLOCK(sc);
|
||||
ieee80211_cancel_scan(vap);
|
||||
} else {
|
||||
sc->sc_flags |= IWM_FLAG_SCAN_RUNNING;
|
||||
iwm_led_blink_start(sc);
|
||||
IWM_UNLOCK(sc);
|
||||
}
|
||||
@ -6278,7 +6290,23 @@ iwm_scan_end(struct ieee80211com *ic)
|
||||
iwm_led_blink_stop(sc);
|
||||
if (vap->iv_state == IEEE80211_S_RUN)
|
||||
iwm_mvm_led_enable(sc);
|
||||
if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) {
|
||||
/*
|
||||
* Removing IWM_FLAG_SCAN_RUNNING now, is fine because
|
||||
* both iwm_scan_end and iwm_scan_start run in the ic->ic_tq
|
||||
* taskqueue.
|
||||
*/
|
||||
sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING;
|
||||
iwm_mvm_scan_stop_wait(sc);
|
||||
}
|
||||
IWM_UNLOCK(sc);
|
||||
|
||||
/*
|
||||
* Make sure we don't race, if sc_es_task is still enqueued here.
|
||||
* This is to make sure that it won't call ieee80211_scan_done
|
||||
* when we have already started the next scan.
|
||||
*/
|
||||
taskqueue_cancel(ic->ic_tq, &sc->sc_es_task, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -415,6 +415,7 @@ struct iwm_softc {
|
||||
#define IWM_FLAG_RFKILL (1 << 3)
|
||||
#define IWM_FLAG_BUSY (1 << 4)
|
||||
#define IWM_FLAG_SCANNING (1 << 5)
|
||||
#define IWM_FLAG_SCAN_RUNNING (1 << 6)
|
||||
|
||||
struct intr_config_hook sc_preinit_hook;
|
||||
struct callout sc_watchdog_to;
|
||||
|
Loading…
Reference in New Issue
Block a user