1 /* $NetBSD: mb8795.c,v 1.70 2023/02/03 23:00:33 tsutsui Exp $ */ 2 /* 3 * Copyright (c) 1998 Darrin B. Jewell 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __KERNEL_RCSID(0, "$NetBSD: mb8795.c,v 1.70 2023/02/03 23:00:33 tsutsui Exp $"); 29 30 #include "opt_inet.h" 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/mbuf.h> 35 #include <sys/syslog.h> 36 #include <sys/socket.h> 37 #include <sys/device.h> 38 #include <sys/malloc.h> 39 #include <sys/ioctl.h> 40 #include <sys/errno.h> 41 #include <sys/rndsource.h> 42 43 #include <net/if.h> 44 #include <net/if_dl.h> 45 #include <net/if_ether.h> 46 #include <net/if_media.h> 47 #include <net/bpf.h> 48 49 #ifdef INET 50 #include <netinet/in.h> 51 #include <netinet/if_inarp.h> 52 #include <netinet/in_systm.h> 53 #include <netinet/in_var.h> 54 #include <netinet/ip.h> 55 #endif 56 57 #include <machine/cpu.h> 58 #include <machine/bus.h> 59 #include <machine/intr.h> 60 61 /* @@@ this is here for the REALIGN_DMABUF hack below */ 62 #include "nextdmareg.h" 63 #include "nextdmavar.h" 64 65 #include "mb8795reg.h" 66 #include "mb8795var.h" 67 68 #include "bmapreg.h" 69 70 #ifdef DEBUG 71 #define MB8795_DEBUG 72 #endif 73 74 #define PRINTF(x) printf x; 75 #ifdef MB8795_DEBUG 76 int mb8795_debug = 0; 77 #define DPRINTF(x) if (mb8795_debug) printf x; 78 #else 79 #define DPRINTF(x) 80 #endif 81 82 extern int turbo; 83 84 /* 85 * Support for 86 * Fujitsu Ethernet Data Link Controller (MB8795) 87 * and the Fujitsu Manchester Encoder/Decoder (MB502). 88 */ 89 90 void mb8795_shutdown(void *); 91 92 bus_dmamap_t mb8795_txdma_restart(bus_dmamap_t, void *); 93 void mb8795_start_dma(struct mb8795_softc *); 94 95 int mb8795_mediachange(struct ifnet *); 96 void mb8795_mediastatus(struct ifnet *, struct ifmediareq *); 97 98 void 99 mb8795_config(struct mb8795_softc *sc, int *media, int nmedia, int defmedia) 100 { 101 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 102 103 DPRINTF(("%s: mb8795_config()\n", device_xname(sc->sc_dev))); 104 105 /* Initialize ifnet structure. */ 106 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 107 ifp->if_softc = sc; 108 ifp->if_start = mb8795_start; 109 ifp->if_ioctl = mb8795_ioctl; 110 ifp->if_watchdog = mb8795_watchdog; 111 ifp->if_flags = IFF_BROADCAST; 112 113 /* Initialize media goo. */ 114 sc->sc_ethercom.ec_ifmedia = &sc->sc_media; 115 ifmedia_init(&sc->sc_media, 0, mb8795_mediachange, mb8795_mediastatus); 116 if (media != NULL) { 117 int i; 118 for (i = 0; i < nmedia; i++) 119 ifmedia_add(&sc->sc_media, media[i], 0, NULL); 120 ifmedia_set(&sc->sc_media, defmedia); 121 } else { 122 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL); 123 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL); 124 } 125 126 /* Attach the interface. */ 127 if_attach(ifp); 128 ether_ifattach(ifp, sc->sc_enaddr); 129 130 sc->sc_sh = shutdownhook_establish(mb8795_shutdown, sc); 131 if (sc->sc_sh == NULL) 132 panic("mb8795_config: can't establish shutdownhook"); 133 134 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 135 RND_TYPE_NET, RND_FLAG_DEFAULT); 136 137 DPRINTF(("%s: leaving mb8795_config()\n", device_xname(sc->sc_dev))); 138 } 139 140 /* 141 * Media change callback. 142 */ 143 int 144 mb8795_mediachange(struct ifnet *ifp) 145 { 146 struct mb8795_softc *sc = ifp->if_softc; 147 int data; 148 149 if (turbo) 150 return 0; 151 152 switch IFM_SUBTYPE(sc->sc_media.ifm_media) { 153 case IFM_AUTO: 154 if ((bus_space_read_1(sc->sc_bmap_bst, sc->sc_bmap_bsh, 155 BMAP_DATA) & BMAP_DATA_UTPENABLED_MASK) || 156 !(bus_space_read_1(sc->sc_bmap_bst, sc->sc_bmap_bsh, 157 BMAP_DATA) & BMAP_DATA_UTPCARRIER_MASK)) { 158 data = BMAP_DATA_UTPENABLE; 159 sc->sc_media.ifm_cur->ifm_data = IFM_ETHER | IFM_10_T; 160 } else { 161 data = BMAP_DATA_BNCENABLE; 162 sc->sc_media.ifm_cur->ifm_data = IFM_ETHER | IFM_10_2; 163 } 164 break; 165 case IFM_10_T: 166 data = BMAP_DATA_UTPENABLE; 167 break; 168 case IFM_10_2: 169 data = BMAP_DATA_BNCENABLE; 170 break; 171 default: 172 return 1; 173 break; 174 } 175 176 bus_space_write_1(sc->sc_bmap_bst, sc->sc_bmap_bsh, 177 BMAP_DDIR, BMAP_DDIR_UTPENABLE_MASK); 178 bus_space_write_1(sc->sc_bmap_bst, sc->sc_bmap_bsh, 179 BMAP_DATA, data); 180 181 return 0; 182 } 183 184 /* 185 * Media status callback. 186 */ 187 void 188 mb8795_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 189 { 190 struct mb8795_softc *sc = ifp->if_softc; 191 192 if (turbo) 193 return; 194 195 if (IFM_SUBTYPE(ifmr->ifm_active) == IFM_AUTO) 196 ifmr->ifm_active = sc->sc_media.ifm_cur->ifm_data; 197 198 if (IFM_SUBTYPE(ifmr->ifm_active) == IFM_10_T) { 199 ifmr->ifm_status = IFM_AVALID; 200 if (!(bus_space_read_1(sc->sc_bmap_bst, sc->sc_bmap_bsh, 201 BMAP_DATA) & BMAP_DATA_UTPCARRIER_MASK)) 202 ifmr->ifm_status |= IFM_ACTIVE; 203 } else 204 ifmr->ifm_status &= ~IFM_AVALID; /* don't know for 10_2 */ 205 206 return; 207 } 208 209 /****************************************************************/ 210 #ifdef MB8795_DEBUG 211 #define XCHR(x) hexdigits[(x) & 0xf] 212 static void 213 mb8795_hex_dump(unsigned char *pkt, size_t len) 214 { 215 size_t i, j; 216 217 printf("00000000 "); 218 for (i=0; i<len; i++) { 219 printf("%c%c ", XCHR(pkt[i]>>4), XCHR(pkt[i])); 220 if ((i+1) % 16 == 8) { 221 printf(" "); 222 } 223 if ((i+1) % 16 == 0) { 224 printf(" %c", '|'); 225 for (j=0; j<16; j++) { 226 printf("%c", 227 (pkt[i-15+j] >= 32 && pkt[i-15+j] < 127) 228 ? pkt[i-15+j] : '.'); 229 } 230 printf("%c\n%c%c%c%c%c%c%c%c ", '|', 231 XCHR((i+1)>>28), XCHR((i+1)>>24), XCHR((i+1)>>20), 232 XCHR((i+1)>>16), XCHR((i+1)>>12), XCHR((i+1)>>8), 233 XCHR((i+1)>>4), XCHR(i+1)); 234 } 235 } 236 printf("\n"); 237 } 238 #undef XCHR 239 #endif 240 241 /* 242 * Controller receive interrupt. 243 */ 244 void 245 mb8795_rint(struct mb8795_softc *sc) 246 { 247 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 248 int error = 0; 249 u_char rxstat; 250 u_char rxmask; 251 252 rxstat = MB_READ_REG(sc, MB8795_RXSTAT); 253 rxmask = MB_READ_REG(sc, MB8795_RXMASK); 254 __USE(rxmask); 255 256 MB_WRITE_REG(sc, MB8795_RXSTAT, MB8795_RXSTAT_CLEAR); 257 258 if (rxstat & MB8795_RXSTAT_RESET) { 259 DPRINTF(("%s: rx reset packet\n", device_xname(sc->sc_dev))); 260 error++; 261 } 262 if (rxstat & MB8795_RXSTAT_SHORT) { 263 DPRINTF(("%s: rx short packet\n", device_xname(sc->sc_dev))); 264 error++; 265 } 266 if (rxstat & MB8795_RXSTAT_ALIGNERR) { 267 DPRINTF(("%s: rx alignment error\n",device_xname(sc->sc_dev))); 268 #if 0 269 error++; 270 #endif 271 } 272 if (rxstat & MB8795_RXSTAT_CRCERR) { 273 DPRINTF(("%s: rx CRC error\n", device_xname(sc->sc_dev))); 274 #if 0 275 error++; 276 #endif 277 } 278 if (rxstat & MB8795_RXSTAT_OVERFLOW) { 279 DPRINTF(("%s: rx overflow error\n", device_xname(sc->sc_dev))); 280 #if 0 281 error++; 282 #endif 283 } 284 285 if (error) { 286 if_statinc(ifp, if_ierrors); 287 /* @@@ handle more gracefully, free memory, etc. */ 288 } 289 290 if (rxstat & MB8795_RXSTAT_OK) { 291 struct mbuf *m; 292 int s; 293 s = spldma(); 294 295 while ((m = MBDMA_RX_MBUF (sc))) { 296 /* CRC is included with the packet; trim it. */ 297 m->m_pkthdr.len = m->m_len = m->m_len - ETHER_CRC_LEN; 298 m_set_rcvif(m, ifp); 299 300 /* Find receive length, keep crc */ 301 /* enable DMA interrupts while we process the packet */ 302 splx(s); 303 304 #if defined(MB8795_DEBUG) 305 /* Peek at the packet */ 306 DPRINTF(("%s: received packet, at VA %p-%p,len %d\n", 307 device_xname(sc->sc_dev), mtod(m,u_char *), 308 mtod(m,u_char *) + m->m_len, m->m_len)); 309 if (mb8795_debug > 3) { 310 mb8795_hex_dump(mtod(m,u_char *), 311 m->m_pkthdr.len); 312 } else if (mb8795_debug > 2) { 313 mb8795_hex_dump(mtod(m,u_char *), 314 m->m_pkthdr.len < 255 315 ? m->m_pkthdr.len : 128); 316 } 317 #endif 318 319 /* Pass the packet up. */ 320 if_percpuq_enqueue(ifp->if_percpuq, m); 321 322 s = spldma(); 323 } 324 325 splx(s); 326 327 } 328 329 #ifdef MB8795_DEBUG 330 if (mb8795_debug) { 331 char sbuf[256]; 332 333 snprintb(sbuf, sizeof(sbuf), MB8795_RXSTAT_BITS, rxstat); 334 printf("%s: rx interrupt, rxstat = %s\n", 335 device_xname(sc->sc_dev), sbuf); 336 337 snprintb(sbuf, sizeof(sbuf), MB8795_RXSTAT_BITS, 338 MB_READ_REG(sc, MB8795_RXSTAT)); 339 340 printf("rxstat = %s\n", sbuf); 341 342 snprintb(sbuf, sizeof(sbuf), MB8795_RXMASK_BITS, 343 MB_READ_REG(sc, MB8795_RXMASK)); 344 printf("rxmask = %s\n", sbuf); 345 346 snprintb(sbuf, sizeof(sbuf), MB8795_RXMODE_BITS, 347 MB_READ_REG(sc, MB8795_RXMODE)); 348 printf("rxmode = %s\n", sbuf); 349 } 350 #endif 351 rnd_add_uint32(&sc->rnd_source, rxstat); 352 353 return; 354 } 355 356 /* 357 * Controller transmit interrupt. 358 */ 359 void 360 mb8795_tint(struct mb8795_softc *sc) 361 { 362 u_char txstat; 363 u_char txmask; 364 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 365 366 panic ("tint"); 367 txstat = MB_READ_REG(sc, MB8795_TXSTAT); 368 txmask = MB_READ_REG(sc, MB8795_TXMASK); 369 __USE(txmask); 370 371 if ((txstat & MB8795_TXSTAT_READY) || 372 (txstat & MB8795_TXSTAT_TXRECV)) { 373 /* printf("X"); */ 374 MB_WRITE_REG(sc, MB8795_TXSTAT, MB8795_TXSTAT_CLEAR); 375 /* MB_WRITE_REG(sc, MB8795_TXMASK, txmask & ~MB8795_TXMASK_READYIE); */ 376 /* MB_WRITE_REG(sc, MB8795_TXMASK, txmask & ~MB8795_TXMASK_TXRXIE); */ 377 MB_WRITE_REG(sc, MB8795_TXMASK, 0); 378 if ((ifp->if_flags & IFF_RUNNING) 379 && !IF_IS_EMPTY(&sc->sc_tx_snd)) { 380 void mb8795_start_dma(struct mb8795_softc *); /* XXX */ 381 /* printf ("Z"); */ 382 mb8795_start_dma(sc); 383 } 384 goto out; 385 } 386 387 if (txstat & MB8795_TXSTAT_SHORTED) { 388 printf("%s: tx cable shorted\n", device_xname(sc->sc_dev)); 389 if_statinc(ifp, if_oerrors); 390 } 391 if (txstat & MB8795_TXSTAT_UNDERFLOW) { 392 printf("%s: tx underflow\n", device_xname(sc->sc_dev)); 393 if_statinc(ifp, if_oerrors); 394 } 395 if (txstat & MB8795_TXSTAT_COLLERR) { 396 DPRINTF(("%s: tx collision\n", device_xname(sc->sc_dev))); 397 if_statinc(ifp, if_collisions); 398 } 399 if (txstat & MB8795_TXSTAT_COLLERR16) { 400 printf("%s: tx 16th collision\n", device_xname(sc->sc_dev)); 401 if_statinc(ifp, if_oerrors); 402 if_statadd(ifp, if_collisions, 16); 403 } 404 405 #if 0 406 if (txstat & MB8795_TXSTAT_READY) { 407 char sbuf[256]; 408 409 snprintb(sbuf, sizeof(sbuf), MB8795_TXSTAT_BITS, txstat); 410 panic("%s: unexpected tx interrupt %s", 411 device_xname(sc->sc_dev), sbuf); 412 413 /* turn interrupt off */ 414 MB_WRITE_REG(sc, MB8795_TXMASK, 415 txmask & ~MB8795_TXMASK_READYIE); 416 } 417 #endif 418 out: 419 rnd_add_uint32(&sc->rnd_source, txstat); 420 421 return; 422 } 423 424 /****************************************************************/ 425 426 void 427 mb8795_reset(struct mb8795_softc *sc) 428 { 429 int s; 430 int i; 431 432 s = splnet(); 433 434 DPRINTF (("%s: mb8795_reset()\n", device_xname(sc->sc_dev))); 435 436 sc->sc_ethercom.ec_if.if_flags &= ~IFF_RUNNING; 437 sc->sc_ethercom.ec_if.if_timer = 0; 438 439 MBDMA_RESET(sc); 440 441 MB_WRITE_REG(sc, MB8795_RESET, MB8795_RESET_MODE); 442 443 mb8795_mediachange(&sc->sc_ethercom.ec_if); 444 445 #if 0 /* This interrupt was sometimes failing to ack correctly 446 * causing a loop @@@ 447 */ 448 MB_WRITE_REG(sc, MB8795_TXMASK, 449 MB8795_TXMASK_UNDERFLOWIE | MB8795_TXMASK_COLLIE 450 | MB8795_TXMASK_COLL16IE | MB8795_TXMASK_PARERRIE); 451 #else 452 MB_WRITE_REG(sc, MB8795_TXMASK, 0); 453 #endif 454 MB_WRITE_REG(sc, MB8795_TXSTAT, MB8795_TXSTAT_CLEAR); 455 456 #if 0 457 MB_WRITE_REG(sc, MB8795_RXMASK, 458 MB8795_RXMASK_OKIE | MB8795_RXMASK_RESETIE | MB8795_RXMASK_SHORTIE 459 | MB8795_RXMASK_ALIGNERRIE | MB8795_RXMASK_CRCERRIE 460 | MB8795_RXMASK_OVERFLOWIE); 461 #else 462 MB_WRITE_REG(sc, MB8795_RXMASK, 463 MB8795_RXMASK_OKIE | MB8795_RXMASK_RESETIE 464 | MB8795_RXMASK_SHORTIE); 465 #endif 466 467 MB_WRITE_REG(sc, MB8795_RXSTAT, MB8795_RXSTAT_CLEAR); 468 469 for (i=0;i<sizeof(sc->sc_enaddr);i++) 470 MB_WRITE_REG(sc, MB8795_ENADDR+i, sc->sc_enaddr[i]); 471 472 DPRINTF(("%s: initializing ethernet %02x:%02x:%02x:%02x:%02x:%02x, " 473 "size=%d\n", device_xname(sc->sc_dev), 474 sc->sc_enaddr[0],sc->sc_enaddr[1],sc->sc_enaddr[2], 475 sc->sc_enaddr[3],sc->sc_enaddr[4],sc->sc_enaddr[5], 476 sizeof(sc->sc_enaddr))); 477 478 MB_WRITE_REG(sc, MB8795_RESET, 0); 479 480 splx(s); 481 } 482 483 void 484 mb8795_watchdog(struct ifnet *ifp) 485 { 486 struct mb8795_softc *sc = ifp->if_softc; 487 488 log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev)); 489 if_statinc(ifp, if_oerrors); 490 491 ifp->if_flags &= ~IFF_RUNNING; 492 mb8795_init(sc); 493 } 494 495 /* 496 * Initialization of interface; set up initialization block 497 * and transmit/receive descriptor rings. 498 */ 499 void 500 mb8795_init(struct mb8795_softc *sc) 501 { 502 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 503 int s; 504 505 DPRINTF (("%s: mb8795_init()\n", device_xname(sc->sc_dev))); 506 507 if (ifp->if_flags & IFF_UP) { 508 int rxmode; 509 510 s = spldma(); 511 if ((ifp->if_flags & IFF_RUNNING) == 0) 512 mb8795_reset(sc); 513 514 if (ifp->if_flags & IFF_PROMISC) 515 rxmode = MB8795_RXMODE_PROMISCUOUS; 516 else 517 rxmode = MB8795_RXMODE_NORMAL; 518 /* XXX add support for multicast */ 519 if (turbo) 520 rxmode |= MB8795_RXMODE_TEST; 521 522 /* switching mode probably borken now with turbo */ 523 MB_WRITE_REG(sc, MB8795_TXMODE, 524 turbo ? MB8795_TXMODE_TURBO1 : MB8795_TXMODE_LB_DISABLE); 525 MB_WRITE_REG(sc, MB8795_RXMODE, rxmode); 526 527 if ((ifp->if_flags & IFF_RUNNING) == 0) { 528 MBDMA_RX_SETUP(sc); 529 MBDMA_TX_SETUP(sc); 530 531 ifp->if_flags |= IFF_RUNNING; 532 ifp->if_timer = 0; 533 534 MBDMA_RX_GO(sc); 535 } 536 splx(s); 537 #if 0 538 s = spldma(); 539 if (! IF_IS_EMPTY(&sc->sc_tx_snd)) 540 mb8795_start_dma(ifp); 541 splx(s); 542 #endif 543 } else 544 mb8795_reset(sc); 545 } 546 547 void 548 mb8795_shutdown(void *arg) 549 { 550 struct mb8795_softc *sc = (struct mb8795_softc *)arg; 551 552 DPRINTF(("%s: mb8795_shutdown()\n", device_xname(sc->sc_dev))); 553 554 mb8795_reset(sc); 555 } 556 557 /****************************************************************/ 558 int 559 mb8795_ioctl(struct ifnet *ifp, u_long cmd, void *data) 560 { 561 struct mb8795_softc *sc = ifp->if_softc; 562 struct ifaddr *ifa = (struct ifaddr *)data; 563 int s, error = 0; 564 565 s = splnet(); 566 567 DPRINTF(("%s: mb8795_ioctl()\n", device_xname(sc->sc_dev))); 568 569 switch (cmd) { 570 571 case SIOCINITIFADDR: 572 DPRINTF(("%s: mb8795_ioctl() SIOCINITIFADDR\n", 573 device_xname(sc->sc_dev))); 574 ifp->if_flags |= IFF_UP; 575 576 mb8795_init(sc); 577 switch (ifa->ifa_addr->sa_family) { 578 #ifdef INET 579 case AF_INET: 580 arp_ifinit(ifp, ifa); 581 break; 582 #endif 583 default: 584 break; 585 } 586 break; 587 588 589 case SIOCSIFFLAGS: 590 DPRINTF(("%s: mb8795_ioctl() SIOCSIFFLAGS\n", 591 device_xname(sc->sc_dev))); 592 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 593 break; 594 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 595 case IFF_RUNNING: 596 /* 597 * If interface is marked down and it is running, then 598 * stop it. 599 */ 600 #if 0 601 ifp->if_flags &= ~IFF_RUNNING; 602 #endif 603 mb8795_reset(sc); 604 break; 605 case IFF_UP: 606 /* 607 * If interface is marked up and it is stopped, then 608 * start it. 609 */ 610 mb8795_init(sc); 611 break; 612 default: 613 /* 614 * Reset the interface to pick up changes in any other 615 * flags that affect hardware registers. 616 */ 617 mb8795_init(sc); 618 break; 619 } 620 #ifdef MB8795_DEBUG 621 if (ifp->if_flags & IFF_DEBUG) 622 sc->sc_debug = 1; 623 else 624 sc->sc_debug = 0; 625 #endif 626 break; 627 628 case SIOCADDMULTI: 629 case SIOCDELMULTI: 630 DPRINTF(("%s: mb8795_ioctl() SIOCADDMULTI\n", 631 device_xname(sc->sc_dev))); 632 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 633 /* 634 * Multicast list has changed; set the hardware filter 635 * accordingly. 636 */ 637 if (ifp->if_flags & IFF_RUNNING) 638 mb8795_init(sc); 639 error = 0; 640 } 641 break; 642 643 default: 644 error = ether_ioctl(ifp, cmd, data); 645 break; 646 } 647 648 splx(s); 649 650 #if 0 651 DPRINTF(("DEBUG: mb8795_ioctl(0x%lx) returning %d\n", cmd, error)); 652 #endif 653 654 return error; 655 } 656 657 /* 658 * Setup output on interface. 659 * Get another datagram to send off of the interface queue, and map it to the 660 * interface before starting the output. 661 * Called only at splnet or interrupt level. 662 */ 663 void 664 mb8795_start(struct ifnet *ifp) 665 { 666 struct mb8795_softc *sc = ifp->if_softc; 667 struct mbuf *m; 668 int s; 669 670 DPRINTF(("%s: mb8795_start()\n", device_xname(sc->sc_dev))); 671 672 #ifdef DIAGNOSTIC 673 IFQ_POLL(&ifp->if_snd, m); 674 if (m == 0) 675 panic("%s: No packet to start", device_xname(sc->sc_dev)); 676 #endif 677 678 while (1) { 679 if ((ifp->if_flags & IFF_RUNNING) == 0) 680 return; 681 682 #if 0 683 return; /* @@@ Turn off xmit for debugging */ 684 #endif 685 686 IFQ_DEQUEUE(&ifp->if_snd, m); 687 if (m == 0) { 688 return; 689 } 690 691 /* Pass packet to bpf if there is a listener. */ 692 bpf_mtap(ifp, m, BPF_D_OUT); 693 694 s = spldma(); 695 IF_ENQUEUE(&sc->sc_tx_snd, m); 696 if (!MBDMA_TX_ISACTIVE(sc)) 697 mb8795_start_dma(sc); 698 splx(s); 699 } 700 } 701 702 void 703 mb8795_start_dma(struct mb8795_softc *sc) 704 { 705 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 706 struct mbuf *m; 707 u_char txmask; 708 709 DPRINTF(("%s: mb8795_start_dma()\n", device_xname(sc->sc_dev))); 710 711 #if (defined(DIAGNOSTIC)) 712 { 713 u_char txstat; 714 txstat = MB_READ_REG(sc, MB8795_TXSTAT); 715 if (!turbo && !(txstat & MB8795_TXSTAT_READY)) { 716 /* 717 * @@@ I used to panic here, but then it panicked once. 718 * Let's see if I can just reset instead. 719 * [ dbj 980706.1900 ] 720 */ 721 printf("%s: transmitter not ready\n", 722 device_xname(sc->sc_dev)); 723 ifp->if_flags &= ~IFF_RUNNING; 724 mb8795_init(sc); 725 return; 726 } 727 } 728 #endif 729 730 #if 0 731 return; /* @@@ Turn off xmit for debugging */ 732 #endif 733 734 IF_DEQUEUE(&sc->sc_tx_snd, m); 735 if (m == 0) { 736 #ifdef DIAGNOSTIC 737 panic("%s: No packet to start_dma", device_xname(sc->sc_dev)); 738 #endif 739 return; 740 } 741 742 MB_WRITE_REG(sc, MB8795_TXSTAT, MB8795_TXSTAT_CLEAR); 743 txmask = MB_READ_REG(sc, MB8795_TXMASK); 744 __USE(txmask); 745 /* MB_WRITE_REG(sc, MB8795_TXMASK, txmask | MB8795_TXMASK_READYIE); */ 746 /* MB_WRITE_REG(sc, MB8795_TXMASK, txmask | MB8795_TXMASK_TXRXIE); */ 747 748 ifp->if_timer = 5; 749 750 if (MBDMA_TX_MBUF(sc, m)) 751 return; 752 753 MBDMA_TX_GO(sc); 754 if (turbo) 755 MB_WRITE_REG(sc, MB8795_TXMODE, 756 MB8795_TXMODE_TURBO1 | MB8795_TXMODE_TURBOSTART); 757 758 if_statinc(ifp, if_opackets); 759 } 760 761 /****************************************************************/ 762