Index: madwifi-ng-r2420-20070602/ath/if_ath.c
===================================================================
--- madwifi-ng-r2420-20070602.orig/ath/if_ath.c	2007-06-04 13:21:56.911324832 +0200
+++ madwifi-ng-r2420-20070602/ath/if_ath.c	2007-06-04 13:21:57.500235304 +0200
@@ -407,7 +407,6 @@
  * and use the next two bits as the index of the VAP.
  */
 #define ATH_SET_VAP_BSSID_MASK(bssid_mask)      ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
-#define ATH_GET_VAP_ID(bssid)                   ((bssid)[0] >> 2)
 #define ATH_SET_VAP_BSSID(bssid, id) \
 		do { \
 			if (id) \
@@ -1048,9 +1047,12 @@
 			ic_opmode = opmode;
 		break;
 	case IEEE80211_M_IBSS:
-		if (sc->sc_nvaps != 0)		/* only one */
-			return NULL;
-		ic_opmode = opmode;
+		if (sc->sc_nvaps == 0)		/* only one */
+			ic_opmode = opmode;
+		else
+			ic_opmode = IEEE80211_M_HOSTAP;
+
+		sc->sc_nibssvaps++;
 		break;
 	case IEEE80211_M_AHDEMO:
 	case IEEE80211_M_MONITOR:
@@ -1080,7 +1082,7 @@
 		return NULL;
 	}
 
-	if (sc->sc_nvaps >= ATH_BCBUF) {
+	if (sc->sc_nvaps + sc->sc_nibssvaps >= ATH_BCBUF) {
 		printk(KERN_WARNING "too many virtual ap's (already got %d)\n", sc->sc_nvaps);
 		return NULL;
 	}
@@ -1115,8 +1117,9 @@
 	 */
 	if (opmode == IEEE80211_M_MONITOR)
 		dev->type = ARPHRD_IEEE80211_RADIOTAP;
-	if ((flags & IEEE80211_CLONE_BSSID) &&
-	    sc->sc_nvaps != 0 && opmode != IEEE80211_M_WDS && sc->sc_hasbmask) {
+	avp->av_bslot = -1;
+	if ((flags & IEEE80211_CLONE_BSSID) && sc->sc_hasbmask && 
+	    (opmode == IEEE80211_M_HOSTAP || opmode == IEEE80211_M_IBSS)) {
 		struct ieee80211vap *v;
 		unsigned int id_mask, id;
 
@@ -1129,18 +1132,22 @@
 
 		/* do a full search to mark all the allocated VAPs */
 		id_mask = 0;
-		TAILQ_FOREACH(v, &ic->ic_vaps, iv_next)
-			id_mask |= (1 << ATH_GET_VAP_ID(v->iv_myaddr));
+		TAILQ_FOREACH(v, &ic->ic_vaps, iv_next) {
+			struct ath_vap *a = (struct ath_vap *) v->iv_dev->priv;
+			if (a->av_bslot >= 0)
+				id_mask |= (1 << a->av_bslot);
+		}
 
-		for (id = 0; id < ATH_BCBUF; id++) {
+		/* IBSS mode has local always set, so don't hand out beacon slot 0 to an IBSS vap */
+		for (id = (opmode == IEEE80211_M_IBSS ? 1 : 0); id < ATH_BCBUF; id++) {
 			/* get the first available slot */
 			if ((id_mask & (1 << id)) == 0) {
 				ATH_SET_VAP_BSSID(vap->iv_myaddr, id);
+				avp->av_bslot = id;
 				break;
 			}
 		}
 	}
-	avp->av_bslot = -1;
 	STAILQ_INIT(&avp->av_mcastq.axq_q);
 	ATH_TXQ_LOCK_INIT(&avp->av_mcastq);
 	if (opmode == IEEE80211_M_HOSTAP || opmode == IEEE80211_M_IBSS) {
@@ -1150,33 +1157,14 @@
 		 */
 		avp->av_bcbuf = STAILQ_FIRST(&sc->sc_bbuf);
 		STAILQ_REMOVE_HEAD(&sc->sc_bbuf, bf_list);
-		if (opmode == IEEE80211_M_HOSTAP || !sc->sc_hasveol) {
+		if ((opmode == IEEE80211_M_IBSS) || (opmode == IEEE80211_M_HOSTAP) || !sc->sc_hasveol) {
 			unsigned int slot;
-			/*
-			 * Assign the VAP to a beacon xmit slot.  As
-			 * above, this cannot fail to find one.
-			 */
-			avp->av_bslot = 0;
-			for (slot = 0; slot < ATH_BCBUF; slot++)
-				if (sc->sc_bslot[slot] == NULL) {
-					/*
-					 * XXX hack, space out slots to better
-					 * deal with misses
-					 */
-					if (slot + 1 < ATH_BCBUF &&
-					    sc->sc_bslot[slot+1] == NULL) {
-						avp->av_bslot = slot + 1;
-						break;
-					}
-					avp->av_bslot = slot;
-					/* NB: keep looking for a double slot */
-				}
 			KASSERT(sc->sc_bslot[avp->av_bslot] == NULL,
 				("beacon slot %u not empty?", avp->av_bslot));
 			sc->sc_bslot[avp->av_bslot] = vap;
 			sc->sc_nbcnvaps++;
 		}
-		if ((opmode == IEEE80211_M_HOSTAP) && (sc->sc_hastsfadd)) {
+		if ((sc->sc_opmode == IEEE80211_M_HOSTAP) && (sc->sc_hastsfadd)) {
 			/*
 			 * Multiple VAPs are to transmit beacons and we
 			 * have h/w support for TSF adjusting; enable use
@@ -1286,7 +1274,9 @@
 			sc->sc_stagbeacons = 0;
 	}
 
-	if (vap->iv_opmode == IEEE80211_M_STA) {
+	if (vap->iv_opmode == IEEE80211_M_IBSS) {
+		sc->sc_nibssvaps--;	
+	} else if (vap->iv_opmode == IEEE80211_M_STA) {
 		sc->sc_nstavaps--;
 		sc->sc_nostabeacons = 0;
 	} else if (vap->iv_opmode == IEEE80211_M_MONITOR)
@@ -3362,7 +3352,7 @@
 	    sc->sc_opmode == HAL_M_IBSS ||	/* NB: AHDEMO too */
 	    (sc->sc_nostabeacons) || sc->sc_scanning)
 		rfilt |= HAL_RX_FILTER_BEACON;
-	if (sc->sc_nmonvaps > 0)
+	if ((sc->sc_nmonvaps > 0) || ((sc->sc_nvaps > 0) && (sc->sc_nibssvaps > 0)))
 		rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
 			  HAL_RX_FILTER_PROBEREQ | HAL_RX_FILTER_PROM);
 	return rfilt;
@@ -5809,12 +5799,20 @@
 			type = ieee80211_input(ni, skb, rs->rs_rssi, rs->rs_tstamp);
 			ieee80211_unref_node(&ni);
 		} else {
+			const struct ieee80211_frame_min *wh = (const struct ieee80211_frame_min *) skb->data;
 			/*
 			 * No key index or no entry, do a lookup and
 			 * add the node to the mapping table if possible.
 			 */
-			ni = ieee80211_find_rxnode(ic,
-				(const struct ieee80211_frame_min *) skb->data);
+			if (((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PROBE_REQ) &&
+					(sc->sc_nibssvaps > 0))
+				/* if this is a probe request, send it to all vaps
+				 * when looking up nodes, hostap will be preferred over ibss,
+				 * because ibss will catch all nodes */
+				ni = NULL;
+			else
+				ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
+
 			if (ni != NULL) {
 				struct ath_node *an = ATH_NODE(ni);
 				ieee80211_keyix_t keyix;
Index: madwifi-ng-r2420-20070602/ath/if_athvar.h
===================================================================
--- madwifi-ng-r2420-20070602.orig/ath/if_athvar.h	2007-06-04 13:21:56.911324832 +0200
+++ madwifi-ng-r2420-20070602/ath/if_athvar.h	2007-06-04 13:21:57.500235304 +0200
@@ -199,7 +199,7 @@
 #define	ATH_RXBUF	40		/* number of RX buffers */
 #define	ATH_TXBUF	200		/* number of TX buffers */
 
-#define	ATH_BCBUF	4		/* number of beacon buffers */
+#define	ATH_BCBUF	8		/* number of beacon buffers */
 
 /* free buffer threshold to restart net dev */
 #define	ATH_TXBUF_FREE_THRESHOLD  (ATH_TXBUF / 20)
@@ -594,6 +594,7 @@
 	u_int16_t sc_nvaps;			/* # of active virtual ap's */
 	u_int8_t sc_nstavaps;			/* # of active station vaps */
 	u_int8_t sc_nmonvaps;			/* # of monitor vaps */
+	u_int8_t sc_nibssvaps;			/* # of active ibss vaps */
 	u_int8_t sc_nbcnvaps;			/* # of vaps sending beacons */
 	u_int sc_fftxqmin;			/* aggregation threshold */
 	HAL_INT sc_imask;			/* interrupt mask copy */
Index: madwifi-ng-r2420-20070602/net80211/ieee80211_beacon.c
===================================================================
--- madwifi-ng-r2420-20070602.orig/net80211/ieee80211_beacon.c	2007-06-04 13:21:53.286875832 +0200
+++ madwifi-ng-r2420-20070602/net80211/ieee80211_beacon.c	2007-06-04 13:21:57.501235152 +0200
@@ -111,7 +111,7 @@
 	bo->bo_tim = frm;
 
 	/* IBSS/TIM */
-	if (vap->iv_opmode == IEEE80211_M_IBSS) {
+	if (ic->ic_opmode == IEEE80211_M_IBSS) {
 		*frm++ = IEEE80211_ELEMID_IBSSPARMS;
 		*frm++ = 2;
 		*frm++ = 0; *frm++ = 0;		/* TODO: ATIM window */
Index: madwifi-ng-r2420-20070602/net80211/ieee80211_input.c
===================================================================
--- madwifi-ng-r2420-20070602.orig/net80211/ieee80211_input.c	2007-06-04 13:21:53.292874920 +0200
+++ madwifi-ng-r2420-20070602/net80211/ieee80211_input.c	2007-06-04 13:21:57.502235000 +0200
@@ -2939,7 +2939,13 @@
 			return;
 		}
 		if (ni == vap->iv_bss) {
-			if (vap->iv_opmode == IEEE80211_M_IBSS) {
+			/* this probe request may have been sent to all vaps
+			 * to give each a chance of creating a node for this.
+			 * important for hostap+ibss mode */
+			ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
+			if (ni) {
+				allocbs = 0;
+			} else if (vap->iv_opmode == IEEE80211_M_IBSS) {
 				/*
 				 * XXX Cannot tell if the sender is operating
 				 * in ibss mode.  But we need a new node to
@@ -2948,12 +2954,13 @@
 				 */
 				ni = ieee80211_fakeup_adhoc_node(vap,
 					wh->i_addr2);
+				allocbs = 1;
 			} else {
 				ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
+				allocbs = 1;
 			}
 			if (ni == NULL)
 				return;
-			allocbs = 1;
 		}
 
 		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
Index: madwifi-ng-r2420-20070602/net80211/ieee80211_node.c
===================================================================
--- madwifi-ng-r2420-20070602.orig/net80211/ieee80211_node.c	2007-06-04 13:21:55.391555872 +0200
+++ madwifi-ng-r2420-20070602/net80211/ieee80211_node.c	2007-06-04 13:21:57.503234848 +0200
@@ -1082,8 +1082,25 @@
 	IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
 
 	hash = IEEE80211_NODE_HASH(macaddr);
+	
+	/* look for non-ibss nodes first */
 	LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
-		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
+		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr) && ni->ni_vap->iv_opmode != IEEE80211_M_IBSS) {
+			ieee80211_ref_node(ni);	/* mark referenced */
+#ifdef IEEE80211_DEBUG_REFCNT
+			IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,
+				"%s (%s:%u) %p<%s> refcnt %d\n", __func__,
+				func, line,
+				ni, ether_sprintf(ni->ni_macaddr),
+				ieee80211_node_refcnt(ni));
+#endif
+			return ni;
+		}
+	}
+
+	/* now look for ibss nodes */
+	LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
+		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr) && ni->ni_vap->iv_opmode == IEEE80211_M_IBSS) {
 			ieee80211_ref_node(ni);	/* mark referenced */
 #ifdef IEEE80211_DEBUG_REFCNT
 			IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,
