PERFORCE change 42105 for review

Sam Leffler sam at FreeBSD.org
Tue Nov 11 21:51:36 PST 2003


http://perforce.freebsd.org/chv.cgi?CH=42105

Change 42105 by sam at sam_ebb on 2003/11/11 21:50:53

	Deal with a scan request prior to an interface being marked
	up.  This may happen, for example, if someone isn't running
	devd, inserts a card, and then runs wicontrol -i ath0 -L
	(the wi driver handels this directly so is not impacted).
	In this case the scan request happens before ic_bss->ni_chan
	has been set to a valid value so the driver blows up. Always
	validate state prior to initiating a scan and, for now, disallow
	a scan if the device isn't marked IFF_UP.  In the future it
	would be good to support this so that users can scan for AP's
	before marking an interface up.

Affected files ...

.. //depot/projects/netperf/sys/net80211/ieee80211_ioctl.c#7 edit

Differences ...

==== //depot/projects/netperf/sys/net80211/ieee80211_ioctl.c#7 (text+ko) ====

@@ -376,6 +376,43 @@
 #undef IEEERATE
 }
 
+/*
+ * Prepare to do a user-initiated scan for AP's.  If no
+ * current/default channel is setup or the current channel
+ * is invalid then pick the first available channel from
+ * the active list as the place to start the scan.
+ */
+static int
+ieee80211_setupscan(struct ieee80211com *ic)
+{
+	u_char *chanlist = ic->ic_chan_active;
+	int i;
+
+	if (ic->ic_ibss_chan == NULL ||
+	    isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) {
+		for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
+			if (isset(chanlist, i)) {
+				ic->ic_ibss_chan = &ic->ic_channels[i];
+				goto found;
+			}
+		return EINVAL;			/* no active channels */
+found:
+		;
+	}
+	if (ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC ||
+	    isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan)))
+		ic->ic_bss->ni_chan = ic->ic_ibss_chan;
+	/*
+	 * XXX don't permit a scan to be started unless we
+	 * know the device is ready.  For the moment this means
+	 * the device is marked up as this is the required to
+	 * initialize the hardware.  It would be better to permit
+	 * scanning prior to being up but that'll require some
+	 * changes to the infrastructure.
+	 */
+	return (ic->ic_if.if_flags & IFF_UP) ? 0 : ENETRESET;
+}
+
 int
 ieee80211_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
@@ -659,8 +696,9 @@
 	case WI_RID_SCAN_REQ:			/* XXX wicontrol */
 		if (ic->ic_opmode == IEEE80211_M_HOSTAP)
 			break;
-		/* NB: ignore channel list and tx rate parameters */
-		error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+		error = ieee80211_setupscan(ic);
+		if (error == 0)
+			error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
 		break;
 	case WI_RID_SCAN_APS:
 		if (ic->ic_opmode == IEEE80211_M_HOSTAP)
@@ -692,18 +730,11 @@
 		}
 		memcpy(ic->ic_chan_active, chanlist,
 		    sizeof(ic->ic_chan_active));
-		if (isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) {
-			for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
-				if (isset(chanlist, i)) {
-					ic->ic_ibss_chan = &ic->ic_channels[i];
-					break;
-				}
-		}
-		if (isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan)))
-			ic->ic_bss->ni_chan = ic->ic_ibss_chan;
-		if (wreq.wi_type == WI_RID_CHANNEL_LIST)
+		error = ieee80211_setupscan(ic);
+		if (wreq.wi_type == WI_RID_CHANNEL_LIST) {
+			/* NB: ignore error from ieee80211_setupscan */
 			error = ENETRESET;
-		else
+		} else if (error == 0)
 			error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
 		break;
 	default:


More information about the p4-projects mailing list