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