Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Mar 2006 20:20:10 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 93062 for review
Message-ID:  <200603092020.k29KKApR022117@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=93062

Change 93062 by imp@imp_Speedy on 2006/03/09 20:19:16

	Get rid of bogus zero length packets.  We were unloading the
	map before flushing, then flushing after.  Ooops.  This doesn't
	work so well.
	
	still have ethernet problems, but things are better now.

Affected files ...

.. //depot/projects/arm/src/sys/arm/at91/if_ate.c#29 edit
.. //depot/projects/arm/src/sys/arm/at91/if_atereg.h#7 edit

Differences ...

==== //depot/projects/arm/src/sys/arm/at91/if_ate.c#29 (text+ko) ====

@@ -364,9 +364,11 @@
 		 * restarts from the first descriptor.
 		 */
 		if (i == ATE_MAX_RX_BUFFERS - 1)
-			seg.ds_addr |= 1 << 1;
-		sc->rx_descs[i].addr = seg.ds_addr;
+			sc->rx_descs[i].addr = seg.ds_addr | ETH_WRAP_BIT;
+		else
+			sc->rx_descs[i].addr = seg.ds_addr;
 		sc->rx_descs[i].status = 0;
+		bus_dmamap_sync(sc->rxtag, sc->rx_map[i], BUS_DMASYNC_PREREAD);
 		bus_dmamap_sync(sc->rxtag, sc->rx_map[i], BUS_DMASYNC_PREWRITE);
 	}
 	bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE);
@@ -580,7 +582,7 @@
 	status = RD4(sc, ETH_ISR);
 	if (status == 0)
 		return;
-	printf("IT IS %x %x\n", RD4(sc, ETH_RSR), RD4(sc, ETH_CTL));
+	printf("status is %x IT IS %x %x\n", status, RD4(sc, ETH_RSR), RD4(sc, ETH_CTL));
 
 	if (status & ETH_ISR_RCOM) {
 		bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
@@ -589,42 +591,62 @@
 			if (sc->rx_descs[i].addr & ETH_CPU_OWNER) {
 				struct mbuf *mb = sc->rx_mbuf[i];
 				bus_dma_segment_t seg;
-				int rx_stat = sc->rx_descs[i].status;
+				int rx_stat;
 				int nsegs;
 
-				printf("GOT ONE\n");
 				bus_dmamap_sync(sc->rxtag,
 				    sc->rx_map[i], BUS_DMASYNC_POSTREAD);
-				bus_dmamap_unload(sc->rxtag,
-				    sc->rx_map[i]);
+				rx_stat = sc->rx_descs[i].status;
+				printf("GOT ONE %d %x\n", i, rx_stat);
+				if ((rx_stat & ETH_LEN_MASK) == 0) {
+					printf("ignoring bogus 0 len packet\n");
+					bus_dmamap_load_mbuf_sg(sc->rxtag,
+					    sc->rx_map[i], sc->rx_mbuf[i],
+					    &seg, &nsegs, 0);
+					sc->rx_descs[i].status = 0;
+					sc->rx_descs[i].addr = seg.ds_addr;
+					if (i == ATE_MAX_RX_BUFFERS - 1)
+						sc->rx_descs[i].addr |=
+						    ETH_WRAP_BIT;
+					bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
+					    BUS_DMASYNC_PREREAD);
+					bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
+					    BUS_DMASYNC_PREWRITE);
+					continue;
+				}
 				WR4(sc, ETH_RSR, RD4(sc, ETH_RSR));
 				/*
 				 * Allocate a new buffer to replace this one.
 				 * if we cannot, then we drop this packet
-				 * and keep the old buffer we had.
+				 * and keep the old buffer we had.  Once allocated
+				 * the new buffer is loaded for dma.
 				 */
 				sc->rx_mbuf[i] = m_getcl(M_DONTWAIT, MT_DATA,
 				    M_PKTHDR);
 				if (!sc->rx_mbuf[i]) {
+					printf("Failed to get another mbuf -- discarding packet\n");
 					sc->rx_mbuf[i] = mb;
 					sc->rx_descs[i].addr &= ~ETH_CPU_OWNER;
-					bus_dmamap_sync(sc->rx_desc_tag,
-					    sc->rx_desc_map, 
+					bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
+					    BUS_DMASYNC_PREREAD);
+					bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
 					    BUS_DMASYNC_PREWRITE);
 					continue;
 				}
+				bus_dmamap_unload(sc->rxtag, sc->rx_map[i]);
 				if (bus_dmamap_load_mbuf_sg(sc->rxtag,
 				    sc->rx_map[i],
 				    sc->rx_mbuf[i], &seg, &nsegs, 0) != 0) {
+					printf("Failed to load mbuf -- discarding packet -- reload old?\n");
 					sc->rx_mbuf[i] = mb;
 					sc->rx_descs[i].addr &= ~ETH_CPU_OWNER;
-					bus_dmamap_sync(sc->rx_desc_tag,
-					    sc->rx_desc_map,
+					bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
+					    BUS_DMASYNC_PREREAD);
+					bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
 					    BUS_DMASYNC_PREWRITE);
 					continue;
 				}
-				mb->m_len = sc->rx_descs[i].status & 
-				    ETH_LEN_MASK;
+				mb->m_len = rx_stat & ETH_LEN_MASK;
 				mb->m_pkthdr.len = mb->m_len;
 				mb->m_pkthdr.rcvif = sc->ifp;
 				/*
@@ -632,11 +654,15 @@
 				 * the controller restarts from the first
 				 * descriptor.
 				 */
+				sc->rx_descs[i].status = 0;
+				sc->rx_descs[i].addr = seg.ds_addr;
 				if (i == ATE_MAX_RX_BUFFERS - 1)
-					seg.ds_addr |= 1 << 1;
-				sc->rx_descs[i].addr = seg.ds_addr;
-				sc->rx_descs[i].status = 0;
-				mb->m_len = rx_stat & ETH_LEN_MASK;
+					sc->rx_descs[i].addr |= ETH_WRAP_BIT;
+				else
+				bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
+				    BUS_DMASYNC_PREREAD);
+				bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
+				    BUS_DMASYNC_PREWRITE);
 				(*sc->ifp->if_input)(sc->ifp, mb);
 				break;
 			}

==== //depot/projects/arm/src/sys/arm/at91/if_atereg.h#7 (text+ko) ====




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