diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2020-07-20 08:20:00 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2020-07-20 08:20:00 +0000 |
commit | 0c39f9204d740b0cb66920777662739d27403f64 (patch) | |
tree | 67e4c77c0d9852af3753432239ad11c13eaa3418 | |
parent | 98e5c50e02a4e254e0c1b1070c65164971618fa5 (diff) |
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.
-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); } |