Remove the INTR_TYPE_* flags. The interrupt type is no longer used to
[dragonfly.git] / sys / contrib / dev / oltr / if_oltr.c
1 /*
2  * Copyright (c) 1998, Larry Lile
3  * All rights reserved.
4  *
5  * For latest sources and information on this driver, please
6  * go to http://anarchy.stdio.com.
7  *
8  * Questions, comments or suggestions should be directed to
9  * Larry Lile <lile@stdio.com>.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice unmodified, this list of conditions, and the following
16  *    disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * $FreeBSD: src/sys/contrib/dev/oltr/if_oltr.c,v 1.11.2.5 2001/10/20 04:15:21 mdodd Exp $
34  * $DragonFly: src/sys/contrib/dev/oltr/Attic/if_oltr.c,v 1.21 2005/10/12 17:35:49 dillon Exp $
35  */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/sockio.h>
40 #include <sys/mbuf.h>
41 #include <sys/malloc.h>
42 #include <sys/kernel.h>
43 #include <sys/socket.h>
44 #include <sys/param.h>
45
46 #include <net/if.h>
47 #include <net/if_arp.h>
48 #include <net/iso88025.h>
49 #include <net/ethernet.h>
50 #include <net/if_dl.h>
51 #include <net/if_media.h>
52 #include <net/iso88025.h>
53
54 #if defined(__DragonFly__) || (NBPFILTER > 0)
55 #include <net/bpf.h>
56 #endif
57
58 #include <vm/vm.h>              /* for vtophys */
59 #include <vm/pmap.h>            /* for vtophys */
60 #include <machine/bus_memio.h>
61 #include <machine/bus_pio.h>
62 #include <machine/bus.h>
63 #include <machine/resource.h>
64 #include <machine/clock.h>
65 #include <sys/bus.h>
66 #include <sys/rman.h>
67 #include <sys/thread2.h>
68
69 #include <bus/pci/pcireg.h>
70 #include <bus/pci/pcivar.h>
71
72 #include "contrib/dev/oltr/trlld.h"
73
74 /*#define DEBUG_MASK DEBUG_POLL*/
75
76 #ifndef DEBUG_MASK
77 #define DEBUG_MASK 0x0000
78 #endif
79
80 #define DEBUG_POLL      0x0001
81 #define DEBUG_INT       0x0002
82 #define DEBUG_INIT      0x0004
83 #define DEBUG_FN_ENT    0x8000
84
85 #define PCI_VENDOR_OLICOM 0x108D
86
87 #define MIN3(A,B,C) (MIN(A, (MIN(B, C))))
88
89 char *AdapterName[] = {
90         /*  0 */ "Olicom XT Adapter [unsupported]",
91         /*  1 */ "Olicom OC-3115",
92         /*  2 */ "Olicom ISA 16/4 Adapter (OC-3117)",
93         /*  3 */ "Olicom ISA 16/4 Adapter (OC-3118)",
94         /*  4 */ "Olicom MCA 16/4 Adapter (OC-3129) [unsupported]",
95         /*  5 */ "Olicom MCA 16/4 Adapter (OC-3129) [unsupported]",
96         /*  6 */ "Olicom MCA 16/4 Adapter (OC-3129) [unsupported]",
97         /*  7 */ "Olicom EISA 16/4 Adapter (OC-3133)",
98         /*  8 */ "Olicom EISA 16/4 Adapter (OC-3133)",
99         /*  9 */ "Olicom EISA 16/4 Server Adapter (OC-3135)",
100         /* 10 */ "Olicom PCI 16/4 Adapter (OC-3136)",
101         /* 11 */ "Olicom PCI 16/4 Adapter (OC-3136)",
102         /* 12 */ "Olicom PCI/II 16/4 Adapter (OC-3137)",
103         /* 13 */ "Olicom PCI 16/4 Adapter (OC-3139)",
104         /* 14 */ "Olicom RapidFire 3140 16/4 PCI Adapter (OC-3140)",
105         /* 15 */ "Olicom RapidFire 3141 Fiber Adapter (OC-3141)",
106         /* 16 */ "Olicom PCMCIA 16/4 Adapter (OC-3220) [unsupported]",
107         /* 17 */ "Olicom PCMCIA 16/4 Adapter (OC-3121, OC-3230, OC-3232) [unsupported]",
108         /* 18 */ "Olicom PCMCIA 16/4 Adapter (OC-3250)",
109         /* 19 */ "Olicom RapidFire 3540 100/16/4 Adapter (OC-3540)"
110 };
111
112 /*
113  * Glue function prototypes for PMW kit IO
114  */
115
116 #ifndef TRlldInlineIO
117 static void DriverOutByte       (unsigned short, unsigned char);
118 static void DriverOutWord       (unsigned short, unsigned short);
119 static void DriverOutDword      (unsigned short, unsigned long);
120 static void DriverRepOutByte    (unsigned short, unsigned char  *, int);
121 static void DriverRepOutWord    (unsigned short, unsigned short *, int);
122 static void DriverRepOutDword   (unsigned short, unsigned long  *, int);
123 static unsigned char  DriverInByte (unsigned short);
124 static unsigned short DriverInWord (unsigned short);
125 static unsigned long  DriverInDword (unsigned short);
126 static void DriverRepInByte     (unsigned short, unsigned char  *, int);
127 static void DriverRepInWord     (unsigned short, unsigned short *, int);
128 static void DriverRepInDword    (unsigned short, unsigned long  *, int);
129 #endif /*TRlldInlineIO*/
130 static void DriverSuspend       (unsigned short);
131 static void DriverStatus        (void *, TRlldStatus_t *);
132 static void DriverCloseCompleted (void *);
133 static void DriverStatistics    (void *, TRlldStatistics_t *);
134 static void DriverTransmitFrameCompleted (void *, void *, int);
135 static void DriverReceiveFrameCompleted (void *, int, int, void *, int);
136
137 static TRlldDriver_t LldDriver = {
138         TRLLD_VERSION,
139 #ifndef TRlldInlineIO
140         DriverOutByte,
141         DriverOutWord,
142         DriverOutDword,
143         DriverRepOutByte,
144         DriverRepOutWord,
145         DriverRepOutDword,
146         DriverInByte,
147         DriverInWord,
148         DriverInDword,
149         DriverRepInByte,
150         DriverRepInWord,
151         DriverRepInDword,
152 #endif /*TRlldInlineIO*/
153         DriverSuspend,
154         DriverStatus,
155         DriverCloseCompleted,
156         DriverStatistics,
157         DriverTransmitFrameCompleted,
158         DriverReceiveFrameCompleted,
159 };
160
161 struct oltr_rx_buf {
162         int                     index;
163         char                    *data;
164         u_long                  address;
165 };
166
167 struct oltr_tx_buf {
168         int                     index;
169         char                    *data;
170         u_long                  address;
171 };
172
173 #define RING_BUFFER_LEN         16
174 #define RING_BUFFER(x)          ((RING_BUFFER_LEN - 1) & x)
175 #define RX_BUFFER_LEN           2048
176 #define TX_BUFFER_LEN           2048
177
178 struct oltr_softc {
179         struct arpcom           arpcom;
180         struct ifmedia          ifmedia;
181         bus_space_handle_t      oltr_bhandle;
182         bus_space_tag_t         oltr_btag;
183         void                    *oltr_intrhand;
184         struct resource         *oltr_irq;
185         struct resource         *oltr_res;
186         int                     unit;
187         int                     state;
188 #define OL_UNKNOWN      0
189 #define OL_INIT         1
190 #define OL_READY        2
191 #define OL_CLOSING      3
192 #define OL_CLOSED       4
193 #define OL_OPENING      5
194 #define OL_OPEN         6
195 #define OL_PROMISC      7
196 #define OL_DEAD         8
197         struct oltr_rx_buf      rx_ring[RING_BUFFER_LEN];
198         int                     tx_head, tx_avail, tx_frame;
199         struct oltr_tx_buf      tx_ring[RING_BUFFER_LEN];
200         TRlldTransmit_t         frame_ring[RING_BUFFER_LEN];
201         struct mbuf             *restart;
202         TRlldAdapter_t          TRlldAdapter;
203         TRlldStatistics_t       statistics;
204         TRlldStatistics_t       current;
205         TRlldAdapterConfig_t    config;
206         u_short                 AdapterMode;
207         u_long                  GroupAddress;
208         u_long                  FunctionalAddress;
209         struct callout          oltr_poll_ch;
210         /*struct callout_handle oltr_stat_ch;*/
211         void                    *work_memory;
212 };
213
214 #define SELF_TEST_POLLS 32
215
216 void oltr_poll                  (void *);
217 /*void oltr_stat                        (void *);*/
218
219 static void oltr_start          (struct ifnet *);
220 static void oltr_stop           (struct oltr_softc *);
221 static void oltr_close          (struct oltr_softc *);
222 static void oltr_init           (void *);
223 static int oltr_ioctl           (struct ifnet *, u_long, caddr_t,
224                                  struct ucred *);
225 static void oltr_intr           (void *);
226 static int oltr_ifmedia_upd     (struct ifnet *);
227 static void oltr_ifmedia_sts    (struct ifnet *, struct ifmediareq *);
228
229 #if defined(__DragonFly__) || __FreeBSD_version > 400000
230
231 static int oltr_pci_probe               (device_t);
232 static int oltr_pci_attach      (device_t);
233 static int oltr_pci_detach      (device_t);
234 static void oltr_pci_shutdown   (device_t);
235
236 static device_method_t oltr_methods[] = {
237         DEVMETHOD(device_probe,         oltr_pci_probe),
238         DEVMETHOD(device_attach,        oltr_pci_attach),
239         DEVMETHOD(device_detach,        oltr_pci_detach),
240         DEVMETHOD(device_shutdown,      oltr_pci_shutdown),
241         { 0, 0 }
242 };
243
244 static driver_t oltr_driver = {
245         "oltr",
246         oltr_methods,
247         sizeof(struct oltr_softc)
248 };
249
250 static devclass_t oltr_devclass;
251
252 DRIVER_MODULE(oltr, pci, oltr_driver, oltr_devclass, 0, 0);
253
254 static int
255 oltr_pci_probe(device_t dev)
256 {
257         int                     i, rc;
258         char                    PCIConfigHeader[64];
259         TRlldAdapterConfig_t    config;
260
261         if ((pci_get_vendor(dev) == PCI_VENDOR_OLICOM) &&
262            ((pci_get_device(dev) == 0x0001) ||
263             (pci_get_device(dev) == 0x0004) ||
264             (pci_get_device(dev) == 0x0005) ||
265             (pci_get_device(dev) == 0x0007) ||
266             (pci_get_device(dev) == 0x0008))) {
267
268                 for (i = 0; i < sizeof(PCIConfigHeader); i++)
269                         PCIConfigHeader[i] = pci_read_config(dev, i, 1);
270
271                 rc = TRlldPCIConfig(&LldDriver, &config, PCIConfigHeader);
272                 if (rc == TRLLD_PCICONFIG_FAIL) {
273                         device_printf(dev, "TRlldPciConfig failed!\n");
274                         return(ENXIO);
275                 }
276                 if (rc == TRLLD_PCICONFIG_VERSION) {
277                         device_printf(dev, "wrong LLD version\n");
278                         return(ENXIO);
279                 }
280                 device_set_desc(dev, AdapterName[config.type]);
281                 return(0);
282         }
283         return(ENXIO);
284 }
285
286 static int
287 oltr_pci_attach(device_t dev)
288 {
289         int                     i, rc = 0, rid,
290                                 scratch_size;
291         int                     media = IFM_TOKEN|IFM_TOK_UTP16;
292         u_long                  command;
293         char                    PCIConfigHeader[64];
294         struct oltr_softc               *sc = device_get_softc(dev);
295         struct ifnet            *ifp = &sc->arpcom.ac_if;
296
297         crit_enter();
298
299         bzero(sc, sizeof(struct oltr_softc));
300         sc->unit = device_get_unit(dev);
301         sc->state = OL_UNKNOWN;
302
303         for (i = 0; i < sizeof(PCIConfigHeader); i++)
304                 PCIConfigHeader[i] = pci_read_config(dev, i, 1);
305
306         switch(TRlldPCIConfig(&LldDriver, &sc->config, PCIConfigHeader)) {
307         case TRLLD_PCICONFIG_OK:
308                 break;
309         case TRLLD_PCICONFIG_SET_COMMAND:
310                 device_printf(dev, "enabling bus master mode\n");
311                 command = pci_read_config(dev, PCIR_COMMAND, 4);
312                 pci_write_config(dev, PCIR_COMMAND,
313                         (command | PCIM_CMD_BUSMASTEREN), 4);
314                 command = pci_read_config(dev, PCIR_COMMAND, 4);
315                 if (!(command & PCIM_CMD_BUSMASTEREN)) {
316                         device_printf(dev, "failed to enable bus master mode\n");
317                         goto config_failed;
318                 }
319                 break;
320         case TRLLD_PCICONFIG_FAIL:
321                 device_printf(dev, "TRlldPciConfig failed!\n");
322                 goto config_failed;
323                 break;
324         case TRLLD_PCICONFIG_VERSION:
325                 device_printf(dev, "wrong LLD version\n");
326                 goto config_failed;
327                 break;
328         }
329         device_printf(dev, "MAC address %6D\n", sc->config.macaddress, ":");
330
331         scratch_size = TRlldAdapterSize();
332         if (bootverbose)
333                 device_printf(dev, "adapter memory block size %d bytes\n", scratch_size);
334         sc->TRlldAdapter = (TRlldAdapter_t)malloc(scratch_size, M_DEVBUF, M_NOWAIT);
335         if (sc->TRlldAdapter == NULL) {
336                 device_printf(dev, "couldn't allocate scratch buffer (%d bytes)\n", scratch_size);
337                 goto config_failed;
338         }
339
340         /*
341          * Allocate RX/TX Pools
342          */
343         for (i = 0; i < RING_BUFFER_LEN; i++) {
344                 sc->rx_ring[i].index = i;
345                 sc->rx_ring[i].data = (char *)malloc(RX_BUFFER_LEN, M_DEVBUF, M_NOWAIT);
346                 sc->rx_ring[i].address = vtophys(sc->rx_ring[i].data);
347                 sc->tx_ring[i].index = i;
348                 sc->tx_ring[i].data = (char *)malloc(TX_BUFFER_LEN, M_DEVBUF, M_NOWAIT);
349                 sc->tx_ring[i].address = vtophys(sc->tx_ring[i].data);
350                 if ((!sc->rx_ring[i].data) || (!sc->tx_ring[i].data)) {
351                         device_printf(dev, "unable to allocate ring buffers\n");
352                         while (i > 0) {
353                                 if (sc->rx_ring[i].data)
354                                         free(sc->rx_ring[i].data, M_DEVBUF);
355                                 if (sc->tx_ring[i].data)
356                                         free(sc->tx_ring[i].data, M_DEVBUF);
357                                 i--;
358                         }
359                         goto config_failed;
360                 }
361         }
362         
363         /*
364          * Allocate interrupt and DMA channel
365          */
366         rid = 0;
367         sc->oltr_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
368                 (sc->config.mode & TRLLD_MODE_SHARE_INTERRUPT ? RF_ACTIVE | RF_SHAREABLE : RF_ACTIVE));
369         if (sc->oltr_irq == NULL) {
370                 device_printf(dev, "couldn't map interrupt\n");
371                 goto config_failed;
372         }
373         if (bus_setup_intr(dev, sc->oltr_irq, 0, oltr_intr, sc,
374             &sc->oltr_intrhand, NULL)) {
375                 device_printf(dev, "couldn't setup interrupt\n");
376                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->oltr_irq);
377                 goto config_failed;
378         }
379
380         /*
381          * Do the ifnet initialization
382          */
383         ifp->if_softc   = sc;
384         if_initname(ifp, "oltr", device_get_unit(dev));
385         ifp->if_init    = oltr_init;
386         ifp->if_start   = oltr_start;
387         ifp->if_ioctl   = oltr_ioctl;
388         ifp->if_flags   = IFF_BROADCAST;
389         bcopy(sc->config.macaddress, sc->arpcom.ac_enaddr, sizeof(sc->config.macaddress));
390
391         /*
392          * Do ifmedia setup.
393          */
394         ifmedia_init(&sc->ifmedia, 0, oltr_ifmedia_upd, oltr_ifmedia_sts);
395         rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
396         switch(sc->config.type) {
397         case TRLLD_ADAPTER_PCI7:        /* OC-3540 */
398                 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP100, 0, NULL);
399                 /* FALL THROUGH */
400         case TRLLD_ADAPTER_PCI4:        /* OC-3139 */
401         case TRLLD_ADAPTER_PCI5:        /* OC-3140 */
402         case TRLLD_ADAPTER_PCI6:        /* OC-3141 */
403                 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_AUTO, 0, NULL);
404                 media = IFM_TOKEN|IFM_AUTO;
405                 rc = TRlldSetSpeed(sc->TRlldAdapter, 0);
406                 /* FALL THROUGH */
407         default:
408                 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP4, 0, NULL);
409                 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP16, 0, NULL);
410                 break;
411         }
412         sc->ifmedia.ifm_media = media;
413         ifmedia_set(&sc->ifmedia, media);
414
415         /*
416          * Attach the interface
417          */
418         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
419         iso88025_ifattach(ifp);
420
421         crit_exit();
422         return(0);
423
424 config_failed:
425
426         crit_exit();
427         return(ENXIO);
428 }
429
430 static int
431 oltr_pci_detach(device_t dev)
432 {
433         struct oltr_softc       *sc = device_get_softc(dev);
434         struct ifnet            *ifp = &sc->arpcom.ac_if;
435         int i;
436
437         device_printf(dev, "driver unloading\n");
438
439         crit_enter();
440
441         if_detach(ifp);
442         if (sc->state > OL_CLOSED)
443                 oltr_stop(sc);
444
445         callout_stop(&sc->oltr_poll_ch);
446         /*untimeout(oltr_stat, (void *)sc, sc->oltr_stat_ch);*/
447
448         bus_teardown_intr(dev, sc->oltr_irq, sc->oltr_intrhand);
449         bus_release_resource(dev, SYS_RES_IRQ, 0, sc->oltr_irq);
450
451         /* Deallocate all dynamic memory regions */
452         for (i = 0; i < RING_BUFFER_LEN; i++) {
453                 free(sc->rx_ring[i].data, M_DEVBUF);
454                 free(sc->tx_ring[i].data, M_DEVBUF);
455         }
456         if (sc->work_memory)
457                 free(sc->work_memory, M_DEVBUF);
458         free(sc->TRlldAdapter, M_DEVBUF);
459
460         crit_exit();
461
462         return(0);
463 }
464
465 static void
466 oltr_pci_shutdown(device_t dev)
467 {
468         struct oltr_softc               *sc = device_get_softc(dev);
469
470         device_printf(dev, "oltr_pci_shutdown called\n");
471
472         if (sc->state > OL_CLOSED)
473                 oltr_stop(sc);
474
475         return;
476 }
477
478 #else
479
480 static const char *oltr_pci_probe       (pcici_t, pcidi_t);
481 static void oltr_pci_attach             (pcici_t, int);
482
483 static unsigned long oltr_count = 0;
484
485 static struct pci_device oltr_device = {
486         "oltr",
487         oltr_pci_probe,
488         oltr_pci_attach,
489         &oltr_count,
490         NULL
491 };
492
493 DATA_SET(pcidevice_set, oltr_device);
494
495 static const char *
496 oltr_pci_probe(pcici_t config_id, pcidi_t device_id)
497 {
498         int                     i, rc;
499         char                    PCIConfigHeader[64];
500         TRlldAdapterConfig_t    config;
501         
502         if (((device_id & 0xffff) == PCI_VENDOR_OLICOM) && (
503             (((device_id >> 16) & 0xffff) == 0x0001) ||
504             (((device_id >> 16) & 0xffff) == 0x0004) ||
505             (((device_id >> 16) & 0xffff) == 0x0005) ||
506             (((device_id >> 16) & 0xffff) == 0x0007) ||
507             (((device_id >> 16) & 0xffff) == 0x0008))) {
508         
509                 for (i = 0; i < 64; i++)
510                         PCIConfigHeader[i] = pci_cfgread(config_id, i, /* bytes */ 1);
511
512                 rc = TRlldPCIConfig(&LldDriver, &config, PCIConfigHeader);
513
514                 if (rc == TRLLD_PCICONFIG_FAIL) {
515                         printf("oltr: TRlldPciConfig failed!\n");
516                         return(NULL);
517                 }
518                 if (rc == TRLLD_PCICONFIG_VERSION) {
519                         printf("oltr: wrong LLD version.\n");
520                         return(NULL);
521                 }
522                 return(AdapterName[config.type]);
523         }
524
525         return(NULL);
526 }
527
528 static void
529 oltr_pci_attach(pcici_t config_id, int unit)
530 {
531         int                     i, rc = 0, scratch_size;
532         int                     media = IFM_TOKEN|IFM_TOK_UTP16;
533         u_long                  command;
534         char                    PCIConfigHeader[64];
535         struct oltr_softc               *sc;
536         struct ifnet            *ifp; /* = &sc->arpcom.ac_if; */
537
538         crit_enter();
539
540         sc = malloc(sizeof(struct oltr_softc), M_DEVBUF, M_NOWAIT | M_ZERO);
541         if (sc == NULL) {
542                 printf("oltr%d: no memory for softc struct!\n", unit);
543                 goto config_failed;
544         }
545         sc->unit = unit;
546         sc->state = OL_UNKNOWN;
547         ifp = &sc->arpcom.ac_if;
548
549         for (i = 0; i < sizeof(PCIConfigHeader); i++)
550                 PCIConfigHeader[i] = pci_cfgread(config_id, i, 1);
551
552         switch(TRlldPCIConfig(&LldDriver, &sc->config, PCIConfigHeader)) {
553         case TRLLD_PCICONFIG_OK:
554                 break;
555         case TRLLD_PCICONFIG_SET_COMMAND:
556                 printf("oltr%d: enabling bus master mode\n", unit);
557                 command = pci_conf_read(config_id, PCIR_COMMAND);
558                 pci_conf_write(config_id, PCIR_COMMAND, (command | PCIM_CMD_BUSMASTEREN));
559                 command = pci_conf_read(config_id, PCIR_COMMAND);
560                 if (!(command & PCIM_CMD_BUSMASTEREN)) {
561                         printf("oltr%d: failed to enable bus master mode\n", unit);
562                         goto config_failed;
563                 }
564                 break;
565         case TRLLD_PCICONFIG_FAIL:
566                 printf("oltr%d: TRlldPciConfig failed!\n", unit);
567                 goto config_failed;
568                 break;
569         case TRLLD_PCICONFIG_VERSION:
570                 printf("oltr%d: wrong LLD version\n", unit);
571                 goto config_failed;
572                 break;
573         }
574         printf("oltr%d: MAC address %6D\n", unit, sc->config.macaddress, ":");
575
576         scratch_size = TRlldAdapterSize();
577         if (bootverbose)
578                 printf("oltr%d: adapter memory block size %d bytes\n", unit, scratch_size);
579         sc->TRlldAdapter = (TRlldAdapter_t)malloc(scratch_size, M_DEVBUF, M_NOWAIT);
580         if (sc->TRlldAdapter == NULL) {
581                 printf("oltr%d: couldn't allocate scratch buffer (%d bytes)\n",unit, scratch_size);
582                 goto config_failed;
583         }
584
585         /*
586          * Allocate RX/TX Pools
587          */
588         for (i = 0; i < RING_BUFFER_LEN; i++) {
589                 sc->rx_ring[i].index = i;
590                 sc->rx_ring[i].data = (char *)malloc(RX_BUFFER_LEN, M_DEVBUF, M_NOWAIT);
591                 sc->rx_ring[i].address = vtophys(sc->rx_ring[i].data);
592                 sc->tx_ring[i].index = i;
593                 sc->tx_ring[i].data = (char *)malloc(TX_BUFFER_LEN, M_DEVBUF, M_NOWAIT);
594                 sc->tx_ring[i].address = vtophys(sc->tx_ring[i].data);
595                 if ((!sc->rx_ring[i].data) || (!sc->tx_ring[i].data)) {
596                         printf("oltr%d: unable to allocate ring buffers\n", unit);
597                         while (i > 0) {
598                                 if (sc->rx_ring[i].data)
599                                         free(sc->rx_ring[i].data, M_DEVBUF);
600                                 if (sc->tx_ring[i].data)
601                                         free(sc->tx_ring[i].data, M_DEVBUF);
602                                 i--;
603                         }
604                         goto config_failed;
605                 }
606         }
607         
608         /*
609          * Allocate interrupt and DMA channel
610          */
611         if (!pci_map_int(config_id, oltr_intr, sc)) {
612                 printf("oltr%d: couldn't setup interrupt\n", unit);
613                 goto config_failed;
614         }
615
616         /*
617          * Do the ifnet initialization
618          */
619         ifp->if_softc   = sc;
620         if_initname(ifp, "oltr", unit);
621         ifp->if_output  = iso88025_output;
622         ifp->if_init    = oltr_init;
623         ifp->if_start   = oltr_start;
624         ifp->if_ioctl   = oltr_ioctl;
625         ifp->if_flags   = IFF_BROADCAST;
626         bcopy(sc->config.macaddress, sc->arpcom.ac_enaddr, sizeof(sc->config.macaddress));
627
628         /*
629          * Do ifmedia setup.
630          */
631         ifmedia_init(&sc->ifmedia, 0, oltr_ifmedia_upd, oltr_ifmedia_sts);
632         rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
633         switch(sc->config.type) {
634         case TRLLD_ADAPTER_PCI7:        /* OC-3540 */
635                 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP100, 0, NULL);
636                 /* FALL THROUGH */
637         case TRLLD_ADAPTER_PCI4:        /* OC-3139 */
638         case TRLLD_ADAPTER_PCI5:        /* OC-3140 */
639         case TRLLD_ADAPTER_PCI6:        /* OC-3141 */
640                 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_AUTO, 0, NULL);
641                 media = IFM_TOKEN|IFM_AUTO;
642                 rc = TRlldSetSpeed(sc->TRlldAdapter, 0);
643                 /* FALL THROUGH */
644         default:
645                 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP4, 0, NULL);
646                 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP16, 0, NULL);
647                 break;
648         }
649         sc->ifmedia.ifm_media = media;
650         ifmedia_set(&sc->ifmedia, media);
651
652         /*
653          * Attach the interface
654          */
655         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
656         iso88025_ifattach(ifp);
657
658         crit_exit();
659         return;
660
661 config_failed:
662         crit_exit();
663
664         return;
665 }
666
667 #endif
668
669 static void
670 oltr_intr(void *xsc)
671 {
672         struct oltr_softc               *sc = (struct oltr_softc *)xsc;
673
674         if (DEBUG_MASK & DEBUG_INT)
675                 printf("I");
676
677         TRlldInterruptService(sc->TRlldAdapter);
678
679         return;
680 }
681
682 static void
683 oltr_start(struct ifnet *ifp)
684 {
685         struct oltr_softc       *sc = ifp->if_softc;
686         struct mbuf             *m0, *m;
687         int                     copy_len, buffer, frame, fragment, rc;
688         
689         /*
690          * Check to see if output is already active
691          */
692         if (ifp->if_flags & IFF_OACTIVE)
693                 return;
694
695 outloop:
696
697         /*
698          * Make sure we have buffers to transmit with
699          */
700         if (sc->tx_avail <= 0) {
701                 printf("oltr%d: tx queue full\n", sc->unit);
702                 ifp->if_flags |= IFF_OACTIVE;
703                 return;
704         }
705
706         if (sc->restart == NULL) {
707                 IF_DEQUEUE(&ifp->if_snd, m);
708                 if (m == NULL)
709                         return;
710         } else {
711                 m = sc->restart;
712                 sc->restart = NULL;
713         }
714
715         m0 = m;
716         frame = RING_BUFFER(sc->tx_frame);
717         buffer = RING_BUFFER(sc->tx_head);
718         fragment = 0;
719         copy_len = 0;
720         sc->frame_ring[frame].FragmentCount = 0;
721         
722         while (copy_len < m0->m_pkthdr.len) {
723                 sc->frame_ring[frame].FragmentCount++;
724                 if (sc->frame_ring[frame].FragmentCount > sc->tx_avail)
725                         goto nobuffers;
726                 sc->frame_ring[frame].TransmitFragment[fragment].VirtualAddress = sc->tx_ring[buffer].data;
727                 sc->frame_ring[frame].TransmitFragment[fragment].PhysicalAddress = sc->tx_ring[buffer].address;
728                 sc->frame_ring[frame].TransmitFragment[fragment].count = MIN(m0->m_pkthdr.len - copy_len, TX_BUFFER_LEN);
729                 m_copydata(m0, copy_len, MIN(m0->m_pkthdr.len - copy_len, TX_BUFFER_LEN), sc->tx_ring[buffer].data);
730                 copy_len += MIN(m0->m_pkthdr.len - copy_len, TX_BUFFER_LEN);
731                 fragment++;
732                 buffer = RING_BUFFER((buffer + 1));
733         }
734
735         crit_enter();
736         rc = TRlldTransmitFrame(sc->TRlldAdapter, &sc->frame_ring[frame],
737                                 (void *)&sc->frame_ring[frame]);
738         crit_exit();
739
740         if (rc != TRLLD_TRANSMIT_OK) {
741                 printf("oltr%d: TRlldTransmitFrame returned %d\n", sc->unit, rc);
742                 ifp->if_oerrors++;
743                 goto bad;
744         }
745
746         sc->tx_avail -= sc->frame_ring[frame].FragmentCount;
747         sc->tx_head = RING_BUFFER((sc->tx_head + sc->frame_ring[frame].FragmentCount));
748         sc->tx_frame++;
749
750         BPF_MTAP(ifp, m0);
751         /*ifp->if_opackets++;*/
752
753 bad:
754         m_freem(m0);
755
756         goto outloop;
757
758 nobuffers:
759
760         printf("oltr%d: queue full\n", sc->unit);
761         ifp->if_flags |= IFF_OACTIVE;
762         ifp->if_oerrors++;
763         /*m_freem(m0);*/
764         sc->restart = m0;
765
766         return;
767 }
768
769 static void
770 oltr_close(struct oltr_softc *sc)
771 {
772         /*printf("oltr%d: oltr_close\n", sc->unit);*/
773
774         oltr_stop(sc);
775
776         tsleep(sc, 0, "oltrclose", 30*hz);
777 }
778
779 static void
780 oltr_stop(struct oltr_softc *sc)
781 {
782         struct ifnet            *ifp = &sc->arpcom.ac_if;
783
784         /*printf("oltr%d: oltr_stop\n", sc->unit);*/
785
786         ifp->if_flags &= ~(IFF_UP | IFF_RUNNING | IFF_OACTIVE);
787         TRlldClose(sc->TRlldAdapter, 0);
788         sc->state = OL_CLOSING;
789 }
790
791 static void
792 oltr_init(void * xsc)
793 {
794         struct oltr_softc       *sc = (struct oltr_softc *)xsc;
795         struct ifnet            *ifp = &sc->arpcom.ac_if;
796         struct ifmedia          *ifm = &sc->ifmedia;
797         int                     poll = 0, i, rc = 0;
798         int                     work_size;
799
800         /*
801          * Check adapter state, don't allow multiple inits
802          */
803         if (sc->state > OL_CLOSED) {
804                 printf("oltr%d: adapter not ready\n", sc->unit);
805                 return;
806         }
807
808         crit_enter();
809
810         /*
811          * Initialize Adapter
812          */
813         if ((rc = TRlldAdapterInit(&LldDriver, sc->TRlldAdapter, vtophys(sc->TRlldAdapter),
814             (void *)sc, &sc->config)) != TRLLD_INIT_OK) {
815                 switch(rc) {
816                 case TRLLD_INIT_NOT_FOUND:
817                         printf("oltr%d: adapter not found\n", sc->unit);
818                         break;
819                 case TRLLD_INIT_UNSUPPORTED:
820                         printf("oltr%d: adapter not supported by low level driver\n", sc->unit);
821                         break;
822                 case TRLLD_INIT_PHYS16:
823                         printf("oltr%d: adapter memory block above 16M cannot DMA\n", sc->unit);
824                         break;
825                 case TRLLD_INIT_VERSION:
826                         printf("oltr%d: low level driver version mismatch\n", sc->unit);
827                         break;
828                 default:
829                         printf("oltr%d: unknown init error %d\n", sc->unit, rc);
830                         break;
831                 }
832                 goto init_failed;
833         }
834         sc->state = OL_INIT;
835
836         switch(sc->config.type) {
837         case TRLLD_ADAPTER_PCI4:        /* OC-3139 */
838                 work_size = 32 * 1024;
839                 break;
840         case TRLLD_ADAPTER_PCI7:        /* OC-3540 */
841                 work_size = 256;
842                 break;
843         default:
844                 work_size = 0;
845         }
846
847         if (work_size) {
848                 if ((sc->work_memory = malloc(work_size, M_DEVBUF, M_NOWAIT)) == NULL) {
849                         printf("oltr%d: failed to allocate work memory (%d octets).\n", sc->unit, work_size);
850                 } else {
851                 TRlldAddMemory(sc->TRlldAdapter, sc->work_memory,
852                     vtophys(sc->work_memory), work_size);
853                 }
854         }
855
856         switch(IFM_SUBTYPE(ifm->ifm_media)) {
857         case IFM_AUTO:
858                 rc = TRlldSetSpeed(sc->TRlldAdapter, 0); /* TRLLD_SPEED_AUTO */
859                 break;
860         case IFM_TOK_UTP4:
861                 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_4MBPS);
862                 break;
863         case IFM_TOK_UTP16:
864                 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
865                 break;
866         case IFM_TOK_UTP100:
867                 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_100MBPS);
868                 break;
869         }
870
871         /*
872          * Download adapter micro-code
873          */
874         if (bootverbose)
875                 printf("oltr%d: Downloading adapter microcode: ", sc->unit);
876
877         switch(sc->config.mactype) {
878         case TRLLD_MAC_TMS:
879                 rc = TRlldDownload(sc->TRlldAdapter, TRlldMacCode);
880                 if (bootverbose)
881                         printf("TMS-380");
882                 break;
883         case TRLLD_MAC_HAWKEYE:
884                 rc = TRlldDownload(sc->TRlldAdapter, TRlldHawkeyeMac);
885                 if (bootverbose)
886                         printf("Hawkeye");
887                 break;
888         case TRLLD_MAC_BULLSEYE:
889                 rc = TRlldDownload(sc->TRlldAdapter, TRlldBullseyeMac);
890                 if (bootverbose)
891                         printf("Bullseye");
892                 break;
893         default:
894                 if (bootverbose)
895                         printf("unknown - failed!\n");
896                 goto init_failed;
897                 break;
898         }
899
900         /*
901          * Check download status
902          */
903         switch(rc) {
904         case TRLLD_DOWNLOAD_OK:
905                 if (bootverbose)
906                         printf(" - ok\n");
907                 break;
908         case TRLLD_DOWNLOAD_ERROR:
909                 if (bootverbose)
910                         printf(" - failed\n");
911                 else
912                         printf("oltr%d: adapter microcode download failed\n", sc->unit);
913                 goto init_failed;
914                 break;
915         case TRLLD_STATE:
916                 if (bootverbose)
917                         printf(" - not ready\n");
918                 goto init_failed;
919                 break;
920         }
921
922         /*
923          * Wait for self-test to complete
924          */
925         i = 0;
926         while ((poll++ < SELF_TEST_POLLS) && (sc->state < OL_READY)) {
927                 if (DEBUG_MASK & DEBUG_INIT)
928                         printf("p");
929                 DELAY(TRlldPoll(sc->TRlldAdapter) * 1000);
930                 if (TRlldInterruptService(sc->TRlldAdapter) != 0)
931                         if (DEBUG_MASK & DEBUG_INIT) printf("i");
932         }
933
934         if (sc->state != OL_CLOSED) {
935                 printf("oltr%d: self-test failed\n", sc->unit);
936                 goto init_failed;
937         }
938
939         /*
940          * Set up adapter poll
941          */
942         callout_init(&sc->oltr_poll_ch);
943         callout_reset(&sc->oltr_poll_ch, 1, oltr_poll, sc);
944
945         sc->state = OL_OPENING;
946
947         /*
948          * Open the adapter
949          */
950         rc = TRlldOpen(sc->TRlldAdapter, sc->arpcom.ac_enaddr, sc->GroupAddress,
951                 sc->FunctionalAddress, 1552, sc->AdapterMode);
952         switch(rc) {
953                 case TRLLD_OPEN_OK:
954                         break;
955                 case TRLLD_OPEN_STATE:
956                         printf("oltr%d: adapter not ready for open\n", sc->unit);
957                         crit_exit();
958                         return;
959                 case TRLLD_OPEN_ADDRESS_ERROR:
960                         printf("oltr%d: illegal MAC address\n", sc->unit);
961                         crit_exit();
962                         return;
963                 case TRLLD_OPEN_MODE_ERROR:
964                         printf("oltr%d: illegal open mode\n", sc->unit);
965                         crit_exit();
966                         return;
967                 default:
968                         printf("oltr%d: unknown open error (%d)\n", sc->unit, rc);
969                         crit_exit();
970                         return;
971         }
972
973         /*
974          * Set promiscious mode for now...
975          */
976         TRlldSetPromiscuousMode(sc->TRlldAdapter, TRLLD_PROM_LLC);
977         ifp->if_flags |= IFF_PROMISC;
978
979         /*
980          * Block on the ring insert and set a timeout
981          */
982         tsleep(sc, 0, "oltropen", 30*hz);
983
984         /*
985          * Set up receive buffer ring
986          */
987         for (i = 0; i < RING_BUFFER_LEN; i++) {
988                 rc = TRlldReceiveFragment(sc->TRlldAdapter, (void *)sc->rx_ring[i].data,
989                         sc->rx_ring[i].address, RX_BUFFER_LEN, (void *)sc->rx_ring[i].index);
990                 if (rc != TRLLD_RECEIVE_OK) {
991                         printf("oltr%d: adapter refused receive fragment %d (rc = %d)\n", sc->unit, i, rc);
992                         break;
993                 }       
994         }
995
996         sc->tx_avail = RING_BUFFER_LEN;
997         sc->tx_head = 0;
998         sc->tx_frame = 0;
999
1000         sc->restart = NULL;
1001
1002         ifp->if_flags |= IFF_RUNNING;
1003         ifp->if_flags &= ~IFF_OACTIVE;
1004
1005         /*
1006          * Set up adapter statistics poll
1007          */
1008         /*callout_handle_init(&sc->oltr_stat_ch);*/
1009         /*sc->oltr_stat_ch = timeout(oltr_stat, (void *)sc, 1*hz);*/
1010
1011         crit_exit();
1012         return;
1013
1014 init_failed:
1015         sc->state = OL_DEAD;
1016         crit_exit();
1017         return;
1018 }
1019
1020 static int
1021 oltr_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
1022 {
1023         struct oltr_softc       *sc = ifp->if_softc;
1024         struct ifreq            *ifr = (struct ifreq *)data;
1025         int                     error = 0;
1026
1027         crit_enter();
1028
1029         switch(command) {
1030         case SIOCSIFADDR:
1031         case SIOCGIFADDR:
1032         case SIOCSIFMTU:
1033                 error = iso88025_ioctl(ifp, command, data);
1034                 break;
1035
1036         case SIOCSIFFLAGS:
1037                 if (ifp->if_flags & IFF_UP) {
1038                         oltr_init(sc);
1039                 } else {
1040                         if (ifp->if_flags & IFF_RUNNING) {
1041                                 oltr_close(sc);
1042                         }
1043                 }
1044                 break;
1045         case SIOCGIFMEDIA:
1046         case SIOCSIFMEDIA:
1047                 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
1048                 break;
1049         default:
1050                 error = EINVAL;
1051                 break;
1052         }
1053
1054         crit_exit();
1055
1056         return(error);
1057 }
1058
1059
1060 void
1061 oltr_poll(void *arg)
1062 {
1063         struct oltr_softc *sc = (struct oltr_softc *)arg;
1064
1065         crit_enter();
1066
1067         if (DEBUG_MASK & DEBUG_POLL) printf("P");
1068
1069         /* Set up next adapter poll */
1070         callout_reset(&sc->oltr_poll_ch,
1071                       (TRlldPoll(sc->TRlldAdapter) * hz / 1000), oltr_poll, sc);
1072
1073         crit_exit();
1074 }
1075
1076 #ifdef NOTYET
1077 void
1078 oltr_stat(void *arg)
1079 {
1080         struct oltr_softc       *sc = (struct oltr_softc *)arg;
1081
1082         crit_enter();
1083
1084         /* Set up next adapter poll */
1085         sc->oltr_stat_ch = timeout(oltr_stat, (void *)sc, 1*hz);
1086         if (TRlldGetStatistics(sc->TRlldAdapter, &sc->current, 0) != 0) {
1087                 /*printf("oltr%d: statistics available immediately...\n", sc->unit);*/
1088                 DriverStatistics((void *)sc, &sc->current);
1089         }
1090
1091         crit_exit();
1092 }
1093 #endif
1094 static int
1095 oltr_ifmedia_upd(struct ifnet *ifp)
1096 {
1097         struct oltr_softc       *sc = ifp->if_softc;
1098         struct ifmedia          *ifm = &sc->ifmedia;
1099         int                     rc;
1100
1101         if (IFM_TYPE(ifm->ifm_media) != IFM_TOKEN)
1102                 return(EINVAL);
1103
1104         switch(IFM_SUBTYPE(ifm->ifm_media)) {
1105         case IFM_AUTO:
1106                 rc = TRlldSetSpeed(sc->TRlldAdapter, 0); /* TRLLD_SPEED_AUTO */
1107                 break;
1108         case IFM_TOK_UTP4:
1109                 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_4MBPS);
1110                 break;
1111         case IFM_TOK_UTP16:
1112                 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
1113                 break;
1114         case IFM_TOK_UTP100:
1115                 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_100MBPS);
1116                 break;
1117         default:
1118                 return(EINVAL);
1119                 break;
1120         }
1121
1122         return(0);
1123
1124 }
1125
1126 static void
1127 oltr_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
1128 {
1129         struct oltr_softc       *sc = ifp->if_softc;
1130         struct ifmedia          *ifm = &sc->ifmedia;
1131
1132         /*printf("oltr%d: oltr_ifmedia_sts\n", sc->unit);*/
1133
1134         ifmr->ifm_active = IFM_TYPE(ifm->ifm_media)|IFM_SUBTYPE(ifm->ifm_media);
1135
1136 }
1137
1138 /*
1139  * ---------------------- PMW Callback Functions -----------------------
1140  */
1141
1142 void
1143 DriverStatistics(void *DriverHandle, TRlldStatistics_t *statistics)
1144 {
1145 #ifdef NOTYET
1146         struct oltr_softc               *sc = (struct oltr_softc *)DriverHandle;
1147
1148         if (sc->statistics.LineErrors != statistics->LineErrors)
1149                 printf("oltr%d: Line Errors %lu\n", sc->unit,
1150                     statistics->LineErrors);
1151         if (sc->statistics.InternalErrors != statistics->InternalErrors)
1152                 printf("oltr%d: Internal Errors %lu\n", sc->unit,
1153                     statistics->InternalErrors);
1154         if (sc->statistics.BurstErrors != statistics->BurstErrors)
1155                 printf("oltr%d: Burst Errors %lu\n", sc->unit,
1156                     statistics->BurstErrors);
1157         if (sc->statistics.AbortDelimiters != statistics->AbortDelimiters)
1158                 printf("oltr%d: Abort Delimiters %lu\n", sc->unit,
1159                     statistics->AbortDelimiters);
1160         if (sc->statistics.ARIFCIErrors != statistics->ARIFCIErrors)
1161                 printf("oltr%d: ARIFCI Errors %lu\n", sc->unit,
1162                     statistics->ARIFCIErrors);
1163         if (sc->statistics.LostFrames != statistics->LostFrames)
1164                 printf("oltr%d: Lost Frames %lu\n", sc->unit,
1165                     statistics->LostFrames);
1166         if (sc->statistics.CongestionErrors != statistics->CongestionErrors)
1167                 printf("oltr%d: Congestion Errors %lu\n", sc->unit,
1168                     statistics->CongestionErrors);
1169         if (sc->statistics.FrequencyErrors != statistics->FrequencyErrors)
1170                 printf("oltr%d: Frequency Errors %lu\n", sc->unit,
1171                     statistics->FrequencyErrors);
1172         if (sc->statistics.TokenErrors != statistics->TokenErrors)
1173                 printf("oltr%d: Token Errors %lu\n", sc->unit,
1174                     statistics->TokenErrors);
1175         if (sc->statistics.DMABusErrors != statistics->DMABusErrors)
1176                 printf("oltr%d: DMA Bus Errors %lu\n", sc->unit,
1177                     statistics->DMABusErrors);
1178         if (sc->statistics.DMAParityErrors != statistics->DMAParityErrors)
1179                 printf("oltr%d: DMA Parity Errors %lu\n", sc->unit,
1180                     statistics->DMAParityErrors);
1181         if (sc->statistics.ReceiveLongFrame != statistics->ReceiveLongFrame)
1182                 printf("oltr%d: Long frames received %lu\n", sc->unit,
1183                     statistics->ReceiveLongFrame);
1184         if (sc->statistics.ReceiveCRCErrors != statistics->ReceiveCRCErrors)
1185                 printf("oltr%d: Receive CRC Errors %lu\n", sc->unit,
1186                     statistics->ReceiveCRCErrors);
1187         if (sc->statistics.ReceiveOverflow != statistics->ReceiveOverflow)
1188                 printf("oltr%d: Recieve overflows %lu\n", sc->unit,
1189                     statistics->ReceiveOverflow);
1190         if (sc->statistics.TransmitUnderrun != statistics->TransmitUnderrun)
1191                 printf("oltr%d: Frequency Errors %lu\n", sc->unit,
1192                     statistics->TransmitUnderrun);
1193         bcopy(statistics, &sc->statistics, sizeof(TRlldStatistics_t));
1194 #endif
1195 }
1196
1197 static void
1198 DriverSuspend(unsigned short MicroSeconds)
1199 {
1200     DELAY(MicroSeconds);
1201 }
1202
1203
1204 static void
1205 DriverStatus(void *DriverHandle, TRlldStatus_t *Status)
1206 {
1207         struct oltr_softc       *sc = (struct oltr_softc *)DriverHandle;
1208         struct ifnet            *ifp = &sc->arpcom.ac_if;
1209
1210         char *Protocol[] = { /* 0 */ "Unknown",
1211                              /* 1 */ "TKP",
1212                              /* 2 */ "TXI" };
1213         char *Timeout[]  = { /* 0 */ "command",
1214                              /* 1 */ "transmit",
1215                              /* 2 */ "interrupt" };
1216         
1217         switch (Status->Type) {
1218
1219         case TRLLD_STS_ON_WIRE:
1220                 printf("oltr%d: ring insert (%d Mbps - %s)\n", sc->unit,
1221                     Status->Specification.OnWireInformation.Speed,
1222                     Protocol[Status->Specification.OnWireInformation.AccessProtocol]);
1223                 sc->state = OL_OPEN;
1224                 wakeup(sc);
1225                 break;
1226         case TRLLD_STS_SELFTEST_STATUS:
1227                 if (Status->Specification.SelftestStatus == TRLLD_ST_OK) {
1228                         sc->state = OL_CLOSED;
1229                         if (bootverbose)
1230                                 printf("oltr%d: self test complete\n", sc->unit);
1231                 }
1232                 if (Status->Specification.SelftestStatus & TRLLD_ST_ERROR) {
1233                         printf("oltr%d: Adapter self test error %d", sc->unit,
1234                         Status->Specification.SelftestStatus & ~TRLLD_ST_ERROR);
1235                         sc->state = OL_DEAD;
1236                 }
1237                 if (Status->Specification.SelftestStatus & TRLLD_ST_TIMEOUT) {
1238                         printf("oltr%d: Adapter self test timed out.\n", sc->unit);
1239                         sc->state = OL_DEAD;
1240                 }
1241                 break;
1242         case TRLLD_STS_INIT_STATUS:
1243                 if (Status->Specification.InitStatus == 0x800) {
1244                         oltr_stop(sc);
1245                         ifmedia_set(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP16);
1246                         TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
1247                         oltr_init(sc);
1248                         break;
1249                 }
1250                 printf("oltr%d: adapter init failure 0x%03x\n", sc->unit,
1251                     Status->Specification.InitStatus);
1252                 oltr_stop(sc);
1253                 break;
1254         case TRLLD_STS_RING_STATUS:
1255                 if (Status->Specification.RingStatus) {
1256                         printf("oltr%d: Ring status change: ", sc->unit);
1257                         if (Status->Specification.RingStatus &
1258                             TRLLD_RS_SIGNAL_LOSS)
1259                                 printf(" [Signal Loss]");
1260                         if (Status->Specification.RingStatus &
1261                             TRLLD_RS_HARD_ERROR)
1262                                 printf(" [Hard Error]");
1263                         if (Status->Specification.RingStatus &
1264                             TRLLD_RS_SOFT_ERROR)
1265                                 printf(" [Soft Error]");
1266                         if (Status->Specification.RingStatus &
1267                             TRLLD_RS_TRANSMIT_BEACON)
1268                                 printf(" [Beacon]");
1269                         if (Status->Specification.RingStatus &
1270                             TRLLD_RS_LOBE_WIRE_FAULT)
1271                                 printf(" [Wire Fault]");
1272                         if (Status->Specification.RingStatus &
1273                             TRLLD_RS_AUTO_REMOVAL_ERROR)
1274                                 printf(" [Auto Removal]");
1275                         if (Status->Specification.RingStatus &
1276                             TRLLD_RS_REMOVE_RECEIVED)
1277                                 printf(" [Remove Received]");
1278                         if (Status->Specification.RingStatus &
1279                             TRLLD_RS_COUNTER_OVERFLOW)
1280                                 printf(" [Counter Overflow]");
1281                         if (Status->Specification.RingStatus &
1282                             TRLLD_RS_SINGLE_STATION)
1283                                 printf(" [Single Station]");
1284                         if (Status->Specification.RingStatus &
1285                                 TRLLD_RS_RING_RECOVERY)
1286                                 printf(" [Ring Recovery]");
1287                         printf("\n");   
1288                 }
1289                 break;
1290         case TRLLD_STS_ADAPTER_CHECK:
1291                 printf("oltr%d: adapter check (%04x %04x %04x %04x)\n", sc->unit,
1292                     Status->Specification.AdapterCheck[0],
1293                     Status->Specification.AdapterCheck[1],
1294                     Status->Specification.AdapterCheck[2],
1295                     Status->Specification.AdapterCheck[3]);
1296                 sc->state = OL_DEAD;
1297                 oltr_stop(sc);
1298                 break;
1299         case TRLLD_STS_PROMISCUOUS_STOPPED:
1300                 printf("oltr%d: promiscuous mode ", sc->unit);
1301                 if (Status->Specification.PromRemovedCause == 1)
1302                         printf("remove received.");
1303                 if (Status->Specification.PromRemovedCause == 2)
1304                         printf("poll failure.");
1305                 if (Status->Specification.PromRemovedCause == 2)
1306                         printf("buffer size failure.");
1307                 printf("\n");
1308                 ifp->if_flags &= ~IFF_PROMISC;
1309                 break;
1310         case TRLLD_STS_LLD_ERROR:
1311                 printf("oltr%d: low level driver internal error ", sc->unit);
1312                 printf("(%04x %04x %04x %04x).\n",
1313                     Status->Specification.InternalError[0],
1314                     Status->Specification.InternalError[1],
1315                     Status->Specification.InternalError[2],
1316                     Status->Specification.InternalError[3]);
1317                 sc->state = OL_DEAD;
1318                 oltr_stop(sc);
1319                 break;
1320         case TRLLD_STS_ADAPTER_TIMEOUT:
1321                 printf("oltr%d: adapter %s timeout.\n", sc->unit,
1322                     Timeout[Status->Specification.AdapterTimeout]);
1323                 break;
1324         default:
1325                 printf("oltr%d: driver status Type = %d\n", sc->unit, Status->Type);
1326                 break;
1327
1328         }
1329         if (Status->Closed) {
1330                 sc->state = OL_CLOSING;
1331                 oltr_stop(sc);
1332         }
1333
1334 }
1335
1336 static void
1337 DriverCloseCompleted(void *DriverHandle)
1338 {
1339         struct oltr_softc               *sc = (struct oltr_softc *)DriverHandle;
1340         
1341         printf("oltr%d: adapter closed\n", sc->unit);
1342         wakeup(sc);
1343         sc->state = OL_CLOSED;
1344 }
1345
1346 static void
1347 DriverTransmitFrameCompleted(void *DriverHandle, void *FrameHandle, int TransmitStatus)
1348 {
1349         struct oltr_softc       *sc = (struct oltr_softc *)DriverHandle;
1350         struct ifnet            *ifp = &sc->arpcom.ac_if;
1351         TRlldTransmit_t         *frame = (TRlldTransmit_t *)FrameHandle;
1352         
1353         /*printf("oltr%d: DriverTransmitFrameCompleted\n", sc->unit);*/
1354
1355         if (TransmitStatus != TRLLD_TRANSMIT_OK) {
1356                 ifp->if_oerrors++;
1357                 printf("oltr%d: transmit error %d\n", sc->unit, TransmitStatus);
1358         } else {
1359                 ifp->if_opackets++;
1360         }
1361         
1362         sc->tx_avail += frame->FragmentCount;
1363
1364         if (ifp->if_flags & IFF_OACTIVE) {
1365                 printf("oltr%d: queue restart\n", sc->unit);
1366                 ifp->if_flags &= ~IFF_OACTIVE;
1367                 oltr_start(ifp);
1368         }
1369
1370
1371 }
1372
1373 static void
1374 DriverReceiveFrameCompleted(void *DriverHandle, int ByteCount, int FragmentCount, void *FragmentHandle, int ReceiveStatus)
1375 {
1376         struct oltr_softc       *sc = (struct oltr_softc *)DriverHandle;
1377         struct ifnet            *ifp = (struct ifnet *)&sc->arpcom.ac_if;
1378         struct mbuf             *m0, *m1, *m;
1379         struct iso88025_header  *th;
1380         int                     frame_len = ByteCount, i = (int)FragmentHandle, rc;
1381         int                     mbuf_offset, mbuf_size, frag_offset, copy_length;
1382         char                    *fragment = sc->rx_ring[RING_BUFFER(i)].data;
1383         
1384         if (sc->state > OL_CLOSED) {
1385                 if (ReceiveStatus == TRLLD_RCV_OK) {
1386                         MGETHDR(m0, MB_DONTWAIT, MT_DATA);
1387                         mbuf_size = MHLEN - 2;
1388                         if (!m0) {
1389                                 ifp->if_ierrors++;
1390                                 goto dropped;
1391                         }
1392                         if (ByteCount + 2 > MHLEN) {
1393                                 MCLGET(m0, MB_DONTWAIT);
1394                                 mbuf_size = MCLBYTES - 2;
1395                                 if (!(m0->m_flags & M_EXT)) {
1396                                         m_freem(m0);
1397                                         ifp->if_ierrors++;
1398                                         goto dropped;
1399                                 }
1400                         }
1401                         m0->m_pkthdr.rcvif = ifp;
1402                         m0->m_pkthdr.len = ByteCount;
1403                         m0->m_len = 0;
1404                         m0->m_data += 2;
1405                         th = mtod(m0, struct iso88025_header *);
1406                         m0->m_pkthdr.header = (void *)th;
1407
1408                         m = m0;
1409                         mbuf_offset = 0;
1410                         frag_offset = 0;
1411                         while (frame_len) {
1412                                 copy_length = MIN3(frame_len,
1413                                     (RX_BUFFER_LEN - frag_offset),
1414                                     (mbuf_size - mbuf_offset));
1415                                 bcopy(fragment + frag_offset, mtod(m, char *) +
1416                                     mbuf_offset, copy_length);
1417                                 m->m_len += copy_length;
1418                                 mbuf_offset += copy_length;
1419                                 frag_offset += copy_length;
1420                                 frame_len -= copy_length;
1421                         
1422                                 if (frag_offset == RX_BUFFER_LEN) {
1423                                         fragment =
1424                                             sc->rx_ring[RING_BUFFER(++i)].data;
1425                                         frag_offset = 0;
1426                                 }
1427                                 if ((mbuf_offset == mbuf_size) && (frame_len > 0)) {
1428                                         MGET(m1, MB_DONTWAIT, MT_DATA);
1429                                         mbuf_size = MHLEN;
1430                                         if (!m1) {
1431                                                 ifp->if_ierrors++;
1432                                                 m_freem(m0);
1433                                                 goto dropped;
1434                                         }
1435                                         if (frame_len > MHLEN) {
1436                                                 MCLGET(m1, MB_DONTWAIT);
1437                                                 mbuf_size = MCLBYTES;
1438                                                 if (!(m1->m_flags & M_EXT)) {
1439                                                         m_freem(m0);
1440                                                         m_freem(m1);
1441                                                         ifp->if_ierrors++;
1442                                                         goto dropped;
1443                                                 }
1444                                         }
1445                                         m->m_next = m1;
1446                                         m = m1;
1447                                         mbuf_offset = 0;
1448                                         m->m_len = 0;
1449                                 }
1450                         }
1451                         BPF_MTAP(ifp, m0);
1452
1453                         /*if (ifp->if_flags & IFF_PROMISC) {*/
1454                                 if (bcmp(th->iso88025_dhost, ifp->if_broadcastaddr,
1455                                          ifp->if_addrlen)) {
1456                                         if ((bcmp(th->iso88025_dhost + 1, sc->arpcom.ac_enaddr + 1, ISO88025_ADDR_LEN - 1)) ||
1457                                             ((th->iso88025_dhost[0] & 0x7f) != sc->arpcom.ac_enaddr[0])) {
1458                                                 m_freem(m0);
1459                                                 goto dropped;
1460                                         }
1461                                 }
1462                         /*}*/
1463                         ifp->if_ipackets++;
1464
1465                         (*ifp->if_input)(ifp, m0);
1466
1467                 } else {        /* Receiver error */
1468                         if (ReceiveStatus != TRLLD_RCV_NO_DATA) {
1469                                 printf("oltr%d: receive error %d\n", sc->unit,
1470                                     ReceiveStatus);
1471                                 ifp->if_ierrors++;
1472                         }
1473                 }
1474
1475 dropped:
1476                 crit_enter();
1477                 i = (int)FragmentHandle;
1478                 while (FragmentCount--) {
1479                         rc = TRlldReceiveFragment(sc->TRlldAdapter,
1480                             (void *)sc->rx_ring[RING_BUFFER(i)].data,
1481                             sc->rx_ring[RING_BUFFER(i)].address,
1482                             RX_BUFFER_LEN, (void *)sc->rx_ring[RING_BUFFER(i)].index);
1483                         if (rc != TRLLD_RECEIVE_OK) {
1484                                 printf("oltr%d: adapter refused receive fragment %d (rc = %d)\n", sc->unit, i, rc);
1485                                 break;
1486                         }
1487                         i++;
1488                 }
1489                 crit_exit();
1490         }
1491 }
1492
1493
1494 /*
1495  * ---------------------------- PMW Glue -------------------------------
1496  */
1497
1498 #ifndef TRlldInlineIO
1499
1500 static void
1501 DriverOutByte(unsigned short IOAddress, unsigned char value)
1502 {
1503         outb(IOAddress, value);
1504 }
1505
1506 static void
1507 DriverOutWord(unsigned short IOAddress, unsigned short value)
1508 {
1509         outw(IOAddress, value);
1510 }
1511
1512 static void
1513 DriverOutDword(unsigned short IOAddress, unsigned long value)
1514 {
1515         outl(IOAddress, value);
1516 }
1517
1518 static void
1519 DriverRepOutByte(unsigned short IOAddress, unsigned char *DataPointer, int ByteCount)
1520 {
1521         outsb(IOAddress, (void *)DataPointer, ByteCount);
1522 }
1523
1524 static void
1525 DriverRepOutWord(unsigned short IOAddress, unsigned short *DataPointer, int WordCount)
1526 {
1527         outsw(IOAddress, (void *)DataPointer, WordCount);
1528 }
1529
1530 static void
1531 DriverRepOutDword(unsigned short IOAddress, unsigned long *DataPointer, int DWordCount)
1532 {
1533         outsl(IOAddress, (void *)DataPointer, DWordCount);
1534 }
1535
1536 static unsigned char
1537 DriverInByte(unsigned short IOAddress)
1538 {
1539         return(inb(IOAddress));
1540 }
1541
1542 static unsigned short
1543 DriverInWord(unsigned short IOAddress)
1544 {
1545         return(inw(IOAddress));
1546 }
1547
1548 static unsigned long
1549 DriverInDword(unsigned short IOAddress)
1550 {
1551         return(inl(IOAddress));
1552 }
1553
1554 static void
1555 DriverRepInByte(unsigned short IOAddress, unsigned char *DataPointer, int ByteCount)
1556 {
1557         insb(IOAddress, (void *)DataPointer, ByteCount);
1558 }
1559
1560 static void
1561 DriverRepInWord(unsigned short IOAddress, unsigned short *DataPointer, int WordCount)
1562 {
1563         insw(IOAddress, (void *)DataPointer, WordCount);
1564 }
1565 static void
1566 DriverRepInDword( unsigned short IOAddress, unsigned long *DataPointer, int DWordCount)
1567 {
1568         insl(IOAddress, (void *)DataPointer, DWordCount);
1569 }
1570 #endif /* TRlldInlineIO */