Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Performance improvements for PCIe and 8168 based dev...
details: https://anonhg.NetBSD.org/src/rev/62173e00e3ca
branches: trunk
changeset: 353061:62173e00e3ca
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Wed Apr 19 00:20:02 2017 +0000
description:
Performance improvements for PCIe and 8168 based devices:
- When using the countdown timer for interrupt moderation on PCIe devices,
use a timer rate value based on a 125MHz PCIe reference clock instead of
33 MHz.
- For 8168 based devices, ditch the countdown timer and instead use the
(undocumented) hardware interrupt moderation feature.
- Support TSOv4 on 8168D and later devices.
diffstat:
sys/dev/ic/rtl8169.c | 73 ++++++++++++++++++++++++++++++------------------
sys/dev/ic/rtl81x9reg.h | 8 ++++-
sys/dev/ic/rtl81x9var.h | 3 +-
sys/dev/pci/if_re_pci.c | 7 +++-
4 files changed, 60 insertions(+), 31 deletions(-)
diffs (236 lines):
diff -r d89c607933c3 -r 62173e00e3ca sys/dev/ic/rtl8169.c
--- a/sys/dev/ic/rtl8169.c Wed Apr 19 00:17:30 2017 +0000
+++ b/sys/dev/ic/rtl8169.c Wed Apr 19 00:20:02 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl8169.c,v 1.149 2017/02/20 06:46:41 ozaki-r Exp $ */
+/* $NetBSD: rtl8169.c,v 1.150 2017/04/19 00:20:02 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.149 2017/02/20 06:46:41 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.150 2017/04/19 00:20:02 jmcneill Exp $");
/* $FreeBSD: /repoman/r/ncvs/src/sys/dev/re/if_re.c,v 1.20 2004/04/11 20:34:08 ru Exp $ */
/*
@@ -837,14 +837,6 @@
IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
IFCAP_TSOv4;
- /*
- * XXX
- * Still have no idea how to make TSO work on 8168C, 8168CP,
- * 8102E, 8111C and 8111CP.
- */
- if ((sc->sc_quirk & RTKQ_DESCV2) != 0)
- ifp->if_capabilities &= ~IFCAP_TSOv4;
-
ifp->if_watchdog = re_watchdog;
ifp->if_init = re_init;
ifp->if_snd.ifq_maxlen = RE_IFQ_MAXLEN;
@@ -1418,7 +1410,8 @@
* This is done in case the transmitter has gone idle.
*/
if (sc->re_ldata.re_txq_free < RE_TX_QLEN) {
- CSR_WRITE_4(sc, RTK_TIMERCNT, 1);
+ if ((sc->sc_quirk & RTKQ_IM_HW) == 0)
+ CSR_WRITE_4(sc, RTK_TIMERCNT, 1);
if ((sc->sc_quirk & RTKQ_PCIE) != 0) {
/*
* Some chips will ignore a second TX request
@@ -1466,6 +1459,9 @@
if ((ifp->if_flags & IFF_UP) == 0)
return 0;
+ const uint16_t status_mask = (sc->sc_quirk & RTKQ_IM_HW) ?
+ RTK_INTRS_IM_HW : RTK_INTRS_CPLUS;
+
for (;;) {
status = CSR_READ_2(sc, RTK_ISR);
@@ -1477,14 +1473,14 @@
CSR_WRITE_2(sc, RTK_ISR, status);
}
- if ((status & RTK_INTRS_CPLUS) == 0)
+ if ((status & status_mask) == 0)
break;
if (status & (RTK_ISR_RX_OK | RTK_ISR_RX_ERR))
re_rxeof(sc);
if (status & (RTK_ISR_TIMEOUT_EXPIRED | RTK_ISR_TX_ERR |
- RTK_ISR_TX_DESC_UNAVAIL))
+ RTK_ISR_TX_DESC_UNAVAIL | RTK_ISR_TX_OK))
re_txeof(sc);
if (status & RTK_ISR_SYSTEM_ERR) {
@@ -1552,8 +1548,14 @@
if ((m->m_pkthdr.csum_flags & M_CSUM_TSOv4) != 0) {
uint32_t segsz = m->m_pkthdr.segsz;
- re_flags = RE_TDESC_CMD_LGSEND |
- (segsz << RE_TDESC_CMD_MSSVAL_SHIFT);
+ if ((sc->sc_quirk & RTKQ_DESCV2) == 0) {
+ re_flags = RE_TDESC_CMD_LGSEND |
+ (segsz << RE_TDESC_CMD_MSSVAL_SHIFT);
+ } else {
+ re_flags = RE_TDESC_CMD_LGSEND_V4;
+ vlanctl |=
+ (segsz << RE_TDESC_VLANCTL_MSSVAL_SHIFT);
+ }
} else {
/*
* set RE_TDESC_CMD_IPCSUM if any checksum offloading
@@ -1746,15 +1748,17 @@
else
CSR_WRITE_1(sc, RTK_GTXSTART, RTK_TXSTART_START);
- /*
- * Use the countdown timer for interrupt moderation.
- * 'TX done' interrupts are disabled. Instead, we reset the
- * countdown timer, which will begin counting until it hits
- * the value in the TIMERINT register, and then trigger an
- * interrupt. Each time we write to the TIMERCNT register,
- * the timer count is reset to 0.
- */
- CSR_WRITE_4(sc, RTK_TIMERCNT, 1);
+ if ((sc->sc_quirk & RTKQ_IM_HW) == 0) {
+ /*
+ * Use the countdown timer for interrupt moderation.
+ * 'TX done' interrupts are disabled. Instead, we reset
+ * the countdown timer, which will begin counting until
+ * it hits the value in the TIMERINT register, and then
+ * trigger an interrupt. Each time we write to the
+ * TIMERCNT register, the timer count is reset to 0.
+ */
+ CSR_WRITE_4(sc, RTK_TIMERCNT, 1);
+ }
/*
* Set a timeout in case the chip goes out to lunch.
@@ -1813,8 +1817,13 @@
CSR_WRITE_2(sc, RTK_CPLUS_CMD, cfg);
/* XXX: from Realtek-supplied Linux driver. Wholly undocumented. */
- if ((sc->sc_quirk & RTKQ_8139CPLUS) == 0)
- CSR_WRITE_2(sc, RTK_IM, 0x0000);
+ if ((sc->sc_quirk & RTKQ_8139CPLUS) == 0) {
+ if ((sc->sc_quirk & RTKQ_IM_HW) == 0) {
+ CSR_WRITE_2(sc, RTK_IM, 0x0000);
+ } else {
+ CSR_WRITE_2(sc, RTK_IM, 0x5151);
+ }
+ }
DELAY(10000);
@@ -1907,6 +1916,8 @@
*/
if (sc->re_testmode)
CSR_WRITE_2(sc, RTK_IMR, 0);
+ else if ((sc->sc_quirk & RTKQ_IM_HW) == 0)
+ CSR_WRITE_2(sc, RTK_IMR, RTK_INTRS_IM_HW);
else
CSR_WRITE_2(sc, RTK_IMR, RTK_INTRS_CPLUS);
@@ -1928,7 +1939,15 @@
if ((sc->sc_quirk & RTKQ_8139CPLUS) != 0)
CSR_WRITE_4(sc, RTK_TIMERINT, 0x400);
else {
- CSR_WRITE_4(sc, RTK_TIMERINT_8169, 0x800);
+ if ((sc->sc_quirk & RTKQ_IM_HW) == 0) {
+ if ((sc->sc_quirk & RTKQ_PCIE) != 0) {
+ CSR_WRITE_4(sc, RTK_TIMERINT_8169, 15000);
+ } else {
+ CSR_WRITE_4(sc, RTK_TIMERINT_8169, 0x800);
+ }
+ } else {
+ CSR_WRITE_4(sc, RTK_TIMERINT_8169, 0);
+ }
/*
* For 8169 gigE NICs, set the max allowed RX packet
diff -r d89c607933c3 -r 62173e00e3ca sys/dev/ic/rtl81x9reg.h
--- a/sys/dev/ic/rtl81x9reg.h Wed Apr 19 00:17:30 2017 +0000
+++ b/sys/dev/ic/rtl81x9reg.h Wed Apr 19 00:20:02 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl81x9reg.h,v 1.47 2015/08/28 13:20:46 nonaka Exp $ */
+/* $NetBSD: rtl81x9reg.h,v 1.48 2017/04/19 00:20:02 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -258,6 +258,8 @@
RTK_ISR_RX_OVERRUN|RTK_ISR_PKT_UNDERRUN|RTK_ISR_FIFO_OFLOW| \
RTK_ISR_PCS_TIMEOUT|RTK_ISR_SYSTEM_ERR|RTK_ISR_TIMEOUT_EXPIRED)
+#define RTK_INTRS_IM_HW \
+ (RTK_INTRS_CPLUS|RTK_ISR_TX_OK)
/*
* Media status register. (8139 only)
@@ -507,12 +509,16 @@
#define RE_TDESC_CMD_SOF 0x20000000 /* start of frame marker */
#define RE_TDESC_CMD_EOR 0x40000000 /* end of ring marker */
#define RE_TDESC_CMD_OWN 0x80000000 /* chip owns descriptor */
+#define RE_TDESC_CMD_LGSEND_V4 0x04000000 /* DESCV2 TCPv4 large send en */
+#define RE_TDESC_CMD_LGSEND_V6 0x08000000 /* DESCV2 TCPv6 large send en */
#define RE_TDESC_VLANCTL_TAG 0x00020000 /* Insert VLAN tag */
#define RE_TDESC_VLANCTL_DATA 0x0000FFFF /* TAG data */
#define RE_TDESC_VLANCTL_UDPCSUM 0x80000000 /* DESCV2 UDP cksum enable */
#define RE_TDESC_VLANCTL_TCPCSUM 0x40000000 /* DESCV2 TCP cksum enable */
#define RE_TDESC_VLANCTL_IPCSUM 0x20000000 /* DESCV2 IP hdr cksum enable */
+#define RE_TDESC_VLANCTL_MSSVAL 0x0ffc0000 /* DESCV2 large send MSS val */
+#define RE_TDESC_VLANCTL_MSSVAL_SHIFT 18
/*
* Error bits are valid only on the last descriptor of a frame
diff -r d89c607933c3 -r 62173e00e3ca sys/dev/ic/rtl81x9var.h
--- a/sys/dev/ic/rtl81x9var.h Wed Apr 19 00:17:30 2017 +0000
+++ b/sys/dev/ic/rtl81x9var.h Wed Apr 19 00:20:02 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl81x9var.h,v 1.55 2015/04/13 16:33:24 riastradh Exp $ */
+/* $NetBSD: rtl81x9var.h,v 1.56 2017/04/19 00:20:02 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -193,6 +193,7 @@
#define RTKQ_CMDSTOP 0x00000200 /* set STOPREQ on stop */
#define RTKQ_PHYWAKE_PM 0x00000400 /* wake PHY from power down */
#define RTKQ_RXDV_GATED 0x00000800
+#define RTKQ_IM_HW 0x00001000 /* HW interrupt mitigation */
bus_dma_tag_t sc_dmat;
diff -r d89c607933c3 -r 62173e00e3ca sys/dev/pci/if_re_pci.c
--- a/sys/dev/pci/if_re_pci.c Wed Apr 19 00:17:30 2017 +0000
+++ b/sys/dev/pci/if_re_pci.c Wed Apr 19 00:20:02 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_re_pci.c,v 1.45 2015/12/14 20:01:17 jakllsch Exp $ */
+/* $NetBSD: if_re_pci.c,v 1.46 2017/04/19 00:20:02 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_re_pci.c,v 1.45 2015/12/14 20:01:17 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_re_pci.c,v 1.46 2017/04/19 00:20:02 jmcneill Exp $");
#include <sys/types.h>
@@ -240,6 +240,9 @@
t->rtk_basetype == RTK_8101E)
sc->sc_quirk |= RTKQ_PCIE;
+ if (t->rtk_basetype == RTK_8168)
+ sc->sc_quirk |= RTKQ_IM_HW;
+
if (pci_dma64_available(pa) && (sc->sc_quirk & RTKQ_PCIE))
sc->sc_dmat = pa->pa_dmat64;
else
Home |
Main Index |
Thread Index |
Old Index