Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Mar 2008 16:51:37 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 138107 for review
Message-ID:  <200803191651.m2JGpbkl036391@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=138107

Change 138107 by sam@sam_ebb on 2008/03/19 16:51:21

	Force the scanvalid parametr to 1.5 x the bg scan interval
	if the device is marked as doing bg scanning; this ensures
	our scan requests that check the scan cache will (almost)
	always find valid results to check before initiating a fg scan.
	Not sure if this belongs here or if the kernel should do this.
	We also don't handle user changing of scan parameters while
	we're running; we assume if someone is going to futz they
	understand what they're doing.

Affected files ...

.. //depot/projects/vap/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c#7 edit

Differences ...

==== //depot/projects/vap/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c#7 (text+ko) ====

@@ -43,8 +43,11 @@
 	int	prev_roaming;		/* roaming state to restore on deinit */
 	int	prev_privacy;		/* privacy state to restore on deinit */
 	int	prev_wpa;		/* wpa state to restore on deinit */
+	int	prev_scanvalid;		/* scan valid to restore on deinit */
 	uint8_t	lastssid[IEEE80211_NWID_LEN];
 	int	lastssid_len;
+	uint32_t drivercaps;		/* general driver capabilities */
+	uint32_t cryptocaps;		/* hardware crypto support */
 };
 
 static int
@@ -739,12 +742,33 @@
 #undef min
 }
 
+#define	GETPARAM(drv, param, v) \
+	(((v) = get80211param(drv, param)) != -1)
+#define	IEEE80211_C_BGSCAN	0x20000000
+
+/*
+ * Set the scan cache valid threshold to 1.5 x bg scan interval
+ * to force all scan requests to consult the cache unless they
+ * explicitly bypass it.
+ */
+static int
+setscanvalid(struct wpa_driver_bsd_data *drv)
+{
+	int bgscan, scanvalid;
+
+	if (!GETPARAM(drv, IEEE80211_IOC_SCANVALID, drv->prev_scanvalid) ||
+	    !GETPARAM(drv, IEEE80211_IOC_BGSCAN_INTERVAL, bgscan))
+		return -1;
+	scanvalid = 3*bgscan/2;
+	return (drv->prev_scanvalid < scanvalid) ?
+	    set80211param(drv, IEEE80211_IOC_SCANVALID, scanvalid) : 0;
+}
+
 static void *
 wpa_driver_bsd_init(void *ctx, const char *ifname)
 {
-#define	GETPARAM(drv, param, v) \
-	(((v) = get80211param(drv, param)) != -1)
 	struct wpa_driver_bsd_data *drv;
+	struct ieee80211_devcaps_req devcaps;
 	int flags;
 
 	drv = malloc(sizeof(*drv));
@@ -783,6 +807,15 @@
 	eloop_register_read_sock(drv->route,
 		wpa_driver_bsd_event_receive, ctx, drv);
 
+	if (get80211var(drv, IEEE80211_IOC_DEVCAPS, &devcaps, sizeof(devcaps)) < 0) {
+		wpa_printf(MSG_DEBUG,
+		    "%s: failed to get device capabilities: %s",
+		    __func__, strerror(errno));
+		goto fail;
+	}
+	drv->drivercaps = devcaps.dc_drivercaps;
+	drv->cryptocaps = devcaps.dc_cryptocaps;
+
 	if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
 		wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s",
 			__func__, strerror(errno));
@@ -803,7 +836,18 @@
 			   "roaming: %s", __func__, strerror(errno));
 		goto fail;
 	}
-
+	if (drv->drivercaps & IEEE80211_C_BGSCAN) {
+		/*
+		 * Driver does background scanning; force the scan valid
+		 * setting to 1.5 x bg scan interval so the scan cache is
+		 * always consulted before we force a foreground scan.
+		 */ 
+		if (setscanvalid(drv) < 0) {
+			wpa_printf(MSG_DEBUG,
+			    "%s: warning, failed to set scanvalid, scanning "
+			    "may be suboptimal: %s", __func__, strerror(errno));
+		}
+	}
 	if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) {
 		wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s",
 			   __func__, strerror(errno));
@@ -816,8 +860,8 @@
 fail1:
 	free(drv);
 	return NULL;
+}
 #undef GETPARAM
-}
 
 static void
 wpa_driver_bsd_deinit(void *priv)
@@ -830,9 +874,17 @@
 		(void) setifflags(drv, flags &~ IFF_UP);
 
 	wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);
-	if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0)
-		wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",
-			__func__);
+	if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) {
+		/* NB: don't whinge if device ejected or equivalent */
+		if (errno != ENXIO)
+			wpa_printf(MSG_DEBUG, "%s: failed to restore roaming "
+			    "state", __func__);
+	}
+	if (drv->drivercaps & IEEE80211_C_BGSCAN) {
+		/* XXX check return value */
+		(void) set80211param(drv, IEEE80211_IOC_SCANVALID,
+		    drv->prev_scanvalid);
+	}
 
 	(void) close(drv->route);		/* ioctl socket */
 	(void) close(drv->sock);		/* event socket */



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