]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/dev/ex/if_ex.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.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                 case SIOCADDMULTI:
806                 case SIOCDELMULTI:
807                         ex_init(sc);
808                         error = 0;
809                         break;
810                 case SIOCSIFMEDIA:
811                 case SIOCGIFMEDIA:
812                         error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd);
813                         break;
814                 default:
815                         DODEBUG(Start_End, printf("unknown"););
816                         error = EINVAL;
817         }
818
819         splx(s);
820
821         DODEBUG(Start_End, printf("\n%s: ex_ioctl: finish\n", ifp->if_xname););
822
823         return(error);
824 }
825
826 static void
827 ex_setmulti(struct ex_softc *sc)
828 {
829         struct ifnet *ifp;
830         struct ifmultiaddr *maddr;
831         uint16_t *addr;
832         int count;
833         int timeout, status;
834         
835         ifp = sc->ifp;
836
837         count = 0;
838         IF_ADDR_LOCK(ifp);
839         TAILQ_FOREACH(maddr, &ifp->if_multiaddrs, ifma_link) {
840                 if (maddr->ifma_addr->sa_family != AF_LINK)
841                         continue;
842                 count++;
843         }
844         IF_ADDR_UNLOCK(ifp);
845
846         if ((ifp->if_flags & IFF_PROMISC) || (ifp->if_flags & IFF_ALLMULTI)
847                         || count > 63) {
848                 /* Interface is in promiscuous mode or there are too many
849                  * multicast addresses for the card to handle */
850                 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
851                 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | Promisc_Mode);
852                 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3));
853                 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
854         }
855         else if ((ifp->if_flags & IFF_MULTICAST) && (count > 0)) {
856                 /* Program multicast addresses plus our MAC address
857                  * into the filter */
858                 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
859                 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | Multi_IA);
860                 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3));
861                 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
862
863                 /* Borrow space from TX buffer; this should be safe
864                  * as this is only called from ex_init */
865                 
866                 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_lower_limit);
867                 CSR_WRITE_2(sc, IO_PORT_REG, MC_Setup_CMD);
868                 CSR_WRITE_2(sc, IO_PORT_REG, 0);
869                 CSR_WRITE_2(sc, IO_PORT_REG, 0);
870                 CSR_WRITE_2(sc, IO_PORT_REG, (count + 1) * 6);
871
872                 IF_ADDR_LOCK(ifp);
873                 TAILQ_FOREACH(maddr, &ifp->if_multiaddrs, ifma_link) {
874                         if (maddr->ifma_addr->sa_family != AF_LINK)
875                                 continue;
876
877                         addr = (uint16_t*)LLADDR((struct sockaddr_dl *)
878                                         maddr->ifma_addr);
879                         CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
880                         CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
881                         CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
882                 }
883                 IF_ADDR_UNLOCK(ifp);
884
885                 /* Program our MAC address as well */
886                 /* XXX: Is this necessary?  The Linux driver does this
887                  * but the NetBSD driver does not */
888                 addr = (uint16_t*)IF_LLADDR(sc->ifp);
889                 CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
890                 CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
891                 CSR_WRITE_2(sc, IO_PORT_REG, *addr++);
892
893                 CSR_READ_2(sc, IO_PORT_REG);
894                 CSR_WRITE_2(sc, XMT_BAR, sc->tx_lower_limit);
895                 CSR_WRITE_1(sc, CMD_REG, MC_Setup_CMD);
896
897                 sc->tx_head = sc->tx_lower_limit;
898                 sc->tx_tail = sc->tx_head + XMT_HEADER_LEN + (count + 1) * 6;
899
900                 for (timeout=0; timeout<100; timeout++) {
901                         DELAY(2);
902                         if ((CSR_READ_1(sc, STATUS_REG) & Exec_Int) == 0)
903                                 continue;
904
905                         status = CSR_READ_1(sc, CMD_REG);
906                         CSR_WRITE_1(sc, STATUS_REG, Exec_Int);
907                         break;
908                 }
909
910                 sc->tx_head = sc->tx_tail;
911         }
912         else
913         {
914                 /* No multicast or promiscuous mode */
915                 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
916                 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) & 0xDE);
917                         /* ~(Multi_IA | Promisc_Mode) */
918                 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3));
919                 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
920         }
921 }
922
923 static void
924 ex_reset(struct ex_softc *sc)
925 {
926         int s;
927
928         DODEBUG(Start_End, printf("ex_reset%d: start\n", unit););
929   
930         s = splimp();
931
932         ex_stop(sc);
933         ex_init(sc);
934
935         splx(s);
936
937         DODEBUG(Start_End, printf("ex_reset%d: finish\n", unit););
938
939         return;
940 }
941
942 static void
943 ex_watchdog(struct ifnet *ifp)
944 {
945         struct ex_softc *       sc = ifp->if_softc;
946
947         DODEBUG(Start_End, printf("%s: ex_watchdog: start\n", ifp->if_xname););
948
949         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
950
951         DODEBUG(Status, printf("OIDLE watchdog\n"););
952
953         ifp->if_oerrors++;
954         ex_reset(sc);
955         ex_start(ifp);
956
957         DODEBUG(Start_End, printf("%s: ex_watchdog: finish\n", ifp->if_xname););
958
959         return;
960 }
961
962 static int
963 ex_get_media(struct ex_softc *sc)
964 {
965         int     current;
966         int     media;
967
968         media = ex_eeprom_read(sc, EE_W5);
969
970         CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
971         current = CSR_READ_1(sc, REG3);
972         CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
973
974         if ((current & TPE_bit) && (media & EE_W5_PORT_TPE))
975                 return(IFM_ETHER|IFM_10_T);
976         if ((current & BNC_bit) && (media & EE_W5_PORT_BNC))
977                 return(IFM_ETHER|IFM_10_2);
978
979         if (media & EE_W5_PORT_AUI)
980                 return (IFM_ETHER|IFM_10_5);
981
982         return (IFM_ETHER|IFM_AUTO);
983 }
984
985 static int
986 ex_ifmedia_upd(ifp)
987         struct ifnet *          ifp;
988 {
989         struct ex_softc *       sc = ifp->if_softc;
990
991         if (IFM_TYPE(sc->ifmedia.ifm_media) != IFM_ETHER)
992                 return EINVAL;
993
994         return (0);
995 }
996
997 static void
998 ex_ifmedia_sts(ifp, ifmr)
999         struct ifnet *          ifp;
1000         struct ifmediareq *     ifmr;
1001 {
1002         struct ex_softc *       sc = ifp->if_softc;
1003
1004         ifmr->ifm_active = ex_get_media(sc);
1005         ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
1006
1007         return;
1008 }
1009
1010 u_short
1011 ex_eeprom_read(struct ex_softc *sc, int location)
1012 {
1013         int i;
1014         u_short data = 0;
1015         int read_cmd = location | EE_READ_CMD;
1016         short ctrl_val = EECS;
1017
1018         CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
1019         CSR_WRITE_1(sc, EEPROM_REG, EECS);
1020         for (i = 8; i >= 0; i--) {
1021                 short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val;
1022                 CSR_WRITE_1(sc, EEPROM_REG, outval);
1023                 CSR_WRITE_1(sc, EEPROM_REG, outval | EESK);
1024                 DELAY(3);
1025                 CSR_WRITE_1(sc, EEPROM_REG, outval);
1026                 DELAY(2);
1027         }
1028         CSR_WRITE_1(sc, EEPROM_REG, ctrl_val);
1029
1030         for (i = 16; i > 0; i--) {
1031                 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val | EESK);
1032                 DELAY(3);
1033                 data = (data << 1) | 
1034                     ((CSR_READ_1(sc, EEPROM_REG) & EEDO) ? 1 : 0);
1035                 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val);
1036                 DELAY(2);
1037         }
1038
1039         ctrl_val &= ~EECS;
1040         CSR_WRITE_1(sc, EEPROM_REG, ctrl_val | EESK);
1041         DELAY(3);
1042         CSR_WRITE_1(sc, EEPROM_REG, ctrl_val);
1043         DELAY(2);
1044         CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
1045         return(data);
1046 }