Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Mar 2018 05:52:27 +0000 (UTC)
From:      Eitan Adler <eadler@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r330174 - stable/11/sys/dev/iwm
Message-ID:  <201803010552.w215qRx2036665@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: eadler
Date: Thu Mar  1 05:52:27 2018
New Revision: 330174
URL: https://svnweb.freebsd.org/changeset/base/330174

Log:
  MFC r313414:
  
  [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.

Modified:
  stable/11/sys/dev/iwm/if_iwm.c
  stable/11/sys/dev/iwm/if_iwmvar.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/iwm/if_iwm.c
==============================================================================
--- stable/11/sys/dev/iwm/if_iwm.c	Thu Mar  1 05:51:35 2018	(r330173)
+++ stable/11/sys/dev/iwm/if_iwm.c	Thu Mar  1 05:52:27 2018	(r330174)
@@ -4925,6 +4925,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
@@ -5449,6 +5450,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;
 		}
 
@@ -5466,9 +5471,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;
 		}
 
@@ -6229,15 +6235,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);
 	}
@@ -6253,7 +6265,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

Modified: stable/11/sys/dev/iwm/if_iwmvar.h
==============================================================================
--- stable/11/sys/dev/iwm/if_iwmvar.h	Thu Mar  1 05:51:35 2018	(r330173)
+++ stable/11/sys/dev/iwm/if_iwmvar.h	Thu Mar  1 05:52:27 2018	(r330174)
@@ -414,6 +414,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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803010552.w215qRx2036665>