summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorMiles Xu, Sun Microsystems <Min.Xu@Sun.COM>2009-03-08 16:24:42 +0800
committerMiles Xu, Sun Microsystems <Min.Xu@Sun.COM>2009-03-08 16:24:42 +0800
commit46ebaa55cce1df60528a191312d12199d38a4493 (patch)
tree269b00305229fc1ceaa1f7f897b52c66d147b33c /usr/src
parente6049c8a3e8cbdd126b50fdc6f161fcabbf0acd5 (diff)
downloadillumos-gate-46ebaa55cce1df60528a191312d12199d38a4493.tar.gz
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
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/io/e1000g/README8
-rw-r--r--usr/src/uts/common/io/e1000g/e1000g_alloc.c9
-rw-r--r--usr/src/uts/common/io/e1000g/e1000g_main.c2
-rw-r--r--usr/src/uts/common/io/e1000g/e1000g_rx.c35
-rw-r--r--usr/src/uts/common/io/e1000g/e1000g_stat.c3
-rw-r--r--usr/src/uts/common/io/e1000g/e1000g_sw.h6
6 files changed, 39 insertions, 24 deletions
diff --git a/usr/src/uts/common/io/e1000g/README b/usr/src/uts/common/io/e1000g/README
index 92761ffbae..5b2c52bcd6 100644
--- a/usr/src/uts/common/io/e1000g/README
+++ b/usr/src/uts/common/io/e1000g/README
@@ -649,3 +649,11 @@ Notes on packaging:
======
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
+
diff --git a/usr/src/uts/common/io/e1000g/e1000g_alloc.c b/usr/src/uts/common/io/e1000g/e1000g_alloc.c
index 8222bf97b2..99583f9034 100644
--- a/usr/src/uts/common/io/e1000g/e1000g_alloc.c
+++ b/usr/src/uts/common/io/e1000g/e1000g_alloc.c
@@ -1350,15 +1350,10 @@ e1000g_alloc_rx_sw_packet(e1000g_rx_data_t *rx_data, ddi_dma_attr_t *p_dma_attr)
* 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;
diff --git a/usr/src/uts/common/io/e1000g/e1000g_main.c b/usr/src/uts/common/io/e1000g/e1000g_main.c
index 6d9b4646d9..c4903db176 100644
--- a/usr/src/uts/common/io/e1000g/e1000g_main.c
+++ b/usr/src/uts/common/io/e1000g/e1000g_main.c
@@ -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
diff --git a/usr/src/uts/common/io/e1000g/e1000g_rx.c b/usr/src/uts/common/io/e1000g/e1000g_rx.c
index b70474446d..e179521ae8 100644
--- a/usr/src/uts/common/io/e1000g/e1000g_rx.c
+++ b/usr/src/uts/common/io/e1000g/e1000g_rx.c
@@ -79,14 +79,9 @@ e1000g_rxfree_func(p_rx_sw_packet_t packet)
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 @@ e1000g_rxfree_func(p_rx_sw_packet_t packet)
(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 @@ e1000g_rxfree_func(p_rx_sw_packet_t packet)
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 @@ e1000g_receive(e1000g_rx_ring_t *rx_ring, mblk_t **tail, uint_t sz)
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 @@ e1000g_receive(e1000g_rx_ring_t *rx_ring, mblk_t **tail, uint_t sz)
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 @@ e1000g_receive(e1000g_rx_ring_t *rx_ring, mblk_t **tail, uint_t sz)
*/
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_copy:
}
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.
diff --git a/usr/src/uts/common/io/e1000g/e1000g_stat.c b/usr/src/uts/common/io/e1000g/e1000g_stat.c
index 9c5f6b2db0..65afa818be 100644
--- a/usr/src/uts/common/io/e1000g/e1000g_stat.c
+++ b/usr/src/uts/common/io/e1000g/e1000g_stat.c
@@ -175,6 +175,7 @@ e1000g_update_stats(kstat_t *ksp, int rw)
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 @@ e1000g_init_stats(struct e1000g *Adapter)
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);
diff --git a/usr/src/uts/common/io/e1000g/e1000g_sw.h b/usr/src/uts/common/io/e1000g/e1000g_sw.h
index 0ed02c7613..4fd6ca8010 100644
--- a/usr/src/uts/common/io/e1000g/e1000g_sw.h
+++ b/usr/src/uts/common/io/e1000g/e1000g_sw.h
@@ -304,6 +304,10 @@ extern "C" {
*/
#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 @@ typedef struct _e1000g_stat {
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 @@ typedef struct _e1000g_rx_ring {
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;