1/* $FreeBSD$ */ 2/* $NecBSD: dp83932.c,v 1.5 1999/07/29 05:08:44 kmatsuda Exp $ */ 3/* $NetBSD: if_snc.c,v 1.18 1998/04/25 21:27:40 scottr Exp $ */ 4 5/*- 6 * Copyright (c) 1997, 1998, 1999 7 * Kouichi Matsuda. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Kouichi Matsuda for 20 * NetBSD/pc98. 21 * 4. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36/* 37 * Modified for FreeBSD(98) 4.0 from NetBSD/pc98 1.4.2 by Motomichi Matsuzaki. 38 */ 39 40/* 41 * Modified for NetBSD/pc98 1.2G from NetBSD/mac68k 1.2G by Kouichi Matsuda. 42 * Make adapted for NEC PC-9801-83, 84, PC-9801-103, 104, PC-9801N-25 and 43 * PC-9801N-J02, J02R, which uses National Semiconductor DP83934AVQB as 44 * Ethernet Controller and National Semiconductor NS46C46 as 45 * (64 * 16 bits) Microwire Serial EEPROM. 46 */ 47 48/*- 49 * National Semiconductor DP8393X SONIC Driver 50 * Copyright (c) 1991 Algorithmics Ltd (http://www.algor.co.uk) 51 * You may use, copy, and modify this program so long as you retain the 52 * copyright line. 53 * 54 * This driver has been substantially modified since Algorithmics donated 55 * it. 56 * 57 * Denton Gentry <denny1@home.com> 58 * and also 59 * Yanagisawa Takeshi <yanagisw@aa.ap.titech.ac.jp> 60 * did the work to get this running on the Macintosh. 61 */ 62 63#include "opt_inet.h" 64 65#include <sys/param.h> 66#include <sys/kernel.h> 67#include <sys/systm.h> 68#include <sys/sockio.h> 69#include <sys/mbuf.h> 70#include <sys/protosw.h> 71#include <sys/socket.h> 72#include <sys/syslog.h> 73#include <sys/errno.h> 74 75#include <net/ethernet.h> 76#include <net/if.h> 77#include <net/if_var.h> 78#include <net/if_arp.h> 79#include <net/if_dl.h> 80#include <net/if_media.h> 81#include <net/if_types.h> 82 83#include <net/bpf.h> 84 85#include <sys/bus.h> 86#include <machine/bus.h> 87#include <dev/snc/dp83932reg.h> 88#include <dev/snc/dp83932var.h> 89 90static void sncwatchdog(void *); 91static void sncinit(void *); 92static void sncinit_locked(struct snc_softc *); 93static int sncstop(struct snc_softc *sc); 94static int sncioctl(struct ifnet *ifp, u_long cmd, caddr_t data); 95static void sncstart(struct ifnet *ifp); 96static void sncstart_locked(struct ifnet *ifp); 97static void sncreset(struct snc_softc *sc); 98 99static void caminitialise(struct snc_softc *); 100static void camentry(struct snc_softc *, int, u_char *ea); 101static void camprogram(struct snc_softc *); 102static void initialise_tda(struct snc_softc *); 103static void initialise_rda(struct snc_softc *); 104static void initialise_rra(struct snc_softc *); 105#ifdef SNCDEBUG 106static void camdump(struct snc_softc *sc); 107#endif 108 109static void sonictxint(struct snc_softc *); 110static void sonicrxint(struct snc_softc *); 111 112static u_int sonicput(struct snc_softc *sc, struct mbuf *m0, int mtd_next); 113static int sonic_read(struct snc_softc *, u_int32_t, int); 114static struct mbuf *sonic_get(struct snc_softc *, u_int32_t, int); 115 116int snc_enable(struct snc_softc *); 117void snc_disable(struct snc_softc *); 118 119int snc_mediachange(struct ifnet *); 120void snc_mediastatus(struct ifnet *, struct ifmediareq *); 121 122#undef assert 123#undef _assert 124 125#ifdef NDEBUG 126#define assert(e) ((void)0) 127#define _assert(e) ((void)0) 128#else 129#define _assert(e) assert(e) 130#ifdef __STDC__ 131#define assert(e) ((e) ? (void)0 : __assert("snc ", __FILE__, __LINE__, #e)) 132#else /* PCC */ 133#define assert(e) ((e) ? (void)0 : __assert("snc "__FILE__, __LINE__, "e")) 134#endif 135#endif 136 137#ifdef SNCDEBUG 138#define SNC_SHOWTXHDR 0x01 /* show tx ether_header */ 139#define SNC_SHOWRXHDR 0x02 /* show rx ether_header */ 140#define SNC_SHOWCAMENT 0x04 /* show CAM entry */ 141#endif /* SNCDEBUG */ 142int sncdebug = 0; 143 144 145int 146sncconfig(struct snc_softc *sc, int *media, int nmedia, int defmedia, 147 u_int8_t *myea) 148{ 149 struct ifnet *ifp; 150 int i; 151 152#ifdef SNCDEBUG 153 if ((sncdebug & SNC_SHOWCAMENT) != 0) { 154 camdump(sc); 155 } 156#endif 157 158 ifp = sc->sc_ifp = if_alloc(IFT_ETHER); 159 if (ifp == NULL) { 160 device_printf(sc->sc_dev, "can not if_alloc()\n"); 161 return (ENOMEM); 162 } 163 164#ifdef SNCDEBUG 165 device_printf(sc->sc_dev, 166 "buffers: rra=0x%x cda=0x%x rda=0x%x tda=0x%x\n", 167 sc->v_rra[0], sc->v_cda, 168 sc->v_rda, sc->mtda[0].mtd_vtxp); 169#endif 170 171 ifp->if_softc = sc; 172 if_initname(ifp, device_get_name(sc->sc_dev), 173 device_get_unit(sc->sc_dev)); 174 ifp->if_ioctl = sncioctl; 175 ifp->if_start = sncstart; 176 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 177 ifp->if_init = sncinit; 178 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 179 180 /* Initialize media goo. */ 181 ifmedia_init(&sc->sc_media, 0, snc_mediachange, 182 snc_mediastatus); 183 if (media != NULL) { 184 for (i = 0; i < nmedia; i++) 185 ifmedia_add(&sc->sc_media, media[i], 0, NULL); 186 ifmedia_set(&sc->sc_media, defmedia); 187 } else { 188 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL); 189 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); 190 } 191 192 ether_ifattach(ifp, myea); 193 return (0); 194} 195 196void 197sncshutdown(void *arg) 198{ 199 struct snc_softc *sc = arg; 200 201 SNC_ASSERT_LOCKED(sc); 202 sncstop(sc); 203} 204 205/* 206 * Media change callback. 207 */ 208int 209snc_mediachange(struct ifnet *ifp) 210{ 211 struct snc_softc *sc = ifp->if_softc; 212 int error; 213 214 SNC_LOCK(sc); 215 if (sc->sc_mediachange) 216 error = (*sc->sc_mediachange)(sc); 217 else 218 error = EINVAL; 219 SNC_UNLOCK(sc); 220 return (error); 221} 222 223/* 224 * Media status callback. 225 */ 226void 227snc_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 228{ 229 struct snc_softc *sc = ifp->if_softc; 230 231 SNC_LOCK(sc); 232 if (sc->sc_enabled == 0) { 233 ifmr->ifm_active = IFM_ETHER | IFM_NONE; 234 ifmr->ifm_status = 0; 235 SNC_UNLOCK(sc); 236 return; 237 } 238 239 if (sc->sc_mediastatus) 240 (*sc->sc_mediastatus)(sc, ifmr); 241 SNC_UNLOCK(sc); 242} 243 244 245static int 246sncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 247{ 248 struct ifreq *ifr; 249 struct snc_softc *sc = ifp->if_softc; 250 int err = 0; 251 252 switch (cmd) { 253 254 case SIOCSIFFLAGS: 255 SNC_LOCK(sc); 256 if ((ifp->if_flags & IFF_UP) == 0 && 257 (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { 258 /* 259 * If interface is marked down and it is running, 260 * then stop it. 261 */ 262 sncstop(sc); 263 snc_disable(sc); 264 } else if ((ifp->if_flags & IFF_UP) != 0 && 265 (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 266 /* 267 * If interface is marked up and it is stopped, 268 * then start it. 269 */ 270 if ((err = snc_enable(sc)) != 0) 271 break; 272 sncinit_locked(sc); 273 } else if (sc->sc_enabled) { 274 /* 275 * reset the interface to pick up any other changes 276 * in flags 277 */ 278 sncreset(sc); 279 sncstart_locked(ifp); 280 } 281 SNC_UNLOCK(sc); 282 break; 283 284 case SIOCADDMULTI: 285 case SIOCDELMULTI: 286 SNC_LOCK(sc); 287 if (sc->sc_enabled == 0) { 288 err = EIO; 289 SNC_UNLOCK(sc); 290 break; 291 } 292 sncreset(sc); 293 SNC_UNLOCK(sc); 294 err = 0; 295 break; 296 case SIOCGIFMEDIA: 297 case SIOCSIFMEDIA: 298 ifr = (struct ifreq *) data; 299 err = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); 300 break; 301 default: 302 err = ether_ioctl(ifp, cmd, data); 303 break; 304 } 305 return (err); 306} 307 308/* 309 * Encapsulate a packet of type family for the local net. 310 */ 311static void 312sncstart(struct ifnet *ifp) 313{ 314 struct snc_softc *sc = ifp->if_softc; 315 316 SNC_LOCK(sc); 317 sncstart_locked(ifp); 318 SNC_UNLOCK(sc); 319} 320 321static void 322sncstart_locked(struct ifnet *ifp) 323{ 324 struct snc_softc *sc = ifp->if_softc; 325 struct mbuf *m; 326 int mtd_next; 327 328 if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != 329 IFF_DRV_RUNNING) 330 return; 331 332outloop: 333 /* Check for room in the xmit buffer. */ 334 if ((mtd_next = (sc->mtd_free + 1)) == NTDA) 335 mtd_next = 0; 336 337 if (mtd_next == sc->mtd_hw) { 338 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 339 return; 340 } 341 342 IF_DEQUEUE(&ifp->if_snd, m); 343 if (m == 0) 344 return; 345 346 /* We need the header for m_pkthdr.len. */ 347 M_ASSERTPKTHDR(m); 348 349 /* 350 * If there is nothing in the o/p queue, and there is room in 351 * the Tx ring, then send the packet directly. Otherwise append 352 * it to the o/p queue. 353 */ 354 if ((sonicput(sc, m, mtd_next)) == 0) { 355 IF_PREPEND(&ifp->if_snd, m); 356 return; 357 } 358 359 /* 360 * If bpf is listening on this interface, let it see the packet 361 * before we commit it to the wire, but only if we are really 362 * committed to send it. 363 * 364 * XXX: Locking must protect m against premature m_freem() in 365 * sonictxint(). 366 */ 367 BPF_MTAP(ifp, m); 368 369 sc->mtd_prev = sc->mtd_free; 370 sc->mtd_free = mtd_next; 371 372 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); /* # of pkts */ 373 374 /* Jump back for possibly more punishment. */ 375 goto outloop; 376} 377 378/* 379 * reset and restart the SONIC. Called in case of fatal 380 * hardware/software errors. 381 */ 382static void 383sncreset(struct snc_softc *sc) 384{ 385 sncstop(sc); 386 sncinit_locked(sc); 387} 388 389static void 390sncinit(void *xsc) 391{ 392 struct snc_softc *sc = xsc; 393 394 SNC_LOCK(sc); 395 sncinit_locked(sc); 396 SNC_UNLOCK(sc); 397} 398 399static void 400sncinit_locked(struct snc_softc *sc) 401{ 402 u_long s_rcr; 403 404 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) 405 /* already running */ 406 return; 407 408 NIC_PUT(sc, SNCR_CR, CR_RST); /* DCR only accessible in reset mode! */ 409 410 /* config it */ 411 NIC_PUT(sc, SNCR_DCR, (sc->sncr_dcr | 412 (sc->bitmode ? DCR_DW32 : DCR_DW16))); 413 NIC_PUT(sc, SNCR_DCR2, sc->sncr_dcr2); 414 415 s_rcr = RCR_BRD | RCR_LBNONE; 416 if (sc->sc_ifp->if_flags & IFF_PROMISC) 417 s_rcr |= RCR_PRO; 418 if (sc->sc_ifp->if_flags & IFF_ALLMULTI) 419 s_rcr |= RCR_AMC; 420 NIC_PUT(sc, SNCR_RCR, s_rcr); 421 422 NIC_PUT(sc, SNCR_IMR, (IMR_PRXEN | IMR_PTXEN | IMR_TXEREN | IMR_LCDEN)); 423 424 /* clear pending interrupts */ 425 NIC_PUT(sc, SNCR_ISR, ISR_ALL); 426 427 /* clear tally counters */ 428 NIC_PUT(sc, SNCR_CRCT, -1); 429 NIC_PUT(sc, SNCR_FAET, -1); 430 NIC_PUT(sc, SNCR_MPT, -1); 431 432 initialise_tda(sc); 433 initialise_rda(sc); 434 initialise_rra(sc); 435 436 /* enable the chip */ 437 NIC_PUT(sc, SNCR_CR, 0); 438 wbflush(); 439 440 /* program the CAM */ 441 camprogram(sc); 442 443 /* get it to read resource descriptors */ 444 NIC_PUT(sc, SNCR_CR, CR_RRRA); 445 wbflush(); 446 while ((NIC_GET(sc, SNCR_CR)) & CR_RRRA) 447 continue; 448 449 /* enable rx */ 450 NIC_PUT(sc, SNCR_CR, CR_RXEN); 451 wbflush(); 452 453 /* flag interface as "running" */ 454 sc->sc_ifp->if_drv_flags |= IFF_DRV_RUNNING; 455 sc->sc_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 456 callout_reset(&sc->sc_timer, hz, sncwatchdog, sc); 457 458 return; 459} 460 461/* 462 * close down an interface and free its buffers 463 * Called on final close of device, or if sncinit() fails 464 * part way through. 465 */ 466static int 467sncstop(struct snc_softc *sc) 468{ 469 struct mtd *mtd; 470 471 SNC_ASSERT_LOCKED(sc); 472 473 /* stick chip in reset */ 474 NIC_PUT(sc, SNCR_CR, CR_RST); 475 wbflush(); 476 477 /* free all receive buffers (currently static so nothing to do) */ 478 479 /* free all pending transmit mbufs */ 480 while (sc->mtd_hw != sc->mtd_free) { 481 mtd = &sc->mtda[sc->mtd_hw]; 482 if (mtd->mtd_mbuf) 483 m_freem(mtd->mtd_mbuf); 484 if (++sc->mtd_hw == NTDA) sc->mtd_hw = 0; 485 } 486 487 callout_stop(&sc->sc_timer); 488 sc->sc_tx_timeout = 0; 489 sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 490 491 return (0); 492} 493 494/* 495 * Called if any Tx packets remain unsent after 5 seconds, 496 * In all cases we just reset the chip, and any retransmission 497 * will be handled by higher level protocol timeouts. 498 */ 499static void 500sncwatchdog(void *arg) 501{ 502 struct snc_softc *sc = arg; 503 struct mtd *mtd; 504 505 SNC_ASSERT_LOCKED(sc); 506 if (sc->sc_tx_timeout && --sc->sc_tx_timeout == 0) { 507 if (sc->mtd_hw != sc->mtd_free) { 508 /* something still pending for transmit */ 509 mtd = &sc->mtda[sc->mtd_hw]; 510 if (SRO(sc, mtd->mtd_vtxp, TXP_STATUS) == 0) 511 log(LOG_ERR, "%s: Tx - timeout\n", 512 device_get_nameunit(sc->sc_dev)); 513 else 514 log(LOG_ERR, "%s: Tx - lost interrupt\n", 515 device_get_nameunit(sc->sc_dev)); 516 sncreset(sc); 517 } 518 } 519 callout_reset(&sc->sc_timer, hz, sncwatchdog, sc); 520} 521 522/* 523 * stuff packet into sonic 524 */ 525static u_int 526sonicput(struct snc_softc *sc, struct mbuf *m0, int mtd_next) 527{ 528 struct mtd *mtdp; 529 struct mbuf *m; 530 u_int32_t buff; 531 u_int32_t txp; 532 u_int len = 0; 533 u_int totlen = 0; 534 535#ifdef whyonearthwouldyoudothis 536 if (NIC_GET(sc, SNCR_CR) & CR_TXP) 537 return (0); 538#endif 539 540 /* grab the replacement mtd */ 541 mtdp = &sc->mtda[sc->mtd_free]; 542 543 buff = mtdp->mtd_vbuf; 544 545 /* this packet goes to mtdnext fill in the TDA */ 546 mtdp->mtd_mbuf = m0; 547 txp = mtdp->mtd_vtxp; 548 549 /* Write to the config word. Every (NTDA/2)+1 packets we set an intr */ 550 if (sc->mtd_pint == 0) { 551 sc->mtd_pint = NTDA/2; 552 SWO(sc, txp, TXP_CONFIG, TCR_PINT); 553 } else { 554 sc->mtd_pint--; 555 SWO(sc, txp, TXP_CONFIG, 0); 556 } 557 558 for (m = m0; m; m = m->m_next) { 559 len = m->m_len; 560 totlen += len; 561 (*sc->sc_copytobuf)(sc, mtod(m, caddr_t), buff, len); 562 buff += len; 563 } 564 if (totlen >= TXBSIZE) { 565 panic("%s: sonicput: packet overflow", 566 device_get_nameunit(sc->sc_dev)); 567 } 568 569 SWO(sc, txp, TXP_FRAGOFF + (0 * TXP_FRAGSIZE) + TXP_FPTRLO, 570 LOWER(mtdp->mtd_vbuf)); 571 SWO(sc, txp, TXP_FRAGOFF + (0 * TXP_FRAGSIZE) + TXP_FPTRHI, 572 UPPER(mtdp->mtd_vbuf)); 573 574 if (totlen < ETHERMIN + sizeof(struct ether_header)) { 575 int pad = ETHERMIN + sizeof(struct ether_header) - totlen; 576 (*sc->sc_zerobuf)(sc, mtdp->mtd_vbuf + totlen, pad); 577 totlen = ETHERMIN + sizeof(struct ether_header); 578 } 579 580 SWO(sc, txp, TXP_FRAGOFF + (0 * TXP_FRAGSIZE) + TXP_FSIZE, 581 totlen); 582 SWO(sc, txp, TXP_FRAGCNT, 1); 583 SWO(sc, txp, TXP_PKTSIZE, totlen); 584 585 /* link onto the next mtd that will be used */ 586 SWO(sc, txp, TXP_FRAGOFF + (1 * TXP_FRAGSIZE) + TXP_FPTRLO, 587 LOWER(sc->mtda[mtd_next].mtd_vtxp) | EOL); 588 589 /* 590 * The previous txp.tlink currently contains a pointer to 591 * our txp | EOL. Want to clear the EOL, so write our 592 * pointer to the previous txp. 593 */ 594 SWO(sc, sc->mtda[sc->mtd_prev].mtd_vtxp, sc->mtd_tlinko, 595 LOWER(mtdp->mtd_vtxp)); 596 597 /* make sure chip is running */ 598 wbflush(); 599 NIC_PUT(sc, SNCR_CR, CR_TXP); 600 wbflush(); 601 602 /* 5 seconds to watch for failing to transmit */ 603 sc->sc_tx_timeout = 5; 604 605 return (totlen); 606} 607 608/* 609 * These are called from sonicioctl() when /etc/ifconfig is run to set 610 * the address or switch the i/f on. 611 */ 612/* 613 * CAM support 614 */ 615static void 616caminitialise(struct snc_softc *sc) 617{ 618 u_int32_t v_cda = sc->v_cda; 619 int i; 620 int camoffset; 621 622 for (i = 0; i < MAXCAM; i++) { 623 camoffset = i * CDA_CAMDESC; 624 SWO(sc, v_cda, (camoffset + CDA_CAMEP), i); 625 SWO(sc, v_cda, (camoffset + CDA_CAMAP2), 0); 626 SWO(sc, v_cda, (camoffset + CDA_CAMAP1), 0); 627 SWO(sc, v_cda, (camoffset + CDA_CAMAP0), 0); 628 } 629 SWO(sc, v_cda, CDA_ENABLE, 0); 630 631#ifdef SNCDEBUG 632 if ((sncdebug & SNC_SHOWCAMENT) != 0) { 633 camdump(sc); 634 } 635#endif 636} 637 638static void 639camentry(struct snc_softc *sc, int entry, u_char *ea) 640{ 641 u_int32_t v_cda = sc->v_cda; 642 int camoffset = entry * CDA_CAMDESC; 643 644 SWO(sc, v_cda, camoffset + CDA_CAMEP, entry); 645 SWO(sc, v_cda, camoffset + CDA_CAMAP2, (ea[5] << 8) | ea[4]); 646 SWO(sc, v_cda, camoffset + CDA_CAMAP1, (ea[3] << 8) | ea[2]); 647 SWO(sc, v_cda, camoffset + CDA_CAMAP0, (ea[1] << 8) | ea[0]); 648 SWO(sc, v_cda, CDA_ENABLE, 649 (SRO(sc, v_cda, CDA_ENABLE) | (1 << entry))); 650} 651 652static void 653camprogram(struct snc_softc *sc) 654{ 655 struct ifmultiaddr *ifma; 656 struct ifnet *ifp; 657 int timeout; 658 int mcount = 0; 659 660 caminitialise(sc); 661 662 ifp = sc->sc_ifp; 663 664 /* Always load our own address first. */ 665 camentry (sc, mcount, IF_LLADDR(sc->sc_ifp)); 666 mcount++; 667 668 /* Assume we won't need allmulti bit. */ 669 ifp->if_flags &= ~IFF_ALLMULTI; 670 671 /* Loop through multicast addresses */ 672 if_maddr_rlock(ifp); 673 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 674 if (ifma->ifma_addr->sa_family != AF_LINK) 675 continue; 676 if (mcount == MAXCAM) { 677 ifp->if_flags |= IFF_ALLMULTI; 678 break; 679 } 680 681 /* program the CAM with the specified entry */ 682 camentry(sc, mcount, 683 LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); 684 mcount++; 685 } 686 if_maddr_runlock(ifp); 687 688 NIC_PUT(sc, SNCR_CDP, LOWER(sc->v_cda)); 689 NIC_PUT(sc, SNCR_CDC, MAXCAM); 690 NIC_PUT(sc, SNCR_CR, CR_LCAM); 691 wbflush(); 692 693 timeout = 10000; 694 while ((NIC_GET(sc, SNCR_CR) & CR_LCAM) && timeout--) 695 continue; 696 if (timeout == 0) { 697 /* XXX */ 698 panic("%s: CAM initialisation failed\n", 699 device_get_nameunit(sc->sc_dev)); 700 } 701 timeout = 10000; 702 while (((NIC_GET(sc, SNCR_ISR) & ISR_LCD) == 0) && timeout--) 703 continue; 704 705 if (NIC_GET(sc, SNCR_ISR) & ISR_LCD) 706 NIC_PUT(sc, SNCR_ISR, ISR_LCD); 707 else 708 device_printf(sc->sc_dev, 709 "CAM initialisation without interrupt\n"); 710} 711 712#ifdef SNCDEBUG 713static void 714camdump(struct snc_softc *sc) 715{ 716 int i; 717 718 printf("CAM entries:\n"); 719 NIC_PUT(sc, SNCR_CR, CR_RST); 720 wbflush(); 721 722 for (i = 0; i < 16; i++) { 723 u_short ap2, ap1, ap0; 724 NIC_PUT(sc, SNCR_CEP, i); 725 wbflush(); 726 ap2 = NIC_GET(sc, SNCR_CAP2); 727 ap1 = NIC_GET(sc, SNCR_CAP1); 728 ap0 = NIC_GET(sc, SNCR_CAP0); 729 printf("%d: ap2=0x%x ap1=0x%x ap0=0x%x\n", i, ap2, ap1, ap0); 730 } 731 printf("CAM enable 0x%x\n", NIC_GET(sc, SNCR_CEP)); 732 733 NIC_PUT(sc, SNCR_CR, 0); 734 wbflush(); 735} 736#endif 737 738static void 739initialise_tda(struct snc_softc *sc) 740{ 741 struct mtd *mtd; 742 int i; 743 744 for (i = 0; i < NTDA; i++) { 745 mtd = &sc->mtda[i]; 746 mtd->mtd_mbuf = 0; 747 } 748 749 sc->mtd_hw = 0; 750 sc->mtd_prev = NTDA - 1; 751 sc->mtd_free = 0; 752 sc->mtd_tlinko = TXP_FRAGOFF + 1*TXP_FRAGSIZE + TXP_FPTRLO; 753 sc->mtd_pint = NTDA/2; 754 755 NIC_PUT(sc, SNCR_UTDA, UPPER(sc->mtda[0].mtd_vtxp)); 756 NIC_PUT(sc, SNCR_CTDA, LOWER(sc->mtda[0].mtd_vtxp)); 757} 758 759static void 760initialise_rda(struct snc_softc *sc) 761{ 762 int i; 763 u_int32_t vv_rda = 0; 764 u_int32_t v_rda = 0; 765 766 /* link the RDA's together into a circular list */ 767 for (i = 0; i < (sc->sc_nrda - 1); i++) { 768 v_rda = sc->v_rda + (i * RXPKT_SIZE(sc)); 769 vv_rda = sc->v_rda + ((i+1) * RXPKT_SIZE(sc)); 770 SWO(sc, v_rda, RXPKT_RLINK, LOWER(vv_rda)); 771 SWO(sc, v_rda, RXPKT_INUSE, 1); 772 } 773 v_rda = sc->v_rda + ((sc->sc_nrda - 1) * RXPKT_SIZE(sc)); 774 SWO(sc, v_rda, RXPKT_RLINK, LOWER(sc->v_rda) | EOL); 775 SWO(sc, v_rda, RXPKT_INUSE, 1); 776 777 /* mark end of receive descriptor list */ 778 sc->sc_rdamark = sc->sc_nrda - 1; 779 780 sc->sc_rxmark = 0; 781 782 NIC_PUT(sc, SNCR_URDA, UPPER(sc->v_rda)); 783 NIC_PUT(sc, SNCR_CRDA, LOWER(sc->v_rda)); 784 wbflush(); 785} 786 787static void 788initialise_rra(struct snc_softc *sc) 789{ 790 int i; 791 u_int v; 792 int bitmode = sc->bitmode; 793 794 if (bitmode) 795 NIC_PUT(sc, SNCR_EOBC, RBASIZE(sc) / 2 - 2); 796 else 797 NIC_PUT(sc, SNCR_EOBC, RBASIZE(sc) / 2 - 1); 798 799 NIC_PUT(sc, SNCR_URRA, UPPER(sc->v_rra[0])); 800 NIC_PUT(sc, SNCR_RSA, LOWER(sc->v_rra[0])); 801 /* rea must point just past the end of the rra space */ 802 NIC_PUT(sc, SNCR_REA, LOWER(sc->v_rea)); 803 NIC_PUT(sc, SNCR_RRP, LOWER(sc->v_rra[0])); 804 NIC_PUT(sc, SNCR_RSC, 0); 805 806 /* fill up SOME of the rra with buffers */ 807 for (i = 0; i < NRBA; i++) { 808 v = SONIC_GETDMA(sc->rbuf[i]); 809 SWO(sc, sc->v_rra[i], RXRSRC_PTRHI, UPPER(v)); 810 SWO(sc, sc->v_rra[i], RXRSRC_PTRLO, LOWER(v)); 811 SWO(sc, sc->v_rra[i], RXRSRC_WCHI, UPPER(PAGE_SIZE/2)); 812 SWO(sc, sc->v_rra[i], RXRSRC_WCLO, LOWER(PAGE_SIZE/2)); 813 } 814 sc->sc_rramark = NRBA; 815 NIC_PUT(sc, SNCR_RWP, LOWER(sc->v_rra[sc->sc_rramark])); 816 wbflush(); 817} 818 819void 820sncintr(void *arg) 821{ 822 struct snc_softc *sc = (struct snc_softc *)arg; 823 int isr; 824 825 if (sc->sc_enabled == 0) 826 return; 827 828 SNC_LOCK(sc); 829 while ((isr = (NIC_GET(sc, SNCR_ISR) & ISR_ALL)) != 0) { 830 /* scrub the interrupts that we are going to service */ 831 NIC_PUT(sc, SNCR_ISR, isr); 832 wbflush(); 833 834 if (isr & (ISR_BR | ISR_LCD | ISR_TC)) 835 device_printf(sc->sc_dev, 836 "unexpected interrupt status 0x%x\n", 837 isr); 838 839 if (isr & (ISR_TXDN | ISR_TXER | ISR_PINT)) 840 sonictxint(sc); 841 842 if (isr & ISR_PKTRX) 843 sonicrxint(sc); 844 845 if (isr & (ISR_HBL | ISR_RDE | ISR_RBE | ISR_RBAE | ISR_RFO)) { 846 if (isr & ISR_HBL) 847 /* 848 * The repeater is not providing a heartbeat. 849 * In itself this isn't harmful, lots of the 850 * cheap repeater hubs don't supply a heartbeat. 851 * So ignore the lack of heartbeat. Its only 852 * if we can't detect a carrier that we have a 853 * problem. 854 */ 855 ; 856 if (isr & ISR_RDE) 857 device_printf(sc->sc_dev, 858 "receive descriptors exhausted\n"); 859 if (isr & ISR_RBE) 860 device_printf(sc->sc_dev, 861 "receive buffers exhausted\n"); 862 if (isr & ISR_RBAE) 863 device_printf(sc->sc_dev, 864 "receive buffer area exhausted\n"); 865 if (isr & ISR_RFO) 866 device_printf(sc->sc_dev, 867 "receive FIFO overrun\n"); 868 } 869 if (isr & (ISR_CRC | ISR_FAE | ISR_MP)) { 870#ifdef notdef 871 if (isr & ISR_CRC) 872 sc->sc_crctally++; 873 if (isr & ISR_FAE) 874 sc->sc_faetally++; 875 if (isr & ISR_MP) 876 sc->sc_mptally++; 877#endif 878 } 879 sncstart_locked(sc->sc_ifp); 880 } 881 SNC_UNLOCK(sc); 882 return; 883} 884 885/* 886 * Transmit interrupt routine 887 */ 888static void 889sonictxint(struct snc_softc *sc) 890{ 891 struct mtd *mtd; 892 u_int32_t txp; 893 unsigned short txp_status; 894 int mtd_hw; 895 struct ifnet *ifp = sc->sc_ifp; 896 897 mtd_hw = sc->mtd_hw; 898 899 if (mtd_hw == sc->mtd_free) 900 return; 901 902 while (mtd_hw != sc->mtd_free) { 903 mtd = &sc->mtda[mtd_hw]; 904 905 txp = mtd->mtd_vtxp; 906 907 if (SRO(sc, txp, TXP_STATUS) == 0) { 908 break; /* it hasn't really gone yet */ 909 } 910 911#ifdef SNCDEBUG 912 if ((sncdebug & SNC_SHOWTXHDR) != 0) 913 { 914 struct ether_header eh; 915 916 (*sc->sc_copyfrombuf)(sc, &eh, mtd->mtd_vbuf, sizeof(eh)); 917 device_printf(sc->sc_dev, 918 "xmit status=0x%x len=%d type=0x%x from %6D", 919 SRO(sc, txp, TXP_STATUS), 920 SRO(sc, txp, TXP_PKTSIZE), 921 htons(eh.ether_type), 922 eh.ether_shost, ":"); 923 printf(" (to %6D)\n", eh.ether_dhost, ":"); 924 } 925#endif /* SNCDEBUG */ 926 927 sc->sc_tx_timeout = 0; 928 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 929 930 if (mtd->mtd_mbuf != 0) { 931 m_freem(mtd->mtd_mbuf); 932 mtd->mtd_mbuf = 0; 933 } 934 if (++mtd_hw == NTDA) mtd_hw = 0; 935 936 txp_status = SRO(sc, txp, TXP_STATUS); 937 938 if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 939 (txp_status & TCR_EXC) ? 16 : 940 ((txp_status & TCR_NC) >> 12)); 941 942 if ((txp_status & TCR_PTX) == 0) { 943 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 944 device_printf(sc->sc_dev, "Tx packet status=0x%x\n", 945 txp_status); 946 947 /* XXX - DG This looks bogus */ 948 if (mtd_hw != sc->mtd_free) { 949 printf("resubmitting remaining packets\n"); 950 mtd = &sc->mtda[mtd_hw]; 951 NIC_PUT(sc, SNCR_CTDA, LOWER(mtd->mtd_vtxp)); 952 NIC_PUT(sc, SNCR_CR, CR_TXP); 953 wbflush(); 954 break; 955 } 956 } 957 } 958 959 sc->mtd_hw = mtd_hw; 960 return; 961} 962 963/* 964 * Receive interrupt routine 965 */ 966static void 967sonicrxint(struct snc_softc *sc) 968{ 969 u_int32_t rda; 970 int orra; 971 int len; 972 int rramark; 973 int rdamark; 974 u_int16_t rxpkt_ptr; 975 976 rda = sc->v_rda + (sc->sc_rxmark * RXPKT_SIZE(sc)); 977 978 while (SRO(sc, rda, RXPKT_INUSE) == 0) { 979 u_int status = SRO(sc, rda, RXPKT_STATUS); 980 981 orra = RBASEQ(SRO(sc, rda, RXPKT_SEQNO)) & RRAMASK; 982 rxpkt_ptr = SRO(sc, rda, RXPKT_PTRLO); 983 /* 984 * Do not trunc ether_header length. 985 * Our sonic_read() and sonic_get() require it. 986 */ 987 len = SRO(sc, rda, RXPKT_BYTEC) - FCSSIZE; 988 if (status & RCR_PRX) { 989 /* XXX: Does PAGE_MASK require? */ 990 u_int32_t pkt = 991 sc->rbuf[orra & RBAMASK] + (rxpkt_ptr & PAGE_MASK); 992 if (sonic_read(sc, pkt, len)) 993 if_inc_counter(sc->sc_ifp, IFCOUNTER_IPACKETS, 1); 994 else 995 if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1); 996 } else 997 if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1); 998 999 /* 1000 * give receive buffer area back to chip. 1001 * 1002 * If this was the last packet in the RRA, give the RRA to 1003 * the chip again. 1004 * If sonic read didn't copy it out then we would have to 1005 * wait !! 1006 * (dont bother add it back in again straight away) 1007 * 1008 * Really, we're doing v_rra[rramark] = v_rra[orra] but 1009 * we have to use the macros because SONIC might be in 1010 * 16 or 32 bit mode. 1011 */ 1012 if (status & RCR_LPKT) { 1013 u_int32_t tmp1, tmp2; 1014 1015 rramark = sc->sc_rramark; 1016 tmp1 = sc->v_rra[rramark]; 1017 tmp2 = sc->v_rra[orra]; 1018 SWO(sc, tmp1, RXRSRC_PTRLO, 1019 SRO(sc, tmp2, RXRSRC_PTRLO)); 1020 SWO(sc, tmp1, RXRSRC_PTRHI, 1021 SRO(sc, tmp2, RXRSRC_PTRHI)); 1022 SWO(sc, tmp1, RXRSRC_WCLO, 1023 SRO(sc, tmp2, RXRSRC_WCLO)); 1024 SWO(sc, tmp1, RXRSRC_WCHI, 1025 SRO(sc, tmp2, RXRSRC_WCHI)); 1026 1027 /* zap old rra for fun */ 1028 SWO(sc, tmp2, RXRSRC_WCHI, 0); 1029 SWO(sc, tmp2, RXRSRC_WCLO, 0); 1030 1031 sc->sc_rramark = (++rramark) & RRAMASK; 1032 NIC_PUT(sc, SNCR_RWP, LOWER(sc->v_rra[rramark])); 1033 wbflush(); 1034 } 1035 1036 /* 1037 * give receive descriptor back to chip simple 1038 * list is circular 1039 */ 1040 rdamark = sc->sc_rdamark; 1041 SWO(sc, rda, RXPKT_INUSE, 1); 1042 SWO(sc, rda, RXPKT_RLINK, 1043 SRO(sc, rda, RXPKT_RLINK) | EOL); 1044 SWO(sc, (sc->v_rda + (rdamark * RXPKT_SIZE(sc))), RXPKT_RLINK, 1045 SRO(sc, (sc->v_rda + (rdamark * RXPKT_SIZE(sc))), 1046 RXPKT_RLINK) & ~EOL); 1047 sc->sc_rdamark = sc->sc_rxmark; 1048 1049 if (++sc->sc_rxmark >= sc->sc_nrda) 1050 sc->sc_rxmark = 0; 1051 rda = sc->v_rda + (sc->sc_rxmark * RXPKT_SIZE(sc)); 1052 } 1053} 1054 1055/* 1056 * sonic_read -- pull packet off interface and forward to 1057 * appropriate protocol handler 1058 */ 1059static int 1060sonic_read(struct snc_softc *sc, u_int32_t pkt, int len) 1061{ 1062 struct ifnet *ifp = sc->sc_ifp; 1063 struct ether_header *et; 1064 struct mbuf *m; 1065 1066 if (len <= sizeof(struct ether_header) || 1067 len > ETHERMTU + sizeof(struct ether_header)) { 1068 device_printf(sc->sc_dev, 1069 "invalid packet length %d bytes\n", len); 1070 return (0); 1071 } 1072 1073 /* Pull packet off interface. */ 1074 m = sonic_get(sc, pkt, len); 1075 if (m == 0) { 1076 return (0); 1077 } 1078 1079 /* We assume that the header fit entirely in one mbuf. */ 1080 et = mtod(m, struct ether_header *); 1081 1082#ifdef SNCDEBUG 1083 if ((sncdebug & SNC_SHOWRXHDR) != 0) 1084 { 1085 device_printf(sc->sc_dev, "rcvd 0x%x len=%d type=0x%x from %6D", 1086 pkt, len, htons(et->ether_type), 1087 et->ether_shost, ":"); 1088 printf(" (to %6D)\n", et->ether_dhost, ":"); 1089 } 1090#endif /* SNCDEBUG */ 1091 1092 /* Pass the packet up. */ 1093 SNC_UNLOCK(sc); 1094 (*ifp->if_input)(ifp, m); 1095 SNC_LOCK(sc); 1096 return (1); 1097} 1098 1099 1100/* 1101 * munge the received packet into an mbuf chain 1102 */ 1103static struct mbuf * 1104sonic_get(struct snc_softc *sc, u_int32_t pkt, int datalen) 1105{ 1106 struct mbuf *m, *top, **mp; 1107 int len; 1108 /* 1109 * Do not trunc ether_header length. 1110 * Our sonic_read() and sonic_get() require it. 1111 */ 1112 1113 MGETHDR(m, M_NOWAIT, MT_DATA); 1114 if (m == 0) 1115 return (0); 1116 m->m_pkthdr.rcvif = sc->sc_ifp; 1117 m->m_pkthdr.len = datalen; 1118 len = MHLEN; 1119 top = 0; 1120 mp = ⊤ 1121 1122 while (datalen > 0) { 1123 if (top) { 1124 MGET(m, M_NOWAIT, MT_DATA); 1125 if (m == 0) { 1126 m_freem(top); 1127 return (0); 1128 } 1129 len = MLEN; 1130 } 1131 if (datalen >= MINCLSIZE) { 1132 if (!(MCLGET(m, M_NOWAIT))) { 1133 if (top) m_freem(top); 1134 return (0); 1135 } 1136 len = MCLBYTES; 1137 } 1138#if 0 1139 /* XXX: Require? */ 1140 if (!top) { 1141 register int pad = 1142 ALIGN(sizeof(struct ether_header)) - 1143 sizeof(struct ether_header); 1144 m->m_data += pad; 1145 len -= pad; 1146 } 1147#endif 1148 m->m_len = len = min(datalen, len); 1149 1150 (*sc->sc_copyfrombuf)(sc, mtod(m, caddr_t), pkt, len); 1151 pkt += len; 1152 datalen -= len; 1153 *mp = m; 1154 mp = &m->m_next; 1155 } 1156 1157 return (top); 1158} 1159/* 1160 * Enable power on the interface. 1161 */ 1162int 1163snc_enable(struct snc_softc *sc) 1164{ 1165 1166#ifdef SNCDEBUG 1167 device_printf(sc->sc_dev, "snc_enable()\n"); 1168#endif /* SNCDEBUG */ 1169 1170 if (sc->sc_enabled == 0 && sc->sc_enable != NULL) { 1171 if ((*sc->sc_enable)(sc) != 0) { 1172 device_printf(sc->sc_dev, "device enable failed\n"); 1173 return (EIO); 1174 } 1175 } 1176 1177 sc->sc_enabled = 1; 1178 return (0); 1179} 1180 1181/* 1182 * Disable power on the interface. 1183 */ 1184void 1185snc_disable(struct snc_softc *sc) 1186{ 1187 1188#ifdef SNCDEBUG 1189 device_printf(sc->sc_dev, "snc_disable()\n"); 1190#endif /* SNCDEBUG */ 1191 1192 if (sc->sc_enabled != 0 && sc->sc_disable != NULL) { 1193 (*sc->sc_disable)(sc); 1194 sc->sc_enabled = 0; 1195 } 1196} 1197 1198 1199