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