if_wb.c revision 113545
1173143Srwatson/*
2159248Srwatson * Copyright (c) 1997, 1998
3159248Srwatson *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4159248Srwatson *
5173143Srwatson * Redistribution and use in source and binary forms, with or without
6159248Srwatson * modification, are permitted provided that the following conditions
7159248Srwatson * are met:
8159248Srwatson * 1. Redistributions of source code must retain the above copyright
9159248Srwatson *    notice, this list of conditions and the following disclaimer.
10159248Srwatson * 2. Redistributions in binary form must reproduce the above copyright
11159248Srwatson *    notice, this list of conditions and the following disclaimer in the
12159248Srwatson *    documentation and/or other materials provided with the distribution.
13159248Srwatson * 3. All advertising materials mentioning features or use of this software
14159248Srwatson *    must display the following acknowledgement:
15159248Srwatson *	This product includes software developed by Bill Paul.
16159248Srwatson * 4. Neither the name of the author nor the names of any co-contributors
17159248Srwatson *    may be used to endorse or promote products derived from this software
18173143Srwatson *    without specific prior written permission.
19159248Srwatson *
20159248Srwatson * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21159248Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22159248Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23159248Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24159248Srwatson * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25159248Srwatson * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26159248Srwatson * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27159248Srwatson * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28159248Srwatson * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29159248Srwatson * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30159248Srwatson * THE POSSIBILITY OF SUCH DAMAGE.
31159248Srwatson */
32159248Srwatson
33159248Srwatson/*
34159248Srwatson * Winbond fast ethernet PCI NIC driver
35159248Srwatson *
36159248Srwatson * Supports various cheap network adapters based on the Winbond W89C840F
37159248Srwatson * fast ethernet controller chip. This includes adapters manufactured by
38159248Srwatson * Winbond itself and some made by Linksys.
39159248Srwatson *
40159248Srwatson * Written by Bill Paul <wpaul@ctr.columbia.edu>
41159248Srwatson * Electrical Engineering Department
42159248Srwatson * Columbia University, New York City
43159248Srwatson */
44159248Srwatson
45159248Srwatson/*
46159248Srwatson * The Winbond W89C840F chip is a bus master; in some ways it resembles
47159248Srwatson * a DEC 'tulip' chip, only not as complicated. Unfortunately, it has
48159248Srwatson * one major difference which is that while the registers do many of
49159248Srwatson * the same things as a tulip adapter, the offsets are different: where
50159248Srwatson * tulip registers are typically spaced 8 bytes apart, the Winbond
51159248Srwatson * registers are spaced 4 bytes apart. The receiver filter is also
52159248Srwatson * programmed differently.
53159248Srwatson *
54159248Srwatson * Like the tulip, the Winbond chip uses small descriptors containing
55159248Srwatson * a status word, a control word and 32-bit areas that can either be used
56173143Srwatson * to point to two external data blocks, or to point to a single block
57159248Srwatson * and another descriptor in a linked list. Descriptors can be grouped
58159248Srwatson * together in blocks to form fixed length rings or can be chained
59159248Srwatson * together in linked lists. A single packet may be spread out over
60159248Srwatson * several descriptors if necessary.
61173143Srwatson *
62173143Srwatson * For the receive ring, this driver uses a linked list of descriptors,
63173143Srwatson * each pointing to a single mbuf cluster buffer, which us large enough
64159248Srwatson * to hold an entire packet. The link list is looped back to created a
65173143Srwatson * closed ring.
66173143Srwatson *
67173143Srwatson * For transmission, the driver creates a linked list of 'super descriptors'
68159248Srwatson * which each contain several individual descriptors linked toghether.
69159248Srwatson * Each 'super descriptor' contains WB_MAXFRAGS descriptors, which we
70159248Srwatson * abuse as fragment pointers. This allows us to use a buffer managment
71159248Srwatson * scheme very similar to that used in the ThunderLAN and Etherlink XL
72159248Srwatson * drivers.
73159248Srwatson *
74159248Srwatson * Autonegotiation is performed using the external PHY via the MII bus.
75159248Srwatson * The sample boards I have all use a Davicom PHY.
76159248Srwatson *
77159248Srwatson * Note: the author of the Linux driver for the Winbond chip alludes
78159248Srwatson * to some sort of flaw in the chip's design that seems to mandate some
79159248Srwatson * drastic workaround which signigicantly impairs transmit performance.
80159248Srwatson * I have no idea what he's on about: transmit performance with all
81159248Srwatson * three of my test boards seems fine.
82159248Srwatson */
83159248Srwatson
84159248Srwatson#include <sys/cdefs.h>
85159248Srwatson__FBSDID("$FreeBSD: head/sys/pci/if_wb.c 113545 2003-04-16 03:16:57Z mdodd $");
86159248Srwatson
87159248Srwatson#include "opt_bdg.h"
88159248Srwatson
89159248Srwatson#include <sys/param.h>
90159248Srwatson#include <sys/systm.h>
91159248Srwatson#include <sys/sockio.h>
92159248Srwatson#include <sys/mbuf.h>
93159248Srwatson#include <sys/malloc.h>
94159248Srwatson#include <sys/kernel.h>
95159248Srwatson#include <sys/socket.h>
96159248Srwatson#include <sys/queue.h>
97159248Srwatson
98159248Srwatson#include <net/if.h>
99159248Srwatson#include <net/if_arp.h>
100159248Srwatson#include <net/ethernet.h>
101159248Srwatson#include <net/if_dl.h>
102159248Srwatson#include <net/if_media.h>
103173143Srwatson
104173143Srwatson#include <net/bpf.h>
105159248Srwatson
106159248Srwatson#include <vm/vm.h>              /* for vtophys */
107159248Srwatson#include <vm/pmap.h>            /* for vtophys */
108159248Srwatson#include <machine/bus_memio.h>
109159248Srwatson#include <machine/bus_pio.h>
110159248Srwatson#include <machine/bus.h>
111159248Srwatson#include <machine/resource.h>
112159248Srwatson#include <sys/bus.h>
113159248Srwatson#include <sys/rman.h>
114159248Srwatson
115159248Srwatson#include <pci/pcireg.h>
116159248Srwatson#include <pci/pcivar.h>
117173143Srwatson
118159248Srwatson#include <dev/mii/mii.h>
119159248Srwatson#include <dev/mii/miivar.h>
120159248Srwatson
121159248Srwatson/* "controller miibus0" required.  See GENERIC if you get errors here. */
122159248Srwatson#include "miibus_if.h"
123159248Srwatson
124159248Srwatson#define WB_USEIOSPACE
125159248Srwatson
126159248Srwatson#include <pci/if_wbreg.h>
127173143Srwatson
128159248SrwatsonMODULE_DEPEND(wb, pci, 1, 1, 1);
129159248SrwatsonMODULE_DEPEND(wb, ether, 1, 1, 1);
130159248SrwatsonMODULE_DEPEND(wb, miibus, 1, 1, 1);
131159248Srwatson
132173143Srwatson/*
133173143Srwatson * Various supported device vendors/types and their names.
134173143Srwatson */
135173143Srwatsonstatic struct wb_type wb_devs[] = {
136159248Srwatson	{ WB_VENDORID, WB_DEVICEID_840F,
137159248Srwatson		"Winbond W89C840F 10/100BaseTX" },
138159248Srwatson	{ CP_VENDORID, CP_DEVICEID_RL100,
139159248Srwatson		"Compex RL100-ATX 10/100baseTX" },
140159248Srwatson	{ 0, 0, NULL }
141159248Srwatson};
142159248Srwatson
143159248Srwatsonstatic int wb_probe		(device_t);
144159248Srwatsonstatic int wb_attach		(device_t);
145159248Srwatsonstatic int wb_detach		(device_t);
146159248Srwatson
147159248Srwatsonstatic void wb_bfree		(void *addr, void *args);
148159248Srwatsonstatic int wb_newbuf		(struct wb_softc *,
149159248Srwatson					struct wb_chain_onefrag *,
150173143Srwatson					struct mbuf *);
151159248Srwatsonstatic int wb_encap		(struct wb_softc *, struct wb_chain *,
152173143Srwatson					struct mbuf *);
153173143Srwatson
154173143Srwatsonstatic void wb_rxeof		(struct wb_softc *);
155159248Srwatsonstatic void wb_rxeoc		(struct wb_softc *);
156159248Srwatsonstatic void wb_txeof		(struct wb_softc *);
157159248Srwatsonstatic void wb_txeoc		(struct wb_softc *);
158159248Srwatsonstatic void wb_intr		(void *);
159159248Srwatsonstatic void wb_tick		(void *);
160159248Srwatsonstatic void wb_start		(struct ifnet *);
161173143Srwatsonstatic int wb_ioctl		(struct ifnet *, u_long, caddr_t);
162159248Srwatsonstatic void wb_init		(void *);
163159248Srwatsonstatic void wb_stop		(struct wb_softc *);
164159248Srwatsonstatic void wb_watchdog		(struct ifnet *);
165159248Srwatsonstatic void wb_shutdown		(device_t);
166159248Srwatsonstatic int wb_ifmedia_upd	(struct ifnet *);
167173143Srwatsonstatic void wb_ifmedia_sts	(struct ifnet *, struct ifmediareq *);
168159248Srwatson
169159248Srwatsonstatic void wb_eeprom_putbyte	(struct wb_softc *, int);
170159248Srwatsonstatic void wb_eeprom_getword	(struct wb_softc *, int, u_int16_t *);
171159248Srwatsonstatic void wb_read_eeprom	(struct wb_softc *, caddr_t, int, int, int);
172173143Srwatsonstatic void wb_mii_sync		(struct wb_softc *);
173159248Srwatsonstatic void wb_mii_send		(struct wb_softc *, u_int32_t, int);
174159248Srwatsonstatic int wb_mii_readreg	(struct wb_softc *, struct wb_mii_frame *);
175173143Srwatsonstatic int wb_mii_writereg	(struct wb_softc *, struct wb_mii_frame *);
176159248Srwatson
177159248Srwatsonstatic void wb_setcfg		(struct wb_softc *, u_int32_t);
178173143Srwatsonstatic u_int8_t wb_calchash	(caddr_t);
179159248Srwatsonstatic void wb_setmulti		(struct wb_softc *);
180159248Srwatsonstatic void wb_reset		(struct wb_softc *);
181173143Srwatsonstatic void wb_fixmedia		(struct wb_softc *);
182173143Srwatsonstatic int wb_list_rx_init	(struct wb_softc *);
183159248Srwatsonstatic int wb_list_tx_init	(struct wb_softc *);
184159248Srwatson
185159248Srwatsonstatic int wb_miibus_readreg	(device_t, int, int);
186159248Srwatsonstatic int wb_miibus_writereg	(device_t, int, int, int);
187159248Srwatsonstatic void wb_miibus_statchg	(device_t);
188159248Srwatson
189159248Srwatson#ifdef WB_USEIOSPACE
190159248Srwatson#define WB_RES			SYS_RES_IOPORT
191159248Srwatson#define WB_RID			WB_PCI_LOIO
192159248Srwatson#else
193159248Srwatson#define WB_RES			SYS_RES_MEMORY
194159248Srwatson#define WB_RID			WB_PCI_LOMEM
195159248Srwatson#endif
196159248Srwatson
197159248Srwatsonstatic device_method_t wb_methods[] = {
198159248Srwatson	/* Device interface */
199159248Srwatson	DEVMETHOD(device_probe,		wb_probe),
200159248Srwatson	DEVMETHOD(device_attach,	wb_attach),
201159248Srwatson	DEVMETHOD(device_detach,	wb_detach),
202159248Srwatson	DEVMETHOD(device_shutdown,	wb_shutdown),
203159248Srwatson
204159248Srwatson	/* bus interface, for miibus */
205159248Srwatson	DEVMETHOD(bus_print_child,	bus_generic_print_child),
206159248Srwatson	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
207159248Srwatson
208159248Srwatson	/* MII interface */
209159248Srwatson	DEVMETHOD(miibus_readreg,	wb_miibus_readreg),
210159248Srwatson	DEVMETHOD(miibus_writereg,	wb_miibus_writereg),
211159248Srwatson	DEVMETHOD(miibus_statchg,	wb_miibus_statchg),
212159248Srwatson	{ 0, 0 }
213159248Srwatson};
214159248Srwatson
215159248Srwatsonstatic driver_t wb_driver = {
216159248Srwatson	"wb",
217159248Srwatson	wb_methods,
218159248Srwatson	sizeof(struct wb_softc)
219159248Srwatson};
220159248Srwatson
221159248Srwatsonstatic devclass_t wb_devclass;
222173143Srwatson
223159248SrwatsonDRIVER_MODULE(wb, pci, wb_driver, wb_devclass, 0, 0);
224159248SrwatsonDRIVER_MODULE(miibus, wb, miibus_driver, miibus_devclass, 0, 0);
225159248Srwatson
226159248Srwatson#define WB_SETBIT(sc, reg, x)				\
227159248Srwatson	CSR_WRITE_4(sc, reg,				\
228159248Srwatson		CSR_READ_4(sc, reg) | (x))
229159248Srwatson
230159248Srwatson#define WB_CLRBIT(sc, reg, x)				\
231159248Srwatson	CSR_WRITE_4(sc, reg,				\
232159248Srwatson		CSR_READ_4(sc, reg) & ~(x))
233159248Srwatson
234159248Srwatson#define SIO_SET(x)					\
235159248Srwatson	CSR_WRITE_4(sc, WB_SIO,				\
236159248Srwatson		CSR_READ_4(sc, WB_SIO) | (x))
237159248Srwatson
238159248Srwatson#define SIO_CLR(x)					\
239159248Srwatson	CSR_WRITE_4(sc, WB_SIO,				\
240159248Srwatson		CSR_READ_4(sc, WB_SIO) & ~(x))
241159248Srwatson
242159248Srwatson/*
243159248Srwatson * Send a read command and address to the EEPROM, check for ACK.
244159248Srwatson */
245159248Srwatsonstatic void
246159248Srwatsonwb_eeprom_putbyte(sc, addr)
247159248Srwatson	struct wb_softc		*sc;
248159248Srwatson	int			addr;
249159248Srwatson{
250173143Srwatson	register int		d, i;
251159248Srwatson
252159248Srwatson	d = addr | WB_EECMD_READ;
253159248Srwatson
254159248Srwatson	/*
255159248Srwatson	 * Feed in each bit and stobe the clock.
256159248Srwatson	 */
257159248Srwatson	for (i = 0x400; i; i >>= 1) {
258159248Srwatson		if (d & i) {
259159248Srwatson			SIO_SET(WB_SIO_EE_DATAIN);
260159248Srwatson		} else {
261159248Srwatson			SIO_CLR(WB_SIO_EE_DATAIN);
262173143Srwatson		}
263173143Srwatson		DELAY(100);
264159248Srwatson		SIO_SET(WB_SIO_EE_CLK);
265159248Srwatson		DELAY(150);
266159248Srwatson		SIO_CLR(WB_SIO_EE_CLK);
267159248Srwatson		DELAY(100);
268159248Srwatson	}
269173143Srwatson
270173143Srwatson	return;
271159248Srwatson}
272159248Srwatson
273159248Srwatson/*
274159248Srwatson * Read a word of data stored in the EEPROM at address 'addr.'
275159248Srwatson */
276173143Srwatsonstatic void
277173143Srwatsonwb_eeprom_getword(sc, addr, dest)
278159248Srwatson	struct wb_softc		*sc;
279159248Srwatson	int			addr;
280159248Srwatson	u_int16_t		*dest;
281159248Srwatson{
282159248Srwatson	register int		i;
283159248Srwatson	u_int16_t		word = 0;
284159248Srwatson
285159248Srwatson	/* Enter EEPROM access mode. */
286159248Srwatson	CSR_WRITE_4(sc, WB_SIO, WB_SIO_EESEL|WB_SIO_EE_CS);
287159248Srwatson
288159248Srwatson	/*
289173143Srwatson	 * Send address of word we want to read.
290159248Srwatson	 */
291159248Srwatson	wb_eeprom_putbyte(sc, addr);
292159248Srwatson
293159248Srwatson	CSR_WRITE_4(sc, WB_SIO, WB_SIO_EESEL|WB_SIO_EE_CS);
294159248Srwatson
295159248Srwatson	/*
296159248Srwatson	 * Start reading bits from EEPROM.
297159248Srwatson	 */
298159248Srwatson	for (i = 0x8000; i; i >>= 1) {
299159248Srwatson		SIO_SET(WB_SIO_EE_CLK);
300159248Srwatson		DELAY(100);
301159248Srwatson		if (CSR_READ_4(sc, WB_SIO) & WB_SIO_EE_DATAOUT)
302159248Srwatson			word |= i;
303159248Srwatson		SIO_CLR(WB_SIO_EE_CLK);
304159248Srwatson		DELAY(100);
305159248Srwatson	}
306159248Srwatson
307159248Srwatson	/* Turn off EEPROM access mode. */
308159248Srwatson	CSR_WRITE_4(sc, WB_SIO, 0);
309159248Srwatson
310159248Srwatson	*dest = word;
311159248Srwatson
312159248Srwatson	return;
313159248Srwatson}
314159248Srwatson
315159248Srwatson/*
316159248Srwatson * Read a sequence of words from the EEPROM.
317159248Srwatson */
318159248Srwatsonstatic void
319159248Srwatsonwb_read_eeprom(sc, dest, off, cnt, swap)
320159248Srwatson	struct wb_softc		*sc;
321159248Srwatson	caddr_t			dest;
322159248Srwatson	int			off;
323159248Srwatson	int			cnt;
324159248Srwatson	int			swap;
325159248Srwatson{
326159248Srwatson	int			i;
327159248Srwatson	u_int16_t		word = 0, *ptr;
328159248Srwatson
329159248Srwatson	for (i = 0; i < cnt; i++) {
330159248Srwatson		wb_eeprom_getword(sc, off + i, &word);
331159248Srwatson		ptr = (u_int16_t *)(dest + (i * 2));
332159248Srwatson		if (swap)
333159248Srwatson			*ptr = ntohs(word);
334159248Srwatson		else
335159248Srwatson			*ptr = word;
336159248Srwatson	}
337159248Srwatson
338159248Srwatson	return;
339159248Srwatson}
340159248Srwatson
341159248Srwatson/*
342159248Srwatson * Sync the PHYs by setting data bit and strobing the clock 32 times.
343159248Srwatson */
344159248Srwatsonstatic void
345159248Srwatsonwb_mii_sync(sc)
346159248Srwatson	struct wb_softc		*sc;
347159248Srwatson{
348159248Srwatson	register int		i;
349159248Srwatson
350159248Srwatson	SIO_SET(WB_SIO_MII_DIR|WB_SIO_MII_DATAIN);
351159248Srwatson
352159248Srwatson	for (i = 0; i < 32; i++) {
353159248Srwatson		SIO_SET(WB_SIO_MII_CLK);
354159248Srwatson		DELAY(1);
355159248Srwatson		SIO_CLR(WB_SIO_MII_CLK);
356159248Srwatson		DELAY(1);
357159248Srwatson	}
358159248Srwatson
359159248Srwatson	return;
360159248Srwatson}
361159248Srwatson
362159248Srwatson/*
363159248Srwatson * Clock a series of bits through the MII.
364159248Srwatson */
365159248Srwatsonstatic void
366159248Srwatsonwb_mii_send(sc, bits, cnt)
367159248Srwatson	struct wb_softc		*sc;
368159248Srwatson	u_int32_t		bits;
369159248Srwatson	int			cnt;
370159248Srwatson{
371159248Srwatson	int			i;
372159248Srwatson
373159248Srwatson	SIO_CLR(WB_SIO_MII_CLK);
374159248Srwatson
375159248Srwatson	for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
376159248Srwatson                if (bits & i) {
377159248Srwatson			SIO_SET(WB_SIO_MII_DATAIN);
378159248Srwatson                } else {
379159248Srwatson			SIO_CLR(WB_SIO_MII_DATAIN);
380159248Srwatson                }
381159248Srwatson		DELAY(1);
382173143Srwatson		SIO_CLR(WB_SIO_MII_CLK);
383173143Srwatson		DELAY(1);
384173143Srwatson		SIO_SET(WB_SIO_MII_CLK);
385173143Srwatson	}
386173143Srwatson}
387173143Srwatson
388173143Srwatson/*
389173143Srwatson * Read an PHY register through the MII.
390173143Srwatson */
391173143Srwatsonstatic int
392173143Srwatsonwb_mii_readreg(sc, frame)
393173143Srwatson	struct wb_softc		*sc;
394159248Srwatson	struct wb_mii_frame	*frame;
395159248Srwatson
396173143Srwatson{
397159248Srwatson	int			i, ack;
398159248Srwatson
399159248Srwatson	WB_LOCK(sc);
400159248Srwatson
401159248Srwatson	/*
402159248Srwatson	 * Set up frame for RX.
403159248Srwatson	 */
404159248Srwatson	frame->mii_stdelim = WB_MII_STARTDELIM;
405159248Srwatson	frame->mii_opcode = WB_MII_READOP;
406159248Srwatson	frame->mii_turnaround = 0;
407159248Srwatson	frame->mii_data = 0;
408159248Srwatson
409159248Srwatson	CSR_WRITE_4(sc, WB_SIO, 0);
410159248Srwatson
411159248Srwatson	/*
412173143Srwatson 	 * Turn on data xmit.
413159248Srwatson	 */
414159248Srwatson	SIO_SET(WB_SIO_MII_DIR);
415159248Srwatson
416159248Srwatson	wb_mii_sync(sc);
417159248Srwatson
418159248Srwatson	/*
419159248Srwatson	 * Send command/address info.
420159248Srwatson	 */
421159248Srwatson	wb_mii_send(sc, frame->mii_stdelim, 2);
422159248Srwatson	wb_mii_send(sc, frame->mii_opcode, 2);
423159248Srwatson	wb_mii_send(sc, frame->mii_phyaddr, 5);
424159248Srwatson	wb_mii_send(sc, frame->mii_regaddr, 5);
425159248Srwatson
426159248Srwatson	/* Idle bit */
427159248Srwatson	SIO_CLR((WB_SIO_MII_CLK|WB_SIO_MII_DATAIN));
428159248Srwatson	DELAY(1);
429159248Srwatson	SIO_SET(WB_SIO_MII_CLK);
430159248Srwatson	DELAY(1);
431159248Srwatson
432159248Srwatson	/* Turn off xmit. */
433159248Srwatson	SIO_CLR(WB_SIO_MII_DIR);
434159248Srwatson	/* Check for ack */
435159248Srwatson	SIO_CLR(WB_SIO_MII_CLK);
436159248Srwatson	DELAY(1);
437159248Srwatson	ack = CSR_READ_4(sc, WB_SIO) & WB_SIO_MII_DATAOUT;
438159248Srwatson	SIO_SET(WB_SIO_MII_CLK);
439159248Srwatson	DELAY(1);
440159248Srwatson	SIO_CLR(WB_SIO_MII_CLK);
441159248Srwatson	DELAY(1);
442159248Srwatson	SIO_SET(WB_SIO_MII_CLK);
443159248Srwatson	DELAY(1);
444159248Srwatson
445159248Srwatson	/*
446159248Srwatson	 * Now try reading data bits. If the ack failed, we still
447173143Srwatson	 * need to clock through 16 cycles to keep the PHY(s) in sync.
448159248Srwatson	 */
449159248Srwatson	if (ack) {
450159248Srwatson		for(i = 0; i < 16; i++) {
451159248Srwatson			SIO_CLR(WB_SIO_MII_CLK);
452159248Srwatson			DELAY(1);
453159248Srwatson			SIO_SET(WB_SIO_MII_CLK);
454159248Srwatson			DELAY(1);
455159248Srwatson		}
456159248Srwatson		goto fail;
457159248Srwatson	}
458159248Srwatson
459159248Srwatson	for (i = 0x8000; i; i >>= 1) {
460159248Srwatson		SIO_CLR(WB_SIO_MII_CLK);
461173143Srwatson		DELAY(1);
462173143Srwatson		if (!ack) {
463159248Srwatson			if (CSR_READ_4(sc, WB_SIO) & WB_SIO_MII_DATAOUT)
464159248Srwatson				frame->mii_data |= i;
465173143Srwatson			DELAY(1);
466173143Srwatson		}
467159248Srwatson		SIO_SET(WB_SIO_MII_CLK);
468159248Srwatson		DELAY(1);
469159248Srwatson	}
470159248Srwatson
471173143Srwatsonfail:
472173143Srwatson
473173143Srwatson	SIO_CLR(WB_SIO_MII_CLK);
474173143Srwatson	DELAY(1);
475159248Srwatson	SIO_SET(WB_SIO_MII_CLK);
476159248Srwatson	DELAY(1);
477159248Srwatson
478159248Srwatson	WB_UNLOCK(sc);
479159248Srwatson
480159248Srwatson	if (ack)
481159248Srwatson		return(1);
482159248Srwatson	return(0);
483159248Srwatson}
484159248Srwatson
485159248Srwatson/*
486159248Srwatson * Write to a PHY register through the MII.
487159248Srwatson */
488159248Srwatsonstatic int
489159248Srwatsonwb_mii_writereg(sc, frame)
490159248Srwatson	struct wb_softc		*sc;
491159248Srwatson	struct wb_mii_frame	*frame;
492159248Srwatson
493159248Srwatson{
494159248Srwatson	WB_LOCK(sc);
495173143Srwatson
496159248Srwatson	/*
497159248Srwatson	 * Set up frame for TX.
498159248Srwatson	 */
499173143Srwatson
500173143Srwatson	frame->mii_stdelim = WB_MII_STARTDELIM;
501159248Srwatson	frame->mii_opcode = WB_MII_WRITEOP;
502159248Srwatson	frame->mii_turnaround = WB_MII_TURNAROUND;
503159248Srwatson
504159248Srwatson	/*
505173143Srwatson 	 * Turn on data output.
506173143Srwatson	 */
507173143Srwatson	SIO_SET(WB_SIO_MII_DIR);
508173143Srwatson
509173143Srwatson	wb_mii_sync(sc);
510159248Srwatson
511159248Srwatson	wb_mii_send(sc, frame->mii_stdelim, 2);
512159248Srwatson	wb_mii_send(sc, frame->mii_opcode, 2);
513173143Srwatson	wb_mii_send(sc, frame->mii_phyaddr, 5);
514173143Srwatson	wb_mii_send(sc, frame->mii_regaddr, 5);
515159248Srwatson	wb_mii_send(sc, frame->mii_turnaround, 2);
516159248Srwatson	wb_mii_send(sc, frame->mii_data, 16);
517159248Srwatson
518159248Srwatson	/* Idle bit. */
519	SIO_SET(WB_SIO_MII_CLK);
520	DELAY(1);
521	SIO_CLR(WB_SIO_MII_CLK);
522	DELAY(1);
523
524	/*
525	 * Turn off xmit.
526	 */
527	SIO_CLR(WB_SIO_MII_DIR);
528
529	WB_UNLOCK(sc);
530
531	return(0);
532}
533
534static int
535wb_miibus_readreg(dev, phy, reg)
536	device_t		dev;
537	int			phy, reg;
538{
539	struct wb_softc		*sc;
540	struct wb_mii_frame	frame;
541
542	sc = device_get_softc(dev);
543
544	bzero((char *)&frame, sizeof(frame));
545
546	frame.mii_phyaddr = phy;
547	frame.mii_regaddr = reg;
548	wb_mii_readreg(sc, &frame);
549
550	return(frame.mii_data);
551}
552
553static int
554wb_miibus_writereg(dev, phy, reg, data)
555	device_t		dev;
556	int			phy, reg, data;
557{
558	struct wb_softc		*sc;
559	struct wb_mii_frame	frame;
560
561	sc = device_get_softc(dev);
562
563	bzero((char *)&frame, sizeof(frame));
564
565	frame.mii_phyaddr = phy;
566	frame.mii_regaddr = reg;
567	frame.mii_data = data;
568
569	wb_mii_writereg(sc, &frame);
570
571	return(0);
572}
573
574static void
575wb_miibus_statchg(dev)
576	device_t		dev;
577{
578	struct wb_softc		*sc;
579	struct mii_data		*mii;
580
581	sc = device_get_softc(dev);
582	WB_LOCK(sc);
583	mii = device_get_softc(sc->wb_miibus);
584	wb_setcfg(sc, mii->mii_media_active);
585	WB_UNLOCK(sc);
586
587	return;
588}
589
590static u_int8_t wb_calchash(addr)
591	caddr_t			addr;
592{
593	u_int32_t		crc, carry;
594	int			i, j;
595	u_int8_t		c;
596
597	/* Compute CRC for the address value. */
598	crc = 0xFFFFFFFF; /* initial value */
599
600	for (i = 0; i < 6; i++) {
601		c = *(addr + i);
602		for (j = 0; j < 8; j++) {
603			carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01);
604			crc <<= 1;
605			c >>= 1;
606			if (carry)
607				crc = (crc ^ 0x04c11db6) | carry;
608		}
609	}
610
611	/*
612	 * return the filter bit position
613	 * Note: I arrived at the following nonsense
614	 * through experimentation. It's not the usual way to
615	 * generate the bit position but it's the only thing
616	 * I could come up with that works.
617	 */
618	return(~(crc >> 26) & 0x0000003F);
619}
620
621/*
622 * Program the 64-bit multicast hash filter.
623 */
624static void
625wb_setmulti(sc)
626	struct wb_softc		*sc;
627{
628	struct ifnet		*ifp;
629	int			h = 0;
630	u_int32_t		hashes[2] = { 0, 0 };
631	struct ifmultiaddr	*ifma;
632	u_int32_t		rxfilt;
633	int			mcnt = 0;
634
635	ifp = &sc->arpcom.ac_if;
636
637	rxfilt = CSR_READ_4(sc, WB_NETCFG);
638
639	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
640		rxfilt |= WB_NETCFG_RX_MULTI;
641		CSR_WRITE_4(sc, WB_NETCFG, rxfilt);
642		CSR_WRITE_4(sc, WB_MAR0, 0xFFFFFFFF);
643		CSR_WRITE_4(sc, WB_MAR1, 0xFFFFFFFF);
644		return;
645	}
646
647	/* first, zot all the existing hash bits */
648	CSR_WRITE_4(sc, WB_MAR0, 0);
649	CSR_WRITE_4(sc, WB_MAR1, 0);
650
651	/* now program new ones */
652	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
653		if (ifma->ifma_addr->sa_family != AF_LINK)
654			continue;
655		h = wb_calchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
656		if (h < 32)
657			hashes[0] |= (1 << h);
658		else
659			hashes[1] |= (1 << (h - 32));
660		mcnt++;
661	}
662
663	if (mcnt)
664		rxfilt |= WB_NETCFG_RX_MULTI;
665	else
666		rxfilt &= ~WB_NETCFG_RX_MULTI;
667
668	CSR_WRITE_4(sc, WB_MAR0, hashes[0]);
669	CSR_WRITE_4(sc, WB_MAR1, hashes[1]);
670	CSR_WRITE_4(sc, WB_NETCFG, rxfilt);
671
672	return;
673}
674
675/*
676 * The Winbond manual states that in order to fiddle with the
677 * 'full-duplex' and '100Mbps' bits in the netconfig register, we
678 * first have to put the transmit and/or receive logic in the idle state.
679 */
680static void
681wb_setcfg(sc, media)
682	struct wb_softc		*sc;
683	u_int32_t		media;
684{
685	int			i, restart = 0;
686
687	if (CSR_READ_4(sc, WB_NETCFG) & (WB_NETCFG_TX_ON|WB_NETCFG_RX_ON)) {
688		restart = 1;
689		WB_CLRBIT(sc, WB_NETCFG, (WB_NETCFG_TX_ON|WB_NETCFG_RX_ON));
690
691		for (i = 0; i < WB_TIMEOUT; i++) {
692			DELAY(10);
693			if ((CSR_READ_4(sc, WB_ISR) & WB_ISR_TX_IDLE) &&
694				(CSR_READ_4(sc, WB_ISR) & WB_ISR_RX_IDLE))
695				break;
696		}
697
698		if (i == WB_TIMEOUT)
699			printf("wb%d: failed to force tx and "
700				"rx to idle state\n", sc->wb_unit);
701	}
702
703	if (IFM_SUBTYPE(media) == IFM_10_T)
704		WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_100MBPS);
705	else
706		WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_100MBPS);
707
708	if ((media & IFM_GMASK) == IFM_FDX)
709		WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_FULLDUPLEX);
710	else
711		WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_FULLDUPLEX);
712
713	if (restart)
714		WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON|WB_NETCFG_RX_ON);
715
716	return;
717}
718
719static void
720wb_reset(sc)
721	struct wb_softc		*sc;
722{
723	register int		i;
724	struct mii_data		*mii;
725
726	CSR_WRITE_4(sc, WB_NETCFG, 0);
727	CSR_WRITE_4(sc, WB_BUSCTL, 0);
728	CSR_WRITE_4(sc, WB_TXADDR, 0);
729	CSR_WRITE_4(sc, WB_RXADDR, 0);
730
731	WB_SETBIT(sc, WB_BUSCTL, WB_BUSCTL_RESET);
732	WB_SETBIT(sc, WB_BUSCTL, WB_BUSCTL_RESET);
733
734	for (i = 0; i < WB_TIMEOUT; i++) {
735		DELAY(10);
736		if (!(CSR_READ_4(sc, WB_BUSCTL) & WB_BUSCTL_RESET))
737			break;
738	}
739	if (i == WB_TIMEOUT)
740		printf("wb%d: reset never completed!\n", sc->wb_unit);
741
742	/* Wait a little while for the chip to get its brains in order. */
743	DELAY(1000);
744
745	if (sc->wb_miibus == NULL)
746		return;
747
748	mii = device_get_softc(sc->wb_miibus);
749	if (mii == NULL)
750		return;
751
752        if (mii->mii_instance) {
753                struct mii_softc        *miisc;
754                LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
755                        mii_phy_reset(miisc);
756        }
757
758        return;
759}
760
761static void
762wb_fixmedia(sc)
763	struct wb_softc		*sc;
764{
765	struct mii_data		*mii = NULL;
766	struct ifnet		*ifp;
767	u_int32_t		media;
768
769	if (sc->wb_miibus == NULL)
770		return;
771
772	mii = device_get_softc(sc->wb_miibus);
773	ifp = &sc->arpcom.ac_if;
774
775	mii_pollstat(mii);
776	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T) {
777		media = mii->mii_media_active & ~IFM_10_T;
778		media |= IFM_100_TX;
779	} else if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
780		media = mii->mii_media_active & ~IFM_100_TX;
781		media |= IFM_10_T;
782	} else
783		return;
784
785	ifmedia_set(&mii->mii_media, media);
786
787	return;
788}
789
790/*
791 * Probe for a Winbond chip. Check the PCI vendor and device
792 * IDs against our list and return a device name if we find a match.
793 */
794static int
795wb_probe(dev)
796	device_t		dev;
797{
798	struct wb_type		*t;
799
800	t = wb_devs;
801
802	while(t->wb_name != NULL) {
803		if ((pci_get_vendor(dev) == t->wb_vid) &&
804		    (pci_get_device(dev) == t->wb_did)) {
805			device_set_desc(dev, t->wb_name);
806			return(0);
807		}
808		t++;
809	}
810
811	return(ENXIO);
812}
813
814/*
815 * Attach the interface. Allocate softc structures, do ifmedia
816 * setup and ethernet/BPF attach.
817 */
818static int
819wb_attach(dev)
820	device_t		dev;
821{
822	u_char			eaddr[ETHER_ADDR_LEN];
823	struct wb_softc		*sc;
824	struct ifnet		*ifp;
825	int			unit, error = 0, rid;
826
827	sc = device_get_softc(dev);
828	unit = device_get_unit(dev);
829
830	mtx_init(&sc->wb_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
831	    MTX_DEF | MTX_RECURSE);
832
833	/*
834	 * Handle power management nonsense.
835	 */
836
837	if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
838		u_int32_t		iobase, membase, irq;
839
840		/* Save important PCI config data. */
841		iobase = pci_read_config(dev, WB_PCI_LOIO, 4);
842		membase = pci_read_config(dev, WB_PCI_LOMEM, 4);
843		irq = pci_read_config(dev, WB_PCI_INTLINE, 4);
844
845		/* Reset the power state. */
846		printf("wb%d: chip is in D%d power mode "
847		    "-- setting to D0\n", unit,
848		    pci_get_powerstate(dev));
849		pci_set_powerstate(dev, PCI_POWERSTATE_D0);
850
851		/* Restore PCI config data. */
852		pci_write_config(dev, WB_PCI_LOIO, iobase, 4);
853		pci_write_config(dev, WB_PCI_LOMEM, membase, 4);
854		pci_write_config(dev, WB_PCI_INTLINE, irq, 4);
855	}
856
857	/*
858	 * Map control/status registers.
859	 */
860	pci_enable_busmaster(dev);
861
862	rid = WB_RID;
863	sc->wb_res = bus_alloc_resource(dev, WB_RES, &rid,
864	    0, ~0, 1, RF_ACTIVE);
865
866	if (sc->wb_res == NULL) {
867		printf("wb%d: couldn't map ports/memory\n", unit);
868		error = ENXIO;
869		goto fail;
870	}
871
872	sc->wb_btag = rman_get_bustag(sc->wb_res);
873	sc->wb_bhandle = rman_get_bushandle(sc->wb_res);
874
875	/* Allocate interrupt */
876	rid = 0;
877	sc->wb_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
878	    RF_SHAREABLE | RF_ACTIVE);
879
880	if (sc->wb_irq == NULL) {
881		printf("wb%d: couldn't map interrupt\n", unit);
882		error = ENXIO;
883		goto fail;
884	}
885
886	/* Save the cache line size. */
887	sc->wb_cachesize = pci_read_config(dev, WB_PCI_CACHELEN, 4) & 0xFF;
888
889	/* Reset the adapter. */
890	wb_reset(sc);
891
892	/*
893	 * Get station address from the EEPROM.
894	 */
895	wb_read_eeprom(sc, (caddr_t)&eaddr, 0, 3, 0);
896
897	/*
898	 * A Winbond chip was detected. Inform the world.
899	 */
900	printf("wb%d: Ethernet address: %6D\n", unit, eaddr, ":");
901
902	sc->wb_unit = unit;
903	bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
904
905	sc->wb_ldata = contigmalloc(sizeof(struct wb_list_data) + 8, M_DEVBUF,
906	    M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
907
908	if (sc->wb_ldata == NULL) {
909		printf("wb%d: no memory for list buffers!\n", unit);
910		error = ENXIO;
911		goto fail;
912	}
913
914	bzero(sc->wb_ldata, sizeof(struct wb_list_data));
915
916	ifp = &sc->arpcom.ac_if;
917	ifp->if_softc = sc;
918	ifp->if_unit = unit;
919	ifp->if_name = "wb";
920	ifp->if_mtu = ETHERMTU;
921	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
922	ifp->if_ioctl = wb_ioctl;
923	ifp->if_output = ether_output;
924	ifp->if_start = wb_start;
925	ifp->if_watchdog = wb_watchdog;
926	ifp->if_init = wb_init;
927	ifp->if_baudrate = 10000000;
928	ifp->if_snd.ifq_maxlen = WB_TX_LIST_CNT - 1;
929
930	/*
931	 * Do MII setup.
932	 */
933	if (mii_phy_probe(dev, &sc->wb_miibus,
934	    wb_ifmedia_upd, wb_ifmedia_sts)) {
935		error = ENXIO;
936		goto fail;
937	}
938
939	/*
940	 * Call MI attach routine.
941	 */
942	ether_ifattach(ifp, eaddr);
943
944	error = bus_setup_intr(dev, sc->wb_irq, INTR_TYPE_NET,
945	    wb_intr, sc, &sc->wb_intrhand);
946
947	if (error) {
948		printf("wb%d: couldn't set up irq\n", unit);
949		goto fail;
950	}
951
952fail:
953	if (error)
954		wb_detach(dev);
955
956	return(error);
957}
958
959static int
960wb_detach(dev)
961	device_t		dev;
962{
963	struct wb_softc		*sc;
964	struct ifnet		*ifp;
965
966	sc = device_get_softc(dev);
967	KASSERT(mtx_initialized(&sc->wb_mtx), ("wb mutex not initialized"));
968	WB_LOCK(sc);
969	ifp = &sc->arpcom.ac_if;
970
971	/* Delete any miibus and phy devices attached to this interface */
972	if (device_is_alive(dev)) {
973		if (bus_child_present(dev))
974			wb_stop(sc);
975		ether_ifdetach(ifp);
976		device_delete_child(dev, sc->wb_miibus);
977		bus_generic_detach(dev);
978	}
979
980	if (sc->wb_intrhand)
981		bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand);
982	if (sc->wb_irq)
983		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
984	if (sc->wb_res)
985		bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
986
987	if (sc->wb_ldata) {
988		contigfree(sc->wb_ldata, sizeof(struct wb_list_data) + 8,
989		    M_DEVBUF);
990	}
991
992	WB_UNLOCK(sc);
993	mtx_destroy(&sc->wb_mtx);
994
995	return(0);
996}
997
998/*
999 * Initialize the transmit descriptors.
1000 */
1001static int
1002wb_list_tx_init(sc)
1003	struct wb_softc		*sc;
1004{
1005	struct wb_chain_data	*cd;
1006	struct wb_list_data	*ld;
1007	int			i;
1008
1009	cd = &sc->wb_cdata;
1010	ld = sc->wb_ldata;
1011
1012	for (i = 0; i < WB_TX_LIST_CNT; i++) {
1013		cd->wb_tx_chain[i].wb_ptr = &ld->wb_tx_list[i];
1014		if (i == (WB_TX_LIST_CNT - 1)) {
1015			cd->wb_tx_chain[i].wb_nextdesc =
1016				&cd->wb_tx_chain[0];
1017		} else {
1018			cd->wb_tx_chain[i].wb_nextdesc =
1019				&cd->wb_tx_chain[i + 1];
1020		}
1021	}
1022
1023	cd->wb_tx_free = &cd->wb_tx_chain[0];
1024	cd->wb_tx_tail = cd->wb_tx_head = NULL;
1025
1026	return(0);
1027}
1028
1029
1030/*
1031 * Initialize the RX descriptors and allocate mbufs for them. Note that
1032 * we arrange the descriptors in a closed ring, so that the last descriptor
1033 * points back to the first.
1034 */
1035static int
1036wb_list_rx_init(sc)
1037	struct wb_softc		*sc;
1038{
1039	struct wb_chain_data	*cd;
1040	struct wb_list_data	*ld;
1041	int			i;
1042
1043	cd = &sc->wb_cdata;
1044	ld = sc->wb_ldata;
1045
1046	for (i = 0; i < WB_RX_LIST_CNT; i++) {
1047		cd->wb_rx_chain[i].wb_ptr =
1048			(struct wb_desc *)&ld->wb_rx_list[i];
1049		cd->wb_rx_chain[i].wb_buf = (void *)&ld->wb_rxbufs[i];
1050		if (wb_newbuf(sc, &cd->wb_rx_chain[i], NULL) == ENOBUFS)
1051			return(ENOBUFS);
1052		if (i == (WB_RX_LIST_CNT - 1)) {
1053			cd->wb_rx_chain[i].wb_nextdesc = &cd->wb_rx_chain[0];
1054			ld->wb_rx_list[i].wb_next =
1055					vtophys(&ld->wb_rx_list[0]);
1056		} else {
1057			cd->wb_rx_chain[i].wb_nextdesc =
1058					&cd->wb_rx_chain[i + 1];
1059			ld->wb_rx_list[i].wb_next =
1060					vtophys(&ld->wb_rx_list[i + 1]);
1061		}
1062	}
1063
1064	cd->wb_rx_head = &cd->wb_rx_chain[0];
1065
1066	return(0);
1067}
1068
1069static void
1070wb_bfree(buf, args)
1071	void			*buf;
1072	void			*args;
1073{
1074	return;
1075}
1076
1077/*
1078 * Initialize an RX descriptor and attach an MBUF cluster.
1079 */
1080static int
1081wb_newbuf(sc, c, m)
1082	struct wb_softc		*sc;
1083	struct wb_chain_onefrag	*c;
1084	struct mbuf		*m;
1085{
1086	struct mbuf		*m_new = NULL;
1087
1088	if (m == NULL) {
1089		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1090		if (m_new == NULL)
1091			return(ENOBUFS);
1092		m_new->m_data = c->wb_buf;
1093		m_new->m_pkthdr.len = m_new->m_len = WB_BUFBYTES;
1094		MEXTADD(m_new, c->wb_buf, WB_BUFBYTES, wb_bfree, NULL, 0,
1095		    EXT_NET_DRV);
1096	} else {
1097		m_new = m;
1098		m_new->m_len = m_new->m_pkthdr.len = WB_BUFBYTES;
1099		m_new->m_data = m_new->m_ext.ext_buf;
1100	}
1101
1102	m_adj(m_new, sizeof(u_int64_t));
1103
1104	c->wb_mbuf = m_new;
1105	c->wb_ptr->wb_data = vtophys(mtod(m_new, caddr_t));
1106	c->wb_ptr->wb_ctl = WB_RXCTL_RLINK | 1536;
1107	c->wb_ptr->wb_status = WB_RXSTAT;
1108
1109	return(0);
1110}
1111
1112/*
1113 * A frame has been uploaded: pass the resulting mbuf chain up to
1114 * the higher level protocols.
1115 */
1116static void
1117wb_rxeof(sc)
1118	struct wb_softc		*sc;
1119{
1120        struct mbuf		*m = NULL;
1121        struct ifnet		*ifp;
1122	struct wb_chain_onefrag	*cur_rx;
1123	int			total_len = 0;
1124	u_int32_t		rxstat;
1125
1126	ifp = &sc->arpcom.ac_if;
1127
1128	while(!((rxstat = sc->wb_cdata.wb_rx_head->wb_ptr->wb_status) &
1129							WB_RXSTAT_OWN)) {
1130		struct mbuf		*m0 = NULL;
1131
1132		cur_rx = sc->wb_cdata.wb_rx_head;
1133		sc->wb_cdata.wb_rx_head = cur_rx->wb_nextdesc;
1134
1135		m = cur_rx->wb_mbuf;
1136
1137		if ((rxstat & WB_RXSTAT_MIIERR) ||
1138		    (WB_RXBYTES(cur_rx->wb_ptr->wb_status) < WB_MIN_FRAMELEN) ||
1139		    (WB_RXBYTES(cur_rx->wb_ptr->wb_status) > 1536) ||
1140		    !(rxstat & WB_RXSTAT_LASTFRAG) ||
1141		    !(rxstat & WB_RXSTAT_RXCMP)) {
1142			ifp->if_ierrors++;
1143			wb_newbuf(sc, cur_rx, m);
1144			printf("wb%x: receiver babbling: possible chip "
1145				"bug, forcing reset\n", sc->wb_unit);
1146			wb_fixmedia(sc);
1147			wb_reset(sc);
1148			wb_init(sc);
1149			return;
1150		}
1151
1152		if (rxstat & WB_RXSTAT_RXERR) {
1153			ifp->if_ierrors++;
1154			wb_newbuf(sc, cur_rx, m);
1155			break;
1156		}
1157
1158		/* No errors; receive the packet. */
1159		total_len = WB_RXBYTES(cur_rx->wb_ptr->wb_status);
1160
1161		/*
1162		 * XXX The Winbond chip includes the CRC with every
1163		 * received frame, and there's no way to turn this
1164		 * behavior off (at least, I can't find anything in
1165	 	 * the manual that explains how to do it) so we have
1166		 * to trim off the CRC manually.
1167		 */
1168		total_len -= ETHER_CRC_LEN;
1169
1170		m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN, ifp,
1171		    NULL);
1172		wb_newbuf(sc, cur_rx, m);
1173		if (m0 == NULL) {
1174			ifp->if_ierrors++;
1175			break;
1176		}
1177		m = m0;
1178
1179		ifp->if_ipackets++;
1180		(*ifp->if_input)(ifp, m);
1181	}
1182}
1183
1184static void
1185wb_rxeoc(sc)
1186	struct wb_softc		*sc;
1187{
1188	wb_rxeof(sc);
1189
1190	WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_RX_ON);
1191	CSR_WRITE_4(sc, WB_RXADDR, vtophys(&sc->wb_ldata->wb_rx_list[0]));
1192	WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_RX_ON);
1193	if (CSR_READ_4(sc, WB_ISR) & WB_RXSTATE_SUSPEND)
1194		CSR_WRITE_4(sc, WB_RXSTART, 0xFFFFFFFF);
1195
1196	return;
1197}
1198
1199/*
1200 * A frame was downloaded to the chip. It's safe for us to clean up
1201 * the list buffers.
1202 */
1203static void
1204wb_txeof(sc)
1205	struct wb_softc		*sc;
1206{
1207	struct wb_chain		*cur_tx;
1208	struct ifnet		*ifp;
1209
1210	ifp = &sc->arpcom.ac_if;
1211
1212	/* Clear the timeout timer. */
1213	ifp->if_timer = 0;
1214
1215	if (sc->wb_cdata.wb_tx_head == NULL)
1216		return;
1217
1218	/*
1219	 * Go through our tx list and free mbufs for those
1220	 * frames that have been transmitted.
1221	 */
1222	while(sc->wb_cdata.wb_tx_head->wb_mbuf != NULL) {
1223		u_int32_t		txstat;
1224
1225		cur_tx = sc->wb_cdata.wb_tx_head;
1226		txstat = WB_TXSTATUS(cur_tx);
1227
1228		if ((txstat & WB_TXSTAT_OWN) || txstat == WB_UNSENT)
1229			break;
1230
1231		if (txstat & WB_TXSTAT_TXERR) {
1232			ifp->if_oerrors++;
1233			if (txstat & WB_TXSTAT_ABORT)
1234				ifp->if_collisions++;
1235			if (txstat & WB_TXSTAT_LATECOLL)
1236				ifp->if_collisions++;
1237		}
1238
1239		ifp->if_collisions += (txstat & WB_TXSTAT_COLLCNT) >> 3;
1240
1241		ifp->if_opackets++;
1242		m_freem(cur_tx->wb_mbuf);
1243		cur_tx->wb_mbuf = NULL;
1244
1245		if (sc->wb_cdata.wb_tx_head == sc->wb_cdata.wb_tx_tail) {
1246			sc->wb_cdata.wb_tx_head = NULL;
1247			sc->wb_cdata.wb_tx_tail = NULL;
1248			break;
1249		}
1250
1251		sc->wb_cdata.wb_tx_head = cur_tx->wb_nextdesc;
1252	}
1253
1254	return;
1255}
1256
1257/*
1258 * TX 'end of channel' interrupt handler.
1259 */
1260static void
1261wb_txeoc(sc)
1262	struct wb_softc		*sc;
1263{
1264	struct ifnet		*ifp;
1265
1266	ifp = &sc->arpcom.ac_if;
1267
1268	ifp->if_timer = 0;
1269
1270	if (sc->wb_cdata.wb_tx_head == NULL) {
1271		ifp->if_flags &= ~IFF_OACTIVE;
1272		sc->wb_cdata.wb_tx_tail = NULL;
1273	} else {
1274		if (WB_TXOWN(sc->wb_cdata.wb_tx_head) == WB_UNSENT) {
1275			WB_TXOWN(sc->wb_cdata.wb_tx_head) = WB_TXSTAT_OWN;
1276			ifp->if_timer = 5;
1277			CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF);
1278		}
1279	}
1280
1281	return;
1282}
1283
1284static void
1285wb_intr(arg)
1286	void			*arg;
1287{
1288	struct wb_softc		*sc;
1289	struct ifnet		*ifp;
1290	u_int32_t		status;
1291
1292	sc = arg;
1293	WB_LOCK(sc);
1294	ifp = &sc->arpcom.ac_if;
1295
1296	if (!(ifp->if_flags & IFF_UP)) {
1297		WB_UNLOCK(sc);
1298		return;
1299	}
1300
1301	/* Disable interrupts. */
1302	CSR_WRITE_4(sc, WB_IMR, 0x00000000);
1303
1304	for (;;) {
1305
1306		status = CSR_READ_4(sc, WB_ISR);
1307		if (status)
1308			CSR_WRITE_4(sc, WB_ISR, status);
1309
1310		if ((status & WB_INTRS) == 0)
1311			break;
1312
1313		if ((status & WB_ISR_RX_NOBUF) || (status & WB_ISR_RX_ERR)) {
1314			ifp->if_ierrors++;
1315			wb_reset(sc);
1316			if (status & WB_ISR_RX_ERR)
1317				wb_fixmedia(sc);
1318			wb_init(sc);
1319			continue;
1320		}
1321
1322		if (status & WB_ISR_RX_OK)
1323			wb_rxeof(sc);
1324
1325		if (status & WB_ISR_RX_IDLE)
1326			wb_rxeoc(sc);
1327
1328		if (status & WB_ISR_TX_OK)
1329			wb_txeof(sc);
1330
1331		if (status & WB_ISR_TX_NOBUF)
1332			wb_txeoc(sc);
1333
1334		if (status & WB_ISR_TX_IDLE) {
1335			wb_txeof(sc);
1336			if (sc->wb_cdata.wb_tx_head != NULL) {
1337				WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
1338				CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF);
1339			}
1340		}
1341
1342		if (status & WB_ISR_TX_UNDERRUN) {
1343			ifp->if_oerrors++;
1344			wb_txeof(sc);
1345			WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
1346			/* Jack up TX threshold */
1347			sc->wb_txthresh += WB_TXTHRESH_CHUNK;
1348			WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_THRESH);
1349			WB_SETBIT(sc, WB_NETCFG, WB_TXTHRESH(sc->wb_txthresh));
1350			WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
1351		}
1352
1353		if (status & WB_ISR_BUS_ERR) {
1354			wb_reset(sc);
1355			wb_init(sc);
1356		}
1357
1358	}
1359
1360	/* Re-enable interrupts. */
1361	CSR_WRITE_4(sc, WB_IMR, WB_INTRS);
1362
1363	if (ifp->if_snd.ifq_head != NULL) {
1364		wb_start(ifp);
1365	}
1366
1367	WB_UNLOCK(sc);
1368
1369	return;
1370}
1371
1372static void
1373wb_tick(xsc)
1374	void			*xsc;
1375{
1376	struct wb_softc		*sc;
1377	struct mii_data		*mii;
1378
1379	sc = xsc;
1380	WB_LOCK(sc);
1381	mii = device_get_softc(sc->wb_miibus);
1382
1383	mii_tick(mii);
1384
1385	sc->wb_stat_ch = timeout(wb_tick, sc, hz);
1386
1387	WB_UNLOCK(sc);
1388
1389	return;
1390}
1391
1392/*
1393 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
1394 * pointers to the fragment pointers.
1395 */
1396static int
1397wb_encap(sc, c, m_head)
1398	struct wb_softc		*sc;
1399	struct wb_chain		*c;
1400	struct mbuf		*m_head;
1401{
1402	int			frag = 0;
1403	struct wb_desc		*f = NULL;
1404	int			total_len;
1405	struct mbuf		*m;
1406
1407	/*
1408 	 * Start packing the mbufs in this chain into
1409	 * the fragment pointers. Stop when we run out
1410 	 * of fragments or hit the end of the mbuf chain.
1411	 */
1412	m = m_head;
1413	total_len = 0;
1414
1415	for (m = m_head, frag = 0; m != NULL; m = m->m_next) {
1416		if (m->m_len != 0) {
1417			if (frag == WB_MAXFRAGS)
1418				break;
1419			total_len += m->m_len;
1420			f = &c->wb_ptr->wb_frag[frag];
1421			f->wb_ctl = WB_TXCTL_TLINK | m->m_len;
1422			if (frag == 0) {
1423				f->wb_ctl |= WB_TXCTL_FIRSTFRAG;
1424				f->wb_status = 0;
1425			} else
1426				f->wb_status = WB_TXSTAT_OWN;
1427			f->wb_next = vtophys(&c->wb_ptr->wb_frag[frag + 1]);
1428			f->wb_data = vtophys(mtod(m, vm_offset_t));
1429			frag++;
1430		}
1431	}
1432
1433	/*
1434	 * Handle special case: we used up all 16 fragments,
1435	 * but we have more mbufs left in the chain. Copy the
1436	 * data into an mbuf cluster. Note that we don't
1437	 * bother clearing the values in the other fragment
1438	 * pointers/counters; it wouldn't gain us anything,
1439	 * and would waste cycles.
1440	 */
1441	if (m != NULL) {
1442		struct mbuf		*m_new = NULL;
1443
1444		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1445		if (m_new == NULL)
1446			return(1);
1447		if (m_head->m_pkthdr.len > MHLEN) {
1448			MCLGET(m_new, M_DONTWAIT);
1449			if (!(m_new->m_flags & M_EXT)) {
1450				m_freem(m_new);
1451				return(1);
1452			}
1453		}
1454		m_copydata(m_head, 0, m_head->m_pkthdr.len,
1455					mtod(m_new, caddr_t));
1456		m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len;
1457		m_freem(m_head);
1458		m_head = m_new;
1459		f = &c->wb_ptr->wb_frag[0];
1460		f->wb_status = 0;
1461		f->wb_data = vtophys(mtod(m_new, caddr_t));
1462		f->wb_ctl = total_len = m_new->m_len;
1463		f->wb_ctl |= WB_TXCTL_TLINK|WB_TXCTL_FIRSTFRAG;
1464		frag = 1;
1465	}
1466
1467	if (total_len < WB_MIN_FRAMELEN) {
1468		f = &c->wb_ptr->wb_frag[frag];
1469		f->wb_ctl = WB_MIN_FRAMELEN - total_len;
1470		f->wb_data = vtophys(&sc->wb_cdata.wb_pad);
1471		f->wb_ctl |= WB_TXCTL_TLINK;
1472		f->wb_status = WB_TXSTAT_OWN;
1473		frag++;
1474	}
1475
1476	c->wb_mbuf = m_head;
1477	c->wb_lastdesc = frag - 1;
1478	WB_TXCTL(c) |= WB_TXCTL_LASTFRAG;
1479	WB_TXNEXT(c) = vtophys(&c->wb_nextdesc->wb_ptr->wb_frag[0]);
1480
1481	return(0);
1482}
1483
1484/*
1485 * Main transmit routine. To avoid having to do mbuf copies, we put pointers
1486 * to the mbuf data regions directly in the transmit lists. We also save a
1487 * copy of the pointers since the transmit list fragment pointers are
1488 * physical addresses.
1489 */
1490
1491static void
1492wb_start(ifp)
1493	struct ifnet		*ifp;
1494{
1495	struct wb_softc		*sc;
1496	struct mbuf		*m_head = NULL;
1497	struct wb_chain		*cur_tx = NULL, *start_tx;
1498
1499	sc = ifp->if_softc;
1500	WB_LOCK(sc);
1501
1502	/*
1503	 * Check for an available queue slot. If there are none,
1504	 * punt.
1505	 */
1506	if (sc->wb_cdata.wb_tx_free->wb_mbuf != NULL) {
1507		ifp->if_flags |= IFF_OACTIVE;
1508		WB_UNLOCK(sc);
1509		return;
1510	}
1511
1512	start_tx = sc->wb_cdata.wb_tx_free;
1513
1514	while(sc->wb_cdata.wb_tx_free->wb_mbuf == NULL) {
1515		IF_DEQUEUE(&ifp->if_snd, m_head);
1516		if (m_head == NULL)
1517			break;
1518
1519		/* Pick a descriptor off the free list. */
1520		cur_tx = sc->wb_cdata.wb_tx_free;
1521		sc->wb_cdata.wb_tx_free = cur_tx->wb_nextdesc;
1522
1523		/* Pack the data into the descriptor. */
1524		wb_encap(sc, cur_tx, m_head);
1525
1526		if (cur_tx != start_tx)
1527			WB_TXOWN(cur_tx) = WB_TXSTAT_OWN;
1528
1529		/*
1530		 * If there's a BPF listener, bounce a copy of this frame
1531		 * to him.
1532		 */
1533		BPF_MTAP(ifp, cur_tx->wb_mbuf);
1534	}
1535
1536	/*
1537	 * If there are no packets queued, bail.
1538	 */
1539	if (cur_tx == NULL) {
1540		WB_UNLOCK(sc);
1541		return;
1542	}
1543
1544	/*
1545	 * Place the request for the upload interrupt
1546	 * in the last descriptor in the chain. This way, if
1547	 * we're chaining several packets at once, we'll only
1548	 * get an interupt once for the whole chain rather than
1549	 * once for each packet.
1550	 */
1551	WB_TXCTL(cur_tx) |= WB_TXCTL_FINT;
1552	cur_tx->wb_ptr->wb_frag[0].wb_ctl |= WB_TXCTL_FINT;
1553	sc->wb_cdata.wb_tx_tail = cur_tx;
1554
1555	if (sc->wb_cdata.wb_tx_head == NULL) {
1556		sc->wb_cdata.wb_tx_head = start_tx;
1557		WB_TXOWN(start_tx) = WB_TXSTAT_OWN;
1558		CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF);
1559	} else {
1560		/*
1561		 * We need to distinguish between the case where
1562		 * the own bit is clear because the chip cleared it
1563		 * and where the own bit is clear because we haven't
1564		 * set it yet. The magic value WB_UNSET is just some
1565		 * ramdomly chosen number which doesn't have the own
1566	 	 * bit set. When we actually transmit the frame, the
1567		 * status word will have _only_ the own bit set, so
1568		 * the txeoc handler will be able to tell if it needs
1569		 * to initiate another transmission to flush out pending
1570		 * frames.
1571		 */
1572		WB_TXOWN(start_tx) = WB_UNSENT;
1573	}
1574
1575	/*
1576	 * Set a timeout in case the chip goes out to lunch.
1577	 */
1578	ifp->if_timer = 5;
1579	WB_UNLOCK(sc);
1580
1581	return;
1582}
1583
1584static void
1585wb_init(xsc)
1586	void			*xsc;
1587{
1588	struct wb_softc		*sc = xsc;
1589	struct ifnet		*ifp = &sc->arpcom.ac_if;
1590	int			i;
1591	struct mii_data		*mii;
1592
1593	WB_LOCK(sc);
1594	mii = device_get_softc(sc->wb_miibus);
1595
1596	/*
1597	 * Cancel pending I/O and free all RX/TX buffers.
1598	 */
1599	wb_stop(sc);
1600	wb_reset(sc);
1601
1602	sc->wb_txthresh = WB_TXTHRESH_INIT;
1603
1604	/*
1605	 * Set cache alignment and burst length.
1606	 */
1607#ifdef foo
1608	CSR_WRITE_4(sc, WB_BUSCTL, WB_BUSCTL_CONFIG);
1609	WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_THRESH);
1610	WB_SETBIT(sc, WB_NETCFG, WB_TXTHRESH(sc->wb_txthresh));
1611#endif
1612
1613	CSR_WRITE_4(sc, WB_BUSCTL, WB_BUSCTL_MUSTBEONE|WB_BUSCTL_ARBITRATION);
1614	WB_SETBIT(sc, WB_BUSCTL, WB_BURSTLEN_16LONG);
1615	switch(sc->wb_cachesize) {
1616	case 32:
1617		WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_32LONG);
1618		break;
1619	case 16:
1620		WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_16LONG);
1621		break;
1622	case 8:
1623		WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_8LONG);
1624		break;
1625	case 0:
1626	default:
1627		WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_NONE);
1628		break;
1629	}
1630
1631	/* This doesn't tend to work too well at 100Mbps. */
1632	WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_EARLY_ON);
1633
1634	/* Init our MAC address */
1635	for (i = 0; i < ETHER_ADDR_LEN; i++) {
1636		CSR_WRITE_1(sc, WB_NODE0 + i, sc->arpcom.ac_enaddr[i]);
1637	}
1638
1639	/* Init circular RX list. */
1640	if (wb_list_rx_init(sc) == ENOBUFS) {
1641		printf("wb%d: initialization failed: no "
1642			"memory for rx buffers\n", sc->wb_unit);
1643		wb_stop(sc);
1644		WB_UNLOCK(sc);
1645		return;
1646	}
1647
1648	/* Init TX descriptors. */
1649	wb_list_tx_init(sc);
1650
1651	/* If we want promiscuous mode, set the allframes bit. */
1652	if (ifp->if_flags & IFF_PROMISC) {
1653		WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_RX_ALLPHYS);
1654	} else {
1655		WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_RX_ALLPHYS);
1656	}
1657
1658	/*
1659	 * Set capture broadcast bit to capture broadcast frames.
1660	 */
1661	if (ifp->if_flags & IFF_BROADCAST) {
1662		WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_RX_BROAD);
1663	} else {
1664		WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_RX_BROAD);
1665	}
1666
1667	/*
1668	 * Program the multicast filter, if necessary.
1669	 */
1670	wb_setmulti(sc);
1671
1672	/*
1673	 * Load the address of the RX list.
1674	 */
1675	WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_RX_ON);
1676	CSR_WRITE_4(sc, WB_RXADDR, vtophys(&sc->wb_ldata->wb_rx_list[0]));
1677
1678	/*
1679	 * Enable interrupts.
1680	 */
1681	CSR_WRITE_4(sc, WB_IMR, WB_INTRS);
1682	CSR_WRITE_4(sc, WB_ISR, 0xFFFFFFFF);
1683
1684	/* Enable receiver and transmitter. */
1685	WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_RX_ON);
1686	CSR_WRITE_4(sc, WB_RXSTART, 0xFFFFFFFF);
1687
1688	WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
1689	CSR_WRITE_4(sc, WB_TXADDR, vtophys(&sc->wb_ldata->wb_tx_list[0]));
1690	WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
1691
1692	mii_mediachg(mii);
1693
1694	ifp->if_flags |= IFF_RUNNING;
1695	ifp->if_flags &= ~IFF_OACTIVE;
1696
1697	sc->wb_stat_ch = timeout(wb_tick, sc, hz);
1698	WB_UNLOCK(sc);
1699
1700	return;
1701}
1702
1703/*
1704 * Set media options.
1705 */
1706static int
1707wb_ifmedia_upd(ifp)
1708	struct ifnet		*ifp;
1709{
1710	struct wb_softc		*sc;
1711
1712	sc = ifp->if_softc;
1713
1714	if (ifp->if_flags & IFF_UP)
1715		wb_init(sc);
1716
1717	return(0);
1718}
1719
1720/*
1721 * Report current media status.
1722 */
1723static void
1724wb_ifmedia_sts(ifp, ifmr)
1725	struct ifnet		*ifp;
1726	struct ifmediareq	*ifmr;
1727{
1728	struct wb_softc		*sc;
1729	struct mii_data		*mii;
1730
1731	sc = ifp->if_softc;
1732
1733	mii = device_get_softc(sc->wb_miibus);
1734
1735	mii_pollstat(mii);
1736	ifmr->ifm_active = mii->mii_media_active;
1737	ifmr->ifm_status = mii->mii_media_status;
1738
1739	return;
1740}
1741
1742static int
1743wb_ioctl(ifp, command, data)
1744	struct ifnet		*ifp;
1745	u_long			command;
1746	caddr_t			data;
1747{
1748	struct wb_softc		*sc = ifp->if_softc;
1749	struct mii_data		*mii;
1750	struct ifreq		*ifr = (struct ifreq *) data;
1751	int			error = 0;
1752
1753	WB_LOCK(sc);
1754
1755	switch(command) {
1756	case SIOCSIFFLAGS:
1757		if (ifp->if_flags & IFF_UP) {
1758			wb_init(sc);
1759		} else {
1760			if (ifp->if_flags & IFF_RUNNING)
1761				wb_stop(sc);
1762		}
1763		error = 0;
1764		break;
1765	case SIOCADDMULTI:
1766	case SIOCDELMULTI:
1767		wb_setmulti(sc);
1768		error = 0;
1769		break;
1770	case SIOCGIFMEDIA:
1771	case SIOCSIFMEDIA:
1772		mii = device_get_softc(sc->wb_miibus);
1773		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
1774		break;
1775	default:
1776		error = ether_ioctl(ifp, command, data);
1777		break;
1778	}
1779
1780	WB_UNLOCK(sc);
1781
1782	return(error);
1783}
1784
1785static void
1786wb_watchdog(ifp)
1787	struct ifnet		*ifp;
1788{
1789	struct wb_softc		*sc;
1790
1791	sc = ifp->if_softc;
1792
1793	WB_LOCK(sc);
1794	ifp->if_oerrors++;
1795	printf("wb%d: watchdog timeout\n", sc->wb_unit);
1796#ifdef foo
1797	if (!(wb_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT))
1798		printf("wb%d: no carrier - transceiver cable problem?\n",
1799								sc->wb_unit);
1800#endif
1801	wb_stop(sc);
1802	wb_reset(sc);
1803	wb_init(sc);
1804
1805	if (ifp->if_snd.ifq_head != NULL)
1806		wb_start(ifp);
1807	WB_UNLOCK(sc);
1808
1809	return;
1810}
1811
1812/*
1813 * Stop the adapter and free any mbufs allocated to the
1814 * RX and TX lists.
1815 */
1816static void
1817wb_stop(sc)
1818	struct wb_softc		*sc;
1819{
1820	register int		i;
1821	struct ifnet		*ifp;
1822
1823	WB_LOCK(sc);
1824	ifp = &sc->arpcom.ac_if;
1825	ifp->if_timer = 0;
1826
1827	untimeout(wb_tick, sc, sc->wb_stat_ch);
1828
1829	WB_CLRBIT(sc, WB_NETCFG, (WB_NETCFG_RX_ON|WB_NETCFG_TX_ON));
1830	CSR_WRITE_4(sc, WB_IMR, 0x00000000);
1831	CSR_WRITE_4(sc, WB_TXADDR, 0x00000000);
1832	CSR_WRITE_4(sc, WB_RXADDR, 0x00000000);
1833
1834	/*
1835	 * Free data in the RX lists.
1836	 */
1837	for (i = 0; i < WB_RX_LIST_CNT; i++) {
1838		if (sc->wb_cdata.wb_rx_chain[i].wb_mbuf != NULL) {
1839			m_freem(sc->wb_cdata.wb_rx_chain[i].wb_mbuf);
1840			sc->wb_cdata.wb_rx_chain[i].wb_mbuf = NULL;
1841		}
1842	}
1843	bzero((char *)&sc->wb_ldata->wb_rx_list,
1844		sizeof(sc->wb_ldata->wb_rx_list));
1845
1846	/*
1847	 * Free the TX list buffers.
1848	 */
1849	for (i = 0; i < WB_TX_LIST_CNT; i++) {
1850		if (sc->wb_cdata.wb_tx_chain[i].wb_mbuf != NULL) {
1851			m_freem(sc->wb_cdata.wb_tx_chain[i].wb_mbuf);
1852			sc->wb_cdata.wb_tx_chain[i].wb_mbuf = NULL;
1853		}
1854	}
1855
1856	bzero((char *)&sc->wb_ldata->wb_tx_list,
1857		sizeof(sc->wb_ldata->wb_tx_list));
1858
1859	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1860	WB_UNLOCK(sc);
1861
1862	return;
1863}
1864
1865/*
1866 * Stop all chip I/O so that the kernel's probe routines don't
1867 * get confused by errant DMAs when rebooting.
1868 */
1869static void
1870wb_shutdown(dev)
1871	device_t		dev;
1872{
1873	struct wb_softc		*sc;
1874
1875	sc = device_get_softc(dev);
1876	wb_stop(sc);
1877
1878	return;
1879}
1880