Fix problems associated with the SiS 635/735 on-board Ethernet,
from Stephen Degler <sdegler@degler.net>, port-i386/15261.
This commit is contained in:
parent
63e29ad187
commit
8edba68a05
|
@ -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 @@ struct sip_softc {
|
|||
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 @@ do { \
|
|||
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 @@ SIP_DECL(attach)(struct device *parent, struct device *self, void *aux)
|
|||
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 @@ SIP_DECL(attach)(struct device *parent, struct device *self, void *aux)
|
|||
* 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 @@ SIP_DECL(reset)(struct sip_softc *sc)
|
|||
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(init)(struct ifnet *ifp)
|
|||
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 @@ SIP_DECL(init)(struct ifnet *ifp)
|
|||
*/
|
||||
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 @@ SIP_DECL(init)(struct ifnet *ifp)
|
|||
/*
|
||||
* 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 @@ SIP_DECL(init)(struct ifnet *ifp)
|
|||
/*
|
||||
* 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 @@ SIP_DECL(init)(struct ifnet *ifp)
|
|||
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 @@ SIP_DECL(sis900_set_filter)(struct sip_softc *sc)
|
|||
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 @@ SIP_DECL(sis900_set_filter)(struct sip_softc *sc)
|
|||
goto allmulti;
|
||||
}
|
||||
|
||||
crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
|
||||
crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
|
||||
|
||||
/* Just want the 7 most significant bits. */
|
||||
crc >>= 25;
|
||||
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 @@ SIP_DECL(sis900_set_filter)(struct sip_softc *sc)
|
|||
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 @@ SIP_DECL(sis900_mii_readreg)(struct device *self, int phy, int reg)
|
|||
* 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 @@ SIP_DECL(sis900_mii_writereg)(struct device *self, int phy, int reg, int val)
|
|||
* 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 @@ SIP_DECL(sis900_read_macaddr)(struct sip_softc *sc,
|
|||
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
|
||||
|
|
|
@ -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 @@ struct sip_desc {
|
|||
#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 @@ struct sip_desc {
|
|||
#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 @@ struct sip_desc {
|
|||
/*
|
||||
* 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.
|
||||
|
|
Loading…
Reference in New Issue