From owner-svn-src-all@FreeBSD.ORG Tue Nov 12 05:49:02 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 ESMTPS id 630C79FF; Tue, 12 Nov 2013 05:49:02 +0000 (UTC) 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 5274920FC; Tue, 12 Nov 2013 05:49:02 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rAC5n2Fp093143; Tue, 12 Nov 2013 05:49:02 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rAC5n2wc093142; Tue, 12 Nov 2013 05:49:02 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201311120549.rAC5n2wc093142@svn.freebsd.org> From: Adrian Chadd Date: Tue, 12 Nov 2013 05:49:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r258034 - 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.16 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: Tue, 12 Nov 2013 05:49:02 -0000 Author: adrian Date: Tue Nov 12 05:49:01 2013 New Revision: 258034 URL: http://svnweb.freebsd.org/changeset/base/258034 Log: Fix up the link quality lookup and re-enable multi-rate retry. This is a terrible solution that at least behaves mostly correctly. It walks the currently active rate table looking for rates to match. It assumes that the code matches the setup path in the link quality setup code (much like the previous, much simpler but even more hackish math did.) It's O(n), but n<15, so we're okay for the time being. Tested: * Intel 5100, STA - 11a, 11n, 11bg modes. Modified: head/sys/dev/iwn/if_iwn.c Modified: head/sys/dev/iwn/if_iwn.c ============================================================================== --- head/sys/dev/iwn/if_iwn.c Tue Nov 12 05:08:24 2013 (r258033) +++ head/sys/dev/iwn/if_iwn.c Tue Nov 12 05:49:01 2013 (r258034) @@ -3570,6 +3570,66 @@ iwn_check_rate_needs_protection(struct i return (1); } +/* + * return a value between 0 and IWN_MAX_TX_RETRIES-1 as an index into + * the link quality table that reflects this particular entry. + */ +static int +iwn_tx_rate_to_linkq_offset(struct iwn_softc *sc, struct ieee80211_node *ni, + uint8_t rate) +{ + struct ieee80211_rateset *rs; + int is_11n; + int nr; + int i; + uint8_t cmp_rate; + + /* + * Figure out if we're using 11n or not here. + */ + if (IEEE80211_IS_CHAN_HT(ni->ni_chan) && ni->ni_htrates.rs_nrates > 0) + is_11n = 1; + else + is_11n = 0; + + /* + * Use the correct rate table. + */ + if (is_11n) { + rs = (struct ieee80211_rateset *) &ni->ni_htrates; + nr = ni->ni_htrates.rs_nrates; + } else { + rs = &ni->ni_rates; + nr = rs->rs_nrates; + } + + /* + * Find the relevant link quality entry in the table. + */ + for (i = 0; i < nr && i < IWN_MAX_TX_RETRIES - 1 ; i++) { + /* + * The link quality table index starts at 0 == highest + * rate, so we walk the rate table backwards. + */ + cmp_rate = rs->rs_rates[(nr - 1) - i]; + if (rate & IEEE80211_RATE_MCS) + cmp_rate |= IEEE80211_RATE_MCS; + + DPRINTF(sc, IWN_DEBUG_XMIT, "%s: idx %d: nr=%d, rate=0x%02x, rateentry=0x%02x\n", + __func__, + i, + nr, + rate, + cmp_rate); + + if (cmp_rate == rate) + return (i); + } + + /* Failed? Start at the end */ + return (IWN_MAX_TX_RETRIES - 1); +} + static int iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) { @@ -3750,29 +3810,14 @@ 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; - /* XXX Alternate between antenna A and B? */ - 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; + tx->linkq = iwn_tx_rate_to_linkq_offset(sc, ni, rate); 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);