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