Date: Fri, 12 Jul 2002 18:20:23 +0200 From: Thomas Moestl <tmoestl@gmx.net> To: "Andrew R. Reiter" <arr@watson.org> Cc: freebsd-sparc64@FreeBSD.org Subject: Re: hme0 -- 0x20000 error (no rx descs) Message-ID: <20020712162023.GD311@crow.dom2ip.de> In-Reply-To: <Pine.NEB.3.96L.1020712014200.86899C-100000@fledge.watson.org> References: <20020711165803.GB318@crow.dom2ip.de> <Pine.NEB.3.96L.1020712014200.86899C-100000@fledge.watson.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 2002/07/12 at 01:44:25 -0400, Andrew R. Reiter wrote: > [snip, see other thread messages for context.] > : > :Hmmm, actually, I think that the kernel on the ISO was compiled with > :KTR, so you just need to set the mask (no recompile required), using > :either a loader tunable ("set debug.ktr.mask=0x2000000" on the loader > :prompt) or sysctl ("sysctl debug.ktr.mask=0x2000000"). Since it > :doesn't seem to happen during boot the sysctl method should suffice. > : > : - thomas > > Here's the related traces; please let me know if you need more context or > other information. > > index trace > ------ ----- > 5186 hme_intr: status 0x20001 > 5185 hme_intr: status 0x20001 > [...] Hmm, I think I know what's up with it. I've attached a patch that should fix it (FWIW, since you can't build kernels currently). It also contains some other fixes I want to commit soon. It would probably be easiest to test by either setting up network booting or creating a new ISO with just the kernel exchanged. The latter can be done relatively easily by just copying the whole ISO contents to a disk, exchanging /boot/kernel/kernel and then creating a new ISO with a correct boot record. I've put a GENERIC kernel with the fix at http://people.FreeBSD.org/~tmm/kernel-hme.bz2. For the boot record, you need to download http://people.FreeBSD.org/~jake/bootfs. The ISO can then be created using: mkisofs -B ,,,,bootfs -r -o sparc64.iso /the/modified/tree If you want to try network booting instead, please tell me (you will need another kernel for that). Thanks, - thomas -- Thomas Moestl <tmoestl@gmx.net> http://www.tu-bs.de/~y0015675/ <tmm@FreeBSD.org> http://people.FreeBSD.org/~tmm/ PGP fingerprint: 1C97 A604 2BD0 E492 51D0 9C0F 1FE6 4F1D 419C 776C Index: if_hme.c =================================================================== RCS file: /home/ncvs/src/sys/dev/hme/if_hme.c,v retrieving revision 1.4 diff -u -r1.4 if_hme.c --- if_hme.c 26 Apr 2002 22:48:21 -0000 1.4 +++ if_hme.c 12 Jul 2002 12:44:20 -0000 @@ -240,6 +240,7 @@ * processed descriptor and may be used later on. */ for (rdesc = 0; rdesc < HME_NRXDESC; rdesc++) { + sc->sc_rb.rb_rxdesc[rdesc].hrx_m = NULL; error = bus_dmamap_create(sc->sc_rdmatag, 0, &sc->sc_rb.rb_rxdesc[rdesc].hrx_dmamap); if (error != 0) @@ -251,13 +252,13 @@ goto fail_rxdesc; /* Same for the TX descs. */ for (tdesc = 0; tdesc < HME_NTXDESC; tdesc++) { + sc->sc_rb.rb_txdesc[tdesc].htx_m = NULL; + sc->sc_rb.rb_txdesc[tdesc].htx_flags = 0; error = bus_dmamap_create(sc->sc_tdmatag, 0, &sc->sc_rb.rb_txdesc[tdesc].htx_dmamap); if (error != 0) goto fail_txdesc; } - bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); device_printf(sc->sc_dev, "Ethernet address:"); for (i = 0; i < 6; i++) @@ -409,6 +410,27 @@ *a = segs[0].ds_addr; } +/* + * Discard the contents of an mbuf in the RX ring, freeing the buffer in the + * ring for subsequent use. + */ +static void +hme_discard_rxbuf(struct hme_softc *sc, int ix, int sync) +{ + + /* + * Dropped a packet, reinitialize the descriptor and turn the + * ownership back to the hardware. + */ + HME_XD_SETFLAGS(sc->sc_pci, sc->sc_rb.rb_rxd, ix, HME_XD_OWN | + HME_XD_ENCODE_RSIZE(ulmin(HME_BUFSZ, + sc->sc_rb.rb_rxdesc[ix].hrx_len))); + if (sync) { + bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + } +} + static int hme_add_rxbuf(struct hme_softc *sc, unsigned int ri, int keepold) { @@ -422,8 +444,14 @@ rd = &sc->sc_rb.rb_rxdesc[ri]; unmap = rd->hrx_m != NULL; - if (unmap && keepold) + if (unmap && keepold) { + /* + * Reinitialize the descriptor flags, as they may have been + * altered by the hardware. + */ + hme_discard_rxbuf(sc, ri, 0); return (0); + } if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) return (ENOBUFS); m_clget(m, M_DONTWAIT); @@ -534,12 +562,15 @@ return (error); } + bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + hr->rb_tdhead = hr->rb_tdtail = 0; hr->rb_td_nbusy = 0; hr->rb_rdtail = 0; - CTR2(KTR_HME, "gem_meminit: tx ring va %p, pa %#lx", hr->rb_txd, + CTR2(KTR_HME, "hme_meminit: tx ring va %p, pa %#lx", hr->rb_txd, hr->rb_txddma); - CTR2(KTR_HME, "gem_meminit: rx ring va %p, pa %#lx", hr->rb_rxd, + CTR2(KTR_HME, "hme_meminit: rx ring va %p, pa %#lx", hr->rb_rxd, hr->rb_rxddma); CTR2(KTR_HME, "rx entry 1: flags %x, address %x", *(u_int32_t *)hr->rb_rxd, *(u_int32_t *)(hr->rb_rxd + 4)); @@ -861,7 +892,7 @@ u_int32_t flags; if ((m->m_flags & M_PKTHDR) == 0) - panic("gem_dmamap_load_mbuf: no packet header"); + panic("hme_dmamap_load_mbuf: no packet header"); totlen = m->m_pkthdr.len; sum = 0; si = sc->sc_rb.rb_tdhead; @@ -965,7 +996,9 @@ HME_WHINE(sc->sc_dev, "invalid packet size %d; dropping\n", len); #endif - goto drop; + ifp->if_ierrors++; + hme_discard_rxbuf(sc, ix, 1); + return; } m = sc->sc_rb.rb_rxdesc[ix].hrx_m; @@ -978,7 +1011,9 @@ * it is sure that a new buffer can be mapped. If it can not, * drop the packet, but leave the interface up. */ - goto drop; + ifp->if_iqdrops++; + hme_discard_rxbuf(sc, ix, 1); + return; } ifp->if_ipackets++; @@ -994,19 +1029,6 @@ m_adj(m, sizeof(struct ether_header)); /* Pass the packet up. */ ether_input(ifp, eh, m); - return; - -drop: - ifp->if_ierrors++; - /* - * Dropped a packet, reinitialize the descriptor and turn the - * ownership back to the hardware. - */ - HME_XD_SETFLAGS(sc->sc_pci, sc->sc_rb.rb_rxd, ix, HME_XD_OWN | - HME_XD_ENCODE_RSIZE(ulmin(HME_BUFSZ, - sc->sc_rb.rb_rxdesc[ix].hrx_len))); - bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } static void @@ -1084,7 +1106,7 @@ td = &sc->sc_rb.rb_txdesc[ri]; CTR1(KTR_HME, "hme_tint: not owned, dflags %#x", td->htx_flags); if ((td->htx_flags & HTXF_MAPPED) != 0) { - bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, + bus_dmamap_sync(sc->sc_tdmatag, td->htx_dmamap, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_tdmatag, td->htx_dmamap); } @@ -1120,6 +1142,7 @@ hme_rint(struct hme_softc *sc) { caddr_t xdr = sc->sc_rb.rb_rxd; + struct ifnet *ifp = &sc->sc_arpcom.ac_if; unsigned int ri, len; u_int32_t flags; @@ -1135,6 +1158,8 @@ if ((flags & HME_XD_OFL) != 0) { device_printf(sc->sc_dev, "buffer overflow, ri=%d; " "flags=0x%x\n", ri, flags); + ifp->if_ierrors++; + hme_discard_rxbuf(sc, ri, 1); } else { len = HME_XD_DECODE_RSIZE(flags); hme_read(sc, ri, len); Index: if_hmereg.h =================================================================== RCS file: /home/ncvs/src/sys/dev/hme/if_hmereg.h,v retrieving revision 1.2 diff -u -r1.2 if_hmereg.h --- if_hmereg.h 5 Jun 2002 15:21:44 -0000 1.2 +++ if_hmereg.h 12 Jul 2002 12:21:24 -0000 @@ -267,12 +267,6 @@ /* * Buffer Descriptors. */ -#ifdef notdef -struct hme_xd { - volatile u_int32_t xd_flags; - volatile u_int32_t xd_addr; /* Buffer address (DMA) */ -}; -#endif #define HME_XD_SIZE 8 #define HME_XD_FLAGS(base, index) ((base) + ((index) * HME_XD_SIZE) + 0) #define HME_XD_ADDR(base, index) ((base) + ((index) * HME_XD_SIZE) + 4) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-sparc" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020712162023.GD311>