2 * Copyright (c) 1998, Larry Lile
5 * For latest sources and information on this driver, please
6 * go to http://anarchy.stdio.com.
8 * Questions, comments or suggestions should be directed to
9 * Larry Lile <lile@stdio.com>.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice unmodified, this list of conditions, and the following
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.
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
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.24 2006/10/25 20:55:52 dillon Exp $
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/sockio.h>
41 #include <sys/malloc.h>
42 #include <sys/kernel.h>
43 #include <sys/socket.h>
44 #include <sys/param.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>
55 #if defined(__DragonFly__) || (NBPFILTER > 0)
59 #include <vm/vm.h> /* for vtophys */
60 #include <vm/pmap.h> /* for vtophys */
61 #include <machine/clock.h>
64 #include <sys/thread2.h>
66 #include <bus/pci/pcireg.h>
67 #include <bus/pci/pcivar.h>
69 #include "contrib/dev/oltr/trlld.h"
71 /*#define DEBUG_MASK DEBUG_POLL*/
74 #define DEBUG_MASK 0x0000
77 #define DEBUG_POLL 0x0001
78 #define DEBUG_INT 0x0002
79 #define DEBUG_INIT 0x0004
80 #define DEBUG_FN_ENT 0x8000
82 #define PCI_VENDOR_OLICOM 0x108D
84 #define MIN3(A,B,C) (MIN(A, (MIN(B, C))))
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)"
110 * Glue function prototypes for PMW kit IO
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);
134 static TRlldDriver_t LldDriver
= {
136 #ifndef TRlldInlineIO
149 #endif /*TRlldInlineIO*/
152 DriverCloseCompleted
,
154 DriverTransmitFrameCompleted
,
155 DriverReceiveFrameCompleted
,
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
176 struct arpcom arpcom
;
177 struct ifmedia ifmedia
;
178 bus_space_handle_t oltr_bhandle
;
179 bus_space_tag_t oltr_btag
;
181 struct resource
*oltr_irq
;
182 struct resource
*oltr_res
;
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
;
205 u_long FunctionalAddress
;
206 struct callout oltr_poll_ch
;
207 /*struct callout_handle oltr_stat_ch;*/
211 #define SELF_TEST_POLLS 32
213 void oltr_poll (void *);
214 /*void oltr_stat (void *);*/
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
,
222 static void oltr_intr (void *);
223 static int oltr_ifmedia_upd (struct ifnet
*);
224 static void oltr_ifmedia_sts (struct ifnet
*, struct ifmediareq
*);
226 #if defined(__DragonFly__) || __FreeBSD_version > 400000
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
);
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
),
241 static driver_t oltr_driver
= {
244 sizeof(struct oltr_softc
)
247 static devclass_t oltr_devclass
;
249 DRIVER_MODULE(oltr
, pci
, oltr_driver
, oltr_devclass
, 0, 0);
252 oltr_pci_probe(device_t dev
)
255 char PCIConfigHeader
[64];
256 TRlldAdapterConfig_t config
;
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))) {
265 for (i
= 0; i
< sizeof(PCIConfigHeader
); i
++)
266 PCIConfigHeader
[i
] = pci_read_config(dev
, i
, 1);
268 rc
= TRlldPCIConfig(&LldDriver
, &config
, PCIConfigHeader
);
269 if (rc
== TRLLD_PCICONFIG_FAIL
) {
270 device_printf(dev
, "TRlldPciConfig failed!\n");
273 if (rc
== TRLLD_PCICONFIG_VERSION
) {
274 device_printf(dev
, "wrong LLD version\n");
277 device_set_desc(dev
, AdapterName
[config
.type
]);
284 oltr_pci_attach(device_t dev
)
288 int media
= IFM_TOKEN
|IFM_TOK_UTP16
;
290 char PCIConfigHeader
[64];
291 struct oltr_softc
*sc
= device_get_softc(dev
);
292 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
296 bzero(sc
, sizeof(struct oltr_softc
));
297 sc
->unit
= device_get_unit(dev
);
298 sc
->state
= OL_UNKNOWN
;
300 for (i
= 0; i
< sizeof(PCIConfigHeader
); i
++)
301 PCIConfigHeader
[i
] = pci_read_config(dev
, i
, 1);
303 switch(TRlldPCIConfig(&LldDriver
, &sc
->config
, PCIConfigHeader
)) {
304 case TRLLD_PCICONFIG_OK
:
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");
317 case TRLLD_PCICONFIG_FAIL
:
318 device_printf(dev
, "TRlldPciConfig failed!\n");
321 case TRLLD_PCICONFIG_VERSION
:
322 device_printf(dev
, "wrong LLD version\n");
326 device_printf(dev
, "MAC address %6D\n", sc
->config
.macaddress
, ":");
328 scratch_size
= TRlldAdapterSize();
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
);
338 * Allocate RX/TX Pools
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");
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
);
361 * Allocate interrupt and DMA channel
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");
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
);
378 * Do the ifnet initialization
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
));
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
);
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);
405 ifmedia_add(&sc
->ifmedia
, IFM_TOKEN
|IFM_TOK_UTP4
, 0, NULL
);
406 ifmedia_add(&sc
->ifmedia
, IFM_TOKEN
|IFM_TOK_UTP16
, 0, NULL
);
409 sc
->ifmedia
.ifm_media
= media
;
410 ifmedia_set(&sc
->ifmedia
, media
);
413 * Attach the interface
415 ifp
->if_snd
.ifq_maxlen
= IFQ_MAXLEN
;
416 iso88025_ifattach(ifp
, NULL
);
428 oltr_pci_detach(device_t dev
)
430 struct oltr_softc
*sc
= device_get_softc(dev
);
431 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
434 device_printf(dev
, "driver unloading\n");
439 if (sc
->state
> OL_CLOSED
)
442 callout_stop(&sc
->oltr_poll_ch
);
443 /*untimeout(oltr_stat, (void *)sc, sc->oltr_stat_ch);*/
445 bus_teardown_intr(dev
, sc
->oltr_irq
, sc
->oltr_intrhand
);
446 bus_release_resource(dev
, SYS_RES_IRQ
, 0, sc
->oltr_irq
);
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
);
454 kfree(sc
->work_memory
, M_DEVBUF
);
455 kfree(sc
->TRlldAdapter
, M_DEVBUF
);
463 oltr_pci_shutdown(device_t dev
)
465 struct oltr_softc
*sc
= device_get_softc(dev
);
467 device_printf(dev
, "oltr_pci_shutdown called\n");
469 if (sc
->state
> OL_CLOSED
)
477 static const char *oltr_pci_probe (pcici_t
, pcidi_t
);
478 static void oltr_pci_attach (pcici_t
, int);
480 static unsigned long oltr_count
= 0;
482 static struct pci_device oltr_device
= {
490 DATA_SET(pcidevice_set
, oltr_device
);
493 oltr_pci_probe(pcici_t config_id
, pcidi_t device_id
)
496 char PCIConfigHeader
[64];
497 TRlldAdapterConfig_t config
;
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))) {
506 for (i
= 0; i
< 64; i
++)
507 PCIConfigHeader
[i
] = pci_cfgread(config_id
, i
, /* bytes */ 1);
509 rc
= TRlldPCIConfig(&LldDriver
, &config
, PCIConfigHeader
);
511 if (rc
== TRLLD_PCICONFIG_FAIL
) {
512 printf("oltr: TRlldPciConfig failed!\n");
515 if (rc
== TRLLD_PCICONFIG_VERSION
) {
516 printf("oltr: wrong LLD version.\n");
519 return(AdapterName
[config
.type
]);
526 oltr_pci_attach(pcici_t config_id
, int unit
)
528 int i
, rc
= 0, scratch_size
;
529 int media
= IFM_TOKEN
|IFM_TOK_UTP16
;
531 char PCIConfigHeader
[64];
532 struct oltr_softc
*sc
;
533 struct ifnet
*ifp
; /* = &sc->arpcom.ac_if; */
537 sc
= kmalloc(sizeof(struct oltr_softc
), M_DEVBUF
, M_NOWAIT
| M_ZERO
);
539 printf("oltr%d: no memory for softc struct!\n", unit
);
543 sc
->state
= OL_UNKNOWN
;
544 ifp
= &sc
->arpcom
.ac_if
;
546 for (i
= 0; i
< sizeof(PCIConfigHeader
); i
++)
547 PCIConfigHeader
[i
] = pci_cfgread(config_id
, i
, 1);
549 switch(TRlldPCIConfig(&LldDriver
, &sc
->config
, PCIConfigHeader
)) {
550 case TRLLD_PCICONFIG_OK
:
552 case TRLLD_PCICONFIG_SET_COMMAND
:
553 printf("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 printf("oltr%d: failed to enable bus master mode\n", unit
);
562 case TRLLD_PCICONFIG_FAIL
:
563 printf("oltr%d: TRlldPciConfig failed!\n", unit
);
566 case TRLLD_PCICONFIG_VERSION
:
567 printf("oltr%d: wrong LLD version\n", unit
);
571 printf("oltr%d: MAC address %6D\n", unit
, sc
->config
.macaddress
, ":");
573 scratch_size
= TRlldAdapterSize();
575 printf("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 printf("oltr%d: couldn't allocate scratch buffer (%d bytes)\n",unit
, scratch_size
);
583 * Allocate RX/TX Pools
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 printf("oltr%d: unable to allocate ring buffers\n", unit
);
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
);
606 * Allocate interrupt and DMA channel
608 if (!pci_map_int(config_id
, oltr_intr
, sc
)) {
609 printf("oltr%d: couldn't setup interrupt\n", unit
);
614 * Do the ifnet initialization
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
));
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
);
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);
642 ifmedia_add(&sc
->ifmedia
, IFM_TOKEN
|IFM_TOK_UTP4
, 0, NULL
);
643 ifmedia_add(&sc
->ifmedia
, IFM_TOKEN
|IFM_TOK_UTP16
, 0, NULL
);
646 sc
->ifmedia
.ifm_media
= media
;
647 ifmedia_set(&sc
->ifmedia
, media
);
650 * Attach the interface
652 ifp
->if_snd
.ifq_maxlen
= IFQ_MAXLEN
;
653 iso88025_ifattach(ifp
);
669 struct oltr_softc
*sc
= (struct oltr_softc
*)xsc
;
671 if (DEBUG_MASK
& DEBUG_INT
)
674 TRlldInterruptService(sc
->TRlldAdapter
);
680 oltr_start(struct ifnet
*ifp
)
682 struct oltr_softc
*sc
= ifp
->if_softc
;
684 int copy_len
, buffer
, frame
, fragment
, rc
;
687 * Check to see if output is already active
689 if (ifp
->if_flags
& IFF_OACTIVE
)
695 * Make sure we have buffers to transmit with
697 if (sc
->tx_avail
<= 0) {
698 printf("oltr%d: tx queue full\n", sc
->unit
);
699 ifp
->if_flags
|= IFF_OACTIVE
;
703 if (sc
->restart
== NULL
) {
704 IF_DEQUEUE(&ifp
->if_snd
, m
);
713 frame
= RING_BUFFER(sc
->tx_frame
);
714 buffer
= RING_BUFFER(sc
->tx_head
);
717 sc
->frame_ring
[frame
].FragmentCount
= 0;
719 while (copy_len
< m0
->m_pkthdr
.len
) {
720 sc
->frame_ring
[frame
].FragmentCount
++;
721 if (sc
->frame_ring
[frame
].FragmentCount
> sc
->tx_avail
)
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
);
729 buffer
= RING_BUFFER((buffer
+ 1));
733 rc
= TRlldTransmitFrame(sc
->TRlldAdapter
, &sc
->frame_ring
[frame
],
734 (void *)&sc
->frame_ring
[frame
]);
737 if (rc
!= TRLLD_TRANSMIT_OK
) {
738 printf("oltr%d: TRlldTransmitFrame returned %d\n", sc
->unit
, rc
);
743 sc
->tx_avail
-= sc
->frame_ring
[frame
].FragmentCount
;
744 sc
->tx_head
= RING_BUFFER((sc
->tx_head
+ sc
->frame_ring
[frame
].FragmentCount
));
748 /*ifp->if_opackets++;*/
757 printf("oltr%d: queue full\n", sc
->unit
);
758 ifp
->if_flags
|= IFF_OACTIVE
;
767 oltr_close(struct oltr_softc
*sc
)
769 /*printf("oltr%d: oltr_close\n", sc->unit);*/
773 tsleep(sc
, 0, "oltrclose", 30*hz
);
777 oltr_stop(struct oltr_softc
*sc
)
779 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
781 /*printf("oltr%d: oltr_stop\n", sc->unit);*/
783 ifp
->if_flags
&= ~(IFF_UP
| IFF_RUNNING
| IFF_OACTIVE
);
784 TRlldClose(sc
->TRlldAdapter
, 0);
785 sc
->state
= OL_CLOSING
;
789 oltr_init(void * xsc
)
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;
798 * Check adapter state, don't allow multiple inits
800 if (sc
->state
> OL_CLOSED
) {
801 printf("oltr%d: adapter not ready\n", sc
->unit
);
810 if ((rc
= TRlldAdapterInit(&LldDriver
, sc
->TRlldAdapter
, vtophys(sc
->TRlldAdapter
),
811 (void *)sc
, &sc
->config
)) != TRLLD_INIT_OK
) {
813 case TRLLD_INIT_NOT_FOUND
:
814 printf("oltr%d: adapter not found\n", sc
->unit
);
816 case TRLLD_INIT_UNSUPPORTED
:
817 printf("oltr%d: adapter not supported by low level driver\n", sc
->unit
);
819 case TRLLD_INIT_PHYS16
:
820 printf("oltr%d: adapter memory block above 16M cannot DMA\n", sc
->unit
);
822 case TRLLD_INIT_VERSION
:
823 printf("oltr%d: low level driver version mismatch\n", sc
->unit
);
826 printf("oltr%d: unknown init error %d\n", sc
->unit
, rc
);
833 switch(sc
->config
.type
) {
834 case TRLLD_ADAPTER_PCI4
: /* OC-3139 */
835 work_size
= 32 * 1024;
837 case TRLLD_ADAPTER_PCI7
: /* OC-3540 */
845 if ((sc
->work_memory
= kmalloc(work_size
, M_DEVBUF
, M_NOWAIT
)) == NULL
) {
846 printf("oltr%d: failed to allocate work memory (%d octets).\n", sc
->unit
, work_size
);
848 TRlldAddMemory(sc
->TRlldAdapter
, sc
->work_memory
,
849 vtophys(sc
->work_memory
), work_size
);
853 switch(IFM_SUBTYPE(ifm
->ifm_media
)) {
855 rc
= TRlldSetSpeed(sc
->TRlldAdapter
, 0); /* TRLLD_SPEED_AUTO */
858 rc
= TRlldSetSpeed(sc
->TRlldAdapter
, TRLLD_SPEED_4MBPS
);
861 rc
= TRlldSetSpeed(sc
->TRlldAdapter
, TRLLD_SPEED_16MBPS
);
864 rc
= TRlldSetSpeed(sc
->TRlldAdapter
, TRLLD_SPEED_100MBPS
);
869 * Download adapter micro-code
872 printf("oltr%d: Downloading adapter microcode: ", sc
->unit
);
874 switch(sc
->config
.mactype
) {
876 rc
= TRlldDownload(sc
->TRlldAdapter
, TRlldMacCode
);
880 case TRLLD_MAC_HAWKEYE
:
881 rc
= TRlldDownload(sc
->TRlldAdapter
, TRlldHawkeyeMac
);
885 case TRLLD_MAC_BULLSEYE
:
886 rc
= TRlldDownload(sc
->TRlldAdapter
, TRlldBullseyeMac
);
892 printf("unknown - failed!\n");
898 * Check download status
901 case TRLLD_DOWNLOAD_OK
:
905 case TRLLD_DOWNLOAD_ERROR
:
907 printf(" - failed\n");
909 printf("oltr%d: adapter microcode download failed\n", sc
->unit
);
914 printf(" - not ready\n");
920 * Wait for self-test to complete
923 while ((poll
++ < SELF_TEST_POLLS
) && (sc
->state
< OL_READY
)) {
924 if (DEBUG_MASK
& DEBUG_INIT
)
926 DELAY(TRlldPoll(sc
->TRlldAdapter
) * 1000);
927 if (TRlldInterruptService(sc
->TRlldAdapter
) != 0)
928 if (DEBUG_MASK
& DEBUG_INIT
) printf("i");
931 if (sc
->state
!= OL_CLOSED
) {
932 printf("oltr%d: self-test failed\n", sc
->unit
);
937 * Set up adapter poll
939 callout_init(&sc
->oltr_poll_ch
);
940 callout_reset(&sc
->oltr_poll_ch
, 1, oltr_poll
, sc
);
942 sc
->state
= OL_OPENING
;
947 rc
= TRlldOpen(sc
->TRlldAdapter
, sc
->arpcom
.ac_enaddr
, sc
->GroupAddress
,
948 sc
->FunctionalAddress
, 1552, sc
->AdapterMode
);
952 case TRLLD_OPEN_STATE
:
953 printf("oltr%d: adapter not ready for open\n", sc
->unit
);
956 case TRLLD_OPEN_ADDRESS_ERROR
:
957 printf("oltr%d: illegal MAC address\n", sc
->unit
);
960 case TRLLD_OPEN_MODE_ERROR
:
961 printf("oltr%d: illegal open mode\n", sc
->unit
);
965 printf("oltr%d: unknown open error (%d)\n", sc
->unit
, rc
);
971 * Set promiscious mode for now...
973 TRlldSetPromiscuousMode(sc
->TRlldAdapter
, TRLLD_PROM_LLC
);
974 ifp
->if_flags
|= IFF_PROMISC
;
977 * Block on the ring insert and set a timeout
979 tsleep(sc
, 0, "oltropen", 30*hz
);
982 * Set up receive buffer ring
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 printf("oltr%d: adapter refused receive fragment %d (rc = %d)\n", sc
->unit
, i
, rc
);
993 sc
->tx_avail
= RING_BUFFER_LEN
;
999 ifp
->if_flags
|= IFF_RUNNING
;
1000 ifp
->if_flags
&= ~IFF_OACTIVE
;
1003 * Set up adapter statistics poll
1005 /*callout_handle_init(&sc->oltr_stat_ch);*/
1006 /*sc->oltr_stat_ch = timeout(oltr_stat, (void *)sc, 1*hz);*/
1012 sc
->state
= OL_DEAD
;
1018 oltr_ioctl(struct ifnet
*ifp
, u_long command
, caddr_t data
, struct ucred
*cr
)
1020 struct oltr_softc
*sc
= ifp
->if_softc
;
1021 struct ifreq
*ifr
= (struct ifreq
*)data
;
1030 error
= iso88025_ioctl(ifp
, command
, data
);
1034 if (ifp
->if_flags
& IFF_UP
) {
1037 if (ifp
->if_flags
& IFF_RUNNING
) {
1044 error
= ifmedia_ioctl(ifp
, ifr
, &sc
->ifmedia
, command
);
1058 oltr_poll(void *arg
)
1060 struct oltr_softc
*sc
= (struct oltr_softc
*)arg
;
1064 if (DEBUG_MASK
& DEBUG_POLL
) printf("P");
1066 /* Set up next adapter poll */
1067 callout_reset(&sc
->oltr_poll_ch
,
1068 (TRlldPoll(sc
->TRlldAdapter
) * hz
/ 1000), oltr_poll
, sc
);
1075 oltr_stat(void *arg
)
1077 struct oltr_softc
*sc
= (struct oltr_softc
*)arg
;
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 /*printf("oltr%d: statistics available immediately...\n", sc->unit);*/
1085 DriverStatistics((void *)sc
, &sc
->current
);
1092 oltr_ifmedia_upd(struct ifnet
*ifp
)
1094 struct oltr_softc
*sc
= ifp
->if_softc
;
1095 struct ifmedia
*ifm
= &sc
->ifmedia
;
1098 if (IFM_TYPE(ifm
->ifm_media
) != IFM_TOKEN
)
1101 switch(IFM_SUBTYPE(ifm
->ifm_media
)) {
1103 rc
= TRlldSetSpeed(sc
->TRlldAdapter
, 0); /* TRLLD_SPEED_AUTO */
1106 rc
= TRlldSetSpeed(sc
->TRlldAdapter
, TRLLD_SPEED_4MBPS
);
1109 rc
= TRlldSetSpeed(sc
->TRlldAdapter
, TRLLD_SPEED_16MBPS
);
1111 case IFM_TOK_UTP100
:
1112 rc
= TRlldSetSpeed(sc
->TRlldAdapter
, TRLLD_SPEED_100MBPS
);
1124 oltr_ifmedia_sts(struct ifnet
*ifp
, struct ifmediareq
*ifmr
)
1126 struct oltr_softc
*sc
= ifp
->if_softc
;
1127 struct ifmedia
*ifm
= &sc
->ifmedia
;
1129 /*printf("oltr%d: oltr_ifmedia_sts\n", sc->unit);*/
1131 ifmr
->ifm_active
= IFM_TYPE(ifm
->ifm_media
)|IFM_SUBTYPE(ifm
->ifm_media
);
1136 * ---------------------- PMW Callback Functions -----------------------
1140 DriverStatistics(void *DriverHandle
, TRlldStatistics_t
*statistics
)
1143 struct oltr_softc
*sc
= (struct oltr_softc
*)DriverHandle
;
1145 if (sc
->statistics
.LineErrors
!= statistics
->LineErrors
)
1146 printf("oltr%d: Line Errors %lu\n", sc
->unit
,
1147 statistics
->LineErrors
);
1148 if (sc
->statistics
.InternalErrors
!= statistics
->InternalErrors
)
1149 printf("oltr%d: Internal Errors %lu\n", sc
->unit
,
1150 statistics
->InternalErrors
);
1151 if (sc
->statistics
.BurstErrors
!= statistics
->BurstErrors
)
1152 printf("oltr%d: Burst Errors %lu\n", sc
->unit
,
1153 statistics
->BurstErrors
);
1154 if (sc
->statistics
.AbortDelimiters
!= statistics
->AbortDelimiters
)
1155 printf("oltr%d: Abort Delimiters %lu\n", sc
->unit
,
1156 statistics
->AbortDelimiters
);
1157 if (sc
->statistics
.ARIFCIErrors
!= statistics
->ARIFCIErrors
)
1158 printf("oltr%d: ARIFCI Errors %lu\n", sc
->unit
,
1159 statistics
->ARIFCIErrors
);
1160 if (sc
->statistics
.LostFrames
!= statistics
->LostFrames
)
1161 printf("oltr%d: Lost Frames %lu\n", sc
->unit
,
1162 statistics
->LostFrames
);
1163 if (sc
->statistics
.CongestionErrors
!= statistics
->CongestionErrors
)
1164 printf("oltr%d: Congestion Errors %lu\n", sc
->unit
,
1165 statistics
->CongestionErrors
);
1166 if (sc
->statistics
.FrequencyErrors
!= statistics
->FrequencyErrors
)
1167 printf("oltr%d: Frequency Errors %lu\n", sc
->unit
,
1168 statistics
->FrequencyErrors
);
1169 if (sc
->statistics
.TokenErrors
!= statistics
->TokenErrors
)
1170 printf("oltr%d: Token Errors %lu\n", sc
->unit
,
1171 statistics
->TokenErrors
);
1172 if (sc
->statistics
.DMABusErrors
!= statistics
->DMABusErrors
)
1173 printf("oltr%d: DMA Bus Errors %lu\n", sc
->unit
,
1174 statistics
->DMABusErrors
);
1175 if (sc
->statistics
.DMAParityErrors
!= statistics
->DMAParityErrors
)
1176 printf("oltr%d: DMA Parity Errors %lu\n", sc
->unit
,
1177 statistics
->DMAParityErrors
);
1178 if (sc
->statistics
.ReceiveLongFrame
!= statistics
->ReceiveLongFrame
)
1179 printf("oltr%d: Long frames received %lu\n", sc
->unit
,
1180 statistics
->ReceiveLongFrame
);
1181 if (sc
->statistics
.ReceiveCRCErrors
!= statistics
->ReceiveCRCErrors
)
1182 printf("oltr%d: Receive CRC Errors %lu\n", sc
->unit
,
1183 statistics
->ReceiveCRCErrors
);
1184 if (sc
->statistics
.ReceiveOverflow
!= statistics
->ReceiveOverflow
)
1185 printf("oltr%d: Recieve overflows %lu\n", sc
->unit
,
1186 statistics
->ReceiveOverflow
);
1187 if (sc
->statistics
.TransmitUnderrun
!= statistics
->TransmitUnderrun
)
1188 printf("oltr%d: Frequency Errors %lu\n", sc
->unit
,
1189 statistics
->TransmitUnderrun
);
1190 bcopy(statistics
, &sc
->statistics
, sizeof(TRlldStatistics_t
));
1195 DriverSuspend(unsigned short MicroSeconds
)
1197 DELAY(MicroSeconds
);
1202 DriverStatus(void *DriverHandle
, TRlldStatus_t
*Status
)
1204 struct oltr_softc
*sc
= (struct oltr_softc
*)DriverHandle
;
1205 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1207 char *Protocol
[] = { /* 0 */ "Unknown",
1210 char *Timeout
[] = { /* 0 */ "command",
1212 /* 2 */ "interrupt" };
1214 switch (Status
->Type
) {
1216 case TRLLD_STS_ON_WIRE
:
1217 printf("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
;
1223 case TRLLD_STS_SELFTEST_STATUS
:
1224 if (Status
->Specification
.SelftestStatus
== TRLLD_ST_OK
) {
1225 sc
->state
= OL_CLOSED
;
1227 printf("oltr%d: self test complete\n", sc
->unit
);
1229 if (Status
->Specification
.SelftestStatus
& TRLLD_ST_ERROR
) {
1230 printf("oltr%d: Adapter self test error %d", sc
->unit
,
1231 Status
->Specification
.SelftestStatus
& ~TRLLD_ST_ERROR
);
1232 sc
->state
= OL_DEAD
;
1234 if (Status
->Specification
.SelftestStatus
& TRLLD_ST_TIMEOUT
) {
1235 printf("oltr%d: Adapter self test timed out.\n", sc
->unit
);
1236 sc
->state
= OL_DEAD
;
1239 case TRLLD_STS_INIT_STATUS
:
1240 if (Status
->Specification
.InitStatus
== 0x800) {
1242 ifmedia_set(&sc
->ifmedia
, IFM_TOKEN
|IFM_TOK_UTP16
);
1243 TRlldSetSpeed(sc
->TRlldAdapter
, TRLLD_SPEED_16MBPS
);
1247 printf("oltr%d: adapter init failure 0x%03x\n", sc
->unit
,
1248 Status
->Specification
.InitStatus
);
1251 case TRLLD_STS_RING_STATUS
:
1252 if (Status
->Specification
.RingStatus
) {
1253 printf("oltr%d: Ring status change: ", sc
->unit
);
1254 if (Status
->Specification
.RingStatus
&
1255 TRLLD_RS_SIGNAL_LOSS
)
1256 printf(" [Signal Loss]");
1257 if (Status
->Specification
.RingStatus
&
1258 TRLLD_RS_HARD_ERROR
)
1259 printf(" [Hard Error]");
1260 if (Status
->Specification
.RingStatus
&
1261 TRLLD_RS_SOFT_ERROR
)
1262 printf(" [Soft Error]");
1263 if (Status
->Specification
.RingStatus
&
1264 TRLLD_RS_TRANSMIT_BEACON
)
1265 printf(" [Beacon]");
1266 if (Status
->Specification
.RingStatus
&
1267 TRLLD_RS_LOBE_WIRE_FAULT
)
1268 printf(" [Wire Fault]");
1269 if (Status
->Specification
.RingStatus
&
1270 TRLLD_RS_AUTO_REMOVAL_ERROR
)
1271 printf(" [Auto Removal]");
1272 if (Status
->Specification
.RingStatus
&
1273 TRLLD_RS_REMOVE_RECEIVED
)
1274 printf(" [Remove Received]");
1275 if (Status
->Specification
.RingStatus
&
1276 TRLLD_RS_COUNTER_OVERFLOW
)
1277 printf(" [Counter Overflow]");
1278 if (Status
->Specification
.RingStatus
&
1279 TRLLD_RS_SINGLE_STATION
)
1280 printf(" [Single Station]");
1281 if (Status
->Specification
.RingStatus
&
1282 TRLLD_RS_RING_RECOVERY
)
1283 printf(" [Ring Recovery]");
1287 case TRLLD_STS_ADAPTER_CHECK
:
1288 printf("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
;
1296 case TRLLD_STS_PROMISCUOUS_STOPPED
:
1297 printf("oltr%d: promiscuous mode ", sc
->unit
);
1298 if (Status
->Specification
.PromRemovedCause
== 1)
1299 printf("remove received.");
1300 if (Status
->Specification
.PromRemovedCause
== 2)
1301 printf("poll failure.");
1302 if (Status
->Specification
.PromRemovedCause
== 2)
1303 printf("buffer size failure.");
1305 ifp
->if_flags
&= ~IFF_PROMISC
;
1307 case TRLLD_STS_LLD_ERROR
:
1308 printf("oltr%d: low level driver internal error ", sc
->unit
);
1309 printf("(%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
;
1317 case TRLLD_STS_ADAPTER_TIMEOUT
:
1318 printf("oltr%d: adapter %s timeout.\n", sc
->unit
,
1319 Timeout
[Status
->Specification
.AdapterTimeout
]);
1322 printf("oltr%d: driver status Type = %d\n", sc
->unit
, Status
->Type
);
1326 if (Status
->Closed
) {
1327 sc
->state
= OL_CLOSING
;
1334 DriverCloseCompleted(void *DriverHandle
)
1336 struct oltr_softc
*sc
= (struct oltr_softc
*)DriverHandle
;
1338 printf("oltr%d: adapter closed\n", sc
->unit
);
1340 sc
->state
= OL_CLOSED
;
1344 DriverTransmitFrameCompleted(void *DriverHandle
, void *FrameHandle
, int TransmitStatus
)
1346 struct oltr_softc
*sc
= (struct oltr_softc
*)DriverHandle
;
1347 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1348 TRlldTransmit_t
*frame
= (TRlldTransmit_t
*)FrameHandle
;
1350 /*printf("oltr%d: DriverTransmitFrameCompleted\n", sc->unit);*/
1352 if (TransmitStatus
!= TRLLD_TRANSMIT_OK
) {
1354 printf("oltr%d: transmit error %d\n", sc
->unit
, TransmitStatus
);
1359 sc
->tx_avail
+= frame
->FragmentCount
;
1361 if (ifp
->if_flags
& IFF_OACTIVE
) {
1362 printf("oltr%d: queue restart\n", sc
->unit
);
1363 ifp
->if_flags
&= ~IFF_OACTIVE
;
1371 DriverReceiveFrameCompleted(void *DriverHandle
, int ByteCount
, int FragmentCount
, void *FragmentHandle
, int ReceiveStatus
)
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
;
1381 if (sc
->state
> OL_CLOSED
) {
1382 if (ReceiveStatus
== TRLLD_RCV_OK
) {
1383 MGETHDR(m0
, MB_DONTWAIT
, MT_DATA
);
1384 mbuf_size
= MHLEN
- 2;
1389 if (ByteCount
+ 2 > MHLEN
) {
1390 MCLGET(m0
, MB_DONTWAIT
);
1391 mbuf_size
= MCLBYTES
- 2;
1392 if (!(m0
->m_flags
& M_EXT
)) {
1398 m0
->m_pkthdr
.rcvif
= ifp
;
1399 m0
->m_pkthdr
.len
= ByteCount
;
1402 th
= mtod(m0
, struct iso88025_header
*);
1403 m0
->m_pkthdr
.header
= (void *)th
;
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
;
1419 if (frag_offset
== RX_BUFFER_LEN
) {
1421 sc
->rx_ring
[RING_BUFFER(++i
)].data
;
1424 if ((mbuf_offset
== mbuf_size
) && (frame_len
> 0)) {
1425 MGET(m1
, MB_DONTWAIT
, MT_DATA
);
1432 if (frame_len
> MHLEN
) {
1433 MCLGET(m1
, MB_DONTWAIT
);
1434 mbuf_size
= MCLBYTES
;
1435 if (!(m1
->m_flags
& M_EXT
)) {
1450 /*if (ifp->if_flags & IFF_PROMISC) {*/
1451 if (bcmp(th
->iso88025_dhost
, ifp
->if_broadcastaddr
,
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])) {
1462 (*ifp
->if_input
)(ifp
, m0
);
1464 } else { /* Receiver error */
1465 if (ReceiveStatus
!= TRLLD_RCV_NO_DATA
) {
1466 printf("oltr%d: receive error %d\n", sc
->unit
,
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 printf("oltr%d: adapter refused receive fragment %d (rc = %d)\n", sc
->unit
, i
, rc
);
1492 * ---------------------------- PMW Glue -------------------------------
1495 #ifndef TRlldInlineIO
1498 DriverOutByte(unsigned short IOAddress
, unsigned char value
)
1500 outb(IOAddress
, value
);
1504 DriverOutWord(unsigned short IOAddress
, unsigned short value
)
1506 outw(IOAddress
, value
);
1510 DriverOutDword(unsigned short IOAddress
, unsigned long value
)
1512 outl(IOAddress
, value
);
1516 DriverRepOutByte(unsigned short IOAddress
, unsigned char *DataPointer
, int ByteCount
)
1518 outsb(IOAddress
, (void *)DataPointer
, ByteCount
);
1522 DriverRepOutWord(unsigned short IOAddress
, unsigned short *DataPointer
, int WordCount
)
1524 outsw(IOAddress
, (void *)DataPointer
, WordCount
);
1528 DriverRepOutDword(unsigned short IOAddress
, unsigned long *DataPointer
, int DWordCount
)
1530 outsl(IOAddress
, (void *)DataPointer
, DWordCount
);
1533 static unsigned char
1534 DriverInByte(unsigned short IOAddress
)
1536 return(inb(IOAddress
));
1539 static unsigned short
1540 DriverInWord(unsigned short IOAddress
)
1542 return(inw(IOAddress
));
1545 static unsigned long
1546 DriverInDword(unsigned short IOAddress
)
1548 return(inl(IOAddress
));
1552 DriverRepInByte(unsigned short IOAddress
, unsigned char *DataPointer
, int ByteCount
)
1554 insb(IOAddress
, (void *)DataPointer
, ByteCount
);
1558 DriverRepInWord(unsigned short IOAddress
, unsigned short *DataPointer
, int WordCount
)
1560 insw(IOAddress
, (void *)DataPointer
, WordCount
);
1563 DriverRepInDword( unsigned short IOAddress
, unsigned long *DataPointer
, int DWordCount
)
1565 insl(IOAddress
, (void *)DataPointer
, DWordCount
);
1567 #endif /* TRlldInlineIO */