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