diff -ur ../madwifi-cvs-20050707/ath/if_ath.c ./ath/if_ath.c
--- ../madwifi-cvs-20050707/ath/if_ath.c	2005-06-25 02:35:12.000000000 +0200
+++ ./ath/if_ath.c	2005-07-30 00:27:46.000000000 +0200
@@ -1117,7 +1117,8 @@
 	/*
 	 * Encapsulate the packet for transmission.
 	 */
-	skb = ieee80211_encap(ic, skb, &ni);
+	if (ic->ic_opmode != IEEE80211_M_MONITOR)
+		skb = ieee80211_encap(ic, skb, &ni);
 	if (skb == NULL) {
 		DPRINTF(sc, ATH_DEBUG_XMIT,
 			"%s: discard, encapsulation failure\n", __func__);
@@ -2830,7 +2831,7 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 	int iswep, ismcast, keyix, hdrlen, pktlen, try0;
-	u_int8_t rix, txrate, ctsrate;
+	u_int8_t rix = 0, txrate, ctsrate;
 	u_int8_t cix = 0xff;		/* NB: silence compiler */
 	struct ath_desc *ds;
 	struct ath_txq *txq;
@@ -2847,7 +2848,7 @@
 	hdrlen = ieee80211_anyhdrsize(wh);
 	pktlen = skb->len;
 
-	if (iswep) {
+	if (iswep && ic->ic_opmode != IEEE80211_M_MONITOR) {
 		const struct ieee80211_cipher *cip;
 		struct ieee80211_key *k;
 
@@ -2909,7 +2910,7 @@
 	 * use short preamble based on the current mode and
 	 * negotiated parameters.
 	 */
-	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
+	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && ni != NULL &&
 	    (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
 		shortPreamble = AH_TRUE;
 		sc->sc_stats.ast_tx_shortpre++;
@@ -2924,6 +2925,11 @@
 	 */
 	switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
 	case IEEE80211_FC0_TYPE_MGT:
+		if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+			atype = HAL_PKT_TYPE_NORMAL;
+			txq = sc->sc_ac2q[skb->priority];
+			break;
+		}
 		subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 		if (subtype == IEEE80211_FC0_SUBTYPE_BEACON)
 			atype = HAL_PKT_TYPE_BEACON;
@@ -2943,6 +2949,11 @@
 		txq = sc->sc_ac2q[WME_AC_VO];
 		break;
 	case IEEE80211_FC0_TYPE_CTL:
+		if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+			atype = HAL_PKT_TYPE_NORMAL;
+			txq = sc->sc_ac2q[skb->priority];
+			break;
+		}
 		atype = HAL_PKT_TYPE_PSPOLL;	/* stop setting of duration */
 		rix = 0;			/* XXX lowest rate */
 		try0 = ATH_TXMAXTRY;
@@ -2958,8 +2969,9 @@
 		/*
 		 * Data frames; consult the rate control module.
 		 */
-		ath_rate_findrate(sc, an, shortPreamble, skb->len,
-			&rix, &try0, &txrate);
+		if (ic->ic_opmode != IEEE80211_M_MONITOR)
+			ath_rate_findrate(sc, an, shortPreamble, skb->len,
+					  &rix, &try0, &txrate);
 		/*
 		 * Default all non-QoS traffic to the background queue.
 		 */
@@ -2970,6 +2982,11 @@
 			txq = sc->sc_ac2q[WME_AC_BK];
 		break;
 	default:
+		if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+			atype = HAL_PKT_TYPE_NORMAL;
+			txq = sc->sc_ac2q[skb->priority];
+			break;
+		}
 		printk("%s: bogus frame type 0x%x (%s)\n", dev->name,
 			wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
 		/* XXX statistic */
@@ -3092,6 +3109,17 @@
 		txq->axq_intrcnt = 0;
 	}
 
+	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+		int i;
+		try0 = 1;   /* no retransmissions */
+		txrate = 0;
+		rt = sc->sc_rates[IEEE80211_MODE_11G];
+                for (i = 0; i < rt->rateCount; i++) {
+                        if (rt->info[i].rateKbps == ic->inject_rate)
+                                txrate = rt->info[i].rateCode;
+                }
+	}
+
 	/*
 	 * Formulate first tx descriptor with tx controls.
 	 */
@@ -3100,7 +3128,7 @@
 		, pktlen		/* packet length */
 		, hdrlen		/* header length */
 		, atype			/* Atheros packet type */
-		, MIN(ni->ni_txpower,60)/* txpower */
+		, 60                    /* txpower */
 		, txrate, try0		/* series 0 rate/tries */
 		, keyix			/* key cache index */
 		, sc->sc_txantenna	/* antenna mode */
@@ -3115,7 +3143,7 @@
 	 * when the hardware supports multi-rate retry and
 	 * we don't use it.
 	 */
-	if (try0 != ATH_TXMAXTRY)
+	if (try0 != ATH_TXMAXTRY && ic->ic_opmode != IEEE80211_M_MONITOR)
 		ath_rate_setupxtxdesc(sc, an, ds, shortPreamble, rix);
 
 	ds->ds_link = 0;
Only in ./ath: if_ath.c.orig
diff -ur ../madwifi-cvs-20050707/net80211/ieee80211_var.h ./net80211/ieee80211_var.h
--- ../madwifi-cvs-20050707/net80211/ieee80211_var.h	2005-02-16 17:09:03.000000000 +0100
+++ ./net80211/ieee80211_var.h	2005-07-29 22:43:08.000000000 +0200
@@ -307,6 +307,8 @@
 	 */
 	const struct ieee80211_aclator *ic_acl;
 	void			*ic_as;
+
+	int inject_rate;	/* injection rate in Monitor mode */
 };
 
 #define	IEEE80211_ADDR_EQ(a1,a2)	(memcmp(a1,a2,IEEE80211_ADDR_LEN) == 0)
diff -ur ../madwifi-cvs-20050707/net80211/ieee80211_wireless.c ./net80211/ieee80211_wireless.c
--- ../madwifi-cvs-20050707/net80211/ieee80211_wireless.c	2005-03-07 17:35:09.000000000 +0100
+++ ./net80211/ieee80211_wireless.c	2005-07-29 22:50:42.000000000 +0200
@@ -328,6 +328,18 @@
 	struct ifreq ifr;
 	int rate;
 
+	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+		rate = rrq->value / 1000;
+		if (rate !=  1000 && rate !=  2000 && rate !=  5500 &&
+		    rate != 11000 && rate !=  6000 && rate !=  9000 &&
+		    rate != 12000 && rate != 18000 && rate != 24000 &&
+		    rate != 36000 && rate != 48000 && rate != 54000 )
+		    return -EINVAL;
+		printk(KERN_DEBUG "setting xmit rate to %d\n", rate);
+		ic->inject_rate = rate;
+		return 0;
+	}
+
 	if (!ic->ic_media.ifm_cur)
 		return -EINVAL;
 	memset(&ifr, 0, sizeof(ifr));
@@ -354,6 +366,11 @@
 	struct ifmediareq imr;
 	int rate;
 
+	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+		rrq->value = ic->inject_rate * 1000;
+		return 0;
+	}
+
 	memset(&imr, 0, sizeof(imr));
 	(*ic->ic_media.ifm_status)(ic->ic_dev, &imr);
 
@@ -782,6 +799,7 @@
 #if WIRELESS_EXT >= 15
 	case IW_MODE_MONITOR:
 		ifr.ifr_media |= IFM_IEEE80211_MONITOR;
+		ic->inject_rate = 5500; /* default = 5.5M DSSS */
 		break;
 #endif
 	default:
