From ade5fbb745749adb5f4c3480ce8feeb5efdf9c7d Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 13 Nov 2013 07:09:00 +0000 Subject: [PATCH] Correctly initialise the 2-chain antenna mask in the link quality table. The previous code simply hard-coded IWN_ANT_AB which is only correct for some of the NICs. Now, if the NIC is a 1-stream TX, you need to set IWN_ANT_AB and _not_ just a single antenna. The Intel 5100 firmware panics the moment the link quality table is updated. So! * no secondary antenna? Set it to IWN_ANT_AB; * two-stream device? Transmit on the full transmit antenna configuration. Tested: * Intel 5100, STA * Intel 2200 (eadler) Obtained from: Linux iwlwifi --- sys/dev/iwn/if_iwn.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 620ecfb39b9..b20b80bed87 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -4788,11 +4788,49 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni) memset(&linkq, 0, sizeof linkq); linkq.id = wn->id; linkq.antmsk_1stream = txant; - linkq.antmsk_2stream = IWN_ANT_AB; + + /* + * The '2 stream' setup is a bit .. odd. + * + * For NICs that support only 1 antenna, default to IWN_ANT_AB or + * the firmware panics (eg Intel 5100.) + * + * For NICs that support two antennas, we use ANT_AB. + * + * For NICs that support three antennas, we use the two that + * wasn't the default one. + * + * XXX TODO: if bluetooth (full concurrent) is enabled, restrict + * this to only one antenna. + */ + + /* So - if there's no secondary antenna, assume IWN_ANT_AB */ + + /* Default - transmit on the other antennas */ + linkq.antmsk_2stream = (sc->txchainmask & ~IWN_LSB(sc->txchainmask)); + + /* Now, if it's zero, set it to IWN_ANT_AB, so to not panic firmware */ + if (linkq.antmsk_2stream == 0) + linkq.antmsk_2stream = IWN_ANT_AB; + + /* + * If the NIC is a two-stream TX NIC, configure the TX mask to + * the default chainmask + */ + else if (sc->ntxchains == 2) + linkq.antmsk_2stream = sc->txchainmask; + linkq.ampdu_max = 32; /* XXX negotiated? */ linkq.ampdu_threshold = 3; linkq.ampdu_limit = htole16(4000); /* 4ms */ + DPRINTF(sc, IWN_DEBUG_XMIT, + "%s: 1stream antenna=0x%02x, 2stream antenna=0x%02x, ntxstreams=%d\n", + __func__, + linkq.antmsk_1stream, + linkq.antmsk_2stream, + sc->ntxchains); + /* * Are we using 11n rates? Ensure the channel is * 11n _and_ we have some 11n rates, or don't