diff options
author | Winson Wang - Sun Microsystems - Beijing China <Zhen.W@Sun.COM> | 2010-01-15 08:52:23 +0800 |
---|---|---|
committer | Winson Wang - Sun Microsystems - Beijing China <Zhen.W@Sun.COM> | 2010-01-15 08:52:23 +0800 |
commit | 7b114c4b72aa312e481641f6d76a0f0194877786 (patch) | |
tree | e7a2df86a3e1465fae78a0b92b6cfb219b8870d7 /usr/src | |
parent | d24234c24aeaca4ca56ee3ac2794507968f274c4 (diff) | |
download | illumos-gate-7b114c4b72aa312e481641f6d76a0f0194877786.tar.gz |
6913754 rge with rtl8169sc caused tx errors repeatedly on plumb
6913756 rge tx performance is very slow for rtl8169sc
6914906 rge with RTL8169S hangs during test12 of nicdrv
Contributed by Masa Murayama (khf04453@nifty.ne.jp)
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/io/rge/rge.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/io/rge/rge_chip.c | 37 | ||||
-rw-r--r-- | usr/src/uts/common/io/rge/rge_rxtx.c | 10 |
3 files changed, 43 insertions, 7 deletions
diff --git a/usr/src/uts/common/io/rge/rge.h b/usr/src/uts/common/io/rge/rge.h index 7765276082..7ee3183434 100644 --- a/usr/src/uts/common/io/rge/rge.h +++ b/usr/src/uts/common/io/rge/rge.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -494,6 +494,7 @@ typedef struct rge { clock_t tick_delta; uint64_t last_opackets; uint64_t last_rpackets; + uint32_t rx_fifo_ovf; } rge_t; /* diff --git a/usr/src/uts/common/io/rge/rge_chip.c b/usr/src/uts/common/io/rge/rge_chip.c index 4bb5f16aca..9c09e0dfc5 100644 --- a/usr/src/uts/common/io/rge/rge_chip.c +++ b/usr/src/uts/common/io/rge/rge_chip.c @@ -43,6 +43,7 @@ static uint32_t rge_autorecover = 1; */ #define RGE_DBG RGE_DBG_REGS /* debug flag for this code */ static uint32_t rge_watchdog_count = 1 << 5; +static uint32_t rge_rx_watchdog_count = 1 << 3; /* * Operating register get/set access routines @@ -716,6 +717,7 @@ rge_chip_ident(rge_t *rgep) /* set pci latency timer */ if (chip->mac_ver == MAC_VER_8169 || chip->mac_ver == MAC_VER_8169S_D || + chip->mac_ver == MAC_VER_8169S_E || chip->mac_ver == MAC_VER_8169SC) pci_config_put8(rgep->cfg_handle, PCI_CONF_LATENCY_TIMER, 0x40); @@ -723,9 +725,9 @@ rge_chip_ident(rge_t *rgep) val16 = rge_reg_get16(rgep, RT_CONFIG_1_REG); val16 &= 0x0300; if (val16 == 0x1) /* 66Mhz PCI */ - pci_config_put32(rgep->cfg_handle, 0x7c, 0x00ff00ff); + rge_reg_put32(rgep, 0x7c, 0x000700ff); else if (val16 == 0x0) /* 33Mhz PCI */ - pci_config_put32(rgep->cfg_handle, 0x7c, 0x00ffff00); + rge_reg_put32(rgep, 0x7c, 0x0007ff00); } /* @@ -921,6 +923,10 @@ rge_chip_init(rge_t *rgep) val16 |= CPLUS_BIT14 | MUL_PCI_RW_ENABLE; rge_reg_put8(rgep, RESV_82_REG, 0x01); } + if (chip->mac_ver == MAC_VER_8169S_E || + chip->mac_ver == MAC_VER_8169SC) { + val16 |= MUL_PCI_RW_ENABLE; + } rge_reg_put16(rgep, CPLUS_COMMAND_REG, val16 & (~0x03)); /* @@ -1060,6 +1066,8 @@ rge_chip_start(rge_t *rgep) if (rgep->chipid.is_pcie) { rgep->int_mask |= NO_TXDESC_INT; } + rgep->rx_fifo_ovf = 0; + rgep->int_mask |= RX_FIFO_OVERFLOW_INT; rge_reg_put16(rgep, INT_MASK_REG, rgep->int_mask); /* @@ -1470,6 +1478,22 @@ rge_intr(caddr_t arg1, caddr_t arg2) rge_chip_cyclic(rgep); } + if (int_status & RX_FIFO_OVERFLOW_INT) { + /* start rx watchdog timeout detection */ + rgep->rx_fifo_ovf = 1; + if (rgep->int_mask & RX_FIFO_OVERFLOW_INT) { + rgep->int_mask &= ~RX_FIFO_OVERFLOW_INT; + update_int_mask = B_TRUE; + } + } else if (int_status & RGE_RX_INT) { + /* stop rx watchdog timeout detection */ + rgep->rx_fifo_ovf = 0; + if ((rgep->int_mask & RX_FIFO_OVERFLOW_INT) == 0) { + rgep->int_mask |= RX_FIFO_OVERFLOW_INT; + update_int_mask = B_TRUE; + } + } + mutex_exit(rgep->genlock); /* @@ -1567,6 +1591,15 @@ rge_factotum_stall_check(rge_t *rgep) ASSERT(mutex_owned(rgep->genlock)); /* + * Specific check for RX stall ... + */ + rgep->rx_fifo_ovf <<= 1; + if (rgep->rx_fifo_ovf > rge_rx_watchdog_count) { + RGE_REPORT((rgep, "rx_hang detected")); + return (B_TRUE); + } + + /* * Specific check for Tx stall ... * * The 'watchdog' counter is incremented whenever a packet diff --git a/usr/src/uts/common/io/rge/rge_rxtx.c b/usr/src/uts/common/io/rge/rge_rxtx.c index 4cf866473a..a2d881c67b 100644 --- a/usr/src/uts/common/io/rge/rge_rxtx.c +++ b/usr/src/uts/common/io/rge/rge_rxtx.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -697,10 +697,12 @@ rge_m_tx(void *arg, mblk_t *mp) rw_enter(rgep->errlock, RW_READER); if ((rgep->rge_mac_state != RGE_MAC_STARTED) || - (rgep->rge_chip_state != RGE_CHIP_RUNNING)) { - RGE_DEBUG(("rge_m_tx: tx doesn't work")); + (rgep->rge_chip_state != RGE_CHIP_RUNNING) || + (rgep->param_link_up != LINK_STATE_UP)) { rw_exit(rgep->errlock); - return (mp); + RGE_DEBUG(("rge_m_tx: tx doesn't work")); + freemsgchain(mp); + return (NULL); } while (mp != NULL) { |