1 /* $NetBSD: if_sn.c,v 1.30 2008/04/09 15:40:30 tsutsui Exp $ */ 2 3 /* 4 * National Semiconductor DP8393X SONIC Driver 5 * Copyright (c) 1991 Algorithmics Ltd (http://www.algor.co.uk) 6 * You may use, copy, and modify this program so long as you retain the 7 * copyright line. 8 * 9 * This driver has been substantially modified since Algorithmics donated 10 * it. 11 * 12 * Denton Gentry <denny1@home.com> 13 * and also 14 * Yanagisawa Takeshi <yanagisw@aa.ap.titech.ac.jp> 15 * did the work to get this running on the Macintosh. 16 */ 17 18 #include <sys/cdefs.h> 19 __KERNEL_RCSID(0, "$NetBSD: if_sn.c,v 1.30 2008/04/09 15:40:30 tsutsui Exp $"); 20 21 #include "opt_inet.h" 22 23 #include <sys/param.h> 24 #include <sys/systm.h> 25 #include <sys/mbuf.h> 26 #include <sys/buf.h> 27 #include <sys/protosw.h> 28 #include <sys/socket.h> 29 #include <sys/syslog.h> 30 #include <sys/ioctl.h> 31 #include <sys/errno.h> 32 #include <sys/device.h> 33 34 #include <net/if.h> 35 #include <net/if_dl.h> 36 #include <net/if_ether.h> 37 38 #ifdef INET 39 #include <netinet/in.h> 40 #include <netinet/in_systm.h> 41 #include <netinet/in_var.h> 42 #include <netinet/ip.h> 43 #include <netinet/if_inarp.h> 44 #endif 45 46 #include <uvm/uvm_extern.h> 47 48 #include "bpfilter.h" 49 #if NBPFILTER > 0 50 #include <net/bpf.h> 51 #include <net/bpfdesc.h> 52 #endif 53 54 #include <machine/cpu.h> 55 #include <newsmips/apbus/apbusvar.h> 56 #include <newsmips/apbus/if_snreg.h> 57 #include <newsmips/apbus/if_snvar.h> 58 59 /* #define SONIC_DEBUG */ 60 61 #ifdef SONIC_DEBUG 62 # define DPRINTF printf 63 #else 64 # define DPRINTF while (0) printf 65 #endif 66 67 static void snwatchdog(struct ifnet *); 68 static int sninit(struct sn_softc *sc); 69 static int snstop(struct sn_softc *sc); 70 static int snioctl(struct ifnet *ifp, u_long cmd, void *data); 71 static void snstart(struct ifnet *ifp); 72 static void snreset(struct sn_softc *sc); 73 74 static void caminitialise(struct sn_softc *); 75 static void camentry(struct sn_softc *, int, const u_char *ea); 76 static void camprogram(struct sn_softc *); 77 static void initialise_tda(struct sn_softc *); 78 static void initialise_rda(struct sn_softc *); 79 static void initialise_rra(struct sn_softc *); 80 #ifdef SNDEBUG 81 static void camdump(struct sn_softc *sc); 82 #endif 83 84 static void sonictxint(struct sn_softc *); 85 static void sonicrxint(struct sn_softc *); 86 87 static inline u_int sonicput(struct sn_softc *sc, struct mbuf *m0, 88 int mtd_next); 89 static inline int sonic_read(struct sn_softc *, void *, int); 90 static inline struct mbuf *sonic_get(struct sn_softc *, void *, int); 91 92 int sndebug = 0; 93 94 /* 95 * SONIC buffers need to be aligned 16 or 32 bit aligned. 96 * These macros calculate and verify alignment. 97 */ 98 #define SOALIGN(m, array) (m ? (roundup((int)array, 4)) : \ 99 (roundup((int)array, 2))) 100 101 #define LOWER(x) ((unsigned)(x) & 0xffff) 102 #define UPPER(x) ((unsigned)(x) >> 16) 103 104 /* 105 * Interface exists: make available by filling in network interface 106 * record. System will initialize the interface when it is ready 107 * to accept packets. 108 */ 109 int 110 snsetup(struct sn_softc *sc, uint8_t *lladdr) 111 { 112 struct ifnet *ifp = &sc->sc_if; 113 uint8_t *p; 114 uint8_t *pp; 115 int i; 116 117 if (sc->space == NULL) { 118 aprint_error_dev(sc->sc_dev, 119 "memory allocation for descriptors failed\n"); 120 return 1; 121 } 122 123 /* 124 * Put the pup in reset mode (sninit() will fix it later), 125 * stop the timer, disable all interrupts and clear any interrupts. 126 */ 127 NIC_PUT(sc, SNR_CR, CR_STP); 128 wbflush(); 129 NIC_PUT(sc, SNR_CR, CR_RST); 130 wbflush(); 131 NIC_PUT(sc, SNR_IMR, 0); 132 wbflush(); 133 NIC_PUT(sc, SNR_ISR, ISR_ALL); 134 wbflush(); 135 136 /* 137 * because the SONIC is basically 16bit device it 'concatenates' 138 * a higher buffer address to a 16 bit offset--this will cause wrap 139 * around problems near the end of 64k !! 140 */ 141 p = sc->space; 142 pp = (uint8_t *)roundup((int)p, PAGE_SIZE); 143 p = pp; 144 145 for (i = 0; i < NRRA; i++) { 146 sc->p_rra[i] = (void *)p; 147 sc->v_rra[i] = SONIC_GETDMA(p); 148 p += RXRSRC_SIZE(sc); 149 } 150 sc->v_rea = SONIC_GETDMA(p); 151 152 p = (uint8_t *)SOALIGN(sc, p); 153 154 sc->p_cda = (void *)(p); 155 sc->v_cda = SONIC_GETDMA(p); 156 p += CDA_SIZE(sc); 157 158 p = (uint8_t *)SOALIGN(sc, p); 159 160 for (i = 0; i < NTDA; i++) { 161 struct mtd *mtdp = &sc->mtda[i]; 162 mtdp->mtd_txp = (void *)p; 163 mtdp->mtd_vtxp = SONIC_GETDMA(p); 164 p += TXP_SIZE(sc); 165 } 166 167 p = (uint8_t *)SOALIGN(sc, p); 168 169 if ((p - pp) > PAGE_SIZE) { 170 aprint_error_dev(sc->sc_dev, "sizeof RRA (%ld) + CDA (%ld) +" 171 "TDA (%ld) > PAGE_SIZE (%d). Punt!\n", 172 (ulong)sc->p_cda - (ulong)sc->p_rra[0], 173 (ulong)sc->mtda[0].mtd_txp - (ulong)sc->p_cda, 174 (ulong)p - (ulong)sc->mtda[0].mtd_txp, 175 PAGE_SIZE); 176 return 1; 177 } 178 179 p = pp + PAGE_SIZE; 180 pp = p; 181 182 sc->sc_nrda = PAGE_SIZE / RXPKT_SIZE(sc); 183 sc->p_rda = (void *)p; 184 sc->v_rda = SONIC_GETDMA(p); 185 186 p = pp + PAGE_SIZE; 187 188 for (i = 0; i < NRBA; i++) { 189 sc->rbuf[i] = (void *)p; 190 p += PAGE_SIZE; 191 } 192 193 pp = p; 194 for (i = 0; i < NTDA; i++) { 195 struct mtd *mtdp = &sc->mtda[i]; 196 197 mtdp->mtd_buf = p; 198 mtdp->mtd_vbuf = SONIC_GETDMA(p); 199 p += TXBSIZE; 200 } 201 202 #ifdef SNDEBUG 203 camdump(sc); 204 #endif 205 aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n", 206 ether_sprintf(lladdr)); 207 208 #ifdef SNDEBUG 209 aprint_debug_dev(sc->sc_dev, "buffers: rra=%p cda=%p rda=%p tda=%p\n", 210 sc->sc_dev.dv_xname, sc->p_rra[0], sc->p_cda, 211 sc->p_rda, sc->mtda[0].mtd_txp); 212 #endif 213 214 strcpy(ifp->if_xname, device_xname(sc->sc_dev)); 215 ifp->if_softc = sc; 216 ifp->if_ioctl = snioctl; 217 ifp->if_start = snstart; 218 ifp->if_flags = 219 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; 220 ifp->if_watchdog = snwatchdog; 221 if_attach(ifp); 222 ether_ifattach(ifp, lladdr); 223 224 return 0; 225 } 226 227 static int 228 snioctl(struct ifnet *ifp, u_long cmd, void *data) 229 { 230 struct ifaddr *ifa; 231 struct sn_softc *sc = ifp->if_softc; 232 int s = splnet(), err = 0; 233 int temp; 234 235 switch (cmd) { 236 237 case SIOCSIFADDR: 238 ifa = (struct ifaddr *)data; 239 ifp->if_flags |= IFF_UP; 240 switch (ifa->ifa_addr->sa_family) { 241 #ifdef INET 242 case AF_INET: 243 (void)sninit(sc); 244 arp_ifinit(ifp, ifa); 245 break; 246 #endif 247 default: 248 (void)sninit(sc); 249 break; 250 } 251 break; 252 253 case SIOCSIFFLAGS: 254 if ((ifp->if_flags & IFF_UP) == 0 && 255 (ifp->if_flags & IFF_RUNNING) != 0) { 256 /* 257 * If interface is marked down and it is running, 258 * then stop it. 259 */ 260 snstop(sc); 261 ifp->if_flags &= ~IFF_RUNNING; 262 } else if ((ifp->if_flags & IFF_UP) != 0 && 263 (ifp->if_flags & IFF_RUNNING) == 0) { 264 /* 265 * If interface is marked up and it is stopped, 266 * then start it. 267 */ 268 (void)sninit(sc); 269 } else { 270 /* 271 * reset the interface to pick up any other changes 272 * in flags 273 */ 274 temp = ifp->if_flags & IFF_UP; 275 snreset(sc); 276 ifp->if_flags |= temp; 277 snstart(ifp); 278 } 279 break; 280 281 case SIOCADDMULTI: 282 case SIOCDELMULTI: 283 if ((err = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 284 /* 285 * Multicast list has changed; set the hardware 286 * filter accordingly. But remember UP flag! 287 */ 288 if (ifp->if_flags & IFF_RUNNING) { 289 temp = ifp->if_flags & IFF_UP; 290 snreset(sc); 291 ifp->if_flags |= temp; 292 } 293 err = 0; 294 } 295 break; 296 default: 297 err = EINVAL; 298 } 299 splx(s); 300 return err; 301 } 302 303 /* 304 * Encapsulate a packet of type family for the local net. 305 */ 306 static void 307 snstart(struct ifnet *ifp) 308 { 309 struct sn_softc *sc = ifp->if_softc; 310 struct mbuf *m; 311 int mtd_next; 312 313 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 314 return; 315 316 outloop: 317 /* Check for room in the xmit buffer. */ 318 if ((mtd_next = (sc->mtd_free + 1)) == NTDA) 319 mtd_next = 0; 320 321 if (mtd_next == sc->mtd_hw) { 322 ifp->if_flags |= IFF_OACTIVE; 323 return; 324 } 325 326 IF_DEQUEUE(&ifp->if_snd, m); 327 if (m == 0) 328 return; 329 330 /* We need the header for m_pkthdr.len. */ 331 if ((m->m_flags & M_PKTHDR) == 0) 332 panic("%s: snstart: no header mbuf", device_xname(sc->sc_dev)); 333 334 #if NBPFILTER > 0 335 /* 336 * If bpf is listening on this interface, let it 337 * see the packet before we commit it to the wire. 338 */ 339 if (ifp->if_bpf) 340 bpf_mtap(ifp->if_bpf, m); 341 #endif 342 343 /* 344 * If there is nothing in the o/p queue, and there is room in 345 * the Tx ring, then send the packet directly. Otherwise append 346 * it to the o/p queue. 347 */ 348 if ((sonicput(sc, m, mtd_next)) == 0) { 349 IF_PREPEND(&ifp->if_snd, m); 350 return; 351 } 352 353 sc->mtd_prev = sc->mtd_free; 354 sc->mtd_free = mtd_next; 355 356 ifp->if_opackets++; /* # of pkts */ 357 358 /* Jump back for possibly more punishment. */ 359 goto outloop; 360 } 361 362 /* 363 * reset and restart the SONIC. Called in case of fatal 364 * hardware/software errors. 365 */ 366 static void 367 snreset(struct sn_softc *sc) 368 { 369 370 snstop(sc); 371 sninit(sc); 372 } 373 374 static int 375 sninit(struct sn_softc *sc) 376 { 377 u_long s_rcr; 378 int s; 379 380 if (sc->sc_if.if_flags & IFF_RUNNING) 381 /* already running */ 382 return 0; 383 384 s = splnet(); 385 386 NIC_PUT(sc, SNR_CR, CR_RST); /* DCR only accessible in reset mode! */ 387 388 /* config it */ 389 NIC_PUT(sc, SNR_DCR, (sc->snr_dcr | 390 (sc->bitmode ? DCR_DW32 : DCR_DW16))); 391 NIC_PUT(sc, SNR_DCR2, sc->snr_dcr2); 392 393 s_rcr = RCR_BRD | RCR_LBNONE; 394 if (sc->sc_if.if_flags & IFF_PROMISC) 395 s_rcr |= RCR_PRO; 396 if (sc->sc_if.if_flags & IFF_ALLMULTI) 397 s_rcr |= RCR_AMC; 398 NIC_PUT(sc, SNR_RCR, s_rcr); 399 400 #if 0 401 NIC_PUT(sc, SNR_IMR, (IMR_PRXEN | IMR_PTXEN | IMR_TXEREN | IMR_LCDEN)); 402 #else 403 NIC_PUT(sc, SNR_IMR, IMR_PRXEN | IMR_PTXEN | IMR_TXEREN | IMR_LCDEN | 404 IMR_BREN | IMR_HBLEN | IMR_RDEEN | IMR_RBEEN | 405 IMR_RBAEEN | IMR_RFOEN); 406 #endif 407 408 /* clear pending interrupts */ 409 NIC_PUT(sc, SNR_ISR, ISR_ALL); 410 411 /* clear tally counters */ 412 NIC_PUT(sc, SNR_CRCT, -1); 413 NIC_PUT(sc, SNR_FAET, -1); 414 NIC_PUT(sc, SNR_MPT, -1); 415 416 initialise_tda(sc); 417 initialise_rda(sc); 418 initialise_rra(sc); 419 420 sn_md_init(sc); /* MD initialization */ 421 422 /* enable the chip */ 423 NIC_PUT(sc, SNR_CR, 0); 424 wbflush(); 425 426 /* program the CAM */ 427 camprogram(sc); 428 429 /* get it to read resource descriptors */ 430 NIC_PUT(sc, SNR_CR, CR_RRRA); 431 wbflush(); 432 while ((NIC_GET(sc, SNR_CR)) & CR_RRRA) 433 continue; 434 435 /* enable rx */ 436 NIC_PUT(sc, SNR_CR, CR_RXEN); 437 wbflush(); 438 439 /* flag interface as "running" */ 440 sc->sc_if.if_flags |= IFF_RUNNING; 441 sc->sc_if.if_flags &= ~IFF_OACTIVE; 442 443 splx(s); 444 return 0; 445 } 446 447 /* 448 * close down an interface and free its buffers 449 * Called on final close of device, or if sninit() fails 450 * part way through. 451 */ 452 static int 453 snstop(struct sn_softc *sc) 454 { 455 struct mtd *mtd; 456 int s = splnet(); 457 458 /* stick chip in reset */ 459 NIC_PUT(sc, SNR_CR, CR_RST); 460 wbflush(); 461 462 /* free all receive buffers (currently static so nothing to do) */ 463 464 /* free all pending transmit mbufs */ 465 while (sc->mtd_hw != sc->mtd_free) { 466 mtd = &sc->mtda[sc->mtd_hw]; 467 if (mtd->mtd_mbuf) 468 m_freem(mtd->mtd_mbuf); 469 if (++sc->mtd_hw == NTDA) sc->mtd_hw = 0; 470 } 471 472 sc->sc_if.if_timer = 0; 473 sc->sc_if.if_flags &= ~(IFF_RUNNING | IFF_UP); 474 475 splx(s); 476 return 0; 477 } 478 479 /* 480 * Called if any Tx packets remain unsent after 5 seconds, 481 * In all cases we just reset the chip, and any retransmission 482 * will be handled by higher level protocol timeouts. 483 */ 484 static void 485 snwatchdog(struct ifnet *ifp) 486 { 487 struct sn_softc *sc = ifp->if_softc; 488 struct mtd *mtd; 489 int temp; 490 491 if (sc->mtd_hw != sc->mtd_free) { 492 /* something still pending for transmit */ 493 mtd = &sc->mtda[sc->mtd_hw]; 494 if (SRO(sc->bitmode, mtd->mtd_txp, TXP_STATUS) == 0) 495 log(LOG_ERR, "%s: Tx - timeout\n", 496 device_xname(sc->sc_dev)); 497 else 498 log(LOG_ERR, "%s: Tx - lost interrupt\n", 499 device_xname(sc->sc_dev)); 500 temp = ifp->if_flags & IFF_UP; 501 snreset(sc); 502 ifp->if_flags |= temp; 503 } 504 } 505 506 /* 507 * stuff packet into sonic (at splnet) 508 */ 509 static inline u_int 510 sonicput(struct sn_softc *sc, struct mbuf *m0, int mtd_next) 511 { 512 struct mtd *mtdp; 513 struct mbuf *m; 514 u_char *buff; 515 void *txp; 516 u_int len = 0; 517 u_int totlen = 0; 518 519 #ifdef whyonearthwouldyoudothis 520 if (NIC_GET(sc, SNR_CR) & CR_TXP) 521 return 0; 522 #endif 523 524 /* grab the replacement mtd */ 525 mtdp = &sc->mtda[sc->mtd_free]; 526 527 buff = mtdp->mtd_buf; 528 529 /* this packet goes to mtdnext fill in the TDA */ 530 mtdp->mtd_mbuf = m0; 531 txp = mtdp->mtd_txp; 532 533 /* Write to the config word. Every (NTDA/2)+1 packets we set an intr */ 534 if (sc->mtd_pint == 0) { 535 sc->mtd_pint = NTDA/2; 536 SWO(sc->bitmode, txp, TXP_CONFIG, TCR_PINT); 537 } else { 538 sc->mtd_pint--; 539 SWO(sc->bitmode, txp, TXP_CONFIG, 0); 540 } 541 542 for (m = m0; m; m = m->m_next) { 543 u_char *data = mtod(m, u_char *); 544 len = m->m_len; 545 totlen += len; 546 memcpy(buff, data, len); 547 buff += len; 548 } 549 if (totlen >= TXBSIZE) { 550 panic("%s: sonicput: packet overflow", 551 device_xname(sc->sc_dev)); 552 } 553 554 SWO(sc->bitmode, txp, TXP_FRAGOFF + (0 * TXP_FRAGSIZE) + TXP_FPTRLO, 555 LOWER(mtdp->mtd_vbuf)); 556 SWO(sc->bitmode, txp, TXP_FRAGOFF + (0 * TXP_FRAGSIZE) + TXP_FPTRHI, 557 UPPER(mtdp->mtd_vbuf)); 558 559 if (totlen < ETHERMIN + ETHER_HDR_LEN) { 560 int pad = ETHERMIN + ETHER_HDR_LEN - totlen; 561 memset((char *)mtdp->mtd_buf + totlen, 0, pad); 562 totlen = ETHERMIN + ETHER_HDR_LEN; 563 } 564 565 SWO(sc->bitmode, txp, TXP_FRAGOFF + (0 * TXP_FRAGSIZE) + TXP_FSIZE, 566 totlen); 567 SWO(sc->bitmode, txp, TXP_FRAGCNT, 1); 568 SWO(sc->bitmode, txp, TXP_PKTSIZE, totlen); 569 570 /* link onto the next mtd that will be used */ 571 SWO(sc->bitmode, txp, TXP_FRAGOFF + (1 * TXP_FRAGSIZE) + TXP_FPTRLO, 572 LOWER(sc->mtda[mtd_next].mtd_vtxp) | EOL); 573 574 /* 575 * The previous txp.tlink currently contains a pointer to 576 * our txp | EOL. Want to clear the EOL, so write our 577 * pointer to the previous txp. 578 */ 579 SWO(sc->bitmode, sc->mtda[sc->mtd_prev].mtd_txp, sc->mtd_tlinko, 580 LOWER(mtdp->mtd_vtxp)); 581 582 /* make sure chip is running */ 583 wbflush(); 584 NIC_PUT(sc, SNR_CR, CR_TXP); 585 wbflush(); 586 sc->sc_if.if_timer = 5; /* 5 seconds to watch for failing to transmit */ 587 588 return totlen; 589 } 590 591 /* 592 * These are called from sonicioctl() when /etc/ifconfig is run to set 593 * the address or switch the i/f on. 594 */ 595 /* 596 * CAM support 597 */ 598 static void 599 caminitialise(struct sn_softc *sc) 600 { 601 void *p_cda = sc->p_cda; 602 int i; 603 int camoffset; 604 605 for (i = 0; i < MAXCAM; i++) { 606 camoffset = i * CDA_CAMDESC; 607 SWO(bitmode, p_cda, (camoffset + CDA_CAMEP), i); 608 SWO(bitmode, p_cda, (camoffset + CDA_CAMAP2), 0); 609 SWO(bitmode, p_cda, (camoffset + CDA_CAMAP1), 0); 610 SWO(bitmode, p_cda, (camoffset + CDA_CAMAP0), 0); 611 } 612 SWO(bitmode, p_cda, CDA_ENABLE, 0); 613 } 614 615 static void 616 camentry(struct sn_softc *sc, int entry, const u_char *ea) 617 { 618 void *p_cda = sc->p_cda; 619 int camoffset = entry * CDA_CAMDESC; 620 621 SWO(bitmode, p_cda, camoffset + CDA_CAMEP, entry); 622 SWO(bitmode, p_cda, camoffset + CDA_CAMAP2, (ea[5] << 8) | ea[4]); 623 SWO(bitmode, p_cda, camoffset + CDA_CAMAP1, (ea[3] << 8) | ea[2]); 624 SWO(bitmode, p_cda, camoffset + CDA_CAMAP0, (ea[1] << 8) | ea[0]); 625 SWO(bitmode, p_cda, CDA_ENABLE, 626 (SRO(bitmode, p_cda, CDA_ENABLE) | (1 << entry))); 627 } 628 629 static void 630 camprogram(struct sn_softc *sc) 631 { 632 struct ether_multistep step; 633 struct ether_multi *enm; 634 struct ifnet *ifp; 635 int timeout; 636 int mcount = 0; 637 638 caminitialise(sc); 639 640 ifp = &sc->sc_if; 641 642 /* Always load our own address first. */ 643 camentry(sc, mcount, CLLADDR(ifp->if_sadl)); 644 mcount++; 645 646 /* Assume we won't need allmulti bit. */ 647 ifp->if_flags &= ~IFF_ALLMULTI; 648 649 /* Loop through multicast addresses */ 650 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm); 651 while (enm != NULL) { 652 if (mcount == MAXCAM) { 653 ifp->if_flags |= IFF_ALLMULTI; 654 break; 655 } 656 657 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 658 sizeof(enm->enm_addrlo)) != 0) { 659 /* 660 * SONIC's CAM is programmed with specific 661 * addresses. It has no way to specify a range. 662 * (Well, thats not exactly true. If the 663 * range is small one could program each addr 664 * within the range as a separate CAM entry) 665 */ 666 ifp->if_flags |= IFF_ALLMULTI; 667 break; 668 } 669 670 /* program the CAM with the specified entry */ 671 camentry(sc, mcount, enm->enm_addrlo); 672 mcount++; 673 674 ETHER_NEXT_MULTI(step, enm); 675 } 676 677 NIC_PUT(sc, SNR_CDP, LOWER(sc->v_cda)); 678 NIC_PUT(sc, SNR_CDC, MAXCAM); 679 NIC_PUT(sc, SNR_CR, CR_LCAM); 680 wbflush(); 681 682 timeout = 10000; 683 while ((NIC_GET(sc, SNR_CR) & CR_LCAM) && timeout--) 684 delay(10); 685 if (timeout == 0) { 686 /* XXX */ 687 panic("%s: CAM initialisation failed", 688 device_xname(sc->sc_dev)); 689 } 690 timeout = 10000; 691 while (((NIC_GET(sc, SNR_ISR) & ISR_LCD) == 0) && timeout--) 692 delay(10); 693 694 if (NIC_GET(sc, SNR_ISR) & ISR_LCD) 695 NIC_PUT(sc, SNR_ISR, ISR_LCD); 696 else 697 printf("%s: CAM initialisation without interrupt\n", 698 device_xname(sc->sc_dev)); 699 } 700 701 #ifdef SNDEBUG 702 static void 703 camdump(struct sn_softc *sc) 704 { 705 int i; 706 707 printf("CAM entries:\n"); 708 NIC_PUT(sc, SNR_CR, CR_RST); 709 wbflush(); 710 711 for (i = 0; i < 16; i++) { 712 ushort ap2, ap1, ap0; 713 NIC_PUT(sc, SNR_CEP, i); 714 wbflush(); 715 ap2 = NIC_GET(sc, SNR_CAP2); 716 ap1 = NIC_GET(sc, SNR_CAP1); 717 ap0 = NIC_GET(sc, SNR_CAP0); 718 printf("%d: ap2=0x%x ap1=0x%x ap0=0x%x\n", i, ap2, ap1, ap0); 719 } 720 printf("CAM enable 0x%x\n", NIC_GET(sc, SNR_CEP)); 721 722 NIC_PUT(sc, SNR_CR, 0); 723 wbflush(); 724 } 725 #endif 726 727 static void 728 initialise_tda(struct sn_softc *sc) 729 { 730 struct mtd *mtd; 731 int i; 732 733 for (i = 0; i < NTDA; i++) { 734 mtd = &sc->mtda[i]; 735 mtd->mtd_mbuf = 0; 736 } 737 738 sc->mtd_hw = 0; 739 sc->mtd_prev = NTDA - 1; 740 sc->mtd_free = 0; 741 sc->mtd_tlinko = TXP_FRAGOFF + 1*TXP_FRAGSIZE + TXP_FPTRLO; 742 sc->mtd_pint = NTDA/2; 743 744 NIC_PUT(sc, SNR_UTDA, UPPER(sc->mtda[0].mtd_vtxp)); 745 NIC_PUT(sc, SNR_CTDA, LOWER(sc->mtda[0].mtd_vtxp)); 746 } 747 748 static void 749 initialise_rda(struct sn_softc *sc) 750 { 751 int i; 752 char *p_rda = 0; 753 uint32_t v_rda = 0; 754 755 /* link the RDA's together into a circular list */ 756 for (i = 0; i < (sc->sc_nrda - 1); i++) { 757 p_rda = (char *)sc->p_rda + (i * RXPKT_SIZE(sc)); 758 v_rda = sc->v_rda + ((i+1) * RXPKT_SIZE(sc)); 759 SWO(bitmode, p_rda, RXPKT_RLINK, LOWER(v_rda)); 760 SWO(bitmode, p_rda, RXPKT_INUSE, 1); 761 } 762 p_rda = (char *)sc->p_rda + ((sc->sc_nrda - 1) * RXPKT_SIZE(sc)); 763 SWO(bitmode, p_rda, RXPKT_RLINK, LOWER(sc->v_rda) | EOL); 764 SWO(bitmode, p_rda, RXPKT_INUSE, 1); 765 766 /* mark end of receive descriptor list */ 767 sc->sc_rdamark = sc->sc_nrda - 1; 768 769 sc->sc_rxmark = 0; 770 771 NIC_PUT(sc, SNR_URDA, UPPER(sc->v_rda)); 772 NIC_PUT(sc, SNR_CRDA, LOWER(sc->v_rda)); 773 wbflush(); 774 } 775 776 static void 777 initialise_rra(struct sn_softc *sc) 778 { 779 int i; 780 u_int v; 781 int bitmode = sc->bitmode; 782 783 if (bitmode) 784 NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 2); 785 else 786 NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 1); 787 788 NIC_PUT(sc, SNR_URRA, UPPER(sc->v_rra[0])); 789 NIC_PUT(sc, SNR_RSA, LOWER(sc->v_rra[0])); 790 /* rea must point just past the end of the rra space */ 791 NIC_PUT(sc, SNR_REA, LOWER(sc->v_rea)); 792 NIC_PUT(sc, SNR_RRP, LOWER(sc->v_rra[0])); 793 NIC_PUT(sc, SNR_RSC, 0); 794 795 /* fill up SOME of the rra with buffers */ 796 for (i = 0; i < NRBA; i++) { 797 v = SONIC_GETDMA(sc->rbuf[i]); 798 SWO(bitmode, sc->p_rra[i], RXRSRC_PTRHI, UPPER(v)); 799 SWO(bitmode, sc->p_rra[i], RXRSRC_PTRLO, LOWER(v)); 800 SWO(bitmode, sc->p_rra[i], RXRSRC_WCHI, UPPER(PAGE_SIZE/2)); 801 SWO(bitmode, sc->p_rra[i], RXRSRC_WCLO, LOWER(PAGE_SIZE/2)); 802 } 803 sc->sc_rramark = NRBA; 804 NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[sc->sc_rramark])); 805 wbflush(); 806 } 807 808 int 809 snintr(void *arg) 810 { 811 struct sn_softc *sc = (struct sn_softc *)arg; 812 int handled = 0; 813 int isr; 814 815 while ((isr = (NIC_GET(sc, SNR_ISR) & ISR_ALL)) != 0) { 816 /* scrub the interrupts that we are going to service */ 817 NIC_PUT(sc, SNR_ISR, isr); 818 handled = 1; 819 wbflush(); 820 821 if (isr & (ISR_BR | ISR_LCD | ISR_TC)) 822 printf("%s: unexpected interrupt status 0x%x\n", 823 device_xname(sc->sc_dev), isr); 824 825 if (isr & (ISR_TXDN | ISR_TXER | ISR_PINT)) 826 sonictxint(sc); 827 828 if (isr & ISR_PKTRX) 829 sonicrxint(sc); 830 831 if (isr & (ISR_HBL | ISR_RDE | ISR_RBE | ISR_RBAE | ISR_RFO)) { 832 if (isr & ISR_HBL) 833 /* 834 * The repeater is not providing a heartbeat. 835 * In itself this isn't harmful, lots of the 836 * cheap repeater hubs don't supply a heartbeat. 837 * So ignore the lack of heartbeat. Its only 838 * if we can't detect a carrier that we have a 839 * problem. 840 */ 841 ; 842 if (isr & ISR_RDE) 843 printf("%s: receive descriptors exhausted\n", 844 device_xname(sc->sc_dev)); 845 if (isr & ISR_RBE) 846 printf("%s: receive buffers exhausted\n", 847 device_xname(sc->sc_dev)); 848 if (isr & ISR_RBAE) 849 printf("%s: receive buffer area exhausted\n", 850 device_xname(sc->sc_dev)); 851 if (isr & ISR_RFO) 852 printf("%s: receive FIFO overrun\n", 853 device_xname(sc->sc_dev)); 854 } 855 if (isr & (ISR_CRC | ISR_FAE | ISR_MP)) { 856 #ifdef notdef 857 if (isr & ISR_CRC) 858 sc->sc_crctally++; 859 if (isr & ISR_FAE) 860 sc->sc_faetally++; 861 if (isr & ISR_MP) 862 sc->sc_mptally++; 863 #endif 864 } 865 snstart(&sc->sc_if); 866 } 867 return handled; 868 } 869 870 /* 871 * Transmit interrupt routine 872 */ 873 static void 874 sonictxint(struct sn_softc *sc) 875 { 876 struct mtd *mtd; 877 void *txp; 878 unsigned short txp_status; 879 int mtd_hw; 880 struct ifnet *ifp = &sc->sc_if; 881 882 mtd_hw = sc->mtd_hw; 883 884 if (mtd_hw == sc->mtd_free) 885 return; 886 887 while (mtd_hw != sc->mtd_free) { 888 mtd = &sc->mtda[mtd_hw]; 889 890 txp = mtd->mtd_txp; 891 892 if (SRO(sc->bitmode, txp, TXP_STATUS) == 0) { 893 break; /* it hasn't really gone yet */ 894 } 895 896 #ifdef SNDEBUG 897 { 898 struct ether_header *eh; 899 900 eh = (struct ether_header *) mtd->mtd_buf; 901 printf("%s: xmit status=0x%x len=%d type=0x%x from %s", 902 device_xname(sc->sc_dev), 903 SRO(sc->bitmode, txp, TXP_STATUS), 904 SRO(sc->bitmode, txp, TXP_PKTSIZE), 905 htons(eh->ether_type), 906 ether_sprintf(eh->ether_shost)); 907 printf(" (to %s)\n", ether_sprintf(eh->ether_dhost)); 908 } 909 #endif /* SNDEBUG */ 910 911 ifp->if_flags &= ~IFF_OACTIVE; 912 913 if (mtd->mtd_mbuf != 0) { 914 m_freem(mtd->mtd_mbuf); 915 mtd->mtd_mbuf = 0; 916 } 917 if (++mtd_hw == NTDA) mtd_hw = 0; 918 919 txp_status = SRO(sc->bitmode, txp, TXP_STATUS); 920 921 ifp->if_collisions += (txp_status & TCR_EXC) ? 16 : 922 ((txp_status & TCR_NC) >> 12); 923 924 if ((txp_status & TCR_PTX) == 0) { 925 ifp->if_oerrors++; 926 printf("%s: Tx packet status=0x%x\n", 927 device_xname(sc->sc_dev), txp_status); 928 929 /* XXX - DG This looks bogus */ 930 if (mtd_hw != sc->mtd_free) { 931 printf("resubmitting remaining packets\n"); 932 mtd = &sc->mtda[mtd_hw]; 933 NIC_PUT(sc, SNR_CTDA, LOWER(mtd->mtd_vtxp)); 934 NIC_PUT(sc, SNR_CR, CR_TXP); 935 wbflush(); 936 break; 937 } 938 } 939 } 940 941 sc->mtd_hw = mtd_hw; 942 return; 943 } 944 945 /* 946 * Receive interrupt routine 947 */ 948 static void 949 sonicrxint(struct sn_softc *sc) 950 { 951 void * rda; 952 int orra; 953 int len; 954 int rramark; 955 int rdamark; 956 uint16_t rxpkt_ptr; 957 958 rda = (char *)sc->p_rda + (sc->sc_rxmark * RXPKT_SIZE(sc)); 959 960 while (SRO(bitmode, rda, RXPKT_INUSE) == 0) { 961 u_int status = SRO(bitmode, rda, RXPKT_STATUS); 962 963 orra = RBASEQ(SRO(bitmode, rda, RXPKT_SEQNO)) & RRAMASK; 964 rxpkt_ptr = SRO(bitmode, rda, RXPKT_PTRLO); 965 len = SRO(bitmode, rda, RXPKT_BYTEC) - FCSSIZE; 966 if (status & RCR_PRX) { 967 void *pkt = 968 (char *)sc->rbuf[orra & RBAMASK] + 969 (rxpkt_ptr & PGOFSET); 970 if (sonic_read(sc, pkt, len)) 971 sc->sc_if.if_ipackets++; 972 else 973 sc->sc_if.if_ierrors++; 974 } else 975 sc->sc_if.if_ierrors++; 976 977 /* 978 * give receive buffer area back to chip. 979 * 980 * If this was the last packet in the RRA, give the RRA to 981 * the chip again. 982 * If sonic read didnt copy it out then we would have to 983 * wait !! 984 * (dont bother add it back in again straight away) 985 * 986 * Really, we're doing p_rra[rramark] = p_rra[orra] but 987 * we have to use the macros because SONIC might be in 988 * 16 or 32 bit mode. 989 */ 990 if (status & RCR_LPKT) { 991 void *tmp1, *tmp2; 992 993 rramark = sc->sc_rramark; 994 tmp1 = sc->p_rra[rramark]; 995 tmp2 = sc->p_rra[orra]; 996 SWO(bitmode, tmp1, RXRSRC_PTRLO, 997 SRO(bitmode, tmp2, RXRSRC_PTRLO)); 998 SWO(bitmode, tmp1, RXRSRC_PTRHI, 999 SRO(bitmode, tmp2, RXRSRC_PTRHI)); 1000 SWO(bitmode, tmp1, RXRSRC_WCLO, 1001 SRO(bitmode, tmp2, RXRSRC_WCLO)); 1002 SWO(bitmode, tmp1, RXRSRC_WCHI, 1003 SRO(bitmode, tmp2, RXRSRC_WCHI)); 1004 1005 /* zap old rra for fun */ 1006 SWO(bitmode, tmp2, RXRSRC_WCHI, 0); 1007 SWO(bitmode, tmp2, RXRSRC_WCLO, 0); 1008 1009 sc->sc_rramark = (++rramark) & RRAMASK; 1010 NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[rramark])); 1011 wbflush(); 1012 } 1013 1014 /* 1015 * give receive descriptor back to chip simple 1016 * list is circular 1017 */ 1018 rdamark = sc->sc_rdamark; 1019 SWO(bitmode, rda, RXPKT_INUSE, 1); 1020 SWO(bitmode, rda, RXPKT_RLINK, 1021 SRO(bitmode, rda, RXPKT_RLINK) | EOL); 1022 SWO(bitmode, ((char *)sc->p_rda + (rdamark * RXPKT_SIZE(sc))), 1023 RXPKT_RLINK, 1024 SRO(bitmode, ((char *)sc->p_rda + 1025 (rdamark * RXPKT_SIZE(sc))), 1026 RXPKT_RLINK) & ~EOL); 1027 sc->sc_rdamark = sc->sc_rxmark; 1028 1029 if (++sc->sc_rxmark >= sc->sc_nrda) 1030 sc->sc_rxmark = 0; 1031 rda = (char *)sc->p_rda + (sc->sc_rxmark * RXPKT_SIZE(sc)); 1032 } 1033 } 1034 1035 /* 1036 * sonic_read -- pull packet off interface and forward to 1037 * appropriate protocol handler 1038 */ 1039 static inline int 1040 sonic_read(struct sn_softc *sc, void *pkt, int len) 1041 { 1042 struct ifnet *ifp = &sc->sc_if; 1043 struct mbuf *m; 1044 1045 #ifdef SNDEBUG 1046 { 1047 printf("%s: rcvd %p len=%d type=0x%x from %s", 1048 devoce_xname(sc->sc_dev), et, len, htons(et->ether_type), 1049 ether_sprintf(et->ether_shost)); 1050 printf(" (to %s)\n", ether_sprintf(et->ether_dhost)); 1051 } 1052 #endif /* SNDEBUG */ 1053 1054 if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN) || 1055 len > (ETHER_MAX_LEN - ETHER_CRC_LEN)) { 1056 printf("%s: invalid packet length %d bytes\n", 1057 device_xname(sc->sc_dev), len); 1058 return 0; 1059 } 1060 1061 m = sonic_get(sc, pkt, len); 1062 if (m == NULL) 1063 return 0; 1064 #if NBPFILTER > 0 1065 /* Pass the packet to any BPF listeners. */ 1066 if (ifp->if_bpf) 1067 bpf_mtap(ifp->if_bpf, m); 1068 #endif 1069 (*ifp->if_input)(ifp, m); 1070 return 1; 1071 } 1072 1073 /* 1074 * munge the received packet into an mbuf chain 1075 */ 1076 static inline struct mbuf * 1077 sonic_get(struct sn_softc *sc, void *pkt, int datalen) 1078 { 1079 struct mbuf *m, *top, **mp; 1080 int len; 1081 1082 MGETHDR(m, M_DONTWAIT, MT_DATA); 1083 if (m == 0) 1084 return 0; 1085 m->m_pkthdr.rcvif = &sc->sc_if; 1086 m->m_pkthdr.len = datalen; 1087 len = MHLEN; 1088 top = 0; 1089 mp = ⊤ 1090 1091 while (datalen > 0) { 1092 if (top) { 1093 MGET(m, M_DONTWAIT, MT_DATA); 1094 if (m == 0) { 1095 m_freem(top); 1096 return 0; 1097 } 1098 len = MLEN; 1099 } 1100 if (datalen >= MINCLSIZE) { 1101 MCLGET(m, M_DONTWAIT); 1102 if ((m->m_flags & M_EXT) == 0) { 1103 if (top) m_freem(top); 1104 return 0; 1105 } 1106 len = MCLBYTES; 1107 } 1108 1109 if (mp == &top) { 1110 char *newdata = (char *) 1111 ALIGN((char *)m->m_data + 1112 sizeof(struct ether_header)) - 1113 sizeof(struct ether_header); 1114 len -= newdata - m->m_data; 1115 m->m_data = newdata; 1116 } 1117 1118 m->m_len = len = min(datalen, len); 1119 1120 memcpy(mtod(m, void *), pkt, (unsigned) len); 1121 pkt = (char *)pkt + len; 1122 datalen -= len; 1123 *mp = m; 1124 mp = &m->m_next; 1125 } 1126 1127 return top; 1128 } 1129