diff options
author | bschmidt <bschmidt@FreeBSD.org> | 2011-04-19 19:47:41 +0000 |
---|---|---|
committer | bschmidt <bschmidt@FreeBSD.org> | 2011-04-19 19:47:41 +0000 |
commit | 6128b7ccd782b8fc5833413dd287fe4b71868931 (patch) | |
tree | 4f25e7bfb403e5f2a2842069174261c818834c1d | |
parent | c3d7e4b40e5b77bac9db58a9b50adcb31f20c0fe (diff) | |
download | FreeBSD-src-6128b7ccd782b8fc5833413dd287fe4b71868931.zip FreeBSD-src-6128b7ccd782b8fc5833413dd287fe4b71868931.tar.gz |
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.
-rw-r--r-- | sys/dev/iwn/if_iwn.c | 19 | ||||
-rw-r--r-- | sys/dev/iwn/if_iwnreg.h | 2 | ||||
-rw-r--r-- | 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; |