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