diff options
author | 2020-07-20 08:19:59 +0000 | |
---|---|---|
committer | 2020-07-20 08:19:59 +0000 | |
commit | 5ed5d284388b1e82e0f3a95f71f179b3407ff7d6 (patch) | |
tree | 5177c9badb950234e602d101c5117d5aa67d332c /sys | |
parent | Add powerpc64 to PIE_ARCH and STATICPIE_ARCH. (diff) | |
download | wireguard-openbsd-5ed5d284388b1e82e0f3a95f71f179b3407ff7d6.tar.xz wireguard-openbsd-5ed5d284388b1e82e0f3a95f71f179b3407ff7d6.zip |
Fix gain calibration for some iwn(4) devices (5000 and up).
IWN_LSB() returns an index starting with 1, however the arrays used
later on (noise and gain in iwn5000_set_gains()) start with 0. The
previous code accounted for this difference when setting the antenna
gain by accessing cmd.gain[i - 1]. However the noise array was accessed
with noise[i], the chainmask was checked against i, and more importantly
the overall for() loop iterated wrongly over the antennas by always
starting with i=2 (the third antenna). One consequence is that gain
calibration never happened in case of only two antennas.
Patch by Holger Mikolon.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_iwn.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c index 25180341892..d95af421f0e 100644 --- a/sys/dev/pci/if_iwn.c +++ b/sys/dev/pci/if_iwn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwn.c,v 1.237 2020/07/20 08:09:30 stsp Exp $ */ +/* $OpenBSD: if_iwn.c,v 1.238 2020/07/20 08:19:59 stsp Exp $ */ /*- * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr> @@ -4598,22 +4598,27 @@ iwn5000_set_gains(struct iwn_softc *sc) cmd.code = sc->noise_gain; cmd.ngroups = 1; cmd.isvalid = 1; - /* Get first available RX antenna as referential. */ - ant = IWN_LSB(sc->rxchainmask); + /* Get first available RX antenna as referential. + * IWN_LSB() return values start with 1, but + * antenna gain array cmd.gain[] and noise array + * calib->noise[] start with 0. */ + ant = IWN_LSB(sc->rxchainmask) - 1; + /* Set differential gains for other antennas. */ for (i = ant + 1; i < 3; i++) { if (sc->chainmask & (1 << i)) { /* The delta is relative to antenna "ant". */ delta = ((int32_t)calib->noise[ant] - (int32_t)calib->noise[i]) / div; + DPRINTF(("Ant[%d] vs. Ant[%d]: delta %d\n", ant, i, delta)); /* Limit to [-4.5dB,+4.5dB]. */ - cmd.gain[i - 1] = MIN(abs(delta), 3); + cmd.gain[i] = MIN(abs(delta), 3); if (delta < 0) - cmd.gain[i - 1] |= 1 << 2; /* sign bit */ + cmd.gain[i] |= 1 << 2; /* sign bit */ + DPRINTF(("Setting differential gains for antenna %d: %x\n", + i, cmd.gain[i])); } } - DPRINTF(("setting differential gains: %x/%x (%x)\n", - cmd.gain[0], cmd.gain[1], sc->chainmask)); return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1); } |