changeset 8995:21494c5e1dc8

6589577 Huron does not discard and does transmit frames greater than maxFrameSize 6809729 Panic in function 'e1000g_rxfree_func' on T2000 6809877 e1000g E1000G_IPALIGNROOM code can be rewritten
author Miles Xu, Sun Microsystems <Min.Xu@Sun.COM>
date Sun, 08 Mar 2009 16:24:42 +0800
parents 3f12cbbe75b6
children a09bdbccfe1d
files usr/src/uts/common/io/e1000g/README usr/src/uts/common/io/e1000g/e1000g_alloc.c usr/src/uts/common/io/e1000g/e1000g_main.c usr/src/uts/common/io/e1000g/e1000g_rx.c usr/src/uts/common/io/e1000g/e1000g_stat.c usr/src/uts/common/io/e1000g/e1000g_sw.h
diffstat 6 files changed, 39 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/e1000g/README	Sat Mar 07 12:19:18 2009 -0700
+++ b/usr/src/uts/common/io/e1000g/README	Sun Mar 08 16:24:42 2009 +0800
@@ -649,3 +649,11 @@
 ======
   This version has the following fix:
    6732858 panic in e1000g_free_dma_buffer
+
+5.3.6
+======
+  This version has the following fixes:
+   6589577 Huron does not discard and does transmit frames greater than maxFrameSize
+   6809729 Panic in function 'e1000g_rxfree_func' on T2000
+   6809877 e1000g E1000G_IPALIGNROOM code can be rewritten
+
--- a/usr/src/uts/common/io/e1000g/e1000g_alloc.c	Sat Mar 07 12:19:18 2009 -0700
+++ b/usr/src/uts/common/io/e1000g/e1000g_alloc.c	Sun Mar 08 16:24:42 2009 +0800
@@ -1350,15 +1350,10 @@
 	 * we can use it. It gives better efficiency.
 	 */
 	packet->mp = desballoc((unsigned char *)
-	    rx_buf->address - E1000G_IPALIGNROOM,
-	    rx_buf->size + E1000G_IPALIGNROOM,
+	    rx_buf->address,
+	    rx_buf->size,
 	    BPRI_MED, &packet->free_rtn);
 
-	if (packet->mp != NULL) {
-		packet->mp->b_rptr += E1000G_IPALIGNROOM;
-		packet->mp->b_wptr += E1000G_IPALIGNROOM;
-	}
-
 	packet->dma_type = e1000g_dma_type;
 	packet->ref_cnt = 1;
 
--- a/usr/src/uts/common/io/e1000g/e1000g_main.c	Sat Mar 07 12:19:18 2009 -0700
+++ b/usr/src/uts/common/io/e1000g/e1000g_main.c	Sun Mar 08 16:24:42 2009 +0800
@@ -46,7 +46,7 @@
 
 static char ident[] = "Intel PRO/1000 Ethernet";
 static char e1000g_string[] = "Intel(R) PRO/1000 Network Connection";
-static char e1000g_version[] = "Driver Ver. 5.3.5";
+static char e1000g_version[] = "Driver Ver. 5.3.6";
 
 /*
  * Proto types for DDI entry points
--- a/usr/src/uts/common/io/e1000g/e1000g_rx.c	Sat Mar 07 12:19:18 2009 -0700
+++ b/usr/src/uts/common/io/e1000g/e1000g_rx.c	Sun Mar 08 16:24:42 2009 +0800
@@ -79,14 +79,9 @@
 		address = (unsigned char *)packet->rx_buf->address;
 		if (address != NULL) {
 			packet->mp = desballoc((unsigned char *)
-			    address - E1000G_IPALIGNROOM,
-			    packet->rx_buf->size + E1000G_IPALIGNROOM,
+			    address, packet->rx_buf->size,
 			    BPRI_MED, &packet->free_rtn);
 		}
-		if (packet->mp != NULL) {
-			packet->mp->b_rptr += E1000G_IPALIGNROOM;
-			packet->mp->b_wptr += E1000G_IPALIGNROOM;
-		}
 	}
 
 	/*
@@ -112,9 +107,6 @@
 		    (rx_data->flag & E1000G_RX_STOPPED)) {
 			devi_node = rx_data->priv_devi_node;
 
-			e1000g_free_rx_pending_buffers(rx_data);
-			e1000g_free_rx_data(rx_data);
-
 			if (devi_node != NULL) {
 				ring_cnt = atomic_dec_32_nv(
 				    &devi_node->pending_rx_count);
@@ -129,6 +121,9 @@
 				atomic_dec_32(
 				    &Adapter->pending_rx_count);
 			}
+
+			e1000g_free_rx_pending_buffers(rx_data);
+			e1000g_free_rx_data(rx_data);
 		}
 		mutex_exit(&e1000g_rx_detach_lock);
 	}
@@ -406,6 +401,8 @@
 	uint16_t cksumflags;
 	uint_t chain_sz = 0;
 	e1000g_rx_data_t *rx_data;
+	uint32_t max_size;
+	uint32_t min_size;
 
 	ret_mp = NULL;
 	ret_nmp = NULL;
@@ -435,6 +432,9 @@
 		return (ret_mp);
 	}
 
+	max_size = Adapter->max_frame_size - ETHERFCSL - VLAN_TAGSZ;
+	min_size = ETHERMIN;
+
 	/*
 	 * Loop through the receive descriptors starting at the last known
 	 * descriptor owned by the hardware that begins a packet.
@@ -580,14 +580,8 @@
 		 */
 		if (packet->mp == NULL) {
 			packet->mp = desballoc((unsigned char *)
-			    rx_buf->address - E1000G_IPALIGNROOM,
-			    length + E1000G_IPALIGNROOM,
+			    rx_buf->address, length,
 			    BPRI_MED, &packet->free_rtn);
-
-			if (packet->mp != NULL) {
-				packet->mp->b_rptr += E1000G_IPALIGNROOM;
-				packet->mp->b_wptr += E1000G_IPALIGNROOM;
-			}
 		}
 
 		if (packet->mp != NULL) {
@@ -739,6 +733,15 @@
 		}
 
 rx_end_of_packet:
+		if (E1000G_IS_VLAN_PACKET(rx_data->rx_mblk->b_rptr))
+			max_size = Adapter->max_frame_size - ETHERFCSL;
+
+		if ((rx_data->rx_mblk_len > max_size) ||
+		    (rx_data->rx_mblk_len < min_size)) {
+			E1000G_STAT(rx_ring->stat_size_error);
+			goto rx_drop;
+		}
+
 		/*
 		 * Found packet with EOP
 		 * Process the last fragment.
--- a/usr/src/uts/common/io/e1000g/e1000g_stat.c	Sat Mar 07 12:19:18 2009 -0700
+++ b/usr/src/uts/common/io/e1000g/e1000g_stat.c	Sun Mar 08 16:24:42 2009 +0800
@@ -175,6 +175,7 @@
 
 	e1000g_ksp->rx_error.value.ul = rx_ring->stat_error;
 	e1000g_ksp->rx_allocb_fail.value.ul = rx_ring->stat_allocb_fail;
+	e1000g_ksp->rx_size_error.value.ul = rx_ring->stat_size_error;
 
 	e1000g_ksp->tx_no_swpkt.value.ul = tx_ring->stat_no_swpkt;
 	e1000g_ksp->tx_no_desc.value.ul = tx_ring->stat_no_desc;
@@ -734,6 +735,8 @@
 	    KSTAT_DATA_ULONG);
 	kstat_named_init(&e1000g_ksp->rx_allocb_fail, "Rx Allocb Failure",
 	    KSTAT_DATA_ULONG);
+	kstat_named_init(&e1000g_ksp->rx_size_error, "Rx Size Error",
+	    KSTAT_DATA_ULONG);
 
 	kstat_named_init(&e1000g_ksp->tx_no_desc, "Tx No Desc",
 	    KSTAT_DATA_ULONG);
--- a/usr/src/uts/common/io/e1000g/e1000g_sw.h	Sat Mar 07 12:19:18 2009 -0700
+++ b/usr/src/uts/common/io/e1000g/e1000g_sw.h	Sun Mar 08 16:24:42 2009 +0800
@@ -304,6 +304,10 @@
  */
 #define	E1000G_TBD_LENGTH_MASK		0x000fffff
 
+#define	E1000G_IS_VLAN_PACKET(ptr)				\
+	((((struct ether_vlan_header *)(uintptr_t)ptr)->ether_tpid) ==	\
+	htons(ETHERTYPE_VLAN))
+
 /*
  * QUEUE_INIT_LIST -- Macro which will init ialize a queue to NULL.
  */
@@ -601,6 +605,7 @@
 
 	kstat_named_t rx_error;		/* Rx Error in Packet */
 	kstat_named_t rx_allocb_fail;	/* Rx Allocb Failure */
+	kstat_named_t rx_size_error;	/* Rx Size Error */
 
 	kstat_named_t tx_no_desc;	/* Tx No Desc */
 	kstat_named_t tx_no_swpkt;	/* Tx No Pkt Buffer */
@@ -807,6 +812,7 @@
 	uint32_t stat_error;
 	uint32_t stat_allocb_fail;
 	uint32_t stat_exceed_pkt;
+	uint32_t stat_size_error;
 #ifdef E1000G_DEBUG
 	uint32_t stat_none;
 	uint32_t stat_multi_desc;