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