]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ex/if_ex.c
Initialize the event tailq.
[FreeBSD/FreeBSD.git] / sys / dev / ex / if_ex.c
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  *
28  * MAINTAINER: Matthew N. Dodd <winter@jurai.net>
29  *                             <mdodd@FreeBSD.org>
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 /*
36  * Intel EtherExpress Pro/10, Pro/10+ Ethernet driver
37  *
38  * Revision history:
39  *
40  * dd-mmm-yyyy: Multicast support ported from NetBSD's if_iy driver.
41  * 30-Oct-1996: first beta version. Inet and BPF supported, but no multicast.
42  */
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.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_dl.h>
61 #include <net/if_media.h> 
62 #include <net/if_types.h> 
63 #include <net/ethernet.h>
64 #include <net/bpf.h>
65
66 #include <netinet/in.h>
67 #include <netinet/if_ether.h>
68
69
70 #include <isa/isavar.h>
71 #include <isa/pnpvar.h>
72
73 #include <dev/ex/if_exreg.h>
74 #include <dev/ex/if_exvar.h>
75
76 #ifdef EXDEBUG
77 # define Start_End 1
78 # define Rcvd_Pkts 2
79 # define Sent_Pkts 4
80 # define Status    8
81 static int debug_mask = 0;
82 # define DODEBUG(level, action) if (level & debug_mask) action
83 #else
84 # define DODEBUG(level, action)
85 #endif
86
87 devclass_t ex_devclass;
88
89 char irq2eemap[] =
90         { -1, -1, 0, 1, -1, 2, -1, -1, -1, 0, 3, 4, -1, -1, -1, -1 };
91 u_char ee2irqmap[] =
92         { 9, 3, 5, 10, 11, 0, 0, 0 };
93                 
94 char plus_irq2eemap[] =
95         { -1, -1, -1, 0, 1, 2, -1, 3, -1, 4, 5, 6, 7, -1, -1, -1 };
96 u_char plus_ee2irqmap[] =
97         { 3, 4, 5, 7, 9, 10, 11, 12 };
98
99 /* Network Interface Functions */
100 static void     ex_init(void *);
101 static void     ex_start(struct ifnet *);
102 static int      ex_ioctl(struct ifnet *, u_long, caddr_t);
103 static void     ex_watchdog(struct ifnet *);
104
105 /* ifmedia Functions    */
106 static int      ex_ifmedia_upd(struct ifnet *);
107 static void     ex_ifmedia_sts(struct ifnet *, struct ifmediareq *);
108
109 static int      ex_get_media(struct ex_softc *);
110
111 static void     ex_reset(struct ex_softc *);
112 static void     ex_setmulti(struct ex_softc *);
113
114 static void     ex_tx_intr(struct ex_softc *);
115 static void     ex_rx_intr(struct ex_softc *);
116
117 void
118 ex_get_address(struct ex_softc *sc, u_char *enaddr)
119 {
120         uint16_t        eaddr_tmp;
121
122         eaddr_tmp = ex_eeprom_read(sc, EE_Eth_Addr_Lo);
123         enaddr[5] = eaddr_tmp & 0xff;
124         enaddr[4] = eaddr_tmp >> 8;
125         eaddr_tmp = ex_eeprom_read(sc, EE_Eth_Addr_Mid);
126         enaddr[3] = eaddr_tmp & 0xff;
127         enaddr[2] = eaddr_tmp >> 8;
128         eaddr_tmp = ex_eeprom_read(sc, EE_Eth_Addr_Hi);
129         enaddr[1] = eaddr_tmp & 0xff;
130         enaddr[0] = eaddr_tmp >> 8;
131         
132         return;
133 }
134
135 int
136 ex_card_type(u_char *enaddr)
137 {
138         if ((enaddr[0] == 0x00) && (enaddr[1] == 0xA0) && (enaddr[2] == 0xC9))
139                 return (CARD_TYPE_EX_10_PLUS);
140
141         return (CARD_TYPE_EX_10);
142 }
143
144 /*
145  * Caller is responsible for eventually calling
146  * ex_release_resources() on failure.
147  */
148 int
149 ex_alloc_resources(device_t dev)
150 {
151         struct ex_softc *       sc = device_get_softc(dev);
152         int                     error = 0;
153
154         sc->ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
155                                             &sc->ioport_rid, RF_ACTIVE);
156         if (!sc->ioport) {
157                 device_printf(dev, "No I/O space?!\n");
158                 error = ENOMEM;
159                 goto bad;
160         }
161         sc->bst = rman_get_bustag(sc->ioport);
162         sc->bsh = rman_get_bushandle(sc->ioport);
163
164         sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
165                                         RF_ACTIVE);
166
167         if (!sc->irq) {
168                 device_printf(dev, "No IRQ?!\n");
169                 error = ENOMEM;
170                 goto bad;
171         }
172
173 bad:
174         return (error);
175 }
176
177 void
178 ex_release_resources(device_t dev)
179 {
180         struct ex_softc *       sc = device_get_softc(dev);
181
182         if (sc->ih) {
183                 bus_teardown_intr(dev, sc->irq, sc->ih);
184                 sc->ih = NULL;
185         }
186
187         if (sc->ioport) {
188                 bus_release_resource(dev, SYS_RES_IOPORT,
189                                         sc->ioport_rid, sc->ioport);
190                 sc->ioport = NULL;
191         }
192
193         if (sc->irq) {
194                 bus_release_resource(dev, SYS_RES_IRQ,
195                                         sc->irq_rid, sc->irq);
196                 sc->irq = NULL;
197         }
198
199         if (sc->ifp)
200                 if_free(sc->ifp);
201
202         return;
203 }
204
205 int
206 ex_attach(device_t dev)
207 {
208         struct ex_softc *       sc = device_get_softc(dev);
209         struct ifnet *          ifp;
210         struct ifmedia *        ifm;
211         uint16_t                temp;
212
213         ifp = sc->ifp = if_alloc(IFT_ETHER);
214         if (ifp == NULL) {
215                 device_printf(dev, "can not if_alloc()\n");
216                 return (ENOSPC);
217         }
218         /* work out which set of irq <-> internal tables to use */
219         if (ex_card_type(sc->enaddr) == CARD_TYPE_EX_10_PLUS) {
220                 sc->irq2ee = plus_irq2eemap;
221                 sc->ee2irq = plus_ee2irqmap;
222         } else {
223                 sc->irq2ee = irq2eemap;
224                 sc->ee2irq = ee2irqmap;
225         }
226
227         sc->mem_size = CARD_RAM_SIZE;   /* XXX This should be read from the card itself. */
228
229         /*
230          * Initialize the ifnet structure.
231          */
232         ifp->if_softc = sc;
233         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
234         ifp->if_mtu = ETHERMTU;
235         ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
236             IFF_NEEDSGIANT;
237         ifp->if_start = ex_start;
238         ifp->if_ioctl = ex_ioctl;
239         ifp->if_watchdog = ex_watchdog;
240         ifp->if_init = ex_init;
241         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
242
243         ifmedia_init(&sc->ifmedia, 0, ex_ifmedia_upd, ex_ifmedia_sts);
244
245         temp = ex_eeprom_read(sc, EE_W5);
246         if (temp & EE_W5_PORT_TPE)
247                 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
248         if (temp & EE_W5_PORT_BNC)
249                 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL);
250         if (temp & EE_W5_PORT_AUI)
251                 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL);
252
253         ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
254         ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_NONE, 0, NULL);
255         ifmedia_set(&sc->ifmedia, ex_get_media(sc));
256
257         ifm = &sc->ifmedia;
258         ifm->ifm_media = ifm->ifm_cur->ifm_media;
259         ex_ifmedia_upd(ifp);
260
261         /*
262          * Attach the interface.
263          */
264         ether_ifattach(ifp, sc->enaddr);
265
266         return(0);
267 }
268
269 int
270 ex_detach(device_t dev)
271 {
272         struct ex_softc *sc;
273         struct ifnet    *ifp;
274
275         sc = device_get_softc(dev);
276         ifp = sc->ifp;
277
278         ex_stop(sc);
279
280         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
281         ether_ifdetach(ifp);
282
283         ex_release_resources(dev);
284
285         return (0);
286 }
287
288 static void
289 ex_init(void *xsc)
290 {
291         struct ex_softc *       sc = (struct ex_softc *) xsc;
292         struct ifnet *          ifp = sc->ifp;
293         int                     s;
294         int                     i;
295         unsigned short          temp_reg;
296
297         DODEBUG(Start_End, printf("%s: ex_init: start\n", ifp->if_xname););
298
299         s = splimp();
300         ifp->if_timer = 0;
301
302         /*
303          * Load the ethernet address into the card.
304          */
305         CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
306         temp_reg = CSR_READ_1(sc, EEPROM_REG);
307         if (temp_reg & Trnoff_Enable) {
308                 CSR_WRITE_1(sc, EEPROM_REG, temp_reg & ~Trnoff_Enable);
309         }
310         for (i = 0; i < ETHER_ADDR_LEN; i++) {
311                 CSR_WRITE_1(sc, I_ADDR_REG0 + i, IF_LLADDR(sc->ifp)[i]);
312         }
313         /*
314          * - Setup transmit chaining and discard bad received frames.
315          * - Match broadcast.
316          * - Clear test mode.
317          * - Set receiving mode.
318          * - Set IRQ number.
319          */
320         CSR_WRITE_1(sc, REG1, CSR_READ_1(sc, REG1) | Tx_Chn_Int_Md | Tx_Chn_ErStp | Disc_Bad_Fr);
321         CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | No_SA_Ins | RX_CRC_InMem);
322         CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3) & 0x3f /* XXX constants. */ );
323         CSR_WRITE_1(sc, CMD_REG, Bank1_Sel);
324         CSR_WRITE_1(sc, INT_NO_REG, (CSR_READ_1(sc, INT_NO_REG) & 0xf8) | sc->irq2ee[sc->irq_no]);
325
326         /*
327          * Divide the available memory in the card into rcv and xmt buffers.
328          * By default, I use the first 3/4 of the memory for the rcv buffer,
329          * and the remaining 1/4 of the memory for the xmt buffer.
330          */
331         sc->rx_mem_size = sc->mem_size * 3 / 4;
332         sc->tx_mem_size = sc->mem_size - sc->rx_mem_size;
333         sc->rx_lower_limit = 0x0000;
334         sc->rx_upper_limit = sc->rx_mem_size - 2;
335         sc->tx_lower_limit = sc->rx_mem_size;
336         sc->tx_upper_limit = sc->mem_size - 2;
337         CSR_WRITE_1(sc, RCV_LOWER_LIMIT_REG, sc->rx_lower_limit >> 8);
338         CSR_WRITE_1(sc, RCV_UPPER_LIMIT_REG, sc->rx_upper_limit >> 8);
339         CSR_WRITE_1(sc, XMT_LOWER_LIMIT_REG, sc->tx_lower_limit >> 8);
340         CSR_WRITE_1(sc, XMT_UPPER_LIMIT_REG, sc->tx_upper_limit >> 8);
341         
342         /*
343          * Enable receive and transmit interrupts, and clear any pending int.
344          */
345         CSR_WRITE_1(sc, REG1, CSR_READ_1(sc, REG1) | TriST_INT);
346         CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
347         CSR_WRITE_1(sc, MASK_REG, All_Int & ~(Rx_Int | Tx_Int));
348         CSR_WRITE_1(sc, STATUS_REG, All_Int);
349
350         /*
351          * Initialize receive and transmit ring buffers.
352          */
353         CSR_WRITE_2(sc, RCV_BAR, sc->rx_lower_limit);
354         sc->rx_head = sc->rx_lower_limit;
355         CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_upper_limit | 0xfe);
356         CSR_WRITE_2(sc, XMT_BAR, sc->tx_lower_limit);
357         sc->tx_head = sc->tx_tail = sc->tx_lower_limit;
358
359         ifp->if_drv_flags |= IFF_DRV_RUNNING;
360         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
361         DODEBUG(Status, printf("OIDLE init\n"););
362         
363         ex_setmulti(sc);
364         
365         /*
366          * Final reset of the board, and enable operation.
367          */
368         CSR_WRITE_1(sc, CMD_REG, Sel_Reset_CMD);
369         DELAY(2);
370         CSR_WRITE_1(sc, CMD_REG, Rcv_Enable_CMD);
371
372         ex_start(ifp);
373         splx(s);
374
375         DODEBUG(Start_End, printf("%s: ex_init: finish\n", ifp->if_xname););
376 }
377
378
379 static void
380 ex_start(struct ifnet *ifp)
381 {
382         struct ex_softc *       sc = ifp->if_softc;
383         int                     i, s, len, data_len, avail, dest, next;
384         unsigned char           tmp16[2];
385         struct mbuf *           opkt;
386         struct mbuf *           m;
387
388         DODEBUG(Start_End, printf("ex_start%d: start\n", unit););
389
390         s = splimp();
391
392         /*
393          * Main loop: send outgoing packets to network card until there are no
394          * more packets left, or the card cannot accept any more yet.
395          */
396         while (((opkt = ifp->if_snd.ifq_head) != NULL) &&
397                !(ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
398
399                 /*
400                  * Ensure there is enough free transmit buffer space for
401                  * this packet, including its header. Note: the header
402                  * cannot wrap around the end of the transmit buffer and
403                  * must be kept together, so we allow space for twice the
404                  * length of the header, just in case.
405                  */
406
407                 for (len = 0, m = opkt; m != NULL; m = m->m_next) {
408                         len += m->m_len;
409                 }
410
411                 data_len = len;
412
413                 DODEBUG(Sent_Pkts, printf("1. Sending packet with %d data bytes. ", data_len););
414
415                 if (len & 1) {
416                         len += XMT_HEADER_LEN + 1;
417                 } else {
418                         len += XMT_HEADER_LEN;
419                 }
420
421                 if ((i = sc->tx_tail - sc->tx_head) >= 0) {
422                         avail = sc->tx_mem_size - i;
423                 } else {
424                         avail = -i;
425                 }
426
427                 DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail););
428
429                 if (avail >= len + XMT_HEADER_LEN) {
430                         IF_DEQUEUE(&ifp->if_snd, opkt);
431
432 #ifdef EX_PSA_INTR      
433                         /*
434                          * Disable rx and tx interrupts, to avoid corruption
435                          * of the host address register by interrupt service
436                          * routines.
437                          * XXX Is this necessary with splimp() enabled?
438                          */
439                         CSR_WRITE_1(sc, MASK_REG, All_Int);
440 #endif
441
442                         /*
443                          * Compute the start and end addresses of this
444                          * frame in the tx buffer.
445                          */
446                         dest = sc->tx_tail;
447                         next = dest + len;
448
449                         if (next > sc->tx_upper_limit) {
450                                 if ((sc->tx_upper_limit + 2 - sc->tx_tail) <=
451                                     XMT_HEADER_LEN) {
452                                         dest = sc->tx_lower_limit;
453                                         next = dest + len;
454                                 } else {
455                                         next = sc->tx_lower_limit +
456                                                 next - sc->tx_upper_limit - 2;
457                                 }
458                         }
459
460                         /*
461                          * Build the packet frame in the card's ring buffer.
462                          */
463                         DODEBUG(Sent_Pkts, printf("2. dest=%d, next=%d. ", dest, next););
464
465                         CSR_WRITE_2(sc, HOST_ADDR_REG, dest);
466                         CSR_WRITE_2(sc, IO_PORT_REG, Transmit_CMD);
467                         CSR_WRITE_2(sc, IO_PORT_REG, 0);
468                         CSR_WRITE_2(sc, IO_PORT_REG, next);
469                         CSR_WRITE_2(sc, IO_PORT_REG, data_len);
470
471                         /*
472                          * Output the packet data to the card. Ensure all
473                          * transfers are 16-bit wide, even if individual
474                          * mbufs have odd length.
475                          */
476                         for (m = opkt, i = 0; m != NULL; m = m->m_next) {
477                                 DODEBUG(Sent_Pkts, printf("[%d]", m->m_len););
478                                 if (i) {
479                                         tmp16[1] = *(mtod(m, caddr_t));
480                                         CSR_WRITE_MULTI_2(sc, IO_PORT_REG,
481                                             (uint16_t *) tmp16, 1);
482                                 }
483                                 CSR_WRITE_MULTI_2(sc, IO_PORT_REG,
484                                     (uint16_t *) (mtod(m, caddr_t) + i),
485                                     (m->m_len - i) / 2);
486                                 if ((i = (m->m_len - i) & 1) != 0) {
487                                         tmp16[0] = *(mtod(m, caddr_t) +
488                                                    m->m_len - 1);
489                                 }
490                         }
491                         if (i)
492                                 CSR_WRITE_MULTI_2(sc, IO_PORT_REG, 
493                                     (uint16_t *) tmp16, 1);
494                         /*
495                          * If there were other frames chained, update the
496                          * chain in the last one.
497                          */
498                         if (sc->tx_head != sc->tx_tail) {
499                                 if (sc->tx_tail != dest) {
500                                         CSR_WRITE_2(sc, HOST_ADDR_REG,
501                                              sc->tx_last + XMT_Chain_Point);
502                                         CSR_WRITE_2(sc, IO_PORT_REG, dest);
503                                 }
504                                 CSR_WRITE_2(sc, HOST_ADDR_REG,
505                                      sc->tx_last + XMT_Byte_Count);
506                                 i = CSR_READ_2(sc, IO_PORT_REG);
507                                 CSR_WRITE_2(sc, HOST_ADDR_REG,
508                                      sc->tx_last + XMT_Byte_Count);
509                                 CSR_WRITE_2(sc, IO_PORT_REG, i | Ch_bit);
510                         }
511         
512                         /*
513                          * Resume normal operation of the card:
514                          * - Make a dummy read to flush the DRAM write
515                          *   pipeline.
516                          * - Enable receive and transmit interrupts.
517                          * - Send Transmit or Resume_XMT command, as
518                          *   appropriate.
519                          */
520                         CSR_READ_2(sc, IO_PORT_REG);
521 #ifdef EX_PSA_INTR
522                         CSR_WRITE_1(sc, MASK_REG, All_Int & ~(Rx_Int | Tx_Int));
523 #endif
524                         if (sc->tx_head == sc->tx_tail) {
525                                 CSR_WRITE_2(sc, XMT_BAR, dest);
526                                 CSR_WRITE_1(sc, CMD_REG, Transmit_CMD);
527                                 sc->tx_head = dest;
528                                 DODEBUG(Sent_Pkts, printf("Transmit\n"););
529                         } else {
530                                 CSR_WRITE_1(sc, CMD_REG, Resume_XMT_List_CMD);
531                                 DODEBUG(Sent_Pkts, printf("Resume\n"););
532                         }
533         
534                         sc->tx_last = dest;
535                         sc->tx_tail = next;
536          
537                         BPF_MTAP(ifp, opkt);
538
539                         ifp->if_timer = 2;
540                         ifp->if_opackets++;
541                         m_freem(opkt);
542                 } else {
543                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
544                         DODEBUG(Status, printf("OACTIVE start\n"););
545                 }
546         }
547
548         splx(s);
549
550         DODEBUG(Start_End, printf("ex_start%d: finish\n", unit););
551 }
552
553 void
554 ex_stop(struct ex_softc *sc)
555 {
556         
557         DODEBUG(Start_End, printf("ex_stop%d: start\n", unit););
558
559         /*
560          * Disable card operation:
561          * - Disable the interrupt line.
562          * - Flush transmission and disable reception.
563          * - Mask and clear all interrupts.
564          * - Reset the 82595.
565          */
566         CSR_WRITE_1(sc, CMD_REG, Bank1_Sel);
567         CSR_WRITE_1(sc, REG1, CSR_READ_1(sc, REG1) & ~TriST_INT);
568         CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
569         CSR_WRITE_1(sc, CMD_REG, Rcv_Stop);
570         sc->tx_head = sc->tx_tail = sc->tx_lower_limit;
571         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. */
572         CSR_WRITE_1(sc, MASK_REG, All_Int);
573         CSR_WRITE_1(sc, STATUS_REG, All_Int);
574         CSR_WRITE_1(sc, CMD_REG, Reset_CMD);
575         DELAY(200);
576
577         DODEBUG(Start_End, printf("ex_stop%d: finish\n", unit););
578
579         return;
580 }
581
582 void
583 ex_intr(void *arg)
584 {
585         struct ex_softc *sc = (struct ex_softc *)arg;
586         struct ifnet    *ifp = sc->ifp;
587         int             int_status, send_pkts;
588         int             loops = 100;
589
590         DODEBUG(Start_End, printf("ex_intr%d: start\n", unit););
591
592         send_pkts = 0;
593         while (loops-- > 0 &&
594             (int_status = CSR_READ_1(sc, STATUS_REG)) & (Tx_Int | Rx_Int)) {
595                 /* don't loop forever */
596                 if (int_status == 0xff)
597                         break;
598                 if (int_status & Rx_Int) {
599                         CSR_WRITE_1(sc, STATUS_REG, Rx_Int);
600                         ex_rx_intr(sc);
601                 } else if (int_status & Tx_Int) {
602                         CSR_WRITE_1(sc, STATUS_REG, Tx_Int);
603                         ex_tx_intr(sc);
604                         send_pkts = 1;
605                 }
606         }
607         if (loops == 0)
608                 printf("100 loops are not enough\n");
609
610         /*
611          * If any packet has been transmitted, and there are queued packets to
612          * be sent, attempt to send more packets to the network card.
613          */
614         if (send_pkts && (ifp->if_snd.ifq_head != NULL))
615                 ex_start(ifp);
616
617         DODEBUG(Start_End, printf("ex_intr%d: finish\n", unit););
618
619         return;
620 }
621
622 static void
623 ex_tx_intr(struct ex_softc *sc)
624 {
625         struct ifnet *  ifp = sc->ifp;
626         int             tx_status;
627
628         DODEBUG(Start_End, printf("ex_tx_intr%d: start\n", unit););
629
630         /*
631          * - Cancel the watchdog.
632          * For all packets transmitted since last transmit interrupt:
633          * - Advance chain pointer to next queued packet.
634          * - Update statistics.
635          */
636
637         ifp->if_timer = 0;
638
639         while (sc->tx_head != sc->tx_tail) {
640                 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_head);
641
642                 if (! CSR_READ_2(sc, IO_PORT_REG) & Done_bit)
643                         break;
644
645                 tx_status = CSR_READ_2(sc, IO_PORT_REG);
646                 sc->tx_head = CSR_READ_2(sc, IO_PORT_REG);
647
648                 if (tx_status & TX_OK_bit) {
649                         ifp->if_opackets++;
650                 } else {
651                         ifp->if_oerrors++;
652                 }
653
654                 ifp->if_collisions += tx_status & No_Collisions_bits;
655         }
656
657         /*
658          * The card should be ready to accept more packets now.
659          */
660
661         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
662
663         DODEBUG(Status, printf("OIDLE tx_intr\n"););
664         DODEBUG(Start_End, printf("ex_tx_intr%d: finish\n", unit););
665
666         return;
667 }
668
669 static void
670 ex_rx_intr(struct ex_softc *sc)
671 {
672         struct ifnet *          ifp = sc->ifp;
673         int                     rx_status;
674         int                     pkt_len;
675         int                     QQQ;
676         struct mbuf *           m;
677         struct mbuf *           ipkt;
678         struct ether_header *   eh;
679
680         DODEBUG(Start_End, printf("ex_rx_intr%d: start\n", unit););
681
682         /*
683          * For all packets received since last receive interrupt:
684          * - If packet ok, read it into a new mbuf and queue it to interface,
685          *   updating statistics.
686          * - If packet bad, just discard it, and update statistics.
687          * Finally, advance receive stop limit in card's memory to new location.
688          */
689
690         CSR_WRITE_2(sc, HOST_ADDR_REG, sc->rx_head);
691
692         while (CSR_READ_2(sc, IO_PORT_REG) == RCV_Done) {
693
694                 rx_status = CSR_READ_2(sc, IO_PORT_REG);
695                 sc->rx_head = CSR_READ_2(sc, IO_PORT_REG);
696                 QQQ = pkt_len = CSR_READ_2(sc, IO_PORT_REG);
697
698                 if (rx_status & RCV_OK_bit) {
699                         MGETHDR(m, M_DONTWAIT, MT_DATA);
700                         ipkt = m;
701                         if (ipkt == NULL) {
702                                 ifp->if_iqdrops++;
703                         } else {
704                                 ipkt->m_pkthdr.rcvif = ifp;
705                                 ipkt->m_pkthdr.len = pkt_len;
706                                 ipkt->m_len = MHLEN;
707
708                                 while (pkt_len > 0) {
709                                         if (pkt_len >= MINCLSIZE) {
710                                                 MCLGET(m, M_DONTWAIT);
711                                                 if (m->m_flags & M_EXT) {
712                                                         m->m_len = MCLBYTES;
713                                                 } else {
714                                                         m_freem(ipkt);
715                                                         ifp->if_iqdrops++;
716                                                         goto rx_another;
717                                                 }
718                                         }
719                                         m->m_len = min(m->m_len, pkt_len);
720
721           /*
722            * NOTE: I'm assuming that all mbufs allocated are of even length,
723            * except for the last one in an odd-length packet.
724            */
725
726                                         CSR_READ_MULTI_2(sc, IO_PORT_REG,
727                                             mtod(m, uint16_t *), m->m_len / 2);
728
729                                         if (m->m_len & 1) {
730                                                 *(mtod(m, caddr_t) + m->m_len - 1) = CSR_READ_1(sc, IO_PORT_REG);
731                                         }
732                                         pkt_len -= m->m_len;
733
734                                         if (pkt_len > 0) {
735                                                 MGET(m->m_next, M_DONTWAIT, MT_DATA);
736                                                 if (m->m_next == NULL) {
737                                                         m_freem(ipkt);
738                                                         ifp->if_iqdrops++;
739                                                         goto rx_another;
740                                                 }
741                                                 m = m->m_next;
742                                                 m->m_len = MLEN;
743                                         }
744                                 }
745                                 eh = mtod(ipkt, struct ether_header *);
746 #ifdef EXDEBUG
747         if (debug_mask & Rcvd_Pkts) {
748                 if ((eh->ether_dhost[5] != 0xff) || (eh->ether_dhost[0] != 0xff)) {
749                         printf("Receive packet with %d data bytes: %6D -> ", QQQ, eh->ether_shost, ":");
750                         printf("%6D\n", eh->ether_dhost, ":");
751                 } /* QQQ */
752         }
753 #endif
754                                 (*ifp->if_input)(ifp, ipkt);
755                                 ifp->if_ipackets++;
756                         }
757                 } else {
758                         ifp->if_ierrors++;
759                 }
760                 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->rx_head);
761 rx_another: ;
762         }
763
764         if (sc->rx_head < sc->rx_lower_limit + 2)
765                 CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_upper_limit);
766         else
767                 CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_head - 2);
768
769         DODEBUG(Start_End, printf("ex_rx_intr%d: finish\n", unit););
770
771         return;
772 }
773
774
775 static int
776 ex_ioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
777 {
778         struct ex_softc *       sc = ifp->if_softc;
779         struct ifreq *          ifr = (struct ifreq *)data;
780         int                     s;
781         int                     error = 0;
782
783         DODEBUG(Start_End, printf("%s: ex_ioctl: start ", ifp->if_xname););
784
785         s = splimp();
786
787         switch(cmd) {
788                 case SIOCSIFADDR:
789                 case SIOCGIFADDR:
790                 case SIOCSIFMTU:
791                         error = ether_ioctl(ifp, cmd, data);
792                         break;
793
794                 case SIOCSIFFLAGS:
795                         DODEBUG(Start_End, printf("SIOCSIFFLAGS"););
796                         if ((ifp->if_flags & IFF_UP) == 0 &&
797                             (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
798
799                                 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
800                                 ex_stop(sc);
801                         } else {
802                                 ex_init(sc);
803                         }
804                         break;
805 #ifdef NODEF
806                 case SIOCGHWADDR:
807                         DODEBUG(Start_End, printf("SIOCGHWADDR"););
808                         bcopy((caddr_t)sc->sc_addr, (caddr_t)&ifr->ifr_data,
809                               sizeof(sc->sc_addr));
810                         break;
811 #endif
812                 case SIOCADDMULTI:
813                 case SIOCDELMULTI:
814                         ex_init(sc);
815                         error = 0;
816                         break;
817                 case SIOCSIFMEDIA:
818                 case SIOCGIFMEDIA:
819                         error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd);
820                         break;
821                 default:
822                         DODEBUG(Start_End, printf("unknown"););
823                         error = EINVAL;
824         }
825
826         splx(s);
827
828         DODEBUG(Start_End, printf("\n%s: ex_ioctl: finish\n", ifp->if_xname););
829
830         return(error);
831 }
832
833 static void
834 ex_setmulti(struct ex_softc *sc)
835 {
836         struct ifnet *ifp;
837         struct ifmultiaddr *maddr;
838         uint16_t *addr;
839         int count;
840         int timeout, status;
841         
842         ifp = sc->ifp;
843
844         count = 0;
845         IF_ADDR_LOCK(ifp);
846         TAILQ_FOREACH(maddr, &ifp->if_multiaddrs, ifma_link) {
847                 if (maddr->ifma_addr->sa_family != AF_LINK)
848                         continue;
849                 count++;
850         }
851         IF_ADDR_UNLOCK(ifp);
852
853         if ((ifp->if_flags & IFF_PROMISC) || (ifp->if_flags & IFF_ALLMULTI)
854                         || count > 63) {
855                 /* Interface is in promiscuous mode or there are too many
856                  * multicast addresses for the card to handle */
857                 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
858                 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | Promisc_Mode);
859                 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3));
860                 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
861         }
862         else if ((ifp->if_flags & IFF_MULTICAST) && (count > 0)) {
863                 /* Program multicast addresses plus our MAC address
864                  * into the filter */
865                 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
866                 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | Multi_IA);
867                 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3));
868                 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
869
870                 /* Borrow space from TX buffer; this should be safe
871                  * as this is only called from ex_init */
872                 
873                 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_lower_limit);
874                 CSR_WRITE_2(sc, IO_PORT_REG, MC_Setup_CMD);
875                 CSR_WRITE_2(sc, IO_PORT_REG, 0);
876                 CSR_WRITE_2(sc, IO_PORT_REG, 0);
877                 CSR_WRITE_2(sc, IO_PORT_REG, (count + 1) * 6);
878
879                 IF_ADDR_LOCK(ifp);
880                 TAILQ_FOREACH(maddr, &ifp->if_multiaddrs, ifma_link) {
881                         if (maddr->ifma_addr->sa_family != AF_LINK)
882                                 continue;
883
884                         addr = (uint16_t*)LLADDR((struct sockaddr_dl *)
885                                         maddr->ifma_addr);
886                         CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
887                         CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
888                         CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
889                 }
890                 IF_ADDR_UNLOCK(ifp);
891
892                 /* Program our MAC address as well */
893                 /* XXX: Is this necessary?  The Linux driver does this
894                  * but the NetBSD driver does not */
895                 addr = (uint16_t*)IF_LLADDR(sc->ifp);
896                 CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
897                 CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
898                 CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
899
900                 CSR_READ_2(sc, IO_PORT_REG);
901                 CSR_WRITE_2(sc, XMT_BAR, sc->tx_lower_limit);
902                 CSR_WRITE_1(sc, CMD_REG, MC_Setup_CMD);
903
904                 sc->tx_head = sc->tx_lower_limit;
905                 sc->tx_tail = sc->tx_head + XMT_HEADER_LEN + (count + 1) * 6;
906
907                 for (timeout=0; timeout<100; timeout++) {
908                         DELAY(2);
909                         if ((CSR_READ_1(sc, STATUS_REG) & Exec_Int) == 0)
910                                 continue;
911
912                         status = CSR_READ_1(sc, CMD_REG);
913                         CSR_WRITE_1(sc, STATUS_REG, Exec_Int);
914                         break;
915                 }
916
917                 sc->tx_head = sc->tx_tail;
918         }
919         else
920         {
921                 /* No multicast or promiscuous mode */
922                 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
923                 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) & 0xDE);
924                         /* ~(Multi_IA | Promisc_Mode) */
925                 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3));
926                 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
927         }
928 }
929
930 static void
931 ex_reset(struct ex_softc *sc)
932 {
933         int s;
934
935         DODEBUG(Start_End, printf("ex_reset%d: start\n", unit););
936   
937         s = splimp();
938
939         ex_stop(sc);
940         ex_init(sc);
941
942         splx(s);
943
944         DODEBUG(Start_End, printf("ex_reset%d: finish\n", unit););
945
946         return;
947 }
948
949 static void
950 ex_watchdog(struct ifnet *ifp)
951 {
952         struct ex_softc *       sc = ifp->if_softc;
953
954         DODEBUG(Start_End, printf("%s: ex_watchdog: start\n", ifp->if_xname););
955
956         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
957
958         DODEBUG(Status, printf("OIDLE watchdog\n"););
959
960         ifp->if_oerrors++;
961         ex_reset(sc);
962         ex_start(ifp);
963
964         DODEBUG(Start_End, printf("%s: ex_watchdog: finish\n", ifp->if_xname););
965
966         return;
967 }
968
969 static int
970 ex_get_media(struct ex_softc *sc)
971 {
972         int     current;
973         int     media;
974
975         media = ex_eeprom_read(sc, EE_W5);
976
977         CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
978         current = CSR_READ_1(sc, REG3);
979         CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
980
981         if ((current & TPE_bit) && (media & EE_W5_PORT_TPE))
982                 return(IFM_ETHER|IFM_10_T);
983         if ((current & BNC_bit) && (media & EE_W5_PORT_BNC))
984                 return(IFM_ETHER|IFM_10_2);
985
986         if (media & EE_W5_PORT_AUI)
987                 return (IFM_ETHER|IFM_10_5);
988
989         return (IFM_ETHER|IFM_AUTO);
990 }
991
992 static int
993 ex_ifmedia_upd(ifp)
994         struct ifnet *          ifp;
995 {
996         struct ex_softc *       sc = ifp->if_softc;
997
998         if (IFM_TYPE(sc->ifmedia.ifm_media) != IFM_ETHER)
999                 return EINVAL;
1000
1001         return (0);
1002 }
1003
1004 static void
1005 ex_ifmedia_sts(ifp, ifmr)
1006         struct ifnet *          ifp;
1007         struct ifmediareq *     ifmr;
1008 {
1009         struct ex_softc *       sc = ifp->if_softc;
1010
1011         ifmr->ifm_active = ex_get_media(sc);
1012         ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
1013
1014         return;
1015 }
1016
1017 u_short
1018 ex_eeprom_read(struct ex_softc *sc, int location)
1019 {
1020         int i;
1021         u_short data = 0;
1022         int read_cmd = location | EE_READ_CMD;
1023         short ctrl_val = EECS;
1024
1025         CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
1026         CSR_WRITE_1(sc, EEPROM_REG, EECS);
1027         for (i = 8; i >= 0; i--) {
1028                 short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val;
1029                 CSR_WRITE_1(sc, EEPROM_REG, outval);
1030                 CSR_WRITE_1(sc, EEPROM_REG, outval | EESK);
1031                 DELAY(3);
1032                 CSR_WRITE_1(sc, EEPROM_REG, outval);
1033                 DELAY(2);
1034         }
1035         CSR_WRITE_1(sc, EEPROM_REG, ctrl_val);
1036
1037         for (i = 16; i > 0; i--) {
1038                 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val | EESK);
1039                 DELAY(3);
1040                 data = (data << 1) | 
1041                     ((CSR_READ_1(sc, EEPROM_REG) & EEDO) ? 1 : 0);
1042                 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val);
1043                 DELAY(2);
1044         }
1045
1046         ctrl_val &= ~EECS;
1047         CSR_WRITE_1(sc, EEPROM_REG, ctrl_val | EESK);
1048         DELAY(3);
1049         CSR_WRITE_1(sc, EEPROM_REG, ctrl_val);
1050         DELAY(2);
1051         CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
1052         return(data);
1053 }