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