Date: Sun, 27 Nov 2005 00:17:40 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 87291 for review Message-ID: <200511270017.jAR0Hee5023850@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=87291 Change 87291 by sam@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200511270017.jAR0Hee5023850>