if_ep.c revision 12724
1/* 2 * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Herb Peyerl. 16 * 4. The name of Herb Peyerl may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * if_ep.c,v 1.19 1995/01/24 20:53:45 davidg Exp 31 */ 32 33/* 34 * Modified from the FreeBSD 1.1.5.1 version by: 35 * Andres Vega Garcia 36 * INRIA - Sophia Antipolis, France 37 * avega@sophia.inria.fr 38 */ 39 40/* 41 * $Id: if_ep.c,v 1.35 1995/12/05 02:00:52 davidg Exp $ 42 * 43 * Promiscuous mode added and interrupt logic slightly changed 44 * to reduce the number of adapter failures. Transceiver select 45 * logic changed to use value from EEPROM. Autoconfiguration 46 * features added. 47 * Done by: 48 * Serge Babkin 49 * Chelindbank (Chelyabinsk, Russia) 50 * babkin@hq.icb.chel.su 51 */ 52 53#include "ep.h" 54#if NEP > 0 55 56#include "bpfilter.h" 57 58#include <sys/param.h> 59#if defined(__FreeBSD__) 60#include <sys/systm.h> 61#include <sys/kernel.h> 62#include <sys/devconf.h> 63#endif 64#include <sys/mbuf.h> 65#include <sys/socket.h> 66#include <sys/ioctl.h> 67#include <sys/errno.h> 68#include <sys/syslog.h> 69#if defined(__NetBSD__) 70#include <sys/select.h> 71#endif 72 73#include <net/if.h> 74#include <net/if_dl.h> 75#include <net/if_types.h> 76 77#ifdef INET 78#include <netinet/in.h> 79#include <netinet/in_systm.h> 80#include <netinet/in_var.h> 81#include <netinet/ip.h> 82#include <netinet/if_ether.h> 83#endif 84 85#ifdef IPX 86#include <netipx/ipx.h> 87#include <netipx/ipx_if.h> 88#endif 89 90#ifdef NS 91#include <netns/ns.h> 92#include <netns/ns_if.h> 93#endif 94 95#if NBPFILTER > 0 96#include <net/bpf.h> 97#include <net/bpfdesc.h> 98#endif 99 100#if defined(__FreeBSD__) 101#include <machine/clock.h> 102#endif 103 104#include <i386/isa/isa.h> 105#include <i386/isa/isa_device.h> 106#include <i386/isa/icu.h> 107#include <i386/isa/if_epreg.h> 108 109static int epprobe __P((struct isa_device *)); 110static int epattach __P((struct isa_device *)); 111static int epioctl __P((struct ifnet * ifp, int, caddr_t)); 112static void epmbuffill __P((caddr_t, int)); 113static void epmbufempty __P((struct ep_softc *)); 114 115static void epinit __P((int)); 116static void epread __P((struct ep_softc *)); 117void epreset __P((int)); 118static void epstart __P((struct ifnet *)); 119static void epstop __P((int)); 120static void epwatchdog __P((struct ifnet *)); 121 122static int send_ID_sequence __P((int)); 123static int get_eeprom_data __P((int, int)); 124 125static struct ep_softc ep_softc[NEP]; 126 127#define ep_ftst(f) (sc->stat&(f)) 128#define ep_fset(f) (sc->stat|=(f)) 129#define ep_frst(f) (sc->stat&=~(f)) 130 131struct isa_driver epdriver = { 132 epprobe, 133 epattach, 134 "ep", 135 0 136}; 137 138static struct kern_devconf kdc_ep[NEP] = { { 139 0, 0, 0, /* filled in by dev_attach */ 140 "ep", 0, { MDDT_ISA, 0, "net" }, 141 isa_generic_externalize, 0, 0, ISA_EXTERNALLEN, 142 &kdc_isa0, /* parent */ 143 0, /* parentdata */ 144 DC_UNCONFIGURED, /* state */ 145 "3Com 3C509 Ethernet adapter", 146 DC_CLS_NETIF /* class */ 147} }; 148 149static inline void 150ep_registerdev(struct isa_device *id) 151{ 152 if(id->id_unit) 153 kdc_ep[id->id_unit] = kdc_ep[0]; 154 kdc_ep[id->id_unit].kdc_unit = id->id_unit; 155 kdc_ep[id->id_unit].kdc_parentdata = id; 156 dev_attach(&kdc_ep[id->id_unit]); 157} 158 159static int ep_current_tag = EP_LAST_TAG + 1; 160 161static struct { 162 int epb_addr; /* address of this board */ 163 char epb_used; /* was this entry already used for configuring ? */ 164 } 165 ep_board[EP_MAX_BOARDS + 1]; 166 167static int 168eeprom_rdy(is) 169 struct isa_device *is; 170{ 171 int i; 172 173 for (i = 0; is_eeprom_busy(IS_BASE) && i < MAX_EEPROMBUSY; i++); 174 if (i >= MAX_EEPROMBUSY) { 175 printf("ep%d: eeprom failed to come ready.\n", is->id_unit); 176 return (0); 177 } 178 return (1); 179} 180 181static int 182ep_look_for_board_at(is) 183 struct isa_device *is; 184{ 185 int data, i, j, io_base, id_port = EP_ID_PORT; 186 int nisa = 0, neisa = 0; 187 188 if (ep_current_tag == (EP_LAST_TAG + 1)) { 189 /* Come here just one time */ 190 191 /* Look for the EISA boards, leave them activated */ 192 for(j = 1; j < 16; j++) { 193 io_base = (j * EP_EISA_START) | EP_EISA_W0; 194 if (inw(io_base + EP_W0_MFG_ID) != MFG_ID) 195 continue; 196 197 /* we must found 0x1f if the board is EISA configurated */ 198 if ((inw(io_base + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f) 199 continue; 200 201 /* Reset and Enable the card */ 202 outb(io_base + EP_W0_CONFIG_CTRL, W0_P4_CMD_RESET_ADAPTER); 203 DELAY(1000); /* we must wait at least 1 ms */ 204 outb(io_base + EP_W0_CONFIG_CTRL, W0_P4_CMD_ENABLE_ADAPTER); 205 206 /* 207 * Once activated, all the registers are mapped in the range 208 * x000 - x00F, where x is the slot number. 209 */ 210 ep_board[neisa].epb_used = 0; 211 ep_board[neisa++].epb_addr = j * EP_EISA_START; 212 } 213 ep_current_tag--; 214 215 /* Look for the ISA boards. Init and leave them actived */ 216 outb(id_port, 0xc0); /* Global reset */ 217 DELAY(10000); 218 for (i = 0; i < EP_MAX_BOARDS; i++) { 219 outb(id_port, 0); 220 outb(id_port, 0); 221 send_ID_sequence(id_port); 222 223 data = get_eeprom_data(id_port, EEPROM_MFG_ID); 224 if (data != MFG_ID) 225 break; 226 227 /* resolve contention using the Ethernet address */ 228 for (j = 0; j < 3; j++) 229 data = get_eeprom_data(id_port, j); 230 231 ep_board[neisa+nisa].epb_used = 0; 232 ep_board[neisa+nisa++].epb_addr = 233 (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200; 234 outb(id_port, ep_current_tag); /* tags board */ 235 outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG); 236 ep_current_tag--; 237 } 238 239 ep_board[neisa+nisa].epb_addr = 0; 240 if (neisa) { 241 printf("%d 3C5x9 board(s) on EISA found at", neisa); 242 for (j = 0; ep_board[j].epb_addr; j++) 243 if (ep_board[j].epb_addr >= EP_EISA_START) 244 printf(" 0x%x", ep_board[j].epb_addr); 245 printf("\n"); 246 } 247 if (nisa) { 248 printf("%d 3C5x9 board(s) on ISA found at", nisa); 249 for (j = 0; ep_board[j].epb_addr; j++) 250 if (ep_board[j].epb_addr < EP_EISA_START) 251 printf(" 0x%x", ep_board[j].epb_addr); 252 printf("\n"); 253 } 254 } 255 256 /* we have two cases: 257 * 258 * 1. Device was configured with 'port ?' 259 * In this case we search for the first unused card in list 260 * 261 * 2. Device was configured with 'port xxx' 262 * In this case we search for the unused card with that address 263 * 264 */ 265 266 if(IS_BASE==-1) { /* port? */ 267 for (i = 0; ep_board[i].epb_addr && ep_board[i].epb_used; i++); 268 if(ep_board[i].epb_addr==0) 269 return 0; 270 271 IS_BASE=ep_board[i].epb_addr; 272 ep_board[i].epb_used=1; 273 return 1; 274 } else { 275 for (i=0; ep_board[i].epb_addr && ep_board[i].epb_addr != IS_BASE; i++); 276 277 if( ep_board[i].epb_used || ep_board[i].epb_addr != IS_BASE) 278 return 0; 279 280 if (inw(IS_BASE + EP_W0_EEPROM_COMMAND) & EEPROM_TST_MODE) 281 printf("ep%d: 3c5x9 at 0x%x in test mode. Erase pencil mark!\n", 282 is->id_unit, IS_BASE); 283 ep_board[i].epb_used=1; 284 return 1; 285 } 286} 287 288/* 289 * get_e: gets a 16 bits word from the EEPROM. we must have set the window 290 * before 291 */ 292static int 293get_e(is, offset) 294 struct isa_device *is; 295 int offset; 296{ 297 if (!eeprom_rdy(is)) 298 return (0xffff); 299 outw(IS_BASE + EP_W0_EEPROM_COMMAND, EEPROM_CMD_RD | offset); 300 if (!eeprom_rdy(is)) 301 return (0xffff); 302 return (inw(IS_BASE + EP_W0_EEPROM_DATA)); 303} 304 305int 306epprobe(is) 307 struct isa_device *is; 308{ 309 struct ep_softc *sc = &ep_softc[is->id_unit]; 310 u_short k; 311 312 ep_registerdev(is); 313 314 if (!ep_look_for_board_at(is)) 315 return (0); 316 /* 317 * The iobase was found and MFG_ID was 0x6d50. PROD_ID should be 318 * 0x9[0-f]50 319 */ 320 GO_WINDOW(0); 321 k = get_e(is, EEPROM_PROD_ID); 322 if ((k & 0xf0ff) != (PROD_ID & 0xf0ff)) { 323 printf("epprobe: ignoring model %04x\n", k); 324 return (0); 325 } 326 327 k = get_e(is, EEPROM_RESOURCE_CFG); 328 k >>= 12; 329 330 /* Now we have two cases again: 331 * 332 * 1. Device was configured with 'irq?' 333 * In this case we use irq read from the board 334 * 335 * 2. Device was configured with 'irq xxx' 336 * In this case we set up the board to use specified interrupt 337 * 338 */ 339 340 if(is->id_irq==0) { /* irq? */ 341 is->id_irq= 1 << ( (k==2) ? 9 : k ); 342 } 343 344 if (BASE >= EP_EISA_START) /* we have an EISA board, we allow 32 bits access */ 345 sc->stat = F_ACCESS_32_BITS; 346 else 347 sc->stat = 0; 348 349 /* By now, the adapter is already activated */ 350 351 return (0x10); /* 16 bytes of I/O space used. */ 352} 353 354static char *ep_conn_type[] = {"UTP", "AUI", "???", "BNC"}; 355 356static int 357epattach(is) 358 struct isa_device *is; 359{ 360 struct ep_softc *sc = &ep_softc[is->id_unit]; 361 struct ifnet *ifp = &sc->arpcom.ac_if; 362 u_short i, j, *p; 363 struct ifaddr *ifa; 364 struct sockaddr_dl *sdl; 365 int irq; 366 367 /* BASE = IS_BASE; */ 368 sc->ep_io_addr = is->id_iobase; 369 370 printf("ep%d: ", is->id_unit); 371 372 sc->ep_connectors = 0; 373 i = inw(IS_BASE + EP_W0_CONFIG_CTRL); 374 j = inw(IS_BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS; 375 if (i & IS_AUI) { 376 printf("aui"); 377 sc->ep_connectors |= AUI; 378 } 379 if (i & IS_BNC) { 380 if (sc->ep_connectors) 381 printf("/"); 382 printf("bnc"); 383 sc->ep_connectors |= BNC; 384 } 385 if (i & IS_UTP) { 386 if (sc->ep_connectors) 387 printf("/"); 388 printf("utp"); 389 sc->ep_connectors |= UTP; 390 } 391 if (!(sc->ep_connectors & 7)) 392 printf("no connectors!"); 393 else 394 printf("[*%s*]", ep_conn_type[j]); 395 396 /* 397 * Read the station address from the eeprom 398 */ 399 p = (u_short *) & sc->arpcom.ac_enaddr; 400 for (i = 0; i < 3; i++) { 401 GO_WINDOW(0); 402 p[i] = htons(get_e(is, i)); 403 GO_WINDOW(2); 404 outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i])); 405 } 406 printf(" address %s", ether_sprintf(sc->arpcom.ac_enaddr)); 407 408 /* 409 * Write IRQ value to board 410 */ 411 412 i=is->id_irq; 413 if(i==0) { 414 printf(" irq STRANGE\n"); 415 return 0; 416 } 417 418 for(irq=0; !(i & 1) && irq<16 ; i>>=1, irq++); 419 420 if(irq==9) 421 irq=2; 422 printf(" irq %d\n",irq); 423 GO_WINDOW(0); 424 outw(BASE + EP_W0_RESOURCE_CFG, SET_IRQ(irq)); 425 426 ifp->if_unit = is->id_unit; 427 ifp->if_name = "ep"; 428 ifp->if_mtu = ETHERMTU; 429 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; 430 ifp->if_output = ether_output; 431 ifp->if_start = epstart; 432 ifp->if_ioctl = epioctl; 433 ifp->if_watchdog = epwatchdog; 434 435 if_attach(ifp); 436 kdc_ep[is->id_unit].kdc_state = DC_BUSY; 437 438 /* 439 * Fill the hardware address into ifa_addr if we find an AF_LINK entry. 440 * We need to do this so bpf's can get the hardware addr of this card. 441 * netstat likes this too! 442 */ 443 ifa = ifp->if_addrlist; 444 while ((ifa != 0) && (ifa->ifa_addr != 0) && 445 (ifa->ifa_addr->sa_family != AF_LINK)) 446 ifa = ifa->ifa_next; 447 448 if ((ifa != 0) && (ifa->ifa_addr != 0)) { 449 sdl = (struct sockaddr_dl *) ifa->ifa_addr; 450 sdl->sdl_type = IFT_ETHER; 451 sdl->sdl_alen = ETHER_ADDR_LEN; 452 sdl->sdl_slen = 0; 453 bcopy(sc->arpcom.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN); 454 } 455 /* we give some initial parameters */ 456 sc->rx_avg_pkt = 128; 457 458 /* 459 * NOTE: In all this I multiply everything by 64. 460 * W_s = the speed the CPU is able to write to the TX FIFO. 461 * T_s = the speed the board sends the info to the Ether. 462 * W_s/T_s = 16 (represents 16/64) => W_s = 25 % of T_s. 463 * This will give us for a packet of 1500 bytes 464 * tx_start_thresh=1125 and for a pkt of 64 bytes tx_start_threshold=48. 465 * We prefer to start thinking the CPU is much slower than the Ethernet 466 * transmission. 467 */ 468 sc->tx_rate = TX_INIT_RATE; 469 sc->tx_counter = 0; 470 sc->rx_latency = RX_INIT_LATENCY; 471 sc->rx_early_thresh = RX_INIT_EARLY_THRESH; 472#ifdef EP_LOCAL_STATS 473 sc->rx_no_first = sc->rx_no_mbuf = 474 sc->rx_bpf_disc = sc->rx_overrunf = sc->rx_overrunl = 475 sc->tx_underrun = 0; 476#endif 477 ep_fset(F_RX_FIRST); 478 sc->top = sc->mcur = 0; 479 480#if NBPFILTER > 0 481 bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 482#endif 483 return 1; 484} 485 486 487/* 488 * The order in here seems important. Otherwise we may not receive 489 * interrupts. ?! 490 */ 491static void 492epinit(unit) 493 int unit; 494{ 495 register struct ep_softc *sc = &ep_softc[unit]; 496 register struct ifnet *ifp = &sc->arpcom.ac_if; 497 int s, i, j; 498 499 /* 500 if (ifp->if_addrlist == (struct ifaddr *) 0) 501 return; 502 */ 503 504 s = splimp(); 505 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); 506 507 GO_WINDOW(0); 508 outw(BASE + EP_COMMAND, STOP_TRANSCEIVER); 509 GO_WINDOW(4); 510 outw(BASE + EP_W4_MEDIA_TYPE, DISABLE_UTP); 511 GO_WINDOW(0); 512 513 /* Disable the card */ 514 outw(BASE + EP_W0_CONFIG_CTRL, 0); 515 516 /* Enable the card */ 517 outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ); 518 519 GO_WINDOW(2); 520 521 /* Reload the ether_addr. */ 522 for (i = 0; i < 6; i++) 523 outb(BASE + EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]); 524 525 outw(BASE + EP_COMMAND, RX_RESET); 526 outw(BASE + EP_COMMAND, TX_RESET); 527 528 /* Window 1 is operating window */ 529 GO_WINDOW(1); 530 for (i = 0; i < 31; i++) 531 inb(BASE + EP_W1_TX_STATUS); 532 533 /* get rid of stray intr's */ 534 outw(BASE + EP_COMMAND, ACK_INTR | 0xff); 535 536 outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_5_INTS); 537 538 outw(BASE + EP_COMMAND, SET_INTR_MASK | S_5_INTS); 539 540 if(ifp->if_flags & IFF_PROMISC) 541 outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL | 542 FIL_GROUP | FIL_BRDCST | FIL_ALL); 543 else 544 outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL | 545 FIL_GROUP | FIL_BRDCST); 546 547 /* 548 * S.B. 549 * 550 * Now behavior was slightly changed: 551 * 552 * if any of flags link[0-2] is used and its connector is 553 * physically present the following connectors are used: 554 * 555 * link0 - AUI * highest precedence 556 * link1 - BNC 557 * link2 - UTP * lowest precedence 558 * 559 * If none of them is specified then 560 * connector specified in the EEPROM is used 561 * (if present on card or AUI if not). 562 * 563 */ 564 565 if(ifp->if_flags & IFF_LINK0 && sc->ep_connectors & AUI) { 566 /* nothing */ 567 } else if(ifp->if_flags & IFF_LINK1 && sc->ep_connectors & BNC) { 568 outw(BASE + EP_COMMAND, START_TRANSCEIVER); 569 DELAY(1000); 570 } else if(ifp->if_flags & IFF_LINK2 && sc->ep_connectors & UTP) { 571 GO_WINDOW(4); 572 outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP); 573 GO_WINDOW(1); 574 } else { 575 GO_WINDOW(0); 576 j = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS; 577 GO_WINDOW(1); 578 switch(j) { 579 case ACF_CONNECTOR_UTP: 580 if(sc->ep_connectors & UTP) { 581 GO_WINDOW(4); 582 outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP); 583 GO_WINDOW(1); 584 } 585 break; 586 case ACF_CONNECTOR_BNC: 587 if(sc->ep_connectors & BNC) { 588 outw(BASE + EP_COMMAND, START_TRANSCEIVER); 589 DELAY(1000); 590 } 591 break; 592 case ACF_CONNECTOR_AUI: 593 /* nothing to do */ 594 break; 595 default: 596 printf("ep%d: strange connector type in EEPROM: assuming AUI\n", 597 unit); 598 break; 599 } 600 } 601 602 outw(BASE + EP_COMMAND, RX_ENABLE); 603 outw(BASE + EP_COMMAND, TX_ENABLE); 604 605 ifp->if_flags |= IFF_RUNNING; 606 ifp->if_flags &= ~IFF_OACTIVE; /* just in case */ 607 608 sc->tx_rate = TX_INIT_RATE; 609 sc->tx_counter = 0; 610 sc->rx_latency = RX_INIT_LATENCY; 611 sc->rx_early_thresh = RX_INIT_EARLY_THRESH; 612#ifdef EP_LOCAL_STATS 613 sc->rx_no_first = sc->rx_no_mbuf = 614 sc->rx_bpf_disc = sc->rx_overrunf = sc->rx_overrunl = 615 sc->tx_underrun = 0; 616#endif 617 ep_fset(F_RX_FIRST); 618 ep_frst(F_RX_TRAILER); 619 if (sc->top) { 620 m_freem(sc->top); 621 sc->top = sc->mcur = 0; 622 } 623 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | sc->rx_early_thresh); 624 625 /* 626 * These clever computations look very interesting 627 * but the fixed threshold gives near no output errors 628 * and if it as low as 16 bytes it gives the max. throughput. 629 * We think that processor is anyway quicker than Ethernet 630 * (and this should be true for any 386 and higher) 631 */ 632 633 outw(BASE + EP_COMMAND, SET_TX_START_THRESH | 16); 634 635 /* 636 * Store up a bunch of mbuf's for use later. (MAX_MBS). First we free up 637 * any that we had in case we're being called from intr or somewhere 638 * else. 639 */ 640 sc->last_mb = 0; 641 sc->next_mb = 0; 642 epmbuffill((caddr_t) sc, 0); 643 644 epstart(ifp); 645 646 splx(s); 647} 648 649static const char padmap[] = {0, 3, 2, 1}; 650 651static void 652epstart(ifp) 653 struct ifnet *ifp; 654{ 655 register struct ep_softc *sc = &ep_softc[ifp->if_unit]; 656 register u_int len; 657 register struct mbuf *m; 658 struct mbuf *top; 659 int s, pad; 660 661 s = splimp(); 662 if (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) { 663 splx(s); 664 return; 665 } 666startagain: 667 /* Sneak a peek at the next packet */ 668 m = sc->arpcom.ac_if.if_snd.ifq_head; 669 if (m == 0) { 670 splx(s); 671 return; 672 } 673#if 0 674 len = m->m_pkthdr.len; 675#else 676 for (len = 0, top = m; m; m = m->m_next) 677 len += m->m_len; 678#endif 679 680 pad = padmap[len & 3]; 681 682 /* 683 * The 3c509 automatically pads short packets to minimum ethernet length, 684 * but we drop packets that are too large. Perhaps we should truncate 685 * them instead? 686 */ 687 if (len + pad > ETHER_MAX_LEN) { 688 /* packet is obviously too large: toss it */ 689 ++sc->arpcom.ac_if.if_oerrors; 690 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); 691 m_freem(m); 692 goto readcheck; 693 } 694 if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) { 695 /* no room in FIFO */ 696 outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4)); 697 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE; 698 splx(s); 699 return; 700 } 701 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); 702 703 outw(BASE + EP_W1_TX_PIO_WR_1, len); 704 outw(BASE + EP_W1_TX_PIO_WR_1, 0x0); /* Second dword meaningless */ 705 706 /* compute the Tx start threshold for this packet */ 707 sc->tx_start_thresh = len = 708 (((len * (64 - sc->tx_rate)) >> 6) & ~3) + 16; 709#if 0 710 /* 711 * The following string does something strange with the card and 712 * we get a lot of output errors due to it so it's commented out 713 * and we use fixed threshold (see above) 714 */ 715 716 outw(BASE + EP_COMMAND, SET_TX_START_THRESH | len); 717#endif 718 719 for (top = m; m != 0; m = m->m_next) 720 if(ep_ftst(F_ACCESS_32_BITS)) { 721 outsl(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t), 722 m->m_len / 4); 723 if (m->m_len & 3) 724 outsb(BASE + EP_W1_TX_PIO_WR_1, 725 mtod(m, caddr_t) + m->m_len / 4, 726 m->m_len & 3); 727 } else { 728 outsw(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t), m->m_len / 2); 729 if (m->m_len & 1) 730 outb(BASE + EP_W1_TX_PIO_WR_1, 731 *(mtod(m, caddr_t) + m->m_len - 1)); 732 } 733 734 while (pad--) 735 outb(BASE + EP_W1_TX_PIO_WR_1, 0); /* Padding */ 736 737#if NBPFILTER > 0 738 if (sc->bpf) { 739 bpf_mtap(sc->bpf, top); 740 } 741#endif 742 743 sc->arpcom.ac_if.if_opackets++; 744 m_freem(top); 745 /* 746 * Every 1024*4 packets we increment the tx_rate if we haven't had 747 * errors, that in the case it has abnormaly goten too low 748 */ 749 if (!(++sc->tx_counter & (1024 * 4 - 1)) && 750 sc->tx_rate < TX_INIT_MAX_RATE) 751 sc->tx_rate++; 752 753 /* 754 * Is another packet coming in? We don't want to overflow the tiny RX 755 * fifo. 756 */ 757readcheck: 758 if (inw(BASE + EP_W1_RX_STATUS) & RX_BYTES_MASK) { 759 /* 760 * we check if we have packets left, in that case we prepare to come 761 * back later 762 */ 763 if (sc->arpcom.ac_if.if_snd.ifq_head) { 764 outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | 765 sc->tx_start_thresh); 766 } 767 splx(s); 768 return; 769 } 770 goto startagain; 771} 772 773void 774epintr(unit) 775 int unit; 776{ 777 register int status; 778 register struct ep_softc *sc = &ep_softc[unit]; 779 int x; 780 781 x=splbio(); 782 783 outw(BASE + EP_COMMAND, SET_INTR_MASK); /* disable all Ints */ 784 785rescan: 786 787 while ((status = inw(BASE + EP_STATUS)) & S_5_INTS) { 788 789 /* first acknowledge all interrupt sources */ 790 outw(BASE + EP_COMMAND, ACK_INTR | (status & S_MASK)); 791 792 if (status & (S_RX_COMPLETE | S_RX_EARLY)) { 793 epread(sc); 794 continue; 795 } 796 if (status & S_TX_AVAIL) { 797 /* we need ACK */ 798 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 799 GO_WINDOW(1); 800 inw(BASE + EP_W1_FREE_TX); 801 epstart(&sc->arpcom.ac_if); 802 } 803 if (status & S_CARD_FAILURE) { 804#ifdef EP_LOCAL_STATS 805 printf("\nep%d:\n\tStatus: %x\n", unit, status); 806 GO_WINDOW(4); 807 printf("\tFIFO Diagnostic: %x\n", inw(BASE + EP_W4_FIFO_DIAG)); 808 printf("\tStat: %x\n", sc->stat); 809 printf("\tIpackets=%d, Opackets=%d\n", 810 sc->arpcom.ac_if.if_ipackets, sc->arpcom.ac_if.if_opackets); 811 printf("\tNOF=%d, NOMB=%d, BPFD=%d, RXOF=%d, RXOL=%d, TXU=%d\n", 812 sc->rx_no_first, sc->rx_no_mbuf, sc->rx_bpf_disc, sc->rx_overrunf, 813 sc->rx_overrunl, sc->tx_underrun); 814#else 815 printf("ep%d: Status: %x\n", unit, status); 816#endif 817 epinit(unit); 818 splx(x); 819 return; 820 } 821 if (status & S_TX_COMPLETE) { 822 /* we need ACK. we do it at the end */ 823 /* 824 * We need to read TX_STATUS until we get a 0 status in order to 825 * turn off the interrupt flag. 826 */ 827 while ((status = inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE) { 828 if (status & TXS_SUCCES_INTR_REQ); 829 else if (status & (TXS_UNDERRUN | TXS_JABBER | TXS_MAX_COLLISION)) { 830 outw(BASE + EP_COMMAND, TX_RESET); 831 if (status & TXS_UNDERRUN) { 832 if (sc->tx_rate > 1) { 833 sc->tx_rate--; /* Actually in steps of 1/64 */ 834 sc->tx_counter = 0; /* We reset it */ 835 } 836#ifdef EP_LOCAL_STATS 837 sc->tx_underrun++; 838#endif 839 } else { 840 if (status & TXS_JABBER); 841 else /* TXS_MAX_COLLISION - we shouldn't get here */ 842 ++sc->arpcom.ac_if.if_collisions; 843 } 844 ++sc->arpcom.ac_if.if_oerrors; 845 outw(BASE + EP_COMMAND, TX_ENABLE); 846 /* 847 * To have a tx_avail_int but giving the chance to the 848 * Reception 849 */ 850 if (sc->arpcom.ac_if.if_snd.ifq_head) { 851 outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | 8); 852 } 853 } 854 outb(BASE + EP_W1_TX_STATUS, 0x0); /* pops up the next 855 * status */ 856 } /* while */ 857 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 858 GO_WINDOW(1); 859 inw(BASE + EP_W1_FREE_TX); 860 epstart(&sc->arpcom.ac_if); 861 } /* end TX_COMPLETE */ 862 } 863 864 outw(BASE + EP_COMMAND, C_INTR_LATCH); /* ACK int Latch */ 865 866 if ((status = inw(BASE + EP_STATUS)) & S_5_INTS) 867 goto rescan; 868 869 /* re-enable Ints */ 870 outw(BASE + EP_COMMAND, SET_INTR_MASK | S_5_INTS); 871 872 splx(x); 873} 874 875static void 876epread(sc) 877 register struct ep_softc *sc; 878{ 879 struct ether_header *eh; 880 struct mbuf *top, *mcur, *m; 881 int lenthisone; 882 883 short rx_fifo2, status; 884 register short delta; 885 register short rx_fifo; 886 887 status = inw(BASE + EP_W1_RX_STATUS); 888 889read_again: 890 891 if (status & ERR_RX) { 892 ++sc->arpcom.ac_if.if_ierrors; 893 if (status & ERR_RX_OVERRUN) { 894 /* 895 * we can think the rx latency is actually greather than we 896 * expect 897 */ 898#ifdef EP_LOCAL_STATS 899 if (ep_ftst(F_RX_FIRST)) 900 sc->rx_overrunf++; 901 else 902 sc->rx_overrunl++; 903#endif 904 if (sc->rx_latency < ETHERMTU) 905 sc->rx_latency += 16; 906 } 907 goto out; 908 } 909 rx_fifo = rx_fifo2 = status & RX_BYTES_MASK; 910 911 if (ep_ftst(F_RX_FIRST)) { 912 if (m = sc->mb[sc->next_mb]) { 913 sc->mb[sc->next_mb] = 0; 914 sc->next_mb = (sc->next_mb + 1) % MAX_MBS; 915 m->m_data = m->m_pktdat; 916 m->m_flags = M_PKTHDR; 917 } else { 918 MGETHDR(m, M_DONTWAIT, MT_DATA); 919 if (!m) 920 goto out; 921 } 922 sc->top = sc->mcur = top = m; 923#define EROUND ((sizeof(struct ether_header) + 3) & ~3) 924#define EOFF (EROUND - sizeof(struct ether_header)) 925 top->m_data += EOFF; 926 927 /* Read what should be the header. */ 928 insw(BASE + EP_W1_RX_PIO_RD_1, 929 mtod(top, caddr_t), sizeof(struct ether_header) / 2); 930 top->m_len = sizeof(struct ether_header); 931 rx_fifo -= sizeof(struct ether_header); 932 sc->cur_len = rx_fifo2; 933 } else { 934 /* come here if we didn't have a complete packet last time */ 935 top = sc->top; 936 m = sc->mcur; 937 sc->cur_len += rx_fifo2; 938 if (ep_ftst(F_RX_TRAILER)) 939 /* We don't read the trailer */ 940 rx_fifo -= sizeof(struct ether_header); 941 } 942 943 /* Reads what is left in the RX FIFO */ 944 while (rx_fifo > 0) { 945 lenthisone = min(rx_fifo, M_TRAILINGSPACE(m)); 946 if (lenthisone == 0) { /* no room in this one */ 947 mcur = m; 948 if (m = sc->mb[sc->next_mb]) { 949 sc->mb[sc->next_mb] = 0; 950 sc->next_mb = (sc->next_mb + 1) % MAX_MBS; 951 } else { 952 MGET(m, M_DONTWAIT, MT_DATA); 953 if (!m) 954 goto out; 955 } 956 957 if (rx_fifo >= MINCLSIZE) 958 MCLGET(m, M_DONTWAIT); 959 m->m_len = 0; 960 mcur->m_next = m; 961 lenthisone = min(rx_fifo, M_TRAILINGSPACE(m)); 962 } 963 if (ep_ftst(F_ACCESS_32_BITS)) { /* default for EISA configured cards*/ 964 insl(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len, 965 lenthisone / 4); 966 m->m_len += (lenthisone & ~3); 967 if (lenthisone & 3) 968 insb(BASE + EP_W1_RX_PIO_RD_1, 969 mtod(m, caddr_t) + m->m_len, 970 lenthisone & 3); 971 m->m_len += (lenthisone & 3); 972 } else { 973 insw(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len, 974 lenthisone / 2); 975 m->m_len += lenthisone; 976 if (lenthisone & 1) 977 *(mtod(m, caddr_t) + m->m_len - 1) = inb(BASE + EP_W1_RX_PIO_RD_1); 978 } 979 rx_fifo -= lenthisone; 980 } 981 982 if (ep_ftst(F_RX_TRAILER)) {/* reads the trailer */ 983 if (m = sc->mb[sc->next_mb]) { 984 sc->mb[sc->next_mb] = 0; 985 sc->next_mb = (sc->next_mb + 1) % MAX_MBS; 986 m->m_data = m->m_pktdat; 987 m->m_flags = M_PKTHDR; 988 } else { 989 MGETHDR(m, M_DONTWAIT, MT_DATA); 990 if (!m) 991 goto out; 992 } 993 insw(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t), 994 sizeof(struct ether_header)); 995 m->m_len = sizeof(struct ether_header); 996 m->m_next = top; 997 sc->top = top = m; 998 /* XXX Accomodate for type and len from beginning of trailer */ 999 sc->cur_len -= (2 * sizeof(u_short)); 1000 ep_frst(F_RX_TRAILER); 1001 goto all_pkt; 1002 } 1003 1004 if (status & ERR_RX_INCOMPLETE) { /* we haven't received the complete 1005 * packet */ 1006 sc->mcur = m; 1007#ifdef EP_LOCAL_STATS 1008 sc->rx_no_first++; /* to know how often we come here */ 1009#endif 1010 /* 1011 * Re-compute rx_latency, the factor used is 1/4 to go up and 1/32 to 1012 * go down 1013 */ 1014 delta = rx_fifo2 - sc->rx_early_thresh; /* last latency seen LLS */ 1015 delta -= sc->rx_latency;/* LLS - estimated_latency */ 1016 if (delta >= 0) 1017 sc->rx_latency += (delta / 4); 1018 else 1019 sc->rx_latency += (delta / 32); 1020 ep_frst(F_RX_FIRST); 1021 if (!((status = inw(BASE + EP_W1_RX_STATUS)) & ERR_RX_INCOMPLETE)) { 1022 /* we see if by now, the packet has completly arrived */ 1023 goto read_again; 1024 } 1025 /* compute rx_early_threshold */ 1026 delta = (sc->rx_avg_pkt - sc->cur_len - sc->rx_latency - 16) & ~3; 1027 if (delta < MIN_RX_EARLY_THRESHL) 1028 delta = MIN_RX_EARLY_THRESHL; 1029 1030 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | 1031 (sc->rx_early_thresh = delta)); 1032 return; 1033 } 1034all_pkt: 1035 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); 1036 /* 1037 * recompute average packet's length, the factor used is 1/8 to go down 1038 * and 1/32 to go up 1039 */ 1040 delta = sc->cur_len - sc->rx_avg_pkt; 1041 if (delta > 0) 1042 sc->rx_avg_pkt += (delta / 32); 1043 else 1044 sc->rx_avg_pkt += (delta / 8); 1045 delta = (sc->rx_avg_pkt - sc->rx_latency - 16) & ~3; 1046 if (delta < MIN_RX_EARLY_THRESHF) 1047 delta = MIN_RX_EARLY_THRESHF; 1048 sc->rx_early_thresh = delta; 1049 ++sc->arpcom.ac_if.if_ipackets; 1050 ep_fset(F_RX_FIRST); 1051 ep_frst(F_RX_TRAILER); 1052 top->m_pkthdr.rcvif = &sc->arpcom.ac_if; 1053 top->m_pkthdr.len = sc->cur_len; 1054 1055#if NBPFILTER > 0 1056 if (sc->bpf) { 1057 bpf_mtap(sc->bpf, top); 1058 1059 /* 1060 * Note that the interface cannot be in promiscuous mode if there are 1061 * no BPF listeners. And if we are in promiscuous mode, we have to 1062 * check if this packet is really ours. 1063 */ 1064 eh = mtod(top, struct ether_header *); 1065 if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) && 1066 (eh->ether_dhost[0] & 1) == 0 && 1067 bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, 1068 sizeof(eh->ether_dhost)) != 0 && 1069 bcmp(eh->ether_dhost, etherbroadcastaddr, 1070 sizeof(eh->ether_dhost)) != 0) { 1071 if (sc->top) { 1072 m_freem(sc->top); 1073 sc->top = 0; 1074 } 1075 ep_fset(F_RX_FIRST); 1076 ep_frst(F_RX_TRAILER); 1077#ifdef EP_LOCAL_STATS 1078 sc->rx_bpf_disc++; 1079#endif 1080 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); 1081 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | delta); 1082 return; 1083 } 1084 } 1085#endif 1086 1087 eh = mtod(top, struct ether_header *); 1088 m_adj(top, sizeof(struct ether_header)); 1089 ether_input(&sc->arpcom.ac_if, eh, top); 1090 if (!sc->mb[sc->next_mb]) 1091 epmbuffill((caddr_t) sc, 0); 1092 sc->top = 0; 1093 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); 1094 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | delta); 1095 return; 1096 1097out: 1098 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); 1099 if (sc->top) { 1100 m_freem(sc->top); 1101 sc->top = 0; 1102#ifdef EP_LOCAL_STATS 1103 sc->rx_no_mbuf++; 1104#endif 1105 } 1106 delta = (sc->rx_avg_pkt - sc->rx_latency - 16) & ~3; 1107 if (delta < MIN_RX_EARLY_THRESHF) 1108 delta = MIN_RX_EARLY_THRESHF; 1109 ep_fset(F_RX_FIRST); 1110 ep_frst(F_RX_TRAILER); 1111 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); 1112 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | 1113 (sc->rx_early_thresh = delta)); 1114} 1115 1116/* 1117 * Look familiar? 1118 */ 1119static int 1120epioctl(ifp, cmd, data) 1121 register struct ifnet *ifp; 1122 int cmd; 1123 caddr_t data; 1124{ 1125 register struct ifaddr *ifa = (struct ifaddr *) data; 1126 struct ep_softc *sc = &ep_softc[ifp->if_unit]; 1127 struct ifreq *ifr = (struct ifreq *) data; 1128 int s, error = 0; 1129 1130 s = splimp(); 1131 1132 switch (cmd) { 1133 case SIOCSIFADDR: 1134 ifp->if_flags |= IFF_UP; 1135 switch (ifa->ifa_addr->sa_family) { 1136#ifdef INET 1137 case AF_INET: 1138 epinit(ifp->if_unit); /* before arpwhohas */ 1139 arp_ifinit((struct arpcom *)ifp, ifa); 1140 break; 1141#endif 1142#ifdef IPX 1143 case AF_IPX: 1144 { 1145 register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); 1146 1147 if (ipx_nullhost(*ina)) 1148 ina->x_host = 1149 *(union ipx_host *) (sc->arpcom.ac_enaddr); 1150 else { 1151 ifp->if_flags &= ~IFF_RUNNING; 1152 bcopy((caddr_t) ina->x_host.c_host, 1153 (caddr_t) sc->arpcom.ac_enaddr, 1154 sizeof(sc->arpcom.ac_enaddr)); 1155 } 1156 epinit(ifp->if_unit); 1157 break; 1158 } 1159#endif 1160#ifdef NS 1161 case AF_NS: 1162 { 1163 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 1164 1165 if (ns_nullhost(*ina)) 1166 ina->x_host = 1167 *(union ns_host *) (sc->arpcom.ac_enaddr); 1168 else { 1169 ifp->if_flags &= ~IFF_RUNNING; 1170 bcopy((caddr_t) ina->x_host.c_host, 1171 (caddr_t) sc->arpcom.ac_enaddr, 1172 sizeof(sc->arpcom.ac_enaddr)); 1173 } 1174 epinit(ifp->if_unit); 1175 break; 1176 } 1177#endif 1178 default: 1179 epinit(ifp->if_unit); 1180 break; 1181 } 1182 break; 1183 case SIOCGIFADDR: 1184 { 1185 struct sockaddr *sa; 1186 1187 sa = (struct sockaddr *) & ifr->ifr_data; 1188 bcopy((caddr_t) sc->arpcom.ac_enaddr, 1189 (caddr_t) sa->sa_data, ETHER_ADDR_LEN); 1190 } 1191 break; 1192 case SIOCSIFFLAGS: 1193 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) { 1194 ifp->if_flags &= ~IFF_RUNNING; 1195 epstop(ifp->if_unit); 1196 epmbufempty(sc); 1197 break; 1198 } else { 1199 /* reinitialize card on any parameter change */ 1200 epinit(ifp->if_unit); 1201 break; 1202 } 1203 1204 /* NOTREACHED */ 1205 1206 if (ifp->if_flags & IFF_UP && (ifp->if_flags & IFF_RUNNING) == 0) 1207 epinit(ifp->if_unit); 1208 1209 if ( (ifp->if_flags & IFF_PROMISC) && !ep_ftst(F_PROMISC) ) { 1210 ep_fset(F_PROMISC); 1211 epinit(ifp->if_unit); 1212 } 1213 else if( !(ifp->if_flags & IFF_PROMISC) && ep_ftst(F_PROMISC) ) { 1214 ep_frst(F_PROMISC); 1215 epinit(ifp->if_unit); 1216 } 1217 1218 break; 1219#ifdef notdef 1220 case SIOCGHWADDR: 1221 bcopy((caddr_t) sc->sc_addr, (caddr_t) & ifr->ifr_data, 1222 sizeof(sc->sc_addr)); 1223 break; 1224#endif 1225 case SIOCSIFMTU: 1226 1227 /* 1228 * Set the interface MTU. 1229 */ 1230 if (ifr->ifr_mtu > ETHERMTU) { 1231 error = EINVAL; 1232 } else { 1233 ifp->if_mtu = ifr->ifr_mtu; 1234 } 1235 break; 1236 1237 default: 1238 error = EINVAL; 1239 } 1240 1241 splx(s); 1242 1243 return (error); 1244} 1245 1246static void 1247epwatchdog(ifp) 1248 struct ifnet *ifp; 1249{ 1250 /* 1251 printf("ep: watchdog\n"); 1252 1253 log(LOG_ERR, "ep%d: watchdog\n", ifp->if_unit); 1254 ifp->if_oerrors++; 1255 */ 1256 1257 ifp->if_flags &= ~IFF_OACTIVE; 1258 epstart(ifp); 1259 epintr(ifp->if_unit); 1260} 1261 1262static void 1263epstop(unit) 1264 int unit; 1265{ 1266 struct ep_softc *sc = &ep_softc[unit]; 1267 1268 outw(BASE + EP_COMMAND, RX_DISABLE); 1269 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); 1270 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); 1271 outw(BASE + EP_COMMAND, TX_DISABLE); 1272 outw(BASE + EP_COMMAND, STOP_TRANSCEIVER); 1273 outw(BASE + EP_COMMAND, RX_RESET); 1274 outw(BASE + EP_COMMAND, TX_RESET); 1275 outw(BASE + EP_COMMAND, C_INTR_LATCH); 1276 outw(BASE + EP_COMMAND, SET_RD_0_MASK); 1277 outw(BASE + EP_COMMAND, SET_INTR_MASK); 1278 outw(BASE + EP_COMMAND, SET_RX_FILTER); 1279} 1280 1281 1282static int 1283send_ID_sequence(port) 1284 int port; 1285{ 1286 int cx, al; 1287 1288 for (al = 0xff, cx = 0; cx < 255; cx++) { 1289 outb(port, al); 1290 al <<= 1; 1291 if (al & 0x100) 1292 al ^= 0xcf; 1293 } 1294 return (1); 1295} 1296 1297 1298/* 1299 * We get eeprom data from the id_port given an offset into the eeprom. 1300 * Basically; after the ID_sequence is sent to all of the cards; they enter 1301 * the ID_CMD state where they will accept command requests. 0x80-0xbf loads 1302 * the eeprom data. We then read the port 16 times and with every read; the 1303 * cards check for contention (ie: if one card writes a 0 bit and another 1304 * writes a 1 bit then the host sees a 0. At the end of the cycle; each card 1305 * compares the data on the bus; if there is a difference then that card goes 1306 * into ID_WAIT state again). In the meantime; one bit of data is returned in 1307 * the AX register which is conveniently returned to us by inb(). Hence; we 1308 * read 16 times getting one bit of data with each read. 1309 */ 1310static int 1311get_eeprom_data(id_port, offset) 1312 int id_port; 1313 int offset; 1314{ 1315 int i, data = 0; 1316 outb(id_port, 0x80 + offset); 1317 DELAY(1000); 1318 for (i = 0; i < 16; i++) 1319 data = (data << 1) | (inw(id_port) & 1); 1320 return (data); 1321} 1322 1323/* 1324 * We suppose this is always called inside a splimp(){...}splx() region 1325 */ 1326static void 1327epmbuffill(sp, dummy_arg) 1328 caddr_t sp; 1329 int dummy_arg; 1330{ 1331 struct ep_softc *sc = (struct ep_softc *) sp; 1332 int i; 1333 1334 i = sc->last_mb; 1335 do { 1336 if (sc->mb[i] == NULL) 1337 MGET(sc->mb[i], M_DONTWAIT, MT_DATA); 1338 if (sc->mb[i] == NULL) 1339 break; 1340 i = (i + 1) % MAX_MBS; 1341 } while (i != sc->next_mb); 1342 sc->last_mb = i; 1343} 1344 1345static void 1346epmbufempty(sc) 1347 struct ep_softc *sc; 1348{ 1349 int s, i; 1350 1351 s = splimp(); 1352 for (i = 0; i < MAX_MBS; i++) { 1353 if (sc->mb[i]) { 1354 m_freem(sc->mb[i]); 1355 sc->mb[i] = NULL; 1356 } 1357 } 1358 sc->last_mb = sc->next_mb = 0; 1359 splx(s); 1360} 1361 1362#endif /* NEP > 0 */ 1363