if_sis.c revision 109976
11573Srgrimes/*
21573Srgrimes * Copyright (c) 1997, 1998, 1999
31573Srgrimes *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 3. All advertising materials mentioning features or use of this software
141573Srgrimes *    must display the following acknowledgement:
151573Srgrimes *	This product includes software developed by Bill Paul.
161573Srgrimes * 4. Neither the name of the author nor the names of any co-contributors
171573Srgrimes *    may be used to endorse or promote products derived from this software
181573Srgrimes *    without specific prior written permission.
191573Srgrimes *
201573Srgrimes * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
231573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
241573Srgrimes * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
251573Srgrimes * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
261573Srgrimes * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
271573Srgrimes * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2854770Sgreen * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2954770Sgreen * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
301573Srgrimes * THE POSSIBILITY OF SUCH DAMAGE.
311573Srgrimes *
32129184Sbde * $FreeBSD: head/sys/pci/if_sis.c 109976 2003-01-28 10:55:38Z mbr $
331573Srgrimes */
3423668Speter
351573Srgrimes/*
36129184Sbde * SiS 900/SiS 7016 fast ethernet PCI NIC driver. Datasheets are
37129184Sbde * available from http://www.sis.com.tw.
3890045Sobrien *
3990045Sobrien * This driver also supports the NatSemi DP83815. Datasheets are
401573Srgrimes * available from http://www.national.com.
4171579Sdeischen *
421573Srgrimes * Written by Bill Paul <wpaul@ee.columbia.edu>
43129161Speadar * Electrical Engineering Department
441573Srgrimes * Columbia University, New York City
451573Srgrimes */
461573Srgrimes
471573Srgrimes/*
481573Srgrimes * The SiS 900 is a fairly simple chip. It uses bus master DMA with
491573Srgrimes * simple TX and RX descriptors of 3 longwords in size. The receiver
501573Srgrimes * has a single perfect filter entry for the station address and a
511573Srgrimes * 128-bit multicast hash table. The SiS 900 has a built-in MII-based
521573Srgrimes * transceiver while the 7016 requires an external transceiver chip.
5371579Sdeischen * Both chips offer the standard bit-bang MII interface as well as
541573Srgrimes * an enchanced PHY interface which simplifies accessing MII registers.
55235647Sgleb *
56235647Sgleb * The only downside to this chipset is that RX descriptors must be
57175688Syar * longword aligned.
5890045Sobrien */
5990045Sobrien
6090045Sobrien#include <sys/param.h>
6190045Sobrien#include <sys/systm.h>
6290045Sobrien#include <sys/sockio.h>
6390045Sobrien#include <sys/mbuf.h>
64175688Syar#include <sys/malloc.h>
65260571Sjilles#include <sys/kernel.h>
6690045Sobrien#include <sys/socket.h>
67129161Speadar#include <sys/sysctl.h>
681573Srgrimes
6928913Simp#include <net/if.h>
701573Srgrimes#include <net/if_arp.h>
7128913Simp#include <net/ethernet.h>
7228913Simp#include <net/if_dl.h>
7328913Simp#include <net/if_media.h>
741573Srgrimes#include <net/if_types.h>
751573Srgrimes#include <net/if_vlan_var.h>
761573Srgrimes
771573Srgrimes#include <net/bpf.h>
781573Srgrimes
791573Srgrimes#include <machine/bus_pio.h>
801573Srgrimes#include <machine/bus_memio.h>
811573Srgrimes#include <machine/bus.h>
82129052Speadar#include <machine/resource.h>
83129161Speadar#include <sys/bus.h>
84129161Speadar#include <sys/rman.h>
85129161Speadar
86129052Speadar#include <dev/mii/mii.h>
87129052Speadar#include <dev/mii/miivar.h>
88129161Speadar
89129161Speadar#include <pci/pcireg.h>
90129161Speadar#include <pci/pcivar.h>
91129161Speadar
92129052Speadar#define SIS_USEIOSPACE
93129052Speadar
94129052Speadar#include <pci/if_sisreg.h>
95129161Speadar
96129161SpeadarMODULE_DEPEND(sis, miibus, 1, 1, 1);
97129161Speadar
98129161Speadar/* "controller miibus0" required.  See GENERIC if you get errors here. */
99129161Speadar#include "miibus_if.h"
100129161Speadar
101129052Speadar#ifndef lint
102129052Speadarstatic const char rcsid[] =
103129052Speadar  "$FreeBSD: head/sys/pci/if_sis.c 109976 2003-01-28 10:55:38Z mbr $";
104129052Speadar#endif
105219696Spjd
106129052Speadar/*
107129052Speadar * Various supported device vendors/types and their names.
108129052Speadar */
109129052Speadarstatic struct sis_type sis_devs[] = {
110129052Speadar	{ SIS_VENDORID, SIS_DEVICEID_900, "SiS 900 10/100BaseTX" },
1111573Srgrimes	{ SIS_VENDORID, SIS_DEVICEID_7016, "SiS 7016 10/100BaseTX" },
112288029Srodrigc	{ NS_VENDORID, NS_DEVICEID_DP83815, "NatSemi DP83815 10/100BaseTX" },
113288029Srodrigc	{ 0, 0, NULL }
1141573Srgrimes};
115129052Speadar
11690045Sobrienstatic int sis_probe		(device_t);
11790045Sobrienstatic int sis_attach		(device_t);
1181573Srgrimesstatic int sis_detach		(device_t);
119175688Syar
1201573Srgrimesstatic int sis_newbuf		(struct sis_softc *,
1211573Srgrimes					struct sis_desc *, struct mbuf *);
1221573Srgrimesstatic int sis_encap		(struct sis_softc *,
1231573Srgrimes					struct mbuf *, u_int32_t *);
1241573Srgrimesstatic void sis_rxeof		(struct sis_softc *);
1251573Srgrimesstatic void sis_rxeoc		(struct sis_softc *);
1261573Srgrimesstatic void sis_txeof		(struct sis_softc *);
127197793Sdelphijstatic void sis_intr		(void *);
128197793Sdelphijstatic void sis_tick		(void *);
129197793Sdelphijstatic void sis_start		(struct ifnet *);
130197793Sdelphijstatic int sis_ioctl		(struct ifnet *, u_long, caddr_t);
131197793Sdelphijstatic void sis_init		(void *);
132197793Sdelphijstatic void sis_stop		(struct sis_softc *);
133129184Sbdestatic void sis_watchdog		(struct ifnet *);
134238963Sdelphijstatic void sis_shutdown		(device_t);
1351573Srgrimesstatic int sis_ifmedia_upd	(struct ifnet *);
136129052Speadarstatic void sis_ifmedia_sts	(struct ifnet *, struct ifmediareq *);
1371573Srgrimes
1381573Srgrimesstatic u_int16_t sis_reverse	(u_int16_t);
1391573Srgrimesstatic void sis_delay		(struct sis_softc *);
14054770Sgreenstatic void sis_eeprom_idle	(struct sis_softc *);
14154770Sgreenstatic void sis_eeprom_putbyte	(struct sis_softc *, int);
14254770Sgreenstatic void sis_eeprom_getword	(struct sis_softc *, int, u_int16_t *);
1431573Srgrimesstatic void sis_read_eeprom	(struct sis_softc *, caddr_t, int, int, int);
1441573Srgrimes#ifdef __i386__
1451573Srgrimesstatic void sis_read_cmos	(struct sis_softc *, device_t, caddr_t,
1461573Srgrimes							int, int);
1471573Srgrimesstatic void sis_read_mac	(struct sis_softc *, device_t, caddr_t);
1481573Srgrimesstatic device_t sis_find_bridge	(device_t);
1491573Srgrimes#endif
1501573Srgrimes
1511573Srgrimesstatic void sis_mii_sync	(struct sis_softc *);
1521573Srgrimesstatic void sis_mii_send	(struct sis_softc *, u_int32_t, int);
1531573Srgrimesstatic int sis_mii_readreg	(struct sis_softc *, struct sis_mii_frame *);
1541573Srgrimesstatic int sis_mii_writereg	(struct sis_softc *, struct sis_mii_frame *);
1551573Srgrimesstatic int sis_miibus_readreg	(device_t, int, int);
1561573Srgrimesstatic int sis_miibus_writereg	(device_t, int, int, int);
1571573Srgrimesstatic void sis_miibus_statchg	(device_t);
1581573Srgrimes
1591573Srgrimesstatic void sis_setmulti_sis	(struct sis_softc *);
16064740Sgreenstatic void sis_setmulti_ns	(struct sis_softc *);
161262872Sjillesstatic u_int32_t sis_crc	(struct sis_softc *, caddr_t);
1621573Srgrimesstatic void sis_reset		(struct sis_softc *);
1631573Srgrimesstatic int sis_list_rx_init	(struct sis_softc *);
1641573Srgrimesstatic int sis_list_tx_init	(struct sis_softc *);
1651573Srgrimes
1661573Srgrimesstatic void sis_dma_map_desc_ptr	(void *, bus_dma_segment_t *, int, int);
167260571Sjillesstatic void sis_dma_map_desc_next	(void *, bus_dma_segment_t *, int, int);
1681573Srgrimesstatic void sis_dma_map_ring		(void *, bus_dma_segment_t *, int, int);
1691573Srgrimes#ifdef SIS_USEIOSPACE
1701573Srgrimes#define SIS_RES			SYS_RES_IOPORT
1711573Srgrimes#define SIS_RID			SIS_PCI_LOIO
1721573Srgrimes#else
1731573Srgrimes#define SIS_RES			SYS_RES_MEMORY
1741573Srgrimes#define SIS_RID			SIS_PCI_LOMEM
1751573Srgrimes#endif
1761573Srgrimes
1771573Srgrimesstatic device_method_t sis_methods[] = {
1781573Srgrimes	/* Device interface */
1791573Srgrimes	DEVMETHOD(device_probe,		sis_probe),
1801573Srgrimes	DEVMETHOD(device_attach,	sis_attach),
1811573Srgrimes	DEVMETHOD(device_detach,	sis_detach),
1821573Srgrimes	DEVMETHOD(device_shutdown,	sis_shutdown),
1831573Srgrimes
1841573Srgrimes	/* bus interface */
1851573Srgrimes	DEVMETHOD(bus_print_child,	bus_generic_print_child),
1861573Srgrimes	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
1871573Srgrimes
1881573Srgrimes	/* MII interface */
1891573Srgrimes	DEVMETHOD(miibus_readreg,	sis_miibus_readreg),
1901573Srgrimes	DEVMETHOD(miibus_writereg,	sis_miibus_writereg),
1911573Srgrimes	DEVMETHOD(miibus_statchg,	sis_miibus_statchg),
1921573Srgrimes
1931573Srgrimes	{ 0, 0 }
1941573Srgrimes};
1951573Srgrimes
1961573Srgrimesstatic driver_t sis_driver = {
1971573Srgrimes	"sis",
1981573Srgrimes	sis_methods,
1991573Srgrimes	sizeof(struct sis_softc)
2001573Srgrimes};
2011573Srgrimes
2021573Srgrimesstatic devclass_t sis_devclass;
2031573Srgrimes
20454770SgreenDRIVER_MODULE(if_sis, pci, sis_driver, sis_devclass, 0, 0);
2051573SrgrimesDRIVER_MODULE(miibus, sis, miibus_driver, miibus_devclass, 0, 0);
2061573Srgrimes
2071573Srgrimes#define SIS_SETBIT(sc, reg, x)				\
2081573Srgrimes	CSR_WRITE_4(sc, reg,				\
2091573Srgrimes		CSR_READ_4(sc, reg) | (x))
210241010Sjilles
211241010Sjilles#define SIS_CLRBIT(sc, reg, x)				\
2121573Srgrimes	CSR_WRITE_4(sc, reg,				\
2131573Srgrimes		CSR_READ_4(sc, reg) & ~(x))
2141573Srgrimes
2151573Srgrimes#define SIO_SET(x)					\
2161573Srgrimes	CSR_WRITE_4(sc, SIS_EECTL, CSR_READ_4(sc, SIS_EECTL) | x)
2171573Srgrimes
2181573Srgrimes#define SIO_CLR(x)					\
2191573Srgrimes	CSR_WRITE_4(sc, SIS_EECTL, CSR_READ_4(sc, SIS_EECTL) & ~x)
2201573Srgrimes
2211573Srgrimesstatic void
2221573Srgrimessis_dma_map_desc_next(arg, segs, nseg, error)
2231573Srgrimes	void *arg;
224231891Sdelphij	bus_dma_segment_t *segs;
2251573Srgrimes	int nseg, error;
226175688Syar{
22790045Sobrien	struct sis_desc	*r;
2281573Srgrimes
2291573Srgrimes	r = arg;
2301573Srgrimes	r->sis_next = segs->ds_addr;
2311573Srgrimes
2321573Srgrimes	return;
2331573Srgrimes}
2341573Srgrimes
2351573Srgrimesstatic void
2361573Srgrimessis_dma_map_desc_ptr(arg, segs, nseg, error)
2371573Srgrimes	void *arg;
2381573Srgrimes	bus_dma_segment_t *segs;
2391573Srgrimes	int nseg, error;
2401573Srgrimes{
2411573Srgrimes	struct sis_desc	*r;
2421573Srgrimes
2431573Srgrimes	r = arg;
2441573Srgrimes	r->sis_ptr = segs->ds_addr;
2451573Srgrimes
2461573Srgrimes	return;
2471573Srgrimes}
248231891Sdelphij
2491573Srgrimesstatic void
25090045Sobriensis_dma_map_ring(arg, segs, nseg, error)
2511573Srgrimes	void *arg;
2521573Srgrimes	bus_dma_segment_t *segs;
2531573Srgrimes	int nseg, error;
2541573Srgrimes{
2551573Srgrimes	u_int32_t *p;
2561573Srgrimes
2571573Srgrimes	p = arg;
2581573Srgrimes	*p = segs->ds_addr;
2591573Srgrimes
2601573Srgrimes	return;
26164740Sgreen}
2621573Srgrimes
2631573Srgrimes/*
2641573Srgrimes * Routine to reverse the bits in a word. Stolen almost
2651573Srgrimes * verbatim from /usr/games/fortune.
2661573Srgrimes */
2671573Srgrimesstatic u_int16_t
2681573Srgrimessis_reverse(n)
2691573Srgrimes	u_int16_t		n;
2701573Srgrimes{
2711573Srgrimes	n = ((n >>  1) & 0x5555) | ((n <<  1) & 0xaaaa);
2721573Srgrimes	n = ((n >>  2) & 0x3333) | ((n <<  2) & 0xcccc);
2731573Srgrimes	n = ((n >>  4) & 0x0f0f) | ((n <<  4) & 0xf0f0);
2741573Srgrimes	n = ((n >>  8) & 0x00ff) | ((n <<  8) & 0xff00);
2751573Srgrimes
2761573Srgrimes	return(n);
27756698Sjasone}
27854770Sgreen
27954770Sgreenstatic void
28054770Sgreensis_delay(sc)
28154770Sgreen	struct sis_softc	*sc;
28254770Sgreen{
28354770Sgreen	int			idx;
28454770Sgreen
28554770Sgreen	for (idx = (300 / 33) + 1; idx > 0; idx--)
2861573Srgrimes		CSR_READ_4(sc, SIS_CSR);
2871573Srgrimes
28837349Sphk	return;
28937349Sphk}
2901573Srgrimes
2911573Srgrimesstatic void
2921573Srgrimessis_eeprom_idle(sc)
2931573Srgrimes	struct sis_softc	*sc;
29428913Simp{
29528913Simp	register int		i;
2961573Srgrimes
2971573Srgrimes	SIO_SET(SIS_EECTL_CSEL);
29828913Simp	sis_delay(sc);
29928913Simp	SIO_SET(SIS_EECTL_CLK);
3001573Srgrimes	sis_delay(sc);
3011573Srgrimes
302231891Sdelphij	for (i = 0; i < 25; i++) {
3031573Srgrimes		SIO_CLR(SIS_EECTL_CLK);
30490045Sobrien		sis_delay(sc);
30590045Sobrien		SIO_SET(SIS_EECTL_CLK);
30690045Sobrien		sis_delay(sc);
3071573Srgrimes	}
3081573Srgrimes
3091573Srgrimes	SIO_CLR(SIS_EECTL_CLK);
3101573Srgrimes	sis_delay(sc);
3111573Srgrimes	SIO_CLR(SIS_EECTL_CSEL);
3121573Srgrimes	sis_delay(sc);
3131573Srgrimes	CSR_WRITE_4(sc, SIS_EECTL, 0x00000000);
3141573Srgrimes
3151573Srgrimes	return;
3161573Srgrimes}
3171573Srgrimes
3181573Srgrimes/*
3191573Srgrimes * Send a read command and address to the EEPROM, check for ACK.
3201573Srgrimes */
3211573Srgrimesstatic void
322260571Sjillessis_eeprom_putbyte(sc, addr)
3231573Srgrimes	struct sis_softc	*sc;
3241573Srgrimes	int			addr;
3251573Srgrimes{
3261573Srgrimes	register int		d, i;
3271573Srgrimes
3281573Srgrimes	d = addr | SIS_EECMD_READ;
3291573Srgrimes
3301573Srgrimes	/*
3311573Srgrimes	 * Feed in each bit and stobe the clock.
3321573Srgrimes	 */
3331573Srgrimes	for (i = 0x400; i; i >>= 1) {
334260571Sjilles		if (d & i) {
33554770Sgreen			SIO_SET(SIS_EECTL_DIN);
336241010Sjilles		} else {
337241010Sjilles			SIO_CLR(SIS_EECTL_DIN);
3381573Srgrimes		}
3391573Srgrimes		sis_delay(sc);
3401573Srgrimes		SIO_SET(SIS_EECTL_CLK);
3411573Srgrimes		sis_delay(sc);
34254770Sgreen		SIO_CLR(SIS_EECTL_CLK);
3431573Srgrimes		sis_delay(sc);
3441573Srgrimes	}
3451573Srgrimes
3461573Srgrimes	return;
3471573Srgrimes}
3481573Srgrimes
3491573Srgrimes/*
35028913Simp * Read a word of data stored in the EEPROM at address 'addr.'
3511573Srgrimes */
35256698Sjasonestatic void
3531573Srgrimessis_eeprom_getword(sc, addr, dest)
3541573Srgrimes	struct sis_softc	*sc;
3551573Srgrimes	int			addr;
3561573Srgrimes	u_int16_t		*dest;
3571573Srgrimes{
3581573Srgrimes	register int		i;
3598870Srgrimes	u_int16_t		word = 0;
3601573Srgrimes
3611573Srgrimes	/* Force EEPROM to idle state. */
36264740Sgreen	sis_eeprom_idle(sc);
36328913Simp
3641573Srgrimes	/* Enter EEPROM access mode. */
3651573Srgrimes	sis_delay(sc);
3661573Srgrimes	SIO_CLR(SIS_EECTL_CLK);
3671573Srgrimes	sis_delay(sc);
3681573Srgrimes	SIO_SET(SIS_EECTL_CSEL);
3691573Srgrimes	sis_delay(sc);
3701573Srgrimes
3711573Srgrimes	/*
3721573Srgrimes	 * Send address of word we want to read.
3731573Srgrimes	 */
3741573Srgrimes	sis_eeprom_putbyte(sc, addr);
3751573Srgrimes
3761573Srgrimes	/*
3771573Srgrimes	 * Start reading bits from EEPROM.
3781573Srgrimes	 */
3791573Srgrimes	for (i = 0x8000; i; i >>= 1) {
38064740Sgreen		SIO_SET(SIS_EECTL_CLK);
38177599Skris		sis_delay(sc);
3821573Srgrimes		if (CSR_READ_4(sc, SIS_EECTL) & SIS_EECTL_DOUT)
3831573Srgrimes			word |= i;
384129184Sbde		sis_delay(sc);
38564740Sgreen		SIO_CLR(SIS_EECTL_CLK);
3861573Srgrimes		sis_delay(sc);
3871573Srgrimes	}
3881573Srgrimes
3891573Srgrimes	/* Turn off EEPROM access mode. */
3901573Srgrimes	sis_eeprom_idle(sc);
3911573Srgrimes
3921573Srgrimes	*dest = word;
3931573Srgrimes
3941573Srgrimes	return;
3951573Srgrimes}
3961573Srgrimes
3971573Srgrimes/*
3981573Srgrimes * Read a sequence of words from the EEPROM.
3991573Srgrimes */
4001573Srgrimesstatic void
40164740Sgreensis_read_eeprom(sc, dest, off, cnt, swap)
4021573Srgrimes	struct sis_softc	*sc;
40354770Sgreen	caddr_t			dest;
40454770Sgreen	int			off;
4051573Srgrimes	int			cnt;
4061573Srgrimes	int			swap;
40728913Simp{
4081573Srgrimes	int			i;
4091573Srgrimes	u_int16_t		word = 0, *ptr;
4101573Srgrimes
411261589Sjilles	for (i = 0; i < cnt; i++) {
4121573Srgrimes		sis_eeprom_getword(sc, off + i, &word);
4131573Srgrimes		ptr = (u_int16_t *)(dest + (i * 2));
4141573Srgrimes		if (swap)
4151573Srgrimes			*ptr = ntohs(word);
4161573Srgrimes		else
4171573Srgrimes			*ptr = word;
4181573Srgrimes	}
4191573Srgrimes
4201573Srgrimes	return;
421261589Sjilles}
422261589Sjilles
4231573Srgrimes#ifdef __i386__
424261589Sjillesstatic device_t
4251573Srgrimessis_find_bridge(dev)
426260571Sjilles	device_t		dev;
42754770Sgreen{
4281573Srgrimes	devclass_t		pci_devclass;
429241010Sjilles	device_t		*pci_devices;
4301573Srgrimes	int			pci_count = 0;
4311573Srgrimes	device_t		*pci_children;
4321573Srgrimes	int			pci_childcount = 0;
4331573Srgrimes	device_t		*busp, *childp;
43454770Sgreen	device_t		child = NULL;
4351573Srgrimes	int			i, j;
4361573Srgrimes
4371573Srgrimes	if ((pci_devclass = devclass_find("pci")) == NULL)
438261589Sjilles		return(NULL);
439261589Sjilles
4401573Srgrimes	devclass_get_devices(pci_devclass, &pci_devices, &pci_count);
4411573Srgrimes
4421573Srgrimes	for (i = 0, busp = pci_devices; i < pci_count; i++, busp++) {
4431573Srgrimes		pci_childcount = 0;
4441573Srgrimes		device_get_children(*busp, &pci_children, &pci_childcount);
4451573Srgrimes		for (j = 0, childp = pci_children;
4461573Srgrimes		    j < pci_childcount; j++, childp++) {
4471573Srgrimes			if (pci_get_vendor(*childp) == SIS_VENDORID &&
4481573Srgrimes			    pci_get_device(*childp) == 0x0008) {
4491573Srgrimes				child = *childp;
4501573Srgrimes				goto done;
4511573Srgrimes			}
4521573Srgrimes		}
4531573Srgrimes	}
454261589Sjilles
4551573Srgrimesdone:
4561573Srgrimes	free(pci_devices, M_TEMP);
4571573Srgrimes	free(pci_children, M_TEMP);
4581573Srgrimes	return(child);
4591573Srgrimes}
46054770Sgreen
4611573Srgrimesstatic void
4621573Srgrimessis_read_cmos(sc, dev, dest, off, cnt)
4631573Srgrimes	struct sis_softc	*sc;
4641573Srgrimes	device_t		dev;
4651573Srgrimes	caddr_t			dest;
4661573Srgrimes	int			off;
4671573Srgrimes	int			cnt;
4681573Srgrimes{
46928913Simp	device_t		bridge;
4701573Srgrimes	u_int8_t		reg;
4711573Srgrimes	int			i;
4721573Srgrimes	bus_space_tag_t		btag;
4731573Srgrimes
4741573Srgrimes	bridge = sis_find_bridge(dev);
4751573Srgrimes	if (bridge == NULL)
47656698Sjasone		return;
4771573Srgrimes	reg = pci_read_config(bridge, 0x48, 1);
4781573Srgrimes	pci_write_config(bridge, 0x48, reg|0x40, 1);
4791573Srgrimes
4801573Srgrimes	/* XXX */
48156698Sjasone	btag = I386_BUS_SPACE_IO;
48277497Skris
483129184Sbde	for (i = 0; i < cnt; i++) {
48477599Skris		bus_space_write_1(btag, 0x0, 0x70, i + off);
48577599Skris		*(dest + i) = bus_space_read_1(btag, 0x0, 0x71);
4861573Srgrimes	}
487261589Sjilles
4881573Srgrimes	pci_write_config(bridge, 0x48, reg & ~0x40, 1);
4891573Srgrimes	return;
4901573Srgrimes}
4911573Srgrimes
4921573Srgrimesstatic void
4931573Srgrimessis_read_mac(sc, dev, dest)
4941573Srgrimes	struct sis_softc	*sc;
4951573Srgrimes	device_t		dev;
4961573Srgrimes	caddr_t			dest;
4971573Srgrimes{
4981573Srgrimes	u_int32_t		filtsave, csrsave;
4991573Srgrimes
500231891Sdelphij	filtsave = CSR_READ_4(sc, SIS_RXFILT_CTL);
5011573Srgrimes	csrsave = CSR_READ_4(sc, SIS_CSR);
50264740Sgreen
5031573Srgrimes	CSR_WRITE_4(sc, SIS_CSR, SIS_CSR_RELOAD | filtsave);
5041573Srgrimes	CSR_WRITE_4(sc, SIS_CSR, 0);
5051573Srgrimes
5061573Srgrimes	CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave & ~SIS_RXFILTCTL_ENABLE);
5071573Srgrimes
5081573Srgrimes	CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR0);
5091573Srgrimes	((u_int16_t *)dest)[0] = CSR_READ_2(sc, SIS_RXFILT_DATA);
5101573Srgrimes	CSR_WRITE_4(sc, SIS_RXFILT_CTL,SIS_FILTADDR_PAR1);
5111573Srgrimes	((u_int16_t *)dest)[1] = CSR_READ_2(sc, SIS_RXFILT_DATA);
512231891Sdelphij	CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR2);
5131573Srgrimes	((u_int16_t *)dest)[2] = CSR_READ_2(sc, SIS_RXFILT_DATA);
51490045Sobrien
515284649Sjilles	CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave);
5161573Srgrimes	CSR_WRITE_4(sc, SIS_CSR, csrsave);
51764740Sgreen	return;
5181573Srgrimes}
5191573Srgrimes#endif
5201573Srgrimes
5211573Srgrimes/*
5221573Srgrimes * Sync the PHYs by setting data bit and strobing the clock 32 times.
5231573Srgrimes */
5241573Srgrimesstatic void sis_mii_sync(sc)
5251573Srgrimes	struct sis_softc	*sc;
5261573Srgrimes{
5271573Srgrimes	register int		i;
5281573Srgrimes
5291573Srgrimes 	SIO_SET(SIS_MII_DIR|SIS_MII_DATA);
5301573Srgrimes
5311573Srgrimes 	for (i = 0; i < 32; i++) {
5321573Srgrimes 		SIO_SET(SIS_MII_CLK);
5331573Srgrimes 		DELAY(1);
5341573Srgrimes 		SIO_CLR(SIS_MII_CLK);
5351573Srgrimes 		DELAY(1);
5361573Srgrimes 	}
5371573Srgrimes
5381573Srgrimes 	return;
5391573Srgrimes}
5401573Srgrimes
5411573Srgrimes/*
5421573Srgrimes * Clock a series of bits through the MII.
5431573Srgrimes */
5441573Srgrimesstatic void sis_mii_send(sc, bits, cnt)
5451573Srgrimes	struct sis_softc	*sc;
5461573Srgrimes	u_int32_t		bits;
5471573Srgrimes	int			cnt;
54864740Sgreen{
5491573Srgrimes	int			i;
5501573Srgrimes
5511573Srgrimes	SIO_CLR(SIS_MII_CLK);
55228913Simp
5531573Srgrimes	for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
5548870Srgrimes		if (bits & i) {
5551573Srgrimes			SIO_SET(SIS_MII_DATA);
5561573Srgrimes		} else {
5571573Srgrimes			SIO_CLR(SIS_MII_DATA);
5581573Srgrimes		}
5591573Srgrimes		DELAY(1);
5601573Srgrimes		SIO_CLR(SIS_MII_CLK);
5611573Srgrimes		DELAY(1);
5621573Srgrimes		SIO_SET(SIS_MII_CLK);
5631573Srgrimes	}
5641573Srgrimes}
5651573Srgrimes
5661573Srgrimes/*
5671573Srgrimes * Read an PHY register through the MII.
568241010Sjilles */
5691573Srgrimesstatic int sis_mii_readreg(sc, frame)
5701573Srgrimes	struct sis_softc	*sc;
571284649Sjilles	struct sis_mii_frame	*frame;
572284649Sjilles
573284649Sjilles{
574284649Sjilles	int			i, ack, s;
575284649Sjilles
576284649Sjilles	s = splimp();
577284649Sjilles
5781573Srgrimes	/*
5791573Srgrimes	 * Set up frame for RX.
5801573Srgrimes	 */
5811573Srgrimes	frame->mii_stdelim = SIS_MII_STARTDELIM;
582103726Swollman	frame->mii_opcode = SIS_MII_READOP;
583103726Swollman	frame->mii_turnaround = 0;
584103726Swollman	frame->mii_data = 0;
585103726Swollman
586103726Swollman	/*
587103726Swollman 	 * Turn on data xmit.
588103726Swollman	 */
589103726Swollman	SIO_SET(SIS_MII_DIR);
590103726Swollman
591103726Swollman	sis_mii_sync(sc);
592103726Swollman
593103726Swollman	/*
594103726Swollman	 * Send command/address info.
595103726Swollman	 */
596103726Swollman	sis_mii_send(sc, frame->mii_stdelim, 2);
597103726Swollman	sis_mii_send(sc, frame->mii_opcode, 2);
598103726Swollman	sis_mii_send(sc, frame->mii_phyaddr, 5);
599103726Swollman	sis_mii_send(sc, frame->mii_regaddr, 5);
600103726Swollman
601103726Swollman	/* Idle bit */
602103726Swollman	SIO_CLR((SIS_MII_CLK|SIS_MII_DATA));
603103726Swollman	DELAY(1);
604103726Swollman	SIO_SET(SIS_MII_CLK);
605103726Swollman	DELAY(1);
606103726Swollman
607103726Swollman	/* Turn off xmit. */
608103726Swollman	SIO_CLR(SIS_MII_DIR);
609103726Swollman
6101573Srgrimes	/* Check for ack */
6111573Srgrimes	SIO_CLR(SIS_MII_CLK);
6121573Srgrimes	DELAY(1);
6131573Srgrimes	ack = CSR_READ_4(sc, SIS_EECTL) & SIS_MII_DATA;
6141573Srgrimes	SIO_SET(SIS_MII_CLK);
6151573Srgrimes	DELAY(1);
6161573Srgrimes
6171573Srgrimes	/*
6181573Srgrimes	 * Now try reading data bits. If the ack failed, we still
6191573Srgrimes	 * need to clock through 16 cycles to keep the PHY(s) in sync.
6201573Srgrimes	 */
6211573Srgrimes	if (ack) {
6221573Srgrimes		for(i = 0; i < 16; i++) {
6231573Srgrimes			SIO_CLR(SIS_MII_CLK);
6241573Srgrimes			DELAY(1);
625231891Sdelphij			SIO_SET(SIS_MII_CLK);
6261573Srgrimes			DELAY(1);
62790045Sobrien		}
62890045Sobrien		goto fail;
6291573Srgrimes	}
6301573Srgrimes
63154770Sgreen	for (i = 0x8000; i; i >>= 1) {
6321573Srgrimes		SIO_CLR(SIS_MII_CLK);
633175688Syar		DELAY(1);
634175688Syar		if (!ack) {
635175688Syar			if (CSR_READ_4(sc, SIS_EECTL) & SIS_MII_DATA)
636175688Syar				frame->mii_data |= i;
6371573Srgrimes			DELAY(1);
6381573Srgrimes		}
6391573Srgrimes		SIO_SET(SIS_MII_CLK);
6401573Srgrimes		DELAY(1);
6411573Srgrimes	}
6421573Srgrimes
6431573Srgrimesfail:
6441573Srgrimes
64523668Speter	SIO_CLR(SIS_MII_CLK);
64623668Speter	DELAY(1);
647129184Sbde	SIO_SET(SIS_MII_CLK);
64823668Speter	DELAY(1);
649129184Sbde
65023668Speter	splx(s);
65123668Speter
65223668Speter	if (ack)
65323668Speter		return(1);
6541573Srgrimes	return(0);
6551573Srgrimes}
6561573Srgrimes
6571573Srgrimes/*
6581573Srgrimes * Write to a PHY register through the MII.
6591573Srgrimes */
6601573Srgrimesstatic int sis_mii_writereg(sc, frame)
6611573Srgrimes	struct sis_softc	*sc;
6621573Srgrimes	struct sis_mii_frame	*frame;
6631573Srgrimes
6641573Srgrimes{
6651573Srgrimes	int			s;
66654770Sgreen
6671573Srgrimes	 s = splimp();
66854770Sgreen 	/*
66954770Sgreen 	 * Set up frame for TX.
67054770Sgreen 	 */
671129052Speadar
672129052Speadar 	frame->mii_stdelim = SIS_MII_STARTDELIM;
673129052Speadar 	frame->mii_opcode = SIS_MII_WRITEOP;
674129052Speadar 	frame->mii_turnaround = SIS_MII_TURNAROUND;
67554770Sgreen
67654770Sgreen 	/*
6771573Srgrimes  	 * Turn on data output.
67854770Sgreen 	 */
67954770Sgreen 	SIO_SET(SIS_MII_DIR);
6801573Srgrimes
6811573Srgrimes 	sis_mii_sync(sc);
6821573Srgrimes
6831573Srgrimes 	sis_mii_send(sc, frame->mii_stdelim, 2);
6841573Srgrimes 	sis_mii_send(sc, frame->mii_opcode, 2);
6851573Srgrimes 	sis_mii_send(sc, frame->mii_phyaddr, 5);
6861573Srgrimes 	sis_mii_send(sc, frame->mii_regaddr, 5);
6871573Srgrimes 	sis_mii_send(sc, frame->mii_turnaround, 2);
6881573Srgrimes 	sis_mii_send(sc, frame->mii_data, 16);
6891573Srgrimes
6901573Srgrimes 	/* Idle bit. */
6911573Srgrimes 	SIO_SET(SIS_MII_CLK);
6921573Srgrimes 	DELAY(1);
6931573Srgrimes 	SIO_CLR(SIS_MII_CLK);
6941573Srgrimes 	DELAY(1);
6951573Srgrimes
6961573Srgrimes 	/*
6971573Srgrimes 	 * Turn off xmit.
6981573Srgrimes 	 */
6991573Srgrimes 	SIO_CLR(SIS_MII_DIR);
7001573Srgrimes
7011573Srgrimes 	splx(s);
70254770Sgreen
703235647Sgleb 	return(0);
7041573Srgrimes}
7051573Srgrimes
7061573Srgrimesstatic int
7071573Srgrimessis_miibus_readreg(dev, phy, reg)
7081573Srgrimes	device_t		dev;
7091573Srgrimes	int			phy, reg;
7101573Srgrimes{
71154770Sgreen	struct sis_softc	*sc;
7121573Srgrimes	struct sis_mii_frame    frame;
7131573Srgrimes
7141573Srgrimes	sc = device_get_softc(dev);
7151573Srgrimes
7161573Srgrimes	if (sc->sis_type == SIS_TYPE_83815) {
7171573Srgrimes		if (phy != 0)
7181573Srgrimes			return(0);
7191573Srgrimes		/*
7201573Srgrimes		 * The NatSemi chip can take a while after
7211573Srgrimes		 * a reset to come ready, during which the BMSR
7221573Srgrimes		 * returns a value of 0. This is *never* supposed
7231573Srgrimes		 * to happen: some of the BMSR bits are meant to
7241573Srgrimes		 * be hardwired in the on position, and this can
7251573Srgrimes		 * confuse the miibus code a bit during the probe
7261573Srgrimes		 * and attach phase. So we make an effort to check
7271573Srgrimes		 * for this condition and wait for it to clear.
72854770Sgreen		 */
72954770Sgreen		if (!CSR_READ_4(sc, NS_BMSR))
73054770Sgreen			DELAY(1000);
7311573Srgrimes		return CSR_READ_4(sc, NS_BMCR + (reg * 4));
73254770Sgreen	}
73354770Sgreen
7341573Srgrimes	/*
7351573Srgrimes	 * Chipsets < SIS_635 seem not to be able to read/write
7361573Srgrimes	 * through mdio. Use the enhanced PHY access register
7371573Srgrimes	 * again for them.
73854770Sgreen	 */
73928913Simp	if (sc->sis_type == SIS_TYPE_900 &&
740128946Skientzle	    sc->sis_rev < SIS_REV_635) {
7411573Srgrimes		int i, val = 0;
7421573Srgrimes
7431573Srgrimes		if (phy != 0)
744175688Syar			return(0);
7451573Srgrimes
746128946Skientzle		CSR_WRITE_4(sc, SIS_PHYCTL,
74754770Sgreen		    (phy << 11) | (reg << 6) | SIS_PHYOP_READ);
748128946Skientzle		SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS);
7491573Srgrimes
7501573Srgrimes		for (i = 0; i < SIS_TIMEOUT; i++) {
7511573Srgrimes			if (!(CSR_READ_4(sc, SIS_PHYCTL) & SIS_PHYCTL_ACCESS))
7521573Srgrimes				break;
7531573Srgrimes		}
7541573Srgrimes
7551573Srgrimes		if (i == SIS_TIMEOUT) {
7561573Srgrimes			printf("sis%d: PHY failed to come ready\n",
7571573Srgrimes			    sc->sis_unit);
7581573Srgrimes			return(0);
7591573Srgrimes		}
7601573Srgrimes
76154770Sgreen		val = (CSR_READ_4(sc, SIS_PHYCTL) >> 16) & 0xFFFF;
7621573Srgrimes
7631573Srgrimes		if (val == 0xFFFF)
76454770Sgreen			return(0);
76554770Sgreen
76654770Sgreen		return(val);
76754770Sgreen	} else {
76854770Sgreen		bzero((char *)&frame, sizeof(frame));
76954770Sgreen
77054770Sgreen		frame.mii_phyaddr = phy;
7711573Srgrimes		frame.mii_regaddr = reg;
7721573Srgrimes		sis_mii_readreg(sc, &frame);
77354770Sgreen
7741573Srgrimes		return(frame.mii_data);
775128946Skientzle	}
7761573Srgrimes}
77723668Speter
77823668Speterstatic int
77923668Spetersis_miibus_writereg(dev, phy, reg, data)
78023668Speter	device_t		dev;
78123668Speter	int			phy, reg, data;
7821573Srgrimes{
7831573Srgrimes	struct sis_softc	*sc;
7841573Srgrimes	struct sis_mii_frame	frame;
7851573Srgrimes
7861573Srgrimes	sc = device_get_softc(dev);
7871573Srgrimes
7881573Srgrimes	if (sc->sis_type == SIS_TYPE_83815) {
7891573Srgrimes		if (phy != 0)
7901573Srgrimes			return(0);
79154770Sgreen		CSR_WRITE_4(sc, NS_BMCR + (reg * 4), data);
79217141Sjkh		return(0);
7931573Srgrimes	}
7941573Srgrimes
7951573Srgrimes	/*
7961573Srgrimes	 * Chipsets < SIS_635 seem not to be able to read/write
7971573Srgrimes	 * through mdio. Use the enhanced PHY access register
7981573Srgrimes	 * again for them.
7991573Srgrimes	 */
8001573Srgrimes	if (sc->sis_type == SIS_TYPE_900 &&
8011573Srgrimes	    sc->sis_rev < SIS_REV_635) {
8021573Srgrimes		int i;
803260571Sjilles
804260571Sjilles		if (phy != 0)
8051573Srgrimes			return(0);
806260571Sjilles
807260571Sjilles		CSR_WRITE_4(sc, SIS_PHYCTL, (data << 16) | (phy << 11) |
8081573Srgrimes		    (reg << 6) | SIS_PHYOP_WRITE);
8091573Srgrimes		SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS);
8101573Srgrimes
8111573Srgrimes		for (i = 0; i < SIS_TIMEOUT; i++) {
8121573Srgrimes			if (!(CSR_READ_4(sc, SIS_PHYCTL) & SIS_PHYCTL_ACCESS))
8131573Srgrimes				break;
8141573Srgrimes		}
8151573Srgrimes
8161573Srgrimes		if (i == SIS_TIMEOUT)
8171573Srgrimes			printf("sis%d: PHY failed to come ready\n",
8181573Srgrimes			    sc->sis_unit);
8191573Srgrimes	} else {
8201573Srgrimes		bzero((char *)&frame, sizeof(frame));
8211573Srgrimes
8221573Srgrimes		frame.mii_phyaddr = phy;
8231573Srgrimes		frame.mii_regaddr = reg;
8241573Srgrimes		frame.mii_data = data;
82528913Simp		sis_mii_writereg(sc, &frame);
82628913Simp	}
8271573Srgrimes	return(0);
8281573Srgrimes}
82954770Sgreen
83054770Sgreenstatic void
8311573Srgrimessis_miibus_statchg(dev)
83254770Sgreen	device_t		dev;
83354770Sgreen{
8341573Srgrimes	struct sis_softc	*sc;
8351573Srgrimes
8361573Srgrimes	sc = device_get_softc(dev);
8371573Srgrimes	sis_init(sc);
8381573Srgrimes
839199844Sjh	return;
840199844Sjh}
8411573Srgrimes
8421573Srgrimesstatic u_int32_t
8431573Srgrimessis_crc(sc, addr)
8441573Srgrimes	struct sis_softc	*sc;
8451573Srgrimes	caddr_t			addr;
8461573Srgrimes{
8471573Srgrimes	u_int32_t		crc, carry;
8481573Srgrimes	int			i, j;
8491573Srgrimes	u_int8_t		c;
8501573Srgrimes
85177599Skris	/* Compute CRC for the address value. */
85277599Skris	crc = 0xFFFFFFFF; /* initial value */
8531573Srgrimes
8541573Srgrimes	for (i = 0; i < 6; i++) {
8551573Srgrimes		c = *(addr + i);
8561573Srgrimes		for (j = 0; j < 8; j++) {
8571573Srgrimes			carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01);
8581573Srgrimes			crc <<= 1;
8591573Srgrimes			c >>= 1;
8601573Srgrimes			if (carry)
8611573Srgrimes				crc = (crc ^ 0x04c11db6) | carry;
8621573Srgrimes		}
8631573Srgrimes	}
8641573Srgrimes
8651573Srgrimes	/*
8661573Srgrimes	 * return the filter bit position
8671573Srgrimes	 *
8681573Srgrimes	 * The NatSemi chip has a 512-bit filter, which is
8691573Srgrimes	 * different than the SiS, so we special-case it.
8701573Srgrimes	 */
871175688Syar	if (sc->sis_type == SIS_TYPE_83815)
872260571Sjilles		return (crc >> 23);
8731573Srgrimes	else if (sc->sis_rev >= SIS_REV_635 ||
87490045Sobrien	    sc->sis_rev == SIS_REV_900B)
87590045Sobrien		return (crc >> 24);
87690045Sobrien	else
8771573Srgrimes		return (crc >> 25);
8781573Srgrimes}
879260571Sjilles
8801573Srgrimesstatic void
881260571Sjillessis_setmulti_ns(sc)
882260571Sjilles	struct sis_softc	*sc;
883260571Sjilles{
884260571Sjilles	struct ifnet		*ifp;
885260571Sjilles	struct ifmultiaddr	*ifma;
8861573Srgrimes	u_int32_t		h = 0, i, filtsave;
8871573Srgrimes	int			bit, index;
8888870Srgrimes
88923668Speter	ifp = &sc->arpcom.ac_if;
890129184Sbde
89123668Speter	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
89223668Speter		SIS_CLRBIT(sc, SIS_RXFILT_CTL, NS_RXFILTCTL_MCHASH);
893129184Sbde		SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLMULTI);
89423668Speter		return;
89523668Speter	}
89623668Speter
89723668Speter	/*
89823668Speter	 * We have to explicitly enable the multicast hash table
89923668Speter	 * on the NatSemi chip if we want to use it, which we do.
9001573Srgrimes	 */
9011573Srgrimes	SIS_SETBIT(sc, SIS_RXFILT_CTL, NS_RXFILTCTL_MCHASH);
9021573Srgrimes	SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLMULTI);
9031573Srgrimes
9041573Srgrimes	filtsave = CSR_READ_4(sc, SIS_RXFILT_CTL);
9051573Srgrimes
906260571Sjilles	/* first, zot all the existing hash bits */
9071573Srgrimes	for (i = 0; i < 32; i++) {
908281082Sjilles		CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_FMEM_LO + (i*2));
909281082Sjilles		CSR_WRITE_4(sc, SIS_RXFILT_DATA, 0);
910281082Sjilles	}
911281082Sjilles
912281082Sjilles	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
913281082Sjilles		if (ifma->ifma_addr->sa_family != AF_LINK)
9141573Srgrimes			continue;
9151573Srgrimes		h = sis_crc(sc, LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
916260571Sjilles		index = h >> 3;
9171573Srgrimes		bit = h & 0x1F;
9181573Srgrimes		CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_FMEM_LO + index);
9191573Srgrimes		if (bit > 0xF)
9201573Srgrimes			bit -= 0x10;
9211573Srgrimes		SIS_SETBIT(sc, SIS_RXFILT_DATA, (1 << bit));
9221573Srgrimes	}
9231573Srgrimes
9241573Srgrimes	CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave);
9251573Srgrimes
9261573Srgrimes	return;
9271573Srgrimes}
9281573Srgrimes
9291573Srgrimesstatic void
9301573Srgrimessis_setmulti_sis(sc)
9311573Srgrimes	struct sis_softc	*sc;
9321573Srgrimes{
9331573Srgrimes	struct ifnet		*ifp;
9341573Srgrimes	struct ifmultiaddr	*ifma;
9351573Srgrimes	u_int32_t		h, i, n, ctl;
9361573Srgrimes	u_int16_t		hashes[16];
9371573Srgrimes
9381573Srgrimes	ifp = &sc->arpcom.ac_if;
9391573Srgrimes
9401573Srgrimes	/* hash table size */
9411573Srgrimes	if (sc->sis_rev >= SIS_REV_635 ||
9421573Srgrimes	    sc->sis_rev == SIS_REV_900B)
9431573Srgrimes		n = 16;
9441573Srgrimes	else
9451573Srgrimes		n = 8;
9461573Srgrimes
9471573Srgrimes	ctl = CSR_READ_4(sc, SIS_RXFILT_CTL) & SIS_RXFILTCTL_ENABLE;
9481573Srgrimes
9491573Srgrimes	if (ifp->if_flags & IFF_BROADCAST)
9501573Srgrimes		ctl |= SIS_RXFILTCTL_BROAD;
9511573Srgrimes
9521573Srgrimes	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
9531573Srgrimes		ctl |= SIS_RXFILTCTL_ALLMULTI;
9541573Srgrimes		if (ifp->if_flags & IFF_PROMISC)
9551573Srgrimes			ctl |= SIS_RXFILTCTL_BROAD|SIS_RXFILTCTL_ALLPHYS;
9561573Srgrimes		for (i = 0; i < n; i++)
9571573Srgrimes			hashes[i] = ~0;
958103726Swollman	} else {
959103726Swollman		for (i = 0; i < n; i++)
960103726Swollman			hashes[i] = 0;
961103726Swollman		i = 0;
962103726Swollman		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
963103726Swollman			if (ifma->ifma_addr->sa_family != AF_LINK)
964103726Swollman			continue;
965103726Swollman			h = sis_crc(sc,
966103726Swollman			    LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
967103726Swollman			hashes[h >> 4] |= 1 << (h & 0xf);
968103726Swollman			i++;
969103726Swollman		}
970103726Swollman		if (i > n) {
971103726Swollman			ctl |= SIS_RXFILTCTL_ALLMULTI;
972103726Swollman			for (i = 0; i < n; i++)
9731573Srgrimes				hashes[i] = ~0;
974231891Sdelphij		}
9751573Srgrimes	}
97690045Sobrien
9771573Srgrimes	for (i = 0; i < n; i++) {
9781573Srgrimes		CSR_WRITE_4(sc, SIS_RXFILT_CTL, (4 + i) << 16);
9791573Srgrimes		CSR_WRITE_4(sc, SIS_RXFILT_DATA, hashes[i]);
9801573Srgrimes	}
9811573Srgrimes
9821573Srgrimes	CSR_WRITE_4(sc, SIS_RXFILT_CTL, ctl);
9831573Srgrimes}
9841573Srgrimes
9851573Srgrimesstatic void
9861573Srgrimessis_reset(sc)
98764740Sgreen	struct sis_softc	*sc;
98854770Sgreen{
9891573Srgrimes	register int		i;
9901573Srgrimes
9911573Srgrimes	SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RESET);
9921573Srgrimes
9931573Srgrimes	for (i = 0; i < SIS_TIMEOUT; i++) {
9941573Srgrimes		if (!(CSR_READ_4(sc, SIS_CSR) & SIS_CSR_RESET))
995103726Swollman			break;
9961573Srgrimes	}
9971573Srgrimes
9981573Srgrimes	if (i == SIS_TIMEOUT)
9991573Srgrimes		printf("sis%d: reset never completed\n", sc->sis_unit);
10001573Srgrimes
10011573Srgrimes	/* Wait a little while for the chip to get its brains in order. */
10021573Srgrimes	DELAY(1000);
1003231891Sdelphij
10041573Srgrimes	/*
100590045Sobrien	 * If this is a NetSemi chip, make sure to clear
10061573Srgrimes	 * PME mode.
10071573Srgrimes	 */
1008103726Swollman	if (sc->sis_type == SIS_TYPE_83815) {
1009103726Swollman		CSR_WRITE_4(sc, NS_CLKRUN, NS_CLKRUN_PMESTS);
1010103726Swollman		CSR_WRITE_4(sc, NS_CLKRUN, 0);
1011103726Swollman	}
1012103726Swollman
10131573Srgrimes        return;
10141573Srgrimes}
10151573Srgrimes
10161573Srgrimes/*
1017103726Swollman * Probe for an SiS chip. Check the PCI vendor and device
10181573Srgrimes * IDs against our list and return a device name if we find a match.
1019103726Swollman */
1020103726Swollmanstatic int
1021103726Swollmansis_probe(dev)
1022103726Swollman	device_t		dev;
1023103726Swollman{
10241573Srgrimes	struct sis_type		*t;
10251573Srgrimes
10261573Srgrimes	t = sis_devs;
1027103726Swollman
1028103726Swollman	while(t->sis_name != NULL) {
1029103726Swollman		if ((pci_get_vendor(dev) == t->sis_vid) &&
1030103726Swollman		    (pci_get_device(dev) == t->sis_did)) {
1031103726Swollman			device_set_desc(dev, t->sis_name);
1032103726Swollman			return(0);
1033103726Swollman		}
1034103726Swollman		t++;
103554770Sgreen	}
1036103726Swollman
103754770Sgreen	return(ENXIO);
10381573Srgrimes}
10391573Srgrimes
10401573Srgrimes/*
10411573Srgrimes * Attach the interface. Allocate softc structures, do ifmedia
10421573Srgrimes * setup and ethernet/BPF attach.
10431573Srgrimes */
10441573Srgrimesstatic int
1045103726Swollmansis_attach(dev)
10461573Srgrimes	device_t		dev;
10471573Srgrimes{
10481573Srgrimes	u_char			eaddr[ETHER_ADDR_LEN];
10491573Srgrimes	u_int32_t		command;
1050231891Sdelphij	struct sis_softc	*sc;
10511573Srgrimes	struct ifnet		*ifp;
105290045Sobrien	int			unit, error = 0, rid, waittime = 0;
10531573Srgrimes
10541573Srgrimes	waittime = 0;
105528913Simp	sc = device_get_softc(dev);
10561573Srgrimes	unit = device_get_unit(dev);
10571573Srgrimes	bzero(sc, sizeof(struct sis_softc));
10581573Srgrimes
10591573Srgrimes	mtx_init(&sc->sis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
10601573Srgrimes	    MTX_DEF | MTX_RECURSE);
10611573Srgrimes
10621573Srgrimes	if (pci_get_device(dev) == SIS_DEVICEID_900)
10631573Srgrimes		sc->sis_type = SIS_TYPE_900;
10641573Srgrimes	if (pci_get_device(dev) == SIS_DEVICEID_7016)
10658870Srgrimes		sc->sis_type = SIS_TYPE_7016;
10661573Srgrimes	if (pci_get_vendor(dev) == NS_VENDORID)
10671573Srgrimes		sc->sis_type = SIS_TYPE_83815;
1068231891Sdelphij
10691573Srgrimes	sc->sis_rev = pci_read_config(dev, PCIR_REVID, 1);
107054770Sgreen
10711573Srgrimes	/*
107264740Sgreen	 * Handle power management nonsense.
107364740Sgreen	 */
107450790Simp	if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
107550790Simp		u_int32_t		iobase, membase, irq;
10761573Srgrimes
10771573Srgrimes		/* Save important PCI config data. */
10781573Srgrimes		iobase = pci_read_config(dev, SIS_PCI_LOIO, 4);
10791573Srgrimes		membase = pci_read_config(dev, SIS_PCI_LOMEM, 4);
10801573Srgrimes		irq = pci_read_config(dev, SIS_PCI_INTLINE, 4);
1081231891Sdelphij
10821573Srgrimes		/* Reset the power state. */
10831573Srgrimes		printf("sis%d: chip is in D%d power mode "
108454770Sgreen		    "-- setting to D0\n", unit,
10851573Srgrimes		    pci_get_powerstate(dev));
108664740Sgreen		pci_set_powerstate(dev, PCI_POWERSTATE_D0);
108754770Sgreen
108854770Sgreen		/* Restore PCI config data. */
108954770Sgreen		pci_write_config(dev, SIS_PCI_LOIO, iobase, 4);
109054770Sgreen		pci_write_config(dev, SIS_PCI_LOMEM, membase, 4);
10911573Srgrimes		pci_write_config(dev, SIS_PCI_INTLINE, irq, 4);
109264740Sgreen	}
10931573Srgrimes
10941573Srgrimes	/*
109554770Sgreen	 * Map control/status registers.
10961573Srgrimes	 */
109754770Sgreen	pci_enable_busmaster(dev);
109854770Sgreen	pci_enable_io(dev, SYS_RES_IOPORT);
109954770Sgreen	pci_enable_io(dev, SYS_RES_MEMORY);
11001573Srgrimes	command = pci_read_config(dev, PCIR_COMMAND, 4);
11011573Srgrimes
11021573Srgrimes#ifdef SIS_USEIOSPACE
11031573Srgrimes	if (!(command & PCIM_CMD_PORTEN)) {
11041573Srgrimes		printf("sis%d: failed to enable I/O ports!\n", unit);
1105288029Srodrigc		error = ENXIO;;
11061573Srgrimes		goto fail;
11071573Srgrimes	}
11081573Srgrimes#else
11091573Srgrimes	if (!(command & PCIM_CMD_MEMEN)) {
11101573Srgrimes		printf("sis%d: failed to enable memory mapping!\n", unit);
11111573Srgrimes		error = ENXIO;;
111254770Sgreen		goto fail;
11131573Srgrimes	}
111428913Simp#endif
111528913Simp
111628913Simp	rid = SIS_RID;
111728913Simp	sc->sis_res = bus_alloc_resource(dev, SIS_RES, &rid,
111828913Simp	    0, ~0, 1, RF_ACTIVE);
111928913Simp
112028913Simp	if (sc->sis_res == NULL) {
1121231891Sdelphij		printf("sis%d: couldn't map ports/memory\n", unit);
112228913Simp		error = ENXIO;
112328913Simp		goto fail;
112428913Simp	}
112528913Simp
112628913Simp	sc->sis_btag = rman_get_bustag(sc->sis_res);
112728913Simp	sc->sis_bhandle = rman_get_bushandle(sc->sis_res);
112828913Simp
1129246641Sjilles	/* Allocate interrupt */
1130246641Sjilles	rid = 0;
113128913Simp	sc->sis_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
113271579Sdeischen	    RF_SHAREABLE | RF_ACTIVE);
113328913Simp
113428913Simp	if (sc->sis_irq == NULL) {
113528913Simp		printf("sis%d: couldn't map interrupt\n", unit);
113628913Simp		bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
113728913Simp		error = ENXIO;
113828913Simp		goto fail;
113928913Simp	}
114028913Simp
114128913Simp	error = bus_setup_intr(dev, sc->sis_irq, INTR_TYPE_NET,
114228913Simp	    sis_intr, sc, &sc->sis_intrhand);
114328913Simp
114428913Simp	if (error) {
114556698Sjasone		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
114628913Simp		bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
114728913Simp		printf("sis%d: couldn't set up irq\n", unit);
114828913Simp		goto fail;
1149129052Speadar	}
1150129052Speadar
1151129052Speadar	/* Reset the adapter. */
1152129052Speadar	sis_reset(sc);
1153129052Speadar
1154129052Speadar	if (sc->sis_type == SIS_TYPE_900 &&
1155129052Speadar            (sc->sis_rev == SIS_REV_635 ||
1156129052Speadar            sc->sis_rev == SIS_REV_900B)) {
1157129052Speadar		SIO_SET(SIS_CFG_RND_CNT);
1158129052Speadar		SIO_SET(SIS_CFG_PERR_DETECT);
1159129161Speadar	}
1160129052Speadar
1161129052Speadar	/*
1162129052Speadar	 * Get station address from the EEPROM.
1163129052Speadar	 */
1164129052Speadar	switch (pci_get_vendor(dev)) {
1165129052Speadar	case NS_VENDORID:
1166129052Speadar		/*
1167129052Speadar		 * Reading the MAC address out of the EEPROM on
1168129052Speadar		 * the NatSemi chip takes a bit more work than
1169129052Speadar		 * you'd expect. The address spans 4 16-bit words,
1170129052Speadar		 * with the first word containing only a single bit.
1171129052Speadar		 * You have to shift everything over one bit to
1172129052Speadar		 * get it aligned properly. Also, the bits are
1173129052Speadar		 * stored backwards (the LSB is really the MSB,
1174129052Speadar		 * and so on) so you have to reverse them in order
1175129052Speadar		 * to get the MAC address into the form we want.
1176129052Speadar		 * Why? Who the hell knows.
1177129052Speadar		 */
1178129052Speadar		{
1179129052Speadar			u_int16_t		tmp[4];
1180129052Speadar
1181129161Speadar			sis_read_eeprom(sc, (caddr_t)&tmp,
1182129052Speadar			    NS_EE_NODEADDR, 4, 0);
1183
1184			/* Shift everything over one bit. */
1185			tmp[3] = tmp[3] >> 1;
1186			tmp[3] |= tmp[2] << 15;
1187			tmp[2] = tmp[2] >> 1;
1188			tmp[2] |= tmp[1] << 15;
1189			tmp[1] = tmp[1] >> 1;
1190			tmp[1] |= tmp[0] << 15;
1191
1192			/* Now reverse all the bits. */
1193			tmp[3] = sis_reverse(tmp[3]);
1194			tmp[2] = sis_reverse(tmp[2]);
1195			tmp[1] = sis_reverse(tmp[1]);
1196
1197			bcopy((char *)&tmp[1], eaddr, ETHER_ADDR_LEN);
1198		}
1199		break;
1200	case SIS_VENDORID:
1201	default:
1202#ifdef __i386__
1203		/*
1204		 * If this is a SiS 630E chipset with an embedded
1205		 * SiS 900 controller, we have to read the MAC address
1206		 * from the APC CMOS RAM. Our method for doing this
1207		 * is very ugly since we have to reach out and grab
1208		 * ahold of hardware for which we cannot properly
1209		 * allocate resources. This code is only compiled on
1210		 * the i386 architecture since the SiS 630E chipset
1211		 * is for x86 motherboards only. Note that there are
1212		 * a lot of magic numbers in this hack. These are
1213		 * taken from SiS's Linux driver. I'd like to replace
1214		 * them with proper symbolic definitions, but that
1215		 * requires some datasheets that I don't have access
1216		 * to at the moment.
1217		 */
1218		if (sc->sis_rev == SIS_REV_630S ||
1219		    sc->sis_rev == SIS_REV_630E ||
1220		    sc->sis_rev == SIS_REV_630EA1)
1221			sis_read_cmos(sc, dev, (caddr_t)&eaddr, 0x9, 6);
1222
1223		else if (sc->sis_rev == SIS_REV_635 ||
1224			 sc->sis_rev == SIS_REV_630ET)
1225			sis_read_mac(sc, dev, (caddr_t)&eaddr);
1226		else if (sc->sis_rev == SIS_REV_96x) {
1227			/* Allow to read EEPROM from LAN. It is shared
1228			 * between a 1394 controller and the NIC and each
1229			 * time we access it, we need to set SIS_EECMD_REQ.
1230			 */
1231			SIO_SET(SIS_EECMD_REQ);
1232			for (waittime = 0; waittime < SIS_TIMEOUT;
1233			    waittime++) {
1234				/* Force EEPROM to idle state. */
1235				sis_eeprom_idle(sc);
1236				if (CSR_READ_4(sc, SIS_EECTL) & SIS_EECMD_GNT) {
1237					sis_read_eeprom(sc, (caddr_t)&eaddr,
1238					    SIS_EE_NODEADDR, 3, 0);
1239					break;
1240				}
1241				DELAY(1);
1242			}
1243			/*
1244			 * Set SIS_EECTL_CLK to high, so a other master
1245			 * can operate on the i2c bus.
1246			 */
1247			SIO_SET(SIS_EECTL_CLK);
1248			/* Refuse EEPROM access by LAN */
1249			SIO_SET(SIS_EECMD_DONE);
1250		} else
1251#endif
1252			sis_read_eeprom(sc, (caddr_t)&eaddr,
1253			    SIS_EE_NODEADDR, 3, 0);
1254		break;
1255	}
1256
1257	/*
1258	 * A SiS chip was detected. Inform the world.
1259	 */
1260	printf("sis%d: Ethernet address: %6D\n", unit, eaddr, ":");
1261
1262	sc->sis_unit = unit;
1263	callout_handle_init(&sc->sis_stat_ch);
1264	bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
1265
1266	/*
1267	 * Allocate the parent bus DMA tag appropriate for PCI.
1268	 */
1269#define SIS_NSEG_NEW 32
1270	 error = bus_dma_tag_create(NULL,	/* parent */
1271			1, 0,			/* alignment, boundary */
1272			BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
1273			BUS_SPACE_MAXADDR,	/* highaddr */
1274			NULL, NULL,		/* filter, filterarg */
1275			MAXBSIZE, SIS_NSEG_NEW,	/* maxsize, nsegments */
1276			BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
1277			BUS_DMA_ALLOCNOW,	/* flags */
1278			&sc->sis_parent_tag);
1279
1280	/*
1281	 * Now allocate a tag for the DMA descriptor lists.
1282	 * All of our lists are allocated as a contiguous block
1283	 * of memory.
1284	 */
1285	error = bus_dma_tag_create(sc->sis_parent_tag,	/* parent */
1286			1, 0,			/* alignment, boundary */
1287			BUS_SPACE_MAXADDR,	/* lowaddr */
1288			BUS_SPACE_MAXADDR,	/* highaddr */
1289			NULL, NULL,		/* filter, filterarg */
1290			SIS_RX_LIST_SZ, 1,	/* maxsize,nsegments */
1291			BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
1292			0,			/* flags */
1293			&sc->sis_ldata.sis_rx_tag);
1294
1295	error = bus_dma_tag_create(sc->sis_parent_tag,	/* parent */
1296			1, 0,			/* alignment, boundary */
1297			BUS_SPACE_MAXADDR,	/* lowaddr */
1298			BUS_SPACE_MAXADDR,	/* highaddr */
1299			NULL, NULL,		/* filter, filterarg */
1300			SIS_TX_LIST_SZ, 1,	/* maxsize,nsegments */
1301			BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
1302			0,			/* flags */
1303			&sc->sis_ldata.sis_tx_tag);
1304
1305	error = bus_dma_tag_create(sc->sis_parent_tag,	/* parent */
1306			1, 0,			/* alignment, boundary */
1307			BUS_SPACE_MAXADDR,	/* lowaddr */
1308			BUS_SPACE_MAXADDR,	/* highaddr */
1309			NULL, NULL,		/* filter, filterarg */
1310			MCLBYTES, 1,		/* maxsize,nsegments */
1311			BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
1312			0,			/* flags */
1313			&sc->sis_tag);
1314
1315	/*
1316	 * Now allocate a chunk of DMA-able memory based on the
1317	 * tag we just created.
1318	 */
1319	error = bus_dmamem_alloc(sc->sis_ldata.sis_tx_tag,
1320	    (void **)&sc->sis_ldata.sis_tx_list, BUS_DMA_NOWAIT,
1321	    &sc->sis_ldata.sis_tx_dmamap);
1322
1323	if (error) {
1324		printf("sis%d: no memory for list buffers!\n", unit);
1325		bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
1326		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
1327		bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
1328		bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
1329		bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
1330		error = ENXIO;
1331		goto fail;
1332	}
1333
1334	error = bus_dmamem_alloc(sc->sis_ldata.sis_rx_tag,
1335	    (void **)&sc->sis_ldata.sis_rx_list, BUS_DMA_NOWAIT,
1336	    &sc->sis_ldata.sis_rx_dmamap);
1337
1338	if (error) {
1339		printf("sis%d: no memory for list buffers!\n", unit);
1340		bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
1341		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
1342		bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
1343		bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
1344		    sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
1345		bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
1346		bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
1347		error = ENXIO;
1348		goto fail;
1349	}
1350
1351
1352	bzero(sc->sis_ldata.sis_tx_list, SIS_TX_LIST_SZ);
1353	bzero(sc->sis_ldata.sis_rx_list, SIS_RX_LIST_SZ);
1354
1355	/*
1356	 * Obtain the physical addresses of the RX and TX
1357	 * rings which we'll need later in the init routine.
1358	 */
1359	bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
1360	    sc->sis_ldata.sis_tx_dmamap, &(sc->sis_ldata.sis_tx_list[0]),
1361	    sizeof(struct sis_desc), sis_dma_map_ring,
1362	    &sc->sis_cdata.sis_tx_paddr, 0);
1363	bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
1364	    sc->sis_ldata.sis_rx_dmamap, &(sc->sis_ldata.sis_rx_list[0]),
1365	    sizeof(struct sis_desc), sis_dma_map_ring,
1366	    &sc->sis_cdata.sis_rx_paddr, 0);
1367
1368	ifp = &sc->arpcom.ac_if;
1369	ifp->if_softc = sc;
1370	ifp->if_unit = unit;
1371	ifp->if_name = "sis";
1372	ifp->if_mtu = ETHERMTU;
1373	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1374	ifp->if_ioctl = sis_ioctl;
1375	ifp->if_output = ether_output;
1376	ifp->if_start = sis_start;
1377	ifp->if_watchdog = sis_watchdog;
1378	ifp->if_init = sis_init;
1379	ifp->if_baudrate = 10000000;
1380	ifp->if_snd.ifq_maxlen = SIS_TX_LIST_CNT - 1;
1381
1382	/*
1383	 * Do MII setup.
1384	 */
1385	if (mii_phy_probe(dev, &sc->sis_miibus,
1386	    sis_ifmedia_upd, sis_ifmedia_sts)) {
1387		printf("sis%d: MII without any PHY!\n", sc->sis_unit);
1388		bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
1389		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
1390		bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
1391		bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
1392		    sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
1393		bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
1394		    sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
1395		bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
1396		bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
1397		error = ENXIO;
1398		goto fail;
1399	}
1400
1401	/*
1402	 * Call MI attach routine.
1403	 */
1404	ether_ifattach(ifp, eaddr);
1405
1406	/*
1407	 * Tell the upper layer(s) we support long frames.
1408	 */
1409	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
1410	ifp->if_capabilities |= IFCAP_VLAN_MTU;
1411
1412	callout_handle_init(&sc->sis_stat_ch);
1413	return(0);
1414
1415fail:
1416	mtx_destroy(&sc->sis_mtx);
1417	return(error);
1418}
1419
1420static int
1421sis_detach(dev)
1422	device_t		dev;
1423{
1424	struct sis_softc	*sc;
1425	struct ifnet		*ifp;
1426
1427
1428	sc = device_get_softc(dev);
1429	SIS_LOCK(sc);
1430	ifp = &sc->arpcom.ac_if;
1431
1432	sis_reset(sc);
1433	sis_stop(sc);
1434	ether_ifdetach(ifp);
1435
1436	bus_generic_detach(dev);
1437	device_delete_child(dev, sc->sis_miibus);
1438
1439	bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
1440	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
1441	bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
1442
1443	bus_dmamap_unload(sc->sis_ldata.sis_rx_tag,
1444	    sc->sis_ldata.sis_rx_dmamap);
1445	bus_dmamap_unload(sc->sis_ldata.sis_tx_tag,
1446	    sc->sis_ldata.sis_tx_dmamap);
1447	bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
1448	    sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
1449	bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
1450	    sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
1451	bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
1452	bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
1453	bus_dma_tag_destroy(sc->sis_parent_tag);
1454
1455	SIS_UNLOCK(sc);
1456	mtx_destroy(&sc->sis_mtx);
1457
1458	return(0);
1459}
1460
1461/*
1462 * Initialize the transmit descriptors.
1463 */
1464static int
1465sis_list_tx_init(sc)
1466	struct sis_softc	*sc;
1467{
1468	struct sis_list_data	*ld;
1469	struct sis_ring_data	*cd;
1470	int			i, nexti;
1471
1472	cd = &sc->sis_cdata;
1473	ld = &sc->sis_ldata;
1474
1475	for (i = 0; i < SIS_TX_LIST_CNT; i++) {
1476		nexti = (i == (SIS_TX_LIST_CNT - 1)) ? 0 : i+1;
1477			ld->sis_tx_list[i].sis_nextdesc =
1478			    &ld->sis_tx_list[nexti];
1479			bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
1480			    sc->sis_ldata.sis_tx_dmamap,
1481			    &ld->sis_tx_list[nexti], sizeof(struct sis_desc),
1482			    sis_dma_map_desc_next, &ld->sis_tx_list[i], 0);
1483		ld->sis_tx_list[i].sis_mbuf = NULL;
1484		ld->sis_tx_list[i].sis_ptr = 0;
1485		ld->sis_tx_list[i].sis_ctl = 0;
1486	}
1487
1488	cd->sis_tx_prod = cd->sis_tx_cons = cd->sis_tx_cnt = 0;
1489
1490	bus_dmamap_sync(sc->sis_ldata.sis_tx_tag,
1491	    sc->sis_ldata.sis_rx_dmamap, BUS_DMASYNC_PREWRITE);
1492
1493	return(0);
1494}
1495
1496/*
1497 * Initialize the RX descriptors and allocate mbufs for them. Note that
1498 * we arrange the descriptors in a closed ring, so that the last descriptor
1499 * points back to the first.
1500 */
1501static int
1502sis_list_rx_init(sc)
1503	struct sis_softc	*sc;
1504{
1505	struct sis_list_data	*ld;
1506	struct sis_ring_data	*cd;
1507	int			i,nexti;
1508
1509	ld = &sc->sis_ldata;
1510	cd = &sc->sis_cdata;
1511
1512	for (i = 0; i < SIS_RX_LIST_CNT; i++) {
1513		if (sis_newbuf(sc, &ld->sis_rx_list[i], NULL) == ENOBUFS)
1514			return(ENOBUFS);
1515		nexti = (i == (SIS_RX_LIST_CNT - 1)) ? 0 : i+1;
1516			ld->sis_rx_list[i].sis_nextdesc =
1517			    &ld->sis_rx_list[nexti];
1518			bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
1519			    sc->sis_ldata.sis_rx_dmamap,
1520			    &ld->sis_rx_list[nexti],
1521			    sizeof(struct sis_desc), sis_dma_map_desc_next,
1522			    &ld->sis_rx_list[i], 0);
1523		}
1524
1525	bus_dmamap_sync(sc->sis_ldata.sis_rx_tag,
1526	    sc->sis_ldata.sis_rx_dmamap, BUS_DMASYNC_PREWRITE);
1527
1528	cd->sis_rx_prod = 0;
1529
1530	return(0);
1531}
1532
1533/*
1534 * Initialize an RX descriptor and attach an MBUF cluster.
1535 */
1536static int
1537sis_newbuf(sc, c, m)
1538	struct sis_softc	*sc;
1539	struct sis_desc		*c;
1540	struct mbuf		*m;
1541{
1542
1543	if (c == NULL)
1544		return(EINVAL);
1545
1546	if (m == NULL) {
1547		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1548		if (m == NULL)
1549			return(ENOBUFS);
1550	} else
1551		m->m_data = m->m_ext.ext_buf;
1552
1553	c->sis_mbuf = m;
1554	c->sis_ctl = SIS_RXLEN;
1555
1556	bus_dmamap_create(sc->sis_tag, 0, &c->sis_map);
1557	bus_dmamap_load(sc->sis_tag, c->sis_map,
1558	    mtod(m, void *), MCLBYTES,
1559	    sis_dma_map_desc_ptr, c, 0);
1560	bus_dmamap_sync(sc->sis_tag, c->sis_map, BUS_DMASYNC_PREWRITE);
1561
1562	return(0);
1563}
1564
1565/*
1566 * A frame has been uploaded: pass the resulting mbuf chain up to
1567 * the higher level protocols.
1568 */
1569static void
1570sis_rxeof(sc)
1571	struct sis_softc	*sc;
1572{
1573        struct mbuf		*m;
1574        struct ifnet		*ifp;
1575	struct sis_desc		*cur_rx;
1576	int			i, total_len = 0;
1577	u_int32_t		rxstat;
1578
1579	ifp = &sc->arpcom.ac_if;
1580	i = sc->sis_cdata.sis_rx_prod;
1581
1582	while(SIS_OWNDESC(&sc->sis_ldata.sis_rx_list[i])) {
1583
1584#ifdef DEVICE_POLLING
1585		if (ifp->if_flags & IFF_POLLING) {
1586			if (sc->rxcycles <= 0)
1587				break;
1588			sc->rxcycles--;
1589		}
1590#endif /* DEVICE_POLLING */
1591		cur_rx = &sc->sis_ldata.sis_rx_list[i];
1592		rxstat = cur_rx->sis_rxstat;
1593		bus_dmamap_sync(sc->sis_tag,
1594		    cur_rx->sis_map, BUS_DMASYNC_POSTWRITE);
1595		bus_dmamap_unload(sc->sis_tag, cur_rx->sis_map);
1596		bus_dmamap_destroy(sc->sis_tag, cur_rx->sis_map);
1597		m = cur_rx->sis_mbuf;
1598		cur_rx->sis_mbuf = NULL;
1599		total_len = SIS_RXBYTES(cur_rx);
1600		SIS_INC(i, SIS_RX_LIST_CNT);
1601
1602		/*
1603		 * If an error occurs, update stats, clear the
1604		 * status word and leave the mbuf cluster in place:
1605		 * it should simply get re-used next time this descriptor
1606	 	 * comes up in the ring.
1607		 */
1608		if (!(rxstat & SIS_CMDSTS_PKT_OK)) {
1609			ifp->if_ierrors++;
1610			if (rxstat & SIS_RXSTAT_COLL)
1611				ifp->if_collisions++;
1612			sis_newbuf(sc, cur_rx, m);
1613			continue;
1614		}
1615
1616		/* No errors; receive the packet. */
1617#ifdef __i386__
1618		/*
1619		 * On the x86 we do not have alignment problems, so try to
1620		 * allocate a new buffer for the receive ring, and pass up
1621		 * the one where the packet is already, saving the expensive
1622		 * copy done in m_devget().
1623		 * If we are on an architecture with alignment problems, or
1624		 * if the allocation fails, then use m_devget and leave the
1625		 * existing buffer in the receive ring.
1626		 */
1627		if (sis_newbuf(sc, cur_rx, NULL) == 0)
1628			m->m_pkthdr.len = m->m_len = total_len;
1629		else
1630#endif
1631		{
1632			struct mbuf		*m0;
1633			m0 = m_devget(mtod(m, char *), total_len,
1634				ETHER_ALIGN, ifp, NULL);
1635			sis_newbuf(sc, cur_rx, m);
1636			if (m0 == NULL) {
1637				ifp->if_ierrors++;
1638				continue;
1639			}
1640			m = m0;
1641		}
1642
1643		ifp->if_ipackets++;
1644		m->m_pkthdr.rcvif = ifp;
1645
1646		(*ifp->if_input)(ifp, m);
1647	}
1648
1649	sc->sis_cdata.sis_rx_prod = i;
1650
1651	return;
1652}
1653
1654static void
1655sis_rxeoc(sc)
1656	struct sis_softc	*sc;
1657{
1658	sis_rxeof(sc);
1659	sis_init(sc);
1660	return;
1661}
1662
1663/*
1664 * A frame was downloaded to the chip. It's safe for us to clean up
1665 * the list buffers.
1666 */
1667
1668static void
1669sis_txeof(sc)
1670	struct sis_softc	*sc;
1671{
1672	struct ifnet		*ifp;
1673	u_int32_t		idx;
1674
1675	ifp = &sc->arpcom.ac_if;
1676
1677	/*
1678	 * Go through our tx list and free mbufs for those
1679	 * frames that have been transmitted.
1680	 */
1681	for (idx = sc->sis_cdata.sis_tx_cons; sc->sis_cdata.sis_tx_cnt > 0;
1682	    sc->sis_cdata.sis_tx_cnt--, SIS_INC(idx, SIS_TX_LIST_CNT) ) {
1683		struct sis_desc *cur_tx = &sc->sis_ldata.sis_tx_list[idx];
1684
1685		if (SIS_OWNDESC(cur_tx))
1686			break;
1687
1688		if (cur_tx->sis_ctl & SIS_CMDSTS_MORE)
1689			continue;
1690
1691		if (!(cur_tx->sis_ctl & SIS_CMDSTS_PKT_OK)) {
1692			ifp->if_oerrors++;
1693			if (cur_tx->sis_txstat & SIS_TXSTAT_EXCESSCOLLS)
1694				ifp->if_collisions++;
1695			if (cur_tx->sis_txstat & SIS_TXSTAT_OUTOFWINCOLL)
1696				ifp->if_collisions++;
1697		}
1698
1699		ifp->if_collisions +=
1700		    (cur_tx->sis_txstat & SIS_TXSTAT_COLLCNT) >> 16;
1701
1702		ifp->if_opackets++;
1703		if (cur_tx->sis_mbuf != NULL) {
1704			m_freem(cur_tx->sis_mbuf);
1705			cur_tx->sis_mbuf = NULL;
1706			bus_dmamap_unload(sc->sis_tag, cur_tx->sis_map);
1707			bus_dmamap_destroy(sc->sis_tag, cur_tx->sis_map);
1708		}
1709	}
1710
1711	if (idx != sc->sis_cdata.sis_tx_cons) {
1712		/* we freed up some buffers */
1713		sc->sis_cdata.sis_tx_cons = idx;
1714		ifp->if_flags &= ~IFF_OACTIVE;
1715	}
1716
1717	ifp->if_timer = (sc->sis_cdata.sis_tx_cnt == 0) ? 0 : 5;
1718
1719	return;
1720}
1721
1722static void
1723sis_tick(xsc)
1724	void			*xsc;
1725{
1726	struct sis_softc	*sc;
1727	struct mii_data		*mii;
1728	struct ifnet		*ifp;
1729
1730	sc = xsc;
1731	SIS_LOCK(sc);
1732	ifp = &sc->arpcom.ac_if;
1733
1734	mii = device_get_softc(sc->sis_miibus);
1735	mii_tick(mii);
1736
1737	if (!sc->sis_link && mii->mii_media_status & IFM_ACTIVE &&
1738	    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
1739		sc->sis_link++;
1740		if (ifp->if_snd.ifq_head != NULL)
1741			sis_start(ifp);
1742	}
1743
1744	sc->sis_stat_ch = timeout(sis_tick, sc, hz);
1745
1746	SIS_UNLOCK(sc);
1747
1748	return;
1749}
1750
1751#ifdef DEVICE_POLLING
1752static poll_handler_t sis_poll;
1753
1754static void
1755sis_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
1756{
1757	struct	sis_softc *sc = ifp->if_softc;
1758
1759	SIS_LOCK(sc);
1760	if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */
1761		CSR_WRITE_4(sc, SIS_IER, 1);
1762		goto done;
1763	}
1764
1765	/*
1766	 * On the sis, reading the status register also clears it.
1767	 * So before returning to intr mode we must make sure that all
1768	 * possible pending sources of interrupts have been served.
1769	 * In practice this means run to completion the *eof routines,
1770	 * and then call the interrupt routine
1771	 */
1772	sc->rxcycles = count;
1773	sis_rxeof(sc);
1774	sis_txeof(sc);
1775	if (ifp->if_snd.ifq_head != NULL)
1776		sis_start(ifp);
1777
1778	if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) {
1779		u_int32_t	status;
1780
1781		/* Reading the ISR register clears all interrupts. */
1782		status = CSR_READ_4(sc, SIS_ISR);
1783
1784		if (status & (SIS_ISR_RX_ERR|SIS_ISR_RX_OFLOW))
1785			sis_rxeoc(sc);
1786
1787		if (status & (SIS_ISR_RX_IDLE))
1788			SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
1789
1790		if (status & SIS_ISR_SYSERR) {
1791			sis_reset(sc);
1792			sis_init(sc);
1793		}
1794	}
1795done:
1796	SIS_UNLOCK(sc);
1797	return;
1798}
1799#endif /* DEVICE_POLLING */
1800
1801static void
1802sis_intr(arg)
1803	void			*arg;
1804{
1805	struct sis_softc	*sc;
1806	struct ifnet		*ifp;
1807	u_int32_t		status;
1808
1809	sc = arg;
1810	ifp = &sc->arpcom.ac_if;
1811
1812	SIS_LOCK(sc);
1813#ifdef DEVICE_POLLING
1814	if (ifp->if_flags & IFF_POLLING)
1815		goto done;
1816	if (ether_poll_register(sis_poll, ifp)) { /* ok, disable interrupts */
1817		CSR_WRITE_4(sc, SIS_IER, 0);
1818		goto done;
1819	}
1820#endif /* DEVICE_POLLING */
1821
1822	/* Supress unwanted interrupts */
1823	if (!(ifp->if_flags & IFF_UP)) {
1824		sis_stop(sc);
1825		goto done;
1826	}
1827
1828	/* Disable interrupts. */
1829	CSR_WRITE_4(sc, SIS_IER, 0);
1830
1831	for (;;) {
1832		/* Reading the ISR register clears all interrupts. */
1833		status = CSR_READ_4(sc, SIS_ISR);
1834
1835		if ((status & SIS_INTRS) == 0)
1836			break;
1837
1838		if (status &
1839		    (SIS_ISR_TX_DESC_OK | SIS_ISR_TX_ERR |
1840		     SIS_ISR_TX_OK | SIS_ISR_TX_IDLE) )
1841			sis_txeof(sc);
1842
1843		if (status & (SIS_ISR_RX_DESC_OK|SIS_ISR_RX_OK|SIS_ISR_RX_IDLE))
1844			sis_rxeof(sc);
1845
1846		if (status & (SIS_ISR_RX_ERR | SIS_ISR_RX_OFLOW))
1847			sis_rxeoc(sc);
1848
1849		if (status & (SIS_ISR_RX_IDLE))
1850			SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
1851
1852		if (status & SIS_ISR_SYSERR) {
1853			sis_reset(sc);
1854			sis_init(sc);
1855		}
1856	}
1857
1858	/* Re-enable interrupts. */
1859	CSR_WRITE_4(sc, SIS_IER, 1);
1860
1861	if (ifp->if_snd.ifq_head != NULL)
1862		sis_start(ifp);
1863done:
1864	SIS_UNLOCK(sc);
1865
1866	return;
1867}
1868
1869/*
1870 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
1871 * pointers to the fragment pointers.
1872 */
1873static int
1874sis_encap(sc, m_head, txidx)
1875	struct sis_softc	*sc;
1876	struct mbuf		*m_head;
1877	u_int32_t		*txidx;
1878{
1879	struct sis_desc		*f = NULL;
1880	struct mbuf		*m;
1881	int			frag, cur, cnt = 0;
1882
1883	/*
1884 	 * Start packing the mbufs in this chain into
1885	 * the fragment pointers. Stop when we run out
1886 	 * of fragments or hit the end of the mbuf chain.
1887	 */
1888	m = m_head;
1889	cur = frag = *txidx;
1890
1891	for (m = m_head; m != NULL; m = m->m_next) {
1892		if (m->m_len != 0) {
1893			if ((SIS_TX_LIST_CNT -
1894			    (sc->sis_cdata.sis_tx_cnt + cnt)) < 2)
1895				return(ENOBUFS);
1896			f = &sc->sis_ldata.sis_tx_list[frag];
1897			f->sis_ctl = SIS_CMDSTS_MORE | m->m_len;
1898			bus_dmamap_create(sc->sis_tag, 0, &f->sis_map);
1899			bus_dmamap_load(sc->sis_tag, f->sis_map,
1900			    mtod(m, void *), m->m_len,
1901			    sis_dma_map_desc_ptr, f, 0);
1902			bus_dmamap_sync(sc->sis_tag,
1903			    f->sis_map, BUS_DMASYNC_PREREAD);
1904			if (cnt != 0)
1905				f->sis_ctl |= SIS_CMDSTS_OWN;
1906			cur = frag;
1907			SIS_INC(frag, SIS_TX_LIST_CNT);
1908			cnt++;
1909		}
1910	}
1911
1912	if (m != NULL)
1913		return(ENOBUFS);
1914
1915	sc->sis_ldata.sis_tx_list[cur].sis_mbuf = m_head;
1916	sc->sis_ldata.sis_tx_list[cur].sis_ctl &= ~SIS_CMDSTS_MORE;
1917	sc->sis_ldata.sis_tx_list[*txidx].sis_ctl |= SIS_CMDSTS_OWN;
1918	sc->sis_cdata.sis_tx_cnt += cnt;
1919	*txidx = frag;
1920
1921	return(0);
1922}
1923
1924/*
1925 * Main transmit routine. To avoid having to do mbuf copies, we put pointers
1926 * to the mbuf data regions directly in the transmit lists. We also save a
1927 * copy of the pointers since the transmit list fragment pointers are
1928 * physical addresses.
1929 */
1930
1931static void
1932sis_start(ifp)
1933	struct ifnet		*ifp;
1934{
1935	struct sis_softc	*sc;
1936	struct mbuf		*m_head = NULL;
1937	u_int32_t		idx;
1938
1939	sc = ifp->if_softc;
1940	SIS_LOCK(sc);
1941
1942	if (!sc->sis_link) {
1943		SIS_UNLOCK(sc);
1944		return;
1945	}
1946
1947	idx = sc->sis_cdata.sis_tx_prod;
1948
1949	if (ifp->if_flags & IFF_OACTIVE) {
1950		SIS_UNLOCK(sc);
1951		return;
1952	}
1953
1954	while(sc->sis_ldata.sis_tx_list[idx].sis_mbuf == NULL) {
1955		IF_DEQUEUE(&ifp->if_snd, m_head);
1956		if (m_head == NULL)
1957			break;
1958
1959		if (sis_encap(sc, m_head, &idx)) {
1960			IF_PREPEND(&ifp->if_snd, m_head);
1961			ifp->if_flags |= IFF_OACTIVE;
1962			break;
1963		}
1964
1965		/*
1966		 * If there's a BPF listener, bounce a copy of this frame
1967		 * to him.
1968		 */
1969		BPF_MTAP(ifp, m_head);
1970
1971	}
1972
1973	/* Transmit */
1974	sc->sis_cdata.sis_tx_prod = idx;
1975	SIS_SETBIT(sc, SIS_CSR, SIS_CSR_TX_ENABLE);
1976
1977	/*
1978	 * Set a timeout in case the chip goes out to lunch.
1979	 */
1980	ifp->if_timer = 5;
1981
1982	SIS_UNLOCK(sc);
1983
1984	return;
1985}
1986
1987static void
1988sis_init(xsc)
1989	void			*xsc;
1990{
1991	struct sis_softc	*sc = xsc;
1992	struct ifnet		*ifp = &sc->arpcom.ac_if;
1993	struct mii_data		*mii;
1994
1995	SIS_LOCK(sc);
1996
1997	/*
1998	 * Cancel pending I/O and free all RX/TX buffers.
1999	 */
2000	sis_stop(sc);
2001
2002	mii = device_get_softc(sc->sis_miibus);
2003
2004	/* Set MAC address */
2005	if (sc->sis_type == SIS_TYPE_83815) {
2006		CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR0);
2007		CSR_WRITE_4(sc, SIS_RXFILT_DATA,
2008		    ((u_int16_t *)sc->arpcom.ac_enaddr)[0]);
2009		CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR1);
2010		CSR_WRITE_4(sc, SIS_RXFILT_DATA,
2011		    ((u_int16_t *)sc->arpcom.ac_enaddr)[1]);
2012		CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR2);
2013		CSR_WRITE_4(sc, SIS_RXFILT_DATA,
2014		    ((u_int16_t *)sc->arpcom.ac_enaddr)[2]);
2015	} else {
2016		CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR0);
2017		CSR_WRITE_4(sc, SIS_RXFILT_DATA,
2018		    ((u_int16_t *)sc->arpcom.ac_enaddr)[0]);
2019		CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR1);
2020		CSR_WRITE_4(sc, SIS_RXFILT_DATA,
2021		    ((u_int16_t *)sc->arpcom.ac_enaddr)[1]);
2022		CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR2);
2023		CSR_WRITE_4(sc, SIS_RXFILT_DATA,
2024		    ((u_int16_t *)sc->arpcom.ac_enaddr)[2]);
2025	}
2026
2027	/* Init circular RX list. */
2028	if (sis_list_rx_init(sc) == ENOBUFS) {
2029		printf("sis%d: initialization failed: no "
2030			"memory for rx buffers\n", sc->sis_unit);
2031		sis_stop(sc);
2032		SIS_UNLOCK(sc);
2033		return;
2034	}
2035
2036	/*
2037	 * Init tx descriptors.
2038	 */
2039	sis_list_tx_init(sc);
2040
2041	/*
2042	 * For the NatSemi chip, we have to explicitly enable the
2043	 * reception of ARP frames, as well as turn on the 'perfect
2044	 * match' filter where we store the station address, otherwise
2045	 * we won't receive unicasts meant for this host.
2046	 */
2047	if (sc->sis_type == SIS_TYPE_83815) {
2048		SIS_SETBIT(sc, SIS_RXFILT_CTL, NS_RXFILTCTL_ARP);
2049		SIS_SETBIT(sc, SIS_RXFILT_CTL, NS_RXFILTCTL_PERFECT);
2050	}
2051
2052	 /* If we want promiscuous mode, set the allframes bit. */
2053	if (ifp->if_flags & IFF_PROMISC) {
2054		SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLPHYS);
2055	} else {
2056		SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLPHYS);
2057	}
2058
2059	/*
2060	 * Set the capture broadcast bit to capture broadcast frames.
2061	 */
2062	if (ifp->if_flags & IFF_BROADCAST) {
2063		SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_BROAD);
2064	} else {
2065		SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_BROAD);
2066	}
2067
2068	/*
2069	 * Load the multicast filter.
2070	 */
2071	if (sc->sis_type == SIS_TYPE_83815)
2072		sis_setmulti_ns(sc);
2073	else
2074		sis_setmulti_sis(sc);
2075
2076	/* Turn the receive filter on */
2077	SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ENABLE);
2078
2079	/*
2080	 * Load the address of the RX and TX lists.
2081	 */
2082	CSR_WRITE_4(sc, SIS_RX_LISTPTR, sc->sis_cdata.sis_rx_paddr);
2083	CSR_WRITE_4(sc, SIS_TX_LISTPTR, sc->sis_cdata.sis_tx_paddr);
2084
2085	/* SIS_CFG_EDB_MASTER_EN indicates the EDB bus is used instead of
2086	 * the PCI bus. When this bit is set, the Max DMA Burst Size
2087	 * for TX/RX DMA should be no larger than 16 double words.
2088	 */
2089	if (CSR_READ_4(sc, SIS_CFG) & SIS_CFG_EDB_MASTER_EN) {
2090		CSR_WRITE_4(sc, SIS_RX_CFG, SIS_RXCFG64);
2091	} else {
2092		CSR_WRITE_4(sc, SIS_RX_CFG, SIS_RXCFG256);
2093	}
2094
2095
2096	/* Accept Long Packets for VLAN support */
2097	SIS_SETBIT(sc, SIS_RX_CFG, SIS_RXCFG_RX_JABBER);
2098
2099	/* Set TX configuration */
2100	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T) {
2101		CSR_WRITE_4(sc, SIS_TX_CFG, SIS_TXCFG_10);
2102	} else {
2103		CSR_WRITE_4(sc, SIS_TX_CFG, SIS_TXCFG_100);
2104	}
2105
2106	/* Set full/half duplex mode. */
2107	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
2108		SIS_SETBIT(sc, SIS_TX_CFG,
2109		    (SIS_TXCFG_IGN_HBEAT|SIS_TXCFG_IGN_CARR));
2110		SIS_SETBIT(sc, SIS_RX_CFG, SIS_RXCFG_RX_TXPKTS);
2111	} else {
2112		SIS_CLRBIT(sc, SIS_TX_CFG,
2113		    (SIS_TXCFG_IGN_HBEAT|SIS_TXCFG_IGN_CARR));
2114		SIS_CLRBIT(sc, SIS_RX_CFG, SIS_RXCFG_RX_TXPKTS);
2115	}
2116
2117	/*
2118	 * Enable interrupts.
2119	 */
2120	CSR_WRITE_4(sc, SIS_IMR, SIS_INTRS);
2121#ifdef DEVICE_POLLING
2122	/*
2123	 * ... only enable interrupts if we are not polling, make sure
2124	 * they are off otherwise.
2125	 */
2126	if (ifp->if_flags & IFF_POLLING)
2127		CSR_WRITE_4(sc, SIS_IER, 0);
2128	else
2129#endif /* DEVICE_POLLING */
2130	CSR_WRITE_4(sc, SIS_IER, 1);
2131
2132	/* Enable receiver and transmitter. */
2133	SIS_CLRBIT(sc, SIS_CSR, SIS_CSR_TX_DISABLE|SIS_CSR_RX_DISABLE);
2134	SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
2135
2136#ifdef notdef
2137	mii_mediachg(mii);
2138#endif
2139
2140	/*
2141	 * Page 75 of the DP83815 manual recommends the
2142	 * following register settings "for optimum
2143	 * performance." Note however that at least three
2144	 * of the registers are listed as "reserved" in
2145	 * the register map, so who knows what they do.
2146	 */
2147	if (sc->sis_type == SIS_TYPE_83815) {
2148		CSR_WRITE_4(sc, NS_PHY_PAGE, 0x0001);
2149		CSR_WRITE_4(sc, NS_PHY_CR, 0x189C);
2150		CSR_WRITE_4(sc, NS_PHY_TDATA, 0x0000);
2151		CSR_WRITE_4(sc, NS_PHY_DSPCFG, 0x5040);
2152		CSR_WRITE_4(sc, NS_PHY_SDCFG, 0x008C);
2153	}
2154
2155	ifp->if_flags |= IFF_RUNNING;
2156	ifp->if_flags &= ~IFF_OACTIVE;
2157
2158	sc->sis_stat_ch = timeout(sis_tick, sc, hz);
2159
2160	SIS_UNLOCK(sc);
2161
2162	return;
2163}
2164
2165/*
2166 * Set media options.
2167 */
2168static int
2169sis_ifmedia_upd(ifp)
2170	struct ifnet		*ifp;
2171{
2172	struct sis_softc	*sc;
2173	struct mii_data		*mii;
2174
2175	sc = ifp->if_softc;
2176
2177	mii = device_get_softc(sc->sis_miibus);
2178	sc->sis_link = 0;
2179	if (mii->mii_instance) {
2180		struct mii_softc	*miisc;
2181		LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
2182			mii_phy_reset(miisc);
2183	}
2184	mii_mediachg(mii);
2185
2186	return(0);
2187}
2188
2189/*
2190 * Report current media status.
2191 */
2192static void
2193sis_ifmedia_sts(ifp, ifmr)
2194	struct ifnet		*ifp;
2195	struct ifmediareq	*ifmr;
2196{
2197	struct sis_softc	*sc;
2198	struct mii_data		*mii;
2199
2200	sc = ifp->if_softc;
2201
2202	mii = device_get_softc(sc->sis_miibus);
2203	mii_pollstat(mii);
2204	ifmr->ifm_active = mii->mii_media_active;
2205	ifmr->ifm_status = mii->mii_media_status;
2206
2207	return;
2208}
2209
2210static int
2211sis_ioctl(ifp, command, data)
2212	struct ifnet		*ifp;
2213	u_long			command;
2214	caddr_t			data;
2215{
2216	struct sis_softc	*sc = ifp->if_softc;
2217	struct ifreq		*ifr = (struct ifreq *) data;
2218	struct mii_data		*mii;
2219	int			error = 0;
2220
2221	switch(command) {
2222	case SIOCSIFFLAGS:
2223		if (ifp->if_flags & IFF_UP) {
2224			sis_init(sc);
2225		} else {
2226			if (ifp->if_flags & IFF_RUNNING)
2227				sis_stop(sc);
2228		}
2229		error = 0;
2230		break;
2231	case SIOCADDMULTI:
2232	case SIOCDELMULTI:
2233		SIS_LOCK(sc);
2234		if (sc->sis_type == SIS_TYPE_83815)
2235			sis_setmulti_ns(sc);
2236		else
2237			sis_setmulti_sis(sc);
2238		SIS_UNLOCK(sc);
2239		error = 0;
2240		break;
2241	case SIOCGIFMEDIA:
2242	case SIOCSIFMEDIA:
2243		mii = device_get_softc(sc->sis_miibus);
2244		SIS_LOCK(sc);
2245		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
2246		SIS_UNLOCK(sc);
2247		break;
2248	default:
2249		error = ether_ioctl(ifp, command, data);
2250		break;
2251	}
2252
2253	return(error);
2254}
2255
2256static void
2257sis_watchdog(ifp)
2258	struct ifnet		*ifp;
2259{
2260	struct sis_softc	*sc;
2261
2262	sc = ifp->if_softc;
2263
2264	SIS_LOCK(sc);
2265
2266	ifp->if_oerrors++;
2267	printf("sis%d: watchdog timeout\n", sc->sis_unit);
2268
2269	sis_stop(sc);
2270	sis_reset(sc);
2271	sis_init(sc);
2272
2273	if (ifp->if_snd.ifq_head != NULL)
2274		sis_start(ifp);
2275
2276	SIS_UNLOCK(sc);
2277
2278	return;
2279}
2280
2281/*
2282 * Stop the adapter and free any mbufs allocated to the
2283 * RX and TX lists.
2284 */
2285static void
2286sis_stop(sc)
2287	struct sis_softc	*sc;
2288{
2289	register int		i;
2290	struct ifnet		*ifp;
2291
2292	SIS_LOCK(sc);
2293	ifp = &sc->arpcom.ac_if;
2294	ifp->if_timer = 0;
2295
2296	untimeout(sis_tick, sc, sc->sis_stat_ch);
2297
2298	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2299#ifdef DEVICE_POLLING
2300	ether_poll_deregister(ifp);
2301#endif
2302	CSR_WRITE_4(sc, SIS_IER, 0);
2303	CSR_WRITE_4(sc, SIS_IMR, 0);
2304	SIS_SETBIT(sc, SIS_CSR, SIS_CSR_TX_DISABLE|SIS_CSR_RX_DISABLE);
2305	DELAY(1000);
2306	CSR_WRITE_4(sc, SIS_TX_LISTPTR, 0);
2307	CSR_WRITE_4(sc, SIS_RX_LISTPTR, 0);
2308
2309	sc->sis_link = 0;
2310
2311	/*
2312	 * Free data in the RX lists.
2313	 */
2314	for (i = 0; i < SIS_RX_LIST_CNT; i++) {
2315		if (sc->sis_ldata.sis_rx_list[i].sis_mbuf != NULL) {
2316			bus_dmamap_unload(sc->sis_tag,
2317			    sc->sis_ldata.sis_rx_list[i].sis_map);
2318			bus_dmamap_destroy(sc->sis_tag,
2319			    sc->sis_ldata.sis_rx_list[i].sis_map);
2320			m_freem(sc->sis_ldata.sis_rx_list[i].sis_mbuf);
2321			sc->sis_ldata.sis_rx_list[i].sis_mbuf = NULL;
2322		}
2323	}
2324	bzero(sc->sis_ldata.sis_rx_list,
2325		sizeof(sc->sis_ldata.sis_rx_list));
2326
2327	/*
2328	 * Free the TX list buffers.
2329	 */
2330	for (i = 0; i < SIS_TX_LIST_CNT; i++) {
2331		if (sc->sis_ldata.sis_tx_list[i].sis_mbuf != NULL) {
2332			bus_dmamap_unload(sc->sis_tag,
2333			    sc->sis_ldata.sis_tx_list[i].sis_map);
2334			bus_dmamap_destroy(sc->sis_tag,
2335			    sc->sis_ldata.sis_tx_list[i].sis_map);
2336			m_freem(sc->sis_ldata.sis_tx_list[i].sis_mbuf);
2337			sc->sis_ldata.sis_tx_list[i].sis_mbuf = NULL;
2338		}
2339	}
2340
2341	bzero(sc->sis_ldata.sis_tx_list,
2342		sizeof(sc->sis_ldata.sis_tx_list));
2343
2344	SIS_UNLOCK(sc);
2345
2346	return;
2347}
2348
2349/*
2350 * Stop all chip I/O so that the kernel's probe routines don't
2351 * get confused by errant DMAs when rebooting.
2352 */
2353static void
2354sis_shutdown(dev)
2355	device_t		dev;
2356{
2357	struct sis_softc	*sc;
2358
2359	sc = device_get_softc(dev);
2360	SIS_LOCK(sc);
2361	sis_reset(sc);
2362	sis_stop(sc);
2363	SIS_UNLOCK(sc);
2364
2365	return;
2366}
2367