Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dev / ic / tropic.c
blob8c0c3729074cc51e101c6ffea3ef6be376479294
1 /* $NetBSD: tropic.c,v 1.39 2009/05/12 14:25:18 cegger Exp $ */
3 /*
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
19 * prior permission.
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 $");
39 #include "opt_inet.h"
40 #include "bpfilter.h"
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/callout.h>
45 #include <sys/kernel.h>
46 #include <sys/proc.h>
47 #include <sys/mbuf.h>
48 #include <sys/buf.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>
55 #include <net/if.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>
63 #ifdef INET
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>
69 #endif
72 #if NBPFILTER > 0
73 #include <net/bpf.h>
74 #include <net/bpfdesc.h>
75 #endif
77 #include <sys/cpu.h>
78 #include <sys/bus.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 *);
103 * TODO:
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
108 * XXX happen ?
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)
126 return EINVAL;
128 switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
129 case IFM_TOK_STP16:
130 case IFM_TOK_UTP16:
131 if ((sc->sc_init_status & RSP_16) == 0) {
132 tr_stop(sc);
133 if (tr_setspeed(sc, 16))
134 return EINVAL;
135 if (tr_reset(sc))
136 return EINVAL;
137 if (tr_config(sc))
138 return EINVAL;
140 break;
141 case IFM_TOK_STP4:
142 case IFM_TOK_UTP4:
143 if ((sc->sc_init_status & RSP_16) != 0) {
144 tr_stop(sc);
145 if (tr_setspeed(sc, 4))
146 return EINVAL;
147 if (tr_reset(sc))
148 return EINVAL;
149 if (tr_config(sc))
150 return EINVAL;
152 break;
155 * XXX Handle Early Token Release !!!!
157 return 0;
160 void
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) {
172 int i;
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)
188 break;
189 delay(100);
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");
194 return 1;
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));
203 return 1;
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);
209 else {
210 if (sc->sc_init_status & RSP_16)
211 sc->sc_maxmtu = sc->sc_dhb16maxsz;
212 else
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;
223 return 0;
227 tr_attach(struct tr_softc *sc)
229 int nmedia, *mediaptr, *defmediaptr;
230 int i, temp;
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) {
235 int numbuf = 0;
237 switch (sc->sc_memsize) {
238 case 65536:
239 numbuf = 58;
240 sc->sc_maxmtu = IPMTU_4MBIT_MAX;
241 break;
242 case 32768:
243 numbuf = 29;
244 sc->sc_maxmtu = IPMTU_4MBIT_MAX;
245 break;
246 case 16384:
247 numbuf = 13;
248 sc->sc_maxmtu = IPMTU_4MBIT_MAX;
249 break;
250 case 8192:
251 numbuf = 5;
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 ?
262 else {
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) {
270 case 8192:
271 sc->sc_dhb4maxsz = 2048;
272 sc->sc_dhb16maxsz = 2048;
273 break;
274 case 16384:
275 sc->sc_dhb4maxsz = 4096;
276 sc->sc_dhb16maxsz = 4096;
277 break;
278 case 32768:
279 sc->sc_dhb4maxsz = 4464;
280 sc->sc_dhb16maxsz = 8192;
281 break;
282 case 65536:
283 sc->sc_dhb4maxsz = 4464;
284 sc->sc_dhb16maxsz = 8192;
285 break;
287 switch (MM_INB(sc, TR_DHB4_OFFSET)) {
288 case 0xF:
289 if (sc->sc_dhb4maxsz > 2048)
290 sc->sc_dhb4maxsz = 2048;
291 break;
292 case 0xE:
293 if (sc->sc_dhb4maxsz > 4096)
294 sc->sc_dhb4maxsz = 4096;
295 break;
296 case 0xD:
297 if (sc->sc_dhb4maxsz > 4464)
298 sc->sc_dhb4maxsz = 4464;
299 break;
302 switch (MM_INB(sc, TR_DHB16_OFFSET)) {
303 case 0xF:
304 if (sc->sc_dhb16maxsz > 2048)
305 sc->sc_dhb16maxsz = 2048;
306 break;
307 case 0xE:
308 if (sc->sc_dhb16maxsz > 4096)
309 sc->sc_dhb16maxsz = 4096;
310 break;
311 case 0xD:
312 if (sc->sc_dhb16maxsz > 8192)
313 sc->sc_dhb16maxsz = 8192;
314 break;
315 case 0xC:
316 if (sc->sc_dhb16maxsz > 8192)
317 sc->sc_dhb16maxsz = 8192;
318 break;
319 case 0xB:
320 if (sc->sc_dhb16maxsz > 8192)
321 sc->sc_dhb16maxsz = 8192;
322 break;
326 if (tr_config(sc))
327 return 1;
330 * init network-visible interface
332 strlcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ);
333 ifp->if_softc = sc;
334 ifp->if_ioctl = tr_ioctl;
335 if (sc->sc_init_status & FAST_PATH_TRANSMIT)
336 ifp->if_start = tr_start;
337 else
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)) {
344 case 0xF:
345 nmedia = 1;
346 mediaptr = &media[6];
347 break;
348 case 0xE:
349 nmedia = 2;
350 mediaptr = &media[0];
351 break;
352 case 0xD:
353 nmedia = 1;
354 mediaptr = &media[4];
355 break;
356 default:
357 nmedia = 0;
358 mediaptr = NULL;
361 switch (MM_INB(sc, TR_RATES_OFFSET)) {
362 case 0xF:
363 /* 4 Mbps */
364 break;
365 case 0xE:
366 /* 16 Mbps */
367 if (mediaptr)
368 mediaptr += nmedia;
369 break;
370 case 0xD:
371 /* 4/16 Mbps */
372 nmedia *= 2;
373 break;
376 switch (MM_INB(sc, TR_MEDIA_OFFSET)) {
377 case 0xF:
378 /* STP */
379 defmediaptr = &media[6];
380 break;
381 case 0xE:
382 /* UTP */
383 defmediaptr = &media[4];
384 break;
385 case 0xD:
386 /* STP and UTP == a single shielded RJ45 which supports both */
387 /* XXX additional types in net/if_media.h ?? */
388 defmediaptr = &media[4];
389 break;
390 default:
391 defmediaptr = NULL;
394 if (defmediaptr && (sc->sc_init_status & RSP_16))
395 ++defmediaptr;
397 if (sc->sc_mediachange == NULL && sc->sc_mediastatus == NULL) {
398 switch (MM_INB(sc, TR_TYP_OFFSET)) {
399 case 0x0D:
400 case 0x0C:
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);
410 if (defmediaptr)
411 ifmedia_set(&sc->sc_media, *defmediaptr);
412 else
413 ifmedia_set(&sc->sc_media, 0);
415 else {
416 ifmedia_add(&sc->sc_media, IFM_TOKEN | IFM_MANUAL, 0, NULL);
417 ifmedia_set(&sc->sc_media, IFM_TOKEN | IFM_MANUAL);
420 if_attach(ifp);
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);
436 return 0;
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. */
449 tr_sleep(sc);
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));
454 return 1;
456 return 0;
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));
466 return EINVAL;
469 void
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)
482 int i;
484 sc->sc_srb = 0;
487 * Reset the card.
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)
506 break;
507 delay(100);
510 if (i == 35000 && sc->sc_srb == 0) {
511 aprint_error_dev(&sc->sc_dev, "no response from adapter after reset\n");
512 return 1;
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));
522 return 1;
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));
527 return 1;
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);
538 return 0;
542 * tr_stop - stop interface (issue a DIR.CLOSE.ADAPTER command)
544 void
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;
555 /* Close command. */
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. */
561 tr_sleep(sc);
562 sc->sc_srb = ACA_RDW(sc, ACA_WRBR);
566 static void
567 tr_shutdown(void *arg)
569 struct tr_softc *sc = arg;
571 tr_stop(sc);
574 void
575 tr_reinit(void *arg)
577 struct tr_softc *sc = arg;
578 int s;
580 s = splnet();
581 if (tr_reset(sc) == 0) {
582 if (tr_config(sc) == 0)
583 tr_init(arg);
585 splx(s);
588 static void
589 tr_reopen(void *arg)
591 int s;
593 s = splnet();
594 tr_init(arg);
595 splx(s);
599 * tr_init - initialize network interface, open adapter for packet
600 * - reception and start any pending output
601 * - must be called at splnet
603 void
604 tr_init(void *arg)
606 struct tr_softc *sc = arg;
607 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
608 bus_size_t open_srb;
609 int num_dhb, resvdmem, availmem, dhbsize;
611 if ((ifp->if_flags & IFF_RUNNING) != 0)
612 return;
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;
619 /* Zero SRB. */
620 bus_space_set_region_1(sc->sc_memt, sc->sc_sramh,
621 open_srb, 0, SRB_OPEN_CMDSIZE);
623 /* Open command. */
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);
631 num_dhb = 1;
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;
648 else {
649 dhbsize = sc->sc_dhb4maxsz;
651 #if 0 /* XXXchb unneeded? */
652 if (dhbsize > 2048)
653 num_dhb = 2;
654 #endif
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
659 * requesting DHBs.
661 availmem -= resvdmem;
662 num_dhb = (availmem / dhbsize) - 2;
663 if (num_dhb > 2)
664 num_dhb = 2; /* firmware can't cope with more DHBs */
665 if (num_dhb < 1)
666 num_dhb = 1; /* we need at least one */
668 else
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
683 void
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)
690 return;
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);
700 void
701 tr_start(struct ifnet *ifp)
703 struct tr_softc *sc = ifp->if_softc;
704 bus_size_t first_txbuf, txbuf;
705 struct mbuf *m0, *m;
706 int size, bufspace;
707 bus_size_t framedata;
709 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
710 return;
713 next:
714 if (sc->sc_xmit_buffers < sc->sc_minbuf)
715 return;
717 /* if data in queue, copy mbuf chain to fast path buffers */
718 IFQ_DEQUEUE(&ifp->if_snd, m0);
720 if (m0 == 0)
721 return;
722 #if NBPFILTER > 0
723 if (ifp->if_bpf)
724 bpf_mtap(ifp->if_bpf, m0);
725 #endif
726 first_txbuf = txbuf = TXCA_INW(sc, TXCA_FREE_QUEUE_HEAD) - XMIT_NEXTBUF;
727 framedata = txbuf + XMIT_FP_DATA;
728 size = 0;
729 bufspace = FP_BUF_LEN - XMIT_FP_DATA;
730 for (m = m0; m; m = m->m_next) {
731 int len = m->m_len;
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);
738 size += bufspace;
739 ptr += bufspace;
740 len -= 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;
747 if (len > 0) {
748 bus_space_write_region_1(sc->sc_memt, sc->sc_sramh,
749 framedata, ptr, len);
750 size += len;
751 bufspace -= len;
752 framedata += 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;
781 ifp->if_opackets++;
782 #if 1
783 /* XXX do while construction */
784 goto next;
785 #endif
790 * tr_intr - interrupt handler. Find the cause of the interrupt and
791 * service it.
794 tr_intr(void *arg)
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));
820 tr_xint(sc);
821 rc = 1;
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? */
829 bus_size_t sap_srb;
830 bus_size_t srb;
831 #ifdef TROPICDEBUG
832 bus_size_t log_srb;
833 #endif
834 if (sc->sc_srb == 0)
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);
839 switch (command) {
840 case 0x80: /* 0x80 == initialization complete */
841 case DIR_CONFIG_FAST_PATH_RAM:
842 break;
843 case XMIT_DIR_FRAME: /* Response to xmit request */
844 case XMIT_UI_FRM: /* Response to xmit request */
845 /* Response not valid? */
846 if (retcode != 0xff)
847 aprint_error_dev(&sc->sc_dev, "error on xmit request = "
848 "0x%x\n", retcode);
849 break;
851 case DIR_OPEN_ADAPTER: /* open-adapter-cmd response */
852 /* Open successful? */
853 if (retcode == 0) {
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 =
872 TXCA_INW(sc,
873 TXCA_BUFFER_COUNT);
874 sc->sc_nbuf =
875 sc->sc_xmit_buffers;
876 #ifdef TROPICDEBUG
877 printf("%s: %d buffers\n",
878 device_xname(&sc->sc_dev),
879 sc->sc_xmit_buffers);
880 #endif
881 sc->sc_xmit_correlator = 0;
882 wakeup(&sc->tr_sleepevent);
884 else
885 tr_opensap(sc, LLC_SNAP_LSAP);
887 else {
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);
899 break;
901 case DIR_CLOSE: /* Response to close adapter command */
902 /* Close not successful? */
903 if (retcode != 0)
904 aprint_error_dev(&sc->sc_dev, "close error = 0x%x\n", retcode);
905 else {
906 ifp->if_flags &= ~IFF_RUNNING;
907 ifp->if_flags &= ~IFF_UP;
908 ifp->if_flags &= ~IFF_OACTIVE;
909 wakeup(&sc->tr_sleepevent);
911 break;
912 case DIR_SET_DEFAULT_RING_SPEED:
913 wakeup(&sc->tr_sleepevent);
914 break;
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)
919 == LLC_SNAP_LSAP)
920 sc->exsap_station =
921 SRB_INW(sc, sap_srb,
922 SRB_OPNSAP_STATIONID);
923 printf("%s: Token Ring opened\n",
924 device_xname(&sc->sc_dev));
925 wakeup(&sc->tr_sleepevent);
926 break;
927 /* XXX DLC_CLOSE_SAP not needed ? */
928 case DLC_CLOSE_SAP: /* Response to close sap cmd */
929 break;
930 case DIR_READ_LOG: /* Response to read log */
931 /* Cmd not successful? */
932 if (retcode != 0)
933 aprint_error_dev(&sc->sc_dev, "read error log cmd err = "
934 "0x%x\n", retcode);
935 #ifdef TROPICDEBUG
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;
957 break;
958 default:
959 printf("%s: bad SRB command encountered 0x%x\n",
960 device_xname(&sc->sc_dev), command);
961 break;
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);
979 switch (command) {
980 case REC_DATA: /* Receive */
981 /* Response not valid? */
982 if (retcode != 0xff)
983 aprint_error_dev(&sc->sc_dev, "ASB bad receive response = 0x%x\n", retcode);
984 break;
985 case XMIT_DIR_FRAME: /* Transmit */
986 case XMIT_UI_FRM: /* Transmit */
987 /* Response not valid? */
988 if (retcode != 0xff)
989 aprint_error_dev(&sc->sc_dev, "ASB response err on xmit = 0x%x\n", retcode);
990 break;
991 default:
992 aprint_error_dev(&sc->sc_dev, "invalid command in ASB = 0x%x\n", command);
993 break;
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);
1002 switch (command) {
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));
1007 break;
1008 case REC_DATA: /* Adapter has data for PC */
1009 /* Call receive interrupt handler */
1010 tr_rint(sc);
1011 break;
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);
1023 else {
1024 #ifdef TROPICDEBUG
1025 if (ARB_INW(sc, arb, ARB_RINGSTATUS) &
1026 ~(SOFT_ERR))
1027 printf("%s: ARB new ring status"
1028 " = 0x%x\n",
1029 device_xname(&sc->sc_dev),
1030 ARB_INW(sc, arb,
1031 ARB_RINGSTATUS));
1032 #endif /* TROPICDEBUG */
1034 if (ARB_INW(sc, arb, ARB_RINGSTATUS) &
1035 LOG_OFLOW){
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,
1041 DIR_READ_LOG);
1042 /* Read & reset err log cmnd in SRB. */
1043 ACA_SETB(sc, ACA_ISRA_o, CMD_IN_SRB);
1045 break;
1047 case XMIT_DATA_REQ: /* Adapter wants data to transmit */
1048 /* Call transmit interrupt handler */
1049 tr_oldxint(sc);
1050 break;
1052 default:
1053 aprint_error_dev(&sc->sc_dev, "invalid command in ARB = 0x%x\n", command);
1054 break;
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);
1070 switch (command) {
1071 case XMIT_UI_FRM:
1072 case XMIT_DIR_FRAME: /* SSB response to SRB xmit cmd */
1073 /* collect status on last packet */
1074 if (retcode != 0) {
1075 printf("%s: xmit return code = 0x%x\n",
1076 device_xname(&sc->sc_dev), retcode);
1077 /* XXXchb */
1078 if (retcode == 0x22) {
1079 printf("%s: FS = 0x%2x\n",
1080 device_xname(&sc->sc_dev),
1081 SSB_INB(sc, ssb,
1082 SSB_XMITERR));
1084 ifp->if_oerrors++;
1086 else
1087 ifp->if_opackets++;
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)
1095 tr_oldstart(ifp);
1096 break;
1098 case XMIT_XID_CMD:
1099 printf("tr_int: xmit XID return code = 0x%x\n",
1100 retcode);
1101 break;
1102 default:
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);
1127 return (rc);
1130 #ifdef notyet
1131 int asb_reply_rcv(void)
1135 int asb_reply_xmit(void)
1139 int asb_response(bus_size_t asb, size_t len)
1141 if (empty_queue) {
1142 answer with RESP_IN_ASB | ASB_FREE
1144 else {
1145 put asb in queue
1148 #endif
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
1160 * tr_softc struct
1161 * determine lan message type, pull packet off interface and
1162 * pass to an appropriate higher-level routine
1165 void
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;
1171 struct mbuf *m;
1172 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1174 #ifdef TROPICDEBUG
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) -
1212 RB_NEXTBUF;
1213 else
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
1219 * of mbufs
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));
1240 if (m == 0) {
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);
1246 ++ifp->if_ierrors;
1247 #ifdef TROPICDEBUG
1248 printf("tr_rint: packet dropped\n");
1249 #endif /* TROPICDEBUG */
1251 else {
1253 * Indicate successful receive.
1255 ASB_OUTB(sc, asb, RECV_RETCODE, 0);
1256 ACA_SETB(sc, ACA_ISRA_o, RESP_IN_ASB);
1257 ++ifp->if_ipackets;
1259 #if NBPFILTER > 0
1260 if (ifp->if_bpf)
1261 bpf_mtap(ifp->if_bpf, m);
1262 #endif
1263 (*ifp->if_input)(ifp, m);
1268 * Interrupt handler for old style "adapter requires data to transmit".
1270 void
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 */
1277 u_short size = 0;
1278 char command;
1279 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1280 struct token_header *trh;
1281 int i;
1282 u_int8_t hlen;
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);
1320 else {
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);
1326 if (m0 != 0) {
1327 #if NBPFILTER > 0
1328 if (ifp->if_bpf)
1329 bpf_mtap(ifp->if_bpf, m0);
1330 #endif
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);
1344 m_freem(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);
1352 else {
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
1369 void
1370 tr_xint(struct tr_softc *sc)
1372 u_short tail;
1373 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1374 bus_size_t txbuf;
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 ?
1381 do {
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) {
1388 ifp->if_oerrors++;
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);
1397 do {
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;
1403 tr_start(ifp);
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;
1414 int len, size = 0;
1415 char *ptr;
1416 struct mbuf *m;
1418 for (m = m0; m; m = m->m_next) {
1419 len = m->m_len;
1420 ptr = mtod(m, char *);
1422 bus_space_write_region_1(sc->sc_memt, sc->sc_sramh,
1423 addr, ptr, len);
1424 size += len;
1425 addr += len;
1427 return (size);
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
1437 * data into mbufs.
1439 * called from tr_rint - receive interrupt routine
1441 struct mbuf *
1442 tr_get(struct tr_softc *sc, int totlen, struct ifnet *ifp)
1444 int len;
1445 struct mbuf *m, *m0, *newm;
1447 MGETHDR(m0, M_DONTWAIT, MT_DATA);
1448 if (m0 == 0)
1449 return (0);
1451 m0->m_pkthdr.rcvif = ifp;
1452 m0->m_pkthdr.len = totlen;
1453 len = MHLEN;
1455 m = m0;
1456 while (totlen > 0) {
1457 if (totlen >= MINCLSIZE) {
1458 MCLGET(m, M_DONTWAIT);
1459 if ((m->m_flags & M_EXT) == 0) {
1460 m_free(m0);
1461 return 0;
1463 len = MCLBYTES;
1467 * Make sure data after the MAC header is aligned.
1469 if (m == m0) {
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);
1478 totlen -= len;
1479 if (totlen > 0) {
1480 MGET(newm, M_DONTWAIT, MT_DATA);
1481 if (newm == 0){
1482 m_freem(m0);
1483 return (0);
1485 m->m_next = newm;
1486 m = newm;
1487 len = MLEN;
1490 * ignore trailers case again
1493 return (m0);
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;
1505 int s;
1506 int error = 0;
1508 s = splnet();
1510 switch (cmd) {
1511 case SIOCINITIFADDR:
1512 if ((error = tr_enable(sc)) != 0)
1513 break;
1515 /* XXX if not running */
1516 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1517 tr_init(sc); /* before arp_ifinit/arpwhohas */
1518 tr_sleep(sc);
1520 switch (ifa->ifa_addr->sa_family) {
1521 #ifdef INET
1522 case AF_INET:
1523 arp_ifinit(ifp, ifa);
1524 break;
1525 #endif /*INET*/
1526 default:
1527 break;
1529 break;
1530 case SIOCSIFFLAGS:
1531 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
1532 break;
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)) {
1540 case IFF_RUNNING:
1541 tr_stop(sc);
1542 ifp->if_flags &= ~IFF_RUNNING;
1543 tr_disable(sc);
1544 break;
1545 case IFF_UP:
1546 if ((error = tr_enable(sc)) != 0)
1547 break;
1548 tr_init(sc);
1549 tr_sleep(sc);
1550 break;
1551 default:
1553 * XXX handle other flag changes
1555 break;
1557 break;
1558 case SIOCGIFMEDIA:
1559 case SIOCSIFMEDIA:
1560 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1561 break;
1562 case SIOCSIFMTU:
1563 if (ifr->ifr_mtu > sc->sc_maxmtu)
1564 error = EINVAL;
1565 else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
1566 error = 0;
1567 break;
1568 default:
1569 error = ifioctl_common(ifp, cmd, data);
1571 splx(s);
1572 return (error);
1577 * tr_bcopy - like bcopy except that it knows about the structure of
1578 * adapter receive buffers.
1580 void
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);
1612 else {
1613 if (len != 0) /* len should equal zero. */
1614 printf("tr_bcopy: residual data not copied\n");
1615 return;
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
1630 void
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'. **
1640 ** **
1641 ** STEPS: **
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' **
1648 ** **
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
1677 void
1678 tr_sleep(struct tr_softc *sc)
1680 int error;
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));
1687 void
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));
1693 ++ifp->if_oerrors;
1695 tr_reset(sc);
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");
1704 return (EIO);
1708 sc->sc_enabled = 1;
1709 return (0);
1712 void
1713 tr_disable(struct tr_softc *sc)
1715 if (sc->sc_enabled != 0 && sc->sc_disable != NULL) {
1716 (*sc->sc_disable)(sc);
1717 sc->sc_enabled = 0;
1722 tr_activate(device_t self, enum devact act)
1724 struct tr_softc *sc = device_private(self);
1726 switch (act) {
1727 case DVACT_DEACTIVATE:
1728 if_deactivate(&sc->sc_ethercom.ec_if);
1729 return 0;
1730 default:
1731 return EOPNOTSUPP;
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;
1741 tr_disable(sc);
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);
1750 if_detach(ifp);
1752 shutdownhook_disestablish(sc->sc_sdhook);
1754 return (0);