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