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