1 /* $NetBSD: if_sn.c,v 1.28 2007/10/17 19:55:54 garbled 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.28 2007/10/17 19:55:54 garbled 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, 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 u_char *p; 114 u_char *pp; 115 int i; 116 117 if (sc->space == NULL) { 118 printf ("%s: memory allocation for descriptors failed\n", 119 sc->sc_dev.dv_xname); 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 = (u_char *)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 = (u_char *)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 = (u_char *)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 = (u_char *)SOALIGN(sc, p); 168 169 if ((p - pp) > PAGE_SIZE) { 170 printf ("%s: sizeof RRA (%ld) + CDA (%ld) +" 171 "TDA (%ld) > PAGE_SIZE (%d). Punt!\n", 172 sc->sc_dev.dv_xname, 173 (ulong)sc->p_cda - (ulong)sc->p_rra[0], 174 (ulong)sc->mtda[0].mtd_txp - (ulong)sc->p_cda, 175 (ulong)p - (ulong)sc->mtda[0].mtd_txp, 176 PAGE_SIZE); 177 return 1; 178 } 179 180 p = pp + PAGE_SIZE; 181 pp = p; 182 183 sc->sc_nrda = PAGE_SIZE / RXPKT_SIZE(sc); 184 sc->p_rda = (void *)p; 185 sc->v_rda = SONIC_GETDMA(p); 186 187 p = pp + PAGE_SIZE; 188 189 for (i = 0; i < NRBA; i++) { 190 sc->rbuf[i] = (void *)p; 191 p += PAGE_SIZE; 192 } 193 194 pp = p; 195 for (i = 0; i < NTDA; i++) { 196 struct mtd *mtdp = &sc->mtda[i]; 197 198 mtdp->mtd_buf = p; 199 mtdp->mtd_vbuf = SONIC_GETDMA(p); 200 p += TXBSIZE; 201 } 202 203 #ifdef SNDEBUG 204 camdump(sc); 205 #endif 206 printf("%s: Ethernet address %s\n", 207 sc->sc_dev.dv_xname, ether_sprintf(lladdr)); 208 209 #ifdef SNDEBUG 210 printf("%s: buffers: rra=%p cda=%p rda=%p tda=%p\n", 211 sc->sc_dev.dv_xname, sc->p_rra[0], sc->p_cda, 212 sc->p_rda, sc->mtda[0].mtd_txp); 213 #endif 214 215 strcpy(ifp->if_xname, sc->sc_dev.dv_xname); 216 ifp->if_softc = sc; 217 ifp->if_ioctl = snioctl; 218 ifp->if_start = snstart; 219 ifp->if_flags = 220 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; 221 ifp->if_watchdog = snwatchdog; 222 if_attach(ifp); 223 ether_ifattach(ifp, lladdr); 224 225 return 0; 226 } 227 228 static int 229 snioctl(struct ifnet *ifp, u_long cmd, void *data) 230 { 231 struct ifaddr *ifa; 232 struct sn_softc *sc = ifp->if_softc; 233 int s = splnet(), err = 0; 234 int temp; 235 236 switch (cmd) { 237 238 case SIOCSIFADDR: 239 ifa = (struct ifaddr *)data; 240 ifp->if_flags |= IFF_UP; 241 switch (ifa->ifa_addr->sa_family) { 242 #ifdef INET 243 case AF_INET: 244 (void)sninit(sc); 245 arp_ifinit(ifp, ifa); 246 break; 247 #endif 248 default: 249 (void)sninit(sc); 250 break; 251 } 252 break; 253 254 case SIOCSIFFLAGS: 255 if ((ifp->if_flags & IFF_UP) == 0 && 256 (ifp->if_flags & IFF_RUNNING) != 0) { 257 /* 258 * If interface is marked down and it is running, 259 * then stop it. 260 */ 261 snstop(sc); 262 ifp->if_flags &= ~IFF_RUNNING; 263 } else if ((ifp->if_flags & IFF_UP) != 0 && 264 (ifp->if_flags & IFF_RUNNING) == 0) { 265 /* 266 * If interface is marked up and it is stopped, 267 * then start it. 268 */ 269 (void)sninit(sc); 270 } else { 271 /* 272 * reset the interface to pick up any other changes 273 * in flags 274 */ 275 temp = ifp->if_flags & IFF_UP; 276 snreset(sc); 277 ifp->if_flags |= temp; 278 snstart(ifp); 279 } 280 break; 281 282 case SIOCADDMULTI: 283 case SIOCDELMULTI: 284 if ((err = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 285 /* 286 * Multicast list has changed; set the hardware 287 * filter accordingly. But remember UP flag! 288 */ 289 if (ifp->if_flags & IFF_RUNNING) { 290 temp = ifp->if_flags & IFF_UP; 291 snreset(sc); 292 ifp->if_flags |= temp; 293 } 294 err = 0; 295 } 296 break; 297 default: 298 err = EINVAL; 299 } 300 splx(s); 301 return err; 302 } 303 304 /* 305 * Encapsulate a packet of type family for the local net. 306 */ 307 static void 308 snstart(struct ifnet *ifp) 309 { 310 struct sn_softc *sc = ifp->if_softc; 311 struct mbuf *m; 312 int mtd_next; 313 314 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 315 return; 316 317 outloop: 318 /* Check for room in the xmit buffer. */ 319 if ((mtd_next = (sc->mtd_free + 1)) == NTDA) 320 mtd_next = 0; 321 322 if (mtd_next == sc->mtd_hw) { 323 ifp->if_flags |= IFF_OACTIVE; 324 return; 325 } 326 327 IF_DEQUEUE(&ifp->if_snd, m); 328 if (m == 0) 329 return; 330 331 /* We need the header for m_pkthdr.len. */ 332 if ((m->m_flags & M_PKTHDR) == 0) 333 panic("%s: snstart: no header mbuf", sc->sc_dev.dv_xname); 334 335 #if NBPFILTER > 0 336 /* 337 * If bpf is listening on this interface, let it 338 * see the packet before we commit it to the wire. 339 */ 340 if (ifp->if_bpf) 341 bpf_mtap(ifp->if_bpf, m); 342 #endif 343 344 /* 345 * If there is nothing in the o/p queue, and there is room in 346 * the Tx ring, then send the packet directly. Otherwise append 347 * it to the o/p queue. 348 */ 349 if ((sonicput(sc, m, mtd_next)) == 0) { 350 IF_PREPEND(&ifp->if_snd, m); 351 return; 352 } 353 354 sc->mtd_prev = sc->mtd_free; 355 sc->mtd_free = mtd_next; 356 357 ifp->if_opackets++; /* # of pkts */ 358 359 /* Jump back for possibly more punishment. */ 360 goto outloop; 361 } 362 363 /* 364 * reset and restart the SONIC. Called in case of fatal 365 * hardware/software errors. 366 */ 367 static void 368 snreset(struct sn_softc *sc) 369 { 370 371 snstop(sc); 372 sninit(sc); 373 } 374 375 static int 376 sninit(struct sn_softc *sc) 377 { 378 u_long s_rcr; 379 int s; 380 381 if (sc->sc_if.if_flags & IFF_RUNNING) 382 /* already running */ 383 return 0; 384 385 s = splnet(); 386 387 NIC_PUT(sc, SNR_CR, CR_RST); /* DCR only accessible in reset mode! */ 388 389 /* config it */ 390 NIC_PUT(sc, SNR_DCR, (sc->snr_dcr | 391 (sc->bitmode ? DCR_DW32 : DCR_DW16))); 392 NIC_PUT(sc, SNR_DCR2, sc->snr_dcr2); 393 394 s_rcr = RCR_BRD | RCR_LBNONE; 395 if (sc->sc_if.if_flags & IFF_PROMISC) 396 s_rcr |= RCR_PRO; 397 if (sc->sc_if.if_flags & IFF_ALLMULTI) 398 s_rcr |= RCR_AMC; 399 NIC_PUT(sc, SNR_RCR, s_rcr); 400 401 #if 0 402 NIC_PUT(sc, SNR_IMR, (IMR_PRXEN | IMR_PTXEN | IMR_TXEREN | IMR_LCDEN)); 403 #else 404 NIC_PUT(sc, SNR_IMR, IMR_PRXEN | IMR_PTXEN | IMR_TXEREN | IMR_LCDEN | 405 IMR_BREN | IMR_HBLEN | IMR_RDEEN | IMR_RBEEN | 406 IMR_RBAEEN | IMR_RFOEN); 407 #endif 408 409 /* clear pending interrupts */ 410 NIC_PUT(sc, SNR_ISR, ISR_ALL); 411 412 /* clear tally counters */ 413 NIC_PUT(sc, SNR_CRCT, -1); 414 NIC_PUT(sc, SNR_FAET, -1); 415 NIC_PUT(sc, SNR_MPT, -1); 416 417 initialise_tda(sc); 418 initialise_rda(sc); 419 initialise_rra(sc); 420 421 sn_md_init(sc); /* MD initialization */ 422 423 /* enable the chip */ 424 NIC_PUT(sc, SNR_CR, 0); 425 wbflush(); 426 427 /* program the CAM */ 428 camprogram(sc); 429 430 /* get it to read resource descriptors */ 431 NIC_PUT(sc, SNR_CR, CR_RRRA); 432 wbflush(); 433 while ((NIC_GET(sc, SNR_CR)) & CR_RRRA) 434 continue; 435 436 /* enable rx */ 437 NIC_PUT(sc, SNR_CR, CR_RXEN); 438 wbflush(); 439 440 /* flag interface as "running" */ 441 sc->sc_if.if_flags |= IFF_RUNNING; 442 sc->sc_if.if_flags &= ~IFF_OACTIVE; 443 444 splx(s); 445 return 0; 446 } 447 448 /* 449 * close down an interface and free its buffers 450 * Called on final close of device, or if sninit() fails 451 * part way through. 452 */ 453 static int 454 snstop(struct sn_softc *sc) 455 { 456 struct mtd *mtd; 457 int s = splnet(); 458 459 /* stick chip in reset */ 460 NIC_PUT(sc, SNR_CR, CR_RST); 461 wbflush(); 462 463 /* free all receive buffers (currently static so nothing to do) */ 464 465 /* free all pending transmit mbufs */ 466 while (sc->mtd_hw != sc->mtd_free) { 467 mtd = &sc->mtda[sc->mtd_hw]; 468 if (mtd->mtd_mbuf) 469 m_freem(mtd->mtd_mbuf); 470 if (++sc->mtd_hw == NTDA) sc->mtd_hw = 0; 471 } 472 473 sc->sc_if.if_timer = 0; 474 sc->sc_if.if_flags &= ~(IFF_RUNNING | IFF_UP); 475 476 splx(s); 477 return 0; 478 } 479 480 /* 481 * Called if any Tx packets remain unsent after 5 seconds, 482 * In all cases we just reset the chip, and any retransmission 483 * will be handled by higher level protocol timeouts. 484 */ 485 static void 486 snwatchdog(struct ifnet *ifp) 487 { 488 struct sn_softc *sc = ifp->if_softc; 489 struct mtd *mtd; 490 int temp; 491 492 if (sc->mtd_hw != sc->mtd_free) { 493 /* something still pending for transmit */ 494 mtd = &sc->mtda[sc->mtd_hw]; 495 if (SRO(sc->bitmode, mtd->mtd_txp, TXP_STATUS) == 0) 496 log(LOG_ERR, "%s: Tx - timeout\n", 497 sc->sc_dev.dv_xname); 498 else 499 log(LOG_ERR, "%s: Tx - lost interrupt\n", 500 sc->sc_dev.dv_xname); 501 temp = ifp->if_flags & IFF_UP; 502 snreset(sc); 503 ifp->if_flags |= temp; 504 } 505 } 506 507 /* 508 * stuff packet into sonic (at splnet) 509 */ 510 static inline u_int 511 sonicput(struct sn_softc *sc, struct mbuf *m0, int mtd_next) 512 { 513 struct mtd *mtdp; 514 struct mbuf *m; 515 u_char *buff; 516 void *txp; 517 u_int len = 0; 518 u_int totlen = 0; 519 520 #ifdef whyonearthwouldyoudothis 521 if (NIC_GET(sc, SNR_CR) & CR_TXP) 522 return 0; 523 #endif 524 525 /* grab the replacement mtd */ 526 mtdp = &sc->mtda[sc->mtd_free]; 527 528 buff = mtdp->mtd_buf; 529 530 /* this packet goes to mtdnext fill in the TDA */ 531 mtdp->mtd_mbuf = m0; 532 txp = mtdp->mtd_txp; 533 534 /* Write to the config word. Every (NTDA/2)+1 packets we set an intr */ 535 if (sc->mtd_pint == 0) { 536 sc->mtd_pint = NTDA/2; 537 SWO(sc->bitmode, txp, TXP_CONFIG, TCR_PINT); 538 } else { 539 sc->mtd_pint--; 540 SWO(sc->bitmode, txp, TXP_CONFIG, 0); 541 } 542 543 for (m = m0; m; m = m->m_next) { 544 u_char *data = mtod(m, u_char *); 545 len = m->m_len; 546 totlen += len; 547 memcpy(buff, data, len); 548 buff += len; 549 } 550 if (totlen >= TXBSIZE) { 551 panic("%s: sonicput: packet overflow", sc->sc_dev.dv_xname); 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, 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, LLADDR(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", sc->sc_dev.dv_xname); 688 } 689 timeout = 10000; 690 while (((NIC_GET(sc, SNR_ISR) & ISR_LCD) == 0) && timeout--) 691 delay(10); 692 693 if (NIC_GET(sc, SNR_ISR) & ISR_LCD) 694 NIC_PUT(sc, SNR_ISR, ISR_LCD); 695 else 696 printf("%s: CAM initialisation without interrupt\n", 697 sc->sc_dev.dv_xname); 698 } 699 700 #ifdef SNDEBUG 701 static void 702 camdump(struct sn_softc *sc) 703 { 704 int i; 705 706 printf("CAM entries:\n"); 707 NIC_PUT(sc, SNR_CR, CR_RST); 708 wbflush(); 709 710 for (i = 0; i < 16; i++) { 711 ushort ap2, ap1, ap0; 712 NIC_PUT(sc, SNR_CEP, i); 713 wbflush(); 714 ap2 = NIC_GET(sc, SNR_CAP2); 715 ap1 = NIC_GET(sc, SNR_CAP1); 716 ap0 = NIC_GET(sc, SNR_CAP0); 717 printf("%d: ap2=0x%x ap1=0x%x ap0=0x%x\n", i, ap2, ap1, ap0); 718 } 719 printf("CAM enable 0x%x\n", NIC_GET(sc, SNR_CEP)); 720 721 NIC_PUT(sc, SNR_CR, 0); 722 wbflush(); 723 } 724 #endif 725 726 static void 727 initialise_tda(struct sn_softc *sc) 728 { 729 struct mtd *mtd; 730 int i; 731 732 for (i = 0; i < NTDA; i++) { 733 mtd = &sc->mtda[i]; 734 mtd->mtd_mbuf = 0; 735 } 736 737 sc->mtd_hw = 0; 738 sc->mtd_prev = NTDA - 1; 739 sc->mtd_free = 0; 740 sc->mtd_tlinko = TXP_FRAGOFF + 1*TXP_FRAGSIZE + TXP_FPTRLO; 741 sc->mtd_pint = NTDA/2; 742 743 NIC_PUT(sc, SNR_UTDA, UPPER(sc->mtda[0].mtd_vtxp)); 744 NIC_PUT(sc, SNR_CTDA, LOWER(sc->mtda[0].mtd_vtxp)); 745 } 746 747 static void 748 initialise_rda(struct sn_softc *sc) 749 { 750 int i; 751 char *p_rda = 0; 752 uint32_t v_rda = 0; 753 754 /* link the RDA's together into a circular list */ 755 for (i = 0; i < (sc->sc_nrda - 1); i++) { 756 p_rda = (char *)sc->p_rda + (i * RXPKT_SIZE(sc)); 757 v_rda = sc->v_rda + ((i+1) * RXPKT_SIZE(sc)); 758 SWO(bitmode, p_rda, RXPKT_RLINK, LOWER(v_rda)); 759 SWO(bitmode, p_rda, RXPKT_INUSE, 1); 760 } 761 p_rda = (char *)sc->p_rda + ((sc->sc_nrda - 1) * RXPKT_SIZE(sc)); 762 SWO(bitmode, p_rda, RXPKT_RLINK, LOWER(sc->v_rda) | EOL); 763 SWO(bitmode, p_rda, RXPKT_INUSE, 1); 764 765 /* mark end of receive descriptor list */ 766 sc->sc_rdamark = sc->sc_nrda - 1; 767 768 sc->sc_rxmark = 0; 769 770 NIC_PUT(sc, SNR_URDA, UPPER(sc->v_rda)); 771 NIC_PUT(sc, SNR_CRDA, LOWER(sc->v_rda)); 772 wbflush(); 773 } 774 775 static void 776 initialise_rra(struct sn_softc *sc) 777 { 778 int i; 779 u_int v; 780 int bitmode = sc->bitmode; 781 782 if (bitmode) 783 NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 2); 784 else 785 NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 1); 786 787 NIC_PUT(sc, SNR_URRA, UPPER(sc->v_rra[0])); 788 NIC_PUT(sc, SNR_RSA, LOWER(sc->v_rra[0])); 789 /* rea must point just past the end of the rra space */ 790 NIC_PUT(sc, SNR_REA, LOWER(sc->v_rea)); 791 NIC_PUT(sc, SNR_RRP, LOWER(sc->v_rra[0])); 792 NIC_PUT(sc, SNR_RSC, 0); 793 794 /* fill up SOME of the rra with buffers */ 795 for (i = 0; i < NRBA; i++) { 796 v = SONIC_GETDMA(sc->rbuf[i]); 797 SWO(bitmode, sc->p_rra[i], RXRSRC_PTRHI, UPPER(v)); 798 SWO(bitmode, sc->p_rra[i], RXRSRC_PTRLO, LOWER(v)); 799 SWO(bitmode, sc->p_rra[i], RXRSRC_WCHI, UPPER(PAGE_SIZE/2)); 800 SWO(bitmode, sc->p_rra[i], RXRSRC_WCLO, LOWER(PAGE_SIZE/2)); 801 } 802 sc->sc_rramark = NRBA; 803 NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[sc->sc_rramark])); 804 wbflush(); 805 } 806 807 int 808 snintr(void *arg) 809 { 810 struct sn_softc *sc = (struct sn_softc *)arg; 811 int handled = 0; 812 int isr; 813 814 while ((isr = (NIC_GET(sc, SNR_ISR) & ISR_ALL)) != 0) { 815 /* scrub the interrupts that we are going to service */ 816 NIC_PUT(sc, SNR_ISR, isr); 817 handled = 1; 818 wbflush(); 819 820 if (isr & (ISR_BR | ISR_LCD | ISR_TC)) 821 printf("%s: unexpected interrupt status 0x%x\n", 822 sc->sc_dev.dv_xname, isr); 823 824 if (isr & (ISR_TXDN | ISR_TXER | ISR_PINT)) 825 sonictxint(sc); 826 827 if (isr & ISR_PKTRX) 828 sonicrxint(sc); 829 830 if (isr & (ISR_HBL | ISR_RDE | ISR_RBE | ISR_RBAE | ISR_RFO)) { 831 if (isr & ISR_HBL) 832 /* 833 * The repeater is not providing a heartbeat. 834 * In itself this isn't harmful, lots of the 835 * cheap repeater hubs don't supply a heartbeat. 836 * So ignore the lack of heartbeat. Its only 837 * if we can't detect a carrier that we have a 838 * problem. 839 */ 840 ; 841 if (isr & ISR_RDE) 842 printf("%s: receive descriptors exhausted\n", 843 sc->sc_dev.dv_xname); 844 if (isr & ISR_RBE) 845 printf("%s: receive buffers exhausted\n", 846 sc->sc_dev.dv_xname); 847 if (isr & ISR_RBAE) 848 printf("%s: receive buffer area exhausted\n", 849 sc->sc_dev.dv_xname); 850 if (isr & ISR_RFO) 851 printf("%s: receive FIFO overrun\n", 852 sc->sc_dev.dv_xname); 853 } 854 if (isr & (ISR_CRC | ISR_FAE | ISR_MP)) { 855 #ifdef notdef 856 if (isr & ISR_CRC) 857 sc->sc_crctally++; 858 if (isr & ISR_FAE) 859 sc->sc_faetally++; 860 if (isr & ISR_MP) 861 sc->sc_mptally++; 862 #endif 863 } 864 snstart(&sc->sc_if); 865 } 866 return handled; 867 } 868 869 /* 870 * Transmit interrupt routine 871 */ 872 static void 873 sonictxint(struct sn_softc *sc) 874 { 875 struct mtd *mtd; 876 void *txp; 877 unsigned short txp_status; 878 int mtd_hw; 879 struct ifnet *ifp = &sc->sc_if; 880 881 mtd_hw = sc->mtd_hw; 882 883 if (mtd_hw == sc->mtd_free) 884 return; 885 886 while (mtd_hw != sc->mtd_free) { 887 mtd = &sc->mtda[mtd_hw]; 888 889 txp = mtd->mtd_txp; 890 891 if (SRO(sc->bitmode, txp, TXP_STATUS) == 0) { 892 break; /* it hasn't really gone yet */ 893 } 894 895 #ifdef SNDEBUG 896 { 897 struct ether_header *eh; 898 899 eh = (struct ether_header *) mtd->mtd_buf; 900 printf("%s: xmit status=0x%x len=%d type=0x%x from %s", 901 sc->sc_dev.dv_xname, 902 SRO(sc->bitmode, txp, TXP_STATUS), 903 SRO(sc->bitmode, txp, TXP_PKTSIZE), 904 htons(eh->ether_type), 905 ether_sprintf(eh->ether_shost)); 906 printf(" (to %s)\n", ether_sprintf(eh->ether_dhost)); 907 } 908 #endif /* SNDEBUG */ 909 910 ifp->if_flags &= ~IFF_OACTIVE; 911 912 if (mtd->mtd_mbuf != 0) { 913 m_freem(mtd->mtd_mbuf); 914 mtd->mtd_mbuf = 0; 915 } 916 if (++mtd_hw == NTDA) mtd_hw = 0; 917 918 txp_status = SRO(sc->bitmode, txp, TXP_STATUS); 919 920 ifp->if_collisions += (txp_status & TCR_EXC) ? 16 : 921 ((txp_status & TCR_NC) >> 12); 922 923 if ((txp_status & TCR_PTX) == 0) { 924 ifp->if_oerrors++; 925 printf("%s: Tx packet status=0x%x\n", 926 sc->sc_dev.dv_xname, txp_status); 927 928 /* XXX - DG This looks bogus */ 929 if (mtd_hw != sc->mtd_free) { 930 printf("resubmitting remaining packets\n"); 931 mtd = &sc->mtda[mtd_hw]; 932 NIC_PUT(sc, SNR_CTDA, LOWER(mtd->mtd_vtxp)); 933 NIC_PUT(sc, SNR_CR, CR_TXP); 934 wbflush(); 935 break; 936 } 937 } 938 } 939 940 sc->mtd_hw = mtd_hw; 941 return; 942 } 943 944 /* 945 * Receive interrupt routine 946 */ 947 static void 948 sonicrxint(struct sn_softc *sc) 949 { 950 void * rda; 951 int orra; 952 int len; 953 int rramark; 954 int rdamark; 955 uint16_t rxpkt_ptr; 956 957 rda = (char *)sc->p_rda + (sc->sc_rxmark * RXPKT_SIZE(sc)); 958 959 while (SRO(bitmode, rda, RXPKT_INUSE) == 0) { 960 u_int status = SRO(bitmode, rda, RXPKT_STATUS); 961 962 orra = RBASEQ(SRO(bitmode, rda, RXPKT_SEQNO)) & RRAMASK; 963 rxpkt_ptr = SRO(bitmode, rda, RXPKT_PTRLO); 964 len = SRO(bitmode, rda, RXPKT_BYTEC) - FCSSIZE; 965 if (status & RCR_PRX) { 966 void *pkt = 967 (char *)sc->rbuf[orra & RBAMASK] + 968 (rxpkt_ptr & PGOFSET); 969 if (sonic_read(sc, pkt, len)) 970 sc->sc_if.if_ipackets++; 971 else 972 sc->sc_if.if_ierrors++; 973 } else 974 sc->sc_if.if_ierrors++; 975 976 /* 977 * give receive buffer area back to chip. 978 * 979 * If this was the last packet in the RRA, give the RRA to 980 * the chip again. 981 * If sonic read didnt copy it out then we would have to 982 * wait !! 983 * (dont bother add it back in again straight away) 984 * 985 * Really, we're doing p_rra[rramark] = p_rra[orra] but 986 * we have to use the macros because SONIC might be in 987 * 16 or 32 bit mode. 988 */ 989 if (status & RCR_LPKT) { 990 void *tmp1, *tmp2; 991 992 rramark = sc->sc_rramark; 993 tmp1 = sc->p_rra[rramark]; 994 tmp2 = sc->p_rra[orra]; 995 SWO(bitmode, tmp1, RXRSRC_PTRLO, 996 SRO(bitmode, tmp2, RXRSRC_PTRLO)); 997 SWO(bitmode, tmp1, RXRSRC_PTRHI, 998 SRO(bitmode, tmp2, RXRSRC_PTRHI)); 999 SWO(bitmode, tmp1, RXRSRC_WCLO, 1000 SRO(bitmode, tmp2, RXRSRC_WCLO)); 1001 SWO(bitmode, tmp1, RXRSRC_WCHI, 1002 SRO(bitmode, tmp2, RXRSRC_WCHI)); 1003 1004 /* zap old rra for fun */ 1005 SWO(bitmode, tmp2, RXRSRC_WCHI, 0); 1006 SWO(bitmode, tmp2, RXRSRC_WCLO, 0); 1007 1008 sc->sc_rramark = (++rramark) & RRAMASK; 1009 NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[rramark])); 1010 wbflush(); 1011 } 1012 1013 /* 1014 * give receive descriptor back to chip simple 1015 * list is circular 1016 */ 1017 rdamark = sc->sc_rdamark; 1018 SWO(bitmode, rda, RXPKT_INUSE, 1); 1019 SWO(bitmode, rda, RXPKT_RLINK, 1020 SRO(bitmode, rda, RXPKT_RLINK) | EOL); 1021 SWO(bitmode, ((char *)sc->p_rda + (rdamark * RXPKT_SIZE(sc))), 1022 RXPKT_RLINK, 1023 SRO(bitmode, ((char *)sc->p_rda + 1024 (rdamark * RXPKT_SIZE(sc))), 1025 RXPKT_RLINK) & ~EOL); 1026 sc->sc_rdamark = sc->sc_rxmark; 1027 1028 if (++sc->sc_rxmark >= sc->sc_nrda) 1029 sc->sc_rxmark = 0; 1030 rda = (char *)sc->p_rda + (sc->sc_rxmark * RXPKT_SIZE(sc)); 1031 } 1032 } 1033 1034 /* 1035 * sonic_read -- pull packet off interface and forward to 1036 * appropriate protocol handler 1037 */ 1038 static inline int 1039 sonic_read(struct sn_softc *sc, void *pkt, int len) 1040 { 1041 struct ifnet *ifp = &sc->sc_if; 1042 struct mbuf *m; 1043 1044 #ifdef SNDEBUG 1045 { 1046 printf("%s: rcvd %p len=%d type=0x%x from %s", 1047 sc->sc_dev.dv_xname, et, len, htons(et->ether_type), 1048 ether_sprintf(et->ether_shost)); 1049 printf(" (to %s)\n", ether_sprintf(et->ether_dhost)); 1050 } 1051 #endif /* SNDEBUG */ 1052 1053 if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN) || 1054 len > (ETHER_MAX_LEN - ETHER_CRC_LEN)) { 1055 printf("%s: invalid packet length %d bytes\n", 1056 sc->sc_dev.dv_xname, len); 1057 return 0; 1058 } 1059 1060 m = sonic_get(sc, pkt, len); 1061 if (m == NULL) 1062 return 0; 1063 #if NBPFILTER > 0 1064 /* Pass the packet to any BPF listeners. */ 1065 if (ifp->if_bpf) 1066 bpf_mtap(ifp->if_bpf, m); 1067 #endif 1068 (*ifp->if_input)(ifp, m); 1069 return 1; 1070 } 1071 1072 /* 1073 * munge the received packet into an mbuf chain 1074 */ 1075 static inline struct mbuf * 1076 sonic_get(struct sn_softc *sc, void *pkt, int datalen) 1077 { 1078 struct mbuf *m, *top, **mp; 1079 int len; 1080 1081 MGETHDR(m, M_DONTWAIT, MT_DATA); 1082 if (m == 0) 1083 return 0; 1084 m->m_pkthdr.rcvif = &sc->sc_if; 1085 m->m_pkthdr.len = datalen; 1086 len = MHLEN; 1087 top = 0; 1088 mp = ⊤ 1089 1090 while (datalen > 0) { 1091 if (top) { 1092 MGET(m, M_DONTWAIT, MT_DATA); 1093 if (m == 0) { 1094 m_freem(top); 1095 return 0; 1096 } 1097 len = MLEN; 1098 } 1099 if (datalen >= MINCLSIZE) { 1100 MCLGET(m, M_DONTWAIT); 1101 if ((m->m_flags & M_EXT) == 0) { 1102 if (top) m_freem(top); 1103 return 0; 1104 } 1105 len = MCLBYTES; 1106 } 1107 1108 if (mp == &top) { 1109 char *newdata = (char *) 1110 ALIGN((char *)m->m_data + 1111 sizeof(struct ether_header)) - 1112 sizeof(struct ether_header); 1113 len -= newdata - m->m_data; 1114 m->m_data = newdata; 1115 } 1116 1117 m->m_len = len = min(datalen, len); 1118 1119 memcpy(mtod(m, void *), pkt, (unsigned) len); 1120 pkt = (char *)pkt + len; 1121 datalen -= len; 1122 *mp = m; 1123 mp = &m->m_next; 1124 } 1125 1126 return top; 1127 } 1128