Mercurial > illumos > illumos-gate
changeset 12865:636a63adb7b9
6861114 System Panics with FMA ereport.io.fire.epkt
6876953 Memory leaks found in e1000g_alloc_rx_sw_packet on snv_111b
6945160 netlbtest fails with Can't set loopback mode on device e1000g6
6960959 panic in e1000g_receive
6965855 e1000g(intel 82571 adapter) needs to support MTU size of 9000
6967530 Need version in e1000g driver
6967873 e1000g needs to clear the link-down status when being unplumbed
author | changqing li - Sun Microsystems - Beijing China <Changqing.Li@Sun.COM> |
---|---|
date | Mon, 19 Jul 2010 11:06:32 +0800 |
parents | 30d581e817b8 |
children | d1953f8e5b5f |
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_sw.h |
diffstat | 5 files changed, 132 insertions(+), 66 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/e1000g/README Sat Jul 17 18:14:22 2010 -0400 +++ b/usr/src/uts/common/io/e1000g/README Mon Jul 19 11:06:32 2010 +0800 @@ -17,12 +17,12 @@ # See the License for the specific language governing permissions # and limitations under the License. # -# -# Copyright 2010 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # # + + 4.0.4 code drop from Intel on 1/30/2003 ======================================= This version is used as the base for putback into both s10 and @@ -757,3 +757,13 @@ 6925276 e1000g not consistent with link_lock usage 6933844 NULL ptr deref in e1000g_rx_setup() due to inconsistency between recv_list & rx_desc_num +5.3.24 +===== + This version has the following fixes: + 6861114 System Panics with FMA ereport.io.fire.epkt + 6876953 Memory leaks found in e1000g_alloc_rx_sw_packet on snv_111b + 6945160 netlbtest fails with Can't set loopback mode on device e1000g6 + 6960959 panic in e1000g_receive + 6965855 e1000g(intel 82571 adapter) needs to support MTU size of 9000 + 6967530 Need version in e1000g driver + 6967873 e1000g needs to clear the link-down status when being unplumbed
--- a/usr/src/uts/common/io/e1000g/e1000g_alloc.c Sat Jul 17 18:14:22 2010 -0400 +++ b/usr/src/uts/common/io/e1000g/e1000g_alloc.c Mon Jul 19 11:06:32 2010 +0800 @@ -19,8 +19,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -48,7 +47,7 @@ static int e1000g_alloc_tx_packets(e1000g_tx_ring_t *); static int e1000g_alloc_rx_packets(e1000g_rx_data_t *); static void e1000g_free_tx_packets(e1000g_tx_ring_t *); -static void e1000g_free_rx_packets(e1000g_rx_data_t *); +static void e1000g_free_rx_packets(e1000g_rx_data_t *, boolean_t); static int e1000g_alloc_dma_buffer(struct e1000g *, dma_buffer_t *, size_t, ddi_dma_attr_t *p_dma_attr); @@ -175,8 +174,7 @@ while ((result != DDI_SUCCESS) && (Adapter->tx_desc_num >= MIN_NUM_TX_DESCRIPTOR) && (Adapter->rx_desc_num >= MIN_NUM_RX_DESCRIPTOR) && - (Adapter->tx_freelist_num >= MIN_NUM_TX_FREELIST) && - (Adapter->rx_freelist_num >= MIN_NUM_RX_FREELIST)) { + (Adapter->tx_freelist_num >= MIN_NUM_TX_FREELIST)) { result = e1000g_alloc_descriptors(Adapter); @@ -203,7 +201,6 @@ (Adapter->rx_desc_num >> 4) << 3; Adapter->tx_freelist_num >>= 1; - Adapter->rx_freelist_num >>= 1; } } @@ -773,7 +770,7 @@ rx_data = Adapter->rx_ring->rx_data; e1000g_free_tx_packets(tx_ring); - e1000g_free_rx_packets(rx_data); + e1000g_free_rx_packets(rx_data, B_FALSE); } #ifdef __sparc @@ -1243,6 +1240,44 @@ return (DDI_FAILURE); } + +int +e1000g_increase_rx_packets(e1000g_rx_data_t *rx_data) +{ + int i; + p_rx_sw_packet_t packet; + p_rx_sw_packet_t cur, next; + struct e1000g *Adapter; + ddi_dma_attr_t dma_attr; + + Adapter = rx_data->rx_ring->adapter; + dma_attr = e1000g_buf_dma_attr; + dma_attr.dma_attr_align = Adapter->rx_buf_align; + cur = NULL; + + for (i = 0; i < RX_FREELIST_INCREASE_SIZE; i++) { + packet = e1000g_alloc_rx_sw_packet(rx_data, &dma_attr); + if (packet == NULL) + break; + packet->next = cur; + cur = packet; + } + Adapter->rx_freelist_num += i; + rx_data->avail_freepkt += i; + + while (cur != NULL) { + QUEUE_PUSH_TAIL(&rx_data->free_list, &cur->Link); + next = cur->next; + cur->next = rx_data->packet_area; + rx_data->packet_area = cur; + + cur = next; + } + + return (DDI_SUCCESS); +} + + static int e1000g_alloc_rx_packets(e1000g_rx_data_t *rx_data) { @@ -1264,7 +1299,7 @@ * need is equal to the number of receive descriptors plus the freelist * size. */ - packet_num = Adapter->rx_desc_num + Adapter->rx_freelist_num; + packet_num = Adapter->rx_desc_num + RX_FREELIST_INCREASE_SIZE; rx_data->packet_area = NULL; for (i = 0; i < packet_num; i++) { @@ -1276,14 +1311,15 @@ rx_data->packet_area = packet; } + Adapter->rx_freelist_num = RX_FREELIST_INCREASE_SIZE; return (DDI_SUCCESS); rx_pkt_fail: - e1000g_free_rx_packets(rx_data); - + e1000g_free_rx_packets(rx_data, B_TRUE); return (DDI_FAILURE); } + static p_rx_sw_packet_t e1000g_alloc_rx_sw_packet(e1000g_rx_data_t *rx_data, ddi_dma_attr_t *p_dma_attr) { @@ -1397,7 +1433,7 @@ } static void -e1000g_free_rx_packets(e1000g_rx_data_t *rx_data) +e1000g_free_rx_packets(e1000g_rx_data_t *rx_data, boolean_t full_release) { p_rx_sw_packet_t packet, next_packet; uint32_t ref_cnt; @@ -1413,7 +1449,7 @@ atomic_inc_32(&rx_data->pending_count); atomic_inc_32(&e1000g_mblks_pending); } else { - e1000g_free_rx_sw_packet(packet, B_FALSE); + e1000g_free_rx_sw_packet(packet, full_release); } packet = next_packet;
--- a/usr/src/uts/common/io/e1000g/e1000g_main.c Sat Jul 17 18:14:22 2010 -0400 +++ b/usr/src/uts/common/io/e1000g/e1000g_main.c Mon Jul 19 11:06:32 2010 +0800 @@ -19,8 +19,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -45,6 +44,8 @@ #include "e1000g_debug.h" static char ident[] = "Intel PRO/1000 Ethernet"; +/* LINTED E_STATIC_UNUSED */ +static char e1000g_version[] = "Driver Ver. 5.3.24"; /* * Proto types for DDI entry points @@ -253,6 +254,7 @@ /* * Global variables */ +uint32_t e1000g_jumbo_mtu = MAXIMUM_MTU_9K; uint32_t e1000g_mblks_pending = 0; /* * Workaround for Dynamic Reconfiguration support, for x86 platform only. @@ -580,7 +582,6 @@ } Adapter->e1000g_state = E1000G_INITIALIZED; - return (DDI_SUCCESS); attach_fail: @@ -886,13 +887,17 @@ case e1000_82574: case e1000_80003es2lan: case e1000_ich10lan: - Adapter->max_mtu = MAXIMUM_MTU_9K; + if (e1000g_jumbo_mtu >= ETHERMTU && + e1000g_jumbo_mtu <= MAXIMUM_MTU_9K) { + Adapter->max_mtu = e1000g_jumbo_mtu; + } else { + Adapter->max_mtu = MAXIMUM_MTU_9K; + } break; /* default limit is 16K */ default: Adapter->max_mtu = FRAME_SIZE_UPTO_16K - - sizeof (struct ether_vlan_header) - ETHERFCSL - - E1000G_IPALIGNPRESERVEROOM; + sizeof (struct ether_vlan_header) - ETHERFCSL; break; } } @@ -938,10 +943,9 @@ ((mac->type == e1000_82545) || (mac->type == e1000_82546) || (mac->type == e1000_82546_rev_3))) { - Adapter->rx_buffer_size = E1000_RX_BUFFER_SIZE_2K + - E1000G_IPALIGNROOM; + Adapter->rx_buffer_size = E1000_RX_BUFFER_SIZE_2K; } else { - rx_size = Adapter->max_frame_size + E1000G_IPALIGNPRESERVEROOM; + rx_size = Adapter->max_frame_size; if ((rx_size > FRAME_SIZE_UPTO_2K) && (rx_size <= FRAME_SIZE_UPTO_4K)) Adapter->rx_buffer_size = E1000_RX_BUFFER_SIZE_4K; @@ -954,6 +958,7 @@ else Adapter->rx_buffer_size = E1000_RX_BUFFER_SIZE_2K; } + Adapter->rx_buffer_size += E1000G_IPALIGNROOM; tx_size = Adapter->max_frame_size; if ((tx_size > FRAME_SIZE_UPTO_2K) && (tx_size <= FRAME_SIZE_UPTO_4K)) @@ -1660,7 +1665,12 @@ case e1000_media_type_copper: if (hw->mac.get_link_status) { (void) e1000_check_for_link(hw); - link_up = !hw->mac.get_link_status; + if ((E1000_READ_REG(hw, E1000_STATUS) & + E1000_STATUS_LU)) { + link_up = B_TRUE; + } else { + link_up = !hw->mac.get_link_status; + } } else { link_up = B_TRUE; } @@ -1993,7 +2003,7 @@ mutex_exit(&e1000g_rx_detach_lock); } - if (Adapter->link_state == LINK_STATE_UP) { + if (Adapter->link_state != LINK_STATE_UNKNOWN) { Adapter->link_state = LINK_STATE_UNKNOWN; if (!Adapter->reset_flag) mac_link_update(Adapter->mh, Adapter->link_state); @@ -3234,9 +3244,7 @@ * resource consumption */ if (Adapter->max_frame_size >= - (FRAME_SIZE_UPTO_4K - - E1000G_IPALIGNPRESERVEROOM)) { - + (FRAME_SIZE_UPTO_4K)) { if (Adapter->tx_desc_num_flag == 0) Adapter->tx_desc_num = DEFAULT_JUMBO_NUM_TX_DESC; @@ -3250,7 +3258,7 @@ DEFAULT_JUMBO_NUM_TX_BUF; if (Adapter->rx_buf_num_flag == 0) - Adapter->rx_freelist_num = + Adapter->rx_freelist_limit = DEFAULT_JUMBO_NUM_RX_BUF; } else { if (Adapter->tx_desc_num_flag == 0) @@ -3266,7 +3274,7 @@ DEFAULT_NUM_TX_FREELIST; if (Adapter->rx_buf_num_flag == 0) - Adapter->rx_freelist_num = + Adapter->rx_freelist_limit = DEFAULT_NUM_RX_FREELIST; } } @@ -3827,9 +3835,7 @@ * decrease the number of descriptors and free packets * for jumbo frames to reduce tx/rx resource consumption */ - if (Adapter->max_frame_size >= - (FRAME_SIZE_UPTO_4K - - E1000G_IPALIGNPRESERVEROOM)) { + if (Adapter->max_frame_size >= FRAME_SIZE_UPTO_4K) { is_jumbo = B_TRUE; } @@ -3865,7 +3871,7 @@ MIN_NUM_RX_FREELIST, MAX_NUM_RX_FREELIST, is_jumbo ? DEFAULT_JUMBO_NUM_RX_BUF : DEFAULT_NUM_RX_FREELIST, &propval); - Adapter->rx_freelist_num = propval; + Adapter->rx_freelist_limit = propval; /* * NumTxPacketList @@ -4502,24 +4508,17 @@ case 0: Adapter->default_mtu = ETHERMTU; break; - /* - * To avoid excessive memory allocation for rx buffers, - * the bytes of E1000G_IPALIGNPRESERVEROOM are reserved. - */ case 1: Adapter->default_mtu = FRAME_SIZE_UPTO_4K - - sizeof (struct ether_vlan_header) - ETHERFCSL - - E1000G_IPALIGNPRESERVEROOM; + sizeof (struct ether_vlan_header) - ETHERFCSL; break; case 2: Adapter->default_mtu = FRAME_SIZE_UPTO_8K - - sizeof (struct ether_vlan_header) - ETHERFCSL - - E1000G_IPALIGNPRESERVEROOM; + sizeof (struct ether_vlan_header) - ETHERFCSL; break; case 3: Adapter->default_mtu = FRAME_SIZE_UPTO_16K - - sizeof (struct ether_vlan_header) - ETHERFCSL - - E1000G_IPALIGNPRESERVEROOM; + sizeof (struct ether_vlan_header) - ETHERFCSL; break; default: Adapter->default_mtu = ETHERMTU;
--- a/usr/src/uts/common/io/e1000g/e1000g_rx.c Sat Jul 17 18:14:22 2010 -0400 +++ b/usr/src/uts/common/io/e1000g/e1000g_rx.c Mon Jul 19 11:06:32 2010 +0800 @@ -19,8 +19,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -266,11 +265,13 @@ */ rctl = E1000_RCTL_EN | /* Enable Receive Unit */ E1000_RCTL_BAM | /* Accept Broadcast Packets */ - E1000_RCTL_LPE | /* Large Packet Enable bit */ (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT) | E1000_RCTL_RDMTS_HALF | E1000_RCTL_LBM_NO; /* Loopback Mode = none */ + if (Adapter->default_mtu > ETHERMTU) + rctl |= E1000_RCTL_LPE; /* Large Packet Enable bit */ + if (Adapter->strip_crc) rctl |= E1000_RCTL_SECRC; /* Strip Ethernet CRC */ @@ -368,29 +369,44 @@ e1000g_get_buf(e1000g_rx_data_t *rx_data) { p_rx_sw_packet_t packet; + struct e1000g *Adapter; + + Adapter = rx_data->rx_ring->adapter; mutex_enter(&rx_data->freelist_lock); packet = (p_rx_sw_packet_t) QUEUE_POP_HEAD(&rx_data->free_list); if (packet != NULL) { rx_data->avail_freepkt--; - } else { - /* - * If the freelist has no packets, check the recycle list - * to see if there are any available descriptor there. - */ - mutex_enter(&rx_data->recycle_lock); - QUEUE_SWITCH(&rx_data->free_list, &rx_data->recycle_list); - rx_data->avail_freepkt = rx_data->recycle_freepkt; - rx_data->recycle_freepkt = 0; - mutex_exit(&rx_data->recycle_lock); + goto end; + } + + /* + * If the freelist has no packets, check the recycle list + * to see if there are any available descriptor there. + */ + mutex_enter(&rx_data->recycle_lock); + QUEUE_SWITCH(&rx_data->free_list, &rx_data->recycle_list); + rx_data->avail_freepkt = rx_data->recycle_freepkt; + rx_data->recycle_freepkt = 0; + mutex_exit(&rx_data->recycle_lock); + packet = (p_rx_sw_packet_t)QUEUE_POP_HEAD(&rx_data->free_list); + if (packet != NULL) { + rx_data->avail_freepkt--; + goto end; + } + + if (Adapter->rx_freelist_num < Adapter->rx_freelist_limit) { + (void) e1000g_increase_rx_packets(rx_data); packet = (p_rx_sw_packet_t) QUEUE_POP_HEAD(&rx_data->free_list); - if (packet != NULL) + if (packet != NULL) { rx_data->avail_freepkt--; + } } + +end: mutex_exit(&rx_data->freelist_lock); - return (packet); } @@ -580,12 +596,15 @@ * drop this fragment, do the processing of * the end of the packet. */ - ASSERT(rx_data->rx_mblk_tail != NULL); + if (rx_data->rx_mblk_tail == NULL) { + E1000G_STAT(rx_ring->stat_crc_only_pkt); + goto rx_next_desc; + } + rx_data->rx_mblk_tail->b_wptr -= ETHERFCSL - length; rx_data->rx_mblk_len -= ETHERFCSL - length; - goto rx_end_of_packet; } }
--- a/usr/src/uts/common/io/e1000g/e1000g_sw.h Sat Jul 17 18:14:22 2010 -0400 +++ b/usr/src/uts/common/io/e1000g/e1000g_sw.h Mon Jul 19 11:06:32 2010 +0800 @@ -19,8 +19,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _E1000G_SW_H @@ -145,6 +144,7 @@ #define DEFAULT_JUMBO_NUM_RX_BUF 2048 #define DEFAULT_JUMBO_NUM_TX_BUF 1152 #define DEFAULT_RX_LIMIT_ON_INTR 128 +#define RX_FREELIST_INCREASE_SIZE 512 #ifdef __sparc #define MAX_INTR_PER_SEC 7100 @@ -224,8 +224,7 @@ * Defined for IP header alignment. We also need to preserve space for * VLAN tag (4 bytes) */ -#define E1000G_IPALIGNROOM 6 -#define E1000G_IPALIGNPRESERVEROOM 64 +#define E1000G_IPALIGNROOM 2 /* * bit flags for 'attach_progress' which is a member variable in struct e1000g @@ -833,6 +832,7 @@ uint32_t stat_allocb_fail; uint32_t stat_exceed_pkt; uint32_t stat_size_error; + uint32_t stat_crc_only_pkt; #ifdef E1000G_DEBUG uint32_t stat_none; uint32_t stat_multi_desc; @@ -877,6 +877,7 @@ uint32_t tx_freelist_num; uint32_t rx_desc_num; uint32_t rx_freelist_num; + uint32_t rx_freelist_limit; uint32_t tx_buffer_size; uint32_t rx_buffer_size; @@ -1042,6 +1043,7 @@ void e1000g_free_rx_sw_packet(p_rx_sw_packet_t packet, boolean_t full_release); void e1000g_tx_setup(struct e1000g *Adapter); void e1000g_rx_setup(struct e1000g *Adapter); +int e1000g_increase_rx_packets(e1000g_rx_data_t *rx_data); int e1000g_recycle(e1000g_tx_ring_t *tx_ring); void e1000g_free_tx_swpkt(p_tx_sw_packet_t packet);