Module Name: src Committed By: msaitoh Date: Sun Feb 15 21:32:33 UTC 2015
Modified Files: src/sys/dev/pci: if_wm.c if_wmreg.h Log Message: - Initialize some hardware bits for 8257[1234], 82583, 80003, ICH* and PCH*. Some of them are workaround code. From other *BSDs, Linux and documents. - Add comment. - Fix typo in comment. To generate a diff of this commit: cvs rdiff -u -r1.311 -r1.312 src/sys/dev/pci/if_wm.c cvs rdiff -u -r1.65 -r1.66 src/sys/dev/pci/if_wmreg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_wm.c diff -u src/sys/dev/pci/if_wm.c:1.311 src/sys/dev/pci/if_wm.c:1.312 --- src/sys/dev/pci/if_wm.c:1.311 Fri Feb 13 09:00:50 2015 +++ src/sys/dev/pci/if_wm.c Sun Feb 15 21:32:33 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.311 2015/02/13 09:00:50 msaitoh Exp $ */ +/* $NetBSD: if_wm.c,v 1.312 2015/02/15 21:32:33 msaitoh Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -81,7 +81,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.311 2015/02/13 09:00:50 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.312 2015/02/15 21:32:33 msaitoh Exp $"); #ifdef _KERNEL_OPT #include "opt_net_mpsafe.h" @@ -565,6 +565,7 @@ static void wm_set_pcie_completion_timeo static void wm_get_auto_rd_done(struct wm_softc *); static void wm_lan_init_done(struct wm_softc *); static void wm_get_cfg_done(struct wm_softc *); +static void wm_initialize_hardware_bits(struct wm_softc *); static void wm_reset(struct wm_softc *); static int wm_add_rxbuf(struct wm_softc *, int); static void wm_rxdrain(struct wm_softc *); @@ -3230,6 +3231,200 @@ wm_get_cfg_done(struct wm_softc *sc) } } +/* Init hardware bits */ +void +wm_initialize_hardware_bits(struct wm_softc *sc) +{ + uint32_t tarc0, tarc1, reg; + + /* For 82571 variant, 80003 and ICHs */ + if (((sc->sc_type >= WM_T_82571) && (sc->sc_type <= WM_T_82583)) + || (sc->sc_type >= WM_T_80003)) { + + /* Transmit Descriptor Control 0 */ + reg = CSR_READ(sc, WMREG_TXDCTL(0)); + reg |= TXDCTL_COUNT_DESC; + CSR_WRITE(sc, WMREG_TXDCTL(0), reg); + + /* Transmit Descriptor Control 1 */ + reg = CSR_READ(sc, WMREG_TXDCTL(1)); + reg |= TXDCTL_COUNT_DESC; + CSR_WRITE(sc, WMREG_TXDCTL(1), reg); + + /* TARC0 */ + tarc0 = CSR_READ(sc, WMREG_TARC0); + switch (sc->sc_type) { + case WM_T_82571: + case WM_T_82572: + case WM_T_82573: + case WM_T_82574: + case WM_T_82583: + case WM_T_80003: + /* Clear bits 30..27 */ + tarc0 &= ~__BITS(30, 27); + break; + default: + break; + } + + switch (sc->sc_type) { + case WM_T_82571: + case WM_T_82572: + tarc0 |= __BITS(26, 23); /* TARC0 bits 23-26 */ + + tarc1 = CSR_READ(sc, WMREG_TARC1); + tarc1 &= ~__BITS(30, 29); /* Clear bits 30 and 29 */ + tarc1 |= __BITS(26, 24); /* TARC1 bits 26-24 */ + /* 8257[12] Errata No.7 */ + tarc1 |= __BIT(22); /* TARC1 bits 22 */ + + /* TARC1 bit 28 */ + if ((CSR_READ(sc, WMREG_TCTL) & TCTL_MULR) != 0) + tarc1 &= ~__BIT(28); + else + tarc1 |= __BIT(28); + CSR_WRITE(sc, WMREG_TARC1, tarc1); + + /* + * 8257[12] Errata No.13 + * Disable Dyamic Clock Gating. + */ + reg = CSR_READ(sc, WMREG_CTRL_EXT); + reg &= ~CTRL_EXT_DMA_DYN_CLK; + CSR_WRITE(sc, WMREG_CTRL_EXT, reg); + break; + case WM_T_82573: + case WM_T_82574: + case WM_T_82583: + if ((sc->sc_type == WM_T_82574) + || (sc->sc_type == WM_T_82583)) + tarc0 |= __BIT(26); /* TARC0 bit 26 */ + + /* Extended Device Control */ + reg = CSR_READ(sc, WMREG_CTRL_EXT); + reg &= ~__BIT(23); /* Clear bit 23 */ + reg |= __BIT(22); /* Set bit 22 */ + CSR_WRITE(sc, WMREG_CTRL_EXT, reg); + + /* Device Control */ + sc->sc_ctrl &= ~__BIT(29); /* Clear bit 29 */ + CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + + /* PCIe Control Register */ + if ((sc->sc_type == WM_T_82574) + || (sc->sc_type == WM_T_82583)) { + /* + * Document says this bit must be set for + * proper operation. + */ + reg = CSR_READ(sc, WMREG_GCR); + reg |= __BIT(22); + CSR_WRITE(sc, WMREG_GCR, reg); + + /* + * Apply workaround for hardware errata + * documented in errata docs Fixes issue where + * some error prone or unreliable PCIe + * completions are occurring, particularly + * with ASPM enabled. Without fix, issue can + * cause Tx timeouts. + */ + reg = CSR_READ(sc, WMREG_GCR2); + reg |= __BIT(0); + CSR_WRITE(sc, WMREG_GCR2, reg); + } + break; + case WM_T_80003: + /* TARC0 */ + if ((sc->sc_mediatype == WM_MEDIATYPE_FIBER) + || (sc->sc_mediatype == WM_MEDIATYPE_SERDES)) + tarc0 &= ~__BIT(20); /* Clear bits 20 */ + + /* TARC1 bit 28 */ + tarc1 = CSR_READ(sc, WMREG_TARC1); + if ((CSR_READ(sc, WMREG_TCTL) & TCTL_MULR) != 0) + tarc1 &= ~__BIT(28); + else + tarc1 |= __BIT(28); + CSR_WRITE(sc, WMREG_TARC1, tarc1); + break; + case WM_T_ICH8: + case WM_T_ICH9: + case WM_T_ICH10: + case WM_T_PCH: + case WM_T_PCH2: + case WM_T_PCH_LPT: + /* TARC 0 */ + if (sc->sc_type == WM_T_ICH8) { + /* Set TARC0 bits 29 and 28 */ + tarc0 |= __BITS(29, 28); + } + /* Set TARC0 bits 23,24,26,27 */ + tarc0 |= __BITS(27, 26) | __BITS(24, 23); + + /* CTRL_EXT */ + reg = CSR_READ(sc, WMREG_CTRL_EXT); + reg |= __BIT(22); /* Set bit 22 */ + /* + * Enable PHY low-power state when MAC is at D3 + * w/o WoL + */ + if (sc->sc_type >= WM_T_PCH) + reg |= CTRL_EXT_PHYPDEN; + CSR_WRITE(sc, WMREG_CTRL_EXT, reg); + + /* TARC1 */ + tarc1 = CSR_READ(sc, WMREG_TARC1); + /* bit 28 */ + if ((CSR_READ(sc, WMREG_TCTL) & TCTL_MULR) != 0) + tarc1 &= ~__BIT(28); + else + tarc1 |= __BIT(28); + tarc1 |= __BIT(24) | __BIT(26) | __BIT(30); + CSR_WRITE(sc, WMREG_TARC1, tarc1); + + /* Device Status */ + if (sc->sc_type == WM_T_ICH8) { + reg = CSR_READ(sc, WMREG_STATUS); + reg &= ~__BIT(31); + CSR_WRITE(sc, WMREG_STATUS, reg); + + } + + /* + * Work-around descriptor data corruption issue during + * NFS v2 UDP traffic, just disable the NFS filtering + * capability. + */ + reg = CSR_READ(sc, WMREG_RFCTL); + reg |= WMREG_RFCTL_NFSWDIS | WMREG_RFCTL_NFSRDIS; + CSR_WRITE(sc, WMREG_RFCTL, reg); + break; + default: + break; + } + CSR_WRITE(sc, WMREG_TARC0, tarc0); + + /* + * 8257[12] Errata No.52 and some others. + * Avoid RSS Hash Value bug. + */ + switch (sc->sc_type) { + case WM_T_82571: + case WM_T_82572: + case WM_T_82573: + case WM_T_80003: + case WM_T_ICH8: + reg = CSR_READ(sc, WMREG_RFCTL); + reg |= WMREG_RFCTL_NEWIPV6EXDIS |WMREG_RFCTL_IPV6EXDIS; + CSR_WRITE(sc, WMREG_RFCTL, reg); + break; + default: + break; + } + } +} + /* * wm_reset: * @@ -3284,6 +3479,7 @@ wm_reset(struct wm_softc *sc) sc->sc_pba = PBA_20K; break; case WM_T_ICH8: + /* Workaround for a bit corruption issue in FIFO memory */ sc->sc_pba = PBA_8K; CSR_WRITE(sc, WMREG_PBS, PBA_16K); break; @@ -3747,16 +3943,13 @@ wm_init_locked(struct ifnet *ifp) break; } + /* Init hardware bits */ + wm_initialize_hardware_bits(sc); + /* Reset the PHY. */ if (sc->sc_flags & WM_F_HAS_MII) wm_gmii_reset(sc); - reg = CSR_READ(sc, WMREG_CTRL_EXT); - /* Enable PHY low-power state when MAC is at D3 w/o WoL */ - if ((sc->sc_type == WM_T_PCH) || (sc->sc_type == WM_T_PCH2) - || (sc->sc_type == WM_T_PCH_LPT)) - CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_PHYPDEN); - /* Initialize the transmit descriptor ring. */ memset(sc->sc_txdescs, 0, WM_TXDESCSIZE(sc)); WM_CDTXSYNC(sc, 0, WM_NTXDESC(sc), @@ -3784,12 +3977,12 @@ wm_init_locked(struct ifnet *ifp) * Don't write TDT before TCTL.EN is set. * See the document. */ - CSR_WRITE(sc, WMREG_TXDCTL, TXDCTL_QUEUE_ENABLE + CSR_WRITE(sc, WMREG_TXDCTL(0), TXDCTL_QUEUE_ENABLE | TXDCTL_PTHRESH(0) | TXDCTL_HTHRESH(0) | TXDCTL_WTHRESH(0)); else { CSR_WRITE(sc, WMREG_TDT, 0); - CSR_WRITE(sc, WMREG_TXDCTL, TXDCTL_PTHRESH(0) | + CSR_WRITE(sc, WMREG_TXDCTL(0), TXDCTL_PTHRESH(0) | TXDCTL_HTHRESH(0) | TXDCTL_WTHRESH(0)); CSR_WRITE(sc, WMREG_RXDCTL, RXDCTL_PTHRESH(0) | RXDCTL_HTHRESH(0) | RXDCTL_WTHRESH(1)); @@ -9440,7 +9633,7 @@ wm_reset_init_script_82575(struct wm_sof { /* * remark: this is untested code - we have no board without EEPROM - * same setup as mentioned int the freeBSD driver for the i82575 + * same setup as mentioned int the FreeBSD driver for the i82575 */ /* SerDes configuration via SERDESCTRL */ Index: src/sys/dev/pci/if_wmreg.h diff -u src/sys/dev/pci/if_wmreg.h:1.65 src/sys/dev/pci/if_wmreg.h:1.66 --- src/sys/dev/pci/if_wmreg.h:1.65 Fri Oct 24 17:58:09 2014 +++ src/sys/dev/pci/if_wmreg.h Sun Feb 15 21:32:33 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmreg.h,v 1.65 2014/10/24 17:58:09 msaitoh Exp $ */ +/* $NetBSD: if_wmreg.h,v 1.66 2015/02/15 21:32:33 msaitoh Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -315,6 +315,7 @@ struct livengood_tcpip_ctxdesc { #define CTRL_EXT_SPD_BYPS (1U << 15) /* speed select bypass */ #define CTRL_EXT_IPS1 (1U << 16) /* invert power state bit 1 */ #define CTRL_EXT_RO_DIS (1U << 17) /* relaxed ordering disabled */ +#define CTRL_EXT_DMA_DYN_CLK (1U << 19) /* DMA Dymamic Gating Enable */ #define CTRL_EXT_LINK_MODE_MASK 0x00C00000 #define CTRL_EXT_LINK_MODE_GMII 0x00000000 #define CTRL_EXT_LINK_MODE_KMRN 0x00000000 @@ -756,11 +757,14 @@ struct livengood_tcpip_ctxdesc { #define WMREG_TDFTS 0x3428 /* Transmit Data FIFO Tail Saved */ #define WMREG_TDFPC 0x3430 /* Transmit Data FIFO Packet Count */ -#define WMREG_TXDCTL 0x3828 /* Trandmit Descriptor Control */ +#define WMREG_TXDCTL(n) /* Trandmit Descriptor Control */ \ + (((n) < 4) ? (0x3828 + ((n) * 0x100)) : (0xe028 + ((n) * 0x40))) #define TXDCTL_PTHRESH(x) ((x) << 0) /* prefetch threshold */ #define TXDCTL_HTHRESH(x) ((x) << 8) /* host threshold */ #define TXDCTL_WTHRESH(x) ((x) << 16) /* write back threshold */ /* flags used starting with 82575 ... */ +#define TXDCTL_COUNT_DESC __BIT(22) /* Enable the counting of desc. + still to be processed. */ #define TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */ #define TXDCTL_SWFLSH 0x04000000 /* Tx Desc. write-back flushing */ #define TXDCTL_PRIORITY 0x08000000 @@ -768,11 +772,12 @@ struct livengood_tcpip_ctxdesc { #define WMREG_TADV 0x382c /* Transmit Absolute Interrupt Delay Timer */ #define WMREG_TSPMT 0x3830 /* TCP Segmentation Pad and Minimum Threshold (Cordova) */ -#define WMREG_TARC0 0x3840 /* Tx arbitration count */ - #define TSPMT_TSMT(x) (x) /* TCP seg min transfer */ #define TSPMT_TSPBP(x) ((x) << 16) /* TCP seg pkt buf padding */ +#define WMREG_TARC0 0x3840 /* Tx arbitration count (0) */ +#define WMREG_TARC1 0x3940 /* Tx arbitration count (1) */ + #define WMREG_CRCERRS 0x4000 /* CRC Error Count */ #define WMREG_ALGNERRC 0x4004 /* Alignment Error Count */ #define WMREG_SYMERRC 0x4008 /* Symbol Error Count */ @@ -799,6 +804,13 @@ struct livengood_tcpip_ctxdesc { #define WMREG_RLPML 0x5004 /* Rx Long Packet Max Length */ +#define WMREG_RFCTL 0x5008 /* Receive Filter Control */ +#define WMREG_RFCTL_NFSWDIS __BIT(6) /* NFS Write Disable */ +#define WMREG_RFCTL_NFSRDIS __BIT(7) /* NFS Read Disable */ +#define WMREG_RFCTL_ACKDIS __BIT(13) /* ACK Accelerate Disable */ +#define WMREG_RFCTL_IPV6EXDIS __BIT(16) /* IPv6 Extension Header Disable */ +#define WMREG_RFCTL_NEWIPV6EXDIS __BIT(17) /* New IPv6 Extension Header */ + #define WMREG_WUC 0x5800 /* Wakeup Control */ #define WUC_APME 0x00000001 /* APM Enable */ #define WUC_PME_EN 0x00000002 /* PME Enable */ @@ -874,6 +886,8 @@ struct livengood_tcpip_ctxdesc { #define SWFW_SOFT_SHIFT 0 /* software semaphores */ #define SWFW_FIRM_SHIFT 16 /* firmware semaphores */ +#define WMREG_GCR2 0x5b64 /* 3GPIO Control Register 2 */ + #define WMREG_CRC_OFFSET 0x5f50 /*