From owner-svn-src-all@FreeBSD.ORG Fri Oct 25 19:44:54 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 507CA9D2; Fri, 25 Oct 2013 19:44:54 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 3C47E2D54; Fri, 25 Oct 2013 19:44:54 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r9PJismS004420; Fri, 25 Oct 2013 19:44:54 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r9PJis6q004419; Fri, 25 Oct 2013 19:44:54 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201310251944.r9PJis6q004419@svn.freebsd.org> From: Adrian Chadd Date: Fri, 25 Oct 2013 19:44:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r257133 - head/sys/dev/iwn X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Oct 2013 19:44:54 -0000 Author: adrian Date: Fri Oct 25 19:44:53 2013 New Revision: 257133 URL: http://svnweb.freebsd.org/changeset/base/257133 Log: Temporarily disable multi-rate retry (link quality) and eliminate rate index lookups. * My recent(ish) change to iwn(4) and the net80211 rate control API to support 11n rates broke the link quality table use. So, until I or someone else decides to fix it, let's just disable it for now. * Teach iwn_tx_data_raw() to use the iwn_rate_to_plcp() function. * Eliminate two uses of the net80211 rate index lookup functions - they are only for legacy rates and they're not needed here. This fixes some invalid looking rate control TX issues that showed up on my 4965 but it doesn't fix the two TX hangs I've noticed. Those look like DMA related issues. Tested: * 4965, STA mode * 5100, STA mode Modified: head/sys/dev/iwn/if_iwn.c Modified: head/sys/dev/iwn/if_iwn.c ============================================================================== --- head/sys/dev/iwn/if_iwn.c Fri Oct 25 19:39:22 2013 (r257132) +++ head/sys/dev/iwn/if_iwn.c Fri Oct 25 19:44:53 2013 (r257133) @@ -3476,6 +3476,53 @@ iwn5000_reset_sched(struct iwn_softc *sc } #endif +/* + * Check whether OFDM 11g protection will be enabled for the given rate. + * + * The original driver code only enabled protection for OFDM rates. + * It didn't check to see whether it was operating in 11a or 11bg mode. + */ +static int +iwn_check_rate_needs_protection(struct iwn_softc *sc, + struct ieee80211vap *vap, uint8_t rate) +{ + struct ieee80211com *ic = vap->iv_ic; + + /* + * Not in 2GHz mode? Then there's no need to enable OFDM + * 11bg protection. + */ + if (! IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { + return (0); + } + + /* + * 11bg protection not enabled? Then don't use it. + */ + if ((ic->ic_flags & IEEE80211_F_USEPROT) == 0) + return (0); + + /* + * If it's an 11n rate, then for now we enable + * protection. + */ + if (rate & IEEE80211_RATE_MCS) { + return (1); + } + + /* + * Do a rate table lookup. If the PHY is CCK, + * don't do protection. + */ + if (ieee80211_rate2phytype(ic->ic_rt, rate) == IEEE80211_T_CCK) + return (0); + + /* + * Yup, enable protection. + */ + return (1); +} + static int iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) { @@ -3496,7 +3543,7 @@ iwn_tx_data(struct iwn_softc *sc, struct uint16_t qos; u_int hdrlen; bus_dma_segment_t *seg, segs[IWN_MAX_SCATTER]; - uint8_t tid, ridx, txant, type; + uint8_t tid, type; int ac, i, totlen, error, pad, nsegs = 0, rate; DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); @@ -3546,8 +3593,6 @@ iwn_tx_data(struct iwn_softc *sc, struct (void) ieee80211_ratectl_rate(ni, NULL, 0); rate = ni->ni_txrate; } - ridx = ieee80211_legacy_rate_lookup(ic->ic_rt, - rate & IEEE80211_RATE_VAL); /* Encrypt the frame if need be. */ if (wh->i_fc[1] & IEEE80211_FC1_WEP) { @@ -3604,13 +3649,15 @@ iwn_tx_data(struct iwn_softc *sc, struct /* NB: Group frames are sent using CCK in 802.11b/g. */ if (totlen + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) { flags |= IWN_TX_NEED_RTS; - } else if ((ic->ic_flags & IEEE80211_F_USEPROT) && - ridx >= IWN_RIDX_OFDM6) { + } else if (iwn_check_rate_needs_protection(sc, vap, rate)) { if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) flags |= IWN_TX_NEED_CTS; else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) flags |= IWN_TX_NEED_RTS; } + + /* XXX HT protection? */ + if (flags & (IWN_TX_NEED_RTS | IWN_TX_NEED_CTS)) { if (sc->hw_type != IWN_HW_REV_TYPE_4965) { /* 5000 autoselects RTS/CTS or CTS-to-self. */ @@ -3654,6 +3701,7 @@ iwn_tx_data(struct iwn_softc *sc, struct tx->data_ntries = 15; tx->lifetime = htole32(IWN_LIFETIME_INFINITE); tx->rate = iwn_rate_to_plcp(sc, ni, rate); +#if 0 if (tx->id == sc->broadcast_id) { /* Group or management frame. */ tx->linkq = 0; @@ -3661,9 +3709,21 @@ iwn_tx_data(struct iwn_softc *sc, struct txant = IWN_LSB(sc->txchainmask); tx->rate |= htole32(IWN_RFLAG_ANT(txant)); } else { + /* + * XXX This is no longer true. ni_rates may actually + * XXX need to be ni_htrates (for 11n rates) and thus + * XXX ridx is totally bogus here. + * + * XXX So, break this out into a function and look up + * XXX the correct place to start the MRR table rate + * XXX attempt. + */ tx->linkq = ni->ni_rates.rs_nrates - ridx - 1; flags |= IWN_TX_LINKQ; /* enable MRR */ } +#else + tx->linkq = 0; /* Don't enable MRR for now */ +#endif /* Set physical address of "scratch area". */ tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr)); tx->hiaddr = IWN_HIADDR(data->scratch_paddr); @@ -3756,9 +3816,9 @@ iwn_tx_data_raw(struct iwn_softc *sc, st struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { struct iwn_ops *ops = &sc->ops; - struct ifnet *ifp = sc->sc_ifp; +// struct ifnet *ifp = sc->sc_ifp; struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ifp->if_l2com; +// struct ieee80211com *ic = ifp->if_l2com; struct iwn_tx_cmd *cmd; struct iwn_cmd_data *tx; struct ieee80211_frame *wh; @@ -3770,7 +3830,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, st uint32_t flags; u_int hdrlen; int ac, totlen, error, pad, nsegs = 0, i, rate; - uint8_t ridx, type, txant; + uint8_t type; DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); @@ -3786,16 +3846,8 @@ iwn_tx_data_raw(struct iwn_softc *sc, st desc = &ring->desc[ring->cur]; data = &ring->data[ring->cur]; - /* Choose a TX rate index. */ + /* Choose a TX rate. */ rate = params->ibp_rate0; - ridx = ieee80211_legacy_rate_lookup(ic->ic_rt, - rate & IEEE80211_RATE_VAL); - if (ridx == (uint8_t)-1) { - /* XXX fall back to mcast/mgmt rate? */ - m_freem(m); - return EINVAL; - } - totlen = m->m_pkthdr.len; /* Prepare TX firmware command. */ @@ -3865,17 +3917,10 @@ iwn_tx_data_raw(struct iwn_softc *sc, st tx->rts_ntries = params->ibp_try1; tx->data_ntries = params->ibp_try0; tx->lifetime = htole32(IWN_LIFETIME_INFINITE); - - /* XXX should just use iwn_rate_to_plcp() */ - tx->rate = htole32(rate2plcp(rate)); - if (ridx < IWN_RIDX_OFDM6 && - IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) - tx->rate |= htole32(IWN_RFLAG_CCK); + tx->rate = iwn_rate_to_plcp(sc, ni, rate); /* Group or management frame. */ tx->linkq = 0; - txant = IWN_LSB(sc->txchainmask); - tx->rate |= htole32(IWN_RFLAG_ANT(txant)); /* Set physical address of "scratch area". */ tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));