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