summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbschmidt <bschmidt@FreeBSD.org>2011-04-19 19:47:41 +0000
committerbschmidt <bschmidt@FreeBSD.org>2011-04-19 19:47:41 +0000
commit6128b7ccd782b8fc5833413dd287fe4b71868931 (patch)
tree4f25e7bfb403e5f2a2842069174261c818834c1d
parentc3d7e4b40e5b77bac9db58a9b50adcb31f20c0fe (diff)
downloadFreeBSD-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.c19
-rw-r--r--sys/dev/iwn/if_iwnreg.h2
-rw-r--r--sys/dev/iwn/if_iwnvar.h2
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;
OpenPOWER on IntegriCloud