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