Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Nov 2011 19:15:32 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r227452 - head/sys/dev/ae
Message-ID:  <201111111915.pABJFWEi003780@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Fri Nov 11 19:15:32 2011
New Revision: 227452
URL: http://svn.freebsd.org/changeset/base/227452

Log:
  To send a frame, controller requires a prepended TX header and
  the length of frame should be treated as multiple of 4. Actual
  frame length is set in the TX header. The TX header position
  should be aligned on 4 byte boundary and actual frame start
  position should be aligned on 4 byte boundary as well. This means
  we need 4(TX header length) + 3(frame length fixup) additional free
  space in TX buffer in addition to actual frame length.
  Make sure TX handler check these additional bytes.
  ae_tx_avail_size() returns actual free space in TX buffer to ease
  the calculation of available TX buffer space in caller. While I'm
  here, replace magic number to appropriate sizeof operator to
  enhance readability.
  
  This change should fix controller lockup issue happened under
  certain conditions but it still does not fix watchdog timeout. It
  seems the watchdog timeout is side-effect of TxS and TxD
  mismatches. The root cause of TxD/TxD mismatch is not known yet but
  it looks like silicon bug. I guess driver may have to reinitialize
  controller whenever it sees TxS and TxD mismatches but leave it as
  it was at this moment.
  
  PR:	kern/145918

Modified:
  head/sys/dev/ae/if_ae.c

Modified: head/sys/dev/ae/if_ae.c
==============================================================================
--- head/sys/dev/ae/if_ae.c	Fri Nov 11 15:24:17 2011	(r227451)
+++ head/sys/dev/ae/if_ae.c	Fri Nov 11 19:15:32 2011	(r227452)
@@ -1431,7 +1431,7 @@ ae_tx_avail_size(ae_softc_t *sc)
 	else
 		avail = sc->txd_ack - sc->txd_cur;
 
-	return (avail - 4);	/* 4-byte header. */
+	return (avail);
 }
 
 static int
@@ -1448,7 +1448,7 @@ ae_encap(ae_softc_t *sc, struct mbuf **m
 	len = m0->m_pkthdr.len;
 	
 	if ((sc->flags & AE_FLAG_TXAVAIL) == 0 ||
-	    ae_tx_avail_size(sc) < len) {
+	    len + sizeof(ae_txd_t) + 3 > ae_tx_avail_size(sc)) {
 #ifdef AE_DEBUG
 		if_printf(sc->ifp, "No free Tx available.\n");
 #endif
@@ -1457,11 +1457,10 @@ ae_encap(ae_softc_t *sc, struct mbuf **m
 
 	hdr = (ae_txd_t *)(sc->txd_base + sc->txd_cur);
 	bzero(hdr, sizeof(*hdr));
-	sc->txd_cur = (sc->txd_cur + 4) % AE_TXD_BUFSIZE_DEFAULT; /* Header
-								     size. */
-	to_end = AE_TXD_BUFSIZE_DEFAULT - sc->txd_cur; /* Space available to
-							* the end of the ring
-							*/
+	/* Skip header size. */
+	sc->txd_cur = (sc->txd_cur + sizeof(ae_txd_t)) % AE_TXD_BUFSIZE_DEFAULT;
+	/* Space available to the end of the ring */
+	to_end = AE_TXD_BUFSIZE_DEFAULT - sc->txd_cur;
 	if (to_end >= len) {
 		m_copydata(m0, 0, len, (caddr_t)(sc->txd_base + sc->txd_cur));
 	} else {
@@ -1840,8 +1839,8 @@ ae_tx_intr(ae_softc_t *sc)
 		/*
 		 * Move txd ack and align on 4-byte boundary.
 		 */
-		sc->txd_ack = ((sc->txd_ack + le16toh(txd->len) + 4 + 3) & ~3) %
-		    AE_TXD_BUFSIZE_DEFAULT;
+		sc->txd_ack = ((sc->txd_ack + le16toh(txd->len) +
+		    sizeof(ae_txs_t) + 3) & ~3) % AE_TXD_BUFSIZE_DEFAULT;
 
 		if ((flags & AE_TXS_SUCCESS) != 0)
 			ifp->if_opackets++;



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