Subject: Re: ECS K7S5A motherboard with SiS 735 - ethernet
To: John Hayward <John.C.Hayward@wheaton.edu>
From: Stephen Degler <sdegler@degler.net>
List: port-i386
Date: 01/11/2002 23:28:03
Hi,
I've just completed hacking in 635/735 support to the sip driver. If
anyone is inclined to test it before I clean it up and submit a PR that
would be great. Patches to if_sip.c and if_sipreg.h are below. Note
that the tests for chip revisions are somewhat bogus and will need to be
replaced with a macro or an enum or something, but the driver is working
on a 735.
I'd also like to know that the patch doesn't break existing if_sip users.
skd
On Fri, Jan 11, 2002 at 09:55:55PM -0600, John Hayward wrote:
> Dear Cary and Matthias,
> I noted that you had sent messages about this chip set and motherboard.
> I note:
> > I'm also having trouble getting the built-in ethernet to work, but
> > so far I'm not convinced if this is a firmware or a driver problem.
>
> Do you have any more success/failures to report on the eithernet on
> this motherboard?
>
> Are you still of the opinion it is fairly solid and well performing?
>
> TIA for your info on this board.
> johnh...
Index: if_sip.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/if_sip.c,v
retrieving revision 1.44
diff -u -r1.44 if_sip.c
--- if_sip.c 2001/12/20 03:32:31 1.44
+++ if_sip.c 2002/01/12 04:04:33
@@ -210,6 +210,8 @@
*/
struct sip_softc {
struct device sc_dev; /* generic device information */
+ pci_chipset_tag_t pc;
+ pcitag_t pt;
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
bus_dma_tag_t sc_dmat; /* bus DMA tag */
@@ -217,6 +219,7 @@
void *sc_sdhook; /* shutdown hook */
const struct sip_product *sc_model; /* which model are we? */
+ pci_revision_t sc_sip_revision; /* and which rev? */
void *sc_ih; /* interrupt cookie */
@@ -571,7 +574,9 @@
printf(": %s\n", sip->sip_name);
sc->sc_model = sip;
-
+ sc->sc_sip_revision = PCI_REVISION(pa->pa_class);
+ sc->pc = pa->pa_pc;
+ sc->pt = pa->pa_tag;
/*
* Map the device.
*/
@@ -611,7 +616,7 @@
/* Enable bus mastering. */
pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
- pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
+ pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
PCI_COMMAND_MASTER_ENABLE);
/* Get it out of power save mode if needed. */
@@ -728,6 +733,18 @@
* in the softc.
*/
sc->sc_cfg = 0;
+ sc->sc_txcfg = 0;
+ sc->sc_rxcfg = 0;
+ sc->sc_tx_fill_thresh = 0;
+ sc->sc_tx_drain_thresh = 0;
+ sc->sc_rx_drain_thresh = 0;
+
+ /* TBD MACROIZE a better test ! */
+ if ( sc->sc_sip_revision == SIS_REV_635 ||
+ sc->sc_sip_revision == SIS_REV_900B ) {
+ sc->sc_cfg |=( CFG_PESEL | CFG_RNDCNT);
+ }
+
(*sip->sip_variant->sipv_read_macaddr)(sc, pa, enaddr);
printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
@@ -1406,6 +1423,9 @@
PRINTERR(ISR_RMABT, "master abort");
PRINTERR(ISR_RTABT, "target abort");
PRINTERR(ISR_RXSOVR, "receive status FIFO overrun");
+
+ pci_conf_write(sc->pc, sc->pt, PCI_COMMAND_STATUS_REG,
+ pci_conf_read(sc->pc, sc->pt, PCI_COMMAND_STATUS_REG) & ~0xf0000000);
(void) SIP_DECL(init)(ifp);
#undef PRINTERR
}
@@ -1913,18 +1933,21 @@
bus_space_handle_t sh = sc->sc_sh;
int i;
- bus_space_write_4(st, sh, SIP_CR, CR_RST);
+ 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|CR_RXR|CR_TXR));
for (i = 0; i < SIP_TIMEOUT; i++) {
if ((bus_space_read_4(st, sh, SIP_CR) & CR_RST) == 0)
break;
- delay(2);
+ delay(100);
}
if (i == SIP_TIMEOUT)
printf("%s: reset failed to complete\n", sc->sc_dev.dv_xname);
- delay(1000);
+ delay(10000);
#ifdef DP83820
/*
@@ -2051,7 +2074,7 @@
* in sip_attach().
*/
bus_space_write_4(st, sh, SIP_CFG, sc->sc_cfg);
-
+
/*
* Initialize the transmit fill and drain thresholds if
* we have never done so.
@@ -2062,7 +2085,7 @@
* minimum (32 bytes), and 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) {
/*
@@ -2075,15 +2098,26 @@
* may trash the first few outgoing packets if the
* PCI bus is saturated.
*/
- sc->sc_tx_drain_thresh = 512 / 32;
+ sc->sc_tx_drain_thresh = 512 / 32;
}
/*
* Initialize the prototype TXCFG register.
*/
- sc->sc_txcfg = TXCFG_ATP | TXCFG_MXDMA_512 |
+ if (sc->sc_model->sip_vendor == PCI_VENDOR_SIS &&
+ sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 &&
+ (sc->sc_sip_revision == SIS_REV_635 || sc->sc_sip_revision == 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;
+ }
+ 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);
/*
@@ -2098,18 +2132,18 @@
* set this value lower than 2; 14 bytes are required to
* filter the packet).
*/
- sc->sc_rx_drain_thresh = RXCFG_DRTH >> RXCFG_DRTH_SHIFT;
+ sc->sc_rx_drain_thresh = RXCFG_DRTH >> RXCFG_DRTH_SHIFT ;
+ /* sc->sc_rx_drain_thresh = 32/8 ; */
}
/*
* 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);
+ /* (*sc->sc_model->sip_variant->sipv_set_filter)(sc); */
#ifdef DP83820
/*
@@ -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,15 @@
goto allmulti;
}
- crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
+ /* Huh? Hash table must be backwards !! */
+ crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
- /* Just want the 7 most significant bits. */
- crc >>= 25;
+ /* Just want the 7 or 8 most significant bits. */
+ if ( sc->sc_sip_revision == SIS_REV_635 ||
+ sc->sc_sip_revision == SIS_REV_900B )
+ crc >>= 24;
+ else
+ crc >>= 25;
/* Set the corresponding bit in the hash table. */
mchash[crc >> 4] |= 1 << (crc & 0xf);
@@ -2501,6 +2543,17 @@
FILTER_EMIT(RFCR_RFADDR_MC5, mchash[5]);
FILTER_EMIT(RFCR_RFADDR_MC6, mchash[6]);
FILTER_EMIT(RFCR_RFADDR_MC7, mchash[7]);
+ if ( sc->sc_sip_revision == SIS_REV_635 ||
+ sc->sc_sip_revision == 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
@@ -2760,9 +2813,11 @@
/*
* The SiS 900 has only an internal PHY on the MII. Only allow
- * MII address 0.
+ * MII address 0. However, the revisions integrated into SiS
+ * 635/735 do.
*/
- if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 && phy != 0)
+ if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 &&
+ sc->sc_sip_revision < SIS_REV_635 && phy != 0)
return (0);
bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_ENPHY,
@@ -2787,9 +2842,11 @@
/*
* The SiS 900 has only an internal PHY on the MII. Only allow
- * MII address 0.
+ * MII address 0. However, the revisions integrated into SiS
+ * 635/735 do.
*/
- if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 && phy != 0)
+ if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 &&
+ sc->sc_sip_revision < SIS_REV_635 && phy != 0)
return;
bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_ENPHY,
@@ -2839,8 +2896,11 @@
flowctl = 0;
}
+ /* If we have not properly set these values, don't emit them */
+ if ( sc->sc_txcfg & TXCFG_ATP ) {
bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXCFG, sc->sc_txcfg);
bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RXCFG, sc->sc_rxcfg);
+ }
bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_IMR, sc->sc_imr);
bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_FLOWCTL, flowctl);
}
@@ -2992,6 +3052,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
Index: if_sipreg.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/if_sipreg.h,v
retrieving revision 1.8
diff -u -r1.8 if_sipreg.h
--- if_sipreg.h 2001/12/20 03:32:31 1.8
+++ if_sipreg.h 2002/01/12 04:04:54
@@ -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 */
@@ -471,6 +474,7 @@
#define RXCFG_MXDMA_256 0x00700000 /* 256 bytes */
#endif /* DP83820 */
#define RXCFG_DRTH 0x0000003e
+/* #define RXCFG_DRTH 14 */
#define RXCFG_DRTH_SHIFT 1
#ifdef DP83820
@@ -519,6 +523,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 */
+/* sis900 B 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 */
@@ -694,6 +707,8 @@
#define SIS_REV_630E 0x81
#define SIS_REV_630S 0x82
#define SIS_REV_630EA1 0x83
+#define SIS_REV_635 0x90 /* same for 735 (745?) */
+#define SIS_REV_900B 0x03
/*
* Serial EEPROM opcodes, including the start bit.