if_nge.c revision 119285
1138568Ssam/*
2186904Ssam * Copyright (c) 2001 Wind River Systems
3138568Ssam * Copyright (c) 1997, 1998, 1999, 2000, 2001
4138568Ssam *	Bill Paul <wpaul@bsdi.com>.  All rights reserved.
5138568Ssam *
6138568Ssam * Redistribution and use in source and binary forms, with or without
7138568Ssam * modification, are permitted provided that the following conditions
8138568Ssam * are met:
9138568Ssam * 1. Redistributions of source code must retain the above copyright
10138568Ssam *    notice, this list of conditions and the following disclaimer.
11138568Ssam * 2. Redistributions in binary form must reproduce the above copyright
12138568Ssam *    notice, this list of conditions and the following disclaimer in the
13138568Ssam *    documentation and/or other materials provided with the distribution.
14138568Ssam * 3. All advertising materials mentioning features or use of this software
15138568Ssam *    must display the following acknowledgement:
16138568Ssam *	This product includes software developed by Bill Paul.
17138568Ssam * 4. Neither the name of the author nor the names of any co-contributors
18138568Ssam *    may be used to endorse or promote products derived from this software
19138568Ssam *    without specific prior written permission.
20138568Ssam *
21138568Ssam * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
22138568Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23138568Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24138568Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
25138568Ssam * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26138568Ssam * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27138568Ssam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28138568Ssam * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29138568Ssam * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30138568Ssam * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31138568Ssam * THE POSSIBILITY OF SUCH DAMAGE.
32178354Ssam */
33178354Ssam
34138568Ssam/*
35138568Ssam * National Semiconductor DP83820/DP83821 gigabit ethernet driver
36138568Ssam * for FreeBSD. Datasheets are available from:
37138568Ssam *
38138568Ssam * http://www.national.com/ds/DP/DP83820.pdf
39138568Ssam * http://www.national.com/ds/DP/DP83821.pdf
40138568Ssam *
41138568Ssam * These chips are used on several low cost gigabit ethernet NICs
42138568Ssam * sold by D-Link, Addtron, SMC and Asante. Both parts are
43138568Ssam * virtually the same, except the 83820 is a 64-bit/32-bit part,
44138568Ssam * while the 83821 is 32-bit only.
45192468Ssam *
46138568Ssam * Many cards also use National gigE transceivers, such as the
47257176Sglebius * DP83891, DP83861 and DP83862 gigPHYTER parts. The DP83861 datasheet
48190526Ssam * contains a full register description that applies to all of these
49178354Ssam * components:
50138568Ssam *
51178354Ssam * http://www.national.com/ds/DP/DP83861.pdf
52138568Ssam *
53138568Ssam * Written by Bill Paul <wpaul@bsdi.com>
54196019Srwatson * BSDi Open Source Solutions
55138568Ssam */
56138568Ssam
57195757Ssam/*
58138568Ssam * The NatSemi DP83820 and 83821 controllers are enhanced versions
59138568Ssam * of the NatSemi MacPHYTER 10/100 devices. They support 10, 100
60138568Ssam * and 1000Mbps speeds with 1000baseX (ten bit interface), MII and GMII
61138568Ssam * ports. Other features include 8K TX FIFO and 32K RX FIFO, TCP/IP
62138568Ssam * hardware checksum offload (IPv4 only), VLAN tagging and filtering,
63138568Ssam * priority TX and RX queues, a 2048 bit multicast hash filter, 4 RX pattern
64138568Ssam * matching buffers, one perfect address filter buffer and interrupt
65138568Ssam * moderation. The 83820 supports both 64-bit and 32-bit addressing
66138568Ssam * and data transfers: the 64-bit support can be toggled on or off
67227293Sed * via software. This affects the size of certain fields in the DMA
68178354Ssam * descriptors.
69242154Sadrian *
70241610Sglebius * There are two bugs/misfeatures in the 83820/83821 that I have
71241610Sglebius * discovered so far:
72242154Sadrian *
73241610Sglebius * - Receive buffers must be aligned on 64-bit boundaries, which means
74178354Ssam *   you must resort to copying data in order to fix up the payload
75178354Ssam *   alignment.
76178354Ssam *
77178354Ssam * - In order to transmit jumbo frames larger than 8170 bytes, you have
78178354Ssam *   to turn off transmit checksum offloading, because the chip can't
79178354Ssam *   compute the checksum on an outgoing frame unless it fits entirely
80178354Ssam *   within the TX FIFO, which is only 8192 bytes in size. If you have
81178354Ssam *   TX checksum offload enabled and you transmit attempt to transmit a
82178354Ssam *   frame larger than 8170 bytes, the transmitter will wedge.
83178354Ssam *
84178354Ssam * To work around the latter problem, TX checksum offload is disabled
85283538Sadrian * if the user selects an MTU larger than 8152 (8170 - 18).
86283538Sadrian */
87178354Ssam
88178354Ssam#include <sys/cdefs.h>
89178354Ssam__FBSDID("$FreeBSD: head/sys/dev/nge/if_nge.c 119285 2003-08-22 06:42:59Z imp $");
90178354Ssam
91178354Ssam#include <sys/param.h>
92178354Ssam#include <sys/systm.h>
93178354Ssam#include <sys/sockio.h>
94178354Ssam#include <sys/mbuf.h>
95283538Sadrian#include <sys/malloc.h>
96178354Ssam#include <sys/kernel.h>
97178354Ssam#include <sys/socket.h>
98138568Ssam
99178354Ssam#include <net/if.h>
100173273Ssam#include <net/if_arp.h>
101178354Ssam#include <net/ethernet.h>
102178354Ssam#include <net/if_dl.h>
103178354Ssam#include <net/if_media.h>
104178354Ssam#include <net/if_types.h>
105173273Ssam#include <net/if_vlan_var.h>
106173273Ssam
107178354Ssam#include <net/bpf.h>
108178354Ssam
109178354Ssam#include <vm/vm.h>              /* for vtophys */
110178354Ssam#include <vm/pmap.h>            /* for vtophys */
111178354Ssam#include <machine/clock.h>      /* for DELAY */
112178354Ssam#include <machine/bus_pio.h>
113178957Ssam#include <machine/bus_memio.h>
114178354Ssam#include <machine/bus.h>
115178354Ssam#include <machine/resource.h>
116178957Ssam#include <sys/bus.h>
117178957Ssam#include <sys/rman.h>
118178957Ssam
119178957Ssam#include <dev/mii/mii.h>
120178957Ssam#include <dev/mii/miivar.h>
121178354Ssam
122178354Ssam#include <dev/pci/pcireg.h>
123178354Ssam#include <dev/pci/pcivar.h>
124178957Ssam
125178957Ssam#define NGE_USEIOSPACE
126178957Ssam
127178957Ssam#include <dev/nge/if_ngereg.h>
128178957Ssam
129186904SsamMODULE_DEPEND(nge, pci, 1, 1, 1);
130186904SsamMODULE_DEPEND(nge, ether, 1, 1, 1);
131186904SsamMODULE_DEPEND(nge, miibus, 1, 1, 1);
132186904Ssam
133186904Ssam/* "controller miibus0" required.  See GENERIC if you get errors here. */
134186904Ssam#include "miibus_if.h"
135186904Ssam
136186904Ssam#define NGE_CSUM_FEATURES	(CSUM_IP | CSUM_TCP | CSUM_UDP)
137186904Ssam
138186904Ssam/*
139242154Sadrian * Various supported device vendors/types and their names.
140241610Sglebius */
141178354Ssamstatic struct nge_type nge_devs[] = {
142178354Ssam	{ NGE_VENDORID, NGE_DEVICEID,
143190526Ssam	    "National Semiconductor Gigabit Ethernet" },
144242154Sadrian	{ 0, 0, NULL }
145242154Sadrian};
146242154Sadrian
147242154Sadrianstatic int nge_probe(device_t);
148242154Sadrianstatic int nge_attach(device_t);
149242154Sadrianstatic int nge_detach(device_t);
150242154Sadrian
151242154Sadrianstatic int nge_alloc_jumbo_mem(struct nge_softc *);
152178354Ssamstatic void nge_free_jumbo_mem(struct nge_softc *);
153178354Ssamstatic void *nge_jalloc(struct nge_softc *);
154178354Ssamstatic void nge_jfree(void *, void *);
155178354Ssam
156178354Ssamstatic int nge_newbuf(struct nge_softc *, struct nge_desc *, struct mbuf *);
157178354Ssamstatic int nge_encap(struct nge_softc *, struct mbuf *, u_int32_t *);
158178354Ssamstatic void nge_rxeof(struct nge_softc *);
159178354Ssamstatic void nge_txeof(struct nge_softc *);
160178354Ssamstatic void nge_intr(void *);
161178354Ssamstatic void nge_tick(void *);
162178354Ssamstatic void nge_start(struct ifnet *);
163178354Ssamstatic int nge_ioctl(struct ifnet *, u_long, caddr_t);
164242155Sadrianstatic void nge_init(void *);
165242154Sadrianstatic void nge_stop(struct nge_softc *);
166242155Sadrianstatic void nge_watchdog(struct ifnet *);
167242154Sadrianstatic void nge_shutdown(device_t);
168178354Ssamstatic int nge_ifmedia_upd(struct ifnet *);
169178354Ssamstatic void nge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
170178354Ssam
171242149Sadrianstatic void nge_delay(struct nge_softc *);
172242154Sadrianstatic void nge_eeprom_idle(struct nge_softc *);
173241610Sglebiusstatic void nge_eeprom_putbyte(struct nge_softc *, int);
174242154Sadrianstatic void nge_eeprom_getword(struct nge_softc *, int, u_int16_t *);
175242154Sadrianstatic void nge_read_eeprom(struct nge_softc *, caddr_t, int, int, int);
176242154Sadrian
177242149Sadrianstatic void nge_mii_sync(struct nge_softc *);
178178354Ssamstatic void nge_mii_send(struct nge_softc *, u_int32_t, int);
179178354Ssamstatic int nge_mii_readreg(struct nge_softc *, struct nge_mii_frame *);
180192473Ssamstatic int nge_mii_writereg(struct nge_softc *, struct nge_mii_frame *);
181178354Ssam
182178354Ssamstatic int nge_miibus_readreg(device_t, int, int);
183178354Ssamstatic int nge_miibus_writereg(device_t, int, int, int);
184178354Ssamstatic void nge_miibus_statchg(device_t);
185178354Ssam
186178354Ssamstatic void nge_setmulti(struct nge_softc *);
187173273Ssamstatic u_int32_t nge_crc(struct nge_softc *, caddr_t);
188173273Ssamstatic void nge_reset(struct nge_softc *);
189178354Ssamstatic int nge_list_rx_init(struct nge_softc *);
190178354Ssamstatic int nge_list_tx_init(struct nge_softc *);
191173273Ssam
192173273Ssam#ifdef NGE_USEIOSPACE
193178354Ssam#define NGE_RES			SYS_RES_IOPORT
194173273Ssam#define NGE_RID			NGE_PCI_LOIO
195138568Ssam#else
196138568Ssam#define NGE_RES			SYS_RES_MEMORY
197138568Ssam#define NGE_RID			NGE_PCI_LOMEM
198138568Ssam#endif
199138568Ssam
200138568Ssamstatic device_method_t nge_methods[] = {
201138568Ssam	/* Device interface */
202138568Ssam	DEVMETHOD(device_probe,		nge_probe),
203138568Ssam	DEVMETHOD(device_attach,	nge_attach),
204138568Ssam	DEVMETHOD(device_detach,	nge_detach),
205138568Ssam	DEVMETHOD(device_shutdown,	nge_shutdown),
206138568Ssam
207138568Ssam	/* bus interface */
208138568Ssam	DEVMETHOD(bus_print_child,	bus_generic_print_child),
209138568Ssam	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
210138568Ssam
211138568Ssam	/* MII interface */
212283529Sglebius	DEVMETHOD(miibus_readreg,	nge_miibus_readreg),
213138568Ssam	DEVMETHOD(miibus_writereg,	nge_miibus_writereg),
214138568Ssam	DEVMETHOD(miibus_statchg,	nge_miibus_statchg),
215181194Ssam
216181194Ssam	{ 0, 0 }
217181194Ssam};
218181194Ssam
219181194Ssamstatic driver_t nge_driver = {
220181194Ssam	"nge",
221181194Ssam	nge_methods,
222181194Ssam	sizeof(struct nge_softc)
223181194Ssam};
224181194Ssam
225181194Ssamstatic devclass_t nge_devclass;
226181194Ssam
227181194SsamDRIVER_MODULE(nge, pci, nge_driver, nge_devclass, 0, 0);
228181194SsamDRIVER_MODULE(miibus, nge, miibus_driver, miibus_devclass, 0, 0);
229181194Ssam
230138568Ssam#define NGE_SETBIT(sc, reg, x)				\
231138568Ssam	CSR_WRITE_4(sc, reg,				\
232138568Ssam		CSR_READ_4(sc, reg) | (x))
233178354Ssam
234178354Ssam#define NGE_CLRBIT(sc, reg, x)				\
235178354Ssam	CSR_WRITE_4(sc, reg,				\
236178354Ssam		CSR_READ_4(sc, reg) & ~(x))
237178354Ssam
238178354Ssam#define SIO_SET(x)					\
239178354Ssam	CSR_WRITE_4(sc, NGE_MEAR, CSR_READ_4(sc, NGE_MEAR) | (x))
240178354Ssam
241178354Ssam#define SIO_CLR(x)					\
242178354Ssam	CSR_WRITE_4(sc, NGE_MEAR, CSR_READ_4(sc, NGE_MEAR) & ~(x))
243178354Ssam
244138568Ssamstatic void
245138568Ssamnge_delay(sc)
246138568Ssam	struct nge_softc	*sc;
247138568Ssam{
248283538Sadrian	int			idx;
249283538Sadrian
250138568Ssam	for (idx = (300 / 33) + 1; idx > 0; idx--)
251178354Ssam		CSR_READ_4(sc, NGE_CSR);
252138568Ssam
253138568Ssam	return;
254138568Ssam}
255138568Ssam
256178354Ssamstatic void
257138568Ssamnge_eeprom_idle(sc)
258138568Ssam	struct nge_softc	*sc;
259138568Ssam{
260217554Smdf	register int		i;
261178354Ssam
262217322Smdf	SIO_SET(NGE_MEAR_EE_CSEL);
263178354Ssam	nge_delay(sc);
264178354Ssam	SIO_SET(NGE_MEAR_EE_CLK);
265138568Ssam	nge_delay(sc);
266178354Ssam
267217322Smdf	for (i = 0; i < 25; i++) {
268178354Ssam		SIO_CLR(NGE_MEAR_EE_CLK);
269138568Ssam		nge_delay(sc);
270138568Ssam		SIO_SET(NGE_MEAR_EE_CLK);
271178354Ssam		nge_delay(sc);
272178354Ssam	}
273178354Ssam
274138568Ssam	SIO_CLR(NGE_MEAR_EE_CLK);
275138568Ssam	nge_delay(sc);
276178354Ssam	SIO_CLR(NGE_MEAR_EE_CSEL);
277138568Ssam	nge_delay(sc);
278138568Ssam	CSR_WRITE_4(sc, NGE_MEAR, 0x00000000);
279138568Ssam
280178354Ssam	return;
281138568Ssam}
282138568Ssam
283138568Ssam/*
284178354Ssam * Send a read command and address to the EEPROM, check for ACK.
285138568Ssam */
286138568Ssamstatic void
287138568Ssamnge_eeprom_putbyte(sc, addr)
288178354Ssam	struct nge_softc	*sc;
289138568Ssam	int			addr;
290138568Ssam{
291178354Ssam	register int		d, i;
292217322Smdf
293178354Ssam	d = addr | NGE_EECMD_READ;
294178354Ssam
295178354Ssam	/*
296217322Smdf	 * Feed in each bit and stobe the clock.
297178354Ssam	 */
298178354Ssam	for (i = 0x400; i; i >>= 1) {
299178354Ssam		if (d & i) {
300217322Smdf			SIO_SET(NGE_MEAR_EE_DIN);
301178354Ssam		} else {
302178354Ssam			SIO_CLR(NGE_MEAR_EE_DIN);
303178354Ssam		}
304217322Smdf		nge_delay(sc);
305178354Ssam		SIO_SET(NGE_MEAR_EE_CLK);
306178354Ssam		nge_delay(sc);
307178354Ssam		SIO_CLR(NGE_MEAR_EE_CLK);
308178354Ssam		nge_delay(sc);
309181194Ssam	}
310181194Ssam
311181194Ssam	return;
312193115Ssam}
313181194Ssam
314178354Ssam/*
315178354Ssam * Read a word of data stored in the EEPROM at address 'addr.'
316138568Ssam */
317138568Ssamstatic void
318138568Ssamnge_eeprom_getword(sc, addr, dest)
319178354Ssam	struct nge_softc	*sc;
320138568Ssam	int			addr;
321138568Ssam	u_int16_t		*dest;
322178354Ssam{
323178354Ssam	register int		i;
324283538Sadrian	u_int16_t		word = 0;
325178354Ssam
326138568Ssam	/* Force EEPROM to idle state. */
327138568Ssam	nge_eeprom_idle(sc);
328138568Ssam
329138568Ssam	/* Enter EEPROM access mode. */
330138568Ssam	nge_delay(sc);
331138568Ssam	SIO_CLR(NGE_MEAR_EE_CLK);
332138568Ssam	nge_delay(sc);
333138568Ssam	SIO_SET(NGE_MEAR_EE_CSEL);
334138568Ssam	nge_delay(sc);
335138568Ssam
336138568Ssam	/*
337165894Ssam	 * Send address of word we want to read.
338165894Ssam	 */
339165894Ssam	nge_eeprom_putbyte(sc, addr);
340165894Ssam
341165894Ssam	/*
342165894Ssam	 * Start reading bits from EEPROM.
343165894Ssam	 */
344165894Ssam	for (i = 0x8000; i; i >>= 1) {
345165894Ssam		SIO_SET(NGE_MEAR_EE_CLK);
346165894Ssam		nge_delay(sc);
347165894Ssam		if (CSR_READ_4(sc, NGE_MEAR) & NGE_MEAR_EE_DOUT)
348165894Ssam			word |= i;
349165894Ssam		nge_delay(sc);
350165894Ssam		SIO_CLR(NGE_MEAR_EE_CLK);
351165894Ssam		nge_delay(sc);
352165894Ssam	}
353165894Ssam
354165894Ssam	/* Turn off EEPROM access mode. */
355165894Ssam	nge_eeprom_idle(sc);
356165894Ssam
357178354Ssam	*dest = word;
358178354Ssam
359178354Ssam	return;
360178354Ssam}
361178354Ssam
362178354Ssam/*
363178354Ssam * Read a sequence of words from the EEPROM.
364178354Ssam */
365178354Ssamstatic void
366178354Ssamnge_read_eeprom(sc, dest, off, cnt, swap)
367178354Ssam	struct nge_softc	*sc;
368178354Ssam	caddr_t			dest;
369178354Ssam	int			off;
370178354Ssam	int			cnt;
371178354Ssam	int			swap;
372178354Ssam{
373178354Ssam	int			i;
374178354Ssam	u_int16_t		word = 0, *ptr;
375178354Ssam
376178354Ssam	for (i = 0; i < cnt; i++) {
377178354Ssam		nge_eeprom_getword(sc, off + i, &word);
378178354Ssam		ptr = (u_int16_t *)(dest + (i * 2));
379178354Ssam		if (swap)
380178354Ssam			*ptr = ntohs(word);
381178354Ssam		else
382178354Ssam			*ptr = word;
383178354Ssam	}
384138568Ssam
385170530Ssam	return;
386170530Ssam}
387170530Ssam
388170530Ssam/*
389170530Ssam * Sync the PHYs by setting data bit and strobing the clock 32 times.
390170530Ssam */
391170530Ssamstatic void
392170530Ssamnge_mii_sync(sc)
393170530Ssam	struct nge_softc		*sc;
394138568Ssam{
395138568Ssam	register int		i;
396138568Ssam
397138568Ssam	SIO_SET(NGE_MEAR_MII_DIR|NGE_MEAR_MII_DATA);
398138568Ssam
399138568Ssam	for (i = 0; i < 32; i++) {
400138568Ssam		SIO_SET(NGE_MEAR_MII_CLK);
401138568Ssam		DELAY(1);
402138568Ssam		SIO_CLR(NGE_MEAR_MII_CLK);
403170530Ssam		DELAY(1);
404138568Ssam	}
405138568Ssam
406138568Ssam	return;
407138568Ssam}
408138568Ssam
409138568Ssam/*
410138568Ssam * Clock a series of bits through the MII.
411138568Ssam */
412170530Ssamstatic void
413138568Ssamnge_mii_send(sc, bits, cnt)
414138568Ssam	struct nge_softc		*sc;
415151967Sandre	u_int32_t		bits;
416138568Ssam	int			cnt;
417138568Ssam{
418138568Ssam	int			i;
419138568Ssam
420138568Ssam	SIO_CLR(NGE_MEAR_MII_CLK);
421138568Ssam
422138568Ssam	for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
423276692Srwatson                if (bits & i) {
424170530Ssam			SIO_SET(NGE_MEAR_MII_DATA);
425151967Sandre                } else {
426170530Ssam			SIO_CLR(NGE_MEAR_MII_DATA);
427170530Ssam                }
428170530Ssam		DELAY(1);
429138568Ssam		SIO_CLR(NGE_MEAR_MII_CLK);
430171984Ssephe		DELAY(1);
431138568Ssam		SIO_SET(NGE_MEAR_MII_CLK);
432138568Ssam	}
433138568Ssam}
434138568Ssam
435138568Ssam/*
436246710Sglebius * Read an PHY register through the MII.
437195757Ssam */
438195757Ssamstatic int
439195757Ssamnge_mii_readreg(sc, frame)
440195757Ssam	struct nge_softc		*sc;
441195757Ssam	struct nge_mii_frame	*frame;
442195757Ssam
443195757Ssam{
444195757Ssam	int			i, ack, s;
445195757Ssam
446195757Ssam	s = splimp();
447195757Ssam
448195757Ssam	/*
449195757Ssam	 * Set up frame for RX.
450243882Sglebius	 */
451195757Ssam	frame->mii_stdelim = NGE_MII_STARTDELIM;
452243882Sglebius	frame->mii_opcode = NGE_MII_READOP;
453195757Ssam	frame->mii_turnaround = 0;
454195757Ssam	frame->mii_data = 0;
455195757Ssam
456195757Ssam	CSR_WRITE_4(sc, NGE_MEAR, 0);
457195757Ssam
458195757Ssam	/*
459195757Ssam 	 * Turn on data xmit.
460195757Ssam	 */
461195757Ssam	SIO_SET(NGE_MEAR_MII_DIR);
462195757Ssam
463195757Ssam	nge_mii_sync(sc);
464195757Ssam
465195757Ssam	/*
466195757Ssam	 * Send command/address info.
467195757Ssam	 */
468195757Ssam	nge_mii_send(sc, frame->mii_stdelim, 2);
469195757Ssam	nge_mii_send(sc, frame->mii_opcode, 2);
470195757Ssam	nge_mii_send(sc, frame->mii_phyaddr, 5);
471195757Ssam	nge_mii_send(sc, frame->mii_regaddr, 5);
472195757Ssam
473246710Sglebius	/* Idle bit */
474195757Ssam	SIO_CLR((NGE_MEAR_MII_CLK|NGE_MEAR_MII_DATA));
475170530Ssam	DELAY(1);
476170530Ssam	SIO_SET(NGE_MEAR_MII_CLK);
477170530Ssam	DELAY(1);
478170530Ssam
479170530Ssam	/* Turn off xmit. */
480170530Ssam	SIO_CLR(NGE_MEAR_MII_DIR);
481170530Ssam	/* Check for ack */
482170530Ssam	SIO_CLR(NGE_MEAR_MII_CLK);
483170530Ssam	DELAY(1);
484170530Ssam	ack = CSR_READ_4(sc, NGE_MEAR) & NGE_MEAR_MII_DATA;
485170530Ssam	SIO_SET(NGE_MEAR_MII_CLK);
486170530Ssam	DELAY(1);
487170530Ssam
488170530Ssam	/*
489170530Ssam	 * Now try reading data bits. If the ack failed, we still
490170530Ssam	 * need to clock through 16 cycles to keep the PHY(s) in sync.
491170530Ssam	 */
492170530Ssam	if (ack) {
493170530Ssam		for(i = 0; i < 16; i++) {
494170530Ssam			SIO_CLR(NGE_MEAR_MII_CLK);
495170530Ssam			DELAY(1);
496170530Ssam			SIO_SET(NGE_MEAR_MII_CLK);
497170530Ssam			DELAY(1);
498170530Ssam		}
499170530Ssam		goto fail;
500170530Ssam	}
501170530Ssam
502170530Ssam	for (i = 0x8000; i; i >>= 1) {
503170530Ssam		SIO_CLR(NGE_MEAR_MII_CLK);
504170530Ssam		DELAY(1);
505170530Ssam		if (!ack) {
506170530Ssam			if (CSR_READ_4(sc, NGE_MEAR) & NGE_MEAR_MII_DATA)
507170530Ssam				frame->mii_data |= i;
508248069Sadrian			DELAY(1);
509248069Sadrian		}
510248069Sadrian		SIO_SET(NGE_MEAR_MII_CLK);
511248069Sadrian		DELAY(1);
512248069Sadrian	}
513248069Sadrian
514248069Sadrianfail:
515254082Sadrian
516248069Sadrian	SIO_CLR(NGE_MEAR_MII_CLK);
517248069Sadrian	DELAY(1);
518248069Sadrian	SIO_SET(NGE_MEAR_MII_CLK);
519248069Sadrian	DELAY(1);
520248069Sadrian
521248069Sadrian	splx(s);
522248069Sadrian
523248069Sadrian	if (ack)
524248069Sadrian		return(1);
525248069Sadrian	return(0);
526248069Sadrian}
527248069Sadrian
528248069Sadrian/*
529248069Sadrian * Write to a PHY register through the MII.
530248069Sadrian */
531248069Sadrianstatic int
532254082Sadriannge_mii_writereg(sc, frame)
533248069Sadrian	struct nge_softc		*sc;
534248069Sadrian	struct nge_mii_frame	*frame;
535248069Sadrian
536248069Sadrian{
537248069Sadrian	int			s;
538248069Sadrian
539248069Sadrian	s = splimp();
540248069Sadrian	/*
541248069Sadrian	 * Set up frame for TX.
542248069Sadrian	 */
543248069Sadrian
544248069Sadrian	frame->mii_stdelim = NGE_MII_STARTDELIM;
545248069Sadrian	frame->mii_opcode = NGE_MII_WRITEOP;
546138568Ssam	frame->mii_turnaround = NGE_MII_TURNAROUND;
547138568Ssam
548138568Ssam	/*
549138568Ssam 	 * Turn on data output.
550138568Ssam	 */
551170530Ssam	SIO_SET(NGE_MEAR_MII_DIR);
552138568Ssam
553138568Ssam	nge_mii_sync(sc);
554170530Ssam
555170530Ssam	nge_mii_send(sc, frame->mii_stdelim, 2);
556170530Ssam	nge_mii_send(sc, frame->mii_opcode, 2);
557170530Ssam	nge_mii_send(sc, frame->mii_phyaddr, 5);
558138568Ssam	nge_mii_send(sc, frame->mii_regaddr, 5);
559138568Ssam	nge_mii_send(sc, frame->mii_turnaround, 2);
560138568Ssam	nge_mii_send(sc, frame->mii_data, 16);
561178354Ssam
562178354Ssam	/* Idle bit. */
563178354Ssam	SIO_SET(NGE_MEAR_MII_CLK);
564178354Ssam	DELAY(1);
565178354Ssam	SIO_CLR(NGE_MEAR_MII_CLK);
566138568Ssam	DELAY(1);
567138568Ssam
568138568Ssam	/*
569191816Szec	 * Turn off xmit.
570144302Ssam	 */
571178354Ssam	SIO_CLR(NGE_MEAR_MII_DIR);
572178354Ssam
573191816Szec	splx(s);
574178354Ssam
575178354Ssam	return(0);
576178354Ssam}
577178354Ssam
578178354Ssamstatic int
579178354Ssamnge_miibus_readreg(dev, phy, reg)
580178354Ssam	device_t		dev;
581178354Ssam	int			phy, reg;
582191816Szec{
583178354Ssam	struct nge_softc	*sc;
584178354Ssam	struct nge_mii_frame	frame;
585178354Ssam
586178354Ssam	sc = device_get_softc(dev);
587178354Ssam
588178354Ssam	bzero((char *)&frame, sizeof(frame));
589138568Ssam
590144302Ssam	frame.mii_phyaddr = phy;
591178354Ssam	frame.mii_regaddr = reg;
592178354Ssam	nge_mii_readreg(sc, &frame);
593138568Ssam
594191816Szec	return(frame.mii_data);
595138568Ssam}
596138568Ssam
597138568Ssamstatic int
598178354Ssamnge_miibus_writereg(dev, phy, reg, data)
599138568Ssam	device_t		dev;
600178354Ssam	int			phy, reg, data;
601178354Ssam{
602138568Ssam	struct nge_softc	*sc;
603191816Szec	struct nge_mii_frame	frame;
604178354Ssam
605178354Ssam	sc = device_get_softc(dev);
606178354Ssam
607178354Ssam	bzero((char *)&frame, sizeof(frame));
608138568Ssam
609138568Ssam	frame.mii_phyaddr = phy;
610138568Ssam	frame.mii_regaddr = reg;
611138568Ssam	frame.mii_data = data;
612178354Ssam	nge_mii_writereg(sc, &frame);
613138568Ssam
614191816Szec	return(0);
615138568Ssam}
616138568Ssam
617138568Ssamstatic void
618178354Ssamnge_miibus_statchg(dev)
619138568Ssam	device_t		dev;
620178354Ssam{
621138568Ssam	int			status;
622178354Ssam	struct nge_softc	*sc;
623138568Ssam	struct mii_data		*mii;
624138568Ssam
625191816Szec	sc = device_get_softc(dev);
626138568Ssam	if (sc->nge_tbi) {
627191816Szec		if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media)
628138568Ssam		    == IFM_AUTO) {
629138568Ssam			status = CSR_READ_4(sc, NGE_TBI_ANLPAR);
630138568Ssam			if (status == 0 || status & NGE_TBIANAR_FDX) {
631178354Ssam				NGE_SETBIT(sc, NGE_TX_CFG,
632138568Ssam				    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
633193541Ssam				NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
634138568Ssam			} else {
635178354Ssam				NGE_CLRBIT(sc, NGE_TX_CFG,
636138568Ssam				    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
637178354Ssam				NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
638226885Sadrian			}
639233531Sadrian
640193541Ssam		} else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK)
641148863Ssam			!= IFM_FDX) {
642138568Ssam			NGE_CLRBIT(sc, NGE_TX_CFG,
643138568Ssam			    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
644138568Ssam			NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
645138568Ssam		} else {
646138568Ssam			NGE_SETBIT(sc, NGE_TX_CFG,
647138568Ssam			    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
648138568Ssam			NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
649148863Ssam		}
650148863Ssam	} else {
651148863Ssam		mii = device_get_softc(sc->nge_miibus);
652148863Ssam
653193541Ssam		if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
654138568Ssam		        NGE_SETBIT(sc, NGE_TX_CFG,
655191816Szec			    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
656138568Ssam			NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
657191816Szec		} else {
658138568Ssam			NGE_CLRBIT(sc, NGE_TX_CFG,
659138568Ssam			    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
660138568Ssam			NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
661138568Ssam		}
662178354Ssam
663138568Ssam		/* If we have a 1000Mbps link, set the mode_1000 bit. */
664138568Ssam		if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
665178354Ssam		    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) {
666138568Ssam			NGE_SETBIT(sc, NGE_CFG, NGE_CFG_MODE_1000);
667178354Ssam		} else {
668178354Ssam			NGE_CLRBIT(sc, NGE_CFG, NGE_CFG_MODE_1000);
669178354Ssam		}
670138568Ssam	}
671138568Ssam	return;
672138568Ssam}
673138568Ssam
674138568Ssamstatic u_int32_t
675138568Ssamnge_crc(sc, addr)
676138568Ssam	struct nge_softc	*sc;
677138568Ssam	caddr_t			addr;
678191816Szec{
679138568Ssam	u_int32_t		crc, carry;
680191816Szec	int			i, j;
681138568Ssam	u_int8_t		c;
682138568Ssam
683138568Ssam	/* Compute CRC for the address value. */
684138568Ssam	crc = 0xFFFFFFFF; /* initial value */
685178354Ssam
686178354Ssam	for (i = 0; i < 6; i++) {
687178354Ssam		c = *(addr + i);
688178354Ssam		for (j = 0; j < 8; j++) {
689178354Ssam			carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01);
690178354Ssam			crc <<= 1;
691178354Ssam			c >>= 1;
692178354Ssam			if (carry)
693178354Ssam				crc = (crc ^ 0x04c11db6) | carry;
694178354Ssam		}
695178354Ssam	}
696178354Ssam
697178354Ssam	/*
698178354Ssam	 * return the filter bit position
699178354Ssam	 */
700178354Ssam
701178354Ssam	return((crc >> 21) & 0x00000FFF);
702178354Ssam}
703178354Ssam
704178354Ssamstatic void
705178354Ssamnge_setmulti(sc)
706248539Sadrian	struct nge_softc	*sc;
707178354Ssam{
708248539Sadrian	struct ifnet		*ifp;
709178354Ssam	struct ifmultiaddr	*ifma;
710178354Ssam	u_int32_t		h = 0, i, filtsave;
711178354Ssam	int			bit, index;
712178354Ssam
713178354Ssam	ifp = &sc->arpcom.ac_if;
714178354Ssam
715178354Ssam	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
716178354Ssam		NGE_CLRBIT(sc, NGE_RXFILT_CTL,
717178354Ssam		    NGE_RXFILTCTL_MCHASH|NGE_RXFILTCTL_UCHASH);
718178354Ssam		NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ALLMULTI);
719178354Ssam		return;
720178354Ssam	}
721178354Ssam
722248539Sadrian	/*
723178354Ssam	 * We have to explicitly enable the multicast hash table
724248539Sadrian	 * on the NatSemi chip if we want to use it, which we do.
725178354Ssam	 * We also have to tell it that we don't want to use the
726178354Ssam	 * hash table for matching unicast addresses.
727178354Ssam	 */
728178354Ssam	NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_MCHASH);
729178354Ssam	NGE_CLRBIT(sc, NGE_RXFILT_CTL,
730178354Ssam	    NGE_RXFILTCTL_ALLMULTI|NGE_RXFILTCTL_UCHASH);
731178354Ssam
732178354Ssam	filtsave = CSR_READ_4(sc, NGE_RXFILT_CTL);
733178354Ssam
734178354Ssam	/* first, zot all the existing hash bits */
735178354Ssam	for (i = 0; i < NGE_MCAST_FILTER_LEN; i += 2) {
736178354Ssam		CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_MCAST_LO + i);
737178354Ssam		CSR_WRITE_4(sc, NGE_RXFILT_DATA, 0);
738178354Ssam	}
739248539Sadrian
740178354Ssam	/*
741248539Sadrian	 * From the 11 bits returned by the crc routine, the top 7
742178354Ssam	 * bits represent the 16-bit word in the mcast hash table
743178354Ssam	 * that needs to be updated, and the lower 4 bits represent
744178354Ssam	 * which bit within that byte needs to be set.
745178354Ssam	 */
746178354Ssam	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
747178354Ssam		if (ifma->ifma_addr->sa_family != AF_LINK)
748178354Ssam			continue;
749178354Ssam		h = nge_crc(sc, LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
750178354Ssam		index = (h >> 4) & 0x7F;
751178354Ssam		bit = h & 0xF;
752178354Ssam		CSR_WRITE_4(sc, NGE_RXFILT_CTL,
753178354Ssam		    NGE_FILTADDR_MCAST_LO + (index * 2));
754178354Ssam		NGE_SETBIT(sc, NGE_RXFILT_DATA, (1 << bit));
755178354Ssam	}
756178354Ssam
757178354Ssam	CSR_WRITE_4(sc, NGE_RXFILT_CTL, filtsave);
758178354Ssam
759178354Ssam	return;
760178354Ssam}
761178354Ssam
762178354Ssamstatic void
763178354Ssamnge_reset(sc)
764178354Ssam	struct nge_softc	*sc;
765178354Ssam{
766178354Ssam	register int		i;
767178354Ssam
768178354Ssam	NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RESET);
769178354Ssam
770178354Ssam	for (i = 0; i < NGE_TIMEOUT; i++) {
771178354Ssam		if (!(CSR_READ_4(sc, NGE_CSR) & NGE_CSR_RESET))
772178354Ssam			break;
773178354Ssam	}
774178354Ssam
775178354Ssam	if (i == NGE_TIMEOUT)
776178354Ssam		printf("nge%d: reset never completed\n", sc->nge_unit);
777248539Sadrian
778178354Ssam	/* Wait a little while for the chip to get its brains in order. */
779248539Sadrian	DELAY(1000);
780178354Ssam
781178354Ssam	/*
782178354Ssam	 * If this is a NetSemi chip, make sure to clear
783178354Ssam	 * PME mode.
784178354Ssam	 */
785178354Ssam	CSR_WRITE_4(sc, NGE_CLKRUN, NGE_CLKRUN_PMESTS);
786178354Ssam	CSR_WRITE_4(sc, NGE_CLKRUN, 0);
787178354Ssam
788178354Ssam        return;
789178354Ssam}
790248539Sadrian
791178354Ssam/*
792248539Sadrian * Probe for a NatSemi chip. Check the PCI vendor and device
793178354Ssam * IDs against our list and return a device name if we find a match.
794178354Ssam */
795178354Ssamstatic int
796138568Ssamnge_probe(dev)
797138568Ssam	device_t		dev;
798159590Sjhb{
799138777Ssam	struct nge_type		*t;
800159590Sjhb
801138777Ssam	t = nge_devs;
802138777Ssam
803138777Ssam	while(t->nge_name != NULL) {
804138568Ssam		if ((pci_get_vendor(dev) == t->nge_vid) &&
805138568Ssam		    (pci_get_device(dev) == t->nge_did)) {
806192468Ssam			device_set_desc(dev, t->nge_name);
807202612Sthompsa			return(0);
808192468Ssam		}
809192468Ssam		t++;
810192764Ssam	}
811192468Ssam
812256294Sadrian	return(ENXIO);
813254082Sadrian}
814256294Sadrian
815192468Ssam/*
816192468Ssam * Attach the interface. Allocate softc structures, do ifmedia
817192468Ssam * setup and ethernet/BPF attach.
818192468Ssam */
819192468Ssamstatic int
820192468Ssamnge_attach(dev)
821192468Ssam	device_t		dev;
822192468Ssam{
823193292Ssam	int			s;
824192468Ssam	u_char			eaddr[ETHER_ADDR_LEN];
825193292Ssam	struct nge_softc	*sc;
826193292Ssam	struct ifnet		*ifp;
827193312Ssam	int			unit, error = 0, rid;
828192468Ssam	const char		*sep = "";
829193292Ssam
830193292Ssam	s = splimp();
831193292Ssam
832192468Ssam	sc = device_get_softc(dev);
833192468Ssam	unit = device_get_unit(dev);
834192468Ssam	bzero(sc, sizeof(struct nge_softc));
835202612Sthompsa
836202612Sthompsa	mtx_init(&sc->nge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
837202612Sthompsa	    MTX_DEF | MTX_RECURSE);
838202612Sthompsa#ifndef BURN_BRIDGES
839202612Sthompsa	/*
840202612Sthompsa	 * Handle power management nonsense.
841202612Sthompsa	 */
842202612Sthompsa	if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
843202612Sthompsa		u_int32_t		iobase, membase, irq;
844202612Sthompsa
845202612Sthompsa		/* Save important PCI config data. */
846202612Sthompsa		iobase = pci_read_config(dev, NGE_PCI_LOIO, 4);
847202612Sthompsa		membase = pci_read_config(dev, NGE_PCI_LOMEM, 4);
848202612Sthompsa		irq = pci_read_config(dev, NGE_PCI_INTLINE, 4);
849202612Sthompsa
850202612Sthompsa		/* Reset the power state. */
851202612Sthompsa		printf("nge%d: chip is in D%d power mode "
852202612Sthompsa		    "-- setting to D0\n", unit,
853202612Sthompsa		    pci_get_powerstate(dev));
854202612Sthompsa		pci_set_powerstate(dev, PCI_POWERSTATE_D0);
855202612Sthompsa
856202612Sthompsa		/* Restore PCI config data. */
857202612Sthompsa		pci_write_config(dev, NGE_PCI_LOIO, iobase, 4);
858202612Sthompsa		pci_write_config(dev, NGE_PCI_LOMEM, membase, 4);
859202612Sthompsa		pci_write_config(dev, NGE_PCI_INTLINE, irq, 4);
860202612Sthompsa	}
861202612Sthompsa#endif
862138568Ssam	/*
863138568Ssam	 * Map control/status registers.
864138568Ssam	 */
865138568Ssam	pci_enable_busmaster(dev);
866138568Ssam
867138568Ssam	rid = NGE_RID;
868138568Ssam	sc->nge_res = bus_alloc_resource(dev, NGE_RES, &rid,
869138568Ssam	    0, ~0, 1, RF_ACTIVE);
870138568Ssam
871138568Ssam	if (sc->nge_res == NULL) {
872138568Ssam		printf("nge%d: couldn't map ports/memory\n", unit);
873138568Ssam		error = ENXIO;
874192468Ssam		goto fail;
875192468Ssam	}
876202612Sthompsa
877202612Sthompsa	sc->nge_btag = rman_get_bustag(sc->nge_res);
878242154Sadrian	sc->nge_bhandle = rman_get_bushandle(sc->nge_res);
879241610Sglebius
880241610Sglebius	/* Allocate interrupt */
881242154Sadrian	rid = 0;
882242154Sadrian	sc->nge_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
883242154Sadrian	    RF_SHAREABLE | RF_ACTIVE);
884178354Ssam
885138568Ssam	if (sc->nge_irq == NULL) {
886138568Ssam		printf("nge%d: couldn't map interrupt\n", unit);
887178354Ssam		bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res);
888242154Sadrian		error = ENXIO;
889241610Sglebius		goto fail;
890242154Sadrian	}
891242154Sadrian
892242154Sadrian	error = bus_setup_intr(dev, sc->nge_irq, INTR_TYPE_NET,
893192468Ssam	    nge_intr, sc, &sc->nge_intrhand);
894202612Sthompsa
895138568Ssam	if (error) {
896138568Ssam		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq);
897138568Ssam		bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res);
898138568Ssam		printf("nge%d: couldn't set up irq\n", unit);
899138568Ssam		goto fail;
900138568Ssam	}
901242154Sadrian
902241610Sglebius	/* Reset the adapter. */
903242154Sadrian	nge_reset(sc);
904242154Sadrian
905242154Sadrian	/*
906138568Ssam	 * Get station address from the EEPROM.
907241394Skevlo	 */
908138568Ssam	nge_read_eeprom(sc, (caddr_t)&eaddr[4], NGE_EE_NODEADDR, 1, 0);
909138568Ssam	nge_read_eeprom(sc, (caddr_t)&eaddr[2], NGE_EE_NODEADDR + 1, 1, 0);
910138568Ssam	nge_read_eeprom(sc, (caddr_t)&eaddr[0], NGE_EE_NODEADDR + 2, 1, 0);
911138568Ssam
912233050Sadrian	/*
913233050Sadrian	 * A NatSemi chip was detected. Inform the world.
914233050Sadrian	 */
915233050Sadrian	printf("nge%d: Ethernet address: %6D\n", unit, eaddr, ":");
916
917	sc->nge_unit = unit;
918	bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
919
920	sc->nge_ldata = contigmalloc(sizeof(struct nge_list_data), M_DEVBUF,
921	    M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
922
923	if (sc->nge_ldata == NULL) {
924		printf("nge%d: no memory for list buffers!\n", unit);
925		bus_teardown_intr(dev, sc->nge_irq, sc->nge_intrhand);
926		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq);
927		bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res);
928		error = ENXIO;
929		goto fail;
930	}
931	bzero(sc->nge_ldata, sizeof(struct nge_list_data));
932
933	/* Try to allocate memory for jumbo buffers. */
934	if (nge_alloc_jumbo_mem(sc)) {
935		printf("nge%d: jumbo buffer allocation failed\n",
936                    sc->nge_unit);
937		contigfree(sc->nge_ldata,
938		    sizeof(struct nge_list_data), M_DEVBUF);
939		bus_teardown_intr(dev, sc->nge_irq, sc->nge_intrhand);
940		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq);
941		bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res);
942		error = ENXIO;
943		goto fail;
944	}
945
946	ifp = &sc->arpcom.ac_if;
947	ifp->if_softc = sc;
948	ifp->if_unit = unit;
949	ifp->if_name = "nge";
950	ifp->if_mtu = ETHERMTU;
951	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
952	ifp->if_ioctl = nge_ioctl;
953	ifp->if_output = ether_output;
954	ifp->if_start = nge_start;
955	ifp->if_watchdog = nge_watchdog;
956	ifp->if_init = nge_init;
957	ifp->if_baudrate = 1000000000;
958	ifp->if_snd.ifq_maxlen = NGE_TX_LIST_CNT - 1;
959	ifp->if_hwassist = NGE_CSUM_FEATURES;
960	ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING;
961	ifp->if_capenable = ifp->if_capabilities;
962
963	/*
964	 * Do MII setup.
965	 */
966	if (mii_phy_probe(dev, &sc->nge_miibus,
967			  nge_ifmedia_upd, nge_ifmedia_sts)) {
968		if (CSR_READ_4(sc, NGE_CFG) & NGE_CFG_TBI_EN) {
969			sc->nge_tbi = 1;
970			device_printf(dev, "Using TBI\n");
971
972			sc->nge_miibus = dev;
973
974			ifmedia_init(&sc->nge_ifmedia, 0, nge_ifmedia_upd,
975				nge_ifmedia_sts);
976#define	ADD(m, c)	ifmedia_add(&sc->nge_ifmedia, (m), (c), NULL)
977#define PRINT(s)	printf("%s%s", sep, s); sep = ", "
978			ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, 0), 0);
979			device_printf(dev, " ");
980			ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, 0, 0), 0);
981			PRINT("1000baseSX");
982			ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, 0),0);
983			PRINT("1000baseSX-FDX");
984			ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0), 0);
985			PRINT("auto");
986
987			printf("\n");
988#undef ADD
989#undef PRINT
990			ifmedia_set(&sc->nge_ifmedia,
991				IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0));
992
993			CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO)
994				| NGE_GPIO_GP4_OUT
995				| NGE_GPIO_GP1_OUTENB | NGE_GPIO_GP2_OUTENB
996				| NGE_GPIO_GP3_OUTENB
997				| NGE_GPIO_GP3_IN | NGE_GPIO_GP4_IN);
998
999		} else {
1000			printf("nge%d: MII without any PHY!\n", sc->nge_unit);
1001			nge_free_jumbo_mem(sc);
1002			bus_teardown_intr(dev, sc->nge_irq, sc->nge_intrhand);
1003			bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq);
1004			bus_release_resource(dev, NGE_RES, NGE_RID,
1005					 sc->nge_res);
1006			error = ENXIO;
1007			goto fail;
1008		}
1009	}
1010
1011	/*
1012	 * Call MI attach routine.
1013	 */
1014	ether_ifattach(ifp, eaddr);
1015	callout_handle_init(&sc->nge_stat_ch);
1016
1017fail:
1018
1019	splx(s);
1020	mtx_destroy(&sc->nge_mtx);
1021	return(error);
1022}
1023
1024static int
1025nge_detach(dev)
1026	device_t		dev;
1027{
1028	struct nge_softc	*sc;
1029	struct ifnet		*ifp;
1030	int			s;
1031
1032	s = splimp();
1033
1034	sc = device_get_softc(dev);
1035	ifp = &sc->arpcom.ac_if;
1036
1037	nge_reset(sc);
1038	nge_stop(sc);
1039	ether_ifdetach(ifp);
1040
1041	bus_generic_detach(dev);
1042	if (!sc->nge_tbi) {
1043		device_delete_child(dev, sc->nge_miibus);
1044	}
1045	bus_teardown_intr(dev, sc->nge_irq, sc->nge_intrhand);
1046	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq);
1047	bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res);
1048
1049	contigfree(sc->nge_ldata, sizeof(struct nge_list_data), M_DEVBUF);
1050	nge_free_jumbo_mem(sc);
1051
1052	splx(s);
1053	mtx_destroy(&sc->nge_mtx);
1054
1055	return(0);
1056}
1057
1058/*
1059 * Initialize the transmit descriptors.
1060 */
1061static int
1062nge_list_tx_init(sc)
1063	struct nge_softc	*sc;
1064{
1065	struct nge_list_data	*ld;
1066	struct nge_ring_data	*cd;
1067	int			i;
1068
1069	cd = &sc->nge_cdata;
1070	ld = sc->nge_ldata;
1071
1072	for (i = 0; i < NGE_TX_LIST_CNT; i++) {
1073		if (i == (NGE_TX_LIST_CNT - 1)) {
1074			ld->nge_tx_list[i].nge_nextdesc =
1075			    &ld->nge_tx_list[0];
1076			ld->nge_tx_list[i].nge_next =
1077			    vtophys(&ld->nge_tx_list[0]);
1078		} else {
1079			ld->nge_tx_list[i].nge_nextdesc =
1080			    &ld->nge_tx_list[i + 1];
1081			ld->nge_tx_list[i].nge_next =
1082			    vtophys(&ld->nge_tx_list[i + 1]);
1083		}
1084		ld->nge_tx_list[i].nge_mbuf = NULL;
1085		ld->nge_tx_list[i].nge_ptr = 0;
1086		ld->nge_tx_list[i].nge_ctl = 0;
1087	}
1088
1089	cd->nge_tx_prod = cd->nge_tx_cons = cd->nge_tx_cnt = 0;
1090
1091	return(0);
1092}
1093
1094
1095/*
1096 * Initialize the RX descriptors and allocate mbufs for them. Note that
1097 * we arrange the descriptors in a closed ring, so that the last descriptor
1098 * points back to the first.
1099 */
1100static int
1101nge_list_rx_init(sc)
1102	struct nge_softc	*sc;
1103{
1104	struct nge_list_data	*ld;
1105	struct nge_ring_data	*cd;
1106	int			i;
1107
1108	ld = sc->nge_ldata;
1109	cd = &sc->nge_cdata;
1110
1111	for (i = 0; i < NGE_RX_LIST_CNT; i++) {
1112		if (nge_newbuf(sc, &ld->nge_rx_list[i], NULL) == ENOBUFS)
1113			return(ENOBUFS);
1114		if (i == (NGE_RX_LIST_CNT - 1)) {
1115			ld->nge_rx_list[i].nge_nextdesc =
1116			    &ld->nge_rx_list[0];
1117			ld->nge_rx_list[i].nge_next =
1118			    vtophys(&ld->nge_rx_list[0]);
1119		} else {
1120			ld->nge_rx_list[i].nge_nextdesc =
1121			    &ld->nge_rx_list[i + 1];
1122			ld->nge_rx_list[i].nge_next =
1123			    vtophys(&ld->nge_rx_list[i + 1]);
1124		}
1125	}
1126
1127	cd->nge_rx_prod = 0;
1128
1129	return(0);
1130}
1131
1132/*
1133 * Initialize an RX descriptor and attach an MBUF cluster.
1134 */
1135static int
1136nge_newbuf(sc, c, m)
1137	struct nge_softc	*sc;
1138	struct nge_desc		*c;
1139	struct mbuf		*m;
1140{
1141	struct mbuf		*m_new = NULL;
1142	caddr_t			*buf = NULL;
1143
1144	if (m == NULL) {
1145		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1146		if (m_new == NULL) {
1147			printf("nge%d: no memory for rx list "
1148			    "-- packet dropped!\n", sc->nge_unit);
1149			return(ENOBUFS);
1150		}
1151
1152		/* Allocate the jumbo buffer */
1153		buf = nge_jalloc(sc);
1154		if (buf == NULL) {
1155#ifdef NGE_VERBOSE
1156			printf("nge%d: jumbo allocation failed "
1157			    "-- packet dropped!\n", sc->nge_unit);
1158#endif
1159			m_freem(m_new);
1160			return(ENOBUFS);
1161		}
1162		/* Attach the buffer to the mbuf */
1163		m_new->m_data = (void *)buf;
1164		m_new->m_len = m_new->m_pkthdr.len = NGE_JUMBO_FRAMELEN;
1165		MEXTADD(m_new, buf, NGE_JUMBO_FRAMELEN, nge_jfree,
1166		    (struct nge_softc *)sc, 0, EXT_NET_DRV);
1167	} else {
1168		m_new = m;
1169		m_new->m_len = m_new->m_pkthdr.len = NGE_JUMBO_FRAMELEN;
1170		m_new->m_data = m_new->m_ext.ext_buf;
1171	}
1172
1173	m_adj(m_new, sizeof(u_int64_t));
1174
1175	c->nge_mbuf = m_new;
1176	c->nge_ptr = vtophys(mtod(m_new, caddr_t));
1177	c->nge_ctl = m_new->m_len;
1178	c->nge_extsts = 0;
1179
1180	return(0);
1181}
1182
1183static int
1184nge_alloc_jumbo_mem(sc)
1185	struct nge_softc	*sc;
1186{
1187	caddr_t			ptr;
1188	register int		i;
1189	struct nge_jpool_entry   *entry;
1190
1191	/* Grab a big chunk o' storage. */
1192	sc->nge_cdata.nge_jumbo_buf = contigmalloc(NGE_JMEM, M_DEVBUF,
1193	    M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
1194
1195	if (sc->nge_cdata.nge_jumbo_buf == NULL) {
1196		printf("nge%d: no memory for jumbo buffers!\n", sc->nge_unit);
1197		return(ENOBUFS);
1198	}
1199
1200	SLIST_INIT(&sc->nge_jfree_listhead);
1201	SLIST_INIT(&sc->nge_jinuse_listhead);
1202
1203	/*
1204	 * Now divide it up into 9K pieces and save the addresses
1205	 * in an array.
1206	 */
1207	ptr = sc->nge_cdata.nge_jumbo_buf;
1208	for (i = 0; i < NGE_JSLOTS; i++) {
1209		sc->nge_cdata.nge_jslots[i] = ptr;
1210		ptr += NGE_JLEN;
1211		entry = malloc(sizeof(struct nge_jpool_entry),
1212		    M_DEVBUF, M_NOWAIT);
1213		if (entry == NULL) {
1214			printf("nge%d: no memory for jumbo "
1215			    "buffer queue!\n", sc->nge_unit);
1216			return(ENOBUFS);
1217		}
1218		entry->slot = i;
1219		SLIST_INSERT_HEAD(&sc->nge_jfree_listhead,
1220		    entry, jpool_entries);
1221	}
1222
1223	return(0);
1224}
1225
1226static void
1227nge_free_jumbo_mem(sc)
1228	struct nge_softc	*sc;
1229{
1230	register int		i;
1231	struct nge_jpool_entry   *entry;
1232
1233	for (i = 0; i < NGE_JSLOTS; i++) {
1234		entry = SLIST_FIRST(&sc->nge_jfree_listhead);
1235		SLIST_REMOVE_HEAD(&sc->nge_jfree_listhead, jpool_entries);
1236		free(entry, M_DEVBUF);
1237	}
1238
1239	contigfree(sc->nge_cdata.nge_jumbo_buf, NGE_JMEM, M_DEVBUF);
1240
1241	return;
1242}
1243
1244/*
1245 * Allocate a jumbo buffer.
1246 */
1247static void *
1248nge_jalloc(sc)
1249	struct nge_softc	*sc;
1250{
1251	struct nge_jpool_entry   *entry;
1252
1253	entry = SLIST_FIRST(&sc->nge_jfree_listhead);
1254
1255	if (entry == NULL) {
1256#ifdef NGE_VERBOSE
1257		printf("nge%d: no free jumbo buffers\n", sc->nge_unit);
1258#endif
1259		return(NULL);
1260	}
1261
1262	SLIST_REMOVE_HEAD(&sc->nge_jfree_listhead, jpool_entries);
1263	SLIST_INSERT_HEAD(&sc->nge_jinuse_listhead, entry, jpool_entries);
1264	return(sc->nge_cdata.nge_jslots[entry->slot]);
1265}
1266
1267/*
1268 * Release a jumbo buffer.
1269 */
1270static void
1271nge_jfree(buf, args)
1272	void			*buf;
1273	void			*args;
1274{
1275	struct nge_softc	*sc;
1276	int		        i;
1277	struct nge_jpool_entry   *entry;
1278
1279	/* Extract the softc struct pointer. */
1280	sc = args;
1281
1282	if (sc == NULL)
1283		panic("nge_jfree: can't find softc pointer!");
1284
1285	/* calculate the slot this buffer belongs to */
1286	i = ((vm_offset_t)buf
1287	     - (vm_offset_t)sc->nge_cdata.nge_jumbo_buf) / NGE_JLEN;
1288
1289	if ((i < 0) || (i >= NGE_JSLOTS))
1290		panic("nge_jfree: asked to free buffer that we don't manage!");
1291
1292	entry = SLIST_FIRST(&sc->nge_jinuse_listhead);
1293	if (entry == NULL)
1294		panic("nge_jfree: buffer not in use!");
1295	entry->slot = i;
1296	SLIST_REMOVE_HEAD(&sc->nge_jinuse_listhead, jpool_entries);
1297	SLIST_INSERT_HEAD(&sc->nge_jfree_listhead, entry, jpool_entries);
1298
1299	return;
1300}
1301/*
1302 * A frame has been uploaded: pass the resulting mbuf chain up to
1303 * the higher level protocols.
1304 */
1305static void
1306nge_rxeof(sc)
1307	struct nge_softc	*sc;
1308{
1309        struct mbuf		*m;
1310        struct ifnet		*ifp;
1311	struct nge_desc		*cur_rx;
1312	int			i, total_len = 0;
1313	u_int32_t		rxstat;
1314
1315	ifp = &sc->arpcom.ac_if;
1316	i = sc->nge_cdata.nge_rx_prod;
1317
1318	while(NGE_OWNDESC(&sc->nge_ldata->nge_rx_list[i])) {
1319		struct mbuf		*m0 = NULL;
1320		u_int32_t		extsts;
1321
1322#ifdef DEVICE_POLLING
1323		if (ifp->if_ipending & IFF_POLLING) {
1324			if (sc->rxcycles <= 0)
1325				break;
1326			sc->rxcycles--;
1327		}
1328#endif /* DEVICE_POLLING */
1329
1330		cur_rx = &sc->nge_ldata->nge_rx_list[i];
1331		rxstat = cur_rx->nge_rxstat;
1332		extsts = cur_rx->nge_extsts;
1333		m = cur_rx->nge_mbuf;
1334		cur_rx->nge_mbuf = NULL;
1335		total_len = NGE_RXBYTES(cur_rx);
1336		NGE_INC(i, NGE_RX_LIST_CNT);
1337		/*
1338		 * If an error occurs, update stats, clear the
1339		 * status word and leave the mbuf cluster in place:
1340		 * it should simply get re-used next time this descriptor
1341	 	 * comes up in the ring.
1342		 */
1343		if (!(rxstat & NGE_CMDSTS_PKT_OK)) {
1344			ifp->if_ierrors++;
1345			nge_newbuf(sc, cur_rx, m);
1346			continue;
1347		}
1348
1349		/*
1350		 * Ok. NatSemi really screwed up here. This is the
1351		 * only gigE chip I know of with alignment constraints
1352		 * on receive buffers. RX buffers must be 64-bit aligned.
1353		 */
1354#ifdef __i386__
1355		/*
1356		 * By popular demand, ignore the alignment problems
1357		 * on the Intel x86 platform. The performance hit
1358		 * incurred due to unaligned accesses is much smaller
1359		 * than the hit produced by forcing buffer copies all
1360		 * the time, especially with jumbo frames. We still
1361		 * need to fix up the alignment everywhere else though.
1362		 */
1363		if (nge_newbuf(sc, cur_rx, NULL) == ENOBUFS) {
1364#endif
1365			m0 = m_devget(mtod(m, char *), total_len,
1366			    ETHER_ALIGN, ifp, NULL);
1367			nge_newbuf(sc, cur_rx, m);
1368			if (m0 == NULL) {
1369				printf("nge%d: no receive buffers "
1370				    "available -- packet dropped!\n",
1371				    sc->nge_unit);
1372				ifp->if_ierrors++;
1373				continue;
1374			}
1375			m = m0;
1376#ifdef __i386__
1377		} else {
1378			m->m_pkthdr.rcvif = ifp;
1379			m->m_pkthdr.len = m->m_len = total_len;
1380		}
1381#endif
1382
1383		ifp->if_ipackets++;
1384
1385		/* Do IP checksum checking. */
1386		if (extsts & NGE_RXEXTSTS_IPPKT)
1387			m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
1388		if (!(extsts & NGE_RXEXTSTS_IPCSUMERR))
1389			m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
1390		if ((extsts & NGE_RXEXTSTS_TCPPKT &&
1391		    !(extsts & NGE_RXEXTSTS_TCPCSUMERR)) ||
1392		    (extsts & NGE_RXEXTSTS_UDPPKT &&
1393		    !(extsts & NGE_RXEXTSTS_UDPCSUMERR))) {
1394			m->m_pkthdr.csum_flags |=
1395			    CSUM_DATA_VALID|CSUM_PSEUDO_HDR;
1396			m->m_pkthdr.csum_data = 0xffff;
1397		}
1398
1399		/*
1400		 * If we received a packet with a vlan tag, pass it
1401		 * to vlan_input() instead of ether_input().
1402		 */
1403		if (extsts & NGE_RXEXTSTS_VLANPKT) {
1404			VLAN_INPUT_TAG(ifp, m,
1405				extsts & NGE_RXEXTSTS_VTCI, continue);
1406		}
1407
1408		(*ifp->if_input)(ifp, m);
1409	}
1410
1411	sc->nge_cdata.nge_rx_prod = i;
1412
1413	return;
1414}
1415
1416/*
1417 * A frame was downloaded to the chip. It's safe for us to clean up
1418 * the list buffers.
1419 */
1420
1421static void
1422nge_txeof(sc)
1423	struct nge_softc	*sc;
1424{
1425	struct nge_desc		*cur_tx = NULL;
1426	struct ifnet		*ifp;
1427	u_int32_t		idx;
1428
1429	ifp = &sc->arpcom.ac_if;
1430
1431	/* Clear the timeout timer. */
1432	ifp->if_timer = 0;
1433
1434	/*
1435	 * Go through our tx list and free mbufs for those
1436	 * frames that have been transmitted.
1437	 */
1438	idx = sc->nge_cdata.nge_tx_cons;
1439	while (idx != sc->nge_cdata.nge_tx_prod) {
1440		cur_tx = &sc->nge_ldata->nge_tx_list[idx];
1441
1442		if (NGE_OWNDESC(cur_tx))
1443			break;
1444
1445		if (cur_tx->nge_ctl & NGE_CMDSTS_MORE) {
1446			sc->nge_cdata.nge_tx_cnt--;
1447			NGE_INC(idx, NGE_TX_LIST_CNT);
1448			continue;
1449		}
1450
1451		if (!(cur_tx->nge_ctl & NGE_CMDSTS_PKT_OK)) {
1452			ifp->if_oerrors++;
1453			if (cur_tx->nge_txstat & NGE_TXSTAT_EXCESSCOLLS)
1454				ifp->if_collisions++;
1455			if (cur_tx->nge_txstat & NGE_TXSTAT_OUTOFWINCOLL)
1456				ifp->if_collisions++;
1457		}
1458
1459		ifp->if_collisions +=
1460		    (cur_tx->nge_txstat & NGE_TXSTAT_COLLCNT) >> 16;
1461
1462		ifp->if_opackets++;
1463		if (cur_tx->nge_mbuf != NULL) {
1464			m_freem(cur_tx->nge_mbuf);
1465			cur_tx->nge_mbuf = NULL;
1466		}
1467
1468		sc->nge_cdata.nge_tx_cnt--;
1469		NGE_INC(idx, NGE_TX_LIST_CNT);
1470		ifp->if_timer = 0;
1471	}
1472
1473	sc->nge_cdata.nge_tx_cons = idx;
1474
1475	if (cur_tx != NULL)
1476		ifp->if_flags &= ~IFF_OACTIVE;
1477
1478	return;
1479}
1480
1481static void
1482nge_tick(xsc)
1483	void			*xsc;
1484{
1485	struct nge_softc	*sc;
1486	struct mii_data		*mii;
1487	struct ifnet		*ifp;
1488	int			s;
1489
1490	s = splimp();
1491
1492	sc = xsc;
1493	ifp = &sc->arpcom.ac_if;
1494
1495	if (sc->nge_tbi) {
1496		if (!sc->nge_link) {
1497			if (CSR_READ_4(sc, NGE_TBI_BMSR)
1498			    & NGE_TBIBMSR_ANEG_DONE) {
1499				printf("nge%d: gigabit link up\n",
1500				    sc->nge_unit);
1501				nge_miibus_statchg(sc->nge_miibus);
1502				sc->nge_link++;
1503				if (ifp->if_snd.ifq_head != NULL)
1504					nge_start(ifp);
1505			}
1506		}
1507	} else {
1508		mii = device_get_softc(sc->nge_miibus);
1509		mii_tick(mii);
1510
1511		if (!sc->nge_link) {
1512			if (mii->mii_media_status & IFM_ACTIVE &&
1513			    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
1514				sc->nge_link++;
1515				if (IFM_SUBTYPE(mii->mii_media_active)
1516				    == IFM_1000_T)
1517					printf("nge%d: gigabit link up\n",
1518					    sc->nge_unit);
1519				if (ifp->if_snd.ifq_head != NULL)
1520					nge_start(ifp);
1521			}
1522		}
1523	}
1524	sc->nge_stat_ch = timeout(nge_tick, sc, hz);
1525
1526	splx(s);
1527
1528	return;
1529}
1530
1531#ifdef DEVICE_POLLING
1532static poll_handler_t nge_poll;
1533
1534static void
1535nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
1536{
1537	struct  nge_softc *sc = ifp->if_softc;
1538
1539	if (cmd == POLL_DEREGISTER) {	/* final call, enable interrupts */
1540		CSR_WRITE_4(sc, NGE_IER, 1);
1541		return;
1542	}
1543
1544	/*
1545	 * On the nge, reading the status register also clears it.
1546	 * So before returning to intr mode we must make sure that all
1547	 * possible pending sources of interrupts have been served.
1548	 * In practice this means run to completion the *eof routines,
1549	 * and then call the interrupt routine
1550	 */
1551	sc->rxcycles = count;
1552	nge_rxeof(sc);
1553	nge_txeof(sc);
1554	if (ifp->if_snd.ifq_head != NULL)
1555		nge_start(ifp);
1556
1557	if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) {
1558		u_int32_t	status;
1559
1560		/* Reading the ISR register clears all interrupts. */
1561		status = CSR_READ_4(sc, NGE_ISR);
1562
1563		if (status & (NGE_ISR_RX_ERR|NGE_ISR_RX_OFLOW))
1564			nge_rxeof(sc);
1565
1566		if (status & (NGE_ISR_RX_IDLE))
1567			NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE);
1568
1569		if (status & NGE_ISR_SYSERR) {
1570			nge_reset(sc);
1571			nge_init(sc);
1572		}
1573	}
1574}
1575#endif /* DEVICE_POLLING */
1576
1577static void
1578nge_intr(arg)
1579	void			*arg;
1580{
1581	struct nge_softc	*sc;
1582	struct ifnet		*ifp;
1583	u_int32_t		status;
1584
1585	sc = arg;
1586	ifp = &sc->arpcom.ac_if;
1587
1588#ifdef DEVICE_POLLING
1589	if (ifp->if_ipending & IFF_POLLING)
1590		return;
1591	if (ether_poll_register(nge_poll, ifp)) { /* ok, disable interrupts */
1592		CSR_WRITE_4(sc, NGE_IER, 0);
1593		nge_poll(ifp, 0, 1);
1594		return;
1595	}
1596#endif /* DEVICE_POLLING */
1597
1598	/* Supress unwanted interrupts */
1599	if (!(ifp->if_flags & IFF_UP)) {
1600		nge_stop(sc);
1601		return;
1602	}
1603
1604	/* Disable interrupts. */
1605	CSR_WRITE_4(sc, NGE_IER, 0);
1606
1607	/* Data LED on for TBI mode */
1608	if(sc->nge_tbi)
1609		 CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO)
1610			     | NGE_GPIO_GP3_OUT);
1611
1612	for (;;) {
1613		/* Reading the ISR register clears all interrupts. */
1614		status = CSR_READ_4(sc, NGE_ISR);
1615
1616		if ((status & NGE_INTRS) == 0)
1617			break;
1618
1619		if ((status & NGE_ISR_TX_DESC_OK) ||
1620		    (status & NGE_ISR_TX_ERR) ||
1621		    (status & NGE_ISR_TX_OK) ||
1622		    (status & NGE_ISR_TX_IDLE))
1623			nge_txeof(sc);
1624
1625		if ((status & NGE_ISR_RX_DESC_OK) ||
1626		    (status & NGE_ISR_RX_ERR) ||
1627		    (status & NGE_ISR_RX_OFLOW) ||
1628		    (status & NGE_ISR_RX_FIFO_OFLOW) ||
1629		    (status & NGE_ISR_RX_IDLE) ||
1630		    (status & NGE_ISR_RX_OK))
1631			nge_rxeof(sc);
1632
1633		if ((status & NGE_ISR_RX_IDLE))
1634			NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE);
1635
1636		if (status & NGE_ISR_SYSERR) {
1637			nge_reset(sc);
1638			ifp->if_flags &= ~IFF_RUNNING;
1639			nge_init(sc);
1640		}
1641
1642#if 0
1643		/*
1644		 * XXX: nge_tick() is not ready to be called this way
1645		 * it screws up the aneg timeout because mii_tick() is
1646		 * only to be called once per second.
1647		 */
1648		if (status & NGE_IMR_PHY_INTR) {
1649			sc->nge_link = 0;
1650			nge_tick(sc);
1651		}
1652#endif
1653	}
1654
1655	/* Re-enable interrupts. */
1656	CSR_WRITE_4(sc, NGE_IER, 1);
1657
1658	if (ifp->if_snd.ifq_head != NULL)
1659		nge_start(ifp);
1660
1661	/* Data LED off for TBI mode */
1662
1663	if(sc->nge_tbi)
1664		CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO)
1665			    & ~NGE_GPIO_GP3_OUT);
1666
1667	return;
1668}
1669
1670/*
1671 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
1672 * pointers to the fragment pointers.
1673 */
1674static int
1675nge_encap(sc, m_head, txidx)
1676	struct nge_softc	*sc;
1677	struct mbuf		*m_head;
1678	u_int32_t		*txidx;
1679{
1680	struct nge_desc		*f = NULL;
1681	struct mbuf		*m;
1682	int			frag, cur, cnt = 0;
1683	struct m_tag		*mtag;
1684
1685	/*
1686 	 * Start packing the mbufs in this chain into
1687	 * the fragment pointers. Stop when we run out
1688 	 * of fragments or hit the end of the mbuf chain.
1689	 */
1690	m = m_head;
1691	cur = frag = *txidx;
1692
1693	for (m = m_head; m != NULL; m = m->m_next) {
1694		if (m->m_len != 0) {
1695			if ((NGE_TX_LIST_CNT -
1696			    (sc->nge_cdata.nge_tx_cnt + cnt)) < 2)
1697				return(ENOBUFS);
1698			f = &sc->nge_ldata->nge_tx_list[frag];
1699			f->nge_ctl = NGE_CMDSTS_MORE | m->m_len;
1700			f->nge_ptr = vtophys(mtod(m, vm_offset_t));
1701			if (cnt != 0)
1702				f->nge_ctl |= NGE_CMDSTS_OWN;
1703			cur = frag;
1704			NGE_INC(frag, NGE_TX_LIST_CNT);
1705			cnt++;
1706		}
1707	}
1708
1709	if (m != NULL)
1710		return(ENOBUFS);
1711
1712	sc->nge_ldata->nge_tx_list[*txidx].nge_extsts = 0;
1713	if (m_head->m_pkthdr.csum_flags) {
1714		if (m_head->m_pkthdr.csum_flags & CSUM_IP)
1715			sc->nge_ldata->nge_tx_list[*txidx].nge_extsts |=
1716			    NGE_TXEXTSTS_IPCSUM;
1717		if (m_head->m_pkthdr.csum_flags & CSUM_TCP)
1718			sc->nge_ldata->nge_tx_list[*txidx].nge_extsts |=
1719			    NGE_TXEXTSTS_TCPCSUM;
1720		if (m_head->m_pkthdr.csum_flags & CSUM_UDP)
1721			sc->nge_ldata->nge_tx_list[*txidx].nge_extsts |=
1722			    NGE_TXEXTSTS_UDPCSUM;
1723	}
1724
1725	mtag = VLAN_OUTPUT_TAG(&sc->arpcom.ac_if, m);
1726	if (mtag != NULL) {
1727		sc->nge_ldata->nge_tx_list[cur].nge_extsts |=
1728			(NGE_TXEXTSTS_VLANPKT|VLAN_TAG_VALUE(mtag));
1729	}
1730
1731	sc->nge_ldata->nge_tx_list[cur].nge_mbuf = m_head;
1732	sc->nge_ldata->nge_tx_list[cur].nge_ctl &= ~NGE_CMDSTS_MORE;
1733	sc->nge_ldata->nge_tx_list[*txidx].nge_ctl |= NGE_CMDSTS_OWN;
1734	sc->nge_cdata.nge_tx_cnt += cnt;
1735	*txidx = frag;
1736
1737	return(0);
1738}
1739
1740/*
1741 * Main transmit routine. To avoid having to do mbuf copies, we put pointers
1742 * to the mbuf data regions directly in the transmit lists. We also save a
1743 * copy of the pointers since the transmit list fragment pointers are
1744 * physical addresses.
1745 */
1746
1747static void
1748nge_start(ifp)
1749	struct ifnet		*ifp;
1750{
1751	struct nge_softc	*sc;
1752	struct mbuf		*m_head = NULL;
1753	u_int32_t		idx;
1754
1755	sc = ifp->if_softc;
1756
1757	if (!sc->nge_link)
1758		return;
1759
1760	idx = sc->nge_cdata.nge_tx_prod;
1761
1762	if (ifp->if_flags & IFF_OACTIVE)
1763		return;
1764
1765	while(sc->nge_ldata->nge_tx_list[idx].nge_mbuf == NULL) {
1766		IF_DEQUEUE(&ifp->if_snd, m_head);
1767		if (m_head == NULL)
1768			break;
1769
1770		if (nge_encap(sc, m_head, &idx)) {
1771			IF_PREPEND(&ifp->if_snd, m_head);
1772			ifp->if_flags |= IFF_OACTIVE;
1773			break;
1774		}
1775
1776		/*
1777		 * If there's a BPF listener, bounce a copy of this frame
1778		 * to him.
1779		 */
1780		BPF_MTAP(ifp, m_head);
1781
1782	}
1783
1784	/* Transmit */
1785	sc->nge_cdata.nge_tx_prod = idx;
1786	NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_ENABLE);
1787
1788	/*
1789	 * Set a timeout in case the chip goes out to lunch.
1790	 */
1791	ifp->if_timer = 5;
1792
1793	return;
1794}
1795
1796static void
1797nge_init(xsc)
1798	void			*xsc;
1799{
1800	struct nge_softc	*sc = xsc;
1801	struct ifnet		*ifp = &sc->arpcom.ac_if;
1802	struct mii_data		*mii;
1803	int			s;
1804
1805	if (ifp->if_flags & IFF_RUNNING)
1806		return;
1807
1808	s = splimp();
1809
1810	/*
1811	 * Cancel pending I/O and free all RX/TX buffers.
1812	 */
1813	nge_stop(sc);
1814
1815	if (sc->nge_tbi) {
1816		mii = NULL;
1817	} else {
1818		mii = device_get_softc(sc->nge_miibus);
1819	}
1820
1821	/* Set MAC address */
1822	CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR0);
1823	CSR_WRITE_4(sc, NGE_RXFILT_DATA,
1824	    ((u_int16_t *)sc->arpcom.ac_enaddr)[0]);
1825	CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR1);
1826	CSR_WRITE_4(sc, NGE_RXFILT_DATA,
1827	    ((u_int16_t *)sc->arpcom.ac_enaddr)[1]);
1828	CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR2);
1829	CSR_WRITE_4(sc, NGE_RXFILT_DATA,
1830	    ((u_int16_t *)sc->arpcom.ac_enaddr)[2]);
1831
1832	/* Init circular RX list. */
1833	if (nge_list_rx_init(sc) == ENOBUFS) {
1834		printf("nge%d: initialization failed: no "
1835			"memory for rx buffers\n", sc->nge_unit);
1836		nge_stop(sc);
1837		(void)splx(s);
1838		return;
1839	}
1840
1841	/*
1842	 * Init tx descriptors.
1843	 */
1844	nge_list_tx_init(sc);
1845
1846	/*
1847	 * For the NatSemi chip, we have to explicitly enable the
1848	 * reception of ARP frames, as well as turn on the 'perfect
1849	 * match' filter where we store the station address, otherwise
1850	 * we won't receive unicasts meant for this host.
1851	 */
1852	NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ARP);
1853	NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_PERFECT);
1854
1855	 /* If we want promiscuous mode, set the allframes bit. */
1856	if (ifp->if_flags & IFF_PROMISC) {
1857		NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ALLPHYS);
1858	} else {
1859		NGE_CLRBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ALLPHYS);
1860	}
1861
1862	/*
1863	 * Set the capture broadcast bit to capture broadcast frames.
1864	 */
1865	if (ifp->if_flags & IFF_BROADCAST) {
1866		NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_BROAD);
1867	} else {
1868		NGE_CLRBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_BROAD);
1869	}
1870
1871	/*
1872	 * Load the multicast filter.
1873	 */
1874	nge_setmulti(sc);
1875
1876	/* Turn the receive filter on */
1877	NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ENABLE);
1878
1879	/*
1880	 * Load the address of the RX and TX lists.
1881	 */
1882	CSR_WRITE_4(sc, NGE_RX_LISTPTR,
1883	    vtophys(&sc->nge_ldata->nge_rx_list[0]));
1884	CSR_WRITE_4(sc, NGE_TX_LISTPTR,
1885	    vtophys(&sc->nge_ldata->nge_tx_list[0]));
1886
1887	/* Set RX configuration */
1888	CSR_WRITE_4(sc, NGE_RX_CFG, NGE_RXCFG);
1889	/*
1890	 * Enable hardware checksum validation for all IPv4
1891	 * packets, do not reject packets with bad checksums.
1892	 */
1893	CSR_WRITE_4(sc, NGE_VLAN_IP_RXCTL, NGE_VIPRXCTL_IPCSUM_ENB);
1894
1895	/*
1896	 * Tell the chip to detect and strip VLAN tag info from
1897	 * received frames. The tag will be provided in the extsts
1898	 * field in the RX descriptors.
1899	 */
1900	NGE_SETBIT(sc, NGE_VLAN_IP_RXCTL,
1901	    NGE_VIPRXCTL_TAG_DETECT_ENB|NGE_VIPRXCTL_TAG_STRIP_ENB);
1902
1903	/* Set TX configuration */
1904	CSR_WRITE_4(sc, NGE_TX_CFG, NGE_TXCFG);
1905
1906	/*
1907	 * Enable TX IPv4 checksumming on a per-packet basis.
1908	 */
1909	CSR_WRITE_4(sc, NGE_VLAN_IP_TXCTL, NGE_VIPTXCTL_CSUM_PER_PKT);
1910
1911	/*
1912	 * Tell the chip to insert VLAN tags on a per-packet basis as
1913	 * dictated by the code in the frame encapsulation routine.
1914	 */
1915	NGE_SETBIT(sc, NGE_VLAN_IP_TXCTL, NGE_VIPTXCTL_TAG_PER_PKT);
1916
1917	/* Set full/half duplex mode. */
1918	if (sc->nge_tbi) {
1919		if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK)
1920		    == IFM_FDX) {
1921			NGE_SETBIT(sc, NGE_TX_CFG,
1922			    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
1923			NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
1924		} else {
1925			NGE_CLRBIT(sc, NGE_TX_CFG,
1926			    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
1927			NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
1928		}
1929	} else {
1930		if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
1931			NGE_SETBIT(sc, NGE_TX_CFG,
1932			    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
1933			NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
1934		} else {
1935			NGE_CLRBIT(sc, NGE_TX_CFG,
1936			    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
1937			NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
1938		}
1939	}
1940
1941	nge_tick(sc);
1942
1943	/*
1944	 * Enable the delivery of PHY interrupts based on
1945	 * link/speed/duplex status changes. Also enable the
1946	 * extsts field in the DMA descriptors (needed for
1947	 * TCP/IP checksum offload on transmit).
1948	 */
1949	NGE_SETBIT(sc, NGE_CFG, NGE_CFG_PHYINTR_SPD|
1950	    NGE_CFG_PHYINTR_LNK|NGE_CFG_PHYINTR_DUP|NGE_CFG_EXTSTS_ENB);
1951
1952	/*
1953	 * Configure interrupt holdoff (moderation). We can
1954	 * have the chip delay interrupt delivery for a certain
1955	 * period. Units are in 100us, and the max setting
1956	 * is 25500us (0xFF x 100us). Default is a 100us holdoff.
1957	 */
1958	CSR_WRITE_4(sc, NGE_IHR, 0x01);
1959
1960	/*
1961	 * Enable interrupts.
1962	 */
1963	CSR_WRITE_4(sc, NGE_IMR, NGE_INTRS);
1964#ifdef DEVICE_POLLING
1965	/*
1966	 * ... only enable interrupts if we are not polling, make sure
1967	 * they are off otherwise.
1968	 */
1969	if (ifp->if_ipending & IFF_POLLING)
1970		CSR_WRITE_4(sc, NGE_IER, 0);
1971	else
1972#endif /* DEVICE_POLLING */
1973	CSR_WRITE_4(sc, NGE_IER, 1);
1974
1975	/* Enable receiver and transmitter. */
1976	NGE_CLRBIT(sc, NGE_CSR, NGE_CSR_TX_DISABLE|NGE_CSR_RX_DISABLE);
1977	NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE);
1978
1979	nge_ifmedia_upd(ifp);
1980
1981	ifp->if_flags |= IFF_RUNNING;
1982	ifp->if_flags &= ~IFF_OACTIVE;
1983
1984	(void)splx(s);
1985
1986	return;
1987}
1988
1989/*
1990 * Set media options.
1991 */
1992static int
1993nge_ifmedia_upd(ifp)
1994	struct ifnet		*ifp;
1995{
1996	struct nge_softc	*sc;
1997	struct mii_data		*mii;
1998
1999	sc = ifp->if_softc;
2000
2001	if (sc->nge_tbi) {
2002		if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media)
2003		     == IFM_AUTO) {
2004			CSR_WRITE_4(sc, NGE_TBI_ANAR,
2005				CSR_READ_4(sc, NGE_TBI_ANAR)
2006					| NGE_TBIANAR_HDX | NGE_TBIANAR_FDX
2007					| NGE_TBIANAR_PS1 | NGE_TBIANAR_PS2);
2008			CSR_WRITE_4(sc, NGE_TBI_BMCR, NGE_TBIBMCR_ENABLE_ANEG
2009				| NGE_TBIBMCR_RESTART_ANEG);
2010			CSR_WRITE_4(sc, NGE_TBI_BMCR, NGE_TBIBMCR_ENABLE_ANEG);
2011		} else if ((sc->nge_ifmedia.ifm_cur->ifm_media
2012			    & IFM_GMASK) == IFM_FDX) {
2013			NGE_SETBIT(sc, NGE_TX_CFG,
2014			    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
2015			NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
2016
2017			CSR_WRITE_4(sc, NGE_TBI_ANAR, 0);
2018			CSR_WRITE_4(sc, NGE_TBI_BMCR, 0);
2019		} else {
2020			NGE_CLRBIT(sc, NGE_TX_CFG,
2021			    (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR));
2022			NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX);
2023
2024			CSR_WRITE_4(sc, NGE_TBI_ANAR, 0);
2025			CSR_WRITE_4(sc, NGE_TBI_BMCR, 0);
2026		}
2027
2028		CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO)
2029			    & ~NGE_GPIO_GP3_OUT);
2030	} else {
2031		mii = device_get_softc(sc->nge_miibus);
2032		sc->nge_link = 0;
2033		if (mii->mii_instance) {
2034			struct mii_softc	*miisc;
2035			for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
2036			    miisc = LIST_NEXT(miisc, mii_list))
2037				mii_phy_reset(miisc);
2038		}
2039		mii_mediachg(mii);
2040	}
2041
2042	return(0);
2043}
2044
2045/*
2046 * Report current media status.
2047 */
2048static void
2049nge_ifmedia_sts(ifp, ifmr)
2050	struct ifnet		*ifp;
2051	struct ifmediareq	*ifmr;
2052{
2053	struct nge_softc	*sc;
2054	struct mii_data		*mii;
2055
2056	sc = ifp->if_softc;
2057
2058	if (sc->nge_tbi) {
2059		ifmr->ifm_status = IFM_AVALID;
2060		ifmr->ifm_active = IFM_ETHER;
2061
2062		if (CSR_READ_4(sc, NGE_TBI_BMSR) & NGE_TBIBMSR_ANEG_DONE) {
2063			ifmr->ifm_status |= IFM_ACTIVE;
2064		}
2065		if (CSR_READ_4(sc, NGE_TBI_BMCR) & NGE_TBIBMCR_LOOPBACK)
2066			ifmr->ifm_active |= IFM_LOOP;
2067		if (!CSR_READ_4(sc, NGE_TBI_BMSR) & NGE_TBIBMSR_ANEG_DONE) {
2068			ifmr->ifm_active |= IFM_NONE;
2069			ifmr->ifm_status = 0;
2070			return;
2071		}
2072		ifmr->ifm_active |= IFM_1000_SX;
2073		if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media)
2074		    == IFM_AUTO) {
2075			ifmr->ifm_active |= IFM_AUTO;
2076			if (CSR_READ_4(sc, NGE_TBI_ANLPAR)
2077			    & NGE_TBIANAR_FDX) {
2078				ifmr->ifm_active |= IFM_FDX;
2079			}else if (CSR_READ_4(sc, NGE_TBI_ANLPAR)
2080				  & NGE_TBIANAR_HDX) {
2081				ifmr->ifm_active |= IFM_HDX;
2082			}
2083		} else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK)
2084			== IFM_FDX)
2085			ifmr->ifm_active |= IFM_FDX;
2086		else
2087			ifmr->ifm_active |= IFM_HDX;
2088
2089	} else {
2090		mii = device_get_softc(sc->nge_miibus);
2091		mii_pollstat(mii);
2092		ifmr->ifm_active = mii->mii_media_active;
2093		ifmr->ifm_status = mii->mii_media_status;
2094	}
2095
2096	return;
2097}
2098
2099static int
2100nge_ioctl(ifp, command, data)
2101	struct ifnet		*ifp;
2102	u_long			command;
2103	caddr_t			data;
2104{
2105	struct nge_softc	*sc = ifp->if_softc;
2106	struct ifreq		*ifr = (struct ifreq *) data;
2107	struct mii_data		*mii;
2108	int			s, error = 0;
2109
2110	s = splimp();
2111
2112	switch(command) {
2113	case SIOCSIFMTU:
2114		if (ifr->ifr_mtu > NGE_JUMBO_MTU)
2115			error = EINVAL;
2116		else {
2117			ifp->if_mtu = ifr->ifr_mtu;
2118			/*
2119			 * Workaround: if the MTU is larger than
2120			 * 8152 (TX FIFO size minus 64 minus 18), turn off
2121			 * TX checksum offloading.
2122			 */
2123			if (ifr->ifr_mtu >= 8152)
2124				ifp->if_hwassist = 0;
2125			else
2126				ifp->if_hwassist = NGE_CSUM_FEATURES;
2127		}
2128		break;
2129	case SIOCSIFFLAGS:
2130		if (ifp->if_flags & IFF_UP) {
2131			if (ifp->if_flags & IFF_RUNNING &&
2132			    ifp->if_flags & IFF_PROMISC &&
2133			    !(sc->nge_if_flags & IFF_PROMISC)) {
2134				NGE_SETBIT(sc, NGE_RXFILT_CTL,
2135				    NGE_RXFILTCTL_ALLPHYS|
2136				    NGE_RXFILTCTL_ALLMULTI);
2137			} else if (ifp->if_flags & IFF_RUNNING &&
2138			    !(ifp->if_flags & IFF_PROMISC) &&
2139			    sc->nge_if_flags & IFF_PROMISC) {
2140				NGE_CLRBIT(sc, NGE_RXFILT_CTL,
2141				    NGE_RXFILTCTL_ALLPHYS);
2142				if (!(ifp->if_flags & IFF_ALLMULTI))
2143					NGE_CLRBIT(sc, NGE_RXFILT_CTL,
2144					    NGE_RXFILTCTL_ALLMULTI);
2145			} else {
2146				ifp->if_flags &= ~IFF_RUNNING;
2147				nge_init(sc);
2148			}
2149		} else {
2150			if (ifp->if_flags & IFF_RUNNING)
2151				nge_stop(sc);
2152		}
2153		sc->nge_if_flags = ifp->if_flags;
2154		error = 0;
2155		break;
2156	case SIOCADDMULTI:
2157	case SIOCDELMULTI:
2158		nge_setmulti(sc);
2159		error = 0;
2160		break;
2161	case SIOCGIFMEDIA:
2162	case SIOCSIFMEDIA:
2163		if (sc->nge_tbi) {
2164			error = ifmedia_ioctl(ifp, ifr, &sc->nge_ifmedia,
2165					      command);
2166		} else {
2167			mii = device_get_softc(sc->nge_miibus);
2168			error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
2169					      command);
2170		}
2171		break;
2172	default:
2173		error = ether_ioctl(ifp, command, data);
2174		break;
2175	}
2176
2177	(void)splx(s);
2178
2179	return(error);
2180}
2181
2182static void
2183nge_watchdog(ifp)
2184	struct ifnet		*ifp;
2185{
2186	struct nge_softc	*sc;
2187
2188	sc = ifp->if_softc;
2189
2190	ifp->if_oerrors++;
2191	printf("nge%d: watchdog timeout\n", sc->nge_unit);
2192
2193	nge_stop(sc);
2194	nge_reset(sc);
2195	ifp->if_flags &= ~IFF_RUNNING;
2196	nge_init(sc);
2197
2198	if (ifp->if_snd.ifq_head != NULL)
2199		nge_start(ifp);
2200
2201	return;
2202}
2203
2204/*
2205 * Stop the adapter and free any mbufs allocated to the
2206 * RX and TX lists.
2207 */
2208static void
2209nge_stop(sc)
2210	struct nge_softc	*sc;
2211{
2212	register int		i;
2213	struct ifnet		*ifp;
2214	struct mii_data		*mii;
2215
2216	ifp = &sc->arpcom.ac_if;
2217	ifp->if_timer = 0;
2218	if (sc->nge_tbi) {
2219		mii = NULL;
2220	} else {
2221		mii = device_get_softc(sc->nge_miibus);
2222	}
2223
2224	untimeout(nge_tick, sc, sc->nge_stat_ch);
2225#ifdef DEVICE_POLLING
2226	ether_poll_deregister(ifp);
2227#endif
2228	CSR_WRITE_4(sc, NGE_IER, 0);
2229	CSR_WRITE_4(sc, NGE_IMR, 0);
2230	NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_DISABLE|NGE_CSR_RX_DISABLE);
2231	DELAY(1000);
2232	CSR_WRITE_4(sc, NGE_TX_LISTPTR, 0);
2233	CSR_WRITE_4(sc, NGE_RX_LISTPTR, 0);
2234
2235	if (!sc->nge_tbi)
2236		mii_down(mii);
2237
2238	sc->nge_link = 0;
2239
2240	/*
2241	 * Free data in the RX lists.
2242	 */
2243	for (i = 0; i < NGE_RX_LIST_CNT; i++) {
2244		if (sc->nge_ldata->nge_rx_list[i].nge_mbuf != NULL) {
2245			m_freem(sc->nge_ldata->nge_rx_list[i].nge_mbuf);
2246			sc->nge_ldata->nge_rx_list[i].nge_mbuf = NULL;
2247		}
2248	}
2249	bzero((char *)&sc->nge_ldata->nge_rx_list,
2250		sizeof(sc->nge_ldata->nge_rx_list));
2251
2252	/*
2253	 * Free the TX list buffers.
2254	 */
2255	for (i = 0; i < NGE_TX_LIST_CNT; i++) {
2256		if (sc->nge_ldata->nge_tx_list[i].nge_mbuf != NULL) {
2257			m_freem(sc->nge_ldata->nge_tx_list[i].nge_mbuf);
2258			sc->nge_ldata->nge_tx_list[i].nge_mbuf = NULL;
2259		}
2260	}
2261
2262	bzero((char *)&sc->nge_ldata->nge_tx_list,
2263		sizeof(sc->nge_ldata->nge_tx_list));
2264
2265	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2266
2267	return;
2268}
2269
2270/*
2271 * Stop all chip I/O so that the kernel's probe routines don't
2272 * get confused by errant DMAs when rebooting.
2273 */
2274static void
2275nge_shutdown(dev)
2276	device_t		dev;
2277{
2278	struct nge_softc	*sc;
2279
2280	sc = device_get_softc(dev);
2281
2282	nge_reset(sc);
2283	nge_stop(sc);
2284
2285	return;
2286}
2287