1 /* $OpenBSD: smc91cxx.c,v 1.38 2015/03/14 03:38:47 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 int 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 *, int); 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 static __inline int ether_cmp(void *, void *); 185 static __inline int 186 ether_cmp(va, vb) 187 void *va, *vb; 188 { 189 u_int8_t *a = va; 190 u_int8_t *b = vb; 191 192 return ((a[5] != b[5]) || (a[4] != b[4]) || (a[3] != b[3]) || 193 (a[2] != b[2]) || (a[1] != b[1]) || (a[0] != b[0])); 194 } 195 196 void 197 smc91cxx_attach(sc, myea) 198 struct smc91cxx_softc *sc; 199 u_int8_t *myea; 200 { 201 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 202 bus_space_tag_t bst = sc->sc_bst; 203 bus_space_handle_t bsh = sc->sc_bsh; 204 struct ifmedia *ifm = &sc->sc_mii.mii_media; 205 u_int32_t miicapabilities; 206 u_int16_t tmp; 207 int i, aui; 208 const char *idstr; 209 210 /* Make sure the chip is stopped. */ 211 smc91cxx_stop(sc); 212 213 SMC_SELECT_BANK(sc, 3); 214 tmp = bus_space_read_2(bst, bsh, REVISION_REG_W); 215 sc->sc_chipid = RR_ID(tmp); 216 /* check magic number */ 217 if ((tmp & BSR_DETECT_MASK) != BSR_DETECT_VALUE) { 218 idstr = NULL; 219 printf("%s: invalid BSR 0x%04x\n", sc->sc_dev.dv_xname, tmp); 220 } else 221 idstr = smc91cxx_idstrs[RR_ID(tmp)]; 222 #ifdef SMC_DEBUG 223 printf("\n%s: ", sc->sc_dev.dv_xname); 224 if (idstr != NULL) 225 printf("%s, ", idstr); 226 else 227 printf("unknown chip id %d, ", sc->sc_chipid); 228 printf("revision %d", RR_REV(tmp)); 229 #endif 230 231 /* Read the station address from the chip. */ 232 SMC_SELECT_BANK(sc, 1); 233 if (myea == NULL) { 234 for (i = 0; i < ETHER_ADDR_LEN; i += 2) { 235 tmp = bus_space_read_2(bst, bsh, IAR_ADDR0_REG_W + i); 236 sc->sc_arpcom.ac_enaddr[i + 1] = (tmp >>8) & 0xff; 237 sc->sc_arpcom.ac_enaddr[i] = tmp & 0xff; 238 } 239 } else { 240 bcopy(myea, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); 241 } 242 243 printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); 244 245 /* Initialize the ifnet structure. */ 246 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 247 ifp->if_softc = sc; 248 ifp->if_start = smc91cxx_start; 249 ifp->if_ioctl = smc91cxx_ioctl; 250 ifp->if_watchdog = smc91cxx_watchdog; 251 ifp->if_flags = 252 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; 253 IFQ_SET_READY(&ifp->if_snd); 254 255 /* Attach the interface. */ 256 if_attach(ifp); 257 ether_ifattach(ifp); 258 259 /* 260 * Initialize our media structures and MII info. We will 261 * probe the MII if we are on the SMC91Cxx 262 */ 263 sc->sc_mii.mii_ifp = ifp; 264 sc->sc_mii.mii_readreg = smc91cxx_mii_readreg; 265 sc->sc_mii.mii_writereg = smc91cxx_mii_writereg; 266 sc->sc_mii.mii_statchg = smc91cxx_statchg; 267 ifmedia_init(ifm, 0, smc91cxx_mediachange, smc91cxx_mediastatus); 268 269 SMC_SELECT_BANK(sc, 1); 270 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); 271 272 miicapabilities = BMSR_MEDIAMASK|BMSR_ANEG; 273 switch (sc->sc_chipid) { 274 case CHIP_91100: 275 /* 276 * The 91100 does not have full-duplex capabilities, 277 * even if the PHY does. 278 */ 279 miicapabilities &= ~(BMSR_100TXFDX | BMSR_10TFDX); 280 /* FALLTHROUGH */ 281 case CHIP_91100FD: 282 if (tmp & CR_MII_SELECT) { 283 #ifdef SMC_DEBUG 284 printf("%s: default media MII\n", 285 sc->sc_dev.dv_xname); 286 #endif 287 mii_attach(&sc->sc_dev, &sc->sc_mii, miicapabilities, 288 MII_PHY_ANY, MII_OFFSET_ANY, 0); 289 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { 290 ifmedia_add(&sc->sc_mii.mii_media, 291 IFM_ETHER|IFM_NONE, 0, NULL); 292 ifmedia_set(&sc->sc_mii.mii_media, 293 IFM_ETHER|IFM_NONE); 294 } else { 295 ifmedia_set(&sc->sc_mii.mii_media, 296 IFM_ETHER|IFM_AUTO); 297 } 298 sc->sc_flags |= SMC_FLAGS_HAS_MII; 299 break; 300 } 301 /* FALLTHROUGH */ 302 default: 303 aui = tmp & CR_AUI_SELECT; 304 #ifdef SMC_DEBUG 305 printf("%s: default media %s\n", sc->sc_dev.dv_xname, 306 aui ? "AUI" : "UTP"); 307 #endif 308 for (i = 0; i < NSMC91CxxMEDIA; i++) 309 ifmedia_add(ifm, smc91cxx_media[i], 0, NULL); 310 ifmedia_set(ifm, IFM_ETHER | (aui ? IFM_10_5 : IFM_10_T)); 311 break; 312 } 313 314 /* The attach is successful. */ 315 sc->sc_flags |= SMC_FLAGS_ATTACHED; 316 } 317 318 /* 319 * Change media according to request. 320 */ 321 int 322 smc91cxx_mediachange(ifp) 323 struct ifnet *ifp; 324 { 325 struct smc91cxx_softc *sc = ifp->if_softc; 326 327 return (smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_media)); 328 } 329 330 int 331 smc91cxx_set_media(sc, media) 332 struct smc91cxx_softc *sc; 333 int media; 334 { 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 /* 340 * If the interface is not currently powered on, just return. 341 * When it is enabled later, smc91cxx_init() will properly set 342 * up the media for us. 343 */ 344 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) 345 return (0); 346 347 if (IFM_TYPE(media) != IFM_ETHER) 348 return (EINVAL); 349 350 if (sc->sc_flags & SMC_FLAGS_HAS_MII) 351 return (mii_mediachg(&sc->sc_mii)); 352 353 switch (IFM_SUBTYPE(media)) { 354 case IFM_10_T: 355 case IFM_10_5: 356 SMC_SELECT_BANK(sc, 1); 357 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); 358 if (IFM_SUBTYPE(media) == IFM_10_5) 359 tmp |= CR_AUI_SELECT; 360 else 361 tmp &= ~CR_AUI_SELECT; 362 bus_space_write_2(bst, bsh, CONFIG_REG_W, tmp); 363 delay(20000); /* XXX is this needed? */ 364 break; 365 366 default: 367 return (EINVAL); 368 } 369 370 return (0); 371 } 372 373 /* 374 * Notify the world which media we're using. 375 */ 376 void 377 smc91cxx_mediastatus(ifp, ifmr) 378 struct ifnet *ifp; 379 struct ifmediareq *ifmr; 380 { 381 struct smc91cxx_softc *sc = ifp->if_softc; 382 bus_space_tag_t bst = sc->sc_bst; 383 bus_space_handle_t bsh = sc->sc_bsh; 384 u_int16_t tmp; 385 386 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) { 387 ifmr->ifm_active = IFM_ETHER | IFM_NONE; 388 ifmr->ifm_status = 0; 389 return; 390 } 391 392 /* 393 * If we have MII, go ask the PHY what's going on. 394 */ 395 if (sc->sc_flags & SMC_FLAGS_HAS_MII) { 396 mii_pollstat(&sc->sc_mii); 397 ifmr->ifm_active = sc->sc_mii.mii_media_active; 398 ifmr->ifm_status = sc->sc_mii.mii_media_status; 399 return; 400 } 401 402 SMC_SELECT_BANK(sc, 1); 403 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); 404 ifmr->ifm_active = 405 IFM_ETHER | ((tmp & CR_AUI_SELECT) ? IFM_10_5 : IFM_10_T); 406 } 407 408 /* 409 * Reset and initialize the chip. 410 */ 411 void 412 smc91cxx_init(sc) 413 struct smc91cxx_softc *sc; 414 { 415 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 416 bus_space_tag_t bst = sc->sc_bst; 417 bus_space_handle_t bsh = sc->sc_bsh; 418 u_int16_t tmp; 419 int s, i; 420 421 s = splnet(); 422 423 /* 424 * This resets the registers mostly to defaults, but doesn't 425 * affect the EEPROM. After the reset cycle, we pause briefly 426 * for the chip to recover. 427 * 428 * XXX how long are we really supposed to delay? --thorpej 429 */ 430 SMC_SELECT_BANK(sc, 0); 431 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, RCR_SOFTRESET); 432 delay(100); 433 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0); 434 delay(200); 435 436 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0); 437 438 /* Set the Ethernet address. */ 439 SMC_SELECT_BANK(sc, 1); 440 for (i = 0; i < ETHER_ADDR_LEN; i++ ) 441 bus_space_write_1(bst, bsh, IAR_ADDR0_REG_W + i, 442 sc->sc_arpcom.ac_enaddr[i]); 443 444 /* 445 * Set the control register to automatically release successfully 446 * transmitted packets (making the best use of our limited memory) 447 * and enable the EPH interrupt on certain TX errors. 448 */ 449 bus_space_write_2(bst, bsh, CONTROL_REG_W, (CTR_AUTO_RELEASE | 450 CTR_TE_ENABLE | CTR_CR_ENABLE | CTR_LE_ENABLE)); 451 452 /* 453 * Reset the MMU and wait for it to be un-busy. 454 */ 455 SMC_SELECT_BANK(sc, 2); 456 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RESET); 457 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 458 /* XXX bound this loop! */ ; 459 460 /* 461 * Disable all interrupts. 462 */ 463 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0); 464 465 /* 466 * Set current media. 467 */ 468 smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_cur->ifm_media); 469 470 /* 471 * Set the receive filter. We want receive enable and auto 472 * strip of CRC from received packet. If we are in promisc. mode, 473 * then set that bit as well. 474 * 475 * XXX Initialize multicast filter. For now, we just accept 476 * XXX all multicast. 477 */ 478 SMC_SELECT_BANK(sc, 0); 479 480 tmp = RCR_ENABLE | RCR_STRIP_CRC | RCR_ALMUL; 481 if (ifp->if_flags & IFF_PROMISC) 482 tmp |= RCR_PROMISC; 483 484 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, tmp); 485 486 /* 487 * Set transmitter control to "enabled". 488 */ 489 tmp = TCR_ENABLE; 490 491 #ifndef SMC91CXX_SW_PAD 492 /* 493 * Enable hardware padding of transmitted packets. 494 * XXX doesn't work? 495 */ 496 tmp |= TCR_PAD_ENABLE; 497 #endif 498 499 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, tmp); 500 501 /* 502 * Now, enable interrupts. 503 */ 504 SMC_SELECT_BANK(sc, 2); 505 506 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 507 IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | IM_TX_INT); 508 509 /* Interface is now running, with no output active. */ 510 ifp->if_flags |= IFF_RUNNING; 511 ifp->if_flags &= ~IFF_OACTIVE; 512 513 if (sc->sc_flags & SMC_FLAGS_HAS_MII) { 514 /* Start the one second clock. */ 515 timeout_set(&sc->sc_mii_timeout, smc91cxx_tick, sc); 516 timeout_add_sec(&sc->sc_mii_timeout, 1); 517 } 518 519 /* 520 * Attempt to start any pending transmission. 521 */ 522 smc91cxx_start(ifp); 523 524 splx(s); 525 } 526 527 /* 528 * Start output on an interface. 529 * Must be called at splnet or interrupt level. 530 */ 531 void 532 smc91cxx_start(ifp) 533 struct ifnet *ifp; 534 { 535 struct smc91cxx_softc *sc = ifp->if_softc; 536 bus_space_tag_t bst = sc->sc_bst; 537 bus_space_handle_t bsh = sc->sc_bsh; 538 u_int len; 539 struct mbuf *m, *top; 540 u_int16_t length, npages; 541 u_int8_t packetno; 542 int timo, pad; 543 544 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 545 return; 546 547 again: 548 /* 549 * Peek at the next packet. 550 */ 551 IFQ_POLL(&ifp->if_snd, m); 552 if (m == NULL) 553 return; 554 555 /* 556 * Compute the frame length and set pad to give an overall even 557 * number of bytes. Below, we assume that the packet length 558 * is even. 559 */ 560 for (len = 0, top = m; m != NULL; m = m->m_next) 561 len += m->m_len; 562 pad = (len & 1); 563 564 /* 565 * We drop packets that are too large. Perhaps we should 566 * truncate them instead? 567 */ 568 if ((len + pad) > (ETHER_MAX_LEN - ETHER_CRC_LEN)) { 569 printf("%s: large packet discarded\n", sc->sc_dev.dv_xname); 570 ifp->if_oerrors++; 571 IFQ_DEQUEUE(&ifp->if_snd, m); 572 m_freem(m); 573 goto readcheck; 574 } 575 576 #ifdef SMC91CXX_SW_PAD 577 /* 578 * Not using hardware padding; pad to ETHER_MIN_LEN. 579 */ 580 if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN)) 581 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len; 582 #endif 583 584 length = pad + len; 585 586 /* 587 * The MMU has a 256 byte page size. The MMU expects us to 588 * ask for "npages - 1". We include space for the status word, 589 * byte count, and control bytes in the allocation request. 590 */ 591 npages = (length + 6) >> 8; 592 593 /* 594 * Now allocate the memory. 595 */ 596 SMC_SELECT_BANK(sc, 2); 597 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ALLOC | npages); 598 599 timo = MEMORY_WAIT_TIME; 600 do { 601 if (bus_space_read_1(bst, bsh, INTR_STAT_REG_B) & IM_ALLOC_INT) 602 break; 603 delay(1); 604 } while (--timo); 605 606 packetno = bus_space_read_1(bst, bsh, ALLOC_RESULT_REG_B); 607 608 if (packetno & ARR_FAILED || timo == 0) { 609 /* 610 * No transmit memory is available. Record the number 611 * of requestd pages and enable the allocation completion 612 * interrupt. Set up the watchdog timer in case we miss 613 * the interrupt. Mark the interface as active so that 614 * no one else attempts to transmit while we're allocating 615 * memory. 616 */ 617 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 618 bus_space_read_1(bst, bsh, INTR_MASK_REG_B) | IM_ALLOC_INT); 619 620 ifp->if_timer = 5; 621 ifp->if_flags |= IFF_OACTIVE; 622 623 return; 624 } 625 626 /* 627 * We have a packet number - set the data window. 628 */ 629 bus_space_write_1(bst, bsh, PACKET_NUM_REG_B, packetno); 630 631 /* 632 * Point to the beginning of the packet. 633 */ 634 bus_space_write_2(bst, bsh, POINTER_REG_W, PTR_AUTOINC /* | 0x0000 */); 635 636 /* 637 * Send the packet length (+6 for stats, length, and control bytes) 638 * and the status word (set to zeros). 639 */ 640 bus_space_write_2(bst, bsh, DATA_REG_W, 0); 641 bus_space_write_1(bst, bsh, DATA_REG_B, (length + 6) & 0xff); 642 bus_space_write_1(bst, bsh, DATA_REG_B, ((length + 6) >> 8) & 0xff); 643 644 /* 645 * Get the packet from the kernel. This will include the Ethernet 646 * frame header, MAC address, etc. 647 */ 648 IFQ_DEQUEUE(&ifp->if_snd, m); 649 650 /* 651 * Push the packet out to the card. 652 */ 653 for (top = m; m != NULL; m = m->m_next) { 654 /* Words... */ 655 if (m->m_len > 1) 656 bus_space_write_multi_stream_2(bst, bsh, DATA_REG_W, 657 mtod(m, u_int16_t *), m->m_len >> 1); 658 659 /* ...and the remaining byte, if any. */ 660 if (m->m_len & 1) 661 bus_space_write_1(bst, bsh, DATA_REG_B, 662 *(u_int8_t *)(mtod(m, u_int8_t *) + (m->m_len - 1))); 663 } 664 665 #ifdef SMC91CXX_SW_PAD 666 /* 667 * Push out padding. 668 */ 669 while (pad > 1) { 670 bus_space_write_2(bst, bsh, DATA_REG_W, 0); 671 pad -= 2; 672 } 673 if (pad) 674 bus_space_write_1(bst, bsh, DATA_REG_B, 0); 675 #endif 676 677 /* 678 * Push out control byte and unused packet byte. The control byte 679 * is 0, meaning the packet is even lengthed and no special 680 * CRC handling is necessary. 681 */ 682 bus_space_write_2(bst, bsh, DATA_REG_W, 0); 683 684 /* 685 * Enable transmit interrupts and let the chip go. Set a watchdog 686 * in case we miss the interrupt. 687 */ 688 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 689 bus_space_read_1(bst, bsh, INTR_MASK_REG_B) | 690 IM_TX_INT | IM_TX_EMPTY_INT); 691 692 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ENQUEUE); 693 694 ifp->if_timer = 5; 695 696 #if NBPFILTER > 0 697 if (ifp->if_bpf) 698 bpf_mtap(ifp->if_bpf, top, BPF_DIRECTION_OUT); 699 #endif 700 701 ifp->if_opackets++; 702 m_freem(top); 703 704 readcheck: 705 /* 706 * Check for incoming pcakets. We don't want to overflow the small 707 * RX FIFO. If nothing has arrived, attempt to queue another 708 * transmit packet. 709 */ 710 if (bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) & FIFO_REMPTY) 711 goto again; 712 } 713 714 /* 715 * Interrupt service routine. 716 */ 717 int 718 smc91cxx_intr(arg) 719 void *arg; 720 { 721 struct smc91cxx_softc *sc = arg; 722 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 723 bus_space_tag_t bst = sc->sc_bst; 724 bus_space_handle_t bsh = sc->sc_bsh; 725 u_int8_t mask, interrupts, status; 726 u_int16_t packetno, tx_status, card_stats; 727 728 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0 || 729 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) 730 return (0); 731 732 SMC_SELECT_BANK(sc, 2); 733 734 /* 735 * Obtain the current interrupt mask. 736 */ 737 mask = bus_space_read_1(bst, bsh, INTR_MASK_REG_B); 738 739 /* 740 * Get the set of interrupt which occurred and eliminate any 741 * which are not enabled. 742 */ 743 interrupts = bus_space_read_1(bst, bsh, INTR_STAT_REG_B); 744 status = interrupts & mask; 745 746 /* Ours? */ 747 if (status == 0) 748 return (0); 749 750 /* 751 * It's ours; disable all interrupts while we process them. 752 */ 753 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0); 754 755 /* 756 * Receive overrun interrupts. 757 */ 758 if (status & IM_RX_OVRN_INT) { 759 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_RX_OVRN_INT); 760 ifp->if_ierrors++; 761 } 762 763 /* 764 * Receive interrupts. 765 */ 766 if (status & IM_RCV_INT) { 767 #if 1 /* DIAGNOSTIC */ 768 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W); 769 if (packetno & FIFO_REMPTY) { 770 printf("%s: receive interrupt on empty fifo\n", 771 sc->sc_dev.dv_xname); 772 goto out; 773 } else 774 #endif 775 smc91cxx_read(sc); 776 } 777 778 /* 779 * Memory allocation interrupts. 780 */ 781 if (status & IM_ALLOC_INT) { 782 /* Disable this interrupt. */ 783 mask &= ~IM_ALLOC_INT; 784 785 /* 786 * Release the just-allocated memory. We will reallocate 787 * it through the normal start logic. 788 */ 789 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 790 /* XXX bound this loop! */ ; 791 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT); 792 793 ifp->if_flags &= ~IFF_OACTIVE; 794 ifp->if_timer = 0; 795 } 796 797 /* 798 * Transmit complete interrupt. Handle transmission error messages. 799 * This will only be called on error condition because of AUTO RELEASE 800 * mode. 801 */ 802 if (status & IM_TX_INT) { 803 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_TX_INT); 804 805 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) & 806 FIFO_TX_MASK; 807 808 /* 809 * Select this as the packet to read from. 810 */ 811 bus_space_write_1(bst, bsh, PACKET_NUM_REG_B, packetno); 812 813 /* 814 * Position the pointer to the beginning of the packet. 815 */ 816 bus_space_write_2(bst, bsh, POINTER_REG_W, 817 PTR_AUTOINC | PTR_READ /* | 0x0000 */); 818 819 /* 820 * Fetch the TX status word. This will be a copy of 821 * the EPH_STATUS_REG_W at the time of the transmission 822 * failure. 823 */ 824 tx_status = bus_space_read_2(bst, bsh, DATA_REG_W); 825 826 if (tx_status & EPHSR_TX_SUC) 827 printf("%s: successful packet caused TX interrupt?!\n", 828 sc->sc_dev.dv_xname); 829 else 830 ifp->if_oerrors++; 831 832 if (tx_status & EPHSR_LATCOL) 833 ifp->if_collisions++; 834 835 /* 836 * Some of these errors disable the transmitter; reenable it. 837 */ 838 SMC_SELECT_BANK(sc, 0); 839 #ifdef SMC91CXX_SW_PAD 840 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, TCR_ENABLE); 841 #else 842 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 843 TCR_ENABLE | TCR_PAD_ENABLE); 844 #endif 845 846 /* 847 * Kill the failed packet and wait for the MMU to unbusy. 848 */ 849 SMC_SELECT_BANK(sc, 2); 850 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 851 /* XXX bound this loop! */ ; 852 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT); 853 854 ifp->if_timer = 0; 855 } 856 857 /* 858 * Transmit underrun interrupts. We use this opportunity to 859 * update transmit statistics from the card. 860 */ 861 if (status & IM_TX_EMPTY_INT) { 862 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_TX_EMPTY_INT); 863 864 /* Disable this interrupt. */ 865 mask &= ~IM_TX_EMPTY_INT; 866 867 SMC_SELECT_BANK(sc, 0); 868 card_stats = bus_space_read_2(bst, bsh, COUNTER_REG_W); 869 870 /* Single collisions. */ 871 ifp->if_collisions += card_stats & ECR_COLN_MASK; 872 873 /* Multiple collisions. */ 874 ifp->if_collisions += (card_stats & ECR_MCOLN_MASK) >> 4; 875 876 SMC_SELECT_BANK(sc, 2); 877 878 ifp->if_timer = 0; 879 } 880 881 /* 882 * Other errors. Reset the interface. 883 */ 884 if (status & IM_EPH_INT) { 885 smc91cxx_stop(sc); 886 smc91cxx_init(sc); 887 } 888 889 /* 890 * Attempt to queue more packets for transmission. 891 */ 892 smc91cxx_start(ifp); 893 894 out: 895 /* 896 * Reenable the interrupts we wish to receive now that processing 897 * is complete. 898 */ 899 mask |= bus_space_read_1(bst, bsh, INTR_MASK_REG_B); 900 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, mask); 901 902 return (1); 903 } 904 905 /* 906 * Read a packet from the card and pass it up to the kernel. 907 * NOTE! WE EXPECT TO BE IN REGISTER WINDOW 2! 908 */ 909 void 910 smc91cxx_read(sc) 911 struct smc91cxx_softc *sc; 912 { 913 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 914 bus_space_tag_t bst = sc->sc_bst; 915 bus_space_handle_t bsh = sc->sc_bsh; 916 struct mbuf *m; 917 u_int16_t status, packetno, packetlen; 918 u_int8_t *data; 919 920 again: 921 /* 922 * Set data pointer to the beginning of the packet. Since 923 * PTR_RCV is set, the packet number will be found automatically 924 * in FIFO_PORTS_REG_W, FIFO_RX_MASK. 925 */ 926 bus_space_write_2(bst, bsh, POINTER_REG_W, 927 PTR_READ | PTR_RCV | PTR_AUTOINC /* | 0x0000 */); 928 929 /* 930 * First two words are status and packet length. 931 */ 932 status = bus_space_read_2(bst, bsh, DATA_REG_W); 933 packetlen = bus_space_read_2(bst, bsh, DATA_REG_W); 934 935 /* 936 * The packet length includes 3 extra words: status, length, 937 * and an extra word that includes the control byte. 938 */ 939 packetlen -= 6; 940 941 /* 942 * Account for receive errors and discard. 943 */ 944 if (status & RS_ERRORS) { 945 ifp->if_ierrors++; 946 goto out; 947 } 948 949 /* 950 * Adjust for odd-length packet. 951 */ 952 if (status & RS_ODDFRAME) 953 packetlen++; 954 955 /* 956 * Allocate a header mbuf. 957 */ 958 MGETHDR(m, M_DONTWAIT, MT_DATA); 959 if (m == NULL) 960 goto out; 961 m->m_pkthdr.rcvif = ifp; 962 m->m_pkthdr.len = packetlen; 963 964 /* 965 * Always put the packet in a cluster. 966 * XXX should chain small mbufs if less than threshold. 967 */ 968 MCLGET(m, M_DONTWAIT); 969 if ((m->m_flags & M_EXT) == 0) { 970 m_freem(m); 971 ifp->if_ierrors++; 972 printf("%s: can't allocate cluster for incoming packet\n", 973 sc->sc_dev.dv_xname); 974 goto out; 975 } 976 977 /* 978 * Pull the packet off the interface. Make sure the payload 979 * is aligned. 980 */ 981 m->m_data = (caddr_t) ALIGN(mtod(m, caddr_t) + 982 sizeof(struct ether_header)) - sizeof(struct ether_header); 983 984 data = mtod(m, u_int8_t *); 985 if (packetlen > 1) 986 bus_space_read_multi_stream_2(bst, bsh, DATA_REG_W, 987 (u_int16_t *)data, packetlen >> 1); 988 if (packetlen & 1) { 989 data += packetlen & ~1; 990 *data = bus_space_read_1(bst, bsh, DATA_REG_B); 991 } 992 993 ifp->if_ipackets++; 994 995 #if NBPFILTER > 0 996 if (ifp->if_bpf) 997 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN); 998 #endif 999 1000 m->m_pkthdr.len = m->m_len = packetlen; 1001 ether_input_mbuf(ifp, m); 1002 1003 out: 1004 /* 1005 * Tell the card to free the memory occupied by this packet. 1006 */ 1007 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 1008 /* XXX bound this loop! */ ; 1009 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RELEASE); 1010 1011 /* 1012 * Check for another packet. 1013 */ 1014 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W); 1015 if (packetno & FIFO_REMPTY) 1016 return; 1017 goto again; 1018 } 1019 1020 /* 1021 * Process an ioctl request. 1022 */ 1023 int 1024 smc91cxx_ioctl(ifp, cmd, data) 1025 struct ifnet *ifp; 1026 u_long cmd; 1027 caddr_t data; 1028 { 1029 struct smc91cxx_softc *sc = ifp->if_softc; 1030 struct ifaddr *ifa = (struct ifaddr *)data; 1031 struct ifreq *ifr = (struct ifreq *)data; 1032 int s, error = 0; 1033 1034 s = splnet(); 1035 1036 switch (cmd) { 1037 case SIOCSIFADDR: 1038 if ((error = smc91cxx_enable(sc)) != 0) 1039 break; 1040 ifp->if_flags |= IFF_UP; 1041 switch (ifa->ifa_addr->sa_family) { 1042 case AF_INET: 1043 smc91cxx_init(sc); 1044 arp_ifinit(&sc->sc_arpcom, ifa); 1045 break; 1046 default: 1047 smc91cxx_init(sc); 1048 break; 1049 } 1050 break; 1051 1052 case SIOCSIFFLAGS: 1053 if ((ifp->if_flags & IFF_UP) == 0 && 1054 (ifp->if_flags & IFF_RUNNING) != 0) { 1055 /* 1056 * If interface is marked down and it is running, 1057 * stop it. 1058 */ 1059 smc91cxx_stop(sc); 1060 ifp->if_flags &= ~IFF_RUNNING; 1061 smc91cxx_disable(sc); 1062 } else if ((ifp->if_flags & IFF_UP) != 0 && 1063 (ifp->if_flags & IFF_RUNNING) == 0) { 1064 /* 1065 * If interface is marked up and it is stopped, 1066 * start it. 1067 */ 1068 if ((error = smc91cxx_enable(sc)) != 0) 1069 break; 1070 smc91cxx_init(sc); 1071 } else if ((ifp->if_flags & IFF_UP) != 0) { 1072 /* 1073 * Reset the interface to pick up changes in any 1074 * other flags that affect hardware registers. 1075 */ 1076 smc91cxx_reset(sc); 1077 } 1078 break; 1079 1080 case SIOCGIFMEDIA: 1081 case SIOCSIFMEDIA: 1082 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd); 1083 break; 1084 1085 default: 1086 error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data); 1087 } 1088 1089 if (error == ENETRESET) { 1090 if (ifp->if_flags & IFF_RUNNING) 1091 smc91cxx_reset(sc); 1092 error = 0; 1093 } 1094 1095 splx(s); 1096 return (error); 1097 } 1098 1099 /* 1100 * Reset the interface. 1101 */ 1102 void 1103 smc91cxx_reset(sc) 1104 struct smc91cxx_softc *sc; 1105 { 1106 int s; 1107 1108 s = splnet(); 1109 smc91cxx_stop(sc); 1110 smc91cxx_init(sc); 1111 splx(s); 1112 } 1113 1114 /* 1115 * Watchdog timer. 1116 */ 1117 void 1118 smc91cxx_watchdog(ifp) 1119 struct ifnet *ifp; 1120 { 1121 struct smc91cxx_softc *sc = ifp->if_softc; 1122 1123 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 1124 ++sc->sc_arpcom.ac_if.if_oerrors; 1125 1126 smc91cxx_reset(sc); 1127 } 1128 1129 /* 1130 * Stop output on the interface. 1131 */ 1132 void 1133 smc91cxx_stop(sc) 1134 struct smc91cxx_softc *sc; 1135 { 1136 bus_space_tag_t bst = sc->sc_bst; 1137 bus_space_handle_t bsh = sc->sc_bsh; 1138 1139 /* 1140 * Clear interrupt mask; disable all interrupts. 1141 */ 1142 SMC_SELECT_BANK(sc, 2); 1143 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0); 1144 1145 /* 1146 * Disable transmitter and receiver. 1147 */ 1148 SMC_SELECT_BANK(sc, 0); 1149 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0); 1150 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0); 1151 1152 /* 1153 * Cancel watchdog timer. 1154 */ 1155 sc->sc_arpcom.ac_if.if_timer = 0; 1156 } 1157 1158 /* 1159 * Enable power on the interface. 1160 */ 1161 int 1162 smc91cxx_enable(sc) 1163 struct smc91cxx_softc *sc; 1164 { 1165 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0 && sc->sc_enable != NULL) { 1166 if ((*sc->sc_enable)(sc) != 0) { 1167 printf("%s: device enable failed\n", 1168 sc->sc_dev.dv_xname); 1169 return (EIO); 1170 } 1171 } 1172 1173 sc->sc_flags |= SMC_FLAGS_ENABLED; 1174 return (0); 1175 } 1176 1177 /* 1178 * Disable power on the interface. 1179 */ 1180 void 1181 smc91cxx_disable(sc) 1182 struct smc91cxx_softc *sc; 1183 { 1184 if ((sc->sc_flags & SMC_FLAGS_ENABLED) != 0 && sc->sc_disable != NULL) { 1185 (*sc->sc_disable)(sc); 1186 sc->sc_flags &= ~SMC_FLAGS_ENABLED; 1187 } 1188 } 1189 1190 int 1191 smc91cxx_activate(self, act) 1192 struct device *self; 1193 int act; 1194 { 1195 #if 0 1196 struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self; 1197 #endif 1198 int rv = 0, s; 1199 1200 s = splnet(); 1201 switch (act) { 1202 case DVACT_DEACTIVATE: 1203 #if 0 1204 if_deactivate(&sc->sc_ic.ic_if); 1205 #endif 1206 break; 1207 } 1208 splx(s); 1209 return(rv); 1210 } 1211 1212 int 1213 smc91cxx_detach(self, flags) 1214 struct device *self; 1215 int flags; 1216 { 1217 struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self; 1218 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 1219 1220 /* Succeed now if there's no work to do. */ 1221 if ((sc->sc_flags & SMC_FLAGS_ATTACHED) == 0) 1222 return(0); 1223 1224 /* smc91cxx_disable() checks SMC_FLAGS_ENABLED */ 1225 smc91cxx_disable(sc); 1226 1227 /* smc91cxx_attach() never fails */ 1228 1229 /* Delete all media. */ 1230 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); 1231 1232 ether_ifdetach(ifp); 1233 if_detach(ifp); 1234 1235 return (0); 1236 } 1237 1238 u_int32_t 1239 smc91cxx_mii_bitbang_read(self) 1240 struct device *self; 1241 { 1242 struct smc91cxx_softc *sc = (void *) self; 1243 1244 /* We're already in bank 3. */ 1245 return (bus_space_read_2(sc->sc_bst, sc->sc_bsh, MGMT_REG_W)); 1246 } 1247 1248 void 1249 smc91cxx_mii_bitbang_write(self, val) 1250 struct device *self; 1251 u_int32_t val; 1252 { 1253 struct smc91cxx_softc *sc = (void *) self; 1254 1255 /* We're already in bank 3. */ 1256 bus_space_write_2(sc->sc_bst, sc->sc_bsh, MGMT_REG_W, val); 1257 } 1258 1259 int 1260 smc91cxx_mii_readreg(self, phy, reg) 1261 struct device *self; 1262 int phy, reg; 1263 { 1264 struct smc91cxx_softc *sc = (void *) self; 1265 int val; 1266 1267 SMC_SELECT_BANK(sc, 3); 1268 1269 val = mii_bitbang_readreg(self, &smc91cxx_mii_bitbang_ops, phy, reg); 1270 1271 SMC_SELECT_BANK(sc, 2); 1272 1273 return (val); 1274 } 1275 1276 void 1277 smc91cxx_mii_writereg(self, phy, reg, val) 1278 struct device *self; 1279 int phy, reg, val; 1280 { 1281 struct smc91cxx_softc *sc = (void *) self; 1282 1283 SMC_SELECT_BANK(sc, 3); 1284 1285 mii_bitbang_writereg(self, &smc91cxx_mii_bitbang_ops, phy, reg, val); 1286 1287 SMC_SELECT_BANK(sc, 2); 1288 } 1289 1290 void 1291 smc91cxx_statchg(self) 1292 struct device *self; 1293 { 1294 struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self; 1295 bus_space_tag_t bst = sc->sc_bst; 1296 bus_space_handle_t bsh = sc->sc_bsh; 1297 int mctl; 1298 1299 SMC_SELECT_BANK(sc, 0); 1300 mctl = bus_space_read_2(bst, bsh, TXMIT_CONTROL_REG_W); 1301 if (sc->sc_mii.mii_media_active & IFM_FDX) 1302 mctl |= TCR_SWFDUP; 1303 else 1304 mctl &= ~TCR_SWFDUP; 1305 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, mctl); 1306 SMC_SELECT_BANK(sc, 2); /* back to operating window */ 1307 } 1308 1309 /* 1310 * One second timer, used to tick the MII. 1311 */ 1312 void 1313 smc91cxx_tick(arg) 1314 void *arg; 1315 { 1316 struct smc91cxx_softc *sc = arg; 1317 int s; 1318 1319 #ifdef DIAGNOSTIC 1320 if ((sc->sc_flags & SMC_FLAGS_HAS_MII) == 0) 1321 panic("smc91cxx_tick"); 1322 #endif 1323 1324 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) 1325 return; 1326 1327 s = splnet(); 1328 mii_tick(&sc->sc_mii); 1329 splx(s); 1330 1331 timeout_add_sec(&sc->sc_mii_timeout, 1); 1332 } 1333