if_ex.c revision 57987
1/*
2 * Copyright (c) 1996, Javier Mart�n Rueda (jmrueda@diatel.upm.es)
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice unmodified, this list of conditions, and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/dev/ex/if_ex.c 57987 2000-03-13 12:23:32Z mdodd $
28 *
29 * MAINTAINER: Matthew N. Dodd <winter@jurai.net>
30 *                             <mdodd@FreeBSD.org>
31 */
32
33/*
34 * Intel EtherExpress Pro/10, Pro/10+ Ethernet driver
35 *
36 * Revision history:
37 *
38 * 30-Oct-1996: first beta version. Inet and BPF supported, but no multicast.
39 */
40
41#include "ex.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/kernel.h>
46#include <sys/conf.h>
47#include <sys/sockio.h>
48#include <sys/mbuf.h>
49#include <sys/socket.h>
50
51#include <sys/module.h>
52#include <sys/bus.h>
53
54#include <machine/bus.h>
55#include <machine/resource.h>
56#include <sys/rman.h>
57
58#include <net/if.h>
59#include <net/if_arp.h>
60#include <net/if_media.h>
61#include <net/ethernet.h>
62#include <net/bpf.h>
63
64#include <netinet/in.h>
65#include <netinet/if_ether.h>
66
67#include <machine/clock.h>
68
69#include <isa/isavar.h>
70#include <isa/pnpvar.h>
71
72#include <dev/ex/if_exreg.h>
73
74#ifdef EXDEBUG
75# define Start_End 1
76# define Rcvd_Pkts 2
77# define Sent_Pkts 4
78# define Status    8
79static int debug_mask = 0;
80static int exintr_count = 0;
81# define DODEBUG(level, action) if (level & debug_mask) action
82#else
83# define DODEBUG(level, action)
84#endif
85
86#define CARD_TYPE_EX_10		1
87#define CARD_TYPE_EX_10_PLUS	2
88
89struct ex_softc {
90  	struct arpcom	arpcom;		/* Ethernet common data */
91	struct ifmedia	ifmedia;
92
93	device_t	dev;
94	struct resource *ioport;
95	struct resource *irq;
96
97	u_int		iobase;		/* I/O base address. */
98	u_short		irq_no;		/* IRQ number. */
99
100	char *		irq2ee;		/* irq <-> internal		*/
101	u_char *	ee2irq;		/* representation conversion	*/
102
103	u_int		mem_size;	/* Total memory size, in bytes. */
104	u_int		rx_mem_size;	/* Rx memory size (by default,	*/
105					/* first 3/4 of total memory).	*/
106
107	u_int		rx_lower_limit;	/* Lower and upper limits of	*/
108	u_int		rx_upper_limit;	/* receive buffer.		*/
109
110	u_int		rx_head;	/* Head of receive ring buffer. */
111	u_int		tx_mem_size;	/* Tx memory size (by default,	*/
112					/* last quarter of total memory).*/
113
114	u_int		tx_lower_limit;	/* Lower and upper limits of	*/
115	u_int		tx_upper_limit;	/* transmit buffer.		*/
116
117	u_int		tx_head;	/* Head and tail of 		*/
118	u_int		tx_tail;	/* transmit ring buffer.	*/
119
120	u_int		tx_last;	/* Pointer to beginning of last	*/
121					/* frame in the chain.		*/
122};
123
124static char irq2eemap[] =
125	{ -1, -1, 0, 1, -1, 2, -1, -1, -1, 0, 3, 4, -1, -1, -1, -1 };
126static u_char ee2irqmap[] =
127	{ 9, 3, 5, 10, 11, 0, 0, 0 };
128
129static char plus_irq2eemap[] =
130	{ -1, -1, -1, 0, 1, 2, -1, 3, -1, 4, 5, 6, 7, -1, -1, -1 };
131static u_char plus_ee2irqmap[] =
132	{ 3, 4, 5, 7, 9, 10, 11, 12 };
133
134/* Bus Front End Functions */
135static void	ex_isa_identify	__P((driver_t *, device_t));
136static int	ex_isa_probe	__P((device_t));
137static int	ex_isa_attach	__P((device_t));
138
139/* Network Interface Functions */
140static void	ex_init		__P((void *));
141static void	ex_start	__P((struct ifnet *));
142static int	ex_ioctl	__P((struct ifnet *, u_long, caddr_t));
143static void	ex_watchdog	__P((struct ifnet *));
144
145/* ifmedia Functions	*/
146static int	ex_ifmedia_upd	__P((struct ifnet *));
147static void	ex_ifmedia_sts	__P((struct ifnet *, struct ifmediareq *));
148
149static void	ex_stop		__P((struct ex_softc *));
150static void	ex_reset	__P((struct ex_softc *));
151
152static driver_intr_t	ex_intr;
153static void	ex_tx_intr	__P((struct ex_softc *));
154static void	ex_rx_intr	__P((struct ex_softc *));
155
156static u_short	eeprom_read	__P((int, int));
157
158static device_method_t ex_methods[] = {
159	/* Device interface */
160	DEVMETHOD(device_identify,	ex_isa_identify),
161	DEVMETHOD(device_probe,		ex_isa_probe),
162	DEVMETHOD(device_attach,	ex_isa_attach),
163
164	{ 0, 0 }
165};
166
167static driver_t ex_driver = {
168	"ex",
169	ex_methods,
170	sizeof(struct ex_softc),
171};
172
173static devclass_t ex_devclass;
174
175DRIVER_MODULE(ex, isa, ex_driver, ex_devclass, 0, 0);
176
177static struct isa_pnp_id ex_ids[] = {
178	{ 0x3110d425,	NULL },	/* INT1031 */
179	{ 0x3010d425,	NULL },	/* INT1030 */
180	{ 0,		NULL },
181};
182
183static int
184look_for_card (u_int iobase)
185{
186	int count1, count2;
187
188	/*
189	 * Check for the i82595 signature, and check that the round robin
190	 * counter actually advances.
191	 */
192	if (((count1 = inb(iobase + ID_REG)) & Id_Mask) != Id_Sig)
193		return(0);
194	count2 = inb(iobase + ID_REG);
195	count2 = inb(iobase + ID_REG);
196	count2 = inb(iobase + ID_REG);
197
198	return((count2 & Counter_bits) == ((count1 + 0xc0) & Counter_bits));
199}
200
201static int
202ex_get_media (u_int32_t iobase)
203{
204	int	tmp;
205
206	outb(iobase + CMD_REG, Bank2_Sel);
207	tmp = inb(iobase + REG3);
208	outb(iobase + CMD_REG, Bank0_Sel);
209
210	if (tmp & TPE_bit)
211		return(IFM_ETHER|IFM_10_T);
212	if (tmp & BNC_bit)
213		return(IFM_ETHER|IFM_10_2);
214
215	return (IFM_ETHER|IFM_10_5);
216}
217
218static void
219ex_get_address (u_int32_t iobase, u_char *enaddr)
220{
221	u_int16_t	eaddr_tmp;
222
223	eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Lo);
224	enaddr[5] = eaddr_tmp & 0xff;
225	enaddr[4] = eaddr_tmp >> 8;
226	eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Mid);
227	enaddr[3] = eaddr_tmp & 0xff;
228	enaddr[2] = eaddr_tmp >> 8;
229	eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Hi);
230	enaddr[1] = eaddr_tmp & 0xff;
231	enaddr[0] = eaddr_tmp >> 8;
232
233	return;
234}
235
236static int
237ex_card_type (u_char *enaddr)
238{
239	if ((enaddr[0] == 0x00) && (enaddr[1] == 0xA0) && (enaddr[2] == 0xC9))
240		return (CARD_TYPE_EX_10_PLUS);
241
242	return (CARD_TYPE_EX_10);
243}
244
245/*
246 * Non-destructive identify.
247 */
248static void
249ex_isa_identify (driver_t *driver, device_t parent)
250{
251	device_t	child;
252	u_int32_t	ioport;
253	u_char 		enaddr[6];
254	u_int		irq;
255	int		tmp;
256	const char *	desc;
257
258	for (ioport = 0x200; ioport < 0x3a0; ioport += 0x10) {
259
260		/* No board found at address */
261		if (!look_for_card(ioport)) {
262			continue;
263		}
264
265		/* Board in PnP mode */
266		if (eeprom_read(ioport, 0) & 0x01) {
267			continue;
268		}
269
270		bzero(enaddr, sizeof(enaddr));
271
272		/* Reset the card. */
273		outb(ioport + CMD_REG, Reset_CMD);
274		DELAY(400);
275
276		ex_get_address(ioport, enaddr);
277		tmp = eeprom_read(ioport, EE_IRQ_No) & IRQ_No_Mask;
278
279		/* work out which set of irq <-> internal tables to use */
280		if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) {
281			irq  = plus_ee2irqmap[tmp];
282			desc = "Intel Pro/10+";
283		} else {
284			irq = ee2irqmap[tmp];
285			desc = "Intel Pro/10";
286		}
287
288		child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ex", -1);
289		device_set_desc_copy(child, desc);
290		device_set_driver(child, driver);
291		bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
292		bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, EX_IOSIZE);
293	}
294
295	return;
296}
297
298static int
299ex_isa_probe(device_t dev)
300{
301	u_int		iobase;
302	u_int		irq;
303	char *		irq2ee;
304	u_char *	ee2irq;
305	u_char 		enaddr[6];
306	int		tmp;
307	int		error;
308
309	DODEBUG(Start_End, printf("ex_probe: start\n"););
310
311	/* Check isapnp ids */
312	error = ISA_PNP_PROBE(device_get_parent(dev), dev, ex_ids);
313
314	/* If the card had a PnP ID that didn't match any we know about */
315	if (error == ENXIO) {
316		return(error);
317	}
318
319	/* If we had some other problem. */
320	if (!(error == 0 || error == ENOENT)) {
321		return(error);
322	}
323
324	iobase = bus_get_resource_start(dev, SYS_RES_IOPORT, 0);
325	if (iobase && !look_for_card(iobase)) {
326		printf("ex: no card found at 0x%03x\n", iobase);
327		return(ENXIO);
328	}
329
330	/*
331	 * Reset the card.
332	 */
333	outb(iobase + CMD_REG, Reset_CMD);
334	DELAY(400);
335
336	ex_get_address(iobase, enaddr);
337
338	/* work out which set of irq <-> internal tables to use */
339	if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) {
340		irq2ee = plus_irq2eemap;
341		ee2irq = plus_ee2irqmap;
342	} else {
343		irq2ee = irq2eemap;
344		ee2irq = ee2irqmap;
345	}
346
347	tmp = eeprom_read(iobase, EE_IRQ_No) & IRQ_No_Mask;
348	irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0);
349
350	if (irq > 0) {
351		/* This will happen if board is in PnP mode. */
352		if (ee2irq[tmp] != irq) {
353			printf("ex: WARNING: board's EEPROM is configured"
354				" for IRQ %d, using %d\n",
355				ee2irq[tmp], irq);
356		}
357	} else {
358		irq = ee2irq[tmp];
359		bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1);
360	}
361
362	if (irq == 0) {
363		printf("ex: invalid IRQ.\n");
364		return(ENXIO);
365	}
366
367	DODEBUG(Start_End, printf("ex_probe: finish\n"););
368
369	return(0);
370}
371
372static int
373ex_isa_attach(device_t dev)
374{
375	struct ex_softc *	sc = device_get_softc(dev);
376	struct ifnet *		ifp = &sc->arpcom.ac_if;
377	struct ifmedia *	ifm;
378	int			unit = device_get_unit(dev);
379	int			error;
380	int			rid;
381	void *			ih;
382	u_int16_t		temp;
383
384	DODEBUG(Start_End, device_printf(dev, "start\n"););
385
386	rid = 0;
387	sc->ioport  = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
388					 0, ~0, 1, RF_ACTIVE);
389
390	if (!sc->ioport) {
391		device_printf(dev, "No I/O space?!\n");
392		goto bad;
393	}
394
395	rid = 0;
396	sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
397				     0, ~0, 1, RF_ACTIVE);
398
399	if (!sc->irq) {
400		device_printf(dev, "No IRQ?!\n");
401		goto bad;
402	}
403
404	error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
405			       ex_intr, (void *)sc, &ih);
406
407	if (error) {
408		device_printf(dev, "bus_setup_intr() failed!\n");
409		goto bad;
410	}
411
412	/*
413	 * Fill in several fields of the softc structure:
414	 *	- I/O base address.
415	 *	- Hardware Ethernet address.
416	 *	- IRQ number (if not supplied in config file, read it from EEPROM).
417	 *	- Connector type.
418	 */
419	sc->dev = dev;
420	sc->iobase = rman_get_start(sc->ioport);
421	sc->irq_no = rman_get_start(sc->irq);
422
423	ex_get_address(sc->iobase, sc->arpcom.ac_enaddr);
424
425	/* work out which set of irq <-> internal tables to use */
426	if (ex_card_type(sc->arpcom.ac_enaddr) == CARD_TYPE_EX_10_PLUS) {
427		sc->irq2ee = plus_irq2eemap;
428		sc->ee2irq = plus_ee2irqmap;
429	} else {
430		sc->irq2ee = irq2eemap;
431		sc->ee2irq = ee2irqmap;
432	}
433
434	sc->mem_size = CARD_RAM_SIZE;	/* XXX This should be read from the card itself. */
435
436	/*
437	 * Initialize the ifnet structure.
438	 */
439	ifp->if_softc = sc;
440	ifp->if_unit = unit;
441	ifp->if_name = "ex";
442	ifp->if_mtu = ETHERMTU;
443	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST /* XXX not done yet. | IFF_MULTICAST */;
444	ifp->if_output = ether_output;
445	ifp->if_start = ex_start;
446	ifp->if_ioctl = ex_ioctl;
447	ifp->if_watchdog = ex_watchdog;
448	ifp->if_init = ex_init;
449	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
450
451	ifmedia_init(&sc->ifmedia, 0, ex_ifmedia_upd, ex_ifmedia_sts);
452
453	temp = eeprom_read(sc->iobase, EE_W5);
454	if (temp & EE_W5_PORT_TPE)
455		ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
456	if (temp & EE_W5_PORT_BNC)
457		ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL);
458	if (temp & EE_W5_PORT_AUI)
459		ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL);
460
461	ifmedia_set(&sc->ifmedia, ex_get_media(sc->iobase));
462
463	ifm = &sc->ifmedia;
464	ifm->ifm_media = ifm->ifm_cur->ifm_media;
465	ex_ifmedia_upd(ifp);
466
467	/*
468	 * Attach the interface.
469	 */
470	if_attach(ifp);
471	ether_ifattach(ifp);
472
473	temp = eeprom_read(sc->iobase, EE_W0);
474	device_printf(sc->dev, "%s config, %s bus, ",
475		(temp & EE_W0_PNP) ? "PnP" : "Manual",
476		(temp & EE_W0_BUS16) ? "16-bit" : "8-bit");
477
478	temp = eeprom_read(sc->iobase, EE_W6);
479	printf("board id 0x%03x, stepping 0x%01x\n",
480			(temp & EE_W6_BOARD_MASK) >> EE_W6_BOARD_SHIFT,
481			temp & EE_W6_STEP_MASK);
482
483	device_printf(sc->dev, "Ethernet address %6D\n",
484			sc->arpcom.ac_enaddr, ":");
485	/*
486	 * If BPF is in the kernel, call the attach for it
487	 */
488	bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
489	DODEBUG(Start_End, printf("ex_isa_attach%d: finish\n", unit););
490
491	return(0);
492bad:
493
494	if (sc->ioport)
495		bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->ioport);
496	if (sc->irq)
497		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
498
499	return (-1);
500}
501
502
503static void
504ex_init(void *xsc)
505{
506	struct ex_softc *	sc = (struct ex_softc *) xsc;
507	struct ifnet *		ifp = &sc->arpcom.ac_if;
508	int			s;
509	int			i;
510	register int		iobase = sc->iobase;
511	unsigned short		temp_reg;
512
513	DODEBUG(Start_End, printf("ex_init%d: start\n", ifp->if_unit););
514
515	if (ifp->if_addrhead.tqh_first == NULL) {
516		return;
517	}
518	s = splimp();
519	sc->arpcom.ac_if.if_timer = 0;
520
521	/*
522	 * Load the ethernet address into the card.
523	 */
524	outb(iobase + CMD_REG, Bank2_Sel);
525	temp_reg = inb(iobase + EEPROM_REG);
526	if (temp_reg & Trnoff_Enable) {
527		outb(iobase + EEPROM_REG, temp_reg & ~Trnoff_Enable);
528	}
529	for (i = 0; i < ETHER_ADDR_LEN; i++) {
530		outb(iobase + I_ADDR_REG0 + i, sc->arpcom.ac_enaddr[i]);
531	}
532	/*
533	 * - Setup transmit chaining and discard bad received frames.
534	 * - Match broadcast.
535	 * - Clear test mode.
536	 * - Set receiving mode.
537	 * - Set IRQ number.
538	 */
539	outb(iobase + REG1, inb(iobase + REG1) | Tx_Chn_Int_Md | Tx_Chn_ErStp | Disc_Bad_Fr);
540	outb(iobase + REG2, inb(iobase + REG2) | No_SA_Ins | RX_CRC_InMem);
541	outb(iobase + REG3, inb(iobase + REG3) & 0x3f /* XXX constants. */ );
542	outb(iobase + CMD_REG, Bank1_Sel);
543	outb(iobase + INT_NO_REG, (inb(iobase + INT_NO_REG) & 0xf8) | sc->irq2ee[sc->irq_no]);
544
545	/*
546	 * Divide the available memory in the card into rcv and xmt buffers.
547	 * By default, I use the first 3/4 of the memory for the rcv buffer,
548	 * and the remaining 1/4 of the memory for the xmt buffer.
549	 */
550	sc->rx_mem_size = sc->mem_size * 3 / 4;
551	sc->tx_mem_size = sc->mem_size - sc->rx_mem_size;
552	sc->rx_lower_limit = 0x0000;
553	sc->rx_upper_limit = sc->rx_mem_size - 2;
554	sc->tx_lower_limit = sc->rx_mem_size;
555	sc->tx_upper_limit = sc->mem_size - 2;
556	outb(iobase + RCV_LOWER_LIMIT_REG, sc->rx_lower_limit >> 8);
557	outb(iobase + RCV_UPPER_LIMIT_REG, sc->rx_upper_limit >> 8);
558	outb(iobase + XMT_LOWER_LIMIT_REG, sc->tx_lower_limit >> 8);
559	outb(iobase + XMT_UPPER_LIMIT_REG, sc->tx_upper_limit >> 8);
560
561	/*
562	 * Enable receive and transmit interrupts, and clear any pending int.
563	 */
564	outb(iobase + REG1, inb(iobase + REG1) | TriST_INT);
565	outb(iobase + CMD_REG, Bank0_Sel);
566	outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int));
567	outb(iobase + STATUS_REG, All_Int);
568
569	/*
570	 * Initialize receive and transmit ring buffers.
571	 */
572	outw(iobase + RCV_BAR, sc->rx_lower_limit);
573	sc->rx_head = sc->rx_lower_limit;
574	outw(iobase + RCV_STOP_REG, sc->rx_upper_limit | 0xfe);
575	outw(iobase + XMT_BAR, sc->tx_lower_limit);
576	sc->tx_head = sc->tx_tail = sc->tx_lower_limit;
577
578	ifp->if_flags |= IFF_RUNNING;
579	ifp->if_flags &= ~IFF_OACTIVE;
580	DODEBUG(Status, printf("OIDLE init\n"););
581
582	/*
583	 * Final reset of the board, and enable operation.
584	 */
585	outb(iobase + CMD_REG, Sel_Reset_CMD);
586	DELAY(2);
587	outb(iobase + CMD_REG, Rcv_Enable_CMD);
588
589	ex_start(ifp);
590	splx(s);
591
592	DODEBUG(Start_End, printf("ex_init%d: finish\n", ifp->if_unit););
593}
594
595
596static void
597ex_start(struct ifnet *ifp)
598{
599	struct ex_softc *	sc = ifp->if_softc;
600	int			iobase = sc->iobase;
601	int			i, s, len, data_len, avail, dest, next;
602	unsigned char		tmp16[2];
603	struct mbuf *		opkt;
604	struct mbuf *		m;
605
606	DODEBUG(Start_End, printf("ex_start%d: start\n", unit););
607
608	s = splimp();
609
610	/*
611	 * Main loop: send outgoing packets to network card until there are no
612	 * more packets left, or the card cannot accept any more yet.
613	 */
614	while (((opkt = ifp->if_snd.ifq_head) != NULL) &&
615	       !(ifp->if_flags & IFF_OACTIVE)) {
616
617		/*
618		 * Ensure there is enough free transmit buffer space for
619		 * this packet, including its header. Note: the header
620		 * cannot wrap around the end of the transmit buffer and
621		 * must be kept together, so we allow space for twice the
622		 * length of the header, just in case.
623		 */
624
625		for (len = 0, m = opkt; m != NULL; m = m->m_next) {
626			len += m->m_len;
627		}
628
629		data_len = len;
630
631		DODEBUG(Sent_Pkts, printf("1. Sending packet with %d data bytes. ", data_len););
632
633		if (len & 1) {
634			len += XMT_HEADER_LEN + 1;
635		} else {
636			len += XMT_HEADER_LEN;
637		}
638
639		if ((i = sc->tx_tail - sc->tx_head) >= 0) {
640			avail = sc->tx_mem_size - i;
641		} else {
642			avail = -i;
643		}
644
645		DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail););
646
647		if (avail >= len + XMT_HEADER_LEN) {
648			IF_DEQUEUE(&ifp->if_snd, opkt);
649
650#ifdef EX_PSA_INTR
651			/*
652			 * Disable rx and tx interrupts, to avoid corruption
653			 * of the host address register by interrupt service
654			 * routines.
655			 * XXX Is this necessary with splimp() enabled?
656			 */
657			outb(iobase + MASK_REG, All_Int);
658#endif
659
660			/*
661			 * Compute the start and end addresses of this
662			 * frame in the tx buffer.
663			 */
664			dest = sc->tx_tail;
665			next = dest + len;
666
667			if (next > sc->tx_upper_limit) {
668				if ((sc->tx_upper_limit + 2 - sc->tx_tail) <=
669				    XMT_HEADER_LEN) {
670					dest = sc->tx_lower_limit;
671					next = dest + len;
672				} else {
673					next = sc->tx_lower_limit +
674						next - sc->tx_upper_limit - 2;
675				}
676			}
677
678			/*
679			 * Build the packet frame in the card's ring buffer.
680			 */
681			DODEBUG(Sent_Pkts, printf("2. dest=%d, next=%d. ", dest, next););
682
683			outw(iobase + HOST_ADDR_REG, dest);
684			outw(iobase + IO_PORT_REG, Transmit_CMD);
685			outw(iobase + IO_PORT_REG, 0);
686			outw(iobase + IO_PORT_REG, next);
687			outw(iobase + IO_PORT_REG, data_len);
688
689			/*
690			 * Output the packet data to the card. Ensure all
691			 * transfers are 16-bit wide, even if individual
692			 * mbufs have odd length.
693			 */
694
695			for (m = opkt, i = 0; m != NULL; m = m->m_next) {
696				DODEBUG(Sent_Pkts, printf("[%d]", m->m_len););
697				if (i) {
698					tmp16[1] = *(mtod(m, caddr_t));
699					outsw(iobase + IO_PORT_REG, tmp16, 1);
700				}
701				outsw(iobase + IO_PORT_REG,
702				      mtod(m, caddr_t) + i, (m->m_len - i) / 2);
703
704				if ((i = (m->m_len - i) & 1) != 0) {
705					tmp16[0] = *(mtod(m, caddr_t) +
706						   m->m_len - 1);
707				}
708			}
709			if (i) {
710				outsw(iobase + IO_PORT_REG, tmp16, 1);
711			}
712
713			/*
714			 * If there were other frames chained, update the
715			 * chain in the last one.
716			 */
717			if (sc->tx_head != sc->tx_tail) {
718				if (sc->tx_tail != dest) {
719					outw(iobase + HOST_ADDR_REG,
720					     sc->tx_last + XMT_Chain_Point);
721					outw(iobase + IO_PORT_REG, dest);
722				}
723				outw(iobase + HOST_ADDR_REG,
724				     sc->tx_last + XMT_Byte_Count);
725				i = inw(iobase + IO_PORT_REG);
726				outw(iobase + HOST_ADDR_REG,
727				     sc->tx_last + XMT_Byte_Count);
728				outw(iobase + IO_PORT_REG, i | Ch_bit);
729			}
730
731			/*
732			 * Resume normal operation of the card:
733			 * - Make a dummy read to flush the DRAM write
734			 *   pipeline.
735			 * - Enable receive and transmit interrupts.
736			 * - Send Transmit or Resume_XMT command, as
737			 *   appropriate.
738			 */
739			inw(iobase + IO_PORT_REG);
740#ifdef EX_PSA_INTR
741			outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int));
742#endif
743			if (sc->tx_head == sc->tx_tail) {
744				outw(iobase + XMT_BAR, dest);
745				outb(iobase + CMD_REG, Transmit_CMD);
746				sc->tx_head = dest;
747				DODEBUG(Sent_Pkts, printf("Transmit\n"););
748			} else {
749				outb(iobase + CMD_REG, Resume_XMT_List_CMD);
750				DODEBUG(Sent_Pkts, printf("Resume\n"););
751			}
752
753			sc->tx_last = dest;
754			sc->tx_tail = next;
755
756			if (ifp->if_bpf != NULL) {
757				bpf_mtap(ifp, opkt);
758			}
759
760			ifp->if_timer = 2;
761			ifp->if_opackets++;
762			m_freem(opkt);
763		} else {
764			ifp->if_flags |= IFF_OACTIVE;
765			DODEBUG(Status, printf("OACTIVE start\n"););
766		}
767	}
768
769	splx(s);
770
771	DODEBUG(Start_End, printf("ex_start%d: finish\n", unit););
772}
773
774static void
775ex_stop(struct ex_softc *sc)
776{
777	int iobase = sc->iobase;
778
779	DODEBUG(Start_End, printf("ex_stop%d: start\n", unit););
780
781	/*
782	 * Disable card operation:
783	 * - Disable the interrupt line.
784	 * - Flush transmission and disable reception.
785	 * - Mask and clear all interrupts.
786	 * - Reset the 82595.
787	 */
788	outb(iobase + CMD_REG, Bank1_Sel);
789	outb(iobase + REG1, inb(iobase + REG1) & ~TriST_INT);
790	outb(iobase + CMD_REG, Bank0_Sel);
791	outb(iobase + CMD_REG, Rcv_Stop);
792	sc->tx_head = sc->tx_tail = sc->tx_lower_limit;
793	sc->tx_last = 0; /* XXX I think these two lines are not necessary, because ex_init will always be called again to reinit the interface. */
794	outb(iobase + MASK_REG, All_Int);
795	outb(iobase + STATUS_REG, All_Int);
796	outb(iobase + CMD_REG, Reset_CMD);
797	DELAY(200);
798
799	DODEBUG(Start_End, printf("ex_stop%d: finish\n", unit););
800
801	return;
802}
803
804
805static void
806ex_intr(void *arg)
807{
808	struct ex_softc *	sc = (struct ex_softc *)arg;
809	struct ifnet *	ifp = &sc->arpcom.ac_if;
810	int			iobase = sc->iobase;
811	int			int_status, send_pkts;
812
813	DODEBUG(Start_End, printf("ex_intr%d: start\n", unit););
814
815#ifdef EXDEBUG
816	if (++exintr_count != 1)
817		printf("WARNING: nested interrupt (%d). Mail the author.\n", exintr_count);
818#endif
819
820	send_pkts = 0;
821	while ((int_status = inb(iobase + STATUS_REG)) & (Tx_Int | Rx_Int)) {
822		if (int_status & Rx_Int) {
823			outb(iobase + STATUS_REG, Rx_Int);
824
825			ex_rx_intr(sc);
826		} else if (int_status & Tx_Int) {
827			outb(iobase + STATUS_REG, Tx_Int);
828
829			ex_tx_intr(sc);
830			send_pkts = 1;
831		}
832	}
833
834	/*
835	 * If any packet has been transmitted, and there are queued packets to
836	 * be sent, attempt to send more packets to the network card.
837	 */
838
839	if (send_pkts && (ifp->if_snd.ifq_head != NULL)) {
840		ex_start(ifp);
841	}
842
843#ifdef EXDEBUG
844	exintr_count--;
845#endif
846
847	DODEBUG(Start_End, printf("ex_intr%d: finish\n", unit););
848
849	return;
850}
851
852static void
853ex_tx_intr(struct ex_softc *sc)
854{
855	struct ifnet *	ifp = &sc->arpcom.ac_if;
856	int		iobase = sc->iobase;
857	int		tx_status;
858
859	DODEBUG(Start_End, printf("ex_tx_intr%d: start\n", unit););
860
861	/*
862	 * - Cancel the watchdog.
863	 * For all packets transmitted since last transmit interrupt:
864	 * - Advance chain pointer to next queued packet.
865	 * - Update statistics.
866	 */
867
868	ifp->if_timer = 0;
869
870	while (sc->tx_head != sc->tx_tail) {
871		outw(iobase + HOST_ADDR_REG, sc->tx_head);
872
873		if (! inw(iobase + IO_PORT_REG) & Done_bit)
874			break;
875
876		tx_status = inw(iobase + IO_PORT_REG);
877		sc->tx_head = inw(iobase + IO_PORT_REG);
878
879		if (tx_status & TX_OK_bit) {
880			ifp->if_opackets++;
881		} else {
882			ifp->if_oerrors++;
883		}
884
885		ifp->if_collisions += tx_status & No_Collisions_bits;
886	}
887
888	/*
889	 * The card should be ready to accept more packets now.
890	 */
891
892	ifp->if_flags &= ~IFF_OACTIVE;
893
894	DODEBUG(Status, printf("OIDLE tx_intr\n"););
895	DODEBUG(Start_End, printf("ex_tx_intr%d: finish\n", unit););
896
897	return;
898}
899
900static void
901ex_rx_intr(struct ex_softc *sc)
902{
903	struct ifnet *		ifp = &sc->arpcom.ac_if;
904	int			iobase = sc->iobase;
905	int			rx_status;
906	int			pkt_len;
907	int			QQQ;
908	struct mbuf *		m;
909	struct mbuf *		ipkt;
910	struct ether_header *	eh;
911
912	DODEBUG(Start_End, printf("ex_rx_intr%d: start\n", unit););
913
914	/*
915	 * For all packets received since last receive interrupt:
916	 * - If packet ok, read it into a new mbuf and queue it to interface,
917	 *   updating statistics.
918	 * - If packet bad, just discard it, and update statistics.
919	 * Finally, advance receive stop limit in card's memory to new location.
920	 */
921
922	outw(iobase + HOST_ADDR_REG, sc->rx_head);
923
924	while (inw(iobase + IO_PORT_REG) == RCV_Done) {
925
926		rx_status = inw(iobase + IO_PORT_REG);
927		sc->rx_head = inw(iobase + IO_PORT_REG);
928		QQQ = pkt_len = inw(iobase + IO_PORT_REG);
929
930		if (rx_status & RCV_OK_bit) {
931			MGETHDR(m, M_DONTWAIT, MT_DATA);
932			ipkt = m;
933			if (ipkt == NULL) {
934				ifp->if_iqdrops++;
935			} else {
936				ipkt->m_pkthdr.rcvif = ifp;
937				ipkt->m_pkthdr.len = pkt_len;
938				ipkt->m_len = MHLEN;
939
940				while (pkt_len > 0) {
941					if (pkt_len > MINCLSIZE) {
942						MCLGET(m, M_DONTWAIT);
943						if (m->m_flags & M_EXT) {
944							m->m_len = MCLBYTES;
945						} else {
946							m_freem(ipkt);
947							ifp->if_iqdrops++;
948							goto rx_another;
949						}
950					}
951					m->m_len = min(m->m_len, pkt_len);
952
953	  /*
954	   * NOTE: I'm assuming that all mbufs allocated are of even length,
955	   * except for the last one in an odd-length packet.
956	   */
957
958					insw(iobase + IO_PORT_REG,
959					     mtod(m, caddr_t), m->m_len / 2);
960
961					if (m->m_len & 1) {
962						*(mtod(m, caddr_t) + m->m_len - 1) = inb(iobase + IO_PORT_REG);
963					}
964					pkt_len -= m->m_len;
965
966					if (pkt_len > 0) {
967						MGET(m->m_next, M_DONTWAIT, MT_DATA);
968						if (m->m_next == NULL) {
969							m_freem(ipkt);
970							ifp->if_iqdrops++;
971							goto rx_another;
972						}
973						m = m->m_next;
974						m->m_len = MLEN;
975					}
976				}
977				eh = mtod(ipkt, struct ether_header *);
978#ifdef EXDEBUG
979	if (debug_mask & Rcvd_Pkts) {
980		if ((eh->ether_dhost[5] != 0xff) || (eh->ether_dhost[0] != 0xff)) {
981			printf("Receive packet with %d data bytes: %6D -> ", QQQ, eh->ether_shost, ":");
982			printf("%6D\n", eh->ether_dhost, ":");
983		} /* QQQ */
984	}
985#endif
986				if (ifp->if_bpf != NULL) {
987					bpf_mtap(ifp, ipkt);
988
989		/*
990		 * Note that the interface cannot be in promiscuous mode
991		 * if there are no BPF listeners. And if we are in
992		 * promiscuous mode, we have to check if this packet is
993		 * really ours.
994		 */
995					if ((ifp->if_flags & IFF_PROMISC) &&
996					    (eh->ether_dhost[0] & 1) == 0 &&
997					    bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, sizeof(eh->ether_dhost)) != 0 &&
998					    bcmp(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost)) != 0) {
999						m_freem(ipkt);
1000						goto rx_another;
1001					}
1002				}
1003				m_adj(ipkt, sizeof(struct ether_header));
1004				ether_input(ifp, eh, ipkt);
1005				ifp->if_ipackets++;
1006			}
1007		} else {
1008			ifp->if_ierrors++;
1009		}
1010		outw(iobase + HOST_ADDR_REG, sc->rx_head);
1011rx_another: ;
1012	}
1013
1014	if (sc->rx_head < sc->rx_lower_limit + 2)
1015		outw(iobase + RCV_STOP_REG, sc->rx_upper_limit);
1016	else
1017		outw(iobase + RCV_STOP_REG, sc->rx_head - 2);
1018
1019	DODEBUG(Start_End, printf("ex_rx_intr%d: finish\n", unit););
1020
1021	return;
1022}
1023
1024
1025static int
1026ex_ioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
1027{
1028	struct ex_softc *	sc = ifp->if_softc;
1029	struct ifreq *		ifr = (struct ifreq *)data;
1030	int			s;
1031	int			error = 0;
1032
1033	DODEBUG(Start_End, printf("ex_ioctl%d: start ", ifp->if_unit););
1034
1035	s = splimp();
1036
1037	switch(cmd) {
1038		case SIOCSIFADDR:
1039		case SIOCGIFADDR:
1040		case SIOCSIFMTU:
1041			error = ether_ioctl(ifp, cmd, data);
1042			break;
1043
1044		case SIOCSIFFLAGS:
1045			DODEBUG(Start_End, printf("SIOCSIFFLAGS"););
1046			if ((ifp->if_flags & IFF_UP) == 0 &&
1047			    (ifp->if_flags & IFF_RUNNING)) {
1048
1049				ifp->if_flags &= ~IFF_RUNNING;
1050				ex_stop(sc);
1051			} else {
1052      				ex_init(sc);
1053			}
1054			break;
1055#ifdef NODEF
1056		case SIOCGHWADDR:
1057			DODEBUG(Start_End, printf("SIOCGHWADDR"););
1058			bcopy((caddr_t)sc->sc_addr, (caddr_t)&ifr->ifr_data,
1059			      sizeof(sc->sc_addr));
1060			break;
1061#endif
1062		case SIOCADDMULTI:
1063			DODEBUG(Start_End, printf("SIOCADDMULTI"););
1064		case SIOCDELMULTI:
1065			DODEBUG(Start_End, printf("SIOCDELMULTI"););
1066			/* XXX Support not done yet. */
1067			error = EINVAL;
1068			break;
1069		case SIOCSIFMEDIA:
1070		case SIOCGIFMEDIA:
1071			error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd);
1072			break;
1073		default:
1074			DODEBUG(Start_End, printf("unknown"););
1075			error = EINVAL;
1076	}
1077
1078	splx(s);
1079
1080	DODEBUG(Start_End, printf("\nex_ioctl%d: finish\n", ifp->if_unit););
1081
1082	return(error);
1083}
1084
1085
1086static void
1087ex_reset(struct ex_softc *sc)
1088{
1089	int s;
1090
1091	DODEBUG(Start_End, printf("ex_reset%d: start\n", unit););
1092
1093	s = splimp();
1094
1095	ex_stop(sc);
1096	ex_init(sc);
1097
1098	splx(s);
1099
1100	DODEBUG(Start_End, printf("ex_reset%d: finish\n", unit););
1101
1102	return;
1103}
1104
1105static void
1106ex_watchdog(struct ifnet *ifp)
1107{
1108	struct ex_softc *	sc = ifp->if_softc;
1109
1110	DODEBUG(Start_End, printf("ex_watchdog%d: start\n", ifp->if_unit););
1111
1112	ifp->if_flags &= ~IFF_OACTIVE;
1113
1114	DODEBUG(Status, printf("OIDLE watchdog\n"););
1115
1116	ifp->if_oerrors++;
1117	ex_reset(sc);
1118	ex_start(ifp);
1119
1120	DODEBUG(Start_End, printf("ex_watchdog%d: finish\n", ifp->if_unit););
1121
1122	return;
1123}
1124
1125static int
1126ex_ifmedia_upd (ifp)
1127	struct ifnet *		ifp;
1128{
1129	struct ex_softc *	sc = ifp->if_softc;
1130
1131	return (0);
1132}
1133
1134static void
1135ex_ifmedia_sts(ifp, ifmr)
1136	struct ifnet *          ifp;
1137	struct ifmediareq *     ifmr;
1138{
1139	struct ex_softc *       sc = ifp->if_softc;
1140
1141	ifmr->ifm_active = ex_get_media(sc->iobase);
1142
1143	return;
1144}
1145
1146static u_short
1147eeprom_read(int iobase, int location)
1148{
1149	int i;
1150	u_short data = 0;
1151	int ee_addr;
1152	int read_cmd = location | EE_READ_CMD;
1153	short ctrl_val = EECS;
1154
1155	ee_addr = iobase + EEPROM_REG;
1156	outb(iobase + CMD_REG, Bank2_Sel);
1157	outb(ee_addr, EECS);
1158	for (i = 8; i >= 0; i--) {
1159		short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val;
1160		outb(ee_addr, outval);
1161		outb(ee_addr, outval | EESK);
1162		DELAY(3);
1163		outb(ee_addr, outval);
1164		DELAY(2);
1165	}
1166	outb(ee_addr, ctrl_val);
1167
1168	for (i = 16; i > 0; i--) {
1169		outb(ee_addr, ctrl_val | EESK);
1170		DELAY(3);
1171		data = (data << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
1172		outb(ee_addr, ctrl_val);
1173		DELAY(2);
1174	}
1175
1176	ctrl_val &= ~EECS;
1177	outb(ee_addr, ctrl_val | EESK);
1178	DELAY(3);
1179	outb(ee_addr, ctrl_val);
1180	DELAY(2);
1181	outb(iobase + CMD_REG, Bank0_Sel);
1182	return(data);
1183}
1184