From 6128b7ccd782b8fc5833413dd287fe4b71868931 Mon Sep 17 00:00:00 2001 From: bschmidt Date: Tue, 19 Apr 2011 19:47:41 +0000 Subject: Pull some features out of the firmware: - If a ENH_SENS TLV section exit the firmware is capable of doing enhanced sensitivity calibration. - Newer devices/firmwares have more calibration commands therefore hardcoding the noise gain/reset commands no longer works. It is supposed to use the next index after the newest calibration type support. Read the command index of the TLV section if available. --- sys/dev/iwn/if_iwn.c | 19 ++++++++++++++++--- sys/dev/iwn/if_iwnreg.h | 2 ++ sys/dev/iwn/if_iwnvar.h | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index a2b12e2..c1c3fb6 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -772,6 +772,8 @@ iwn5000_attach(struct iwn_softc *sc, uint16_t pid) sc->fw_data_maxsz = IWN5000_FW_DATA_MAXSZ; sc->fwsz = IWN5000_FWSZ; sc->sched_txfact_addr = IWN5000_SCHED_TXFACT; + sc->reset_noise_gain = IWN5000_PHY_CALIB_RESET_NOISE_GAIN; + sc->noise_gain = IWN5000_PHY_CALIB_NOISE_GAIN; switch (sc->hw_type) { case IWN_HW_REV_TYPE_5100: @@ -4367,7 +4369,7 @@ iwn5000_init_gains(struct iwn_softc *sc) struct iwn_phy_calib cmd; memset(&cmd, 0, sizeof cmd); - cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN; + cmd.code = sc->reset_noise_gain; cmd.ngroups = 1; cmd.isvalid = 1; DPRINTF(sc, IWN_DEBUG_CALIBRATE, @@ -4419,7 +4421,7 @@ iwn5000_set_gains(struct iwn_softc *sc) div = (sc->hw_type == IWN_HW_REV_TYPE_6050) ? 20 : 30; memset(&cmd, 0, sizeof cmd); - cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN; + cmd.code = sc->noise_gain; cmd.ngroups = 1; cmd.isvalid = 1; /* Get first available RX antenna as referential. */ @@ -5900,7 +5902,7 @@ iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw, const struct iwn_fw_tlv *tlv; const uint8_t *ptr, *end; uint64_t altmask; - uint32_t len; + uint32_t len, tmp; if (fw->size < sizeof (*hdr)) { device_printf(sc->sc_dev, "%s: firmware too short: %zu bytes\n", @@ -5965,6 +5967,17 @@ iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw, fw->boot.text = ptr; fw->boot.textsz = len; break; + case IWN_FW_TLV_ENH_SENS: + if (!len) + sc->sc_flags |= IWN_FLAG_ENH_SENS; + break; + case IWN_FW_TLV_PHY_CALIB: + tmp = htole32(*ptr); + if (tmp < 253) { + sc->reset_noise_gain = tmp; + sc->noise_gain = tmp + 1; + } + break; default: DPRINTF(sc, IWN_DEBUG_RESET, "TLV type %d not handled\n", le16toh(tlv->type)); diff --git a/sys/dev/iwn/if_iwnreg.h b/sys/dev/iwn/if_iwnreg.h index da79f6e..d6ff91c 100644 --- a/sys/dev/iwn/if_iwnreg.h +++ b/sys/dev/iwn/if_iwnreg.h @@ -1322,6 +1322,8 @@ struct iwn_fw_tlv { #define IWN_FW_TLV_INIT_DATA 4 #define IWN_FW_TLV_BOOT_TEXT 5 #define IWN_FW_TLV_PBREQ_MAXLEN 6 +#define IWN_FW_TLV_ENH_SENS 14 +#define IWN_FW_TLV_PHY_CALIB 15 uint16_t alt; uint32_t len; diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h index ca2055d..8d45eeb 100644 --- a/sys/dev/iwn/if_iwnvar.h +++ b/sys/dev/iwn/if_iwnvar.h @@ -222,6 +222,8 @@ struct iwn_softc { uint32_t fw_data_maxsz; uint32_t fwsz; bus_size_t sched_txfact_addr; + uint32_t reset_noise_gain; + uint32_t noise_gain; /* TX scheduler rings. */ struct iwn_dma_info sched_dma; -- cgit v1.1