Index: if_em.c
===================================================================
--- if_em.c	(revision 212405)
+++ if_em.c	(working copy)
@@ -3671,11 +3671,13 @@
 	bus_dma_segment_t	segs[1];
 	bus_dmamap_t		map;
 	struct em_buffer	*rxbuf;
-	int			i, error, nsegs, cleaned;
+	int			i, j, error, nsegs, cleaned;
 
-	i = rxr->next_to_refresh;
+	i = j = rxr->next_to_refresh;
 	cleaned = -1;
-	while (i != limit) {
+	if (++j == adapter->num_rx_desc)
+		j = 0;
+	while (j != limit) {
 		m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
 		if (m == NULL)
 			goto update;
@@ -3711,9 +3713,10 @@
 		rxr->rx_base[i].buffer_addr = htole64(segs[0].ds_addr);
 
 		cleaned = i;
+		i = j;
 		/* Calculate next index */
-		if (++i == adapter->num_rx_desc)
-			i = 0;
+		if (++j == adapter->num_rx_desc)
+			j = 0;
 		/* This is the work marker for refresh */
 		rxr->next_to_refresh = i;
 	}
@@ -3722,7 +3725,7 @@
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	if (cleaned != -1) /* Update tail index */
 		E1000_WRITE_REG(&adapter->hw,
-		    E1000_RDT(rxr->me), cleaned);
+		    E1000_RDT(rxr->me), rxr->next_to_refresh);
 
 	return;
 }
@@ -3809,32 +3812,22 @@
 	struct	adapter 	*adapter = rxr->adapter;
 	struct em_buffer	*rxbuf;
 	bus_dma_segment_t	seg[1];
-	int			rsize, nsegs, error;
+	int			i, j, nsegs, error;
 
 
 	/* Clear the ring contents */
 	EM_RX_LOCK(rxr);
-	rsize = roundup2(adapter->num_rx_desc *
-	    sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
-	bzero((void *)rxr->rx_base, rsize);
-
-	/*
-	** Free current RX buffer structs and their mbufs
-	*/
-	for (int i = 0; i < adapter->num_rx_desc; i++) {
-		rxbuf = &rxr->rx_buffers[i];
-		if (rxbuf->m_head != NULL) {
-			bus_dmamap_sync(rxr->rxtag, rxbuf->map,
-			    BUS_DMASYNC_POSTREAD);
-			bus_dmamap_unload(rxr->rxtag, rxbuf->map);
-			m_freem(rxbuf->m_head);
-		}
+	for (i = 0; i < adapter->num_rx_desc; i++) {
+		struct e1000_rx_desc* cur;
+		cur = &rxr->rx_base[i];
+		cur->status = 0;
 	}
 
-	/* Now replenish the mbufs */
-	for (int j = 0; j != adapter->num_rx_desc; ++j) {
-
-		rxbuf = &rxr->rx_buffers[j];
+	i = j = rxr->next_to_refresh;
+	if (++j == adapter->num_rx_desc)
+		j = 0;
+	while(j != rxr->next_to_check) {
+		rxbuf = &rxr->rx_buffers[i];
 		rxbuf->m_head = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
 		if (rxbuf->m_head == NULL)
 			panic("RX ring hdr initialization failed!\n");
@@ -3852,13 +3845,14 @@
 		    rxbuf->map, BUS_DMASYNC_PREREAD);
 
 		/* Update descriptor */
-		rxr->rx_base[j].buffer_addr = htole64(seg[0].ds_addr);
+		rxr->rx_base[i].buffer_addr = htole64(seg[0].ds_addr);
+		i = j;
+		if (++j == adapter->num_rx_desc)
+			j = 0;
 	}
 
-
 	/* Setup our descriptor indices */
-	rxr->next_to_check = 0;
-	rxr->next_to_refresh = 0;
+	rxr->next_to_refresh = i;
 
 	bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -3938,6 +3932,7 @@
 {
 	struct adapter		*adapter = rxr->adapter;
 	struct em_buffer	*rxbuf = NULL;
+	int 			i;
 
 	INIT_DEBUGOUT("free_receive_buffers: begin");
 
@@ -3947,7 +3942,8 @@
 	}
 
 	if (rxr->rx_buffers != NULL) {
-		for (int i = 0; i < adapter->num_rx_desc; i++) {
+		i = rxr->next_to_check;
+		while(i != rxr->next_to_refresh) {
 			rxbuf = &rxr->rx_buffers[i];
 			if (rxbuf->map != NULL) {
 				bus_dmamap_sync(rxr->rxtag, rxbuf->map,
@@ -3959,6 +3955,8 @@
 				m_freem(rxbuf->m_head);
 				rxbuf->m_head = NULL;
 			}
+			if (++i == adapter->num_rx_desc)
+				i = 0;			
 		}
 		free(rxr->rx_buffers, M_DEVBUF);
 		rxr->rx_buffers = NULL;
@@ -4044,8 +4042,8 @@
 		E1000_WRITE_REG(hw, E1000_RDBAH(i), (u32)(bus_addr >> 32));
 		E1000_WRITE_REG(hw, E1000_RDBAL(i), (u32)bus_addr);
 		/* Setup the Head and Tail Descriptor Pointers */
-		E1000_WRITE_REG(hw, E1000_RDH(i), 0);
-		E1000_WRITE_REG(hw, E1000_RDT(i), adapter->num_rx_desc - 1);
+		E1000_WRITE_REG(hw, E1000_RDH(i), rxr->next_to_check);
+		E1000_WRITE_REG(hw, E1000_RDT(i), rxr->next_to_refresh);
 	}
 
 	/* Setup the Receive Control Register */
@@ -4206,7 +4204,7 @@
 	}
 
 	/* Catch any remaining refresh work */
-	if (processed != 0) {
+	if (processed != 0 || i == rxr->next_to_refresh) {
 		em_refresh_mbufs(rxr, i);
 		processed = 0;
 	}
