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