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