Date: Fri, 2 Dec 2005 22:36:03 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 87660 for review Message-ID: <200512022236.jB2Ma3sw090019@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=87660 Change 87660 by sam@sam_ebb on 2005/12/02 22:35:47 cleanups for setting channel: o when checking for an 11g channel upgrade search the entire table instead of assuming b channels are sorted before g o set ic_curchan for monitor+wds modes since the INIT -> RUN transition starts operation on that channel and not the desired channel (which may not be set) o break out channel set code; it's large enough now Affected files ... .. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#55 edit Differences ... ==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#55 (text+ko) ==== @@ -1350,10 +1350,19 @@ } static int -find11gchannel(struct ieee80211com *ic, int i, int freq) +find11gchannel(struct ieee80211com *ic, int start, int freq) { - for (; i < ic->ic_nchans; i++) { - const struct ieee80211_channel *c = &ic->ic_channels[i]; + const struct ieee80211_channel *c; + int i; + + for (i = start+1; i < ic->ic_nchans; i++) { + c = &ic->ic_channels[i]; + if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) + return 1; + } + /* NB: should not be needed but in case things are mis-sorted */ + for (i = 0; i < start; i++) { + c = &ic->ic_channels[i]; if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) return 1; } @@ -1391,7 +1400,7 @@ * are present. */ if (!IEEE80211_IS_CHAN_B(c) || - !find11gchannel(ic, i+1, c->ic_freq)) + !find11gchannel(ic, i, c->ic_freq)) return c; } else { if ((c->ic_flags & modeflags) == modeflags) @@ -1413,16 +1422,94 @@ return (IEEE80211_IS_CHAN_ANYG(c)); case IEEE80211_MODE_11A: return (IEEE80211_IS_CHAN_A(c)); -#ifdef IEEE80211_MODE_TURBO_STATIC_A - case IEEE80211_MODE_TURBO_STATIC_A: - return (IEEE80211_IS_CHAN_A(c) && IEEE80211_IS_CHAN_STURBO(c)); -#endif + case IEEE80211_MODE_STURBO_A: + return (IEEE80211_IS_CHAN_STURBO(c)); } return 1; } static int +ieee80211_ioctl_setchannel(struct ieee80211com *ic, + const struct ieee80211req *ireq) +{ + int error; + + /* XXX 0xffff overflows 16-bit signed */ + if (ireq->i_val == 0 || + ireq->i_val == (int16_t) IEEE80211_CHAN_ANY) { + ic->ic_des_chan = IEEE80211_CHAN_ANYC; + } else if ((u_int) ireq->i_val > IEEE80211_CHAN_MAX) { + return EINVAL; + } else { + struct ieee80211_channel *c, *c2; + + c = findchannel(ic, ireq->i_val, ic->ic_des_mode); + if (c == NULL) { + c = findchannel(ic, ireq->i_val, + IEEE80211_MODE_AUTO); + if (c == NULL) + return EINVAL; + } + /* + * Fine tune channel selection based on desired mode: + * if 11b is requested, find the 11b version of any + * 11g channel returned, + * if static turbo, find the turbo version of any + * 11a channel return, + * otherwise we should be ok with what we've got. + */ + switch (ic->ic_des_mode) { + case IEEE80211_MODE_11B: + if (IEEE80211_IS_CHAN_ANYG(c)) { + c2 = findchannel(ic, ireq->i_val, + IEEE80211_MODE_11B); + /* NB: should not happen, =>'s 11g w/o 11b */ + if (c2 != NULL) + c = c2; + } + break; + case IEEE80211_MODE_TURBO_A: + if (IEEE80211_IS_CHAN_A(c)) { + c2 = findchannel(ic, ireq->i_val, + IEEE80211_MODE_TURBO_A); + if (c2 != NULL) + c = c2; + } + break; + default: /* NB: no static turboG */ + break; + } + if (ic->ic_opmode == IEEE80211_M_HOSTAP && + !check_mode_consistency(c, ic->ic_des_mode)) + return EINVAL; + if (ic->ic_state == IEEE80211_S_RUN && c == ic->ic_bsschan) + return 0; /* NB: nothing to do */ + ic->ic_des_chan = c; + } + error = 0; + if ((ic->ic_opmode == IEEE80211_M_MONITOR || + ic->ic_opmode == IEEE80211_M_WDS) && + ic->ic_des_chan != IEEE80211_CHAN_ANYC) { + /* + * Monitor and wds modes can switch directly. + */ + ic->ic_curchan = ic->ic_des_chan; + if (ic->ic_state == IEEE80211_S_RUN) + ic->ic_set_channel(ic); + } else { + /* + * Need to go through the state machine in case we + * need to reassociate or the like. The state machine + * will pickup the desired channel and avoid scanning. + */ + if (IS_UP_AUTO(ic)) + error = ieee80211_init(ic, RESCAN); + } + return error; +} + +static int ieee80211_ioctl_set80211(struct ieee80211com *ic, u_long cmd, struct ieee80211req *ireq) { static const u_int8_t zerobssid[IEEE80211_ADDR_LEN]; @@ -1547,78 +1634,7 @@ error = ieee80211_init(ic, RESCAN); break; case IEEE80211_IOC_CHANNEL: - /* XXX 0xffff overflows 16-bit signed */ - if (ireq->i_val == 0 || - ireq->i_val == (int16_t) IEEE80211_CHAN_ANY) { - ic->ic_des_chan = IEEE80211_CHAN_ANYC; - } else if ((u_int) ireq->i_val > IEEE80211_CHAN_MAX) { - return EINVAL; - } else { - struct ieee80211_channel *c, *c2; - - c = findchannel(ic, ireq->i_val, ic->ic_des_mode); - if (c == NULL) { - c = findchannel(ic, ireq->i_val, - IEEE80211_MODE_AUTO); - if (c == NULL) - return EINVAL; - } - /* - * Fine tune channel selection based on desired mode: - * if 11b is requested, find the 11b version of any - * 11g channel returned, - * if static turbo, find the turbo version of any - * 11a channel return, - * otherwise we should be ok with what we've got. - */ - switch (ic->ic_des_mode) { - case IEEE80211_MODE_11B: - if (IEEE80211_IS_CHAN_ANYG(c)) { - c2 = findchannel(ic, ireq->i_val, - IEEE80211_MODE_11B); - /* NB: should not happen, =>'s 11g w/o 11b */ - if (c2 != NULL) - c = c2; - } - break; - case IEEE80211_MODE_TURBO_A: - if (IEEE80211_IS_CHAN_A(c)) { - c2 = findchannel(ic, ireq->i_val, - IEEE80211_MODE_TURBO_A); - if (c2 != NULL) - c = c2; - } - break; - default: /* NB: no static turboG */ - break; - } - if (ic->ic_opmode == IEEE80211_M_HOSTAP && - !check_mode_consistency(c, ic->ic_des_mode)) - return EINVAL; - if (ic->ic_state == IEEE80211_S_RUN && - c == ic->ic_bsschan) - break; - ic->ic_des_chan = c; - } - if ((ic->ic_opmode == IEEE80211_M_MONITOR || - ic->ic_opmode == IEEE80211_M_WDS) && - ic->ic_des_chan != IEEE80211_CHAN_ANYC) { - /* - * Monitor and wds modes can switch directly. - */ - if (ic->ic_state == IEEE80211_S_RUN) { - ic->ic_curchan = ic->ic_des_chan; - ic->ic_set_channel(ic); - } - } else { - /* - * Need to go through the state machine in case we - * need to reassociate or the like. The state machine - * will pickup the desired channel and avoid scanning. - */ - if (IS_UP_AUTO(ic)) - error = ieee80211_init(ic, RESCAN); - } + error = ieee80211_ioctl_setchannel(ic, ireq); break; case IEEE80211_IOC_POWERSAVE: switch (ireq->i_val) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200512022236.jB2Ma3sw090019>