1 /* $OpenBSD: tropic.c,v 1.8 2004/05/12 06:35:10 tedu Exp $ */
2 /* $NetBSD: tropic.c,v 1.6 1999/12/17 08:26:31 fvdl Exp $ */
3
4 /*
5 * Ported to NetBSD by Onno van der Linden
6 * Many thanks to Larry Lile for sending me the IBM TROPIC documentation.
7 *
8 * Mach Operating System
9 * Copyright (c) 1991 Carnegie Mellon University
10 * Copyright (c) 1991 IBM Corporation
11 * All Rights Reserved.
12 *
13 * Permission to use, copy, modify and distribute this software and its
14 * documentation is hereby granted, provided that both the copyright
15 * notice and this permission notice appear in all copies of the
16 * software, derivative works or modified versions, and any portions
17 * thereof, and that both notices appear in supporting documentation,
18 * and that the name IBM not be used in advertising or publicity
19 * pertaining to distribution of the software without specific, written
20 * prior permission.
21 *
22 * CARNEGIE MELLON AND IBM ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
23 * CONDITION. CARNEGIE MELLON AND IBM DISCLAIM ANY LIABILITY OF ANY KIND FOR
24 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
25 *
26 * Carnegie Mellon requests users of this software to return to
27 *
28 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
29 * School of Computer Science
30 * Carnegie Mellon University
31 * Pittsburgh PA 15213-3890
32 *
33 * any improvements or extensions that they make and grant Carnegie Mellon
34 * the rights to redistribute these changes.
35 */
36
37 #include "bpfilter.h"
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/proc.h>
43 #include <sys/mbuf.h>
44 #include <sys/buf.h>
45 #include <sys/socket.h>
46 #include <sys/syslog.h>
47 #include <sys/ioctl.h>
48 #include <sys/errno.h>
49 #include <sys/device.h>
50 #include <sys/timeout.h>
51
52 #include <net/if.h>
53 #include <net/if_llc.h>
54 #include <net/if_media.h>
55 #include <net/netisr.h>
56 #include <net/route.h>
57
58 #ifdef INET
59 #include <netinet/in.h>
60 #include <netinet/in_systm.h>
61 #include <netinet/if_ether.h>
62 #include <netinet/ip.h>
63 #include <netinet/in_var.h>
64 #include <net/if_token.h>
65 #endif
66
67 #ifdef NS
68 #include <netns/ns.h>
69 #include <netns/ns_if.h>
70 #endif
71
72 #if NBPFILTER > 0
73 #include <net/bpf.h>
74 #endif
75
76 #ifndef ifr_mtu
77 #define ifr_mtu ifr_metric
78 #endif
79
80 #include <machine/cpu.h>
81 #include <machine/bus.h>
82
83 #include <dev/ic/tropicreg.h>
84 #include <dev/ic/tropicvar.h>
85
86 static void tr_shutdown(void *);
87
88 void tr_rint(struct tr_softc *);
89 void tr_xint(struct tr_softc *);
90 void tr_oldxint(struct tr_softc *);
91 struct mbuf *tr_get(struct tr_softc *, int, struct ifnet *);
92 void tr_opensap(struct tr_softc *, u_char);
93 int tr_mbcopy(struct tr_softc *, bus_size_t, struct mbuf *);
94 void tr_bcopy(struct tr_softc *, u_char *, int);
95 void tr_start(struct ifnet *);
96 void tr_oldstart(struct ifnet *);
97 void tr_watchdog(struct ifnet *);
98 int tr_mediachange(struct ifnet *);
99 void tr_mediastatus(struct ifnet *, struct ifmediareq *);
100 int tropic_mediachange(struct tr_softc *);
101 void tropic_mediastatus(struct tr_softc *, struct ifmediareq *);
102 void tr_reinit(void *);
103
104 struct cfdriver tr_cd = {
105 NULL, "tr", DV_IFNET
106 };
107
108 /*
109 * TODO:
110 * clean up tr_intr: more subroutines
111 * IFF_LINK0 == IFM_TOK_SRCRT change to link flag implies media flag change
112 * IFF_LINK1 == IFM_TOK_ALLR change to link flag implies media flag change
113 * XXX Create receive_done queue to kill "ASB not free", but does this ever
114 * XXX happen ?
115 */
116
117 static int media[] = {
118 IFM_TOKEN | IFM_TOK_UTP4,
119 IFM_TOKEN | IFM_TOK_STP4,
120 IFM_TOKEN | IFM_TOK_UTP16,
121 IFM_TOKEN | IFM_TOK_STP16,
122 IFM_TOKEN | IFM_TOK_UTP4,
123 IFM_TOKEN | IFM_TOK_UTP16,
124 IFM_TOKEN | IFM_TOK_STP4,
125 IFM_TOKEN | IFM_TOK_STP16
126 };
127
128 int
tropic_mediachange(sc)129 tropic_mediachange(sc)
130 struct tr_softc *sc;
131 {
132 if (IFM_TYPE(sc->sc_media.ifm_media) != IFM_TOKEN)
133 return EINVAL;
134
135 switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
136 case IFM_TOK_STP16:
137 case IFM_TOK_UTP16:
138 if ((sc->sc_init_status & RSP_16) == 0) {
139 tr_stop(sc);
140 if (tr_setspeed(sc, 16))
141 return EINVAL;
142 if (tr_reset(sc))
143 return EINVAL;
144 if (tr_config(sc))
145 return EINVAL;
146 }
147 break;
148 case IFM_TOK_STP4:
149 case IFM_TOK_UTP4:
150 if ((sc->sc_init_status & RSP_16) != 0) {
151 tr_stop(sc);
152 if (tr_setspeed(sc, 4))
153 return EINVAL;
154 if (tr_reset(sc))
155 return EINVAL;
156 if (tr_config(sc))
157 return EINVAL;
158 }
159 break;
160 }
161 /*
162 * XXX Handle Early Token Release !!!!
163 */
164 return 0;
165 }
166
167 void
tropic_mediastatus(sc,ifmr)168 tropic_mediastatus(sc, ifmr)
169 struct tr_softc *sc;
170 struct ifmediareq *ifmr;
171 {
172 struct ifmedia *ifm = &sc->sc_media;
173
174 ifmr->ifm_active = ifm->ifm_cur->ifm_media;
175 }
176
177 int
tr_config(sc)178 tr_config(sc)
179 struct tr_softc *sc;
180 {
181 if (sc->sc_init_status & FAST_PATH_TRANSMIT) {
182 int i;
183
184 for (i=0; i < SRB_CFP_CMDSIZE; i++)
185 SRB_OUTB(sc, sc->sc_srb, i, 0);
186
187 SRB_OUTB(sc, sc->sc_srb, SRB_CMD, DIR_CONFIG_FAST_PATH_RAM);
188
189 SRB_OUTW(sc, sc->sc_srb, SRB_CFP_RAMSIZE,
190 (16 + (sc->sc_nbuf * FP_BUF_LEN) / 8));
191 SRB_OUTW(sc, sc->sc_srb, SRB_CFP_BUFSIZE, FP_BUF_LEN);
192
193 /* tell adapter: command in SRB */
194 ACA_SETB(sc, ACA_ISRA_o, CMD_IN_SRB);
195
196 for (i = 0; i < 30000; i++) {
197 if (ACA_RDB(sc, ACA_ISRP_o) & SRB_RESP_INT)
198 break;
199 delay(100);
200 }
201
202 if (i == 30000 && sc->sc_srb == ACA_RDW(sc, ACA_WRBR)) {
203 printf("No response for fast path cfg\n");
204 return 1;
205 }
206
207 ACA_RSTB(sc, ACA_ISRP_o, ~(SRB_RESP_INT));
208
209
210 if ((SRB_INB(sc, sc->sc_srb, SRB_RETCODE) != 0)) {
211 printf("cfg fast path returned: %02x\n",
212 SRB_INB(sc, sc->sc_srb, SRB_RETCODE));
213 return 1;
214 }
215
216 sc->sc_txca = SRB_INW(sc, sc->sc_srb, SRB_CFPRESP_FPXMIT);
217 sc->sc_srb = SRB_INW(sc, sc->sc_srb, SRB_CFPRESP_SRBADDR);
218 }
219 else {
220 if (sc->sc_init_status & RSP_16)
221 sc->sc_maxmtu = sc->sc_dhb16maxsz;
222 else
223 sc->sc_maxmtu = sc->sc_dhb4maxsz;
224 /*
225 * XXX Not completely true because Fast Path Transmit has 514 byte buffers
226 * XXX and TR_MAX_LINK_HDR is only correct when source-routing is used.
227 * XXX depending on wether source routing is used change the calculation
228 * XXX use IFM_TOK_SRCRT (IFF_LINK0)
229 * XXX recompute sc_minbuf !!
230 */
231 sc->sc_maxmtu -= TR_MAX_LINK_HDR;
232 }
233 return 0;
234 }
235
236 int
tr_attach(sc)237 tr_attach(sc)
238 struct tr_softc *sc;
239 {
240 int nmedia, *mediaptr, *defmediaptr;
241 int i, temp;
242 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
243
244 if (sc->sc_init_status & FAST_PATH_TRANSMIT) {
245 bus_size_t srb;
246 int nbuf = 0;
247
248 srb = sc->sc_srb;
249
250 switch (sc->sc_memsize) {
251 case 65536:
252 nbuf = 58;
253 sc->sc_maxmtu = IPMTU_4MBIT_MAX;
254 break;
255 case 32768:
256 nbuf = 29;
257 sc->sc_maxmtu = IPMTU_4MBIT_MAX;
258 break;
259 case 16384:
260 nbuf = 13;
261 sc->sc_maxmtu = IPMTU_4MBIT_MAX;
262 break;
263 case 8192:
264 nbuf = 5;
265 sc->sc_maxmtu = ISO88025_MTU;
266 }
267
268 sc->sc_minbuf = ((sc->sc_maxmtu + 511) / 512) + 1;
269 sc->sc_nbuf = nbuf;
270
271 /*
272 * Create circular queues caching the buffer pointers ?
273 */
274 }
275 else {
276 /*
277 * MAX_MACFRAME_SIZE = DHB_SIZE - 6
278 * IPMTU = MAX_MACFRAME_SIZE - (14 + 18 + 8)
279 * (14 = header, 18 = sroute, 8 = llcsnap)
280 */
281
282 switch (sc->sc_memsize) {
283 case 8192:
284 sc->sc_dhb4maxsz = 2048;
285 sc->sc_dhb16maxsz = 2048;
286 break;
287 case 16384:
288 sc->sc_dhb4maxsz = 4096;
289 sc->sc_dhb16maxsz = 4096;
290 break;
291 case 32768:
292 sc->sc_dhb4maxsz = 4464;
293 sc->sc_dhb16maxsz = 8192;
294 break;
295 case 65536:
296 sc->sc_dhb4maxsz = 4464;
297 sc->sc_dhb16maxsz = 8192;
298 break;
299 }
300 switch (MM_INB(sc, TR_DHB4_OFFSET)) {
301 case 0xF:
302 if (sc->sc_dhb4maxsz > 2048)
303 sc->sc_dhb4maxsz = 2048;
304 break;
305 case 0xE:
306 if (sc->sc_dhb4maxsz > 4096)
307 sc->sc_dhb4maxsz = 4096;
308 break;
309 case 0xD:
310 if (sc->sc_dhb4maxsz > 4464)
311 sc->sc_dhb4maxsz = 4464;
312 break;
313 }
314
315 switch (MM_INB(sc, TR_DHB16_OFFSET)) {
316 case 0xF:
317 if (sc->sc_dhb16maxsz > 2048)
318 sc->sc_dhb16maxsz = 2048;
319 break;
320 case 0xE:
321 if (sc->sc_dhb16maxsz > 4096)
322 sc->sc_dhb16maxsz = 4096;
323 break;
324 case 0xD:
325 if (sc->sc_dhb16maxsz > 8192)
326 sc->sc_dhb16maxsz = 8192;
327 break;
328 case 0xC:
329 if (sc->sc_dhb16maxsz > 8192)
330 sc->sc_dhb16maxsz = 8192;
331 break;
332 case 0xB:
333 if (sc->sc_dhb16maxsz > 8192)
334 sc->sc_dhb16maxsz = 8192;
335 break;
336 }
337 }
338
339 if (tr_config(sc))
340 return 1;
341
342 /*
343 * init network-visible interface
344 */
345 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
346 ifp->if_softc = sc;
347 ifp->if_ioctl = tr_ioctl;
348 if (sc->sc_init_status & FAST_PATH_TRANSMIT)
349 ifp->if_start = tr_start;
350 else
351 ifp->if_start = tr_oldstart;
352 ifp->if_flags = IFF_BROADCAST | IFF_NOTRAILERS;
353 ifp->if_watchdog = tr_watchdog;
354 IFQ_SET_READY(&ifp->if_snd);
355
356 switch (MM_INB(sc, TR_MEDIAS_OFFSET)) {
357 case 0xF:
358 nmedia = 1;
359 mediaptr = &media[6];
360 break;
361 case 0xE:
362 nmedia = 2;
363 mediaptr = &media[0];
364 break;
365 case 0xD:
366 nmedia = 1;
367 mediaptr = &media[4];
368 break;
369 default:
370 nmedia = 0;
371 mediaptr = NULL;
372 }
373
374 switch (MM_INB(sc, TR_RATES_OFFSET)) {
375 case 0xF:
376 /* 4 Mbps */
377 break;
378 case 0xE:
379 /* 16 Mbps */
380 if (mediaptr)
381 mediaptr += nmedia;
382 break;
383 case 0xD:
384 /* 4/16 Mbps */
385 nmedia *= 2;
386 break;
387 }
388
389 switch (MM_INB(sc, TR_MEDIA_OFFSET)) {
390 case 0xF:
391 /* STP */
392 defmediaptr = &media[6];
393 break;
394 case 0xE:
395 /* UTP */
396 defmediaptr = &media[4];
397 break;
398 case 0xD:
399 /* STP and UTP == a single shielded RJ45 which supports both */
400 /* XXX additional types in net/if_media.h ?? */
401 defmediaptr = &media[4];
402 break;
403 default:
404 defmediaptr = NULL;
405 }
406
407 if (defmediaptr && (sc->sc_init_status & RSP_16))
408 ++defmediaptr;
409
410 if (sc->sc_mediachange == NULL && sc->sc_mediastatus == NULL) {
411 switch (MM_INB(sc, TR_TYP_OFFSET)) {
412 case 0x0D:
413 case 0x0C:
414 sc->sc_mediachange = tropic_mediachange;
415 sc->sc_mediastatus = tropic_mediastatus;
416 }
417 }
418
419 ifmedia_init(&sc->sc_media, 0, tr_mediachange, tr_mediastatus);
420 if (mediaptr != NULL) {
421 for (i = 0; i < nmedia; i++)
422 ifmedia_add(&sc->sc_media, mediaptr[i], 0, NULL);
423 if (defmediaptr)
424 ifmedia_set(&sc->sc_media, *defmediaptr);
425 else
426 ifmedia_set(&sc->sc_media, 0);
427 }
428 else {
429 ifmedia_add(&sc->sc_media, IFM_TOKEN | IFM_MANUAL, 0, NULL);
430 ifmedia_set(&sc->sc_media, IFM_TOKEN | IFM_MANUAL);
431 }
432
433 if_attach(ifp);
434
435 for (i = 0, temp = 0; i < ISO88025_ADDR_LEN; i++, temp += 4) {
436 sc->sc_arpcom.ac_enaddr[i] =
437 (MM_INB(sc, (TR_MAC_OFFSET + temp)) & 0xf) << 4;
438 sc->sc_arpcom.ac_enaddr[i] |=
439 MM_INB(sc, (TR_MAC_OFFSET + temp + 2)) & 0xf;
440 }
441
442 token_ifattach(ifp);
443
444 printf("\n%s: address %s ring speed %d Mbps\n",
445 sc->sc_dev.dv_xname, token_sprintf(sc->sc_arpcom.ac_enaddr),
446 (sc->sc_init_status & RSP_16) ? 16 : 4);
447
448 #if NBPFILTER > 0
449 bpfattach(&ifp->if_bpf, ifp, DLT_IEEE802, sizeof(struct token_header));
450 #endif
451
452 /*
453 * XXX rnd stuff
454 */
455 shutdownhook_establish(tr_shutdown, sc);
456 return 0;
457 }
458
459 int
tr_setspeed(sc,speed)460 tr_setspeed(sc, speed)
461 struct tr_softc *sc;
462 u_int8_t speed;
463 {
464 SRB_OUTB(sc, sc->sc_srb, SRB_CMD, DIR_SET_DEFAULT_RING_SPEED);
465 SRB_OUTB(sc, sc->sc_srb, CMD_RETCODE, 0xfe);
466 SRB_OUTB(sc, sc->sc_srb, SRB_SET_DEFRSP, speed);
467 /* Tell adapter: command in SRB. */
468 ACA_SETB(sc, ACA_ISRA_o, CMD_IN_SRB);
469
470 /* Wait for it to complete. */
471 tr_sleep(sc);
472
473 if ((SRB_INB(sc, sc->sc_srb, SRB_RETCODE) != 0)) {
474 printf("set default ringspeed returned: %02x\n",
475 SRB_INB(sc, sc->sc_srb, SRB_RETCODE));
476 return 1;
477 }
478 return 0;
479 }
480
481 int
tr_mediachange(ifp)482 tr_mediachange(ifp)
483 struct ifnet *ifp;
484 {
485 struct tr_softc *sc = ifp->if_softc;
486
487 if (sc->sc_mediachange)
488 return ((*sc->sc_mediachange)(sc));
489 return EINVAL;
490 }
491
492 void
tr_mediastatus(ifp,ifmr)493 tr_mediastatus(ifp, ifmr)
494 struct ifnet *ifp;
495 struct ifmediareq *ifmr;
496 {
497 struct tr_softc *sc = ifp->if_softc;
498
499 /* set LINK0 and/or LINK1 */
500 if (sc->sc_mediastatus)
501 (*sc->sc_mediastatus)(sc, ifmr);
502 }
503
504 int
tr_reset(sc)505 tr_reset(sc)
506 struct tr_softc *sc;
507 {
508 int i;
509
510 sc->sc_srb = 0;
511
512 /*
513 * Reset the card.
514 */
515 /* latch on an unconditional adapter reset */
516 bus_space_write_1(sc->sc_piot, sc->sc_pioh, TR_RESET, 0);
517 delay(50000); /* delay 50ms */
518 /*
519 * XXX set paging if we have the right type of card
520 */
521 /* turn off adapter reset */
522 bus_space_write_1(sc->sc_piot, sc->sc_pioh, TR_RELEASE, 0);
523
524 /* Enable interrupts. */
525
526 ACA_SETB(sc, ACA_ISRP_e, INT_ENABLE);
527
528 /* Wait for an answer from the adapter. */
529
530 for (i = 0; i < 35000; i++) {
531 if (ACA_RDB(sc, ACA_ISRP_o) & SRB_RESP_INT)
532 break;
533 delay(100);
534 }
535
536 if (i == 35000 && sc->sc_srb == 0) {
537 printf("No response from adapter after reset\n");
538 return 1;
539 }
540
541 ACA_RSTB(sc, ACA_ISRP_o, ~(SRB_RESP_INT));
542
543 ACA_OUTB(sc, ACA_RRR_e, (sc->sc_maddr >> 12));
544 sc->sc_srb = ACA_RDW(sc, ACA_WRBR);
545 if (SRB_INB(sc, sc->sc_srb, SRB_CMD) != 0x80) {
546 printf("Initialization incomplete, status: %02x\n",
547 SRB_INB(sc, sc->sc_srb, SRB_CMD));
548 return 1;
549 }
550 if (SRB_INB(sc, sc->sc_srb, SRB_INIT_BUC) != 0) {
551 printf("Bring Up Code %02x\n",
552 SRB_INB(sc, sc->sc_srb, SRB_INIT_BUC));
553 return 1;
554 }
555
556 sc->sc_init_status = SRB_INB(sc, sc->sc_srb, SRB_INIT_STATUS);
557
558 sc->sc_xmit_head = sc->sc_xmit_tail = 0;
559
560 /* XXX should depend on sc_resvdmem. */
561 if (MM_INB(sc, TR_RAM_OFFSET) == 0xB && sc->sc_memsize == 65536)
562 for (i = 0; i < 512; i++)
563 SR_OUTB(sc, 0xfe00 + i, 0);
564 return 0;
565 }
566
567 /*
568 * tr_stop - stop interface (issue a DIR CLOSE ADAPTER command)
569 */
570 void
tr_stop(sc)571 tr_stop(sc)
572 struct tr_softc *sc;
573 {
574 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
575
576 if ((ifp->if_flags & IFF_RUNNING) != 0) {
577 /*
578 * transmitter cannot be used from now on
579 */
580 ifp->if_flags |= IFF_OACTIVE;
581
582 /* Close command. */
583 SRB_OUTB(sc, sc->sc_srb, SRB_CMD, DIR_CLOSE);
584 /* Tell adapter: command in SRB. */
585 ACA_SETB(sc, ACA_ISRA_o, CMD_IN_SRB);
586
587 /* Wait for it to complete. */
588 tr_sleep(sc);
589 sc->sc_srb = ACA_RDW(sc, ACA_WRBR);
590 }
591 }
592
593 static void
tr_shutdown(arg)594 tr_shutdown(arg)
595 void *arg;
596 {
597 struct tr_softc *sc = arg;
598
599 tr_stop(sc);
600 }
601
602 void
tr_reinit(arg)603 tr_reinit(arg)
604 void *arg;
605 {
606 if (tr_reset((struct tr_softc *) arg))
607 return;
608 if (tr_config((struct tr_softc *) arg))
609 return;
610 tr_init(arg);
611 }
612
613 /*
614 * tr_init - initialize network interface, open adapter for packet
615 * reception and start any pending output
616 */
617 void
tr_init(arg)618 tr_init(arg)
619 void *arg;
620 {
621 struct tr_softc *sc = arg;
622 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
623 bus_size_t open_srb;
624 int s, num_dhb;
625 int resvdmem, availmem, dhbsize;
626
627 if ((ifp->if_flags & IFF_RUNNING) != 0)
628 return;
629
630 s = splimp();
631
632 ifp->if_flags &= ~IFF_OACTIVE;
633 sc->sc_xmit_head = sc->sc_xmit_tail = 0; /* XXX tr_reset() */
634
635 open_srb = sc->sc_srb;
636
637 /* Zero SRB. */
638 bus_space_set_region_1(sc->sc_memt, sc->sc_sramh,
639 open_srb, 0, SRB_OPEN_CMDSIZE);
640
641 /* Open command. */
642 SRB_OUTB(sc, open_srb, SRB_CMD, DIR_OPEN_ADAPTER);
643 /*
644 * XXX handle IFM_TOK_ETR !!!!
645 */
646 /* Set open parameters in SRB. */
647 SRB_OUTW(sc, open_srb, SRB_OPEN_OPTIONS, OPEN_PASS_BCON_MAC);
648
649 num_dhb = 1;
650
651 if ((sc->sc_init_status & FAST_PATH_TRANSMIT) == 0) {
652 availmem = sc->sc_memsize;
653 resvdmem = RESVDMEM_SIZE + sc->sc_memreserved;
654
655 /* allow MAX of two SAPS */
656 SRB_OUTB(sc, open_srb, SRB_OPEN_DLCMAXSAP, 2);
657 resvdmem += 2 * SAPCB_SIZE;
658
659 /* allow MAX of 4 stations */
660 SRB_OUTB(sc, open_srb, SRB_OPEN_DLCMAXSTA, 4);
661 resvdmem += 4 * LSCB_SIZE;
662
663 if (sc->sc_init_status & RSP_16) {
664 dhbsize = sc->sc_dhb16maxsz;
665 }
666 else {
667 dhbsize = sc->sc_dhb4maxsz;
668 }
669 #if 0 /* XXXchb unneeded? */
670 if (dhbsize > 2048)
671 num_dhb = 2;
672 #endif
673 SRB_OUTW(sc, open_srb, SRB_OPEN_DHBLEN, dhbsize);
674 sc->sc_nbuf = (dhbsize + 511) / 512;
675 /*
676 * Try to leave room for two fullsized packets when
677 * requesting DHBs.
678 */
679 availmem -= resvdmem;
680 num_dhb = (availmem / dhbsize) - 2;
681 if (num_dhb > 2)
682 num_dhb = 2; /* firmware can't cope with more DHBs */
683 if (num_dhb < 1)
684 num_dhb = 1; /* we need at least one */
685 }
686 else
687 SRB_OUTW(sc, open_srb, SRB_OPEN_DHBLEN, DHB_LENGTH);
688
689 SRB_OUTB(sc, open_srb, SRB_OPEN_NUMDHB, num_dhb);
690 SRB_OUTW(sc, open_srb, SRB_OPEN_RCVBUFLEN, RCV_BUF_LEN);
691 SRB_OUTW(sc, open_srb, SRB_OPEN_NUMRCVBUF, sc->sc_nbuf);
692
693 /* Tell adapter: command in SRB. */
694 ACA_SETB(sc, ACA_ISRA_o, CMD_IN_SRB);
695
696 splx(s);
697 }
698
699 /*
700 * tr_oldstart - Present transmit request to adapter
701 */
702 void
tr_oldstart(ifp)703 tr_oldstart(ifp)
704 struct ifnet *ifp;
705 {
706 struct tr_softc *sc = ifp->if_softc;
707 bus_size_t srb = sc->sc_srb;
708
709 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
710 return;
711
712 ifp->if_flags |= IFF_OACTIVE;
713
714 /* Load SRB to request transmit. */
715 SRB_OUTB(sc, srb, SRB_CMD, XMIT_UI_FRM);
716 SRB_OUTW(sc, srb, XMIT_STATIONID, sc->exsap_station);
717 ACA_SETB(sc, ACA_ISRA_o, CMD_IN_SRB);
718 }
719
720 void
tr_start(ifp)721 tr_start(ifp)
722 struct ifnet *ifp;
723 {
724 struct tr_softc *sc = ifp->if_softc;
725 bus_size_t first_txbuf, txbuf;
726 struct mbuf *m0, *m;
727 int size, bufspace;
728 bus_size_t framedata;
729
730 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
731 return;
732
733
734 next:
735 if (sc->sc_xmit_buffers < sc->sc_minbuf)
736 return;
737
738 /* if data in queue, copy mbuf chain to fast path buffers */
739 IFQ_DEQUEUE(&ifp->if_snd, m0);
740
741 if (m0 == 0)
742 return;
743 #if NBPFILTER > 0
744 if (ifp->if_bpf)
745 bpf_mtap(ifp->if_bpf, m0);
746 #endif
747 first_txbuf = txbuf = TXCA_INW(sc, TXCA_FREE_QUEUE_HEAD) - XMIT_NEXTBUF;
748 framedata = txbuf + XMIT_FP_DATA;
749 size = 0;
750 bufspace = FP_BUF_LEN - XMIT_FP_DATA;
751 --sc->sc_xmit_buffers;
752 for (m = m0; m; m = m->m_next) {
753 int len = m->m_len;
754 char *ptr = mtod(m, char *);
755
756 while (len >= bufspace) {
757 --sc->sc_xmit_buffers;
758 bus_space_write_region_1(sc->sc_memt, sc->sc_sramh,
759 framedata, ptr, bufspace);
760 size += bufspace;
761 ptr += bufspace;
762 len -= bufspace;
763 TXB_OUTW(sc, txbuf, XMIT_BUFLEN,
764 (FP_BUF_LEN - XMIT_FP_DATA));
765 txbuf = TXB_INW(sc, txbuf, XMIT_NEXTBUF) - XMIT_NEXTBUF;
766 framedata = txbuf + XMIT_FP_DATA;
767 bufspace = FP_BUF_LEN - XMIT_FP_DATA;
768 }
769 if (len > 0) {
770 bus_space_write_region_1(sc->sc_memt, sc->sc_sramh,
771 framedata, ptr, len);
772 size += len;
773 bufspace -= len;
774 framedata += len;
775 }
776 }
777 TXB_OUTW(sc, txbuf, XMIT_BUFLEN, (FP_BUF_LEN - XMIT_FP_DATA - bufspace));
778 m_freem(m0); /* free mbuf chain */
779
780 TXB_OUTB(sc, first_txbuf, XMIT_RETCODE, 0xfe);
781 TXB_OUTW(sc, first_txbuf, XMIT_FRAMELEN, size);
782 TXB_OUTW(sc, first_txbuf, XMIT_LASTBUF, (txbuf + XMIT_NEXTBUF));
783 TXB_OUTB(sc, first_txbuf, XMIT_CMD, XMIT_DIR_FRAME);
784 TXB_OUTW(sc, first_txbuf, XMIT_STATIONID, 0);
785 TXB_OUTB(sc, first_txbuf, XMIT_CMDCORR, sc->sc_xmit_correlator);
786 sc->sc_xmit_correlator = (sc->sc_xmit_correlator + 1) & 0x7f;
787
788 /*
789 * To prevent race conditions on 8-bit cards when reading or writing
790 * 16-bit values. See page 4-12 of the IBM manual.
791 */
792 TXCA_OUTW(sc, TXCA_FREE_QUEUE_HEAD, 1);
793 TXCA_OUTW(sc, TXCA_FREE_QUEUE_HEAD, TXB_INW(sc, txbuf, XMIT_NEXTBUF));
794
795 ACA_SETB(sc, ACA_ISRA_o, XMIT_REQ);
796
797 ifp->if_flags |= IFF_OACTIVE;
798 ifp->if_opackets++;
799 #if 1
800 /* XXX do while construction */
801 goto next;
802 #endif
803 }
804
805 /*
806 * tr_intr - interrupt handler. Find the cause of the interrupt and
807 * service it.
808 */
809 int
tr_intr(arg)810 tr_intr(arg)
811 void *arg;
812 {
813 struct tr_softc *sc = arg;
814 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
815 u_char status; /* holds status from adapter status register */
816 u_char command; /* holds command from status or request block */
817 u_char retcode; /* holds return value from status or request block */
818 int rc = 0; /* 0 = unclaimed interrupt, 1 = interrupt claimed */
819
820 status = ACA_RDB(sc, ACA_ISRP_o);
821 while (status != 0) {
822
823 /* Is this interrupt caused by an adapter check? */
824 if (status & ADAP_CHK_INT) {
825 printf("%s: adapter check 0x%04x\n",
826 sc->sc_dev.dv_xname,
827 (unsigned int)ntohs(ACA_RDW(sc, ACA_WWCR)));
828
829 /* Clear this interrupt bit */
830 ACA_RSTB(sc, ACA_ISRP_o, ~(ADAP_CHK_INT));
831
832 rc = 1; /* Claim interrupt. */
833 break; /* Terminate loop. */
834 }
835 else if (status & XMIT_COMPLETE) {
836 ACA_RSTB(sc, ACA_ISRP_o, ~(XMIT_COMPLETE));
837 tr_xint(sc);
838 rc = 1;
839 }
840
841 /*
842 * Process SRB_RESP_INT, ASB_FREE_INT, ARB_CMD_INT
843 * & SSB_RESP_INT in that order, ISRP-L Hi to Lo
844 */
845 else if (status & SRB_RESP_INT) { /* Adapter response in SRB? */
846 bus_size_t sap_srb;
847 bus_size_t srb;
848 #ifdef TROPICDEBUG
849 bus_size_t log_srb;
850 #endif
851 if (sc->sc_srb == 0)
852 sc->sc_srb = ACA_RDW(sc, ACA_WRBR);
853 srb = sc->sc_srb; /* pointer to SRB */
854 retcode = SRB_INB(sc, srb, SRB_RETCODE);
855 command = SRB_INB(sc, srb, SRB_CMD);
856 switch (command) {
857 case 0x80: /* 0x80 == initialization complete */
858 case DIR_CONFIG_FAST_PATH_RAM:
859 break;
860 case XMIT_DIR_FRAME: /* Response to xmit request */
861 case XMIT_UI_FRM: /* Response to xmit request */
862 /* Response not valid? */
863 if (retcode != 0xff)
864 printf("%s: error on xmit request =%x\n",
865 sc->sc_dev.dv_xname, retcode);
866 break;
867
868 case DIR_OPEN_ADAPTER: /* open-adapter-cmd response */
869 /* Open successful? */
870 if (retcode == 0) {
871 ifp->if_flags |= IFF_UP | IFF_RUNNING;
872 /* Save new ACA ctrl block addresses */
873 sc->sc_ssb = SRB_INW(sc, srb,
874 SRB_OPENRESP_SSBADDR);
875 sc->sc_arb = SRB_INW(sc, srb,
876 SRB_OPENRESP_ARBADDR);
877 sc->sc_srb = SRB_INW(sc, srb,
878 SRB_OPENRESP_SRBADDR);
879 sc->sc_asb = SRB_INW(sc, srb,
880 SRB_OPENRESP_ASBADDR);
881
882 /*
883 * XXX, what about LLC_{X25,ISO}_LSAP ?
884 * open two more saps .....
885 */
886 if (sc->sc_init_status &
887 FAST_PATH_TRANSMIT) {
888 sc->sc_xmit_buffers =
889 TXCA_INW(sc, TXCA_BUFFER_COUNT);
890 sc->sc_nbuf =
891 sc->sc_xmit_buffers;
892 #ifdef TROPICDEBUG
893 printf("buffers = %d\n",
894 sc->sc_xmit_buffers);
895 #endif
896 sc->sc_xmit_correlator = 0;
897 wakeup(&sc->tr_sleepevent);
898 }
899 else
900 tr_opensap(sc, LLC_SNAP_LSAP);
901 }
902 else {
903 printf("%s: Open error = %x\n",
904 sc->sc_dev.dv_xname,
905 SRB_INB(sc, srb, SRB_RETCODE));
906 ifp->if_flags &= ~IFF_RUNNING;
907 ifp->if_flags &= ~IFF_UP;
908 /*
909 * XXX untimeout depending on the error, timeout in other cases
910 * XXX error 0x24 && autospeed mode: open again !!!!
911 */
912 if (!timeout_initialized(&sc->init_timeout))
913 timeout_set(&sc->init_timeout,
914 tr_init, sc);
915 timeout_add(&sc->init_timeout, hz * 30);
916 }
917 break;
918
919 case DIR_CLOSE: /* Response to close adapter command */
920 /* Close not successful? */
921 if (retcode != 0)
922 printf("%s: close error = %x\n",
923 sc->sc_dev.dv_xname, retcode);
924 else {
925 ifp->if_flags &= ~IFF_RUNNING;
926 ifp->if_flags &= ~IFF_UP;
927 ifp->if_flags &= ~IFF_OACTIVE;
928 wakeup(&sc->tr_sleepevent);
929 }
930 break;
931 case DIR_SET_DEFAULT_RING_SPEED:
932 wakeup(&sc->tr_sleepevent);
933 break;
934
935 case DLC_OPEN_SAP: /* Response to open sap cmd */
936 sap_srb = sc->sc_srb;
937 if (SRB_INB(sc, sap_srb, SRB_OPNSAP_SAPVALUE)
938 == LLC_SNAP_LSAP)
939 sc->exsap_station =
940 SRB_INW(sc, sap_srb,
941 SRB_OPNSAP_STATIONID);
942 printf("%s: Token Ring opened\n",
943 sc->sc_dev.dv_xname);
944 wakeup(&sc->tr_sleepevent);
945 break;
946 /* XXX DLC_CLOSE_SAP not needed ? */
947 case DLC_CLOSE_SAP: /* Response to close sap cmd */
948 break;
949 case DIR_READ_LOG: /* Response to read log */
950 /* Cmd not successful? */
951 if (retcode != 0)
952 printf("%s: read error log cmd err =%x\n",
953 sc->sc_dev.dv_xname, retcode);
954 #ifdef TROPICDEBUG
955 log_srb = sc->sc_srb;
956 printf("%s: ERROR LOG:\n",sc->sc_dev.dv_xname);
957 printf("%s: Line=%d, Internal=%d, Burst=%d\n",
958 sc->sc_dev.dv_xname,
959 (SRB_INB(sc, log_srb, SRB_LOG_LINEERRS)),
960 (SRB_INB(sc, log_srb, SRB_LOG_INTERRS)),
961 (SRB_INB(sc, log_srb, SRB_LOG_BRSTERRS)));
962 printf("%s: A/C=%d, Abort=%d, Lost frames=%d\n",
963 sc->sc_dev.dv_xname,
964 (SRB_INB(sc, log_srb, SRB_LOG_ACERRS)),
965 (SRB_INB(sc, log_srb, SRB_LOG_ABRTERRS)),
966 (SRB_INB(sc, log_srb, SRB_LOG_LOSTFRMS)));
967 printf("%s: Receive congestion=%d, Frame copied=%d, Frequency=%d\n",
968 sc->sc_dev.dv_xname,
969 (SRB_INB(sc, log_srb, SRB_LOG_RCVCONG)),
970 (SRB_INB(sc, log_srb, SRB_LOG_FCPYERRS)),
971 (SRB_INB(sc, log_srb, SRB_LOG_FREQERRS)));
972 printf("%s: Token=%d\n",sc->sc_dev.dv_xname,
973 (SRB_INB(sc, log_srb, SRB_LOG_TOKENERRS)));
974 #endif /* TROPICDEBUG */
975 ifp->if_flags &= ~IFF_OACTIVE;
976 break;
977 default:
978 printf("%s: bad SRB command encountered %x\n",
979 sc->sc_dev.dv_xname, command);
980 break;
981 }
982 /* clear the SRB-response interrupt bit */
983 ACA_RSTB(sc, ACA_ISRP_o, ~(SRB_RESP_INT));
984
985 }
986
987 else if (status & ASB_FREE_INT) { /* Is ASB Free? */
988 bus_size_t asb = sc->sc_asb;
989
990 /*
991 * Remove message from asb queue, first element in
992 * structure is the command. command == REC_DATA?
993 * size = 8 : size = 10
994 * reply in isra_l with (RESP_IN_ASB | ASB_FREE)
995 */
996 retcode = ASB_INB(sc, asb, CMD_RETCODE);
997 command = ASB_INB(sc, asb, CMD_CMD);
998 switch (command) {
999 case REC_DATA: /* Receive */
1000 /* Response not valid? */
1001 if (retcode != 0xff)
1002 printf("%s: ASB bad receive response =%x\n",
1003 sc->sc_dev.dv_xname, retcode);
1004 break;
1005 case XMIT_DIR_FRAME: /* Transmit */
1006 case XMIT_UI_FRM: /* Transmit */
1007 /* Response not valid? */
1008 if (retcode != 0xff)
1009 printf("%s: ASB response err on xmit =%x\n",
1010 sc->sc_dev.dv_xname, retcode);
1011 break;
1012 default:
1013 printf("%s: Invalid command in ASB =%x\n",
1014 sc->sc_dev.dv_xname, command);
1015 break;
1016 }
1017 /* Clear this interrupt bit */
1018 ACA_RSTB(sc, ACA_ISRP_o, ~(ASB_FREE_INT));
1019 }
1020 else if (status & ARB_CMD_INT) { /* Command for PC to handle? */
1021 bus_size_t arb = sc->sc_arb;
1022
1023 command = ARB_INB(sc, arb, ARB_CMD);
1024 switch (command) {
1025 case DLC_STATUS: /* DLC status change */
1026 printf("%s: ARB new DLC status = 0x%x\n",
1027 sc->sc_dev.dv_xname,
1028 ARB_INW(sc, arb, ARB_DLCSTAT_STATUS));
1029 break;
1030 case REC_DATA: /* Adapter has data for PC */
1031 /* Call receive interrupt handler */
1032 tr_rint(sc);
1033 break;
1034
1035 case RING_STAT_CHANGE: /* Ring status change */
1036 if (ARB_INW(sc, arb, ARB_RINGSTATUS) &
1037 (SIGNAL_LOSS + LOBE_FAULT)){
1038 printf("%s: SIGNAL LOSS/LOBE FAULT\n",
1039 sc->sc_dev.dv_xname);
1040 ifp->if_flags &= ~IFF_RUNNING;
1041 ifp->if_flags &= ~IFF_UP;
1042 IFQ_PURGE(&ifp->if_snd);
1043 if (!timeout_initialized(&sc->reinit_timeout))
1044 timeout_set(&sc->reinit_timeout,
1045 tr_reinit, sc);
1046 timeout_add(&sc->reinit_timeout, hz * 30);
1047 }
1048 else {
1049 #ifdef TROPICDEBUG
1050 if (ARB_INW(sc, arb, ARB_RINGSTATUS) &
1051 ~(SOFT_ERR))
1052 printf(
1053 "%s: ARB new ring status = 0x%x\n",
1054 sc->sc_dev.dv_xname,
1055 ARB_INW(sc, arb,
1056 ARB_RINGSTATUS));
1057 #endif /* TROPICDEBUG */
1058 }
1059 if (ARB_INW(sc, arb, ARB_RINGSTATUS) &
1060 LOG_OFLOW){
1061 /*
1062 * XXX CMD_IN_SRB, handle with SRB_FREE_INT ?
1063 */
1064 ifp->if_flags |= IFF_OACTIVE;
1065 SRB_OUTB(sc, sc->sc_srb, SRB_CMD,
1066 DIR_READ_LOG);
1067 /* Read & reset err log cmnd in SRB. */
1068 ACA_SETB(sc, ACA_ISRA_o, CMD_IN_SRB);
1069 }
1070 break;
1071
1072 case XMIT_DATA_REQ: /* Adapter wants data to transmit */
1073 /* Call transmit interrupt handler */
1074 tr_oldxint(sc);
1075 break;
1076
1077 default:
1078 printf("%s: Invalid command in ARB =%x\n",
1079 sc->sc_dev.dv_xname, command);
1080 break;
1081 }
1082
1083 /* Clear this interrupt bit */
1084 ACA_RSTB(sc, ACA_ISRP_o, ~(ARB_CMD_INT));
1085
1086 /* Tell adapter that ARB is now free */
1087 ACA_SETB(sc, ACA_ISRA_o, ARB_FREE);
1088 }
1089
1090
1091 else if (status & SSB_RESP_INT) { /* SSB resp. to SRB cmd? */
1092 bus_size_t ssb = sc->sc_ssb;
1093
1094 retcode = SSB_INB(sc, ssb, SSB_RETCODE);
1095 command = SSB_INB(sc, ssb, SSB_CMD);
1096 switch (command) {
1097 case XMIT_UI_FRM:
1098 case XMIT_DIR_FRAME: /* SSB response to SRB xmit cmd */
1099 /* collect status on last packet */
1100 if (retcode != 0) {
1101 printf("xmit return code = 0x%x\n",
1102 retcode);
1103 /* XXXchb */
1104 if (retcode == 0x22) {
1105 printf("FS = 0x%2x\n",
1106 SSB_INB(sc, ssb,
1107 SSB_XMITERR));
1108 }
1109 ifp->if_oerrors++;
1110 }
1111 else
1112 ifp->if_opackets++;
1113
1114 ifp->if_flags &= ~IFF_OACTIVE;
1115 /*
1116 * XXX should this be done here ?
1117 */
1118 /* if data on send queue */
1119 if (!IFQ_IS_EMPTY(&ifp->if_snd))
1120 tr_oldstart(ifp);
1121 break;
1122
1123 case XMIT_XID_CMD:
1124 printf("tr_int: xmit XID return code = 0x%x\n",
1125 retcode);
1126 break;
1127 default:
1128 printf("%s: SSB error, invalid command =%x\n",
1129 sc->sc_dev.dv_xname, command);
1130 }
1131 /* clear this interrupt bit */
1132 ACA_RSTB(sc, ACA_ISRP_o, ~(SSB_RESP_INT));
1133
1134 /* tell adapter that SSB is available */
1135 ACA_SETB(sc, ACA_ISRA_o, SSB_FREE);
1136 }
1137 rc = 1; /* Claim responsibility for interrupt */
1138 status = ACA_RDB(sc, ACA_ISRP_o);
1139 }
1140 /* Is this interrupt caused by an adapter error or access violation? */
1141 if (ACA_RDB(sc, ACA_ISRP_e) & (TCR_INT | ERR_INT | ACCESS_INT)) {
1142 printf("%s: adapter error, ISRP_e = %x\n",
1143 sc->sc_dev.dv_xname, ACA_RDB(sc, ACA_ISRP_e));
1144
1145 /* Clear these interrupt bits */
1146 ACA_RSTB(sc, ACA_ISRP_e, ~(TCR_INT | ERR_INT | ACCESS_INT));
1147 rc = 1; /* Claim responsibility for interrupt */
1148
1149 }
1150
1151 /* Clear IRQ latch in order to reenable interrupts. */
1152 bus_space_write_1(sc->sc_piot, sc->sc_pioh, TR_CLEARINT, 0);
1153 return (rc);
1154 }
1155
1156 #ifdef notyet
asb_reply_rcv()1157 int asb_reply_rcv()
1158 {
1159 }
1160
asb_reply_xmit()1161 int asb_reply_xmit()
1162 {
1163 }
1164
asb_response(bus_size_t asb,size_t len)1165 int asb_response(bus_size_t asb, size_t len)
1166 {
1167 if (empty_queue) {
1168 answer with RESP_IN_ASB | ASB_FREE
1169 }
1170 else {
1171 put asb in queue
1172 }
1173 }
1174 #endif
1175
1176
1177 /*
1178 * U-B receive interrupt.
1179 *
1180 * in the original version, this routine had three tasks:
1181 *
1182 * 1. move the data into the receive buffer and set up various pointers
1183 * in the tr_softc struct
1184 * 2. switch on the type field for ip and arp, dropping all else
1185 * 3. resetting the adaptor status block info (asb) and updating the
1186 * tr_softc struct
1187 * determine lan message type, pull packet off interface and
1188 * pass to an appropriate higher-level routine
1189 *
1190 */
1191 void
tr_rint(sc)1192 tr_rint(sc)
1193 struct tr_softc *sc;
1194 {
1195 bus_size_t arb = sc->sc_arb;
1196 bus_size_t asb = sc->sc_asb;
1197 struct rbcb *rbc = &sc->rbc;
1198 struct mbuf *m;
1199 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1200
1201 #ifdef TROPICDEBUG
1202 printf("tr_rint: arb.command = %x, arb.station_id= %x\n",
1203 ARB_INB(sc, arb, ARB_CMD), ARB_INW(sc, arb, ARB_STATIONID));
1204 printf("arb.buf_addr = %x, arb.lan_hdr_len = %x\n",
1205 ARB_INW(sc, arb, ARB_RXD_BUFADDR),
1206 ARB_INB(sc, arb, ARB_RXD_LANHDRLEN));
1207 printf("arb.dlc_hdr_len = %d, arb.frame_len = %d\n",
1208 ARB_INB(sc, arb, ARB_RXD_DLCHDRLEN),
1209 ARB_INW(sc, arb, ARB_RXD_FRAMELEN));
1210 printf("arb.msg_type = %x\n", ARB_INB(sc, arb, ARB_RXD_MSGTYPE));
1211 #endif /* TROPICDEBUG */
1212 /*
1213 * copy the offset in RAM of the first receive buffer from the
1214 * receive-data block of the adapter request block associated
1215 * with the unit's softc struct into the receive control block.
1216 */
1217 rbc->rbufp = ARB_INW(sc, arb, ARB_RXD_BUFADDR);
1218
1219 /*
1220 * copy the pointer to data in first receive buffer
1221 */
1222 rbc->rbuf_datap = rbc->rbufp + RB_DATA;
1223 /*
1224 * the token-ring header is viewed as two header structs: the physical
1225 * header (aka TR header) with access, frame, dest, src, and routing
1226 * information, and the logical link control header (aka LLC header)
1227 * with dsap, ssap, llc, proto and type fields.
1228 *
1229 * rfc1042 requires support for unnumbered information (UI) commands,
1230 * but does not specify a required semantic, so we'll discard them.
1231 *
1232 */
1233
1234 /*
1235 * if there is a second receive buffer, set up the next pointer
1236 */
1237 if (RB_INW(sc, rbc->rbufp, RB_NEXTBUF))
1238 rbc->rbufp_next = RB_INW(sc, rbc->rbufp, RB_NEXTBUF) -
1239 RB_NEXTBUF;
1240 else
1241 rbc->rbufp_next = 0; /* we're finished */
1242
1243 rbc->data_len = RB_INW(sc, rbc->rbufp, RB_BUFLEN);
1244 /*
1245 * At this point we move the packet from the adapter to a chain
1246 * of mbufs
1247 */
1248 m = tr_get(sc, ARB_INW(sc, arb, ARB_RXD_FRAMELEN), ifp);
1249 /*
1250 * XXX Clear ARB interrupt here?
1251 */
1252 /*
1253 * XXX create a queue where the responses are buffered
1254 * XXX but is it really needed ?
1255 */
1256
1257 if (ASB_INB(sc, asb, RECV_RETCODE) != 0xff)
1258 printf("tr_rint: ASB IS NOT FREE!!!\n");
1259 /*
1260 * Load receive response into ASB.
1261 */
1262 ASB_OUTB(sc, asb, RECV_CMD, REC_DATA);
1263 ASB_OUTW(sc, asb, RECV_STATIONID, ARB_INW(sc, arb, ARB_STATIONID));
1264 ASB_OUTW(sc, asb, RECV_RESP_RECBUFADDR,
1265 ARB_INW(sc, arb, ARB_RXD_BUFADDR));
1266
1267 if (m == 0) {
1268 /*
1269 * Tell adapter data lost, no mbufs.
1270 */
1271 ASB_OUTB(sc, asb, RECV_RETCODE, 0x20);
1272 ACA_SETB(sc, ACA_ISRA_o, RESP_IN_ASB);
1273 ++ifp->if_ierrors;
1274 #ifdef TROPICDEBUG
1275 printf("tr_rint: packet dropped\n");
1276 #endif /* TROPICDEBUG */
1277 }
1278 else {
1279 /*
1280 * Indicate successful receive.
1281 */
1282 ASB_OUTB(sc, asb, RECV_RETCODE, 0);
1283 ACA_SETB(sc, ACA_ISRA_o, RESP_IN_ASB);
1284 ++ifp->if_ipackets;
1285
1286 #if NBPFILTER > 0
1287 if (ifp->if_bpf)
1288 bpf_mtap(ifp->if_bpf, m);
1289 #endif
1290 token_input(ifp, m);
1291 }
1292 }
1293
1294 /*
1295 * Interrupt handler for old style "adapter requires data to transmit".
1296 */
1297 void
tr_oldxint(sc)1298 tr_oldxint(sc)
1299 struct tr_softc *sc;
1300 {
1301 bus_size_t arb = sc->sc_arb; /* pointer to ARB */
1302 bus_size_t asb = sc->sc_asb; /* pointer to ASB */
1303 bus_size_t dhb; /* pointer to DHB */
1304 struct mbuf *m0; /* pointer to top of mbuf chain */
1305 u_short size = 0;
1306 char command;
1307 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1308 struct token_header *trh;
1309 int i;
1310 u_int8_t hlen;
1311
1312 /*
1313 * XXX xmit_asb_response()
1314 */
1315 if (ASB_INB(sc, asb, XMIT_RETCODE) != 0xff)
1316 printf("tr_oldxint: ASB IS NOT FREE!!!\n");
1317
1318 /* load parameters into ASB */
1319 ASB_OUTB(sc, asb, XMIT_CMDCORR, ARB_INB(sc, arb, ARB_XMT_CMDCORR));
1320 ASB_OUTW(sc, asb, XMIT_STATIONID, ARB_INW(sc, arb, ARB_STATIONID));
1321 ASB_OUTB(sc, asb, XMIT_RETCODE, 0);
1322 /*
1323 * XXX LLC_{X25,ISO}_LSAP
1324 */
1325 ASB_OUTB(sc, asb, XMIT_REMSAP, LLC_SNAP_LSAP);
1326
1327 /* XXX if num_dhb == 2 this should alternate between the two buffers */
1328 dhb = ARB_INW(sc, arb, ARB_XMT_DHBADDR);
1329
1330 command = SRB_INB(sc, sc->sc_srb, SRB_CMD);
1331
1332 if (command == XMIT_XID_CMD || command == XMIT_TEST_CMD) {
1333 ASB_OUTB(sc, asb, XMIT_CMD, command);
1334 ASB_OUTW(sc, asb, XMIT_FRAMELEN, 0x11);
1335 /*
1336 * XXX 0xe == sizeof(struct token_header)
1337 */
1338 ASB_OUTB(sc, asb, XMIT_HDRLEN, 0x0e);
1339
1340 SR_OUTB(sc, (dhb + 0), TOKEN_AC);
1341 SR_OUTB(sc, (dhb + 1), TOKEN_FC);
1342 /* Load destination and source addresses. */
1343 for (i=0; i < ISO88025_ADDR_LEN; i++) {
1344 SR_OUTB(sc, (dhb + 2 + i), 0xff);
1345 SR_OUTB(sc, (dhb + 8 + i), 0x00);
1346 }
1347 }
1348 else {
1349 /*
1350 * XXX what's command here ? command = 0x0d (always ?)
1351 */
1352 /* if data in queue, copy mbuf chain to DHB */
1353 IFQ_DEQUEUE(&ifp->if_snd, m0);
1354 if (m0 != 0) {
1355 #if NBPFILTER > 0
1356 if (ifp->if_bpf)
1357 bpf_mtap(ifp->if_bpf, m0);
1358 #endif
1359 /* Pull packet off interface send queue, fill DHB. */
1360 trh = mtod(m0, struct token_header *);
1361 hlen = sizeof(struct token_header);
1362 if (trh->token_shost[0] & TOKEN_RI_PRESENT) {
1363 /*
1364 * XXX assumes route info is in the same mbuf as the token-ring header
1365 */
1366 struct token_rif *rif;
1367
1368 rif = TOKEN_RIF(trh);
1369 hlen += ((ntohs(rif->tr_rcf) & TOKEN_RCF_LEN_MASK) >> 8);
1370 }
1371 size = tr_mbcopy(sc, dhb, m0);
1372 m_freem(m0);
1373
1374 ASB_OUTB(sc, asb, XMIT_CMD, XMIT_UI_FRM);
1375 ASB_OUTB(sc, asb, XMIT_HDRLEN, hlen);
1376
1377 /* Set size of transmission frame in ASB. */
1378 ASB_OUTW(sc, asb, XMIT_FRAMELEN, size);
1379 }
1380 else {
1381 printf("%s: unexpected empty mbuf send queue\n",
1382 sc->sc_dev.dv_xname);
1383
1384 /* Set size of transmission frame in ASB to zero. */
1385 ASB_OUTW(sc, asb, XMIT_FRAMELEN, 0);
1386 }
1387 }
1388 /*
1389 * XXX asb_response(void *asb, len)
1390 */
1391 /* tell adapter that there is a response in the ASB */
1392 ACA_SETB(sc, ACA_ISRA_o, RESP_IN_ASB);
1393 }
1394
1395 /*
1396 * Interrupt handler for fast path transmit complete
1397 */
1398 void
tr_xint(sc)1399 tr_xint(sc)
1400 struct tr_softc *sc;
1401 {
1402 u_short tail;
1403 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1404 bus_size_t txbuf;
1405
1406 /*
1407 * To prevent race conditions on 8-bit cards when reading or writing
1408 * 16-bit values. See page 4-12 of the IBM manual.
1409 * XXX use volatile ?
1410 */
1411 do {
1412 tail = TXCA_INW(sc, TXCA_COMPLETION_QUEUE_TAIL);
1413 } while (tail != TXCA_INW(sc, TXCA_COMPLETION_QUEUE_TAIL));
1414 while (tail != TXCA_INW(sc, TXCA_FREE_QUEUE_TAIL)) {
1415 txbuf = TXCA_INW(sc, TXCA_FREE_QUEUE_TAIL) - XMIT_NEXTBUF;
1416 txbuf = TXB_INW(sc, txbuf, XMIT_NEXTBUF) - XMIT_NEXTBUF;
1417 if (TXB_INB(sc, txbuf, XMIT_RETCODE) != 0) {
1418 ifp->if_oerrors++;
1419 printf("tx: retcode = %x\n",
1420 TXB_INB(sc, txbuf, XMIT_RETCODE));
1421 }
1422 sc->sc_xmit_buffers +=
1423 (TXB_INW(sc, txbuf, XMIT_FRAMELEN) + 514 - 1) / 514;
1424 tail = TXB_INW(sc, txbuf, XMIT_LASTBUF);
1425 TXCA_OUTW(sc, TXCA_FREE_QUEUE_TAIL, tail);
1426 tail = TXCA_INW(sc, TXCA_COMPLETION_QUEUE_TAIL);
1427 do {
1428 tail = TXCA_INW(sc, TXCA_COMPLETION_QUEUE_TAIL);
1429 } while (tail != TXCA_INW(sc, TXCA_COMPLETION_QUEUE_TAIL));
1430 }
1431 if (sc->sc_xmit_buffers == sc->sc_nbuf)
1432 ifp->if_flags &= ~IFF_OACTIVE;
1433 tr_start(ifp);
1434 }
1435
1436
1437 /*
1438 * copy out the packet byte-by-byte in reasonably optimal fashion
1439 */
1440 int
tr_mbcopy(sc,dhb,m0)1441 tr_mbcopy(sc, dhb, m0)
1442 struct tr_softc *sc;
1443 bus_size_t dhb;
1444 struct mbuf *m0;
1445 {
1446 bus_size_t addr = dhb;
1447 int len, size = 0;
1448 char *ptr;
1449 struct mbuf *m;
1450
1451 for (m = m0; m; m = m->m_next) {
1452 len = m->m_len;
1453 ptr = mtod(m, char *);
1454
1455 bus_space_write_region_1(sc->sc_memt, sc->sc_sramh,
1456 addr, ptr, len);
1457 size += len;
1458 addr += len;
1459 }
1460 return (size);
1461 }
1462
1463 /*
1464 * Pull read data off an interface.
1465 * Len is length of data, with local net header stripped.
1466 * Off is non-zero if a trailer protocol was used, and
1467 * gives the offset of the trailer information.
1468 * XXX trailer information, really ????
1469 * We copy the trailer information and then all the normal
1470 * data into mbufs.
1471 *
1472 * called from tr_rint - receive interrupt routine
1473 */
1474 struct mbuf *
tr_get(sc,totlen,ifp)1475 tr_get(sc, totlen, ifp)
1476 struct tr_softc *sc;
1477 int totlen;
1478 struct ifnet *ifp;
1479 {
1480 int len;
1481 struct mbuf *m, *m0, *newm;
1482
1483 MGETHDR(m0, M_DONTWAIT, MT_DATA);
1484 if (m0 == 0)
1485 return (0);
1486
1487 m0->m_pkthdr.rcvif = ifp;
1488 m0->m_pkthdr.len = totlen;
1489 len = MHLEN;
1490
1491 m = m0;
1492 while (totlen > 0) {
1493 if (totlen >= MINCLSIZE) {
1494 MCLGET(m, M_DONTWAIT);
1495 if ((m->m_flags & M_EXT) == 0) {
1496 m_free(m0);
1497 return 0;
1498 }
1499 len = MCLBYTES;
1500 }
1501
1502 /*
1503 * Make sure data after the MAC header is aligned.
1504 */
1505 if (m == m0) {
1506 caddr_t newdata = (caddr_t)
1507 ALIGN(m->m_data + sizeof(struct token_header)) -
1508 sizeof(struct token_header);
1509 len -= newdata - m->m_data;
1510 m->m_data = newdata;
1511 }
1512 m->m_len = len = min(totlen, len);
1513 tr_bcopy(sc, mtod(m, char *), len);
1514 totlen -= len;
1515 if (totlen > 0) {
1516 MGET(newm, M_DONTWAIT, MT_DATA);
1517 if (newm == 0){
1518 m_freem(m0);
1519 return (0);
1520 }
1521 m->m_next = newm;
1522 m = newm;
1523 len = MLEN;
1524 }
1525 /*
1526 * ignore trailers case again
1527 */
1528 }
1529 return (m0);
1530 }
1531
1532 /*
1533 * tr_ioctl - process an ioctl request
1534 */
1535 int
tr_ioctl(ifp,cmd,data)1536 tr_ioctl(ifp, cmd, data)
1537 struct ifnet *ifp;
1538 u_long cmd;
1539 caddr_t data;
1540 {
1541 struct tr_softc *sc = ifp->if_softc;
1542 struct ifreq *ifr = (struct ifreq *) data;
1543 struct ifaddr *ifa = (struct ifaddr *) data;
1544 int s;
1545 int error = 0;
1546
1547 s = splnet();
1548
1549 switch (cmd) {
1550 case SIOCSIFADDR:
1551
1552 switch (ifa->ifa_addr->sa_family) {
1553 #ifdef INET
1554 case AF_INET:
1555 /* XXX if not running */
1556 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1557 tr_init(sc); /* before arp_ifinit */
1558 tr_sleep(sc);
1559 }
1560 arp_ifinit(&sc->sc_arpcom, ifa);
1561 break;
1562 #endif /* INET */
1563 default:
1564 /* XXX if not running */
1565 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1566 tr_init(sc); /* before arpwhohas */
1567 tr_sleep(sc);
1568 }
1569 break;
1570 }
1571 break;
1572 case SIOCSIFFLAGS:
1573 /*
1574 * 1- If the adapter is DOWN , turn the device off
1575 * ie. adapter down but still running
1576 * 2- If the adapter is UP, turn the device on
1577 * ie. adapter up but not running yet
1578 */
1579 if ((ifp->if_flags & (IFF_RUNNING | IFF_UP)) == IFF_RUNNING) {
1580 tr_stop(sc);
1581 ifp->if_flags &= ~IFF_RUNNING;
1582 }
1583 else if ((ifp->if_flags & (IFF_RUNNING | IFF_UP)) == IFF_UP) {
1584 tr_init(sc);
1585 tr_sleep(sc);
1586 }
1587 else {
1588 /*
1589 * XXX handle other flag changes
1590 */
1591 }
1592 break;
1593 case SIOCGIFMEDIA:
1594 case SIOCSIFMEDIA:
1595 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1596 break;
1597 #ifdef SIOCSIFMTU
1598 case SIOCSIFMTU:
1599 if (ifr->ifr_mtu > sc->sc_maxmtu)
1600 error = EINVAL;
1601 else
1602 ifp->if_mtu = ifr->ifr_mtu;
1603 break;
1604 #endif
1605 default:
1606 error = EINVAL;
1607 }
1608 splx(s);
1609 return (error);
1610 }
1611
1612
1613 /*
1614 * tr_bcopy - like bcopy except that it knows about the structure of
1615 * adapter receive buffers.
1616 */
1617 void
tr_bcopy(sc,dest,len)1618 tr_bcopy(sc, dest, len)
1619 struct tr_softc *sc; /* pointer to softc struct for this adapter */
1620 u_char *dest; /* destination address */
1621 int len; /* number of bytes to copy */
1622 {
1623 struct rbcb *rbc = &sc->rbc; /* pointer to rec buf ctl blk */
1624
1625 /* While amount of data needed >= amount in current receive buffer. */
1626 while (len >= rbc->data_len) {
1627 /* Copy all data from receive buffer to destination. */
1628
1629 bus_space_read_region_1(sc->sc_memt, sc->sc_sramh,
1630 rbc->rbuf_datap, dest, (bus_size_t)rbc->data_len);
1631 len -= rbc->data_len; /* update length left to transfer */
1632 dest += rbc->data_len; /* update destination address */
1633
1634 /* Make next receive buffer current receive buffer. */
1635 rbc->rbufp = rbc->rbufp_next;
1636 if (rbc->rbufp != 0) { /* More receive buffers? */
1637
1638 /* Calculate pointer to next receive buffer. */
1639 rbc->rbufp_next = RB_INW(sc, rbc->rbufp, RB_NEXTBUF);
1640 if (rbc->rbufp_next != 0)
1641 rbc->rbufp_next -= RB_NEXTBUF;
1642
1643 /* Get pointer to data in current receive buffer. */
1644 rbc->rbuf_datap = rbc->rbufp + RB_DATA;
1645
1646 /* Get length of data in current receive buffer. */
1647 rbc->data_len = RB_INW(sc, rbc->rbufp, RB_BUFLEN);
1648 }
1649 else {
1650 if (len != 0) /* len should equal zero. */
1651 printf("tr_bcopy: residual data not copied\n");
1652 return;
1653 }
1654 }
1655
1656 /* Amount of data needed is < amount in current receive buffer. */
1657
1658 bus_space_read_region_1(sc->sc_memt, sc->sc_sramh,
1659 rbc->rbuf_datap, dest, (bus_size_t)len);
1660 rbc->data_len -= len; /* Update count of data in receive buffer. */
1661 rbc->rbuf_datap += len; /* Update pointer to receive buffer data. */
1662 }
1663
1664 /*
1665 * tr_opensap - open the token ring SAP interface
1666 */
1667 void
tr_opensap(sc,type)1668 tr_opensap(sc, type)
1669 struct tr_softc *sc;
1670 u_char type;
1671 {
1672 bus_size_t srb = sc->sc_srb;
1673
1674 /************************************************************************
1675 ** To use the SAP level interface, we will have to execute a **
1676 ** DLC.OPEN.SAP (pg.6-61 of the Token Ring Tech. Ref.) after we have **
1677 ** received a good return code from the DIR.OPEN.ADAPTER command. **
1678 ** We will open the IP SAP x'aa'. **
1679 ** **
1680 ** STEPS: **
1681 ** 1) Reset SRB response interrupt bit **
1682 ** 2) Use the open_sap srb. **
1683 ** 3) Fill the following fields: **
1684 ** command - x'15' **
1685 ** sap_value - x'aa' **
1686 ** sap_options- x'24' **
1687 ** **
1688 ***********************************************************************/
1689
1690 ACA_RSTB(sc, ACA_ISRP_o, ~(SRB_RESP_INT));
1691
1692 SRB_OUTB(sc, srb, SRB_CMD, DLC_OPEN_SAP);
1693 SRB_OUTB(sc, srb, SRB_RETCODE, 0x00);
1694 SRB_OUTW(sc, srb, SRB_OPNSAP_STATIONID, 0x0000);
1695 SRB_OUTB(sc, srb, SRB_OPNSAP_TIMERT1, 0x00);
1696 SRB_OUTB(sc, srb, SRB_OPNSAP_TIMERT2, 0x00);
1697 SRB_OUTB(sc, srb, SRB_OPNSAP_TIMERTI, 0x00);
1698 SRB_OUTB(sc, srb, SRB_OPNSAP_MAXOUT, 0x00);
1699 SRB_OUTB(sc, srb, SRB_OPNSAP_MAXIN, 0x00);
1700 SRB_OUTB(sc, srb, SRB_OPNSAP_MAXOUTINCR, 0x00);
1701 SRB_OUTB(sc, srb, SRB_OPNSAP_MAXRETRY, 0x00);
1702 SRB_OUTB(sc, srb, SRB_OPNSAP_GSAPMAXMEMB, 0x00);
1703 SRB_OUTW(sc, srb, SRB_OPNSAP_MAXIFIELD, 0x0088);
1704 SRB_OUTB(sc, srb, SRB_OPNSAP_SAPVALUE, type);
1705 SRB_OUTB(sc, srb, SRB_OPNSAP_SAPOPTIONS, 0x24);
1706 SRB_OUTB(sc, srb, SRB_OPNSAP_STATIONCNT, 0x01);
1707 SRB_OUTB(sc, srb, SRB_OPNSAP_SAPGSAPMEMB, 0x00);
1708
1709 ACA_SETB(sc, ACA_ISRP_e, INT_ENABLE);
1710 ACA_SETB(sc, ACA_ISRA_o, CMD_IN_SRB);
1711 }
1712
1713 /*
1714 * tr_sleep - sleep to wait for adapter to open
1715 */
1716 void
tr_sleep(sc)1717 tr_sleep(sc)
1718 struct tr_softc *sc;
1719 {
1720 int error;
1721
1722 error = tsleep(&sc->tr_sleepevent, 1, "trsleep", hz * 30);
1723 if (error == EWOULDBLOCK)
1724 printf("%s: sleep event timeout\n", sc->sc_dev.dv_xname);
1725 }
1726
1727 void
tr_watchdog(ifp)1728 tr_watchdog(ifp)
1729 struct ifnet *ifp;
1730 {
1731 struct tr_softc *sc = ifp->if_softc;
1732
1733 log(LOG_ERR,"%s: device timeout\n", sc->sc_dev.dv_xname);
1734 ++ifp->if_oerrors;
1735
1736 tr_reset(sc);
1737 }
1738