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