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