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