1 /* $NetBSD: tropic.c,v 1.39 2009/05/12 14:25:18 cegger Exp $ */
4 * Ported to NetBSD by Onno van der Linden
5 * Many thanks to Larry Lile for sending me the IBM TROPIC documentation.
7 * Mach Operating System
8 * Copyright (c) 1991 Carnegie Mellon University
9 * Copyright (c) 1991 IBM Corporation
10 * All Rights Reserved.
12 * Permission to use, copy, modify and distribute this software and its
13 * documentation is hereby granted, provided that both the copyright
14 * notice and this permission notice appear in all copies of the
15 * software, derivative works or modified versions, and any portions
16 * thereof, and that both notices appear in supporting documentation,
17 * and that the name IBM not be used in advertising or publicity
18 * pertaining to distribution of the software without specific, written
21 * CARNEGIE MELLON AND IBM ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
22 * CONDITION. CARNEGIE MELLON AND IBM DISCLAIM ANY LIABILITY OF ANY KIND FOR
23 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
25 * Carnegie Mellon requests users of this software to return to
27 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
28 * School of Computer Science
29 * Carnegie Mellon University
30 * Pittsburgh PA 15213-3890
32 * any improvements or extensions that they make and grant Carnegie Mellon
33 * the rights to redistribute these changes.
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: tropic.c,v 1.39 2009/05/12 14:25:18 cegger Exp $");
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/callout.h>
45 #include <sys/kernel.h>
49 #include <sys/socket.h>
50 #include <sys/syslog.h>
51 #include <sys/ioctl.h>
52 #include <sys/errno.h>
53 #include <sys/device.h>
56 #include <net/if_llc.h>
57 #include <net/if_ether.h>
58 #include <net/if_media.h>
59 #include <net/netisr.h>
60 #include <net/route.h>
61 #include <net/if_token.h>
64 #include <netinet/in.h>
65 #include <netinet/if_inarp.h>
66 #include <netinet/in_systm.h>
67 #include <netinet/ip.h>
68 #include <netinet/in_var.h>
74 #include <net/bpfdesc.h>
80 #include <dev/ic/tropicreg.h>
81 #include <dev/ic/tropicvar.h>
83 static void tr_shutdown(void *);
84 static void tr_reopen(void *);
86 void tr_rint(struct tr_softc
*);
87 void tr_xint(struct tr_softc
*);
88 void tr_oldxint(struct tr_softc
*);
89 struct mbuf
*tr_get(struct tr_softc
*, int, struct ifnet
*);
90 void tr_opensap(struct tr_softc
*, u_char
);
91 int tr_mbcopy(struct tr_softc
*, bus_size_t
, struct mbuf
*);
92 void tr_bcopy(struct tr_softc
*, u_char
*, int);
93 void tr_start(struct ifnet
*);
94 void tr_oldstart(struct ifnet
*);
95 void tr_watchdog(struct ifnet
*);
96 int tr_mediachange(struct ifnet
*);
97 void tr_mediastatus(struct ifnet
*, struct ifmediareq
*);
98 int tropic_mediachange(struct tr_softc
*);
99 void tropic_mediastatus(struct tr_softc
*, struct ifmediareq
*);
100 void tr_reinit(void *);
104 * clean up tr_intr: more subroutines
105 * IFF_LINK0 == IFM_TOK_SRCRT change to link flag implies media flag change
106 * IFF_LINK1 == IFM_TOK_ALLR change to link flag implies media flag change
107 * XXX Create receive_done queue to kill "ASB not free", but does this ever
111 static int media
[] = {
112 IFM_TOKEN
| IFM_TOK_UTP4
,
113 IFM_TOKEN
| IFM_TOK_STP4
,
114 IFM_TOKEN
| IFM_TOK_UTP16
,
115 IFM_TOKEN
| IFM_TOK_STP16
,
116 IFM_TOKEN
| IFM_TOK_UTP4
,
117 IFM_TOKEN
| IFM_TOK_UTP16
,
118 IFM_TOKEN
| IFM_TOK_STP4
,
119 IFM_TOKEN
| IFM_TOK_STP16
123 tropic_mediachange(struct tr_softc
*sc
)
125 if (IFM_TYPE(sc
->sc_media
.ifm_media
) != IFM_TOKEN
)
128 switch (IFM_SUBTYPE(sc
->sc_media
.ifm_media
)) {
131 if ((sc
->sc_init_status
& RSP_16
) == 0) {
133 if (tr_setspeed(sc
, 16))
143 if ((sc
->sc_init_status
& RSP_16
) != 0) {
145 if (tr_setspeed(sc
, 4))
155 * XXX Handle Early Token Release !!!!
161 tropic_mediastatus(struct tr_softc
*sc
, struct ifmediareq
*ifmr
)
163 struct ifmedia
*ifm
= &sc
->sc_media
;
165 ifmr
->ifm_active
= ifm
->ifm_cur
->ifm_media
;
169 tr_config(struct tr_softc
*sc
)
171 if (sc
->sc_init_status
& FAST_PATH_TRANSMIT
) {
174 for (i
=0; i
< SRB_CFP_CMDSIZE
; i
++)
175 SRB_OUTB(sc
, sc
->sc_srb
, i
, 0);
177 SRB_OUTB(sc
, sc
->sc_srb
, SRB_CMD
, DIR_CONFIG_FAST_PATH_RAM
);
179 SRB_OUTW(sc
, sc
->sc_srb
, SRB_CFP_RAMSIZE
,
180 (16 + (sc
->sc_nbuf
* FP_BUF_LEN
) / 8));
181 SRB_OUTW(sc
, sc
->sc_srb
, SRB_CFP_BUFSIZE
, FP_BUF_LEN
);
183 /* tell adapter: command in SRB */
184 ACA_SETB(sc
, ACA_ISRA_o
, CMD_IN_SRB
);
186 for (i
= 0; i
< 30000; i
++) {
187 if (ACA_RDB(sc
, ACA_ISRP_o
) & SRB_RESP_INT
)
192 if (i
== 30000 && sc
->sc_srb
== ACA_RDW(sc
, ACA_WRBR
)) {
193 aprint_error_dev(&sc
->sc_dev
, "no response for fast path cfg\n");
197 ACA_RSTB(sc
, ACA_ISRP_o
, ~(SRB_RESP_INT
));
199 if ((SRB_INB(sc
, sc
->sc_srb
, SRB_RETCODE
) != 0)) {
200 printf("%s: cfg fast path returned: 0x%02x\n",
201 device_xname(&sc
->sc_dev
),
202 SRB_INB(sc
, sc
->sc_srb
, SRB_RETCODE
));
206 sc
->sc_txca
= SRB_INW(sc
, sc
->sc_srb
, SRB_CFPRESP_FPXMIT
);
207 sc
->sc_srb
= SRB_INW(sc
, sc
->sc_srb
, SRB_CFPRESP_SRBADDR
);
210 if (sc
->sc_init_status
& RSP_16
)
211 sc
->sc_maxmtu
= sc
->sc_dhb16maxsz
;
213 sc
->sc_maxmtu
= sc
->sc_dhb4maxsz
;
215 * XXX Not completely true because Fast Path Transmit has 514 byte buffers
216 * XXX and TR_MAX_LINK_HDR is only correct when source-routing is used.
217 * XXX depending on wether source routing is used change the calculation
218 * XXX use IFM_TOK_SRCRT (IFF_LINK0)
219 * XXX recompute sc_minbuf !!
221 sc
->sc_maxmtu
-= TR_MAX_LINK_HDR
;
227 tr_attach(struct tr_softc
*sc
)
229 int nmedia
, *mediaptr
, *defmediaptr
;
231 u_int8_t myaddr
[ISO88025_ADDR_LEN
];
232 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
234 if (sc
->sc_init_status
& FAST_PATH_TRANSMIT
) {
237 switch (sc
->sc_memsize
) {
240 sc
->sc_maxmtu
= IPMTU_4MBIT_MAX
;
244 sc
->sc_maxmtu
= IPMTU_4MBIT_MAX
;
248 sc
->sc_maxmtu
= IPMTU_4MBIT_MAX
;
252 sc
->sc_maxmtu
= ISO88025_MTU
;
255 sc
->sc_minbuf
= ((sc
->sc_maxmtu
+ 511) / 512) + 1;
256 sc
->sc_nbuf
= numbuf
;
259 * Create circular queues caching the buffer pointers ?
264 * MAX_MACFRAME_SIZE = DHB_SIZE - 6
265 * IPMTU = MAX_MACFRAME_SIZE - (14 + 18 + 8)
266 * (14 = header, 18 = sroute, 8 = llcsnap)
269 switch (sc
->sc_memsize
) {
271 sc
->sc_dhb4maxsz
= 2048;
272 sc
->sc_dhb16maxsz
= 2048;
275 sc
->sc_dhb4maxsz
= 4096;
276 sc
->sc_dhb16maxsz
= 4096;
279 sc
->sc_dhb4maxsz
= 4464;
280 sc
->sc_dhb16maxsz
= 8192;
283 sc
->sc_dhb4maxsz
= 4464;
284 sc
->sc_dhb16maxsz
= 8192;
287 switch (MM_INB(sc
, TR_DHB4_OFFSET
)) {
289 if (sc
->sc_dhb4maxsz
> 2048)
290 sc
->sc_dhb4maxsz
= 2048;
293 if (sc
->sc_dhb4maxsz
> 4096)
294 sc
->sc_dhb4maxsz
= 4096;
297 if (sc
->sc_dhb4maxsz
> 4464)
298 sc
->sc_dhb4maxsz
= 4464;
302 switch (MM_INB(sc
, TR_DHB16_OFFSET
)) {
304 if (sc
->sc_dhb16maxsz
> 2048)
305 sc
->sc_dhb16maxsz
= 2048;
308 if (sc
->sc_dhb16maxsz
> 4096)
309 sc
->sc_dhb16maxsz
= 4096;
312 if (sc
->sc_dhb16maxsz
> 8192)
313 sc
->sc_dhb16maxsz
= 8192;
316 if (sc
->sc_dhb16maxsz
> 8192)
317 sc
->sc_dhb16maxsz
= 8192;
320 if (sc
->sc_dhb16maxsz
> 8192)
321 sc
->sc_dhb16maxsz
= 8192;
330 * init network-visible interface
332 strlcpy(ifp
->if_xname
, device_xname(&sc
->sc_dev
), IFNAMSIZ
);
334 ifp
->if_ioctl
= tr_ioctl
;
335 if (sc
->sc_init_status
& FAST_PATH_TRANSMIT
)
336 ifp
->if_start
= tr_start
;
338 ifp
->if_start
= tr_oldstart
;
339 ifp
->if_flags
= IFF_BROADCAST
| IFF_NOTRAILERS
;
340 ifp
->if_watchdog
= tr_watchdog
;
341 IFQ_SET_READY(&ifp
->if_snd
);
343 switch (MM_INB(sc
, TR_MEDIAS_OFFSET
)) {
346 mediaptr
= &media
[6];
350 mediaptr
= &media
[0];
354 mediaptr
= &media
[4];
361 switch (MM_INB(sc
, TR_RATES_OFFSET
)) {
376 switch (MM_INB(sc
, TR_MEDIA_OFFSET
)) {
379 defmediaptr
= &media
[6];
383 defmediaptr
= &media
[4];
386 /* STP and UTP == a single shielded RJ45 which supports both */
387 /* XXX additional types in net/if_media.h ?? */
388 defmediaptr
= &media
[4];
394 if (defmediaptr
&& (sc
->sc_init_status
& RSP_16
))
397 if (sc
->sc_mediachange
== NULL
&& sc
->sc_mediastatus
== NULL
) {
398 switch (MM_INB(sc
, TR_TYP_OFFSET
)) {
401 sc
->sc_mediachange
= tropic_mediachange
;
402 sc
->sc_mediastatus
= tropic_mediastatus
;
406 ifmedia_init(&sc
->sc_media
, 0, tr_mediachange
, tr_mediastatus
);
407 if (mediaptr
!= NULL
) {
408 for (i
= 0; i
< nmedia
; i
++)
409 ifmedia_add(&sc
->sc_media
, mediaptr
[i
], 0, NULL
);
411 ifmedia_set(&sc
->sc_media
, *defmediaptr
);
413 ifmedia_set(&sc
->sc_media
, 0);
416 ifmedia_add(&sc
->sc_media
, IFM_TOKEN
| IFM_MANUAL
, 0, NULL
);
417 ifmedia_set(&sc
->sc_media
, IFM_TOKEN
| IFM_MANUAL
);
422 for (i
= 0, temp
= 0; i
< ISO88025_ADDR_LEN
; i
++, temp
+= 4) {
423 myaddr
[i
] = (MM_INB(sc
, (TR_MAC_OFFSET
+ temp
)) & 0xf) << 4;
424 myaddr
[i
] |= MM_INB(sc
, (TR_MAC_OFFSET
+ temp
+ 2)) & 0xf;
427 token_ifattach(ifp
, myaddr
);
429 printf("%s: address %s ring speed %d Mbps\n", device_xname(&sc
->sc_dev
),
430 token_sprintf(myaddr
), (sc
->sc_init_status
& RSP_16
) ? 16 : 4);
432 callout_init(&sc
->sc_init_callout
, 0);
433 callout_init(&sc
->sc_reinit_callout
, 0);
435 sc
->sc_sdhook
= shutdownhook_establish(tr_shutdown
, sc
);
440 tr_setspeed(struct tr_softc
*sc
, u_int8_t speed
)
442 SRB_OUTB(sc
, sc
->sc_srb
, SRB_CMD
, DIR_SET_DEFAULT_RING_SPEED
);
443 SRB_OUTB(sc
, sc
->sc_srb
, CMD_RETCODE
, 0xfe);
444 SRB_OUTB(sc
, sc
->sc_srb
, SRB_SET_DEFRSP
, speed
);
445 /* Tell adapter: command in SRB. */
446 ACA_SETB(sc
, ACA_ISRA_o
, CMD_IN_SRB
);
448 /* Wait for it to complete. */
451 if ((SRB_INB(sc
, sc
->sc_srb
, SRB_RETCODE
) != 0)) {
452 printf("%s: set default ringspeed returned: 0x%02x\n",
453 device_xname(&sc
->sc_dev
), SRB_INB(sc
, sc
->sc_srb
, SRB_RETCODE
));
460 tr_mediachange(struct ifnet
*ifp
)
462 struct tr_softc
*sc
= ifp
->if_softc
;
464 if (sc
->sc_mediachange
)
465 return ((*sc
->sc_mediachange
)(sc
));
470 tr_mediastatus(struct ifnet
*ifp
, struct ifmediareq
*ifmr
)
472 struct tr_softc
*sc
= ifp
->if_softc
;
474 /* set LINK0 and/or LINK1 */
475 if (sc
->sc_mediastatus
)
476 (*sc
->sc_mediastatus
)(sc
, ifmr
);
480 tr_reset(struct tr_softc
*sc
)
489 /* latch on an unconditional adapter reset */
490 bus_space_write_1(sc
->sc_piot
, sc
->sc_pioh
, TR_RESET
, 0);
491 delay(50000); /* delay 50ms */
493 * XXX set paging if we have the right type of card
495 /* turn off adapter reset */
496 bus_space_write_1(sc
->sc_piot
, sc
->sc_pioh
, TR_RELEASE
, 0);
498 /* Enable interrupts. */
500 ACA_SETB(sc
, ACA_ISRP_e
, INT_ENABLE
);
502 /* Wait for an answer from the adapter. */
504 for (i
= 0; i
< 35000; i
++) {
505 if (ACA_RDB(sc
, ACA_ISRP_o
) & SRB_RESP_INT
)
510 if (i
== 35000 && sc
->sc_srb
== 0) {
511 aprint_error_dev(&sc
->sc_dev
, "no response from adapter after reset\n");
515 ACA_RSTB(sc
, ACA_ISRP_o
, ~(SRB_RESP_INT
));
517 ACA_OUTB(sc
, ACA_RRR_e
, (sc
->sc_maddr
>> 12));
518 sc
->sc_srb
= ACA_RDW(sc
, ACA_WRBR
);
519 if (SRB_INB(sc
, sc
->sc_srb
, SRB_CMD
) != 0x80) {
520 aprint_error_dev(&sc
->sc_dev
, "initialization incomplete, status: 0x%02x\n",
521 SRB_INB(sc
, sc
->sc_srb
, SRB_CMD
));
524 if (SRB_INB(sc
, sc
->sc_srb
, SRB_INIT_BUC
) != 0) {
525 aprint_error_dev(&sc
->sc_dev
, "Bring Up Code %02x\n",
526 SRB_INB(sc
, sc
->sc_srb
, SRB_INIT_BUC
));
530 sc
->sc_init_status
= SRB_INB(sc
, sc
->sc_srb
, SRB_INIT_STATUS
);
532 sc
->sc_xmit_head
= sc
->sc_xmit_tail
= 0;
534 /* XXX should depend on sc_resvdmem. */
535 if (MM_INB(sc
, TR_RAM_OFFSET
) == 0xB && sc
->sc_memsize
== 65536)
536 for (i
= 0; i
< 512; i
++)
537 SR_OUTB(sc
, 0xfe00 + i
, 0);
542 * tr_stop - stop interface (issue a DIR.CLOSE.ADAPTER command)
545 tr_stop(struct tr_softc
*sc
)
547 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
549 if ((ifp
->if_flags
& IFF_RUNNING
) != 0) {
551 * transmitter cannot be used from now on
553 ifp
->if_flags
|= IFF_OACTIVE
;
556 SRB_OUTB(sc
, sc
->sc_srb
, SRB_CMD
, DIR_CLOSE
);
557 /* Tell adapter: command in SRB. */
558 ACA_SETB(sc
, ACA_ISRA_o
, CMD_IN_SRB
);
560 /* Wait for it to complete. */
562 sc
->sc_srb
= ACA_RDW(sc
, ACA_WRBR
);
567 tr_shutdown(void *arg
)
569 struct tr_softc
*sc
= arg
;
577 struct tr_softc
*sc
= arg
;
581 if (tr_reset(sc
) == 0) {
582 if (tr_config(sc
) == 0)
599 * tr_init - initialize network interface, open adapter for packet
600 * - reception and start any pending output
601 * - must be called at splnet
606 struct tr_softc
*sc
= arg
;
607 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
609 int num_dhb
, resvdmem
, availmem
, dhbsize
;
611 if ((ifp
->if_flags
& IFF_RUNNING
) != 0)
614 ifp
->if_flags
&= ~IFF_OACTIVE
;
615 sc
->sc_xmit_head
= sc
->sc_xmit_tail
= 0; /* XXX tr_reset() */
617 open_srb
= sc
->sc_srb
;
620 bus_space_set_region_1(sc
->sc_memt
, sc
->sc_sramh
,
621 open_srb
, 0, SRB_OPEN_CMDSIZE
);
624 SRB_OUTB(sc
, open_srb
, SRB_CMD
, DIR_OPEN_ADAPTER
);
626 * XXX handle IFM_TOK_ETR !!!!
628 /* Set open parameters in SRB. */
629 SRB_OUTW(sc
, open_srb
, SRB_OPEN_OPTIONS
, OPEN_PASS_BCON_MAC
);
633 if ((sc
->sc_init_status
& FAST_PATH_TRANSMIT
) == 0) {
634 availmem
= sc
->sc_memsize
;
635 resvdmem
= RESVDMEM_SIZE
+ sc
->sc_memreserved
;
637 /* allow MAX of two SAPS */
638 SRB_OUTB(sc
, open_srb
, SRB_OPEN_DLCMAXSAP
, 2);
639 resvdmem
+= 2 * SAPCB_SIZE
;
641 /* allow MAX of 4 stations */
642 SRB_OUTB(sc
, open_srb
, SRB_OPEN_DLCMAXSTA
, 4);
643 resvdmem
+= 4 * LSCB_SIZE
;
645 if (sc
->sc_init_status
& RSP_16
) {
646 dhbsize
= sc
->sc_dhb16maxsz
;
649 dhbsize
= sc
->sc_dhb4maxsz
;
651 #if 0 /* XXXchb unneeded? */
655 SRB_OUTW(sc
, open_srb
, SRB_OPEN_DHBLEN
, dhbsize
);
656 sc
->sc_nbuf
= (dhbsize
+ 511) / 512;
658 * Try to leave room for two fullsized packets when
661 availmem
-= resvdmem
;
662 num_dhb
= (availmem
/ dhbsize
) - 2;
664 num_dhb
= 2; /* firmware can't cope with more DHBs */
666 num_dhb
= 1; /* we need at least one */
669 SRB_OUTW(sc
, open_srb
, SRB_OPEN_DHBLEN
, DHB_LENGTH
);
671 SRB_OUTB(sc
, open_srb
, SRB_OPEN_NUMDHB
, num_dhb
);
672 SRB_OUTW(sc
, open_srb
, SRB_OPEN_RCVBUFLEN
, RCV_BUF_LEN
);
673 SRB_OUTW(sc
, open_srb
, SRB_OPEN_NUMRCVBUF
, sc
->sc_nbuf
);
675 /* Tell adapter: command in SRB. */
676 ACA_SETB(sc
, ACA_ISRA_o
, CMD_IN_SRB
);
681 * tr_oldstart - Present transmit request to adapter
684 tr_oldstart(struct ifnet
*ifp
)
686 struct tr_softc
*sc
= ifp
->if_softc
;
687 bus_size_t srb
= sc
->sc_srb
;
689 if ((ifp
->if_flags
& (IFF_RUNNING
| IFF_OACTIVE
)) != IFF_RUNNING
)
692 ifp
->if_flags
|= IFF_OACTIVE
;
694 /* Load SRB to request transmit. */
695 SRB_OUTB(sc
, srb
, SRB_CMD
, XMIT_UI_FRM
);
696 SRB_OUTW(sc
, srb
, XMIT_STATIONID
, sc
->exsap_station
);
697 ACA_SETB(sc
, ACA_ISRA_o
, CMD_IN_SRB
);
701 tr_start(struct ifnet
*ifp
)
703 struct tr_softc
*sc
= ifp
->if_softc
;
704 bus_size_t first_txbuf
, txbuf
;
707 bus_size_t framedata
;
709 if ((ifp
->if_flags
& (IFF_RUNNING
| IFF_OACTIVE
)) != IFF_RUNNING
)
714 if (sc
->sc_xmit_buffers
< sc
->sc_minbuf
)
717 /* if data in queue, copy mbuf chain to fast path buffers */
718 IFQ_DEQUEUE(&ifp
->if_snd
, m0
);
724 bpf_mtap(ifp
->if_bpf
, m0
);
726 first_txbuf
= txbuf
= TXCA_INW(sc
, TXCA_FREE_QUEUE_HEAD
) - XMIT_NEXTBUF
;
727 framedata
= txbuf
+ XMIT_FP_DATA
;
729 bufspace
= FP_BUF_LEN
- XMIT_FP_DATA
;
730 for (m
= m0
; m
; m
= m
->m_next
) {
732 char *ptr
= mtod(m
, char *);
734 while (len
>= bufspace
) {
735 --sc
->sc_xmit_buffers
;
736 bus_space_write_region_1(sc
->sc_memt
, sc
->sc_sramh
,
737 framedata
, ptr
, bufspace
);
741 TXB_OUTW(sc
, txbuf
, XMIT_BUFLEN
,
742 (FP_BUF_LEN
- XMIT_FP_DATA
));
743 txbuf
= TXB_INW(sc
, txbuf
, XMIT_NEXTBUF
) - XMIT_NEXTBUF
;
744 framedata
= txbuf
+ XMIT_FP_DATA
;
745 bufspace
= FP_BUF_LEN
- XMIT_FP_DATA
;
748 bus_space_write_region_1(sc
->sc_memt
, sc
->sc_sramh
,
749 framedata
, ptr
, len
);
755 if (size
% (FP_BUF_LEN
- XMIT_FP_DATA
)) {
756 --sc
->sc_xmit_buffers
;
757 TXB_OUTW(sc
, txbuf
, XMIT_BUFLEN
,
758 (FP_BUF_LEN
- XMIT_FP_DATA
- bufspace
));
761 m_freem(m0
); /* free mbuf chain */
763 TXB_OUTB(sc
, first_txbuf
, XMIT_RETCODE
, 0xfe);
764 TXB_OUTW(sc
, first_txbuf
, XMIT_FRAMELEN
, size
);
765 TXB_OUTW(sc
, first_txbuf
, XMIT_LASTBUF
, (txbuf
+ XMIT_NEXTBUF
));
766 TXB_OUTB(sc
, first_txbuf
, XMIT_CMD
, XMIT_DIR_FRAME
);
767 TXB_OUTW(sc
, first_txbuf
, XMIT_STATIONID
, 0);
768 TXB_OUTB(sc
, first_txbuf
, XMIT_CMDCORR
, sc
->sc_xmit_correlator
);
769 sc
->sc_xmit_correlator
= (sc
->sc_xmit_correlator
+ 1) & 0x7f;
772 * To prevent race conditions on 8-bit cards when reading or writing
773 * 16-bit values. See page 4-12 of the IBM manual.
775 TXCA_OUTW(sc
, TXCA_FREE_QUEUE_HEAD
, 1);
776 TXCA_OUTW(sc
, TXCA_FREE_QUEUE_HEAD
, TXB_INW(sc
, txbuf
, XMIT_NEXTBUF
));
778 ACA_SETB(sc
, ACA_ISRA_o
, XMIT_REQ
);
780 ifp
->if_flags
|= IFF_OACTIVE
;
783 /* XXX do while construction */
790 * tr_intr - interrupt handler. Find the cause of the interrupt and
796 struct tr_softc
*sc
= arg
;
797 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
798 u_char status
; /* holds status from adapter status register */
799 u_char command
; /* holds command from status or request block */
800 u_char retcode
; /* holds return value from status or request block */
801 int rc
= 0; /* 0 = unclaimed interrupt, 1 = interrupt claimed */
803 status
= ACA_RDB(sc
, ACA_ISRP_o
);
804 while (status
!= 0) {
806 /* Is this interrupt caused by an adapter check? */
807 if (status
& ADAP_CHK_INT
) {
808 printf("%s: adapter check 0x%04x\n",
809 device_xname(&sc
->sc_dev
),
810 (unsigned int)ntohs(ACA_RDW(sc
, ACA_WWCR
)));
812 /* Clear this interrupt bit */
813 ACA_RSTB(sc
, ACA_ISRP_o
, ~(ADAP_CHK_INT
));
815 rc
= 1; /* Claim interrupt. */
816 break; /* Terminate loop. */
818 else if (status
& XMIT_COMPLETE
) {
819 ACA_RSTB(sc
, ACA_ISRP_o
, ~(XMIT_COMPLETE
));
825 * Process SRB_RESP_INT, ASB_FREE_INT, ARB_CMD_INT
826 * & SSB_RESP_INT in that order, ISRP-L Hi to Lo
828 else if (status
& SRB_RESP_INT
) { /* Adapter response in SRB? */
835 sc
->sc_srb
= ACA_RDW(sc
, ACA_WRBR
);
836 srb
= sc
->sc_srb
; /* pointer to SRB */
837 retcode
= SRB_INB(sc
, srb
, SRB_RETCODE
);
838 command
= SRB_INB(sc
, srb
, SRB_CMD
);
840 case 0x80: /* 0x80 == initialization complete */
841 case DIR_CONFIG_FAST_PATH_RAM
:
843 case XMIT_DIR_FRAME
: /* Response to xmit request */
844 case XMIT_UI_FRM
: /* Response to xmit request */
845 /* Response not valid? */
847 aprint_error_dev(&sc
->sc_dev
, "error on xmit request = "
851 case DIR_OPEN_ADAPTER
: /* open-adapter-cmd response */
852 /* Open successful? */
854 ifp
->if_flags
|= IFF_UP
| IFF_RUNNING
;
855 /* Save new ACA ctrl block addresses */
856 sc
->sc_ssb
= SRB_INW(sc
, srb
,
857 SRB_OPENRESP_SSBADDR
);
858 sc
->sc_arb
= SRB_INW(sc
, srb
,
859 SRB_OPENRESP_ARBADDR
);
860 sc
->sc_srb
= SRB_INW(sc
, srb
,
861 SRB_OPENRESP_SRBADDR
);
862 sc
->sc_asb
= SRB_INW(sc
, srb
,
863 SRB_OPENRESP_ASBADDR
);
866 * XXX, what about LLC_{X25,ISO}_LSAP ?
867 * open two more saps .....
869 if (sc
->sc_init_status
&
870 FAST_PATH_TRANSMIT
) {
871 sc
->sc_xmit_buffers
=
877 printf("%s: %d buffers\n",
878 device_xname(&sc
->sc_dev
),
879 sc
->sc_xmit_buffers
);
881 sc
->sc_xmit_correlator
= 0;
882 wakeup(&sc
->tr_sleepevent
);
885 tr_opensap(sc
, LLC_SNAP_LSAP
);
888 aprint_error_dev(&sc
->sc_dev
, "open error = 0x%x\n",
889 SRB_INB(sc
, srb
, SRB_RETCODE
));
890 ifp
->if_flags
&= ~IFF_RUNNING
;
891 ifp
->if_flags
&= ~IFF_UP
;
893 * XXX untimeout depending on the error, timeout in other cases
894 * XXX error 0x24 && autospeed mode: open again !!!!
896 callout_reset(&sc
->sc_init_callout
,
897 hz
* 30, tr_reopen
, sc
);
901 case DIR_CLOSE
: /* Response to close adapter command */
902 /* Close not successful? */
904 aprint_error_dev(&sc
->sc_dev
, "close error = 0x%x\n", retcode
);
906 ifp
->if_flags
&= ~IFF_RUNNING
;
907 ifp
->if_flags
&= ~IFF_UP
;
908 ifp
->if_flags
&= ~IFF_OACTIVE
;
909 wakeup(&sc
->tr_sleepevent
);
912 case DIR_SET_DEFAULT_RING_SPEED
:
913 wakeup(&sc
->tr_sleepevent
);
916 case DLC_OPEN_SAP
: /* Response to open sap cmd */
917 sap_srb
= sc
->sc_srb
;
918 if (SRB_INB(sc
, sap_srb
, SRB_OPNSAP_SAPVALUE
)
922 SRB_OPNSAP_STATIONID
);
923 printf("%s: Token Ring opened\n",
924 device_xname(&sc
->sc_dev
));
925 wakeup(&sc
->tr_sleepevent
);
927 /* XXX DLC_CLOSE_SAP not needed ? */
928 case DLC_CLOSE_SAP
: /* Response to close sap cmd */
930 case DIR_READ_LOG
: /* Response to read log */
931 /* Cmd not successful? */
933 aprint_error_dev(&sc
->sc_dev
, "read error log cmd err = "
936 log_srb
= sc
->sc_srb
;
937 printf("%s: ERROR LOG:\n", device_xname(&sc
->sc_dev
));
938 printf("%s: Line=%d, Internal=%d, Burst=%d\n",
939 device_xname(&sc
->sc_dev
),
940 (SRB_INB(sc
, log_srb
, SRB_LOG_LINEERRS
)),
941 (SRB_INB(sc
, log_srb
, SRB_LOG_INTERRS
)),
942 (SRB_INB(sc
, log_srb
, SRB_LOG_BRSTERRS
)));
943 printf("%s: A/C=%d, Abort=%d, Lost frames=%d\n",
944 device_xname(&sc
->sc_dev
),
945 (SRB_INB(sc
, log_srb
, SRB_LOG_ACERRS
)),
946 (SRB_INB(sc
, log_srb
, SRB_LOG_ABRTERRS
)),
947 (SRB_INB(sc
, log_srb
, SRB_LOG_LOSTFRMS
)));
948 printf("%s: Receive congestion=%d, Frame copied=%d, Frequency=%d\n",
949 device_xname(&sc
->sc_dev
),
950 (SRB_INB(sc
, log_srb
, SRB_LOG_RCVCONG
)),
951 (SRB_INB(sc
, log_srb
, SRB_LOG_FCPYERRS
)),
952 (SRB_INB(sc
, log_srb
, SRB_LOG_FREQERRS
)));
953 printf("%s: Token=%d\n", device_xname(&sc
->sc_dev
),
954 (SRB_INB(sc
, log_srb
, SRB_LOG_TOKENERRS
)));
955 #endif /* TROPICDEBUG */
956 ifp
->if_flags
&= ~IFF_OACTIVE
;
959 printf("%s: bad SRB command encountered 0x%x\n",
960 device_xname(&sc
->sc_dev
), command
);
963 /* clear the SRB-response interrupt bit */
964 ACA_RSTB(sc
, ACA_ISRP_o
, ~(SRB_RESP_INT
));
968 else if (status
& ASB_FREE_INT
) { /* Is ASB Free? */
969 bus_size_t asb
= sc
->sc_asb
;
972 * Remove message from asb queue, first element in
973 * structure is the command. command == REC_DATA?
974 * size = 8 : size = 10
975 * reply in isra_l with (RESP_IN_ASB | ASB_FREE)
977 retcode
= ASB_INB(sc
, asb
, CMD_RETCODE
);
978 command
= ASB_INB(sc
, asb
, CMD_CMD
);
980 case REC_DATA
: /* Receive */
981 /* Response not valid? */
983 aprint_error_dev(&sc
->sc_dev
, "ASB bad receive response = 0x%x\n", retcode
);
985 case XMIT_DIR_FRAME
: /* Transmit */
986 case XMIT_UI_FRM
: /* Transmit */
987 /* Response not valid? */
989 aprint_error_dev(&sc
->sc_dev
, "ASB response err on xmit = 0x%x\n", retcode
);
992 aprint_error_dev(&sc
->sc_dev
, "invalid command in ASB = 0x%x\n", command
);
995 /* Clear this interrupt bit */
996 ACA_RSTB(sc
, ACA_ISRP_o
, ~(ASB_FREE_INT
));
998 else if (status
& ARB_CMD_INT
) { /* Command for PC to handle? */
999 bus_size_t arb
= sc
->sc_arb
;
1001 command
= ARB_INB(sc
, arb
, ARB_CMD
);
1003 case DLC_STATUS
: /* DLC status change */
1004 printf("%s: ARB new DLC status = 0x%x\n",
1005 device_xname(&sc
->sc_dev
),
1006 ARB_INW(sc
, arb
, ARB_DLCSTAT_STATUS
));
1008 case REC_DATA
: /* Adapter has data for PC */
1009 /* Call receive interrupt handler */
1013 case RING_STAT_CHANGE
: /* Ring status change */
1014 if (ARB_INW(sc
, arb
, ARB_RINGSTATUS
) &
1015 (SIGNAL_LOSS
+ LOBE_FAULT
)){
1016 aprint_error_dev(&sc
->sc_dev
, "signal loss / lobe fault\n");
1017 ifp
->if_flags
&= ~IFF_RUNNING
;
1018 ifp
->if_flags
&= ~IFF_UP
;
1019 IFQ_PURGE(&ifp
->if_snd
);
1020 callout_reset(&sc
->sc_reinit_callout
,
1021 hz
* 30, tr_reinit
, sc
);
1025 if (ARB_INW(sc
, arb
, ARB_RINGSTATUS
) &
1027 printf("%s: ARB new ring status"
1029 device_xname(&sc
->sc_dev
),
1032 #endif /* TROPICDEBUG */
1034 if (ARB_INW(sc
, arb
, ARB_RINGSTATUS
) &
1037 * XXX CMD_IN_SRB, handle with SRB_FREE_INT ?
1039 ifp
->if_flags
|= IFF_OACTIVE
;
1040 SRB_OUTB(sc
, sc
->sc_srb
, SRB_CMD
,
1042 /* Read & reset err log cmnd in SRB. */
1043 ACA_SETB(sc
, ACA_ISRA_o
, CMD_IN_SRB
);
1047 case XMIT_DATA_REQ
: /* Adapter wants data to transmit */
1048 /* Call transmit interrupt handler */
1053 aprint_error_dev(&sc
->sc_dev
, "invalid command in ARB = 0x%x\n", command
);
1057 /* Clear this interrupt bit */
1058 ACA_RSTB(sc
, ACA_ISRP_o
, ~(ARB_CMD_INT
));
1060 /* Tell adapter that ARB is now free */
1061 ACA_SETB(sc
, ACA_ISRA_o
, ARB_FREE
);
1065 else if (status
& SSB_RESP_INT
) { /* SSB resp. to SRB cmd? */
1066 bus_size_t ssb
= sc
->sc_ssb
;
1068 retcode
= SSB_INB(sc
, ssb
, SSB_RETCODE
);
1069 command
= SSB_INB(sc
, ssb
, SSB_CMD
);
1072 case XMIT_DIR_FRAME
: /* SSB response to SRB xmit cmd */
1073 /* collect status on last packet */
1075 printf("%s: xmit return code = 0x%x\n",
1076 device_xname(&sc
->sc_dev
), retcode
);
1078 if (retcode
== 0x22) {
1079 printf("%s: FS = 0x%2x\n",
1080 device_xname(&sc
->sc_dev
),
1089 ifp
->if_flags
&= ~IFF_OACTIVE
;
1091 * XXX should this be done here ?
1093 /* if data on send queue */
1094 if (IFQ_IS_EMPTY(&ifp
->if_snd
) == 0)
1099 printf("tr_int: xmit XID return code = 0x%x\n",
1103 aprint_error_dev(&sc
->sc_dev
, "SSB error, invalid command =%x\n", command
);
1105 /* clear this interrupt bit */
1106 ACA_RSTB(sc
, ACA_ISRP_o
, ~(SSB_RESP_INT
));
1108 /* tell adapter that SSB is available */
1109 ACA_SETB(sc
, ACA_ISRA_o
, SSB_FREE
);
1111 rc
= 1; /* Claim responsibility for interrupt */
1112 status
= ACA_RDB(sc
, ACA_ISRP_o
);
1114 /* Is this interrupt caused by an adapter error or access violation? */
1115 if (ACA_RDB(sc
, ACA_ISRP_e
) & (TCR_INT
| ERR_INT
| ACCESS_INT
)) {
1116 printf("%s: adapter error, ISRP_e = 0x%x\n",
1117 device_xname(&sc
->sc_dev
), ACA_RDB(sc
, ACA_ISRP_e
));
1119 /* Clear these interrupt bits */
1120 ACA_RSTB(sc
, ACA_ISRP_e
, ~(TCR_INT
| ERR_INT
| ACCESS_INT
));
1121 rc
= 1; /* Claim responsibility for interrupt */
1125 /* Clear IRQ latch in order to reenable interrupts. */
1126 bus_space_write_1(sc
->sc_piot
, sc
->sc_pioh
, TR_CLEARINT
, 0);
1131 int asb_reply_rcv(void)
1135 int asb_reply_xmit(void)
1139 int asb_response(bus_size_t asb
, size_t len
)
1142 answer with RESP_IN_ASB
| ASB_FREE
1152 * U-B receive interrupt.
1154 * in the original version, this routine had three tasks:
1156 * 1. move the data into the receive buffer and set up various pointers
1157 * in the tr_softc struct
1158 * 2. switch on the type field for ip and arp, dropping all else
1159 * 3. resetting the adaptor status block info (asb) and updating the
1161 * determine lan message type, pull packet off interface and
1162 * pass to an appropriate higher-level routine
1166 tr_rint(struct tr_softc
*sc
)
1168 bus_size_t arb
= sc
->sc_arb
;
1169 bus_size_t asb
= sc
->sc_asb
;
1170 struct rbcb
*rbc
= &sc
->rbc
;
1172 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
1175 printf("tr_rint: arb.command = %x, arb.station_id= %x\n",
1176 ARB_INB(sc
, arb
, ARB_CMD
), ARB_INW(sc
, arb
, ARB_STATIONID
));
1177 printf("arb.buf_addr = %x, arb.lan_hdr_len = %x\n",
1178 ARB_INW(sc
, arb
, ARB_RXD_BUFADDR
),
1179 ARB_INB(sc
, arb
, ARB_RXD_LANHDRLEN
));
1180 printf("arb.dlc_hdr_len = %d, arb.frame_len = %d\n",
1181 ARB_INB(sc
, arb
, ARB_RXD_DLCHDRLEN
),
1182 ARB_INW(sc
, arb
, ARB_RXD_FRAMELEN
));
1183 printf("arb.msg_type = %x\n", ARB_INB(sc
, arb
, ARB_RXD_MSGTYPE
));
1184 #endif /* TROPICDEBUG */
1186 * copy the offset in RAM of the first receive buffer from the
1187 * receive-data block of the adapter request block associated
1188 * with the unit's softc struct into the receive control block.
1190 rbc
->rbufp
= ARB_INW(sc
, arb
, ARB_RXD_BUFADDR
);
1193 * copy the pointer to data in first receive buffer
1195 rbc
->rbuf_datap
= rbc
->rbufp
+ RB_DATA
;
1197 * the token-ring header is viewed as two header structs: the physical
1198 * header (aka TR header) with access, frame, dest, src, and routing
1199 * information, and the logical link control header (aka LLC header)
1200 * with dsap, ssap, llc, proto and type fields.
1202 * rfc1042 requires support for unnumbered information (UI) commands,
1203 * but does not specify a required semantic, so we'll discard them.
1208 * if there is a second receive buffer, set up the next pointer
1210 if (RB_INW(sc
, rbc
->rbufp
, RB_NEXTBUF
))
1211 rbc
->rbufp_next
= RB_INW(sc
, rbc
->rbufp
, RB_NEXTBUF
) -
1214 rbc
->rbufp_next
= 0; /* we're finished */
1216 rbc
->data_len
= RB_INW(sc
, rbc
->rbufp
, RB_BUFLEN
);
1218 * At this point we move the packet from the adapter to a chain
1221 m
= tr_get(sc
, ARB_INW(sc
, arb
, ARB_RXD_FRAMELEN
), ifp
);
1223 * XXX Clear ARB interrupt here?
1226 * XXX create a queue where the responses are buffered
1227 * XXX but is it really needed ?
1230 if (ASB_INB(sc
, asb
, RECV_RETCODE
) != 0xff)
1231 printf("tr_rint: ASB IS NOT FREE!!!\n");
1233 * Load receive response into ASB.
1235 ASB_OUTB(sc
, asb
, RECV_CMD
, REC_DATA
);
1236 ASB_OUTW(sc
, asb
, RECV_STATIONID
, ARB_INW(sc
, arb
, ARB_STATIONID
));
1237 ASB_OUTW(sc
, asb
, RECV_RESP_RECBUFADDR
,
1238 ARB_INW(sc
, arb
, ARB_RXD_BUFADDR
));
1242 * Tell adapter data lost, no mbufs.
1244 ASB_OUTB(sc
, asb
, RECV_RETCODE
, 0x20);
1245 ACA_SETB(sc
, ACA_ISRA_o
, RESP_IN_ASB
);
1248 printf("tr_rint: packet dropped\n");
1249 #endif /* TROPICDEBUG */
1253 * Indicate successful receive.
1255 ASB_OUTB(sc
, asb
, RECV_RETCODE
, 0);
1256 ACA_SETB(sc
, ACA_ISRA_o
, RESP_IN_ASB
);
1261 bpf_mtap(ifp
->if_bpf
, m
);
1263 (*ifp
->if_input
)(ifp
, m
);
1268 * Interrupt handler for old style "adapter requires data to transmit".
1271 tr_oldxint(struct tr_softc
*sc
)
1273 bus_size_t arb
= sc
->sc_arb
; /* pointer to ARB */
1274 bus_size_t asb
= sc
->sc_asb
; /* pointer to ASB */
1275 bus_size_t dhb
; /* pointer to DHB */
1276 struct mbuf
*m0
; /* pointer to top of mbuf chain */
1279 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
1280 struct token_header
*trh
;
1285 * XXX xmit_asb_response()
1287 if (ASB_INB(sc
, asb
, XMIT_RETCODE
) != 0xff)
1288 printf("tr_oldxint: ASB IS NOT FREE!!!\n");
1290 /* load parameters into ASB */
1291 ASB_OUTB(sc
, asb
, XMIT_CMDCORR
, ARB_INB(sc
, arb
, ARB_XMT_CMDCORR
));
1292 ASB_OUTW(sc
, asb
, XMIT_STATIONID
, ARB_INW(sc
, arb
, ARB_STATIONID
));
1293 ASB_OUTB(sc
, asb
, XMIT_RETCODE
, 0);
1295 * XXX LLC_{X25,ISO}_LSAP
1297 ASB_OUTB(sc
, asb
, XMIT_REMSAP
, LLC_SNAP_LSAP
);
1299 /* XXX if num_dhb == 2 this should alternate between the two buffers */
1300 dhb
= ARB_INW(sc
, arb
, ARB_XMT_DHBADDR
);
1302 command
= SRB_INB(sc
, sc
->sc_srb
, SRB_CMD
);
1304 if (command
== XMIT_XID_CMD
|| command
== XMIT_TEST_CMD
) {
1305 ASB_OUTB(sc
, asb
, XMIT_CMD
, command
);
1306 ASB_OUTW(sc
, asb
, XMIT_FRAMELEN
, 0x11);
1308 * XXX 0xe == sizeof(struct token_header)
1310 ASB_OUTB(sc
, asb
, XMIT_HDRLEN
, 0x0e);
1312 SR_OUTB(sc
, (dhb
+ 0), TOKEN_AC
);
1313 SR_OUTB(sc
, (dhb
+ 1), TOKEN_FC
);
1314 /* Load destination and source addresses. */
1315 for (i
=0; i
< ISO88025_ADDR_LEN
; i
++) {
1316 SR_OUTB(sc
, (dhb
+ 2 + i
), 0xff);
1317 SR_OUTB(sc
, (dhb
+ 8 + i
), 0x00);
1322 * XXX what's command here ? command = 0x0d (always ?)
1324 /* if data in queue, copy mbuf chain to DHB */
1325 IFQ_DEQUEUE(&ifp
->if_snd
, m0
);
1329 bpf_mtap(ifp
->if_bpf
, m0
);
1331 /* Pull packet off interface send queue, fill DHB. */
1332 trh
= mtod(m0
, struct token_header
*);
1333 hlen
= sizeof(struct token_header
);
1334 if (trh
->token_shost
[0] & TOKEN_RI_PRESENT
) {
1336 * XXX assumes route info is in the same mbuf as the token-ring header
1338 struct token_rif
*rif
;
1340 rif
= TOKEN_RIF(trh
);
1341 hlen
+= ((ntohs(rif
->tr_rcf
) & TOKEN_RCF_LEN_MASK
) >> 8);
1343 size
= tr_mbcopy(sc
, dhb
, m0
);
1346 ASB_OUTB(sc
, asb
, XMIT_CMD
, XMIT_UI_FRM
);
1347 ASB_OUTB(sc
, asb
, XMIT_HDRLEN
, hlen
);
1349 /* Set size of transmission frame in ASB. */
1350 ASB_OUTW(sc
, asb
, XMIT_FRAMELEN
, size
);
1353 aprint_error_dev(&sc
->sc_dev
, "unexpected empty mbuf send queue\n");
1355 /* Set size of transmission frame in ASB to zero. */
1356 ASB_OUTW(sc
, asb
, XMIT_FRAMELEN
, 0);
1360 * XXX asb_response(void *asb, len)
1362 /* tell adapter that there is a response in the ASB */
1363 ACA_SETB(sc
, ACA_ISRA_o
, RESP_IN_ASB
);
1367 * Interrupt handler for fast path transmit complete
1370 tr_xint(struct tr_softc
*sc
)
1373 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
1377 * To prevent race conditions on 8-bit cards when reading or writing
1378 * 16-bit values. See page 4-12 of the IBM manual.
1379 * XXX use volatile ?
1382 tail
= TXCA_INW(sc
, TXCA_COMPLETION_QUEUE_TAIL
);
1383 } while (tail
!= TXCA_INW(sc
, TXCA_COMPLETION_QUEUE_TAIL
));
1384 while (tail
!= TXCA_INW(sc
, TXCA_FREE_QUEUE_TAIL
)) {
1385 txbuf
= TXCA_INW(sc
, TXCA_FREE_QUEUE_TAIL
) - XMIT_NEXTBUF
;
1386 txbuf
= TXB_INW(sc
, txbuf
, XMIT_NEXTBUF
) - XMIT_NEXTBUF
;
1387 if (TXB_INB(sc
, txbuf
, XMIT_RETCODE
) != 0) {
1389 aprint_error_dev(&sc
->sc_dev
, "xmit error = 0x%x\n",
1390 TXB_INB(sc
, txbuf
, XMIT_RETCODE
));
1392 sc
->sc_xmit_buffers
+=
1393 (TXB_INW(sc
, txbuf
, XMIT_FRAMELEN
) + 514 - 1) / 514;
1394 tail
= TXB_INW(sc
, txbuf
, XMIT_LASTBUF
);
1395 TXCA_OUTW(sc
, TXCA_FREE_QUEUE_TAIL
, tail
);
1396 tail
= TXCA_INW(sc
, TXCA_COMPLETION_QUEUE_TAIL
);
1398 tail
= TXCA_INW(sc
, TXCA_COMPLETION_QUEUE_TAIL
);
1399 } while (tail
!= TXCA_INW(sc
, TXCA_COMPLETION_QUEUE_TAIL
));
1401 if (sc
->sc_xmit_buffers
== sc
->sc_nbuf
)
1402 ifp
->if_flags
&= ~IFF_OACTIVE
;
1408 * copy out the packet byte-by-byte in reasonably optimal fashion
1411 tr_mbcopy(struct tr_softc
*sc
, bus_size_t dhb
, struct mbuf
*m0
)
1413 bus_size_t addr
= dhb
;
1418 for (m
= m0
; m
; m
= m
->m_next
) {
1420 ptr
= mtod(m
, char *);
1422 bus_space_write_region_1(sc
->sc_memt
, sc
->sc_sramh
,
1431 * Pull read data off an interface.
1432 * Len is length of data, with local net header stripped.
1433 * Off is non-zero if a trailer protocol was used, and
1434 * gives the offset of the trailer information.
1435 * XXX trailer information, really ????
1436 * We copy the trailer information and then all the normal
1439 * called from tr_rint - receive interrupt routine
1442 tr_get(struct tr_softc
*sc
, int totlen
, struct ifnet
*ifp
)
1445 struct mbuf
*m
, *m0
, *newm
;
1447 MGETHDR(m0
, M_DONTWAIT
, MT_DATA
);
1451 m0
->m_pkthdr
.rcvif
= ifp
;
1452 m0
->m_pkthdr
.len
= totlen
;
1456 while (totlen
> 0) {
1457 if (totlen
>= MINCLSIZE
) {
1458 MCLGET(m
, M_DONTWAIT
);
1459 if ((m
->m_flags
& M_EXT
) == 0) {
1467 * Make sure data after the MAC header is aligned.
1470 char *newdata
= (char *)
1471 ALIGN(m
->m_data
+ sizeof(struct token_header
)) -
1472 sizeof(struct token_header
);
1473 len
-= newdata
- m
->m_data
;
1474 m
->m_data
= newdata
;
1476 m
->m_len
= len
= min(totlen
, len
);
1477 tr_bcopy(sc
, mtod(m
, char *), len
);
1480 MGET(newm
, M_DONTWAIT
, MT_DATA
);
1490 * ignore trailers case again
1497 * tr_ioctl - process an ioctl request
1500 tr_ioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
1502 struct tr_softc
*sc
= ifp
->if_softc
;
1503 struct ifreq
*ifr
= (struct ifreq
*) data
;
1504 struct ifaddr
*ifa
= (struct ifaddr
*) data
;
1511 case SIOCINITIFADDR
:
1512 if ((error
= tr_enable(sc
)) != 0)
1515 /* XXX if not running */
1516 if ((ifp
->if_flags
& IFF_RUNNING
) == 0) {
1517 tr_init(sc
); /* before arp_ifinit/arpwhohas */
1520 switch (ifa
->ifa_addr
->sa_family
) {
1523 arp_ifinit(ifp
, ifa
);
1531 if ((error
= ifioctl_common(ifp
, cmd
, data
)) != 0)
1534 * 1- If the adapter is DOWN , turn the device off
1535 * ie. adapter down but still running
1536 * 2- If the adapter is UP, turn the device on
1537 * ie. adapter up but not running yet
1539 switch (ifp
->if_flags
& (IFF_UP
|IFF_RUNNING
)) {
1542 ifp
->if_flags
&= ~IFF_RUNNING
;
1546 if ((error
= tr_enable(sc
)) != 0)
1553 * XXX handle other flag changes
1560 error
= ifmedia_ioctl(ifp
, ifr
, &sc
->sc_media
, cmd
);
1563 if (ifr
->ifr_mtu
> sc
->sc_maxmtu
)
1565 else if ((error
= ifioctl_common(ifp
, cmd
, data
)) == ENETRESET
)
1569 error
= ifioctl_common(ifp
, cmd
, data
);
1577 * tr_bcopy - like bcopy except that it knows about the structure of
1578 * adapter receive buffers.
1581 tr_bcopy(struct tr_softc
*sc
, u_char
*dest
, int len
)
1582 /* sc: pointer to softc struct for this adapter */
1583 /* dest: destination address */
1584 /* len: number of bytes to copy */
1586 struct rbcb
*rbc
= &sc
->rbc
; /* pointer to rec buf ctl blk */
1588 /* While amount of data needed >= amount in current receive buffer. */
1589 while (len
>= rbc
->data_len
) {
1590 /* Copy all data from receive buffer to destination. */
1592 bus_space_read_region_1(sc
->sc_memt
, sc
->sc_sramh
,
1593 rbc
->rbuf_datap
, dest
, (bus_size_t
)rbc
->data_len
);
1594 len
-= rbc
->data_len
; /* update length left to transfer */
1595 dest
+= rbc
->data_len
; /* update destination address */
1597 /* Make next receive buffer current receive buffer. */
1598 rbc
->rbufp
= rbc
->rbufp_next
;
1599 if (rbc
->rbufp
!= 0) { /* More receive buffers? */
1601 /* Calculate pointer to next receive buffer. */
1602 rbc
->rbufp_next
= RB_INW(sc
, rbc
->rbufp
, RB_NEXTBUF
);
1603 if (rbc
->rbufp_next
!= 0)
1604 rbc
->rbufp_next
-= RB_NEXTBUF
;
1606 /* Get pointer to data in current receive buffer. */
1607 rbc
->rbuf_datap
= rbc
->rbufp
+ RB_DATA
;
1609 /* Get length of data in current receive buffer. */
1610 rbc
->data_len
= RB_INW(sc
, rbc
->rbufp
, RB_BUFLEN
);
1613 if (len
!= 0) /* len should equal zero. */
1614 printf("tr_bcopy: residual data not copied\n");
1619 /* Amount of data needed is < amount in current receive buffer. */
1621 bus_space_read_region_1(sc
->sc_memt
, sc
->sc_sramh
,
1622 rbc
->rbuf_datap
, dest
, (bus_size_t
)len
);
1623 rbc
->data_len
-= len
; /* Update count of data in receive buffer. */
1624 rbc
->rbuf_datap
+= len
; /* Update pointer to receive buffer data. */
1628 * tr_opensap - open the token ring SAP interface
1631 tr_opensap(struct tr_softc
*sc
, u_char type
)
1633 bus_size_t srb
= sc
->sc_srb
;
1635 /************************************************************************
1636 ** To use the SAP level interface, we will have to execute a **
1637 ** DLC.OPEN.SAP (pg.6-61 of the Token Ring Tech. Ref.) after we have **
1638 ** received a good return code from the DIR.OPEN.ADAPTER command. **
1639 ** We will open the IP SAP x'aa'. **
1642 ** 1) Reset SRB response interrupt bit **
1643 ** 2) Use the open_sap srb. **
1644 ** 3) Fill the following fields: **
1645 ** command - x'15' **
1646 ** sap_value - x'aa' **
1647 ** sap_options- x'24' **
1649 ***********************************************************************/
1651 ACA_RSTB(sc
, ACA_ISRP_o
, ~(SRB_RESP_INT
));
1653 SRB_OUTB(sc
, srb
, SRB_CMD
, DLC_OPEN_SAP
);
1654 SRB_OUTB(sc
, srb
, SRB_RETCODE
, 0x00);
1655 SRB_OUTW(sc
, srb
, SRB_OPNSAP_STATIONID
, 0x0000);
1656 SRB_OUTB(sc
, srb
, SRB_OPNSAP_TIMERT1
, 0x00);
1657 SRB_OUTB(sc
, srb
, SRB_OPNSAP_TIMERT2
, 0x00);
1658 SRB_OUTB(sc
, srb
, SRB_OPNSAP_TIMERTI
, 0x00);
1659 SRB_OUTB(sc
, srb
, SRB_OPNSAP_MAXOUT
, 0x00);
1660 SRB_OUTB(sc
, srb
, SRB_OPNSAP_MAXIN
, 0x00);
1661 SRB_OUTB(sc
, srb
, SRB_OPNSAP_MAXOUTINCR
, 0x00);
1662 SRB_OUTB(sc
, srb
, SRB_OPNSAP_MAXRETRY
, 0x00);
1663 SRB_OUTB(sc
, srb
, SRB_OPNSAP_GSAPMAXMEMB
, 0x00);
1664 SRB_OUTW(sc
, srb
, SRB_OPNSAP_MAXIFIELD
, 0x0088);
1665 SRB_OUTB(sc
, srb
, SRB_OPNSAP_SAPVALUE
, type
);
1666 SRB_OUTB(sc
, srb
, SRB_OPNSAP_SAPOPTIONS
, 0x24);
1667 SRB_OUTB(sc
, srb
, SRB_OPNSAP_STATIONCNT
, 0x01);
1668 SRB_OUTB(sc
, srb
, SRB_OPNSAP_SAPGSAPMEMB
, 0x00);
1670 ACA_SETB(sc
, ACA_ISRP_e
, INT_ENABLE
);
1671 ACA_SETB(sc
, ACA_ISRA_o
, CMD_IN_SRB
);
1675 * tr_sleep - sleep to wait for adapter to open
1678 tr_sleep(struct tr_softc
*sc
)
1682 error
= tsleep(&sc
->tr_sleepevent
, 1, "trsleep", hz
* 30);
1683 if (error
== EWOULDBLOCK
)
1684 printf("%s: sleep event timeout\n", device_xname(&sc
->sc_dev
));
1688 tr_watchdog(struct ifnet
*ifp
)
1690 struct tr_softc
*sc
= ifp
->if_softc
;
1692 log(LOG_ERR
,"%s: device timeout\n", device_xname(&sc
->sc_dev
));
1699 tr_enable(struct tr_softc
*sc
)
1701 if (sc
->sc_enabled
== 0 && sc
->sc_enable
!= NULL
) {
1702 if ((*sc
->sc_enable
)(sc
) != 0) {
1703 aprint_error_dev(&sc
->sc_dev
, "device enable failed\n");
1713 tr_disable(struct tr_softc
*sc
)
1715 if (sc
->sc_enabled
!= 0 && sc
->sc_disable
!= NULL
) {
1716 (*sc
->sc_disable
)(sc
);
1722 tr_activate(device_t self
, enum devact act
)
1724 struct tr_softc
*sc
= device_private(self
);
1727 case DVACT_DEACTIVATE
:
1728 if_deactivate(&sc
->sc_ethercom
.ec_if
);
1736 tr_detach(device_t self
, int flags
)
1738 struct tr_softc
*sc
= (struct tr_softc
*)self
;
1739 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
1743 callout_stop(&sc
->sc_init_callout
);
1744 callout_stop(&sc
->sc_reinit_callout
);
1746 /* Delete all remaining media. */
1747 ifmedia_delete_instance(&sc
->sc_media
, IFM_INST_ANY
);
1749 token_ifdetach(ifp
);
1752 shutdownhook_disestablish(sc
->sc_sdhook
);