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