Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Feb 2011 15:43:38 +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: r218488 - head/sys/dev/ath
Message-ID:  <201102091543.p19FhcpV089065@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Wed Feb  9 15:43:38 2011
New Revision: 218488
URL: http://svn.freebsd.org/changeset/base/218488

Log:
  Add in the (very!) optional glue to flip the 11n bits for if_ath.
  
  There's still a lot of random issues to sort out with the radio side of
  things and AMPDU RX handling (and completely missing AMPDU TX handling!)
  but if people wish to give this a go and assist in debugging the
  issues, they can define ATH_DO_11N to enable it.
  
  I'm just re-iterating - this is here to allow people to assist in
  further 11n development; it is not any indication that the 11n support
  is complete and functional.
  
  Important notes:
  
  * This doesn't support 1-stream cards yet - (eg AR9285) - the various bits
    that negotiate TX/RX MCS don't know not to try >1 stream TX or negotiate
    1-stream RX; so don't enable 11n unless you've first taught the rate
    control module and the net80211 stack to negotiate 1-stream stuff;
  
  * The only rate control module minimally 11n aware is ath_rate_sample;
  
  * ath_rate_sample doesn't know about HT/40; so airtime will be incorrectly
    calculated;
  
  * The AR9160 and AR9280 radio code is unreliable at the higher MCS rates for
    some reason; this will definitely impact 11n performance;
  
  * AMPDU-TX isn't yet implemented;
  
  * AMPDU-RX may be a bit buggy still and will definitely suffer from the
    radio unreliability mentioned above (ie, don't expect 150/300mbit
    RX just yet.)

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

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Wed Feb  9 15:40:48 2011	(r218487)
+++ head/sys/dev/ath/if_ath.c	Wed Feb  9 15:43:38 2011	(r218488)
@@ -283,6 +283,10 @@ SYSCTL_INT(_hw_ath, OID_AUTO, bstuck, CT
 
 MALLOC_DEFINE(M_ATHDEV, "athdev", "ath driver dma buffers");
 
+#define	HAL_MODE_HT20 (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20)
+#define	HAL_MODE_HT40 \
+	(HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \
+	HAL_MODE_11NA_HT40PLUS | HAL_MODE_11NA_HT40MINUS)
 int
 ath_attach(u_int16_t devid, struct ath_softc *sc)
 {
@@ -611,6 +615,52 @@ ath_attach(u_int16_t devid, struct ath_s
 		ic->ic_tdma_update = ath_tdma_update;
 	}
 #endif
+
+	/*
+	 * 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.
+	 */
+
+#ifdef	DO_ATH_11N
+	/*
+	 * Query HT capabilities
+	 */
+	if (ath_hal_getcapability(ah, HAL_CAP_HT, 0, NULL) == HAL_OK &&
+	    (wmodes & (HAL_MODE_HT20 | HAL_MODE_HT40))) {
+		int rxs, txs;
+
+		device_printf(sc->sc_dev, "[HT] enabling HT modes\n");
+		ic->ic_htcaps = IEEE80211_HTC_HT		/* HT operation */
+			    | IEEE80211_HTC_AMPDU		/* A-MPDU tx/rx */
+			    | IEEE80211_HTC_AMSDU		/* A-MSDU tx/rx */
+			    | IEEE80211_HTCAP_MAXAMSDU_3839	/* max A-MSDU length */
+			    | IEEE80211_HTCAP_SHORTGI20		/* short GI in 20MHz */
+			    | IEEE80211_HTCAP_SMPS_OFF;		/* SM power save off */
+			;
+
+		if (wmodes & HAL_MODE_HT40)
+			ic->ic_htcaps |= IEEE80211_HTCAP_CHWIDTH40
+			    |  IEEE80211_HTCAP_SHORTGI40;
+
+		/*
+		 * rx/tx stream is not currently used anywhere; it needs to be taken
+		 * into account when negotiating which MCS rates it'll receive and
+		 * what MCS rates are available for TX.
+		 */
+		(void) ath_hal_getcapability(ah, HAL_CAP_STREAMS, 0, &rxs);
+		(void) ath_hal_getcapability(ah, HAL_CAP_STREAMS, 1, &txs);
+
+		ath_hal_getrxchainmask(ah, &sc->sc_rxchainmask);
+		ath_hal_gettxchainmask(ah, &sc->sc_txchainmask);
+
+		ic->ic_txstream = txs;
+		ic->ic_rxstream = rxs;
+
+		device_printf(sc->sc_dev, "[HT] %d RX streams; %d TX streams\n", rxs, txs);
+	}
+#endif
+
 	/*
 	 * Indicate we need the 802.11 header padded to a
 	 * 32-bit boundary for 4-address and QoS frames.



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