Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci Fix problems associated with the SiS 635/735 on-...



details:   https://anonhg.NetBSD.org/src/rev/cf4f3e5956f9
branches:  trunk
changeset: 521969:cf4f3e5956f9
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sat Feb 09 21:04:02 2002 +0000

description:
Fix problems associated with the SiS 635/735 on-board Ethernet,
from Stephen Degler <sdegler%degler.net@localhost>, port-i386/15261.

diffstat:

 sys/dev/pci/if_sip.c    |  99 ++++++++++++++++++++++++++++++++++++++----------
 sys/dev/pci/if_sipreg.h |  16 +++++++-
 2 files changed, 93 insertions(+), 22 deletions(-)

diffs (278 lines):

diff -r d3a4a4c6350a -r cf4f3e5956f9 sys/dev/pci/if_sip.c
--- a/sys/dev/pci/if_sip.c      Sat Feb 09 20:01:34 2002 +0000
+++ b/sys/dev/pci/if_sip.c      Sat Feb 09 21:04:02 2002 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: if_sip.c,v 1.44 2001/12/20 03:32:31 thorpej Exp $      */
+/*     $NetBSD: if_sip.c,v 1.45 2002/02/09 21:04:02 thorpej Exp $      */
 
 /*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -82,7 +82,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.44 2001/12/20 03:32:31 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.45 2002/02/09 21:04:02 thorpej Exp $");
 
 #include "bpfilter.h"
 
@@ -217,6 +217,7 @@
        void *sc_sdhook;                /* shutdown hook */
 
        const struct sip_product *sc_model; /* which model are we? */
+       int sc_rev;                     /* chip revision */
 
        void *sc_ih;                    /* interrupt cookie */
 
@@ -366,6 +367,20 @@
        SIP_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
 } while (0)
 
+#define        SIP_CHIP_VERS(sc, v, p, r)                                      \
+       ((sc)->sc_model->sip_vendor == (v) &&                           \
+        (sc)->sc_model->sip_product == (p) &&                          \
+        (sc)->sc_rev == (r))
+
+#define        SIP_CHIP_MODEL(sc, v, p)                                        \
+       ((sc)->sc_model->sip_vendor == (v) &&                           \
+        (sc)->sc_model->sip_product == (p))
+
+#if !defined(DP83820)
+#define        SIP_SIS900_REV(sc, rev)                                         \
+       SIP_CHIP_VERS((sc), PCI_VENDOR_SIS, PCI_PRODUCT_SIS_900, (rev))
+#endif
+
 #define SIP_TIMEOUT 1000
 
 void   SIP_DECL(start)(struct ifnet *);
@@ -567,6 +582,7 @@
                printf("\n");
                panic(SIP_STR(attach) ": impossible");
        }
+       sc->sc_rev = PCI_REVISION(pa->pa_class);
 
        printf(": %s\n", sip->sip_name);
 
@@ -728,6 +744,12 @@
         * in the softc.
         */
        sc->sc_cfg = 0;
+#if !defined(DP83820)
+       if (SIP_SIS900_REV(sc,SIS_REV_635) ||
+           SIP_SIS900_REV(sc,SIS_REV_900B))
+               sc->sc_cfg |= (CFG_PESEL | CFG_RNDCNT);
+#endif
+
        (*sip->sip_variant->sipv_read_macaddr)(sc, pa, enaddr);
 
        printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
@@ -1913,6 +1935,9 @@
        bus_space_handle_t sh = sc->sc_sh;
        int i;
 
+       bus_space_write_4(st, sh, SIP_IER, 0);
+       bus_space_write_4(st, sh, SIP_IMR, 0);
+       bus_space_write_4(st, sh, SIP_RFCR, 0);
        bus_space_write_4(st, sh, SIP_CR, CR_RST);
 
        for (i = 0; i < SIP_TIMEOUT; i++) {
@@ -1964,8 +1989,7 @@
        SIP_DECL(reset)(sc);
 
 #if !defined(DP83820)
-       if (sc->sc_model->sip_vendor == PCI_VENDOR_NS &&
-           sc->sc_model->sip_product == PCI_PRODUCT_NS_DP83815) {
+       if (SIP_CHIP_MODEL(sc, PCI_VENDOR_NS, PCI_PRODUCT_NS_DP83815)) {
                /*
                 * DP83815 manual, page 78:
                 *    4.4 Recommended Registers Configuration
@@ -2058,11 +2082,10 @@
         */
        if (sc->sc_tx_fill_thresh == 0) {
                /*
-                * XXX This value should be tuned.  This is the
-                * minimum (32 bytes), and we may be able to
+                * XXX This value should be tuned.  We may be able to
                 * improve performance by increasing it.
                 */
-               sc->sc_tx_fill_thresh = 1;
+               sc->sc_tx_fill_thresh = 64/32;
        }
        if (sc->sc_tx_drain_thresh == 0) {
                /*
@@ -2081,7 +2104,22 @@
        /*
         * Initialize the prototype TXCFG register.
         */
-       sc->sc_txcfg = TXCFG_ATP | TXCFG_MXDMA_512 |
+#if defined(DP83820)
+       sc->sc_txcfg = TXCFG_MXDMA_512;
+       sc->sc_rxcfg = RXCFG_MXDMA_512;
+#else
+       if ((SIP_SIS900_REV(sc, SIS_REV_635) ||
+            SIP_SIS900_REV(sc, SIS_REV_900B)) &&
+           (bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_CFG) & CFG_EDBMASTEN)) {
+               sc->sc_txcfg = TXCFG_MXDMA_64;
+               sc->sc_rxcfg = RXCFG_MXDMA_64;
+       } else {
+               sc->sc_txcfg = TXCFG_MXDMA_512;
+               sc->sc_rxcfg = RXCFG_MXDMA_512;
+       }
+#endif /* DP83820 */
+
+       sc->sc_txcfg |= TXCFG_ATP |
            (sc->sc_tx_fill_thresh << TXCFG_FLTH_SHIFT) |
            sc->sc_tx_drain_thresh;
        bus_space_write_4(st, sh, SIP_TXCFG, sc->sc_txcfg);
@@ -2104,13 +2142,9 @@
        /*
         * Initialize the prototype RXCFG register.
         */
-       sc->sc_rxcfg = RXCFG_MXDMA_512 |
-           (sc->sc_rx_drain_thresh << RXCFG_DRTH_SHIFT);
+       sc->sc_rxcfg |= (sc->sc_rx_drain_thresh << RXCFG_DRTH_SHIFT);
        bus_space_write_4(st, sh, SIP_RXCFG, sc->sc_rxcfg);
 
-       /* Set up the receive filter. */
-       (*sc->sc_model->sip_variant->sipv_set_filter)(sc);
-
 #ifdef DP83820
        /*
         * Initialize the VLAN/IP receive control register.
@@ -2160,6 +2194,9 @@
            ISR_TXURN|ISR_TXDESC|ISR_RXORN|ISR_RXIDLE|ISR_RXDESC;
        bus_space_write_4(st, sh, SIP_IMR, sc->sc_imr);
 
+       /* Set up the receive filter. */
+       (*sc->sc_model->sip_variant->sipv_set_filter)(sc);
+
        /*
         * Set the current media.  Do this after initializing the prototype
         * IMR, since sip_mii_statchg() modifies the IMR for 802.3x flow
@@ -2418,7 +2455,7 @@
        struct ether_multi *enm;
        u_int8_t *cp;
        struct ether_multistep step;
-       u_int32_t crc, mchash[8];
+       u_int32_t crc, mchash[16];
 
        /*
         * Initialize the prototype RFCR.
@@ -2456,10 +2493,16 @@
                        goto allmulti;
                }
 
-               crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
-
-               /* Just want the 7 most significant bits. */
-               crc >>= 25;
+               crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
+
+               if (SIP_SIS900_REV(sc, SIS_REV_635) ||
+                   SIP_SIS900_REV(sc, SIS_REV_900B)) {
+                       /* Just want the 8 most significant bits. */
+                       crc >>= 24;
+               } else {
+                       /* Just want the 7 most significant bits. */
+                       crc >>= 25;
+               }
 
                /* Set the corresponding bit in the hash table. */
                mchash[crc >> 4] |= 1 << (crc & 0xf);
@@ -2501,6 +2544,17 @@
                FILTER_EMIT(RFCR_RFADDR_MC5, mchash[5]);
                FILTER_EMIT(RFCR_RFADDR_MC6, mchash[6]);
                FILTER_EMIT(RFCR_RFADDR_MC7, mchash[7]);
+               if (SIP_SIS900_REV(sc, SIS_REV_635) ||
+                   SIP_SIS900_REV(sc, SIS_REV_900B)) {
+                       FILTER_EMIT(RFCR_RFADDR_MC8, mchash[8]);
+                       FILTER_EMIT(RFCR_RFADDR_MC9, mchash[9]);
+                       FILTER_EMIT(RFCR_RFADDR_MC10, mchash[10]);
+                       FILTER_EMIT(RFCR_RFADDR_MC11, mchash[11]);
+                       FILTER_EMIT(RFCR_RFADDR_MC12, mchash[12]);
+                       FILTER_EMIT(RFCR_RFADDR_MC13, mchash[13]);
+                       FILTER_EMIT(RFCR_RFADDR_MC14, mchash[14]);
+                       FILTER_EMIT(RFCR_RFADDR_MC15, mchash[15]);
+               }
        }
 #undef FILTER_EMIT
 
@@ -2762,7 +2816,8 @@
         * The SiS 900 has only an internal PHY on the MII.  Only allow
         * MII address 0.
         */
-       if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 && phy != 0)
+       if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 &&
+           sc->sc_rev < SIS_REV_635 && phy != 0)
                return (0);
 
        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_ENPHY,
@@ -2789,7 +2844,8 @@
         * The SiS 900 has only an internal PHY on the MII.  Only allow
         * MII address 0.
         */
-       if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 && phy != 0)
+       if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 &&
+           sc->sc_rev < SIS_REV_635 && phy != 0)
                return;
 
        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_ENPHY,
@@ -2992,6 +3048,7 @@
        case SIS_REV_630S:
        case SIS_REV_630E:
        case SIS_REV_630EA1:
+       case SIS_REV_635:
                /*
                 * The MAC address for the on-board Ethernet of
                 * the SiS 630 chipset is in the NVRAM.  Kick
diff -r d3a4a4c6350a -r cf4f3e5956f9 sys/dev/pci/if_sipreg.h
--- a/sys/dev/pci/if_sipreg.h   Sat Feb 09 20:01:34 2002 +0000
+++ b/sys/dev/pci/if_sipreg.h   Sat Feb 09 21:04:02 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_sipreg.h,v 1.8 2001/12/20 03:32:31 thorpej Exp $    */
+/*     $NetBSD: if_sipreg.h,v 1.9 2002/02/09 21:04:02 thorpej Exp $    */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -249,6 +249,9 @@
 #else
 #define        CFG_EUPHCOMP    0x00000100      /* 83810 descriptor compat (83815) */
 #endif /* DP83820 */
+#define        CFG_EDBMASTEN   0x00002000      /* 635,900B ?? from linux driver */
+#define        CFG_RNDCNT      0x00000400      /* 635,900B ?? from linux driver */
+#define        CFG_FAIRBO      0x00000200      /* 635,900B ?? from linux driver */
 #define        CFG_REQALG      0x00000080      /* PCI bus request alg. */
 #define        CFG_SB          0x00000040      /* single backoff */
 #define        CFG_POW         0x00000020      /* program out of window timer */
@@ -519,6 +522,15 @@
 #define        RFCR_RFADDR_MC5   0x00090000    /* multicast hash word 5 */
 #define        RFCR_RFADDR_MC6   0x000a0000    /* multicast hash word 6 */
 #define        RFCR_RFADDR_MC7   0x000b0000    /* multicast hash word 7 */
+/* For SiS900B and 635/735 only */
+#define        RFCR_RFADDR_MC8   0x000c0000    /* multicast hash word 8 */
+#define        RFCR_RFADDR_MC9   0x000d0000    /* multicast hash word 9 */
+#define        RFCR_RFADDR_MC10  0x000e0000    /* multicast hash word 10 */
+#define        RFCR_RFADDR_MC11  0x000f0000    /* multicast hash word 11 */
+#define        RFCR_RFADDR_MC12  0x00100000    /* multicast hash word 12 */
+#define        RFCR_RFADDR_MC13  0x00110000    /* multicast hash word 13 */
+#define        RFCR_RFADDR_MC14  0x00120000    /* multicast hash word 14 */
+#define        RFCR_RFADDR_MC15  0x00130000    /* multicast hash word 15 */
 
 #define        RFCR_NS_RFADDR_PMATCH0  0x0000  /* perfect match octets 1-0 */
 #define        RFCR_NS_RFADDR_PMATCH2  0x0002  /* perfect match octets 3-2 */
@@ -691,9 +703,11 @@
 /*
  * Revision codes for the SiS 630 chipset built-in Ethernet.
  */
+#define        SIS_REV_900B    0x03
 #define        SIS_REV_630E    0x81
 #define        SIS_REV_630S    0x82
 #define        SIS_REV_630EA1  0x83
+#define        SIS_REV_635     0x90    /* same for 735 (745?) */
 
 /*
  * Serial EEPROM opcodes, including the start bit.



Home | Main Index | Thread Index | Old Index