1 /* $NetBSD: mb86950.c,v 1.5 2006/05/11 23:54:39 mrg Exp $ */ 2 3 /* 4 * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 5 * 6 * This software may be used, modified, copied, distributed, and sold, in 7 * both source and binary form provided that the above copyright, these 8 * terms and the following disclaimer are retained. The name of the author 9 * and/or the contributor may not be used to endorse or promote products 10 * derived from this software without specific prior written permission. 11 * 12 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND 13 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE 16 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 18 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION. 19 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 20 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 21 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 22 * SUCH DAMAGE. 23 */ 24 25 /* 26 * Portions copyright (C) 1993, David Greenman. This software may be used, 27 * modified, copied, distributed, and sold, in both source and binary form 28 * provided that the above copyright and these terms are retained. Under no 29 * circumstances is the author responsible for the proper functioning of this 30 * software, nor does the author assume any responsibility for damages 31 * incurred with its use. 32 */ 33 34 /* 35 * Portions copyright (c) 1995 Mika Kortelainen 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * This product includes software developed by Mika Kortelainen 49 * 4. The name of the author may not be used to endorse or promote products 50 * derived from this software without specific prior written permission 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 54 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 55 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 56 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 57 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 61 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64 /* 65 * Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards. 66 * Contributed by M.S. <seki@sysrap.cs.fujitsu.co.jp> 67 */ 68 69 #include <sys/cdefs.h> 70 __KERNEL_RCSID(0, "$NetBSD: mb86950.c,v 1.5 2006/05/11 23:54:39 mrg Exp $"); 71 72 /* 73 * Device driver for Fujitsu mb86950 based Ethernet cards. 74 * Adapted by Dave J. Barnes from various Internet sources including 75 * mb86960.c (NetBSD), if_qn.c (NetBSD/Amiga), DOS Packet Driver (Brian Fisher, 76 * Queens University), EtherBoot Driver (Ken Yap). 77 */ 78 79 /* XXX There are still rough edges...... 80 * 81 * (1) There is no watchdog timer for the transmitter. It's doubtful that 82 * transmit from the chip could be restarted without a hardware reset 83 * though. (Fixed - not fully tested) 84 * 85 * (2) The media interface callback goo is broke. No big deal since to change 86 * from aui to bnc on the old Tiara LANCard requires moving 8 board jumpers. 87 * Other cards (SMC ?) using the EtherStar chip may support media change 88 * via software. (Fixed - tested) 89 * 90 * (3) The maximum outstanding transmit packets is set to 4. What 91 * is a good limit of outstanding transmit packets for the EtherStar? 92 * Is there a way to tell how many bytes are remaining to be 93 * transmitted? [no] 94 --- 95 When the EtherStar was designed, CPU power was a fraction 96 of what it is now. The single EtherStar transmit buffer 97 was fine. It was unlikely that the CPU could outrun the 98 EtherStar. However, things in 2004 are quite different. 99 sc->txb_size is used to keep the CPU from overrunning the 100 EtherStar. At most allow one packet transmitting and one 101 going into the fifo. 102 103 --- 104 No, that isn't right either :( 105 106 * (4) Multicast isn't supported. Feel free to add multicast code 107 * if you know how to make the EtherStar do multicast. Otherwise 108 * you'd have to use promiscuous mode and do multicast in software. OUCH! 109 * 110 * (5) There are no bus_space_barrier calls used. Are they needed? Maybe not. 111 * 112 * (6) Access to the fifo assumes word (16 bit) mode. Cards configured for 113 * byte wide fifo access will require driver code changes. 114 * 115 * Only the minimum code necessary to make the Tiara LANCard work 116 * has been tested. Other cards may require more work, especially 117 * byte mode fifo and if DMA is used. 118 * 119 * djb / 2004 120 */ 121 122 #include "opt_inet.h" 123 #include "opt_ns.h" 124 #include "bpfilter.h" 125 #include "rnd.h" 126 127 #include <sys/param.h> 128 #include <sys/systm.h> 129 #include <sys/errno.h> 130 #include <sys/ioctl.h> 131 #include <sys/mbuf.h> 132 #include <sys/socket.h> 133 #include <sys/syslog.h> 134 #include <sys/device.h> 135 #if NRND > 0 136 #include <sys/rnd.h> 137 #endif 138 139 #include <net/if.h> 140 #include <net/if_dl.h> 141 #include <net/if_types.h> 142 #include <net/if_media.h> 143 #include <net/if_ether.h> 144 145 #ifdef INET 146 #include <netinet/in.h> 147 #include <netinet/in_systm.h> 148 #include <netinet/in_var.h> 149 #include <netinet/ip.h> 150 #include <netinet/if_inarp.h> 151 #endif 152 153 #ifdef NS 154 #include <netns/ns.h> 155 #include <netns/ns_if.h> 156 #endif 157 158 #if NBPFILTER > 0 159 #include <net/bpf.h> 160 #include <net/bpfdesc.h> 161 #endif 162 163 #include <machine/bus.h> 164 165 #include <dev/ic/mb86950reg.h> 166 #include <dev/ic/mb86950var.h> 167 168 #ifndef __BUS_SPACE_HAS_STREAM_METHODS 169 #define bus_space_write_stream_2 bus_space_write_2 170 #define bus_space_write_multi_stream_2 bus_space_write_multi_2 171 #define bus_space_read_multi_stream_2 bus_space_read_multi_2 172 #endif /* __BUS_SPACE_HAS_STREAM_METHODS */ 173 174 /* Standard driver entry points. These can be static. */ 175 int mb86950_ioctl __P((struct ifnet *, u_long, caddr_t)); 176 void mb86950_init __P((struct mb86950_softc *)); 177 void mb86950_start __P((struct ifnet *)); 178 void mb86950_watchdog __P((struct ifnet *)); 179 void mb86950_reset __P((struct mb86950_softc *)); 180 181 /* Local functions. */ 182 void mb86950_stop __P((struct mb86950_softc *)); 183 void mb86950_tint __P((struct mb86950_softc *, u_int8_t)); 184 void mb86950_rint __P((struct mb86950_softc *, u_int8_t)); 185 int mb86950_get_fifo __P((struct mb86950_softc *, u_int)); 186 ushort mb86950_put_fifo __P((struct mb86950_softc *, struct mbuf *)); 187 void mb86950_drain_fifo __P((struct mb86950_softc *)); 188 189 int mb86950_mediachange __P((struct ifnet *)); 190 void mb86950_mediastatus __P((struct ifnet *, struct ifmediareq *)); 191 192 193 #if ESTAR_DEBUG >= 1 194 void mb86950_dump __P((int, struct mb86950_softc *)); 195 #endif 196 197 /********************************************************************/ 198 199 void 200 mb86950_attach(sc, myea) 201 struct mb86950_softc *sc; 202 u_int8_t *myea; 203 { 204 205 #ifdef DIAGNOSTIC 206 if (myea == NULL) { 207 printf("%s: ethernet address shouldn't be NULL\n", 208 sc->sc_dev.dv_xname); 209 panic("NULL ethernet address"); 210 } 211 #endif 212 213 /* Initialize 86950. */ 214 mb86950_stop(sc); 215 216 memcpy(sc->sc_enaddr, myea, sizeof(sc->sc_enaddr)); 217 218 sc->sc_stat |= ESTAR_STAT_ENABLED; 219 } 220 221 /* 222 * Stop everything on the interface. 223 * 224 * All buffered packets, both transmitting and receiving, 225 * if any, will be lost by stopping the interface. 226 */ 227 void 228 mb86950_stop(sc) 229 struct mb86950_softc *sc; 230 { 231 bus_space_tag_t bst = sc->sc_bst; 232 bus_space_handle_t bsh = sc->sc_bsh; 233 234 /* Stop interface hardware. */ 235 bus_space_write_1(bst, bsh, DLCR_CONFIG, DISABLE_DLC); 236 delay(200); 237 238 /* Disable interrupts. */ 239 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, 0); 240 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, 0); 241 242 /* Ack / Clear all interrupt status. */ 243 bus_space_write_1(bst, bsh, DLCR_TX_STAT, 0xff); 244 bus_space_write_1(bst, bsh, DLCR_RX_STAT, 0xff); 245 246 /* Clear DMA Bit */ 247 bus_space_write_2(bst, bsh, BMPR_DMA, 0); 248 249 /* accept no packets */ 250 bus_space_write_1(bst, bsh, DLCR_TX_MODE, 0); 251 bus_space_write_1(bst, bsh, DLCR_RX_MODE, 0); 252 253 mb86950_drain_fifo(sc); 254 255 } 256 257 void 258 mb86950_drain_fifo(sc) 259 struct mb86950_softc *sc; 260 { 261 bus_space_tag_t bst = sc->sc_bst; 262 bus_space_handle_t bsh = sc->sc_bsh; 263 264 /* Read data until bus read error (i.e. buffer empty). */ 265 /* XXX There ought to be a better way, eats CPU and bothers the chip */ 266 while (!(bus_space_read_1(bst, bsh, DLCR_RX_STAT) & RX_BUS_RD_ERR)) 267 bus_space_read_2(bst, bsh, BMPR_FIFO); 268 /* XXX */ 269 270 /* Clear Bus Rd Error */ 271 bus_space_write_1(bst, bsh, DLCR_RX_STAT, RX_BUS_RD_ERR); 272 } 273 274 /* 275 * Install interface into kernel networking data structures 276 */ 277 void 278 mb86950_config(sc, media, nmedia, defmedia) 279 struct mb86950_softc *sc; 280 int *media, nmedia, defmedia; 281 { 282 struct ifnet *ifp = &sc->sc_ec.ec_if; 283 bus_space_tag_t bst = sc->sc_bst; 284 bus_space_handle_t bsh = sc->sc_bsh; 285 286 /* Initialize ifnet structure. */ 287 strcpy(ifp->if_xname, sc->sc_dev.dv_xname); 288 ifp->if_softc = sc; 289 ifp->if_start = mb86950_start; 290 ifp->if_ioctl = mb86950_ioctl; 291 ifp->if_watchdog = mb86950_watchdog; 292 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; 293 294 IFQ_SET_READY(&ifp->if_snd); 295 296 /* Initialize media goo. */ 297 /* XXX The Tiara LANCard uses board jumpers to change media. 298 * This code may have to be changed for other cards. 299 */ 300 ifmedia_init(&sc->sc_media, 0, mb86950_mediachange, mb86950_mediastatus); 301 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL); 302 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL); 303 304 /* Attach the interface. */ 305 if_attach(ifp); 306 307 /* Feed the chip the station address. */ 308 bus_space_write_region_1(bst, bsh, DLCR_NODE_ID, sc->sc_enaddr, ETHER_ADDR_LEN); 309 310 ether_ifattach(ifp, sc->sc_enaddr); 311 312 #if NRND > 0 313 rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname, 314 RND_TYPE_NET, 0); 315 #endif 316 317 /* XXX No! This doesn't work - DLCR6 of the mb86950 is different 318 319 bus_space_write_1(bst, bsh, DLCR_CONFIG, 0x0f); 320 buf_config = bus_space_read_1(bst, bsh, DLCR_CONFIG); 321 322 sc->txb_count = ((buf_config & 0x0c) ? 2 : 1); 323 sc->txb_size = 1024 * (2 << ((buf_config & 0x0c) ? (((buf_config & 0x0c) >> 2) - 1) : 0)); 324 sc->txb_free = (sc->txb_size * sc->txb_count) / 1500; 325 326 sc->rxb_size = ((8 << (buf_config & 3)) * 1024) - (sc->txb_size * sc->txb_count); 327 sc->rxb_max = sc->rxb_size / 64; 328 329 printf("mb86950: Buffer Size %dKB with %d transmit buffer(s) %dKB each.\n", 330 (8 << (buf_config & 3)), sc->txb_count, (sc->txb_size / 1024)); 331 printf(" Transmit Buffer Space for %d maximum sized packet(s).\n",sc->txb_free); 332 printf(" System Bus Width %d bits, Buffer Memory %d bits.\n", 333 ((buf_config & 0x20) ? 8 : 16), 334 ((buf_config & 0x10) ? 8 : 16)); 335 336 */ 337 338 /* Set reasonable values for number of packet flow control if not 339 * set elsewhere */ 340 if (sc->txb_num_pkt == 0) sc->txb_num_pkt = 1; 341 if (sc->rxb_num_pkt == 0) sc->rxb_num_pkt = 100; 342 343 /* Print additional info when attached. */ 344 printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname, 345 ether_sprintf(sc->sc_enaddr)); 346 347 /* The attach is successful. */ 348 sc->sc_stat |= ESTAR_STAT_ATTACHED; 349 } 350 351 /* 352 * Media change callback. 353 */ 354 int 355 mb86950_mediachange(ifp) 356 struct ifnet *ifp; 357 { 358 359 struct mb86950_softc *sc = ifp->if_softc; 360 361 if (sc->sc_mediachange) 362 return ((*sc->sc_mediachange)(sc)); 363 364 return (0); 365 } 366 367 /* 368 * Media status callback. 369 */ 370 void 371 mb86950_mediastatus(ifp, ifmr) 372 struct ifnet *ifp; 373 struct ifmediareq *ifmr; 374 { 375 struct mb86950_softc *sc = ifp->if_softc; 376 377 if ((sc->sc_stat & ESTAR_STAT_ENABLED) == 0) { 378 ifmr->ifm_active = IFM_ETHER | IFM_NONE; 379 ifmr->ifm_status = 0; 380 return; 381 } 382 383 if (sc->sc_mediastatus) 384 (*sc->sc_mediastatus)(sc, ifmr); 385 386 } 387 388 /* 389 * Reset interface. 390 */ 391 void 392 mb86950_reset(sc) 393 struct mb86950_softc *sc; 394 { 395 int s; 396 397 s = splnet(); 398 log(LOG_ERR, "%s: device reset\n", sc->sc_dev.dv_xname); 399 mb86950_stop(sc); 400 mb86950_init(sc); 401 splx(s); 402 } 403 404 /* 405 * Device timeout/watchdog routine. Entered if the device neglects to 406 * generate an interrupt after a transmit has been started on it. 407 */ 408 void 409 mb86950_watchdog(ifp) 410 struct ifnet *ifp; 411 { 412 struct mb86950_softc *sc = ifp->if_softc; 413 bus_space_tag_t bst = sc->sc_bst; 414 bus_space_handle_t bsh = sc->sc_bsh; 415 u_int8_t tstat; 416 417 /* verbose watchdog messages for debugging timeouts */ 418 if ((tstat = bus_space_read_1(bst, bsh, DLCR_TX_STAT)) != 0) { 419 if (tstat & TX_CR_LOST) { 420 if ((tstat & (TX_COL | TX_16COL)) == 0) { 421 log(LOG_ERR, "%s: carrier lost\n", 422 sc->sc_dev.dv_xname); 423 } else { 424 log(LOG_ERR, "%s: excessive collisions\n", 425 sc->sc_dev.dv_xname); 426 } 427 } 428 else if ((tstat & (TX_UNDERFLO | TX_BUS_WR_ERR)) != 0) { 429 log(LOG_ERR, "%s: tx fifo underflow/overflow\n", 430 sc->sc_dev.dv_xname); 431 } else { 432 log(LOG_ERR, "%s: transmit error\n", 433 sc->sc_dev.dv_xname); 434 } 435 } else { 436 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 437 } 438 439 /* Don't know how many packets are lost by this accident. 440 * ... So just errors = errors + 1 441 */ 442 ifp->if_oerrors++; 443 444 mb86950_reset(sc); 445 446 } 447 448 /* 449 ******************** IOCTL 450 * Process an ioctl request. 451 */ 452 int 453 mb86950_ioctl(ifp, cmd, data) 454 struct ifnet *ifp; 455 u_long cmd; 456 caddr_t data; 457 { 458 struct mb86950_softc *sc = ifp->if_softc; 459 struct ifaddr *ifa = (struct ifaddr *)data; 460 struct ifreq *ifr = (struct ifreq *)data; 461 462 int s, error = 0; 463 464 s = splnet(); 465 466 switch (cmd) { 467 case SIOCSIFADDR: 468 /* XXX depreciated ? What should I use instead? */ 469 if ((error = mb86950_enable(sc)) != 0) 470 break; 471 472 ifp->if_flags |= IFF_UP; 473 474 switch (ifa->ifa_addr->sa_family) { 475 476 #ifdef INET 477 case AF_INET: 478 mb86950_init(sc); 479 arp_ifinit(ifp, ifa); 480 break; 481 #endif 482 483 #ifdef NS 484 case AF_NS: 485 { 486 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 487 488 if (ns_nullhost(*ina)) 489 ina->x_host = *(union ns_host *)LLADDR(ifp->if_sadl); 490 else { 491 memcpy(LLADDR(ifp->if_sadl), ina->x_host.c_host, ETHER_ADDR_LEN); 492 } 493 /* Set new address. */ 494 mb86950_init(sc); 495 break; 496 } 497 #endif 498 499 default: 500 mb86950_init(sc); 501 break; 502 } 503 break; 504 505 case SIOCSIFFLAGS: 506 if ((ifp->if_flags & IFF_UP) == 0 && 507 (ifp->if_flags & IFF_RUNNING) != 0) { 508 /* 509 * If interface is marked down and it is running, then 510 * stop it. 511 */ 512 mb86950_stop(sc); 513 ifp->if_flags &= ~IFF_RUNNING; 514 mb86950_disable(sc); 515 516 } else if ((ifp->if_flags & IFF_UP) != 0 && 517 (ifp->if_flags & IFF_RUNNING) == 0) { 518 /* 519 * If interface is marked up and it is stopped, then 520 * start it. 521 */ 522 if ((error = mb86950_enable(sc)) != 0) 523 break; 524 mb86950_init(sc); 525 526 } else if ((ifp->if_flags & IFF_UP) != 0) { 527 /* 528 * Reset the interface to pick up changes in any other 529 * flags that affect hardware registers. 530 */ 531 /* Setmode not supported 532 mb86950_setmode(sc); 533 */ 534 } 535 536 #if ESTAR_DEBUG >= 1 537 /* "ifconfig fe0 debug" to print register dump. */ 538 if (ifp->if_flags & IFF_DEBUG) { 539 log(LOG_INFO, "%s: SIOCSIFFLAGS(DEBUG)\n", 540 sc->sc_dev.dv_xname); 541 mb86950_dump(LOG_DEBUG, sc); 542 } 543 #endif 544 break; 545 546 case SIOCGIFMEDIA: 547 case SIOCSIFMEDIA: 548 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); 549 break; 550 551 default: 552 error = EINVAL; 553 break; 554 } 555 556 splx(s); 557 return (error); 558 } 559 560 /* 561 * Initialize device. 562 */ 563 void 564 mb86950_init(sc) 565 struct mb86950_softc *sc; 566 { 567 bus_space_tag_t bst = sc->sc_bst; 568 bus_space_handle_t bsh = sc->sc_bsh; 569 struct ifnet *ifp = &sc->sc_ec.ec_if; 570 571 /* Reset transmitter flags. */ 572 ifp->if_flags &= ~IFF_OACTIVE; 573 ifp->if_timer = 0; 574 sc->txb_sched = 0; 575 576 bus_space_write_1(bst, bsh, DLCR_TX_MODE, LBC); 577 bus_space_write_1(bst, bsh, DLCR_RX_MODE, NORMAL_MODE); 578 579 /* Enable interrupts. */ 580 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK); 581 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, RX_MASK); 582 583 /* Enable transmitter and receiver. */ 584 bus_space_write_1(bst, bsh, DLCR_CONFIG, ENABLE_DLC); 585 delay(200); 586 587 /* Set 'running' flag. */ 588 ifp->if_flags |= IFF_RUNNING; 589 590 /* ...and attempt to start output. */ 591 mb86950_start(ifp); 592 593 } 594 595 void 596 mb86950_start(ifp) 597 struct ifnet *ifp; 598 { 599 struct mb86950_softc *sc = ifp->if_softc; 600 bus_space_tag_t bst = sc->sc_bst; 601 bus_space_handle_t bsh = sc->sc_bsh; 602 struct mbuf *m; 603 int len; 604 605 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 606 return; 607 608 IF_DEQUEUE(&ifp->if_snd, m); 609 if (m == 0) 610 return; 611 612 #if NBPFILTER > 0 613 /* Tap off here if there is a BPF listener. */ 614 if (ifp->if_bpf) 615 bpf_mtap(ifp->if_bpf, m); 616 #endif 617 618 /* Send the packet to the mb86950 */ 619 len = mb86950_put_fifo(sc,m); 620 m_freem(m); 621 622 /* XXX bus_space_barrier here ? */ 623 if (bus_space_read_1(bst, bsh, DLCR_TX_STAT) & (TX_UNDERFLO | TX_BUS_WR_ERR)) { 624 log(LOG_ERR, "%s: tx fifo underflow/overflow\n", sc->sc_dev.dv_xname); 625 } 626 627 bus_space_write_2(bst, bsh, BMPR_TX_LENGTH, len | TRANSMIT_START); 628 629 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK); 630 /* XXX */ 631 sc->txb_sched++; 632 633 /* We have space for 'n' transmit packets of size 'mtu. */ 634 if (sc->txb_sched > sc->txb_num_pkt) { 635 ifp->if_flags |= IFF_OACTIVE; 636 ifp->if_timer = 2; 637 } 638 } 639 640 /* 641 * Send packet - copy packet from mbuf to the fifo 642 */ 643 u_short 644 mb86950_put_fifo(sc, m) 645 struct mb86950_softc *sc; 646 struct mbuf *m; 647 { 648 bus_space_tag_t bst = sc->sc_bst; 649 bus_space_handle_t bsh = sc->sc_bsh; 650 u_short *data; 651 u_char savebyte[2]; 652 int len, len1, wantbyte; 653 u_short totlen; 654 655 memset(savebyte, 0, sizeof(savebyte)); /* XXX gcc */ 656 657 totlen = wantbyte = 0; 658 659 for (; m != NULL; m = m->m_next) { 660 data = mtod(m, u_short *); 661 len = m->m_len; 662 if (len > 0) { 663 totlen += len; 664 665 /* Finish the last word. */ 666 if (wantbyte) { 667 savebyte[1] = *((u_char *)data); 668 bus_space_write_2(bst, bsh, BMPR_FIFO, *savebyte); 669 data = (u_short *)((u_char *)data + 1); 670 len--; 671 wantbyte = 0; 672 } 673 /* Output contiguous words. */ 674 if (len > 1) { 675 len1 = len/2; 676 bus_space_write_multi_stream_2(bst, bsh, BMPR_FIFO, data, len1); 677 data += len1; 678 len &= 1; 679 } 680 /* Save last byte, if necessary. */ 681 if (len == 1) { 682 savebyte[0] = *((u_char *)data); 683 wantbyte = 1; 684 } 685 } 686 } 687 688 if (wantbyte) { 689 savebyte[1] = 0; 690 bus_space_write_2(bst, bsh, BMPR_FIFO, *savebyte); 691 } 692 693 if (totlen < (ETHER_MIN_LEN - ETHER_CRC_LEN)) { 694 695 /* Fill the rest of the packet with zeros. */ 696 /* XXX Replace this mess with something else, eats CPU */ 697 /* The zero fill and last byte ought to be combined somehow */ 698 for(len = totlen + 1; len < (ETHER_MIN_LEN - ETHER_CRC_LEN); len += 2) 699 bus_space_write_2(bst, bsh, BMPR_FIFO, 0); 700 /* XXX */ 701 702 totlen = (ETHER_MIN_LEN - ETHER_CRC_LEN); 703 } 704 705 return (totlen); 706 } 707 708 /* 709 * Handle interrupts. 710 * Ethernet interface interrupt processor 711 */ 712 int 713 mb86950_intr(arg) 714 void *arg; 715 { 716 struct mb86950_softc *sc = arg; 717 bus_space_tag_t bst = sc->sc_bst; 718 bus_space_handle_t bsh = sc->sc_bsh; 719 struct ifnet *ifp = &sc->sc_ec.ec_if; 720 u_int8_t tstat, rstat; 721 722 /* Get interrupt status. */ 723 tstat = bus_space_read_1(bst, bsh, DLCR_TX_STAT); 724 rstat = bus_space_read_1(bst, bsh, DLCR_RX_STAT); 725 726 if (tstat == 0 && rstat == 0) return (0); 727 728 /* Disable etherstar interrupts so that we won't miss anything. */ 729 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, 0); 730 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, 0); 731 732 /* 733 * Handle transmitter interrupts. Handle these first because 734 * the receiver will reset the board under some conditions. 735 */ 736 if (tstat != 0) { 737 738 mb86950_tint(sc, tstat); 739 740 /* acknowledge transmit interrupt status. */ 741 bus_space_write_1(bst, bsh, DLCR_TX_STAT, tstat); 742 743 } 744 745 /* Handle receiver interrupts. */ 746 if (rstat != 0) { 747 748 mb86950_rint(sc, rstat); 749 750 /* acknowledge receive interrupt status. */ 751 bus_space_write_1(bst, bsh, DLCR_RX_STAT, rstat); 752 753 } 754 755 /* If tx still pending reset tx interrupt mask */ 756 if (sc->txb_sched > 0) 757 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK); 758 759 /* 760 * If it looks like the transmitter can take more data, 761 * attempt to start output on the interface. This is done 762 * after handling the receiver interrupt to give the 763 * receive operation priority. 764 */ 765 766 if ((ifp->if_flags & IFF_OACTIVE) == 0) 767 mb86950_start(ifp); 768 769 /* Set receive interrupts back */ 770 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, RX_MASK); 771 772 return(1); 773 } 774 775 /* Transmission interrupt handler */ 776 void 777 mb86950_tint(sc, tstat) 778 struct mb86950_softc *sc; 779 u_int8_t tstat; 780 { 781 bus_space_tag_t bst = sc->sc_bst; 782 bus_space_handle_t bsh = sc->sc_bsh; 783 struct ifnet *ifp = &sc->sc_ec.ec_if; 784 int col; 785 786 if (tstat & (TX_UNDERFLO | TX_BUS_WR_ERR)) { 787 /* XXX What do we need to do here? reset ? */ 788 ifp->if_oerrors++; 789 } 790 791 /* excessive collision */ 792 if (tstat & TX_16COL) { 793 ifp->if_collisions += 16; 794 /* 16 collisions means that the packet has been thrown away. */ 795 if (sc->txb_sched > 0) 796 sc->txb_sched--; 797 } 798 799 /* transmission complete. */ 800 if (tstat & TX_DONE) { 801 /* successfully transmitted packets ++. */ 802 ifp->if_opackets++; 803 if (sc->txb_sched > 0) 804 sc->txb_sched--; 805 806 /* Collision count valid only when TX_DONE is set */ 807 if (tstat & TX_COL) { 808 col = (bus_space_read_1(bst, bsh, DLCR_TX_MODE) & COL_MASK) >> 4; 809 ifp->if_collisions = ifp->if_collisions + col; 810 } 811 } 812 813 if (sc->txb_sched == 0) { 814 /* Reset output active flag and stop timer. */ 815 ifp->if_flags &= ~IFF_OACTIVE; 816 ifp->if_timer = 0; 817 } 818 } 819 820 /* receiver interrupt. */ 821 void 822 mb86950_rint(sc, rstat) 823 struct mb86950_softc *sc; 824 u_int8_t rstat; 825 { 826 bus_space_tag_t bst = sc->sc_bst; 827 bus_space_handle_t bsh = sc->sc_bsh; 828 struct ifnet *ifp = &sc->sc_ec.ec_if; 829 u_int status, len; 830 int i; 831 832 /* Update statistics if this interrupt is caused by an error. */ 833 if (rstat & RX_ERR_MASK) { 834 835 /* tried to read past end of fifo, should be harmless 836 * count everything else 837 */ 838 if ((rstat & RX_BUS_RD_ERR) == 0) { 839 ifp->if_ierrors++; 840 } 841 } 842 843 /* 844 * mb86950 has a flag indicating "receive buffer empty." 845 * We just loop checking the flag to pull out all received 846 * packets. 847 * 848 * We limit the number of iterrations to avoid infinite loop. 849 * It can be caused by a very slow CPU (some broken 850 * peripheral may insert incredible number of wait cycles) 851 * or, worse, by a broken mb86950 chip. 852 */ 853 for (i = 0; i < sc->rxb_num_pkt; i++) { 854 /* Stop the iterration if 86950 indicates no packets. */ 855 if (bus_space_read_1(bst, bsh, DLCR_RX_MODE) & RX_BUF_EMTY) 856 break; 857 858 /* receive packet status */ 859 status = bus_space_read_2(bst, bsh, BMPR_FIFO); 860 861 /* bad packet? */ 862 if ((status & GOOD_PKT) == 0) { 863 ifp->if_ierrors++; 864 mb86950_drain_fifo(sc); 865 continue; 866 } 867 868 /* Length valid ? */ 869 len = bus_space_read_2(bst, bsh, BMPR_FIFO); 870 871 if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN) || len < ETHER_HDR_LEN) { 872 ifp->if_ierrors++; 873 mb86950_drain_fifo(sc); 874 continue; 875 } 876 877 if (mb86950_get_fifo(sc, len) != 0) { 878 /* No mbufs? Drop packet. */ 879 ifp->if_ierrors++; 880 mb86950_drain_fifo(sc); 881 return; 882 } 883 884 /* Successfully received a packet. Update stat. */ 885 ifp->if_ipackets++; 886 } 887 } 888 889 /* 890 * Receive packet. 891 * Retrieve packet from receive buffer and send to the next level up via 892 * ether_input(). If there is a BPF listener, give a copy to BPF, too. 893 * Returns 0 if success, -1 if error (i.e., mbuf allocation failure). 894 */ 895 int 896 mb86950_get_fifo(sc, len) 897 struct mb86950_softc *sc; 898 u_int len; 899 { 900 bus_space_tag_t bst = sc->sc_bst; 901 bus_space_handle_t bsh = sc->sc_bsh; 902 struct ifnet *ifp = &sc->sc_ec.ec_if; 903 struct mbuf *m; 904 905 /* Allocate a header mbuf. */ 906 MGETHDR(m, M_DONTWAIT, MT_DATA); 907 if (m == 0) 908 return (-1); 909 910 /* 911 * Round len to even value. 912 */ 913 if (len & 1) 914 len++; 915 916 m->m_pkthdr.rcvif = ifp; 917 m->m_pkthdr.len = len; 918 919 /* The following silliness is to make NFS happy. */ 920 #define EROUND ((sizeof(struct ether_header) + 3) & ~3) 921 #define EOFF (EROUND - sizeof(struct ether_header)) 922 923 /* 924 * Our strategy has one more problem. There is a policy on 925 * mbuf cluster allocation. It says that we must have at 926 * least MINCLSIZE (208 bytes) to allocate a cluster. For a 927 * packet of a size between (MHLEN - 2) to (MINCLSIZE - 2), 928 * our code violates the rule... 929 * On the other hand, the current code is short, simple, 930 * and fast, however. It does no harmful thing, just wastes 931 * some memory. Any comments? FIXME. 932 */ 933 934 /* Attach a cluster if this packet doesn't fit in a normal mbuf. */ 935 if (len > MHLEN - EOFF) { 936 MCLGET(m, M_DONTWAIT); 937 if ((m->m_flags & M_EXT) == 0) { 938 m_freem(m); 939 return (-1); 940 } 941 } 942 943 /* 944 * The following assumes there is room for the ether header in the 945 * header mbuf. 946 */ 947 m->m_data += EOFF; 948 949 /* Set the length of this packet. */ 950 m->m_len = len; 951 952 /* Get a packet. */ 953 bus_space_read_multi_stream_2(bst, bsh, BMPR_FIFO, mtod(m, u_int16_t *), (len + 1) >> 1); 954 955 #if NBPFILTER > 0 956 /* 957 * Check if there's a BPF listener on this interface. If so, hand off 958 * the raw packet to bpf. 959 */ 960 if (ifp->if_bpf) 961 bpf_mtap(ifp->if_bpf, m); 962 #endif 963 964 (*ifp->if_input)(ifp, m); 965 return (0); 966 } 967 968 /* 969 * Enable power on the interface. 970 */ 971 int 972 mb86950_enable(sc) 973 struct mb86950_softc *sc; 974 { 975 976 if ((sc->sc_stat & ESTAR_STAT_ENABLED) == 0 && sc->sc_enable != NULL) { 977 if ((*sc->sc_enable)(sc) != 0) { 978 printf("%s: device enable failed\n", 979 sc->sc_dev.dv_xname); 980 return (EIO); 981 } 982 } 983 984 sc->sc_stat |= ESTAR_STAT_ENABLED; 985 return (0); 986 } 987 988 /* 989 * Disable power on the interface. 990 */ 991 void 992 mb86950_disable(sc) 993 struct mb86950_softc *sc; 994 { 995 996 if ((sc->sc_stat & ESTAR_STAT_ENABLED) != 0 && sc->sc_disable != NULL) { 997 (*sc->sc_disable)(sc); 998 sc->sc_stat &= ~ESTAR_STAT_ENABLED; 999 } 1000 } 1001 1002 /* 1003 * mbe_activate: 1004 * 1005 * Handle device activation/deactivation requests. 1006 */ 1007 int 1008 mb86950_activate(self, act) 1009 struct device *self; 1010 enum devact act; 1011 { 1012 struct mb86950_softc *sc = (struct mb86950_softc *)self; 1013 int rv, s; 1014 1015 rv = 0; 1016 s = splnet(); 1017 switch (act) { 1018 case DVACT_ACTIVATE: 1019 rv = EOPNOTSUPP; 1020 break; 1021 1022 case DVACT_DEACTIVATE: 1023 if_deactivate(&sc->sc_ec.ec_if); 1024 break; 1025 } 1026 splx(s); 1027 return (rv); 1028 } 1029 1030 /* 1031 * mb86950_detach: 1032 * 1033 * Detach a mb86950 interface. 1034 */ 1035 int 1036 mb86950_detach(sc) 1037 struct mb86950_softc *sc; 1038 { 1039 struct ifnet *ifp = &sc->sc_ec.ec_if; 1040 1041 /* Succeed now if there's no work to do. */ 1042 if ((sc->sc_stat & ESTAR_STAT_ATTACHED) == 0) 1043 return (0); 1044 1045 /* Delete all media. */ 1046 ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY); 1047 1048 #if NRND > 0 1049 /* Unhook the entropy source. */ 1050 rnd_detach_source(&sc->rnd_source); 1051 #endif 1052 ether_ifdetach(ifp); 1053 if_detach(ifp); 1054 1055 return (0); 1056 } 1057 1058 #if ESTAR_DEBUG >= 1 1059 void 1060 mb86950_dump(level, sc) 1061 int level; 1062 struct mb86950_softc *sc; 1063 { 1064 bus_space_tag_t bst = sc->sc_bst; 1065 bus_space_handle_t bsh = sc->sc_bsh; 1066 1067 log(level, "\tDLCR = %02x %02x %02x %02x %02x %02x %02x\n", 1068 bus_space_read_1(bst, bsh, DLCR_TX_STAT), 1069 bus_space_read_1(bst, bsh, DLCR_TX_INT_EN), 1070 bus_space_read_1(bst, bsh, DLCR_RX_STAT), 1071 bus_space_read_1(bst, bsh, DLCR_RX_INT_EN), 1072 bus_space_read_1(bst, bsh, DLCR_TX_MODE), 1073 bus_space_read_1(bst, bsh, DLCR_RX_MODE), 1074 bus_space_read_1(bst, bsh, DLCR_CONFIG)); 1075 1076 /* XXX BMPR2, 4 write only ? 1077 log(level, "\tBMPR = xxxx %04x %04x\n", 1078 bus_space_read_2(bst, bsh, BMPR_TX_LENGTH), 1079 bus_space_read_2(bst, bsh, BMPR_DMA)); 1080 */ 1081 } 1082 #endif 1083