1 /* $NetBSD: mb86950.c,v 1.20 2012/10/27 17:18:21 chs 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.20 2012/10/27 17:18:21 chs 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 124 #include <sys/param.h> 125 #include <sys/systm.h> 126 #include <sys/errno.h> 127 #include <sys/ioctl.h> 128 #include <sys/mbuf.h> 129 #include <sys/socket.h> 130 #include <sys/syslog.h> 131 #include <sys/device.h> 132 #include <sys/rnd.h> 133 134 #include <net/if.h> 135 #include <net/if_dl.h> 136 #include <net/if_types.h> 137 #include <net/if_media.h> 138 #include <net/if_ether.h> 139 140 #ifdef INET 141 #include <netinet/in.h> 142 #include <netinet/in_systm.h> 143 #include <netinet/in_var.h> 144 #include <netinet/ip.h> 145 #include <netinet/if_inarp.h> 146 #endif 147 148 149 #include <net/bpf.h> 150 #include <net/bpfdesc.h> 151 152 #include <sys/bus.h> 153 154 #include <dev/ic/mb86950reg.h> 155 #include <dev/ic/mb86950var.h> 156 157 #ifndef __BUS_SPACE_HAS_STREAM_METHODS 158 #define bus_space_write_stream_2 bus_space_write_2 159 #define bus_space_write_multi_stream_2 bus_space_write_multi_2 160 #define bus_space_read_multi_stream_2 bus_space_read_multi_2 161 #endif /* __BUS_SPACE_HAS_STREAM_METHODS */ 162 163 /* Standard driver entry points. These can be static. */ 164 int mb86950_ioctl(struct ifnet *, u_long, void *); 165 void mb86950_init(struct mb86950_softc *); 166 void mb86950_start(struct ifnet *); 167 void mb86950_watchdog(struct ifnet *); 168 void mb86950_reset(struct mb86950_softc *); 169 170 /* Local functions. */ 171 void mb86950_stop(struct mb86950_softc *); 172 void mb86950_tint(struct mb86950_softc *, u_int8_t); 173 void mb86950_rint(struct mb86950_softc *, u_int8_t); 174 int mb86950_get_fifo(struct mb86950_softc *, u_int); 175 ushort mb86950_put_fifo(struct mb86950_softc *, struct mbuf *); 176 void mb86950_drain_fifo(struct mb86950_softc *); 177 178 int mb86950_mediachange(struct ifnet *); 179 void mb86950_mediastatus(struct ifnet *, struct ifmediareq *); 180 181 182 #if ESTAR_DEBUG >= 1 183 void mb86950_dump(int, struct mb86950_softc *); 184 #endif 185 186 /********************************************************************/ 187 188 void 189 mb86950_attach(struct mb86950_softc *sc, u_int8_t *myea) 190 { 191 192 #ifdef DIAGNOSTIC 193 if (myea == NULL) { 194 printf("%s: ethernet address shouldn't be NULL\n", 195 device_xname(sc->sc_dev)); 196 panic("NULL ethernet address"); 197 } 198 #endif 199 200 /* Initialize 86950. */ 201 mb86950_stop(sc); 202 203 memcpy(sc->sc_enaddr, myea, sizeof(sc->sc_enaddr)); 204 205 sc->sc_stat |= ESTAR_STAT_ENABLED; 206 } 207 208 /* 209 * Stop everything on the interface. 210 * 211 * All buffered packets, both transmitting and receiving, 212 * if any, will be lost by stopping the interface. 213 */ 214 void 215 mb86950_stop(struct mb86950_softc *sc) 216 { 217 bus_space_tag_t bst = sc->sc_bst; 218 bus_space_handle_t bsh = sc->sc_bsh; 219 220 /* Stop interface hardware. */ 221 bus_space_write_1(bst, bsh, DLCR_CONFIG, DISABLE_DLC); 222 delay(200); 223 224 /* Disable interrupts. */ 225 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, 0); 226 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, 0); 227 228 /* Ack / Clear all interrupt status. */ 229 bus_space_write_1(bst, bsh, DLCR_TX_STAT, 0xff); 230 bus_space_write_1(bst, bsh, DLCR_RX_STAT, 0xff); 231 232 /* Clear DMA Bit */ 233 bus_space_write_2(bst, bsh, BMPR_DMA, 0); 234 235 /* accept no packets */ 236 bus_space_write_1(bst, bsh, DLCR_TX_MODE, 0); 237 bus_space_write_1(bst, bsh, DLCR_RX_MODE, 0); 238 239 mb86950_drain_fifo(sc); 240 241 } 242 243 void 244 mb86950_drain_fifo(struct mb86950_softc *sc) 245 { 246 bus_space_tag_t bst = sc->sc_bst; 247 bus_space_handle_t bsh = sc->sc_bsh; 248 249 /* Read data until bus read error (i.e. buffer empty). */ 250 /* XXX There ought to be a better way, eats CPU and bothers the chip */ 251 while (!(bus_space_read_1(bst, bsh, DLCR_RX_STAT) & RX_BUS_RD_ERR)) 252 bus_space_read_2(bst, bsh, BMPR_FIFO); 253 /* XXX */ 254 255 /* Clear Bus Rd Error */ 256 bus_space_write_1(bst, bsh, DLCR_RX_STAT, RX_BUS_RD_ERR); 257 } 258 259 /* 260 * Install interface into kernel networking data structures 261 */ 262 void 263 mb86950_config(struct mb86950_softc *sc, int *media, 264 int nmedia, int defmedia) 265 { 266 struct ifnet *ifp = &sc->sc_ec.ec_if; 267 bus_space_tag_t bst = sc->sc_bst; 268 bus_space_handle_t bsh = sc->sc_bsh; 269 270 /* Initialize ifnet structure. */ 271 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 272 ifp->if_softc = sc; 273 ifp->if_start = mb86950_start; 274 ifp->if_ioctl = mb86950_ioctl; 275 ifp->if_watchdog = mb86950_watchdog; 276 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; 277 278 IFQ_SET_READY(&ifp->if_snd); 279 280 /* Initialize media goo. */ 281 /* XXX The Tiara LANCard uses board jumpers to change media. 282 * This code may have to be changed for other cards. 283 */ 284 ifmedia_init(&sc->sc_media, 0, mb86950_mediachange, mb86950_mediastatus); 285 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL); 286 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL); 287 288 /* Attach the interface. */ 289 if_attach(ifp); 290 291 /* Feed the chip the station address. */ 292 bus_space_write_region_1(bst, bsh, DLCR_NODE_ID, sc->sc_enaddr, ETHER_ADDR_LEN); 293 294 ether_ifattach(ifp, sc->sc_enaddr); 295 296 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 297 RND_TYPE_NET, 0); 298 299 /* XXX No! This doesn't work - DLCR6 of the mb86950 is different 300 301 bus_space_write_1(bst, bsh, DLCR_CONFIG, 0x0f); 302 buf_config = bus_space_read_1(bst, bsh, DLCR_CONFIG); 303 304 sc->txb_count = ((buf_config & 0x0c) ? 2 : 1); 305 sc->txb_size = 1024 * (2 << ((buf_config & 0x0c) ? (((buf_config & 0x0c) >> 2) - 1) : 0)); 306 sc->txb_free = (sc->txb_size * sc->txb_count) / 1500; 307 308 sc->rxb_size = ((8 << (buf_config & 3)) * 1024) - (sc->txb_size * sc->txb_count); 309 sc->rxb_max = sc->rxb_size / 64; 310 311 printf("mb86950: Buffer Size %dKB with %d transmit buffer(s) %dKB each.\n", 312 (8 << (buf_config & 3)), sc->txb_count, (sc->txb_size / 1024)); 313 printf(" Transmit Buffer Space for %d maximum sized packet(s).\n",sc->txb_free); 314 printf(" System Bus Width %d bits, Buffer Memory %d bits.\n", 315 ((buf_config & 0x20) ? 8 : 16), 316 ((buf_config & 0x10) ? 8 : 16)); 317 318 */ 319 320 /* Set reasonable values for number of packet flow control if not 321 * set elsewhere */ 322 if (sc->txb_num_pkt == 0) sc->txb_num_pkt = 1; 323 if (sc->rxb_num_pkt == 0) sc->rxb_num_pkt = 100; 324 325 /* Print additional info when attached. */ 326 printf("%s: Ethernet address %s\n", device_xname(sc->sc_dev), 327 ether_sprintf(sc->sc_enaddr)); 328 329 /* The attach is successful. */ 330 sc->sc_stat |= ESTAR_STAT_ATTACHED; 331 } 332 333 /* 334 * Media change callback. 335 */ 336 int 337 mb86950_mediachange(struct ifnet *ifp) 338 { 339 340 struct mb86950_softc *sc = ifp->if_softc; 341 342 if (sc->sc_mediachange) 343 return ((*sc->sc_mediachange)(sc)); 344 345 return (0); 346 } 347 348 /* 349 * Media status callback. 350 */ 351 void 352 mb86950_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 353 { 354 struct mb86950_softc *sc = ifp->if_softc; 355 356 if ((sc->sc_stat & ESTAR_STAT_ENABLED) == 0) { 357 ifmr->ifm_active = IFM_ETHER | IFM_NONE; 358 ifmr->ifm_status = 0; 359 return; 360 } 361 362 if (sc->sc_mediastatus) 363 (*sc->sc_mediastatus)(sc, ifmr); 364 365 } 366 367 /* 368 * Reset interface. 369 */ 370 void 371 mb86950_reset(struct mb86950_softc *sc) 372 { 373 int s; 374 375 s = splnet(); 376 log(LOG_ERR, "%s: device reset\n", device_xname(sc->sc_dev)); 377 mb86950_stop(sc); 378 mb86950_init(sc); 379 splx(s); 380 } 381 382 /* 383 * Device timeout/watchdog routine. Entered if the device neglects to 384 * generate an interrupt after a transmit has been started on it. 385 */ 386 void 387 mb86950_watchdog(struct ifnet *ifp) 388 { 389 struct mb86950_softc *sc = ifp->if_softc; 390 bus_space_tag_t bst = sc->sc_bst; 391 bus_space_handle_t bsh = sc->sc_bsh; 392 u_int8_t tstat; 393 394 /* verbose watchdog messages for debugging timeouts */ 395 if ((tstat = bus_space_read_1(bst, bsh, DLCR_TX_STAT)) != 0) { 396 if (tstat & TX_CR_LOST) { 397 if ((tstat & (TX_COL | TX_16COL)) == 0) { 398 log(LOG_ERR, "%s: carrier lost\n", 399 device_xname(sc->sc_dev)); 400 } else { 401 log(LOG_ERR, "%s: excessive collisions\n", 402 device_xname(sc->sc_dev)); 403 } 404 } 405 else if ((tstat & (TX_UNDERFLO | TX_BUS_WR_ERR)) != 0) { 406 log(LOG_ERR, "%s: tx fifo underflow/overflow\n", 407 device_xname(sc->sc_dev)); 408 } else { 409 log(LOG_ERR, "%s: transmit error\n", 410 device_xname(sc->sc_dev)); 411 } 412 } else { 413 log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev)); 414 } 415 416 /* Don't know how many packets are lost by this accident. 417 * ... So just errors = errors + 1 418 */ 419 ifp->if_oerrors++; 420 421 mb86950_reset(sc); 422 423 } 424 425 /* 426 ******************** IOCTL 427 * Process an ioctl request. 428 */ 429 int 430 mb86950_ioctl(struct ifnet *ifp, unsigned long cmd, void *data) 431 { 432 struct mb86950_softc *sc = ifp->if_softc; 433 struct ifaddr *ifa = (struct ifaddr *)data; 434 struct ifreq *ifr = (struct ifreq *)data; 435 436 int s, error = 0; 437 438 s = splnet(); 439 440 switch (cmd) { 441 case SIOCINITIFADDR: 442 /* XXX deprecated ? What should I use instead? */ 443 if ((error = mb86950_enable(sc)) != 0) 444 break; 445 446 ifp->if_flags |= IFF_UP; 447 448 mb86950_init(sc); 449 switch (ifa->ifa_addr->sa_family) { 450 451 #ifdef INET 452 case AF_INET: 453 arp_ifinit(ifp, ifa); 454 break; 455 #endif 456 457 458 default: 459 break; 460 } 461 break; 462 463 case SIOCSIFFLAGS: 464 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 465 break; 466 /* XXX re-use ether_ioctl() */ 467 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 468 case IFF_RUNNING: 469 /* 470 * If interface is marked down and it is running, then 471 * stop it. 472 */ 473 mb86950_stop(sc); 474 ifp->if_flags &= ~IFF_RUNNING; 475 mb86950_disable(sc); 476 break; 477 case IFF_UP: 478 /* 479 * If interface is marked up and it is stopped, then 480 * start it. 481 */ 482 if ((error = mb86950_enable(sc)) != 0) 483 break; 484 mb86950_init(sc); 485 break; 486 case IFF_UP|IFF_RUNNING: 487 /* 488 * Reset the interface to pick up changes in any other 489 * flags that affect hardware registers. 490 */ 491 #if 0 492 /* Setmode not supported */ 493 mb86950_setmode(sc); 494 #endif 495 break; 496 case 0: 497 break; 498 } 499 500 #if ESTAR_DEBUG >= 1 501 /* "ifconfig fe0 debug" to print register dump. */ 502 if (ifp->if_flags & IFF_DEBUG) { 503 log(LOG_INFO, "%s: SIOCSIFFLAGS(DEBUG)\n", 504 device_xname(sc->sc_dev)); 505 mb86950_dump(LOG_DEBUG, sc); 506 } 507 #endif 508 break; 509 510 case SIOCGIFMEDIA: 511 case SIOCSIFMEDIA: 512 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); 513 break; 514 515 default: 516 error = ether_ioctl(ifp, cmd, data); 517 break; 518 } 519 520 splx(s); 521 return (error); 522 } 523 524 /* 525 * Initialize device. 526 */ 527 void 528 mb86950_init(struct mb86950_softc *sc) 529 { 530 bus_space_tag_t bst = sc->sc_bst; 531 bus_space_handle_t bsh = sc->sc_bsh; 532 struct ifnet *ifp = &sc->sc_ec.ec_if; 533 534 /* Reset transmitter flags. */ 535 ifp->if_flags &= ~IFF_OACTIVE; 536 ifp->if_timer = 0; 537 sc->txb_sched = 0; 538 539 bus_space_write_1(bst, bsh, DLCR_TX_MODE, LBC); 540 bus_space_write_1(bst, bsh, DLCR_RX_MODE, NORMAL_MODE); 541 542 /* Enable interrupts. */ 543 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK); 544 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, RX_MASK); 545 546 /* Enable transmitter and receiver. */ 547 bus_space_write_1(bst, bsh, DLCR_CONFIG, ENABLE_DLC); 548 delay(200); 549 550 /* Set 'running' flag. */ 551 ifp->if_flags |= IFF_RUNNING; 552 553 /* ...and attempt to start output. */ 554 mb86950_start(ifp); 555 556 } 557 558 void 559 mb86950_start(struct ifnet *ifp) 560 { 561 struct mb86950_softc *sc = ifp->if_softc; 562 bus_space_tag_t bst = sc->sc_bst; 563 bus_space_handle_t bsh = sc->sc_bsh; 564 struct mbuf *m; 565 int len; 566 567 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 568 return; 569 570 IF_DEQUEUE(&ifp->if_snd, m); 571 if (m == 0) 572 return; 573 574 /* Tap off here if there is a BPF listener. */ 575 bpf_mtap(ifp, m); 576 577 /* Send the packet to the mb86950 */ 578 len = mb86950_put_fifo(sc,m); 579 m_freem(m); 580 581 /* XXX bus_space_barrier here ? */ 582 if (bus_space_read_1(bst, bsh, DLCR_TX_STAT) & (TX_UNDERFLO | TX_BUS_WR_ERR)) { 583 log(LOG_ERR, "%s: tx fifo underflow/overflow\n", device_xname(sc->sc_dev)); 584 } 585 586 bus_space_write_2(bst, bsh, BMPR_TX_LENGTH, len | TRANSMIT_START); 587 588 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK); 589 /* XXX */ 590 sc->txb_sched++; 591 592 /* We have space for 'n' transmit packets of size 'mtu. */ 593 if (sc->txb_sched > sc->txb_num_pkt) { 594 ifp->if_flags |= IFF_OACTIVE; 595 ifp->if_timer = 2; 596 } 597 } 598 599 /* 600 * Send packet - copy packet from mbuf to the fifo 601 */ 602 u_short 603 mb86950_put_fifo(struct mb86950_softc *sc, struct mbuf *m) 604 { 605 bus_space_tag_t bst = sc->sc_bst; 606 bus_space_handle_t bsh = sc->sc_bsh; 607 u_short *data; 608 u_char savebyte[2]; 609 int len, len1, wantbyte; 610 u_short totlen; 611 612 memset(savebyte, 0, sizeof(savebyte)); /* XXX gcc */ 613 614 totlen = wantbyte = 0; 615 616 for (; m != NULL; m = m->m_next) { 617 data = mtod(m, u_short *); 618 len = m->m_len; 619 if (len > 0) { 620 totlen += len; 621 622 /* Finish the last word. */ 623 if (wantbyte) { 624 savebyte[1] = *((u_char *)data); 625 bus_space_write_2(bst, bsh, BMPR_FIFO, *savebyte); 626 data = (u_short *)((u_char *)data + 1); 627 len--; 628 wantbyte = 0; 629 } 630 /* Output contiguous words. */ 631 if (len > 1) { 632 len1 = len/2; 633 bus_space_write_multi_stream_2(bst, bsh, BMPR_FIFO, data, len1); 634 data += len1; 635 len &= 1; 636 } 637 /* Save last byte, if necessary. */ 638 if (len == 1) { 639 savebyte[0] = *((u_char *)data); 640 wantbyte = 1; 641 } 642 } 643 } 644 645 if (wantbyte) { 646 savebyte[1] = 0; 647 bus_space_write_2(bst, bsh, BMPR_FIFO, *savebyte); 648 } 649 650 if (totlen < (ETHER_MIN_LEN - ETHER_CRC_LEN)) { 651 652 /* Fill the rest of the packet with zeros. */ 653 /* XXX Replace this mess with something else, eats CPU */ 654 /* The zero fill and last byte ought to be combined somehow */ 655 for(len = totlen + 1; len < (ETHER_MIN_LEN - ETHER_CRC_LEN); len += 2) 656 bus_space_write_2(bst, bsh, BMPR_FIFO, 0); 657 /* XXX */ 658 659 totlen = (ETHER_MIN_LEN - ETHER_CRC_LEN); 660 } 661 662 return (totlen); 663 } 664 665 /* 666 * Handle interrupts. 667 * Ethernet interface interrupt processor 668 */ 669 int 670 mb86950_intr(void *arg) 671 { 672 struct mb86950_softc *sc = arg; 673 bus_space_tag_t bst = sc->sc_bst; 674 bus_space_handle_t bsh = sc->sc_bsh; 675 struct ifnet *ifp = &sc->sc_ec.ec_if; 676 u_int8_t tstat, rstat; 677 678 /* Get interrupt status. */ 679 tstat = bus_space_read_1(bst, bsh, DLCR_TX_STAT); 680 rstat = bus_space_read_1(bst, bsh, DLCR_RX_STAT); 681 682 if (tstat == 0 && rstat == 0) return (0); 683 684 /* Disable etherstar interrupts so that we won't miss anything. */ 685 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, 0); 686 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, 0); 687 688 /* 689 * Handle transmitter interrupts. Handle these first because 690 * the receiver will reset the board under some conditions. 691 */ 692 if (tstat != 0) { 693 694 mb86950_tint(sc, tstat); 695 696 /* acknowledge transmit interrupt status. */ 697 bus_space_write_1(bst, bsh, DLCR_TX_STAT, tstat); 698 699 } 700 701 /* Handle receiver interrupts. */ 702 if (rstat != 0) { 703 704 mb86950_rint(sc, rstat); 705 706 /* acknowledge receive interrupt status. */ 707 bus_space_write_1(bst, bsh, DLCR_RX_STAT, rstat); 708 709 } 710 711 /* If tx still pending reset tx interrupt mask */ 712 if (sc->txb_sched > 0) 713 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK); 714 715 /* 716 * If it looks like the transmitter can take more data, 717 * attempt to start output on the interface. This is done 718 * after handling the receiver interrupt to give the 719 * receive operation priority. 720 */ 721 722 if ((ifp->if_flags & IFF_OACTIVE) == 0) 723 mb86950_start(ifp); 724 725 /* Set receive interrupts back */ 726 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, RX_MASK); 727 728 return(1); 729 } 730 731 /* Transmission interrupt handler */ 732 void 733 mb86950_tint(struct mb86950_softc *sc, u_int8_t tstat) 734 { 735 bus_space_tag_t bst = sc->sc_bst; 736 bus_space_handle_t bsh = sc->sc_bsh; 737 struct ifnet *ifp = &sc->sc_ec.ec_if; 738 int col; 739 740 if (tstat & (TX_UNDERFLO | TX_BUS_WR_ERR)) { 741 /* XXX What do we need to do here? reset ? */ 742 ifp->if_oerrors++; 743 } 744 745 /* excessive collision */ 746 if (tstat & TX_16COL) { 747 ifp->if_collisions += 16; 748 /* 16 collisions means that the packet has been thrown away. */ 749 if (sc->txb_sched > 0) 750 sc->txb_sched--; 751 } 752 753 /* transmission complete. */ 754 if (tstat & TX_DONE) { 755 /* successfully transmitted packets ++. */ 756 ifp->if_opackets++; 757 if (sc->txb_sched > 0) 758 sc->txb_sched--; 759 760 /* Collision count valid only when TX_DONE is set */ 761 if (tstat & TX_COL) { 762 col = (bus_space_read_1(bst, bsh, DLCR_TX_MODE) & COL_MASK) >> 4; 763 ifp->if_collisions = ifp->if_collisions + col; 764 } 765 } 766 767 if (sc->txb_sched == 0) { 768 /* Reset output active flag and stop timer. */ 769 ifp->if_flags &= ~IFF_OACTIVE; 770 ifp->if_timer = 0; 771 } 772 } 773 774 /* receiver interrupt. */ 775 void 776 mb86950_rint(struct mb86950_softc *sc, u_int8_t rstat) 777 { 778 bus_space_tag_t bst = sc->sc_bst; 779 bus_space_handle_t bsh = sc->sc_bsh; 780 struct ifnet *ifp = &sc->sc_ec.ec_if; 781 u_int status, len; 782 int i; 783 784 /* Update statistics if this interrupt is caused by an error. */ 785 if (rstat & RX_ERR_MASK) { 786 787 /* tried to read past end of fifo, should be harmless 788 * count everything else 789 */ 790 if ((rstat & RX_BUS_RD_ERR) == 0) { 791 ifp->if_ierrors++; 792 } 793 } 794 795 /* 796 * mb86950 has a flag indicating "receive buffer empty." 797 * We just loop checking the flag to pull out all received 798 * packets. 799 * 800 * We limit the number of iterrations to avoid infinite loop. 801 * It can be caused by a very slow CPU (some broken 802 * peripheral may insert incredible number of wait cycles) 803 * or, worse, by a broken mb86950 chip. 804 */ 805 for (i = 0; i < sc->rxb_num_pkt; i++) { 806 /* Stop the iterration if 86950 indicates no packets. */ 807 if (bus_space_read_1(bst, bsh, DLCR_RX_MODE) & RX_BUF_EMTY) 808 break; 809 810 /* receive packet status */ 811 status = bus_space_read_2(bst, bsh, BMPR_FIFO); 812 813 /* bad packet? */ 814 if ((status & GOOD_PKT) == 0) { 815 ifp->if_ierrors++; 816 mb86950_drain_fifo(sc); 817 continue; 818 } 819 820 /* Length valid ? */ 821 len = bus_space_read_2(bst, bsh, BMPR_FIFO); 822 823 if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN) || len < ETHER_HDR_LEN) { 824 ifp->if_ierrors++; 825 mb86950_drain_fifo(sc); 826 continue; 827 } 828 829 if (mb86950_get_fifo(sc, len) != 0) { 830 /* No mbufs? Drop packet. */ 831 ifp->if_ierrors++; 832 mb86950_drain_fifo(sc); 833 return; 834 } 835 836 /* Successfully received a packet. Update stat. */ 837 ifp->if_ipackets++; 838 } 839 } 840 841 /* 842 * Receive packet. 843 * Retrieve packet from receive buffer and send to the next level up via 844 * ether_input(). If there is a BPF listener, give a copy to BPF, too. 845 * Returns 0 if success, -1 if error (i.e., mbuf allocation failure). 846 */ 847 int 848 mb86950_get_fifo(struct mb86950_softc *sc, u_int len) 849 { 850 bus_space_tag_t bst = sc->sc_bst; 851 bus_space_handle_t bsh = sc->sc_bsh; 852 struct ifnet *ifp = &sc->sc_ec.ec_if; 853 struct mbuf *m; 854 855 /* Allocate a header mbuf. */ 856 MGETHDR(m, M_DONTWAIT, MT_DATA); 857 if (m == 0) 858 return (-1); 859 860 /* 861 * Round len to even value. 862 */ 863 if (len & 1) 864 len++; 865 866 m->m_pkthdr.rcvif = ifp; 867 m->m_pkthdr.len = len; 868 869 /* The following silliness is to make NFS happy. */ 870 #define EROUND ((sizeof(struct ether_header) + 3) & ~3) 871 #define EOFF (EROUND - sizeof(struct ether_header)) 872 873 /* 874 * Our strategy has one more problem. There is a policy on 875 * mbuf cluster allocation. It says that we must have at 876 * least MINCLSIZE (208 bytes) to allocate a cluster. For a 877 * packet of a size between (MHLEN - 2) to (MINCLSIZE - 2), 878 * our code violates the rule... 879 * On the other hand, the current code is short, simple, 880 * and fast, however. It does no harmful thing, just wastes 881 * some memory. Any comments? FIXME. 882 */ 883 884 /* Attach a cluster if this packet doesn't fit in a normal mbuf. */ 885 if (len > MHLEN - EOFF) { 886 MCLGET(m, M_DONTWAIT); 887 if ((m->m_flags & M_EXT) == 0) { 888 m_freem(m); 889 return (-1); 890 } 891 } 892 893 /* 894 * The following assumes there is room for the ether header in the 895 * header mbuf. 896 */ 897 m->m_data += EOFF; 898 899 /* Set the length of this packet. */ 900 m->m_len = len; 901 902 /* Get a packet. */ 903 bus_space_read_multi_stream_2(bst, bsh, BMPR_FIFO, mtod(m, u_int16_t *), (len + 1) >> 1); 904 905 /* 906 * Check if there's a BPF listener on this interface. If so, hand off 907 * the raw packet to bpf. 908 */ 909 bpf_mtap(ifp, m); 910 911 (*ifp->if_input)(ifp, m); 912 return (0); 913 } 914 915 /* 916 * Enable power on the interface. 917 */ 918 int 919 mb86950_enable(struct mb86950_softc *sc) 920 { 921 922 if ((sc->sc_stat & ESTAR_STAT_ENABLED) == 0 && sc->sc_enable != NULL) { 923 if ((*sc->sc_enable)(sc) != 0) { 924 aprint_error_dev(sc->sc_dev, "device enable failed\n"); 925 return (EIO); 926 } 927 } 928 929 sc->sc_stat |= ESTAR_STAT_ENABLED; 930 return (0); 931 } 932 933 /* 934 * Disable power on the interface. 935 */ 936 void 937 mb86950_disable(struct mb86950_softc *sc) 938 { 939 940 if ((sc->sc_stat & ESTAR_STAT_ENABLED) != 0 && sc->sc_disable != NULL) { 941 (*sc->sc_disable)(sc); 942 sc->sc_stat &= ~ESTAR_STAT_ENABLED; 943 } 944 } 945 946 /* 947 * mbe_activate: 948 * 949 * Handle device activation/deactivation requests. 950 */ 951 int 952 mb86950_activate(device_t self, enum devact act) 953 { 954 struct mb86950_softc *sc = device_private(self); 955 956 switch (act) { 957 case DVACT_DEACTIVATE: 958 if_deactivate(&sc->sc_ec.ec_if); 959 return 0; 960 default: 961 return EOPNOTSUPP; 962 } 963 } 964 965 /* 966 * mb86950_detach: 967 * 968 * Detach a mb86950 interface. 969 */ 970 int 971 mb86950_detach(struct mb86950_softc *sc) 972 { 973 struct ifnet *ifp = &sc->sc_ec.ec_if; 974 975 /* Succeed now if there's no work to do. */ 976 if ((sc->sc_stat & ESTAR_STAT_ATTACHED) == 0) 977 return (0); 978 979 /* Delete all media. */ 980 ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY); 981 982 /* Unhook the entropy source. */ 983 rnd_detach_source(&sc->rnd_source); 984 985 ether_ifdetach(ifp); 986 if_detach(ifp); 987 988 return (0); 989 } 990 991 #if ESTAR_DEBUG >= 1 992 void 993 mb86950_dump(int level, struct mb86950_softc *sc) 994 { 995 bus_space_tag_t bst = sc->sc_bst; 996 bus_space_handle_t bsh = sc->sc_bsh; 997 998 log(level, "\tDLCR = %02x %02x %02x %02x %02x %02x %02x\n", 999 bus_space_read_1(bst, bsh, DLCR_TX_STAT), 1000 bus_space_read_1(bst, bsh, DLCR_TX_INT_EN), 1001 bus_space_read_1(bst, bsh, DLCR_RX_STAT), 1002 bus_space_read_1(bst, bsh, DLCR_RX_INT_EN), 1003 bus_space_read_1(bst, bsh, DLCR_TX_MODE), 1004 bus_space_read_1(bst, bsh, DLCR_RX_MODE), 1005 bus_space_read_1(bst, bsh, DLCR_CONFIG)); 1006 1007 /* XXX BMPR2, 4 write only ? 1008 log(level, "\tBMPR = xxxx %04x %04x\n", 1009 bus_space_read_2(bst, bsh, BMPR_TX_LENGTH), 1010 bus_space_read_2(bst, bsh, BMPR_DMA)); 1011 */ 1012 } 1013 #endif 1014