if_ex.c revision 55953
1/* 2 * Copyright (c) 1996, Javier Mart�n Rueda (jmrueda@diatel.upm.es) 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 unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: head/sys/dev/ex/if_ex.c 55953 2000-01-14 07:14:17Z peter $ 28 * 29 * MAINTAINER: Matthew N. Dodd <winter@jurai.net> 30 * <mdodd@FreeBSD.org> 31 */ 32 33/* 34 * Intel EtherExpress Pro/10, Pro/10+ Ethernet driver 35 * 36 * Revision history: 37 * 38 * 30-Oct-1996: first beta version. Inet and BPF supported, but no multicast. 39 */ 40 41#include "ex.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/kernel.h> 46#include <sys/conf.h> 47#include <sys/sockio.h> 48#include <sys/mbuf.h> 49#include <sys/socket.h> 50 51#include <sys/module.h> 52#include <sys/bus.h> 53 54#include <machine/bus.h> 55#include <machine/resource.h> 56#include <sys/rman.h> 57 58#include <net/ethernet.h> 59#include <net/if.h> 60 61#include <netinet/in.h> 62#include <netinet/if_ether.h> 63 64#include <net/bpf.h> 65 66#include <machine/clock.h> 67 68#include <isa/isavar.h> 69#include <isa/pnpvar.h> 70 71#include <dev/ex/if_exreg.h> 72 73#ifdef EXDEBUG 74# define Start_End 1 75# define Rcvd_Pkts 2 76# define Sent_Pkts 4 77# define Status 8 78static int debug_mask = 0; 79static int exintr_count = 0; 80# define DODEBUG(level, action) if (level & debug_mask) action 81#else 82# define DODEBUG(level, action) 83#endif 84 85#define Conn_BNC 1 86#define Conn_TPE 2 87#define Conn_AUI 3 88 89#define CARD_TYPE_EX_10 1 90#define CARD_TYPE_EX_10_PLUS 2 91 92struct ex_softc { 93 struct arpcom arpcom; /* Ethernet common data */ 94 95 device_t dev; 96 struct resource *ioport; 97 struct resource *irq; 98 99 u_int iobase; /* I/O base address. */ 100 u_short irq_no; /* IRQ number. */ 101 102 char * irq2ee; /* irq <-> internal */ 103 u_char * ee2irq; /* representation conversion */ 104 105 u_short connector; /* Connector type. */ 106 107 u_int mem_size; /* Total memory size, in bytes. */ 108 u_int rx_mem_size; /* Rx memory size (by default, */ 109 /* first 3/4 of total memory). */ 110 111 u_int rx_lower_limit; /* Lower and upper limits of */ 112 u_int rx_upper_limit; /* receive buffer. */ 113 114 u_int rx_head; /* Head of receive ring buffer. */ 115 u_int tx_mem_size; /* Tx memory size (by default, */ 116 /* last quarter of total memory).*/ 117 118 u_int tx_lower_limit; /* Lower and upper limits of */ 119 u_int tx_upper_limit; /* transmit buffer. */ 120 121 u_int tx_head; /* Head and tail of */ 122 u_int tx_tail; /* transmit ring buffer. */ 123 124 u_int tx_last; /* Pointer to beginning of last */ 125 /* frame in the chain. */ 126}; 127 128static char irq2eemap[] = 129 { -1, -1, 0, 1, -1, 2, -1, -1, -1, 0, 3, 4, -1, -1, -1, -1 }; 130static u_char ee2irqmap[] = 131 { 9, 3, 5, 10, 11, 0, 0, 0 }; 132 133static char plus_irq2eemap[] = 134 { -1, -1, -1, 0, 1, 2, -1, 3, -1, 4, 5, 6, 7, -1, -1, -1 }; 135static u_char plus_ee2irqmap[] = 136 { 3, 4, 5, 7, 9, 10, 11, 12 }; 137 138/* Bus Front End Functions */ 139static void ex_isa_identify __P((driver_t *, device_t)); 140static int ex_isa_probe __P((device_t)); 141static int ex_isa_attach __P((device_t)); 142 143/* Network Interface Functions */ 144static void ex_init __P((void *)); 145static void ex_start __P((struct ifnet *)); 146static int ex_ioctl __P((struct ifnet *, u_long, caddr_t)); 147static void ex_watchdog __P((struct ifnet *)); 148 149static void ex_stop __P((struct ex_softc *)); 150static void ex_reset __P((struct ex_softc *)); 151 152static driver_intr_t ex_intr; 153static void ex_tx_intr __P((struct ex_softc *)); 154static void ex_rx_intr __P((struct ex_softc *)); 155 156static u_short eeprom_read __P((int, int)); 157 158static device_method_t ex_methods[] = { 159 /* Device interface */ 160 DEVMETHOD(device_identify, ex_isa_identify), 161 DEVMETHOD(device_probe, ex_isa_probe), 162 DEVMETHOD(device_attach, ex_isa_attach), 163 164 { 0, 0 } 165}; 166 167static driver_t ex_driver = { 168 "ex", 169 ex_methods, 170 sizeof(struct ex_softc), 171}; 172 173static devclass_t ex_devclass; 174 175DRIVER_MODULE(ex, isa, ex_driver, ex_devclass, 0, 0); 176 177static struct isa_pnp_id ex_ids[] = { 178 { 0x3110d425, NULL }, /* INT1031 */ 179 { 0x3010d425, NULL }, /* INT1030 */ 180 { 0, NULL }, 181}; 182 183static int 184look_for_card (u_int iobase) 185{ 186 int count1, count2; 187 188 /* 189 * Check for the i82595 signature, and check that the round robin 190 * counter actually advances. 191 */ 192 if (((count1 = inb(iobase + ID_REG)) & Id_Mask) != Id_Sig) 193 return(0); 194 count2 = inb(iobase + ID_REG); 195 count2 = inb(iobase + ID_REG); 196 count2 = inb(iobase + ID_REG); 197 198 return((count2 & Counter_bits) == ((count1 + 0xc0) & Counter_bits)); 199} 200 201static int 202ex_get_media (u_int32_t iobase) 203{ 204 int tmp; 205 206 outb(iobase + CMD_REG, Bank2_Sel); 207 tmp = inb(iobase + REG3); 208 outb(iobase + CMD_REG, Bank0_Sel); 209 210 if (tmp & TPE_bit) 211 return(Conn_TPE); 212 if (tmp & BNC_bit) 213 return(Conn_BNC); 214 215 return (Conn_AUI); 216} 217 218static void 219ex_get_address (u_int32_t iobase, u_char *enaddr) 220{ 221 u_int16_t eaddr_tmp; 222 223 eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Lo); 224 enaddr[5] = eaddr_tmp & 0xff; 225 enaddr[4] = eaddr_tmp >> 8; 226 eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Mid); 227 enaddr[3] = eaddr_tmp & 0xff; 228 enaddr[2] = eaddr_tmp >> 8; 229 eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Hi); 230 enaddr[1] = eaddr_tmp & 0xff; 231 enaddr[0] = eaddr_tmp >> 8; 232 233 return; 234} 235 236static int 237ex_card_type (u_char *enaddr) 238{ 239 if ((enaddr[0] == 0x00) && (enaddr[1] == 0xA0) && (enaddr[2] == 0xC9)) 240 return (CARD_TYPE_EX_10_PLUS); 241 242 return (CARD_TYPE_EX_10); 243} 244 245/* 246 * Non-destructive identify. 247 */ 248static void 249ex_isa_identify (driver_t *driver, device_t parent) 250{ 251 device_t child; 252 u_int32_t ioport; 253 u_char enaddr[6]; 254 u_int irq; 255 int tmp; 256 const char * desc; 257 258 for (ioport = 0x200; ioport < 0x3a0; ioport += 0x10) { 259 260 /* No board found at address */ 261 if (!look_for_card(ioport)) { 262 continue; 263 } 264 265 /* Board in PnP mode */ 266 if (eeprom_read(ioport, 0) & 0x01) { 267 continue; 268 } 269 270 bzero(enaddr, sizeof(enaddr)); 271 272 /* Reset the card. */ 273 outb(ioport + CMD_REG, Reset_CMD); 274 DELAY(400); 275 276 ex_get_address(ioport, enaddr); 277 tmp = eeprom_read(ioport, EE_IRQ_No) & IRQ_No_Mask; 278 279 /* work out which set of irq <-> internal tables to use */ 280 if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) { 281 irq = plus_ee2irqmap[tmp]; 282 desc = "Intel Pro/10+"; 283 } else { 284 irq = ee2irqmap[tmp]; 285 desc = "Intel Pro/10"; 286 } 287 288 child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ex", -1); 289 device_set_desc_copy(child, desc); 290 device_set_driver(child, driver); 291 bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); 292 bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, EX_IOSIZE); 293 } 294 295 return; 296} 297 298static int 299ex_isa_probe(device_t dev) 300{ 301 u_int iobase; 302 u_int irq; 303 char * irq2ee; 304 u_char * ee2irq; 305 u_char enaddr[6]; 306 int tmp; 307 int error; 308 309 DODEBUG(Start_End, printf("ex_probe: start\n");); 310 311 /* Check isapnp ids */ 312 error = ISA_PNP_PROBE(device_get_parent(dev), dev, ex_ids); 313 314 /* If the card had a PnP ID that didn't match any we know about */ 315 if (error == ENXIO) { 316 return(error); 317 } 318 319 /* If we had some other problem. */ 320 if (!(error == 0 || error == ENOENT)) { 321 return(error); 322 } 323 324 iobase = bus_get_resource_start(dev, SYS_RES_IOPORT, 0); 325 if (iobase && !look_for_card(iobase)) { 326 printf("ex: no card found at 0x%03x\n", iobase); 327 return(ENXIO); 328 } 329 330 /* 331 * Reset the card. 332 */ 333 outb(iobase + CMD_REG, Reset_CMD); 334 DELAY(400); 335 336 ex_get_address(iobase, enaddr); 337 338 /* work out which set of irq <-> internal tables to use */ 339 if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) { 340 irq2ee = plus_irq2eemap; 341 ee2irq = plus_ee2irqmap; 342 } else { 343 irq2ee = irq2eemap; 344 ee2irq = ee2irqmap; 345 } 346 347 tmp = eeprom_read(iobase, EE_IRQ_No) & IRQ_No_Mask; 348 irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0); 349 350 if (irq > 0) { 351 /* This will happen if board is in PnP mode. */ 352 if (ee2irq[tmp] != irq) { 353 printf("ex: WARNING: board's EEPROM is configured" 354 " for IRQ %d, using %d\n", 355 ee2irq[tmp], irq); 356 } 357 } else { 358 irq = ee2irq[tmp]; 359 bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1); 360 } 361 362 if (irq == 0) { 363 printf("ex: invalid IRQ.\n"); 364 return(ENXIO); 365 } 366 367 DODEBUG(Start_End, printf("ex_probe: finish\n");); 368 369 return(0); 370} 371 372static int 373ex_isa_attach(device_t dev) 374{ 375 struct ex_softc * sc = device_get_softc(dev); 376 struct ifnet * ifp = &sc->arpcom.ac_if; 377 int unit = device_get_unit(dev); 378 int error; 379 int rid; 380 void * ih; 381 382 DODEBUG(Start_End, device_printf(dev, "start\n");); 383 384 rid = 0; 385 sc->ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 386 0, ~0, 1, RF_ACTIVE); 387 388 if (!sc->ioport) { 389 device_printf(dev, "No I/O space?!\n"); 390 goto bad; 391 } 392 393 rid = 0; 394 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 395 0, ~0, 1, RF_ACTIVE); 396 397 if (!sc->irq) { 398 device_printf(dev, "No IRQ?!\n"); 399 goto bad; 400 } 401 402 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, 403 ex_intr, (void *)sc, &ih); 404 405 if (error) { 406 device_printf(dev, "bus_setup_intr() failed!\n"); 407 goto bad; 408 } 409 410 /* 411 * Fill in several fields of the softc structure: 412 * - I/O base address. 413 * - Hardware Ethernet address. 414 * - IRQ number (if not supplied in config file, read it from EEPROM). 415 * - Connector type. 416 */ 417 sc->dev = dev; 418 sc->iobase = rman_get_start(sc->ioport); 419 sc->irq_no = rman_get_start(sc->irq); 420 421 ex_get_address(sc->iobase, sc->arpcom.ac_enaddr); 422 423 /* work out which set of irq <-> internal tables to use */ 424 if (ex_card_type(sc->arpcom.ac_enaddr) == CARD_TYPE_EX_10_PLUS) { 425 sc->irq2ee = plus_irq2eemap; 426 sc->ee2irq = plus_ee2irqmap; 427 } else { 428 sc->irq2ee = irq2eemap; 429 sc->ee2irq = ee2irqmap; 430 } 431 432 sc->connector = ex_get_media(sc->iobase); 433 sc->mem_size = CARD_RAM_SIZE; /* XXX This should be read from the card itself. */ 434 435 /* 436 * Initialize the ifnet structure. 437 */ 438 ifp->if_softc = sc; 439 ifp->if_unit = unit; 440 ifp->if_name = "ex"; 441 ifp->if_mtu = ETHERMTU; 442 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST /* XXX not done yet. | IFF_MULTICAST */; 443 ifp->if_output = ether_output; 444 ifp->if_start = ex_start; 445 ifp->if_ioctl = ex_ioctl; 446 ifp->if_watchdog = ex_watchdog; 447 ifp->if_init = ex_init; 448 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 449 450 /* 451 * Attach the interface. 452 */ 453 if_attach(ifp); 454 ether_ifattach(ifp); 455 456 device_printf(sc->dev, "Ethernet address %6D\n", 457 sc->arpcom.ac_enaddr, ":"); 458 459 /* 460 * If BPF is in the kernel, call the attach for it 461 */ 462 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); 463 DODEBUG(Start_End, printf("ex_isa_attach%d: finish\n", unit);); 464 465 return(0); 466bad: 467 468 if (sc->ioport) 469 bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->ioport); 470 if (sc->irq) 471 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); 472 473 return (-1); 474} 475 476 477static void 478ex_init(void *xsc) 479{ 480 struct ex_softc * sc = (struct ex_softc *) xsc; 481 struct ifnet * ifp = &sc->arpcom.ac_if; 482 int s; 483 int i; 484 register int iobase = sc->iobase; 485 unsigned short temp_reg; 486 487 DODEBUG(Start_End, printf("ex_init%d: start\n", ifp->if_unit);); 488 489 if (ifp->if_addrhead.tqh_first == NULL) { 490 return; 491 } 492 s = splimp(); 493 sc->arpcom.ac_if.if_timer = 0; 494 495 /* 496 * Load the ethernet address into the card. 497 */ 498 outb(iobase + CMD_REG, Bank2_Sel); 499 temp_reg = inb(iobase + EEPROM_REG); 500 if (temp_reg & Trnoff_Enable) { 501 outb(iobase + EEPROM_REG, temp_reg & ~Trnoff_Enable); 502 } 503 for (i = 0; i < ETHER_ADDR_LEN; i++) { 504 outb(iobase + I_ADDR_REG0 + i, sc->arpcom.ac_enaddr[i]); 505 } 506 /* 507 * - Setup transmit chaining and discard bad received frames. 508 * - Match broadcast. 509 * - Clear test mode. 510 * - Set receiving mode. 511 * - Set IRQ number. 512 */ 513 outb(iobase + REG1, inb(iobase + REG1) | Tx_Chn_Int_Md | Tx_Chn_ErStp | Disc_Bad_Fr); 514 outb(iobase + REG2, inb(iobase + REG2) | No_SA_Ins | RX_CRC_InMem); 515 outb(iobase + REG3, inb(iobase + REG3) & 0x3f /* XXX constants. */ ); 516 outb(iobase + CMD_REG, Bank1_Sel); 517 outb(iobase + INT_NO_REG, (inb(iobase + INT_NO_REG) & 0xf8) | sc->irq2ee[sc->irq_no]); 518 519 /* 520 * Divide the available memory in the card into rcv and xmt buffers. 521 * By default, I use the first 3/4 of the memory for the rcv buffer, 522 * and the remaining 1/4 of the memory for the xmt buffer. 523 */ 524 sc->rx_mem_size = sc->mem_size * 3 / 4; 525 sc->tx_mem_size = sc->mem_size - sc->rx_mem_size; 526 sc->rx_lower_limit = 0x0000; 527 sc->rx_upper_limit = sc->rx_mem_size - 2; 528 sc->tx_lower_limit = sc->rx_mem_size; 529 sc->tx_upper_limit = sc->mem_size - 2; 530 outb(iobase + RCV_LOWER_LIMIT_REG, sc->rx_lower_limit >> 8); 531 outb(iobase + RCV_UPPER_LIMIT_REG, sc->rx_upper_limit >> 8); 532 outb(iobase + XMT_LOWER_LIMIT_REG, sc->tx_lower_limit >> 8); 533 outb(iobase + XMT_UPPER_LIMIT_REG, sc->tx_upper_limit >> 8); 534 535 /* 536 * Enable receive and transmit interrupts, and clear any pending int. 537 */ 538 outb(iobase + REG1, inb(iobase + REG1) | TriST_INT); 539 outb(iobase + CMD_REG, Bank0_Sel); 540 outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); 541 outb(iobase + STATUS_REG, All_Int); 542 543 /* 544 * Initialize receive and transmit ring buffers. 545 */ 546 outw(iobase + RCV_BAR, sc->rx_lower_limit); 547 sc->rx_head = sc->rx_lower_limit; 548 outw(iobase + RCV_STOP_REG, sc->rx_upper_limit | 0xfe); 549 outw(iobase + XMT_BAR, sc->tx_lower_limit); 550 sc->tx_head = sc->tx_tail = sc->tx_lower_limit; 551 552 ifp->if_flags |= IFF_RUNNING; 553 ifp->if_flags &= ~IFF_OACTIVE; 554 DODEBUG(Status, printf("OIDLE init\n");); 555 556 /* 557 * Final reset of the board, and enable operation. 558 */ 559 outb(iobase + CMD_REG, Sel_Reset_CMD); 560 DELAY(2); 561 outb(iobase + CMD_REG, Rcv_Enable_CMD); 562 563 ex_start(ifp); 564 splx(s); 565 566 DODEBUG(Start_End, printf("ex_init%d: finish\n", ifp->if_unit);); 567} 568 569 570static void 571ex_start(struct ifnet *ifp) 572{ 573 struct ex_softc * sc = ifp->if_softc; 574 int iobase = sc->iobase; 575 int i, s, len, data_len, avail, dest, next; 576 unsigned char tmp16[2]; 577 struct mbuf * opkt; 578 struct mbuf * m; 579 580 DODEBUG(Start_End, printf("ex_start%d: start\n", unit);); 581 582 s = splimp(); 583 584 /* 585 * Main loop: send outgoing packets to network card until there are no 586 * more packets left, or the card cannot accept any more yet. 587 */ 588 while (((opkt = ifp->if_snd.ifq_head) != NULL) && 589 !(ifp->if_flags & IFF_OACTIVE)) { 590 591 /* 592 * Ensure there is enough free transmit buffer space for 593 * this packet, including its header. Note: the header 594 * cannot wrap around the end of the transmit buffer and 595 * must be kept together, so we allow space for twice the 596 * length of the header, just in case. 597 */ 598 599 for (len = 0, m = opkt; m != NULL; m = m->m_next) { 600 len += m->m_len; 601 } 602 603 data_len = len; 604 605 DODEBUG(Sent_Pkts, printf("1. Sending packet with %d data bytes. ", data_len);); 606 607 if (len & 1) { 608 len += XMT_HEADER_LEN + 1; 609 } else { 610 len += XMT_HEADER_LEN; 611 } 612 613 if ((i = sc->tx_tail - sc->tx_head) >= 0) { 614 avail = sc->tx_mem_size - i; 615 } else { 616 avail = -i; 617 } 618 619 DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail);); 620 621 if (avail >= len + XMT_HEADER_LEN) { 622 IF_DEQUEUE(&ifp->if_snd, opkt); 623 624#ifdef EX_PSA_INTR 625 /* 626 * Disable rx and tx interrupts, to avoid corruption 627 * of the host address register by interrupt service 628 * routines. 629 * XXX Is this necessary with splimp() enabled? 630 */ 631 outb(iobase + MASK_REG, All_Int); 632#endif 633 634 /* 635 * Compute the start and end addresses of this 636 * frame in the tx buffer. 637 */ 638 dest = sc->tx_tail; 639 next = dest + len; 640 641 if (next > sc->tx_upper_limit) { 642 if ((sc->tx_upper_limit + 2 - sc->tx_tail) <= 643 XMT_HEADER_LEN) { 644 dest = sc->tx_lower_limit; 645 next = dest + len; 646 } else { 647 next = sc->tx_lower_limit + 648 next - sc->tx_upper_limit - 2; 649 } 650 } 651 652 /* 653 * Build the packet frame in the card's ring buffer. 654 */ 655 DODEBUG(Sent_Pkts, printf("2. dest=%d, next=%d. ", dest, next);); 656 657 outw(iobase + HOST_ADDR_REG, dest); 658 outw(iobase + IO_PORT_REG, Transmit_CMD); 659 outw(iobase + IO_PORT_REG, 0); 660 outw(iobase + IO_PORT_REG, next); 661 outw(iobase + IO_PORT_REG, data_len); 662 663 /* 664 * Output the packet data to the card. Ensure all 665 * transfers are 16-bit wide, even if individual 666 * mbufs have odd length. 667 */ 668 669 for (m = opkt, i = 0; m != NULL; m = m->m_next) { 670 DODEBUG(Sent_Pkts, printf("[%d]", m->m_len);); 671 if (i) { 672 tmp16[1] = *(mtod(m, caddr_t)); 673 outsw(iobase + IO_PORT_REG, tmp16, 1); 674 } 675 outsw(iobase + IO_PORT_REG, 676 mtod(m, caddr_t) + i, (m->m_len - i) / 2); 677 678 if ((i = (m->m_len - i) & 1) != 0) { 679 tmp16[0] = *(mtod(m, caddr_t) + 680 m->m_len - 1); 681 } 682 } 683 if (i) { 684 outsw(iobase + IO_PORT_REG, tmp16, 1); 685 } 686 687 /* 688 * If there were other frames chained, update the 689 * chain in the last one. 690 */ 691 if (sc->tx_head != sc->tx_tail) { 692 if (sc->tx_tail != dest) { 693 outw(iobase + HOST_ADDR_REG, 694 sc->tx_last + XMT_Chain_Point); 695 outw(iobase + IO_PORT_REG, dest); 696 } 697 outw(iobase + HOST_ADDR_REG, 698 sc->tx_last + XMT_Byte_Count); 699 i = inw(iobase + IO_PORT_REG); 700 outw(iobase + HOST_ADDR_REG, 701 sc->tx_last + XMT_Byte_Count); 702 outw(iobase + IO_PORT_REG, i | Ch_bit); 703 } 704 705 /* 706 * Resume normal operation of the card: 707 * - Make a dummy read to flush the DRAM write 708 * pipeline. 709 * - Enable receive and transmit interrupts. 710 * - Send Transmit or Resume_XMT command, as 711 * appropriate. 712 */ 713 inw(iobase + IO_PORT_REG); 714#ifdef EX_PSA_INTR 715 outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); 716#endif 717 if (sc->tx_head == sc->tx_tail) { 718 outw(iobase + XMT_BAR, dest); 719 outb(iobase + CMD_REG, Transmit_CMD); 720 sc->tx_head = dest; 721 DODEBUG(Sent_Pkts, printf("Transmit\n");); 722 } else { 723 outb(iobase + CMD_REG, Resume_XMT_List_CMD); 724 DODEBUG(Sent_Pkts, printf("Resume\n");); 725 } 726 727 sc->tx_last = dest; 728 sc->tx_tail = next; 729 730 if (ifp->if_bpf != NULL) { 731 bpf_mtap(ifp, opkt); 732 } 733 734 ifp->if_timer = 2; 735 ifp->if_opackets++; 736 m_freem(opkt); 737 } else { 738 ifp->if_flags |= IFF_OACTIVE; 739 DODEBUG(Status, printf("OACTIVE start\n");); 740 } 741 } 742 743 splx(s); 744 745 DODEBUG(Start_End, printf("ex_start%d: finish\n", unit);); 746} 747 748static void 749ex_stop(struct ex_softc *sc) 750{ 751 int iobase = sc->iobase; 752 753 DODEBUG(Start_End, printf("ex_stop%d: start\n", unit);); 754 755 /* 756 * Disable card operation: 757 * - Disable the interrupt line. 758 * - Flush transmission and disable reception. 759 * - Mask and clear all interrupts. 760 * - Reset the 82595. 761 */ 762 outb(iobase + CMD_REG, Bank1_Sel); 763 outb(iobase + REG1, inb(iobase + REG1) & ~TriST_INT); 764 outb(iobase + CMD_REG, Bank0_Sel); 765 outb(iobase + CMD_REG, Rcv_Stop); 766 sc->tx_head = sc->tx_tail = sc->tx_lower_limit; 767 sc->tx_last = 0; /* XXX I think these two lines are not necessary, because ex_init will always be called again to reinit the interface. */ 768 outb(iobase + MASK_REG, All_Int); 769 outb(iobase + STATUS_REG, All_Int); 770 outb(iobase + CMD_REG, Reset_CMD); 771 DELAY(200); 772 773 DODEBUG(Start_End, printf("ex_stop%d: finish\n", unit);); 774 775 return; 776} 777 778 779static void 780ex_intr(void *arg) 781{ 782 struct ex_softc * sc = (struct ex_softc *)arg; 783 struct ifnet * ifp = &sc->arpcom.ac_if; 784 int iobase = sc->iobase; 785 int int_status, send_pkts; 786 787 DODEBUG(Start_End, printf("ex_intr%d: start\n", unit);); 788 789#ifdef EXDEBUG 790 if (++exintr_count != 1) 791 printf("WARNING: nested interrupt (%d). Mail the author.\n", exintr_count); 792#endif 793 794 send_pkts = 0; 795 while ((int_status = inb(iobase + STATUS_REG)) & (Tx_Int | Rx_Int)) { 796 if (int_status & Rx_Int) { 797 outb(iobase + STATUS_REG, Rx_Int); 798 799 ex_rx_intr(sc); 800 } else if (int_status & Tx_Int) { 801 outb(iobase + STATUS_REG, Tx_Int); 802 803 ex_tx_intr(sc); 804 send_pkts = 1; 805 } 806 } 807 808 /* 809 * If any packet has been transmitted, and there are queued packets to 810 * be sent, attempt to send more packets to the network card. 811 */ 812 813 if (send_pkts && (ifp->if_snd.ifq_head != NULL)) { 814 ex_start(ifp); 815 } 816 817#ifdef EXDEBUG 818 exintr_count--; 819#endif 820 821 DODEBUG(Start_End, printf("ex_intr%d: finish\n", unit);); 822 823 return; 824} 825 826static void 827ex_tx_intr(struct ex_softc *sc) 828{ 829 struct ifnet * ifp = &sc->arpcom.ac_if; 830 int iobase = sc->iobase; 831 int tx_status; 832 833 DODEBUG(Start_End, printf("ex_tx_intr%d: start\n", unit);); 834 835 /* 836 * - Cancel the watchdog. 837 * For all packets transmitted since last transmit interrupt: 838 * - Advance chain pointer to next queued packet. 839 * - Update statistics. 840 */ 841 842 ifp->if_timer = 0; 843 844 while (sc->tx_head != sc->tx_tail) { 845 outw(iobase + HOST_ADDR_REG, sc->tx_head); 846 847 if (! inw(iobase + IO_PORT_REG) & Done_bit) 848 break; 849 850 tx_status = inw(iobase + IO_PORT_REG); 851 sc->tx_head = inw(iobase + IO_PORT_REG); 852 853 if (tx_status & TX_OK_bit) { 854 ifp->if_opackets++; 855 } else { 856 ifp->if_oerrors++; 857 } 858 859 ifp->if_collisions += tx_status & No_Collisions_bits; 860 } 861 862 /* 863 * The card should be ready to accept more packets now. 864 */ 865 866 ifp->if_flags &= ~IFF_OACTIVE; 867 868 DODEBUG(Status, printf("OIDLE tx_intr\n");); 869 DODEBUG(Start_End, printf("ex_tx_intr%d: finish\n", unit);); 870 871 return; 872} 873 874static void 875ex_rx_intr(struct ex_softc *sc) 876{ 877 struct ifnet * ifp = &sc->arpcom.ac_if; 878 int iobase = sc->iobase; 879 int rx_status; 880 int pkt_len; 881 int QQQ; 882 struct mbuf * m; 883 struct mbuf * ipkt; 884 struct ether_header * eh; 885 886 DODEBUG(Start_End, printf("ex_rx_intr%d: start\n", unit);); 887 888 /* 889 * For all packets received since last receive interrupt: 890 * - If packet ok, read it into a new mbuf and queue it to interface, 891 * updating statistics. 892 * - If packet bad, just discard it, and update statistics. 893 * Finally, advance receive stop limit in card's memory to new location. 894 */ 895 896 outw(iobase + HOST_ADDR_REG, sc->rx_head); 897 898 while (inw(iobase + IO_PORT_REG) == RCV_Done) { 899 900 rx_status = inw(iobase + IO_PORT_REG); 901 sc->rx_head = inw(iobase + IO_PORT_REG); 902 QQQ = pkt_len = inw(iobase + IO_PORT_REG); 903 904 if (rx_status & RCV_OK_bit) { 905 MGETHDR(m, M_DONTWAIT, MT_DATA); 906 ipkt = m; 907 if (ipkt == NULL) { 908 ifp->if_iqdrops++; 909 } else { 910 ipkt->m_pkthdr.rcvif = ifp; 911 ipkt->m_pkthdr.len = pkt_len; 912 ipkt->m_len = MHLEN; 913 914 while (pkt_len > 0) { 915 if (pkt_len > MINCLSIZE) { 916 MCLGET(m, M_DONTWAIT); 917 if (m->m_flags & M_EXT) { 918 m->m_len = MCLBYTES; 919 } else { 920 m_freem(ipkt); 921 ifp->if_iqdrops++; 922 goto rx_another; 923 } 924 } 925 m->m_len = min(m->m_len, pkt_len); 926 927 /* 928 * NOTE: I'm assuming that all mbufs allocated are of even length, 929 * except for the last one in an odd-length packet. 930 */ 931 932 insw(iobase + IO_PORT_REG, 933 mtod(m, caddr_t), m->m_len / 2); 934 935 if (m->m_len & 1) { 936 *(mtod(m, caddr_t) + m->m_len - 1) = inb(iobase + IO_PORT_REG); 937 } 938 pkt_len -= m->m_len; 939 940 if (pkt_len > 0) { 941 MGET(m->m_next, M_DONTWAIT, MT_DATA); 942 if (m->m_next == NULL) { 943 m_freem(ipkt); 944 ifp->if_iqdrops++; 945 goto rx_another; 946 } 947 m = m->m_next; 948 m->m_len = MLEN; 949 } 950 } 951 eh = mtod(ipkt, struct ether_header *); 952#ifdef EXDEBUG 953 if (debug_mask & Rcvd_Pkts) { 954 if ((eh->ether_dhost[5] != 0xff) || (eh->ether_dhost[0] != 0xff)) { 955 printf("Receive packet with %d data bytes: %6D -> ", QQQ, eh->ether_shost, ":"); 956 printf("%6D\n", eh->ether_dhost, ":"); 957 } /* QQQ */ 958 } 959#endif 960 if (ifp->if_bpf != NULL) { 961 bpf_mtap(ifp, ipkt); 962 963 /* 964 * Note that the interface cannot be in promiscuous mode 965 * if there are no BPF listeners. And if we are in 966 * promiscuous mode, we have to check if this packet is 967 * really ours. 968 */ 969 if ((ifp->if_flags & IFF_PROMISC) && 970 (eh->ether_dhost[0] & 1) == 0 && 971 bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, sizeof(eh->ether_dhost)) != 0 && 972 bcmp(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost)) != 0) { 973 m_freem(ipkt); 974 goto rx_another; 975 } 976 } 977 m_adj(ipkt, sizeof(struct ether_header)); 978 ether_input(ifp, eh, ipkt); 979 ifp->if_ipackets++; 980 } 981 } else { 982 ifp->if_ierrors++; 983 } 984 outw(iobase + HOST_ADDR_REG, sc->rx_head); 985rx_another: ; 986 } 987 988 if (sc->rx_head < sc->rx_lower_limit + 2) 989 outw(iobase + RCV_STOP_REG, sc->rx_upper_limit); 990 else 991 outw(iobase + RCV_STOP_REG, sc->rx_head - 2); 992 993 DODEBUG(Start_End, printf("ex_rx_intr%d: finish\n", unit);); 994 995 return; 996} 997 998 999static int 1000ex_ioctl(register struct ifnet *ifp, u_long cmd, caddr_t data) 1001{ 1002 struct ex_softc * sc = ifp->if_softc; 1003 int s; 1004 int error = 0; 1005 1006 DODEBUG(Start_End, printf("ex_ioctl%d: start ", ifp->if_unit);); 1007 1008 s = splimp(); 1009 1010 switch(cmd) { 1011 case SIOCSIFADDR: 1012 case SIOCGIFADDR: 1013 case SIOCSIFMTU: 1014 error = ether_ioctl(ifp, cmd, data); 1015 break; 1016 1017 case SIOCSIFFLAGS: 1018 DODEBUG(Start_End, printf("SIOCSIFFLAGS");); 1019 if ((ifp->if_flags & IFF_UP) == 0 && 1020 (ifp->if_flags & IFF_RUNNING)) { 1021 1022 ifp->if_flags &= ~IFF_RUNNING; 1023 ex_stop(sc); 1024 } else { 1025 ex_init(sc); 1026 } 1027 break; 1028#ifdef NODEF 1029 case SIOCGHWADDR: 1030 DODEBUG(Start_End, printf("SIOCGHWADDR");); 1031 bcopy((caddr_t)sc->sc_addr, (caddr_t)&ifr->ifr_data, 1032 sizeof(sc->sc_addr)); 1033 break; 1034#endif 1035 case SIOCADDMULTI: 1036 DODEBUG(Start_End, printf("SIOCADDMULTI");); 1037 case SIOCDELMULTI: 1038 DODEBUG(Start_End, printf("SIOCDELMULTI");); 1039 /* XXX Support not done yet. */ 1040 error = EINVAL; 1041 break; 1042 default: 1043 DODEBUG(Start_End, printf("unknown");); 1044 error = EINVAL; 1045 } 1046 1047 splx(s); 1048 1049 DODEBUG(Start_End, printf("\nex_ioctl%d: finish\n", ifp->if_unit);); 1050 1051 return(error); 1052} 1053 1054 1055static void 1056ex_reset(struct ex_softc *sc) 1057{ 1058 int s; 1059 1060 DODEBUG(Start_End, printf("ex_reset%d: start\n", unit);); 1061 1062 s = splimp(); 1063 1064 ex_stop(sc); 1065 ex_init(sc); 1066 1067 splx(s); 1068 1069 DODEBUG(Start_End, printf("ex_reset%d: finish\n", unit);); 1070 1071 return; 1072} 1073 1074 1075static void 1076ex_watchdog(struct ifnet *ifp) 1077{ 1078 struct ex_softc * sc = ifp->if_softc; 1079 1080 DODEBUG(Start_End, printf("ex_watchdog%d: start\n", ifp->if_unit);); 1081 1082 ifp->if_flags &= ~IFF_OACTIVE; 1083 1084 DODEBUG(Status, printf("OIDLE watchdog\n");); 1085 1086 ifp->if_oerrors++; 1087 ex_reset(sc); 1088 ex_start(ifp); 1089 1090 DODEBUG(Start_End, printf("ex_watchdog%d: finish\n", ifp->if_unit);); 1091 1092 return; 1093} 1094 1095 1096static u_short 1097eeprom_read(int iobase, int location) 1098{ 1099 int i; 1100 u_short data = 0; 1101 int ee_addr; 1102 int read_cmd = location | EE_READ_CMD; 1103 short ctrl_val = EECS; 1104 1105 ee_addr = iobase + EEPROM_REG; 1106 outb(iobase + CMD_REG, Bank2_Sel); 1107 outb(ee_addr, EECS); 1108 for (i = 8; i >= 0; i--) { 1109 short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val; 1110 outb(ee_addr, outval); 1111 outb(ee_addr, outval | EESK); 1112 DELAY(3); 1113 outb(ee_addr, outval); 1114 DELAY(2); 1115 } 1116 outb(ee_addr, ctrl_val); 1117 1118 for (i = 16; i > 0; i--) { 1119 outb(ee_addr, ctrl_val | EESK); 1120 DELAY(3); 1121 data = (data << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0); 1122 outb(ee_addr, ctrl_val); 1123 DELAY(2); 1124 } 1125 1126 ctrl_val &= ~EECS; 1127 outb(ee_addr, ctrl_val | EESK); 1128 DELAY(3); 1129 outb(ee_addr, ctrl_val); 1130 DELAY(2); 1131 outb(iobase + CMD_REG, Bank0_Sel); 1132 return(data); 1133} 1134