if_sis.c revision 51042
1/*
2 * Copyright (c) 1997, 1998, 1999
3 *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * $FreeBSD: head/sys/pci/if_sis.c 51042 1999-09-06 23:29:50Z wpaul $
33 */
34
35/*
36 * SiS 900/SiS 7016 fast ethernet PCI NIC driver. Datasheets are
37 * available from http://www.sis.com.tw.
38 *
39 * Written by Bill Paul <wpaul@ee.columbia.edu>
40 * Electrical Engineering Department
41 * Columbia University, New York City
42 */
43
44/*
45 * The SiS 900 is a fairly simple chip. It uses bus master DMA with
46 * simple TX and RX descriptors of 3 longwords in size. The receiver
47 * has a single perfect filter entry for the station address and a
48 * 128-bit multicast hash table. The SiS 900 has a built-in MII-based
49 * transceiver while the 7016 requires an external transceiver chip.
50 * Both chips offer the standard bit-bang MII interface as well as
51 * an enchanced PHY interface which simplifies accessing MII registers.
52 *
53 * The only downside to this chipset is that RX descriptors must be
54 * longword aligned.
55 */
56
57#include "bpf.h"
58
59#include <sys/param.h>
60#include <sys/systm.h>
61#include <sys/sockio.h>
62#include <sys/mbuf.h>
63#include <sys/malloc.h>
64#include <sys/kernel.h>
65#include <sys/socket.h>
66
67#include <net/if.h>
68#include <net/if_arp.h>
69#include <net/ethernet.h>
70#include <net/if_dl.h>
71#include <net/if_media.h>
72
73#if NBPF > 0
74#include <net/bpf.h>
75#endif
76
77#include <vm/vm.h>              /* for vtophys */
78#include <vm/pmap.h>            /* for vtophys */
79#include <machine/clock.h>      /* for DELAY */
80#include <machine/bus_pio.h>
81#include <machine/bus_memio.h>
82#include <machine/bus.h>
83#include <machine/resource.h>
84#include <sys/bus.h>
85#include <sys/rman.h>
86
87#include <dev/mii/mii.h>
88#include <dev/mii/miivar.h>
89
90#include <pci/pcireg.h>
91#include <pci/pcivar.h>
92
93#define SIS_USEIOSPACE
94
95#include <pci/if_sisreg.h>
96
97#include "miibus_if.h"
98
99#ifndef lint
100static const char rcsid[] =
101  "$FreeBSD: head/sys/pci/if_sis.c 51042 1999-09-06 23:29:50Z wpaul $";
102#endif
103
104/*
105 * Various supported device vendors/types and their names.
106 */
107static struct sis_type sis_devs[] = {
108	{ SIS_VENDORID, SIS_DEVICEID_900, "SiS 900 10/100BaseTX" },
109	{ SIS_VENDORID, SIS_DEVICEID_7016, "SiS 7016 10/100BaseTX" },
110	{ 0, 0, NULL }
111};
112
113static int sis_probe		__P((device_t));
114static int sis_attach		__P((device_t));
115static int sis_detach		__P((device_t));
116
117static int sis_newbuf		__P((struct sis_softc *,
118					struct sis_desc *,
119					struct mbuf *));
120static int sis_encap		__P((struct sis_softc *,
121					struct mbuf *, u_int32_t *));
122static void sis_rxeof		__P((struct sis_softc *));
123static void sis_rxeoc		__P((struct sis_softc *));
124static void sis_txeof		__P((struct sis_softc *));
125static void sis_intr		__P((void *));
126static void sis_tick		__P((void *));
127static void sis_start		__P((struct ifnet *));
128static int sis_ioctl		__P((struct ifnet *, u_long, caddr_t));
129static void sis_init		__P((void *));
130static void sis_stop		__P((struct sis_softc *));
131static void sis_watchdog		__P((struct ifnet *));
132static void sis_shutdown		__P((device_t));
133static int sis_ifmedia_upd	__P((struct ifnet *));
134static void sis_ifmedia_sts	__P((struct ifnet *, struct ifmediareq *));
135
136static void sis_delay		__P((struct sis_softc *));
137static void sis_eeprom_idle	__P((struct sis_softc *));
138static void sis_eeprom_putbyte	__P((struct sis_softc *, int));
139static void sis_eeprom_getword	__P((struct sis_softc *, int, u_int16_t *));
140static void sis_read_eeprom	__P((struct sis_softc *, caddr_t, int,
141							int, int));
142static int sis_miibus_readreg	__P((device_t, int, int));
143static int sis_miibus_writereg	__P((device_t, int, int, int));
144static void sis_miibus_statchg	__P((device_t));
145
146static void sis_setmulti	__P((struct sis_softc *));
147static u_int32_t sis_calchash	__P((caddr_t));
148static void sis_reset		__P((struct sis_softc *));
149static int sis_list_rx_init	__P((struct sis_softc *));
150static int sis_list_tx_init	__P((struct sis_softc *));
151
152#ifdef SIS_USEIOSPACE
153#define SIS_RES			SYS_RES_IOPORT
154#define SIS_RID			SIS_PCI_LOIO
155#else
156#define SIS_RES			SYS_RES_MEMORY
157#define SIS_RID			SIS_PCI_LOMEM
158#endif
159
160static device_method_t sis_methods[] = {
161	/* Device interface */
162	DEVMETHOD(device_probe,		sis_probe),
163	DEVMETHOD(device_attach,	sis_attach),
164	DEVMETHOD(device_detach,	sis_detach),
165	DEVMETHOD(device_shutdown,	sis_shutdown),
166
167	/* bus interface */
168	DEVMETHOD(bus_print_child,	bus_generic_print_child),
169	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
170
171	/* MII interface */
172	DEVMETHOD(miibus_readreg,	sis_miibus_readreg),
173	DEVMETHOD(miibus_writereg,	sis_miibus_writereg),
174	DEVMETHOD(miibus_statchg,	sis_miibus_statchg),
175
176	{ 0, 0 }
177};
178
179static driver_t sis_driver = {
180	"sis",
181	sis_methods,
182	sizeof(struct sis_softc)
183};
184
185static devclass_t sis_devclass;
186
187DRIVER_MODULE(sis, pci, sis_driver, sis_devclass, 0, 0);
188DRIVER_MODULE(miibus, sis, miibus_driver, miibus_devclass, 0, 0);
189
190#define SIS_SETBIT(sc, reg, x)				\
191	CSR_WRITE_4(sc, reg,				\
192		CSR_READ_4(sc, reg) | (x))
193
194#define SIS_CLRBIT(sc, reg, x)				\
195	CSR_WRITE_4(sc, reg,				\
196		CSR_READ_4(sc, reg) & ~(x))
197
198#define SIO_SET(x)					\
199	CSR_WRITE_4(sc, SIS_EECTL, CSR_READ_4(sc, SIS_EECTL) | x)
200
201#define SIO_CLR(x)					\
202	CSR_WRITE_4(sc, SIS_EECTL, CSR_READ_4(sc, SIS_EECTL) & ~x)
203
204static void sis_delay(sc)
205	struct sis_softc	*sc;
206{
207	int			idx;
208
209	for (idx = (300 / 33) + 1; idx > 0; idx--)
210		CSR_READ_4(sc, SIS_CSR);
211
212	return;
213}
214
215static void sis_eeprom_idle(sc)
216	struct sis_softc	*sc;
217{
218	register int		i;
219
220	SIO_SET(SIS_EECTL_CSEL);
221	sis_delay(sc);
222	SIO_SET(SIS_EECTL_CLK);
223	sis_delay(sc);
224
225	for (i = 0; i < 25; i++) {
226		SIO_CLR(SIS_EECTL_CLK);
227		sis_delay(sc);
228		SIO_SET(SIS_EECTL_CLK);
229		sis_delay(sc);
230	}
231
232	SIO_CLR(SIS_EECTL_CLK);
233	sis_delay(sc);
234	SIO_CLR(SIS_EECTL_CSEL);
235	sis_delay(sc);
236	CSR_WRITE_4(sc, SIS_EECTL, 0x00000000);
237
238	return;
239}
240
241/*
242 * Send a read command and address to the EEPROM, check for ACK.
243 */
244static void sis_eeprom_putbyte(sc, addr)
245	struct sis_softc	*sc;
246	int			addr;
247{
248	register int		d, i;
249
250	d = addr | SIS_EECMD_READ;
251
252	/*
253	 * Feed in each bit and stobe the clock.
254	 */
255	for (i = 0x400; i; i >>= 1) {
256		if (d & i) {
257			SIO_SET(SIS_EECTL_DIN);
258		} else {
259			SIO_CLR(SIS_EECTL_DIN);
260		}
261		sis_delay(sc);
262		SIO_SET(SIS_EECTL_CLK);
263		sis_delay(sc);
264		SIO_CLR(SIS_EECTL_CLK);
265		sis_delay(sc);
266	}
267
268	return;
269}
270
271/*
272 * Read a word of data stored in the EEPROM at address 'addr.'
273 */
274static void sis_eeprom_getword(sc, addr, dest)
275	struct sis_softc	*sc;
276	int			addr;
277	u_int16_t		*dest;
278{
279	register int		i;
280	u_int16_t		word = 0;
281
282	/* Force EEPROM to idle state. */
283	sis_eeprom_idle(sc);
284
285	/* Enter EEPROM access mode. */
286	sis_delay(sc);
287	SIO_SET(SIS_EECTL_CSEL);
288	sis_delay(sc);
289	SIO_SET(SIS_EECTL_CLK);
290	sis_delay(sc);
291
292	/*
293	 * Send address of word we want to read.
294	 */
295	sis_eeprom_putbyte(sc, addr);
296
297	/*
298	 * Start reading bits from EEPROM.
299	 */
300	for (i = 0x8000; i; i >>= 1) {
301		SIO_SET(SIS_EECTL_CLK);
302		sis_delay(sc);
303		if (CSR_READ_4(sc, SIS_EECTL) & SIS_EECTL_DOUT)
304			word |= i;
305		sis_delay(sc);
306		SIO_CLR(SIS_EECTL_CLK);
307		sis_delay(sc);
308	}
309
310	/* Turn off EEPROM access mode. */
311	sis_eeprom_idle(sc);
312
313	*dest = word;
314
315	return;
316}
317
318/*
319 * Read a sequence of words from the EEPROM.
320 */
321static void sis_read_eeprom(sc, dest, off, cnt, swap)
322	struct sis_softc	*sc;
323	caddr_t			dest;
324	int			off;
325	int			cnt;
326	int			swap;
327{
328	int			i;
329	u_int16_t		word = 0, *ptr;
330
331	for (i = 0; i < cnt; i++) {
332		sis_eeprom_getword(sc, off + i, &word);
333		ptr = (u_int16_t *)(dest + (i * 2));
334		if (swap)
335			*ptr = ntohs(word);
336		else
337			*ptr = word;
338	}
339
340	return;
341}
342
343static int sis_miibus_readreg(dev, phy, reg)
344	device_t		dev;
345	int			phy, reg;
346{
347	struct sis_softc	*sc;
348	int			i, val;
349
350	sc = device_get_softc(dev);
351
352	if (sc->sis_type == SIS_TYPE_900 && phy != 0)
353		return(0);
354
355	CSR_WRITE_4(sc, SIS_PHYCTL, (phy << 11) | (reg << 6) | SIS_PHYOP_READ);
356	SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS);
357
358	for (i = 0; i < SIS_TIMEOUT; i++) {
359		if (!(CSR_READ_4(sc, SIS_PHYCTL) & SIS_PHYCTL_ACCESS))
360			break;
361	}
362
363	if (i == SIS_TIMEOUT) {
364		printf("sis%d: PHY failed to come ready\n", sc->sis_unit);
365		return(0);
366	}
367
368	val = (CSR_READ_4(sc, SIS_PHYCTL) >> 16) & 0xFFFF;
369
370	if (val == 0xFFFF)
371		return(0);
372
373	return(val);
374}
375
376static int sis_miibus_writereg(dev, phy, reg, data)
377	device_t		dev;
378	int			phy, reg, data;
379{
380	struct sis_softc	*sc;
381	int			i;
382
383	sc = device_get_softc(dev);
384
385	if (sc->sis_type == SIS_TYPE_900 && phy != 0)
386		return(0);
387
388	CSR_WRITE_4(sc, SIS_PHYCTL, (data << 16) | (phy << 11) |
389	    (reg << 6) | SIS_PHYOP_WRITE);
390	SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS);
391
392	for (i = 0; i < SIS_TIMEOUT; i++) {
393		if (!(CSR_READ_4(sc, SIS_PHYCTL) & SIS_PHYCTL_ACCESS))
394			break;
395	}
396
397	if (i == SIS_TIMEOUT)
398		printf("sis%d: PHY failed to come ready\n", sc->sis_unit);
399
400	return(0);
401}
402
403static void sis_miibus_statchg(dev)
404	device_t		dev;
405{
406	struct sis_softc	*sc;
407	struct mii_data		*mii;
408
409	sc = device_get_softc(dev);
410	mii = device_get_softc(sc->sis_miibus);
411
412	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
413		SIS_SETBIT(sc, SIS_TX_CFG,
414		    (SIS_TXCFG_IGN_HBEAT|SIS_TXCFG_IGN_CARR));
415		SIS_SETBIT(sc, SIS_RX_CFG, SIS_RXCFG_RX_TXPKTS);
416	} else {
417		SIS_CLRBIT(sc, SIS_TX_CFG,
418		    (SIS_TXCFG_IGN_HBEAT|SIS_TXCFG_IGN_CARR));
419		SIS_CLRBIT(sc, SIS_RX_CFG, SIS_RXCFG_RX_TXPKTS);
420	}
421
422	return;
423}
424
425static u_int32_t sis_calchash(addr)
426	caddr_t			addr;
427{
428	u_int32_t		crc, carry;
429	int			i, j;
430	u_int8_t		c;
431
432	/* Compute CRC for the address value. */
433	crc = 0xFFFFFFFF; /* initial value */
434
435	for (i = 0; i < 6; i++) {
436		c = *(addr + i);
437		for (j = 0; j < 8; j++) {
438			carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01);
439			crc <<= 1;
440			c >>= 1;
441			if (carry)
442				crc = (crc ^ 0x04c11db6) | carry;
443		}
444	}
445
446	/* return the filter bit position */
447	return((crc >> 25) & 0x0000007F);
448}
449
450static void sis_setmulti(sc)
451	struct sis_softc	*sc;
452{
453	struct ifnet		*ifp;
454	struct ifmultiaddr	*ifma;
455	u_int32_t		h = 0, i, filtsave;
456
457	ifp = &sc->arpcom.ac_if;
458
459	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
460		SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLMULTI);
461		return;
462	}
463
464	SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLMULTI);
465
466	filtsave = CSR_READ_4(sc, SIS_RXFILT_CTL);
467
468	/* first, zot all the existing hash bits */
469	for (i = 0; i < 8; i++) {
470		CSR_WRITE_4(sc, SIS_RXFILT_CTL, (4 + ((i * 16) >> 4)) << 16);
471		CSR_WRITE_4(sc, SIS_RXFILT_DATA, 0);
472	}
473
474	/* now program new ones */
475	for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
476	    ifma = ifma->ifma_link.le_next) {
477		if (ifma->ifma_addr->sa_family != AF_LINK)
478			continue;
479		h = sis_calchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
480		CSR_WRITE_4(sc, SIS_RXFILT_CTL, (4 + (h >> 4)) << 16);
481		SIS_SETBIT(sc, SIS_RXFILT_DATA, (1 << (h & 0xF)));
482	}
483
484	CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave);
485
486	return;
487}
488
489static void sis_reset(sc)
490	struct sis_softc	*sc;
491{
492	register int		i;
493
494	SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RESET);
495
496	for (i = 0; i < SIS_TIMEOUT; i++) {
497		if (!(CSR_READ_4(sc, SIS_CSR) & SIS_CSR_RESET))
498			break;
499	}
500
501	if (i == SIS_TIMEOUT)
502		printf("sis%d: reset never completed\n", sc->sis_unit);
503
504	/* Wait a little while for the chip to get its brains in order. */
505	DELAY(1000);
506        return;
507}
508
509/*
510 * Probe for an SiS chip. Check the PCI vendor and device
511 * IDs against our list and return a device name if we find a match.
512 */
513static int sis_probe(dev)
514	device_t		dev;
515{
516	struct sis_type		*t;
517
518	t = sis_devs;
519
520	while(t->sis_name != NULL) {
521		if ((pci_get_vendor(dev) == t->sis_vid) &&
522		    (pci_get_device(dev) == t->sis_did)) {
523			device_set_desc(dev, t->sis_name);
524			return(0);
525		}
526		t++;
527	}
528
529	return(ENXIO);
530}
531
532/*
533 * Attach the interface. Allocate softc structures, do ifmedia
534 * setup and ethernet/BPF attach.
535 */
536static int sis_attach(dev)
537	device_t		dev;
538{
539	int			s;
540	u_char			eaddr[ETHER_ADDR_LEN];
541	u_int32_t		command;
542	struct sis_softc	*sc;
543	struct ifnet		*ifp;
544	int			unit, error = 0, rid;
545
546	s = splimp();
547
548	sc = device_get_softc(dev);
549	unit = device_get_unit(dev);
550	bzero(sc, sizeof(struct sis_softc));
551
552	if (pci_get_device(dev) == SIS_DEVICEID_900)
553		sc->sis_type = SIS_TYPE_900;
554	if (pci_get_device(dev) == SIS_DEVICEID_7016)
555		sc->sis_type = SIS_TYPE_7016;
556
557	/*
558	 * Handle power management nonsense.
559	 */
560
561	command = pci_read_config(dev, SIS_PCI_CAPID, 4) & 0x000000FF;
562	if (command == 0x01) {
563
564		command = pci_read_config(dev, SIS_PCI_PWRMGMTCTRL, 4);
565		if (command & SIS_PSTATE_MASK) {
566			u_int32_t		iobase, membase, irq;
567
568			/* Save important PCI config data. */
569			iobase = pci_read_config(dev, SIS_PCI_LOIO, 4);
570			membase = pci_read_config(dev, SIS_PCI_LOMEM, 4);
571			irq = pci_read_config(dev, SIS_PCI_INTLINE, 4);
572
573			/* Reset the power state. */
574			printf("sis%d: chip is in D%d power mode "
575			"-- setting to D0\n", unit, command & SIS_PSTATE_MASK);
576			command &= 0xFFFFFFFC;
577			pci_write_config(dev, SIS_PCI_PWRMGMTCTRL, command, 4);
578
579			/* Restore PCI config data. */
580			pci_write_config(dev, SIS_PCI_LOIO, iobase, 4);
581			pci_write_config(dev, SIS_PCI_LOMEM, membase, 4);
582			pci_write_config(dev, SIS_PCI_INTLINE, irq, 4);
583		}
584	}
585
586	/*
587	 * Map control/status registers.
588	 */
589	command = pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4);
590	command |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
591	pci_write_config(dev, PCI_COMMAND_STATUS_REG, command, 4);
592	command = pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4);
593
594#ifdef SIS_USEIOSPACE
595	if (!(command & PCIM_CMD_PORTEN)) {
596		printf("sis%d: failed to enable I/O ports!\n", unit);
597		error = ENXIO;;
598		goto fail;
599	}
600#else
601	if (!(command & PCIM_CMD_MEMEN)) {
602		printf("sis%d: failed to enable memory mapping!\n", unit);
603		error = ENXIO;;
604		goto fail;
605	}
606#endif
607
608	rid = SIS_RID;
609	sc->sis_res = bus_alloc_resource(dev, SIS_RES, &rid,
610	    0, ~0, 1, RF_ACTIVE);
611
612	if (sc->sis_res == NULL) {
613		printf("sis%d: couldn't map ports/memory\n", unit);
614		error = ENXIO;
615		goto fail;
616	}
617
618	sc->sis_btag = rman_get_bustag(sc->sis_res);
619	sc->sis_bhandle = rman_get_bushandle(sc->sis_res);
620
621	/* Allocate interrupt */
622	rid = 0;
623	sc->sis_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
624	    RF_SHAREABLE | RF_ACTIVE);
625
626	if (sc->sis_irq == NULL) {
627		printf("sis%d: couldn't map interrupt\n", unit);
628		bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
629		error = ENXIO;
630		goto fail;
631	}
632
633	error = bus_setup_intr(dev, sc->sis_irq, INTR_TYPE_NET,
634	    sis_intr, sc, &sc->sis_intrhand);
635
636	if (error) {
637		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_res);
638		bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
639		printf("sis%d: couldn't set up irq\n", unit);
640		goto fail;
641	}
642
643	/* Reset the adapter. */
644	sis_reset(sc);
645
646	/*
647	 * Get station address from the EEPROM.
648	 */
649	sis_read_eeprom(sc, (caddr_t)&eaddr, SIS_EE_NODEADDR, 3, 0);
650
651	/*
652	 * A SiS chip was detected. Inform the world.
653	 */
654	printf("sis%d: Ethernet address: %6D\n", unit, eaddr, ":");
655
656	sc->sis_unit = unit;
657	callout_handle_init(&sc->sis_stat_ch);
658	bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
659
660	sc->sis_ldata = contigmalloc(sizeof(struct sis_list_data), M_DEVBUF,
661	    M_NOWAIT, 0x100000, 0xffffffff, PAGE_SIZE, 0);
662
663	if (sc->sis_ldata == NULL) {
664		printf("sis%d: no memory for list buffers!\n", unit);
665		bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
666		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
667		bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
668		error = ENXIO;
669		goto fail;
670	}
671	bzero(sc->sis_ldata, sizeof(struct sis_list_data));
672
673	ifp = &sc->arpcom.ac_if;
674	ifp->if_softc = sc;
675	ifp->if_unit = unit;
676	ifp->if_name = "sis";
677	ifp->if_mtu = ETHERMTU;
678	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
679	ifp->if_ioctl = sis_ioctl;
680	ifp->if_output = ether_output;
681	ifp->if_start = sis_start;
682	ifp->if_watchdog = sis_watchdog;
683	ifp->if_init = sis_init;
684	ifp->if_baudrate = 10000000;
685	ifp->if_snd.ifq_maxlen = SIS_TX_LIST_CNT - 1;
686
687	/*
688	 * Do MII setup.
689	 */
690	if (mii_phy_probe(dev, &sc->sis_miibus,
691	    sis_ifmedia_upd, sis_ifmedia_sts)) {
692		printf("sis%d: MII without any PHY!\n", sc->sis_unit);
693		bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
694		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
695		bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
696		error = ENXIO;
697		goto fail;
698	}
699
700	/*
701	 * Call MI attach routines.
702	 */
703	if_attach(ifp);
704	ether_ifattach(ifp);
705	callout_handle_init(&sc->sis_stat_ch);
706
707#if NBPF > 0
708	bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
709#endif
710
711fail:
712	splx(s);
713	return(error);
714}
715
716static int sis_detach(dev)
717	device_t		dev;
718{
719	struct sis_softc	*sc;
720	struct ifnet		*ifp;
721	int			s;
722
723	s = splimp();
724
725	sc = device_get_softc(dev);
726	ifp = &sc->arpcom.ac_if;
727
728	sis_reset(sc);
729	sis_stop(sc);
730	if_detach(ifp);
731
732	bus_generic_detach(dev);
733	device_delete_child(dev, sc->sis_miibus);
734
735	bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
736	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
737	bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
738
739	contigfree(sc->sis_ldata, sizeof(struct sis_list_data), M_DEVBUF);
740
741	splx(s);
742
743	return(0);
744}
745
746/*
747 * Initialize the transmit descriptors.
748 */
749static int sis_list_tx_init(sc)
750	struct sis_softc	*sc;
751{
752	struct sis_list_data	*ld;
753	struct sis_ring_data	*cd;
754	int			i;
755
756	cd = &sc->sis_cdata;
757	ld = sc->sis_ldata;
758
759	for (i = 0; i < SIS_TX_LIST_CNT; i++) {
760		if (i == (SIS_TX_LIST_CNT - 1)) {
761			ld->sis_tx_list[i].sis_nextdesc =
762			    &ld->sis_tx_list[0];
763			ld->sis_tx_list[i].sis_next =
764			    vtophys(&ld->sis_tx_list[0]);
765		} else {
766			ld->sis_tx_list[i].sis_nextdesc =
767			    &ld->sis_tx_list[i + 1];
768			ld->sis_tx_list[i].sis_next =
769			    vtophys(&ld->sis_tx_list[i + 1]);
770		}
771		ld->sis_tx_list[i].sis_mbuf = NULL;
772		ld->sis_tx_list[i].sis_ptr = 0;
773		ld->sis_tx_list[i].sis_ctl = 0;
774	}
775
776	cd->sis_tx_prod = cd->sis_tx_cons = cd->sis_tx_cnt = 0;
777
778	return(0);
779}
780
781
782/*
783 * Initialize the RX descriptors and allocate mbufs for them. Note that
784 * we arrange the descriptors in a closed ring, so that the last descriptor
785 * points back to the first.
786 */
787static int sis_list_rx_init(sc)
788	struct sis_softc	*sc;
789{
790	struct sis_list_data	*ld;
791	struct sis_ring_data	*cd;
792	int			i;
793
794	ld = sc->sis_ldata;
795	cd = &sc->sis_cdata;
796
797	for (i = 0; i < SIS_RX_LIST_CNT; i++) {
798		if (sis_newbuf(sc, &ld->sis_rx_list[i], NULL) == ENOBUFS)
799			return(ENOBUFS);
800		if (i == (SIS_RX_LIST_CNT - 1)) {
801			ld->sis_rx_list[i].sis_nextdesc =
802			    &ld->sis_rx_list[0];
803			ld->sis_rx_list[i].sis_next =
804			    vtophys(&ld->sis_rx_list[0]);
805		} else {
806			ld->sis_rx_list[i].sis_nextdesc =
807			    &ld->sis_rx_list[i + 1];
808			ld->sis_rx_list[i].sis_next =
809			    vtophys(&ld->sis_rx_list[i + 1]);
810		}
811	}
812
813	cd->sis_rx_prod = 0;
814
815	return(0);
816}
817
818/*
819 * Initialize an RX descriptor and attach an MBUF cluster.
820 */
821static int sis_newbuf(sc, c, m)
822	struct sis_softc	*sc;
823	struct sis_desc		*c;
824	struct mbuf		*m;
825{
826	struct mbuf		*m_new = NULL;
827
828	if (m == NULL) {
829		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
830		if (m_new == NULL) {
831			printf("sis%d: no memory for rx list "
832			    "-- packet dropped!\n", sc->sis_unit);
833			return(ENOBUFS);
834		}
835
836		MCLGET(m_new, M_DONTWAIT);
837		if (!(m_new->m_flags & M_EXT)) {
838			printf("sis%d: no memory for rx list "
839			    "-- packet dropped!\n", sc->sis_unit);
840			m_freem(m_new);
841			return(ENOBUFS);
842		}
843		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
844	} else {
845		m_new = m;
846		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
847		m_new->m_data = m_new->m_ext.ext_buf;
848	}
849
850	m_adj(m_new, sizeof(u_int64_t));
851
852	c->sis_mbuf = m_new;
853	c->sis_ptr = vtophys(mtod(m_new, caddr_t));
854	c->sis_ctl = SIS_RXLEN;
855
856	return(0);
857}
858
859/*
860 * A frame has been uploaded: pass the resulting mbuf chain up to
861 * the higher level protocols.
862 */
863static void sis_rxeof(sc)
864	struct sis_softc	*sc;
865{
866        struct ether_header	*eh;
867        struct mbuf		*m;
868        struct ifnet		*ifp;
869	struct sis_desc		*cur_rx;
870	int			i, total_len = 0;
871	u_int32_t		rxstat;
872
873	ifp = &sc->arpcom.ac_if;
874	i = sc->sis_cdata.sis_rx_prod;
875
876	while(SIS_OWNDESC(&sc->sis_ldata->sis_rx_list[i])) {
877		struct mbuf		*m0 = NULL;
878
879		cur_rx = &sc->sis_ldata->sis_rx_list[i];
880		rxstat = cur_rx->sis_rxstat;
881		m = cur_rx->sis_mbuf;
882		cur_rx->sis_mbuf = NULL;
883		total_len = SIS_RXBYTES(cur_rx);
884		SIS_INC(i, SIS_RX_LIST_CNT);
885
886		/*
887		 * If an error occurs, update stats, clear the
888		 * status word and leave the mbuf cluster in place:
889		 * it should simply get re-used next time this descriptor
890	 	 * comes up in the ring.
891		 */
892		if (!(rxstat & SIS_CMDSTS_PKT_OK)) {
893			ifp->if_ierrors++;
894			if (rxstat & SIS_RXSTAT_COLL)
895				ifp->if_collisions++;
896			sis_newbuf(sc, cur_rx, m);
897			continue;
898		}
899
900		/* No errors; receive the packet. */
901		m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
902		    total_len + ETHER_ALIGN, 0, ifp, NULL);
903		sis_newbuf(sc, cur_rx, m);
904		if (m0 == NULL) {
905			ifp->if_ierrors++;
906			continue;
907		}
908		m_adj(m0, ETHER_ALIGN);
909		m = m0;
910
911		ifp->if_ipackets++;
912		eh = mtod(m, struct ether_header *);
913#if NBPF > 0
914		/*
915		 * Handle BPF listeners. Let the BPF user see the packet, but
916		 * don't pass it up to the ether_input() layer unless it's
917		 * a broadcast packet, multicast packet, matches our ethernet
918		 * address or the interface is in promiscuous mode.
919		 */
920		if (ifp->if_bpf) {
921			bpf_mtap(ifp, m);
922			if (ifp->if_flags & IFF_PROMISC &&
923			    (bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
924			    ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
925				m_freem(m);
926				continue;
927			}
928		}
929#endif
930		/* Remove header from mbuf and pass it on. */
931		m_adj(m, sizeof(struct ether_header));
932		ether_input(ifp, eh, m);
933	}
934
935	sc->sis_cdata.sis_rx_prod = i;
936
937	return;
938}
939
940void sis_rxeoc(sc)
941	struct sis_softc	*sc;
942{
943	sis_rxeof(sc);
944	sis_init(sc);
945	return;
946}
947
948/*
949 * A frame was downloaded to the chip. It's safe for us to clean up
950 * the list buffers.
951 */
952
953static void sis_txeof(sc)
954	struct sis_softc	*sc;
955{
956	struct sis_desc		*cur_tx = NULL;
957	struct ifnet		*ifp;
958	u_int32_t		idx;
959
960	ifp = &sc->arpcom.ac_if;
961
962	/* Clear the timeout timer. */
963	ifp->if_timer = 0;
964
965	/*
966	 * Go through our tx list and free mbufs for those
967	 * frames that have been transmitted.
968	 */
969	idx = sc->sis_cdata.sis_tx_cons;
970	while (idx != sc->sis_cdata.sis_tx_prod) {
971		cur_tx = &sc->sis_ldata->sis_tx_list[idx];
972
973		if (SIS_OWNDESC(cur_tx))
974			break;
975
976		if (cur_tx->sis_ctl & SIS_CMDSTS_MORE) {
977			sc->sis_cdata.sis_tx_cnt--;
978			SIS_INC(idx, SIS_TX_LIST_CNT);
979			continue;
980		}
981
982		if (!(cur_tx->sis_ctl & SIS_CMDSTS_PKT_OK)) {
983			ifp->if_oerrors++;
984			if (cur_tx->sis_txstat & SIS_TXSTAT_EXCESSCOLLS)
985				ifp->if_collisions++;
986			if (cur_tx->sis_txstat & SIS_TXSTAT_OUTOFWINCOLL)
987				ifp->if_collisions++;
988		}
989
990		ifp->if_collisions +=
991		    (cur_tx->sis_txstat & SIS_TXSTAT_COLLCNT) >> 16;
992
993		ifp->if_opackets++;
994		if (cur_tx->sis_mbuf != NULL) {
995			m_freem(cur_tx->sis_mbuf);
996			cur_tx->sis_mbuf = NULL;
997		}
998
999		sc->sis_cdata.sis_tx_cnt--;
1000		SIS_INC(idx, SIS_TX_LIST_CNT);
1001		ifp->if_timer = 0;
1002	}
1003
1004	sc->sis_cdata.sis_tx_cons = idx;
1005
1006	if (cur_tx != NULL)
1007		ifp->if_flags &= ~IFF_OACTIVE;
1008
1009	return;
1010}
1011
1012static void sis_tick(xsc)
1013	void			*xsc;
1014{
1015	struct sis_softc	*sc;
1016	struct mii_data		*mii;
1017	int			s;
1018
1019	s = splimp();
1020
1021	sc = xsc;
1022	mii = device_get_softc(sc->sis_miibus);
1023	mii_tick(mii);
1024	sc->sis_stat_ch = timeout(sis_tick, sc, hz);
1025
1026	splx(s);
1027
1028	return;
1029}
1030
1031static void sis_intr(arg)
1032	void			*arg;
1033{
1034	struct sis_softc	*sc;
1035	struct ifnet		*ifp;
1036	u_int32_t		status;
1037
1038	sc = arg;
1039	ifp = &sc->arpcom.ac_if;
1040
1041	/* Supress unwanted interrupts */
1042	if (!(ifp->if_flags & IFF_UP)) {
1043		sis_stop(sc);
1044		return;
1045	}
1046
1047	/* Disable interrupts. */
1048	CSR_WRITE_4(sc, SIS_IER, 0);
1049
1050	for (;;) {
1051		/* Reading the ISR register clears all interrupts. */
1052		status = CSR_READ_4(sc, SIS_ISR);
1053
1054		if ((status & SIS_INTRS) == 0)
1055			break;
1056
1057		if ((status & SIS_ISR_TX_OK) ||
1058		    (status & SIS_ISR_TX_ERR) ||
1059		    (status & SIS_ISR_TX_IDLE))
1060			sis_txeof(sc);
1061
1062		if (status & SIS_ISR_RX_OK)
1063			sis_rxeof(sc);
1064
1065		if ((status & SIS_ISR_RX_ERR) ||
1066		    (status & SIS_ISR_RX_OFLOW)) {
1067			sis_rxeoc(sc);
1068		}
1069
1070		if (status & SIS_ISR_SYSERR) {
1071			sis_reset(sc);
1072			sis_init(sc);
1073		}
1074	}
1075
1076	/* Re-enable interrupts. */
1077	CSR_WRITE_4(sc, SIS_IER, 1);
1078
1079	if (ifp->if_snd.ifq_head != NULL)
1080		sis_start(ifp);
1081
1082	return;
1083}
1084
1085/*
1086 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
1087 * pointers to the fragment pointers.
1088 */
1089static int sis_encap(sc, m_head, txidx)
1090	struct sis_softc	*sc;
1091	struct mbuf		*m_head;
1092	u_int32_t		*txidx;
1093{
1094	struct sis_desc		*f = NULL;
1095	struct mbuf		*m;
1096	int			frag, cur, cnt = 0;
1097
1098	/*
1099 	 * Start packing the mbufs in this chain into
1100	 * the fragment pointers. Stop when we run out
1101 	 * of fragments or hit the end of the mbuf chain.
1102	 */
1103	m = m_head;
1104	cur = frag = *txidx;
1105
1106	for (m = m_head; m != NULL; m = m->m_next) {
1107		if (m->m_len != 0) {
1108			if ((SIS_TX_LIST_CNT -
1109			    (sc->sis_cdata.sis_tx_cnt + cnt)) < 2)
1110				return(ENOBUFS);
1111			f = &sc->sis_ldata->sis_tx_list[frag];
1112			f->sis_ctl = SIS_CMDSTS_MORE | m->m_len;
1113			f->sis_ptr = vtophys(mtod(m, vm_offset_t));
1114			if (cnt != 0)
1115				f->sis_ctl |= SIS_CMDSTS_OWN;
1116			cur = frag;
1117			SIS_INC(frag, SIS_TX_LIST_CNT);
1118			cnt++;
1119		}
1120	}
1121
1122	if (m != NULL)
1123		return(ENOBUFS);
1124
1125	sc->sis_ldata->sis_tx_list[cur].sis_mbuf = m_head;
1126	sc->sis_ldata->sis_tx_list[cur].sis_ctl &= ~SIS_CMDSTS_MORE;
1127	sc->sis_ldata->sis_tx_list[*txidx].sis_ctl |= SIS_CMDSTS_OWN;
1128	sc->sis_cdata.sis_tx_cnt += cnt;
1129	*txidx = frag;
1130
1131	return(0);
1132}
1133
1134/*
1135 * Main transmit routine. To avoid having to do mbuf copies, we put pointers
1136 * to the mbuf data regions directly in the transmit lists. We also save a
1137 * copy of the pointers since the transmit list fragment pointers are
1138 * physical addresses.
1139 */
1140
1141static void sis_start(ifp)
1142	struct ifnet		*ifp;
1143{
1144	struct sis_softc	*sc;
1145	struct mbuf		*m_head = NULL;
1146	u_int32_t		idx;
1147
1148	sc = ifp->if_softc;
1149
1150	idx = sc->sis_cdata.sis_tx_prod;
1151
1152	if (ifp->if_flags & IFF_OACTIVE)
1153		return;
1154
1155	while(sc->sis_ldata->sis_tx_list[idx].sis_mbuf == NULL) {
1156		IF_DEQUEUE(&ifp->if_snd, m_head);
1157		if (m_head == NULL)
1158			break;
1159
1160		if (sis_encap(sc, m_head, &idx)) {
1161			IF_PREPEND(&ifp->if_snd, m_head);
1162			ifp->if_flags |= IFF_OACTIVE;
1163			break;
1164		}
1165
1166#if NBPF > 0
1167		/*
1168		 * If there's a BPF listener, bounce a copy of this frame
1169		 * to him.
1170		 */
1171		if (ifp->if_bpf)
1172			bpf_mtap(ifp, m_head);
1173#endif
1174	}
1175
1176	/* Transmit */
1177	sc->sis_cdata.sis_tx_prod = idx;
1178	SIS_SETBIT(sc, SIS_CSR, SIS_CSR_TX_ENABLE);
1179
1180	/*
1181	 * Set a timeout in case the chip goes out to lunch.
1182	 */
1183	ifp->if_timer = 5;
1184
1185	return;
1186}
1187
1188static void sis_init(xsc)
1189	void			*xsc;
1190{
1191	struct sis_softc	*sc = xsc;
1192	struct ifnet		*ifp = &sc->arpcom.ac_if;
1193	struct mii_data		*mii;
1194	int			s;
1195
1196	s = splimp();
1197
1198	/*
1199	 * Cancel pending I/O and free all RX/TX buffers.
1200	 */
1201	sis_stop(sc);
1202
1203	mii = device_get_softc(sc->sis_miibus);
1204
1205	/* Set MAC address */
1206	CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR0);
1207	CSR_WRITE_4(sc, SIS_RXFILT_DATA,
1208	    ((u_int16_t *)sc->arpcom.ac_enaddr)[0]);
1209	CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR1);
1210	CSR_WRITE_4(sc, SIS_RXFILT_DATA,
1211	    ((u_int16_t *)sc->arpcom.ac_enaddr)[1]);
1212	CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR2);
1213	CSR_WRITE_4(sc, SIS_RXFILT_DATA,
1214	    ((u_int16_t *)sc->arpcom.ac_enaddr)[2]);
1215
1216	/* Init circular RX list. */
1217	if (sis_list_rx_init(sc) == ENOBUFS) {
1218		printf("sis%d: initialization failed: no "
1219			"memory for rx buffers\n", sc->sis_unit);
1220		sis_stop(sc);
1221		(void)splx(s);
1222		return;
1223	}
1224
1225	/*
1226	 * Init tx descriptors.
1227	 */
1228	sis_list_tx_init(sc);
1229
1230	 /* If we want promiscuous mode, set the allframes bit. */
1231	if (ifp->if_flags & IFF_PROMISC) {
1232		SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLPHYS);
1233	} else {
1234		SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLPHYS);
1235	}
1236
1237	/*
1238	 * Set the capture broadcast bit to capture broadcast frames.
1239	 */
1240	if (ifp->if_flags & IFF_BROADCAST) {
1241		SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_BROAD);
1242	} else {
1243		SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_BROAD);
1244	}
1245
1246	/*
1247	 * Load the multicast filter.
1248	 */
1249	sis_setmulti(sc);
1250
1251	/* Turn the receive filter on */
1252	SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ENABLE);
1253
1254	/*
1255	 * Load the address of the RX and TX lists.
1256	 */
1257	CSR_WRITE_4(sc, SIS_RX_LISTPTR,
1258	    vtophys(&sc->sis_ldata->sis_rx_list[0]));
1259	CSR_WRITE_4(sc, SIS_TX_LISTPTR,
1260	    vtophys(&sc->sis_ldata->sis_tx_list[0]));
1261
1262	/* Set RX configuration */
1263	CSR_WRITE_4(sc, SIS_RX_CFG, SIS_RXCFG);
1264	/* Set TX configuration */
1265	CSR_WRITE_4(sc, SIS_TX_CFG, SIS_TXCFG);
1266
1267	/*
1268	 * Enable interrupts.
1269	 */
1270	CSR_WRITE_4(sc, SIS_IMR, SIS_INTRS);
1271	CSR_WRITE_4(sc, SIS_IER, 1);
1272
1273	/* Enable receiver and transmitter. */
1274	SIS_CLRBIT(sc, SIS_CSR, SIS_CSR_TX_DISABLE|SIS_CSR_RX_DISABLE);
1275	SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
1276
1277	mii_mediachg(mii);
1278
1279	ifp->if_flags |= IFF_RUNNING;
1280	ifp->if_flags &= ~IFF_OACTIVE;
1281
1282	(void)splx(s);
1283
1284	sc->sis_stat_ch = timeout(sis_tick, sc, hz);
1285
1286	return;
1287}
1288
1289/*
1290 * Set media options.
1291 */
1292static int sis_ifmedia_upd(ifp)
1293	struct ifnet		*ifp;
1294{
1295	struct sis_softc	*sc;
1296
1297	sc = ifp->if_softc;
1298
1299	if (ifp->if_flags & IFF_UP)
1300		sis_init(sc);
1301
1302	return(0);
1303}
1304
1305/*
1306 * Report current media status.
1307 */
1308static void sis_ifmedia_sts(ifp, ifmr)
1309	struct ifnet		*ifp;
1310	struct ifmediareq	*ifmr;
1311{
1312	struct sis_softc	*sc;
1313	struct mii_data		*mii;
1314
1315	sc = ifp->if_softc;
1316
1317	mii = device_get_softc(sc->sis_miibus);
1318	mii_pollstat(mii);
1319	ifmr->ifm_active = mii->mii_media_active;
1320	ifmr->ifm_status = mii->mii_media_status;
1321
1322	return;
1323}
1324
1325static int sis_ioctl(ifp, command, data)
1326	struct ifnet		*ifp;
1327	u_long			command;
1328	caddr_t			data;
1329{
1330	struct sis_softc	*sc = ifp->if_softc;
1331	struct ifreq		*ifr = (struct ifreq *) data;
1332	struct mii_data		*mii;
1333	int			s, error = 0;
1334
1335	s = splimp();
1336
1337	switch(command) {
1338	case SIOCSIFADDR:
1339	case SIOCGIFADDR:
1340	case SIOCSIFMTU:
1341		error = ether_ioctl(ifp, command, data);
1342		break;
1343	case SIOCSIFFLAGS:
1344		if (ifp->if_flags & IFF_UP) {
1345			sis_init(sc);
1346		} else {
1347			if (ifp->if_flags & IFF_RUNNING)
1348				sis_stop(sc);
1349		}
1350		error = 0;
1351		break;
1352	case SIOCADDMULTI:
1353	case SIOCDELMULTI:
1354		sis_setmulti(sc);
1355		error = 0;
1356		break;
1357	case SIOCGIFMEDIA:
1358	case SIOCSIFMEDIA:
1359		mii = device_get_softc(sc->sis_miibus);
1360		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
1361		break;
1362	default:
1363		error = EINVAL;
1364		break;
1365	}
1366
1367	(void)splx(s);
1368
1369	return(error);
1370}
1371
1372static void sis_watchdog(ifp)
1373	struct ifnet		*ifp;
1374{
1375	struct sis_softc	*sc;
1376
1377	sc = ifp->if_softc;
1378
1379	ifp->if_oerrors++;
1380	printf("sis%d: watchdog timeout\n", sc->sis_unit);
1381
1382	sis_stop(sc);
1383	sis_reset(sc);
1384	sis_init(sc);
1385
1386	if (ifp->if_snd.ifq_head != NULL)
1387		sis_start(ifp);
1388
1389	return;
1390}
1391
1392/*
1393 * Stop the adapter and free any mbufs allocated to the
1394 * RX and TX lists.
1395 */
1396static void sis_stop(sc)
1397	struct sis_softc	*sc;
1398{
1399	register int		i;
1400	struct ifnet		*ifp;
1401
1402	ifp = &sc->arpcom.ac_if;
1403	ifp->if_timer = 0;
1404
1405	untimeout(sis_tick, sc, sc->sis_stat_ch);
1406	CSR_WRITE_4(sc, SIS_IER, 0);
1407	CSR_WRITE_4(sc, SIS_IMR, 0);
1408	SIS_SETBIT(sc, SIS_CSR, SIS_CSR_TX_DISABLE|SIS_CSR_RX_DISABLE);
1409	DELAY(1000);
1410	CSR_WRITE_4(sc, SIS_TX_LISTPTR, 0);
1411	CSR_WRITE_4(sc, SIS_RX_LISTPTR, 0);
1412
1413	/*
1414	 * Free data in the RX lists.
1415	 */
1416	for (i = 0; i < SIS_RX_LIST_CNT; i++) {
1417		if (sc->sis_ldata->sis_rx_list[i].sis_mbuf != NULL) {
1418			m_freem(sc->sis_ldata->sis_rx_list[i].sis_mbuf);
1419			sc->sis_ldata->sis_rx_list[i].sis_mbuf = NULL;
1420		}
1421	}
1422	bzero((char *)&sc->sis_ldata->sis_rx_list,
1423		sizeof(sc->sis_ldata->sis_rx_list));
1424
1425	/*
1426	 * Free the TX list buffers.
1427	 */
1428	for (i = 0; i < SIS_TX_LIST_CNT; i++) {
1429		if (sc->sis_ldata->sis_tx_list[i].sis_mbuf != NULL) {
1430			m_freem(sc->sis_ldata->sis_tx_list[i].sis_mbuf);
1431			sc->sis_ldata->sis_tx_list[i].sis_mbuf = NULL;
1432		}
1433	}
1434
1435	bzero((char *)&sc->sis_ldata->sis_tx_list,
1436		sizeof(sc->sis_ldata->sis_tx_list));
1437
1438	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1439
1440	return;
1441}
1442
1443/*
1444 * Stop all chip I/O so that the kernel's probe routines don't
1445 * get confused by errant DMAs when rebooting.
1446 */
1447static void sis_shutdown(dev)
1448	device_t		dev;
1449{
1450	struct sis_softc	*sc;
1451
1452	sc = device_get_softc(dev);
1453
1454	sis_reset(sc);
1455	sis_stop(sc);
1456
1457	return;
1458}
1459