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