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