1 /* $NetBSD: mb86950.c,v 1.34 2020/02/04 05:25:39 thorpej 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.34 2020/02/04 05:25:39 thorpej 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 void 240 mb86950_drain_fifo(struct mb86950_softc *sc) 241 { 242 bus_space_tag_t bst = sc->sc_bst; 243 bus_space_handle_t bsh = sc->sc_bsh; 244 245 /* Read data until bus read error (i.e. buffer empty). */ 246 /* XXX There ought to be a better way, eats CPU and bothers the chip */ 247 while (!(bus_space_read_1(bst, bsh, DLCR_RX_STAT) & RX_BUS_RD_ERR)) 248 bus_space_read_2(bst, bsh, BMPR_FIFO); 249 /* XXX */ 250 251 /* Clear Bus Rd Error */ 252 bus_space_write_1(bst, bsh, DLCR_RX_STAT, RX_BUS_RD_ERR); 253 } 254 255 /* 256 * Install interface into kernel networking data structures 257 */ 258 void 259 mb86950_config(struct mb86950_softc *sc, int *media, int nmedia, int defmedia) 260 { 261 struct ifnet *ifp = &sc->sc_ec.ec_if; 262 bus_space_tag_t bst = sc->sc_bst; 263 bus_space_handle_t bsh = sc->sc_bsh; 264 265 /* Initialize ifnet structure. */ 266 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 267 ifp->if_softc = sc; 268 ifp->if_start = mb86950_start; 269 ifp->if_ioctl = mb86950_ioctl; 270 ifp->if_watchdog = mb86950_watchdog; 271 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; 272 273 IFQ_SET_READY(&ifp->if_snd); 274 275 /* Initialize media goo. */ 276 /* XXX The Tiara LANCard uses board jumpers to change media. 277 * This code may have to be changed for other cards. 278 */ 279 sc->sc_ec.ec_ifmedia = &sc->sc_media; 280 ifmedia_init(&sc->sc_media, 0, mb86950_mediachange, 281 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, 291 ETHER_ADDR_LEN); 292 293 ether_ifattach(ifp, sc->sc_enaddr); 294 295 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 296 RND_TYPE_NET, RND_FLAG_DEFAULT); 297 298 /* XXX No! This doesn't work - DLCR6 of the mb86950 is different 299 300 bus_space_write_1(bst, bsh, DLCR_CONFIG, 0x0f); 301 buf_config = bus_space_read_1(bst, bsh, DLCR_CONFIG); 302 303 sc->txb_count = ((buf_config & 0x0c) ? 2 : 1); 304 sc->txb_size = 1024 * (2 << ((buf_config & 0x0c) ? (((buf_config & 0x0c) >> 2) - 1) : 0)); 305 sc->txb_free = (sc->txb_size * sc->txb_count) / 1500; 306 307 sc->rxb_size = ((8 << (buf_config & 3)) * 1024) - (sc->txb_size * sc->txb_count); 308 sc->rxb_max = sc->rxb_size / 64; 309 310 printf("mb86950: Buffer Size %dKB with %d transmit buffer(s) %dKB each.\n", 311 (8 << (buf_config & 3)), sc->txb_count, (sc->txb_size / 1024)); 312 printf(" Transmit Buffer Space for %d maximum sized packet(s).\n",sc->txb_free); 313 printf(" System Bus Width %d bits, Buffer Memory %d bits.\n", 314 ((buf_config & 0x20) ? 8 : 16), 315 ((buf_config & 0x10) ? 8 : 16)); 316 317 */ 318 319 /* Set reasonable values for number of packet flow control if not 320 * set elsewhere */ 321 if (sc->txb_num_pkt == 0) sc->txb_num_pkt = 1; 322 if (sc->rxb_num_pkt == 0) sc->rxb_num_pkt = 100; 323 324 /* Print additional info when attached. */ 325 printf("%s: Ethernet address %s\n", device_xname(sc->sc_dev), 326 ether_sprintf(sc->sc_enaddr)); 327 328 /* The attach is successful. */ 329 sc->sc_stat |= ESTAR_STAT_ATTACHED; 330 } 331 332 /* 333 * Media change callback. 334 */ 335 int 336 mb86950_mediachange(struct ifnet *ifp) 337 { 338 339 struct mb86950_softc *sc = ifp->if_softc; 340 341 if (sc->sc_mediachange) 342 return (*sc->sc_mediachange)(sc); 343 344 return 0; 345 } 346 347 /* 348 * Media status callback. 349 */ 350 void 351 mb86950_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 352 { 353 struct mb86950_softc *sc = ifp->if_softc; 354 355 if ((sc->sc_stat & ESTAR_STAT_ENABLED) == 0) { 356 ifmr->ifm_active = IFM_ETHER | IFM_NONE; 357 ifmr->ifm_status = 0; 358 return; 359 } 360 361 if (sc->sc_mediastatus) 362 (*sc->sc_mediastatus)(sc, ifmr); 363 364 } 365 366 /* 367 * Reset interface. 368 */ 369 void 370 mb86950_reset(struct mb86950_softc *sc) 371 { 372 int s; 373 374 s = splnet(); 375 log(LOG_ERR, "%s: device reset\n", device_xname(sc->sc_dev)); 376 mb86950_stop(sc); 377 mb86950_init(sc); 378 splx(s); 379 } 380 381 /* 382 * Device timeout/watchdog routine. Entered if the device neglects to 383 * generate an interrupt after a transmit has been started on it. 384 */ 385 void 386 mb86950_watchdog(struct ifnet *ifp) 387 { 388 struct mb86950_softc *sc = ifp->if_softc; 389 bus_space_tag_t bst = sc->sc_bst; 390 bus_space_handle_t bsh = sc->sc_bsh; 391 u_int8_t tstat; 392 393 /* Verbose watchdog messages for debugging timeouts */ 394 if ((tstat = bus_space_read_1(bst, bsh, DLCR_TX_STAT)) != 0) { 395 if (tstat & TX_CR_LOST) { 396 if ((tstat & (TX_COL | TX_16COL)) == 0) { 397 log(LOG_ERR, "%s: carrier lost\n", 398 device_xname(sc->sc_dev)); 399 } else { 400 log(LOG_ERR, "%s: excessive collisions\n", 401 device_xname(sc->sc_dev)); 402 } 403 } 404 else if ((tstat & (TX_UNDERFLO | TX_BUS_WR_ERR)) != 0) { 405 log(LOG_ERR, "%s: tx fifo underflow/overflow\n", 406 device_xname(sc->sc_dev)); 407 } else { 408 log(LOG_ERR, "%s: transmit error\n", 409 device_xname(sc->sc_dev)); 410 } 411 } else 412 log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev)); 413 414 /* 415 * Don't know how many packets are lost by this accident. 416 * ... So just errors = errors + 1 417 */ 418 if_statinc(ifp, if_oerrors); 419 420 mb86950_reset(sc); 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 433 int s, error = 0; 434 435 s = splnet(); 436 437 switch (cmd) { 438 case SIOCINITIFADDR: 439 /* XXX deprecated ? What should I use instead? */ 440 if ((error = mb86950_enable(sc)) != 0) 441 break; 442 443 ifp->if_flags |= IFF_UP; 444 445 mb86950_init(sc); 446 switch (ifa->ifa_addr->sa_family) { 447 448 #ifdef INET 449 case AF_INET: 450 arp_ifinit(ifp, ifa); 451 break; 452 #endif 453 454 455 default: 456 break; 457 } 458 break; 459 460 case SIOCSIFFLAGS: 461 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 462 break; 463 /* XXX re-use ether_ioctl() */ 464 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 465 case IFF_RUNNING: 466 /* 467 * If interface is marked down and it is running, then 468 * stop it. 469 */ 470 mb86950_stop(sc); 471 ifp->if_flags &= ~IFF_RUNNING; 472 mb86950_disable(sc); 473 break; 474 case IFF_UP: 475 /* 476 * If interface is marked up and it is stopped, then 477 * start it. 478 */ 479 if ((error = mb86950_enable(sc)) != 0) 480 break; 481 mb86950_init(sc); 482 break; 483 case IFF_UP|IFF_RUNNING: 484 /* 485 * Reset the interface to pick up changes in any other 486 * flags that affect hardware registers. 487 */ 488 #if 0 489 /* Setmode not supported */ 490 mb86950_setmode(sc); 491 #endif 492 break; 493 case 0: 494 break; 495 } 496 497 #if ESTAR_DEBUG >= 1 498 /* "ifconfig fe0 debug" to print register dump. */ 499 if (ifp->if_flags & IFF_DEBUG) { 500 log(LOG_INFO, "%s: SIOCSIFFLAGS(DEBUG)\n", 501 device_xname(sc->sc_dev)); 502 mb86950_dump(LOG_DEBUG, sc); 503 } 504 #endif 505 break; 506 507 default: 508 error = ether_ioctl(ifp, cmd, data); 509 break; 510 } 511 512 splx(s); 513 return error; 514 } 515 516 /* 517 * Initialize device. 518 */ 519 void 520 mb86950_init(struct mb86950_softc *sc) 521 { 522 bus_space_tag_t bst = sc->sc_bst; 523 bus_space_handle_t bsh = sc->sc_bsh; 524 struct ifnet *ifp = &sc->sc_ec.ec_if; 525 526 /* Reset transmitter flags. */ 527 ifp->if_flags &= ~IFF_OACTIVE; 528 ifp->if_timer = 0; 529 sc->txb_sched = 0; 530 531 bus_space_write_1(bst, bsh, DLCR_TX_MODE, LBC); 532 bus_space_write_1(bst, bsh, DLCR_RX_MODE, NORMAL_MODE); 533 534 /* Enable interrupts. */ 535 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK); 536 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, RX_MASK); 537 538 /* Enable transmitter and receiver. */ 539 bus_space_write_1(bst, bsh, DLCR_CONFIG, ENABLE_DLC); 540 delay(200); 541 542 /* Set 'running' flag. */ 543 ifp->if_flags |= IFF_RUNNING; 544 545 /* ...and attempt to start output. */ 546 mb86950_start(ifp); 547 } 548 549 void 550 mb86950_start(struct ifnet *ifp) 551 { 552 struct mb86950_softc *sc = ifp->if_softc; 553 bus_space_tag_t bst = sc->sc_bst; 554 bus_space_handle_t bsh = sc->sc_bsh; 555 struct mbuf *m; 556 int len; 557 558 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 559 return; 560 561 IF_DEQUEUE(&ifp->if_snd, m); 562 if (m == 0) 563 return; 564 565 /* Tap off here if there is a BPF listener. */ 566 bpf_mtap(ifp, m, BPF_D_OUT); 567 568 /* Send the packet to the mb86950 */ 569 len = mb86950_put_fifo(sc,m); 570 m_freem(m); 571 572 /* XXX bus_space_barrier here ? */ 573 if (bus_space_read_1(bst, bsh, DLCR_TX_STAT) 574 & (TX_UNDERFLO | TX_BUS_WR_ERR)) { 575 log(LOG_ERR, "%s: tx fifo underflow/overflow\n", 576 device_xname(sc->sc_dev)); 577 } 578 579 bus_space_write_2(bst, bsh, BMPR_TX_LENGTH, len | TRANSMIT_START); 580 581 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK); 582 /* XXX */ 583 sc->txb_sched++; 584 585 /* We have space for 'n' transmit packets of size 'mtu. */ 586 if (sc->txb_sched > sc->txb_num_pkt) { 587 ifp->if_flags |= IFF_OACTIVE; 588 ifp->if_timer = 2; 589 } 590 } 591 592 /* 593 * Send packet - copy packet from mbuf to the fifo 594 */ 595 u_short 596 mb86950_put_fifo(struct mb86950_softc *sc, struct mbuf *m) 597 { 598 bus_space_tag_t bst = sc->sc_bst; 599 bus_space_handle_t bsh = sc->sc_bsh; 600 u_short *data; 601 u_char savebyte[2]; 602 int len, len1, wantbyte; 603 u_short totlen; 604 605 memset(savebyte, 0, sizeof(savebyte)); /* XXX gcc */ 606 607 totlen = wantbyte = 0; 608 609 for (; m != NULL; m = m->m_next) { 610 data = mtod(m, u_short *); 611 len = m->m_len; 612 if (len > 0) { 613 totlen += len; 614 615 /* Finish the last word. */ 616 if (wantbyte) { 617 savebyte[1] = *((u_char *)data); 618 bus_space_write_2(bst, bsh, BMPR_FIFO, 619 *savebyte); 620 data = (u_short *)((u_char *)data + 1); 621 len--; 622 wantbyte = 0; 623 } 624 /* Output contiguous words. */ 625 if (len > 1) { 626 len1 = len/2; 627 bus_space_write_multi_stream_2(bst, bsh, 628 BMPR_FIFO, data, len1); 629 data += len1; 630 len &= 1; 631 } 632 /* Save last byte, if necessary. */ 633 if (len == 1) { 634 savebyte[0] = *((u_char *)data); 635 wantbyte = 1; 636 } 637 } 638 } 639 640 if (wantbyte) { 641 savebyte[1] = 0; 642 bus_space_write_2(bst, bsh, BMPR_FIFO, *savebyte); 643 } 644 645 if (totlen < (ETHER_MIN_LEN - ETHER_CRC_LEN)) { 646 647 /* Fill the rest of the packet with zeros. */ 648 /* XXX Replace this mess with something else, eats CPU */ 649 /* The zero fill and last byte ought to be combined somehow */ 650 for (len = totlen + 1; len < (ETHER_MIN_LEN - ETHER_CRC_LEN); 651 len += 2) 652 bus_space_write_2(bst, bsh, BMPR_FIFO, 0); 653 /* XXX */ 654 655 totlen = (ETHER_MIN_LEN - ETHER_CRC_LEN); 656 } 657 658 return totlen; 659 } 660 661 /* 662 * Handle interrupts. 663 * Ethernet interface interrupt processor 664 */ 665 int 666 mb86950_intr(void *arg) 667 { 668 struct mb86950_softc *sc = arg; 669 bus_space_tag_t bst = sc->sc_bst; 670 bus_space_handle_t bsh = sc->sc_bsh; 671 struct ifnet *ifp = &sc->sc_ec.ec_if; 672 u_int8_t tstat, rstat; 673 674 /* Get interrupt status. */ 675 tstat = bus_space_read_1(bst, bsh, DLCR_TX_STAT); 676 rstat = bus_space_read_1(bst, bsh, DLCR_RX_STAT); 677 678 if (tstat == 0 && rstat == 0) return 0; 679 680 /* Disable etherstar interrupts so that we won't miss anything. */ 681 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, 0); 682 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, 0); 683 684 /* 685 * Handle transmitter interrupts. Handle these first because 686 * the receiver will reset the board under some conditions. 687 */ 688 if (tstat != 0) { 689 690 mb86950_tint(sc, tstat); 691 692 /* acknowledge transmit interrupt status. */ 693 bus_space_write_1(bst, bsh, DLCR_TX_STAT, tstat); 694 695 } 696 697 /* Handle receiver interrupts. */ 698 if (rstat != 0) { 699 700 mb86950_rint(sc, rstat); 701 702 /* acknowledge receive interrupt status. */ 703 bus_space_write_1(bst, bsh, DLCR_RX_STAT, rstat); 704 705 } 706 707 /* If tx still pending reset tx interrupt mask */ 708 if (sc->txb_sched > 0) 709 bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK); 710 711 /* 712 * If it looks like the transmitter can take more data, 713 * attempt to start output on the interface. This is done 714 * after handling the receiver interrupt to give the 715 * receive operation priority. 716 */ 717 718 if ((ifp->if_flags & IFF_OACTIVE) == 0) 719 if_schedule_deferred_start(ifp); 720 721 /* Set receive interrupts back */ 722 bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, RX_MASK); 723 724 return 1; 725 } 726 727 /* Transmission interrupt handler */ 728 void 729 mb86950_tint(struct mb86950_softc *sc, u_int8_t tstat) 730 { 731 bus_space_tag_t bst = sc->sc_bst; 732 bus_space_handle_t bsh = sc->sc_bsh; 733 struct ifnet *ifp = &sc->sc_ec.ec_if; 734 int col; 735 736 if (tstat & (TX_UNDERFLO | TX_BUS_WR_ERR)) { 737 /* XXX What do we need to do here? reset ? */ 738 if_statinc(ifp, if_oerrors); 739 } 740 741 /* Excessive collision */ 742 if (tstat & TX_16COL) { 743 if_statadd(ifp, if_collisions, 16); 744 /* 16 collisions means that the packet has been thrown away. */ 745 if (sc->txb_sched > 0) 746 sc->txb_sched--; 747 } 748 749 /* Transmission complete. */ 750 if (tstat & TX_DONE) { 751 /* Successfully transmitted packets ++. */ 752 if_statinc(ifp, if_opackets); 753 if (sc->txb_sched > 0) 754 sc->txb_sched--; 755 756 /* Collision count valid only when TX_DONE is set */ 757 if (tstat & TX_COL) { 758 col = (bus_space_read_1(bst, bsh, DLCR_TX_MODE) 759 & COL_MASK) >> 4; 760 if_statadd(ifp, if_collisions, col); 761 } 762 } 763 764 if (sc->txb_sched == 0) { 765 /* Reset output active flag and stop timer. */ 766 ifp->if_flags &= ~IFF_OACTIVE; 767 ifp->if_timer = 0; 768 } 769 } 770 771 /* Receiver interrupt. */ 772 void 773 mb86950_rint(struct mb86950_softc *sc, u_int8_t rstat) 774 { 775 bus_space_tag_t bst = sc->sc_bst; 776 bus_space_handle_t bsh = sc->sc_bsh; 777 struct ifnet *ifp = &sc->sc_ec.ec_if; 778 u_int status, len; 779 int i; 780 781 /* Update statistics if this interrupt is caused by an error. */ 782 if (rstat & RX_ERR_MASK) { 783 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 if_statinc(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 if_statinc(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) 822 || len < ETHER_HDR_LEN) { 823 if_statinc(ifp, if_ierrors); 824 mb86950_drain_fifo(sc); 825 continue; 826 } 827 828 if (mb86950_get_fifo(sc, len) != 0) { 829 /* No mbufs? Drop packet. */ 830 if_statinc(ifp, if_ierrors); 831 mb86950_drain_fifo(sc); 832 return; 833 } 834 } 835 } 836 837 /* 838 * Receive packet. 839 * Retrieve packet from receive buffer and send to the next level up via 840 * ether_input(). 841 * Returns 0 if success, -1 if error (i.e., mbuf allocation failure). 842 */ 843 int 844 mb86950_get_fifo(struct mb86950_softc *sc, u_int len) 845 { 846 bus_space_tag_t bst = sc->sc_bst; 847 bus_space_handle_t bsh = sc->sc_bsh; 848 struct ifnet *ifp = &sc->sc_ec.ec_if; 849 struct mbuf *m; 850 851 /* Allocate a header mbuf. */ 852 MGETHDR(m, M_DONTWAIT, MT_DATA); 853 if (m == 0) 854 return -1; 855 856 /* Round len to even value. */ 857 if (len & 1) 858 len++; 859 860 m_set_rcvif(m, ifp); 861 m->m_pkthdr.len = len; 862 863 /* The following silliness is to make NFS happy. */ 864 #define EROUND ((sizeof(struct ether_header) + 3) & ~3) 865 #define EOFF (EROUND - sizeof(struct ether_header)) 866 867 /* 868 * Our strategy has one more problem. There is a policy on 869 * mbuf cluster allocation. It says that we must have at 870 * least MINCLSIZE (208 bytes) to allocate a cluster. For a 871 * packet of a size between (MHLEN - 2) to (MINCLSIZE - 2), 872 * our code violates the rule... 873 * On the other hand, the current code is short, simple, 874 * and fast, however. It does no harmful thing, just wastes 875 * some memory. Any comments? FIXME. 876 */ 877 878 /* Attach a cluster if this packet doesn't fit in a normal mbuf. */ 879 if (len > MHLEN - EOFF) { 880 MCLGET(m, M_DONTWAIT); 881 if ((m->m_flags & M_EXT) == 0) { 882 m_freem(m); 883 return -1; 884 } 885 } 886 887 /* 888 * The following assumes there is room for the ether header in the 889 * header mbuf. 890 */ 891 m->m_data += EOFF; 892 893 /* Set the length of this packet. */ 894 m->m_len = len; 895 896 /* Get a packet. */ 897 bus_space_read_multi_stream_2(bst, bsh, BMPR_FIFO, 898 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 /* Unhook the entropy source. */ 969 rnd_detach_source(&sc->rnd_source); 970 971 ether_ifdetach(ifp); 972 if_detach(ifp); 973 974 /* Delete all media. */ 975 ifmedia_fini(&sc->sc_media); 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