Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Feb 2012 10:01:10 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r231369 - head/sys/dev/ath
Message-ID:  <201202101001.q1AA1A7v065696@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Fri Feb 10 10:01:09 2012
New Revision: 231369
URL: http://svn.freebsd.org/changeset/base/231369

Log:
  Add in a new driver feature to allow the TX and RX chainmask to be
  overridden at attach time.
  
  Some 802.11n NICs may only have one physical antenna connected.
  The radios will be very upset if you try enabling radios which aren't
  connected to antennas.
  
  This allows hints to override the TX and RX chainmask.
  
  These hints are:
  
  hint.ath.X.rx_chainmask
  hint.ath.X.tx_chainmask
  
  They can be set at either boot time or in kenv before the module is loaded.
  
  This and the previous HAL commit were sponsored in late 2011 by Hobnob, Inc.
  
  Sponsored by:	Hobnob, Inc.

Modified:
  head/sys/dev/ath/if_ath.c
  head/sys/dev/ath/if_athvar.h

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Fri Feb 10 09:58:20 2012	(r231368)
+++ head/sys/dev/ath/if_ath.c	Fri Feb 10 10:01:09 2012	(r231369)
@@ -284,6 +284,7 @@ ath_attach(u_int16_t devid, struct ath_s
 	int error = 0, i;
 	u_int wmodes;
 	uint8_t macaddr[IEEE80211_ADDR_LEN];
+	int rx_chainmask, tx_chainmask;
 
 	DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
 
@@ -634,6 +635,29 @@ ath_attach(u_int16_t devid, struct ath_s
 #endif
 
 	/*
+	 * Allow the TX and RX chainmasks to be overridden by
+	 * environment variables and/or device.hints.
+	 *
+	 * This must be done early - before the hardware is
+	 * calibrated or before the 802.11n stream calculation
+	 * is done.
+	 */
+	if (resource_int_value(device_get_name(sc->sc_dev),
+	    device_get_unit(sc->sc_dev), "rx_chainmask",
+	    &rx_chainmask) == 0) {
+		device_printf(sc->sc_dev, "Setting RX chainmask to 0x%x\n",
+		    rx_chainmask);
+		(void) ath_hal_setrxchainmask(sc->sc_ah, rx_chainmask);
+	}
+	if (resource_int_value(device_get_name(sc->sc_dev),
+	    device_get_unit(sc->sc_dev), "tx_chainmask",
+	    &tx_chainmask) == 0) {
+		device_printf(sc->sc_dev, "Setting TX chainmask to 0x%x\n",
+		    tx_chainmask);
+		(void) ath_hal_settxchainmask(sc->sc_ah, rx_chainmask);
+	}
+
+	/*
 	 * The if_ath 11n support is completely not ready for normal use.
 	 * Enabling this option will likely break everything and everything.
 	 * Don't think of doing that unless you know what you're doing.

Modified: head/sys/dev/ath/if_athvar.h
==============================================================================
--- head/sys/dev/ath/if_athvar.h	Fri Feb 10 09:58:20 2012	(r231368)
+++ head/sys/dev/ath/if_athvar.h	Fri Feb 10 10:01:09 2012	(r231369)
@@ -888,6 +888,10 @@ void	ath_intr(void *);
 	(ath_hal_getcapability(_ah, HAL_CAP_RX_CHAINMASK, 0, _prxchainmask))
 #define	ath_hal_gettxchainmask(_ah, _ptxchainmask) \
 	(ath_hal_getcapability(_ah, HAL_CAP_TX_CHAINMASK, 0, _ptxchainmask))
+#define	ath_hal_setrxchainmask(_ah, _rx) \
+	(ath_hal_setcapability(_ah, HAL_CAP_RX_CHAINMASK, 1, _rx, NULL))
+#define	ath_hal_settxchainmask(_ah, _tx) \
+	(ath_hal_setcapability(_ah, HAL_CAP_TX_CHAINMASK, 1, _tx, NULL))
 #define	ath_hal_split4ktrans(_ah) \
 	(ath_hal_getcapability(_ah, HAL_CAP_SPLIT_4KB_TRANS, \
 	0, NULL) == HAL_OK)



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