svn commit: r206444 - head/sys/dev/iwn

Bernhard Schmidt bschmidt at FreeBSD.org
Sat Apr 10 06:58:25 UTC 2010


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;


More information about the svn-src-all mailing list