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 (
[email protected])
--- a/usr/src/uts/common/io/rge/rge.h Thu Jan 14 14:38:50 2010 -0800
+++ b/usr/src/uts/common/io/rge/rge.h Fri Jan 15 08:52:23 2010 +0800
@@ -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 @@
clock_t tick_delta;
uint64_t last_opackets;
uint64_t last_rpackets;
+ uint32_t rx_fifo_ovf;
} rge_t;
/*
--- a/usr/src/uts/common/io/rge/rge_chip.c Thu Jan 14 14:38:50 2010 -0800
+++ b/usr/src/uts/common/io/rge/rge_chip.c Fri Jan 15 08:52:23 2010 +0800
@@ -43,6 +43,7 @@
*/
#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 @@
/* 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 @@
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 @@
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 @@
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_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 @@
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
--- a/usr/src/uts/common/io/rge/rge_rxtx.c Thu Jan 14 14:38:50 2010 -0800
+++ b/usr/src/uts/common/io/rge/rge_rxtx.c Fri Jan 15 08:52:23 2010 +0800
@@ -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 @@
rw_enter(rgep->errlock, RW_READER);
if ((rgep->rge_mac_state != RGE_MAC_STARTED) ||
- (rgep->rge_chip_state != RGE_CHIP_RUNNING)) {
+ (rgep->rge_chip_state != RGE_CHIP_RUNNING) ||
+ (rgep->param_link_up != LINK_STATE_UP)) {
+ rw_exit(rgep->errlock);
RGE_DEBUG(("rge_m_tx: tx doesn't work"));
- rw_exit(rgep->errlock);
- return (mp);
+ freemsgchain(mp);
+ return (NULL);
}
while (mp != NULL) {