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