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