Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Jun 2011 12:10:07 +0000 (UTC)
From:      Bernhard Schmidt <bschmidt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r223251 - stable/8/sys/dev/iwn
Message-ID:  <201106181210.p5ICA7xZ040333@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bschmidt
Date: Sat Jun 18 12:10:06 2011
New Revision: 223251
URL: http://svn.freebsd.org/changeset/base/223251

Log:
  MFC r220866-220867:
  - 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.
  - Enable DC calibration for all 6000 series devices, except those
    with an internal PA.
  - Override the chainmask also for the 6050.

Modified:
  stable/8/sys/dev/iwn/if_iwn.c
  stable/8/sys/dev/iwn/if_iwnreg.h
  stable/8/sys/dev/iwn/if_iwnvar.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/iwn/if_iwn.c
==============================================================================
--- stable/8/sys/dev/iwn/if_iwn.c	Sat Jun 18 12:07:06 2011	(r223250)
+++ stable/8/sys/dev/iwn/if_iwn.c	Sat Jun 18 12:10:06 2011	(r223251)
@@ -772,6 +772,8 @@ iwn5000_attach(struct iwn_softc *sc, uin
 	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:
@@ -807,6 +809,9 @@ iwn5000_attach(struct iwn_softc *sc, uin
 	case IWN_HW_REV_TYPE_6050:
 		sc->limits = &iwn6000_sensitivity_limits;
 		sc->fwname = "iwn6050fw";
+		/* Override chains masks, ROM is known to be broken. */
+		sc->txchainmask = IWN_ANT_AB;
+		sc->rxchainmask = IWN_ANT_AB;
 		break;
 	case IWN_HW_REV_TYPE_6005:
 		sc->limits = &iwn6000_sensitivity_limits;
@@ -2385,7 +2390,9 @@ 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->sc_flags & IWN_FLAG_INTERNAL_PA) == 0 &&
+		    (sc->hw_type == IWN_HW_REV_TYPE_5150 ||
+		     sc->hw_type >= IWN_HW_REV_TYPE_6000))
 			idx = 0;
 		break;
 	case IWN5000_PHY_CALIB_LO:
@@ -4367,7 +4374,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 +4426,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 +5907,7 @@ iwn_read_firmware_tlv(struct iwn_softc *
 	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 +5972,17 @@ iwn_read_firmware_tlv(struct iwn_softc *
 			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));

Modified: stable/8/sys/dev/iwn/if_iwnreg.h
==============================================================================
--- stable/8/sys/dev/iwn/if_iwnreg.h	Sat Jun 18 12:07:06 2011	(r223250)
+++ stable/8/sys/dev/iwn/if_iwnreg.h	Sat Jun 18 12:10:06 2011	(r223251)
@@ -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;

Modified: stable/8/sys/dev/iwn/if_iwnvar.h
==============================================================================
--- stable/8/sys/dev/iwn/if_iwnvar.h	Sat Jun 18 12:07:06 2011	(r223250)
+++ stable/8/sys/dev/iwn/if_iwnvar.h	Sat Jun 18 12:10:06 2011	(r223251)
@@ -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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106181210.p5ICA7xZ040333>