summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211.c29
-rw-r--r--sys/net80211/ieee80211_node.c17
-rw-r--r--sys/net80211/ieee80211_var.h3
3 files changed, 46 insertions, 3 deletions
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index ab2c5a3b9bd..dd2a6531467 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211.c,v 1.5 2005/04/20 19:52:43 reyk Exp $ */
+/* $OpenBSD: ieee80211.c,v 1.6 2005/04/21 22:47:15 reyk Exp $ */
/* $NetBSD: ieee80211.c,v 1.19 2004/06/06 05:45:29 dyoung Exp $ */
/*-
@@ -802,6 +802,33 @@ ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode)
#undef N
}
+void
+ieee80211_next_mode(struct ifnet *ifp)
+{
+ struct ieee80211com *ic = (void *)ifp;
+
+ if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO)
+ return;
+
+ /*
+ * Get the next supported mode
+ */
+ for (++ic->ic_curmode;
+ ic->ic_curmode <= IEEE80211_MODE_TURBO;
+ ic->ic_curmode++) {
+ /* Wrap around and ignore turbo mode */
+ if (ic->ic_curmode >= IEEE80211_MODE_TURBO) {
+ ic->ic_curmode = IEEE80211_MODE_AUTO;
+ break;
+ }
+
+ if (ic->ic_modecaps & (1 << ic->ic_curmode))
+ break;
+ }
+
+ ieee80211_setmode(ic, ic->ic_curmode);
+}
+
/*
* Return the phy mode for with the specified channel so the
* caller can select a rate set. This is problematic and the
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index f8d70b4e26e..7bed1fc2b3b 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_node.c,v 1.3 2005/02/17 18:28:05 reyk Exp $ */
+/* $OpenBSD: ieee80211_node.c,v 1.4 2005/04/21 22:47:15 reyk Exp $ */
/* $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $ */
/*-
@@ -239,6 +239,12 @@ ieee80211_begin_scan(struct ifnet *ifp)
ieee80211_reset_scan(ifp);
ieee80211_free_allnodes(ic);
+ /* Reset the current mode. */
+ if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO) {
+ ic->ic_curmode = IEEE80211_MODE_AUTO;
+ ieee80211_setmode(ic, ic->ic_curmode);
+ }
+
/* Scan the next channel. */
ieee80211_next_scan(ifp);
}
@@ -431,6 +437,15 @@ ieee80211_end_scan(struct ifnet *ifp)
ieee80211_create_ibss(ic, ic->ic_ibss_chan);
return;
}
+
+ /*
+ * Scan the next mode if nothing has been found. This
+ * is necessary if the device supports different
+ * incompatible modes in the same channel range, like
+ * like 11b and "pure" 11G mode.
+ */
+ ieee80211_next_mode(ifp);
+
/*
* Reset the list of channels to scan and start again.
*/
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 11aa668fa88..479ea5c7513 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_var.h,v 1.6 2005/02/17 18:28:05 reyk Exp $ */
+/* $OpenBSD: ieee80211_var.h,v 1.7 2005/04/21 22:47:15 reyk Exp $ */
/* $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */
/*-
@@ -321,6 +321,7 @@ u_int ieee80211_mhz2ieee(u_int, u_int);
u_int ieee80211_chan2ieee(struct ieee80211com *, struct ieee80211_channel *);
u_int ieee80211_ieee2mhz(u_int, u_int);
int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode);
+void ieee80211_next_mode(struct ifnet *);
enum ieee80211_phymode ieee80211_chan2mode(struct ieee80211com *,
struct ieee80211_channel *);