Skip site navigation (1)Skip section navigation (2)
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>