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