1 /* $OpenBSD: if_ef_isapnp.c,v 1.38 2016/04/13 10:49:26 mpi Exp $ */ 2 3 /* 4 * Copyright (c) 1999 Jason L. Wright (jason@thought.net) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "bpfilter.h" 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/mbuf.h> 34 #include <sys/socket.h> 35 #include <sys/ioctl.h> 36 #include <sys/errno.h> 37 #include <sys/syslog.h> 38 #include <sys/selinfo.h> 39 #include <sys/device.h> 40 #include <sys/queue.h> 41 #include <sys/kernel.h> 42 #include <sys/timeout.h> 43 44 #include <net/if.h> 45 #include <net/if_media.h> 46 47 #include <netinet/in.h> 48 #include <netinet/if_ether.h> 49 50 #if NBPFILTER > 0 51 #include <net/bpf.h> 52 #endif 53 54 #include <machine/cpu.h> 55 #include <machine/bus.h> 56 #include <machine/intr.h> 57 58 #include <dev/mii/mii.h> 59 #include <dev/mii/miivar.h> 60 #include <dev/isa/isavar.h> 61 #include <dev/isa/isadmavar.h> 62 #include <dev/ic/elink3reg.h> 63 64 #undef EF_DEBUG 65 66 struct ef_softc { 67 struct device sc_dv; 68 bus_space_tag_t sc_iot; 69 bus_space_handle_t sc_ioh; 70 struct arpcom sc_arpcom; 71 struct mii_data sc_mii; 72 struct timeout sc_tick_tmo; 73 void * sc_ih; 74 int sc_tx_start_thresh; 75 int sc_tx_succ_ok; 76 int sc_busmaster; 77 }; 78 79 #define EF_W0_EEPROM_COMMAND 0x200a 80 #define EF_EEPROM_BUSY (1 << 9) 81 #define EF_EEPROM_READ (1 << 7) 82 #define EF_W0_EEPROM_DATA 0x200c 83 84 #define EF_W1_TX_PIO_WR_1 0x10 85 #define EF_W1_RX_PIO_RR_1 0x10 86 #define EF_W1_RX_ERRORS 0x14 87 #define EF_W1_RX_STATUS 0x18 88 #define EF_W1_TX_STATUS 0x1b 89 #define EF_W1_FREE_TX 0x1c 90 91 #define EF_W4_MEDIA 0x0a 92 #define EF_MEDIA_SQE 0x0008 /* sqe error for aui */ 93 #define EF_MEDIA_TP 0x00c0 /* link/jabber, 10baseT */ 94 #define EF_MEDIA_LNK 0x0080 /* linkbeat, 100baseTX/FX */ 95 #define EF_MEDIA_LNKBEAT 0x0800 96 97 /* Window 4: EP_W4_CTRLR_STATUS: mii manipulation */ 98 #define EF_MII_CLK 0x01 /* clock bit */ 99 #define EF_MII_DATA 0x02 /* data bit */ 100 #define EF_MII_DIR 0x04 /* direction */ 101 102 int ef_isapnp_match(struct device *, void *, void *); 103 void ef_isapnp_attach(struct device *, struct device *, void *); 104 105 void efstart(struct ifnet *); 106 int efioctl(struct ifnet *, u_long, caddr_t); 107 void efwatchdog(struct ifnet *); 108 void efreset(struct ef_softc *); 109 void efstop(struct ef_softc *); 110 void efsetmulti(struct ef_softc *); 111 int efbusyeeprom(struct ef_softc *); 112 int efintr(void *); 113 void efinit(struct ef_softc *); 114 void efcompletecmd(struct ef_softc *, u_int, u_int); 115 void eftxstat(struct ef_softc *); 116 void efread(struct ef_softc *); 117 struct mbuf *efget(struct ef_softc *, int totlen); 118 119 void ef_miibus_writereg(struct device *, int, int, int); 120 void ef_miibus_statchg(struct device *); 121 int ef_miibus_readreg(struct device *, int, int); 122 void ef_mii_writeb(struct ef_softc *, int); 123 void ef_mii_sync(struct ef_softc *); 124 int ef_ifmedia_upd(struct ifnet *); 125 void ef_ifmedia_sts(struct ifnet *, struct ifmediareq *); 126 void ef_tick(void *); 127 128 struct cfdriver ef_cd = { 129 NULL, "ef", DV_IFNET 130 }; 131 132 struct cfattach ef_isapnp_ca = { 133 sizeof(struct ef_softc), ef_isapnp_match, ef_isapnp_attach 134 }; 135 136 int 137 ef_isapnp_match(parent, match, aux) 138 struct device *parent; 139 void *match, *aux; 140 { 141 return (1); 142 } 143 144 void 145 ef_isapnp_attach(parent, self, aux) 146 struct device *parent, *self; 147 void *aux; 148 { 149 struct ef_softc *sc = (void *)self; 150 struct isa_attach_args *ia = aux; 151 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 152 bus_space_tag_t iot; 153 bus_space_handle_t ioh; 154 int i; 155 u_int16_t x; 156 u_int32_t cfg; 157 158 sc->sc_iot = iot = ia->ia_iot; 159 sc->sc_ioh = ioh = ia->ipa_io[0].h; 160 161 efcompletecmd(sc, EP_COMMAND, GLOBAL_RESET); 162 DELAY(1500); 163 164 for (i = 0; i < 3; i++) { 165 if (efbusyeeprom(sc)) 166 return; 167 168 bus_space_write_2(iot, ioh, EF_W0_EEPROM_COMMAND, 169 EF_EEPROM_READ | i); 170 171 if (efbusyeeprom(sc)) 172 return; 173 174 x = bus_space_read_2(iot, ioh, EF_W0_EEPROM_DATA); 175 176 sc->sc_arpcom.ac_enaddr[(i << 1)] = x >> 8; 177 sc->sc_arpcom.ac_enaddr[(i << 1) + 1] = x; 178 } 179 180 printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); 181 182 GO_WINDOW(3); 183 cfg = bus_space_read_4(iot, ioh, EP_W3_INTERNAL_CONFIG); 184 cfg &= ~(0x00f00000); 185 cfg |= (0x06 << 20); 186 bus_space_write_4(iot, ioh, EP_W3_INTERNAL_CONFIG, cfg); 187 188 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 189 IPL_NET, efintr, sc, sc->sc_dv.dv_xname); 190 191 if (ia->ia_drq != DRQUNK) 192 isadma_cascade(ia->ia_drq); 193 194 timeout_set(&sc->sc_tick_tmo, ef_tick, sc); 195 196 bcopy(sc->sc_dv.dv_xname, ifp->if_xname, IFNAMSIZ); 197 ifp->if_softc = sc; 198 ifp->if_start = efstart; 199 ifp->if_ioctl = efioctl; 200 ifp->if_watchdog = efwatchdog; 201 ifp->if_flags = 202 IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 203 204 sc->sc_mii.mii_ifp = ifp; 205 sc->sc_mii.mii_readreg = ef_miibus_readreg; 206 sc->sc_mii.mii_writereg = ef_miibus_writereg; 207 sc->sc_mii.mii_statchg = ef_miibus_statchg; 208 ifmedia_init(&sc->sc_mii.mii_media, 0, ef_ifmedia_upd, ef_ifmedia_sts); 209 mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 210 0); 211 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { 212 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); 213 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE); 214 } else 215 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); 216 217 if_attach(ifp); 218 ether_ifattach(ifp); 219 220 sc->sc_tx_start_thresh = 20; 221 222 efcompletecmd(sc, EP_COMMAND, RX_RESET); 223 efcompletecmd(sc, EP_COMMAND, TX_RESET); 224 } 225 226 void 227 efstart(ifp) 228 struct ifnet *ifp; 229 { 230 struct ef_softc *sc = ifp->if_softc; 231 bus_space_tag_t iot = sc->sc_iot; 232 bus_space_handle_t ioh = sc->sc_ioh; 233 struct mbuf *m, *m0; 234 int s, len, pad, i; 235 int fillcnt = 0; 236 u_int32_t filler = 0; 237 238 if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd)) 239 return; 240 241 startagain: 242 m0 = ifq_deq_begin(&ifp->if_snd); 243 if (m0 == NULL) 244 return; 245 246 if ((m0->m_flags & M_PKTHDR) == 0) 247 panic("efstart: no header mbuf"); 248 len = m0->m_pkthdr.len; 249 pad = (4 - len) & 3; 250 251 if (len + pad > ETHER_MAX_LEN) { 252 ifp->if_oerrors++; 253 ifq_deq_commit(&ifp->if_snd, m0); 254 m_freem(m0); 255 goto startagain; 256 } 257 258 if (bus_space_read_2(iot, ioh, EF_W1_FREE_TX) < len + pad + 4) { 259 bus_space_write_2(iot, ioh, EP_COMMAND, 260 SET_TX_AVAIL_THRESH | ((len + pad) >> 2)); 261 ifq_deq_rollback(&ifp->if_snd, m0); 262 ifq_set_oactive(&ifp->if_snd); 263 return; 264 } else { 265 bus_space_write_2(iot, ioh, EP_COMMAND, 266 SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE); 267 } 268 269 bus_space_write_2(iot, ioh, EP_COMMAND, SET_TX_START_THRESH | 270 ((len / 4 + sc->sc_tx_start_thresh))); 271 272 #if NBPFILTER 273 if (ifp->if_bpf) 274 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT); 275 #endif 276 277 ifq_deq_commit(&ifp->if_snd, m0); 278 if (m0 == NULL) /* XXX not needed */ 279 return; 280 281 s = splhigh(); 282 283 bus_space_write_4(iot, ioh, EF_W1_TX_PIO_WR_1, len); 284 for (m = m0; m; ) { 285 if (fillcnt) { 286 while (m->m_len && fillcnt < 4) { 287 fillcnt++; 288 filler >>= 8; 289 filler |= m->m_data[0] << 24; 290 m->m_data++; 291 m->m_len--; 292 } 293 if (fillcnt == 4) { 294 bus_space_write_4(iot, ioh, 295 EF_W1_TX_PIO_WR_1, filler); 296 filler = 0; 297 fillcnt = 0; 298 } 299 } 300 301 if (m->m_len & ~3) 302 bus_space_write_multi_4(iot, ioh, 303 EF_W1_TX_PIO_WR_1, (u_int32_t *)m->m_data, 304 m->m_len >> 2); 305 for (i = 0; i < (m->m_len & 3); i++) { 306 fillcnt++; 307 filler >>= 8; 308 filler |= m->m_data[(m->m_len & ~3) + i] << 24; 309 } 310 m0 = m_free(m); 311 m = m0; 312 } 313 314 if (fillcnt) { 315 bus_space_write_4(iot, ioh, EF_W1_TX_PIO_WR_1, 316 filler >> (32 - (8 * fillcnt))); 317 fillcnt = 0; 318 filler = 0; 319 } 320 321 splx(s); 322 323 ifp->if_opackets++; 324 325 goto startagain; 326 } 327 328 int 329 efioctl(ifp, cmd, data) 330 struct ifnet *ifp; 331 u_long cmd; 332 caddr_t data; 333 { 334 struct ef_softc *sc = ifp->if_softc; 335 struct ifreq *ifr = (struct ifreq *)data; 336 int s, error = 0; 337 338 s = splnet(); 339 340 switch (cmd) { 341 case SIOCSIFADDR: 342 ifp->if_flags |= IFF_UP; 343 efinit(sc); 344 break; 345 case SIOCSIFMEDIA: 346 case SIOCGIFMEDIA: 347 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd); 348 break; 349 case SIOCSIFFLAGS: 350 if ((ifp->if_flags & IFF_UP) == 0 && 351 (ifp->if_flags & IFF_RUNNING) != 0) { 352 efstop(sc); 353 ifp->if_flags &= ~IFF_RUNNING; 354 } else if ((ifp->if_flags & IFF_UP) != 0 && 355 (ifp->if_flags & IFF_RUNNING) == 0) { 356 efinit(sc); 357 } 358 efsetmulti(sc); 359 break; 360 361 default: 362 error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data); 363 } 364 365 if (error == ENETRESET) { 366 if (ifp->if_flags & IFF_RUNNING) { 367 efreset(sc); 368 efsetmulti(sc); 369 } 370 error = 0; 371 } 372 373 splx(s); 374 return (error); 375 } 376 377 void 378 efinit(sc) 379 struct ef_softc *sc; 380 { 381 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 382 bus_space_tag_t iot = sc->sc_iot; 383 bus_space_handle_t ioh = sc->sc_ioh; 384 int i, s; 385 386 s = splnet(); 387 388 efstop(sc); 389 390 while (bus_space_read_2(iot, ioh, EP_STATUS) & S_COMMAND_IN_PROGRESS) 391 ; 392 393 GO_WINDOW(2); 394 for (i = 0; i < 6; i++) 395 bus_space_write_1(iot, ioh, EP_W2_ADDR_0 + i, 396 sc->sc_arpcom.ac_enaddr[i]); 397 for (i = 0; i < 3; i += 2) 398 bus_space_write_2(iot, ioh, EP_W2_RECVMASK_0 + (i * 2), 0); 399 400 efcompletecmd(sc, EP_COMMAND, RX_RESET); 401 efcompletecmd(sc, EP_COMMAND, TX_RESET); 402 403 bus_space_write_2(iot, ioh, EP_COMMAND, 404 SET_TX_AVAIL_THRESH | (ETHER_MAX_DIX_LEN >> 2)); 405 406 efsetmulti(sc); 407 408 bus_space_write_2(iot, ioh, EP_COMMAND, STATUS_ENABLE | 0); 409 410 GO_WINDOW(6); 411 for (i = 0; i < 10; i++) 412 (void)bus_space_read_1(iot, ioh, i); 413 (void)bus_space_read_2(iot, ioh, 10); 414 (void)bus_space_read_2(iot, ioh, 12); 415 GO_WINDOW(4); 416 (void)bus_space_read_1(iot, ioh, 12); 417 bus_space_write_2(iot, ioh, EP_W4_NET_DIAG, 0x0040); 418 419 GO_WINDOW(7); 420 421 efsetmulti(sc); 422 423 bus_space_write_2(iot, ioh, EP_COMMAND, RX_ENABLE); 424 bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE); 425 426 bus_space_write_2(iot, ioh, EP_COMMAND, STATUS_ENABLE | 427 S_CARD_FAILURE | S_INT_RQD | S_UPD_STATS | S_TX_COMPLETE | 428 S_TX_AVAIL | S_RX_COMPLETE | 429 (sc->sc_busmaster ? S_DMA_DONE : 0)); 430 bus_space_write_2(iot, ioh, EP_COMMAND, ACK_INTR | 431 S_INTR_LATCH | S_TX_AVAIL | S_RX_EARLY | S_INT_RQD); 432 bus_space_write_2(iot, ioh, EP_COMMAND, SET_INTR_MASK | 433 S_INTR_LATCH | S_TX_AVAIL | S_RX_COMPLETE | S_UPD_STATS | 434 (sc->sc_busmaster ? S_DMA_DONE : 0) | S_UP_COMPLETE | 435 S_DOWN_COMPLETE | S_CARD_FAILURE | S_TX_COMPLETE); 436 437 mii_mediachg(&sc->sc_mii); 438 439 ifp->if_flags |= IFF_RUNNING; 440 ifq_clr_oactive(&ifp->if_snd); 441 442 splx(s); 443 444 timeout_add_sec(&sc->sc_tick_tmo, 1); 445 446 efstart(ifp); 447 } 448 449 void 450 efreset(sc) 451 struct ef_softc *sc; 452 { 453 int s; 454 455 s = splnet(); 456 efstop(sc); 457 efinit(sc); 458 splx(s); 459 } 460 461 void 462 efstop(sc) 463 struct ef_softc *sc; 464 { 465 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 466 bus_space_tag_t iot = sc->sc_iot; 467 bus_space_handle_t ioh = sc->sc_ioh; 468 469 ifp->if_timer = 0; 470 ifp->if_flags &= ~IFF_RUNNING; 471 ifq_clr_oactive(&ifp->if_snd); 472 473 timeout_del(&sc->sc_tick_tmo); 474 475 bus_space_write_2(iot, ioh, EP_COMMAND, RX_DISABLE); 476 efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK); 477 478 bus_space_write_2(iot, ioh, EP_COMMAND, TX_DISABLE); 479 bus_space_write_2(iot, ioh, EP_COMMAND, STOP_TRANSCEIVER); 480 481 efcompletecmd(sc, EP_COMMAND, RX_RESET); 482 efcompletecmd(sc, EP_COMMAND, TX_RESET); 483 484 bus_space_write_2(iot, ioh, EP_COMMAND, C_INTR_LATCH); 485 bus_space_write_2(iot, ioh, EP_COMMAND, SET_RD_0_MASK); 486 bus_space_write_2(iot, ioh, EP_COMMAND, SET_INTR_MASK); 487 bus_space_write_2(iot, ioh, EP_COMMAND, SET_RX_FILTER); 488 } 489 490 void 491 efcompletecmd(sc, cmd, arg) 492 struct ef_softc *sc; 493 u_int cmd, arg; 494 { 495 bus_space_tag_t iot = sc->sc_iot; 496 bus_space_handle_t ioh = sc->sc_ioh; 497 498 bus_space_write_2(iot, ioh, cmd, arg); 499 while (bus_space_read_2(iot, ioh, EP_STATUS) & S_COMMAND_IN_PROGRESS) 500 ; 501 } 502 503 int 504 efintr(vsc) 505 void *vsc; 506 { 507 struct ef_softc *sc = vsc; 508 bus_space_tag_t iot = sc->sc_iot; 509 bus_space_handle_t ioh = sc->sc_ioh; 510 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 511 u_int16_t status; 512 int r = 0; 513 514 status = bus_space_read_2(iot, ioh, EP_STATUS); 515 516 do { 517 if (status & S_RX_COMPLETE) { 518 r = 1; 519 bus_space_write_2(iot, ioh, EP_STATUS, C_RX_COMPLETE); 520 efread(sc); 521 } 522 if (status & S_TX_AVAIL) { 523 bus_space_write_2(iot, ioh, EP_STATUS, C_TX_AVAIL); 524 r = 1; 525 ifq_clr_oactive(&sc->sc_arpcom.ac_if.if_snd); 526 efstart(&sc->sc_arpcom.ac_if); 527 } 528 if (status & S_CARD_FAILURE) { 529 r = 1; 530 efreset(sc); 531 printf("%s: adapter failure (%x)\n", 532 sc->sc_dv.dv_xname, status); 533 bus_space_write_2(iot, ioh, EP_COMMAND, 534 C_CARD_FAILURE); 535 return (1); 536 } 537 if (status & S_TX_COMPLETE) { 538 r = 1; 539 eftxstat(sc); 540 efstart(ifp); 541 } 542 bus_space_write_2(iot, ioh, EP_COMMAND, 543 C_INTR_LATCH | C_INT_RQD); 544 } while ((status = bus_space_read_2(iot, ioh, EP_STATUS)) & 545 (S_INT_RQD | S_RX_COMPLETE)); 546 547 return (r); 548 } 549 550 void 551 eftxstat(sc) 552 struct ef_softc *sc; 553 { 554 bus_space_tag_t iot = sc->sc_iot; 555 bus_space_handle_t ioh = sc->sc_ioh; 556 int i; 557 558 while ((i = bus_space_read_1(iot, ioh, EF_W1_TX_STATUS)) & 559 TXS_COMPLETE) { 560 bus_space_write_1(iot, ioh, EF_W1_TX_STATUS, 0); 561 562 if (i & TXS_JABBER) { 563 sc->sc_arpcom.ac_if.if_oerrors++; 564 #ifdef EF_DEBUG 565 if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG) 566 printf("%s: jabber (%x)\n", 567 sc->sc_dv.dv_xname, i); 568 #endif 569 efreset(sc); 570 } 571 else if (i & TXS_UNDERRUN) { 572 sc->sc_arpcom.ac_if.if_oerrors++; 573 #ifdef EF_DEBUG 574 if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG) 575 printf("%s: fifo underrun (%x) @%d\n", 576 sc->sc_dv.dv_xname, i, 577 sc->sc_tx_start_thresh); 578 #endif 579 if (sc->sc_tx_succ_ok < 100) 580 sc->sc_tx_start_thresh = min(ETHER_MAX_LEN, 581 sc->sc_tx_start_thresh + 20); 582 sc->sc_tx_succ_ok = 0; 583 efreset(sc); 584 } 585 else if (i & TXS_MAX_COLLISION) { 586 sc->sc_arpcom.ac_if.if_collisions++; 587 bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE); 588 ifq_clr_oactive(&sc->sc_arpcom.ac_if.if_snd); 589 } 590 else 591 sc->sc_tx_succ_ok = (sc->sc_tx_succ_ok + 1) & 127; 592 } 593 } 594 595 int 596 efbusyeeprom(sc) 597 struct ef_softc *sc; 598 { 599 int i = 100, j; 600 601 while (i--) { 602 j = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 603 EF_W0_EEPROM_COMMAND); 604 if (j & EF_EEPROM_BUSY) 605 delay(100); 606 else 607 break; 608 } 609 if (i == 0) { 610 printf("%s: eeprom failed to come ready\n", 611 sc->sc_dv.dv_xname); 612 return (1); 613 } 614 615 return (0); 616 } 617 618 void 619 efwatchdog(ifp) 620 struct ifnet *ifp; 621 { 622 struct ef_softc *sc = ifp->if_softc; 623 624 printf("%s: device timeout\n", sc->sc_dv.dv_xname); 625 sc->sc_arpcom.ac_if.if_oerrors++; 626 efreset(sc); 627 } 628 629 void 630 efsetmulti(sc) 631 struct ef_softc *sc; 632 { 633 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 634 struct arpcom *ac = &sc->sc_arpcom; 635 bus_space_tag_t iot = sc->sc_iot; 636 bus_space_handle_t ioh = sc->sc_ioh; 637 struct ether_multi *enm; 638 struct ether_multistep step; 639 u_int16_t cmd = SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST; 640 int mcnt = 0; 641 642 ETHER_FIRST_MULTI(step, ac, enm); 643 while (enm != NULL) { 644 mcnt++; 645 ETHER_NEXT_MULTI(step, enm); 646 } 647 if (mcnt || ifp->if_flags & IFF_ALLMULTI) 648 cmd |= FIL_MULTICAST; 649 650 if (ifp->if_flags & IFF_PROMISC) 651 cmd |= FIL_PROMISC; 652 653 bus_space_write_2(iot, ioh, EP_COMMAND, cmd); 654 } 655 656 void 657 efread(sc) 658 struct ef_softc *sc; 659 { 660 bus_space_tag_t iot = sc->sc_iot; 661 bus_space_handle_t ioh = sc->sc_ioh; 662 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 663 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 664 struct mbuf *m; 665 int len; 666 667 len = bus_space_read_2(iot, ioh, EF_W1_RX_STATUS); 668 669 #ifdef EF_DEBUG 670 if (ifp->if_flags & IFF_DEBUG) { 671 int err = len & ERR_MASK; 672 char *s = NULL; 673 674 if (len & ERR_INCOMPLETE) 675 s = "incomplete packet"; 676 else if (err == ERR_OVERRUN) 677 s = "packet overrun"; 678 else if (err == ERR_RUNT) 679 s = "runt packet"; 680 else if (err == ERR_ALIGNMENT) 681 s = "bad alignment"; 682 else if (err == ERR_CRC) 683 s = "bad crc"; 684 else if (err == ERR_OVERSIZE) 685 s = "oversized packet"; 686 else if (err == ERR_DRIBBLE) 687 s = "dribble bits"; 688 689 if (s) 690 printf("%s: %s\n", sc->sc_dv.dv_xname, s); 691 } 692 #endif 693 694 if (len & ERR_INCOMPLETE) 695 return; 696 697 if (len & ERR_RX) { 698 ifp->if_ierrors++; 699 efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK); 700 return; 701 } 702 703 len &= RX_BYTES_MASK; 704 m = efget(sc, len); 705 if (m == NULL) { 706 ifp->if_ierrors++; 707 efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK); 708 return; 709 } 710 711 ml_enqueue(&ml, m); 712 if_input(ifp, &ml); 713 } 714 715 struct mbuf * 716 efget(sc, totlen) 717 struct ef_softc *sc; 718 int totlen; 719 { 720 bus_space_tag_t iot = sc->sc_iot; 721 bus_space_handle_t ioh = sc->sc_ioh; 722 struct mbuf *top, **mp, *m; 723 int len, pad, s; 724 725 MGETHDR(m, M_DONTWAIT, MT_DATA); 726 if (m == NULL) 727 return (NULL); 728 m->m_pkthdr.len = totlen; 729 pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header); 730 m->m_data += pad; 731 len = MHLEN -pad; 732 top = 0; 733 mp = ⊤ 734 735 s = splhigh(); 736 737 while (totlen > 0) { 738 if (top) { 739 MGET(m, M_DONTWAIT, MT_DATA); 740 if (m == NULL) { 741 m_freem(top); 742 splx(s); 743 return (NULL); 744 } 745 len = MLEN; 746 } 747 if (top && totlen >= MINCLSIZE) { 748 MCLGET(m, M_DONTWAIT); 749 if (m->m_flags & M_EXT) 750 len = MCLBYTES; 751 } 752 len = min(totlen, len); 753 if (len > 1) { 754 len &= ~1; 755 bus_space_read_raw_multi_2(iot, ioh, 756 EF_W1_RX_PIO_RR_1, mtod(m, u_int8_t *), 757 len); 758 } else 759 *(mtod(m, u_int8_t *)) = 760 bus_space_read_1(iot, ioh, EF_W1_RX_PIO_RR_1); 761 762 m->m_len = len; 763 totlen -= len; 764 *mp = m; 765 mp = &m->m_next; 766 } 767 768 efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK); 769 770 splx(s); 771 772 return (top); 773 } 774 775 #define MII_SET(sc, x) \ 776 bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS, \ 777 bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS) \ 778 | (x)) 779 780 #define MII_CLR(sc, x) \ 781 bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS, \ 782 bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS) \ 783 & (~(x))) 784 785 void 786 ef_mii_writeb(sc, b) 787 struct ef_softc *sc; 788 int b; 789 { 790 MII_CLR(sc, EF_MII_CLK); 791 792 if (b) 793 MII_SET(sc, EF_MII_DATA); 794 else 795 MII_CLR(sc, EF_MII_DATA); 796 797 MII_CLR(sc, EF_MII_CLK); 798 DELAY(1); 799 MII_SET(sc, EF_MII_CLK); 800 DELAY(1); 801 } 802 803 void 804 ef_mii_sync(sc) 805 struct ef_softc *sc; 806 { 807 int i; 808 809 for (i = 0; i < 32; i++) 810 ef_mii_writeb(sc, 1); 811 } 812 813 int 814 ef_miibus_readreg(dev, phy, reg) 815 struct device *dev; 816 int phy, reg; 817 { 818 struct ef_softc *sc = (struct ef_softc *)dev; 819 int i, ack, s, val = 0; 820 821 s = splnet(); 822 823 GO_WINDOW(4); 824 bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_CTRLR_STATUS, 0); 825 826 /* Turn on xmit */ 827 MII_SET(sc, EF_MII_DIR); 828 MII_CLR(sc, EF_MII_CLK); 829 830 ef_mii_sync(sc); 831 832 /* Transmit start sequence */ 833 ef_mii_writeb(sc, 0); 834 ef_mii_writeb(sc, 1); 835 836 /* Transmit read sequence */ 837 ef_mii_writeb(sc, 1); 838 ef_mii_writeb(sc, 0); 839 840 /* Transmit phy addr */ 841 for (i = 0x10; i; i >>= 1) 842 ef_mii_writeb(sc, (phy & i) ? 1 : 0); 843 844 /* Transmit reg addr */ 845 for (i = 0x10; i; i >>= 1) 846 ef_mii_writeb(sc, (reg & i) ? 1 : 0); 847 848 /* First cycle of turnaround */ 849 MII_CLR(sc, EF_MII_CLK | EF_MII_DATA); 850 DELAY(1); 851 MII_SET(sc, EF_MII_CLK); 852 DELAY(1); 853 854 /* Turn off xmit */ 855 MII_CLR(sc, EF_MII_DIR); 856 857 /* Second cycle of turnaround */ 858 MII_CLR(sc, EF_MII_CLK); 859 DELAY(1); 860 MII_SET(sc, EF_MII_CLK); 861 DELAY(1); 862 ack = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W4_CTRLR_STATUS) & 863 EF_MII_DATA; 864 865 /* Read 16bit data */ 866 for (i = 0x8000; i; i >>= 1) { 867 MII_CLR(sc, EF_MII_CLK); 868 DELAY(1); 869 if (bus_space_read_2(sc->sc_iot, sc->sc_ioh, 870 EP_W4_CTRLR_STATUS) & EF_MII_DATA) 871 val |= i; 872 MII_SET(sc, EF_MII_CLK); 873 DELAY(1); 874 } 875 876 MII_CLR(sc, EF_MII_CLK); 877 DELAY(1); 878 MII_SET(sc, EF_MII_CLK); 879 DELAY(1); 880 881 splx(s); 882 883 return (val); 884 } 885 886 void 887 ef_miibus_writereg(dev, phy, reg, val) 888 struct device *dev; 889 int phy, reg, val; 890 { 891 struct ef_softc *sc = (struct ef_softc *)dev; 892 int s, i; 893 894 s = splnet(); 895 896 GO_WINDOW(4); 897 bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_CTRLR_STATUS, 0); 898 899 /* Turn on xmit */ 900 MII_SET(sc, EF_MII_DIR); 901 902 ef_mii_sync(sc); 903 904 ef_mii_writeb(sc, 0); 905 ef_mii_writeb(sc, 1); 906 ef_mii_writeb(sc, 0); 907 ef_mii_writeb(sc, 1); 908 909 for (i = 0x10; i; i >>= 1) 910 ef_mii_writeb(sc, (phy & i) ? 1 : 0); 911 912 for (i = 0x10; i; i >>= 1) 913 ef_mii_writeb(sc, (reg & i) ? 1 : 0); 914 915 ef_mii_writeb(sc, 1); 916 ef_mii_writeb(sc, 0); 917 918 for (i = 0x8000; i; i >>= 1) 919 ef_mii_writeb(sc, (val & i) ? 1 : 0); 920 921 splx(s); 922 } 923 924 int 925 ef_ifmedia_upd(ifp) 926 struct ifnet *ifp; 927 { 928 struct ef_softc *sc = ifp->if_softc; 929 930 mii_mediachg(&sc->sc_mii); 931 return (0); 932 } 933 934 void 935 ef_ifmedia_sts(ifp, ifmr) 936 struct ifnet *ifp; 937 struct ifmediareq *ifmr; 938 { 939 struct ef_softc *sc = ifp->if_softc; 940 941 mii_pollstat(&sc->sc_mii); 942 ifmr->ifm_status = sc->sc_mii.mii_media_status; 943 ifmr->ifm_active = sc->sc_mii.mii_media_active; 944 } 945 946 void 947 ef_miibus_statchg(self) 948 struct device *self; 949 { 950 struct ef_softc *sc = (struct ef_softc *)self; 951 int s; 952 953 s = splnet(); 954 GO_WINDOW(3); 955 /* Set duplex bit appropriately */ 956 if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX) 957 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 958 EP_W3_MAC_CONTROL, 0x20); 959 else 960 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 961 EP_W3_MAC_CONTROL, 0x00); 962 GO_WINDOW(7); 963 splx(s); 964 } 965 966 void 967 ef_tick(v) 968 void *v; 969 { 970 struct ef_softc *sc = v; 971 int s; 972 973 s = splnet(); 974 mii_tick(&sc->sc_mii); 975 splx(s); 976 timeout_add_sec(&sc->sc_tick_tmo, 1); 977 } 978