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