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