aboutsummaryrefslogtreecommitdiff
path: root/sys/net80211/ieee80211_proto.c
diff options
context:
space:
mode:
authorSam Leffler <sam@FreeBSD.org>2009-06-04 15:57:38 +0000
committerSam Leffler <sam@FreeBSD.org>2009-06-04 15:57:38 +0000
commitc70761e6b54def6b51874d2967c0bd5a8d133db8 (patch)
tree0087ddfa0d20ea5694d61834bf30fbd8cf190b9f /sys/net80211/ieee80211_proto.c
parent3144f812215550ac4bb500dd2eb66a4f90169149 (diff)
downloadsrc-c70761e6b54def6b51874d2967c0bd5a8d133db8.tar.gz
src-c70761e6b54def6b51874d2967c0bd5a8d133db8.zip
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
Notes
Notes: svn path=/head/; revision=193439
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 7e69929d6d79..9f80cdffd024 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);
}
/*