Subject: net80211/ work-in-progress
To: None <tech-net@netbsd.org, current-users@netbsd.org>
From: David Young <dyoung@pobox.com>
List: current-users
Date: 09/03/2003 01:12:53
--azLHFNyN32YCQGCU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Didn't as much done as I hoped with integrating sys/net80211/, but here's
a preview: patches against sys/net80211/ for FreeBSD/NetBSD compatibility,
and patches against sys/net/if_media.h.

Next for me to tackle is the 802.11 ioctls. I've about changed my mind,
25 ioctls is not enough, so we pro'ly *should* converge on FreeBSD-style
SIOCS80211/SIOCG80211 ioctls, but it's necessary to get a lot of parties'
agreement on what that convergence looks like, and then figure out the
backwards-compatibility issues. I will stick to NetBSD ioctls for now.

After the ioctls, multi-mode media-handling in ifconfig. Adapt wi. Test.
Adapt atw. Test. Adapt awi. Maybe test (gotta debug awi on the Mac,
first---bleh). Commit. Hand the baton to Bruce.

What am I missing?

Dave

-- 
David Young             OJC Technologies
dyoung@ojctech.com      Urbana, IL * (217) 278-3933

--azLHFNyN32YCQGCU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=ifmdiffs

Index: if_media.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_media.h,v
retrieving revision 1.35
diff -u -r1.35 if_media.h
--- if_media.h	2003/07/08 07:13:51	1.35
+++ if_media.h	2003/09/03 05:44:46
@@ -153,7 +153,8 @@
  *	0-4	Media subtype		MAX SUBTYPE == 31!
  *	5-7	Media type
  *	8-15	Type specific options
- *	16-19	RFU
+ *	16-18	Mode (for multi-mode devices)
+ *	19	RFU
  *	20-27	Shared (global) options
  *	28-31	Instance
  */
@@ -211,11 +212,27 @@
 #define	IFM_IEEE80211_DS5	6	/* Direct Sequence 5Mbps*/
 #define	IFM_IEEE80211_DS11	7	/* Direct Sequence 11Mbps*/
 #define	IFM_IEEE80211_DS1	8	/* Direct Sequence 1Mbps */
+#define	IFM_IEEE80211_DS22	9	/* Direct Sequence 22Mbps */
+#define	IFM_IEEE80211_OFDM6	10	/* OFDM 6Mbps */
+#define	IFM_IEEE80211_OFDM9	11	/* OFDM 9Mbps */
+#define	IFM_IEEE80211_OFDM12	12	/* OFDM 12Mbps */
+#define	IFM_IEEE80211_OFDM18	13	/* OFDM 18Mbps */
+#define	IFM_IEEE80211_OFDM24	14	/* OFDM 24Mbps */
+#define	IFM_IEEE80211_OFDM36	15	/* OFDM 36Mbps */
+#define	IFM_IEEE80211_OFDM48	16	/* OFDM 48Mbps */
+#define	IFM_IEEE80211_OFDM54	17	/* OFDM 54Mbps */
+#define	IFM_IEEE80211_OFDM72	18	/* OFDM 72Mbps */
 
 #define	IFM_IEEE80211_ADHOC	 0x00000100	/* Operate in Adhoc mode */
 #define	IFM_IEEE80211_HOSTAP	 0x00000200	/* Operate in Host AP mode */
 #define	IFM_IEEE80211_MONITOR	 0x00000400	/* Operate in Monitor mode */
+#define	IFM_IEEE80211_TURBO	 0x00000800	/* Operate in Turbo mode */
 
+/* operating mode for multi-mode devices */
+#define	IFM_IEEE80211_11A	1	/* 5Ghz, OFDM mode */
+#define	IFM_IEEE80211_11B	2	/* Direct Sequence mode */
+#define	IFM_IEEE80211_11G	3	/* 2Ghz, CCK mode */
+
 /*
  * Shared media sub-types
  */
@@ -242,6 +259,8 @@
 #define	IFM_IMASK	0xf0000000	/* Instance */
 #define	IFM_ISHIFT	28		/* Instance shift */
 #define	IFM_OMASK	0x0000ff00	/* Type specific options */
+#define	IFM_MMASK	0x00070000	/* Mode */
+#define	IFM_MSHIFT	16		/* Mode shift */
 #define	IFM_GMASK	0x0ff00000	/* Global options */
 
 #define	IFM_NMIN	IFM_ETHER	/* lowest Network type */
@@ -269,6 +288,7 @@
 #define	IFM_SUBTYPE(x)	((x) & IFM_TMASK)
 #define	IFM_INST(x)	(((x) & IFM_IMASK) >> IFM_ISHIFT)
 #define	IFM_OPTIONS(x)	((x) & (IFM_OMASK|IFM_GMASK))
+#define	IFM_MODE(x)	    (((x) & IFM_MMASK) >> IFM_MSHIFT)
 
 #define	IFM_INST_MAX	IFM_INST(IFM_IMASK)
 #define	IFM_INST_ANY	((u_int) -1)
@@ -278,6 +298,8 @@
  */
 #define	IFM_MAKEWORD(type, subtype, options, instance)			\
 	((type) | (subtype) | (options) | ((instance) << IFM_ISHIFT))
+#define	IFM_MAKEMODE(mode) \
+	(((mode) << IFM_MSHIFT) & IFM_MMASK)
 
 /*
  * NetBSD extension not defined in the BSDI API.  This is used in various
@@ -406,6 +428,14 @@
 	{ 0, NULL },							\
 }
 
+#define IFM_MODE_DESCRIPTIONS {						\
+	{ IFM_AUTO, "autoselect" },					\
+	{ IFM_IEEE80211_11A, "11a" },					\
+	{ IFM_IEEE80211_11B, "11b" },					\
+	{ IFM_IEEE80211_11G, "11g" },					\
+	{ 0, NULL },							\
+}
+
 #define	IFM_OPTION_DESCRIPTIONS {					\
 	{ IFM_FDX,			"full-duplex" },		\
 	{ IFM_FDX,			"fdx" },			\
@@ -434,6 +464,7 @@
 	{ IFM_IEEE80211|IFM_IEEE80211_ADHOC,	"ibss" },		\
 	{ IFM_IEEE80211|IFM_IEEE80211_HOSTAP,	"hostap" },		\
 	{ IFM_IEEE80211|IFM_IEEE80211_MONITOR,	"monitor" },		\
+	{ IFM_IEEE80211|IFM_IEEE80211_TURBO,	"turbo" },		\
 									\
 	{ 0, NULL },							\
 }

--azLHFNyN32YCQGCU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=i8diffs

Index: ieee80211.c
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ieee80211.c
--- ieee80211.c	2003/08/30 21:26:03	1.1.1.1
+++ ieee80211.c	2003/09/03 05:38:37
@@ -52,13 +52,17 @@
 #include <sys/proc.h>
 #include <sys/sysctl.h>
 
+#ifdef __FreeBSD__
 #include <machine/atomic.h>
+#endif
  
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
 #include <net/if_arp.h>
+#ifdef __FreeBSD__
 #include <net/ethernet.h>
+#endif
 #include <net/if_llc.h>
 
 #include <net80211/ieee80211_var.h>
@@ -845,6 +849,7 @@
 #undef N
 }
 
+#ifdef __FreeBSD__
 /*
  * Module glue.
  *
@@ -873,3 +878,4 @@
 DECLARE_MODULE(wlan, ieee80211_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
 MODULE_VERSION(wlan, 1);
 MODULE_DEPEND(wlan, rc4, 1, 1, 1);
+#endif
Index: ieee80211_crypto.c
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211_crypto.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ieee80211_crypto.c
--- ieee80211_crypto.c	2003/08/30 21:26:03	1.1.1.1
+++ ieee80211_crypto.c	2003/09/03 05:38:38
@@ -48,13 +48,17 @@
 #include <sys/proc.h>
 #include <sys/sysctl.h>
 
+#ifdef __FreeBSD__
 #include <machine/atomic.h>
+#endif
  
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
 #include <net/if_arp.h>
+#ifdef __FreeBSD__
 #include <net/ethernet.h>
+#endif
 #include <net/if_llc.h>
 
 #include <net80211/ieee80211_var.h>
@@ -66,10 +70,14 @@
 #include <netinet/if_ether.h>
 #endif
 
+#ifdef __FreeBSD__
 #include <crypto/rc4/rc4.h>
 #define	arc4_ctxlen()			sizeof (struct rc4_state)
 #define	arc4_setkey(_c,_k,_l)		rc4_init(_c,_k,_l)
 #define	arc4_encrypt(_c,_d,_s,_l)	rc4_crypt(_c,_s,_d,_l)
+#else
+#include <crypto/arc4/arc4.h>
+#endif
 
 static	void ieee80211_crc_init(void);
 static	u_int32_t ieee80211_crc_update(u_int32_t crc, u_int8_t *buf, int len);
Index: ieee80211_input.c
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211_input.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ieee80211_input.c
--- ieee80211_input.c	2003/08/30 21:26:04	1.1.1.1
+++ ieee80211_input.c	2003/09/03 05:38:38
@@ -48,13 +48,17 @@
 #include <sys/proc.h>
 #include <sys/sysctl.h>
 
+#ifdef __FreeBSD__
 #include <machine/atomic.h>
+#endif
  
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
 #include <net/if_arp.h>
+#ifdef __FreeBSD__
 #include <net/ethernet.h>
+#endif
 #include <net/if_llc.h>
 
 #include <net80211/ieee80211_var.h>
@@ -653,7 +657,7 @@
 			ni->ni_esslen = ssid[1];
 			memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
 			memcpy(ni->ni_essid, ssid + 2, ssid[1]);
-		} else if (ssid[1] != 0 && ISPROBE(subtype)) {
+		} else if (ssid[1] != 0) {
 			/*
 			 * Update ESSID at probe response to adopt hidden AP by
 			 * Lucent/Cisco, which announces null ESSID in beacon.
Index: ieee80211_ioctl.c
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211_ioctl.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ieee80211_ioctl.c
--- ieee80211_ioctl.c	2003/08/30 21:26:04	1.1.1.1
+++ ieee80211_ioctl.c	2003/09/03 05:38:38
@@ -47,7 +47,9 @@
 #include <net/if.h>
 #include <net/if_arp.h>
 #include <net/if_media.h>
+#ifdef __FreeBSD__
 #include <net/ethernet.h>
+#endif
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_ioctl.h>
@@ -959,7 +961,7 @@
 			break;
 		case IEEE80211_IOCT_RTSTHRESHOLD:
 			if (!(IEEE80211_RTS_MIN < ireq->i_val &&
-			      ireq->i_val < IEEE80211_RTS_MAX)) {
+			      ireq->i_val <= IEEE80211_RTS_MAX + 1)) {
 				error = EINVAL;
 				break;
 			}
Index: ieee80211_node.c
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ieee80211_node.c
--- ieee80211_node.c	2003/08/30 21:26:04	1.1.1.1
+++ ieee80211_node.c	2003/09/03 05:38:39
@@ -48,13 +48,17 @@
 #include <sys/proc.h>
 #include <sys/sysctl.h>
 
+#ifdef __FreeBSD__
 #include <machine/atomic.h>
+#endif
  
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
 #include <net/if_arp.h>
+#ifdef __FreeBSD__
 #include <net/ethernet.h>
+#endif
 #include <net/if_llc.h>
 
 #include <net80211/ieee80211_var.h>
@@ -80,8 +84,10 @@
 {
 	struct ieee80211com *ic = (void *)ifp;
 
+#ifdef __FreeBSD__
 	/* XXX need unit */
 	mtx_init(&ic->ic_nodelock, ifp->if_name, "802.11 node table", MTX_DEF);
+#endif
 	TAILQ_INIT(&ic->ic_node);
 	ic->ic_node_alloc = ieee80211_node_alloc;
 	ic->ic_node_free = ieee80211_node_free;
@@ -106,7 +112,9 @@
 	if (ic->ic_bss != NULL)
 		(*ic->ic_node_free)(ic, ic->ic_bss);
 	ieee80211_free_allnodes(ic);
+#ifdef __FreeBSD__
 	mtx_destroy(&ic->ic_nodelock);
+#endif
 }
 
 /*
@@ -411,11 +419,12 @@
 	struct ieee80211_node *ni, u_int8_t *macaddr)
 {
 	int hash;
+	ieee80211_node_critsec_decl(s);
 
 	IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);
 	hash = IEEE80211_NODE_HASH(macaddr);
 	ni->ni_refcnt = 1;		/* mark referenced */
-	mtx_lock(&ic->ic_nodelock);
+	ieee80211_node_critsec_begin(ic, s);
 	TAILQ_INSERT_TAIL(&ic->ic_node, ni, ni_list);
 	LIST_INSERT_HEAD(&ic->ic_hash[hash], ni, ni_hash);
 	/* 
@@ -429,7 +438,7 @@
 	 */
 	if (ic->ic_opmode != IEEE80211_M_STA)
 		ic->ic_inact_timer = IEEE80211_INACT_WAIT;
-	mtx_unlock(&ic->ic_nodelock);
+	ieee80211_node_critsec_end(ic, s);
 }
 
 struct ieee80211_node *
@@ -457,16 +466,17 @@
 {
 	struct ieee80211_node *ni;
 	int hash;
+	ieee80211_node_critsec_decl(s);
 
 	hash = IEEE80211_NODE_HASH(macaddr);
-	mtx_lock(&ic->ic_nodelock);
+	ieee80211_node_critsec_begin(ic, s);
 	LIST_FOREACH(ni, &ic->ic_hash[hash], ni_hash) {
 		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
-			atomic_add_int(&ni->ni_refcnt, 1); /* mark referenced */
+			ieee80211_node_incref(ni); /* mark referenced */
 			break;
 		}
 	}
-	mtx_unlock(&ic->ic_nodelock);
+	ieee80211_node_critsec_end(ic, s);
 	return ni;
 }
 
@@ -479,16 +489,17 @@
 {
 	struct ieee80211_node *ni;
 	int hash;
+	ieee80211_node_critsec_decl(s);
 
 	hash = IEEE80211_NODE_HASH(macaddr);
-	mtx_lock(&ic->ic_nodelock);
+	ieee80211_node_critsec_begin(ic, s);
 	LIST_FOREACH(ni, &ic->ic_hash[hash], ni_hash) {
 		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr) && ni->ni_chan == chan) {
-			atomic_add_int(&ni->ni_refcnt, 1);/* mark referenced */
+			ieee80211_node_incref(ni);/* mark referenced */
 			break;
 		}
 	}
-	mtx_unlock(&ic->ic_nodelock);
+	ieee80211_node_critsec_end(ic, s);
 	return ni;
 }
 
@@ -507,14 +518,14 @@
 void
 ieee80211_free_node(struct ieee80211com *ic, struct ieee80211_node *ni)
 {
+	ieee80211_node_critsec_decl(s);
+
 	KASSERT(ni != ic->ic_bss, ("freeing ic_bss"));
 
-	/* XXX need equivalent of atomic_dec_and_test */
-	atomic_subtract_int(&ni->ni_refcnt, 1);
-	if (atomic_cmpset_int(&ni->ni_refcnt, 0, 1)) {
-		mtx_lock(&ic->ic_nodelock);
+	if (ieee80211_node_decref(ni) == 0) {
+		ieee80211_node_critsec_begin(ic, s);
 		_ieee80211_free_node(ic, ni);
-		mtx_unlock(&ic->ic_nodelock);
+		ieee80211_node_critsec_end(ic, s);
 	}
 }
 
@@ -522,19 +533,21 @@
 ieee80211_free_allnodes(struct ieee80211com *ic)
 {
 	struct ieee80211_node *ni;
+	ieee80211_node_critsec_decl(s);
 
-	mtx_lock(&ic->ic_nodelock);
+	ieee80211_node_critsec_begin(ic, s);
 	while ((ni = TAILQ_FIRST(&ic->ic_node)) != NULL)
 		_ieee80211_free_node(ic, ni);  
-	mtx_unlock(&ic->ic_nodelock);
+	ieee80211_node_critsec_end(ic, s);
 }
 
 void
 ieee80211_timeout_nodes(struct ieee80211com *ic)
 {
 	struct ieee80211_node *ni, *nextbs;
+	ieee80211_node_critsec_decl(s);
 
-	mtx_lock(&ic->ic_nodelock);
+	ieee80211_node_critsec_begin(ic, s);
 	for (ni = TAILQ_FIRST(&ic->ic_node); ni != NULL;) {
 		if (++ni->ni_inact > IEEE80211_INACT_MAX) {
 			IEEE80211_DPRINTF(("station %s timed out "
@@ -555,16 +568,17 @@
 	}
 	if (!TAILQ_EMPTY(&ic->ic_node))
 		ic->ic_inact_timer = IEEE80211_INACT_WAIT;
-	mtx_unlock(&ic->ic_nodelock);
+	ieee80211_node_critsec_end(ic, s);
 }
 
 void
 ieee80211_iterate_nodes(struct ieee80211com *ic, ieee80211_iter_func *f, void *arg)
 {
 	struct ieee80211_node *ni;
+	ieee80211_node_critsec_decl(s);
 
-	mtx_lock(&ic->ic_nodelock);
+	ieee80211_node_critsec_begin(ic, s);
 	TAILQ_FOREACH(ni, &ic->ic_node, ni_list)
 		(*f)(arg, ni);
-	mtx_unlock(&ic->ic_nodelock);
+	ieee80211_node_critsec_end(ic, s);
 }
Index: ieee80211_node.h
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211_node.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ieee80211_node.h
--- ieee80211_node.h	2003/08/30 21:26:05	1.1.1.1
+++ ieee80211_node.h	2003/09/03 05:38:39
@@ -106,14 +106,14 @@
 static __inline struct ieee80211_node *
 ieee80211_ref_node(struct ieee80211_node *ni)
 {
-	atomic_add_int(&ni->ni_refcnt, 1);
+	ieee80211_node_incref(ni);
 	return ni;
 }
 
 static __inline void
 ieee80211_unref_node(struct ieee80211_node **ni)
 {
-	atomic_subtract_int(&(*ni)->ni_refcnt, 1);
+	ieee80211_node_decref(ni);
 	*ni = NULL;			/* guard against use */
 }
 
Index: ieee80211_output.c
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211_output.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ieee80211_output.c
--- ieee80211_output.c	2003/08/30 21:26:05	1.1.1.1
+++ ieee80211_output.c	2003/09/03 05:38:39
@@ -48,15 +48,20 @@
 #include <sys/proc.h>
 #include <sys/sysctl.h>
 
+#ifdef __FreeBSD__
 #include <machine/atomic.h>
- 
+#endif
+
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
 #include <net/if_arp.h>
+#ifdef __FreeBSD__
 #include <net/ethernet.h>
+#endif
 #include <net/if_llc.h>
 
+#include <net80211/ieee80211_compat.h>
 #include <net80211/ieee80211_var.h>
 
 #include <net/bpf.h>
@@ -104,8 +109,8 @@
 	wh = mtod(m, struct ieee80211_frame *);
 	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | type;
 	wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
-	*(u_int16_t *)wh->i_dur = 0;
-	*(u_int16_t *)wh->i_seq =
+	*(u_int16_t *)&wh->i_dur[0] = 0;
+	*(u_int16_t *)&wh->i_seq[0] =
 	    htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
 	ni->ni_txseq++;
 	IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
@@ -193,8 +198,8 @@
 		goto bad;
 	wh = mtod(m, struct ieee80211_frame *);
 	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
-	*(u_int16_t *)wh->i_dur = 0;
-	*(u_int16_t *)wh->i_seq =
+	*(u_int16_t *)&wh->i_dur[0] = 0;
+	*(u_int16_t *)&wh->i_seq[0] =
 	    htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
 	ni->ni_txseq++;
 	switch (ic->ic_opmode) {
@@ -284,10 +289,16 @@
 {
 	struct mbuf *m;
 
+#ifdef __FreeBSD__
 	if (pktlen > MHLEN)
 		MGETHDR(m, flags, type);
 	else
 		m = m_getcl(flags, type, M_PKTHDR);
+#else
+	MGETHDR(m, flags, type);
+	if (m != NULL && pktlen > MHLEN)
+		MCLGET(m, flags);
+#endif
 	return m;
 }
 
Index: ieee80211_proto.c
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211_proto.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ieee80211_proto.c
--- ieee80211_proto.c	2003/08/30 21:26:05	1.1.1.1
+++ ieee80211_proto.c	2003/09/03 05:38:39
@@ -52,13 +52,17 @@
 #include <sys/proc.h>
 #include <sys/sysctl.h>
 
+#ifdef __FreeBSD__
 #include <machine/atomic.h>
+#endif
  
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
 #include <net/if_arp.h>
+#ifdef __FreeBSD__
 #include <net/ethernet.h>
+#endif
 #include <net/if_llc.h>
 
 #include <net80211/ieee80211_var.h>
@@ -103,7 +107,9 @@
 	ic->ic_fragthreshold = 2346;		/* XXX not used yet */
 	ic->ic_fixed_rate = -1;			/* no fixed rate */
 
+#ifdef __FreeBSD__
 	mtx_init(&ic->ic_mgtq.ifq_mtx, ifp->if_name, "mgmt send q", MTX_DEF);
+#endif
 
 	/* protocol state change handler */
 	ic->ic_newstate = ieee80211_newstate;
@@ -293,6 +299,7 @@
 	struct ifnet *ifp = &ic->ic_if;
 	struct ieee80211_node *ni;
 	enum ieee80211_state ostate;
+	ieee80211_node_critsec_decl(s);
 
 	ostate = ic->ic_state;
 	IEEE80211_DPRINTF(("%s: %s -> %s\n", __func__,
@@ -312,7 +319,7 @@
 				    IEEE80211_REASON_ASSOC_LEAVE);
 				break;
 			case IEEE80211_M_HOSTAP:
-				mtx_lock(&ic->ic_nodelock);
+				ieee80211_node_critsec_begin(ic, s);
 				TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
 					if (ni->ni_associd == 0)
 						continue;
@@ -320,7 +327,7 @@
 					    IEEE80211_FC0_SUBTYPE_DISASSOC,
 					    IEEE80211_REASON_ASSOC_LEAVE);
 				}
-				mtx_unlock(&ic->ic_nodelock);
+				ieee80211_node_critsec_end(ic, s);
 				break;
 			default:
 				break;
@@ -334,13 +341,13 @@
 				    IEEE80211_REASON_AUTH_LEAVE);
 				break;
 			case IEEE80211_M_HOSTAP:
-				mtx_lock(&ic->ic_nodelock);
+				ieee80211_node_critsec_begin(ic, s);
 				TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
 					IEEE80211_SEND_MGMT(ic, ni,
 					    IEEE80211_FC0_SUBTYPE_DEAUTH,
 					    IEEE80211_REASON_AUTH_LEAVE);
 				}
-				mtx_unlock(&ic->ic_nodelock);
+				ieee80211_node_critsec_end(ic, s);
 				break;
 			default:
 				break;
Index: ieee80211_var.h
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211_var.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ieee80211_var.h
--- ieee80211_var.h	2003/08/30 21:26:05	1.1.1.1
+++ ieee80211_var.h	2003/09/03 05:38:39
@@ -158,13 +158,19 @@
 	enum ieee80211_opmode	ic_opmode;	/* operation mode */
 	enum ieee80211_state	ic_state;	/* 802.11 state */
 	struct ifmedia		ic_media;	/* interface media config */
+#ifdef __FreeBSD__
 	struct bpf_if		*ic_rawbpf;	/* packet filter structure */
+#else
+	caddr_t			ic_rawbpf;	/* packet filter structure */
+#endif
 	struct ieee80211_node	*ic_bss;	/* information for this node */
 	struct ieee80211_channel *ic_ibss_chan;
 	int			ic_fixed_rate;	/* index to ic_sup_rates[] */
 	u_int16_t		ic_rtsthreshold;
 	u_int16_t		ic_fragthreshold;
+#ifdef __FreeBSD__
 	struct mtx		ic_nodelock;	/* on node table */
+#endif
 	struct ieee80211_node	*(*ic_node_alloc)(struct ieee80211com *);
 	void			(*ic_node_free)(struct ieee80211com *,
 					struct ieee80211_node *);

--azLHFNyN32YCQGCU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ieee80211_compat.c"

/*-
 * Copyright (c) 2003, 2004 David Young
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <net/if.h>
#include <sys/systm.h>

#ifdef __NetBSD__
int
if_printf(struct ifnet *ifp, const char *fmt, ...)
{
	int rc;
	va_list ap;

	va_start(ap, fmt);
	if (printf("%s: ", ifp->if_xname) == -1)
		return -1;
	rc = vprintf(fmt, ap);
	va_end(ap);
	return rc;
}
#endif /* __NetBSD__ */

--azLHFNyN32YCQGCU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ieee80211_compat.h"

/*-
 * Copyright (c) 2003, 2004 David Young
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef _NET80211_IEEE80211_COMPAT_H_
#define _NET80211_IEEE80211_COMPAT_H_

#ifdef __NetBSD__
extern int if_printf(struct ifnet *ifp, const char *fmt, ...);
#endif

#ifdef __NetBSD__
#define ieee80211_node_critsec_decl(v) int v
#define ieee80211_node_critsec_begin(ic, v) do { v = splnet() } while (0)
#define ieee80211_node_critsec_end(ic, v) splx(v)
#else
#define ieee80211_node_critsec_decl(v) /* empty */
#define ieee80211_node_critsec_begin(ic, v) mtx_lock(&(ic)->ic_nodelock)
#define ieee80211_node_critsec_end(ic, v) mtx_unlock(&ic->ic_nodelock)
#endif

#ifdef __NetBSD__
#define ieee80211_node_incref(ni)			\
	do {						\
		int _s = splnet();			\
		(ni)->ni_refcnt++;			\
		splx(_s);				\
	} while (0)

static __inline int
ieee80211_node_decref(struct ieee80211_node *ni)
{
	int refcnt, s;
	s = splnet();
	refcnt = --ni->ni_refcnt;
	splx(s);
	return refcnt;
}

#else
#define ieee80211_node_incref(ni) atomic_add_int(&(ni)->ni_refcnt, 1)
static __inline int
ieee80211_node_decref(struct ieee80211_node *ni)
{
	int orefcnt;
	do {
		orefcnt = ni->ni_refcnt;
	} while (atomic_cmpset_int(&ni->ni_refcnt, orefcnt, orefcnt - 1) == 0);
	return orefcnt - 1;
}
#endif

#endif /* _NET80211_IEEE80211_COMPAT_H_ */

--azLHFNyN32YCQGCU--