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
36 #include <sys/param.h>
37 #include <sys/sockio.h>
38 #include <sys/malloc.h>
39 #include <sys/kernel.h>
40 #include <sys/module.h>
41 #include <sys/socket.h>
44 #include <net/if_dl.h>
45 #include <net/iso88025.h>
46 #include <net/if_media.h>
47 #include <net/if_types.h>
51 #define BPF_MTAP(_ifp, _m) do { \
53 bpf_mtap((_ifp), (_m)); \
57 #include <vm/vm.h> /* for vtophys */
58 #include <vm/pmap.h> /* for vtophys */
60 #include <machine/bus.h>
61 #include <machine/resource.h>
66 #include "contrib/dev/oltr/trlld.h"
67 #include "contrib/dev/oltr/if_oltrvar.h"
70 * Glue function prototypes for PMW kit IO
74 static void DriverOutByte __P((unsigned short, unsigned char));
75 static void DriverOutWord __P((unsigned short, unsigned short));
76 static void DriverOutDword __P((unsigned short, unsigned long));
77 static void DriverRepOutByte __P((unsigned short, unsigned char *, int));
78 static void DriverRepOutWord __P((unsigned short, unsigned short *, int));
79 static void DriverRepOutDword __P((unsigned short, unsigned long *, int));
80 static unsigned char DriverInByte __P((unsigned short));
81 static unsigned short DriverInWord __P((unsigned short));
82 static unsigned long DriverInDword __P((unsigned short));
83 static void DriverRepInByte __P((unsigned short, unsigned char *, int));
84 static void DriverRepInWord __P((unsigned short, unsigned short *, int));
85 static void DriverRepInDword __P((unsigned short, unsigned long *, int));
86 #endif /*TRlldInlineIO*/
87 static void DriverSuspend __P((unsigned short));
88 static void DriverStatus __P((void *, TRlldStatus_t *));
89 static void DriverCloseCompleted __P((void *));
90 static void DriverStatistics __P((void *, TRlldStatistics_t *));
91 static void DriverTransmitFrameCompleted __P((void *, void *, int));
92 static void DriverReceiveFrameCompleted __P((void *, int, int, void *, int));
94 TRlldDriver_t LldDriver = {
109 #endif /*TRlldInlineIO*/
112 DriverCloseCompleted,
114 DriverTransmitFrameCompleted,
115 DriverReceiveFrameCompleted,
119 static void oltr_start __P((struct ifnet *));
120 static void oltr_close __P((struct oltr_softc *));
121 static void oltr_init __P((void *));
122 static int oltr_ioctl __P((struct ifnet *, u_long, caddr_t));
123 static void oltr_intr __P((void *));
124 static int oltr_ifmedia_upd __P((struct ifnet *));
125 static void oltr_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
130 oltr_attach(device_t dev)
133 struct oltr_softc *sc = device_get_softc(dev);
136 int media = IFM_TOKEN|IFM_TOK_UTP16;
138 ifp = sc->ifp = if_alloc(IFT_ISO88025);
140 device_printf(dev, "couldn't if_alloc()");
145 * Allocate interrupt and DMA channel
149 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
150 (sc->config.mode & TRLLD_MODE_SHARE_INTERRUPT) ?
151 RF_ACTIVE | RF_SHAREABLE : RF_ACTIVE);
152 if (sc->irq_res == NULL) {
153 device_printf(dev, "couldn't map interrupt\n");
157 if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, NULL, oltr_intr,
158 sc, &sc-> oltr_intrhand)) {
159 device_printf(dev, "couldn't setup interrupt\n");
160 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
166 * Do the ifnet initialization
169 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
170 ifp->if_init = oltr_init;
171 ifp->if_start = oltr_start;
172 ifp->if_ioctl = oltr_ioctl;
173 ifp->if_flags = IFF_BROADCAST | IFF_NEEDSGIANT;
174 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
179 ifmedia_init(&sc->ifmedia, 0, oltr_ifmedia_upd, oltr_ifmedia_sts);
180 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
181 switch(sc->config.type) {
182 case TRLLD_ADAPTER_PCI7: /* OC-3540 */
183 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP100, 0, NULL);
185 case TRLLD_ADAPTER_PCI4: /* OC-3139 */
186 case TRLLD_ADAPTER_PCI5: /* OC-3140 */
187 case TRLLD_ADAPTER_PCI6: /* OC-3141 */
188 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_AUTO, 0, NULL);
189 media = IFM_TOKEN|IFM_AUTO;
190 rc = TRlldSetSpeed(sc->TRlldAdapter, 0);
193 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP4, 0, NULL);
194 ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP16, 0, NULL);
197 sc->ifmedia.ifm_media = media;
198 ifmedia_set(&sc->ifmedia, media);
201 * Attach the interface
204 iso88025_ifattach(ifp, sc->config.macaddress, ISO88025_BPF_SUPPORTED);
213 struct oltr_softc *sc = (struct oltr_softc *)xsc;
215 if (DEBUG_MASK & DEBUG_INT)
218 TRlldInterruptService(sc->TRlldAdapter);
224 oltr_start(struct ifnet *ifp)
226 struct oltr_softc *sc = ifp->if_softc;
228 int copy_len, buffer, frame, fragment, rc, s;
231 * Check to see if output is already active
233 if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
239 * Make sure we have buffers to transmit with
241 if (sc->tx_avail <= 0) {
242 printf("oltr%d: tx queue full\n", sc->unit);
243 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
247 if (sc->restart == NULL) {
248 IF_DEQUEUE(&ifp->if_snd, m);
257 frame = RING_BUFFER(sc->tx_frame);
258 buffer = RING_BUFFER(sc->tx_head);
261 sc->frame_ring[frame].FragmentCount = 0;
263 while (copy_len < m0->m_pkthdr.len) {
264 sc->frame_ring[frame].FragmentCount++;
265 if (sc->frame_ring[frame].FragmentCount > sc->tx_avail)
267 sc->frame_ring[frame].TransmitFragment[fragment].VirtualAddress = sc->tx_ring[buffer].data;
268 sc->frame_ring[frame].TransmitFragment[fragment].PhysicalAddress = sc->tx_ring[buffer].address;
269 sc->frame_ring[frame].TransmitFragment[fragment].count = MIN(m0->m_pkthdr.len - copy_len, TX_BUFFER_LEN);
270 m_copydata(m0, copy_len, MIN(m0->m_pkthdr.len - copy_len, TX_BUFFER_LEN), sc->tx_ring[buffer].data);
271 copy_len += MIN(m0->m_pkthdr.len - copy_len, TX_BUFFER_LEN);
273 buffer = RING_BUFFER((buffer + 1));
277 rc = TRlldTransmitFrame(sc->TRlldAdapter, &sc->frame_ring[frame], (void *)&sc->frame_ring[frame]);
280 if (rc != TRLLD_TRANSMIT_OK) {
281 printf("oltr%d: TRlldTransmitFrame returned %d\n", sc->unit, rc);
286 sc->tx_avail -= sc->frame_ring[frame].FragmentCount;
287 sc->tx_head = RING_BUFFER((sc->tx_head + sc->frame_ring[frame].FragmentCount));
291 /*ifp->if_opackets++;*/
300 printf("oltr%d: queue full\n", sc->unit);
301 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
310 oltr_close(struct oltr_softc *sc)
312 /*printf("oltr%d: oltr_close\n", sc->unit);*/
316 tsleep(sc, PWAIT, "oltrclose", 30*hz);
320 oltr_stop(struct oltr_softc *sc)
322 struct ifnet *ifp = sc->ifp;
324 /*printf("oltr%d: oltr_stop\n", sc->unit);*/
326 ifp->if_flags &= ~IFF_UP;
327 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
328 TRlldClose(sc->TRlldAdapter, 0);
329 sc->state = OL_CLOSING;
333 oltr_init(void * xsc)
335 struct oltr_softc *sc = (struct oltr_softc *)xsc;
336 struct ifnet *ifp = sc->ifp;
337 struct ifmedia *ifm = &sc->ifmedia;
338 int poll = 0, i, rc = 0, s;
342 * Check adapter state, don't allow multiple inits
344 if (sc->state > OL_CLOSED) {
345 printf("oltr%d: adapter not ready\n", sc->unit);
354 if ((rc = TRlldAdapterInit(&LldDriver, sc->TRlldAdapter, sc->TRlldAdapter_phys,
355 (void *)sc, &sc->config)) != TRLLD_INIT_OK) {
357 case TRLLD_INIT_NOT_FOUND:
358 printf("oltr%d: adapter not found\n", sc->unit);
360 case TRLLD_INIT_UNSUPPORTED:
361 printf("oltr%d: adapter not supported by low level driver\n", sc->unit);
363 case TRLLD_INIT_PHYS16:
364 printf("oltr%d: adapter memory block above 16M cannot DMA\n", sc->unit);
366 case TRLLD_INIT_VERSION:
367 printf("oltr%d: low level driver version mismatch\n", sc->unit);
370 printf("oltr%d: unknown init error %d\n", sc->unit, rc);
377 switch(sc->config.type) {
378 case TRLLD_ADAPTER_PCI4: /* OC-3139 */
379 work_size = 32 * 1024;
381 case TRLLD_ADAPTER_PCI7: /* OC-3540 */
389 if ((sc->work_memory = malloc(work_size, M_DEVBUF, M_NOWAIT)) == NULL) {
390 printf("oltr%d: failed to allocate work memory (%d octets).\n", sc->unit, work_size);
392 TRlldAddMemory(sc->TRlldAdapter, sc->work_memory,
393 vtophys(sc->work_memory), work_size);
397 switch(IFM_SUBTYPE(ifm->ifm_media)) {
399 rc = TRlldSetSpeed(sc->TRlldAdapter, 0); /* TRLLD_SPEED_AUTO */
402 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_4MBPS);
405 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
408 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_100MBPS);
413 * Download adapter micro-code
416 printf("oltr%d: Downloading adapter microcode: ", sc->unit);
418 switch(sc->config.mactype) {
420 rc = TRlldDownload(sc->TRlldAdapter, TRlldMacCode);
424 case TRLLD_MAC_HAWKEYE:
425 rc = TRlldDownload(sc->TRlldAdapter, TRlldHawkeyeMac);
429 case TRLLD_MAC_BULLSEYE:
430 rc = TRlldDownload(sc->TRlldAdapter, TRlldBullseyeMac);
436 printf("unknown - failed!\n");
442 * Check download status
445 case TRLLD_DOWNLOAD_OK:
449 case TRLLD_DOWNLOAD_ERROR:
451 printf(" - failed\n");
453 printf("oltr%d: adapter microcode download failed\n", sc->unit);
458 printf(" - not ready\n");
464 * Wait for self-test to complete
467 while ((poll++ < SELF_TEST_POLLS) && (sc->state < OL_READY)) {
468 if (DEBUG_MASK & DEBUG_INIT)
470 DELAY(TRlldPoll(sc->TRlldAdapter) * 1000);
471 if (TRlldInterruptService(sc->TRlldAdapter) != 0)
472 if (DEBUG_MASK & DEBUG_INIT) printf("i");
475 if (sc->state != OL_CLOSED) {
476 printf("oltr%d: self-test failed\n", sc->unit);
481 * Set up adapter poll
483 callout_handle_init(&sc->oltr_poll_ch);
484 sc->oltr_poll_ch = timeout(oltr_poll, (void *)sc, 1);
486 sc->state = OL_OPENING;
491 rc = TRlldOpen(sc->TRlldAdapter, IF_LLADDR(sc->ifp), sc->GroupAddress,
492 sc->FunctionalAddress, 1552, sc->AdapterMode);
496 case TRLLD_OPEN_STATE:
497 printf("oltr%d: adapter not ready for open\n", sc->unit);
500 case TRLLD_OPEN_ADDRESS_ERROR:
501 printf("oltr%d: illegal MAC address\n", sc->unit);
504 case TRLLD_OPEN_MODE_ERROR:
505 printf("oltr%d: illegal open mode\n", sc->unit);
509 printf("oltr%d: unknown open error (%d)\n", sc->unit, rc);
515 * Set promiscious mode for now...
517 TRlldSetPromiscuousMode(sc->TRlldAdapter, TRLLD_PROM_LLC);
518 ifp->if_flags |= IFF_PROMISC;
521 * Block on the ring insert and set a timeout
523 tsleep(sc, PWAIT, "oltropen", 30*hz);
526 * Set up receive buffer ring
528 for (i = 0; i < RING_BUFFER_LEN; i++) {
529 rc = TRlldReceiveFragment(sc->TRlldAdapter, (void *)sc->rx_ring[i].data,
530 sc->rx_ring[i].address, RX_BUFFER_LEN, (void *)sc->rx_ring[i].index);
531 if (rc != TRLLD_RECEIVE_OK) {
532 printf("oltr%d: adapter refused receive fragment %d (rc = %d)\n", sc->unit, i, rc);
537 sc->tx_avail = RING_BUFFER_LEN;
543 ifp->if_drv_flags |= IFF_DRV_RUNNING;
544 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
547 * Set up adapter statistics poll
549 /*callout_handle_init(&sc->oltr_stat_ch);*/
550 /*sc->oltr_stat_ch = timeout(oltr_stat, (void *)sc, 1*hz);*/
562 oltr_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
564 struct oltr_softc *sc = ifp->if_softc;
565 struct ifreq *ifr = (struct ifreq *)data;
574 error = iso88025_ioctl(ifp, command, data);
578 if (ifp->if_flags & IFF_UP) {
581 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
588 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
604 struct oltr_softc *sc = (struct oltr_softc *)arg;
609 if (DEBUG_MASK & DEBUG_POLL) printf("P");
611 /* Set up next adapter poll */
612 sc->oltr_poll_ch = timeout(oltr_poll, (void *)sc, (TRlldPoll(sc->TRlldAdapter) * hz / 1000));
621 struct oltr_softc *sc = (struct oltr_softc *)arg;
626 /* Set up next adapter poll */
627 sc->oltr_stat_ch = timeout(oltr_stat, (void *)sc, 1*hz);
628 if (TRlldGetStatistics(sc->TRlldAdapter, &sc->current, 0) != 0) {
629 /*printf("oltr%d: statistics available immediately...\n", sc->unit);*/
630 DriverStatistics((void *)sc, &sc->current);
637 oltr_ifmedia_upd(struct ifnet *ifp)
639 struct oltr_softc *sc = ifp->if_softc;
640 struct ifmedia *ifm = &sc->ifmedia;
643 if (IFM_TYPE(ifm->ifm_media) != IFM_TOKEN)
646 switch(IFM_SUBTYPE(ifm->ifm_media)) {
648 rc = TRlldSetSpeed(sc->TRlldAdapter, 0); /* TRLLD_SPEED_AUTO */
651 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_4MBPS);
654 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
657 rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_100MBPS);
669 oltr_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
671 struct oltr_softc *sc = ifp->if_softc;
672 struct ifmedia *ifm = &sc->ifmedia;
674 /*printf("oltr%d: oltr_ifmedia_sts\n", sc->unit);*/
676 ifmr->ifm_active = IFM_TYPE(ifm->ifm_media)|IFM_SUBTYPE(ifm->ifm_media);
681 * ---------------------- PMW Callback Functions -----------------------
685 DriverStatistics(void *DriverHandle, TRlldStatistics_t *statistics)
688 struct oltr_softc *sc = (struct oltr_softc *)DriverHandle;
690 if (sc->statistics.LineErrors != statistics->LineErrors)
691 printf("oltr%d: Line Errors %lu\n", sc->unit,
692 statistics->LineErrors);
693 if (sc->statistics.InternalErrors != statistics->InternalErrors)
694 printf("oltr%d: Internal Errors %lu\n", sc->unit,
695 statistics->InternalErrors);
696 if (sc->statistics.BurstErrors != statistics->BurstErrors)
697 printf("oltr%d: Burst Errors %lu\n", sc->unit,
698 statistics->BurstErrors);
699 if (sc->statistics.AbortDelimiters != statistics->AbortDelimiters)
700 printf("oltr%d: Abort Delimiters %lu\n", sc->unit,
701 statistics->AbortDelimiters);
702 if (sc->statistics.ARIFCIErrors != statistics->ARIFCIErrors)
703 printf("oltr%d: ARIFCI Errors %lu\n", sc->unit,
704 statistics->ARIFCIErrors);
705 if (sc->statistics.LostFrames != statistics->LostFrames)
706 printf("oltr%d: Lost Frames %lu\n", sc->unit,
707 statistics->LostFrames);
708 if (sc->statistics.CongestionErrors != statistics->CongestionErrors)
709 printf("oltr%d: Congestion Errors %lu\n", sc->unit,
710 statistics->CongestionErrors);
711 if (sc->statistics.FrequencyErrors != statistics->FrequencyErrors)
712 printf("oltr%d: Frequency Errors %lu\n", sc->unit,
713 statistics->FrequencyErrors);
714 if (sc->statistics.TokenErrors != statistics->TokenErrors)
715 printf("oltr%d: Token Errors %lu\n", sc->unit,
716 statistics->TokenErrors);
717 if (sc->statistics.DMABusErrors != statistics->DMABusErrors)
718 printf("oltr%d: DMA Bus Errors %lu\n", sc->unit,
719 statistics->DMABusErrors);
720 if (sc->statistics.DMAParityErrors != statistics->DMAParityErrors)
721 printf("oltr%d: DMA Parity Errors %lu\n", sc->unit,
722 statistics->DMAParityErrors);
723 if (sc->statistics.ReceiveLongFrame != statistics->ReceiveLongFrame)
724 printf("oltr%d: Long frames received %lu\n", sc->unit,
725 statistics->ReceiveLongFrame);
726 if (sc->statistics.ReceiveCRCErrors != statistics->ReceiveCRCErrors)
727 printf("oltr%d: Receive CRC Errors %lu\n", sc->unit,
728 statistics->ReceiveCRCErrors);
729 if (sc->statistics.ReceiveOverflow != statistics->ReceiveOverflow)
730 printf("oltr%d: Recieve overflows %lu\n", sc->unit,
731 statistics->ReceiveOverflow);
732 if (sc->statistics.TransmitUnderrun != statistics->TransmitUnderrun)
733 printf("oltr%d: Frequency Errors %lu\n", sc->unit,
734 statistics->TransmitUnderrun);
735 bcopy(statistics, &sc->statistics, sizeof(TRlldStatistics_t));
740 DriverSuspend(unsigned short MicroSeconds)
747 DriverStatus(void *DriverHandle, TRlldStatus_t *Status)
749 struct oltr_softc *sc = (struct oltr_softc *)DriverHandle;
750 struct ifnet *ifp = sc->ifp;
752 char *Protocol[] = { /* 0 */ "Unknown",
755 char *Timeout[] = { /* 0 */ "command",
757 /* 2 */ "interrupt" };
759 switch (Status->Type) {
761 case TRLLD_STS_ON_WIRE:
762 printf("oltr%d: ring insert (%d Mbps - %s)\n", sc->unit,
763 Status->Specification.OnWireInformation.Speed,
764 Protocol[Status->Specification.OnWireInformation.AccessProtocol]);
768 case TRLLD_STS_SELFTEST_STATUS:
769 if (Status->Specification.SelftestStatus == TRLLD_ST_OK) {
770 sc->state = OL_CLOSED;
772 printf("oltr%d: self test complete\n", sc->unit);
774 if (Status->Specification.SelftestStatus & TRLLD_ST_ERROR) {
775 printf("oltr%d: Adapter self test error %d", sc->unit,
776 Status->Specification.SelftestStatus & ~TRLLD_ST_ERROR);
779 if (Status->Specification.SelftestStatus & TRLLD_ST_TIMEOUT) {
780 printf("oltr%d: Adapter self test timed out.\n", sc->unit);
784 case TRLLD_STS_INIT_STATUS:
785 if (Status->Specification.InitStatus == 0x800) {
787 ifmedia_set(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP16);
788 TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
792 printf("oltr%d: adapter init failure 0x%03x\n", sc->unit,
793 Status->Specification.InitStatus);
796 case TRLLD_STS_RING_STATUS:
797 if (Status->Specification.RingStatus) {
798 printf("oltr%d: Ring status change: ", sc->unit);
799 if (Status->Specification.RingStatus &
800 TRLLD_RS_SIGNAL_LOSS)
801 printf(" [Signal Loss]");
802 if (Status->Specification.RingStatus &
804 printf(" [Hard Error]");
805 if (Status->Specification.RingStatus &
807 printf(" [Soft Error]");
808 if (Status->Specification.RingStatus &
809 TRLLD_RS_TRANSMIT_BEACON)
811 if (Status->Specification.RingStatus &
812 TRLLD_RS_LOBE_WIRE_FAULT)
813 printf(" [Wire Fault]");
814 if (Status->Specification.RingStatus &
815 TRLLD_RS_AUTO_REMOVAL_ERROR)
816 printf(" [Auto Removal]");
817 if (Status->Specification.RingStatus &
818 TRLLD_RS_REMOVE_RECEIVED)
819 printf(" [Remove Received]");
820 if (Status->Specification.RingStatus &
821 TRLLD_RS_COUNTER_OVERFLOW)
822 printf(" [Counter Overflow]");
823 if (Status->Specification.RingStatus &
824 TRLLD_RS_SINGLE_STATION)
825 printf(" [Single Station]");
826 if (Status->Specification.RingStatus &
827 TRLLD_RS_RING_RECOVERY)
828 printf(" [Ring Recovery]");
832 case TRLLD_STS_ADAPTER_CHECK:
833 printf("oltr%d: adapter check (%04x %04x %04x %04x)\n", sc->unit,
834 Status->Specification.AdapterCheck[0],
835 Status->Specification.AdapterCheck[1],
836 Status->Specification.AdapterCheck[2],
837 Status->Specification.AdapterCheck[3]);
841 case TRLLD_STS_PROMISCUOUS_STOPPED:
842 printf("oltr%d: promiscuous mode ", sc->unit);
843 if (Status->Specification.PromRemovedCause == 1)
844 printf("remove received.");
845 if (Status->Specification.PromRemovedCause == 2)
846 printf("poll failure.");
847 if (Status->Specification.PromRemovedCause == 2)
848 printf("buffer size failure.");
850 ifp->if_flags &= ~IFF_PROMISC;
852 case TRLLD_STS_LLD_ERROR:
853 printf("oltr%d: low level driver internal error ", sc->unit);
854 printf("(%04x %04x %04x %04x).\n",
855 Status->Specification.InternalError[0],
856 Status->Specification.InternalError[1],
857 Status->Specification.InternalError[2],
858 Status->Specification.InternalError[3]);
862 case TRLLD_STS_ADAPTER_TIMEOUT:
863 printf("oltr%d: adapter %s timeout.\n", sc->unit,
864 Timeout[Status->Specification.AdapterTimeout]);
867 printf("oltr%d: driver status Type = %d\n", sc->unit, Status->Type);
871 if (Status->Closed) {
872 sc->state = OL_CLOSING;
879 DriverCloseCompleted(void *DriverHandle)
881 struct oltr_softc *sc = (struct oltr_softc *)DriverHandle;
883 printf("oltr%d: adapter closed\n", sc->unit);
885 sc->state = OL_CLOSED;
889 DriverTransmitFrameCompleted(void *DriverHandle, void *FrameHandle, int TransmitStatus)
891 struct oltr_softc *sc = (struct oltr_softc *)DriverHandle;
892 struct ifnet *ifp = sc->ifp;
893 TRlldTransmit_t *frame = (TRlldTransmit_t *)FrameHandle;
895 /*printf("oltr%d: DriverTransmitFrameCompleted\n", sc->unit);*/
897 if (TransmitStatus != TRLLD_TRANSMIT_OK) {
899 printf("oltr%d: transmit error %d\n", sc->unit, TransmitStatus);
904 sc->tx_avail += frame->FragmentCount;
906 if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
907 printf("oltr%d: queue restart\n", sc->unit);
908 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
916 DriverReceiveFrameCompleted(void *DriverHandle, int ByteCount, int FragmentCount, void *FragmentHandle, int ReceiveStatus)
918 struct oltr_softc *sc = (struct oltr_softc *)DriverHandle;
919 struct ifnet *ifp = sc->ifp;
920 struct mbuf *m0, *m1, *m;
921 int frame_len = ByteCount, i = (int)FragmentHandle, rc, s;
922 int mbuf_offset, mbuf_size, frag_offset, copy_length;
923 char *fragment = sc->rx_ring[RING_BUFFER(i)].data;
925 if (sc->state > OL_CLOSED) {
926 if (ReceiveStatus == TRLLD_RCV_OK) {
927 MGETHDR(m0, M_DONTWAIT, MT_DATA);
928 mbuf_size = MHLEN - 2;
933 if (ByteCount + 2 > MHLEN) {
934 MCLGET(m0, M_DONTWAIT);
935 mbuf_size = MCLBYTES - 2;
936 if (!(m0->m_flags & M_EXT)) {
942 m0->m_pkthdr.rcvif = ifp;
943 m0->m_pkthdr.len = ByteCount;
951 copy_length = MIN3(frame_len,
952 (RX_BUFFER_LEN - frag_offset),
953 (mbuf_size - mbuf_offset));
954 bcopy(fragment + frag_offset, mtod(m, char *) +
955 mbuf_offset, copy_length);
956 m->m_len += copy_length;
957 mbuf_offset += copy_length;
958 frag_offset += copy_length;
959 frame_len -= copy_length;
961 if (frag_offset == RX_BUFFER_LEN) {
963 sc->rx_ring[RING_BUFFER(++i)].data;
966 if ((mbuf_offset == mbuf_size) && (frame_len > 0)) {
967 MGET(m1, M_DONTWAIT, MT_DATA);
974 if (frame_len > MHLEN) {
975 MCLGET(m1, M_DONTWAIT);
976 mbuf_size = MCLBYTES;
977 if (!(m1->m_flags & M_EXT)) {
990 iso88025_input(ifp, m0);
991 } else { /* Receiver error */
992 if (ReceiveStatus != TRLLD_RCV_NO_DATA) {
993 printf("oltr%d: receive error %d\n", sc->unit,
1001 i = (int)FragmentHandle;
1002 while (FragmentCount--) {
1003 rc = TRlldReceiveFragment(sc->TRlldAdapter,
1004 (void *)sc->rx_ring[RING_BUFFER(i)].data,
1005 sc->rx_ring[RING_BUFFER(i)].address,
1006 RX_BUFFER_LEN, (void *)sc->rx_ring[RING_BUFFER(i)].index);
1007 if (rc != TRLLD_RECEIVE_OK) {
1008 printf("oltr%d: adapter refused receive fragment %d (rc = %d)\n", sc->unit, i, rc);
1019 * ---------------------------- PMW Glue -------------------------------
1022 #ifndef TRlldInlineIO
1025 DriverOutByte(unsigned short IOAddress, unsigned char value)
1027 outbv(IOAddress, value);
1031 DriverOutWord(unsigned short IOAddress, unsigned short value)
1033 outw(IOAddress, value);
1037 DriverOutDword(unsigned short IOAddress, unsigned long value)
1039 outl(IOAddress, value);
1043 DriverRepOutByte(unsigned short IOAddress, unsigned char *DataPointer, int ByteCount)
1045 outsb(IOAddress, (void *)DataPointer, ByteCount);
1049 DriverRepOutWord(unsigned short IOAddress, unsigned short *DataPointer, int WordCount)
1051 outsw(IOAddress, (void *)DataPointer, WordCount);
1055 DriverRepOutDword(unsigned short IOAddress, unsigned long *DataPointer, int DWordCount)
1057 outsl(IOAddress, (void *)DataPointer, DWordCount);
1060 static unsigned char
1061 DriverInByte(unsigned short IOAddress)
1063 return(inbv(IOAddress));
1066 static unsigned short
1067 DriverInWord(unsigned short IOAddress)
1069 return(inw(IOAddress));
1072 static unsigned long
1073 DriverInDword(unsigned short IOAddress)
1075 return(inl(IOAddress));
1079 DriverRepInByte(unsigned short IOAddress, unsigned char *DataPointer, int ByteCount)
1081 insb(IOAddress, (void *)DataPointer, ByteCount);
1085 DriverRepInWord(unsigned short IOAddress, unsigned short *DataPointer, int WordCount)
1087 insw(IOAddress, (void *)DataPointer, WordCount);
1090 DriverRepInDword( unsigned short IOAddress, unsigned long *DataPointer, int DWordCount)
1092 insl(IOAddress, (void *)DataPointer, DWordCount);
1094 #endif /* TRlldInlineIO */