summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_proto.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-06-04 15:57:38 +0000
committersam <sam@FreeBSD.org>2009-06-04 15:57:38 +0000
commite673d3b5e90d6ec6fe0c6bca82c4b813b1af6e3d (patch)
tree0087ddfa0d20ea5694d61834bf30fbd8cf190b9f /sys/net80211/ieee80211_proto.c
parent981682577c61c5ffe81deb34e9b9b1f0658c7fb0 (diff)
downloadFreeBSD-src-e673d3b5e90d6ec6fe0c6bca82c4b813b1af6e3d.zip
FreeBSD-src-e673d3b5e90d6ec6fe0c6bca82c4b813b1af6e3d.tar.gz
o station mode channel switch support
o IEEE80211_IOC_CHANSWITCH fixups: - restrict to hostap vaps - return EOPNOTSUPP instead of EINVAL when applied to !hostap vap or to a vap w/o 11h enabled - interpret count of 0 to mean cancel the current CSA Reviewed by: rpaulo, avatar
Diffstat (limited to 'sys/net80211/ieee80211_proto.c')
-rw-r--r--sys/net80211/ieee80211_proto.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 7e69929..9f80cdf 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -1374,7 +1374,7 @@ beacon_miss(void *arg, int npending)
* handlers duplicating these checks.
*/
if (vap->iv_opmode == IEEE80211_M_STA &&
- vap->iv_state == IEEE80211_S_RUN &&
+ vap->iv_state >= IEEE80211_S_RUN &&
vap->iv_bmiss != NULL)
vap->iv_bmiss(vap);
}
@@ -1451,8 +1451,8 @@ ieee80211_csa_startswitch(struct ieee80211com *ic,
IEEE80211_LOCK_ASSERT(ic);
ic->ic_csa_newchan = c;
+ ic->ic_csa_mode = mode;
ic->ic_csa_count = count;
- /* XXX record mode? */
ic->ic_flags |= IEEE80211_F_CSAPENDING;
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
@@ -1465,6 +1465,19 @@ ieee80211_csa_startswitch(struct ieee80211com *ic,
ieee80211_notify_csa(ic, c, mode, count);
}
+static void
+csa_completeswitch(struct ieee80211com *ic)
+{
+ struct ieee80211vap *vap;
+
+ ic->ic_csa_newchan = NULL;
+ ic->ic_flags &= ~IEEE80211_F_CSAPENDING;
+
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
+ if (vap->iv_state == IEEE80211_S_CSA)
+ ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0);
+}
+
/*
* Complete an 802.11h channel switch started by ieee80211_csa_startswitch.
* We clear state and move all vap's in CSA state to RUN state
@@ -1473,19 +1486,25 @@ ieee80211_csa_startswitch(struct ieee80211com *ic,
void
ieee80211_csa_completeswitch(struct ieee80211com *ic)
{
- struct ieee80211vap *vap;
-
IEEE80211_LOCK_ASSERT(ic);
KASSERT(ic->ic_flags & IEEE80211_F_CSAPENDING, ("csa not pending"));
ieee80211_setcurchan(ic, ic->ic_csa_newchan);
- ic->ic_csa_newchan = NULL;
- ic->ic_flags &= ~IEEE80211_F_CSAPENDING;
+ csa_completeswitch(ic);
+}
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
- if (vap->iv_state == IEEE80211_S_CSA)
- ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0);
+/*
+ * Cancel an 802.11h channel switch started by ieee80211_csa_startswitch.
+ * We clear state and move all vap's in CSA state to RUN state
+ * so they can again transmit.
+ */
+void
+ieee80211_csa_cancelswitch(struct ieee80211com *ic)
+{
+ IEEE80211_LOCK_ASSERT(ic);
+
+ csa_completeswitch(ic);
}
/*
OpenPOWER on IntegriCloud