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