Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci - Initialize some hardware bits for 8257[1234], ...



details:   https://anonhg.NetBSD.org/src/rev/d0a2a2361208
branches:  trunk
changeset: 806320:d0a2a2361208
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Sun Feb 15 21:32:33 2015 +0000

description:
- 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.

diffstat:

 sys/dev/pci/if_wm.c    |  215 ++++++++++++++++++++++++++++++++++++++++++++++--
 sys/dev/pci/if_wmreg.h |   22 ++++-
 2 files changed, 222 insertions(+), 15 deletions(-)

diffs (truncated from 350 to 300 lines):

diff -r 37bc1c3fedf1 -r d0a2a2361208 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Sun Feb 15 21:28:17 2015 +0000
+++ b/sys/dev/pci/if_wm.c       Sun Feb 15 21:32:33 2015 +0000
@@ -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_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 @@
        }
 }
 
+/* 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 @@
                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 @@
                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 @@
                         * 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 @@
 {
        /*
         * 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 */
diff -r 37bc1c3fedf1 -r d0a2a2361208 sys/dev/pci/if_wmreg.h
--- a/sys/dev/pci/if_wmreg.h    Sun Feb 15 21:28:17 2015 +0000
+++ b/sys/dev/pci/if_wmreg.h    Sun Feb 15 21:32:33 2015 +0000
@@ -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 @@
 #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 @@
 #define        WMREG_TDFTS     0x3428  /* Transmit Data FIFO Tail Saved */
 #define        WMREG_TDFPC     0x3430  /* Transmit Data FIFO Packet Count */
 



Home | Main Index | Thread Index | Old Index