1 /* $OpenBSD: smc91cxx.c,v 1.53 2024/05/13 01:15:50 jsg Exp $ */ 2 /* $NetBSD: smc91cxx.c,v 1.11 1998/08/08 23:51:41 mycroft Exp $ */ 3 4 /*- 5 * Copyright (c) 1997 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (c) 1996 Gardner Buchanan <gbuchanan@shl.com> 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * This product includes software developed by Gardner Buchanan. 49 * 4. The name of Gardner Buchanan may not be used to endorse or promote 50 * products derived from this software without specific prior written 51 * permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 54 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 55 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 56 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 57 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 58 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 59 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 60 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 61 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 62 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 63 * 64 * from FreeBSD Id: if_sn.c,v 1.4 1996/03/18 15:47:16 gardner Exp 65 */ 66 67 /* 68 * Core driver for the SMC 91Cxx family of Ethernet chips. 69 * 70 * Memory allocation interrupt logic is derived from an SMC 91C90 driver 71 * written for NetBSD/amiga by Michael Hitch. 72 */ 73 74 #include "bpfilter.h" 75 76 #include <sys/param.h> 77 #include <sys/systm.h> 78 #include <sys/mbuf.h> 79 #include <sys/syslog.h> 80 #include <sys/socket.h> 81 #include <sys/device.h> 82 #include <sys/timeout.h> 83 #include <sys/kernel.h> 84 #include <sys/malloc.h> 85 #include <sys/ioctl.h> 86 #include <sys/errno.h> 87 88 #include <machine/bus.h> 89 #include <machine/intr.h> 90 91 #include <net/if.h> 92 #include <net/if_media.h> 93 94 #include <netinet/in.h> 95 #include <netinet/if_ether.h> 96 97 #if NBPFILTER > 0 98 #include <net/bpf.h> 99 #endif 100 101 #include <dev/mii/mii.h> 102 #include <dev/mii/miivar.h> 103 #include <dev/mii/mii_bitbang.h> 104 105 #include <dev/ic/smc91cxxreg.h> 106 #include <dev/ic/smc91cxxvar.h> 107 108 #ifndef __BUS_SPACE_HAS_STREAM_METHODS 109 #define bus_space_write_multi_stream_2 bus_space_write_multi_2 110 #define bus_space_write_multi_stream_4 bus_space_write_multi_4 111 #define bus_space_read_multi_stream_2 bus_space_read_multi_2 112 #define bus_space_read_multi_stream_4 bus_space_read_multi_4 113 #endif /* __BUS_SPACE_HAS_STREAM_METHODS */ 114 115 /* XXX Hardware padding doesn't work yet(?) */ 116 #define SMC91CXX_SW_PAD 117 118 const char *smc91cxx_idstrs[] = { 119 NULL, /* 0 */ 120 NULL, /* 1 */ 121 NULL, /* 2 */ 122 "SMC91C90/91C92", /* 3 */ 123 "SMC91C94/91C96", /* 4 */ 124 "SMC91C95", /* 5 */ 125 NULL, /* 6 */ 126 "SMC91C100", /* 7 */ 127 "SMC91C100FD", /* 8 */ 128 NULL, /* 9 */ 129 NULL, /* 10 */ 130 NULL, /* 11 */ 131 NULL, /* 12 */ 132 NULL, /* 13 */ 133 NULL, /* 14 */ 134 NULL, /* 15 */ 135 }; 136 137 /* Supported media types. */ 138 const uint64_t smc91cxx_media[] = { 139 IFM_ETHER|IFM_10_T, 140 IFM_ETHER|IFM_10_5, 141 }; 142 #define NSMC91CxxMEDIA (sizeof(smc91cxx_media) / sizeof(smc91cxx_media[0])) 143 144 /* 145 * MII bit-bang glue. 146 */ 147 u_int32_t smc91cxx_mii_bitbang_read(struct device *); 148 void smc91cxx_mii_bitbang_write(struct device *, u_int32_t); 149 150 const struct mii_bitbang_ops smc91cxx_mii_bitbang_ops = { 151 smc91cxx_mii_bitbang_read, 152 smc91cxx_mii_bitbang_write, 153 { 154 MR_MDO, /* MII_BIT_MDO */ 155 MR_MDI, /* MII_BIT_MDI */ 156 MR_MCLK, /* MII_BIT_MDC */ 157 MR_MDOE, /* MII_BIT_DIR_HOST_PHY */ 158 0, /* MII_BIT_DIR_PHY_HOST */ 159 } 160 }; 161 162 struct cfdriver sm_cd = { 163 NULL, "sm", DV_IFNET 164 }; 165 166 /* MII callbacks */ 167 int smc91cxx_mii_readreg(struct device *, int, int); 168 void smc91cxx_mii_writereg(struct device *, int, int, int); 169 void smc91cxx_statchg(struct device *); 170 void smc91cxx_tick(void *); 171 172 int smc91cxx_mediachange(struct ifnet *); 173 void smc91cxx_mediastatus(struct ifnet *, struct ifmediareq *); 174 175 int smc91cxx_set_media(struct smc91cxx_softc *, uint64_t); 176 177 void smc91cxx_read(struct smc91cxx_softc *); 178 void smc91cxx_reset(struct smc91cxx_softc *); 179 void smc91cxx_start(struct ifnet *); 180 void smc91cxx_watchdog(struct ifnet *); 181 int smc91cxx_ioctl(struct ifnet *, u_long, caddr_t); 182 183 void 184 smc91cxx_attach(struct smc91cxx_softc *sc, u_int8_t *myea) 185 { 186 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 187 bus_space_tag_t bst = sc->sc_bst; 188 bus_space_handle_t bsh = sc->sc_bsh; 189 struct ifmedia *ifm = &sc->sc_mii.mii_media; 190 u_int32_t miicapabilities; 191 u_int16_t tmp; 192 int i, aui; 193 const char *idstr; 194 195 /* Make sure the chip is stopped. */ 196 smc91cxx_stop(sc); 197 198 SMC_SELECT_BANK(sc, 3); 199 tmp = bus_space_read_2(bst, bsh, REVISION_REG_W); 200 sc->sc_chipid = RR_ID(tmp); 201 /* check magic number */ 202 if ((tmp & BSR_DETECT_MASK) != BSR_DETECT_VALUE) { 203 idstr = NULL; 204 printf("%s: invalid BSR 0x%04x\n", sc->sc_dev.dv_xname, tmp); 205 } else 206 idstr = smc91cxx_idstrs[RR_ID(tmp)]; 207 #ifdef SMC_DEBUG 208 printf("\n%s: ", sc->sc_dev.dv_xname); 209 if (idstr != NULL) 210 printf("%s, ", idstr); 211 else 212 printf("unknown chip id %d, ", sc->sc_chipid); 213 printf("revision %d", RR_REV(tmp)); 214 #endif 215 216 /* Read the station address from the chip. */ 217 SMC_SELECT_BANK(sc, 1); 218 if (myea == NULL) { 219 for (i = 0; i < ETHER_ADDR_LEN; i += 2) { 220 tmp = bus_space_read_2(bst, bsh, IAR_ADDR0_REG_W + i); 221 sc->sc_arpcom.ac_enaddr[i + 1] = (tmp >>8) & 0xff; 222 sc->sc_arpcom.ac_enaddr[i] = tmp & 0xff; 223 } 224 } else { 225 bcopy(myea, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); 226 } 227 228 printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); 229 230 /* Initialize the ifnet structure. */ 231 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 232 ifp->if_softc = sc; 233 ifp->if_start = smc91cxx_start; 234 ifp->if_ioctl = smc91cxx_ioctl; 235 ifp->if_watchdog = smc91cxx_watchdog; 236 ifp->if_flags = 237 IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 238 239 /* Attach the interface. */ 240 if_attach(ifp); 241 ether_ifattach(ifp); 242 243 /* 244 * Initialize our media structures and MII info. We will 245 * probe the MII if we are on the SMC91Cxx 246 */ 247 sc->sc_mii.mii_ifp = ifp; 248 sc->sc_mii.mii_readreg = smc91cxx_mii_readreg; 249 sc->sc_mii.mii_writereg = smc91cxx_mii_writereg; 250 sc->sc_mii.mii_statchg = smc91cxx_statchg; 251 ifmedia_init(ifm, 0, smc91cxx_mediachange, smc91cxx_mediastatus); 252 253 SMC_SELECT_BANK(sc, 1); 254 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); 255 256 miicapabilities = BMSR_MEDIAMASK|BMSR_ANEG; 257 switch (sc->sc_chipid) { 258 case CHIP_91100: 259 /* 260 * The 91100 does not have full-duplex capabilities, 261 * even if the PHY does. 262 */ 263 miicapabilities &= ~(BMSR_100TXFDX | BMSR_10TFDX); 264 /* FALLTHROUGH */ 265 case CHIP_91100FD: 266 if (tmp & CR_MII_SELECT) { 267 #ifdef SMC_DEBUG 268 printf("%s: default media MII\n", 269 sc->sc_dev.dv_xname); 270 #endif 271 mii_attach(&sc->sc_dev, &sc->sc_mii, miicapabilities, 272 MII_PHY_ANY, MII_OFFSET_ANY, 0); 273 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { 274 ifmedia_add(&sc->sc_mii.mii_media, 275 IFM_ETHER|IFM_NONE, 0, NULL); 276 ifmedia_set(&sc->sc_mii.mii_media, 277 IFM_ETHER|IFM_NONE); 278 } else { 279 ifmedia_set(&sc->sc_mii.mii_media, 280 IFM_ETHER|IFM_AUTO); 281 } 282 sc->sc_flags |= SMC_FLAGS_HAS_MII; 283 break; 284 } 285 /* FALLTHROUGH */ 286 default: 287 aui = tmp & CR_AUI_SELECT; 288 #ifdef SMC_DEBUG 289 printf("%s: default media %s\n", sc->sc_dev.dv_xname, 290 aui ? "AUI" : "UTP"); 291 #endif 292 for (i = 0; i < NSMC91CxxMEDIA; i++) 293 ifmedia_add(ifm, smc91cxx_media[i], 0, NULL); 294 ifmedia_set(ifm, IFM_ETHER | (aui ? IFM_10_5 : IFM_10_T)); 295 break; 296 } 297 298 /* The attach is successful. */ 299 sc->sc_flags |= SMC_FLAGS_ATTACHED; 300 } 301 302 /* 303 * Change media according to request. 304 */ 305 int 306 smc91cxx_mediachange(struct ifnet *ifp) 307 { 308 struct smc91cxx_softc *sc = ifp->if_softc; 309 310 return (smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_media)); 311 } 312 313 int 314 smc91cxx_set_media(struct smc91cxx_softc *sc, uint64_t media) 315 { 316 bus_space_tag_t bst = sc->sc_bst; 317 bus_space_handle_t bsh = sc->sc_bsh; 318 u_int16_t tmp; 319 320 /* 321 * If the interface is not currently powered on, just return. 322 * When it is enabled later, smc91cxx_init() will properly set 323 * up the media for us. 324 */ 325 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) 326 return (0); 327 328 if (IFM_TYPE(media) != IFM_ETHER) 329 return (EINVAL); 330 331 if (sc->sc_flags & SMC_FLAGS_HAS_MII) 332 return (mii_mediachg(&sc->sc_mii)); 333 334 switch (IFM_SUBTYPE(media)) { 335 case IFM_10_T: 336 case IFM_10_5: 337 SMC_SELECT_BANK(sc, 1); 338 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); 339 if (IFM_SUBTYPE(media) == IFM_10_5) 340 tmp |= CR_AUI_SELECT; 341 else 342 tmp &= ~CR_AUI_SELECT; 343 bus_space_write_2(bst, bsh, CONFIG_REG_W, tmp); 344 delay(20000); /* XXX is this needed? */ 345 break; 346 347 default: 348 return (EINVAL); 349 } 350 351 return (0); 352 } 353 354 /* 355 * Notify the world which media we're using. 356 */ 357 void 358 smc91cxx_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 359 { 360 struct smc91cxx_softc *sc = ifp->if_softc; 361 bus_space_tag_t bst = sc->sc_bst; 362 bus_space_handle_t bsh = sc->sc_bsh; 363 u_int16_t tmp; 364 365 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) { 366 ifmr->ifm_active = IFM_ETHER | IFM_NONE; 367 ifmr->ifm_status = 0; 368 return; 369 } 370 371 /* 372 * If we have MII, go ask the PHY what's going on. 373 */ 374 if (sc->sc_flags & SMC_FLAGS_HAS_MII) { 375 mii_pollstat(&sc->sc_mii); 376 ifmr->ifm_active = sc->sc_mii.mii_media_active; 377 ifmr->ifm_status = sc->sc_mii.mii_media_status; 378 return; 379 } 380 381 SMC_SELECT_BANK(sc, 1); 382 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); 383 ifmr->ifm_active = 384 IFM_ETHER | ((tmp & CR_AUI_SELECT) ? IFM_10_5 : IFM_10_T); 385 } 386 387 /* 388 * Reset and initialize the chip. 389 */ 390 void 391 smc91cxx_init(struct smc91cxx_softc *sc) 392 { 393 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 394 bus_space_tag_t bst = sc->sc_bst; 395 bus_space_handle_t bsh = sc->sc_bsh; 396 u_int16_t tmp; 397 int s, i; 398 399 s = splnet(); 400 401 /* 402 * This resets the registers mostly to defaults, but doesn't 403 * affect the EEPROM. After the reset cycle, we pause briefly 404 * for the chip to recover. 405 * 406 * XXX how long are we really supposed to delay? --thorpej 407 */ 408 SMC_SELECT_BANK(sc, 0); 409 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, RCR_SOFTRESET); 410 delay(100); 411 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0); 412 delay(200); 413 414 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0); 415 416 /* Set the Ethernet address. */ 417 SMC_SELECT_BANK(sc, 1); 418 for (i = 0; i < ETHER_ADDR_LEN; i++ ) 419 bus_space_write_1(bst, bsh, IAR_ADDR0_REG_W + i, 420 sc->sc_arpcom.ac_enaddr[i]); 421 422 /* 423 * Set the control register to automatically release successfully 424 * transmitted packets (making the best use of our limited memory) 425 * and enable the EPH interrupt on certain TX errors. 426 */ 427 bus_space_write_2(bst, bsh, CONTROL_REG_W, (CTR_AUTO_RELEASE | 428 CTR_TE_ENABLE | CTR_CR_ENABLE | CTR_LE_ENABLE)); 429 430 /* 431 * Reset the MMU and wait for it to be un-busy. 432 */ 433 SMC_SELECT_BANK(sc, 2); 434 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RESET); 435 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 436 /* XXX bound this loop! */ ; 437 438 /* 439 * Disable all interrupts. 440 */ 441 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0); 442 443 /* 444 * Set current media. 445 */ 446 smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_cur->ifm_media); 447 448 /* 449 * Set the receive filter. We want receive enable and auto 450 * strip of CRC from received packet. If we are in promisc. mode, 451 * then set that bit as well. 452 * 453 * XXX Initialize multicast filter. For now, we just accept 454 * XXX all multicast. 455 */ 456 SMC_SELECT_BANK(sc, 0); 457 458 tmp = RCR_ENABLE | RCR_STRIP_CRC | RCR_ALMUL; 459 if (ifp->if_flags & IFF_PROMISC) 460 tmp |= RCR_PROMISC; 461 462 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, tmp); 463 464 /* 465 * Set transmitter control to "enabled". 466 */ 467 tmp = TCR_ENABLE; 468 469 #ifndef SMC91CXX_SW_PAD 470 /* 471 * Enable hardware padding of transmitted packets. 472 * XXX doesn't work? 473 */ 474 tmp |= TCR_PAD_ENABLE; 475 #endif 476 477 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, tmp); 478 479 /* 480 * Now, enable interrupts. 481 */ 482 SMC_SELECT_BANK(sc, 2); 483 484 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 485 IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | IM_TX_INT); 486 487 /* Interface is now running, with no output active. */ 488 ifp->if_flags |= IFF_RUNNING; 489 ifq_clr_oactive(&ifp->if_snd); 490 491 if (sc->sc_flags & SMC_FLAGS_HAS_MII) { 492 /* Start the one second clock. */ 493 timeout_set(&sc->sc_mii_timeout, smc91cxx_tick, sc); 494 timeout_add_sec(&sc->sc_mii_timeout, 1); 495 } 496 497 /* 498 * Attempt to start any pending transmission. 499 */ 500 smc91cxx_start(ifp); 501 502 splx(s); 503 } 504 505 /* 506 * Start output on an interface. 507 * Must be called at splnet or interrupt level. 508 */ 509 void 510 smc91cxx_start(struct ifnet *ifp) 511 { 512 struct smc91cxx_softc *sc = ifp->if_softc; 513 bus_space_tag_t bst = sc->sc_bst; 514 bus_space_handle_t bsh = sc->sc_bsh; 515 u_int len; 516 struct mbuf *m, *top; 517 u_int16_t length, npages; 518 u_int8_t packetno; 519 int timo, pad; 520 521 if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd)) 522 return; 523 524 again: 525 /* 526 * Peek at the next packet. 527 */ 528 m = ifq_deq_begin(&ifp->if_snd); 529 if (m == NULL) 530 return; 531 532 /* 533 * Compute the frame length and set pad to give an overall even 534 * number of bytes. Below, we assume that the packet length 535 * is even. 536 */ 537 for (len = 0, top = m; m != NULL; m = m->m_next) 538 len += m->m_len; 539 pad = (len & 1); 540 541 /* 542 * We drop packets that are too large. Perhaps we should 543 * truncate them instead? 544 */ 545 if ((len + pad) > (ETHER_MAX_LEN - ETHER_CRC_LEN)) { 546 printf("%s: large packet discarded\n", sc->sc_dev.dv_xname); 547 ifp->if_oerrors++; 548 ifq_deq_commit(&ifp->if_snd, m); 549 m_freem(m); 550 goto readcheck; 551 } 552 553 #ifdef SMC91CXX_SW_PAD 554 /* 555 * Not using hardware padding; pad to ETHER_MIN_LEN. 556 */ 557 if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN)) 558 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len; 559 #endif 560 561 length = pad + len; 562 563 /* 564 * The MMU has a 256 byte page size. The MMU expects us to 565 * ask for "npages - 1". We include space for the status word, 566 * byte count, and control bytes in the allocation request. 567 */ 568 npages = (length + 6) >> 8; 569 570 /* 571 * Now allocate the memory. 572 */ 573 SMC_SELECT_BANK(sc, 2); 574 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ALLOC | npages); 575 576 timo = MEMORY_WAIT_TIME; 577 do { 578 if (bus_space_read_1(bst, bsh, INTR_STAT_REG_B) & IM_ALLOC_INT) 579 break; 580 delay(1); 581 } while (--timo); 582 583 packetno = bus_space_read_1(bst, bsh, ALLOC_RESULT_REG_B); 584 585 if (packetno & ARR_FAILED || timo == 0) { 586 /* 587 * No transmit memory is available. Record the number 588 * of requested pages and enable the allocation completion 589 * interrupt. Set up the watchdog timer in case we miss 590 * the interrupt. Mark the interface as active so that 591 * no one else attempts to transmit while we're allocating 592 * memory. 593 */ 594 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 595 bus_space_read_1(bst, bsh, INTR_MASK_REG_B) | IM_ALLOC_INT); 596 597 ifp->if_timer = 5; 598 ifq_deq_rollback(&ifp->if_snd, m); 599 ifq_set_oactive(&ifp->if_snd); 600 return; 601 } 602 603 /* 604 * We have a packet number - set the data window. 605 */ 606 bus_space_write_1(bst, bsh, PACKET_NUM_REG_B, packetno); 607 608 /* 609 * Point to the beginning of the packet. 610 */ 611 bus_space_write_2(bst, bsh, POINTER_REG_W, PTR_AUTOINC /* | 0x0000 */); 612 613 /* 614 * Send the packet length (+6 for stats, length, and control bytes) 615 * and the status word (set to zeros). 616 */ 617 bus_space_write_2(bst, bsh, DATA_REG_W, 0); 618 bus_space_write_1(bst, bsh, DATA_REG_B, (length + 6) & 0xff); 619 bus_space_write_1(bst, bsh, DATA_REG_B, ((length + 6) >> 8) & 0xff); 620 621 /* 622 * Get the packet from the kernel. This will include the Ethernet 623 * frame header, MAC address, etc. 624 */ 625 ifq_deq_commit(&ifp->if_snd, m); 626 627 /* 628 * Push the packet out to the card. 629 */ 630 for (top = m; m != NULL; m = m->m_next) { 631 /* Words... */ 632 if (m->m_len > 1) 633 bus_space_write_multi_stream_2(bst, bsh, DATA_REG_W, 634 mtod(m, u_int16_t *), m->m_len >> 1); 635 636 /* ...and the remaining byte, if any. */ 637 if (m->m_len & 1) 638 bus_space_write_1(bst, bsh, DATA_REG_B, 639 *(u_int8_t *)(mtod(m, u_int8_t *) + (m->m_len - 1))); 640 } 641 642 #ifdef SMC91CXX_SW_PAD 643 /* 644 * Push out padding. 645 */ 646 while (pad > 1) { 647 bus_space_write_2(bst, bsh, DATA_REG_W, 0); 648 pad -= 2; 649 } 650 if (pad) 651 bus_space_write_1(bst, bsh, DATA_REG_B, 0); 652 #endif 653 654 /* 655 * Push out control byte and unused packet byte. The control byte 656 * is 0, meaning the packet is even lengthed and no special 657 * CRC handling is necessary. 658 */ 659 bus_space_write_2(bst, bsh, DATA_REG_W, 0); 660 661 /* 662 * Enable transmit interrupts and let the chip go. Set a watchdog 663 * in case we miss the interrupt. 664 */ 665 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 666 bus_space_read_1(bst, bsh, INTR_MASK_REG_B) | 667 IM_TX_INT | IM_TX_EMPTY_INT); 668 669 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ENQUEUE); 670 671 ifp->if_timer = 5; 672 673 #if NBPFILTER > 0 674 if (ifp->if_bpf) 675 bpf_mtap(ifp->if_bpf, top, BPF_DIRECTION_OUT); 676 #endif 677 678 m_freem(top); 679 680 readcheck: 681 /* 682 * Check for incoming packets. We don't want to overflow the small 683 * RX FIFO. If nothing has arrived, attempt to queue another 684 * transmit packet. 685 */ 686 if (bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) & FIFO_REMPTY) 687 goto again; 688 } 689 690 /* 691 * Interrupt service routine. 692 */ 693 int 694 smc91cxx_intr(void *arg) 695 { 696 struct smc91cxx_softc *sc = arg; 697 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 698 bus_space_tag_t bst = sc->sc_bst; 699 bus_space_handle_t bsh = sc->sc_bsh; 700 u_int8_t mask, interrupts, status; 701 u_int16_t packetno, tx_status, card_stats; 702 703 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0 || 704 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) 705 return (0); 706 707 SMC_SELECT_BANK(sc, 2); 708 709 /* 710 * Obtain the current interrupt mask. 711 */ 712 mask = bus_space_read_1(bst, bsh, INTR_MASK_REG_B); 713 714 /* 715 * Get the set of interrupt which occurred and eliminate any 716 * which are not enabled. 717 */ 718 interrupts = bus_space_read_1(bst, bsh, INTR_STAT_REG_B); 719 status = interrupts & mask; 720 721 /* Ours? */ 722 if (status == 0) 723 return (0); 724 725 /* 726 * It's ours; disable all interrupts while we process them. 727 */ 728 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0); 729 730 /* 731 * Receive overrun interrupts. 732 */ 733 if (status & IM_RX_OVRN_INT) { 734 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_RX_OVRN_INT); 735 ifp->if_ierrors++; 736 } 737 738 /* 739 * Receive interrupts. 740 */ 741 if (status & IM_RCV_INT) { 742 #if 1 /* DIAGNOSTIC */ 743 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W); 744 if (packetno & FIFO_REMPTY) { 745 printf("%s: receive interrupt on empty fifo\n", 746 sc->sc_dev.dv_xname); 747 goto out; 748 } else 749 #endif 750 smc91cxx_read(sc); 751 } 752 753 /* 754 * Memory allocation interrupts. 755 */ 756 if (status & IM_ALLOC_INT) { 757 /* Disable this interrupt. */ 758 mask &= ~IM_ALLOC_INT; 759 760 /* 761 * Release the just-allocated memory. We will reallocate 762 * it through the normal start logic. 763 */ 764 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 765 /* XXX bound this loop! */ ; 766 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT); 767 768 ifq_clr_oactive(&ifp->if_snd); 769 ifp->if_timer = 0; 770 } 771 772 /* 773 * Transmit complete interrupt. Handle transmission error messages. 774 * This will only be called on error condition because of AUTO RELEASE 775 * mode. 776 */ 777 if (status & IM_TX_INT) { 778 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_TX_INT); 779 780 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) & 781 FIFO_TX_MASK; 782 783 /* 784 * Select this as the packet to read from. 785 */ 786 bus_space_write_1(bst, bsh, PACKET_NUM_REG_B, packetno); 787 788 /* 789 * Position the pointer to the beginning of the packet. 790 */ 791 bus_space_write_2(bst, bsh, POINTER_REG_W, 792 PTR_AUTOINC | PTR_READ /* | 0x0000 */); 793 794 /* 795 * Fetch the TX status word. This will be a copy of 796 * the EPH_STATUS_REG_W at the time of the transmission 797 * failure. 798 */ 799 tx_status = bus_space_read_2(bst, bsh, DATA_REG_W); 800 801 if (tx_status & EPHSR_TX_SUC) 802 printf("%s: successful packet caused TX interrupt?!\n", 803 sc->sc_dev.dv_xname); 804 else 805 ifp->if_oerrors++; 806 807 if (tx_status & EPHSR_LATCOL) 808 ifp->if_collisions++; 809 810 /* 811 * Some of these errors disable the transmitter; reenable it. 812 */ 813 SMC_SELECT_BANK(sc, 0); 814 #ifdef SMC91CXX_SW_PAD 815 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, TCR_ENABLE); 816 #else 817 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 818 TCR_ENABLE | TCR_PAD_ENABLE); 819 #endif 820 821 /* 822 * Kill the failed packet and wait for the MMU to unbusy. 823 */ 824 SMC_SELECT_BANK(sc, 2); 825 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 826 /* XXX bound this loop! */ ; 827 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT); 828 829 ifp->if_timer = 0; 830 } 831 832 /* 833 * Transmit underrun interrupts. We use this opportunity to 834 * update transmit statistics from the card. 835 */ 836 if (status & IM_TX_EMPTY_INT) { 837 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_TX_EMPTY_INT); 838 839 /* Disable this interrupt. */ 840 mask &= ~IM_TX_EMPTY_INT; 841 842 SMC_SELECT_BANK(sc, 0); 843 card_stats = bus_space_read_2(bst, bsh, COUNTER_REG_W); 844 845 /* Single collisions. */ 846 ifp->if_collisions += card_stats & ECR_COLN_MASK; 847 848 /* Multiple collisions. */ 849 ifp->if_collisions += (card_stats & ECR_MCOLN_MASK) >> 4; 850 851 SMC_SELECT_BANK(sc, 2); 852 853 ifp->if_timer = 0; 854 } 855 856 /* 857 * Other errors. Reset the interface. 858 */ 859 if (status & IM_EPH_INT) { 860 smc91cxx_stop(sc); 861 smc91cxx_init(sc); 862 } 863 864 /* 865 * Attempt to queue more packets for transmission. 866 */ 867 smc91cxx_start(ifp); 868 869 out: 870 /* 871 * Reenable the interrupts we wish to receive now that processing 872 * is complete. 873 */ 874 mask |= bus_space_read_1(bst, bsh, INTR_MASK_REG_B); 875 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, mask); 876 877 return (1); 878 } 879 880 /* 881 * Read a packet from the card and pass it up to the kernel. 882 * NOTE! WE EXPECT TO BE IN REGISTER WINDOW 2! 883 */ 884 void 885 smc91cxx_read(struct smc91cxx_softc *sc) 886 { 887 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 888 bus_space_tag_t bst = sc->sc_bst; 889 bus_space_handle_t bsh = sc->sc_bsh; 890 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 891 struct mbuf *m; 892 u_int16_t status, packetno, packetlen; 893 u_int8_t *data; 894 895 again: 896 /* 897 * Set data pointer to the beginning of the packet. Since 898 * PTR_RCV is set, the packet number will be found automatically 899 * in FIFO_PORTS_REG_W, FIFO_RX_MASK. 900 */ 901 bus_space_write_2(bst, bsh, POINTER_REG_W, 902 PTR_READ | PTR_RCV | PTR_AUTOINC /* | 0x0000 */); 903 904 /* 905 * First two words are status and packet length. 906 */ 907 status = bus_space_read_2(bst, bsh, DATA_REG_W); 908 packetlen = bus_space_read_2(bst, bsh, DATA_REG_W); 909 910 /* 911 * The packet length includes 3 extra words: status, length, 912 * and an extra word that includes the control byte. 913 */ 914 packetlen -= 6; 915 916 /* 917 * Account for receive errors and discard. 918 */ 919 if (status & RS_ERRORS) { 920 ifp->if_ierrors++; 921 goto out; 922 } 923 924 /* 925 * Adjust for odd-length packet. 926 */ 927 if (status & RS_ODDFRAME) 928 packetlen++; 929 930 /* 931 * Allocate a header mbuf. 932 */ 933 MGETHDR(m, M_DONTWAIT, MT_DATA); 934 if (m == NULL) 935 goto out; 936 m->m_pkthdr.len = packetlen; 937 938 /* 939 * Always put the packet in a cluster. 940 * XXX should chain small mbufs if less than threshold. 941 */ 942 MCLGET(m, M_DONTWAIT); 943 if ((m->m_flags & M_EXT) == 0) { 944 m_freem(m); 945 ifp->if_ierrors++; 946 printf("%s: can't allocate cluster for incoming packet\n", 947 sc->sc_dev.dv_xname); 948 goto out; 949 } 950 951 /* 952 * Pull the packet off the interface. Make sure the payload 953 * is aligned. 954 */ 955 m->m_data = (caddr_t) ALIGN(mtod(m, caddr_t) + 956 sizeof(struct ether_header)) - sizeof(struct ether_header); 957 958 data = mtod(m, u_int8_t *); 959 if (packetlen > 1) 960 bus_space_read_multi_stream_2(bst, bsh, DATA_REG_W, 961 (u_int16_t *)data, packetlen >> 1); 962 if (packetlen & 1) { 963 data += packetlen & ~1; 964 *data = bus_space_read_1(bst, bsh, DATA_REG_B); 965 } 966 967 m->m_pkthdr.len = m->m_len = packetlen; 968 ml_enqueue(&ml, m); 969 970 out: 971 /* 972 * Tell the card to free the memory occupied by this packet. 973 */ 974 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY) 975 /* XXX bound this loop! */ ; 976 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RELEASE); 977 978 /* 979 * Check for another packet. 980 */ 981 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W); 982 if (packetno & FIFO_REMPTY) { 983 if_input(ifp, &ml); 984 return; 985 } 986 goto again; 987 } 988 989 /* 990 * Process an ioctl request. 991 */ 992 int 993 smc91cxx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 994 { 995 struct smc91cxx_softc *sc = ifp->if_softc; 996 struct ifreq *ifr = (struct ifreq *)data; 997 int s, error = 0; 998 999 s = splnet(); 1000 1001 switch (cmd) { 1002 case SIOCSIFADDR: 1003 if ((error = smc91cxx_enable(sc)) != 0) 1004 break; 1005 ifp->if_flags |= IFF_UP; 1006 smc91cxx_init(sc); 1007 break; 1008 1009 case SIOCSIFFLAGS: 1010 if ((ifp->if_flags & IFF_UP) == 0 && 1011 (ifp->if_flags & IFF_RUNNING) != 0) { 1012 /* 1013 * If interface is marked down and it is running, 1014 * stop it. 1015 */ 1016 smc91cxx_stop(sc); 1017 ifp->if_flags &= ~IFF_RUNNING; 1018 smc91cxx_disable(sc); 1019 } else if ((ifp->if_flags & IFF_UP) != 0 && 1020 (ifp->if_flags & IFF_RUNNING) == 0) { 1021 /* 1022 * If interface is marked up and it is stopped, 1023 * start it. 1024 */ 1025 if ((error = smc91cxx_enable(sc)) != 0) 1026 break; 1027 smc91cxx_init(sc); 1028 } else if ((ifp->if_flags & IFF_UP) != 0) { 1029 /* 1030 * Reset the interface to pick up changes in any 1031 * other flags that affect hardware registers. 1032 */ 1033 smc91cxx_reset(sc); 1034 } 1035 break; 1036 1037 case SIOCGIFMEDIA: 1038 case SIOCSIFMEDIA: 1039 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd); 1040 break; 1041 1042 default: 1043 error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data); 1044 } 1045 1046 if (error == ENETRESET) { 1047 if (ifp->if_flags & IFF_RUNNING) 1048 smc91cxx_reset(sc); 1049 error = 0; 1050 } 1051 1052 splx(s); 1053 return (error); 1054 } 1055 1056 /* 1057 * Reset the interface. 1058 */ 1059 void 1060 smc91cxx_reset(struct smc91cxx_softc *sc) 1061 { 1062 int s; 1063 1064 s = splnet(); 1065 smc91cxx_stop(sc); 1066 smc91cxx_init(sc); 1067 splx(s); 1068 } 1069 1070 /* 1071 * Watchdog timer. 1072 */ 1073 void 1074 smc91cxx_watchdog(struct ifnet *ifp) 1075 { 1076 struct smc91cxx_softc *sc = ifp->if_softc; 1077 1078 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 1079 ++sc->sc_arpcom.ac_if.if_oerrors; 1080 1081 smc91cxx_reset(sc); 1082 } 1083 1084 /* 1085 * Stop output on the interface. 1086 */ 1087 void 1088 smc91cxx_stop(struct smc91cxx_softc *sc) 1089 { 1090 bus_space_tag_t bst = sc->sc_bst; 1091 bus_space_handle_t bsh = sc->sc_bsh; 1092 1093 /* 1094 * Clear interrupt mask; disable all interrupts. 1095 */ 1096 SMC_SELECT_BANK(sc, 2); 1097 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0); 1098 1099 /* 1100 * Disable transmitter and receiver. 1101 */ 1102 SMC_SELECT_BANK(sc, 0); 1103 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0); 1104 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0); 1105 1106 /* 1107 * Cancel watchdog timer. 1108 */ 1109 sc->sc_arpcom.ac_if.if_timer = 0; 1110 } 1111 1112 /* 1113 * Enable power on the interface. 1114 */ 1115 int 1116 smc91cxx_enable(struct smc91cxx_softc *sc) 1117 { 1118 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0 && sc->sc_enable != NULL) { 1119 if ((*sc->sc_enable)(sc) != 0) { 1120 printf("%s: device enable failed\n", 1121 sc->sc_dev.dv_xname); 1122 return (EIO); 1123 } 1124 } 1125 1126 sc->sc_flags |= SMC_FLAGS_ENABLED; 1127 return (0); 1128 } 1129 1130 /* 1131 * Disable power on the interface. 1132 */ 1133 void 1134 smc91cxx_disable(struct smc91cxx_softc *sc) 1135 { 1136 if ((sc->sc_flags & SMC_FLAGS_ENABLED) != 0 && sc->sc_disable != NULL) { 1137 (*sc->sc_disable)(sc); 1138 sc->sc_flags &= ~SMC_FLAGS_ENABLED; 1139 } 1140 } 1141 1142 int 1143 smc91cxx_detach(struct device *self, int flags) 1144 { 1145 struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self; 1146 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 1147 1148 /* Succeed now if there's no work to do. */ 1149 if ((sc->sc_flags & SMC_FLAGS_ATTACHED) == 0) 1150 return(0); 1151 1152 /* smc91cxx_disable() checks SMC_FLAGS_ENABLED */ 1153 smc91cxx_disable(sc); 1154 1155 /* smc91cxx_attach() never fails */ 1156 1157 /* Delete all media. */ 1158 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); 1159 1160 ether_ifdetach(ifp); 1161 if_detach(ifp); 1162 1163 return (0); 1164 } 1165 1166 u_int32_t 1167 smc91cxx_mii_bitbang_read(struct device *self) 1168 { 1169 struct smc91cxx_softc *sc = (void *) self; 1170 1171 /* We're already in bank 3. */ 1172 return (bus_space_read_2(sc->sc_bst, sc->sc_bsh, MGMT_REG_W)); 1173 } 1174 1175 void 1176 smc91cxx_mii_bitbang_write(struct device *self, u_int32_t val) 1177 { 1178 struct smc91cxx_softc *sc = (void *) self; 1179 1180 /* We're already in bank 3. */ 1181 bus_space_write_2(sc->sc_bst, sc->sc_bsh, MGMT_REG_W, val); 1182 } 1183 1184 int 1185 smc91cxx_mii_readreg(struct device *self, int phy, int reg) 1186 { 1187 struct smc91cxx_softc *sc = (void *) self; 1188 int val; 1189 1190 SMC_SELECT_BANK(sc, 3); 1191 1192 val = mii_bitbang_readreg(self, &smc91cxx_mii_bitbang_ops, phy, reg); 1193 1194 SMC_SELECT_BANK(sc, 2); 1195 1196 return (val); 1197 } 1198 1199 void 1200 smc91cxx_mii_writereg(struct device *self, int phy, int reg, int val) 1201 { 1202 struct smc91cxx_softc *sc = (void *) self; 1203 1204 SMC_SELECT_BANK(sc, 3); 1205 1206 mii_bitbang_writereg(self, &smc91cxx_mii_bitbang_ops, phy, reg, val); 1207 1208 SMC_SELECT_BANK(sc, 2); 1209 } 1210 1211 void 1212 smc91cxx_statchg(struct device *self) 1213 { 1214 struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self; 1215 bus_space_tag_t bst = sc->sc_bst; 1216 bus_space_handle_t bsh = sc->sc_bsh; 1217 int mctl; 1218 1219 SMC_SELECT_BANK(sc, 0); 1220 mctl = bus_space_read_2(bst, bsh, TXMIT_CONTROL_REG_W); 1221 if (sc->sc_mii.mii_media_active & IFM_FDX) 1222 mctl |= TCR_SWFDUP; 1223 else 1224 mctl &= ~TCR_SWFDUP; 1225 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, mctl); 1226 SMC_SELECT_BANK(sc, 2); /* back to operating window */ 1227 } 1228 1229 /* 1230 * One second timer, used to tick the MII. 1231 */ 1232 void 1233 smc91cxx_tick(void *arg) 1234 { 1235 struct smc91cxx_softc *sc = arg; 1236 int s; 1237 1238 #ifdef DIAGNOSTIC 1239 if ((sc->sc_flags & SMC_FLAGS_HAS_MII) == 0) 1240 panic("smc91cxx_tick"); 1241 #endif 1242 1243 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) 1244 return; 1245 1246 s = splnet(); 1247 mii_tick(&sc->sc_mii); 1248 splx(s); 1249 1250 timeout_add_sec(&sc->sc_mii_timeout, 1); 1251 } 1252