Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Apr 2011 14:52:32 +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: r220324 - in head/sys/dev/ath: . ath_hal ath_hal/ar5210 ath_hal/ar5211 ath_hal/ar5212 ath_hal/ar5416
Message-ID:  <201104041452.p34EqW5w086530@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Mon Apr  4 14:52:31 2011
New Revision: 220324
URL: http://svn.freebsd.org/changeset/base/220324

Log:
  Add a HAL capability bit for supporting self-linked RX descriptors and disable it for the 11n chipsets.
  
  From the ath9k source:
  
  ==
  
  11N: we can no longer afford to self link the last descriptor.
  MAC acknowledges BA status as long as it copies frames to host
  buffer (or rx fifo). This can incorrectly acknowledge packets
  to a sender if last desc is self-linked.
  
  ==
  
  Since this is useful for pre-AR5416 chips that communicate PHY errors
  via error frames rather than by on-chip counters, leave the support
  in there, but disable it for AR5416 and later.

Modified:
  head/sys/dev/ath/ath_hal/ah.c
  head/sys/dev/ath/ath_hal/ah.h
  head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c
  head/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
  head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
  head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
  head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
  head/sys/dev/ath/if_ath.c
  head/sys/dev/ath/if_athvar.h

Modified: head/sys/dev/ath/ath_hal/ah.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ah.c	Mon Apr  4 11:01:53 2011	(r220323)
+++ head/sys/dev/ath/ath_hal/ah.c	Mon Apr  4 14:52:31 2011	(r220324)
@@ -616,6 +616,8 @@ ath_hal_getcapability(struct ath_hal *ah
 		return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP;
 	case HAL_CAP_HAS_PSPOLL:	/* hardware has ps-poll support */
 		return pCap->halHasPsPollSupport ? HAL_OK : HAL_ENOTSUPP;
+	case HAL_CAP_RXDESC_SELFLINK:	/* hardware supports self-linked final RX descriptors correctly */
+		return pCap->halHasRxSelfLinkedTail ? HAL_OK : HAL_ENOTSUPP;
 	default:
 		return HAL_EINVAL;
 	}

Modified: head/sys/dev/ath/ath_hal/ah.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ah.h	Mon Apr  4 11:01:53 2011	(r220323)
+++ head/sys/dev/ath/ath_hal/ah.h	Mon Apr  4 14:52:31 2011	(r220324)
@@ -114,6 +114,7 @@ typedef enum {
 	HAL_CAP_STREAMS		= 39,	/* how many 802.11n spatial streams are available */
 	HAL_CAP_SPLIT_4KB_TRANS	= 40,	/* hardware supports descriptors straddling a 4k page boundary */
 	HAL_CAP_HAS_PSPOLL	= 41,	/* hardware has ps-poll support */
+	HAL_CAP_RXDESC_SELFLINK	= 42,	/* support a self-linked tail RX descriptor */
 } HAL_CAPABILITY_TYPE;
 
 /* 

Modified: head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c	Mon Apr  4 11:01:53 2011	(r220323)
+++ head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c	Mon Apr  4 14:52:31 2011	(r220324)
@@ -378,6 +378,7 @@ ar5210FillCapabilityInfo(struct ath_hal 
 			;
 
 	pCap->hal4kbSplitTransSupport = AH_TRUE;
+	pCap->halHasRxSelfLinkedTail = AH_TRUE;
 
 	ahpriv->ah_rxornIsFatal = AH_TRUE;
 	return AH_TRUE;

Modified: head/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c	Mon Apr  4 11:01:53 2011	(r220323)
+++ head/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c	Mon Apr  4 14:52:31 2011	(r220324)
@@ -510,6 +510,7 @@ ar5211FillCapabilityInfo(struct ath_hal 
 			;
 
 	pCap->hal4kbSplitTransSupport = AH_TRUE;
+	pCap->halHasRxSelfLinkedTail = AH_TRUE;
 
 	/* XXX might be ok w/ some chip revs */
 	ahpriv->ah_rxornIsFatal = AH_TRUE;

Modified: head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c	Mon Apr  4 11:01:53 2011	(r220323)
+++ head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c	Mon Apr  4 14:52:31 2011	(r220324)
@@ -861,6 +861,7 @@ ar5212FillCapabilityInfo(struct ath_hal 
 		pCap->halIntrMask &= ~HAL_INT_TBTT;
 
 	pCap->hal4kbSplitTransSupport = AH_TRUE;
+	pCap->halHasRxSelfLinkedTail = AH_TRUE;
 
 	return AH_TRUE;
 #undef IS_COBRA

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c	Mon Apr  4 11:01:53 2011	(r220323)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c	Mon Apr  4 14:52:31 2011	(r220324)
@@ -843,6 +843,8 @@ ar5416FillCapabilityInfo(struct ath_hal 
 	pCap->halBtCoexSupport = AH_FALSE;	/* XXX need support */
 	pCap->halAutoSleepSupport = AH_FALSE;
 	pCap->hal4kbSplitTransSupport = AH_TRUE;
+	/* Disable this so Block-ACK works correctly */
+	pCap->halHasRxSelfLinkedTail = AH_FALSE;
 #if 0	/* XXX not yet */
 	pCap->halNumAntCfg2GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_2GHZ);
 	pCap->halNumAntCfg5GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_5GHZ);

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c	Mon Apr  4 11:01:53 2011	(r220323)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c	Mon Apr  4 14:52:31 2011	(r220324)
@@ -99,18 +99,9 @@ ar5416ProcRxDesc(struct ath_hal *ah, str
     struct ath_rx_status *rs)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
-	struct ar5416_desc *ands = AR5416DESC(nds);
 
 	if ((ads->ds_rxstatus8 & AR_RxDone) == 0)
 		return HAL_EINPROGRESS;
-	/*
-	 * Given the use of a self-linked tail be very sure that the hw is
-	 * done with this descriptor; the hw may have done this descriptor
-	 * once and picked it up again...make sure the hw has moved on.
-	 */
-	if ((ands->ds_rxstatus8 & AR_RxDone) == 0
-	    && OS_REG_READ(ah, AR_RXDP) == pa)
-		return HAL_EINPROGRESS;
 
 	rs->rs_status = 0;
 	rs->rs_flags = 0;

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Mon Apr  4 11:01:53 2011	(r220323)
+++ head/sys/dev/ath/if_ath.c	Mon Apr  4 14:52:31 2011	(r220324)
@@ -595,6 +595,7 @@ ath_attach(u_int16_t devid, struct ath_s
 	sc->sc_hasbmask = ath_hal_hasbssidmask(ah);
 	sc->sc_hasbmatch = ath_hal_hasbssidmatch(ah);
 	sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);
+	sc->sc_rxslink = ath_hal_self_linked_final_rxdesc(ah);
 	if (ath_hal_hasfastframes(ah))
 		ic->ic_caps |= IEEE80211_C_FF;
 	wmodes = ath_hal_getwirelessmodes(ah);
@@ -3135,8 +3136,17 @@ ath_rxbuf_init(struct ath_softc *sc, str
 	 * descriptor list.  This insures the hardware always has
 	 * someplace to write a new frame.
 	 */
+	/*
+	 * 11N: we can no longer afford to self link the last descriptor.
+	 * MAC acknowledges BA status as long as it copies frames to host
+	 * buffer (or rx fifo). This can incorrectly acknowledge packets
+	 * to a sender if last desc is self-linked.
+	 */
 	ds = bf->bf_desc;
-	ds->ds_link = bf->bf_daddr;	/* link to self */
+	if (sc->sc_rxslink)
+		ds->ds_link = bf->bf_daddr;	/* link to self */
+	else
+		ds->ds_link = 0;		/* terminate the list */
 	ds->ds_data = bf->bf_segs[0].ds_addr;
 	ath_hal_setuprxdesc(ah, ds
 		, m->m_len		/* buffer size */
@@ -3321,9 +3331,16 @@ ath_rx_proc(void *arg, int npending)
 	tsf = ath_hal_gettsf64(ah);
 	do {
 		bf = STAILQ_FIRST(&sc->sc_rxbuf);
-		if (bf == NULL) {		/* NB: shouldn't happen */
+		if (sc->sc_rxslink && bf == NULL) {	/* NB: shouldn't happen */
 			if_printf(ifp, "%s: no buffer!\n", __func__);
 			break;
+		} else if (bf == NULL) {
+			/*
+			 * End of List:
+			 * this can happen for non-self-linked RX chains
+			 */
+			sc->sc_stats.ast_rx_hitqueueend++;
+			break;
 		}
 		m = bf->bf_m;
 		if (m == NULL) {		/* NB: shouldn't happen */

Modified: head/sys/dev/ath/if_athvar.h
==============================================================================
--- head/sys/dev/ath/if_athvar.h	Mon Apr  4 11:01:53 2011	(r220323)
+++ head/sys/dev/ath/if_athvar.h	Mon Apr  4 14:52:31 2011	(r220324)
@@ -253,7 +253,8 @@ struct ath_softc {
 				sc_resume_up: 1,/* on resume, start all vaps */
 				sc_tdma	    : 1,/* TDMA in use */
 				sc_setcca   : 1,/* set/clr CCA with TDMA */
-				sc_resetcal : 1;/* reset cal state next trip */
+				sc_resetcal : 1,/* reset cal state next trip */
+				sc_rxslink  : 1;/* do self-linked final descriptor */
 	uint32_t		sc_eerd;	/* regdomain from EEPROM */
 	uint32_t		sc_eecc;	/* country code from EEPROM */
 						/* rate tables */
@@ -646,6 +647,8 @@ void	ath_intr(void *);
 	(ath_hal_getcapability(_ah, HAL_CAP_TX_CHAINMASK, 0, _ptxchainmask))
 #define	ath_hal_split4ktrans(_ah) \
 	(ath_hal_getcapability(_ah, HAP_CAP_SPLIT_4KB_TRANS, 0, NULL) == HAL_OK)
+#define	ath_hal_self_linked_final_rxdesc(_ah) \
+	(ath_hal_getcapability(_ah, HAL_CAP_RXDESC_SELFLINK, 0, NULL) == HAL_OK)
 
 #define	ath_hal_setuprxdesc(_ah, _ds, _size, _intreq) \
 	((*(_ah)->ah_setupRxDesc)((_ah), (_ds), (_size), (_intreq)))



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