Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Oct 2010 16:52:13 +0000 (UTC)
From:      Bernhard Schmidt <bschmidt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r213729 - head/sys/dev/iwi
Message-ID:  <201010121652.o9CGqDWd054006@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bschmidt
Date: Tue Oct 12 16:52:13 2010
New Revision: 213729
URL: http://svn.freebsd.org/changeset/base/213729

Log:
  Fix monitor mode which is implemented by doing a firmware scan. This
  is a port of stable/6, seems like the code got lost during the
  background scan changes in r170530.
  
  Pointed out by:	danfe
  MFC after:	2 weeks

Modified:
  head/sys/dev/iwi/if_iwi.c
  head/sys/dev/iwi/if_iwivar.h

Modified: head/sys/dev/iwi/if_iwi.c
==============================================================================
--- head/sys/dev/iwi/if_iwi.c	Tue Oct 12 16:23:50 2010	(r213728)
+++ head/sys/dev/iwi/if_iwi.c	Tue Oct 12 16:52:13 2010	(r213729)
@@ -180,6 +180,7 @@ static void	iwi_release_fw_dma(struct iw
 static int	iwi_config(struct iwi_softc *);
 static int	iwi_get_firmware(struct iwi_softc *, enum ieee80211_opmode);
 static void	iwi_put_firmware(struct iwi_softc *);
+static void	iwi_monitor_scan(void *, int);
 static int	iwi_scanchan(struct iwi_softc *, unsigned long, int);
 static void	iwi_scan_start(struct ieee80211com *);
 static void	iwi_scan_end(struct ieee80211com *);
@@ -292,6 +293,7 @@ iwi_attach(device_t dev)
 	TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc);
 	TASK_INIT(&sc->sc_disassoctask, 0, iwi_disassoc, sc);
 	TASK_INIT(&sc->sc_wmetask, 0, iwi_update_wme, sc);
+	TASK_INIT(&sc->sc_monitortask, 0, iwi_monitor_scan, sc);
 
 	callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0);
 	callout_init_mtx(&sc->sc_rftimer, &sc->sc_mtx, 0);
@@ -460,6 +462,7 @@ iwi_detach(device_t dev)
 	ieee80211_draintask(ic, &sc->sc_radiofftask);
 	ieee80211_draintask(ic, &sc->sc_restarttask);
 	ieee80211_draintask(ic, &sc->sc_disassoctask);
+	ieee80211_draintask(ic, &sc->sc_monitortask);
 
 	iwi_stop(sc);
 
@@ -988,7 +991,8 @@ iwi_newstate(struct ieee80211vap *vap, e
 			 * This is all totally bogus and needs to be redone.
 			 */
 			iwi_auth_and_assoc(sc, vap);
-		}
+		} else if (vap->iv_opmode == IEEE80211_M_MONITOR)
+			ieee80211_runtask(ic, &sc->sc_monitortask);
 		break;
 	case IEEE80211_S_ASSOC:
 		/*
@@ -1407,6 +1411,18 @@ iwi_notification_intr(struct iwi_softc *
 
 		IWI_STATE_END(sc, IWI_FW_SCANNING);
 
+		/*
+		 * Monitor mode works by doing a passive scan to set
+		 * the channel and enable rx.  Because we don't want
+		 * to abort a scan lest the firmware crash we scan
+		 * for a short period of time and automatically restart
+		 * the scan when notified the sweep has completed.
+		 */
+		if (vap->iv_opmode == IEEE80211_M_MONITOR) {
+			ieee80211_runtask(ic, &sc->sc_monitortask);
+			break;
+		}
+
 		if (scan->status == IWI_SCAN_COMPLETED) {
 			/* NB: don't need to defer, net80211 does it for us */
 			ieee80211_scan_next(vap);
@@ -2557,6 +2573,11 @@ iwi_config(struct iwi_softc *sc)
 	config.answer_pbreq = (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 : 0;
 	config.disable_unicast_decryption = 1;
 	config.disable_multicast_decryption = 1;
+	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+		config.allow_invalid_frames = 1;
+		config.allow_beacon_and_probe_resp = 1;
+		config.allow_mgt = 1;
+	}
 	DPRINTF(("Configuring adapter\n"));
 	error = iwi_cmd(sc, IWI_CMD_SET_CONFIG, &config, sizeof config);
 	if (error != 0)
@@ -2642,6 +2663,17 @@ scan_band(const struct ieee80211_channel
 	return IEEE80211_IS_CHAN_5GHZ(c) ?  IWI_CHAN_5GHZ : IWI_CHAN_2GHZ;
 }
 
+static void
+iwi_monitor_scan(void *arg, int npending)
+{
+	struct iwi_softc *sc = arg;
+	IWI_LOCK_DECL;
+
+	IWI_LOCK(sc);
+	(void) iwi_scanchan(sc, 2000, 0);
+	IWI_UNLOCK(sc);
+}
+
 /*
  * Start a scan on the current channel or all channels.
  */

Modified: head/sys/dev/iwi/if_iwivar.h
==============================================================================
--- head/sys/dev/iwi/if_iwivar.h	Tue Oct 12 16:23:50 2010	(r213728)
+++ head/sys/dev/iwi/if_iwivar.h	Tue Oct 12 16:52:13 2010	(r213729)
@@ -193,6 +193,7 @@ struct iwi_softc {
 	struct task		sc_restarttask;	/* restart adapter processing */
 	struct task		sc_disassoctask;
 	struct task		sc_wmetask;	/* set wme parameters */
+	struct task		sc_monitortask;
 
 	unsigned int		sc_softled : 1,	/* enable LED gpio status */
 				sc_ledstate: 1,	/* LED on/off state */



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