From owner-freebsd-sparc64@FreeBSD.ORG Tue Feb 22 02:45:20 2005 Return-Path: Delivered-To: freebsd-sparc64@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B43E316A4CE for ; Tue, 22 Feb 2005 02:45:20 +0000 (GMT) Received: from ns.kt-is.co.kr (ns.kt-is.co.kr [211.218.149.125]) by mx1.FreeBSD.org (Postfix) with ESMTP id F050243D3F for ; Tue, 22 Feb 2005 02:45:19 +0000 (GMT) (envelope-from yongari@kt-is.co.kr) Received: from michelle.kt-is.co.kr (ns2.kt-is.co.kr [220.76.118.193]) (authenticated bits=128) by ns.kt-is.co.kr (8.12.10/8.12.10) with ESMTP id j1M2j2Ah047928 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Tue, 22 Feb 2005 11:45:02 +0900 (KST) Received: from michelle.kt-is.co.kr (localhost.kt-is.co.kr [127.0.0.1]) by michelle.kt-is.co.kr (8.13.1/8.13.1) with ESMTP id j1M2jHDG005033 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 22 Feb 2005 11:45:17 +0900 (KST) (envelope-from yongari@kt-is.co.kr) Received: (from yongari@localhost) by michelle.kt-is.co.kr (8.13.1/8.13.1/Submit) id j1M2jEwB005032; Tue, 22 Feb 2005 11:45:14 +0900 (KST) (envelope-from yongari@kt-is.co.kr) Date: Tue, 22 Feb 2005 11:45:14 +0900 From: Pyun YongHyeon To: Andrew Belashov Message-ID: <20050222024514.GA4799@kt-is.co.kr> References: <20050221102511.GD1756@kt-is.co.kr> <4219CAA9.2010503@orel.ru> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="SLDf9lqlvOQaIe6s" Content-Disposition: inline In-Reply-To: <4219CAA9.2010503@orel.ru> User-Agent: Mutt/1.4.2.1i X-Filter-Version: 1.11a (ns.kt-is.co.kr) cc: freebsd-sparc64@freebsd.org Subject: Re: Call for hme(4) testers X-BeenThere: freebsd-sparc64@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: yongari@kt-is.co.kr List-Id: Porting FreeBSD to the Sparc List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Feb 2005 02:45:20 -0000 --SLDf9lqlvOQaIe6s Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon, Feb 21, 2005 at 02:48:57PM +0300, Andrew Belashov wrote: > >. make sure to invoke hme_init_locked() to unfreeze DMA enine when > > What is "DMA enine"? > It's typo. It should be read "DMA engine". > > I have patch collision with CURRENT: > Patch regenerated against latest CURRENT. Sorry for inconvenience. -- Regards, Pyun YongHyeon http://www.kr.freebsd.org/~yongari | yongari@freebsd.org --SLDf9lqlvOQaIe6s Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="if_hme.diff.0222" --- sys/dev/hme/if_hme.c.orig Wed Feb 2 17:35:11 2005 +++ sys/dev/hme/if_hme.c Tue Feb 22 11:36:53 2005 @@ -126,8 +126,6 @@ static void hme_rxcksum(struct mbuf *, u_int32_t); static void hme_cdma_callback(void *, bus_dma_segment_t *, int, int); -static void hme_txdma_callback(void *, bus_dma_segment_t *, int, - bus_size_t, int); devclass_t hme_devclass; @@ -223,14 +221,14 @@ if (error) goto fail_ptag; - error = bus_dma_tag_create(sc->sc_pdmatag, max(0x10, sc->sc_burst), 0, + error = bus_dma_tag_create(sc->sc_pdmatag, imax(0x10, sc->sc_burst), 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, HME_NRXDESC, BUS_SPACE_MAXSIZE_32BIT, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_rdmatag); if (error) goto fail_ctag; - error = bus_dma_tag_create(sc->sc_pdmatag, max(0x10, sc->sc_burst), 0, + error = bus_dma_tag_create(sc->sc_pdmatag, imax(0x10, sc->sc_burst), 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, HME_NTXDESC, BUS_SPACE_MAXSIZE_32BIT, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_tdmatag); @@ -439,8 +437,31 @@ hme_tick(void *arg) { struct hme_softc *sc = arg; + struct ifnet *ifp; int s; + + HME_LOCK(sc); + ifp = &sc->sc_arpcom.ac_if; + + /* + * Unload collision counters + */ + ifp->if_collisions += + HME_MAC_READ_4(sc, HME_MACI_NCCNT) + + HME_MAC_READ_4(sc, HME_MACI_FCCNT) + + HME_MAC_READ_4(sc, HME_MACI_EXCNT) + + HME_MAC_READ_4(sc, HME_MACI_LTCNT); + + /* + * then clear the hardware counters. + */ + HME_MAC_WRITE_4(sc, HME_MACI_NCCNT, 0); + HME_MAC_WRITE_4(sc, HME_MACI_FCCNT, 0); + HME_MAC_WRITE_4(sc, HME_MACI_EXCNT, 0); + HME_MAC_WRITE_4(sc, HME_MACI_LTCNT, 0); + HME_UNLOCK(sc); + s = splnet(); mii_tick(sc->sc_mii); splx(s); @@ -463,11 +484,17 @@ static void hme_stop(struct hme_softc *sc) { + struct ifnet *ifp; u_int32_t v; int n; + ifp = &sc->sc_arpcom.ac_if; + ifp->if_timer = 0; callout_stop(&sc->sc_tick_ch); + /* mask all interrupts */ + HME_SEB_WRITE_4(sc, HME_SEBI_IMASK, 0xffffffff); + /* Reset transmitter and receiver */ HME_SEB_WRITE_4(sc, HME_SEBI_RESET, HME_SEB_RESET_ETX | HME_SEB_RESET_ERX); @@ -527,7 +554,7 @@ * the mapping must be done in a way that a burst can start on a * natural boundary we might need to extend this. */ - a = max(HME_MINRXALIGN, sc->sc_burst); + a = imax(HME_MINRXALIGN, sc->sc_burst); /* * Make sure the buffer suitably aligned. The 2 byte offset is removed * when the mbuf is handed up. XXX: this ensures at least 16 byte @@ -607,10 +634,10 @@ for (i = 0; i < HME_NTXQ; i++) { td = &sc->sc_rb.rb_txdesc[i]; if (td->htx_m != NULL) { - m_freem(td->htx_m); bus_dmamap_sync(sc->sc_tdmatag, td->htx_dmamap, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_tdmatag, td->htx_dmamap); + m_freem(td->htx_m); td->htx_m = NULL; } STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txfreeq, td, htx_q); @@ -879,69 +906,6 @@ hme_start_locked(ifp); } -struct hme_txdma_arg { - struct hme_softc *hta_sc; - struct hme_txdesc *hta_htx; - int hta_ndescs; -}; - -/* - * XXX: this relies on the fact that segments returned by bus_dmamap_load_mbuf() - * are readable from the nearest burst boundary on (i.e. potentially before - * ds_addr) to the first boundary beyond the end. This is usually a safe - * assumption to make, but is not documented. - */ -static void -hme_txdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, - bus_size_t totsz, int error) -{ - struct hme_txdma_arg *ta = xsc; - struct hme_txdesc *htx; - bus_size_t len = 0; - caddr_t txd; - u_int32_t flags = 0; - int i, tdhead, pci; - - if (error != 0) - return; - - tdhead = ta->hta_sc->sc_rb.rb_tdhead; - pci = ta->hta_sc->sc_pci; - txd = ta->hta_sc->sc_rb.rb_txd; - htx = ta->hta_htx; - - if (ta->hta_sc->sc_rb.rb_td_nbusy + nsegs >= HME_NTXDESC) { - ta->hta_ndescs = -1; - return; - } - ta->hta_ndescs = nsegs; - - for (i = 0; i < nsegs; i++) { - if (segs[i].ds_len == 0) - continue; - - /* Fill the ring entry. */ - flags = HME_XD_ENCODE_TSIZE(segs[i].ds_len); - if (len == 0) - flags |= HME_XD_SOP; - if (len + segs[i].ds_len == totsz) - flags |= HME_XD_EOP; - CTR5(KTR_HME, "hme_txdma_callback: seg %d/%d, ri %d, " - "flags %#x, addr %#x", i + 1, nsegs, tdhead, (u_int)flags, - (u_int)segs[i].ds_addr); - HME_XD_SETFLAGS(pci, txd, tdhead, flags); - HME_XD_SETADDR(pci, txd, tdhead, segs[i].ds_addr); - - ta->hta_sc->sc_rb.rb_td_nbusy++; - htx->htx_lastdesc = tdhead; - tdhead = (tdhead + 1) % HME_NTXDESC; - len += segs[i].ds_len; - } - ta->hta_sc->sc_rb.rb_tdhead = tdhead; - KASSERT((flags & HME_XD_EOP) != 0, - ("hme_txdma_callback: missed end of packet!")); -} - /* TX TCP/UDP checksum */ static void hme_txcksum(struct mbuf *m, u_int32_t *cflags) @@ -988,50 +952,65 @@ static int hme_load_txmbuf(struct hme_softc *sc, struct mbuf *m0) { - struct hme_txdma_arg cba; - struct hme_txdesc *td; - int error, si, ri; + struct hme_txdesc *htx; + caddr_t txd; + int error; + int i, pci, si, ri, nseg; u_int32_t flags, cflags = 0; - si = sc->sc_rb.rb_tdhead; - if ((td = STAILQ_FIRST(&sc->sc_rb.rb_txfreeq)) == NULL) - return (-1); + if ((htx = STAILQ_FIRST(&sc->sc_rb.rb_txfreeq)) == NULL) { + error = -1; + goto fail; + } if ((m0->m_pkthdr.csum_flags & sc->sc_csum_features) != 0) hme_txcksum(m0, &cflags); - cba.hta_sc = sc; - cba.hta_htx = td; - if ((error = bus_dmamap_load_mbuf(sc->sc_tdmatag, td->htx_dmamap, - m0, hme_txdma_callback, &cba, 0)) != 0) + error = bus_dmamap_load_mbuf_sg(sc->sc_tdmatag, htx->htx_dmamap, + m0, sc->sc_rb.rb_txsegs, &nseg, BUS_DMA_NOWAIT); + if (error != 0) goto fail; - if (cba.hta_ndescs == -1) { - error = -1; + if (sc->sc_rb.rb_td_nbusy + nseg >= HME_NTXDESC) { + bus_dmamap_unload(sc->sc_tdmatag, htx->htx_dmamap); + error = -2; goto fail; } - bus_dmamap_sync(sc->sc_tdmatag, td->htx_dmamap, - BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->sc_tdmatag, htx->htx_dmamap, BUS_DMASYNC_PREWRITE); - STAILQ_REMOVE_HEAD(&sc->sc_rb.rb_txfreeq, htx_q); - STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txbusyq, td, htx_q); - td->htx_m = m0; - - /* Turn descriptor ownership to the hme, back to forth. */ - ri = sc->sc_rb.rb_tdhead; - CTR2(KTR_HME, "hme_load_mbuf: next desc is %d (%#x)", - ri, HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri)); - do { - ri = (ri + HME_NTXDESC - 1) % HME_NTXDESC; - flags = HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri) | - HME_XD_OWN | cflags; - CTR3(KTR_HME, "hme_load_mbuf: activating ri %d, si %d (%#x)", - ri, si, flags); - HME_XD_SETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri, flags); - } while (ri != si); + si = ri = sc->sc_rb.rb_tdhead; + txd = sc->sc_rb.rb_txd; + pci = sc->sc_pci; + for (i = 0; i < nseg; i++) { + /* Fill the ring entry. */ + flags = HME_XD_ENCODE_TSIZE(sc->sc_rb.rb_txsegs[i].ds_len); + if (i == 0) + flags |= HME_XD_SOP | cflags; + else + flags |= HME_XD_OWN | cflags; + HME_XD_SETADDR(pci, txd, ri, sc->sc_rb.rb_txsegs[i].ds_addr); + HME_XD_SETFLAGS(pci, txd, ri, flags); + sc->sc_rb.rb_td_nbusy++; + htx->htx_lastdesc = ri; + ri = (ri + 1) % HME_NTXDESC; + } + sc->sc_rb.rb_tdhead = ri; + + /* set EOP on the last descriptor */ + ri = (ri + HME_NTXDESC - 1) % HME_NTXDESC; + flags = HME_XD_GETFLAGS(pci, txd, ri); + flags |= HME_XD_EOP; + HME_XD_SETFLAGS(pci, txd, ri, flags); + + /* Turn the first descriptor ownership to the hme */ + flags = HME_XD_GETFLAGS(sc->sc_pci, txd, si); + flags |= HME_XD_OWN; + HME_XD_SETFLAGS(pci, txd, si, flags); + STAILQ_REMOVE_HEAD(&sc->sc_rb.rb_txfreeq, htx_q); + STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txbusyq, htx, htx_q); + htx->htx_m = m0; /* start the transmission. */ HME_ETX_WRITE_4(sc, HME_ETXI_PENDING, HME_ETX_TP_DMAWAKEUP); return (0); fail: - bus_dmamap_unload(sc->sc_tdmatag, td->htx_dmamap); return (error); } @@ -1103,30 +1082,23 @@ if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) return; - error = 0; for (;;) { IFQ_DRV_DEQUEUE(&ifp->if_snd, m); if (m == NULL) break; error = hme_load_txmbuf(sc, m); - if (error == -1) { + if (error != 0) { ifp->if_flags |= IFF_OACTIVE; IFQ_DRV_PREPEND(&ifp->if_snd, m); break; - } else if (error > 0) { - printf("hme_start: error %d while loading mbuf\n", - error); - } else { - enq = 1; - BPF_MTAP(ifp, m); } + enq++; + BPF_MTAP(ifp, m); } - if (sc->sc_rb.rb_td_nbusy == HME_NTXDESC || error == -1) - ifp->if_flags |= IFF_OACTIVE; /* Set watchdog timer if a packet was queued */ - if (enq) { + if (enq > 0) { bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_PREWRITE); ifp->if_timer = 5; @@ -1143,23 +1115,6 @@ struct hme_txdesc *htx; unsigned int ri, txflags; - /* - * Unload collision counters - */ - ifp->if_collisions += - HME_MAC_READ_4(sc, HME_MACI_NCCNT) + - HME_MAC_READ_4(sc, HME_MACI_FCCNT) + - HME_MAC_READ_4(sc, HME_MACI_EXCNT) + - HME_MAC_READ_4(sc, HME_MACI_LTCNT); - - /* - * then clear the hardware counters. - */ - HME_MAC_WRITE_4(sc, HME_MACI_NCCNT, 0); - HME_MAC_WRITE_4(sc, HME_MACI_FCCNT, 0); - HME_MAC_WRITE_4(sc, HME_MACI_EXCNT, 0); - HME_MAC_WRITE_4(sc, HME_MACI_LTCNT, 0); - htx = STAILQ_FIRST(&sc->sc_rb.rb_txbusyq); bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_POSTREAD); /* Fetch current position in the transmit ring */ @@ -1197,17 +1152,13 @@ STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txfreeq, htx, htx_q); htx = STAILQ_FIRST(&sc->sc_rb.rb_txbusyq); } - /* Turn off watchdog */ - if (sc->sc_rb.rb_td_nbusy == 0) - ifp->if_timer = 0; + /* Turn off watchdog if hme(4) transmitted queued packet */ + ifp->if_timer = sc->sc_rb.rb_td_nbusy > 0 ? 5 : 0; /* Update ring */ sc->sc_rb.rb_tdtail = ri; hme_start_locked(ifp); - - if (sc->sc_rb.rb_td_nbusy == 0) - ifp->if_timer = 0; } /* @@ -1325,6 +1276,12 @@ } HME_WHINE(sc->sc_dev, "error signaled, status=%#x\n", status); + /* check for fatal errors that needs reset to unfreeze DMA engine */ + if ((status & (HME_SEB_STAT_SLVERR | HME_SEB_STAT_SLVERR | + HME_SEB_STAT_TXTERR | HME_SEB_STAT_TXPERR | HME_SEB_STAT_TXLERR | + HME_SEB_STAT_TXEACK | HME_SEB_STAT_RXTERR | HME_SEB_STAT_RXPERR | + HME_SEB_STAT_RXLATERR | HME_SEB_STAT_RXERR)) != 0) + hme_init_locked(sc); } void @@ -1347,7 +1304,6 @@ hme_rint(sc); HME_UNLOCK(sc); } - static void hme_watchdog(struct ifnet *ifp) --- sys/dev/hme/if_hmevar.h.orig Mon Nov 22 15:46:30 2004 +++ sys/dev/hme/if_hmevar.h Tue Feb 22 11:33:22 2005 @@ -100,6 +100,7 @@ /* Descriptors */ struct hme_rxdesc rb_rxdesc[HME_NRXDESC]; struct hme_txdesc rb_txdesc[HME_NTXQ]; + bus_dma_segment_t rb_txsegs[HME_NTXDESC]; struct hme_txdq rb_txfreeq; struct hme_txdq rb_txbusyq; --SLDf9lqlvOQaIe6s--