-@@ -3623,9 +3624,9 @@
- }
-
- /* Okay, take the first queued packet and put it out... */
-- IEEE80211_NODE_SAVEQ_LOCK(ni);
-+ IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni);
- IEEE80211_NODE_SAVEQ_DEQUEUE(ni, skb, qlen);
-- IEEE80211_NODE_SAVEQ_UNLOCK(ni);
-+ IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni);
- if (skb == NULL) {
- IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_POWER, wh->i_addr2,
- "%s", "recv ps-poll, but queue empty");
-diff -urN madwifi-ng-refcount-r2313-20070505.old/net80211/ieee80211_linux.h madwifi-ng-refcount-r2313-20070505.dev/net80211/ieee80211_linux.h
---- madwifi-ng-refcount-r2313-20070505.old/net80211/ieee80211_linux.h 2007-05-04 02:10:06.000000000 +0200
-+++ madwifi-ng-refcount-r2313-20070505.dev/net80211/ieee80211_linux.h 2007-05-13 18:17:56.598964688 +0200
-@@ -31,6 +31,10 @@
-
- #include <linux/wireless.h>
-
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+#define irqs_disabled() 0
-+#endif
-+
- /*
- * Task deferral
- *
-@@ -86,8 +90,12 @@
- } while (0)
- #define IEEE80211_UNLOCK_IRQ_EARLY(_ic) \
- spin_unlock_irqrestore(&(_ic)->ic_comlock, __ilockflags);
--#define IEEE80211_LOCK_BH(_ic) spin_lock_bh(&(_ic)->ic_comlock)
--#define IEEE80211_UNLOCK_BH(_ic) spin_unlock_bh(&(_ic)->ic_comlock)
-+#define IEEE80211_LOCK_BH(_ic) \
-+ if (!irqs_disabled()) \
-+ spin_lock_bh(&(_ic)->ic_comlock)
-+#define IEEE80211_UNLOCK_BH(_ic) \
-+ if (!irqs_disabled()) \
-+ spin_unlock_bh(&(_ic)->ic_comlock)
- #define IEEE80211_LOCK(_ic) spin_lock(&(_ic)->ic_comlock)
- #define IEEE80211_UNLOCK(_ic) spin_unlock(&(_ic)->ic_comlock)
-
-@@ -104,15 +112,22 @@
- #define IEEE80211_VAPS_LOCK_DESTROY(_ic)
- #define IEEE80211_VAPS_LOCK(_ic) spin_lock(&(_ic)->ic_vapslock);
- #define IEEE80211_VAPS_UNLOCK(_ic) spin_unlock(&(_ic)->ic_vapslock);
--#define IEEE80211_VAPS_LOCK_BH(_ic) spin_lock_bh(&(_ic)->ic_vapslock);
--#define IEEE80211_VAPS_UNLOCK_BH(_ic) spin_unlock_bh(&(_ic)->ic_vapslock);
--#define IEEE80211_VAPS_LOCK_IRQ(_ic) do { \
-- int _vaps_lockflags; \
-- spin_lock_irqsave(&(_ic)->ic_vapslock, _vaps_lockflags);
--#define IEEE80211_VAPS_UNLOCK_IRQ(_ic) \
-- spin_unlock_irqrestore(&(_ic)->ic_vapslock, _vaps_lockflags); \
--} while (0)
--#define IEEE80211_VAPS_UNLOCK_IRQ_EARLY(_ic) spin_unlock_irqrestore(&(_ic)->ic_vapslock, _vaps_lockflags)
-+#define IEEE80211_VAPS_LOCK_BH(_ic) \
-+ if (!irqs_disabled()) \
-+ spin_lock_bh(&(_ic)->ic_vapslock);
-+#define IEEE80211_VAPS_UNLOCK_BH(_ic) \
-+ if (!irqs_disabled()) \
-+ spin_unlock_bh(&(_ic)->ic_vapslock);
-+#define IEEE80211_VAPS_LOCK_IRQ(_ic) do { \
-+ unsigned long __vlockflags=0; \
-+ unsigned int __vlocked=0; \
-+ __vlocked=spin_is_locked(&(_ic)->ic_vapslock); \
-+ if(!__vlocked) spin_lock_irqsave(&(_ic)->ic_vapslock, __vlockflags);
-+#define IEEE80211_VAPS_UNLOCK_IRQ(_ic) \
-+ if(!__vlocked) spin_unlock_irqrestore(&(_ic)->ic_vapslock, __vlockflags); \
-+} while (0);
-+#define IEEE80211_VAPS_UNLOCK_IRQ_EARLY(_ic) \
-+ if (!__vlocked) spin_unlock_irqrestore(&(_ic)->ic_vapslock, _vaps_lockflags)
-
- #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
- #define IEEE80211_VAPS_LOCK_ASSERT(_ic) \
-@@ -122,6 +137,11 @@
- #define IEEE80211_VAPS_LOCK_ASSERT(_ic)
- #endif
-
-+/*
-+ * Beacon locking definitions; piggyback on com lock.
-+ */
-+#define IEEE80211_BEACON_LOCK(_ic) IEEE80211_LOCK_IRQ(_ic)
-+#define IEEE80211_BEACON_UNLOCK(_ic) IEEE80211_UNLOCK_IRQ(_ic)
-
- /*
- * Node locking definitions.
-@@ -191,8 +211,12 @@
- typedef spinlock_t ieee80211_scan_lock_t;
- #define IEEE80211_SCAN_LOCK_INIT(_nt, _name) spin_lock_init(&(_nt)->nt_scanlock)
- #define IEEE80211_SCAN_LOCK_DESTROY(_nt)
--#define IEEE80211_SCAN_LOCK_BH(_nt) spin_lock_bh(&(_nt)->nt_scanlock)
--#define IEEE80211_SCAN_UNLOCK_BH(_nt) spin_unlock_bh(&(_nt)->nt_scanlock)
-+#define IEEE80211_SCAN_LOCK_BH(_nt) \
-+ if (!irqs_disabled()) \
-+ spin_lock_bh(&(_nt)->nt_scanlock)
-+#define IEEE80211_SCAN_UNLOCK_BH(_nt) \
-+ if (!irqs_disabled()) \
-+ spin_unlock_bh(&(_nt)->nt_scanlock)
- #define IEEE80211_SCAN_LOCK_IRQ(_nt) do { \
- unsigned long __scan_lockflags; \
- spin_lock_irqsave(&(_nt)->nt_scanlock, __scan_lockflags);
-@@ -217,8 +241,12 @@
- #define ACL_LOCK_DESTROY(_as)
- #define ACL_LOCK(_as) spin_lock(&(_as)->as_lock)
- #define ACL_UNLOCK(_as) spin_unlock(&(_as)->as_lock)
--#define ACL_LOCK_BH(_as) spin_lock_bh(&(_as)->as_lock)
--#define ACL_UNLOCK_BH(_as) spin_unlock_bh(&(_as)->as_lock)
-+#define ACL_LOCK_BH(_as) \
-+ if (!irqs_disabled()) \
-+ spin_lock_bh(&(_as)->as_lock)
-+#define ACL_UNLOCK_BH(_as) \
-+ if (!irqs_disabled()) \
-+ spin_unlock_bh(&(_as)->as_lock)
-
- #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
- #define ACL_LOCK_ASSERT(_as) \
-diff -urN madwifi-ng-refcount-r2313-20070505.old/net80211/ieee80211_node.c madwifi-ng-refcount-r2313-20070505.dev/net80211/ieee80211_node.c
---- madwifi-ng-refcount-r2313-20070505.old/net80211/ieee80211_node.c 2007-05-13 18:17:56.273014240 +0200
-+++ madwifi-ng-refcount-r2313-20070505.dev/net80211/ieee80211_node.c 2007-05-13 18:17:56.599964536 +0200
-@@ -1567,7 +1567,7 @@
- struct ieee80211_node *ni;
- u_int gen;
-
-- IEEE80211_SCAN_LOCK_IRQ(nt);
-+ IEEE80211_SCAN_LOCK_BH(nt);
- gen = ++nt->nt_scangen;
-
- restart:
-@@ -1587,7 +1587,7 @@
- }
- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
-
-- IEEE80211_SCAN_UNLOCK_IRQ(nt);
-+ IEEE80211_SCAN_UNLOCK_BH(nt);
- }
- EXPORT_SYMBOL(ieee80211_iterate_dev_nodes);
-
-diff -urN madwifi-ng-refcount-r2313-20070505.old/net80211/ieee80211_power.c madwifi-ng-refcount-r2313-20070505.dev/net80211/ieee80211_power.c
---- madwifi-ng-refcount-r2313-20070505.old/net80211/ieee80211_power.c 2007-04-25 22:29:55.000000000 +0200
-+++ madwifi-ng-refcount-r2313-20070505.dev/net80211/ieee80211_power.c 2007-05-13 18:17:56.599964536 +0200
-@@ -147,7 +147,7 @@
- #endif
- struct sk_buff *skb;
-
-- IEEE80211_NODE_SAVEQ_LOCK(ni);
-+ IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni);
- while ((skb = skb_peek(&ni->ni_savedq)) != NULL &&
- M_AGE_GET(skb) < IEEE80211_INACT_WAIT) {
- IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
-@@ -159,7 +159,7 @@
- }
- if (skb != NULL)
- M_AGE_SUB(skb, IEEE80211_INACT_WAIT);
-- IEEE80211_NODE_SAVEQ_UNLOCK(ni);
-+ IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni);
-
- IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
- "discard %u frames for age", discard);
-@@ -185,7 +185,7 @@
- KASSERT(aid < vap->iv_max_aid,
- ("bogus aid %u, max %u", aid, vap->iv_max_aid));
-
-- IEEE80211_LOCK(ni->ni_ic);
-+ IEEE80211_BEACON_LOCK(ni->ni_ic);
- if (set != (isset(vap->iv_tim_bitmap, aid) != 0)) {
- if (set) {
- setbit(vap->iv_tim_bitmap, aid);
-@@ -196,7 +196,7 @@
- }
- vap->iv_flags |= IEEE80211_F_TIMUPDATE;
- }
-- IEEE80211_UNLOCK(ni->ni_ic);
-+ IEEE80211_BEACON_UNLOCK(ni->ni_ic);
- }
-
- /*
-@@ -297,9 +297,9 @@
- struct sk_buff *skb;
- int qlen;
-
-- IEEE80211_NODE_SAVEQ_LOCK(ni);
-+ IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni);
- IEEE80211_NODE_SAVEQ_DEQUEUE(ni, skb, qlen);
-- IEEE80211_NODE_SAVEQ_UNLOCK(ni);
-+ IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni);
- if (skb == NULL)
- break;
- /*
-@@ -363,9 +363,9 @@
- for (;;) {
- struct sk_buff *skb;
-
-- IEEE80211_NODE_SAVEQ_LOCK(ni);
-+ IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni);
- skb = __skb_dequeue(&ni->ni_savedq);
-- IEEE80211_NODE_SAVEQ_UNLOCK(ni);
-+ IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni);
- if (skb == NULL)
- break;
- ieee80211_parent_queue_xmit(skb);
-diff -urN madwifi-ng-refcount-r2313-20070505.old/net80211/ieee80211_proto.c madwifi-ng-refcount-r2313-20070505.dev/net80211/ieee80211_proto.c
---- madwifi-ng-refcount-r2313-20070505.old/net80211/ieee80211_proto.c 2007-05-13 18:17:56.578967728 +0200
-+++ madwifi-ng-refcount-r2313-20070505.dev/net80211/ieee80211_proto.c 2007-05-13 18:17:56.600964384 +0200
-@@ -635,9 +635,9 @@
- {
- struct ieee80211com *ic = vap->iv_ic;
-
-- IEEE80211_LOCK(ic);
-+ IEEE80211_BEACON_LOCK(ic);
- ieee80211_wme_initparams_locked(vap);
-- IEEE80211_UNLOCK(ic);
-+ IEEE80211_BEACON_UNLOCK(ic);
- }
-
- void
-@@ -920,9 +920,9 @@
- struct ieee80211com *ic = vap->iv_ic;
-
- if (ic->ic_caps & IEEE80211_C_WME) {
-- IEEE80211_LOCK(ic);
-+ IEEE80211_BEACON_LOCK(ic);
- ieee80211_wme_updateparams_locked(vap);
-- IEEE80211_UNLOCK(ic);
-+ IEEE80211_BEACON_UNLOCK(ic);
- }
- }
-
-diff -urN madwifi-ng-refcount-r2313-20070505.old/net80211/ieee80211_scan_sta.c madwifi-ng-refcount-r2313-20070505.dev/net80211/ieee80211_scan_sta.c
---- madwifi-ng-refcount-r2313-20070505.old/net80211/ieee80211_scan_sta.c 2007-02-01 21:49:37.000000000 +0100
-+++ madwifi-ng-refcount-r2313-20070505.dev/net80211/ieee80211_scan_sta.c 2007-05-13 18:17:56.601964232 +0200
-@@ -163,9 +163,11 @@
- {
- struct sta_table *st = ss->ss_priv;
-
-- spin_lock(&st->st_lock);
-+ if (!irqs_disabled())
-+ spin_lock_bh(&st->st_lock);
- sta_flush_table(st);
-- spin_unlock(&st->st_lock);
-+ if (!irqs_disabled())
-+ spin_unlock_bh(&st->st_lock);
- ss->ss_last = 0;
- return 0;
- }
-@@ -215,7 +217,8 @@
- int hash;
-
- hash = STA_HASH(macaddr);
-- spin_lock(&st->st_lock);
-+ if (!irqs_disabled())
-+ spin_lock_bh(&st->st_lock);
- LIST_FOREACH(se, &st->st_hash[hash], se_hash)
- if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr) &&
- sp->ssid[1] == se->base.se_ssid[1] &&
-@@ -225,7 +228,7 @@
- MALLOC(se, struct sta_entry *, sizeof(struct sta_entry),
- M_80211_SCAN, M_NOWAIT | M_ZERO);
- if (se == NULL) {
-- spin_unlock(&st->st_lock);
-+ spin_unlock_bh(&st->st_lock);
- return 0;
- }
- se->se_scangen = st->st_scangen-1;
-@@ -287,7 +290,8 @@
- se->se_seen = 1;
- se->se_notseen = 0;
-
-- spin_unlock(&st->st_lock);
-+ if (!irqs_disabled())
-+ spin_unlock_bh(&st->st_lock);
-
- /*
- * If looking for a quick choice and nothing's
-@@ -1063,7 +1067,8 @@
- u_int gen;
- int res = 0;
-
-- spin_lock(&st->st_scanlock);
-+ if (!irqs_disabled())
-+ spin_lock_bh(&st->st_scanlock);
- gen = st->st_scangen++;
- restart:
- spin_lock(&st->st_lock);
-@@ -1086,7 +1091,8 @@
- spin_unlock(&st->st_lock);
-
- done:
-- spin_unlock(&st->st_scanlock);
-+ if (!irqs_disabled())
-+ spin_unlock_bh(&st->st_scanlock);
-
- return res;
- }
-@@ -1235,7 +1241,8 @@
- bestchan = NULL;
- bestrssi = -1;
-
-- spin_lock(&st->st_lock);
-+ if (!irqs_disabled())
-+ spin_lock_bh(&st->st_lock);
- for (i = 0; i < ss->ss_last; i++) {
- c = ss->ss_chans[i];
- maxrssi = 0;
-@@ -1248,7 +1255,8 @@
- if (bestchan == NULL || maxrssi < bestrssi)
- bestchan = c;
- }
-- spin_unlock(&st->st_lock);
-+ if (!irqs_disabled())
-+ spin_unlock_bh(&st->st_lock);
-
- return bestchan;
- }