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