Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jun 2012 05:23:33 +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: r237626 - head/sys/dev/ath/ath_hal/ar5416
Message-ID:  <201206270523.q5R5NXMO083703@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Wed Jun 27 05:23:33 2012
New Revision: 237626
URL: http://svn.freebsd.org/changeset/base/237626

Log:
  Fix a subtle corner case surrounding the handling of OFDM restart along
  with AMPDU aggregate delimiters.
  
  If there's an OFDM restart during an aggregate, the hardware ACKs
  the previous frame, but communicates the RXed frame to the hardware
  as having had CRC delimiter error + OFDM_RESTART phy error.
  The frame however didn't have a CRC error and since the hardware ACKed
  the aggregate to the sender, it thinks the frame was received.
  
  Since I have no idea how often this occurs in the real world, add a
  debug statement so trigger whenever this occurs.  I'd appreciate an
  email if someone finds this particular situation is triggered.

Modified:
  head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c	Wed Jun 27 04:39:30 2012	(r237625)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c	Wed Jun 27 05:23:33 2012	(r237626)
@@ -240,11 +240,25 @@ ar5416ProcRxDesc(struct ath_hal *ah, str
 		if (ads->ds_rxstatus8 & AR_PHYErr) {
 			u_int phyerr;
 
-			rs->rs_status |= HAL_RXERR_PHY;
+			/*
+			 * Packets with OFDM_RESTART on post delimiter are CRC OK and
+			 * usable and MAC ACKs them.
+			 * To avoid packet from being lost, we remove the PHY Err flag
+			 * so that driver layer does not drop them.
+			 */
 			phyerr = MS(ads->ds_rxstatus8, AR_PHYErrCode);
-			rs->rs_phyerr = phyerr;
-		}
 
+			if ((phyerr == HAL_PHYERR_OFDM_RESTART) &&
+			    (ads->ds_rxstatus8 & AR_PostDelimCRCErr)) {
+				ath_hal_printf(ah,
+				    "%s: OFDM_RESTART on post-delim CRC error\n",
+				    __func__);
+				rs->rs_phyerr = 0;
+			} else {
+				rs->rs_status |= HAL_RXERR_PHY;
+				rs->rs_phyerr = phyerr;
+			}
+		}
 		if (ads->ds_rxstatus8 & AR_CRCErr)
 			rs->rs_status |= HAL_RXERR_CRC;
 		else if (ads->ds_rxstatus8 & AR_DecryptCRCErr)



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