PERFORCE change 87660 for review
Sam Leffler
sam at FreeBSD.org
Fri Dec 2 22:36:05 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=87660
Change 87660 by sam at 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) {
More information about the p4-projects
mailing list