From owner-p4-projects@FreeBSD.ORG Wed May 9 16:33:25 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B664116A584; Wed, 9 May 2007 16:33:24 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 8CEE516A548 for ; Wed, 9 May 2007 16:33:24 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 7878A13C469 for ; Wed, 9 May 2007 16:33:24 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l49GXOU8002944 for ; Wed, 9 May 2007 16:33:24 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l49GXOLP002940 for perforce@freebsd.org; Wed, 9 May 2007 16:33:24 GMT (envelope-from sam@freebsd.org) Date: Wed, 9 May 2007 16:33:24 GMT Message-Id: <200705091633.l49GXOLP002940@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 119569 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 May 2007 16:33:25 -0000 http://perforce.freebsd.org/chv.cgi?CH=119569 Change 119569 by sam@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 -__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)