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