PERFORCE change 119569 for review

Sam Leffler sam at FreeBSD.org
Wed May 9 16:33:25 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=119569

Change 119569 by sam at sam_ebb on 2007/05/09 16:32:56

	add enough 11n support to do monitor mode; needs new hal

Affected files ...

.. //depot/projects/wifi/sys/dev/ath/if_ath.c#140 edit

Differences ...

==== //depot/projects/wifi/sys/dev/ath/if_ath.c#140 (text+ko) ====

@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.166 2007/04/23 05:57:06 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.165 2007/04/19 13:09:56 sephe Exp $");
 
 /*
  * Driver for the Atheros Wireless LAN controller.
@@ -370,6 +370,8 @@
 	ath_rate_setup(sc, IEEE80211_MODE_TURBO_A);
 	ath_rate_setup(sc, IEEE80211_MODE_TURBO_G);
 	ath_rate_setup(sc, IEEE80211_MODE_STURBO_A);
+	ath_rate_setup(sc, IEEE80211_MODE_11NA);
+	ath_rate_setup(sc, IEEE80211_MODE_11NG);
 	ath_rate_setup(sc, IEEE80211_MODE_HALF);
 	ath_rate_setup(sc, IEEE80211_MODE_QUARTER);
 
@@ -957,7 +959,7 @@
 ath_mapchan(HAL_CHANNEL *hc, const struct ieee80211_channel *chan)
 {
 #define	N(a)	(sizeof(a) / sizeof(a[0]))
-	static const u_int modeflags[] = {
+	static const u_int modeflags[IEEE80211_MODE_MAX] = {
 		0,			/* IEEE80211_MODE_AUTO */
 		CHANNEL_A,		/* IEEE80211_MODE_11A */
 		CHANNEL_B,		/* IEEE80211_MODE_11B */
@@ -965,7 +967,9 @@
 		0,			/* IEEE80211_MODE_FH */
 		CHANNEL_108A,		/* IEEE80211_MODE_TURBO_A */
 		CHANNEL_108G,		/* IEEE80211_MODE_TURBO_G */
-		CHANNEL_ST		/* IEEE80211_MODE_STURBO_A */
+		CHANNEL_ST,		/* IEEE80211_MODE_STURBO_A */
+		CHANNEL_A,		/* IEEE80211_MODE_11NA */
+		CHANNEL_PUREG,		/* IEEE80211_MODE_11NG */
 	};
 	enum ieee80211_phymode mode = ieee80211_chan2mode(chan);
 
@@ -976,6 +980,12 @@
 		hc->channelFlags |= CHANNEL_HALF;
 	if (IEEE80211_IS_CHAN_QUARTER(chan))
 		hc->channelFlags |= CHANNEL_QUARTER;
+	if (IEEE80211_IS_CHAN_HT20(chan))
+		hc->channelFlags |= CHANNEL_HT20;
+	if (IEEE80211_IS_CHAN_HT40D(chan))
+		hc->channelFlags |= CHANNEL_HT40MINUS;
+	if (IEEE80211_IS_CHAN_HT40U(chan))
+		hc->channelFlags |= CHANNEL_HT40PLUS;
 
 	hc->channel = IEEE80211_IS_CHAN_GSM(chan) ?
 		2422 + (922 - chan->ic_freq) : chan->ic_freq;
@@ -3417,6 +3427,7 @@
 ath_rx_tap(struct ath_softc *sc, struct mbuf *m,
 	const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf)
 {
+#define	CHANNEL_HT	(CHANNEL_HT20|CHANNEL_HT40PLUS|CHANNEL_HT40MINUS)
 	u_int8_t rix;
 
 	KASSERT(sc->sc_drvbpf != NULL, ("no tap"));
@@ -3430,13 +3441,31 @@
 		sc->sc_stats.ast_rx_tooshort++;
 		return 0;
 	}
-	sc->sc_rx_th.wr_tsf = htole64(ath_extend_tsf(rs->rs_tstamp, tsf));
 	rix = rs->rs_rate;
+	sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate;
 	sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags;
+	if (sc->sc_curchan.channelFlags & CHANNEL_HT) {
+		/*
+		 * For HT operation we must specify the channel
+		 * attributes for each packet since they vary.
+		 * We deduce this by from HT40 bit in the rx
+		 * status and the MCS/legacy rate bit.
+		 */
+		sc->sc_rx_th.wr_chan_flags &= ~IEEE80211_CHAN_HT;
+		if (sc->sc_rx_th.wr_rate & 0x80) {	/* HT rate */
+			/* XXX 40U/40D */
+			sc->sc_rx_th.wr_chan_flags |=
+			    (rs->rs_flags & HAL_RX_2040) ?
+				IEEE80211_CHAN_HT40U : IEEE80211_CHAN_HT20;
+			if ((rs->rs_flags & HAL_RX_GI) == 0)
+				sc->sc_rx_th.wr_flags |=
+				    IEEE80211_RADIOTAP_F_SHORTGI;
+		}
+	}
+	sc->sc_rx_th.wr_tsf = htole64(ath_extend_tsf(rs->rs_tstamp, tsf));
 	if (rs->rs_status & HAL_RXERR_CRC)
 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
 	/* XXX propagate other error flags from descriptor */
-	sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate;
 	sc->sc_rx_th.wr_antsignal = rs->rs_rssi + nf;
 	sc->sc_rx_th.wr_antnoise = nf;
 	sc->sc_rx_th.wr_antenna = rs->rs_antenna;
@@ -3444,6 +3473,7 @@
 	bpf_mtap2(sc->sc_drvbpf, &sc->sc_rx_th, sc->sc_rx_th_len, m);
 
 	return 1;
+#undef CHANNEL_HT
 }
 
 static void
@@ -4964,7 +4994,6 @@
 ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan)
 {
 	enum ieee80211_phymode mode;
-	u_int16_t flags;
 
 	/*
 	 * Change channels and update the h/w rate map
@@ -4978,26 +5007,15 @@
 		mode = ieee80211_chan2mode(chan);
 	if (mode != sc->sc_curmode)
 		ath_setcurmode(sc, mode);
-	/*
-	 * Update BPF state.  NB: ethereal et. al. don't handle
-	 * merged flags well so pick a unique mode for their use.
-	 */
-	if (IEEE80211_IS_CHAN_A(chan))
-		flags = IEEE80211_CHAN_A;
-	else if (IEEE80211_IS_CHAN_ANYG(chan))
-		flags = IEEE80211_CHAN_G;
-	else
-		flags = IEEE80211_CHAN_B;
-	if (IEEE80211_IS_CHAN_TURBO(chan))
-		flags |= IEEE80211_CHAN_TURBO;
-	if (IEEE80211_IS_CHAN_HALF(chan))
-		flags |= IEEE80211_CHAN_HALF;
-	if (IEEE80211_IS_CHAN_QUARTER(chan))
-		flags |= IEEE80211_CHAN_QUARTER;
-	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
-		htole16(chan->ic_freq);
-	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
-		htole16(flags);
+
+	sc->sc_rx_th.wr_chan_flags = htole32(chan->ic_flags);
+	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags;
+	sc->sc_rx_th.wr_chan_freq = htole16(chan->ic_freq);
+	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq;
+	sc->sc_rx_th.wr_chan_ieee = chan->ic_ieee;
+	sc->sc_tx_th.wt_chan_ieee = sc->sc_rx_th.wr_chan_ieee;
+	sc->sc_rx_th.wr_chan_maxpow = chan->ic_maxregpower;
+	sc->sc_tx_th.wt_chan_maxpow = sc->sc_rx_th.wr_chan_maxpow;
 }
 
 /*
@@ -5499,12 +5517,13 @@
 			    c->channel, c->channelFlags, ichan->ic_ieee);
 		ichan->ic_freq = c->channel;
 
-		if (c->channelFlags == CHANNEL_PUREG) {
+		if ((c->channelFlags & CHANNEL_PUREG) == CHANNEL_PUREG) {
 			/*
 			 * Except for AR5211, HAL's PUREG means mixed
 			 * DSSS and OFDM.
 			 */
-			ichan->ic_flags = IEEE80211_CHAN_G;
+			ichan->ic_flags = c->channelFlags &~ CHANNEL_PUREG;
+			ichan->ic_flags |= IEEE80211_CHAN_G;
 		} else {
 			ichan->ic_flags = c->channelFlags;
 		}
@@ -5637,6 +5656,12 @@
 	case IEEE80211_MODE_STURBO_A:
 		rt = ath_hal_getratetable(ah, HAL_MODE_TURBO);
 		break;
+	case IEEE80211_MODE_11NA:
+		rt = ath_hal_getratetable(ah, HAL_MODE_11NA_HT20);
+		break;
+	case IEEE80211_MODE_11NG:
+		rt = ath_hal_getratetable(ah, HAL_MODE_11NG_HT20);
+		break;
 	default:
 		DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid mode %u\n",
 			__func__, mode);
@@ -5690,6 +5715,8 @@
 		}
 		sc->sc_hwmap[i].ieeerate =
 			rt->info[ix].dot11Rate & IEEE80211_RATE_VAL;
+		if (rt->info[ix].phy == IEEE80211_T_HT)
+			sc->sc_hwmap[i].ieeerate |= 0x80;	/* MCS */
 		sc->sc_hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD;
 		if (rt->info[ix].shortPreamble ||
 		    rt->info[ix].phy == IEEE80211_T_OFDM)


More information about the p4-projects mailing list