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