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