diff options
-rw-r--r-- | usr/src/uts/common/io/e1000g/README | 8 | ||||
-rw-r--r-- | usr/src/uts/common/io/e1000g/e1000g_alloc.c | 9 | ||||
-rw-r--r-- | usr/src/uts/common/io/e1000g/e1000g_main.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/e1000g/e1000g_rx.c | 35 | ||||
-rw-r--r-- | usr/src/uts/common/io/e1000g/e1000g_stat.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/io/e1000g/e1000g_sw.h | 6 |
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; |