summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2020-07-20 08:20:00 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2020-07-20 08:20:00 +0000
commit0c39f9204d740b0cb66920777662739d27403f64 (patch)
tree67e4c77c0d9852af3753432239ad11c13eaa3418
parent98e5c50e02a4e254e0c1b1070c65164971618fa5 (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.c19
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);
}