The 6005 series devices need additional temperature offset calibration

as well as the IWN_GP_DRIVER_CALIB_VER6 bit set.

Obtained from:	OpenBSD
This commit is contained in:
Bernhard Schmidt 2011-04-15 20:35:15 +00:00
parent 083e216732
commit 89a84499e4
2 changed files with 44 additions and 1 deletions

View File

@ -222,6 +222,7 @@ static void iwn5000_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t);
static int iwn5000_query_calibration(struct iwn_softc *);
static int iwn5000_send_calibration(struct iwn_softc *);
static int iwn5000_send_wimax_coex(struct iwn_softc *);
static int iwn5000_temp_offset_calib(struct iwn_softc *);
static int iwn5000_crystal_calib(struct iwn_softc *);
static int iwn4965_post_alive(struct iwn_softc *);
static int iwn5000_post_alive(struct iwn_softc *);
@ -4539,6 +4540,16 @@ iwn_config(struct iwn_softc *sc)
int error;
uint16_t rxchain;
if (sc->hw_type == IWN_HW_REV_TYPE_6005) {
/* Set radio temperature sensor offset. */
error = iwn5000_temp_offset_calib(sc);
if (error != 0) {
device_printf(sc->sc_dev,
"%s: could not set temperature offset\n", __func__);
return error;
}
}
/* Configure valid TX chains for 5000 Series. */
if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
txmask = htole32(sc->txchainmask);
@ -5326,6 +5337,24 @@ iwn5000_crystal_calib(struct iwn_softc *sc)
return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
}
static int
iwn5000_temp_offset_calib(struct iwn_softc *sc)
{
struct iwn5000_phy_calib_temp_offset cmd;
memset(&cmd, 0, sizeof cmd);
cmd.code = IWN5000_PHY_CALIB_TEMP_OFFSET;
cmd.ngroups = 1;
cmd.isvalid = 1;
if (sc->eeprom_temp != 0)
cmd.offset = htole16(sc->eeprom_temp);
else
cmd.offset = htole16(IWN_DEFAULT_TEMP_OFFSET);
DPRINTF(sc, IWN_DEBUG_CALIBRATE, "setting radio sensor offset to %d\n",
le16toh(cmd.offset));
return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
}
/*
* This function is called after the runtime firmware notifies us of its
* readiness (called in a process context.)
@ -6028,7 +6057,8 @@ iwn5000_nic_config(struct iwn_softc *sc)
/* Use internal power amplifier only. */
IWN_WRITE(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_RADIO_2X2_IPA);
}
if (sc->hw_type == IWN_HW_REV_TYPE_6050 && sc->calib_ver >= 6) {
if ((sc->hw_type == IWN_HW_REV_TYPE_6050 ||
sc->hw_type == IWN_HW_REV_TYPE_6005) && sc->calib_ver >= 6) {
/* Indicate that ROM calibration version is >=6. */
IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_CALIB_VER6);
}

View File

@ -885,6 +885,8 @@ struct iwn_phy_calib {
#define IWN5000_PHY_CALIB_CRYSTAL 15
#define IWN5000_PHY_CALIB_BASE_BAND 16
#define IWN5000_PHY_CALIB_TX_IQ_PERIODIC 17
#define IWN5000_PHY_CALIB_TEMP_OFFSET 18
#define IWN5000_PHY_CALIB_RESET_NOISE_GAIN 18
#define IWN5000_PHY_CALIB_NOISE_GAIN 19
@ -903,6 +905,17 @@ struct iwn5000_phy_calib_crystal {
uint8_t reserved[2];
} __packed;
struct iwn5000_phy_calib_temp_offset {
uint8_t code;
uint8_t group;
uint8_t ngroups;
uint8_t isvalid;
int16_t offset;
#define IWN_DEFAULT_TEMP_OFFSET 2700
uint16_t reserved;
} __packed;
struct iwn_phy_calib_gain {
uint8_t code;
uint8_t group;