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