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.