From owner-svn-src-head@FreeBSD.ORG Sat Apr 10 06:58:25 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 527D6106566B; Sat, 10 Apr 2010 06:58:25 +0000 (UTC) (envelope-from bschmidt@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3E9918FC12; Sat, 10 Apr 2010 06:58:25 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o3A6wPIf004993; Sat, 10 Apr 2010 06:58:25 GMT (envelope-from bschmidt@svn.freebsd.org) Received: (from bschmidt@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o3A6wPHH004989; Sat, 10 Apr 2010 06:58:25 GMT (envelope-from bschmidt@svn.freebsd.org) Message-Id: <201004100658.o3A6wPHH004989@svn.freebsd.org> From: Bernhard Schmidt Date: Sat, 10 Apr 2010 06:58:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r206444 - head/sys/dev/iwn X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 10 Apr 2010 06:58:25 -0000 Author: bschmidt Date: Sat Apr 10 06:58:24 2010 New Revision: 206444 URL: http://svn.freebsd.org/changeset/base/206444 Log: * Rename bluetooth coexistence flags, no binary change. * Enable DC calibration and crystal calibration on Centrino Advanced-N 6250 parts. * Workaround for a HW bug (does not affect 4965AGN) that may sporadically affect latency under some rare circumstances. From a similar commit to iwlwifi. * Update sensitivity settings for 5000 series to workaround a performance bug in the DSP (1000 is not affected so we keep the old values for 5000). * Update sensitivity settings for 6000 series. * Set differential gains on 6250 too (but use a 1.0 factor, not 1.5). * Init OFDM sensitivity with min value (which depends on the chip) instead of hardcoding it to 90. * Read calibration version from ROM and set IWN_GP_DRIVER_CALIB_VER6 bit on 6x50 if version >= 6. Approved by: rpaulo (mentor) Obtained from: OpenBSD MFC after: 2 weeks Modified: head/sys/dev/iwn/if_iwn.c head/sys/dev/iwn/if_iwnreg.h head/sys/dev/iwn/if_iwnvar.h Modified: head/sys/dev/iwn/if_iwn.c ============================================================================== --- head/sys/dev/iwn/if_iwn.c Sat Apr 10 06:55:29 2010 (r206443) +++ head/sys/dev/iwn/if_iwn.c Sat Apr 10 06:58:24 2010 (r206444) @@ -562,12 +562,15 @@ iwn_attach(device_t dev) #if IWN_RBUF_SIZE == 8192 IEEE80211_HTCAP_AMSDU7935 | #endif - IEEE80211_HTCAP_SMPS_DIS | IEEE80211_HTCAP_CBW20_40 | IEEE80211_HTCAP_SGI20 | IEEE80211_HTCAP_SGI40; if (sc->hw_type != IWN_HW_REV_TYPE_4965) ic->ic_htcaps |= IEEE80211_HTCAP_GF; + if (sc->hw_type == IWN_HW_REV_TYPE_6050) + ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DYN; + else + ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DIS; #endif /* Read MAC address, channels, etc from EEPROM. */ @@ -680,7 +683,7 @@ iwn_hal_attach(struct iwn_softc *sc) break; case IWN_HW_REV_TYPE_1000: sc->sc_hal = &iwn5000_hal; - sc->limits = &iwn5000_sensitivity_limits; + sc->limits = &iwn1000_sensitivity_limits; sc->fwname = "iwn1000fw"; sc->txchainmask = IWN_ANT_A; sc->rxchainmask = IWN_ANT_AB; @@ -1609,6 +1612,7 @@ iwn4965_print_power_group(struct iwn_sof void iwn5000_read_eeprom(struct iwn_softc *sc) { + struct iwn5000_eeprom_calib_hdr hdr; int32_t temp, volt; uint32_t addr, base; int i; @@ -1632,6 +1636,12 @@ iwn5000_read_eeprom(struct iwn_softc *sc iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2); base = le16toh(val); + iwn_read_prom_data(sc, base, &hdr, sizeof hdr); + DPRINTF(sc, IWN_DEBUG_CALIBRATE, + "%s: calib version=%u pa type=%u voltage=%u\n", + __func__, hdr.version, hdr.pa_type, le16toh(hdr.volt)); + sc->calib_ver = hdr.version; + if (sc->hw_type == IWN_HW_REV_TYPE_5150) { /* Compute temperature offset. */ iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2); @@ -2138,7 +2148,8 @@ iwn5000_rx_calib_results(struct iwn_soft switch (calib->code) { case IWN5000_PHY_CALIB_DC: - if (sc->hw_type == IWN_HW_REV_TYPE_5150) + if (sc->hw_type == IWN_HW_REV_TYPE_5150 || + sc->hw_type == IWN_HW_REV_TYPE_6050) idx = 0; break; case IWN5000_PHY_CALIB_LO: @@ -2668,8 +2679,10 @@ iwn_intr(void *arg) sc->ict_cur = (sc->ict_cur + 1) % IWN_ICT_COUNT; } tmp = le32toh(tmp); - if (tmp == 0xffffffff) - tmp = 0; /* Shouldn't happen. */ + if (tmp == 0xffffffff) /* Shouldn't happen. */ + tmp = 0; + else if (tmp & 0xc0000) /* Workaround a HW bug. */ + tmp |= 0x8000; r1 = (tmp & 0xff00) << 16 | (tmp & 0xff); r2 = 0; /* Unused. */ } else { @@ -4022,7 +4035,7 @@ iwn_init_sensitivity(struct iwn_softc *s /* Set initial correlation values. */ calib->ofdm_x1 = sc->limits->min_ofdm_x1; calib->ofdm_mrc_x1 = sc->limits->min_ofdm_mrc_x1; - calib->ofdm_x4 = 90; + calib->ofdm_x4 = sc->limits->min_ofdm_x4; calib->ofdm_mrc_x4 = sc->limits->min_ofdm_mrc_x4; calib->cck_x4 = 125; calib->cck_mrc_x4 = sc->limits->min_cck_mrc_x4; @@ -4115,9 +4128,6 @@ iwn5000_init_gains(struct iwn_softc *sc) { struct iwn_phy_calib cmd; - if (sc->hw_type == IWN_HW_REV_TYPE_6050) - return 0; - memset(&cmd, 0, sizeof cmd); cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN; cmd.ngroups = 1; @@ -4165,10 +4175,10 @@ iwn5000_set_gains(struct iwn_softc *sc) { struct iwn_calib_state *calib = &sc->calib; struct iwn_phy_calib_gain cmd; - int i, ant, delta; + int i, ant, delta, div; - if (sc->hw_type == IWN_HW_REV_TYPE_6050) - return 0; + /* We collected 20 beacons and !=6050 need a 1.5 factor. */ + div = (sc->hw_type == IWN_HW_REV_TYPE_6050) ? 20 : 30; memset(&cmd, 0, sizeof cmd); cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN; @@ -4181,7 +4191,7 @@ iwn5000_set_gains(struct iwn_softc *sc) if (sc->chainmask & (1 << i)) { /* The delta is relative to antenna "ant". */ delta = ((int32_t)calib->noise[ant] - - (int32_t)calib->noise[i]) / 30; + (int32_t)calib->noise[i]) / div; /* Limit to [-4.5dB,+4.5dB]. */ cmd.gain[i - 1] = MIN(abs(delta), 3); if (delta < 0) @@ -4464,7 +4474,7 @@ iwn_config(struct iwn_softc *sc) /* Configure bluetooth coexistence. */ memset(&bluetooth, 0, sizeof bluetooth); - bluetooth.flags = IWN_BT_COEX_MODE_4WIRE; + bluetooth.flags = IWN_BT_COEX_CHAN_ANN | IWN_BT_COEX_BT_PRIO; bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF; bluetooth.max_kill = IWN_BT_MAX_KILL_DEF; DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n", @@ -5824,6 +5834,10 @@ 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) { + /* Indicate that ROM calibration version is >=6. */ + IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_CALIB_VER6); + } return 0; } Modified: head/sys/dev/iwn/if_iwnreg.h ============================================================================== --- head/sys/dev/iwn/if_iwnreg.h Sat Apr 10 06:55:29 2010 (r206443) +++ head/sys/dev/iwn/if_iwnreg.h Sat Apr 10 06:58:24 2010 (r206444) @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $OpenBSD: if_iwnreg.h,v 1.34 2009/11/08 11:54:48 damien Exp $ */ +/* $OpenBSD: if_iwnreg.h,v 1.37 2010/02/17 18:23:00 damien Exp $ */ /*- * Copyright (c) 2007, 2008 @@ -216,6 +216,7 @@ #define IWN_GP_DRIVER_RADIO_3X3_HYB (0 << 0) #define IWN_GP_DRIVER_RADIO_2X2_HYB (1 << 0) #define IWN_GP_DRIVER_RADIO_2X2_IPA (2 << 0) +#define IWN_GP_DRIVER_CALIB_VER6 (1 << 2) /* Possible flags for register IWN_UCODE_GP1_CLR. */ #define IWN_UCODE_GP1_RFKILL (1 << 1) @@ -832,10 +833,9 @@ struct iwn5000_cmd_txpower { /* Structure for command IWN_CMD_BLUETOOTH. */ struct iwn_bluetooth { uint8_t flags; -#define IWN_BT_COEX_DISABLE 0 -#define IWN_BT_COEX_MODE_2WIRE 1 -#define IWN_BT_COEX_MODE_3WIRE 2 -#define IWN_BT_COEX_MODE_4WIRE 3 +#define IWN_BT_COEX_CHAN_ANN (1 << 0) +#define IWN_BT_COEX_BT_PRIO (1 << 1) +#define IWN_BT_COEX_2_WIRE (1 << 2) uint8_t lead_time; #define IWN_BT_LEAD_TIME_DEF 30 @@ -1326,6 +1326,12 @@ struct iwn_eeprom_enhinfo { int8_t mimo3; /* max power in half-dBm */ } __packed; +struct iwn5000_eeprom_calib_hdr { + uint8_t version; + uint8_t pa_type; + uint16_t volt; +} __packed; + #define IWN_NSAMPLES 3 struct iwn4965_eeprom_chan_samples { uint8_t num; @@ -1552,8 +1558,8 @@ static const struct iwn_sensitivity_limi }; static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = { - 120, 155, - 240, 290, + 120, 120, /* min = max for performance bug in DSP. */ + 240, 240, /* min = max for performance bug in DSP. */ 90, 120, 170, 210, 125, 200, @@ -1575,8 +1581,20 @@ static const struct iwn_sensitivity_limi 95 }; +static const struct iwn_sensitivity_limits iwn1000_sensitivity_limits = { + 120, 155, + 240, 290, + 90, 120, + 170, 210, + 125, 200, + 170, 400, + 95, + 95, + 95 +}; + static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = { - 105, 145, + 105, 110, 192, 232, 80, 145, 128, 232, @@ -1642,7 +1660,7 @@ static const char * const iwn_fw_errmsg[ "DEBUG_1", "DEBUG_2", "DEBUG_3", - "UNKNOWN" + "ADVANCED_SYSASSERT" }; /* Find least significant bit that is set. */ Modified: head/sys/dev/iwn/if_iwnvar.h ============================================================================== --- head/sys/dev/iwn/if_iwnvar.h Sat Apr 10 06:55:29 2010 (r206443) +++ head/sys/dev/iwn/if_iwnvar.h Sat Apr 10 06:58:24 2010 (r206444) @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $OpenBSD: if_iwnvar.h,v 1.16 2009/11/04 17:46:52 damien Exp $ */ +/* $OpenBSD: if_iwnvar.h,v 1.17 2010/02/17 18:23:00 damien Exp $ */ /*- * Copyright (c) 2007, 2008 @@ -281,6 +281,7 @@ struct iwn_softc { bands[IWN_NBANDS]; struct iwn_eeprom_chan eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND]; uint16_t rfcfg; + uint8_t calib_ver; char eeprom_domain[4]; uint32_t eeprom_crystal; int16_t eeprom_voltage;