PERFORCE change 117716 for review
Sam Leffler
sam at FreeBSD.org
Mon Apr 9 04:16:04 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=117716
Change 117716 by sam at sam_ebb on 2007/04/09 04:15:50
use common code to set the current channel; also bring in
fix to set the current channel displayed by ifconfig et al
when interface is not up+running
Affected files ...
.. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#74 edit
Differences ...
==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#74 (text+ko) ====
@@ -1635,6 +1635,11 @@
return NULL;
}
+/*
+ * Check the specified against any desired mode (aka netband).
+ * This is only used (presently) when operating in hostap mode
+ * to enforce consistency.
+ */
static int
check_mode_consistency(const struct ieee80211_channel *c, int mode)
{
@@ -1654,20 +1659,69 @@
}
+/*
+ * Common code to set the current channel. If the device
+ * is up and running this may result in an immediate channel
+ * change or a kick of the state machine.
+ */
+static int
+setcurchan(struct ieee80211com *ic, struct ieee80211_channel *c)
+{
+ int error;
+
+ if (c != IEEE80211_CHAN_ANYC) {
+ 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);
+ else if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
+ /*
+ * When not up+running and a real channel has
+ * been specified fix the current channel so
+ * there is immediate feedback; e.g. via ifconfig.
+ */
+ ic->ic_curchan = ic->ic_des_chan;
+ }
+ }
+ return error;
+}
+
static int
ieee80211_ioctl_setchannel(struct ieee80211com *ic,
const struct ieee80211req *ireq)
{
- int error;
+ struct ieee80211_channel *c;
/* 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;
+ c = IEEE80211_CHAN_ANYC;
} else if ((u_int) ireq->i_val > IEEE80211_CHAN_MAX) {
return EINVAL;
} else {
- struct ieee80211_channel *c, *c2;
+ struct ieee80211_channel *c2;
c = findchannel(ic, ireq->i_val, ic->ic_des_mode);
if (c == NULL) {
@@ -1712,33 +1766,14 @@
if (ic->ic_state == IEEE80211_S_RUN && c == ic->ic_bsschan)
return 0; /* NB: nothing to do */
}
- 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;
+ return setcurchan(ic, c);
}
static int
ieee80211_ioctl_setcurchan(struct ieee80211com *ic,
const struct ieee80211req *ireq)
{
- struct ieee80211_channel chan;
+ struct ieee80211_channel chan, *c;
int error;
if (ireq->i_len != sizeof(chan))
@@ -1748,49 +1783,13 @@
return error;
/* XXX 0xffff overflows 16-bit signed */
if (chan.ic_freq == 0 || chan.ic_freq == IEEE80211_CHAN_ANY) {
- ic->ic_des_chan = IEEE80211_CHAN_ANYC;
+ c = IEEE80211_CHAN_ANYC;
} else {
- struct ieee80211_channel *c;
-
c = ieee80211_find_channel(ic, chan.ic_freq, chan.ic_flags);
if (c == NULL)
return EINVAL;
- /* XXX? */
- if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
- !check_mode_consistency(c, ic->ic_des_mode))
- return EINVAL;
- ic->ic_des_chan = c;
- if (ic->ic_state == IEEE80211_S_RUN && c == ic->ic_bsschan)
- return 0; /* NB: nothing to do */
}
- 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);
- else if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
- /*
- * When not up+running and a real channel has
- * been specified fix the current channel so
- * there is immediate feedback; e.g. via ifconfig.
- */
- ic->ic_curchan = ic->ic_des_chan;
- }
- }
- return error;
+ return setcurchan(ic, c);
}
static int
More information about the p4-projects
mailing list