PERFORCE change 93062 for review

Warner Losh imp at FreeBSD.org
Thu Mar 9 12:20:11 PST 2006


http://perforce.freebsd.org/chv.cgi?CH=93062

Change 93062 by imp at 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) ====



More information about the p4-projects mailing list