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