aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/iwn
diff options
context:
space:
mode:
authorBernhard Schmidt <bschmidt@FreeBSD.org>2011-11-21 22:19:12 +0000
committerBernhard Schmidt <bschmidt@FreeBSD.org>2011-11-21 22:19:12 +0000
commit26ddc9835ab74951b10e19c9991b01f9b768c172 (patch)
tree3bddb02e078657d09ea3b0b7c31ba5643de67278 /sys/dev/iwn
parent5856d663aece8b4fb4e140c06bf5dd498e479519 (diff)
downloadsrc-26ddc9835ab74951b10e19c9991b01f9b768c172.tar.gz
src-26ddc9835ab74951b10e19c9991b01f9b768c172.zip
The DC calibration result obtained during initialization can't be
passed over to the runtime firmware on 6050 devices. Instead let the runtime firmware do the calibration itself. This fixes support for the 6050 series devices. Obtained from: OpenBSD Submitted by: kevlo Tested by: lx, Tz-Huan Huang(earlier version)
Notes
Notes: svn path=/head/; revision=227805
Diffstat (limited to 'sys/dev/iwn')
-rw-r--r--sys/dev/iwn/if_iwn.c28
-rw-r--r--sys/dev/iwn/if_iwnreg.h2
2 files changed, 29 insertions, 1 deletions
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index 8a02752f30b4..a28e40b76367 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -246,6 +246,7 @@ static int iwn_send_sensitivity(struct iwn_softc *);
static int iwn_set_pslevel(struct iwn_softc *, int, int, int);
static int iwn_send_btcoex(struct iwn_softc *);
static int iwn_send_advanced_btcoex(struct iwn_softc *);
+static int iwn5000_runtime_calib(struct iwn_softc *);
static int iwn_config(struct iwn_softc *);
static uint8_t *ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int);
static int iwn_scan(struct iwn_softc *);
@@ -2505,7 +2506,8 @@ iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
case IWN5000_PHY_CALIB_DC:
if ((sc->sc_flags & IWN_FLAG_INTERNAL_PA) == 0 &&
(sc->hw_type == IWN_HW_REV_TYPE_5150 ||
- sc->hw_type >= IWN_HW_REV_TYPE_6000))
+ sc->hw_type >= IWN_HW_REV_TYPE_6000) &&
+ sc->hw_type != IWN_HW_REV_TYPE_6050)
idx = 0;
break;
case IWN5000_PHY_CALIB_LO:
@@ -4996,6 +4998,19 @@ iwn_send_advanced_btcoex(struct iwn_softc *sc)
}
static int
+iwn5000_runtime_calib(struct iwn_softc *sc)
+{
+ struct iwn5000_calib_config cmd;
+
+ memset(&cmd, 0, sizeof cmd);
+ cmd.ucode.once.enable = 0xffffffff;
+ cmd.ucode.once.start = IWN5000_CALIB_DC;
+ DPRINTF(sc, IWN_DEBUG_CALIBRATE,
+ "%s: configuring runtime calibration\n", __func__);
+ return iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof(cmd), 0);
+}
+
+static int
iwn_config(struct iwn_softc *sc)
{
struct iwn_ops *ops = &sc->ops;
@@ -5015,6 +5030,17 @@ iwn_config(struct iwn_softc *sc)
}
}
+ if (sc->hw_type == IWN_HW_REV_TYPE_6050) {
+ /* Configure runtime DC calibration. */
+ error = iwn5000_runtime_calib(sc);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "%s: could not configure runtime calibration\n",
+ __func__);
+ return error;
+ }
+ }
+
/* Configure valid TX chains for >=5000 Series. */
if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
txmask = htole32(sc->txchainmask);
diff --git a/sys/dev/iwn/if_iwnreg.h b/sys/dev/iwn/if_iwnreg.h
index c3079e6e3f80..062125fb3ab0 100644
--- a/sys/dev/iwn/if_iwnreg.h
+++ b/sys/dev/iwn/if_iwnreg.h
@@ -739,6 +739,8 @@ struct iwn5000_wimax_coex {
struct iwn5000_calib_elem {
uint32_t enable;
uint32_t start;
+#define IWN5000_CALIB_DC (1 << 1)
+
uint32_t send;
uint32_t apply;
uint32_t reserved;