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