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