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