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