PERFORCE change 87291 for review
Sam Leffler
sam at FreeBSD.org
Sun Nov 27 00:17:48 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=87291
Change 87291 by sam at sam_ebb on 2005/11/27 00:17:11
Revamp ioctl handling a la linux: don't pass ENETRESET
back from ieee80211_ioctl except in cases where the device
must be re-initialized; instead handle state changes
internally. This eliminates most gratuitous scanning.
Affected files ...
.. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#52 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#39 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.h#25 edit
Differences ...
==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#52 (text+ko) ====
@@ -70,6 +70,7 @@
((_ic)->ic_ifp->if_drv_flags & IFF_DRV_RUNNING))
#define IS_UP_AUTO(_ic) \
(IS_UP(_ic) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
+#define RESCAN 1
static struct ieee80211_channel *findchannel(struct ieee80211com *,
int ieee, int mode);
@@ -1201,7 +1202,7 @@
isclr(chanlist, ic->ic_bsschan->ic_ieee))
ic->ic_bsschan = IEEE80211_CHAN_ANYC;
memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active));
- return IS_UP_AUTO(ic) ? ENETRESET : 0;
+ return IS_UP_AUTO(ic) ? ieee80211_init(ic, RESCAN) : 0;
}
static int
@@ -1412,7 +1413,8 @@
ic->ic_des_ssid[0].len = ireq->i_len;
memcpy(ic->ic_des_ssid[0].ssid, tmpssid, ireq->i_len);
ic->ic_des_nssid = (ireq->i_len > 0);
- error = ENETRESET;
+ if (IS_UP_AUTO(ic))
+ error = ieee80211_init(ic, RESCAN);
break;
case IEEE80211_IOC_WEP:
switch (ireq->i_val) {
@@ -1429,7 +1431,8 @@
ic->ic_flags &= ~IEEE80211_F_DROPUNENC;
break;
}
- error = ENETRESET;
+ if (IS_UP_AUTO(ic))
+ error = ieee80211_init(ic, RESCAN);
break;
case IEEE80211_IOC_WEPKEY:
kid = (u_int) ireq->i_val;
@@ -1458,8 +1461,6 @@
} else
error = EINVAL;
ieee80211_key_update_end(ic);
- if (!error) /* NB: for compatibility */
- error = ENETRESET;
break;
case IEEE80211_IOC_WEPTXKEY:
kid = (u_int) ireq->i_val;
@@ -1467,7 +1468,6 @@
(u_int16_t) kid != IEEE80211_KEYIX_NONE)
return EINVAL;
ic->ic_def_txkey = kid;
- error = ENETRESET; /* push to hardware */
break;
case IEEE80211_IOC_AUTHMODE:
switch (ireq->i_val) {
@@ -1507,7 +1507,8 @@
ic->ic_bss->ni_authmode = ireq->i_val;
/* XXX mixed/mode/usage? */
ic->ic_auth = auth;
- error = ENETRESET;
+ if (IS_UP_AUTO(ic))
+ error = ieee80211_init(ic, RESCAN);
break;
case IEEE80211_IOC_CHANNEL:
/* XXX 0xffff overflows 16-bit signed */
@@ -1580,18 +1581,7 @@
* will pickup the desired channel and avoid scanning.
*/
if (IS_UP_AUTO(ic))
- error = ENETRESET;
- }
- if (error == ENETRESET && ic->ic_opmode == IEEE80211_M_MONITOR) {
- if (IS_UP(ic)) {
- /*
- * Monitor mode can switch directly.
- */
- if (ic->ic_des_chan != IEEE80211_CHAN_ANYC)
- ic->ic_curchan = ic->ic_des_chan;
- error = ic->ic_reset(ic->ic_ifp);
- } else
- error = 0;
+ error = ieee80211_init(ic, RESCAN);
}
break;
case IEEE80211_IOC_POWERSAVE:
@@ -1702,7 +1692,7 @@
ic->ic_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
break;
}
- error = ENETRESET; /* XXX? */
+ error = ENETRESET;
break;
case IEEE80211_IOC_WME:
if (ireq->i_val) {
@@ -1711,7 +1701,8 @@
ic->ic_flags |= IEEE80211_F_WME;
} else
ic->ic_flags &= ~IEEE80211_F_WME;
- error = ENETRESET; /* XXX maybe not for station? */
+ if (IS_UP_AUTO(ic))
+ error = ieee80211_init(ic, 0);
break;
case IEEE80211_IOC_HIDESSID:
if (ireq->i_val)
@@ -1801,7 +1792,8 @@
ic->ic_flags &= ~IEEE80211_F_DESBSSID;
else
ic->ic_flags |= IEEE80211_F_DESBSSID;
- error = ENETRESET;
+ if (IS_UP_AUTO(ic))
+ error = ieee80211_init(ic, RESCAN);
break;
case IEEE80211_IOC_CHANLIST:
error = ieee80211_ioctl_setchanlist(ic, ireq);
@@ -1873,7 +1865,7 @@
ic->ic_flags |= IEEE80211_F_FF;
} else
ic->ic_flags &= ~IEEE80211_F_FF;
- error = ENETRESET; /* XXX maybe not for station? */
+ error = ENETRESET;
break;
case IEEE80211_IOC_TURBOP:
if (ireq->i_val) {
@@ -1882,7 +1874,7 @@
ic->ic_flags |= IEEE80211_F_TURBOP;
} else
ic->ic_flags &= ~IEEE80211_F_TURBOP;
- error = ENETRESET; /* XXX maybe not for station? */
+ error = ENETRESET;
break;
case IEEE80211_IOC_BGSCAN:
if (ireq->i_val) {
@@ -1942,8 +1934,8 @@
error = EINVAL;
break;
}
- if (error == ENETRESET && !IS_UP_AUTO(ic))
- error = 0;
+ if (error == ENETRESET)
+ error = IS_UP_AUTO(ic) ? ieee80211_init(ic, 0) : 0;
return error;
}
==== //depot/projects/wifi/sys/net80211/ieee80211_proto.c#39 (text+ko) ====
@@ -843,6 +843,56 @@
}
/*
+ * Start a device. If this is the first vap running on the
+ * underlying device then we first bring it up.
+ */
+int
+ieee80211_init(struct ieee80211com *ic, int forcescan)
+{
+ struct ifnet *ifp = ic->ic_ifp;
+
+ IEEE80211_DPRINTF(ic,
+ IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
+ "%s\n", "start running");
+
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ ifp->if_init(ifp);
+ /*
+ * Kick the 802.11 state machine as appropriate.
+ */
+ if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) {
+ if (ic->ic_opmode == IEEE80211_M_STA) {
+ /*
+ * Try to be intelligent about clocking the state
+ * machine. If we're currently in RUN state then
+ * we should be able to apply any new state/parameters
+ * simply by re-associating. Otherwise we need to
+ * re-scan to select an appropriate ap.
+ */
+ if (ic->ic_state != IEEE80211_S_RUN || forcescan)
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
+ else
+ ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1);
+ } else {
+ /*
+ * For monitor+wds modes there's nothing to do but
+ * start running. Otherwise, if this is the first
+ * vap to be brought up, start a scan which may be
+ * preempted if the station is locked to a particular
+ * channel.
+ */
+ if (ic->ic_opmode == IEEE80211_M_MONITOR ||
+ ic->ic_opmode == IEEE80211_M_WDS) {
+ ic->ic_state = IEEE80211_S_INIT; /* XXX*/
+ ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+ } else
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
+ }
+ }
+ return 0;
+}
+
+/*
* Switch between turbo and non-turbo operating modes.
* Use the specified channel flags to locate the new
* channel, update 802.11 state, and then call back into
==== //depot/projects/wifi/sys/net80211/ieee80211_proto.h#25 (text+ko) ====
@@ -217,6 +217,7 @@
#define ieee80211_new_state(_ic, _nstate, _arg) \
(((_ic)->ic_newstate)((_ic), (_nstate), (_arg)))
+int ieee80211_init(struct ieee80211com *, int forcescan);
void ieee80211_dturbo_switch(struct ieee80211com *, int newflags);
void ieee80211_beacon_miss(struct ieee80211com *);
void ieee80211_print_essid(const u_int8_t *, int);
More information about the p4-projects
mailing list