Index: sys/dev/iwn/if_iwn.c =================================================================== --- sys/dev/iwn/if_iwn.c (revision 285016) +++ sys/dev/iwn/if_iwn.c (working copy) @@ -6503,6 +6503,34 @@ return iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof(cmd), 0); } +static uint32_t +iwn_get_rxon_ht_flags(struct iwn_softc *sc, struct ieee80211_channel *c) +{ + uint32_t htflags = 0; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + if (! IEEE80211_IS_CHAN_HT(c)) + return (0); + + htflags |= IWN_RXON_HT_PROTMODE(ic->ic_curhtprotmode); + + if (IEEE80211_IS_CHAN_HT40(c)) { + switch (ic->ic_curhtprotmode) { + case IEEE80211_HTINFO_OPMODE_HT20PR: + htflags |= IWN_RXON_HT_MODEPURE40; + break; + default: + htflags |= IWN_RXON_HT_MODEMIXED; + break; + } + } + if (IEEE80211_IS_CHAN_HT40D(c)) + htflags |= IWN_RXON_HT_HT40MINUS; + + return (htflags); +} + static int iwn_config(struct iwn_softc *sc) { @@ -6633,7 +6661,12 @@ __func__, sc->rxchainmask, sc->nrxchains); - DPRINTF(sc, IWN_DEBUG_RESET, "%s: setting configuration\n", __func__); + + sc->rxon->flags |= htole32(iwn_get_rxon_ht_flags(sc, ic->ic_curchan)); + + DPRINTF(sc, IWN_DEBUG_RESET, + "%s: setting configuration; flags=0x%08x\n", + __func__, le32toh(sc->rxon->flags)); if (sc->sc_is_scanning) device_printf(sc->sc_dev, "%s: is_scanning set, before RXON\n", @@ -7036,6 +7069,10 @@ sc->rxon->cck_mask = 0x03; sc->rxon->ofdm_mask = 0x15; } + + /* try HT */ + sc->rxon->flags |= htole32(iwn_get_rxon_ht_flags(sc, ic->ic_curchan)); + DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x cck %x ofdm %x\n", sc->rxon->chan, sc->rxon->flags, sc->rxon->cck_mask, sc->rxon->ofdm_mask); @@ -7080,7 +7117,6 @@ struct ieee80211com *ic = ifp->if_l2com; struct ieee80211_node *ni = vap->iv_bss; struct iwn_node_info node; - uint32_t htflags = 0; int error; DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); @@ -7119,25 +7155,11 @@ sc->rxon->cck_mask = 0x0f; sc->rxon->ofdm_mask = 0x15; } - if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) { - htflags |= IWN_RXON_HT_PROTMODE(ic->ic_curhtprotmode); - if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { - switch (ic->ic_curhtprotmode) { - case IEEE80211_HTINFO_OPMODE_HT20PR: - htflags |= IWN_RXON_HT_MODEPURE40; - break; - default: - htflags |= IWN_RXON_HT_MODEMIXED; - break; - } - } - if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan)) - htflags |= IWN_RXON_HT_HT40MINUS; - } - sc->rxon->flags |= htole32(htflags); + /* try HT */ + sc->rxon->flags |= htole32(iwn_get_rxon_ht_flags(sc, ni->ni_chan)); sc->rxon->filter |= htole32(IWN_FILTER_BSS); - DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x\n", - sc->rxon->chan, sc->rxon->flags); + DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x, curhtprotmode=%d\n", + sc->rxon->chan, le32toh(sc->rxon->flags), ic->ic_curhtprotmode); if (sc->sc_is_scanning) device_printf(sc->sc_dev, "%s: is_scanning set, before RXON\n", Index: sys/dev/iwn/if_iwnreg.h =================================================================== --- sys/dev/iwn/if_iwnreg.h (revision 285016) +++ sys/dev/iwn/if_iwnreg.h (working copy) @@ -586,9 +586,13 @@ #define IWN_RXON_ANTENNA_B (1 << 9) #define IWN_RXON_TSF (1 << 15) #define IWN_RXON_HT_HT40MINUS (1 << 22) + #define IWN_RXON_HT_PROTMODE(x) (x << 23) + +/* 0=legacy, 1=pure40, 2=mixed */ #define IWN_RXON_HT_MODEPURE40 (1 << 25) #define IWN_RXON_HT_MODEMIXED (2 << 25) + #define IWN_RXON_CTS_TO_SELF (1 << 30) uint32_t filter;