Date: Wed, 4 Jan 2012 21:27:03 +0000 (UTC) From: Pyun YongHyeon <yongari@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r229522 - stable/8/sys/dev/ae Message-ID: <201201042127.q04LR37w097039@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: yongari Date: Wed Jan 4 21:27:03 2012 New Revision: 229522 URL: http://svn.freebsd.org/changeset/base/229522 Log: MFC r227452: 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: stable/8/sys/dev/ae/if_ae.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/dev/ae/if_ae.c ============================================================================== --- stable/8/sys/dev/ae/if_ae.c Wed Jan 4 21:26:47 2012 (r229521) +++ stable/8/sys/dev/ae/if_ae.c Wed Jan 4 21:27:03 2012 (r229522) @@ -1432,7 +1432,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 @@ -1449,7 +1449,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 @@ -1458,11 +1458,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 { @@ -1841,8 +1840,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?201201042127.q04LR37w097039>