1 /* $OpenBSD: smc91cxx.c,v 1.17 2003/10/21 18:58:49 jmc Exp $ */ 2 /* $NetBSD: smc91cxx.c,v 1.11 1998/08/08 23:51:41 mycroft Exp $ */ 3 4 /*- 5 * Copyright (c) 1997 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 /* 42 * Copyright (c) 1996 Gardner Buchanan <gbuchanan@shl.com> 43 * All rights reserved. 44 * 45 * Redistribution and use in source and binary forms, with or without 46 * modification, are permitted provided that the following conditions 47 * are met: 48 * 1. Redistributions of source code must retain the above copyright 49 * notice, this list of conditions and the following disclaimer. 50 * 2. Redistributions in binary form must reproduce the above copyright 51 * notice, this list of conditions and the following disclaimer in the 52 * documentation and/or other materials provided with the distribution. 53 * 3. All advertising materials mentioning features or use of this software 54 * must display the following acknowledgement: 55 * This product includes software developed by Gardner Buchanan. 56 * 4. The name of Gardner Buchanan may not be used to endorse or promote 57 * products derived from this software without specific prior written 58 * permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 61 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 62 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 63 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 64 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 65 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 66 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 67 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 68 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 69 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 70 * 71 * from FreeBSD Id: if_sn.c,v 1.4 1996/03/18 15:47:16 gardner Exp 72 */ 73 74 /* 75 * Core driver for the SMC 91Cxx family of Ethernet chips. 76 * 77 * Memory allocation interrupt logic is drived from an SMC 91C90 driver 78 * written for NetBSD/amiga by Michael Hitch. 79 */ 80 81 #include "bpfilter.h" 82 83 #include <sys/param.h> 84 #include <sys/systm.h> 85 #include <sys/mbuf.h> 86 #include <sys/syslog.h> 87 #include <sys/socket.h> 88 #include <sys/device.h> 89 #include <sys/malloc.h> 90 #include <sys/ioctl.h> 91 #include <sys/errno.h> 92 #if NRND > 0 93 #include <sys/rnd.h> 94 #endif 95 96 #include <machine/bus.h> 97 #include <machine/intr.h> 98 99 #include <net/if.h> 100 #include <net/if_dl.h> 101 #include <net/if_media.h> 102 103 #ifdef INET 104 #include <netinet/in.h> 105 #include <netinet/if_ether.h> 106 #include <netinet/in_systm.h> 107 #include <netinet/in_var.h> 108 #include <netinet/ip.h> 109 #endif 110 111 #ifdef NS 112 #include <netns/ns.h> 113 #include <netns/ns_if.h> 114 #endif 115 116 #if defined(CCITT) && defined(LLC) 117 #include <sys/socketvar.h> 118 #include <netccitt/x25.h> 119 #include <netccitt/pk.h> 120 #include <netccitt/pk_var.h> 121 #include <netccitt/pk_extern.h> 122 #endif 123 124 #if NBPFILTER > 0 125 #include <net/bpf.h> 126 #include <net/bpfdesc.h> 127 #endif 128 129 #include <dev/ic/smc91cxxreg.h> 130 #include <dev/ic/smc91cxxvar.h> 131 132 /* XXX Hardware padding doesn't work yet(?) */ 133 #define SMC91CXX_SW_PAD 134 135 const char *smc91cxx_idstrs[] = { 136 NULL, /* 0 */ 137 NULL, /* 1 */ 138 NULL, /* 2 */ 139 "SMC91C90/91C92", /* 3 */ 140 "SMC91C94", /* 4 */ 141 "SMC91C95", /* 5 */ 142 NULL, /* 6 */ 143 "SMC91C100", /* 7 */ 144 NULL, /* 8 */ 145 NULL, /* 9 */ 146 NULL, /* 10 */ 147 NULL, /* 11 */ 148 NULL, /* 12 */ 149 NULL, /* 13 */ 150 NULL, /* 14 */ 151 NULL, /* 15 */ 152 }; 153 154 /* Supported media types. */ 155 const int smc91cxx_media[] = { 156 IFM_ETHER|IFM_10_T, 157 IFM_ETHER|IFM_10_5, 158 }; 159 #define NSMC91CxxMEDIA (sizeof(smc91cxx_media) / sizeof(smc91cxx_media[0])) 160 161 struct cfdriver sm_cd = { 162 NULL, "sm", DV_IFNET 163 }; 164 165 int smc91cxx_mediachange(struct ifnet *); 166 void smc91cxx_mediastatus(struct ifnet *, struct ifmediareq *); 167 168 int smc91cxx_set_media(struct smc91cxx_softc *, int); 169 170 void smc91cxx_read(struct smc91cxx_softc *); 171 void smc91cxx_reset(struct smc91cxx_softc *); 172 void smc91cxx_start(struct ifnet *); 173 void smc91cxx_resume(struct smc91cxx_softc *); 174 void smc91cxx_watchdog(struct ifnet *); 175 int smc91cxx_ioctl(struct ifnet *, u_long, caddr_t); 176 177 int smc91cxx_enable(struct smc91cxx_softc *); 178 void smc91cxx_disable(struct smc91cxx_softc *); 179 180 static __inline int ether_cmp(void *, void *); 181 static __inline int 182 ether_cmp(va, vb) 183 void *va, *vb; 184 { 185 u_int8_t *a = va; 186 u_int8_t *b = vb; 187 188 return ((a[5] != b[5]) || (a[4] != b[4]) || (a[3] != b[3]) || 189 (a[2] != b[2]) || (a[1] != b[1]) || (a[0] != b[0])); 190 } 191 192 void 193 smc91cxx_attach(sc, myea) 194 struct smc91cxx_softc *sc; 195 u_int8_t *myea; 196 { 197 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 198 bus_space_tag_t bst = sc->sc_bst; 199 bus_space_handle_t bsh = sc->sc_bsh; 200 u_int16_t tmp; 201 int i, aui; 202 #ifdef SMC_DEBUG 203 const char *idstr; 204 #endif 205 206 /* Make sure the chip is stopped. */ 207 smc91cxx_stop(sc); 208 209 #ifdef SMC_DEBUG 210 SMC_SELECT_BANK(sc, 3); 211 tmp = bus_space_read_2(bst, bsh, REVISION_REG_W); 212 idstr = smc91cxx_idstrs[RR_ID(tmp)]; 213 printf("%s: ", sc->sc_dev.dv_xname); 214 if (idstr != NULL) 215 printf("%s, ", idstr); 216 else 217 printf("unknown chip id %d, ", RR_ID(tmp)); 218 printf("revision %d\n", RR_REV(tmp)); 219 #endif 220 221 /* Read the station address from the chip. */ 222 SMC_SELECT_BANK(sc, 1); 223 if (myea == NULL) { 224 for (i = 0; i < ETHER_ADDR_LEN; i += 2) { 225 tmp = bus_space_read_2(bst, bsh, IAR_ADDR0_REG_W + i); 226 sc->sc_arpcom.ac_enaddr[i + 1] = (tmp >>8) & 0xff; 227 sc->sc_arpcom.ac_enaddr[i] = tmp & 0xff; 228 } 229 } else { 230 bcopy(myea, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); 231 } 232 233 printf(": address %s, ", 234 ether_sprintf(sc->sc_arpcom.ac_enaddr)); 235 236 /* ..and default media. */ 237 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); 238 printf("utp/aui (default %s)\n", (aui = (tmp & CR_AUI_SELECT)) ? 239 "aui" : "utp"); 240 241 /* Initialize the ifnet structure. */ 242 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 243 ifp->if_softc = sc; 244 ifp->if_start = smc91cxx_start; 245 ifp->if_ioctl = smc91cxx_ioctl; 246 ifp->if_watchdog = smc91cxx_watchdog; 247 ifp->if_flags = 248 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; 249 IFQ_SET_READY(&ifp->if_snd); 250 251 /* Attach the interface. */ 252 if_attach(ifp); 253 ether_ifattach(ifp); 254 255 /* Initialize the media structures. */ 256 ifmedia_init(&sc->sc_media, 0, smc91cxx_mediachange, 257 smc91cxx_mediastatus); 258 for (i = 0; i < NSMC91CxxMEDIA; i++) 259 ifmedia_add(&sc->sc_media, smc91cxx_media[i], 0, NULL); 260 ifmedia_set(&sc->sc_media, IFM_ETHER | (aui ? IFM_10_5 : IFM_10_T)); 261 262 #if NRND > 0 263 rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname, RND_TYPE_NET); 264 #endif 265 } 266 267 /* 268 * Change media according to request. 269 */ 270 int 271 smc91cxx_mediachange(ifp) 272 struct ifnet *ifp; 273 { 274 struct smc91cxx_softc *sc = ifp->if_softc; 275 276 return (smc91cxx_set_media(sc, sc->sc_media.ifm_media)); 277 } 278 279 int 280 smc91cxx_set_media(sc, media) 281 struct smc91cxx_softc *sc; 282 int media; 283 { 284 bus_space_tag_t bst = sc->sc_bst; 285 bus_space_handle_t bsh = sc->sc_bsh; 286 u_int16_t tmp; 287 288 /* 289 * If the interface is not currently powered on, just return. 290 * When it is enabled later, smc91cxx_init() will properly set 291 * up the media for us. 292 */ 293 if (sc->sc_enabled == 0) 294 return (0); 295 296 if (IFM_TYPE(media) != IFM_ETHER) 297 return (EINVAL); 298 299 switch (IFM_SUBTYPE(media)) { 300 case IFM_10_T: 301 case IFM_10_5: 302 SMC_SELECT_BANK(sc, 1); 303 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); 304 if (IFM_SUBTYPE(media) == IFM_10_5) 305 tmp |= CR_AUI_SELECT; 306 else 307 tmp &= ~CR_AUI_SELECT; 308 bus_space_write_2(bst, bsh, CONFIG_REG_W, tmp); 309 delay(20000); /* XXX is this needed? */ 310 break; 311 312 default: 313 return (EINVAL); 314 } 315 316 return (0); 317 } 318 319 /* 320 * Notify the world which media we're using. 321 */ 322 void 323 smc91cxx_mediastatus(ifp, ifmr) 324 struct ifnet *ifp; 325 struct ifmediareq *ifmr; 326 { 327 struct smc91cxx_softc *sc = ifp->if_softc; 328 bus_space_tag_t bst = sc->sc_bst; 329 bus_space_handle_t bsh = sc->sc_bsh; 330 u_int16_t tmp; 331 332 if (sc->sc_enabled == 0) { 333 ifmr->ifm_active = IFM_ETHER | IFM_NONE; 334 ifmr->ifm_status = 0; 335 return; 336 } 337 338 SMC_SELECT_BANK(sc, 1); 339 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); 340 ifmr->ifm_active = 341 IFM_ETHER | ((tmp & CR_AUI_SELECT) ? IFM_10_5 : IFM_10_T); 342 } 343 344 /* 345 * Reset and initialize the chip. 346 */ 347 void 348 smc91cxx_init(sc) 349 struct smc91cxx_softc *sc; 350 { 351 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 352 bus_space_tag_t bst = sc->sc_bst; 353 bus_space_handle_t bsh = sc->sc_bsh; 354 u_int16_t tmp; 355 int s, i; 356 357 s = splnet(); 358 359 /* 360 * This resets the registers mostly to defaults, but doesn't 361 * affect the EEPROM. After the reset cycle, we pause briefly 362 * for the chip to recover. 363 * 364 * XXX how long are we really supposed to delay? --thorpej 365 */ 366 SMC_SELECT_BANK(sc, 0); 367 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, RCR_SOFTRESET); 368 delay(100); 369 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0); 370 delay(200); 371 372 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0); 373 374 /* Set the Ethernet address. */ 375 SMC_SELECT_BANK(sc, 1); 376 for (i = 0; i < ETHER_ADDR_LEN; i++ ) 377 bus_space_write_1(bst, bsh, IAR_ADDR0_REG_W + i, 378 sc->sc_arpcom.ac_enaddr[i]); 379 380 /* 381 * Set the control register to automatically release successfully 382 * transmitted packets (making the best use of our limited memory) 383 * and enable the EPH interrupt on certain TX errors. 384 */ 385 bus_space_write_2(bst, bsh, CONTROL_REG_W, (CTR_AUTO_RELEASE | 386 CTR_TE_ENABLE | CTR_CR_ENABLE | CTR_LE_ENABLE)); 387 388 /* 389 * Reset the MMU and wait for it to be un-busy. 390 */ 391 SMC_SELECT_BANK(sc, 2); 392 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RESET); 393 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 394 /* XXX bound this loop! */ ; 395 396 /* 397 * Disable all interrupts. 398 */ 399 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0); 400 401 /* 402 * Set current media. 403 */ 404 smc91cxx_set_media(sc, sc->sc_media.ifm_cur->ifm_media); 405 406 /* 407 * Set the receive filter. We want receive enable and auto 408 * strip of CRC from received packet. If we are in promisc. mode, 409 * then set that bit as well. 410 * 411 * XXX Initialize multicast filter. For now, we just accept 412 * XXX all multicast. 413 */ 414 SMC_SELECT_BANK(sc, 0); 415 416 tmp = RCR_ENABLE | RCR_STRIP_CRC | RCR_ALMUL; 417 if (ifp->if_flags & IFF_PROMISC) 418 tmp |= RCR_PROMISC; 419 420 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, tmp); 421 422 /* 423 * Set transmitter control to "enabled". 424 */ 425 tmp = TCR_ENABLE; 426 427 #ifndef SMC91CXX_SW_PAD 428 /* 429 * Enable hardware padding of transmitted packets. 430 * XXX doesn't work? 431 */ 432 tmp |= TCR_PAD_ENABLE; 433 #endif 434 435 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, tmp); 436 437 /* 438 * Now, enable interrupts. 439 */ 440 SMC_SELECT_BANK(sc, 2); 441 442 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 443 IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | IM_TX_INT); 444 445 /* Interface is now running, with no output active. */ 446 ifp->if_flags |= IFF_RUNNING; 447 ifp->if_flags &= ~IFF_OACTIVE; 448 449 /* 450 * Attempt to start any pending transmission. 451 */ 452 smc91cxx_start(ifp); 453 454 splx(s); 455 } 456 457 /* 458 * Start output on an interface. 459 * Must be called at splnet or interrupt level. 460 */ 461 void 462 smc91cxx_start(ifp) 463 struct ifnet *ifp; 464 { 465 struct smc91cxx_softc *sc = ifp->if_softc; 466 bus_space_tag_t bst = sc->sc_bst; 467 bus_space_handle_t bsh = sc->sc_bsh; 468 u_int len; 469 struct mbuf *m, *top; 470 u_int16_t length, npages; 471 u_int8_t packetno; 472 int timo, pad; 473 474 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 475 return; 476 477 again: 478 /* 479 * Peek at the next packet. 480 */ 481 IFQ_POLL(&ifp->if_snd, m); 482 if (m == NULL) 483 return; 484 485 /* 486 * Compute the frame length and set pad to give an overall even 487 * number of bytes. Below, we assume that the packet length 488 * is even. 489 */ 490 for (len = 0, top = m; m != NULL; m = m->m_next) 491 len += m->m_len; 492 pad = (len & 1); 493 494 /* 495 * We drop packets that are too large. Perhaps we should 496 * truncate them instead? 497 */ 498 if ((len + pad) > (ETHER_MAX_LEN - ETHER_CRC_LEN)) { 499 printf("%s: large packet discarded\n", sc->sc_dev.dv_xname); 500 ifp->if_oerrors++; 501 IFQ_DEQUEUE(&ifp->if_snd, m); 502 m_freem(m); 503 goto readcheck; 504 } 505 506 #ifdef SMC91CXX_SW_PAD 507 /* 508 * Not using hardware padding; pad to ETHER_MIN_LEN. 509 */ 510 if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN)) 511 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len; 512 #endif 513 514 length = pad + len; 515 516 /* 517 * The MMU has a 256 byte page size. The MMU expects us to 518 * ask for "npages - 1". We include space for the status word, 519 * byte count, and control bytes in the allocation request. 520 */ 521 npages = (length + 6) >> 8; 522 523 /* 524 * Now allocate the memory. 525 */ 526 SMC_SELECT_BANK(sc, 2); 527 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ALLOC | npages); 528 529 timo = MEMORY_WAIT_TIME; 530 do { 531 if (bus_space_read_1(bst, bsh, INTR_STAT_REG_B) & IM_ALLOC_INT) 532 break; 533 delay(1); 534 } while (--timo); 535 536 packetno = bus_space_read_1(bst, bsh, ALLOC_RESULT_REG_B); 537 538 if (packetno & ARR_FAILED || timo == 0) { 539 /* 540 * No transmit memory is available. Record the number 541 * of requestd pages and enable the allocation completion 542 * interrupt. Set up the watchdog timer in case we miss 543 * the interrupt. Mark the interface as active so that 544 * no one else attempts to transmit while we're allocating 545 * memory. 546 */ 547 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 548 bus_space_read_1(bst, bsh, INTR_MASK_REG_B) | IM_ALLOC_INT); 549 550 ifp->if_timer = 5; 551 ifp->if_flags |= IFF_OACTIVE; 552 553 return; 554 } 555 556 /* 557 * We have a packet number - set the data window. 558 */ 559 bus_space_write_1(bst, bsh, PACKET_NUM_REG_B, packetno); 560 561 /* 562 * Point to the beginning of the packet. 563 */ 564 bus_space_write_2(bst, bsh, POINTER_REG_W, PTR_AUTOINC /* | 0x0000 */); 565 566 /* 567 * Send the packet length (+6 for stats, length, and control bytes) 568 * and the status word (set to zeros). 569 */ 570 bus_space_write_2(bst, bsh, DATA_REG_W, 0); 571 bus_space_write_1(bst, bsh, DATA_REG_B, (length + 6) & 0xff); 572 bus_space_write_1(bst, bsh, DATA_REG_B, ((length + 6) >> 8) & 0xff); 573 574 /* 575 * Get the packet from the kernel. This will include the Ethernet 576 * frame header, MAC address, etc. 577 */ 578 IFQ_DEQUEUE(&ifp->if_snd, m); 579 580 /* 581 * Push the packet out to the card. 582 */ 583 for (top = m; m != NULL; m = m->m_next) { 584 /* Words... */ 585 bus_space_write_multi_2(bst, bsh, DATA_REG_W, 586 mtod(m, u_int16_t *), m->m_len >> 1); 587 588 /* ...and the remaining byte, if any. */ 589 if (m->m_len & 1) 590 bus_space_write_1(bst, bsh, DATA_REG_B, 591 *(u_int8_t *)(mtod(m, u_int8_t *) + (m->m_len - 1))); 592 } 593 594 #ifdef SMC91CXX_SW_PAD 595 /* 596 * Push out padding. 597 */ 598 while (pad > 1) { 599 bus_space_write_2(bst, bsh, DATA_REG_W, 0); 600 pad -= 2; 601 } 602 if (pad) 603 bus_space_write_1(bst, bsh, DATA_REG_B, 0); 604 #endif 605 606 /* 607 * Push out control byte and unused packet byte. The control byte 608 * is 0, meaning the packet is even lengthed and no special 609 * CRC handling is necessary. 610 */ 611 bus_space_write_2(bst, bsh, DATA_REG_W, 0); 612 613 /* 614 * Enable transmit interrupts and let the chip go. Set a watchdog 615 * in case we miss the interrupt. 616 */ 617 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 618 bus_space_read_1(bst, bsh, INTR_MASK_REG_B) | 619 IM_TX_INT | IM_TX_EMPTY_INT); 620 621 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ENQUEUE); 622 623 ifp->if_timer = 5; 624 625 #if NBPFILTER > 0 626 /* Hand off a copy to the bpf. */ 627 if (ifp->if_bpf) 628 bpf_mtap(ifp->if_bpf, top); 629 #endif 630 631 ifp->if_opackets++; 632 m_freem(top); 633 634 readcheck: 635 /* 636 * Check for incoming pcakets. We don't want to overflow the small 637 * RX FIFO. If nothing has arrived, attempt to queue another 638 * transmit packet. 639 */ 640 if (bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) & FIFO_REMPTY) 641 goto again; 642 } 643 644 /* 645 * Interrupt service routine. 646 */ 647 int 648 smc91cxx_intr(arg) 649 void *arg; 650 { 651 struct smc91cxx_softc *sc = arg; 652 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 653 bus_space_tag_t bst = sc->sc_bst; 654 bus_space_handle_t bsh = sc->sc_bsh; 655 u_int8_t mask, interrupts, status; 656 u_int16_t packetno, tx_status, card_stats; 657 658 if (sc->sc_enabled == 0) 659 return (0); 660 661 SMC_SELECT_BANK(sc, 2); 662 663 /* 664 * Obtain the current interrupt mask. 665 */ 666 mask = bus_space_read_1(bst, bsh, INTR_MASK_REG_B); 667 668 /* 669 * Get the set of interrupt which occurred and eliminate any 670 * which are not enabled. 671 */ 672 interrupts = bus_space_read_1(bst, bsh, INTR_STAT_REG_B); 673 status = interrupts & mask; 674 675 /* Ours? */ 676 if (status == 0) 677 return (0); 678 679 /* 680 * It's ours; disable all interrupts while we process them. 681 */ 682 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0); 683 684 /* 685 * Receive overrun interrupts. 686 */ 687 if (status & IM_RX_OVRN_INT) { 688 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_RX_OVRN_INT); 689 ifp->if_ierrors++; 690 } 691 692 /* 693 * Receive interrupts. 694 */ 695 if (status & IM_RCV_INT) { 696 #if 1 /* DIAGNOSTIC */ 697 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W); 698 if (packetno & FIFO_REMPTY) 699 printf("%s: receive interrupt on empty fifo\n", 700 sc->sc_dev.dv_xname); 701 else 702 #endif 703 smc91cxx_read(sc); 704 } 705 706 /* 707 * Memory allocation interrupts. 708 */ 709 if (status & IM_ALLOC_INT) { 710 /* Disable this interrupt. */ 711 mask &= ~IM_ALLOC_INT; 712 713 /* 714 * Release the just-allocated memory. We will reallocate 715 * it through the normal start logic. 716 */ 717 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 718 /* XXX bound this loop! */ ; 719 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT); 720 721 ifp->if_flags &= ~IFF_OACTIVE; 722 ifp->if_timer = 0; 723 } 724 725 /* 726 * Transmit complete interrupt. Handle transmission error messages. 727 * This will only be called on error condition because of AUTO RELEASE 728 * mode. 729 */ 730 if (status & IM_TX_INT) { 731 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_TX_INT); 732 733 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) & 734 FIFO_TX_MASK; 735 736 /* 737 * Select this as the packet to read from. 738 */ 739 bus_space_write_1(bst, bsh, PACKET_NUM_REG_B, packetno); 740 741 /* 742 * Position the pointer to the beginning of the packet. 743 */ 744 bus_space_write_2(bst, bsh, POINTER_REG_W, 745 PTR_AUTOINC | PTR_READ /* | 0x0000 */); 746 747 /* 748 * Fetch the TX status word. This will be a copy of 749 * the EPH_STATUS_REG_W at the time of the transmission 750 * failure. 751 */ 752 tx_status = bus_space_read_2(bst, bsh, DATA_REG_W); 753 754 if (tx_status & EPHSR_TX_SUC) 755 printf("%s: successful packet caused TX interrupt?!\n", 756 sc->sc_dev.dv_xname); 757 else 758 ifp->if_oerrors++; 759 760 if (tx_status & EPHSR_LATCOL) 761 ifp->if_collisions++; 762 763 /* 764 * Some of these errors disable the transmitter; reenable it. 765 */ 766 SMC_SELECT_BANK(sc, 0); 767 #ifdef SMC91CXX_SW_PAD 768 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, TCR_ENABLE); 769 #else 770 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 771 TCR_ENABLE | TCR_PAD_ENABLE); 772 #endif 773 774 /* 775 * Kill the failed packet and wait for the MMU to unbusy. 776 */ 777 SMC_SELECT_BANK(sc, 2); 778 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 779 /* XXX bound this loop! */ ; 780 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT); 781 782 ifp->if_timer = 0; 783 } 784 785 /* 786 * Transmit underrun interrupts. We use this opportunity to 787 * update transmit statistics from the card. 788 */ 789 if (status & IM_TX_EMPTY_INT) { 790 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_TX_EMPTY_INT); 791 792 /* Disable this interrupt. */ 793 mask &= ~IM_TX_EMPTY_INT; 794 795 SMC_SELECT_BANK(sc, 0); 796 card_stats = bus_space_read_2(bst, bsh, COUNTER_REG_W); 797 798 /* Single collisions. */ 799 ifp->if_collisions += card_stats & ECR_COLN_MASK; 800 801 /* Multiple collisions. */ 802 ifp->if_collisions += (card_stats & ECR_MCOLN_MASK) >> 4; 803 804 SMC_SELECT_BANK(sc, 2); 805 806 ifp->if_timer = 0; 807 } 808 809 /* 810 * Other errors. Reset the interface. 811 */ 812 if (status & IM_EPH_INT) { 813 smc91cxx_stop(sc); 814 smc91cxx_init(sc); 815 } 816 817 /* 818 * Attempt to queue more packets for transmission. 819 */ 820 smc91cxx_start(ifp); 821 822 /* 823 * Reenable the interrupts we wish to receive now that processing 824 * is complete. 825 */ 826 mask |= bus_space_read_1(bst, bsh, INTR_MASK_REG_B); 827 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, mask); 828 829 #if NRND > 0 830 if (status) 831 rnd_add_uint32(&sc->rnd_source, status); 832 #endif 833 834 return (1); 835 } 836 837 /* 838 * Read a packet from the card and pass it up to the kernel. 839 * NOTE! WE EXPECT TO BE IN REGISTER WINDOW 2! 840 */ 841 void 842 smc91cxx_read(sc) 843 struct smc91cxx_softc *sc; 844 { 845 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 846 bus_space_tag_t bst = sc->sc_bst; 847 bus_space_handle_t bsh = sc->sc_bsh; 848 struct mbuf *m; 849 u_int16_t status, packetno, packetlen; 850 u_int8_t *data; 851 852 again: 853 /* 854 * Set data pointer to the beginning of the packet. Since 855 * PTR_RCV is set, the packet number will be found automatically 856 * in FIFO_PORTS_REG_W, FIFO_RX_MASK. 857 */ 858 bus_space_write_2(bst, bsh, POINTER_REG_W, 859 PTR_READ | PTR_RCV | PTR_AUTOINC /* | 0x0000 */); 860 861 /* 862 * First two words are status and packet length. 863 */ 864 status = bus_space_read_2(bst, bsh, DATA_REG_W); 865 packetlen = bus_space_read_2(bst, bsh, DATA_REG_W); 866 867 /* 868 * The packet length includes 3 extra words: status, length, 869 * and an extra word that includes the control byte. 870 */ 871 packetlen -= 6; 872 873 /* 874 * Account for receive errors and discard. 875 */ 876 if (status & RS_ERRORS) { 877 ifp->if_ierrors++; 878 goto out; 879 } 880 881 /* 882 * Adjust for odd-length packet. 883 */ 884 if (status & RS_ODDFRAME) 885 packetlen++; 886 887 /* 888 * Allocate a header mbuf. 889 */ 890 MGETHDR(m, M_DONTWAIT, MT_DATA); 891 if (m == NULL) 892 goto out; 893 894 m->m_pkthdr.rcvif = ifp; 895 m->m_pkthdr.len = m->m_len = packetlen; 896 897 /* 898 * Always put the packet in a cluster. 899 * XXX should chain small mbufs if less than threshold. 900 */ 901 MCLGET(m, M_DONTWAIT); 902 if ((m->m_flags & M_EXT) == 0) { 903 m_freem(m); 904 ifp->if_ierrors++; 905 printf("%s: can't allocate cluster for incoming packet\n", 906 sc->sc_dev.dv_xname); 907 goto out; 908 } 909 910 /* 911 * Pull the packet off the interface. 912 */ 913 data = mtod(m, u_int8_t *); 914 bus_space_read_multi_2(bst, bsh, DATA_REG_W, (u_int16_t *)data, 915 packetlen >> 1); 916 if (packetlen & 1) { 917 data += packetlen & ~1; 918 *data = bus_space_read_1(bst, bsh, DATA_REG_B); 919 } 920 921 ifp->if_ipackets++; 922 923 #if NBPFILTER > 0 924 /* 925 * Hand the packet off to bpf listeners. If there's a bpf listener, 926 * we need to check if the packet is ours. 927 */ 928 if (ifp->if_bpf) 929 bpf_mtap(ifp->if_bpf, m); 930 #endif 931 932 m->m_pkthdr.len = m->m_len = packetlen; 933 ether_input_mbuf(ifp, m); 934 935 out: 936 /* 937 * Tell the card to free the memory occupied by this packet. 938 */ 939 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 940 /* XXX bound this loop! */ ; 941 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RELEASE); 942 943 /* 944 * Check for another packet. 945 */ 946 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W); 947 if (packetno & FIFO_REMPTY) 948 return; 949 goto again; 950 } 951 952 /* 953 * Process an ioctl request. 954 */ 955 int 956 smc91cxx_ioctl(ifp, cmd, data) 957 struct ifnet *ifp; 958 u_long cmd; 959 caddr_t data; 960 { 961 struct smc91cxx_softc *sc = ifp->if_softc; 962 struct ifaddr *ifa = (struct ifaddr *)data; 963 struct ifreq *ifr = (struct ifreq *)data; 964 int s, error = 0; 965 966 s = splnet(); 967 968 switch (cmd) { 969 case SIOCSIFADDR: 970 if ((error = smc91cxx_enable(sc)) != 0) 971 break; 972 ifp->if_flags |= IFF_UP; 973 switch (ifa->ifa_addr->sa_family) { 974 #ifdef INET 975 case AF_INET: 976 smc91cxx_init(sc); 977 arp_ifinit(&sc->sc_arpcom, ifa); 978 break; 979 #endif 980 #ifdef NS 981 case AF_NS: 982 { 983 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 984 985 if (ns_nullhost(*ina)) 986 ina->x_host = 987 *(union ns_host *)LLADDR(ifp->if_sadl); 988 else { 989 bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl), 990 ETHER_ADDR_LEN); 991 } 992 993 /* 994 * Set new address. Reset, because the receiver 995 * has to be stopped before we can set the new 996 * MAC address. 997 */ 998 smc91cxx_reset(sc); 999 break; 1000 } 1001 #endif 1002 default: 1003 smc91cxx_init(sc); 1004 break; 1005 } 1006 break; 1007 1008 #if defined(CCITT) && defined(LLC) 1009 case SIOCSIFCONF_X25: 1010 if ((error = smc91cxx_enable(sc)) != 0) 1011 break; 1012 ifp->if_flags |= IFF_UP; 1013 ifa->ifa_rtrequest = cons_rtrequest; /* XXX */ 1014 error = x25_llcglue(PRC_IFUP, ifa->ifa_addr); 1015 if (error == 0) 1016 smc91cxx_init(sc); 1017 break; 1018 #endif 1019 1020 case SIOCSIFFLAGS: 1021 if ((ifp->if_flags & IFF_UP) == 0 && 1022 (ifp->if_flags & IFF_RUNNING) != 0) { 1023 /* 1024 * If interface is marked down and it is running, 1025 * stop it. 1026 */ 1027 smc91cxx_stop(sc); 1028 ifp->if_flags &= ~IFF_RUNNING; 1029 smc91cxx_disable(sc); 1030 } else if ((ifp->if_flags & IFF_UP) != 0 && 1031 (ifp->if_flags & IFF_RUNNING) == 0) { 1032 /* 1033 * If interface is marked up and it is stopped, 1034 * start it. 1035 */ 1036 if ((error = smc91cxx_enable(sc)) != 0) 1037 break; 1038 smc91cxx_init(sc); 1039 } else if (sc->sc_enabled) { 1040 /* 1041 * Reset the interface to pick up changes in any 1042 * other flags that affect hardware registers. 1043 */ 1044 smc91cxx_reset(sc); 1045 } 1046 break; 1047 1048 case SIOCADDMULTI: 1049 case SIOCDELMULTI: 1050 if (sc->sc_enabled == 0) { 1051 error = EIO; 1052 break; 1053 } 1054 1055 error = (cmd == SIOCADDMULTI) ? 1056 ether_addmulti(ifr, &sc->sc_arpcom) : 1057 ether_delmulti(ifr, &sc->sc_arpcom); 1058 if (error == ENETRESET) { 1059 /* 1060 * Multicast list has changed; set the hardware 1061 * filter accordingly. 1062 */ 1063 smc91cxx_reset(sc); 1064 error = 0; 1065 } 1066 break; 1067 1068 case SIOCGIFMEDIA: 1069 case SIOCSIFMEDIA: 1070 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); 1071 break; 1072 1073 default: 1074 error = EINVAL; 1075 break; 1076 } 1077 1078 splx(s); 1079 return (error); 1080 } 1081 1082 /* 1083 * Reset the interface. 1084 */ 1085 void 1086 smc91cxx_reset(sc) 1087 struct smc91cxx_softc *sc; 1088 { 1089 int s; 1090 1091 s = splnet(); 1092 smc91cxx_stop(sc); 1093 smc91cxx_init(sc); 1094 splx(s); 1095 } 1096 1097 /* 1098 * Watchdog timer. 1099 */ 1100 void 1101 smc91cxx_watchdog(ifp) 1102 struct ifnet *ifp; 1103 { 1104 struct smc91cxx_softc *sc = ifp->if_softc; 1105 1106 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 1107 ++sc->sc_arpcom.ac_if.if_oerrors; 1108 1109 smc91cxx_reset(sc); 1110 } 1111 1112 /* 1113 * Stop output on the interface. 1114 */ 1115 void 1116 smc91cxx_stop(sc) 1117 struct smc91cxx_softc *sc; 1118 { 1119 bus_space_tag_t bst = sc->sc_bst; 1120 bus_space_handle_t bsh = sc->sc_bsh; 1121 1122 /* 1123 * Clear interrupt mask; disable all interrupts. 1124 */ 1125 SMC_SELECT_BANK(sc, 2); 1126 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0); 1127 1128 /* 1129 * Disable transmitter and receiver. 1130 */ 1131 SMC_SELECT_BANK(sc, 0); 1132 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0); 1133 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0); 1134 1135 /* 1136 * Cancel watchdog timer. 1137 */ 1138 sc->sc_arpcom.ac_if.if_timer = 0; 1139 } 1140 1141 /* 1142 * Enable power on the interface. 1143 */ 1144 int 1145 smc91cxx_enable(sc) 1146 struct smc91cxx_softc *sc; 1147 { 1148 1149 if (sc->sc_enabled == 0 && sc->sc_enable != NULL) { 1150 if ((*sc->sc_enable)(sc) != 0) { 1151 printf("%s: device enable failed\n", 1152 sc->sc_dev.dv_xname); 1153 return (EIO); 1154 } 1155 } 1156 1157 sc->sc_enabled = 1; 1158 return (0); 1159 } 1160 1161 /* 1162 * Disable power on the interface. 1163 */ 1164 void 1165 smc91cxx_disable(sc) 1166 struct smc91cxx_softc *sc; 1167 { 1168 1169 if (sc->sc_enabled != 0 && sc->sc_disable != NULL) { 1170 (*sc->sc_disable)(sc); 1171 sc->sc_enabled = 0; 1172 } 1173 } 1174