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.
This commit is contained in:
parent
415d159521
commit
cf1efaaa6a
|
@ -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 @@ re_attach(struct rtk_softc *sc)
|
|||
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 @@ re_txeof(struct rtk_softc *sc)
|
|||
* 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 @@ re_intr(void *arg)
|
|||
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 @@ re_intr(void *arg)
|
|||
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 @@ re_start(struct ifnet *ifp)
|
|||
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 @@ re_start(struct ifnet *ifp)
|
|||
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 @@ re_init(struct ifnet *ifp)
|
|||
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 @@ re_init(struct ifnet *ifp)
|
|||
*/
|
||||
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 @@ re_init(struct ifnet *ifp)
|
|||
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
|
||||
|
|
|
@ -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 @@ struct re_desc {
|
|||
#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
|
||||
|
|
|
@ -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 @@ struct rtk_softc {
|
|||
#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;
|
||||
|
||||
|
|
|
@ -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 @@ re_pci_attach(device_t parent, device_t self, void *aux)
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue